From f693ac3b3fbbfe73f63df0c392f798d9d409f8ed Mon Sep 17 00:00:00 2001 From: Cam Mannett Date: Tue, 18 Jul 2023 12:48:27 +0000 Subject: [PATCH] i#3044 AArch64 SVE codec: Add memory tagged load/stores (#6215) This patch adds the appropriate macros, tests and codec entries to decode and encode the following instructions: ``` LDG , [, #] ST2G , [], # ST2G , [, #]! ST2G , [, #] STG , [], # STG , [, #]! STG , [, #] STZ2G , [], # STZ2G , [, #]! STZ2G , [, #] STZG , [], # STZG , [, #]! STZG , [, #] STGP , , [], # STGP , , [, #]! STGP , , [, #] ``` Issue #3044 Co-authored-by: Joshua Warburton --- core/arch/aarch64/proc.c | 15 +- core/arch/proc_api.h | 3 + core/ir/aarch64/codec.c | 288 ++++++++++++++++++++++++++++ core/ir/aarch64/codec_v86.txt | 16 ++ core/ir/aarch64/instr_create_api.h | 293 ++++++++++++++++++++++++++++- core/ir/aarch64/opnd_defs.txt | 9 +- suite/tests/api/dis-a64-v86.txt | 288 ++++++++++++++++++++++++++++ suite/tests/api/ir_aarch64.h | 4 +- suite/tests/api/ir_aarch64_v86.c | 240 +++++++++++++++++++++++ 9 files changed, 1151 insertions(+), 5 deletions(-) diff --git a/core/arch/aarch64/proc.c b/core/arch/aarch64/proc.c index 4d75c002c9c..7538c70e05d 100644 --- a/core/arch/aarch64/proc.c +++ b/core/arch/aarch64/proc.c @@ -59,6 +59,7 @@ read_feature_regs(uint64 isa_features[]) MRS(ID_AA64PFR0_EL1, AA64PFR0, isa_features); MRS(ID_AA64MMFR1_EL1, AA64MMFR1, isa_features); MRS(ID_AA64DFR0_EL1, AA64DFR0, isa_features); + MRS(ID_AA64PFR1_EL1, AA64PFR1, isa_features); /* TODO i#3044: Can't use the MRS macro with id_aa64zfr0_el1 as current GCC * binutils assembler fails to recognise it without -march=armv9-a+bf16+i8mm @@ -89,7 +90,7 @@ get_processor_specific_info(void) /* Reads instruction attribute and preocessor feature registers * ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1, ID_AA64PFR0_EL1, ID_AA64MMFR1_EL1, - * ID_AA64DFR0_EL1, ID_AA64ZFR0_EL1. + * ID_AA64DFR0_EL1, ID_AA64ZFR0_EL1, ID_AA64PFR1_EL1. */ read_feature_regs(isa_features); cpu_info.features.flags_aa64isar0 = isa_features[AA64ISAR0]; @@ -98,6 +99,7 @@ get_processor_specific_info(void) cpu_info.features.flags_aa64mmfr1 = isa_features[AA64MMFR1]; cpu_info.features.flags_aa64dfr0 = isa_features[AA64DFR0]; cpu_info.features.flags_aa64zfr0 = isa_features[AA64ZFR0]; + cpu_info.features.flags_aa64pfr1 = isa_features[AA64PFR1]; # if !defined(DR_HOST_NOT_TARGET) && defined(SVE) /* TODO i#3044: Vector length will be set by reading value from h/w. */ @@ -182,6 +184,10 @@ proc_init_arch(void) LOG_FEATURE(FEATURE_BF16); LOG_FEATURE(FEATURE_I8MM); LOG_FEATURE(FEATURE_F64MM); + + LOG(GLOBAL, LOG_TOP, 1, "Processor features:\n ID_AA64PFR1_EL1 = 0x%016lx\n", + cpu_info.features.flags_aa64pfr1); + LOG_FEATURE(FEATURE_MTE); }); # endif #endif @@ -228,7 +234,8 @@ proc_has_feature(feature_bit_t f) case FEATURE_SVEAES: case FEATURE_SVESHA3: case FEATURE_SVESM4: - case FEATURE_SVEBitPerm: return true; + case FEATURE_SVEBitPerm: + case FEATURE_MTE: return true; case FEATURE_AESX: case FEATURE_PMULL: @@ -268,6 +275,10 @@ proc_has_feature(feature_bit_t f) freg_val = cpu_info.features.flags_aa64zfr0; break; } + case AA64PFR1: { + freg_val = cpu_info.features.flags_aa64pfr1; + break; + } default: CLIENT_ASSERT(false, "proc_has_feature: invalid feature register"); } diff --git a/core/arch/proc_api.h b/core/arch/proc_api.h index ae48467aabf..ed1b6e5b5c8 100644 --- a/core/arch/proc_api.h +++ b/core/arch/proc_api.h @@ -180,6 +180,7 @@ typedef struct { uint64 flags_aa64mmfr1; /**< AArch64 feature flags stored in ID_AA64MMFR1_EL1 */ uint64 flags_aa64dfr0; /**< AArch64 feature flags stored in ID_AA64DFR0_EL1 */ uint64 flags_aa64zfr0; /**< AArch64 feature flags stored in ID_AA64ZFR0_EL1 */ + uint64 flags_aa64pfr1; /**< AArch64 feature flags stored in ID_AA64PFR1_EL1 */ } features_t; typedef enum { AA64ISAR0 = 0, @@ -188,6 +189,7 @@ typedef enum { AA64MMFR1 = 3, AA64DFR0 = 4, AA64ZFR0 = 5, + AA64PFR1 = 6, } feature_reg_idx_t; #endif #ifdef RISCV64 @@ -361,6 +363,7 @@ typedef enum { FEATURE_SVESHA3 = DEF_FEAT(AA64ZFR0, 8, 1, 0), /**< SVE2 + SHA3(AArch64) */ FEATURE_SVESM4 = DEF_FEAT(AA64ZFR0, 10, 1, 0), /**< SVE2 + SM4(AArch64) */ FEATURE_SVEBitPerm = DEF_FEAT(AA64ZFR0, 4, 1, 0), /**< SVE2 + BitPerm(AArch64) */ + FEATURE_MTE = DEF_FEAT(AA64PFR1, 2, 1, 0), /**< Memory Tagging Extension */ } feature_bit_t; #endif #ifdef RISCV64 diff --git a/core/ir/aarch64/codec.c b/core/ir/aarch64/codec.c index adea08dc697..c8ac064bfb8 100644 --- a/core/ir/aarch64/codec.c +++ b/core/ir/aarch64/codec.c @@ -48,6 +48,16 @@ #include "codec.h" +/* Tag granule scaling */ +const uint log2_tag_granule = 4; + +/* Memory op indexing type */ +enum mem_op_index_t { + MEM_OP_INDEX_POST = 1, + MEM_OP_INDEX_NONE = 2, // AKA offset + MEM_OP_INDEX_PRE = 3, +}; + /* Decode immediate argument of bitwise operations. * Returns zero if the encoding is invalid. */ @@ -4764,6 +4774,20 @@ encode_opnd_mem9off(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_o return encode_opnd_int(12, 9, true, 0, 0, opnd, enc_out); } +/* mem9off_tag: Same as mem9off, but performs memory tag scaling */ + +static inline bool +decode_opnd_mem9off_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_opnd_int(12, 9, true, log2_tag_granule, OPSZ_PTR, 0, enc, opnd); +} + +static inline bool +encode_opnd_mem9off_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + return encode_opnd_int(12, 9, true, log2_tag_granule, 0, opnd, enc_out); +} + /* mem9q: memory operand with 9-bit offset; size is 16 bytes */ static inline bool @@ -4778,6 +4802,37 @@ encode_opnd_mem9q(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out return encode_opnd_mem9_bytes(16, false, opnd, enc_out); } +/* mem9_ldg_tag: Same as mem9_tag but fixed at offset with 0 bytes transferred */ + +static inline bool +decode_opnd_mem9_ldg_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + const reg_id_t Xn = decode_reg(extract_uint(enc, 5, 5), true, true); + const uint disp = extract_int(enc, 12, 9) << log2_tag_granule; + + *opnd = opnd_create_base_disp_aarch64(Xn, DR_REG_NULL, DR_EXTEND_UXTX, false, disp, 0, + OPSZ_0); + return true; +} + +static inline bool +encode_opnd_mem9_ldg_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + uint xn; + if (!is_base_imm(opnd, &xn) || opnd_get_size(opnd) != OPSZ_0) + return false; + + /* Disp must be multiple of 16 */ + int disp = (int)opnd_get_disp(opnd); + IF_RETURN_FALSE((disp % (1 << log2_tag_granule)) != 0) + + disp >>= log2_tag_granule; + IF_RETURN_FALSE(disp < -256 || disp > 255) + + *enc_out = xn << 5 | (disp & 0x1ff) << 12; + return true; +} + /* prf9: prefetch variant of mem9 */ static inline bool @@ -5251,6 +5306,20 @@ encode_opnd_svemem_gpr_simm9_vl(uint enc, int opcode, byte *pc, opnd_t opnd, return true; } +/* mem7off_tag: Same as mem7off, but performs memory tag scaling */ + +static inline bool +decode_opnd_mem7off_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_opnd_int(15, 7, true, log2_tag_granule, OPSZ_PTR, 0, enc, opnd); +} + +static inline bool +encode_opnd_mem7off_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + return encode_opnd_int(15, 7, true, log2_tag_granule, 0, opnd, enc_out); +} + /* imm12: 12-bit immediate operand of ADD/SUB */ static inline bool @@ -6263,6 +6332,139 @@ encode_opnd_z_tb_bhs_5(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *en return encode_sized_z_tb(5, BYTE_REG, SINGLE_REG, opnd, enc_out); } +static inline bool +decode_mem7_tag(uint enc, OUT opnd_t *opnd) +{ + // Post/Pre/None + const uint index_type = extract_uint(enc, 23, 2); + switch (index_type) { + case MEM_OP_INDEX_POST: + case MEM_OP_INDEX_NONE: + case MEM_OP_INDEX_PRE: break; + default: ASSERT_NOT_REACHED(); + } + + const reg_id_t Xn = decode_reg(extract_uint(enc, 5, 5), true, true); + // Disp is zero for post-indexed + const uint disp = index_type == MEM_OP_INDEX_POST + ? 0 + : (extract_int(enc, 15, 7) << log2_tag_granule); + + *opnd = opnd_create_base_disp_aarch64(Xn, DR_REG_NULL, DR_EXTEND_UXTX, false, disp, 0, + OPSZ_16); + if (index_type == MEM_OP_INDEX_PRE) + opnd->value.base_disp.pre_index = true; + + return true; +} + +static inline bool +encode_mem7_base_tag(uint enc, opnd_t opnd, OUT enum mem_op_index_t *index_type_out, + OUT uint *enc_out) +{ + uint xn; + if (!is_base_imm(opnd, &xn) || opnd_get_size(opnd) != OPSZ_16) + return false; + + /* Check the indexed state matches the expected pre_index value */ + const uint index_type = extract_uint(enc, 23, 2); + if ((index_type == MEM_OP_INDEX_POST || index_type == MEM_OP_INDEX_NONE) && + opnd.value.base_disp.pre_index) + return false; + if (index_type == MEM_OP_INDEX_PRE && !opnd.value.base_disp.pre_index) + return false; + + if (index_type_out) + *index_type_out = index_type; + + *enc_out = xn << 5; + return true; +} + +static inline bool +decode_mem9_tag(uint enc, OUT opnd_t *opnd) +{ + // Post/Pre/None + const uint index_type = extract_uint(enc, 10, 2); + switch (index_type) { + case MEM_OP_INDEX_POST: + case MEM_OP_INDEX_NONE: + case MEM_OP_INDEX_PRE: break; + default: ASSERT_NOT_REACHED(); + } + + // Bytes to write + opnd_size_t bytes; + switch (extract_uint(enc, 22, 2)) { + case 0x1: bytes = OPSZ_16; break; + case 0x3: bytes = OPSZ_32; break; + default: bytes = OPSZ_0; break; + } + + const reg_id_t Xn = decode_reg(extract_uint(enc, 5, 5), true, true); + // Disp is zero for post-indexed + const uint disp = index_type == MEM_OP_INDEX_POST + ? 0 + : (extract_int(enc, 12, 9) << log2_tag_granule); + + *opnd = opnd_create_base_disp_aarch64(Xn, DR_REG_NULL, DR_EXTEND_UXTX, false, disp, 0, + bytes); + if (index_type == MEM_OP_INDEX_PRE) + opnd->value.base_disp.pre_index = true; + + return true; +} + +static inline bool +encode_mem9_base_tag(uint enc, opnd_t opnd, OUT enum mem_op_index_t *index_type_out, + OUT uint *enc_out) +{ + /* Bytes to write */ + opnd_size_t bytes; + switch (extract_uint(enc, 22, 2)) { + case 0x1: bytes = OPSZ_16; break; + case 0x3: bytes = OPSZ_32; break; + default: bytes = OPSZ_0; break; + } + + uint xn; + if (!is_base_imm(opnd, &xn) || opnd_get_size(opnd) != bytes) + return false; + + /* Check the indexed state matches the expected pre_index value */ + const uint index_type = extract_uint(enc, 10, 2); + if ((index_type == MEM_OP_INDEX_POST || index_type == MEM_OP_INDEX_NONE) && + opnd.value.base_disp.pre_index) + return false; + if (index_type == MEM_OP_INDEX_PRE && !opnd.value.base_disp.pre_index) + return false; + + if (index_type_out) + *index_type_out = index_type; + + *enc_out = xn << 5; + return true; +} + +/* mem9post_tag: Same as mem9_tag but specifically post-indexed */ + +static inline bool +decode_opnd_mem9post_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_mem9_tag(enc, opnd); +} + +static inline bool +encode_opnd_mem9post_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + enum mem_op_index_t index_type; + const bool result = encode_mem9_base_tag(enc, opnd, &index_type, enc_out); + + /* Operand only for post-index */ + IF_RETURN_FALSE(result && (index_type != MEM_OP_INDEX_POST)) + return result; +} + /* fpimm8_5: floating-point 8 bit imm at pos 5 */ static inline bool @@ -6534,6 +6736,48 @@ encode_opnd_fpimm8_13(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc } } +static inline bool +extract_memtag_disp(opnd_t opnd, enum mem_op_index_t index_type, OUT int *disp_out) +{ + /* Disp must be multiple of 16 and be zero for post-indexed */ + int disp = opnd_get_disp(opnd); + IF_RETURN_FALSE((disp % (1 << log2_tag_granule)) != 0) + IF_RETURN_FALSE(index_type == MEM_OP_INDEX_POST && disp != 0) + + disp >>= log2_tag_granule; + IF_RETURN_FALSE(disp < -256 || disp > 255) + + if (disp_out) + *disp_out = disp; + + return true; +} + +/* mem9_tag: memory operand with written bytes in 23:22, post/pre/offset is in 11:10, with + * memory tag scaling + */ + +static inline bool +decode_opnd_mem9_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_mem9_tag(enc, opnd); +} + +static inline bool +encode_opnd_mem9_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + enum mem_op_index_t index_type; + if (!encode_mem9_base_tag(enc, opnd, &index_type, enc_out)) + return false; + + int disp; + if (!extract_memtag_disp(opnd, index_type, &disp)) + return false; + + *enc_out |= BITS((uint)disp, 8, 0) << 12; + return true; +} + /* b_sz: Vector element width for SIMD instructions. */ static inline bool @@ -7447,6 +7691,25 @@ encode_svemem_vec_imm5(uint enc, aarch64_reg_offset element_size, bool is_prefet return true; } +/* mem7post_tag: Same as mem7_tag but specifically post-indexed */ + +static inline bool +decode_opnd_mem7post_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_mem7_tag(enc, opnd); +} + +static inline bool +encode_opnd_mem7post_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + uint index_type; + const bool result = encode_mem7_base_tag(enc, opnd, &index_type, enc_out); + + /* Operand only for post-index */ + IF_RETURN_FALSE(result && (index_type != MEM_OP_INDEX_POST)) + return result; +} + /* SVE memory address [.S{, #}] */ static inline bool decode_opnd_svemem_vec_s_imm5(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) @@ -7516,6 +7779,31 @@ encode_opnd_svemem_gpr_vec64(uint enc, int opcode, byte *pc, opnd_t opnd, encode_svemem_gpr_vec(enc, DOUBLE_REG, msz, scaled, opnd, enc_out); } +/* mem7_tag: Write bytes is fixed at 16bytes, post/pre/offset is in 24:23, with memory tag + * scaling + */ + +static inline bool +decode_opnd_mem7_tag(uint enc, int opcode, byte *pc, OUT opnd_t *opnd) +{ + return decode_mem7_tag(enc, opnd); +} + +static inline bool +encode_opnd_mem7_tag(uint enc, int opcode, byte *pc, opnd_t opnd, OUT uint *enc_out) +{ + enum mem_op_index_t index_type; + if (!encode_mem7_base_tag(enc, opnd, &index_type, enc_out)) + return false; + + int disp; + if (!extract_memtag_disp(opnd, index_type, &disp)) + return false; + + *enc_out |= BITS((uint)disp, 6, 0) << 15; + return true; +} + static inline bool dtype_is_signed(uint dtype) { diff --git a/core/ir/aarch64/codec_v86.txt b/core/ir/aarch64/codec_v86.txt index 7dc2927286b..e45c7f409f2 100644 --- a/core/ir/aarch64/codec_v86.txt +++ b/core/ir/aarch64/codec_v86.txt @@ -46,7 +46,23 @@ 01101110110xxxxx111111xxxxxxxxxx n 956 BF16 bfmlalt q0 : q0 q5 q16 h_sz 0100111111xxxxxx1111x0xxxxxxxxxx n 956 BF16 bfmlalt q0 : q0 q5 q4_16 vindex_H h_sz 01101110010xxxxx111011xxxxxxxxxx n 957 BF16 bfmmla q0 : q0 q5 q16 h_sz +11011001011xxxxxxxxx00xxxxxxxxxx n 1201 MTE ldg x0 : x0 mem9_ldg_tag 01001110100xxxxx101001xxxxxxxxxx n 958 I8MM smmla q0 : q0 q5 q16 b_const_sz +11011001101xxxxxxxxx01xxxxxxxxxx n 1197 MTE st2g mem9post_tag x5sp : x0sp x5sp mem9off_tag +11011001101xxxxxxxxx11xxxxxxxxxx n 1197 MTE st2g mem9_tag x5sp : x0sp x5sp mem9off_tag +11011001101xxxxxxxxx10xxxxxxxxxx n 1197 MTE st2g mem9_tag : x0sp +11011001001xxxxxxxxx01xxxxxxxxxx n 1198 MTE stg mem9post_tag x5sp : x0sp x5sp mem9off_tag +11011001001xxxxxxxxx11xxxxxxxxxx n 1198 MTE stg mem9_tag x5sp : x0sp x5sp mem9off_tag +11011001001xxxxxxxxx10xxxxxxxxxx n 1198 MTE stg mem9_tag : x0sp +0110100010xxxxxxxxxxxxxxxxxxxxxx n 1202 MTE stgp mem7post_tag x5sp : x0 x10 x5sp mem7off_tag +0110100110xxxxxxxxxxxxxxxxxxxxxx n 1202 MTE stgp mem7_tag x5sp : x0 x10 x5sp mem7off_tag +0110100100xxxxxxxxxxxxxxxxxxxxxx n 1202 MTE stgp mem7_tag : x0 x10 +11011001111xxxxxxxxx01xxxxxxxxxx n 1199 MTE stz2g mem9post_tag x5sp : x0sp x5sp mem9off_tag +11011001111xxxxxxxxx11xxxxxxxxxx n 1199 MTE stz2g mem9_tag x5sp : x0sp x5sp mem9off_tag +11011001111xxxxxxxxx10xxxxxxxxxx n 1199 MTE stz2g mem9_tag : x0sp +11011001011xxxxxxxxx01xxxxxxxxxx n 1200 MTE stzg mem9post_tag x5sp : x0sp x5sp mem9off_tag +11011001011xxxxxxxxx11xxxxxxxxxx n 1200 MTE stzg mem9_tag x5sp : x0sp x5sp mem9off_tag +11011001011xxxxxxxxx10xxxxxxxxxx n 1200 MTE stzg mem9_tag : x0sp 0x00111100xxxxxx1111x0xxxxxxxxxx n 959 I8MM sudot dq0 : dq0 dq5 q16 vindex_S b_const_sz 01101110100xxxxx101001xxxxxxxxxx n 960 I8MM ummla q0 : q0 q5 q16 b_const_sz 0x001110100xxxxx100111xxxxxxxxxx n 961 I8MM usdot dq0 : dq0 dq5 dq16 b_const_sz diff --git a/core/ir/aarch64/instr_create_api.h b/core/ir/aarch64/instr_create_api.h index 4d96598a934..8f1f6896b89 100644 --- a/core/ir/aarch64/instr_create_api.h +++ b/core/ir/aarch64/instr_create_api.h @@ -10999,7 +10999,7 @@ * \param Pg The governing predicate register, P (Predicate). * \param Rn The first source base register with a register offset, * constructed with the function: - * For the [\{, \, LSL #3}] viriant: + * For the [\{, \, LSL #3}] variant: * opnd_create_base_disp_shift_aarch64(Rn, Rm, * DR_EXTEND_UXTX, 1, 0, 0, OPSZ_32, 3) * For the [\.D{, #\}] variant: @@ -17642,4 +17642,295 @@ */ #define INSTR_CREATE_whilewr_sve(dc, Pd, Rn, Rm) \ instr_create_1dst_2src(dc, OP_whilewr, Pd, Rn, Rm) + +/** + * Creates a LDG instruction. + * + * This macro is used to encode the forms: + \verbatim + LDG , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rt The source and destination register, X (Extended, 64 bits). + * \param Rn The source base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_0) + */ +#define INSTR_CREATE_ldg(dc, Rt, Rn) instr_create_1dst_2src(dc, OP_ldg, Rt, Rt, Rn) + +/** + * Creates a ST2G instruction. + * + * This macro is used to encode the forms: + \verbatim + ST2G , [], # + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, 0, 0, + * OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + * \param simm The immediate integer offset, must be a multiple of 16 between -4096 and + * 4080. + */ +#define INSTR_CREATE_st2g_post(dc, Rn, Rt, simm) \ + instr_create_2dst_3src(dc, OP_st2g, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), simm) + +/** + * Creates a ST2G instruction. + * + * This macro is used to encode the forms: + \verbatim + ST2G , [, #]! + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp(Rn, DR_REG_NULL, 0, simm, OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_st2g_pre(dc, Rn, Rt) \ + instr_create_2dst_3src(dc, OP_st2g, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), \ + OPND_CREATE_INT(opnd_get_disp(Rn))) + +/** + * Creates a ST2G instruction. + * + * This macro is used to encode the forms: + \verbatim + ST2G , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_st2g_offset(dc, Rn, Rt) instr_create_1dst_1src(dc, OP_st2g, Rn, Rt) + +/** + * Creates a STG instruction. + * + * This macro is used to encode the forms: + \verbatim + STG , [], # + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, 0, 0, + * OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + * \param simm The immediate integer offset, must be a multiple of 16 between -4096 and + * 4080. + */ +#define INSTR_CREATE_stg_post(dc, Rn, Rt, simm) \ + instr_create_2dst_3src(dc, OP_stg, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), simm) + +/** + * Creates a STG instruction. + * + * This macro is used to encode the forms: + \verbatim + STG , [, #]! + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp(Rn, DR_REG_NULL, 0, simm, OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stg_pre(dc, Rn, Rt) \ + instr_create_2dst_3src(dc, OP_stg, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), \ + OPND_CREATE_INT(opnd_get_disp(Rn))) + +/** + * Creates a STG instruction. + * + * This macro is used to encode the forms: + \verbatim + STG , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_0) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stg_offset(dc, Rn, Rt) instr_create_1dst_1src(dc, OP_stg, Rn, Rt) + +/** + * Creates a STZ2G instruction. + * + * This macro is used to encode the forms: + \verbatim + STZ2G , [], # + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, 0, 0, + * OPSZ_32) + * \param Rt The first source register, X (Extended, 64 bits). + * \param simm The immediate integer offset, must be a multiple of 16 between -4096 and + * 4080. + */ +#define INSTR_CREATE_stz2g_post(dc, Rn, Rt, simm) \ + instr_create_2dst_3src(dc, OP_stz2g, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), simm) + +/** + * Creates a STZ2G instruction. + * + * This macro is used to encode the forms: + \verbatim + STZ2G , [, #]! + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp(Rn, DR_REG_NULL, 0, simm, OPSZ_32) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stz2g_pre(dc, Rn, Rt) \ + instr_create_2dst_3src(dc, OP_stz2g, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), \ + OPND_CREATE_INT(opnd_get_disp(Rn))) + +/** + * Creates a STZ2G instruction. + * + * This macro is used to encode the forms: + \verbatim + STZ2G , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_32) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stz2g_offset(dc, Rn, Rt) instr_create_1dst_1src(dc, OP_stz2g, Rn, Rt) + +/** + * Creates a STZG instruction. + * + * This macro is used to encode the forms: + \verbatim + STZG , [], # + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, 0, 0, + * OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + * \param simm The immediate integer offset, must be a multiple of 16 between -4096 and + * 4080. + */ +#define INSTR_CREATE_stzg_post(dc, Rn, Rt, simm) \ + instr_create_2dst_3src(dc, OP_stzg, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), simm) + +/** + * Creates a STZG instruction. + * + * This macro is used to encode the forms: + \verbatim + STZG , [, #]! + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp(Rn, DR_REG_NULL, 0, simm, OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stzg_pre(dc, Rn, Rt) \ + instr_create_2dst_3src(dc, OP_stzg, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, \ + opnd_create_reg(opnd_get_base(Rn)), \ + OPND_CREATE_INT(opnd_get_disp(Rn))) + +/** + * Creates a STZG instruction. + * + * This macro is used to encode the forms: + \verbatim + STZG , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The second source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stzg_offset(dc, Rn, Rt) instr_create_1dst_1src(dc, OP_stzg, Rn, Rt) + +/** + * Creates a STGP instruction. + * + * This macro is used to encode the forms: + \verbatim + STGP , , [], # + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The third source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, 0, 0, + * OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + * \param Rt2 The second source register, X (Extended, 64 bits). + * \param simm The immediate integer offset, must be a multiple of 16 between -1024 and + * 1008. + */ +#define INSTR_CREATE_stgp_post(dc, Rn, Rt, Rt2, simm) \ + instr_create_2dst_4src(dc, OP_stgp, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, Rt2, \ + opnd_create_reg(opnd_get_base(Rn)), simm) + +/** + * Creates a STGP instruction. + * + * This macro is used to encode the forms: + \verbatim + STGP , , [, #]! + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The third source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp(Rn, DR_REG_NULL, 0, simm, OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + * \param Rt2 The second source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stgp_pre(dc, Rn, Rt, Rt2) \ + instr_create_2dst_4src(dc, OP_stgp, Rn, opnd_create_reg(opnd_get_base(Rn)), Rt, Rt2, \ + opnd_create_reg(opnd_get_base(Rn)), \ + OPND_CREATE_INT(opnd_get_disp(Rn))) + +/** + * Creates a STGP instruction. + * + * This macro is used to encode the forms: + \verbatim + STGP , , [, #] + \endverbatim + * \param dc The void * dcontext used to allocate memory for the #instr_t. + * \param Rn The third source and destination base register with an immediate offset, + * constructed with the function: + * opnd_create_base_disp_aarch64(Rn, DR_REG_NULL, DR_EXTEND_UXTX, 0, simm, 0, + * OPSZ_16) + * \param Rt The first source register, X (Extended, 64 bits). + * \param Rt2 The second source register, X (Extended, 64 bits). + */ +#define INSTR_CREATE_stgp_offset(dc, Rn, Rt, Rt2) \ + instr_create_1dst_2src(dc, OP_stgp, Rn, Rt, Rt2) + #endif /* DR_IR_MACROS_AARCH64_H */ diff --git a/core/ir/aarch64/opnd_defs.txt b/core/ir/aarch64/opnd_defs.txt index 92580de6912..8e2cfe735f2 100644 --- a/core/ir/aarch64/opnd_defs.txt +++ b/core/ir/aarch64/opnd_defs.txt @@ -225,8 +225,10 @@ -----------xxxxx-??---xxxxx----- sveprf_gpr_vec64 # SVE prefetch memory address (64-bit offset) [, .D{, }] -----------xxxxxx--------------- imm6_15 # 6 bit immediate from 20:15 -----------xxxxxxx-------------- imm7 # 7 bit immediate from 20:14 ------------xxxxxxxxx------------ mem9off # immed offset for mem9/mem9post +-----------xxxxxxxxx------------ mem9off # immed offset for mem9/mem9post +-----------xxxxxxxxx------------ mem9off_tag # Same as mem9off, but performs memory tag scaling -----------xxxxxxxxx--xxxxx----- mem9q # size is 16 bytes +-----------xxxxxxxxx--xxxxx----- mem9_ldg_tag # Same as mem9_tag but fixed at offset with 0 bytes transferred -----------xxxxxxxxx--xxxxx----- prf9 # size is 0 bytes (prefetch variant of mem9) -----------xxxxxxxxx--xxxxx----- memregq # register offset, size is 16 bytes -----------xxxxxxxxx--xxxxx----- prfreg # register offset, size is 0 (prefetch) @@ -244,6 +246,7 @@ ----------xxxxxx------xxxxx----- svememx6_s_5 # vector memory reg with 6 bit imm for single value ----------xxxxxx------xxxxx----- svememx6_d_5 # vector memory reg with 6 bit imm for double value ----------xxxxxx-?-xxxxxxxx----- svemem_gpr_simm9_vl # imm offset and base reg for SVE ld/st +----------xxxxxxx--------------- mem7off_tag # Same as mem7off, but performs memory tag scaling ----------xxxxxxxxxxxx---------- imm12 # immediate for ADD/SUB ----------xxxxxxxxxxxxxxxxx----- mem12q # size is 16 bytes ----------xxxxxxxxxxxxxxxxx----- prf12 # size is 0 bytes (prefetch variant of mem12) @@ -283,6 +286,7 @@ --------??------------xxxxx----- wx_size_5_sp # GPR scalar register, register size, W or X depending on size bits --------??------------xxxxx----- wx_size_5_zr # GPR scalar register, register size, W or X depending on size bits --------??------------xxxxx----- z_tb_bhs_5 # sve vector reg, elsz depending on size Tb +--------??----------??xxxxx----- mem9post_tag # Same as mem9_tag but specifically post-indexed --------??---------xxxxxxxx----- fpimm8_5 # floating-point 8 bit imm at pos 5 --------??-??--------------xxxxx z_tszl19_bhsd_0 # z element register mediated by the tszl and tszh fields --------??-??--------------xxxxx z_tszl19_bhs_0 # z element register mediated by the tszl and tszh fields @@ -293,6 +297,7 @@ --------??-xxxxx---------------- wx_size_16_zr # GPR scalar register, register size, W or X depending on size bits --------??-xxxxx----xxxxxxx----- svemem_vec_vec_idx # SVE memory address [., .{, }] --------??-xxxxxxxx------------- fpimm8_13 # floating-point immediate for scalar fmov +--------??-xxxxxxxxx??xxxxx----- mem9_tag # Write bytes is in 23:22, post/pre/offset is in 11:10, with memory tag scaling --------xx---------------------- b_sz # element width of a vector (8<.S{, #}] -------??--xxxxx------xxxxx----- svemem_vec_d_imm5 # SVE memory address [.D{, #}] -------??--xxxxx------xxxxx----- sveprf_gpr_shf # SVE memory address [, , LSL #x] for prefetch operation -------??-?xxxxx------xxxxx----- svemem_gpr_vec64 # SVE memory address (64-bit offset) [, .D{, }] +-------??-xxxxxxx-----xxxxx----- mem7_tag # Write bytes is fixed at 16bytes, post/pre/offset is in 24:23, with memory tag scaling -------????-xxxx------xxxxx----- svemem_gpr_simm4_vl_1reg # SVE memory operand [{, #, MUL VL}] # 1 src/dest register -------????xxxxx------xxxxx----- svemem_ssz_gpr_shf # SVE memory operand [, , LSL #x] diff --git a/suite/tests/api/dis-a64-v86.txt b/suite/tests/api/dis-a64-v86.txt index 0dd38cd6a88..863e98ef985 100644 --- a/suite/tests/api/dis-a64-v86.txt +++ b/suite/tests/api/dis-a64-v86.txt @@ -244,6 +244,24 @@ 6e5def9b : bfmmla v27.4s, v28.8h, v29.8h : bfmmla %q27 %q28 %q29 $0x01 -> %q27 6e5fefff : bfmmla v31.4s, v31.8h, v31.8h : bfmmla %q31 %q31 %q31 $0x01 -> %q31 +# LDG , [, #] (LDG-R.RI-offset) +d9700000 : ldg x0, [x0, #-4096] : ldg %x0 -0x1000(%x0) -> %x0 +d9720062 : ldg x2, [x3, #-3584] : ldg %x2 -0x0e00(%x3) -> %x2 +d97400a4 : ldg x4, [x5, #-3072] : ldg %x4 -0x0c00(%x5) -> %x4 +d97600e6 : ldg x6, [x7, #-2560] : ldg %x6 -0x0a00(%x7) -> %x6 +d9780128 : ldg x8, [x9, #-2048] : ldg %x8 -0x0800(%x9) -> %x8 +d97a0149 : ldg x9, [x10, #-1536] : ldg %x9 -0x0600(%x10) -> %x9 +d97c018b : ldg x11, [x12, #-1024] : ldg %x11 -0x0400(%x12) -> %x11 +d97e01cd : ldg x13, [x14, #-512] : ldg %x13 -0x0200(%x14) -> %x13 +d960020f : ldg x15, [x16] : ldg %x15 (%x16) -> %x15 +d961f251 : ldg x17, [x18, #496] : ldg %x17 +0x01f0(%x18) -> %x17 +d963f293 : ldg x19, [x20, #1008] : ldg %x19 +0x03f0(%x20) -> %x19 +d965f2d5 : ldg x21, [x22, #1520] : ldg %x21 +0x05f0(%x22) -> %x21 +d967f2f6 : ldg x22, [x23, #2032] : ldg %x22 +0x07f0(%x23) -> %x22 +d969f338 : ldg x24, [x25, #2544] : ldg %x24 +0x09f0(%x25) -> %x24 +d96bf37a : ldg x26, [x27, #3056] : ldg %x26 +0x0bf0(%x27) -> %x26 +d96ff3fe : ldg x30, [sp, #4080] : ldg %x30 +0x0ff0(%sp) -> %x30 + # SMMLA .4S, .16B, .16B (SMMLA-Q.QQ-Vec) 4e80a400 : smmla v0.4s, v0.16b, v0.16b : smmla %q0 %q0 %q0 $0x00 -> %q0 4e84a462 : smmla v2.4s, v3.16b, v4.16b : smmla %q2 %q3 %q4 $0x00 -> %q2 @@ -262,6 +280,276 @@ 4e9da79b : smmla v27.4s, v28.16b, v29.16b : smmla %q27 %q28 %q29 $0x00 -> %q27 4e9fa7ff : smmla v31.4s, v31.16b, v31.16b : smmla %q31 %q31 %q31 $0x00 -> %q31 +# ST2G , [], # +d9b00400 : st2g x0, [x0], #-4096 : st2g %x0 %x0 $0xfffffffffffff000 -> (%x0) %x0 +d9b20462 : st2g x2, [x3], #-3584 : st2g %x2 %x3 $0xfffffffffffff200 -> (%x3) %x3 +d9b404a4 : st2g x4, [x5], #-3072 : st2g %x4 %x5 $0xfffffffffffff400 -> (%x5) %x5 +d9b604e6 : st2g x6, [x7], #-2560 : st2g %x6 %x7 $0xfffffffffffff600 -> (%x7) %x7 +d9b80528 : st2g x8, [x9], #-2048 : st2g %x8 %x9 $0xfffffffffffff800 -> (%x9) %x9 +d9ba0549 : st2g x9, [x10], #-1536 : st2g %x9 %x10 $0xfffffffffffffa00 -> (%x10) %x10 +d9bc058b : st2g x11, [x12], #-1024 : st2g %x11 %x12 $0xfffffffffffffc00 -> (%x12) %x12 +d9be05cd : st2g x13, [x14], #-512 : st2g %x13 %x14 $0xfffffffffffffe00 -> (%x14) %x14 +d9a0060f : st2g x15, [x16], #0 : st2g %x15 %x16 $0x0000000000000000 -> (%x16) %x16 +d9a1f651 : st2g x17, [x18], #496 : st2g %x17 %x18 $0x00000000000001f0 -> (%x18) %x18 +d9a3f693 : st2g x19, [x20], #1008 : st2g %x19 %x20 $0x00000000000003f0 -> (%x20) %x20 +d9a5f6d5 : st2g x21, [x22], #1520 : st2g %x21 %x22 $0x00000000000005f0 -> (%x22) %x22 +d9a7f6f6 : st2g x22, [x23], #2032 : st2g %x22 %x23 $0x00000000000007f0 -> (%x23) %x23 +d9a9f738 : st2g x24, [x25], #2544 : st2g %x24 %x25 $0x00000000000009f0 -> (%x25) %x25 +d9abf77a : st2g x26, [x27], #3056 : st2g %x26 %x27 $0x0000000000000bf0 -> (%x27) %x27 +d9aff7fe : st2g x30, [sp], #4080 : st2g %x30 %sp $0x0000000000000ff0 -> (%sp) %sp + +# ST2G , [, #]! +d9b00c00 : st2g x0, [x0, #-4096]! : st2g %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0) %x0 +d9b20c62 : st2g x2, [x3, #-3584]! : st2g %x2 %x3 $0xfffffffffffff200 -> -0x0e00(%x3) %x3 +d9b40ca4 : st2g x4, [x5, #-3072]! : st2g %x4 %x5 $0xfffffffffffff400 -> -0x0c00(%x5) %x5 +d9b60ce6 : st2g x6, [x7, #-2560]! : st2g %x6 %x7 $0xfffffffffffff600 -> -0x0a00(%x7) %x7 +d9b80d28 : st2g x8, [x9, #-2048]! : st2g %x8 %x9 $0xfffffffffffff800 -> -0x0800(%x9) %x9 +d9ba0d49 : st2g x9, [x10, #-1536]! : st2g %x9 %x10 $0xfffffffffffffa00 -> -0x0600(%x10) %x10 +d9bc0d8b : st2g x11, [x12, #-1024]! : st2g %x11 %x12 $0xfffffffffffffc00 -> -0x0400(%x12) %x12 +d9be0dcd : st2g x13, [x14, #-512]! : st2g %x13 %x14 $0xfffffffffffffe00 -> -0x0200(%x14) %x14 +d9a00e0f : st2g x15, [x16, #0]! : st2g %x15 %x16 $0x0000000000000000 -> (%x16) %x16 +d9a1fe51 : st2g x17, [x18, #496]! : st2g %x17 %x18 $0x00000000000001f0 -> +0x01f0(%x18) %x18 +d9a3fe93 : st2g x19, [x20, #1008]! : st2g %x19 %x20 $0x00000000000003f0 -> +0x03f0(%x20) %x20 +d9a5fed5 : st2g x21, [x22, #1520]! : st2g %x21 %x22 $0x00000000000005f0 -> +0x05f0(%x22) %x22 +d9a7fef6 : st2g x22, [x23, #2032]! : st2g %x22 %x23 $0x00000000000007f0 -> +0x07f0(%x23) %x23 +d9a9ff38 : st2g x24, [x25, #2544]! : st2g %x24 %x25 $0x00000000000009f0 -> +0x09f0(%x25) %x25 +d9abff7a : st2g x26, [x27, #3056]! : st2g %x26 %x27 $0x0000000000000bf0 -> +0x0bf0(%x27) %x27 +d9affffe : st2g x30, [sp, #4080]! : st2g %x30 %sp $0x0000000000000ff0 -> +0x0ff0(%sp) %sp + +# ST2G , [, #] +d9b00800 : st2g x0, [x0, #-4096] : st2g %x0 -> -0x1000(%x0) +d9b20862 : st2g x2, [x3, #-3584] : st2g %x2 -> -0x0e00(%x3) +d9b408a4 : st2g x4, [x5, #-3072] : st2g %x4 -> -0x0c00(%x5) +d9b608e6 : st2g x6, [x7, #-2560] : st2g %x6 -> -0x0a00(%x7) +d9b80928 : st2g x8, [x9, #-2048] : st2g %x8 -> -0x0800(%x9) +d9ba0949 : st2g x9, [x10, #-1536] : st2g %x9 -> -0x0600(%x10) +d9bc098b : st2g x11, [x12, #-1024] : st2g %x11 -> -0x0400(%x12) +d9be09cd : st2g x13, [x14, #-512] : st2g %x13 -> -0x0200(%x14) +d9a00a0f : st2g x15, [x16, #0] : st2g %x15 -> (%x16) +d9a1fa51 : st2g x17, [x18, #496] : st2g %x17 -> +0x01f0(%x18) +d9a3fa93 : st2g x19, [x20, #1008] : st2g %x19 -> +0x03f0(%x20) +d9a5fad5 : st2g x21, [x22, #1520] : st2g %x21 -> +0x05f0(%x22) +d9a7faf6 : st2g x22, [x23, #2032] : st2g %x22 -> +0x07f0(%x23) +d9a9fb38 : st2g x24, [x25, #2544] : st2g %x24 -> +0x09f0(%x25) +d9abfb7a : st2g x26, [x27, #3056] : st2g %x26 -> +0x0bf0(%x27) +d9affbfe : st2g x30, [sp, #4080] : st2g %x30 -> +0x0ff0(%sp) + +# STG , [], # +d9300400 : stg x0, [x0], #-4096 : stg %x0 %x0 $0xfffffffffffff000 -> (%x0) %x0 +d9320462 : stg x2, [x3], #-3584 : stg %x2 %x3 $0xfffffffffffff200 -> (%x3) %x3 +d93404a4 : stg x4, [x5], #-3072 : stg %x4 %x5 $0xfffffffffffff400 -> (%x5) %x5 +d93604e6 : stg x6, [x7], #-2560 : stg %x6 %x7 $0xfffffffffffff600 -> (%x7) %x7 +d9380528 : stg x8, [x9], #-2048 : stg %x8 %x9 $0xfffffffffffff800 -> (%x9) %x9 +d93a0549 : stg x9, [x10], #-1536 : stg %x9 %x10 $0xfffffffffffffa00 -> (%x10) %x10 +d93c058b : stg x11, [x12], #-1024 : stg %x11 %x12 $0xfffffffffffffc00 -> (%x12) %x12 +d93e05cd : stg x13, [x14], #-512 : stg %x13 %x14 $0xfffffffffffffe00 -> (%x14) %x14 +d920060f : stg x15, [x16], #0 : stg %x15 %x16 $0x0000000000000000 -> (%x16) %x16 +d921f651 : stg x17, [x18], #496 : stg %x17 %x18 $0x00000000000001f0 -> (%x18) %x18 +d923f693 : stg x19, [x20], #1008 : stg %x19 %x20 $0x00000000000003f0 -> (%x20) %x20 +d925f6d5 : stg x21, [x22], #1520 : stg %x21 %x22 $0x00000000000005f0 -> (%x22) %x22 +d927f6f6 : stg x22, [x23], #2032 : stg %x22 %x23 $0x00000000000007f0 -> (%x23) %x23 +d929f738 : stg x24, [x25], #2544 : stg %x24 %x25 $0x00000000000009f0 -> (%x25) %x25 +d92bf77a : stg x26, [x27], #3056 : stg %x26 %x27 $0x0000000000000bf0 -> (%x27) %x27 +d92ff7fe : stg x30, [sp], #4080 : stg %x30 %sp $0x0000000000000ff0 -> (%sp) %sp + +# STG , [, #]! +d9300c00 : stg x0, [x0, #-4096]! : stg %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0) %x0 +d9320c62 : stg x2, [x3, #-3584]! : stg %x2 %x3 $0xfffffffffffff200 -> -0x0e00(%x3) %x3 +d9340ca4 : stg x4, [x5, #-3072]! : stg %x4 %x5 $0xfffffffffffff400 -> -0x0c00(%x5) %x5 +d9360ce6 : stg x6, [x7, #-2560]! : stg %x6 %x7 $0xfffffffffffff600 -> -0x0a00(%x7) %x7 +d9380d28 : stg x8, [x9, #-2048]! : stg %x8 %x9 $0xfffffffffffff800 -> -0x0800(%x9) %x9 +d93a0d49 : stg x9, [x10, #-1536]! : stg %x9 %x10 $0xfffffffffffffa00 -> -0x0600(%x10) %x10 +d93c0d8b : stg x11, [x12, #-1024]! : stg %x11 %x12 $0xfffffffffffffc00 -> -0x0400(%x12) %x12 +d93e0dcd : stg x13, [x14, #-512]! : stg %x13 %x14 $0xfffffffffffffe00 -> -0x0200(%x14) %x14 +d9200e0f : stg x15, [x16, #0]! : stg %x15 %x16 $0x0000000000000000 -> (%x16) %x16 +d921fe51 : stg x17, [x18, #496]! : stg %x17 %x18 $0x00000000000001f0 -> +0x01f0(%x18) %x18 +d923fe93 : stg x19, [x20, #1008]! : stg %x19 %x20 $0x00000000000003f0 -> +0x03f0(%x20) %x20 +d925fed5 : stg x21, [x22, #1520]! : stg %x21 %x22 $0x00000000000005f0 -> +0x05f0(%x22) %x22 +d927fef6 : stg x22, [x23, #2032]! : stg %x22 %x23 $0x00000000000007f0 -> +0x07f0(%x23) %x23 +d929ff38 : stg x24, [x25, #2544]! : stg %x24 %x25 $0x00000000000009f0 -> +0x09f0(%x25) %x25 +d92bff7a : stg x26, [x27, #3056]! : stg %x26 %x27 $0x0000000000000bf0 -> +0x0bf0(%x27) %x27 +d92ffffe : stg x30, [sp, #4080]! : stg %x30 %sp $0x0000000000000ff0 -> +0x0ff0(%sp) %sp + +# STG , [, #] +d9300800 : stg x0, [x0, #-4096] : stg %x0 -> -0x1000(%x0) +d9320862 : stg x2, [x3, #-3584] : stg %x2 -> -0x0e00(%x3) +d93408a4 : stg x4, [x5, #-3072] : stg %x4 -> -0x0c00(%x5) +d93608e6 : stg x6, [x7, #-2560] : stg %x6 -> -0x0a00(%x7) +d9380928 : stg x8, [x9, #-2048] : stg %x8 -> -0x0800(%x9) +d93a0949 : stg x9, [x10, #-1536] : stg %x9 -> -0x0600(%x10) +d93c098b : stg x11, [x12, #-1024] : stg %x11 -> -0x0400(%x12) +d93e09cd : stg x13, [x14, #-512] : stg %x13 -> -0x0200(%x14) +d9200a0f : stg x15, [x16, #0] : stg %x15 -> (%x16) +d921fa51 : stg x17, [x18, #496] : stg %x17 -> +0x01f0(%x18) +d923fa93 : stg x19, [x20, #1008] : stg %x19 -> +0x03f0(%x20) +d925fad5 : stg x21, [x22, #1520] : stg %x21 -> +0x05f0(%x22) +d927faf6 : stg x22, [x23, #2032] : stg %x22 -> +0x07f0(%x23) +d929fb38 : stg x24, [x25, #2544] : stg %x24 -> +0x09f0(%x25) +d92bfb7a : stg x26, [x27, #3056] : stg %x26 -> +0x0bf0(%x27) +d92ffbfe : stg x30, [sp, #4080] : stg %x30 -> +0x0ff0(%sp) + +# STGP , , [], # +68a00000 : stgp x0, x0, [x0], #-1024 : stgp %x0 %x0 %x0 $0xfffffffffffffc00 -> (%x0)[16byte] %x0 +68a40c82 : stgp x2, x3, [x4], #-896 : stgp %x2 %x3 %x4 $0xfffffffffffffc80 -> (%x4)[16byte] %x4 +68a814c4 : stgp x4, x5, [x6], #-768 : stgp %x4 %x5 %x6 $0xfffffffffffffd00 -> (%x6)[16byte] %x6 +68ac1d06 : stgp x6, x7, [x8], #-640 : stgp %x6 %x7 %x8 $0xfffffffffffffd80 -> (%x8)[16byte] %x8 +68b02548 : stgp x8, x9, [x10], #-512 : stgp %x8 %x9 %x10 $0xfffffffffffffe00 -> (%x10)[16byte] %x10 +68b42969 : stgp x9, x10, [x11], #-384 : stgp %x9 %x10 %x11 $0xfffffffffffffe80 -> (%x11)[16byte] %x11 +68b831ab : stgp x11, x12, [x13], #-256 : stgp %x11 %x12 %x13 $0xffffffffffffff00 -> (%x13)[16byte] %x13 +68bc39ed : stgp x13, x14, [x15], #-128 : stgp %x13 %x14 %x15 $0xffffffffffffff80 -> (%x15)[16byte] %x15 +6880422f : stgp x15, x16, [x17], #0 : stgp %x15 %x16 %x17 $0x0000000000000000 -> (%x17)[16byte] %x17 +6883ca71 : stgp x17, x18, [x19], #112 : stgp %x17 %x18 %x19 $0x0000000000000070 -> (%x19)[16byte] %x19 +6887d2b3 : stgp x19, x20, [x21], #240 : stgp %x19 %x20 %x21 $0x00000000000000f0 -> (%x21)[16byte] %x21 +688bdaf5 : stgp x21, x22, [x23], #368 : stgp %x21 %x22 %x23 $0x0000000000000170 -> (%x23)[16byte] %x23 +688fdf16 : stgp x22, x23, [x24], #496 : stgp %x22 %x23 %x24 $0x00000000000001f0 -> (%x24)[16byte] %x24 +6893e758 : stgp x24, x25, [x26], #624 : stgp %x24 %x25 %x26 $0x0000000000000270 -> (%x26)[16byte] %x26 +6897ef9a : stgp x26, x27, [x28], #752 : stgp %x26 %x27 %x28 $0x00000000000002f0 -> (%x28)[16byte] %x28 +689ffbfe : stgp x30, x30, [sp], #1008 : stgp %x30 %x30 %sp $0x00000000000003f0 -> (%sp)[16byte] %sp + +# STGP , , [, #]! +69a00000 : stgp x0, x0, [x0, #-1024]! : stgp %x0 %x0 %x0 $0xfffffffffffffc00 -> -0x0400(%x0)[16byte] %x0 +69a40c82 : stgp x2, x3, [x4, #-896]! : stgp %x2 %x3 %x4 $0xfffffffffffffc80 -> -0x0380(%x4)[16byte] %x4 +69a814c4 : stgp x4, x5, [x6, #-768]! : stgp %x4 %x5 %x6 $0xfffffffffffffd00 -> -0x0300(%x6)[16byte] %x6 +69ac1d06 : stgp x6, x7, [x8, #-640]! : stgp %x6 %x7 %x8 $0xfffffffffffffd80 -> -0x0280(%x8)[16byte] %x8 +69b02548 : stgp x8, x9, [x10, #-512]! : stgp %x8 %x9 %x10 $0xfffffffffffffe00 -> -0x0200(%x10)[16byte] %x10 +69b42969 : stgp x9, x10, [x11, #-384]! : stgp %x9 %x10 %x11 $0xfffffffffffffe80 -> -0x0180(%x11)[16byte] %x11 +69b831ab : stgp x11, x12, [x13, #-256]! : stgp %x11 %x12 %x13 $0xffffffffffffff00 -> -0x0100(%x13)[16byte] %x13 +69bc39ed : stgp x13, x14, [x15, #-128]! : stgp %x13 %x14 %x15 $0xffffffffffffff80 -> -0x80(%x15)[16byte] %x15 +6980422f : stgp x15, x16, [x17, #0]! : stgp %x15 %x16 %x17 $0x0000000000000000 -> (%x17)[16byte] %x17 +6983ca71 : stgp x17, x18, [x19, #112]! : stgp %x17 %x18 %x19 $0x0000000000000070 -> +0x70(%x19)[16byte] %x19 +6987d2b3 : stgp x19, x20, [x21, #240]! : stgp %x19 %x20 %x21 $0x00000000000000f0 -> +0xf0(%x21)[16byte] %x21 +698bdaf5 : stgp x21, x22, [x23, #368]! : stgp %x21 %x22 %x23 $0x0000000000000170 -> +0x0170(%x23)[16byte] %x23 +698fdf16 : stgp x22, x23, [x24, #496]! : stgp %x22 %x23 %x24 $0x00000000000001f0 -> +0x01f0(%x24)[16byte] %x24 +6993e758 : stgp x24, x25, [x26, #624]! : stgp %x24 %x25 %x26 $0x0000000000000270 -> +0x0270(%x26)[16byte] %x26 +6997ef9a : stgp x26, x27, [x28, #752]! : stgp %x26 %x27 %x28 $0x00000000000002f0 -> +0x02f0(%x28)[16byte] %x28 +699ffbfe : stgp x30, x30, [sp, #1008]! : stgp %x30 %x30 %sp $0x00000000000003f0 -> +0x03f0(%sp)[16byte] %sp + +# STGP , , [, #] +69200000 : stgp x0, x0, [x0, #-1024] : stgp %x0 %x0 -> -0x0400(%x0)[16byte] +69240c82 : stgp x2, x3, [x4, #-896] : stgp %x2 %x3 -> -0x0380(%x4)[16byte] +692814c4 : stgp x4, x5, [x6, #-768] : stgp %x4 %x5 -> -0x0300(%x6)[16byte] +692c1d06 : stgp x6, x7, [x8, #-640] : stgp %x6 %x7 -> -0x0280(%x8)[16byte] +69302548 : stgp x8, x9, [x10, #-512] : stgp %x8 %x9 -> -0x0200(%x10)[16byte] +69342969 : stgp x9, x10, [x11, #-384] : stgp %x9 %x10 -> -0x0180(%x11)[16byte] +693831ab : stgp x11, x12, [x13, #-256] : stgp %x11 %x12 -> -0x0100(%x13)[16byte] +693c39ed : stgp x13, x14, [x15, #-128] : stgp %x13 %x14 -> -0x80(%x15)[16byte] +6900422f : stgp x15, x16, [x17, #0] : stgp %x15 %x16 -> (%x17)[16byte] +6903ca71 : stgp x17, x18, [x19, #112] : stgp %x17 %x18 -> +0x70(%x19)[16byte] +6907d2b3 : stgp x19, x20, [x21, #240] : stgp %x19 %x20 -> +0xf0(%x21)[16byte] +690bdaf5 : stgp x21, x22, [x23, #368] : stgp %x21 %x22 -> +0x0170(%x23)[16byte] +690fdf16 : stgp x22, x23, [x24, #496] : stgp %x22 %x23 -> +0x01f0(%x24)[16byte] +6913e758 : stgp x24, x25, [x26, #624] : stgp %x24 %x25 -> +0x0270(%x26)[16byte] +6917ef9a : stgp x26, x27, [x28, #752] : stgp %x26 %x27 -> +0x02f0(%x28)[16byte] +691ffbfe : stgp x30, x30, [sp, #1008] : stgp %x30 %x30 -> +0x03f0(%sp)[16byte] + +# STZ2G , [], # +d9f00400 : stz2g x0, [x0], #-4096 : stz2g %x0 %x0 $0xfffffffffffff000 -> (%x0)[32byte] %x0 +d9f20462 : stz2g x2, [x3], #-3584 : stz2g %x2 %x3 $0xfffffffffffff200 -> (%x3)[32byte] %x3 +d9f404a4 : stz2g x4, [x5], #-3072 : stz2g %x4 %x5 $0xfffffffffffff400 -> (%x5)[32byte] %x5 +d9f604e6 : stz2g x6, [x7], #-2560 : stz2g %x6 %x7 $0xfffffffffffff600 -> (%x7)[32byte] %x7 +d9f80528 : stz2g x8, [x9], #-2048 : stz2g %x8 %x9 $0xfffffffffffff800 -> (%x9)[32byte] %x9 +d9fa0549 : stz2g x9, [x10], #-1536 : stz2g %x9 %x10 $0xfffffffffffffa00 -> (%x10)[32byte] %x10 +d9fc058b : stz2g x11, [x12], #-1024 : stz2g %x11 %x12 $0xfffffffffffffc00 -> (%x12)[32byte] %x12 +d9fe05cd : stz2g x13, [x14], #-512 : stz2g %x13 %x14 $0xfffffffffffffe00 -> (%x14)[32byte] %x14 +d9e0060f : stz2g x15, [x16], #0 : stz2g %x15 %x16 $0x0000000000000000 -> (%x16)[32byte] %x16 +d9e1f651 : stz2g x17, [x18], #496 : stz2g %x17 %x18 $0x00000000000001f0 -> (%x18)[32byte] %x18 +d9e3f693 : stz2g x19, [x20], #1008 : stz2g %x19 %x20 $0x00000000000003f0 -> (%x20)[32byte] %x20 +d9e5f6d5 : stz2g x21, [x22], #1520 : stz2g %x21 %x22 $0x00000000000005f0 -> (%x22)[32byte] %x22 +d9e7f6f6 : stz2g x22, [x23], #2032 : stz2g %x22 %x23 $0x00000000000007f0 -> (%x23)[32byte] %x23 +d9e9f738 : stz2g x24, [x25], #2544 : stz2g %x24 %x25 $0x00000000000009f0 -> (%x25)[32byte] %x25 +d9ebf77a : stz2g x26, [x27], #3056 : stz2g %x26 %x27 $0x0000000000000bf0 -> (%x27)[32byte] %x27 +d9eff7fe : stz2g x30, [sp], #4080 : stz2g %x30 %sp $0x0000000000000ff0 -> (%sp)[32byte] %sp + +# STZ2G , [, #]! +d9f00c00 : stz2g x0, [x0, #-4096]! : stz2g %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0)[32byte] %x0 +d9f20c62 : stz2g x2, [x3, #-3584]! : stz2g %x2 %x3 $0xfffffffffffff200 -> -0x0e00(%x3)[32byte] %x3 +d9f40ca4 : stz2g x4, [x5, #-3072]! : stz2g %x4 %x5 $0xfffffffffffff400 -> -0x0c00(%x5)[32byte] %x5 +d9f60ce6 : stz2g x6, [x7, #-2560]! : stz2g %x6 %x7 $0xfffffffffffff600 -> -0x0a00(%x7)[32byte] %x7 +d9f80d28 : stz2g x8, [x9, #-2048]! : stz2g %x8 %x9 $0xfffffffffffff800 -> -0x0800(%x9)[32byte] %x9 +d9fa0d49 : stz2g x9, [x10, #-1536]! : stz2g %x9 %x10 $0xfffffffffffffa00 -> -0x0600(%x10)[32byte] %x10 +d9fc0d8b : stz2g x11, [x12, #-1024]! : stz2g %x11 %x12 $0xfffffffffffffc00 -> -0x0400(%x12)[32byte] %x12 +d9fe0dcd : stz2g x13, [x14, #-512]! : stz2g %x13 %x14 $0xfffffffffffffe00 -> -0x0200(%x14)[32byte] %x14 +d9e00e0f : stz2g x15, [x16, #0]! : stz2g %x15 %x16 $0x0000000000000000 -> (%x16)[32byte] %x16 +d9e1fe51 : stz2g x17, [x18, #496]! : stz2g %x17 %x18 $0x00000000000001f0 -> +0x01f0(%x18)[32byte] %x18 +d9e3fe93 : stz2g x19, [x20, #1008]! : stz2g %x19 %x20 $0x00000000000003f0 -> +0x03f0(%x20)[32byte] %x20 +d9e5fed5 : stz2g x21, [x22, #1520]! : stz2g %x21 %x22 $0x00000000000005f0 -> +0x05f0(%x22)[32byte] %x22 +d9e7fef6 : stz2g x22, [x23, #2032]! : stz2g %x22 %x23 $0x00000000000007f0 -> +0x07f0(%x23)[32byte] %x23 +d9e9ff38 : stz2g x24, [x25, #2544]! : stz2g %x24 %x25 $0x00000000000009f0 -> +0x09f0(%x25)[32byte] %x25 +d9ebff7a : stz2g x26, [x27, #3056]! : stz2g %x26 %x27 $0x0000000000000bf0 -> +0x0bf0(%x27)[32byte] %x27 +d9effffe : stz2g x30, [sp, #4080]! : stz2g %x30 %sp $0x0000000000000ff0 -> +0x0ff0(%sp)[32byte] %sp + +# STZ2G , [, #] +d9f00800 : stz2g x0, [x0, #-4096] : stz2g %x0 -> -0x1000(%x0)[32byte] +d9f20862 : stz2g x2, [x3, #-3584] : stz2g %x2 -> -0x0e00(%x3)[32byte] +d9f408a4 : stz2g x4, [x5, #-3072] : stz2g %x4 -> -0x0c00(%x5)[32byte] +d9f608e6 : stz2g x6, [x7, #-2560] : stz2g %x6 -> -0x0a00(%x7)[32byte] +d9f80928 : stz2g x8, [x9, #-2048] : stz2g %x8 -> -0x0800(%x9)[32byte] +d9fa0949 : stz2g x9, [x10, #-1536] : stz2g %x9 -> -0x0600(%x10)[32byte] +d9fc098b : stz2g x11, [x12, #-1024] : stz2g %x11 -> -0x0400(%x12)[32byte] +d9fe09cd : stz2g x13, [x14, #-512] : stz2g %x13 -> -0x0200(%x14)[32byte] +d9e00a0f : stz2g x15, [x16, #0] : stz2g %x15 -> (%x16)[32byte] +d9e1fa51 : stz2g x17, [x18, #496] : stz2g %x17 -> +0x01f0(%x18)[32byte] +d9e3fa93 : stz2g x19, [x20, #1008] : stz2g %x19 -> +0x03f0(%x20)[32byte] +d9e5fad5 : stz2g x21, [x22, #1520] : stz2g %x21 -> +0x05f0(%x22)[32byte] +d9e7faf6 : stz2g x22, [x23, #2032] : stz2g %x22 -> +0x07f0(%x23)[32byte] +d9e9fb38 : stz2g x24, [x25, #2544] : stz2g %x24 -> +0x09f0(%x25)[32byte] +d9ebfb7a : stz2g x26, [x27, #3056] : stz2g %x26 -> +0x0bf0(%x27)[32byte] +d9effbfe : stz2g x30, [sp, #4080] : stz2g %x30 -> +0x0ff0(%sp)[32byte] + +# STZG , [], # +d9700400 : stzg x0, [x0], #-4096 : stzg %x0 %x0 $0xfffffffffffff000 -> (%x0)[16byte] %x0 +d9720462 : stzg x2, [x3], #-3584 : stzg %x2 %x3 $0xfffffffffffff200 -> (%x3)[16byte] %x3 +d97404a4 : stzg x4, [x5], #-3072 : stzg %x4 %x5 $0xfffffffffffff400 -> (%x5)[16byte] %x5 +d97604e6 : stzg x6, [x7], #-2560 : stzg %x6 %x7 $0xfffffffffffff600 -> (%x7)[16byte] %x7 +d9780528 : stzg x8, [x9], #-2048 : stzg %x8 %x9 $0xfffffffffffff800 -> (%x9)[16byte] %x9 +d97a0549 : stzg x9, [x10], #-1536 : stzg %x9 %x10 $0xfffffffffffffa00 -> (%x10)[16byte] %x10 +d97c058b : stzg x11, [x12], #-1024 : stzg %x11 %x12 $0xfffffffffffffc00 -> (%x12)[16byte] %x12 +d97e05cd : stzg x13, [x14], #-512 : stzg %x13 %x14 $0xfffffffffffffe00 -> (%x14)[16byte] %x14 +d960060f : stzg x15, [x16], #0 : stzg %x15 %x16 $0x0000000000000000 -> (%x16)[16byte] %x16 +d961f651 : stzg x17, [x18], #496 : stzg %x17 %x18 $0x00000000000001f0 -> (%x18)[16byte] %x18 +d963f693 : stzg x19, [x20], #1008 : stzg %x19 %x20 $0x00000000000003f0 -> (%x20)[16byte] %x20 +d965f6d5 : stzg x21, [x22], #1520 : stzg %x21 %x22 $0x00000000000005f0 -> (%x22)[16byte] %x22 +d967f6f6 : stzg x22, [x23], #2032 : stzg %x22 %x23 $0x00000000000007f0 -> (%x23)[16byte] %x23 +d969f738 : stzg x24, [x25], #2544 : stzg %x24 %x25 $0x00000000000009f0 -> (%x25)[16byte] %x25 +d96bf77a : stzg x26, [x27], #3056 : stzg %x26 %x27 $0x0000000000000bf0 -> (%x27)[16byte] %x27 +d96ff7fe : stzg x30, [sp], #4080 : stzg %x30 %sp $0x0000000000000ff0 -> (%sp)[16byte] %sp + +# STZG , [, #]! +d9700c00 : stzg x0, [x0, #-4096]! : stzg %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0)[16byte] %x0 +d9720c62 : stzg x2, [x3, #-3584]! : stzg %x2 %x3 $0xfffffffffffff200 -> -0x0e00(%x3)[16byte] %x3 +d9740ca4 : stzg x4, [x5, #-3072]! : stzg %x4 %x5 $0xfffffffffffff400 -> -0x0c00(%x5)[16byte] %x5 +d9760ce6 : stzg x6, [x7, #-2560]! : stzg %x6 %x7 $0xfffffffffffff600 -> -0x0a00(%x7)[16byte] %x7 +d9780d28 : stzg x8, [x9, #-2048]! : stzg %x8 %x9 $0xfffffffffffff800 -> -0x0800(%x9)[16byte] %x9 +d97a0d49 : stzg x9, [x10, #-1536]! : stzg %x9 %x10 $0xfffffffffffffa00 -> -0x0600(%x10)[16byte] %x10 +d97c0d8b : stzg x11, [x12, #-1024]! : stzg %x11 %x12 $0xfffffffffffffc00 -> -0x0400(%x12)[16byte] %x12 +d97e0dcd : stzg x13, [x14, #-512]! : stzg %x13 %x14 $0xfffffffffffffe00 -> -0x0200(%x14)[16byte] %x14 +d9600e0f : stzg x15, [x16, #0]! : stzg %x15 %x16 $0x0000000000000000 -> (%x16)[16byte] %x16 +d961fe51 : stzg x17, [x18, #496]! : stzg %x17 %x18 $0x00000000000001f0 -> +0x01f0(%x18)[16byte] %x18 +d963fe93 : stzg x19, [x20, #1008]! : stzg %x19 %x20 $0x00000000000003f0 -> +0x03f0(%x20)[16byte] %x20 +d965fed5 : stzg x21, [x22, #1520]! : stzg %x21 %x22 $0x00000000000005f0 -> +0x05f0(%x22)[16byte] %x22 +d967fef6 : stzg x22, [x23, #2032]! : stzg %x22 %x23 $0x00000000000007f0 -> +0x07f0(%x23)[16byte] %x23 +d969ff38 : stzg x24, [x25, #2544]! : stzg %x24 %x25 $0x00000000000009f0 -> +0x09f0(%x25)[16byte] %x25 +d96bff7a : stzg x26, [x27, #3056]! : stzg %x26 %x27 $0x0000000000000bf0 -> +0x0bf0(%x27)[16byte] %x27 +d96ffffe : stzg x30, [sp, #4080]! : stzg %x30 %sp $0x0000000000000ff0 -> +0x0ff0(%sp)[16byte] %sp + +# STZG , [, #] +d9700800 : stzg x0, [x0, #-4096] : stzg %x0 -> -0x1000(%x0)[16byte] +d9720862 : stzg x2, [x3, #-3584] : stzg %x2 -> -0x0e00(%x3)[16byte] +d97408a4 : stzg x4, [x5, #-3072] : stzg %x4 -> -0x0c00(%x5)[16byte] +d97608e6 : stzg x6, [x7, #-2560] : stzg %x6 -> -0x0a00(%x7)[16byte] +d9780928 : stzg x8, [x9, #-2048] : stzg %x8 -> -0x0800(%x9)[16byte] +d97a0949 : stzg x9, [x10, #-1536] : stzg %x9 -> -0x0600(%x10)[16byte] +d97c098b : stzg x11, [x12, #-1024] : stzg %x11 -> -0x0400(%x12)[16byte] +d97e09cd : stzg x13, [x14, #-512] : stzg %x13 -> -0x0200(%x14)[16byte] +d9600a0f : stzg x15, [x16, #0] : stzg %x15 -> (%x16)[16byte] +d961fa51 : stzg x17, [x18, #496] : stzg %x17 -> +0x01f0(%x18)[16byte] +d963fa93 : stzg x19, [x20, #1008] : stzg %x19 -> +0x03f0(%x20)[16byte] +d965fad5 : stzg x21, [x22, #1520] : stzg %x21 -> +0x05f0(%x22)[16byte] +d967faf6 : stzg x22, [x23, #2032] : stzg %x22 -> +0x07f0(%x23)[16byte] +d969fb38 : stzg x24, [x25, #2544] : stzg %x24 -> +0x09f0(%x25)[16byte] +d96bfb7a : stzg x26, [x27, #3056] : stzg %x26 -> +0x0bf0(%x27)[16byte] +d96ffbfe : stzg x30, [sp, #4080] : stzg %x30 -> +0x0ff0(%sp)[16byte] + # SUDOT ., ., .4B[] (SUDOT-Q.QQi-asimdelem_L) 0f00f000 : sudot v0.2s, v0.8b, v0.4b[0] : sudot %d0 %d0 %q0 $0x00 $0x00 -> %d0 0f04f062 : sudot v2.2s, v3.8b, v4.4b[0] : sudot %d2 %d3 %q4 $0x00 $0x00 -> %d2 diff --git a/suite/tests/api/ir_aarch64.h b/suite/tests/api/ir_aarch64.h index 899a2dcb0b8..5f9369a551d 100644 --- a/suite/tests/api/ir_aarch64.h +++ b/suite/tests/api/ir_aarch64.h @@ -153,10 +153,12 @@ const reg_id_t Pn_six_offset_2[6] = { DR_REG_P0, DR_REG_P4, DR_REG_P7, DR_REG_P10, DR_REG_P12, DR_REG_P15 }; const reg_id_t Xn_six_offset_1_zr[6] = { DR_REG_X0, DR_REG_X6, DR_REG_X11, DR_REG_X16, DR_REG_X21, DR_REG_XZR }; +const reg_id_t Xn_six_offset_0_sp[6] = { DR_REG_X0, DR_REG_X5, DR_REG_X10, + DR_REG_X15, DR_REG_X20, DR_REG_XSP }; const reg_id_t Xn_six_offset_1_sp[6] = { DR_REG_X0, DR_REG_X6, DR_REG_X11, DR_REG_X16, DR_REG_X21, DR_REG_XSP }; const reg_id_t Xn_six_offset_2_sp[6] = { DR_REG_X0, DR_REG_X7, DR_REG_X12, - DR_REG_X17, DR_REG_X22, DR_REG_SP }; + DR_REG_X17, DR_REG_X22, DR_REG_XSP }; const reg_id_t Wn_six_offset_0[6] = { DR_REG_W0, DR_REG_W5, DR_REG_W10, DR_REG_W15, DR_REG_W20, DR_REG_W30 }; const reg_id_t Wn_six_offset_1[6] = { DR_REG_W0, DR_REG_W6, DR_REG_W11, diff --git a/suite/tests/api/ir_aarch64_v86.c b/suite/tests/api/ir_aarch64_v86.c index 48cabe77a4e..165b794013d 100644 --- a/suite/tests/api/ir_aarch64_v86.c +++ b/suite/tests/api/ir_aarch64_v86.c @@ -347,6 +347,239 @@ TEST_INSTR(usdot_vector_idx) opnd_create_immed_uint(index_0_0[i], OPSZ_2b)); } +TEST_INSTR(ldg) +{ + /* Testing LDG , [, #] */ + static const int imm9[6] = { -4096, -2704, -1344, 32, 1392, 4080 }; + const char *const expected[6] = { + "ldg %x0 -0x1000(%x0) -> %x0", "ldg %x5 -0x0a90(%x6) -> %x5", + "ldg %x10 -0x0540(%x11) -> %x10", "ldg %x15 +0x20(%x16) -> %x15", + "ldg %x20 +0x0570(%x21) -> %x20", "ldg %x30 +0x0ff0(%sp) -> %x30", + }; + TEST_LOOP(ldg, ldg, 6, expected[i], opnd_create_reg(Xn_six_offset_0[i]), + opnd_create_base_disp_aarch64(Xn_six_offset_1_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm9[i], 0, OPSZ_0)); +} + +TEST_INSTR(st2g) +{ + /* Testing ST2G , [], # */ + static const int imm9[6] = { -4096, -2704, -1344, 32, 1392, 4080 }; + const char *const expected_0[6] = { + "st2g %x0 %x0 $0xfffffffffffff000 -> (%x0) %x0", + "st2g %x6 %x5 $0xfffffffffffff570 -> (%x5) %x5", + "st2g %x11 %x10 $0xfffffffffffffac0 -> (%x10) %x10", + "st2g %x16 %x15 $0x0000000000000020 -> (%x15) %x15", + "st2g %x21 %x20 $0x0000000000000570 -> (%x20) %x20", + "st2g %sp %sp $0x0000000000000ff0 -> (%sp) %sp", + }; + TEST_LOOP(st2g, st2g_post, 6, expected_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, 0, 0, OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i]), OPND_CREATE_INT(imm9[i])); + + /* Testing ST2G , [, #]! */ + const char *const expected_1[6] = { + "st2g %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0) %x0", + "st2g %x6 %x5 $0xfffffffffffff570 -> -0x0a90(%x5) %x5", + "st2g %x11 %x10 $0xfffffffffffffac0 -> -0x0540(%x10) %x10", + "st2g %x16 %x15 $0x0000000000000020 -> +0x20(%x15) %x15", + "st2g %x21 %x20 $0x0000000000000570 -> +0x0570(%x20) %x20", + "st2g %sp %sp $0x0000000000000ff0 -> +0x0ff0(%sp) %sp", + }; + TEST_LOOP( + st2g, st2g_pre, 6, expected_1[i], + opnd_create_base_disp(Xn_six_offset_0_sp[i], DR_REG_NULL, 0, imm9[i], OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i])); + + // /* Testing ST2G , [, #] */ + const char *const expected_2[6] = { + "st2g %x0 -> -0x1000(%x0)", "st2g %x6 -> -0x0a90(%x5)", + "st2g %x11 -> -0x0540(%x10)", "st2g %x16 -> +0x20(%x15)", + "st2g %x21 -> +0x0570(%x20)", "st2g %sp -> +0x0ff0(%sp)", + }; + TEST_LOOP(st2g, st2g_offset, 6, expected_2[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm9[i], 0, OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i])); +} + +TEST_INSTR(stg) +{ + /* Testing STG , [], # */ + static const int imm9[6] = { -4096, -2704, -1344, 32, 1392, 4080 }; + const char *const expected_0[6] = { + "stg %x0 %x0 $0xfffffffffffff000 -> (%x0) %x0", + "stg %x6 %x5 $0xfffffffffffff570 -> (%x5) %x5", + "stg %x11 %x10 $0xfffffffffffffac0 -> (%x10) %x10", + "stg %x16 %x15 $0x0000000000000020 -> (%x15) %x15", + "stg %x21 %x20 $0x0000000000000570 -> (%x20) %x20", + "stg %sp %sp $0x0000000000000ff0 -> (%sp) %sp", + }; + TEST_LOOP(stg, stg_post, 6, expected_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, 0, 0, OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i]), OPND_CREATE_INT(imm9[i])); + + /* Testing STG , [, #]! */ + const char *const expected_1[6] = { + "stg %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0) %x0", + "stg %x6 %x5 $0xfffffffffffff570 -> -0x0a90(%x5) %x5", + "stg %x11 %x10 $0xfffffffffffffac0 -> -0x0540(%x10) %x10", + "stg %x16 %x15 $0x0000000000000020 -> +0x20(%x15) %x15", + "stg %x21 %x20 $0x0000000000000570 -> +0x0570(%x20) %x20", + "stg %sp %sp $0x0000000000000ff0 -> +0x0ff0(%sp) %sp", + }; + TEST_LOOP( + stg, stg_pre, 6, expected_1[i], + opnd_create_base_disp(Xn_six_offset_0_sp[i], DR_REG_NULL, 0, imm9[i], OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i])); + + /* Testing STG , [, #] */ + const char *const expected_2[6] = { + "stg %x0 -> -0x1000(%x0)", "stg %x6 -> -0x0a90(%x5)", + "stg %x11 -> -0x0540(%x10)", "stg %x16 -> +0x20(%x15)", + "stg %x21 -> +0x0570(%x20)", "stg %sp -> +0x0ff0(%sp)", + }; + TEST_LOOP(stg, stg_offset, 6, expected_2[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm9[i], 0, OPSZ_0), + opnd_create_reg(Xn_six_offset_1_sp[i])); +} + +TEST_INSTR(stz2g) +{ + /* Testing STZ2G , [], # */ + static const int imm9[6] = { -4096, -2704, -1344, 32, 1392, 4080 }; + const char *const expected_0[6] = { + "stz2g %x0 %x0 $0xfffffffffffff000 -> (%x0)[32byte] %x0", + "stz2g %x6 %x5 $0xfffffffffffff570 -> (%x5)[32byte] %x5", + "stz2g %x11 %x10 $0xfffffffffffffac0 -> (%x10)[32byte] %x10", + "stz2g %x16 %x15 $0x0000000000000020 -> (%x15)[32byte] %x15", + "stz2g %x21 %x20 $0x0000000000000570 -> (%x20)[32byte] %x20", + "stz2g %sp %sp $0x0000000000000ff0 -> (%sp)[32byte] %sp", + }; + TEST_LOOP(stz2g, stz2g_post, 6, expected_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, 0, 0, OPSZ_32), + opnd_create_reg(Xn_six_offset_1_sp[i]), OPND_CREATE_INT(imm9[i])); + + /* Testing STZ2G , [, #]! */ + const char *const expected_1[6] = { + "stz2g %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0)[32byte] %x0", + "stz2g %x6 %x5 $0xfffffffffffff570 -> -0x0a90(%x5)[32byte] %x5", + "stz2g %x11 %x10 $0xfffffffffffffac0 -> -0x0540(%x10)[32byte] %x10", + "stz2g %x16 %x15 $0x0000000000000020 -> +0x20(%x15)[32byte] %x15", + "stz2g %x21 %x20 $0x0000000000000570 -> +0x0570(%x20)[32byte] %x20", + "stz2g %sp %sp $0x0000000000000ff0 -> +0x0ff0(%sp)[32byte] %sp", + }; + TEST_LOOP( + stz2g, stz2g_pre, 6, expected_1[i], + opnd_create_base_disp(Xn_six_offset_0_sp[i], DR_REG_NULL, 0, imm9[i], OPSZ_32), + opnd_create_reg(Xn_six_offset_1_sp[i])); + + /* Testing STZ2G , [, #] */ + const char *const expected_2[6] = { + "stz2g %x0 -> -0x1000(%x0)[32byte]", "stz2g %x6 -> -0x0a90(%x5)[32byte]", + "stz2g %x11 -> -0x0540(%x10)[32byte]", "stz2g %x16 -> +0x20(%x15)[32byte]", + "stz2g %x21 -> +0x0570(%x20)[32byte]", "stz2g %sp -> +0x0ff0(%sp)[32byte]", + }; + TEST_LOOP(stz2g, stz2g_offset, 6, expected_2[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm9[i], 0, OPSZ_32), + opnd_create_reg(Xn_six_offset_1_sp[i])); +} + +TEST_INSTR(stzg) +{ + /* Testing STZG , [], # */ + static const int imm9[6] = { -4096, -2704, -1344, 32, 1392, 4080 }; + const char *const expected_0[6] = { + "stzg %x0 %x0 $0xfffffffffffff000 -> (%x0)[16byte] %x0", + "stzg %x6 %x5 $0xfffffffffffff570 -> (%x5)[16byte] %x5", + "stzg %x11 %x10 $0xfffffffffffffac0 -> (%x10)[16byte] %x10", + "stzg %x16 %x15 $0x0000000000000020 -> (%x15)[16byte] %x15", + "stzg %x21 %x20 $0x0000000000000570 -> (%x20)[16byte] %x20", + "stzg %sp %sp $0x0000000000000ff0 -> (%sp)[16byte] %sp", + }; + TEST_LOOP(stzg, stzg_post, 6, expected_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, 0, 0, OPSZ_16), + opnd_create_reg(Xn_six_offset_1_sp[i]), OPND_CREATE_INT(imm9[i])); + + /* Testing STZG , [, #]! */ + const char *const expected_1[6] = { + "stzg %x0 %x0 $0xfffffffffffff000 -> -0x1000(%x0)[16byte] %x0", + "stzg %x6 %x5 $0xfffffffffffff570 -> -0x0a90(%x5)[16byte] %x5", + "stzg %x11 %x10 $0xfffffffffffffac0 -> -0x0540(%x10)[16byte] %x10", + "stzg %x16 %x15 $0x0000000000000020 -> +0x20(%x15)[16byte] %x15", + "stzg %x21 %x20 $0x0000000000000570 -> +0x0570(%x20)[16byte] %x20", + "stzg %sp %sp $0x0000000000000ff0 -> +0x0ff0(%sp)[16byte] %sp", + }; + TEST_LOOP( + stzg, stzg_pre, 6, expected_1[i], + opnd_create_base_disp(Xn_six_offset_0_sp[i], DR_REG_NULL, 0, imm9[i], OPSZ_16), + opnd_create_reg(Xn_six_offset_1_sp[i])); + + /* Testing STZG , [, #] */ + const char *const expected_2[6] = { + "stzg %x0 -> -0x1000(%x0)[16byte]", "stzg %x6 -> -0x0a90(%x5)[16byte]", + "stzg %x11 -> -0x0540(%x10)[16byte]", "stzg %x16 -> +0x20(%x15)[16byte]", + "stzg %x21 -> +0x0570(%x20)[16byte]", "stzg %sp -> +0x0ff0(%sp)[16byte]", + }; + TEST_LOOP(stzg, stzg_offset, 6, expected_2[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm9[i], 0, OPSZ_16), + opnd_create_reg(Xn_six_offset_1_sp[i])); +} + +TEST_INSTR(stgp) +{ + /* Testing STGP , , [], # */ + static const int imm7[6] = { -1024, -640, -304, 48, 384, 1008 }; + const char *const expected_0_0[6] = { + "stgp %x0 %x0 %x0 $0xfffffffffffffc00 -> (%x0)[16byte] %x0", + "stgp %x6 %x7 %x5 $0xfffffffffffffd80 -> (%x5)[16byte] %x5", + "stgp %x11 %x12 %x10 $0xfffffffffffffed0 -> (%x10)[16byte] %x10", + "stgp %x16 %x17 %x15 $0x0000000000000030 -> (%x15)[16byte] %x15", + "stgp %x21 %x22 %x20 $0x0000000000000180 -> (%x20)[16byte] %x20", + "stgp %x30 %x30 %sp $0x00000000000003f0 -> (%sp)[16byte] %sp", + }; + TEST_LOOP(stgp, stgp_post, 6, expected_0_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_0_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, 0, 0, OPSZ_16), + opnd_create_reg(Xn_six_offset_1[i]), opnd_create_reg(Xn_six_offset_2[i]), + OPND_CREATE_INT(imm7[i])); + + /* Testing STGP , , [, #]! */ + const char *const expected_1_0[6] = { + "stgp %x0 %x0 %x0 $0xfffffffffffffc00 -> -0x0400(%x0)[16byte] %x0", + "stgp %x6 %x7 %x5 $0xfffffffffffffd80 -> -0x0280(%x5)[16byte] %x5", + "stgp %x11 %x12 %x10 $0xfffffffffffffed0 -> -0x0130(%x10)[16byte] %x10", + "stgp %x16 %x17 %x15 $0x0000000000000030 -> +0x30(%x15)[16byte] %x15", + "stgp %x21 %x22 %x20 $0x0000000000000180 -> +0x0180(%x20)[16byte] %x20", + "stgp %x30 %x30 %sp $0x00000000000003f0 -> +0x03f0(%sp)[16byte] %sp", + }; + TEST_LOOP( + stgp, stgp_pre, 6, expected_1_0[i], + opnd_create_base_disp(Xn_six_offset_0_sp[i], DR_REG_NULL, 0, imm7[i], OPSZ_16), + opnd_create_reg(Xn_six_offset_1[i]), opnd_create_reg(Xn_six_offset_2[i])); + + /* Testing STGP , , [, #] */ + const char *const expected_2_0[6] = { + "stgp %x0 %x0 -> -0x0400(%x0)[16byte]", + "stgp %x5 %x6 -> -0x0280(%x7)[16byte]", + "stgp %x10 %x11 -> -0x0130(%x12)[16byte]", + "stgp %x15 %x16 -> +0x30(%x17)[16byte]", + "stgp %x20 %x21 -> +0x0180(%x22)[16byte]", + "stgp %x30 %x30 -> +0x03f0(%sp)[16byte]", + }; + TEST_LOOP(stgp, stgp_offset, 6, expected_2_0[i], + opnd_create_base_disp_aarch64(Xn_six_offset_2_sp[i], DR_REG_NULL, + DR_EXTEND_UXTX, 0, imm7[i], 0, OPSZ_16), + opnd_create_reg(Xn_six_offset_0[i]), opnd_create_reg(Xn_six_offset_1[i])); +} + int main(int argc, char *argv[]) { @@ -377,6 +610,13 @@ main(int argc, char *argv[]) RUN_INSTR_TEST(usdot_vector); RUN_INSTR_TEST(usdot_vector_idx); + RUN_INSTR_TEST(ldg); + RUN_INSTR_TEST(st2g); + RUN_INSTR_TEST(stg); + RUN_INSTR_TEST(stz2g); + RUN_INSTR_TEST(stzg); + RUN_INSTR_TEST(stgp); + print("All v8.6 tests complete.\n"); #ifndef STANDALONE_DECODER dr_standalone_exit();