From 6e1306923c60b3d6c1cefb1fcc240f1a064d6f20 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Thu, 18 Sep 2025 11:46:39 -0700 Subject: [AArch64] Update disassembler based on 2025-06 ARM ISA data Alongside this I also added support for decoding: * LDR / STR (table) * PMULLB / PMULLT * ABS / CNT / CTZ * SMIN / SMAX / UMIN / UMAX * RPRFM * PSEL Note that while these instructions will now be disassembled, they are not yet lifted to LLIL. Additionally, I fixed a number of errors in the decoding of some less commonly occurring instructions. --- arch/arm64/disassembler/decode_scratchpad.c | 1137 ++++++++++++++------------- 1 file changed, 608 insertions(+), 529 deletions(-) (limited to 'arch/arm64/disassembler/decode_scratchpad.c') diff --git a/arch/arm64/disassembler/decode_scratchpad.c b/arch/arm64/disassembler/decode_scratchpad.c index ebab3755..f50ad23d 100644 --- a/arch/arm64/disassembler/decode_scratchpad.c +++ b/arch/arm64/disassembler/decode_scratchpad.c @@ -359,12 +359,12 @@ static const Register regMap[2][10][32] = { /* third coordinate into regMap is [0,31] */ -int table_wbase_xbase[2] = {REG_W_BASE, REG_X_BASE}; +static const int table_wbase_xbase[2] = {REG_W_BASE, REG_X_BASE}; #define REG(SP_OR_ZR, REG_BASE, REG_NUM) regMap[(SP_OR_ZR)][(REG_BASE)][(REG_NUM)] /* prefetch operation */ -const char* prfop_lookup(unsigned prfop) +static const char* prfop_lookup(unsigned prfop) { switch (prfop) { @@ -438,7 +438,7 @@ const char* prfop_lookup(unsigned prfop) } /* prefetch operation */ -const char* prfop_lookup_4(unsigned prfop) +static const char* prfop_lookup_4(unsigned prfop) { switch (prfop) { @@ -479,7 +479,7 @@ const char* prfop_lookup_4(unsigned prfop) } } -const char* pattern_lookup(unsigned pattern, unsigned uimm5) +static const char* pattern_lookup(unsigned pattern, unsigned uimm5) { switch (pattern & 0x1f) { @@ -551,7 +551,7 @@ const char* pattern_lookup(unsigned pattern, unsigned uimm5) 01xx 1 4S 1xxx x RESERVED */ -ArrangementSpec arr_spec_method0(uint32_t imm5, uint32_t Q) +static ArrangementSpec arr_spec_method0(uint32_t imm5, uint32_t Q) { if (Q == 0) { @@ -576,7 +576,7 @@ ArrangementSpec arr_spec_method0(uint32_t imm5, uint32_t Q) return ARRSPEC_NONE; } -ArrangementSpec arr_spec_method1(unsigned key) +static ArrangementSpec arr_spec_method1(unsigned key) { // 00000 RESERVED // xxxx1 B @@ -584,6 +584,7 @@ ArrangementSpec arr_spec_method1(unsigned key) // xx100 S // x1000 D // 10000 Q + // if((key & 0b01111) == 0b00000) return ARRSPEC_NONE; // x0000 RESERVED if ((key & 0b00001) == 0b00001) return _1B; // xxxx1 B if ((key & 0b00011) == 0b00010) @@ -597,7 +598,7 @@ ArrangementSpec arr_spec_method1(unsigned key) return ARRSPEC_NONE; } -ArrangementSpec arr_spec_method2(unsigned immh) +static ArrangementSpec arr_spec_method2(unsigned immh) { // 0000 SEE Advanced SIMD modified immediate if (immh == 1) @@ -609,7 +610,7 @@ ArrangementSpec arr_spec_method2(unsigned immh) return ARRSPEC_NONE; // 1xxx RESERVED } -ArrangementSpec arr_spec_method3(unsigned immh, unsigned q) +static ArrangementSpec arr_spec_method3(unsigned immh, unsigned q) { switch ((immh << 1) | q) { @@ -649,7 +650,7 @@ ArrangementSpec arr_spec_method3(unsigned immh, unsigned q) return ARRSPEC_NONE; } -ArrangementSpec arr_spec_method4(unsigned imm5, unsigned q) +static ArrangementSpec arr_spec_method4(unsigned imm5, unsigned q) { unsigned key = (imm5 << 1) | q; // if((key & 0b011110) == 0b000000) return RESERVED; // x0000 x RESERVED @@ -671,35 +672,33 @@ ArrangementSpec arr_spec_method4(unsigned imm5, unsigned q) return ARRSPEC_NONE; } -ArrangementSpec table_1s_1d[2] = {_1S, _1D}; -ArrangementSpec table_2s_4s[2] = {_2S, _4S}; -ArrangementSpec table_2s_2d[2] = {_2S, _2D}; -ArrangementSpec table_2h_4h[2] = {_2H, _4H}; -ArrangementSpec table_4h_8h[2] = {_4H, _8H}; -ArrangementSpec table_4s_2d[2] = {_4S, _2D}; -ArrangementSpec table_8b_16b[2] = {_8B, _16B}; -ArrangementSpec table_2s_r_4s_2d[4] = {_2S, ARRSPEC_NONE, _4S, _2D}; -ArrangementSpec table_2s_4s_r_2d[4] = {_2S, _4S, ARRSPEC_NONE, _2D}; -ArrangementSpec table_8h_4s_2d_1q[4] = {_8H, _4S, _2D, _1Q}; -ArrangementSpec table_4h_8h_2s_4s_1d_2d_r_r[8] = { +static const ArrangementSpec table_1s_1d[2] = {_1S, _1D}; +static const ArrangementSpec table_2s_4s[2] = {_2S, _4S}; +static const ArrangementSpec table_2s_2d[2] = {_2S, _2D}; +static const ArrangementSpec table_2h_4h[2] = {_2H, _4H}; +static const ArrangementSpec table_4h_8h[2] = {_4H, _8H}; +static const ArrangementSpec table_4s_2d[2] = {_4S, _2D}; +static const ArrangementSpec table_8b_16b[2] = {_8B, _16B}; +static const ArrangementSpec table_2s_r_4s_2d[4] = {_2S, ARRSPEC_NONE, _4S, _2D}; +static const ArrangementSpec table_2s_4s_r_2d[4] = {_2S, _4S, ARRSPEC_NONE, _2D}; +static const ArrangementSpec table_8h_4s_2d_1q[4] = {_8H, _4S, _2D, _1Q}; +static const ArrangementSpec table_r_h_s_r_d[5] = { ARRSPEC_NONE, _1H, _1S, ARRSPEC_NONE, _1D}; +static const ArrangementSpec table_r_b_h_r_s[5] = { ARRSPEC_NONE, _1B, _1H, ARRSPEC_NONE, _1S}; +static const ArrangementSpec table_4h_8h_2s_4s_1d_2d_r_r[8] = { _4H, _8H, _2S, _4S, _1D, _2D, ARRSPEC_NONE, ARRSPEC_NONE}; -ArrangementSpec table_8b_16b_4h_8h_2s_4s_1d_2d[8] = {_8B, _16B, _4H, _8H, _2S, _4S, _1D, _2D}; -ArrangementSpec table_r_b_h_r_r_s_r_r[8] = { +static const ArrangementSpec table_8b_16b_4h_8h_2s_4s_1d_2d[8] = {_8B, _16B, _4H, _8H, _2S, _4S, _1D, _2D}; +static const ArrangementSpec table_r_b_h_r_r_s_r_r[8] = { ARRSPEC_NONE, _1B, _1H, ARRSPEC_NONE, ARRSPEC_NONE, _1S, ARRSPEC_NONE, ARRSPEC_NONE}; -ArrangementSpec table_r_h_s_r_r_d_r_r[8] = { +static const ArrangementSpec table_r_h_s_r_r_d_r_r[8] = { ARRSPEC_NONE, _1H, _1S, ARRSPEC_NONE, ARRSPEC_NONE, _1D, ARRSPEC_NONE, ARRSPEC_NONE}; -ArrangementSpec table_r_h_s_s_d_d_d_d[8] = { - ARRSPEC_NONE, _1H, _1S, _1S, _1D, _1D, _1D, _1D}; -ArrangementSpec table_r_b_h_h_s_s_s_s[8] = { - ARRSPEC_NONE, _1B, _1H, _1H, _1S, _1S, _1S, _1S}; -ArrangementSpec table16_r_b_h_s_d[16] = { +static ArrangementSpec table16_r_b_h_s_d[16] = { ARRSPEC_NONE, _1B, _1H, _1H, _1S, _1S, _1S, _1S, _1D, _1D, _1D, _1D, _1D, _1D, _1D, _1D}; //----------------------------------------------------------------------------- // element size (usually to fill in a ".") //----------------------------------------------------------------------------- -ArrangementSpec size_spec_method0(uint8_t /*bit*/ a, uint8_t /*bit(6)*/ b) +static ArrangementSpec size_spec_method0(uint8_t /*bit*/ a, uint8_t /*bit(6)*/ b) { if (a == 0) { @@ -713,7 +712,7 @@ ArrangementSpec size_spec_method0(uint8_t /*bit*/ a, uint8_t /*bit(6)*/ b) return _1B; if ((b & 0x3E) == 0x3C) return _1B; - return 0; + return ARRSPEC_NONE; } else { @@ -721,7 +720,7 @@ ArrangementSpec size_spec_method0(uint8_t /*bit*/ a, uint8_t /*bit(6)*/ b) } } -ArrangementSpec size_spec_method1(unsigned imm13) +static ArrangementSpec size_spec_method1(unsigned imm13) { unsigned key = (((imm13 >> 12) & 1) << 6) | (imm13 & 0b111111); @@ -739,10 +738,10 @@ ArrangementSpec size_spec_method1(unsigned imm13) // if((key & 0b1111111) == 0b0111111) return "RESERVED"; // 0 111111 RESERVED if ((key & 0b1000000) == 0b1000000) return _1D; // 1 xxxxxx D - return 0; + return ARRSPEC_NONE; } -ArrangementSpec size_spec_method3(int x) +static ArrangementSpec size_spec_method3(int x) { if ((x & 0b01111) == 0b00000) return ARRSPEC_NONE; // x0000 RESERVED @@ -754,30 +753,30 @@ ArrangementSpec size_spec_method3(int x) return _1S; // xx100 S if ((x & 0b01111) == 0b01000) return _1D; // x1000 D - return 0; + return ARRSPEC_NONE; } -ArrangementSpec table_b_h[2] = {_1B, _1H}; -ArrangementSpec table_s_d[2] = {_1S, _1D}; -ArrangementSpec table_b_d_h_s[4] = {_1B, _1D, _1H, _1S}; -ArrangementSpec table_b_h_s_d[4] = {_1B, _1H, _1S, _1D}; -ArrangementSpec table_d_b_h_s[4] = {_1D, _1B, _1H, _1S}; -ArrangementSpec table_q_h_s_d[4] = {_1Q, _1H, _1S, _1D}; -ArrangementSpec table_r_h_s_d[4] = {ARRSPEC_NONE, _1H, _1S, _1D}; -ArrangementSpec table_r_b_h_s[4] = {ARRSPEC_NONE, _1B, _1H, _1S}; -ArrangementSpec table_r_s_d_r[4] = {ARRSPEC_NONE, _1S, _1D, ARRSPEC_NONE}; +static const ArrangementSpec table_b_h[2] = {_1B, _1H}; +static const ArrangementSpec table_s_d[2] = {_1S, _1D}; +static const ArrangementSpec table_b_d_h_s[4] = {_1B, _1D, _1H, _1S}; +static const ArrangementSpec table_b_h_s_d[4] = {_1B, _1H, _1S, _1D}; +static const ArrangementSpec table_d_b_h_s[4] = {_1D, _1B, _1H, _1S}; +static const ArrangementSpec table_q_h_s_d[4] = {_1Q, _1H, _1S, _1D}; +static const ArrangementSpec table_r_h_s_d[4] = {ARRSPEC_NONE, _1H, _1S, _1D}; +static const ArrangementSpec table_r_b_h_s[4] = {ARRSPEC_NONE, _1B, _1H, _1S}; //----------------------------------------------------------------------------- // other tables //----------------------------------------------------------------------------- -enum Condition table_cond[16] = {COND_EQ, COND_NE, COND_CS, COND_CC, COND_MI, COND_PL, COND_VS, +static const enum Condition table_cond[16] = {COND_EQ, COND_NE, COND_CS, COND_CC, COND_MI, COND_PL, COND_VS, COND_VC, COND_HI, COND_LS, COND_GE, COND_LT, COND_GT, COND_LE, COND_AL, COND_NV}; -enum Condition table_cond_neg[16] = {COND_NE, COND_EQ, COND_CC, COND_CS, COND_PL, COND_MI, COND_VC, +static const enum Condition table_cond_neg[16] = {COND_NE, COND_EQ, COND_CC, COND_CS, COND_PL, COND_MI, COND_VC, COND_VS, COND_LS, COND_HI, COND_LT, COND_GE, COND_LE, COND_GT, COND_NV, COND_AL}; -float table_imm8_to_float[256] = {2.000000000000000000e+00, 2.125000000000000000e+00, +static const float table_imm8_to_float[256] = { + 2.000000000000000000e+00, 2.125000000000000000e+00, 2.250000000000000000e+00, 2.375000000000000000e+00, 2.500000000000000000e+00, 2.625000000000000000e+00, 2.750000000000000000e+00, 2.875000000000000000e+00, 3.000000000000000000e+00, 3.125000000000000000e+00, 3.250000000000000000e+00, @@ -864,7 +863,7 @@ float table_imm8_to_float[256] = {2.000000000000000000e+00, 2.125000000000000000 -1.687500000000000000e+00, -1.750000000000000000e+00, -1.812500000000000000e+00, -1.875000000000000000e+00, -1.937500000000000000e+00}; -const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", +static const char* const reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15"}; #define ABCDEFGH \ @@ -959,11 +958,16 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_OPERAND_ZN ADD_OPERAND_REG(REGSET_ZR, REG_Z_BASE, ctx->n); #define ADD_OPERAND_ZT ADD_OPERAND_REG(REGSET_ZR, REG_Z_BASE, ctx->t); +#define ADD_OPERAND_ZT0 \ + instr->operands[i].operandClass = REG; \ + instr->operands[i].reg[0] = REG_ZT0; \ + i++; + #define ADD_OPERAND_PRED_REG(REGNUM) ADD_OPERAND_REG(REGSET_ZR, REG_P_BASE, REGNUM); #define ADD_OPERAND_PRED_REG_T(REGNUM, ARR_SPEC) \ ADD_OPERAND_PRED_REG(REGNUM); \ - instr->operands[i - 1].arrSpec = ARR_SPEC; + instr->operands[i - 1].arrSpec = (ArrangementSpec)(ARR_SPEC); #define ADD_OPERAND_PRED_REG_QUAL(REGNUM, QUALIFIER) \ ADD_OPERAND_PRED_REG(REGNUM); \ @@ -974,7 +978,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_INDEXED_ELEMENT(REGNUM, ARRSPEC, REGINDEX, IMM) \ instr->operands[i].operandClass = INDEXED_ELEMENT; \ instr->operands[i].reg[0] = REG(REGSET_ZR, REG_P_BASE, (REGNUM)); \ - instr->operands[i].arrSpec = (ARRSPEC); \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARRSPEC); \ instr->operands[i].reg[1] = REG(REGSET_ZR, REG_W_BASE, (REGINDEX)); \ instr->operands[i].immediate = (IMM); \ i++ @@ -1000,7 +1004,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_OPERAND_MEM_REG_OFFSET_T(REGSET, BASE, REGNUM, OFFSET, ARR_SPEC) \ instr->operands[i].operandClass = MEM_OFFSET; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ instr->operands[i].immediate = OFFSET; \ instr->operands[i].signedImm = 1; \ i++; @@ -1054,7 +1058,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", instr->operands[i].operandClass = MEM_EXTENDED; \ instr->operands[i].reg[0] = REG(REGSET_SP, BASE0, REGNUM0); \ instr->operands[i].reg[1] = REG(REGSET_ZR, BASE1, REGNUM1); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_MEM_EXTENDED_T_SHIFT( \ @@ -1062,7 +1066,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", instr->operands[i].operandClass = MEM_EXTENDED; \ instr->operands[i].reg[0] = REG(REGSET_SP, BASE0, REGNUM0); \ instr->operands[i].reg[1] = REG(REGSET_ZR, BASE1, REGNUM1); \ - instr->operands[i].arrSpec = SZ1; \ + instr->operands[i].arrSpec = (ArrangementSpec)(SZ1); \ instr->operands[i].shiftType = SHIFT_TYPE; \ instr->operands[i].shiftValue = SHIFT_AMT; \ instr->operands[i].shiftValueUsed = SHIFT_USED; \ @@ -1101,6 +1105,8 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", //#define SEXT4(x) (x & 0x +#define Z_M_OPERAND (ctx->Z ? 'z' : 'm') + /* string immediate (like "mul #0x12") */ #define ADD_OPERAND_STR_IMM(STRING, VALUE) \ instr->operands[i].operandClass = STR_IMM; \ @@ -1120,7 +1126,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", ; \ instr->operands[i].operandClass = MULTI_REG; \ instr->operands[i].reg[0] = REG(REGSET_ZR, REG_BASE, REGNUM); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_MULTIREG_2(REG_BASE, ARR_SPEC, REGNUM) \ @@ -1128,7 +1134,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", instr->operands[i].operandClass = MULTI_REG; \ instr->operands[i].reg[0] = REG(REGSET_ZR, REG_BASE, REGNUM); \ instr->operands[i].reg[1] = REG(REGSET_ZR, REG_BASE, (REGNUM + 1) % 32); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_MULTIREG_3(REG_BASE, ARR_SPEC, REGNUM) \ @@ -1137,7 +1143,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", instr->operands[i].reg[0] = REG(REGSET_ZR, REG_BASE, REGNUM); \ instr->operands[i].reg[1] = REG(REGSET_ZR, REG_BASE, (REGNUM + 1) % 32); \ instr->operands[i].reg[2] = REG(REGSET_ZR, REG_BASE, (REGNUM + 2) % 32); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_MULTIREG_4(REG_BASE, ARR_SPEC, REGNUM) \ @@ -1147,7 +1153,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", instr->operands[i].reg[1] = REG(REGSET_ZR, REG_BASE, (REGNUM + 1) % 32); \ instr->operands[i].reg[2] = REG(REGSET_ZR, REG_BASE, (REGNUM + 2) % 32); \ instr->operands[i].reg[3] = REG(REGSET_ZR, REG_BASE, (REGNUM + 3) % 32); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_MULTIREG_1_LANE(REG_BASE, ARR_SPEC, REGNUM) \ @@ -1178,7 +1184,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_OPERAND_REG_T(BASE, ARR_SPEC, REGNUM) \ instr->operands[i].operandClass = REG; \ instr->operands[i].reg[0] = REG(REGSET_ZR, BASE, REGNUM); \ - instr->operands[i].arrSpec = ARR_SPEC; \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARR_SPEC); \ i++; #define ADD_OPERAND_VREG_T(REGNUM, ARR_SPEC) ADD_OPERAND_REG_T(REG_V_BASE, ARR_SPEC, REGNUM) @@ -1234,10 +1240,9 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_OPERAND_SYSTEMREG_SENSE \ { \ - SystemReg sr = ((ctx->sys_op0 << 14) | (ctx->sys_op1 << 11) | (ctx->sys_crn << 7) | \ - (ctx->sys_crm << 3) | ctx->sys_op2); \ - const char* name = get_system_register_name(sr); \ - if (name[0]) \ + SystemReg sr = (SystemReg)(((ctx->sys_op0 << 14) | (ctx->sys_op1 << 11) | (ctx->sys_crn << 7) | \ + (ctx->sys_crm << 3) | ctx->sys_op2)); \ + if (has_system_register_name(sr)) \ { \ ADD_OPERAND_SYSTEMREG(sr); \ } \ @@ -1261,16 +1266,16 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", #define ADD_OPERAND_SME_TILE(TILE_NUM, SLICE_INDICATOR, ARRSPEC, BASEREG, OFFSET) \ instr->operands[i].operandClass = SME_TILE; \ instr->operands[i].tile = (TILE_NUM); \ - instr->operands[i].slice = (SLICE_INDICATOR); \ - instr->operands[i].arrSpec = (ARRSPEC); \ - instr->operands[i].reg[0] = (BASEREG); \ + instr->operands[i].slice = (SliceIndicator)(SLICE_INDICATOR); \ + instr->operands[i].arrSpec = (ArrangementSpec)(ARRSPEC); \ + instr->operands[i].reg[0] = (Register)(BASEREG); \ instr->operands[i].immediate = (OFFSET); \ - instr->operands[i].signedImm = 1; \ + instr->operands[i].signedImm = true; \ i++; #define ADD_OPERAND_ACCUM_ARRAY(BASEREG, OFFSET) \ instr->operands[i].operandClass = ACCUM_ARRAY; \ - instr->operands[i].reg[0] = (BASEREG); \ + instr->operands[i].reg[0] = (Register)(BASEREG); \ instr->operands[i].immediate = (OFFSET); \ i++; @@ -1278,7 +1283,7 @@ const char* reg_lookup_c[16] = {"c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", // register base lookups //----------------------------------------------------------------------------- -unsigned rwwwx_0123x_reg(int x, int r) +static unsigned rwwwx_0123x_reg(int x, int r) { if ((x & 0b01111) == 0b00000) return 0; // x0000 RESERVED @@ -1293,7 +1298,7 @@ unsigned rwwwx_0123x_reg(int x, int r) return 0; } -unsigned rbhsdq_5bit_reg(unsigned key) +static unsigned rbhsdq_5bit_reg(unsigned key) { // if((key & 0b01111) == 0b00000) return 0; // x0000 RESERVED if (key == 0) @@ -1311,14 +1316,14 @@ unsigned rbhsdq_5bit_reg(unsigned key) return 0; } -unsigned wwwx_0123_reg(unsigned size) +static unsigned wwwx_0123_reg(unsigned size) { if (size == 0b11) return REG_X_BASE; return REG_W_BASE; } -unsigned sd_01_reg(int v) +static unsigned sd_01_reg(int v) { switch (v & 1) { @@ -1326,12 +1331,13 @@ unsigned sd_01_reg(int v) return REG_S_BASE; case 1: return REG_D_BASE; + default: + return 0; } - return 0; } // ,, -unsigned bhsd_0123_reg(int v) +static unsigned bhsd_0123_reg(int v) { switch (v & 3) { @@ -1343,11 +1349,12 @@ unsigned bhsd_0123_reg(int v) return REG_S_BASE; case 3: return REG_D_BASE; + default: + return 0; } - return 0; } -unsigned rsdr_0123_reg(int v) +static unsigned rsdr_0123_reg(int v) { switch (v & 3) { @@ -1355,11 +1362,12 @@ unsigned rsdr_0123_reg(int v) return REG_S_BASE; case 2: return REG_D_BASE; + default: + return 0; } - return 0; } -unsigned hsdr_0123_reg(int v) +static unsigned hsdr_0123_reg(int v) { switch (v & 3) { @@ -1374,7 +1382,7 @@ unsigned hsdr_0123_reg(int v) } } -unsigned rhsd_0123_reg(int v) +static unsigned rhsd_0123_reg(int v) { if (v == 1) return REG_H_BASE; @@ -1383,7 +1391,7 @@ unsigned rhsd_0123_reg(int v) return 0; } -unsigned rhsd_0123x_reg(int v) +static unsigned rhsd_0123x_reg(int v) { // if(x & 0xE == 0) return 0; // 000x if ((v & 0xE) == 2) @@ -1395,7 +1403,7 @@ unsigned rhsd_0123x_reg(int v) return 0; } -unsigned rbhsd_0123x_reg(int v) +static unsigned rbhsd_0123x_reg(int v) { // 0000 RESERVED if (v == 1) return REG_B_BASE; // 0001 B @@ -1408,7 +1416,7 @@ unsigned rbhsd_0123x_reg(int v) return 0; } -unsigned rhsdr_0123x_reg(int v) +static unsigned rhsdr_0123x_reg(int v) { if (v == 1) return REG_H_BASE; @@ -1422,7 +1430,7 @@ unsigned rhsdr_0123x_reg(int v) #define OPTIONAL_SHIFT_AMOUNT \ if (!(ctx->shift_type == 1 && ctx->shift_amount == 0)) \ { \ - instr->operands[i - 1].shiftType = ctx->shift_type; \ + instr->operands[i - 1].shiftType = (ShiftType)(ctx->shift_type); \ instr->operands[i - 1].shiftValue = ctx->shift_amount; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ @@ -1432,7 +1440,7 @@ unsigned rhsdr_0123x_reg(int v) } #define OPTIONAL_EXTEND_AMOUNT(SPECIAL_LSL) \ - instr->operands[i - 1].shiftType = ctx->extend_type; \ + instr->operands[i - 1].shiftType = (ShiftType)(ctx->extend_type); \ instr->operands[i - 1].shiftValue = ctx->shift; \ if (ctx->option == SPECIAL_LSL) \ { \ @@ -1450,7 +1458,7 @@ unsigned rhsdr_0123x_reg(int v) } #define OPTIONAL_EXTEND_AMOUNT_0 \ - instr->operands[i - 1].shiftType = ctx->extend_type; \ + instr->operands[i - 1].shiftType = (ShiftType)(ctx->extend_type); \ instr->operands[i - 1].shiftValue = 0; \ instr->operands[i - 1].shiftValueUsed = ctx->S ? 1 : 0; @@ -1557,7 +1565,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) instr->operation = enc_to_oper(instr->encoding); /* default to 0 operands */ - InstructionOperand zero = {0}; + InstructionOperand zero = {(OperandClass)(0)}; for (uint32_t ii = 0; ii < MAX_OPERANDS; ++ii) instr->operands[ii] = zero; @@ -1762,7 +1770,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SADDV_R_P_Z_: case ENC_UADDV_R_P_Z_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; //
,,. ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_PRED_REG(ctx->g); @@ -2124,12 +2132,15 @@ int decode_scratchpad(context* ctx, Instruction* instr) break; } - case ENC_URECPE_Z_P_Z_: - case ENC_URSQRTE_Z_P_Z_: + case ENC_URECPE_Z_P_Z_M: + case ENC_URECPE_Z_P_Z_Z: + case ENC_URSQRTE_Z_P_Z_M: + case ENC_URSQRTE_Z_P_Z_Z: { // .S,/M,.S + // .S,/Z,.S ADD_OPERAND_ZREG_T(ctx->d, _1S) - ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'm'); + ADD_OPERAND_PRED_REG_QUAL(ctx->g, Z_M_OPERAND); ADD_OPERAND_ZREG_T(ctx->n, _1S) break; } @@ -2239,16 +2250,16 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } - case ENC_CMPLE_CMPGE_P_P_ZZ_: - case ENC_CMPLO_CMPHI_P_P_ZZ_: - case ENC_CMPLS_CMPHS_P_P_ZZ_: - case ENC_CMPLT_CMPGT_P_P_ZZ_: - case ENC_FACLE_FACGE_P_P_ZZ_: - case ENC_FACLT_FACGT_P_P_ZZ_: - case ENC_FCMLE_FCMGE_P_P_ZZ_: - case ENC_FCMLT_FCMGT_P_P_ZZ_: + case ENC_CMPLE_P_P_ZZ__CMPGE_P_P_ZZ_: + case ENC_CMPLO_P_P_ZZ__CMPHI_P_P_ZZ_: + case ENC_CMPLS_P_P_ZZ__CMPHS_P_P_ZZ_: + case ENC_CMPLT_P_P_ZZ__CMPGT_P_P_ZZ_: + case ENC_FACLE_P_P_ZZ__FACGE_P_P_ZZ_: + case ENC_FACLT_P_P_ZZ__FACGT_P_P_ZZ_: + case ENC_FCMLE_P_P_ZZ__FCMGE_P_P_ZZ_: + case ENC_FCMLT_P_P_ZZ__FCMGT_P_P_ZZ_: { - ArrangementSpec arr_spec = table_b_d_h_s[ctx->size]; + arr_spec = table_b_d_h_s[ctx->size]; // .,/Z,.,. ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); @@ -2263,7 +2274,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCMLT_P_P_Z0_: case ENC_FCMNE_P_P_Z0_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,/Z,., #0.0 ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); @@ -2283,7 +2294,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_CMPNE_P_P_ZI_: { uint64_t imm = ctx->imm; - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,/Z,., # ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); @@ -2305,7 +2316,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCMNE_P_P_ZZ_: case ENC_FCMUO_P_P_ZZ_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,/Z,.,. ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); @@ -2324,7 +2335,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_CMPLT_P_P_ZW_: case ENC_CMPNE_P_P_ZW_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,/Z,.,.D ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); @@ -2334,7 +2345,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_REV_P_P_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,. ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_T(ctx->n, arr_spec); @@ -2343,7 +2354,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_TRN1_P_PP_: case ENC_TRN2_P_PP_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,.,. ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_T(ctx->n, arr_spec); @@ -2355,7 +2366,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ZIP1_P_PP_: case ENC_ZIP2_P_PP_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .,.,. ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_PRED_REG_T(ctx->n, arr_spec); @@ -2371,7 +2382,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_WHILEHI_P_P_RR_: case ENC_WHILEHS_P_P_RR_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; unsigned rn_base = ctx->sf ? REG_X_BASE : REG_W_BASE; unsigned rm_base = rn_base; // .,, @@ -2383,7 +2394,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_PTRUE_P_S_: case ENC_PTRUES_P_S_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // .{,} ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); ADD_OPERAND_OPTIONAL_PATTERN; @@ -2415,28 +2426,29 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_PRED_REG_T(ctx->n, _1B); break; } - case ENC_REVD_Z_P_Z_: // .Q,/M,.Q + case ENC_REVD_Z_P_Z_M: // .Q,/M,.Q + case ENC_REVD_Z_P_Z_Z: // .Q,/Z,.Q { ADD_OPERAND_ZREG_T(ctx->Zd, _1Q); - ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'm'); - ADD_OPERAND_ZREG_T(ctx->Zd, _1Q); + ADD_OPERAND_PRED_REG_QUAL(ctx->g, Z_M_OPERAND); + ADD_OPERAND_ZREG_T(ctx->Zn, _1Q); break; } - case ENC_MOV_MOVA_Z_P_RZA_B: // .B,/M, ZA0.B[, #] - case ENC_MOV_MOVA_Z_P_RZA_H: // .H,/M,.H[, #] - case ENC_MOV_MOVA_Z_P_RZA_W: // .S,/M,.S[, #] - case ENC_MOV_MOVA_Z_P_RZA_D: // .D,/M,.D[, #] - case ENC_MOV_MOVA_Z_P_RZA_Q: // .Q,/M,.Q[] + case ENC_MOV_Z_P_RZA_B_MOVA_Z_P_RZA_B: // .B,/M, ZA0.B[, #] + case ENC_MOV_Z_P_RZA_H_MOVA_Z_P_RZA_H: // .H,/M,.H[, #] + case ENC_MOV_Z_P_RZA_W_MOVA_Z_P_RZA_W: // .S,/M,.S[, #] + case ENC_MOV_Z_P_RZA_D_MOVA_Z_P_RZA_D: // .D,/M,.D[, #] + case ENC_MOV_Z_P_RZA_Q_MOVA_Z_P_RZA_Q: // .Q,/M,.Q[] { instr->operation = ARM64_MOVA; ArrangementSpec as = ARRSPEC_NONE; uint64_t imm=0, n=0; switch(instr->encoding) { - case ENC_MOV_MOVA_Z_P_RZA_B: as=_1B; imm=ctx->imm4; n=0; break; - case ENC_MOV_MOVA_Z_P_RZA_H: as=_1H; imm=ctx->imm3; n=ctx->n; break; - case ENC_MOV_MOVA_Z_P_RZA_W: as=_1S; imm=ctx->imm2; n=ctx->n; break; - case ENC_MOV_MOVA_Z_P_RZA_D: as=_1D; imm=ctx->i1; n=ctx->n; break; - case ENC_MOV_MOVA_Z_P_RZA_Q: as=_1Q; imm=0; n=ctx->n; break; + case ENC_MOV_Z_P_RZA_B_MOVA_Z_P_RZA_B: as=_1B; imm=ctx->off4; n=0; break; + case ENC_MOV_Z_P_RZA_H_MOVA_Z_P_RZA_H: as=_1H; imm=ctx->off3; n=ctx->n; break; + case ENC_MOV_Z_P_RZA_W_MOVA_Z_P_RZA_W: as=_1S; imm=ctx->off2; n=ctx->n; break; + case ENC_MOV_Z_P_RZA_D_MOVA_Z_P_RZA_D: as=_1D; imm=ctx->o1; n=ctx->n; break; + case ENC_MOV_Z_P_RZA_Q_MOVA_Z_P_RZA_Q: as=_1Q; imm=0; n=ctx->n; break; default: break; } ADD_OPERAND_ZREG_T(ctx->Zd, as); @@ -2444,21 +2456,21 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_SME_TILE(n, ctx->V, as, REG_W0+12+ctx->Rs, imm); break; } - case ENC_MOV_MOVA_ZA_P_RZ_B: // ZA0.B[, #], /M, .B - case ENC_MOV_MOVA_ZA_P_RZ_H: // .H[, #], /M, .H - case ENC_MOV_MOVA_ZA_P_RZ_W: // .S[, #], /M, .S - case ENC_MOV_MOVA_ZA_P_RZ_D: // .D[, #], /M, .D - case ENC_MOV_MOVA_ZA_P_RZ_Q: // .Q[ ], /M, .Q + case ENC_MOV_ZA_P_RZ_B_MOVA_ZA_P_RZ_B: // ZA0.B[, #], /M, .B + case ENC_MOV_ZA_P_RZ_H_MOVA_ZA_P_RZ_H: // .H[, #], /M, .H + case ENC_MOV_ZA_P_RZ_W_MOVA_ZA_P_RZ_W: // .S[, #], /M, .S + case ENC_MOV_ZA_P_RZ_D_MOVA_ZA_P_RZ_D: // .D[, #], /M, .D + case ENC_MOV_ZA_P_RZ_Q_MOVA_ZA_P_RZ_Q: // .Q[ ], /M, .Q { instr->operation = ARM64_MOVA; ArrangementSpec as = ARRSPEC_NONE; uint64_t imm=0, d=0; switch(instr->encoding) { - case ENC_MOV_MOVA_ZA_P_RZ_B: as=_1B; imm=ctx->imm4; d=0; break; - case ENC_MOV_MOVA_ZA_P_RZ_H: as=_1H; imm=ctx->imm3; d=ctx->d; break; - case ENC_MOV_MOVA_ZA_P_RZ_W: as=_1S; imm=ctx->imm2; d=ctx->d; break; - case ENC_MOV_MOVA_ZA_P_RZ_D: as=_1D; imm=ctx->i1; d=ctx->d; break; - case ENC_MOV_MOVA_ZA_P_RZ_Q: as=_1Q; imm=0; d=ctx->d; break; + case ENC_MOV_ZA_P_RZ_B_MOVA_ZA_P_RZ_B: as=_1B; imm=ctx->off4; d=0; break; + case ENC_MOV_ZA_P_RZ_H_MOVA_ZA_P_RZ_H: as=_1H; imm=ctx->off3; d=ctx->d; break; + case ENC_MOV_ZA_P_RZ_W_MOVA_ZA_P_RZ_W: as=_1S; imm=ctx->off2; d=ctx->d; break; + case ENC_MOV_ZA_P_RZ_D_MOVA_ZA_P_RZ_D: as=_1D; imm=ctx->o1; d=ctx->d; break; + case ENC_MOV_ZA_P_RZ_Q_MOVA_ZA_P_RZ_Q: as=_1Q; imm=0; d=ctx->d; break; default: break; } ADD_OPERAND_SME_TILE(d, ctx->V, as, REG_W0+12+ctx->Rs, imm); @@ -2466,7 +2478,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_ZREG_T(ctx->Zn, as); break; } - case ENC_MOV_SEL_P_P_PP_: + case ENC_MOVM_P_P_P__SEL_P_P_PP_: { // .B,/M,.B ADD_OPERAND_PRED_REG_T(ctx->d, _1B); @@ -2482,10 +2494,10 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); break; } - case ENC_MOVS_ANDS_P_P_PP_Z: - case ENC_MOV_AND_P_P_PP_Z: - case ENC_NOTS_EORS_P_P_PP_Z: - case ENC_NOT_EOR_P_P_PP_Z: + case ENC_MOVZS_P_P_P__ANDS_P_P_PP_Z: + case ENC_MOVZ_P_P_P__AND_P_P_PP_Z: + case ENC_NOTS_P_P_P_Z_EORS_P_P_PP_Z: + case ENC_NOT_P_P_P_Z_EOR_P_P_PP_Z: case ENC_BRKAS_P_P_P_Z: case ENC_BRKBS_P_P_P_Z: { @@ -2532,8 +2544,8 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_PRED_REG_T(ctx->m, T); break; } - case ENC_MOVS_ORRS_P_P_PP_Z: - case ENC_MOV_ORR_P_P_PP_Z: + case ENC_MOVS_P_P__ORRS_P_P_PP_Z: + case ENC_MOV_P_P__ORR_P_P_PP_Z: { // .B,.B ADD_OPERAND_PRED_REG_T(ctx->d, _1B); @@ -2560,10 +2572,10 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_PNEXT_P_P_P_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; - // .,,. + arr_spec = table_b_h_s_d[ctx->size]; + // .,,. ADD_OPERAND_PRED_REG_T(ctx->Pdn, arr_spec); - ADD_OPERAND_PRED_REG(ctx->g); + ADD_OPERAND_PRED_REG(ctx->v); ADD_OPERAND_PRED_REG_T(ctx->Pdn, arr_spec); break; } @@ -2575,7 +2587,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_PRED_REG_T(ctx->Pdn, _1B); break; } - case ENC_PTEST_P_P_: + case ENC_PTEST__P_P_: { // ,.B ADD_OPERAND_PRED_REG(ctx->g); @@ -2712,7 +2724,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_LASTA_R_P_Z_: case ENC_LASTB_R_P_Z_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; unsigned rd_base = wwwx_0123_reg(ctx->size); // ,,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); @@ -2723,7 +2735,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_CLASTA_R_P_Z_: case ENC_CLASTB_R_P_Z_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; unsigned rdn_base = wwwx_0123_reg(ctx->size); // ,,,. ADD_OPERAND_REG(REGSET_ZR, rdn_base, ctx->Rdn); @@ -2994,7 +3006,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_UMAXV_R_P_Z_: case ENC_UMINV_R_P_Z_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; unsigned rd_base = bhsd_0123_reg(ctx->size); // ,,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); @@ -3175,7 +3187,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { unsigned rn_base = sd_01_reg(ctx->sz); unsigned rd_base = sd_01_reg(ctx->sz); - ArrangementSpec arr_spec = table_s_d[ctx->sz]; + arr_spec = table_s_d[ctx->sz]; // ,,.[] ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_REG(REGSET_ZR, rn_base, ctx->n); @@ -3189,7 +3201,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { unsigned rd_base = rhsd_0123_reg(ctx->size); unsigned rn_base = rhsd_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // ,,.[] ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_REG(REGSET_ZR, rn_base, ctx->n); @@ -3235,7 +3247,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ADDP_ASISDPAIR_ONLY: { unsigned rd_base = REG_D_BASE; - ArrangementSpec arr_spec = _2D; + arr_spec = _2D; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3253,7 +3265,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ADDV_ASIMDALL_ONLY: { unsigned rd_base = bhsd_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3278,7 +3290,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FMINP_ASISDPAIR_ONLY_SD: { unsigned rd_base = sd_01_reg(ctx->sz); - ArrangementSpec arr_spec = table_2s_2d[ctx->sz]; + arr_spec = table_2s_2d[ctx->sz]; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3290,7 +3302,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FMINV_ASIMDALL_ONLY_H: { unsigned rd_base = REG_H_BASE; - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3303,7 +3315,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FMINV_ASIMDALL_ONLY_SD: { unsigned rd_base = REG_S_BASE; - ArrangementSpec arr_spec = _4S; + arr_spec = _4S; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3313,7 +3325,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SADDLV_ASIMDALL_ONLY: { unsigned rd_base = hsdr_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3325,7 +3337,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SMINV_ASIMDALL_ONLY: { unsigned rd_base = bhsd_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; // ,. ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3334,7 +3346,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_MOV_DUP_ASISDONE_ONLY: { unsigned rd_base = rbhsdq_5bit_reg(ctx->imm5); - ArrangementSpec arr_spec = arr_spec_method1(ctx->imm5); + arr_spec = arr_spec_method1(ctx->imm5); // ,.[] ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T_LANE(ctx->n, arr_spec, ctx->index); @@ -3343,26 +3355,26 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_DUP_ASISDONE_ONLY: { unsigned rd_base = bhsd_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_b_d_h_s[ctx->size]; + arr_spec = table_b_d_h_s[ctx->size]; // ,.[] ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_VREG_T_LANE(ctx->n, arr_spec, ctx->index); break; } - case ENC_DUP_P_P_PI_: + case ENC_PSEL_P_PPI_: { - ArrangementSpec arr_spec = arr_spec_method1((ctx->tszh << 3) | ctx->tszl); - // DUP ., /Z, .[{, #}] - ADD_OPERAND_PRED_REG_T(ctx->d, arr_spec); - ADD_OPERAND_PRED_REG_QUAL(ctx->g, 'z'); - ADD_INDEXED_ELEMENT(ctx->n, arr_spec, ctx->m, ctx->imm); + // PSEL , , .[, ] + arr_spec = arr_spec_method1(ctx->tszh << 3 | ctx->tszl); + ADD_OPERAND_PRED_REG(ctx->d); + ADD_OPERAND_PRED_REG(ctx->n); + ADD_INDEXED_ELEMENT(ctx->m, arr_spec, ctx->v, ctx->imm); break; } case ENC_CLASTA_V_P_Z_: case ENC_CLASTB_V_P_Z_: case ENC_FADDA_V_P_Z_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; unsigned rdn_base = bhsd_0123_reg(ctx->size); // ,,,. ADD_OPERAND_REG(REGSET_ZR, rdn_base, ctx->Vdn); @@ -3390,7 +3402,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { unsigned rd_base = rsdr_0123_reg(ctx->size); unsigned rn_base = bhsd_0123_reg(ctx->size); - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // ,,.[] ADD_OPERAND_REG(REGSET_ZR, rd_base, ctx->d); ADD_OPERAND_REG(REGSET_ZR, rn_base, ctx->n); @@ -3563,18 +3575,18 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_MVNI_ASIMDIMM_M_SM: // 32-bit shifting ones (cmode == 110x) { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = table_2s_4s[ctx->Q]; + arr_spec = table_2s_4s[ctx->Q]; // ., #, MSL # ADD_OPERAND_VREG_T(ctx->rd, arr_spec) ADD_OPERAND_IMM8; instr->operands[1].shiftType = ShiftType_MSL; instr->operands[1].shiftValue = (ctx->cmode & 1) ? 16 : 8; - instr->operands[1].shiftValueUsed = 1; + instr->operands[1].shiftValueUsed = true; break; } case ENC_MOVI_ASIMDIMM_N_B: { - ArrangementSpec arr_spec = table_8b_16b[ctx->Q]; + arr_spec = table_8b_16b[ctx->Q]; uint64_t imm8 = ctx->imm & 0xFF; // ., #{, LSL #0} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3584,7 +3596,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ORR_ASIMDIMM_L_SL: { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = table_2s_4s[ctx->Q]; + arr_spec = table_2s_4s[ctx->Q]; int AMOUNT = 8 * ((ctx->cmode >> 1) & 0b11); // ., #{, LSL #} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3598,7 +3610,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ORR_ASIMDIMM_L_HL: { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; int AMOUNT = (ctx->cmode & 2) ? 8 : 0; // ., #{, LSL #} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3614,7 +3626,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_MVNI_ASIMDIMM_L_HL: // 16-bit shifted immediate (cmode == 10x0) { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; unsigned AMOUNT = (ctx->cmode & 0b10) << 2; // ., #{, LSL #} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3629,7 +3641,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_MVNI_ASIMDIMM_L_SL: // cmode == '0xx0' (32-bit shifted immediate) { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = table_2s_4s[ctx->Q]; + arr_spec = table_2s_4s[ctx->Q]; unsigned AMOUNT = (ctx->cmode & 0b0110) << 2; // ., #{, LSL #} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3644,7 +3656,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_BIC_ASIMDIMM_L_SL: { uint64_t imm8 = ABCDEFGH; - ArrangementSpec arr_spec = ARRSPEC_NONE; + arr_spec = ARRSPEC_NONE; unsigned AMOUNT = 0; if ((ctx->cmode & 0b1101) == 0b1001) { // 16-bit (cmode == 10x1) @@ -3674,7 +3686,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { uint64_t imm8 = ABCDEFGH; unsigned AMOUNT = (ctx->cmode & 0b110) << 2; - ArrangementSpec arr_spec = table_2s_4s[ctx->Q]; + arr_spec = table_2s_4s[ctx->Q]; // ., #{, LSL #} ADD_OPERAND_VREG_T(ctx->rd, arr_spec) ADD_OPERAND_IMM8; @@ -3687,7 +3699,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_FMOV_ASIMDIMM_H_H: { - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; float fimm = table_imm8_to_float[ABCDEFGH]; // ., # ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3696,7 +3708,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_FMOV_ASIMDIMM_S_S: { - ArrangementSpec arr_spec = table_2s_4s[ctx->Q]; + arr_spec = table_2s_4s[ctx->Q]; float fimm = table_imm8_to_float[ABCDEFGH]; // ., # ADD_OPERAND_VREG_T(ctx->rd, arr_spec) @@ -3705,7 +3717,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_DUP_ASIMDINS_DR_R: { - ArrangementSpec arr_spec = arr_spec_method4(ctx->imm5, ctx->Q); + arr_spec = arr_spec_method4(ctx->imm5, ctx->Q); unsigned rn_base = rwwwx_0123x_reg(ctx->imm5, ctx->Rn); // ., ADD_OPERAND_VREG_T(ctx->d, arr_spec) @@ -3737,7 +3749,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FRINTZ_ASIMDMISCFP16_R: case ENC_FRSQRTE_ASIMDMISCFP16_R: { - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; // .,. ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3755,7 +3767,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCVTNS_ASIMDMISC_R: case ENC_FCVTZU_ASIMDMISC_R: { - ArrangementSpec arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; + arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; // .,. ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3775,7 +3787,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_USQADD_ASIMDMISC_R: case ENC_SUQADD_ASIMDMISC_R: { - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; // .,. ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3811,7 +3823,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_URECPE_ASIMDMISC_R: case ENC_URSQRTE_ASIMDMISC_R: { - ArrangementSpec arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; + arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; // .,. ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3823,7 +3835,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCMLE_ASIMDMISC_FZ: case ENC_FCMLT_ASIMDMISC_FZ: { - ArrangementSpec arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; + arr_spec = table_2s_4s_r_2d[(ctx->sz << 1) | ctx->Q]; // .,., #0.0 ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3836,7 +3848,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCMLE_ASIMDMISCFP16_FZ: case ENC_FCMLT_ASIMDMISCFP16_FZ: { - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; // .,., #0.0 ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3849,7 +3861,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_CMLE_ASIMDMISC_Z: case ENC_CMLT_ASIMDMISC_Z: { - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; // .,., #0 ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -3861,7 +3873,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SCVTF_ASIMDSHF_C: case ENC_UCVTF_ASIMDSHF_C: { - ArrangementSpec arr_spec = arr_spec_method3(ctx->immh, ctx->Q); + arr_spec = arr_spec_method3(ctx->immh, ctx->Q); uint64_t fbits = ctx->fracbits; // .,., # ADD_OPERAND_VREG_T(ctx->d, arr_spec) @@ -3885,7 +3897,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_USRA_ASIMDSHF_R: { unsigned shift = ctx->shift; - ArrangementSpec arr_spec = arr_spec_method3(ctx->immh, ctx->Q); + arr_spec = arr_spec_method3(ctx->immh, ctx->Q); // .,., # ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -4028,7 +4040,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ORN_ASIMDSAME_ONLY: case ENC_BIC_ASIMDSAME_ONLY: { - ArrangementSpec arr_spec = table_8b_16b[ctx->Q]; + arr_spec = table_8b_16b[ctx->Q]; // .,.,. ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -4037,7 +4049,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_EXT_ASIMDEXT_ONLY: { - ArrangementSpec arr_spec = table_8b_16b[ctx->Q]; + arr_spec = table_8b_16b[ctx->Q]; uint64_t const_ = ctx->imm4; // .,.,., # ADD_OPERAND_VREG_T(ctx->d, arr_spec) @@ -4049,7 +4061,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FCADD_ASIMDSAME2_C: case ENC_FCMLA_ASIMDSAME2_C: { - ArrangementSpec arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; + arr_spec = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; uint64_t rotate; if (instr->encoding == ENC_FCADD_ASIMDSAME2_C) rotate = ctx->rot ? 270 : 90; @@ -4091,8 +4103,9 @@ int decode_scratchpad(context* ctx, Instruction* instr) ADD_OPERAND_VREG_T_LANE(ctx->m, arr_spec1, ctx->index); break; } - case ENC_FCMLA_ASIMDELEM_C_H: - case ENC_FCMLA_ASIMDELEM_C_S: + // case ENC_FCMLA_ASIMDELEM_C_H: + // case ENC_FCMLA_ASIMDELEM_C_S: + case ENC_FCMLA_ADVSIMD_ELT: { ArrangementSpec arr_spec0 = table_8b_16b_4h_8h_2s_4s_1d_2d[(ctx->size << 1) | ctx->Q]; ArrangementSpec arr_spec1 = table_r_h_s_d[ctx->size]; @@ -4109,7 +4122,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_FMULX_ASIMDELEM_RH_H: case ENC_FMUL_ASIMDELEM_RH_H: { - ArrangementSpec arr_spec = table_4h_8h[ctx->Q]; + arr_spec = table_4h_8h[ctx->Q]; // .,.,.H[] ADD_OPERAND_VREG_T(ctx->d, arr_spec) ADD_OPERAND_VREG_T(ctx->n, arr_spec) @@ -4394,10 +4407,9 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_INS_ASIMDINS_IV_V: case ENC_MOV_INS_ASIMDINS_IV_V: { - ArrangementSpec arr_spec = size_spec_method3(ctx->imm5); + arr_spec = size_spec_method3(ctx->imm5); - /* - uint64_t INDEX1= 0, INDEX2 = 0; + uint64_t INDEX1 = 0, INDEX2 = 0; if ((ctx->imm5 & 1) == 1) { INDEX1 = (ctx->imm5 >> 1) & 15; @@ -4418,8 +4430,8 @@ int decode_scratchpad(context* ctx, Instruction* instr) INDEX1 = (ctx->imm5 >> 4) & 1; INDEX2 = (ctx->imm4 >> 3) & 1; } - */ - + (void) INDEX1; + (void) INDEX2; // .[],.[] ADD_OPERAND_VREG_T_LANE(ctx->d, arr_spec, ctx->dst_index); ADD_OPERAND_VREG_T_LANE(ctx->n, arr_spec, ctx->src_index); @@ -4429,7 +4441,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_MOV_INS_ASIMDINS_IR_R: { unsigned rn_base = rwwwx_0123x_reg(ctx->imm5, ctx->Rn); - ArrangementSpec arr_spec = size_spec_method3(ctx->imm5); + arr_spec = size_spec_method3(ctx->imm5); // .[], ADD_OPERAND_VREG_T_LANE(ctx->d, arr_spec, ctx->index); ADD_OPERAND_REG(REGSET_ZR, rn_base, ctx->n); @@ -4466,7 +4478,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { instr->operands[1].shiftType = ShiftType_LSL; instr->operands[1].shiftValue = 16; - instr->operands[1].shiftValueUsed = 1; + instr->operands[1].shiftValueUsed = true; } break; } @@ -4564,7 +4576,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SMOV_ASIMDINS_W_W: case ENC_UMOV_ASIMDINS_W_W: { - ArrangementSpec arr_spec = ctx->esize == 16 ? _1H : _1B; + arr_spec = ctx->esize == 16 ? _1H : _1B; // ,.[] ADD_OPERAND_WD; ADD_OPERAND_VREG_T_LANE(ctx->n, arr_spec, ctx->index); @@ -4813,7 +4825,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_UQDECP_R_P_R_UW: case ENC_UQINCP_R_P_R_UW: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // ,. ADD_OPERAND_WDN; ADD_OPERAND_PRED_REG_T(ctx->m, arr_spec); @@ -5404,6 +5416,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) break; } case ENC_RDVL_R_I_: + case ENC_RDSVL_R_I_: case ENC_MOV_MOVZ_64_MOVEWIDE: { int64_t imm = ctx->imm << (ctx->hw * 16); @@ -5433,7 +5446,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) { instr->operands[1].shiftType = ShiftType_LSL; instr->operands[1].shiftValue = 16 * ctx->hw; - instr->operands[1].shiftValueUsed = 1; + instr->operands[1].shiftValueUsed = true; } break; } @@ -5503,7 +5516,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_CNTP_R_P_P_: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // ,,. ADD_OPERAND_XD; ADD_OPERAND_PRED_REG(ctx->g); @@ -5539,7 +5552,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_SMOV_ASIMDINS_X_X: case ENC_UMOV_ASIMDINS_X_X: { - ArrangementSpec arr_spec = table_b_h_s_d[ctx->size]; + arr_spec = table_b_h_s_d[ctx->size]; // ,.[] ADD_OPERAND_XD; ADD_OPERAND_VREG_T_LANE(ctx->n, arr_spec, ctx->index); @@ -5706,6 +5719,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) } case ENC_MADD_64A_DP_3SRC: case ENC_MSUB_64A_DP_3SRC: + case ENC_MADDPT_64A_DP_3SRC: { // ,,, ADD_OPERAND_XD; @@ -5841,7 +5855,7 @@ int decode_scratchpad(context* ctx, Instruction* instr) case ENC_ADR_ONLY_PCRELADDR: { uint64_t eaddr = - ctx->page ? (ctx->address & 0xFFFFFFFFFFFFF000) + ctx->imm : ctx->address + ctx->imm; + (ctx->page || ctx->op) ? (ctx->address & 0xFFFFFFFFFFFFF000) + ctx->imm : ctx->address + ctx->imm; // ,