#include "decode.h" #include "pcode.h" #include #include #include //----------------------------------------------------------------------------- // registers //----------------------------------------------------------------------------- // regMap[0][?][?] uses SP for R31 // regMap[1][?][?] uses ZR for R31 static const Register regMap[2][10][32] = { { { REG_W0, REG_W1, REG_W2, REG_W3, REG_W4, REG_W5, REG_W6, REG_W7, REG_W8, REG_W9, REG_W10, REG_W11, REG_W12, REG_W13, REG_W14, REG_W15, REG_W16, REG_W17, REG_W18, REG_W19, REG_W20, REG_W21, REG_W22, REG_W23, REG_W24, REG_W25, REG_W26, REG_W27, REG_W28, REG_W29, REG_W30, REG_WSP, }, {REG_X0, REG_X1, REG_X2, REG_X3, REG_X4, REG_X5, REG_X6, REG_X7, REG_X8, REG_X9, REG_X10, REG_X11, REG_X12, REG_X13, REG_X14, REG_X15, REG_X16, REG_X17, REG_X18, REG_X19, REG_X20, REG_X21, REG_X22, REG_X23, REG_X24, REG_X25, REG_X26, REG_X27, REG_X28, REG_X29, REG_X30, REG_SP}, {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7, REG_V8, REG_V9, REG_V10, REG_V11, REG_V12, REG_V13, REG_V14, REG_V15, REG_V16, REG_V17, REG_V18, REG_V19, REG_V20, REG_V21, REG_V22, REG_V23, REG_V24, REG_V25, REG_V26, REG_V27, REG_V28, REG_V29, REG_V30, REG_V31}, {REG_B0, REG_B1, REG_B2, REG_B3, REG_B4, REG_B5, REG_B6, REG_B7, REG_B8, REG_B9, REG_B10, REG_B11, REG_B12, REG_B13, REG_B14, REG_B15, REG_B16, REG_B17, REG_B18, REG_B19, REG_B20, REG_B21, REG_B22, REG_B23, REG_B24, REG_B25, REG_B26, REG_B27, REG_B28, REG_B29, REG_B30, REG_B31}, {REG_H0, REG_H1, REG_H2, REG_H3, REG_H4, REG_H5, REG_H6, REG_H7, REG_H8, REG_H9, REG_H10, REG_H11, REG_H12, REG_H13, REG_H14, REG_H15, REG_H16, REG_H17, REG_H18, REG_H19, REG_H20, REG_H21, REG_H22, REG_H23, REG_H24, REG_H25, REG_H26, REG_H27, REG_H28, REG_H29, REG_H30, REG_H31}, {REG_S0, REG_S1, REG_S2, REG_S3, REG_S4, REG_S5, REG_S6, REG_S7, REG_S8, REG_S9, REG_S10, REG_S11, REG_S12, REG_S13, REG_S14, REG_S15, REG_S16, REG_S17, REG_S18, REG_S19, REG_S20, REG_S21, REG_S22, REG_S23, REG_S24, REG_S25, REG_S26, REG_S27, REG_S28, REG_S29, REG_S30, REG_S31}, {REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7, REG_D8, REG_D9, REG_D10, REG_D11, REG_D12, REG_D13, REG_D14, REG_D15, REG_D16, REG_D17, REG_D18, REG_D19, REG_D20, REG_D21, REG_D22, REG_D23, REG_D24, REG_D25, REG_D26, REG_D27, REG_D28, REG_D29, REG_D30, REG_D31}, {REG_Q0, REG_Q1, REG_Q2, REG_Q3, REG_Q4, REG_Q5, REG_Q6, REG_Q7, REG_Q8, REG_Q9, REG_Q10, REG_Q11, REG_Q12, REG_Q13, REG_Q14, REG_Q15, REG_Q16, REG_Q17, REG_Q18, REG_Q19, REG_Q20, REG_Q21, REG_Q22, REG_Q23, REG_Q24, REG_Q25, REG_Q26, REG_Q27, REG_Q28, REG_Q29, REG_Q30, REG_Q31}, {REG_Z0, REG_Z1, REG_Z2, REG_Z3, REG_Z4, REG_Z5, REG_Z6, REG_Z7, REG_Z8, REG_Z9, REG_Z10, REG_Z11, REG_Z12, REG_Z13, REG_Z14, REG_Z15, REG_Z16, REG_Z17, REG_Z18, REG_Z19, REG_Z20, REG_Z21, REG_Z22, REG_Z23, REG_Z24, REG_Z25, REG_Z26, REG_Z27, REG_Z28, REG_Z29, REG_Z30, REG_Z31}, {REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_P6, REG_P7, REG_P8, REG_P9, REG_P10, REG_P11, REG_P12, REG_P13, REG_P14, REG_P15, REG_P16, REG_P17, REG_P18, REG_P19, REG_P20, REG_P21, REG_P22, REG_P23, REG_P24, REG_P25, REG_P26, REG_P27, REG_P28, REG_P29, REG_P30, REG_P31}, }, {{ REG_W0, REG_W1, REG_W2, REG_W3, REG_W4, REG_W5, REG_W6, REG_W7, REG_W8, REG_W9, REG_W10, REG_W11, REG_W12, REG_W13, REG_W14, REG_W15, REG_W16, REG_W17, REG_W18, REG_W19, REG_W20, REG_W21, REG_W22, REG_W23, REG_W24, REG_W25, REG_W26, REG_W27, REG_W28, REG_W29, REG_W30, REG_WZR, }, { REG_X0, REG_X1, REG_X2, REG_X3, REG_X4, REG_X5, REG_X6, REG_X7, REG_X8, REG_X9, REG_X10, REG_X11, REG_X12, REG_X13, REG_X14, REG_X15, REG_X16, REG_X17, REG_X18, REG_X19, REG_X20, REG_X21, REG_X22, REG_X23, REG_X24, REG_X25, REG_X26, REG_X27, REG_X28, REG_X29, REG_X30, REG_XZR, }, { REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7, REG_V8, REG_V9, REG_V10, REG_V11, REG_V12, REG_V13, REG_V14, REG_V15, REG_V16, REG_V17, REG_V18, REG_V19, REG_V20, REG_V21, REG_V22, REG_V23, REG_V24, REG_V25, REG_V26, REG_V27, REG_V28, REG_V29, REG_V30, REG_V31, }, { REG_B0, REG_B1, REG_B2, REG_B3, REG_B4, REG_B5, REG_B6, REG_B7, REG_B8, REG_B9, REG_B10, REG_B11, REG_B12, REG_B13, REG_B14, REG_B15, REG_B16, REG_B17, REG_B18, REG_B19, REG_B20, REG_B21, REG_B22, REG_B23, REG_B24, REG_B25, REG_B26, REG_B27, REG_B28, REG_B29, REG_B30, REG_B31, }, { REG_H0, REG_H1, REG_H2, REG_H3, REG_H4, REG_H5, REG_H6, REG_H7, REG_H8, REG_H9, REG_H10, REG_H11, REG_H12, REG_H13, REG_H14, REG_H15, REG_H16, REG_H17, REG_H18, REG_H19, REG_H20, REG_H21, REG_H22, REG_H23, REG_H24, REG_H25, REG_H26, REG_H27, REG_H28, REG_H29, REG_H30, REG_H31, }, { REG_S0, REG_S1, REG_S2, REG_S3, REG_S4, REG_S5, REG_S6, REG_S7, REG_S8, REG_S9, REG_S10, REG_S11, REG_S12, REG_S13, REG_S14, REG_S15, REG_S16, REG_S17, REG_S18, REG_S19, REG_S20, REG_S21, REG_S22, REG_S23, REG_S24, REG_S25, REG_S26, REG_S27, REG_S28, REG_S29, REG_S30, REG_S31, }, { REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7, REG_D8, REG_D9, REG_D10, REG_D11, REG_D12, REG_D13, REG_D14, REG_D15, REG_D16, REG_D17, REG_D18, REG_D19, REG_D20, REG_D21, REG_D22, REG_D23, REG_D24, REG_D25, REG_D26, REG_D27, REG_D28, REG_D29, REG_D30, REG_D31, }, {REG_Q0, REG_Q1, REG_Q2, REG_Q3, REG_Q4, REG_Q5, REG_Q6, REG_Q7, REG_Q8, REG_Q9, REG_Q10, REG_Q11, REG_Q12, REG_Q13, REG_Q14, REG_Q15, REG_Q16, REG_Q17, REG_Q18, REG_Q19, REG_Q20, REG_Q21, REG_Q22, REG_Q23, REG_Q24, REG_Q25, REG_Q26, REG_Q27, REG_Q28, REG_Q29, REG_Q30, REG_Q31}, {REG_Z0, REG_Z1, REG_Z2, REG_Z3, REG_Z4, REG_Z5, REG_Z6, REG_Z7, REG_Z8, REG_Z9, REG_Z10, REG_Z11, REG_Z12, REG_Z13, REG_Z14, REG_Z15, REG_Z16, REG_Z17, REG_Z18, REG_Z19, REG_Z20, REG_Z21, REG_Z22, REG_Z23, REG_Z24, REG_Z25, REG_Z26, REG_Z27, REG_Z28, REG_Z29, REG_Z30, REG_Z31}, {REG_P0, REG_P1, REG_P2, REG_P3, REG_P4, REG_P5, REG_P6, REG_P7, REG_P8, REG_P9, REG_P10, REG_P11, REG_P12, REG_P13, REG_P14, REG_P15, REG_P16, REG_P17, REG_P18, REG_P19, REG_P20, REG_P21, REG_P22, REG_P23, REG_P24, REG_P25, REG_P26, REG_P27, REG_P28, REG_P29, REG_P30, REG_P31}, }}; /* first coordinate into regMap */ #define REGSET_SP 0 #define REGSET_ZR 1 /* second coordinate into regMap */ #define REG_W_BASE 0 #define REG_X_BASE 1 #define REG_V_BASE 2 #define REG_B_BASE 3 #define REG_H_BASE 4 #define REG_S_BASE 5 #define REG_D_BASE 6 #define REG_Q_BASE 7 #define REG_Z_BASE 8 #define REG_P_BASE 9 /* third coordinate into regMap is [0,31] */ 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) { switch (prfop) { case 0b00000: return "pldl1keep"; case 0b00001: return "pldl1strm"; case 0b00010: return "pldl2keep"; case 0b00011: return "pldl2strm"; case 0b00100: return "pldl3keep"; case 0b00101: return "pldl3strm"; case 0b00110: return "#6"; case 0b00111: return "#7"; case 0b01000: return "plil1keep"; case 0b01001: return "plil1strm"; case 0b01010: return "plil2keep"; case 0b01011: return "plil2strm"; case 0b01100: return "plil3keep"; case 0b01101: return "plil3strm"; case 0b01110: return "#14"; case 0b01111: return "#15"; case 0b10000: return "pstl1keep"; case 0b10001: return "pstl1strm"; case 0b10010: return "pstl2keep"; case 0b10011: return "pstl2strm"; case 0b10100: return "pstl3keep"; case 0b10101: return "pstl3strm"; case 0b10110: return "#22"; case 0b10111: return "#23"; case 0b11000: return "#24"; case 0b11001: return "#25"; case 0b11010: return "#26"; case 0b11011: return "#27"; case 0b11100: return "#28"; case 0b11101: return "#29"; case 0b11110: return "#30"; case 0b11111: return "#31"; default: return "error"; } } /* prefetch operation */ const char* prfop_lookup_4(unsigned prfop) { switch (prfop) { case 0b0000: return "pldl1keep"; case 0b0001: return "pldl1strm"; case 0b0010: return "pldl2keep"; case 0b0011: return "pldl2strm"; case 0b0100: return "pldl3keep"; case 0b0101: return "pldl3strm"; case 0b0110: return "#6"; case 0b0111: return "#7"; case 0b1000: return "pstl1keep"; case 0b1001: return "pstl1strm"; case 0b1010: return "pstl2keep"; case 0b1011: return "pstl2strm"; case 0b1100: return "pstl3keep"; case 0b1101: return "pstl3strm"; case 0b1110: return "#14"; case 0b1111: return "#15"; default: return "error"; } } const char* pattern_lookup(unsigned pattern, unsigned uimm5) { switch (pattern & 0x1f) { case 0b00000: return "pow2"; case 0b00001: return "vl1"; case 0b00010: return "vl2"; case 0b00011: return "vl3"; case 0b00100: return "vl4"; case 0b00101: return "vl5"; case 0b00110: return "vl6"; case 0b00111: return "vl7"; case 0b01000: return "vl8"; case 0b01001: return "vl16"; case 0b01010: return "vl32"; case 0b01011: return "vl64"; case 0b01100: return "vl128"; case 0b01101: return "vl256"; case 0b11101: return "mul4"; case 0b11110: return "mul3"; case 0b11111: return "all"; default: return "error"; } } //----------------------------------------------------------------------------- // arrangement specifiers and lookups (usually fills in a ".", ".", "<.Tb>") //----------------------------------------------------------------------------- #define _1B ARRSPEC_1BYTE #define _1H ARRSPEC_1HALF #define _1S ARRSPEC_1SINGLE #define _1D ARRSPEC_1DOUBLE #define _1Q ARRSPEC_FULL #define _2H ARRSPEC_2HALVES #define _2S ARRSPEC_2SINGLES #define _2D ARRSPEC_2DOUBLES #define _4B ARRSPEC_4BYTES #define _4H ARRSPEC_4HALVES #define _4S ARRSPEC_4SINGLES #define _8B ARRSPEC_8BYTES #define _8H ARRSPEC_8HALVES #define _16B ARRSPEC_16BYTES /* arrangement specifiers 0000 x SEE Advanced SIMD modified immediate 0001 0 8B 0001 1 16B 001x 0 4H 001x 1 8H 01xx 0 2S 01xx 1 4S 1xxx x RESERVED */ ArrangementSpec arr_spec_method0(uint32_t imm5, uint32_t Q) { if (Q == 0) { if (imm5 & 1) return _8B; if (imm5 & 2) return _4H; if (imm5 & 4) return _2S; } else { if (imm5 & 1) return _16B; if (imm5 & 2) return _8H; if (imm5 & 4) return _4S; if (imm5 & 8) return _2D; } return ARRSPEC_NONE; } ArrangementSpec arr_spec_method1(unsigned key) { // 00000 RESERVED // xxxx1 B // xxx10 H // xx100 S // x1000 D // 10000 Q if ((key & 0b00001) == 0b00001) return _1B; // xxxx1 B if ((key & 0b00011) == 0b00010) return _1H; // xxx10 H if ((key & 0b00111) == 0b00100) return _1S; // xx100 S if ((key & 0b01111) == 0b01000) return _1D; // x1000 D if ((key & 0b11111) == 0b10000) return _1Q; // 10000 Q return ARRSPEC_NONE; } ArrangementSpec arr_spec_method2(unsigned immh) { // 0000 SEE Advanced SIMD modified immediate if (immh == 1) return _8H; // 0001 8H if ((immh & 0b1110) == 0b0010) return _4S; // 001x 4S if ((immh & 0b1100) == 0b0100) return _2D; // 01xx 2D return ARRSPEC_NONE; // 1xxx RESERVED } ArrangementSpec arr_spec_method3(unsigned immh, unsigned q) { switch ((immh << 1) | q) { // 0000 x SEE Advanced SIMD modified immediate case 0b00010: return _8B; // 0001 0 8B case 0b00011: return _16B; // 0001 1 16B case 0b00100: case 0b00110: return _4H; // 001x 0 4H case 0b00101: case 0b00111: return _8H; // 001x 1 8H case 0b01000: case 0b01010: case 0b01100: case 0b01110: return _2S; // 01xx 0 2S case 0b01001: case 0b01011: case 0b01101: case 0b01111: return _4S; // 01xx 1 4S case 0b10001: case 0b10011: case 0b10101: case 0b10111: case 0b11001: case 0b11011: case 0b11101: case 0b11111: return _2D; default: break; // 1xxx 1 RESERVED } return ARRSPEC_NONE; } ArrangementSpec arr_spec_method4(unsigned imm5, unsigned q) { unsigned key = (imm5 << 1) | q; // if((key & 0b011110) == 0b000000) return RESERVED; // x0000 x RESERVED if ((key & 0b000011) == 0b000010) return _8B; // xxxx1 0 8B if ((key & 0b000011) == 0b000011) return _16B; // xxxx1 1 16B if ((key & 0b000111) == 0b000100) return _4H; // xxx10 0 4H if ((key & 0b000111) == 0b000101) return _8H; // xxx10 1 8H if ((key & 0b001111) == 0b001000) return _2S; // xx100 0 2S if ((key & 0b001111) == 0b001001) return _4S; // xx100 1 4S // if((key & 0b011111) == 0b010000) return RESERVED; // x1000 0 RESERVED if ((key & 0b011111) == 0b010001) return _2D; // x1000 1 2D 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] = { _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] = { ARRSPEC_NONE, _1B, _1H, ARRSPEC_NONE, ARRSPEC_NONE, _1S, ARRSPEC_NONE, ARRSPEC_NONE}; 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] = { 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) { if (a == 0) { if ((b & 0x20) == 0) return _1S; if ((b & 0x30) == 0x20) return _1H; if ((b & 0x38) == 0x30) return _1B; if ((b & 0x3C) == 0x38) return _1B; if ((b & 0x3E) == 0x3C) return _1B; return 0; } else { return _1D; } } ArrangementSpec size_spec_method1(unsigned imm13) { unsigned key = (((imm13 >> 12) & 1) << 6) | (imm13 & 0b111111); if ((key & 0b1100000) == 0b0000000) return _1S; // 0 0xxxxx S if ((key & 0b1110000) == 0b0100000) return _1H; // 0 10xxxx H if ((key & 0b1111000) == 0b0110000) return _1B; // 0 110xxx B if ((key & 0b1111100) == 0b0111000) return _1B; // 0 1110xx B if ((key & 0b1111110) == 0b0111100) return _1B; // 0 11110x B // if((key & 0b1111111) == 0b0111110) return "RESERVED"; // 0 111110 RESERVED // if((key & 0b1111111) == 0b0111111) return "RESERVED"; // 0 111111 RESERVED if ((key & 0b1000000) == 0b1000000) return _1D; // 1 xxxxxx D return 0; } ArrangementSpec size_spec_method3(int x) { if ((x & 0b01111) == 0b00000) return ARRSPEC_NONE; // x0000 RESERVED if ((x & 0b00001) == 0b00001) return _1B; // xxxx1 B if ((x & 0b00011) == 0b00010) return _1H; // xxx10 H if ((x & 0b00111) == 0b00100) return _1S; // xx100 S if ((x & 0b01111) == 0b01000) return _1D; // x1000 D return 0; } 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}; //----------------------------------------------------------------------------- // other tables //----------------------------------------------------------------------------- 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, 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, 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, 3.375000000000000000e+00, 3.500000000000000000e+00, 3.625000000000000000e+00, 3.750000000000000000e+00, 3.875000000000000000e+00, 4.000000000000000000e+00, 4.250000000000000000e+00, 4.500000000000000000e+00, 4.750000000000000000e+00, 5.000000000000000000e+00, 5.250000000000000000e+00, 5.500000000000000000e+00, 5.750000000000000000e+00, 6.000000000000000000e+00, 6.250000000000000000e+00, 6.500000000000000000e+00, 6.750000000000000000e+00, 7.000000000000000000e+00, 7.250000000000000000e+00, 7.500000000000000000e+00, 7.750000000000000000e+00, 8.000000000000000000e+00, 8.500000000000000000e+00, 9.000000000000000000e+00, 9.500000000000000000e+00, 1.000000000000000000e+01, 1.050000000000000000e+01, 1.100000000000000000e+01, 1.150000000000000000e+01, 1.200000000000000000e+01, 1.250000000000000000e+01, 1.300000000000000000e+01, 1.350000000000000000e+01, 1.400000000000000000e+01, 1.450000000000000000e+01, 1.500000000000000000e+01, 1.550000000000000000e+01, 1.600000000000000000e+01, 1.700000000000000000e+01, 1.800000000000000000e+01, 1.900000000000000000e+01, 2.000000000000000000e+01, 2.100000000000000000e+01, 2.200000000000000000e+01, 2.300000000000000000e+01, 2.400000000000000000e+01, 2.500000000000000000e+01, 2.600000000000000000e+01, 2.700000000000000000e+01, 2.800000000000000000e+01, 2.900000000000000000e+01, 3.000000000000000000e+01, 3.100000000000000000e+01, 1.250000000000000000e-01, 1.328125000000000000e-01, 1.406250000000000000e-01, 1.484375000000000000e-01, 1.562500000000000000e-01, 1.640625000000000000e-01, 1.718750000000000000e-01, 1.796875000000000000e-01, 1.875000000000000000e-01, 1.953125000000000000e-01, 2.031250000000000000e-01, 2.109375000000000000e-01, 2.187500000000000000e-01, 2.265625000000000000e-01, 2.343750000000000000e-01, 2.421875000000000000e-01, 2.500000000000000000e-01, 2.656250000000000000e-01, 2.812500000000000000e-01, 2.968750000000000000e-01, 3.125000000000000000e-01, 3.281250000000000000e-01, 3.437500000000000000e-01, 3.593750000000000000e-01, 3.750000000000000000e-01, 3.906250000000000000e-01, 4.062500000000000000e-01, 4.218750000000000000e-01, 4.375000000000000000e-01, 4.531250000000000000e-01, 4.687500000000000000e-01, 4.843750000000000000e-01, 5.000000000000000000e-01, 5.312500000000000000e-01, 5.625000000000000000e-01, 5.937500000000000000e-01, 6.250000000000000000e-01, 6.562500000000000000e-01, 6.875000000000000000e-01, 7.187500000000000000e-01, 7.500000000000000000e-01, 7.812500000000000000e-01, 8.125000000000000000e-01, 8.437500000000000000e-01, 8.750000000000000000e-01, 9.062500000000000000e-01, 9.375000000000000000e-01, 9.687500000000000000e-01, 1.000000000000000000e+00, 1.062500000000000000e+00, 1.125000000000000000e+00, 1.187500000000000000e+00, 1.250000000000000000e+00, 1.312500000000000000e+00, 1.375000000000000000e+00, 1.437500000000000000e+00, 1.500000000000000000e+00, 1.562500000000000000e+00, 1.625000000000000000e+00, 1.687500000000000000e+00, 1.750000000000000000e+00, 1.812500000000000000e+00, 1.875000000000000000e+00, 1.937500000000000000e+00, -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, -3.375000000000000000e+00, -3.500000000000000000e+00, -3.625000000000000000e+00, -3.750000000000000000e+00, -3.875000000000000000e+00, -4.000000000000000000e+00, -4.250000000000000000e+00, -4.500000000000000000e+00, -4.750000000000000000e+00, -5.000000000000000000e+00, -5.250000000000000000e+00, -5.500000000000000000e+00, -5.750000000000000000e+00, -6.000000000000000000e+00, -6.250000000000000000e+00, -6.500000000000000000e+00, -6.750000000000000000e+00, -7.000000000000000000e+00, -7.250000000000000000e+00, -7.500000000000000000e+00, -7.750000000000000000e+00, -8.000000000000000000e+00, -8.500000000000000000e+00, -9.000000000000000000e+00, -9.500000000000000000e+00, -1.000000000000000000e+01, -1.050000000000000000e+01, -1.100000000000000000e+01, -1.150000000000000000e+01, -1.200000000000000000e+01, -1.250000000000000000e+01, -1.300000000000000000e+01, -1.350000000000000000e+01, -1.400000000000000000e+01, -1.450000000000000000e+01, -1.500000000000000000e+01, -1.550000000000000000e+01, -1.600000000000000000e+01, -1.700000000000000000e+01, -1.800000000000000000e+01, -1.900000000000000000e+01, -2.000000000000000000e+01, -2.100000000000000000e+01, -2.200000000000000000e+01, -2.300000000000000000e+01, -2.400000000000000000e+01, -2.500000000000000000e+01, -2.600000000000000000e+01, -2.700000000000000000e+01, -2.800000000000000000e+01, -2.900000000000000000e+01, -3.000000000000000000e+01, -3.100000000000000000e+01, -1.250000000000000000e-01, -1.328125000000000000e-01, -1.406250000000000000e-01, -1.484375000000000000e-01, -1.562500000000000000e-01, -1.640625000000000000e-01, -1.718750000000000000e-01, -1.796875000000000000e-01, -1.875000000000000000e-01, -1.953125000000000000e-01, -2.031250000000000000e-01, -2.109375000000000000e-01, -2.187500000000000000e-01, -2.265625000000000000e-01, -2.343750000000000000e-01, -2.421875000000000000e-01, -2.500000000000000000e-01, -2.656250000000000000e-01, -2.812500000000000000e-01, -2.968750000000000000e-01, -3.125000000000000000e-01, -3.281250000000000000e-01, -3.437500000000000000e-01, -3.593750000000000000e-01, -3.750000000000000000e-01, -3.906250000000000000e-01, -4.062500000000000000e-01, -4.218750000000000000e-01, -4.375000000000000000e-01, -4.531250000000000000e-01, -4.687500000000000000e-01, -4.843750000000000000e-01, -5.000000000000000000e-01, -5.312500000000000000e-01, -5.625000000000000000e-01, -5.937500000000000000e-01, -6.250000000000000000e-01, -6.562500000000000000e-01, -6.875000000000000000e-01, -7.187500000000000000e-01, -7.500000000000000000e-01, -7.812500000000000000e-01, -8.125000000000000000e-01, -8.437500000000000000e-01, -8.750000000000000000e-01, -9.062500000000000000e-01, -9.375000000000000000e-01, -9.687500000000000000e-01, -1.000000000000000000e+00, -1.062500000000000000e+00, -1.125000000000000000e+00, -1.187500000000000000e+00, -1.250000000000000000e+00, -1.312500000000000000e+00, -1.375000000000000000e+00, -1.437500000000000000e+00, -1.500000000000000000e+00, -1.562500000000000000e+00, -1.625000000000000000e+00, -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", "c11", "c12", "c13", "c14", "c15"}; #define ABCDEFGH \ ((ctx->a << 7) | (ctx->b << 6) | (ctx->c << 5) | (ctx->d << 4) | (ctx->e << 3) | (ctx->f << 2) | \ (ctx->g << 1) | ctx->h) #define IMMR ctx->immr #define IMMS ctx->imms #define INDEX ctx->index /* register operand macros */ #define ADD_OPERAND_REG(REGSET, BASE, REGNUM) \ instr->operands[i].operandClass = REG; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ i++; #define ADD_OPERAND_BT ADD_OPERAND_REG(REGSET_ZR, REG_B_BASE, ctx->t); #define ADD_OPERAND_DA ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->a); #define ADD_OPERAND_DD ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); #define ADD_OPERAND_DN ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->n); #define ADD_OPERAND_DM ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->m); #define ADD_OPERAND_DT ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->t); #define ADD_OPERAND_DT1 ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->t); #define ADD_OPERAND_DT2 ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->t2); #define ADD_OPERAND_HA ADD_OPERAND_REG(REGSET_ZR, REG_H_BASE, ctx->a); #define ADD_OPERAND_HD ADD_OPERAND_REG(REGSET_ZR, REG_H_BASE, ctx->d); #define ADD_OPERAND_HN ADD_OPERAND_REG(REGSET_ZR, REG_H_BASE, ctx->n); #define ADD_OPERAND_HM ADD_OPERAND_REG(REGSET_ZR, REG_H_BASE, ctx->m); #define ADD_OPERAND_HT ADD_OPERAND_REG(REGSET_ZR, REG_H_BASE, ctx->t); #define ADD_OPERAND_QA ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->a); #define ADD_OPERAND_QD ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->d); #define ADD_OPERAND_QDN ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->n); #define ADD_OPERAND_QN ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->n); #define ADD_OPERAND_QM ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->m); #define ADD_OPERAND_QS ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->s); #define ADD_OPERAND_QT ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->t); #define ADD_OPERAND_QT1 ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->t); #define ADD_OPERAND_QT2 ADD_OPERAND_REG(REGSET_ZR, REG_Q_BASE, ctx->t2); #define ADD_OPERAND_SA ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->a); #define ADD_OPERAND_SD ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->d); #define ADD_OPERAND_SN ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->n); #define ADD_OPERAND_SM ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->m); #define ADD_OPERAND_ST ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->t); #define ADD_OPERAND_ST1 ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->t); #define ADD_OPERAND_ST2 ADD_OPERAND_REG(REGSET_ZR, REG_S_BASE, ctx->t2); #define ADD_OPERAND_WA ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->a); #define ADD_OPERAND_WD ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->d); #define ADD_OPERAND_WDN ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->dn); #define ADD_OPERAND_WN ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->n); #define ADD_OPERAND_WM ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->m); #define ADD_OPERAND_WS ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->s); #define ADD_OPERAND_WT \ ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->t); \ ; #define ADD_OPERAND_WT1 ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->t); #define ADD_OPERAND_WT2 ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, ctx->t2); #define ADD_OPERAND_WS_PLUS_1 ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, (ctx->s + 1) % 32); #define ADD_OPERAND_WT_PLUS_1 ADD_OPERAND_REG(REGSET_ZR, REG_W_BASE, (ctx->t + 1) % 32); #define ADD_OPERAND_WD_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->d); #define ADD_OPERAND_WN_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->n); #define ADD_OPERAND_WM_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->m); #define ADD_OPERAND_WT_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->n); #define ADD_OPERAND_XA ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->a); #define ADD_OPERAND_XD ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->d); #define ADD_OPERAND_XDN ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->Rdn); #define ADD_OPERAND_XN ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->n); #define ADD_OPERAND_XM ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->m); #define ADD_OPERAND_XS ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->s); #define ADD_OPERAND_XT ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->t); #define ADD_OPERAND_XT1 ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->t); #define ADD_OPERAND_XT2 ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, ctx->t2); #define ADD_OPERAND_XS_PLUS_1 ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, (ctx->s + 1) % 32); #define ADD_OPERAND_XT_PLUS_1 ADD_OPERAND_REG(REGSET_ZR, REG_X_BASE, (ctx->t + 1) % 32); #define ADD_OPERAND_XD_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->d); #define ADD_OPERAND_XN_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->n); #define ADD_OPERAND_XDN_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->n); #define ADD_OPERAND_XM_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->m); #define ADD_OPERAND_XT_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->t); #define ADD_OPERAND_XT2_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->t2); #define ADD_OPERAND_ZD ADD_OPERAND_REG(REGSET_ZR, REG_Z_BASE, ctx->d); #define ADD_OPERAND_ZM ADD_OPERAND_REG(REGSET_ZR, REG_Z_BASE, ctx->m); #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_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; #define ADD_OPERAND_PRED_REG_QUAL(REGNUM, QUALIFIER) \ ADD_OPERAND_PRED_REG(REGNUM); \ instr->operands[i - 1].pred_qual = QUALIFIER; /* indexed element */ // .[{, #}] #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].reg[1] = REG(REGSET_ZR, REG_W_BASE, (REGINDEX)); \ instr->operands[i].immediate = (IMM); \ i++ /* register indirect adder */ #define ADD_OPERAND_MEM_REG(REGSET, BASE, REGNUM) \ instr->operands[i].operandClass = MEM_REG; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ i++ #define ADD_OPERAND_MEM_XN_SP ADD_OPERAND_MEM_REG(REGSET_SP, REG_X_BASE, ctx->n); /* general register indirect + offset adder */ // [{, #}] #define ADD_OPERAND_MEM_REG_OFFSET(REGSET, BASE, REGNUM, OFFSET) \ instr->operands[i].operandClass = MEM_OFFSET; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ instr->operands[i].immediate = OFFSET; \ instr->operands[i].signedImm = 1; \ i++; // [.X{, #}] #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].immediate = OFFSET; \ instr->operands[i].signedImm = 1; \ i++; // [{, #, MUL VL}] #define ADD_OPERAND_MEM_REG_OFFSET_VL(REGSET, BASE, REGNUM, OFFSET) \ ADD_OPERAND_MEM_REG_OFFSET(REGSET, BASE, REGNUM, OFFSET); \ instr->operands[i - 1].mul_vl = 1; /* general mem post index */ // [], # #define ADD_OPERAND_MEM_POST_INDEX(REGSET, BASE, REGNUM, OFFSET) \ instr->operands[i].operandClass = MEM_POST_IDX; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ instr->operands[i].immediate = OFFSET; \ instr->operands[i].signedImm = 1; // [], #define ADD_OPERAND_MEM_POST_INDEX_REG(REGSET, BASE, REGNUM, REG_PIDX) \ instr->operands[i].operandClass = MEM_POST_IDX; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ instr->operands[i].reg[1] = REG(REGSET_ZR, REG_X_BASE, REG_PIDX); /* mem pre index */ // [, #] #define ADD_OPERAND_MEM_PRE_INDEX(REGSET, BASE, REGNUM, OFFSET) \ instr->operands[i].operandClass = MEM_PRE_IDX; \ instr->operands[i].reg[0] = REG(REGSET, BASE, REGNUM); \ instr->operands[i].immediate = OFFSET; \ instr->operands[i].signedImm = 1; /* mem extended */ // [, ] // [,{, LSL #0}] with optional LSL #define ADD_OPERAND_MEM_EXTENDED(BASE, REGNUM0, REGNUM1) \ instr->operands[i].operandClass = MEM_EXTENDED; \ instr->operands[i].reg[0] = REG(REGSET_SP, REG_X_BASE, REGNUM0); \ instr->operands[i].reg[1] = REG(REGSET_ZR, BASE, REGNUM1); \ i++; #define ADD_OPERAND_XN_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->n); #define ADD_OPERAND_XM_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->m); #define ADD_OPERAND_XT_SP ADD_OPERAND_REG(REGSET_SP, REG_X_BASE, ctx->t); #define ADD_OPERAND_WD_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->d); #define ADD_OPERAND_WN_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->n); #define ADD_OPERAND_WM_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->m); #define ADD_OPERAND_WT_SP ADD_OPERAND_REG(REGSET_SP, REG_W_BASE, ctx->n); #define ADD_OPERAND_MEM_EXTENDED_T(BASE0, REGNUM0, BASE1, REGNUM1, ARR_SPEC) \ 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; \ i++; #define ADD_OPERAND_MEM_EXTENDED_T_SHIFT( \ BASE0, REGNUM0, SZ0, BASE1, REGNUM1, SZ1, SHIFT_TYPE, SHIFT_AMT, SHIFT_USED) \ 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].shiftType = SHIFT_TYPE; \ instr->operands[i].shiftValue = SHIFT_AMT; \ instr->operands[i].shiftValueUsed = SHIFT_USED; \ i += 1; /* general immediate operand adder */ #define ADD_OPERAND_IMM32(VALUE, SIGNED) \ instr->operands[i].operandClass = IMM32; \ instr->operands[i].signedImm = SIGNED; \ instr->operands[i].immediate = VALUE; \ i++; #define ADD_OPERAND_IMM64(VALUE, SIGNED) \ instr->operands[i].operandClass = IMM64; \ instr->operands[i].signedImm = SIGNED; \ instr->operands[i].immediate = VALUE; \ i++; #define ADD_OPERAND_FLOAT32(VALUE) \ instr->operands[i].operandClass = FIMM32; \ *(float*)&(instr->operands[i].immediate) = VALUE; \ i++; #define ADD_OPERAND_CONST ADD_OPERAND_IMM64(const_, 0) #define ADD_OPERAND_FBITS ADD_OPERAND_IMM32(fbits, 0) #define ADD_OPERAND_FIMM ADD_OPERAND_FLOAT32(fimm) #define ADD_OPERAND_IMM0 ADD_OPERAND_IMM32(0, 0) #define ADD_OPERAND_IMM1 ADD_OPERAND_IMM32(imm1, 0) #define ADD_OPERAND_IMM2 ADD_OPERAND_IMM32(imm2, 0) #define ADD_OPERAND_IMM6 ADD_OPERAND_IMM32(imm6, 0) #define ADD_OPERAND_IMM8 ADD_OPERAND_IMM32(imm8, 0) #define ADD_OPERAND_LSB ADD_OPERAND_IMM32(lsb, 0) #define ADD_OPERAND_NZCV ADD_OPERAND_IMM32(ctx->nzcv, 0) #define ADD_OPERAND_ROTATE ADD_OPERAND_IMM32(rotate, 0) #define ADD_OPERAND_WIDTH ADD_OPERAND_IMM32(width, 0) //#define SEXT4(x) (x & 0x /* string immediate (like "mul #0x12") */ #define ADD_OPERAND_STR_IMM(STRING, VALUE) \ instr->operands[i].operandClass = STR_IMM; \ instr->operands[i].immediate = VALUE; \ instr->operands[i].signedImm = 0; \ strcpy(instr->operands[i].name, STRING); \ i++; /* specialized immediate operands */ #define ADD_OPERAND_NAME(VALUE) \ instr->operands[i].operandClass = NAME; \ strcpy(instr->operands[i].name, VALUE); \ i++; /* multi reg stuff, like {v0.b, v1.b} */ #define ADD_OPERAND_MULTIREG_1(REG_BASE, ARR_SPEC, REGNUM) \ ; \ instr->operands[i].operandClass = MULTI_REG; \ instr->operands[i].reg[0] = REG(REGSET_ZR, REG_BASE, REGNUM); \ instr->operands[i].arrSpec = ARR_SPEC; \ i++; #define ADD_OPERAND_MULTIREG_2(REG_BASE, ARR_SPEC, REGNUM) \ ; \ 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; \ i++; #define ADD_OPERAND_MULTIREG_3(REG_BASE, ARR_SPEC, REGNUM) \ ; \ 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].reg[2] = REG(REGSET_ZR, REG_BASE, (REGNUM + 2) % 32); \ instr->operands[i].arrSpec = ARR_SPEC; \ i++; #define ADD_OPERAND_MULTIREG_4(REG_BASE, ARR_SPEC, REGNUM) \ ; \ 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].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; \ i++; #define ADD_OPERAND_MULTIREG_1_LANE(REG_BASE, ARR_SPEC, REGNUM) \ ; \ ADD_OPERAND_MULTIREG_1(REG_BASE, ARR_SPEC, REGNUM); \ instr->operands[i - 1].laneUsed = 1; \ instr->operands[i - 1].lane = ctx->index; #define ADD_OPERAND_MULTIREG_2_LANE(REG_BASE, ARR_SPEC, REGNUM) \ ; \ ADD_OPERAND_MULTIREG_2(REG_BASE, ARR_SPEC, REGNUM); \ instr->operands[i - 1].laneUsed = 1; \ instr->operands[i - 1].lane = ctx->index; #define ADD_OPERAND_MULTIREG_3_LANE(REG_BASE, ARR_SPEC, REGNUM) \ ; \ ADD_OPERAND_MULTIREG_3(REG_BASE, ARR_SPEC, REGNUM) \ instr->operands[i - 1].laneUsed = 1; \ instr->operands[i - 1].lane = ctx->index; #define ADD_OPERAND_MULTIREG_4_LANE(REG_BASE, ARR_SPEC, REGNUM) \ ; \ ADD_OPERAND_MULTIREG_4(REG_BASE, ARR_SPEC, REGNUM) \ instr->operands[i - 1].laneUsed = 1; \ instr->operands[i - 1].lane = ctx->index; /* v register plus ARRANGEMENT specifier: {1,2,4,8,16} x {b,h,s,d,q} */ #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; \ i++; #define ADD_OPERAND_VREG_T(REGNUM, ARR_SPEC) ADD_OPERAND_REG_T(REG_V_BASE, ARR_SPEC, REGNUM) #define ADD_OPERAND_ZREG_T(REGNUM, ARR_SPEC) ADD_OPERAND_REG_T(REG_Z_BASE, ARR_SPEC, REGNUM) /* and with lane */ #define ADD_OPERAND_VREG_T_LANE(REGNUM, ARR_SPEC, INDEX_VALUE) \ ADD_OPERAND_VREG_T(REGNUM, ARR_SPEC) \ instr->operands[i - 1].lane = INDEX_VALUE; \ instr->operands[i - 1].laneUsed = 1; #define ADD_OPERAND_ZREG_T_LANE(REGNUM, ARR_SPEC, INDEX_VALUE) \ ADD_OPERAND_ZREG_T(REGNUM, ARR_SPEC) \ instr->operands[i - 1].lane = INDEX_VALUE; \ instr->operands[i - 1].laneUsed = 1; /* */ #define ADD_OPERAND_COND \ instr->operands[i].operandClass = CONDITION; \ instr->operands[i].cond = table_cond[ctx->condition]; \ i++; #define ADD_OPERAND_COND_NEG \ instr->operands[i].operandClass = CONDITION; \ instr->operands[i].cond = table_cond_neg[ctx->condition]; \ i++; #define ADD_OPERAND_LABEL \ instr->operands[i].operandClass = LABEL; \ instr->operands[i].immediate = eaddr; \ i++; #define ADD_OPERAND_SYSTEMREG_IMPL_SPEC(SR) \ instr->operands[i].operandClass = IMPLEMENTATION_SPECIFIC; \ instr->operands[i].implspec[0] = ctx->sys_op0; \ instr->operands[i].implspec[1] = ctx->sys_op1; \ instr->operands[i].implspec[2] = ctx->sys_crn; \ instr->operands[i].implspec[3] = ctx->sys_crm; \ instr->operands[i].implspec[4] = ctx->sys_op2; \ instr->operands[i].sysreg = (SR); \ i++; #define ADD_OPERAND_SYSTEMREG(R) \ instr->operands[i].operandClass = SYS_REG; \ instr->operands[i].sysreg = (R); \ i++; #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]) \ { \ ADD_OPERAND_SYSTEMREG(sr); \ } \ else \ { \ ADD_OPERAND_SYSTEMREG_IMPL_SPEC(sr); \ } \ } #define ADD_OPERAND_PATTERN \ if (ctx->pattern > 0b1101 && ctx->pattern < 0b11101) \ { \ ADD_OPERAND_IMM32(ctx->pattern, 0); \ } \ else \ { \ ADD_OPERAND_NAME(pattern_lookup(ctx->pattern, ctx->imm)); \ } /* SME */ #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].immediate = (OFFSET); \ instr->operands[i].signedImm = 1; \ i++; #define ADD_OPERAND_ACCUM_ARRAY(BASEREG, OFFSET) \ instr->operands[i].operandClass = ACCUM_ARRAY; \ instr->operands[i].reg[0] = (BASEREG); \ instr->operands[i].immediate = (OFFSET); \ i++; //----------------------------------------------------------------------------- // register base lookups //----------------------------------------------------------------------------- unsigned rwwwx_0123x_reg(int x, int r) { if ((x & 0b01111) == 0b00000) return 0; // x0000 RESERVED if ((x & 0b00001) == 0b00001) return REG_W_BASE; // xxxx1 W if ((x & 0b00011) == 0b00010) return REG_W_BASE; // xxx10 W if ((x & 0b00111) == 0b00100) return REG_W_BASE; // xx100 W if ((x & 0b01111) == 0b01000) return REG_X_BASE; // x1000 X return 0; } unsigned rbhsdq_5bit_reg(unsigned key) { // if((key & 0b01111) == 0b00000) return 0; // x0000 RESERVED if (key == 0) return 0; // x0000 RESERVED if ((key & 0b00001) == 0b00001) return REG_B_BASE; // xxxx1 B if ((key & 0b00011) == 0b00010) return REG_H_BASE; // xxx10 H if ((key & 0b00111) == 0b00100) return REG_S_BASE; // xx100 S if ((key & 0b01111) == 0b01000) return REG_D_BASE; // xx100 D if ((key & 0b11111) == 0b10000) return REG_Q_BASE; // xx100 Q return 0; } unsigned wwwx_0123_reg(unsigned size) { if (size == 0b11) return REG_X_BASE; return REG_W_BASE; } unsigned sd_01_reg(int v) { switch (v & 1) { case 0: return REG_S_BASE; case 1: return REG_D_BASE; } return 0; } // ,, unsigned bhsd_0123_reg(int v) { switch (v & 3) { case 0: return REG_B_BASE; case 1: return REG_H_BASE; case 2: return REG_S_BASE; case 3: return REG_D_BASE; } return 0; } unsigned rsdr_0123_reg(int v) { switch (v & 3) { case 1: return REG_S_BASE; case 2: return REG_D_BASE; } return 0; } unsigned hsdr_0123_reg(int v) { switch (v & 3) { case 0: return REG_H_BASE; case 1: return REG_S_BASE; case 2: return REG_D_BASE; default: return 0; } } unsigned rhsd_0123_reg(int v) { if (v == 1) return REG_H_BASE; if (v == 2) return REG_S_BASE; return 0; } unsigned rhsd_0123x_reg(int v) { // if(x & 0xE == 0) return 0; // 000x if ((v & 0xE) == 2) return REG_H_BASE; // 001x if ((v & 0xC) == 4) return REG_S_BASE; // 01xx if ((v & 0x8) == 8) return REG_D_BASE; // 1xxx return 0; } unsigned rbhsd_0123x_reg(int v) { // 0000 RESERVED if (v == 1) return REG_B_BASE; // 0001 B if ((v & 0b1110) == 0b0010) return REG_H_BASE; // 001x H if ((v & 0b1100) == 0b0100) return REG_S_BASE; // 01xx S if ((v & 0b1000) == 0b1000) return REG_D_BASE; // 1xxx D return 0; } unsigned rhsdr_0123x_reg(int v) { if (v == 1) return REG_H_BASE; if ((v & 0b1110) == 0b0010) return REG_S_BASE; if ((v & 0b1100) == 0b0100) return REG_D_BASE; return 0; } #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].shiftValue = ctx->shift_amount; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ else \ { \ instr->operands[i - 1].shiftValueUsed = 0; \ } #define OPTIONAL_EXTEND_AMOUNT(SPECIAL_LSL) \ instr->operands[i - 1].shiftType = ctx->extend_type; \ instr->operands[i - 1].shiftValue = ctx->shift; \ if (ctx->option == SPECIAL_LSL) \ { \ if (ctx->shift) \ { \ instr->operands[i - 1].shiftType = ShiftType_LSL; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ else \ instr->operands[i - 1].shiftType = ShiftType_NONE; \ } \ else \ { \ instr->operands[i - 1].shiftValueUsed = ctx->shift ? 1 : 0; \ } #define OPTIONAL_EXTEND_AMOUNT_0 \ instr->operands[i - 1].shiftType = ctx->extend_type; \ instr->operands[i - 1].shiftValue = 0; \ instr->operands[i - 1].shiftValueUsed = ctx->S ? 1 : 0; #define OPTIONAL_EXTEND_LSL0 \ if (ctx->S) \ { \ instr->operands[i - 1].shiftType = ShiftType_LSL; \ instr->operands[i - 1].shiftValue = 0; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ else \ instr->operands[i - 1].shiftType = ShiftType_NONE; #define OPTIONAL_EXTEND_AMOUNT_32(EXCEPTIONAL_REG) \ ShiftType st = DecodeRegExtend(ctx->option); \ if (st == ShiftType_UXTW) \ { \ if (EXCEPTIONAL_REG == 31 && ctx->imm3 != 0) \ { \ st = ShiftType_LSL; \ } \ } \ instr->operands[i - 1].shiftType = st; \ instr->operands[i - 1].shiftValue = ctx->shift; \ if (ctx->shift) \ { \ instr->operands[i - 1].shiftValueUsed = 1; \ } #define OPTIONAL_EXTEND_AMOUNT_64_BEHAVIOR0 \ ShiftType st = DecodeRegExtend(ctx->option); \ if (ctx->Rn == 31 && ctx->option == 3) \ { \ st = ShiftType_LSL; \ if (ctx->imm3 == 0) \ st = ShiftType_NONE; \ } \ if (st != ShiftType_NONE) \ { \ instr->operands[i - 1].shiftType = st; \ instr->operands[i - 1].shiftValue = ctx->shift; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ if (!ctx->shift) \ { \ instr->operands[i - 1].shiftValueUsed = 0; \ } #define OPTIONAL_EXTEND_AMOUNT_64_BEHAVIOR1 \ ShiftType st = DecodeRegExtend(ctx->option); \ if ((ctx->Rd == 31 || ctx->Rn == 31) && ctx->option == 3) \ { \ st = ShiftType_LSL; \ if (ctx->imm3 == 0) \ st = ShiftType_NONE; \ } \ if (st != ShiftType_NONE) \ { \ instr->operands[i - 1].shiftType = st; \ instr->operands[i - 1].shiftValue = ctx->shift; \ instr->operands[i - 1].shiftValueUsed = 1; \ } \ if (!ctx->shift) \ { \ instr->operands[i - 1].shiftValueUsed = 0; \ } #define LAST_OPERAND_SHIFT(SHIFT_TYPE, SHIFT_VALUE) \ instr->operands[i - 1].shiftType = SHIFT_TYPE; \ instr->operands[i - 1].shiftValue = SHIFT_VALUE; \ instr->operands[i - 1].shiftValueUsed = 1; #define LAST_OPERAND_LSL_12 LAST_OPERAND_SHIFT(ShiftType_LSL, 12) #define ADD_OPERAND_OPTIONAL_PATTERN_MUL \ { \ bool print_mul = ctx->imm != 1; \ bool print_pattern = print_mul || ctx->pattern != 0x1f; \ if (print_pattern) \ { \ ADD_OPERAND_PATTERN; \ } \ if (print_mul) \ { \ ADD_OPERAND_STR_IMM("mul", ctx->imm); \ } \ } #define ADD_OPERAND_OPTIONAL_PATTERN \ if (ctx->pattern != 0x1f) \ { \ ADD_OPERAND_PATTERN; \ } /* convert the result of pcode execution to a human-friendly list of operands */ int decode_scratchpad(context* ctx, Instruction* instr) { ArrangementSpec arr_spec = _1B; /* index of operand array, as it's built */ int i = 0; /* populate operation */ instr->operation = enc_to_oper(instr->encoding); /* default to 0 operands */ InstructionOperand zero = {0}; for (uint32_t ii = 0; ii < MAX_OPERANDS; ++ii) instr->operands[ii] = zero; switch (instr->encoding) { /* instrucitons with no operands */ case ENC_AUTIA1716_HI_HINTS: case ENC_AUTIASP_HI_HINTS: case ENC_AUTIAZ_HI_HINTS: case ENC_AUTIB1716_HI_HINTS: case ENC_AUTIBSP_HI_HINTS: case ENC_AUTIBZ_HI_HINTS: case ENC_AXFLAG_M_PSTATE: case ENC_CFINV_M_PSTATE: case ENC_CSDB_HI_HINTS: case ENC_DGH_HI_HINTS: case ENC_DRPS_64E_BRANCH_REG: case ENC_ERETAA_64E_BRANCH_REG: case ENC_ERETAB_64E_BRANCH_REG: case ENC_ERET_64E_BRANCH_REG: case ENC_ESB_HI_HINTS: case ENC_NOP_HI_HINTS: case ENC_PACIA1716_HI_HINTS: case ENC_PACIASP_HI_HINTS: case ENC_PACIAZ_HI_HINTS: case ENC_PACIB1716_HI_HINTS: case ENC_PACIBSP_HI_HINTS: case ENC_PACIBZ_HI_HINTS: case ENC_RETAA_64E_BRANCH_REG: case ENC_RETAB_64E_BRANCH_REG: case ENC_SEVL_HI_HINTS: case ENC_SEV_HI_HINTS: case ENC_WFE_HI_HINTS: case ENC_WFI_HI_HINTS: case ENC_XAFLAG_M_PSTATE: case ENC_XPACLRI_HI_HINTS: case ENC_YIELD_HI_HINTS: case ENC_SETFFR_F_: // case ENC_SSBB_ONLY_BARRIERS: // case ENC_PSSBB_ONLY_BARRIERS: case ENC_SB_ONLY_BARRIERS: case ENC_TCOMMIT_ONLY_BARRIERS: case ENC_PSSBB_DSB_BO_BARRIERS: case ENC_SSBB_DSB_BO_BARRIERS: break; case ENC_WFET_ONLY_SYSTEMINSTRSWITHREG: case ENC_WFIT_ONLY_SYSTEMINSTRSWITHREG: { // ADD_OPERAND_XD; break; } case ENC_PSB_HC_HINTS: case ENC_TSB_HC_HINTS: { ADD_OPERAND_NAME("csync"); break; } case ENC_LDR_B_LDST_IMMPRE: case ENC_STR_B_LDST_IMMPRE: { // , [, #]! ADD_OPERAND_BT; ADD_OPERAND_MEM_PRE_INDEX(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDR_B_LDST_REGOFF: case ENC_STR_B_LDST_REGOFF: { int reg_base = table_wbase_xbase[ctx->option & 1]; // , [, (|),{}] ADD_OPERAND_BT; ADD_OPERAND_MEM_EXTENDED(reg_base, ctx->n, ctx->m); if (ctx->option & 1) { OPTIONAL_EXTEND_AMOUNT_32(3); } else { OPTIONAL_EXTEND_AMOUNT_64_BEHAVIOR1; } if (ctx->S) { OPTIONAL_EXTEND_AMOUNT_0 } break; } case ENC_LDR_BL_LDST_REGOFF: case ENC_STR_BL_LDST_REGOFF: { // , [,{, LSL #0}] ADD_OPERAND_BT; ADD_OPERAND_MEM_EXTENDED(REG_X_BASE, ctx->n, ctx->m); OPTIONAL_EXTEND_LSL0; break; } case ENC_LDR_B_LDST_IMMPOST: case ENC_STR_B_LDST_IMMPOST: { // , [], # ADD_OPERAND_BT; ADD_OPERAND_MEM_POST_INDEX(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDR_B_LDST_POS: case ENC_STR_B_LDST_POS: { // , [{, #}] ADD_OPERAND_BT; ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDUR_B_LDST_UNSCALED: case ENC_STUR_B_LDST_UNSCALED: { // , [{, #}] ADD_OPERAND_BT; ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_MOVI_ASIMDIMM_D_DS: // display as hex { uint64_t imm = ctx->imm; //
, # ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->rd); ADD_OPERAND_IMM64(imm, 0); break; } case ENC_FMOV_D_FLOATIMM: // display as float { float fimm = table_imm8_to_float[ctx->imm8]; //
, # ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_FIMM; break; } case ENC_FABS_D_FLOATDP1: case ENC_FMOV_D_FLOATDP1: case ENC_FNEG_D_FLOATDP1: case ENC_FRINT32X_D_FLOATDP1: case ENC_FRINT32Z_D_FLOATDP1: case ENC_FRINT64X_D_FLOATDP1: case ENC_FRINT64Z_D_FLOATDP1: case ENC_FRINTA_D_FLOATDP1: case ENC_FRINTI_D_FLOATDP1: case ENC_FRINTM_D_FLOATDP1: case ENC_FRINTN_D_FLOATDP1: case ENC_FRINTP_D_FLOATDP1: case ENC_FRINTX_D_FLOATDP1: case ENC_FRINTZ_D_FLOATDP1: case ENC_FSQRT_D_FLOATDP1: { //
, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_DN; break; } case ENC_FADD_D_FLOATDP2: case ENC_FDIV_D_FLOATDP2: case ENC_FMAXNM_D_FLOATDP2: case ENC_FMAX_D_FLOATDP2: case ENC_FMINNM_D_FLOATDP2: case ENC_FMIN_D_FLOATDP2: case ENC_FMUL_D_FLOATDP2: case ENC_FNMUL_D_FLOATDP2: case ENC_FSUB_D_FLOATDP2: { //
,, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_DN; ADD_OPERAND_DM; break; } case ENC_FMADD_D_FLOATDP3: case ENC_FMSUB_D_FLOATDP3: case ENC_FNMADD_D_FLOATDP3: case ENC_FNMSUB_D_FLOATDP3: { //
,,, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_DN; ADD_OPERAND_DM; ADD_OPERAND_DA; break; } case ENC_FCSEL_D_FLOATSEL: { //
,,, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_DN; ADD_OPERAND_DM; ADD_OPERAND_COND; break; } case ENC_FCVT_DH_FLOATDP1: { //
, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_HN; break; } case ENC_SADDV_R_P_Z_: case ENC_UADDV_R_P_Z_: { ArrangementSpec 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); ADD_OPERAND_ZREG_T(ctx->n, arr_spec) break; } case ENC_FCVT_DS_FLOATDP1: { //
, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_SN; break; } case ENC_SCVTF_D32_FLOAT2INT: case ENC_UCVTF_D32_FLOAT2INT: { //
, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_WN; break; } case ENC_SCVTF_D32_FLOAT2FIX: case ENC_UCVTF_D32_FLOAT2FIX: { uint64_t fbits = ctx->fracbits; //
,, # ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_WN; ADD_OPERAND_FBITS; break; } case ENC_FMOV_D64_FLOAT2INT: case ENC_SCVTF_D64_FLOAT2INT: case ENC_UCVTF_D64_FLOAT2INT: { //
, ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_XN; break; } case ENC_SCVTF_D64_FLOAT2FIX: case ENC_UCVTF_D64_FLOAT2FIX: { uint64_t fbits = ctx->fracbits; //
,, # ADD_OPERAND_REG(REGSET_ZR, REG_D_BASE, ctx->d); ADD_OPERAND_XN; ADD_OPERAND_FBITS; break; } case ENC_FCMPE_DZ_FLOATCMP: case ENC_FCMP_DZ_FLOATCMP: { // , #0.0 ADD_OPERAND_DN; ADD_OPERAND_FLOAT32(0); break; } case ENC_FCMPE_D_FLOATCMP: case ENC_FCMP_D_FLOATCMP: { // , ADD_OPERAND_DN; ADD_OPERAND_DM; break; } case ENC_FCCMPE_D_FLOATCCMP: case ENC_FCCMP_D_FLOATCCMP: { // ,, #, ADD_OPERAND_DN; ADD_OPERAND_DM; ADD_OPERAND_NZCV; ADD_OPERAND_COND; break; } case ENC_LDP_D_LDSTPAIR_PRE: case ENC_STP_D_LDSTPAIR_PRE: { // ,, [, #]! ADD_OPERAND_DT1; ADD_OPERAND_DT2; ADD_OPERAND_MEM_PRE_INDEX(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDP_D_LDSTPAIR_POST: case ENC_STP_D_LDSTPAIR_POST: { uint64_t imm = ctx->offset; // ,, [], # ADD_OPERAND_DT1; ADD_OPERAND_DT2; ADD_OPERAND_MEM_POST_INDEX(REGSET_SP, REG_X_BASE, ctx->n, imm); break; } case ENC_LDNP_D_LDSTNAPAIR_OFFS: case ENC_LDP_D_LDSTPAIR_OFF: case ENC_STNP_D_LDSTNAPAIR_OFFS: case ENC_STP_D_LDSTPAIR_OFF: { uint64_t imm = ctx->offset; // ,, [{, #}] ADD_OPERAND_DT1; ADD_OPERAND_DT2; ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, imm); break; } case ENC_LDR_D_LDST_IMMPRE: case ENC_STR_D_LDST_IMMPRE: { //
, [, #]! ADD_OPERAND_DT; ADD_OPERAND_MEM_PRE_INDEX(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDR_D_LDST_REGOFF: case ENC_STR_D_LDST_REGOFF: { int reg_base = table_wbase_xbase[ctx->option & 1]; //
, [, (|){,{}}] ADD_OPERAND_DT; ADD_OPERAND_MEM_EXTENDED(reg_base, ctx->n, ctx->m); OPTIONAL_EXTEND_AMOUNT(3); break; } case ENC_LDR_D_LDST_IMMPOST: case ENC_STR_D_LDST_IMMPOST: { //
, [], # ADD_OPERAND_DT; ADD_OPERAND_MEM_POST_INDEX(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDR_D_LDST_POS: case ENC_STR_D_LDST_POS: { //
, [{, #}] ADD_OPERAND_DT; ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDUR_D_LDST_UNSCALED: case ENC_STUR_D_LDST_UNSCALED: { //
, [{, #}] ADD_OPERAND_DT; ADD_OPERAND_MEM_REG_OFFSET(REGSET_SP, REG_X_BASE, ctx->n, ctx->offset); break; } case ENC_LDR_D_LOADLIT: { uint64_t eaddr = ctx->address + ctx->offset; //
,