agx: Pack local load/store instructions

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21326>
This commit is contained in:
Alyssa Rosenzweig 2023-02-08 20:33:53 -05:00 committed by Marge Bot
parent 96904f83b4
commit 2a021b1818

View file

@ -166,6 +166,41 @@ agx_pack_memory_index(agx_index index, bool *flag)
}
}
static uint16_t
agx_pack_local_base(agx_index index, unsigned *flags)
{
assert(index.size == AGX_SIZE_16);
if (index.type == AGX_INDEX_IMMEDIATE) {
assert(index.value == 0);
*flags = 2;
return 0;
} else if (index.type == AGX_INDEX_UNIFORM) {
*flags = 1 | ((index.value >> 8) << 1);
return index.value & BITFIELD_MASK(7);
} else {
assert_register_is_aligned(index);
*flags = 0;
return index.value;
}
}
static uint16_t
agx_pack_local_index(agx_index index, bool *flag)
{
assert(index.size == AGX_SIZE_16);
if (index.type == AGX_INDEX_IMMEDIATE) {
assert(index.value < 0x10000);
*flag = 1;
return index.value;
} else {
assert_register_is_aligned(index);
*flag = 0;
return index.value;
}
}
static unsigned
agx_pack_atomic_source(agx_index index)
{
@ -605,6 +640,30 @@ agx_pack_instr(struct util_dynarray *emission, struct util_dynarray *fixups,
break;
}
case AGX_OPCODE_LOCAL_LOAD:
case AGX_OPCODE_LOCAL_STORE: {
bool is_load = I->op == AGX_OPCODE_LOCAL_LOAD;
bool L = true; /* TODO: when would you want short? */
unsigned At;
bool Rt, Ot;
unsigned R = agx_pack_memory_reg(is_load ? I->dest[0] : I->src[0], &Rt);
unsigned A = agx_pack_local_base(is_load ? I->src[0] : I->src[1], &At);
unsigned O = agx_pack_local_index(is_load ? I->src[1] : I->src[2], &Ot);
uint64_t raw =
agx_opcodes_info[I->op].encoding.exact | (Rt ? BITFIELD64_BIT(8) : 0) |
((R & BITFIELD_MASK(6)) << 9) | (L ? BITFIELD64_BIT(15) : 0) |
((A & BITFIELD_MASK(6)) << 16) | (At << 22) | (I->format << 24) |
((O & BITFIELD64_MASK(6)) << 28) | (Ot ? BITFIELD64_BIT(34) : 0) |
(((uint64_t)I->mask) << 36) | (((uint64_t)(O >> 6)) << 48) |
(((uint64_t)(A >> 6)) << 58) | (((uint64_t)(R >> 6)) << 60);
unsigned size = L ? 8 : 6;
memcpy(util_dynarray_grow_bytes(emission, 1, size), &raw, size);
break;
}
case AGX_OPCODE_ATOMIC: {
bool At, Ot, Rt;
unsigned A = agx_pack_memory_base(I->src[1], &At);