Skip to content

Commit

Permalink
i#3044 AArch64 SVE codec: Add LD1RQ* (#5990)
Browse files Browse the repository at this point in the history
This patch adds the appropriate macros, tests and codec entries to
encode the following variants:
LD1RQB  { <Zt>.D }, <Pg>/Z, [<Xn|SP>{, #<simm>}]
LD1RQB  { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Xm>]
LD1RQD  { <Zt>.D }, <Pg>/Z, [<Xn|SP>{, #<simm>}]
LD1RQD  { <Zt>.D }, <Pg>/Z, [<Xn|SP>, <Xm>, LSL #3]
LD1RQH  { <Zt>.H }, <Pg>/Z, [<Xn|SP>{, #<simm>}]
LD1RQH  { <Zt>.H }, <Pg>/Z, [<Xn|SP>, <Xm>, LSL #1]
LD1RQW  { <Zt>.S }, <Pg>/Z, [<Xn|SP>{, #<simm>}]
LD1RQW  { <Zt>.S }, <Pg>/Z, [<Xn|SP>, <Xm>, LSL #2]

Issue: #3044
  • Loading branch information
jackgallagher-arm authored Apr 21, 2023
1 parent ca8233d commit 5d89aee
Show file tree
Hide file tree
Showing 6 changed files with 468 additions and 69 deletions.
141 changes: 102 additions & 39 deletions core/ir/aarch64/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -4467,16 +4467,19 @@ encode_opnd_s16(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
return encode_opnd_vector_reg(16, 2, opnd, enc_out);
}

static inline bool
svemem_gprs_per_element_decode(uint bytes_per_element, aarch64_reg_offset element_size,
uint shift_amount, uint enc, int opcode, byte *pc,
OUT opnd_t *opnd)
static inline opnd_size_t
calculate_mem_transfer(uint bytes_per_element, aarch64_reg_offset element_size)
{
ASSERT(element_size >= BYTE_REG && element_size <= DOUBLE_REG);

const uint elements = get_elements_in_sve_vector(element_size);
const opnd_size_t mem_transfer = opnd_size_from_bytes(bytes_per_element * elements);
return opnd_size_from_bytes(bytes_per_element * elements);
}

static inline bool
svemem_gprs_per_element_decode(opnd_size_t mem_transfer, uint shift_amount, uint enc,
int opcode, byte *pc, OUT opnd_t *opnd)
{
*opnd = opnd_create_base_disp_shift_aarch64(
decode_reg(extract_uint(enc, 5, 5), true, true),
decode_reg(extract_uint(enc, 16, 5), true, false), DR_EXTEND_UXTX,
Expand All @@ -4485,15 +4488,9 @@ svemem_gprs_per_element_decode(uint bytes_per_element, aarch64_reg_offset elemen
}

static inline bool
svemem_gprs_per_element_encode(uint bytes_per_element, aarch64_reg_offset element_size,
uint shift_amount, uint enc, int opcode, byte *pc,
opnd_t opnd, OUT uint *enc_out)
svemem_gprs_per_element_encode(opnd_size_t mem_transfer, uint shift_amount, uint enc,
int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
{
ASSERT(element_size >= BYTE_REG && element_size <= DOUBLE_REG);

const uint elements = get_elements_in_sve_vector(element_size);
const opnd_size_t mem_transfer = opnd_size_from_bytes(bytes_per_element * elements);

if (!opnd_is_base_disp(opnd) || opnd_get_size(opnd) != mem_transfer ||
opnd_get_disp(opnd) != 0)
return false;
Expand All @@ -4518,13 +4515,15 @@ svemem_gprs_per_element_encode(uint bytes_per_element, aarch64_reg_offset elemen
static inline bool
decode_opnd_svemem_gprs_b1(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
return svemem_gprs_per_element_decode(1, BYTE_REG, 0, enc, opcode, pc, opnd);
return svemem_gprs_per_element_decode(calculate_mem_transfer(1, BYTE_REG), 0, enc,
opcode, pc, opnd);
}

static inline bool
encode_opnd_svemem_gprs_b1(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
{
return svemem_gprs_per_element_encode(1, BYTE_REG, 0, enc, opcode, pc, opnd, enc_out);
return svemem_gprs_per_element_encode(calculate_mem_transfer(1, BYTE_REG), 0, enc,
opcode, pc, opnd, enc_out);
}

/* imm8_10: 8 bit imm at pos 10, split across 20:16 and 12:10. */
Expand Down Expand Up @@ -5190,8 +5189,7 @@ encode_opnd_prf12(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out
}

static inline bool
decode_svemem_gpr_simm4_vl(uint enc, opnd_size_t transfer_size, int scale,
OUT opnd_t *opnd)
decode_svemem_gpr_simm4(uint enc, opnd_size_t transfer_size, int scale, OUT opnd_t *opnd)
{
const int offset = extract_int(enc, 16, 4) * scale;
const reg_id_t rn = decode_reg(extract_uint(enc, 5, 5), true, true);
Expand All @@ -5202,8 +5200,8 @@ decode_svemem_gpr_simm4_vl(uint enc, opnd_size_t transfer_size, int scale,
}

static inline bool
encode_svemem_gpr_simm4_vl(uint enc, opnd_size_t transfer_size, int scale, opnd_t opnd,
OUT uint *enc_out)
encode_svemem_gpr_simm4(uint enc, opnd_size_t transfer_size, int scale, opnd_t opnd,
OUT uint *enc_out)
{
if (!opnd_is_base_disp(opnd) || opnd_get_size(opnd) != transfer_size ||
opnd_get_index(opnd) != DR_REG_NULL)
Expand All @@ -5223,6 +5221,36 @@ encode_svemem_gpr_simm4_vl(uint enc, opnd_size_t transfer_size, int scale, opnd_
return true;
}

static inline bool
decode_ssz(uint enc, OUT opnd_size_t *transfer_size)
{
switch (BITS(enc, 22, 21)) {
case 0b00: *transfer_size = OPSZ_16; return true;
case 0b01: *transfer_size = OPSZ_32; return true;
default: break;
}
return false;
}

/* svemem_gpr_simm4: SVE memory operand [<Xn|SP>{, #<imm>}] */

static inline bool
decode_opnd_svemem_ssz_gpr_simm4(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
opnd_size_t transfer_size;
return decode_ssz(enc, &transfer_size) &&
decode_svemem_gpr_simm4(enc, transfer_size, 16, opnd);
}

static inline bool
encode_opnd_svemem_ssz_gpr_simm4(uint enc, int opcode, byte *pc, opnd_t opnd,
OUT uint *enc_out)
{
opnd_size_t transfer_size;
return decode_ssz(enc, &transfer_size) &&
encode_svemem_gpr_simm4(enc, OPSZ_16, 16, opnd, enc_out);
}

/* SVE memory operand [<Xn|SP>{, #<imm>, MUL VL}] multiple dest registers or nt */

static inline bool
Expand All @@ -5232,7 +5260,7 @@ decode_opnd_svemem_gpr_simm4_vl_xreg(uint enc, int opcode, byte *pc, OUT opnd_t
const opnd_size_t transfer_size =
opnd_size_from_bytes((register_count * dr_get_sve_vl()) / 8);

return decode_svemem_gpr_simm4_vl(enc, transfer_size, register_count, opnd);
return decode_svemem_gpr_simm4(enc, transfer_size, register_count, opnd);
}

static inline bool
Expand All @@ -5243,7 +5271,7 @@ encode_opnd_svemem_gpr_simm4_vl_xreg(uint enc, int opcode, byte *pc, opnd_t opnd
const opnd_size_t transfer_size =
opnd_size_from_bytes((register_count * dr_get_sve_vl()) / 8);

return encode_svemem_gpr_simm4_vl(enc, transfer_size, register_count, opnd, enc_out);
return encode_svemem_gpr_simm4(enc, transfer_size, register_count, opnd, enc_out);
}

/* hsd_immh_sz: The element size of a vector mediated by immh with possible values h, s
Expand Down Expand Up @@ -7028,15 +7056,44 @@ memory_transfer_size_from_dtype(uint enc)
static inline bool
decode_opnd_svemem_gpr_simm4_vl_1reg(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
return decode_svemem_gpr_simm4_vl(enc, memory_transfer_size_from_dtype(enc), 1, opnd);
return decode_svemem_gpr_simm4(enc, memory_transfer_size_from_dtype(enc), 1, opnd);
}

static inline bool
encode_opnd_svemem_gpr_simm4_vl_1reg(uint enc, int opcode, byte *pc, opnd_t opnd,
OUT uint *enc_out)
{
return encode_svemem_gpr_simm4_vl(enc, memory_transfer_size_from_dtype(enc), 1, opnd,
enc_out);
return encode_svemem_gpr_simm4(enc, memory_transfer_size_from_dtype(enc), 1, opnd,
enc_out);
}

/* SVE memory operand [<Xn|SP>, <Xm> LSL #x], mem transfer size based on ssz */

static inline bool
decode_opnd_svemem_ssz_gpr_shf(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
opnd_size_t mem_transfer;
if (!decode_ssz(enc, &mem_transfer))
return false;

const uint shift_amount = BITS(enc, 24, 23);

return svemem_gprs_per_element_decode(mem_transfer, shift_amount, enc, opcode, pc,
opnd);
}

static inline bool
encode_opnd_svemem_ssz_gpr_shf(uint enc, int opcode, byte *pc, opnd_t opnd,
OUT uint *enc_out)
{
opnd_size_t mem_transfer;
if (!decode_ssz(enc, &mem_transfer))
return false;

const uint shift_amount = BITS(enc, 24, 23);

return svemem_gprs_per_element_encode(mem_transfer, shift_amount, enc, opcode, pc,
opnd, enc_out);
}

static inline bool
Expand All @@ -7047,8 +7104,9 @@ decode_opnd_svemem_msz_gpr_shf(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)

const uint shift_amount = elsz;

return svemem_gprs_per_element_decode((1 << elsz) * (dests + 1), elsz, shift_amount,
enc, opcode, pc, opnd);
return svemem_gprs_per_element_decode(
calculate_mem_transfer((1 << elsz) * (dests + 1), elsz), shift_amount, enc,
opcode, pc, opnd);
}

static inline bool
Expand All @@ -7060,8 +7118,9 @@ encode_opnd_svemem_msz_gpr_shf(uint enc, int opcode, byte *pc, opnd_t opnd,

const uint shift_amount = elsz;

return svemem_gprs_per_element_encode((1 << elsz) * (dests + 1), elsz, shift_amount,
enc, opcode, pc, opnd, enc_out);
return svemem_gprs_per_element_encode(
calculate_mem_transfer((1 << elsz) * (dests + 1), elsz), shift_amount, enc,
opcode, pc, opnd, enc_out);
}

static inline bool
Expand All @@ -7074,8 +7133,9 @@ decode_opnd_svemem_msz_stgpr_shf(uint enc, int opcode, byte *pc, OUT opnd_t *opn

const uint shift_amount = elsz;

return svemem_gprs_per_element_decode((1 << elsz) * (dests + 1), elsz, shift_amount,
enc, opcode, pc, opnd);
return svemem_gprs_per_element_decode(
calculate_mem_transfer((1 << elsz) * (dests + 1), elsz), shift_amount, enc,
opcode, pc, opnd);
}

static inline bool
Expand All @@ -7088,7 +7148,8 @@ encode_opnd_svemem_msz_stgpr_shf(uint enc, int opcode, byte *pc, opnd_t opnd,
const uint shift_amount = elsz;

bool success = svemem_gprs_per_element_encode(
(1 << elsz) * (dests + 1), elsz, shift_amount, enc, opcode, pc, opnd, enc_out);
calculate_mem_transfer((1 << elsz) * (dests + 1), elsz), shift_amount, enc,
opcode, pc, opnd, enc_out);

if (BITS(enc, 20, 16) == 0b11111)
return false;
Expand All @@ -7102,8 +7163,8 @@ decode_opnd_svemem_gpr_shf(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)

const uint shift_amount = opnd_size_to_shift_amount(get_opnd_size_from_offset(insz));

return svemem_gprs_per_element_decode(1 << insz, elsz, shift_amount, enc, opcode, pc,
opnd);
return svemem_gprs_per_element_decode(calculate_mem_transfer(1 << insz, elsz),
shift_amount, enc, opcode, pc, opnd);
}

static inline bool
Expand All @@ -7114,8 +7175,8 @@ encode_opnd_svemem_gpr_shf(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint

const uint shift_amount = opnd_size_to_shift_amount(get_opnd_size_from_offset(insz));

return svemem_gprs_per_element_encode(1 << insz, elsz, shift_amount, enc, opcode, pc,
opnd, enc_out);
return svemem_gprs_per_element_encode(calculate_mem_transfer(1 << insz, elsz),
shift_amount, enc, opcode, pc, opnd, enc_out);
}

static inline bool
Expand All @@ -7124,7 +7185,8 @@ decode_opnd_svemem_gprs_bhsdx(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
aarch64_reg_offset insz, elsz;
sizes_from_dtype(enc, &elsz, &insz, true);

return svemem_gprs_per_element_decode(insz + 1, elsz, 0, enc, opcode, pc, opnd);
return svemem_gprs_per_element_decode(calculate_mem_transfer(insz + 1, elsz), 0, enc,
opcode, pc, opnd);
}

static inline bool
Expand All @@ -7134,8 +7196,8 @@ encode_opnd_svemem_gprs_bhsdx(uint enc, int opcode, byte *pc, opnd_t opnd,
aarch64_reg_offset insz, elsz;
sizes_from_dtype(enc, &elsz, &insz, true);

return svemem_gprs_per_element_encode(insz + 1, elsz, 0, enc, opcode, pc, opnd,
enc_out);
return svemem_gprs_per_element_encode(calculate_mem_transfer(insz + 1, elsz), 0, enc,
opcode, pc, opnd, enc_out);
}

static inline bool
Expand Down Expand Up @@ -7750,7 +7812,8 @@ encode_opnd_mem12(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out
return encode_opnd_mem12_scale(extract_uint(enc, 30, 2), false, opnd, enc_out);
}

/* SVE prefetch memory address (32-bit offset) [<Xn|SP>, <Zm>.<T>, <mod>{ <amount>}] */
/* SVE prefetch memory address (32-bit offset) [<Xn|SP>, <Zm>.<T>, <mod>{ <amount>}]
*/
static inline bool
decode_opnd_sveprf_gpr_vec32(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
Expand Down
11 changes: 9 additions & 2 deletions core/ir/aarch64/codec_sve.txt
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,15 @@
1000010011xxxxxx101xxxxxxxxxxxxx n 910 SVE ld1rh z_h_0 : svememx6_h_5 p10_zer_lo
1000010011xxxxxx110xxxxxxxxxxxxx n 910 SVE ld1rh z_s_0 : svememx6_h_5 p10_zer_lo
1000010011xxxxxx111xxxxxxxxxxxxx n 910 SVE ld1rh z_d_0 : svememx6_h_5 p10_zer_lo
10100100001xxxxx000xxxxxxxxxxxxx n 947 SVE ld1rob z_b_0 : svemem_gprs_b1 p10_zer_lo
10100100000xxxxx000xxxxxxxxxxxxx n 948 SVE ld1rqb z_b_0 : svemem_gprs_b1 p10_zer_lo
10100100001xxxxx000xxxxxxxxxxxxx n 947 SVE ld1rob z_b_0 : svemem_ssz_gpr_shf p10_zer_lo
101001000000xxxx001xxxxxxxxxxxxx n 948 SVE ld1rqb z_b_0 : svemem_ssz_gpr_simm4 p10_zer_lo
10100100000xxxxx000xxxxxxxxxxxxx n 948 SVE ld1rqb z_b_0 : svemem_ssz_gpr_shf p10_zer_lo
101001011000xxxx001xxxxxxxxxxxxx n 1060 SVE ld1rqd z_d_0 : svemem_ssz_gpr_simm4 p10_zer_lo
10100101100xxxxx000xxxxxxxxxxxxx n 1060 SVE ld1rqd z_d_0 : svemem_ssz_gpr_shf p10_zer_lo
101001001000xxxx001xxxxxxxxxxxxx n 1061 SVE ld1rqh z_h_0 : svemem_ssz_gpr_simm4 p10_zer_lo
10100100100xxxxx000xxxxxxxxxxxxx n 1061 SVE ld1rqh z_h_0 : svemem_ssz_gpr_shf p10_zer_lo
101001010000xxxx001xxxxxxxxxxxxx n 1062 SVE ld1rqw z_s_0 : svemem_ssz_gpr_simm4 p10_zer_lo
10100101000xxxxx000xxxxxxxxxxxxx n 1062 SVE ld1rqw z_s_0 : svemem_ssz_gpr_shf p10_zer_lo
1000010111xxxxxx110xxxxxxxxxxxxx n 911 SVE ld1rsb z_h_0 : svememx6_b_5 p10_zer_lo
1000010111xxxxxx101xxxxxxxxxxxxx n 911 SVE ld1rsb z_s_0 : svememx6_b_5 p10_zer_lo
1000010111xxxxxx100xxxxxxxxxxxxx n 911 SVE ld1rsb z_d_0 : svememx6_b_5 p10_zer_lo
Expand Down
Loading

0 comments on commit 5d89aee

Please sign in to comment.