Skip to content

Commit

Permalink
i#2626: AArch64 v8 decode: Fix incorrect decode of add/s, sub/s, tb(n…
Browse files Browse the repository at this point in the history
…)z (#5282)

This patch fixes two underlying issues:
 * Several of the instruction variants were decoding to an x register
   when they should have been decoding to a w register
 * LSL #12 was being decoded as 0x10 (16) rather than 0x0c (12)

issues: #2626
  • Loading branch information
joshua-warburton committed Jan 14, 2022
1 parent 87cda24 commit 247e98c
Show file tree
Hide file tree
Showing 5 changed files with 959 additions and 33 deletions.
33 changes: 27 additions & 6 deletions core/ir/aarch64/codec.c
Expand Up @@ -3007,18 +3007,32 @@ encode_opnd_vindex_SD(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc
return true;
}

/* imm12sh: shift amount for 12-bit immediate of ADD/SUB, 0 or 16 */
/* imm12sh: shift amount for 12-bit immediate of ADD/SUB, 0 or 12 */

static inline bool
decode_opnd_imm12sh(uint enc, int opcode, byte *pc, OUT opnd_t *opnd)
{
return decode_opnd_int(22, 1, false, 4, OPSZ_5b, 0, enc, opnd);

uint shift_bits = extract_uint(enc, 22, 2);
if (shift_bits > 1)
return false; /* 1x is reserved */

*opnd = opnd_create_immed_int(shift_bits * 12, OPSZ_5b);
return true;
}

static inline bool
encode_opnd_imm12sh(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out)
{
return encode_opnd_int(22, 1, false, 4, 0, opnd, enc_out);
if (!opnd_is_immed_int(opnd))
return false;

uint value = opnd_get_immed_int(opnd);
if (value != 0 && value != 12)
return false;

*enc_out = value / 12 << 22;
return true;
}

/* sd_sz: Operand size for single and double precision encoding of floating point
Expand Down Expand Up @@ -4533,7 +4547,9 @@ decode_opnds_tbz(uint enc, dcontext_t *dcontext, byte *pc, instr_t *instr, int o
instr_set_num_opnds(dcontext, instr, 0, 3);
instr_set_src(instr, 0, opnd_create_pc(pc + extract_int(enc, 5, 14) * 4));
instr_set_src(instr, 1,
opnd_create_reg(decode_reg(extract_uint(enc, 0, 5), true, false)));
opnd_create_reg(decode_reg(extract_uint(enc, 0, 5),
TEST(1U << 31, enc), /* true if x, else w*/
false)));
instr_set_src(instr, 2,
opnd_create_immed_int((enc >> 19 & 31) | (enc >> 26 & 32), OPSZ_5b));
return true;
Expand All @@ -4543,10 +4559,15 @@ static inline uint
encode_opnds_tbz(byte *pc, instr_t *instr, uint enc, decode_info_t *di)
{
uint xt, imm6, off;
reg_id_t reg = opnd_get_reg(instr_get_src(instr, 1));
/* TBZ accepts a x register in all cases, but will decode it
* to a w register when imm6 is less than 32 */
bool is_x_register = reg >= DR_REG_X0 && reg <= DR_REG_X30;
if (instr_num_dsts(instr) == 0 && instr_num_srcs(instr) == 3 &&
encode_pc_off(&off, 14, pc, instr, instr_get_src(instr, 0), di) &&
encode_opnd_wxn(true, false, 0, instr_get_src(instr, 1), &xt) &&
encode_opnd_int(0, 6, false, 0, 0, instr_get_src(instr, 2), &imm6))
encode_opnd_int(0, 6, false, 0, 0, instr_get_src(instr, 2), &imm6) &&
encode_opnd_wxn((imm6 > 31) || is_x_register, false, 0, instr_get_src(instr, 1),
&xt))
return (enc | off << 5 | xt | (imm6 & 31) << 19 | (imm6 & 32) << 26);
return ENCFAIL;
}
Expand Down
20 changes: 16 additions & 4 deletions core/ir/aarch64/codec.txt
Expand Up @@ -306,7 +306,10 @@ x0011010000xxxxx000000xxxxxxxxxx r 7 adc wx0 : wx5 wx16
x0111010000xxxxx000000xxxxxxxxxx rw 8 adcs wx0 : wx5 wx16
x00100010xxxxxxxxxxxxxxxxxxxxxxx n 9 add wx0sp : wx5sp imm12 lsl imm12sh
x0001011xx0xxxxxxxxxxxxxxxxxxxxx n 9 add wx0 : wx5 wx16 shift3 imm6
x0001011001xxxxxxxxxxxxxxxxxxxxx n 9 add wx0sp : wx5sp wx16 ext extam
00001011001xxxxxxxxxxxxxxxxxxxxx n 9 add wx0sp : wx5sp wx16 ext extam
10001011001xxxxxx0xxxxxxxxxxxxxx n 9 add wx0sp : wx5sp w16 ext extam
10001011001xxxxxxx0xxxxxxxxxxxxx n 9 add wx0sp : wx5sp w16 ext extam
10001011001xxxxxx11xxxxxxxxxxxxx n 9 add wx0sp : wx5sp x16 ext extam
0x001110xx1xxxxx100001xxxxxxxxxx n 9 add dq0 : dq5 dq16 bhsd_sz
01011110111xxxxx100001xxxxxxxxxx n 9 add d0 : d5 d16
00001110xx1xxxxx010000xxxxxxxxxx n 10 addhn d0 : q5 q16 bhs_sz
Expand All @@ -315,7 +318,10 @@ x0001011001xxxxxxxxxxxxxxxxxxxxx n 9 add wx0sp : wx5sp wx1
0101111011110001101110xxxxxxxxxx n 12 addp d0 : q5
x01100010xxxxxxxxxxxxxxxxxxxxxxx w 13 adds wx0 : wx5sp imm12 lsl imm12sh
x0101011xx0xxxxxxxxxxxxxxxxxxxxx w 13 adds wx0 : wx5 wx16 shift3 imm6
x0101011001xxxxxxxxxxxxxxxxxxxxx w 13 adds wx0 : wx5sp wx16 ext extam
00101011001xxxxxxxxxxxxxxxxxxxxx w 13 adds wx0 : wx5sp wx16 ext extam
10101011001xxxxxx0xxxxxxxxxxxxxx w 13 adds wx0 : wx5sp w16 ext extam
10101011001xxxxxxx0xxxxxxxxxxxxx w 13 adds wx0 : wx5sp w16 ext extam
10101011001xxxxxx11xxxxxxxxxxxxx w 13 adds wx0 : wx5sp x16 ext extam
0x001110xx110001101110xxxxxxxxxx n 14 addv dq0 : dq5 bhsd_sz
0xx10000xxxxxxxxxxxxxxxxxxxxxxxx n 15 adr adr
1xx10000xxxxxxxxxxxxxxxxxxxxxxxx n 16 adrp adr
Expand Down Expand Up @@ -1462,14 +1468,20 @@ x0011010110xxxxx000011xxxxxxxxxx n 363 sdiv wx0 : wx5 wx16
01001000000xxxxx0^^^^^xxxxxxxxxx n 469 stxrh mem0 w16 : w0
x10100010xxxxxxxxxxxxxxxxxxxxxxx n 470 sub wx0sp : wx5sp imm12 lsl imm12sh
x1001011xx0xxxxxxxxxxxxxxxxxxxxx n 470 sub wx0 : wx5 wx16 shift3 imm6
x1001011001xxxxxxxxxxxxxxxxxxxxx n 470 sub wx0sp : wx5sp wx16 ext extam
01001011001xxxxxxxxxxxxxxxxxxxxx n 470 sub wx0sp : wx5sp wx16 ext extam
11001011001xxxxxx0xxxxxxxxxxxxxx n 470 sub wx0sp : wx5sp w16 ext extam
11001011001xxxxxxx0xxxxxxxxxxxxx n 470 sub wx0sp : wx5sp w16 ext extam
11001011001xxxxxx11xxxxxxxxxxxxx n 470 sub wx0sp : wx5sp x16 ext extam
0x101110xx1xxxxx100001xxxxxxxxxx n 470 sub dq0 : dq5 dq16 bhsd_sz
01111110111xxxxx100001xxxxxxxxxx n 470 sub d0 : d5 d16
00001110xx1xxxxx011000xxxxxxxxxx n 471 subhn d0 : q5 q16 bhs_sz
01001110xx1xxxxx011000xxxxxxxxxx n 472 subhn2 q0 : q5 q16 bhs_sz
x11100010xxxxxxxxxxxxxxxxxxxxxxx w 473 subs wx0 : wx5sp imm12 lsl imm12sh
x1101011xx0xxxxxxxxxxxxxxxxxxxxx w 473 subs wx0 : wx5 wx16 shift3 imm6
x1101011001xxxxxxxxxxxxxxxxxxxxx w 473 subs wx0 : wx5sp wx16 ext extam
01101011001xxxxxxxxxxxxxxxxxxxxx w 473 subs wx0 : wx5sp wx16 ext extam
11101011001xxxxxx0xxxxxxxxxxxxxx w 473 subs wx0 : wx5sp w16 ext extam
11101011001xxxxxxx0xxxxxxxxxxxxx w 473 subs wx0 : wx5sp w16 ext extam
11101011001xxxxxx11xxxxxxxxxxxxx w 473 subs wx0 : wx5sp x16 ext extam
0101111000100000001110xxxxxxxxxx n 474 suqadd b0 : b5
0101111001100000001110xxxxxxxxxx n 474 suqadd h0 : h5
0101111010100000001110xxxxxxxxxx n 474 suqadd s0 : s5
Expand Down

0 comments on commit 247e98c

Please sign in to comment.