From 14bfb4bb15dc9dce0816ed78a177566ba73d4034 Mon Sep 17 00:00:00 2001 From: Yury Khrustalev Date: Fri, 23 Oct 2020 15:10:53 +0100 Subject: [PATCH 01/10] i#2440: Macros for creating conditional instructions Add macros to create conditional instructions Add functions conidtional predicate operands Add tests to verify the added functiononality --- core/ir/aarch64/instr_create.h | 131 ++++++ core/ir/opnd.h | 28 ++ core/ir/opnd_shared.c | 96 +++- suite/tests/api/dis-a64.txt | 731 ++++++++++++++++++++++++++++++ suite/tests/api/ir_aarch64.c | 685 ++++++++++++++++++++++++++++ suite/tests/api/ir_aarch64.expect | 13 + 6 files changed, 1683 insertions(+), 1 deletion(-) diff --git a/core/ir/aarch64/instr_create.h b/core/ir/aarch64/instr_create.h index c3f4226fee6..2244abecbf4 100644 --- a/core/ir/aarch64/instr_create.h +++ b/core/ir/aarch64/instr_create.h @@ -2565,5 +2565,136 @@ enum { */ #define INSTR_CREATE_fmov_scalar_imm(dc, Rd, f) instr_create_1dst_1src(dc, OP_fmov, Rd, f) +/** + * Creates a CCMN (Conditional Compare Negative) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rn The source register. + * \param Op Either a 5-bit immediate (use opnd_create_immed_uint(val, OPSZ_5b) + * to create the operand) or a source register. + * \param nzcv The 4 bit flag bit specifier + * (use opnd_create_immed_uint(val, OPSZ_4b) to create the operand). + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_ccmn(dc, Rn, Op, nzcv, cond) \ + instr_create_0dst_4src(dc, OP_ccmn, Rn, Op, nzcv, cond) + +/** + * Creates a CCMP (Conditional Compare) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rn The source register. + * \param Op Either a 5-bit immediate (use opnd_create_immed_uint(val, OPSZ_5b) + * to create the operand) or a source register. + * \param nzcv The 4 bit flag bit specifier + * (use opnd_create_immed_uint(val, OPSZ_4b) to create the operand). + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_ccmp(dc, Rn, Op, nzcv, cond) \ + instr_create_0dst_4src(dc, OP_ccmp, Rn, Op, nzcv, cond) + +/** + * Creates a CINC (Conditional Increment) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_cinc(dc, Rd, Rn, cond) \ + instr_create_1dst_3src(dc, OP_csinc, Rd, Rn, Rn, opnd_invert_cond(cond)) + +/** + * Creates a CINV (Conditional Invert) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_cinv(dc, Rd, Rn, cond) \ + instr_create_1dst_3src(dc, OP_csinv, Rd, Rn, Rn, opnd_invert_cond(cond)) + +/** + * Creates a CNEG (Conditional Negate) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_cneg(dc, Rd, Rn, cond) \ + instr_create_1dst_3src(dc, OP_csneg, Rd, Rn, Rn, opnd_invert_cond(cond)) + +/** + * Creates a CSEL (Conditional Select) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The first input register. + * \param Rm The second input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_csel(dc, Rd, Rn, Rm, cond) \ + instr_create_1dst_3src(dc, OP_csel, Rd, Rn, Rm, cond) + +/** + * Creates a CSET (Conditional Set) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_cset(dc, Rd, cond) \ + instr_create_1dst_3src(dc, OP_csinc, Rd, \ + OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), opnd_invert_cond(cond)) + +/** + * Creates a CSETM (Conditional Set Mask) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_csetm(dc, Rd, cond) \ + instr_create_1dst_3src(dc, OP_csinv, Rd, \ + OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), opnd_invert_cond(cond)) + +/** + * Creates a CSINC (Conditional Select Increment) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The first input register. + * \param Rm The second input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_csinc(dc, Rd, Rn, Rm, cond) \ + instr_create_1dst_3src(dc, OP_csinc, Rd, Rn, Rm, cond) + +/** + * Creates a CSINV (Conditional Select Invert) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The first input register. + * \param Rm The second input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_csinv(dc, Rd, Rn, Rm, cond) \ + instr_create_1dst_3src(dc, OP_csinv, Rd, Rn, Rm, cond) + +/** + * Creates a CSNEG (Conditional Select Negate) instruction. + * \param dc The void * dcontext used to allocate memory for the instr_t. + * \param Rd The output register. + * \param Rn The first input register. + * \param Rm The second input register. + * \param cond A 4-bit immediate value for condition + * (use opnd_create_cond(val) to create the operand). + */ +#define INSTR_CREATE_csneg(dc, Rd, Rn, Rm, cond) \ + instr_create_1dst_3src(dc, OP_csneg, Rd, Rn, Rm, cond) + /* DR_API EXPORT END */ #endif /* INSTR_CREATE_H */ diff --git a/core/ir/opnd.h b/core/ir/opnd.h index 6450d74c384..577290e73c0 100644 --- a/core/ir/opnd.h +++ b/core/ir/opnd.h @@ -1777,6 +1777,34 @@ opnd_t opnd_create_base_disp_aarch64(reg_id_t base_reg, reg_id_t index_reg, dr_extend_type_t extend_type, bool scaled, int disp, dr_opnd_flags_t flags, opnd_size_t size); +DR_API +/** + * Creates an unsigned immediate integer operand for condition defined by enum + * constant \p cond of type #dr_pred_type_t. + * \note AArch64-only. + */ +opnd_t +opnd_create_cond(int cond); + +DR_API +/** + * Assumes the operand is an unsigned immediate 4-bit integer and returns a + * #dr_pred_type_t constant corresponding to the value of the operand. + * \note AArch64-only. + */ +int +opnd_get_cond(opnd_t opnd); + +DR_API +/** + * Assumes the operand is an unsigned immediate 4-bit integer and returns an + * operand which contains inverted condition (see #dr_pred_type_t). + * \note Does not support AL and NV conditions. + * \note AArch64-only. + */ +opnd_t +opnd_invert_cond(opnd_t opnd); + #endif DR_API diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c index 5a4cbb953af..66d8bca20ce 100644 --- a/core/ir/opnd_shared.c +++ b/core/ir/opnd_shared.c @@ -743,7 +743,101 @@ opnd_create_base_disp_aarch64(reg_id_t base_reg, reg_id_t index_reg, CLIENT_ASSERT(false, "opnd_create_base_disp_aarch64: invalid extend type"); return opnd; } -#endif + +opnd_t +opnd_create_cond(int cond) +{ + /* FIXME i#1569: Move definition of dr_pred_type_t to opnd.h for AArch64 + * to avoid using int instead of dr_pred_type_t */ + switch (cond) { + case DR_PRED_EQ: + return opnd_create_immed_uint(0b0000, OPSZ_4b); + case DR_PRED_NE: + return opnd_create_immed_uint(0b0001, OPSZ_4b); + case DR_PRED_CS: + return opnd_create_immed_uint(0b0010, OPSZ_4b); + case DR_PRED_CC: + return opnd_create_immed_uint(0b0011, OPSZ_4b); + case DR_PRED_MI: + return opnd_create_immed_uint(0b0100, OPSZ_4b); + case DR_PRED_PL: + return opnd_create_immed_uint(0b0101, OPSZ_4b); + case DR_PRED_VS: + return opnd_create_immed_uint(0b0110, OPSZ_4b); + case DR_PRED_VC: + return opnd_create_immed_uint(0b0111, OPSZ_4b); + case DR_PRED_HI: + return opnd_create_immed_uint(0b1000, OPSZ_4b); + case DR_PRED_LS: + return opnd_create_immed_uint(0b1001, OPSZ_4b); + case DR_PRED_GE: + return opnd_create_immed_uint(0b1010, OPSZ_4b); + case DR_PRED_LT: + return opnd_create_immed_uint(0b1011, OPSZ_4b); + case DR_PRED_GT: + return opnd_create_immed_uint(0b1100, OPSZ_4b); + case DR_PRED_LE: + return opnd_create_immed_uint(0b1101, OPSZ_4b); + case DR_PRED_AL: + return opnd_create_immed_uint(0b1110, OPSZ_4b); + case DR_PRED_NV: + return opnd_create_immed_uint(0b1111, OPSZ_4b); + default: + CLIENT_ASSERT(false, "invalid condition constant"); + return opnd_create_null(); + } +} + +int +opnd_get_cond(opnd_t opnd) +{ + /* FIXME i#1569: Move definition of dr_pred_type_t to opnd.h for AArch64 + * to avoid using int instead of dr_pred_type_t */ + switch (((uint64)opnd_get_immed_int(opnd) & 0xfu)) { + case 0b0000: return DR_PRED_EQ; + case 0b0001: return DR_PRED_NE; + case 0b0010: return DR_PRED_CS; + case 0b0011: return DR_PRED_CC; + case 0b0100: return DR_PRED_MI; + case 0b0101: return DR_PRED_PL; + case 0b0110: return DR_PRED_VS; + case 0b0111: return DR_PRED_VC; + case 0b1000: return DR_PRED_HI; + case 0b1001: return DR_PRED_LS; + case 0b1010: return DR_PRED_GE; + case 0b1011: return DR_PRED_LT; + case 0b1100: return DR_PRED_GT; + case 0b1101: return DR_PRED_LE; + case 0b1110: return DR_PRED_AL; + case 0b1111: return DR_PRED_NV; + } + return DR_PRED_NONE; +} + +opnd_t +opnd_invert_cond(opnd_t opnd) +{ + switch (opnd_get_cond(opnd)) { + case DR_PRED_EQ: return opnd_create_cond(DR_PRED_NE); + case DR_PRED_NE: return opnd_create_cond(DR_PRED_EQ); + case DR_PRED_CS: return opnd_create_cond(DR_PRED_CC); + case DR_PRED_CC: return opnd_create_cond(DR_PRED_CS); + case DR_PRED_MI: return opnd_create_cond(DR_PRED_PL); + case DR_PRED_PL: return opnd_create_cond(DR_PRED_MI); + case DR_PRED_VS: return opnd_create_cond(DR_PRED_VC); + case DR_PRED_VC: return opnd_create_cond(DR_PRED_VS); + case DR_PRED_HI: return opnd_create_cond(DR_PRED_LS); + case DR_PRED_LS: return opnd_create_cond(DR_PRED_HI); + case DR_PRED_GE: return opnd_create_cond(DR_PRED_LT); + case DR_PRED_LT: return opnd_create_cond(DR_PRED_GE); + case DR_PRED_GT: return opnd_create_cond(DR_PRED_LE); + case DR_PRED_LE: return opnd_create_cond(DR_PRED_GT); + default: + CLIENT_ASSERT(false, "invalid condition constant"); + return opnd_create_null(); + } +} +#endif /* AARCH64 */ #undef opnd_get_base #undef opnd_get_disp diff --git a/suite/tests/api/dis-a64.txt b/suite/tests/api/dis-a64.txt index ecadd2f0b63..2842a2238f6 100644 --- a/suite/tests/api/dis-a64.txt +++ b/suite/tests/api/dis-a64.txt @@ -2336,3 +2336,734 @@ fd7fffff : ldr d31, [sp,#32760] : ldr +0x7ff8(%sp)[8byte] -> %d31 6e23c0c6 : umull2 v6.8h, v6.16b, v3.16b : umull2 %q6 %q3 $0x00 -> %q6 6e63c0c6 : umull2 v6.4s, v6.8h, v3.8h : umull2 %q6 %q3 $0x01 -> %q6 6ea3c0c6 : umull2 v6.2d, v6.4s, v3.4s : umull2 %q6 %q3 $0x02 -> %q6 +3a458887 : ccmn w4, #5, #7, hi : ccmn %w4 $0x05 $0x07 hi +ba41f8a2 : ccmn x5, #1, #2, nv : ccmn %x5 $0x01 $0x02 nv +3a498087 : ccmn w4, w9, #7, hi : ccmn %w4 %w9 $0x07 hi +ba496023 : ccmn x1, x9, #3, vs : ccmn %x1 %x9 $0x03 vs +7a40f9a1 : ccmp w13, #0, #1, nv : ccmp %w13 $0x00 $0x01 nv +fa4259a0 : ccmp x13, #2, #0, pl : ccmp %x13 $0x02 $0x00 pl +7a5fe1a5 : ccmp w13, wzr, #5, al : ccmp %w13 %wzr $0x05 al +fa4141a9 : ccmp x13, x1, #9, mi : ccmp %x13 %x1 $0x09 mi +1a94d681 : cinc w1, w20, gt : csinc %w20 %w20 le -> %w1 +9a8ec5c8 : cinc x8, x14, le : csinc %x14 %x14 gt -> %x8 +5a82c041 : cinv w1, w2, le : csinv %w2 %w2 gt -> %w1 +da80d013 : cinv x19, x0, gt : csinv %x0 %x0 le -> %x19 +5a9666c8 : cneg w8, w22, vc : csneg %w22 %w22 vs -> %w8 +da899520 : cneg x0, x9, hi : csneg %x9 %x9 ls -> %x0 +1a829020 : csel w0, w1, w2, ls : csel %w1 %w2 ls -> %w0 +9a9fc3d4 : csel x20, x30, xzr, gt : csel %x30 %xzr gt -> %x20 +1a9f07e0 : cset w0, ne : csinc %wzr %wzr eq -> %w0 +9a9f37ff : cset xzr, cs : csinc %xzr %xzr cc -> %xzr +5a9f83ec : csetm w12, ls : csinv %wzr %wzr hi -> %w12 +da9fd3e4 : csetm x4, gt : csinv %xzr %xzr le -> %x4 +1a9fe4e1 : csinc w1, w7, wzr, al : csinc %w7 %wzr al -> %w1 +9a89f507 : csinc x7, x8, x9, nv : csinc %x8 %x9 nv -> %x7 +5a8193ff : csinv wzr, wzr, w1, ls : csinv %wzr %w1 ls -> %wzr +da8283e0 : csinv x0, xzr, x2, hi : csinv %xzr %x2 hi -> %x0 +5a8277e5 : csneg w5, wzr, w2, vc : csneg %wzr %w2 vc -> %w5 +da8744e0 : csneg x0, x7, x7, mi : csneg %x7 %x7 mi -> %x0 +3a5c2888 : ccmn w4, #28, #8, cs : ccmn %w4 $0x1c $0x08 cs +3a4229ce : ccmn w14, #2, #14, cs : ccmn %w14 $0x02 $0x0e cs +3a4608a8 : ccmn w5, #6, #8, eq : ccmn %w5 $0x06 $0x08 eq +3a5fd944 : ccmn w10, #31, #4, le : ccmn %w10 $0x1f $0x04 le +3a58794c : ccmn w10, #24, #12, vc : ccmn %w10 $0x18 $0x0c vc +3a529bea : ccmn wzr, #18, #10, ls : ccmn %wzr $0x12 $0x0a ls +3a48db22 : ccmn w25, #8, #2, le : ccmn %w25 $0x08 $0x02 le +3a5b9b26 : ccmn w25, #27, #6, ls : ccmn %w25 $0x1b $0x06 ls +3a567867 : ccmn w3, #22, #7, vc : ccmn %w3 $0x16 $0x07 vc +3a50ea05 : ccmn w16, #16, #5, al : ccmn %w16 $0x10 $0x05 al +3a500944 : ccmn w10, #16, #4, eq : ccmn %w10 $0x10 $0x04 eq +3a5ee86d : ccmn w3, #30, #13, al : ccmn %w3 $0x1e $0x0d al +3a5d0b29 : ccmn w25, #29, #9, eq : ccmn %w25 $0x1d $0x09 eq +3a4cc8e0 : ccmn w7, #12, #0, gt : ccmn %w7 $0x0c $0x00 gt +3a473826 : ccmn w1, #7, #6, cc : ccmn %w1 $0x07 $0x06 cc +3a5b4baa : ccmn w29, #27, #10, mi : ccmn %w29 $0x1b $0x0a mi +3a5dcbaf : ccmn w29, #29, #15, gt : ccmn %w29 $0x1d $0x0f gt +3a4a5965 : ccmn w11, #10, #5, pl : ccmn %w11 $0x0a $0x05 pl +3a42d963 : ccmn w11, #2, #3, le : ccmn %w11 $0x02 $0x03 le +3a5089e4 : ccmn w15, #16, #4, hi : ccmn %w15 $0x10 $0x04 hi +3a4a0800 : ccmn w0, #10, #0, eq : ccmn %w0 $0x0a $0x00 eq +3a559a89 : ccmn w20, #21, #9, ls : ccmn %w20 $0x15 $0x09 ls +3a542b8e : ccmn w28, #20, #14, cs : ccmn %w28 $0x14 $0x0e cs +3a4a1b62 : ccmn w27, #10, #2, ne : ccmn %w27 $0x0a $0x02 ne +3a4cab8d : ccmn w28, #12, #13, ge : ccmn %w28 $0x0c $0x0d ge +3a4cc803 : ccmn w0, #12, #3, gt : ccmn %w0 $0x0c $0x03 gt +3a469b26 : ccmn w25, #6, #6, ls : ccmn %w25 $0x06 $0x06 ls +3a4d6aac : ccmn w21, #13, #12, vs : ccmn %w21 $0x0d $0x0c vs +3a5d7988 : ccmn w12, #29, #8, vc : ccmn %w12 $0x1d $0x08 vc +3a55ca0c : ccmn w16, #21, #12, gt : ccmn %w16 $0x15 $0x0c gt +3a573aaf : ccmn w21, #23, #15, cc : ccmn %w21 $0x17 $0x0f cc +3a580a07 : ccmn w16, #24, #7, eq : ccmn %w16 $0x18 $0x07 eq +ba4ec906 : ccmn x8, #14, #6, gt : ccmn %x8 $0x0e $0x06 gt +ba52e8ce : ccmn x6, #18, #14, al : ccmn %x6 $0x12 $0x0e al +ba496903 : ccmn x8, #9, #3, vs : ccmn %x8 $0x09 $0x03 vs +ba45198e : ccmn x12, #5, #14, ne : ccmn %x12 $0x05 $0x0e ne +ba408806 : ccmn x0, #0, #6, hi : ccmn %x0 $0x00 $0x06 hi +ba4e99ab : ccmn x13, #14, #11, ls : ccmn %x13 $0x0e $0x0b ls +ba40cac3 : ccmn x22, #0, #3, gt : ccmn %x22 $0x00 $0x03 gt +ba44c8a8 : ccmn x5, #4, #8, gt : ccmn %x5 $0x04 $0x08 gt +ba516a89 : ccmn x20, #17, #9, vs : ccmn %x20 $0x11 $0x09 vs +ba569b8f : ccmn x28, #22, #15, ls : ccmn %x28 $0x16 $0x0f ls +ba557908 : ccmn x8, #21, #8, vc : ccmn %x8 $0x15 $0x08 vc +ba4eaaca : ccmn x22, #14, #10, ge : ccmn %x22 $0x0e $0x0a ge +ba57e8a3 : ccmn x5, #23, #3, al : ccmn %x5 $0x17 $0x03 al +ba4fca68 : ccmn x19, #15, #8, gt : ccmn %x19 $0x0f $0x08 gt +ba5998ad : ccmn x5, #25, #13, ls : ccmn %x5 $0x19 $0x0d ls +ba54fb69 : ccmn x27, #20, #9, nv : ccmn %x27 $0x14 $0x09 nv +ba40ca0c : ccmn x16, #0, #12, gt : ccmn %x16 $0x00 $0x0c gt +ba407981 : ccmn x12, #0, #1, vc : ccmn %x12 $0x00 $0x01 vc +ba480ac2 : ccmn x22, #8, #2, eq : ccmn %x22 $0x08 $0x02 eq +ba4bf94d : ccmn x10, #11, #13, nv : ccmn %x10 $0x0b $0x0d nv +ba5d982f : ccmn x1, #29, #15, ls : ccmn %x1 $0x1d $0x0f ls +ba43ca6e : ccmn x19, #3, #14, gt : ccmn %x19 $0x03 $0x0e gt +ba41488f : ccmn x4, #1, #15, mi : ccmn %x4 $0x01 $0x0f mi +ba552a8b : ccmn x20, #21, #11, cs : ccmn %x20 $0x15 $0x0b cs +ba54f88e : ccmn x4, #20, #14, nv : ccmn %x4 $0x14 $0x0e nv +ba5beac2 : ccmn x22, #27, #2, al : ccmn %x22 $0x1b $0x02 al +ba42cb83 : ccmn x28, #2, #3, gt : ccmn %x28 $0x02 $0x03 gt +ba53caab : ccmn x21, #19, #11, gt : ccmn %x21 $0x13 $0x0b gt +ba416a2e : ccmn x17, #1, #14, vs : ccmn %x17 $0x01 $0x0e vs +ba5049c8 : ccmn x14, #16, #8, mi : ccmn %x14 $0x10 $0x08 mi +ba406a48 : ccmn x18, #0, #8, vs : ccmn %x18 $0x00 $0x08 vs +ba547987 : ccmn x12, #20, #7, vc : ccmn %x12 $0x14 $0x07 vc +7a45d82b : ccmp w1, #5, #11, le : ccmp %w1 $0x05 $0x0b le +7a4a4a86 : ccmp w20, #10, #6, mi : ccmp %w20 $0x0a $0x06 mi +7a48b8eb : ccmp w7, #8, #11, lt : ccmp %w7 $0x08 $0x0b lt +7a404aa0 : ccmp w21, #0, #0, mi : ccmp %w21 $0x00 $0x00 mi +7a59196a : ccmp w11, #25, #10, ne : ccmp %w11 $0x19 $0x0a ne +7a429b48 : ccmp w26, #2, #8, ls : ccmp %w26 $0x02 $0x08 ls +7a562b83 : ccmp w28, #22, #3, cs : ccmp %w28 $0x16 $0x03 cs +7a5bf803 : ccmp w0, #27, #3, nv : ccmp %w0 $0x1b $0x03 nv +7a456b4d : ccmp w26, #5, #13, vs : ccmp %w26 $0x05 $0x0d vs +7a45fb65 : ccmp w27, #5, #5, nv : ccmp %w27 $0x05 $0x05 nv +7a4bba09 : ccmp w16, #11, #9, lt : ccmp %w16 $0x0b $0x09 lt +7a43ba2b : ccmp w17, #3, #11, lt : ccmp %w17 $0x03 $0x0b lt +7a556a61 : ccmp w19, #21, #1, vs : ccmp %w19 $0x15 $0x01 vs +7a474b48 : ccmp w26, #7, #8, mi : ccmp %w26 $0x07 $0x08 mi +7a4e9a22 : ccmp w17, #14, #2, ls : ccmp %w17 $0x0e $0x02 ls +7a583ac8 : ccmp w22, #24, #8, cc : ccmp %w22 $0x18 $0x08 cc +7a5e18c4 : ccmp w6, #30, #4, ne : ccmp %w6 $0x1e $0x04 ne +7a45db60 : ccmp w27, #5, #0, le : ccmp %w27 $0x05 $0x00 le +7a50d9a8 : ccmp w13, #16, #8, le : ccmp %w13 $0x10 $0x08 le +7a418a8c : ccmp w20, #1, #12, hi : ccmp %w20 $0x01 $0x0c hi +7a49a80b : ccmp w0, #9, #11, ge : ccmp %w0 $0x09 $0x0b ge +7a446a24 : ccmp w17, #4, #4, vs : ccmp %w17 $0x04 $0x04 vs +7a43e8a6 : ccmp w5, #3, #6, al : ccmp %w5 $0x03 $0x06 al +7a5f69e2 : ccmp w15, #31, #2, vs : ccmp %w15 $0x1f $0x02 vs +7a4979a6 : ccmp w13, #9, #6, vc : ccmp %w13 $0x09 $0x06 vc +7a4cb80d : ccmp w0, #12, #13, lt : ccmp %w0 $0x0c $0x0d lt +7a4b79a0 : ccmp w13, #11, #0, vc : ccmp %w13 $0x0b $0x00 vc +7a58bb84 : ccmp w28, #24, #4, lt : ccmp %w28 $0x18 $0x04 lt +7a52ab0c : ccmp w24, #18, #12, ge : ccmp %w24 $0x12 $0x0c ge +7a4c8b49 : ccmp w26, #12, #9, hi : ccmp %w26 $0x0c $0x09 hi +7a4be9aa : ccmp w13, #11, #10, al : ccmp %w13 $0x0b $0x0a al +7a5eba69 : ccmp w19, #30, #9, lt : ccmp %w19 $0x1e $0x09 lt +fa5d8be9 : ccmp xzr, #29, #9, hi : ccmp %xzr $0x1d $0x09 hi +fa486867 : ccmp x3, #8, #7, vs : ccmp %x3 $0x08 $0x07 vs +fa401b82 : ccmp x28, #0, #2, ne : ccmp %x28 $0x00 $0x02 ne +fa53d928 : ccmp x9, #19, #8, le : ccmp %x9 $0x13 $0x08 le +fa4cea45 : ccmp x18, #12, #5, al : ccmp %x18 $0x0c $0x05 al +fa5da90d : ccmp x8, #29, #13, ge : ccmp %x8 $0x1d $0x0d ge +fa53598a : ccmp x12, #19, #10, pl : ccmp %x12 $0x13 $0x0a pl +fa56884d : ccmp x2, #22, #13, hi : ccmp %x2 $0x16 $0x0d hi +fa59082a : ccmp x1, #25, #10, eq : ccmp %x1 $0x19 $0x0a eq +fa5b8901 : ccmp x8, #27, #1, hi : ccmp %x8 $0x1b $0x01 hi +fa57fb4c : ccmp x26, #23, #12, nv : ccmp %x26 $0x17 $0x0c nv +fa5569ad : ccmp x13, #21, #13, vs : ccmp %x13 $0x15 $0x0d vs +fa48ebeb : ccmp xzr, #8, #11, al : ccmp %xzr $0x08 $0x0b al +fa444aeb : ccmp x23, #4, #11, mi : ccmp %x23 $0x04 $0x0b mi +fa5c9b86 : ccmp x28, #28, #6, ls : ccmp %x28 $0x1c $0x06 ls +fa48db0b : ccmp x24, #8, #11, le : ccmp %x24 $0x08 $0x0b le +fa5e088f : ccmp x4, #30, #15, eq : ccmp %x4 $0x1e $0x0f eq +fa505940 : ccmp x10, #16, #0, pl : ccmp %x10 $0x10 $0x00 pl +fa538922 : ccmp x9, #19, #2, hi : ccmp %x9 $0x13 $0x02 hi +fa565a60 : ccmp x19, #22, #0, pl : ccmp %x19 $0x16 $0x00 pl +fa5ba94a : ccmp x10, #27, #10, ge : ccmp %x10 $0x1b $0x0a ge +fa46c9a1 : ccmp x13, #6, #1, gt : ccmp %x13 $0x06 $0x01 gt +fa473a47 : ccmp x18, #7, #7, cc : ccmp %x18 $0x07 $0x07 cc +fa589a25 : ccmp x17, #24, #5, ls : ccmp %x17 $0x18 $0x05 ls +fa535803 : ccmp x0, #19, #3, pl : ccmp %x0 $0x13 $0x03 pl +fa429bc1 : ccmp x30, #2, #1, ls : ccmp %x30 $0x02 $0x01 ls +fa54ba8d : ccmp x20, #20, #13, lt : ccmp %x20 $0x14 $0x0d lt +fa485ba8 : ccmp x29, #8, #8, pl : ccmp %x29 $0x08 $0x08 pl +fa4c9a4b : ccmp x18, #12, #11, ls : ccmp %x18 $0x0c $0x0b ls +fa416a84 : ccmp x20, #1, #4, vs : ccmp %x20 $0x01 $0x04 vs +fa580803 : ccmp x0, #24, #3, eq : ccmp %x0 $0x18 $0x03 eq +fa403bc8 : ccmp x30, #0, #8, cc : ccmp %x30 $0x00 $0x08 cc +1a9546a8 : cinc w8, w21, pl : csinc %w21 %w21 mi -> %w8 +1a807404 : cinc w4, w0, vs : csinc %w0 %w0 vc -> %w4 +1a92264d : cinc w13, w18, cc : csinc %w18 %w18 cs -> %w13 +1a991738 : cinc w24, w25, eq : csinc %w25 %w25 ne -> %w24 +1a926650 : cinc w16, w18, vc : csinc %w18 %w18 vs -> %w16 +1a93a669 : cinc w9, w19, lt : csinc %w19 %w19 ge -> %w9 +1a882517 : cinc w23, w8, cc : csinc %w8 %w8 cs -> %w23 +1a8c359c : cinc w28, w12, cs : csinc %w12 %w12 cc -> %w28 +1a826459 : cinc w25, w2, vc : csinc %w2 %w2 vs -> %w25 +1a8794fc : cinc w28, w7, hi : csinc %w7 %w7 ls -> %w28 +1a9c0796 : cinc w22, w28, ne : csinc %w28 %w28 eq -> %w22 +1a833477 : cinc w23, w3, cs : csinc %w3 %w3 cc -> %w23 +1a93866e : cinc w14, w19, ls : csinc %w19 %w19 hi -> %w14 +1a82d45c : cinc w28, w2, gt : csinc %w2 %w2 le -> %w28 +1a8554a3 : cinc w3, w5, mi : csinc %w5 %w5 pl -> %w3 +1a9b2777 : cinc w23, w27, cc : csinc %w27 %w27 cs -> %w23 +1a82044e : cinc w14, w2, ne : csinc %w2 %w2 eq -> %w14 +1a9d07b4 : cinc w20, w29, ne : csinc %w29 %w29 eq -> %w20 +1a8e05cc : cinc w12, w14, ne : csinc %w14 %w14 eq -> %w12 +1a8a2555 : cinc w21, w10, cc : csinc %w10 %w10 cs -> %w21 +1a927655 : cinc w21, w18, vs : csinc %w18 %w18 vc -> %w21 +1a87c4e5 : cinc w5, w7, le : csinc %w7 %w7 gt -> %w5 +1a83b47b : cinc w27, w3, ge : csinc %w3 %w3 lt -> %w27 +1a945693 : cinc w19, w20, mi : csinc %w20 %w20 pl -> %w19 +1a89b531 : cinc w17, w9, ge : csinc %w9 %w9 lt -> %w17 +1a820453 : cinc w19, w2, ne : csinc %w2 %w2 eq -> %w19 +1a9b6767 : cinc w7, w27, vc : csinc %w27 %w27 vs -> %w7 +1a806409 : cinc w9, w0, vc : csinc %w0 %w0 vs -> %w9 +1a88951e : cinc w30, w8, hi : csinc %w8 %w8 ls -> %w30 +1a88750c : cinc w12, w8, vs : csinc %w8 %w8 vc -> %w12 +1a9d97bd : cinc w29, w29, hi : csinc %w29 %w29 ls -> %w29 +1a8e35ce : cinc w14, w14, cs : csinc %w14 %w14 cc -> %w14 +9a803405 : cinc x5, x0, cs : csinc %x0 %x0 cc -> %x5 +9a9b6769 : cinc x9, x27, vc : csinc %x27 %x27 vs -> %x9 +9a8da5a7 : cinc x7, x13, lt : csinc %x13 %x13 ge -> %x7 +9a8664cd : cinc x13, x6, vc : csinc %x6 %x6 vs -> %x13 +9a9e87cf : cinc x15, x30, ls : csinc %x30 %x30 hi -> %x15 +9a9676da : cinc x26, x22, vs : csinc %x22 %x22 vc -> %x26 +9a89a523 : cinc x3, x9, lt : csinc %x9 %x9 ge -> %x3 +9a9506a6 : cinc x6, x21, ne : csinc %x21 %x21 eq -> %x6 +9a883506 : cinc x6, x8, cs : csinc %x8 %x8 cc -> %x6 +9a98971f : cinc xzr, x24, hi : csinc %x24 %x24 ls -> %xzr +9a99a722 : cinc x2, x25, lt : csinc %x25 %x25 ge -> %x2 +9a883503 : cinc x3, x8, cs : csinc %x8 %x8 cc -> %x3 +9a90b610 : cinc x16, x16, ge : csinc %x16 %x16 lt -> %x16 +9a97b6f0 : cinc x16, x23, ge : csinc %x23 %x23 lt -> %x16 +9a8534a8 : cinc x8, x5, cs : csinc %x5 %x5 cc -> %x8 +9a85d4a1 : cinc x1, x5, gt : csinc %x5 %x5 le -> %x1 +9a92465c : cinc x28, x18, pl : csinc %x18 %x18 mi -> %x28 +9a80841a : cinc x26, x0, ls : csinc %x0 %x0 hi -> %x26 +9a9cc78f : cinc x15, x28, le : csinc %x28 %x28 gt -> %x15 +9a99c724 : cinc x4, x25, le : csinc %x25 %x25 gt -> %x4 +9a9796e9 : cinc x9, x23, hi : csinc %x23 %x23 ls -> %x9 +9a810427 : cinc x7, x1, ne : csinc %x1 %x1 eq -> %x7 +9a8764fc : cinc x28, x7, vc : csinc %x7 %x7 vs -> %x28 +9a95b6a7 : cinc x7, x21, ge : csinc %x21 %x21 lt -> %x7 +9a8dc5a5 : cinc x5, x13, le : csinc %x13 %x13 gt -> %x5 +9a9e47d0 : cinc x16, x30, pl : csinc %x30 %x30 mi -> %x16 +9a82d455 : cinc x21, x2, gt : csinc %x2 %x2 le -> %x21 +9a9676c0 : cinc x0, x22, vs : csinc %x22 %x22 vc -> %x0 +9a887515 : cinc x21, x8, vs : csinc %x8 %x8 vc -> %x21 +9a926652 : cinc x18, x18, vc : csinc %x18 %x18 vs -> %x18 +9a96a6d1 : cinc x17, x22, lt : csinc %x22 %x22 ge -> %x17 +9a99473a : cinc x26, x25, pl : csinc %x25 %x25 mi -> %x26 +5a9bc370 : cinv w16, w27, le : csinv %w27 %w27 gt -> %w16 +5a8b5169 : cinv w9, w11, mi : csinv %w11 %w11 pl -> %w9 +5a88810d : cinv w13, w8, ls : csinv %w8 %w8 hi -> %w13 +5a84d082 : cinv w2, w4, gt : csinv %w4 %w4 le -> %w2 +5a85c0b9 : cinv w25, w5, le : csinv %w5 %w5 gt -> %w25 +5a80800c : cinv w12, w0, ls : csinv %w0 %w0 hi -> %w12 +5a8600d9 : cinv w25, w6, ne : csinv %w6 %w6 eq -> %w25 +5a985301 : cinv w1, w24, mi : csinv %w24 %w24 pl -> %w1 +5a8e71d1 : cinv w17, w14, vs : csinv %w14 %w14 vc -> %w17 +5a880105 : cinv w5, w8, ne : csinv %w8 %w8 eq -> %w5 +5a898131 : cinv w17, w9, ls : csinv %w9 %w9 hi -> %w17 +5a9782e6 : cinv w6, w23, ls : csinv %w23 %w23 hi -> %w6 +5a9722f4 : cinv w20, w23, cc : csinv %w23 %w23 cs -> %w20 +5a8f81f1 : cinv w17, w15, ls : csinv %w15 %w15 hi -> %w17 +5a8630df : cinv wzr, w6, cs : csinv %w6 %w6 cc -> %wzr +5a80400f : cinv w15, w0, pl : csinv %w0 %w0 mi -> %w15 +5a8a7147 : cinv w7, w10, vs : csinv %w10 %w10 vc -> %w7 +5a9522aa : cinv w10, w21, cc : csinv %w21 %w21 cs -> %w10 +5a91123e : cinv w30, w17, eq : csinv %w17 %w17 ne -> %w30 +5a95c2ab : cinv w11, w21, le : csinv %w21 %w21 gt -> %w11 +5a87c0f8 : cinv w24, w7, le : csinv %w7 %w7 gt -> %w24 +5a9e53c6 : cinv w6, w30, mi : csinv %w30 %w30 pl -> %w6 +5a95d2ab : cinv w11, w21, gt : csinv %w21 %w21 le -> %w11 +5a8dc1a8 : cinv w8, w13, le : csinv %w13 %w13 gt -> %w8 +5a88d11c : cinv w28, w8, gt : csinv %w8 %w8 le -> %w28 +5a9e23dc : cinv w28, w30, cc : csinv %w30 %w30 cs -> %w28 +5a8bb176 : cinv w22, w11, ge : csinv %w11 %w11 lt -> %w22 +5a8a5150 : cinv w16, w10, mi : csinv %w10 %w10 pl -> %w16 +5a82705f : cinv wzr, w2, vs : csinv %w2 %w2 vc -> %wzr +5a806001 : cinv w1, w0, vc : csinv %w0 %w0 vs -> %w1 +5a8ed1c6 : cinv w6, w14, gt : csinv %w14 %w14 le -> %w6 +5a923256 : cinv w22, w18, cs : csinv %w18 %w18 cc -> %w22 +da98931e : cinv x30, x24, hi : csinv %x24 %x24 ls -> %x30 +da894139 : cinv x25, x9, pl : csinv %x9 %x9 mi -> %x25 +da9bc366 : cinv x6, x27, le : csinv %x27 %x27 gt -> %x6 +da934276 : cinv x22, x19, pl : csinv %x19 %x19 mi -> %x22 +da9cb383 : cinv x3, x28, ge : csinv %x28 %x28 lt -> %x3 +da80901e : cinv x30, x0, hi : csinv %x0 %x0 ls -> %x30 +da9542b4 : cinv x20, x21, pl : csinv %x21 %x21 mi -> %x20 +da9f53ff : cinv xzr, xzr, mi : csinv %xzr %xzr pl -> %xzr +da9f23f0 : cinv x16, xzr, cc : csinv %xzr %xzr cs -> %x16 +da98731e : cinv x30, x24, vs : csinv %x24 %x24 vc -> %x30 +da8f61f4 : cinv x20, x15, vc : csinv %x15 %x15 vs -> %x20 +da9e73c6 : cinv x6, x30, vs : csinv %x30 %x30 vc -> %x6 +da9b536e : cinv x14, x27, mi : csinv %x27 %x27 pl -> %x14 +da96a2c5 : cinv x5, x22, lt : csinv %x22 %x22 ge -> %x5 +da8e81c1 : cinv x1, x14, ls : csinv %x14 %x14 hi -> %x1 +da91323c : cinv x28, x17, cs : csinv %x17 %x17 cc -> %x28 +da92025e : cinv x30, x18, ne : csinv %x18 %x18 eq -> %x30 +da997326 : cinv x6, x25, vs : csinv %x25 %x25 vc -> %x6 +da83407d : cinv x29, x3, pl : csinv %x3 %x3 mi -> %x29 +da9e73c7 : cinv x7, x30, vs : csinv %x30 %x30 vc -> %x7 +da85d0b7 : cinv x23, x5, gt : csinv %x5 %x5 le -> %x23 +da916225 : cinv x5, x17, vc : csinv %x17 %x17 vs -> %x5 +da838068 : cinv x8, x3, ls : csinv %x3 %x3 hi -> %x8 +da96c2ca : cinv x10, x22, le : csinv %x22 %x22 gt -> %x10 +da94729a : cinv x26, x20, vs : csinv %x20 %x20 vc -> %x26 +da81c02a : cinv x10, x1, le : csinv %x1 %x1 gt -> %x10 +da910238 : cinv x24, x17, ne : csinv %x17 %x17 eq -> %x24 +da928254 : cinv x20, x18, ls : csinv %x18 %x18 hi -> %x20 +da811022 : cinv x2, x1, eq : csinv %x1 %x1 ne -> %x2 +da8bb17b : cinv x27, x11, ge : csinv %x11 %x11 lt -> %x27 +da83206c : cinv x12, x3, cc : csinv %x3 %x3 cs -> %x12 +da8f01fd : cinv x29, x15, ne : csinv %x15 %x15 eq -> %x29 +5a9cc79e : cneg w30, w28, le : csneg %w28 %w28 gt -> %w30 +5a908600 : cneg w0, w16, ls : csneg %w16 %w16 hi -> %w0 +5a98c70e : cneg w14, w24, le : csneg %w24 %w24 gt -> %w14 +5a8dc5aa : cneg w10, w13, le : csneg %w13 %w13 gt -> %w10 +5a9546b2 : cneg w18, w21, pl : csneg %w21 %w21 mi -> %w18 +5a8a654c : cneg w12, w10, vc : csneg %w10 %w10 vs -> %w12 +5a9a675b : cneg w27, w26, vc : csneg %w26 %w26 vs -> %w27 +5a8f85e2 : cneg w2, w15, ls : csneg %w15 %w15 hi -> %w2 +5a917631 : cneg w17, w17, vs : csneg %w17 %w17 vc -> %w17 +5a91d627 : cneg w7, w17, gt : csneg %w17 %w17 le -> %w7 +5a9a375f : cneg wzr, w26, cs : csneg %w26 %w26 cc -> %wzr +5a8a6542 : cneg w2, w10, vc : csneg %w10 %w10 vs -> %w2 +5a91763c : cneg w28, w17, vs : csneg %w17 %w17 vc -> %w28 +5a818422 : cneg w2, w1, ls : csneg %w1 %w1 hi -> %w2 +5a95d6b5 : cneg w21, w21, gt : csneg %w21 %w21 le -> %w21 +5a9ed7c1 : cneg w1, w30, gt : csneg %w30 %w30 le -> %w1 +5a995736 : cneg w22, w25, mi : csneg %w25 %w25 pl -> %w22 +5a834475 : cneg w21, w3, pl : csneg %w3 %w3 mi -> %w21 +5a94268e : cneg w14, w20, cc : csneg %w20 %w20 cs -> %w14 +5a926659 : cneg w25, w18, vc : csneg %w18 %w18 vs -> %w25 +5a95a6b2 : cneg w18, w21, lt : csneg %w21 %w21 ge -> %w18 +5a8ea5c0 : cneg w0, w14, lt : csneg %w14 %w14 ge -> %w0 +5a9e07d3 : cneg w19, w30, ne : csneg %w30 %w30 eq -> %w19 +5a8d95be : cneg w30, w13, hi : csneg %w13 %w13 ls -> %w30 +5a9e77d3 : cneg w19, w30, vs : csneg %w30 %w30 vc -> %w19 +5a9ba76a : cneg w10, w27, lt : csneg %w27 %w27 ge -> %w10 +5a8624c7 : cneg w7, w6, cc : csneg %w6 %w6 cs -> %w7 +5a9e97c5 : cneg w5, w30, hi : csneg %w30 %w30 ls -> %w5 +5a9526a9 : cneg w9, w21, cc : csneg %w21 %w21 cs -> %w9 +5a8754f5 : cneg w21, w7, mi : csneg %w7 %w7 pl -> %w21 +5a85c4bf : cneg wzr, w5, le : csneg %w5 %w5 gt -> %wzr +5a8fd5eb : cneg w11, w15, gt : csneg %w15 %w15 le -> %w11 +da8a9559 : cneg x25, x10, hi : csneg %x10 %x10 ls -> %x25 +da842480 : cneg x0, x4, cc : csneg %x4 %x4 cs -> %x0 +da8624c4 : cneg x4, x6, cc : csneg %x6 %x6 cs -> %x4 +da94d68d : cneg x13, x20, gt : csneg %x20 %x20 le -> %x13 +da9e57cf : cneg x15, x30, mi : csneg %x30 %x30 pl -> %x15 +da9696c6 : cneg x6, x22, hi : csneg %x22 %x22 ls -> %x6 +da941697 : cneg x23, x20, eq : csneg %x20 %x20 ne -> %x23 +da91162d : cneg x13, x17, eq : csneg %x17 %x17 ne -> %x13 +da9fc7ef : cneg x15, xzr, le : csneg %xzr %xzr gt -> %x15 +da9b6779 : cneg x25, x27, vc : csneg %x27 %x27 vs -> %x25 +da904617 : cneg x23, x16, pl : csneg %x16 %x16 mi -> %x23 +da81a423 : cneg x3, x1, lt : csneg %x1 %x1 ge -> %x3 +da8f75e8 : cneg x8, x15, vs : csneg %x15 %x15 vc -> %x8 +da80c406 : cneg x6, x0, le : csneg %x0 %x0 gt -> %x6 +da9b476e : cneg x14, x27, pl : csneg %x27 %x27 mi -> %x14 +da89853f : cneg xzr, x9, ls : csneg %x9 %x9 hi -> %xzr +da882513 : cneg x19, x8, cc : csneg %x8 %x8 cs -> %x19 +da95d6a9 : cneg x9, x21, gt : csneg %x21 %x21 le -> %x9 +da9f07f9 : cneg x25, xzr, ne : csneg %xzr %xzr eq -> %x25 +da8c2581 : cneg x1, x12, cc : csneg %x12 %x12 cs -> %x1 +da84c490 : cneg x16, x4, le : csneg %x4 %x4 gt -> %x16 +da81242a : cneg x10, x1, cc : csneg %x1 %x1 cs -> %x10 +da97d6f6 : cneg x22, x23, gt : csneg %x23 %x23 le -> %x22 +da8514bd : cneg x29, x5, eq : csneg %x5 %x5 ne -> %x29 +da8fd5e9 : cneg x9, x15, gt : csneg %x15 %x15 le -> %x9 +da9776e7 : cneg x7, x23, vs : csneg %x23 %x23 vc -> %x7 +da8b1570 : cneg x16, x11, eq : csneg %x11 %x11 ne -> %x16 +da919632 : cneg x18, x17, hi : csneg %x17 %x17 ls -> %x18 +da8ac55f : cneg xzr, x10, le : csneg %x10 %x10 gt -> %xzr +da8a1556 : cneg x22, x10, eq : csneg %x10 %x10 ne -> %x22 +da8634c9 : cneg x9, x6, cs : csneg %x6 %x6 cc -> %x9 +da9ca78f : cneg x15, x28, lt : csneg %x28 %x28 ge -> %x15 +1a90d0d7 : csel w23, w6, w16, le : csel %w6 %w16 le -> %w23 +1a9681ed : csel w13, w15, w22, hi : csel %w15 %w22 hi -> %w13 +1a8c205a : csel w26, w2, w12, cs : csel %w2 %w12 cs -> %w26 +1a9e53cf : csel w15, w30, w30, pl : csel %w30 %w30 pl -> %w15 +1a8b7320 : csel w0, w25, w11, vc : csel %w25 %w11 vc -> %w0 +1a8bc258 : csel w24, w18, w11, gt : csel %w18 %w11 gt -> %w24 +1a874378 : csel w24, w27, w7, mi : csel %w27 %w7 mi -> %w24 +1a88d3de : csel w30, w30, w8, le : csel %w30 %w8 le -> %w30 +1a9670ff : csel wzr, w7, w22, vc : csel %w7 %w22 vc -> %wzr +1a95c396 : csel w22, w28, w21, gt : csel %w28 %w21 gt -> %w22 +1a8c8222 : csel w2, w17, w12, hi : csel %w17 %w12 hi -> %w2 +1a8802cd : csel w13, w22, w8, eq : csel %w22 %w8 eq -> %w13 +1a8aa39c : csel w28, w28, w10, ge : csel %w28 %w10 ge -> %w28 +1a8a70e6 : csel w6, w7, w10, vc : csel %w7 %w10 vc -> %w6 +1a85724a : csel w10, w18, w5, vc : csel %w18 %w5 vc -> %w10 +1a97b040 : csel w0, w2, w23, lt : csel %w2 %w23 lt -> %w0 +1a8d50bb : csel w27, w5, w13, pl : csel %w5 %w13 pl -> %w27 +1a8373f0 : csel w16, wzr, w3, vc : csel %wzr %w3 vc -> %w16 +1a88b091 : csel w17, w4, w8, lt : csel %w4 %w8 lt -> %w17 +1a85134d : csel w13, w26, w5, ne : csel %w26 %w5 ne -> %w13 +1a8a221a : csel w26, w16, w10, cs : csel %w16 %w10 cs -> %w26 +1a9ed39a : csel w26, w28, w30, le : csel %w28 %w30 le -> %w26 +1a8a514e : csel w14, w10, w10, pl : csel %w10 %w10 pl -> %w14 +1a9a204b : csel w11, w2, w26, cs : csel %w2 %w26 cs -> %w11 +1a93602a : csel w10, w1, w19, vs : csel %w1 %w19 vs -> %w10 +1a9db14d : csel w13, w10, w29, lt : csel %w10 %w29 lt -> %w13 +1a938235 : csel w21, w17, w19, hi : csel %w17 %w19 hi -> %w21 +1a9d32c2 : csel w2, w22, w29, cc : csel %w22 %w29 cc -> %w2 +1a8ab25d : csel w29, w18, w10, lt : csel %w18 %w10 lt -> %w29 +1a8f72bf : csel wzr, w21, w15, vc : csel %w21 %w15 vc -> %wzr +1a971184 : csel w4, w12, w23, ne : csel %w12 %w23 ne -> %w4 +1a980267 : csel w7, w19, w24, eq : csel %w19 %w24 eq -> %w7 +9a93a041 : csel x1, x2, x19, ge : csel %x2 %x19 ge -> %x1 +9a92a1e5 : csel x5, x15, x18, ge : csel %x15 %x18 ge -> %x5 +9a9e42e4 : csel x4, x23, x30, mi : csel %x23 %x30 mi -> %x4 +9a911243 : csel x3, x18, x17, ne : csel %x18 %x17 ne -> %x3 +9a92a163 : csel x3, x11, x18, ge : csel %x11 %x18 ge -> %x3 +9a9342dc : csel x28, x22, x19, mi : csel %x22 %x19 mi -> %x28 +9a9700a5 : csel x5, x5, x23, eq : csel %x5 %x23 eq -> %x5 +9a849215 : csel x21, x16, x4, ls : csel %x16 %x4 ls -> %x21 +9a8a61f0 : csel x16, x15, x10, vs : csel %x15 %x10 vs -> %x16 +9a83b3d2 : csel x18, x30, x3, lt : csel %x30 %x3 lt -> %x18 +9a815334 : csel x20, x25, x1, pl : csel %x25 %x1 pl -> %x20 +9a9a8178 : csel x24, x11, x26, hi : csel %x11 %x26 hi -> %x24 +9a9052db : csel x27, x22, x16, pl : csel %x22 %x16 pl -> %x27 +9a86312a : csel x10, x9, x6, cc : csel %x9 %x6 cc -> %x10 +9a9ba3de : csel x30, x30, x27, ge : csel %x30 %x27 ge -> %x30 +9a8c2348 : csel x8, x26, x12, cs : csel %x26 %x12 cs -> %x8 +9a90533b : csel x27, x25, x16, pl : csel %x25 %x16 pl -> %x27 +9a9e70f8 : csel x24, x7, x30, vc : csel %x7 %x30 vc -> %x24 +9a8570f0 : csel x16, x7, x5, vc : csel %x7 %x5 vc -> %x16 +9a8782ef : csel x15, x23, x7, hi : csel %x23 %x7 hi -> %x15 +9a9c8361 : csel x1, x27, x28, hi : csel %x27 %x28 hi -> %x1 +9a86c08a : csel x10, x4, x6, gt : csel %x4 %x6 gt -> %x10 +9a968120 : csel x0, x9, x22, hi : csel %x9 %x22 hi -> %x0 +9a852068 : csel x8, x3, x5, cs : csel %x3 %x5 cs -> %x8 +9a9f0020 : csel x0, x1, xzr, eq : csel %x1 %xzr eq -> %x0 +9a8bc312 : csel x18, x24, x11, gt : csel %x24 %x11 gt -> %x18 +9a8f032e : csel x14, x25, x15, eq : csel %x25 %x15 eq -> %x14 +9a91c2e3 : csel x3, x23, x17, gt : csel %x23 %x17 gt -> %x3 +9a9cb11a : csel x26, x8, x28, lt : csel %x8 %x28 lt -> %x26 +9a920323 : csel x3, x25, x18, eq : csel %x25 %x18 eq -> %x3 +9a8f208b : csel x11, x4, x15, cs : csel %x4 %x15 cs -> %x11 +9a8c420e : csel x14, x16, x12, mi : csel %x16 %x12 mi -> %x14 +1a9fd7ff : cset wzr, gt : csinc %wzr %wzr le -> %wzr +1a9f37ee : cset w14, cs : csinc %wzr %wzr cc -> %w14 +1a9f17fb : cset w27, eq : csinc %wzr %wzr ne -> %w27 +1a9f47e9 : cset w9, pl : csinc %wzr %wzr mi -> %w9 +1a9f57f7 : cset w23, mi : csinc %wzr %wzr pl -> %w23 +1a9fc7e1 : cset w1, le : csinc %wzr %wzr gt -> %w1 +1a9f07f9 : cset w25, ne : csinc %wzr %wzr eq -> %w25 +1a9f77f8 : cset w24, vs : csinc %wzr %wzr vc -> %w24 +1a9f07e2 : cset w2, ne : csinc %wzr %wzr eq -> %w2 +1a9fd7f3 : cset w19, gt : csinc %wzr %wzr le -> %w19 +1a9f17ea : cset w10, eq : csinc %wzr %wzr ne -> %w10 +1a9fb7e2 : cset w2, ge : csinc %wzr %wzr lt -> %w2 +1a9fd7ee : cset w14, gt : csinc %wzr %wzr le -> %w14 +1a9fd7fa : cset w26, gt : csinc %wzr %wzr le -> %w26 +1a9fc7fc : cset w28, le : csinc %wzr %wzr gt -> %w28 +1a9fc7f4 : cset w20, le : csinc %wzr %wzr gt -> %w20 +1a9f27ea : cset w10, cc : csinc %wzr %wzr cs -> %w10 +1a9f47fc : cset w28, pl : csinc %wzr %wzr mi -> %w28 +1a9fb7ef : cset w15, ge : csinc %wzr %wzr lt -> %w15 +1a9f27f4 : cset w20, cc : csinc %wzr %wzr cs -> %w20 +1a9f47ea : cset w10, pl : csinc %wzr %wzr mi -> %w10 +1a9f17fa : cset w26, eq : csinc %wzr %wzr ne -> %w26 +1a9fa7e8 : cset w8, lt : csinc %wzr %wzr ge -> %w8 +1a9f67e5 : cset w5, vc : csinc %wzr %wzr vs -> %w5 +1a9f77f6 : cset w22, vs : csinc %wzr %wzr vc -> %w22 +1a9f07e3 : cset w3, ne : csinc %wzr %wzr eq -> %w3 +1a9f17f1 : cset w17, eq : csinc %wzr %wzr ne -> %w17 +1a9f97e9 : cset w9, hi : csinc %wzr %wzr ls -> %w9 +1a9f37fd : cset w29, cs : csinc %wzr %wzr cc -> %w29 +1a9f57e0 : cset w0, mi : csinc %wzr %wzr pl -> %w0 +1a9f17ee : cset w14, eq : csinc %wzr %wzr ne -> %w14 +1a9f77ed : cset w13, vs : csinc %wzr %wzr vc -> %w13 +9a9f47f0 : cset x16, pl : csinc %xzr %xzr mi -> %x16 +9a9f57fc : cset x28, mi : csinc %xzr %xzr pl -> %x28 +9a9fd7f3 : cset x19, gt : csinc %xzr %xzr le -> %x19 +9a9f57ff : cset xzr, mi : csinc %xzr %xzr pl -> %xzr +9a9fd7e4 : cset x4, gt : csinc %xzr %xzr le -> %x4 +9a9f97ea : cset x10, hi : csinc %xzr %xzr ls -> %x10 +9a9f47e4 : cset x4, pl : csinc %xzr %xzr mi -> %x4 +9a9f97e1 : cset x1, hi : csinc %xzr %xzr ls -> %x1 +9a9f07fe : cset x30, ne : csinc %xzr %xzr eq -> %x30 +9a9fc7ee : cset x14, le : csinc %xzr %xzr gt -> %x14 +9a9fb7f9 : cset x25, ge : csinc %xzr %xzr lt -> %x25 +9a9fb7fc : cset x28, ge : csinc %xzr %xzr lt -> %x28 +9a9f87ef : cset x15, ls : csinc %xzr %xzr hi -> %x15 +9a9f07f5 : cset x21, ne : csinc %xzr %xzr eq -> %x21 +9a9fc7f4 : cset x20, le : csinc %xzr %xzr gt -> %x20 +9a9f37f8 : cset x24, cs : csinc %xzr %xzr cc -> %x24 +9a9f17f1 : cset x17, eq : csinc %xzr %xzr ne -> %x17 +9a9f17e9 : cset x9, eq : csinc %xzr %xzr ne -> %x9 +9a9f67fb : cset x27, vc : csinc %xzr %xzr vs -> %x27 +9a9fc7f0 : cset x16, le : csinc %xzr %xzr gt -> %x16 +9a9f07f8 : cset x24, ne : csinc %xzr %xzr eq -> %x24 +9a9fa7ff : cset xzr, lt : csinc %xzr %xzr ge -> %xzr +9a9f87ea : cset x10, ls : csinc %xzr %xzr hi -> %x10 +9a9f27f2 : cset x18, cc : csinc %xzr %xzr cs -> %x18 +9a9f07f0 : cset x16, ne : csinc %xzr %xzr eq -> %x16 +9a9f77f1 : cset x17, vs : csinc %xzr %xzr vc -> %x17 +9a9f67e0 : cset x0, vc : csinc %xzr %xzr vs -> %x0 +9a9f07ee : cset x14, ne : csinc %xzr %xzr eq -> %x14 +9a9f67f2 : cset x18, vc : csinc %xzr %xzr vs -> %x18 +9a9f17fc : cset x28, eq : csinc %xzr %xzr ne -> %x28 +9a9fc7e8 : cset x8, le : csinc %xzr %xzr gt -> %x8 +9a9fd7e5 : cset x5, gt : csinc %xzr %xzr le -> %x5 +5a9f23fe : csetm w30, cc : csinv %wzr %wzr cs -> %w30 +5a9f43f4 : csetm w20, pl : csinv %wzr %wzr mi -> %w20 +5a9fb3f5 : csetm w21, ge : csinv %wzr %wzr lt -> %w21 +5a9f03ff : csetm wzr, ne : csinv %wzr %wzr eq -> %wzr +5a9f13e5 : csetm w5, eq : csinv %wzr %wzr ne -> %w5 +5a9f23e6 : csetm w6, cc : csinv %wzr %wzr cs -> %w6 +5a9fd3f0 : csetm w16, gt : csinv %wzr %wzr le -> %w16 +5a9f43e1 : csetm w1, pl : csinv %wzr %wzr mi -> %w1 +5a9fd3fb : csetm w27, gt : csinv %wzr %wzr le -> %w27 +5a9f83f8 : csetm w24, ls : csinv %wzr %wzr hi -> %w24 +5a9fa3e9 : csetm w9, lt : csinv %wzr %wzr ge -> %w9 +5a9f83fb : csetm w27, ls : csinv %wzr %wzr hi -> %w27 +5a9f73e5 : csetm w5, vs : csinv %wzr %wzr vc -> %w5 +5a9f23e9 : csetm w9, cc : csinv %wzr %wzr cs -> %w9 +5a9f83f5 : csetm w21, ls : csinv %wzr %wzr hi -> %w21 +5a9f63f7 : csetm w23, vc : csinv %wzr %wzr vs -> %w23 +5a9f53fe : csetm w30, mi : csinv %wzr %wzr pl -> %w30 +5a9f63fc : csetm w28, vc : csinv %wzr %wzr vs -> %w28 +5a9f33ea : csetm w10, cs : csinv %wzr %wzr cc -> %w10 +5a9f03eb : csetm w11, ne : csinv %wzr %wzr eq -> %w11 +5a9f53f1 : csetm w17, mi : csinv %wzr %wzr pl -> %w17 +5a9f23f8 : csetm w24, cc : csinv %wzr %wzr cs -> %w24 +5a9f23fb : csetm w27, cc : csinv %wzr %wzr cs -> %w27 +5a9f63ea : csetm w10, vc : csinv %wzr %wzr vs -> %w10 +5a9fb3f8 : csetm w24, ge : csinv %wzr %wzr lt -> %w24 +5a9f03e8 : csetm w8, ne : csinv %wzr %wzr eq -> %w8 +5a9f83f7 : csetm w23, ls : csinv %wzr %wzr hi -> %w23 +5a9fa3ea : csetm w10, lt : csinv %wzr %wzr ge -> %w10 +5a9f53f6 : csetm w22, mi : csinv %wzr %wzr pl -> %w22 +5a9f03f7 : csetm w23, ne : csinv %wzr %wzr eq -> %w23 +5a9f83f9 : csetm w25, ls : csinv %wzr %wzr hi -> %w25 +5a9f43ea : csetm w10, pl : csinv %wzr %wzr mi -> %w10 +da9f13ef : csetm x15, eq : csinv %xzr %xzr ne -> %x15 +da9f83e3 : csetm x3, ls : csinv %xzr %xzr hi -> %x3 +da9f93f3 : csetm x19, hi : csinv %xzr %xzr ls -> %x19 +da9f33f5 : csetm x21, cs : csinv %xzr %xzr cc -> %x21 +da9f13f5 : csetm x21, eq : csinv %xzr %xzr ne -> %x21 +da9fc3f9 : csetm x25, le : csinv %xzr %xzr gt -> %x25 +da9f23f2 : csetm x18, cc : csinv %xzr %xzr cs -> %x18 +da9f03f4 : csetm x20, ne : csinv %xzr %xzr eq -> %x20 +da9f43f3 : csetm x19, pl : csinv %xzr %xzr mi -> %x19 +da9fb3e6 : csetm x6, ge : csinv %xzr %xzr lt -> %x6 +da9f43ea : csetm x10, pl : csinv %xzr %xzr mi -> %x10 +da9f33fd : csetm x29, cs : csinv %xzr %xzr cc -> %x29 +da9f53e2 : csetm x2, mi : csinv %xzr %xzr pl -> %x2 +da9f93e4 : csetm x4, hi : csinv %xzr %xzr ls -> %x4 +da9f93f1 : csetm x17, hi : csinv %xzr %xzr ls -> %x17 +da9f23e4 : csetm x4, cc : csinv %xzr %xzr cs -> %x4 +da9f13e2 : csetm x2, eq : csinv %xzr %xzr ne -> %x2 +da9fd3fb : csetm x27, gt : csinv %xzr %xzr le -> %x27 +da9fd3ee : csetm x14, gt : csinv %xzr %xzr le -> %x14 +da9fb3ee : csetm x14, ge : csinv %xzr %xzr lt -> %x14 +da9fc3f3 : csetm x19, le : csinv %xzr %xzr gt -> %x19 +da9fa3f4 : csetm x20, lt : csinv %xzr %xzr ge -> %x20 +da9f13ec : csetm x12, eq : csinv %xzr %xzr ne -> %x12 +da9f93e7 : csetm x7, hi : csinv %xzr %xzr ls -> %x7 +da9f33f1 : csetm x17, cs : csinv %xzr %xzr cc -> %x17 +da9f43eb : csetm x11, pl : csinv %xzr %xzr mi -> %x11 +da9f63e8 : csetm x8, vc : csinv %xzr %xzr vs -> %x8 +da9f43e1 : csetm x1, pl : csinv %xzr %xzr mi -> %x1 +da9f53e7 : csetm x7, mi : csinv %xzr %xzr pl -> %x7 +da9f03e4 : csetm x4, ne : csinv %xzr %xzr eq -> %x4 +da9fa3e5 : csetm x5, lt : csinv %xzr %xzr ge -> %x5 +da9f73ee : csetm x14, vs : csinv %xzr %xzr vc -> %x14 +1a898680 : csinc w0, w20, w9, hi : csinc %w20 %w9 hi -> %w0 +1a8d94ab : csinc w11, w5, w13, ls : csinc %w5 %w13 ls -> %w11 +1a9195f7 : csinc w23, w15, w17, ls : csinc %w15 %w17 ls -> %w23 +1a9694e2 : csinc w2, w7, w22, ls : csinc %w7 %w22 ls -> %w2 +1a8866c1 : csinc w1, w22, w8, vs : csinc %w22 %w8 vs -> %w1 +1a8786f7 : csinc w23, w23, w7, hi : csinc %w23 %w7 hi -> %w23 +1a9b47af : csinc w15, w29, w27, mi : csinc %w29 %w27 mi -> %w15 +1a8927b3 : csinc w19, w29, w9, cs : csinc %w29 %w9 cs -> %w19 +1a9c2444 : csinc w4, w2, w28, cs : csinc %w2 %w28 cs -> %w4 +1a8e65a4 : csinc w4, w13, w14, vs : csinc %w13 %w14 vs -> %w4 +1a9c4647 : csinc w7, w18, w28, mi : csinc %w18 %w28 mi -> %w7 +1a91244f : csinc w15, w2, w17, cs : csinc %w2 %w17 cs -> %w15 +1a881736 : csinc w22, w25, w8, ne : csinc %w25 %w8 ne -> %w22 +1a8e36a8 : csinc w8, w21, w14, cc : csinc %w21 %w14 cc -> %w8 +1a8464bb : csinc w27, w5, w4, vs : csinc %w5 %w4 vs -> %w27 +1a8624cd : csinc w13, w6, w6, cs : csinc %w6 %w6 cs -> %w13 +1a90c4d6 : csinc w22, w6, w16, gt : csinc %w6 %w16 gt -> %w22 +1a938515 : csinc w21, w8, w19, hi : csinc %w8 %w19 hi -> %w21 +1a8125b3 : csinc w19, w13, w1, cs : csinc %w13 %w1 cs -> %w19 +1a80a6db : csinc w27, w22, w0, ge : csinc %w22 %w0 ge -> %w27 +1a898548 : csinc w8, w10, w9, hi : csinc %w10 %w9 hi -> %w8 +1a916559 : csinc w25, w10, w17, vs : csinc %w10 %w17 vs -> %w25 +1a991624 : csinc w4, w17, w25, ne : csinc %w17 %w25 ne -> %w4 +1a889768 : csinc w8, w27, w8, ls : csinc %w27 %w8 ls -> %w8 +1a84a595 : csinc w21, w12, w4, ge : csinc %w12 %w4 ge -> %w21 +1a8c569c : csinc w28, w20, w12, pl : csinc %w20 %w12 pl -> %w28 +1a8a974e : csinc w14, w26, w10, ls : csinc %w26 %w10 ls -> %w14 +1a903605 : csinc w5, w16, w16, cc : csinc %w16 %w16 cc -> %w5 +1a86d586 : csinc w6, w12, w6, le : csinc %w12 %w6 le -> %w6 +1a920483 : csinc w3, w4, w18, eq : csinc %w4 %w18 eq -> %w3 +1a96c60d : csinc w13, w16, w22, gt : csinc %w16 %w22 gt -> %w13 +1a89046f : csinc w15, w3, w9, eq : csinc %w3 %w9 eq -> %w15 +9a904436 : csinc x22, x1, x16, mi : csinc %x1 %x16 mi -> %x22 +9a8ca682 : csinc x2, x20, x12, ge : csinc %x20 %x12 ge -> %x2 +9a84d4c1 : csinc x1, x6, x4, le : csinc %x6 %x4 le -> %x1 +9a8f17f2 : csinc x18, xzr, x15, ne : csinc %xzr %x15 ne -> %x18 +9a989796 : csinc x22, x28, x24, ls : csinc %x28 %x24 ls -> %x22 +9a8f17b6 : csinc x22, x29, x15, ne : csinc %x29 %x15 ne -> %x22 +9a8f16b1 : csinc x17, x21, x15, ne : csinc %x21 %x15 ne -> %x17 +9a8017a0 : csinc x0, x29, x0, ne : csinc %x29 %x0 ne -> %x0 +9a9755fe : csinc x30, x15, x23, pl : csinc %x15 %x23 pl -> %x30 +9a96d5c8 : csinc x8, x14, x22, le : csinc %x14 %x22 le -> %x8 +9a89c51c : csinc x28, x8, x9, gt : csinc %x8 %x9 gt -> %x28 +9a9eb46c : csinc x12, x3, x30, lt : csinc %x3 %x30 lt -> %x12 +9a8cc5d7 : csinc x23, x14, x12, gt : csinc %x14 %x12 gt -> %x23 +9a88372c : csinc x12, x25, x8, cc : csinc %x25 %x8 cc -> %x12 +9a9d149a : csinc x26, x4, x29, ne : csinc %x4 %x29 ne -> %x26 +9a95d43d : csinc x29, x1, x21, le : csinc %x1 %x21 le -> %x29 +9a98a576 : csinc x22, x11, x24, ge : csinc %x11 %x24 ge -> %x22 +9a80c4c6 : csinc x6, x6, x0, gt : csinc %x6 %x0 gt -> %x6 +9a84558d : csinc x13, x12, x4, pl : csinc %x12 %x4 pl -> %x13 +9a9fd647 : csinc x7, x18, xzr, le : csinc %x18 %xzr le -> %x7 +9a9e2456 : csinc x22, x2, x30, cs : csinc %x2 %x30 cs -> %x22 +9a9ca76f : csinc x15, x27, x28, ge : csinc %x27 %x28 ge -> %x15 +9a82b54a : csinc x10, x10, x2, lt : csinc %x10 %x2 lt -> %x10 +9a962453 : csinc x19, x2, x22, cs : csinc %x2 %x22 cs -> %x19 +9a86954f : csinc x15, x10, x6, ls : csinc %x10 %x6 ls -> %x15 +9a88346d : csinc x13, x3, x8, cc : csinc %x3 %x8 cc -> %x13 +9a898593 : csinc x19, x12, x9, hi : csinc %x12 %x9 hi -> %x19 +9a9f6719 : csinc x25, x24, xzr, vs : csinc %x24 %xzr vs -> %x25 +9a8f2594 : csinc x20, x12, x15, cs : csinc %x12 %x15 cs -> %x20 +9a90c5fe : csinc x30, x15, x16, gt : csinc %x15 %x16 gt -> %x30 +9a8974e4 : csinc x4, x7, x9, vc : csinc %x7 %x9 vc -> %x4 +9a97171a : csinc x26, x24, x23, ne : csinc %x24 %x23 ne -> %x26 +5a8cb0e3 : csinv w3, w7, w12, lt : csinv %w7 %w12 lt -> %w3 +5a92b0cd : csinv w13, w6, w18, lt : csinv %w6 %w18 lt -> %w13 +5a9a22ce : csinv w14, w22, w26, cs : csinv %w22 %w26 cs -> %w14 +5a8a634f : csinv w15, w26, w10, vs : csinv %w26 %w10 vs -> %w15 +5a9e82c5 : csinv w5, w22, w30, hi : csinv %w22 %w30 hi -> %w5 +5a9e427f : csinv wzr, w19, w30, mi : csinv %w19 %w30 mi -> %wzr +5a9ba042 : csinv w2, w2, w27, ge : csinv %w2 %w27 ge -> %w2 +5a9a41bd : csinv w29, w13, w26, mi : csinv %w13 %w26 mi -> %w29 +5a98218e : csinv w14, w12, w24, cs : csinv %w12 %w24 cs -> %w14 +5a844317 : csinv w23, w24, w4, mi : csinv %w24 %w4 mi -> %w23 +5a97931e : csinv w30, w24, w23, ls : csinv %w24 %w23 ls -> %w30 +5a99527c : csinv w28, w19, w25, pl : csinv %w19 %w25 pl -> %w28 +5a8a92a9 : csinv w9, w21, w10, ls : csinv %w21 %w10 ls -> %w9 +5a927191 : csinv w17, w12, w18, vc : csinv %w12 %w18 vc -> %w17 +5a8c731a : csinv w26, w24, w12, vc : csinv %w24 %w12 vc -> %w26 +5a99c3b8 : csinv w24, w29, w25, gt : csinv %w29 %w25 gt -> %w24 +5a8e6300 : csinv w0, w24, w14, vs : csinv %w24 %w14 vs -> %w0 +5a98923a : csinv w26, w17, w24, ls : csinv %w17 %w24 ls -> %w26 +5a873282 : csinv w2, w20, w7, cc : csinv %w20 %w7 cc -> %w2 +5a9f6357 : csinv w23, w26, wzr, vs : csinv %w26 %wzr vs -> %w23 +5a8912c9 : csinv w9, w22, w9, ne : csinv %w22 %w9 ne -> %w9 +5a8fd0f7 : csinv w23, w7, w15, le : csinv %w7 %w15 le -> %w23 +5a80d39d : csinv w29, w28, w0, le : csinv %w28 %w0 le -> %w29 +5a87401b : csinv w27, w0, w7, mi : csinv %w0 %w7 mi -> %w27 +5a973167 : csinv w7, w11, w23, cc : csinv %w11 %w23 cc -> %w7 +5a8f1304 : csinv w4, w24, w15, ne : csinv %w24 %w15 ne -> %w4 +5a8e7079 : csinv w25, w3, w14, vc : csinv %w3 %w14 vc -> %w25 +5a9f80d8 : csinv w24, w6, wzr, hi : csinv %w6 %wzr hi -> %w24 +5a9bd208 : csinv w8, w16, w27, le : csinv %w16 %w27 le -> %w8 +5a8ac358 : csinv w24, w26, w10, gt : csinv %w26 %w10 gt -> %w24 +5a9090c5 : csinv w5, w6, w16, ls : csinv %w6 %w16 ls -> %w5 +5a92d2dc : csinv w28, w22, w18, le : csinv %w22 %w18 le -> %w28 +da88d395 : csinv x21, x28, x8, le : csinv %x28 %x8 le -> %x21 +da82c0be : csinv x30, x5, x2, gt : csinv %x5 %x2 gt -> %x30 +da8133ff : csinv xzr, xzr, x1, cc : csinv %xzr %x1 cc -> %xzr +da85139a : csinv x26, x28, x5, ne : csinv %x28 %x5 ne -> %x26 +da88c28f : csinv x15, x20, x8, gt : csinv %x20 %x8 gt -> %x15 +da8250ea : csinv x10, x7, x2, pl : csinv %x7 %x2 pl -> %x10 +da94619f : csinv xzr, x12, x20, vs : csinv %x12 %x20 vs -> %xzr +da83411e : csinv x30, x8, x3, mi : csinv %x8 %x3 mi -> %x30 +da86a1eb : csinv x11, x15, x6, ge : csinv %x15 %x6 ge -> %x11 +da8da26b : csinv x11, x19, x13, ge : csinv %x19 %x13 ge -> %x11 +da8712b1 : csinv x17, x21, x7, ne : csinv %x21 %x7 ne -> %x17 +da8a03d4 : csinv x20, x30, x10, eq : csinv %x30 %x10 eq -> %x20 +da9e8104 : csinv x4, x8, x30, hi : csinv %x8 %x30 hi -> %x4 +da8480f9 : csinv x25, x7, x4, hi : csinv %x7 %x4 hi -> %x25 +da90407b : csinv x27, x3, x16, mi : csinv %x3 %x16 mi -> %x27 +da8022f7 : csinv x23, x23, x0, cs : csinv %x23 %x0 cs -> %x23 +da99d02a : csinv x10, x1, x25, le : csinv %x1 %x25 le -> %x10 +da8d7223 : csinv x3, x17, x13, vc : csinv %x17 %x13 vc -> %x3 +da9c728c : csinv x12, x20, x28, vc : csinv %x20 %x28 vc -> %x12 +da94b091 : csinv x17, x4, x20, lt : csinv %x4 %x20 lt -> %x17 +da8271c6 : csinv x6, x14, x2, vc : csinv %x14 %x2 vc -> %x6 +da9081ce : csinv x14, x14, x16, hi : csinv %x14 %x16 hi -> %x14 +da826074 : csinv x20, x3, x2, vs : csinv %x3 %x2 vs -> %x20 +da80b1fc : csinv x28, x15, x0, lt : csinv %x15 %x0 lt -> %x28 +da9832be : csinv x30, x21, x24, cc : csinv %x21 %x24 cc -> %x30 +da824308 : csinv x8, x24, x2, mi : csinv %x24 %x2 mi -> %x8 +da98920d : csinv x13, x16, x24, ls : csinv %x16 %x24 ls -> %x13 +da94d320 : csinv x0, x25, x20, le : csinv %x25 %x20 le -> %x0 +da8cc3b3 : csinv x19, x29, x12, gt : csinv %x29 %x12 gt -> %x19 +da9993b3 : csinv x19, x29, x25, ls : csinv %x29 %x25 ls -> %x19 +da9331aa : csinv x10, x13, x19, cc : csinv %x13 %x19 cc -> %x10 +da934097 : csinv x23, x4, x19, mi : csinv %x4 %x19 mi -> %x23 +5a8e2321 : csinv w1, w25, w14, cs : csinv %w25 %w14 cs -> %w1 +5a8d8129 : csinv w9, w9, w13, hi : csinv %w9 %w13 hi -> %w9 +5a9fa253 : csinv w19, w18, wzr, ge : csinv %w18 %wzr ge -> %w19 +5a9830a5 : csinv w5, w5, w24, cc : csinv %w5 %w24 cc -> %w5 +5a979188 : csinv w8, w12, w23, ls : csinv %w12 %w23 ls -> %w8 +5a8f71e3 : csinv w3, w15, w15, vc : csinv %w15 %w15 vc -> %w3 +5a8d50fa : csinv w26, w7, w13, pl : csinv %w7 %w13 pl -> %w26 +5a87b136 : csinv w22, w9, w7, lt : csinv %w9 %w7 lt -> %w22 +5a9b43e3 : csinv w3, wzr, w27, mi : csinv %wzr %w27 mi -> %w3 +5a89c3d9 : csinv w25, w30, w9, gt : csinv %w30 %w9 gt -> %w25 +5a9a01e3 : csinv w3, w15, w26, eq : csinv %w15 %w26 eq -> %w3 +5a9f015a : csinv w26, w10, wzr, eq : csinv %w10 %wzr eq -> %w26 +5a83a054 : csinv w20, w2, w3, ge : csinv %w2 %w3 ge -> %w20 +5a9113c1 : csinv w1, w30, w17, ne : csinv %w30 %w17 ne -> %w1 +5a925246 : csinv w6, w18, w18, pl : csinv %w18 %w18 pl -> %w6 +5a9030d8 : csinv w24, w6, w16, cc : csinv %w6 %w16 cc -> %w24 +5a9323a0 : csinv w0, w29, w19, cs : csinv %w29 %w19 cs -> %w0 +5a8b31fc : csinv w28, w15, w11, cc : csinv %w15 %w11 cc -> %w28 +5a9f1009 : csinv w9, w0, wzr, ne : csinv %w0 %wzr ne -> %w9 +5a8c33c8 : csinv w8, w30, w12, cc : csinv %w30 %w12 cc -> %w8 +5a9213db : csinv w27, w30, w18, ne : csinv %w30 %w18 ne -> %w27 +5a887387 : csinv w7, w28, w8, vc : csinv %w28 %w8 vc -> %w7 +5a97b3fd : csinv w29, wzr, w23, lt : csinv %wzr %w23 lt -> %w29 +5a8b22d9 : csinv w25, w22, w11, cs : csinv %w22 %w11 cs -> %w25 +5a8a5097 : csinv w23, w4, w10, pl : csinv %w4 %w10 pl -> %w23 +5a99d311 : csinv w17, w24, w25, le : csinv %w24 %w25 le -> %w17 +5a8b7178 : csinv w24, w11, w11, vc : csinv %w11 %w11 vc -> %w24 +5a92d31f : csinv wzr, w24, w18, le : csinv %w24 %w18 le -> %wzr +5a9753b5 : csinv w21, w29, w23, pl : csinv %w29 %w23 pl -> %w21 +5a9473d1 : csinv w17, w30, w20, vc : csinv %w30 %w20 vc -> %w17 +5a8ad1f4 : csinv w20, w15, w10, le : csinv %w15 %w10 le -> %w20 +5a842065 : csinv w5, w3, w4, cs : csinv %w3 %w4 cs -> %w5 +da85a141 : csinv x1, x10, x5, ge : csinv %x10 %x5 ge -> %x1 +da9352cd : csinv x13, x22, x19, pl : csinv %x22 %x19 pl -> %x13 +da944106 : csinv x6, x8, x20, mi : csinv %x8 %x20 mi -> %x6 +da8e22d0 : csinv x16, x22, x14, cs : csinv %x22 %x14 cs -> %x16 +da80d0f0 : csinv x16, x7, x0, le : csinv %x7 %x0 le -> %x16 +da805320 : csinv x0, x25, x0, pl : csinv %x25 %x0 pl -> %x0 +da8d320d : csinv x13, x16, x13, cc : csinv %x16 %x13 cc -> %x13 +da929277 : csinv x23, x19, x18, ls : csinv %x19 %x18 ls -> %x23 +da962140 : csinv x0, x10, x22, cs : csinv %x10 %x22 cs -> %x0 +da888115 : csinv x21, x8, x8, hi : csinv %x8 %x8 hi -> %x21 +da9771cd : csinv x13, x14, x23, vc : csinv %x14 %x23 vc -> %x13 +da94a021 : csinv x1, x1, x20, ge : csinv %x1 %x20 ge -> %x1 +da9330ea : csinv x10, x7, x19, cc : csinv %x7 %x19 cc -> %x10 +da9522ad : csinv x13, x21, x21, cs : csinv %x21 %x21 cs -> %x13 +da993394 : csinv x20, x28, x25, cc : csinv %x28 %x25 cc -> %x20 +da8a7328 : csinv x8, x25, x10, vc : csinv %x25 %x10 vc -> %x8 +da8a217e : csinv x30, x11, x10, cs : csinv %x11 %x10 cs -> %x30 +da8e5258 : csinv x24, x18, x14, pl : csinv %x18 %x14 pl -> %x24 +da9f104c : csinv x12, x2, xzr, ne : csinv %x2 %xzr ne -> %x12 +da85a294 : csinv x20, x20, x5, ge : csinv %x20 %x5 ge -> %x20 +da9c71a7 : csinv x7, x13, x28, vc : csinv %x13 %x28 vc -> %x7 +da868096 : csinv x22, x4, x6, hi : csinv %x4 %x6 hi -> %x22 +da832284 : csinv x4, x20, x3, cs : csinv %x20 %x3 cs -> %x4 +da9a414c : csinv x12, x10, x26, mi : csinv %x10 %x26 mi -> %x12 +da93b3bc : csinv x28, x29, x19, lt : csinv %x29 %x19 lt -> %x28 +da83a357 : csinv x23, x26, x3, ge : csinv %x26 %x3 ge -> %x23 +da8e8160 : csinv x0, x11, x14, hi : csinv %x11 %x14 hi -> %x0 +da8543d4 : csinv x20, x30, x5, mi : csinv %x30 %x5 mi -> %x20 +da9d41e6 : csinv x6, x15, x29, mi : csinv %x15 %x29 mi -> %x6 +da85b082 : csinv x2, x4, x5, lt : csinv %x4 %x5 lt -> %x2 +da8cb351 : csinv x17, x26, x12, lt : csinv %x26 %x12 lt -> %x17 +da92d26a : csinv x10, x19, x18, le : csinv %x19 %x18 le -> %x10 + diff --git a/suite/tests/api/ir_aarch64.c b/suite/tests/api/ir_aarch64.c index 9c415eeba61..345dad20966 100644 --- a/suite/tests/api/ir_aarch64.c +++ b/suite/tests/api/ir_aarch64.c @@ -118,6 +118,41 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) instr_destroy(dc, decin); } +static void +test_instr_enc(void *dc, uint opcode, instr_t *instr, const char *exp) +{ + instr_t *decin; + byte *pc; + char text[256]; + instr_disassemble_to_buffer(dc, instr, text, sizeof(text) - 1); + + if (instr_get_opcode(instr) != opcode) { + print("test for `%s` has failed (wrong opcode)\n", text); + ASSERT(false); // test has failed + } + + if(strcmp(text, exp) != 0) { + print("test for `%s` has failed (expected `%s`)\n", text, exp); + ASSERT(false); // test has failed + } + + if (!instr_is_encoding_possible(instr)) { + print("test for `%s` has failed (encoding is not possible)\n", text); + print("expected: %s\n", exp); + ASSERT(false); // test has failed + } + pc = instr_encode(dc, instr, buf); + decin = instr_create(dc); + decode(dc, buf, decin); + if(!instr_same(instr, decin)) { + print("test for `%s` has failed (decoded / encoding mismatch)\n", text); + ASSERT(false); // test has failed + } + + instr_destroy(dc, instr); + instr_destroy(dc, decin); +} + static void test_add(void *dc) { @@ -4332,6 +4367,617 @@ test_sys(void *dc) test_instr_encoding(dc, OP_sys, instr); } +static int conditions[] = { + DR_PRED_EQ, DR_PRED_NE, + DR_PRED_CS, DR_PRED_CC, + DR_PRED_MI, DR_PRED_PL, + DR_PRED_VS, DR_PRED_VC, + DR_PRED_HI, DR_PRED_LS, + DR_PRED_GE, DR_PRED_LT, + DR_PRED_GT, DR_PRED_LE, + DR_PRED_AL, DR_PRED_NV +}; + +static void +test_ccmn_imm(void *dc) +{ + /* ccmn , #, #, */ + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmn(dc, + opnd_create_reg(rn), + opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x\0", + get_register_name(rn), imm5, nzcv, k); + test_instr_enc(dc, OP_ccmn, instr, u); + } + } + } + } + /* ccmn , #, #, */ + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmn(dc, + opnd_create_reg(rn), + opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x\0", + get_register_name(rn), imm5, nzcv, k); + test_instr_enc(dc, OP_ccmn, instr, u); + } + } + } + } +} + +static void +test_ccmn_reg(void *dc) +{ + /* ccmn , , #, */ + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmn(dc, + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x\0", + get_register_name(rn), get_register_name(rm), + nzcv, k); + test_instr_enc(dc, OP_ccmn, instr, u); + } + } + } + } + /* ccmn , , #, */ + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmn(dc, + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x\0", + get_register_name(rn), get_register_name(rm), + nzcv, k); + test_instr_enc(dc, OP_ccmn, instr, u); + } + } + } + } +} + +static void +test_ccmp_imm(void *dc) +{ + /* ccmp , #, #, */ + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmp(dc, + opnd_create_reg(rn), + opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x\0", + get_register_name(rn), imm5, nzcv, k); + test_instr_enc(dc, OP_ccmp, instr, u); + } + } + } + } + /* ccmp , #, #, */ + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmp(dc, + opnd_create_reg(rn), + opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x\0", + get_register_name(rn), imm5, nzcv, k); + test_instr_enc(dc, OP_ccmp, instr, u); + } + } + } + } +} + +static void +test_ccmp_reg(void *dc) +{ + /* ccmp , , #, */ + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmp(dc, + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x\0", + get_register_name(rn), get_register_name(rm), + nzcv, k); + test_instr_enc(dc, OP_ccmp, instr, u); + } + } + } + } + /* ccmp , , #, */ + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_ccmp(dc, + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x\0", + get_register_name(rn), get_register_name(rm), + nzcv, k); + test_instr_enc(dc, OP_ccmp, instr, u); + } + } + } + } +} + +static void +test_cinc(void *dc) +{ + /* cinc , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cinc(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } + } + + /* cinc , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cinc(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } + } +} + +static void +test_cinv(void *dc) +{ + /* cinv , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cinv(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } + } + + /* cinv , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cinv(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } + } +} + +static void +test_cneg(void *dc) +{ + /* cneg , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cneg(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csneg, instr, u); + } + } + } + + /* cneg , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cneg(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + test_instr_enc(dc, OP_csneg, instr, u); + } + } + } +} + +static void +test_csel(void *dc) +{ + /* csel , , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csel(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csel, instr, u); + } + } + } + } + + /* csel , , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csel(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csel, instr, u); + } + } + } + } +} + +static void +test_cset(void *dc) +{ + /* cset , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cset(dc, + opnd_create_reg(rd), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%xzr %%xzr $0x%02x -> %%%s", + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } + + /* cset , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_cset(dc, + opnd_create_reg(rd), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%wzr %%wzr $0x%02x -> %%%s", + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } +} + +static void +test_csetm(void *dc) +{ + /* csetm , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csetm(dc, + opnd_create_reg(rd), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%xzr %%xzr $0x%02x -> %%%s", + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } + + /* csetm , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1101; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csetm(dc, + opnd_create_reg(rd), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%wzr %%wzr $0x%02x -> %%%s", + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } +} + +static void +test_csinc(void *dc) +{ + /* csinc , , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csinc(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } + } + } + + /* csinc , , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csinc(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); + } + } + } + } +} + +static void +test_csinv(void *dc) +{ + /* csinv , , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csinv(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } + } + } + + /* csinv , , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csinv(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csinv, instr, u); + } + } + } + } +} + +static void +test_csneg(void *dc) +{ + /* csneg , , , */ + for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { continue; } + for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { continue; } + for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csneg(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csneg, instr, u); + } + } + } + } + + /* csneg , , , */ + for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { continue; } + for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { continue; } + for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { continue; } + for (int k = 0b0000; k <= 0b1111; k++) { + int cond = conditions[k]; + instr_t *instr = INSTR_CREATE_csneg(dc, + opnd_create_reg(rd), + opnd_create_reg(rn), + opnd_create_reg(rm), + opnd_create_cond(cond)); + char u[256]; + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); + test_instr_enc(dc, OP_csneg, instr, u); + } + } + } + } +} + int main(int argc, char *argv[]) { @@ -4395,6 +5041,45 @@ main(int argc, char *argv[]) test_sys(dcontext); print("test_sys complete\n"); + test_ccmn_imm(dcontext); + print("test_ccmn_imm complete\n"); + + test_ccmn_reg(dcontext); + print("test_ccmn_reg complete\n"); + + test_ccmp_imm(dcontext); + print("test_ccmp_imm complete\n"); + + test_ccmp_reg(dcontext); + print("test_ccmp_reg complete\n"); + + test_cinc(dcontext); + print("test_cinc complete\n"); + + test_cinv(dcontext); + print("test_cinv complete\n"); + + test_cneg(dcontext); + print("test_cneg complete\n"); + + test_csel(dcontext); + print("test_csel complete\n"); + + test_cset(dcontext); + print("test_cset complete\n"); + + test_csetm(dcontext); + print("test_csetm complete\n"); + + test_csinc(dcontext); + print("test_csinc complete\n"); + + test_csinv(dcontext); + print("test_csinv complete\n"); + + test_csneg(dcontext); + print("test_csneg complete\n"); + print("All tests complete\n"); #ifndef STANDALONE_DECODER dr_standalone_exit(); diff --git a/suite/tests/api/ir_aarch64.expect b/suite/tests/api/ir_aarch64.expect index 6b605572997..b994cab3341 100644 --- a/suite/tests/api/ir_aarch64.expect +++ b/suite/tests/api/ir_aarch64.expect @@ -837,4 +837,17 @@ sys $0x1bd9 (%x29)[1byte] sys $0x1bf1 (%x30)[1byte] sys $0x1ba9 (%x1)[1byte] test_sys complete +test_ccmn_imm complete +test_ccmn_reg complete +test_ccmp_imm complete +test_ccmp_reg complete +test_cinc complete +test_cinv complete +test_cneg complete +test_csel complete +test_cset complete +test_csetm complete +test_csinc complete +test_csinv complete +test_csneg complete All tests complete From 08ce2c47616453f248f92e58a01172a84d46696e Mon Sep 17 00:00:00 2001 From: Yury Khrustalev Date: Thu, 29 Oct 2020 13:27:26 +0000 Subject: [PATCH 02/10] i#2440: Fix formatting issues --- core/ir/aarch64/instr_create.h | 14 +- core/ir/opnd_shared.c | 48 +-- suite/tests/api/ir_aarch64.c | 702 ++++++++++++++++++--------------- 3 files changed, 399 insertions(+), 365 deletions(-) diff --git a/core/ir/aarch64/instr_create.h b/core/ir/aarch64/instr_create.h index 2244abecbf4..e837a487b69 100644 --- a/core/ir/aarch64/instr_create.h +++ b/core/ir/aarch64/instr_create.h @@ -2613,7 +2613,7 @@ enum { * (use opnd_create_cond(val) to create the operand). */ #define INSTR_CREATE_cinv(dc, Rd, Rn, cond) \ - instr_create_1dst_3src(dc, OP_csinv, Rd, Rn, Rn, opnd_invert_cond(cond)) + instr_create_1dst_3src(dc, OP_csinv, Rd, Rn, Rn, opnd_invert_cond(cond)) /** * Creates a CNEG (Conditional Negate) instruction. @@ -2645,9 +2645,9 @@ enum { * \param cond A 4-bit immediate value for condition * (use opnd_create_cond(val) to create the operand). */ -#define INSTR_CREATE_cset(dc, Rd, cond) \ - instr_create_1dst_3src(dc, OP_csinc, Rd, \ - OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), opnd_invert_cond(cond)) +#define INSTR_CREATE_cset(dc, Rd, cond) \ + instr_create_1dst_3src(dc, OP_csinc, Rd, OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), \ + opnd_invert_cond(cond)) /** * Creates a CSETM (Conditional Set Mask) instruction. @@ -2656,9 +2656,9 @@ enum { * \param cond A 4-bit immediate value for condition * (use opnd_create_cond(val) to create the operand). */ -#define INSTR_CREATE_csetm(dc, Rd, cond) \ - instr_create_1dst_3src(dc, OP_csinv, Rd, \ - OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), opnd_invert_cond(cond)) +#define INSTR_CREATE_csetm(dc, Rd, cond) \ + instr_create_1dst_3src(dc, OP_csinv, Rd, OPND_CREATE_ZR(Rd), OPND_CREATE_ZR(Rd), \ + opnd_invert_cond(cond)) /** * Creates a CSINC (Conditional Select Increment) instruction. diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c index 66d8bca20ce..57c9b29191a 100644 --- a/core/ir/opnd_shared.c +++ b/core/ir/opnd_shared.c @@ -750,38 +750,22 @@ opnd_create_cond(int cond) /* FIXME i#1569: Move definition of dr_pred_type_t to opnd.h for AArch64 * to avoid using int instead of dr_pred_type_t */ switch (cond) { - case DR_PRED_EQ: - return opnd_create_immed_uint(0b0000, OPSZ_4b); - case DR_PRED_NE: - return opnd_create_immed_uint(0b0001, OPSZ_4b); - case DR_PRED_CS: - return opnd_create_immed_uint(0b0010, OPSZ_4b); - case DR_PRED_CC: - return opnd_create_immed_uint(0b0011, OPSZ_4b); - case DR_PRED_MI: - return opnd_create_immed_uint(0b0100, OPSZ_4b); - case DR_PRED_PL: - return opnd_create_immed_uint(0b0101, OPSZ_4b); - case DR_PRED_VS: - return opnd_create_immed_uint(0b0110, OPSZ_4b); - case DR_PRED_VC: - return opnd_create_immed_uint(0b0111, OPSZ_4b); - case DR_PRED_HI: - return opnd_create_immed_uint(0b1000, OPSZ_4b); - case DR_PRED_LS: - return opnd_create_immed_uint(0b1001, OPSZ_4b); - case DR_PRED_GE: - return opnd_create_immed_uint(0b1010, OPSZ_4b); - case DR_PRED_LT: - return opnd_create_immed_uint(0b1011, OPSZ_4b); - case DR_PRED_GT: - return opnd_create_immed_uint(0b1100, OPSZ_4b); - case DR_PRED_LE: - return opnd_create_immed_uint(0b1101, OPSZ_4b); - case DR_PRED_AL: - return opnd_create_immed_uint(0b1110, OPSZ_4b); - case DR_PRED_NV: - return opnd_create_immed_uint(0b1111, OPSZ_4b); + case DR_PRED_EQ: return opnd_create_immed_uint(0b0000, OPSZ_4b); + case DR_PRED_NE: return opnd_create_immed_uint(0b0001, OPSZ_4b); + case DR_PRED_CS: return opnd_create_immed_uint(0b0010, OPSZ_4b); + case DR_PRED_CC: return opnd_create_immed_uint(0b0011, OPSZ_4b); + case DR_PRED_MI: return opnd_create_immed_uint(0b0100, OPSZ_4b); + case DR_PRED_PL: return opnd_create_immed_uint(0b0101, OPSZ_4b); + case DR_PRED_VS: return opnd_create_immed_uint(0b0110, OPSZ_4b); + case DR_PRED_VC: return opnd_create_immed_uint(0b0111, OPSZ_4b); + case DR_PRED_HI: return opnd_create_immed_uint(0b1000, OPSZ_4b); + case DR_PRED_LS: return opnd_create_immed_uint(0b1001, OPSZ_4b); + case DR_PRED_GE: return opnd_create_immed_uint(0b1010, OPSZ_4b); + case DR_PRED_LT: return opnd_create_immed_uint(0b1011, OPSZ_4b); + case DR_PRED_GT: return opnd_create_immed_uint(0b1100, OPSZ_4b); + case DR_PRED_LE: return opnd_create_immed_uint(0b1101, OPSZ_4b); + case DR_PRED_AL: return opnd_create_immed_uint(0b1110, OPSZ_4b); + case DR_PRED_NV: return opnd_create_immed_uint(0b1111, OPSZ_4b); default: CLIENT_ASSERT(false, "invalid condition constant"); return opnd_create_null(); diff --git a/suite/tests/api/ir_aarch64.c b/suite/tests/api/ir_aarch64.c index 345dad20966..b83d3bf520b 100644 --- a/suite/tests/api/ir_aarch64.c +++ b/suite/tests/api/ir_aarch64.c @@ -131,7 +131,7 @@ test_instr_enc(void *dc, uint opcode, instr_t *instr, const char *exp) ASSERT(false); // test has failed } - if(strcmp(text, exp) != 0) { + if (strcmp(text, exp) != 0) { print("test for `%s` has failed (expected `%s`)\n", text, exp); ASSERT(false); // test has failed } @@ -144,7 +144,7 @@ test_instr_enc(void *dc, uint opcode, instr_t *instr, const char *exp) pc = instr_encode(dc, instr, buf); decin = instr_create(dc); decode(dc, buf, decin); - if(!instr_same(instr, decin)) { + if (!instr_same(instr, decin)) { print("test for `%s` has failed (decoded / encoding mismatch)\n", text); ASSERT(false); // test has failed } @@ -4367,55 +4367,49 @@ test_sys(void *dc) test_instr_encoding(dc, OP_sys, instr); } -static int conditions[] = { - DR_PRED_EQ, DR_PRED_NE, - DR_PRED_CS, DR_PRED_CC, - DR_PRED_MI, DR_PRED_PL, - DR_PRED_VS, DR_PRED_VC, - DR_PRED_HI, DR_PRED_LS, - DR_PRED_GE, DR_PRED_LT, - DR_PRED_GT, DR_PRED_LE, - DR_PRED_AL, DR_PRED_NV -}; +static int conditions[] = { DR_PRED_EQ, DR_PRED_NE, DR_PRED_CS, DR_PRED_CC, + DR_PRED_MI, DR_PRED_PL, DR_PRED_VS, DR_PRED_VC, + DR_PRED_HI, DR_PRED_LS, DR_PRED_GE, DR_PRED_LT, + DR_PRED_GT, DR_PRED_LE, DR_PRED_AL, DR_PRED_NV }; static void test_ccmn_imm(void *dc) { /* ccmn , #, #, */ - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { + continue; + } + for (int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmn(dc, - opnd_create_reg(rn), - opnd_create_immed_uint(imm5, OPSZ_5b), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmn( + dc, opnd_create_reg(rn), opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x\0", - get_register_name(rn), imm5, nzcv, k); + sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x", + get_register_name(rn), imm5, nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } } } /* ccmn , #, #, */ - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { + continue; + } + for (int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmn(dc, - opnd_create_reg(rn), - opnd_create_immed_uint(imm5, OPSZ_5b), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmn( + dc, opnd_create_reg(rn), opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x\0", - get_register_name(rn), imm5, nzcv, k); + sprintf(u, "ccmn %%%s $0x%02x $0x%02x $0x%02x", + get_register_name(rn), imm5, nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } @@ -4427,44 +4421,46 @@ static void test_ccmn_reg(void *dc) { /* ccmn , , #, */ - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { + continue; + } + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmn(dc, - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmn( + dc, opnd_create_reg(rn), opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x\0", - get_register_name(rn), get_register_name(rm), - nzcv, k); + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", + get_register_name(rn), get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } } } /* ccmn , , #, */ - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { + continue; + } + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmn(dc, - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmn( + dc, opnd_create_reg(rn), opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x\0", - get_register_name(rn), get_register_name(rm), - nzcv, k); + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", + get_register_name(rn), get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } @@ -4476,40 +4472,40 @@ static void test_ccmp_imm(void *dc) { /* ccmp , #, #, */ - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { + continue; + } + for (int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmp(dc, - opnd_create_reg(rn), - opnd_create_immed_uint(imm5, OPSZ_5b), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmp( + dc, opnd_create_reg(rn), opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x\0", - get_register_name(rn), imm5, nzcv, k); + sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x", + get_register_name(rn), imm5, nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } } } /* ccmp , #, #, */ - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { + continue; + } + for (int imm5 = 0b00000; imm5 <= 0b11111; imm5++) { + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmp(dc, - opnd_create_reg(rn), - opnd_create_immed_uint(imm5, OPSZ_5b), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmp( + dc, opnd_create_reg(rn), opnd_create_immed_uint(imm5, OPSZ_5b), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x\0", - get_register_name(rn), imm5, nzcv, k); + sprintf(u, "ccmp %%%s $0x%02x $0x%02x $0x%02x", + get_register_name(rn), imm5, nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } @@ -4521,44 +4517,46 @@ static void test_ccmp_reg(void *dc) { /* ccmp , , #, */ - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { + if (rm == DR_REG_XSP) { + continue; + } + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmp(dc, - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmp( + dc, opnd_create_reg(rn), opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x\0", - get_register_name(rn), get_register_name(rm), - nzcv, k); + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", + get_register_name(rn), get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } } } /* ccmp , , #, */ - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for(int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { + if (rm == DR_REG_WSP) { + continue; + } + for (int nzcv = 0b0000; nzcv <= 0b1111; nzcv++) { for (int k = 0b0000; k <= 0b1111; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_ccmp(dc, - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_immed_uint(nzcv, OPSZ_4b), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_ccmp( + dc, opnd_create_reg(rn), opnd_create_reg(rm), + opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x\0", - get_register_name(rn), get_register_name(rm), - nzcv, k); + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", + get_register_name(rn), get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } @@ -4570,40 +4568,46 @@ static void test_cinc(void *dc) { /* cinc , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { + if (rn == DR_REG_XSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cinc(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cinc( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } } /* cinc , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { + if (rn == DR_REG_WSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cinc(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cinc( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4614,40 +4618,46 @@ static void test_cinv(void *dc) { /* cinv , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1101; k++) { + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd += 2) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X1; rn <= DR_REG_XZR; rn += 2) { + if (rn == DR_REG_XSP) { + continue; + } + for (int k = 0b0000; k <= 0b1101; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cinv(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cinv( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } } /* cinv , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1101; k++) { + for (reg_id_t rd = DR_REG_W1; rd <= DR_REG_WZR; rd += 2) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn += 2) { + if (rn == DR_REG_WSP) { + continue; + } + for (int k = 0b0000; k <= 0b1101; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cinv(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cinv( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4658,40 +4668,46 @@ static void test_cneg(void *dc) { /* cneg , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1101; k++) { + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd += 2) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X1; rn <= DR_REG_XZR; rn += 2) { + if (rn == DR_REG_XSP) { + continue; + } + for (int k = 0b0001; k <= 0b1101; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cneg(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cneg( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } } /* cneg , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1101; k++) { + for (reg_id_t rd = DR_REG_W1; rd <= DR_REG_WZR; rd += 2) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn += 2) { + if (rn == DR_REG_WSP) { + continue; + } + for (int k = 0b0001; k <= 0b1101; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cneg(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_cond(cond)); + instr_t *instr = INSTR_CREATE_cneg( + dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rn), - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rn), + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } @@ -4702,23 +4718,27 @@ static void test_csel(void *dc) { /* csel , , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_X1; rd <= DR_REG_XZR; rd+=3) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn+=2) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X1; rm <= DR_REG_XZR; rm+=2) { + if (rm == DR_REG_XSP) { + continue; + } + for (int k = 0b0001; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csel(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csel(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csel, instr, u); } } @@ -4726,23 +4746,27 @@ test_csel(void *dc) } /* csel , , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_W1; rd <= DR_REG_WZR; rd+=3) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn+=2) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W1; rm <= DR_REG_WZR; rm+=2) { + if (rm == DR_REG_WSP) { + continue; + } + for (int k = 0b0001; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csel(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csel(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csel, instr, u); } } @@ -4754,33 +4778,33 @@ static void test_cset(void *dc) { /* cset , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cset(dc, - opnd_create_reg(rd), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_cset(dc, opnd_create_reg(rd), opnd_create_cond(cond)); char u[256]; sprintf(u, "csinc %%xzr %%xzr $0x%02x -> %%%s", - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, - get_register_name(rd)); - test_instr_enc(dc, OP_csinc, instr, u); + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); + test_instr_enc(dc, OP_csinc, instr, u); } } /* cset , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { if (rd == DR_REG_WSP) { continue; } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_cset(dc, - opnd_create_reg(rd), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_cset(dc, opnd_create_reg(rd), opnd_create_cond(cond)); char u[256]; sprintf(u, "csinc %%wzr %%wzr $0x%02x -> %%%s", - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, - get_register_name(rd)); + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4790,33 +4814,35 @@ static void test_csetm(void *dc) { /* csetm , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { + if (rd == DR_REG_XSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csetm(dc, - opnd_create_reg(rd), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csetm(dc, opnd_create_reg(rd), opnd_create_cond(cond)); char u[256]; sprintf(u, "csinv %%xzr %%xzr $0x%02x -> %%%s", - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, - get_register_name(rd)); + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } /* csetm , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { + if (rd == DR_REG_WSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csetm(dc, - opnd_create_reg(rd), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csetm(dc, opnd_create_reg(rd), opnd_create_cond(cond)); char u[256]; sprintf(u, "csinv %%wzr %%wzr $0x%02x -> %%%s", - opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, - get_register_name(rd)); + opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, + get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4826,23 +4852,27 @@ static void test_csinc(void *dc) { /* csinc , , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd += 2) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X1; rn <= DR_REG_XZR; rn += 3) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm += 2) { + if (rm == DR_REG_XSP) { + continue; + } + for (int k = 0b0001; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csinc(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csinc(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4850,23 +4880,27 @@ test_csinc(void *dc) } /* csinc , , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd += 2) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W1; rn <= DR_REG_WZR; rn += 3) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm += 2) { + if (rm == DR_REG_WSP) { + continue; + } + for (int k = 0b0001; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csinc(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csinc(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4878,23 +4912,27 @@ static void test_csinv(void *dc) { /* csinv , , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd += 2) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X1; rn <= DR_REG_XZR; rn += 3) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm += 2) { + if (rm == DR_REG_XSP) { + continue; + } + for (int k = 0b0010; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csinv(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csinv(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4902,23 +4940,27 @@ test_csinv(void *dc) } /* csinv , , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd += 2) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W1; rn <= DR_REG_WZR; rn += 3) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm += 2) { + if (rm == DR_REG_WSP) { + continue; + } + for (int k = 0b0010; k <= 0b1111; k += 2) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csinv(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csinv(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4930,23 +4972,27 @@ static void test_csneg(void *dc) { /* csneg , , , */ - for(reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd++) { - if (rd == DR_REG_XSP) { continue; } - for(reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn++) { - if (rn == DR_REG_XSP) { continue; } - for(reg_id_t rm = DR_REG_X0; rm <= DR_REG_XZR; rm++) { - if (rm == DR_REG_XSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_X0; rd <= DR_REG_XZR; rd += 2) { + if (rd == DR_REG_XSP) { + continue; + } + for (reg_id_t rn = DR_REG_X1; rn <= DR_REG_XZR; rn += 2) { + if (rn == DR_REG_XSP) { + continue; + } + for (reg_id_t rm = DR_REG_X2; rm <= DR_REG_XZR; rm += 2) { + if (rm == DR_REG_XSP) { + continue; + } + for (int k = 0b0010; k <= 0b1111; k += 3) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csneg(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csneg(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } @@ -4954,23 +5000,27 @@ test_csneg(void *dc) } /* csneg , , , */ - for(reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } - for(reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn++) { - if (rn == DR_REG_WSP) { continue; } - for(reg_id_t rm = DR_REG_W0; rm <= DR_REG_WZR; rm++) { - if (rm == DR_REG_WSP) { continue; } - for (int k = 0b0000; k <= 0b1111; k++) { + for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd += 2) { + if (rd == DR_REG_WSP) { + continue; + } + for (reg_id_t rn = DR_REG_W1; rn <= DR_REG_WZR; rn += 2) { + if (rn == DR_REG_WSP) { + continue; + } + for (reg_id_t rm = DR_REG_W3; rm <= DR_REG_WZR; rm += 2) { + if (rm == DR_REG_WSP) { + continue; + } + for (int k = 0b0001; k <= 0b1111; k += 3) { int cond = conditions[k]; - instr_t *instr = INSTR_CREATE_csneg(dc, - opnd_create_reg(rd), - opnd_create_reg(rn), - opnd_create_reg(rm), - opnd_create_cond(cond)); + instr_t *instr = + INSTR_CREATE_csneg(dc, opnd_create_reg(rd), opnd_create_reg(rn), + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s\0", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", + get_register_name(rn), get_register_name(rm), + k, get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } From 3c13a137b05b75ddf4cee40abc00f07b218a1a2a Mon Sep 17 00:00:00 2001 From: Yury Khrustalev Date: Thu, 29 Oct 2020 14:09:06 +0000 Subject: [PATCH 03/10] i#2440: Fix more formatting issues --- suite/tests/api/ir_aarch64.c | 80 +++++++++++++++++------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/suite/tests/api/ir_aarch64.c b/suite/tests/api/ir_aarch64.c index b83d3bf520b..42cbe927f6b 100644 --- a/suite/tests/api/ir_aarch64.c +++ b/suite/tests/api/ir_aarch64.c @@ -4436,8 +4436,8 @@ test_ccmn_reg(void *dc) dc, opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", - get_register_name(rn), get_register_name(rm), nzcv, k); + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", get_register_name(rn), + get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } @@ -4459,8 +4459,8 @@ test_ccmn_reg(void *dc) dc, opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", - get_register_name(rn), get_register_name(rm), nzcv, k); + sprintf(u, "ccmn %%%s %%%s $0x%02x $0x%02x", get_register_name(rn), + get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmn, instr, u); } } @@ -4532,8 +4532,8 @@ test_ccmp_reg(void *dc) dc, opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", - get_register_name(rn), get_register_name(rm), nzcv, k); + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", get_register_name(rn), + get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } @@ -4555,8 +4555,8 @@ test_ccmp_reg(void *dc) dc, opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_immed_uint(nzcv, OPSZ_4b), opnd_create_cond(cond)); char u[256]; - sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", - get_register_name(rn), get_register_name(rm), nzcv, k); + sprintf(u, "ccmp %%%s %%%s $0x%02x $0x%02x", get_register_name(rn), + get_register_name(rm), nzcv, k); test_instr_enc(dc, OP_ccmp, instr, u); } } @@ -4581,7 +4581,7 @@ test_cinc(void *dc) instr_t *instr = INSTR_CREATE_cinc( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4604,7 +4604,7 @@ test_cinc(void *dc) instr_t *instr = INSTR_CREATE_cinc( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4631,7 +4631,7 @@ test_cinv(void *dc) instr_t *instr = INSTR_CREATE_cinv( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4654,7 +4654,7 @@ test_cinv(void *dc) instr_t *instr = INSTR_CREATE_cinv( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4681,7 +4681,7 @@ test_cneg(void *dc) instr_t *instr = INSTR_CREATE_cneg( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4704,7 +4704,7 @@ test_cneg(void *dc) instr_t *instr = INSTR_CREATE_cneg( dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rn), opnd_get_cond(opnd_invert_cond(opnd_create_cond(cond))) - 1, get_register_name(rd)); @@ -4718,11 +4718,11 @@ static void test_csel(void *dc) { /* csel , , , */ - for (reg_id_t rd = DR_REG_X1; rd <= DR_REG_XZR; rd+=3) { + for (reg_id_t rd = DR_REG_X1; rd <= DR_REG_XZR; rd += 3) { if (rd == DR_REG_XSP) { continue; } - for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn+=2) { + for (reg_id_t rn = DR_REG_X0; rn <= DR_REG_XZR; rn += 2) { if (rn == DR_REG_XSP) { continue; } @@ -4736,9 +4736,8 @@ test_csel(void *dc) INSTR_CREATE_csel(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csel, instr, u); } } @@ -4746,11 +4745,11 @@ test_csel(void *dc) } /* csel , , , */ - for (reg_id_t rd = DR_REG_W1; rd <= DR_REG_WZR; rd+=3) { + for (reg_id_t rd = DR_REG_W1; rd <= DR_REG_WZR; rd += 3) { if (rd == DR_REG_WSP) { continue; } - for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn+=2) { + for (reg_id_t rn = DR_REG_W0; rn <= DR_REG_WZR; rn += 2) { if (rn == DR_REG_WSP) { continue; } @@ -4764,9 +4763,8 @@ test_csel(void *dc) INSTR_CREATE_csel(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csel %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csel, instr, u); } } @@ -4796,7 +4794,9 @@ test_cset(void *dc) /* cset , */ for (reg_id_t rd = DR_REG_W0; rd <= DR_REG_WZR; rd++) { - if (rd == DR_REG_WSP) { continue; } + if (rd == DR_REG_WSP) { + continue; + } for (int k = 0b0000; k <= 0b1101; k++) { int cond = conditions[k]; instr_t *instr = @@ -4870,9 +4870,8 @@ test_csinc(void *dc) INSTR_CREATE_csinc(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4898,9 +4897,8 @@ test_csinc(void *dc) INSTR_CREATE_csinc(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinc %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csinc, instr, u); } } @@ -4930,9 +4928,8 @@ test_csinv(void *dc) INSTR_CREATE_csinv(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4958,9 +4955,8 @@ test_csinv(void *dc) INSTR_CREATE_csinv(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csinv, instr, u); } } @@ -4990,9 +4986,8 @@ test_csneg(void *dc) INSTR_CREATE_csneg(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } @@ -5018,9 +5013,8 @@ test_csneg(void *dc) INSTR_CREATE_csneg(dc, opnd_create_reg(rd), opnd_create_reg(rn), opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; - sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", - get_register_name(rn), get_register_name(rm), - k, get_register_name(rd)); + sprintf(u, "csneg %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), + get_register_name(rm), k, get_register_name(rd)); test_instr_enc(dc, OP_csneg, instr, u); } } From 16f30baf6257a6f176356e876bbe45762f83d961 Mon Sep 17 00:00:00 2001 From: Yury Khrustalev Date: Thu, 29 Oct 2020 14:59:35 +0000 Subject: [PATCH 04/10] i#2440: Fix more formatting issues --- suite/tests/api/ir_aarch64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/suite/tests/api/ir_aarch64.c b/suite/tests/api/ir_aarch64.c index 42cbe927f6b..807c4eee895 100644 --- a/suite/tests/api/ir_aarch64.c +++ b/suite/tests/api/ir_aarch64.c @@ -4726,7 +4726,7 @@ test_csel(void *dc) if (rn == DR_REG_XSP) { continue; } - for (reg_id_t rm = DR_REG_X1; rm <= DR_REG_XZR; rm+=2) { + for (reg_id_t rm = DR_REG_X1; rm <= DR_REG_XZR; rm += 2) { if (rm == DR_REG_XSP) { continue; } @@ -4753,7 +4753,7 @@ test_csel(void *dc) if (rn == DR_REG_WSP) { continue; } - for (reg_id_t rm = DR_REG_W1; rm <= DR_REG_WZR; rm+=2) { + for (reg_id_t rm = DR_REG_W1; rm <= DR_REG_WZR; rm += 2) { if (rm == DR_REG_WSP) { continue; } @@ -4953,7 +4953,7 @@ test_csinv(void *dc) int cond = conditions[k]; instr_t *instr = INSTR_CREATE_csinv(dc, opnd_create_reg(rd), opnd_create_reg(rn), - opnd_create_reg(rm), opnd_create_cond(cond)); + opnd_create_reg(rm), opnd_create_cond(cond)); char u[256]; sprintf(u, "csinv %%%s %%%s $0x%02x -> %%%s", get_register_name(rn), get_register_name(rm), k, get_register_name(rd)); From 4d8f379b22b4c23e1179208e916a07e1793fe899 Mon Sep 17 00:00:00 2001 From: Derek Bruening Date: Thu, 29 Oct 2020 23:07:57 -0400 Subject: [PATCH 05/10] i#1569 AArch64: Enable -steal_reg_at_reset for AArch64 (#4503) Enables the diagnostic option -steal_reg_at_reset for AArch64, generalizing the existing ARM code. Switches -reset_at_fragment_count to work in release build by using the sum of the release stats num_bbs and num_traces. Adds a release-build syslog for an informational notification when any reset occurs. Adds a test of -steal_reg_at_reset. Includes the key fix for #4497 since it could show up on the new test or with use of this now-enabled option; the full fix for that with better tests for its code path will come in separately. Issue: #1569, #4497 --- core/arch/arch.c | 11 ++++++++--- core/fcache.c | 12 +++++++----- core/fragment.c | 18 +++++++----------- core/synch.c | 7 +++++-- core/win32/events.mc | 8 ++++++++ suite/tests/CMakeLists.txt | 11 +++++++++++ 6 files changed, 46 insertions(+), 21 deletions(-) diff --git a/core/arch/arch.c b/core/arch/arch.c index 7ef2b0e61ce..bd93ce0cd1a 100644 --- a/core/arch/arch.c +++ b/core/arch/arch.c @@ -593,26 +593,31 @@ arch_reset_stolen_reg(void) * shared_code, which means we do not need to update each thread's pointers * to gencode stored in TLS. */ +# ifdef ARM dr_isa_mode_t old_mode; - dcontext_t *dcontext; -# ifdef AARCH64 - ASSERT_NOT_IMPLEMENTED(false); /* FIXME i#1569 */ # endif + dcontext_t *dcontext; if (DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset) == dr_reg_stolen) return; SYSLOG_INTERNAL_INFO("swapping stolen reg from %s to %s", reg_names[dr_reg_stolen], reg_names[DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset)]); dcontext = get_thread_private_dcontext(); ASSERT(dcontext != NULL); +# ifdef ARM dr_set_isa_mode(dcontext, DR_ISA_ARM_THUMB, &old_mode); +# endif SELF_UNPROTECT_DATASEC(DATASEC_RARELY_PROT); dr_reg_stolen = DR_REG_R0 + INTERNAL_OPTION(steal_reg_at_reset); ASSERT(dr_reg_stolen >= DR_REG_STOLEN_MIN && dr_reg_stolen <= DR_REG_STOLEN_MAX); + protect_generated_code(shared_code, WRITABLE); shared_gencode_emit(shared_code); + protect_generated_code(shared_code, READONLY); SELF_PROTECT_DATASEC(DATASEC_RARELY_PROT); +# ifdef ARM dr_set_isa_mode(dcontext, old_mode, NULL); +# endif DOLOG(3, LOG_EMIT, { dump_emitted_routines(GLOBAL_DCONTEXT, GLOBAL, "swap stolen reg", shared_code, shared_code->gen_end_pc); diff --git a/core/fcache.c b/core/fcache.c index b36b9e1e5b5..4bc641cac8f 100644 --- a/core/fcache.c +++ b/core/fcache.c @@ -4228,10 +4228,12 @@ fcache_reset_all_caches_proactively(uint target) LOG(GLOBAL, LOG_CACHE, 2, "fcache_reset_all_caches_proactively: walking the threads\n"); - DOSTATS({ - SYSLOG_INTERNAL_INFO("proactive reset @ %d fragments", - GLOBAL_STAT(num_fragments)); - }); + char buf[16]; + snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%d", + GLOBAL_STAT(num_bbs) + GLOBAL_STAT(num_traces)); + NULL_TERMINATE_BUFFER(buf); + SYSLOG(SYSLOG_INFORMATION, INFO_RESET_IN_PROGRESS, 3, buf, get_application_name(), + get_application_pid()); /* reset_free and reset_init may write to .data. * All threads are suspended so no security risk. @@ -4241,7 +4243,7 @@ fcache_reset_all_caches_proactively(uint target) /* no lock needed */ dynamo_resetting = true; - IF_ARM({ + IF_AARCHXX({ if (INTERNAL_OPTION(steal_reg_at_reset) != 0) arch_reset_stolen_reg(); }); diff --git a/core/fragment.c b/core/fragment.c index 39c38d170d5..6725b01462c 100644 --- a/core/fragment.c +++ b/core/fragment.c @@ -2403,17 +2403,13 @@ fragment_create(dcontext_t *dcontext, app_pc tag, int body_size, int direct_exit if (!fragment_lookup_deleted(dcontext, tag) && !TEST(FRAG_COARSE_GRAIN, flags)) STATS_INC(num_unique_fragments); }); - /* FIXME: make fragment count a release-build stat so we can do this in - * release builds - */ - DOSTATS({ - if (d_r_stats != NULL && - (uint)GLOBAL_STAT(num_fragments) == - INTERNAL_OPTION(reset_at_fragment_count)) { - ASSERT(INTERNAL_OPTION(reset_at_fragment_count) != 0); - schedule_reset(RESET_ALL); - } - }); + if (d_r_stats != NULL && + /* num_fragments is debug-only so we use the two release-build stats. */ + (uint)GLOBAL_STAT(num_bbs) + GLOBAL_STAT(num_traces) == + INTERNAL_OPTION(reset_at_fragment_count)) { + ASSERT(INTERNAL_OPTION(reset_at_fragment_count) != 0); + schedule_reset(RESET_ALL); + } DODEBUG({ if ((uint)GLOBAL_STAT(num_fragments) == INTERNAL_OPTION(log_at_fragment_count)) { /* we started at loglevel 1 and now we raise to the requested level */ diff --git a/core/synch.c b/core/synch.c index 22f9f655249..80cb3cccfa7 100644 --- a/core/synch.c +++ b/core/synch.c @@ -1714,7 +1714,7 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy free_cxt = false; } #endif - IF_ARM({ + IF_AARCHXX({ if (INTERNAL_OPTION(steal_reg_at_reset) != 0) { /* We don't want to translate, just update the stolen reg values */ arch_mcontext_reset_stolen_reg(dcontext, mc); @@ -1741,7 +1741,7 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy } LOG(GLOBAL, LOG_CACHE, 2, "\ttranslation pc = " PFX "\n", mc->pc); ASSERT(!is_dynamo_address((app_pc)mc->pc) && !in_fcache((app_pc)mc->pc)); - IF_ARM({ + IF_AARCHXX({ if (INTERNAL_OPTION(steal_reg_at_reset) != 0) { /* XXX: do we need this? Will signal.c will fix it up prior * to sigreturn from suspend handler? @@ -1815,6 +1815,9 @@ translate_from_synchall_to_dispatch(thread_record_t *tr, thread_synch_state_t sy */ mc->pc = (app_pc)get_reset_exit_stub(dcontext); LOG(GLOBAL, LOG_CACHE, 2, "\tsent to reset exit stub " PFX "\n", mc->pc); + /* TODO i#4497: Replace with the official fix from PR#4498. */ + IF_AARCHXX(set_stolen_reg_val(mc, (reg_t)os_get_dr_tls_base(dcontext))); + IF_AARCHXX(ASSERT_NOT_TESTED()); /* PR#4498 will improve test coverage. */ #ifdef WINDOWS /* i#25: we could have interrupted thread in DR, where has priv fls data * in TEB, and fcache_return blindly copies into app fls: so swap to app diff --git a/core/win32/events.mc b/core/win32/events.mc index a2de2d22056..a519846db0c 100644 --- a/core/win32/events.mc +++ b/core/win32/events.mc @@ -134,6 +134,14 @@ Language=English Attached to %1!s! threads in application %2!s! (%3!s!) . +MessageId = +Severity = Informational +Facility = DRCore +SymbolicName = MSG_INFO_RESET_IN_PROGRESS +Language=English +Resetting caches and non-persistent memory @ %1!s! fragments in application %2!s! (%3!s!). +. + ;//;;;;;;;;;;;;;;;;;;; Security MessageId = diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 387b3b45632..fed65e5d006 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -4073,6 +4073,17 @@ if (UNIX) "-enable_reset -reset_at_fragment_count 100" "") torunonly(linux.clone-reset linux.clone linux/clone.c "-enable_reset -reset_at_fragment_count 100" "") + if (AARCHXX) + # Test our diagnostic option -steal_reg_at_reset, which is also a stress + # test of reset and register stealing. + if (ARM) + set(new_reg 9) + else () + set(new_reg 29) + endif () + torunonly(linux.steal-switch linux.thread linux/thread.c + "-enable_reset -reset_at_fragment_count 100 -steal_reg_at_reset ${new_reg}" "") + endif () tobuild(pthreads.pthreads pthreads/pthreads.c) tobuild(pthreads.pthreads_exit pthreads/pthreads_exit.c) tobuild(pthreads.ptsig pthreads/ptsig.c) From 8a9a574606ba1a1db7784d42701844b2a3e772e4 Mon Sep 17 00:00:00 2001 From: Abhinav Anil Sharma Date: Fri, 30 Oct 2020 01:04:50 -0400 Subject: [PATCH 06/10] Optimise mcontext init by avoiding excessive zeroing. (#4499) Instead of using partial struct initialisation, initialise the required fields individually. We've found that the time taken to zero a large struct shows up as noticeable overhead for optimised clients. So, instead of using partial struct initialisation, we set the fields required individually. --- api/samples/cbr.c | 24 +++++--- ext/drbbdup/drbbdup.c | 7 +-- suite/tests/client-interface/avx512ctx.dll.c | 7 +-- suite/tests/client-interface/cbr3.dll.c | 14 ++--- suite/tests/client-interface/cleancall.dll.c | 56 ++++++++----------- .../client-interface/drreg-end-restore.dll.c | 7 +-- suite/tests/client-interface/events.dll.c | 8 +-- suite/tests/client-interface/flush.dll.c | 11 ++-- suite/tests/client-interface/syscall.dll.c | 7 +-- 9 files changed, 66 insertions(+), 75 deletions(-) diff --git a/api/samples/cbr.c b/api/samples/cbr.c index 9d27e9f1d82..b7084e22623 100644 --- a/api/samples/cbr.c +++ b/api/samples/cbr.c @@ -232,10 +232,14 @@ insert(hash_table_t table, app_pc addr, cbr_state_t state) static void at_taken(app_pc src, app_pc targ) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + /* + * We've found that the time taken to zero a large struct shows up as + * noticeable overhead for optimized clients. So, instead of using partial + * struct initialization, we set the fields required individually. + */ + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; void *drcontext = dr_get_current_drcontext(); /* @@ -261,10 +265,14 @@ at_taken(app_pc src, app_pc targ) static void at_not_taken(app_pc src, app_pc fall) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + /* + * We've found that the time taken to zero a large struct shows up as + * noticeable overhead for optimized clients. So, instead of using partial + * struct initialization, we set the fields required individually. + */ + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; void *drcontext = dr_get_current_drcontext(); /* diff --git a/ext/drbbdup/drbbdup.c b/ext/drbbdup/drbbdup.c index 348af37bbdf..f345618420b 100644 --- a/ext/drbbdup/drbbdup.c +++ b/ext/drbbdup/drbbdup.c @@ -1211,10 +1211,9 @@ drbbdup_handle_new_case() (drbbdup_per_thread *)drmgr_get_tls_field(drcontext, tls_idx); /* Must use DR_MC_ALL due to dr_redirect_execution. */ - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); /* Scratch register holds the tag. */ diff --git a/suite/tests/client-interface/avx512ctx.dll.c b/suite/tests/client-interface/avx512ctx.dll.c index 61d48c32b97..9ab3725ab01 100644 --- a/suite/tests/client-interface/avx512ctx.dll.c +++ b/suite/tests/client-interface/avx512ctx.dll.c @@ -86,10 +86,9 @@ read_avx512_state() dr_fprintf(STDERR, "Reading application state\n"); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); bool get_reg_value_ok = true; diff --git a/suite/tests/client-interface/cbr3.dll.c b/suite/tests/client-interface/cbr3.dll.c index ba56c591743..3380dcaaf2f 100644 --- a/suite/tests/client-interface/cbr3.dll.c +++ b/suite/tests/client-interface/cbr3.dll.c @@ -210,10 +210,9 @@ insert(hash_table_t table, app_pc addr, cbr_state_t state) static void at_taken(app_pc src, app_pc targ) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; void *drcontext = dr_get_current_drcontext(); /* @@ -239,10 +238,9 @@ at_taken(app_pc src, app_pc targ) static void at_not_taken(app_pc src, app_pc fall) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; void *drcontext = dr_get_current_drcontext(); /* diff --git a/suite/tests/client-interface/cleancall.dll.c b/suite/tests/client-interface/cleancall.dll.c index b95407d8f09..ab25a27b4e7 100644 --- a/suite/tests/client-interface/cleancall.dll.c +++ b/suite/tests/client-interface/cleancall.dll.c @@ -59,10 +59,9 @@ set_gpr() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_XAX, &mcontext, orig_reg_val_buf); reg_get_value_ex(DR_REG_XAX, &mcontext, new_reg_val_buf); @@ -80,10 +79,9 @@ check_gpr() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_XAX, &mcontext, new_reg_val_buf); print_error_on_fail(new_reg_val_buf[0] == 0x75); @@ -99,10 +97,9 @@ set_xmm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_XMM0, &mcontext, orig_reg_val_buf); reg_get_value_ex(DR_REG_XMM0, &mcontext, new_reg_val_buf); @@ -120,10 +117,9 @@ check_xmm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_XMM0, &mcontext, new_reg_val_buf); print_error_on_fail(new_reg_val_buf[0] == 0x77); @@ -139,10 +135,9 @@ set_ymm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_YMM0, &mcontext, orig_reg_val_buf); reg_get_value_ex(DR_REG_YMM0, &mcontext, new_reg_val_buf); @@ -162,10 +157,9 @@ check_ymm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_YMM0, &mcontext, new_reg_val_buf); print_error_on_fail(new_reg_val_buf[0] == 0x77); @@ -184,10 +178,9 @@ set_zmm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_ZMM0, &mcontext, orig_reg_val_buf); reg_get_value_ex(DR_REG_ZMM0, &mcontext, new_reg_val_buf); @@ -210,10 +203,9 @@ check_zmm() { check_stack_alignment(); void *drcontext = dr_get_current_drcontext(); - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); reg_get_value_ex(DR_REG_ZMM0, &mcontext, new_reg_val_buf); print_error_on_fail(new_reg_val_buf[0] == 0x77); diff --git a/suite/tests/client-interface/drreg-end-restore.dll.c b/suite/tests/client-interface/drreg-end-restore.dll.c index 807b78dc4cb..3f0d0fa21e9 100644 --- a/suite/tests/client-interface/drreg-end-restore.dll.c +++ b/suite/tests/client-interface/drreg-end-restore.dll.c @@ -129,10 +129,9 @@ event_bb_analysis(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, static reg_t get_val_from_ctx(void *drcontext, reg_id_t reg_id) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_get_mcontext(drcontext, &mcontext); return reg_get_value(reg_id, &mcontext); } diff --git a/suite/tests/client-interface/events.dll.c b/suite/tests/client-interface/events.dll.c index d711f79d179..593831caaa4 100644 --- a/suite/tests/client-interface/events.dll.c +++ b/suite/tests/client-interface/events.dll.c @@ -452,7 +452,8 @@ kernel_xfer_event2(void *drcontext, const dr_kernel_xfer_info_t *info) if (info->type == DR_XFER_CLIENT_REDIRECT) { /* Test for exception event redirect. */ ASSERT(info->source_mcontext != NULL); - dr_mcontext_t mc = { sizeof(mc) }; + dr_mcontext_t mc; + mc.size = sizeof(mc); mc.flags = DR_MC_CONTROL; bool ok = dr_get_mcontext(drcontext, &mc); ASSERT(ok); @@ -469,10 +470,7 @@ static bool exception_event_redirect(void *dcontext, dr_exception_t *excpt) { app_pc addr; - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; module_data_t *data = dr_lookup_module_by_name("client." EVENTS ".exe"); dr_fprintf(STDERR, "exception event redirect\n"); if (data == NULL) { diff --git a/suite/tests/client-interface/flush.dll.c b/suite/tests/client-interface/flush.dll.c index 75d4cb9541d..145736f23bf 100644 --- a/suite/tests/client-interface/flush.dll.c +++ b/suite/tests/client-interface/flush.dll.c @@ -188,11 +188,9 @@ callback(void *tag, app_pc next_pc) if (callback_count % 100 == 0) { if (callback_count % 200 == 0) { /* For windows test dr_flush_region() half the time */ - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; - + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event); dr_get_mcontext(dr_get_current_drcontext(), &mcontext); mcontext.pc = next_pc; @@ -285,7 +283,8 @@ kernel_xfer_event(void *drcontext, const dr_kernel_xfer_info_t *info) /* Test kernel xfer on dr_redirect_execution */ dr_fprintf(STDERR, "%s: type %d\n", __FUNCTION__, info->type); ASSERT(info->source_mcontext != NULL); - dr_mcontext_t mc = { sizeof(mc) }; + dr_mcontext_t mc; + mc.size = sizeof(mc); mc.flags = DR_MC_CONTROL; bool ok = dr_get_mcontext(drcontext, &mc); ASSERT(ok); diff --git a/suite/tests/client-interface/syscall.dll.c b/suite/tests/client-interface/syscall.dll.c index 307239167c4..01620c48d5a 100644 --- a/suite/tests/client-interface/syscall.dll.c +++ b/suite/tests/client-interface/syscall.dll.c @@ -47,10 +47,9 @@ static void at_syscall() { if (monitoring) { - dr_mcontext_t mcontext = { - sizeof(mcontext), - DR_MC_ALL, - }; + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; void *drcontext = dr_get_current_drcontext(); dr_get_mcontext(drcontext, &mcontext); dr_fprintf(STDERR, PFX "\n", mcontext.xax); From feecbf173881de02fb50f0be5c58e0fdf7584369 Mon Sep 17 00:00:00 2001 From: Abhinav Anil Sharma Date: Fri, 30 Oct 2020 03:45:50 -0400 Subject: [PATCH 07/10] i#1369: Use synch flush callback to enable drcachesim tracing. (#4491) DR translates a fault in the code cache to a fault at the corresponding application address. This is done using ilist reconstruction for the fragment where the fault occurred. But, this does not work as expected when the DR client changes instrumentation during execution; currently, drcachesim does this to enable tracing after -trace_after_instrs. The reconstructed basic block gets the new instrumentation whereas the one in code cache has the old one. This causes issues during fault handling. In the current drcachesim case, it appears as though a meta-instr has faulted because the reconstructed ilist has a meta-instr at the code cache fault pc. This issue may manifest differently if the basic block with the new instrumentation is smaller than the old one (unlike the drcachesim 'meta-instr faulted' case) and the faulting address lies beyond the end of the new instrumented basic block. We may see an ASSERT_NOT_REACHED due to the ilist walk ending before the faulting code cache pc was found in the reconstructed ilist. In the existing code, drcachesim attempts to avoid this by flushing old fragments using dr_unlink_flush_region after it switches to the tracing instrumentation. However, due to the flush being asynch, there's a race and the flush does not complete in time. This PR adds support for a callback in the synchronous dr_flush_region API. The callback is executed after the flush but before the threads are resumed. Using the dr_flush_region callback to change drcachesim instrumentation ensures that old instrumentation is not applied after the flush and the new one is not applied before. Fixes: #1369 --- api/docs/bt.dox | 12 ++-- api/docs/release.dox | 3 + clients/drcachesim/tracer/tracer.cpp | 57 +++++++++++++------ core/dispatch.c | 4 +- core/fragment.c | 19 +++++-- core/fragment.h | 4 +- core/lib/instrument.c | 31 +++++++--- core/lib/instrument_api.h | 9 +++ core/unix/os.c | 4 +- core/win32/callback.c | 63 ++++++++++++--------- suite/tests/CMakeLists.txt | 4 ++ suite/tests/client-interface/flush.dll.c | 9 ++- suite/tests/client-interface/flush.template | 2 + 13 files changed, 155 insertions(+), 66 deletions(-) diff --git a/api/docs/bt.dox b/api/docs/bt.dox index 788d894009c..bb8ca09d65c 100644 --- a/api/docs/bt.dox +++ b/api/docs/bt.dox @@ -981,15 +981,17 @@ dr_insert_cbr_instrumentation() \subsection sec_adaptive Dynamic Instrumentation DynamoRIO allows a client to dynamically adjust its instrumentation -by providing routines to flush all cached fragments corresponding to -an application code region: +by providing a routine to flush all cached fragments corresponding to +an application code region and register (or unregister) instrumentation +event callbacks: \code -dr_flush_region() -dr_unlink_flush_region() -dr_delay_flush_region() +dr_flush_region_ex() \endcode +The client should provide a callback to this routine, that unregisters +old instrumentation event callbacks, and registers new ones. + In order to directly modify the instrumentation on a particular fragment (as opposed to replacing instrumentation on all copies of fragments corresponding to particular application code), DynamoRIO also supports diff --git a/api/docs/release.dox b/api/docs/release.dox index 7614d50a632..4488ad0e5ec 100644 --- a/api/docs/release.dox +++ b/api/docs/release.dox @@ -173,6 +173,9 @@ Further non-compatibility-affecting changes include: - Added opnd_create_immed_double(), opnd_get_immed_double() and opnd_is_immed_double() to enable the creation and handling of double precision floating-point operands. + - Added dr_flush_region_ex API that accepts a callback to be executed after synch + flush but before the threads are resumed. The existing dr_flush_region API + is modified to invoke dr_flush_region_ex with a NULL callback. **************************************************
diff --git a/clients/drcachesim/tracer/tracer.cpp b/clients/drcachesim/tracer/tracer.cpp index 30251cf04d1..151dd88be9f 100644 --- a/clients/drcachesim/tracer/tracer.cpp +++ b/clients/drcachesim/tracer/tracer.cpp @@ -1316,13 +1316,14 @@ event_kernel_xfer(void *drcontext, const dr_kernel_xfer_info_t *info) */ static uint64 instr_count; -static volatile bool tracing_enabled; -static void *enable_tracing_lock; +static bool tracing_enabled; +static volatile bool tracing_scheduled; +static void *schedule_tracing_lock; #ifdef X86_64 # define DELAYED_CHECK_INLINED 1 #else -// XXX: we don't have the inlining implemented yet. +// XXX i#4487: we don't have the inlining implemented yet. #endif static dr_emit_flags_t @@ -1345,7 +1346,7 @@ enable_delay_instrumentation() if (!drmgr_register_bb_instrumentation_event( event_delay_bb_analysis, event_delay_app_instruction, &memtrace_pri)) DR_ASSERT(false); - enable_tracing_lock = dr_mutex_create(); + schedule_tracing_lock = dr_mutex_create(); } static void @@ -1358,8 +1359,8 @@ disable_delay_instrumentation() static void exit_delay_instrumentation() { - if (enable_tracing_lock != NULL) - dr_mutex_destroy(enable_tracing_lock); + if (schedule_tracing_lock != NULL) + dr_mutex_destroy(schedule_tracing_lock); #ifdef DELAYED_CHECK_INLINED drx_exit(); #endif @@ -1379,28 +1380,46 @@ enable_tracing_instrumentation() } static void -hit_instr_count_threshold() +change_instrumentation_callback(void *unused_user_data) +{ + NOTIFY(0, "Hit delay threshold: enabling tracing.\n"); + disable_delay_instrumentation(); + enable_tracing_instrumentation(); +} + +static void +hit_instr_count_threshold(app_pc next_pc) { bool do_flush = false; - dr_mutex_lock(enable_tracing_lock); - if (!tracing_enabled) { // Already came here? - NOTIFY(0, "Hit delay threshold: enabling tracing.\n"); - disable_delay_instrumentation(); - enable_tracing_instrumentation(); + dr_mutex_lock(schedule_tracing_lock); + if (!tracing_scheduled) { do_flush = true; + tracing_scheduled = true; } - dr_mutex_unlock(enable_tracing_lock); - if (do_flush && !dr_unlink_flush_region(NULL, ~0UL)) + dr_mutex_unlock(schedule_tracing_lock); + + if (do_flush) { + if (!dr_flush_region_ex(NULL, ~0UL, change_instrumentation_callback, + NULL /*user_data*/)) + DR_ASSERT(false); + + dr_mcontext_t mcontext; + mcontext.size = sizeof(mcontext); + mcontext.flags = DR_MC_ALL; + dr_get_mcontext(dr_get_current_drcontext(), &mcontext); + mcontext.pc = next_pc; + dr_redirect_execution(&mcontext); DR_ASSERT(false); + } } #ifndef DELAYED_CHECK_INLINED static void -check_instr_count_threshold(uint incby) +check_instr_count_threshold(uint incby, app_pc next_pc) { instr_count += incby; if (instr_count > op_trace_after_instrs.get_value()) - hit_instr_count_threshold(); + hit_instr_count_threshold(next_pc); } #endif @@ -1450,7 +1469,8 @@ event_delay_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t } MINSERT(bb, instr, INSTR_CREATE_jcc(drcontext, OP_jl, opnd_create_instr(skip_call))); dr_insert_clean_call(drcontext, bb, instr, (void *)hit_instr_count_threshold, - false /*fpstate */, 0); + false /*fpstate */, 1, + OPND_CREATE_INTPTR((ptr_uint_t)instr_get_app_pc(instr))); MINSERT(bb, instr, skip_call); if (scratch != DR_REG_NULL) { if (drreg_unreserve_register(drcontext, bb, instr, scratch) != DRREG_SUCCESS) @@ -1463,7 +1483,8 @@ event_delay_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t // XXX: drx_insert_counter_update doesn't support 64-bit, and there's no // XINST_CREATE_load_8bytes. For now we pay the cost of a clean call every time. dr_insert_clean_call(drcontext, bb, instr, (void *)check_instr_count_threshold, - false /*fpstate */, 1, OPND_CREATE_INT32(num_instrs)); + false /*fpstate */, 2, OPND_CREATE_INT32(num_instrs), + OPND_CREATE_INTPTR((ptr_uint_t)instr_get_app_pc(instr))); #endif return DR_EMIT_DEFAULT; } diff --git a/core/dispatch.c b/core/dispatch.c index 6bb55e23320..6051f55b38d 100644 --- a/core/dispatch.c +++ b/core/dispatch.c @@ -902,7 +902,9 @@ dispatch_enter_dynamorio(dcontext_t *dcontext) app_pc begin = (app_pc)dcontext->local_state->spill_space.r2; app_pc end = (app_pc)dcontext->local_state->spill_space.r3; dcontext->next_tag = (app_pc)dcontext->local_state->spill_space.r4; - flush_fragments_from_region(dcontext, begin, end - begin, true); + flush_fragments_from_region(dcontext, begin, end - begin, true, + NULL /*flush_completion_callback*/, + NULL /*user_data*/); } #endif diff --git a/core/fragment.c b/core/fragment.c index 6725b01462c..805f44d1308 100644 --- a/core/fragment.c +++ b/core/fragment.c @@ -5654,13 +5654,15 @@ process_client_flush_requests(dcontext_t *dcontext, dcontext_t *alloc_dcontext, /* FIXME - for implementation simplicity we do a synch-all flush so * that we can inform the client right away, it might be nice to use * the more performant regular flush when possible. */ - flush_fragments_from_region(dcontext, iter->start, iter->size, - true /*force synchall*/); + flush_fragments_from_region( + dcontext, iter->start, iter->size, true /*force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); (*iter->flush_callback)(iter->flush_id); } else { /* do a regular flush */ - flush_fragments_from_region(dcontext, iter->start, iter->size, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, iter->start, iter->size, false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); } } HEAP_TYPE_FREE(alloc_dcontext, iter, client_flush_req_t, ACCT_CLIENT, @@ -6877,10 +6879,13 @@ flush_fragments_and_remove_region(dcontext_t *dcontext, app_pc base, size_t size /* Flushes fragments from the region without any changes to the exec list. * Does not free futures and caller can't be holding the initexit lock. + * Invokes the given callback after flushing and before resuming threads. * FIXME - add argument parameters (free futures etc.) as needed. */ void flush_fragments_from_region(dcontext_t *dcontext, app_pc base, size_t size, - bool force_synchall) + bool force_synchall, + void (*flush_completion_callback)(void *user_data), + void *user_data) { /* we pass false to flush_fragments_in_region_start() below for owning the initexit * lock */ @@ -6891,6 +6896,10 @@ flush_fragments_from_region(dcontext_t *dcontext, app_pc base, size_t size, flush_fragments_in_region_start(dcontext, base, size, false /*don't own initexit*/, false /*don't free futures*/, false /*exec valid*/, force_synchall _IF_DGCDIAG(NULL)); + if (flush_completion_callback != NULL) { + (*flush_completion_callback)(user_data); + } + flush_fragments_in_region_finish(dcontext, false); } diff --git a/core/fragment.h b/core/fragment.h index 6a41ab208e8..80dfa62f9cb 100644 --- a/core/fragment.h +++ b/core/fragment.h @@ -1141,7 +1141,9 @@ flush_fragments_and_remove_region(dcontext_t *dcontext, app_pc base, size_t size void flush_fragments_from_region(dcontext_t *dcontext, app_pc base, size_t size, - bool force_synchall); + bool force_synchall, + void (*flush_completion_callback)(void *user_data), + void *user_data); void flush_fragments_custom_list(dcontext_t *dcontext, fragment_t *list, diff --git a/core/lib/instrument.c b/core/lib/instrument.c index 1dd4edfedcf..9216ca0b1dd 100644 --- a/core/lib/instrument.c +++ b/core/lib/instrument.c @@ -7171,10 +7171,12 @@ DR_API /* Flush all fragments that contain code from the region [start, start+size). * Uses a synchall flush to guarantee that no execution occurs out of the fragments * flushed once this returns. Requires caller to be holding no locks (dr or client) and - * to be !couldbelinking (xref PR 199115, 227619). Caller must use + * to be !couldbelinking (xref PR 199115, 227619). Invokes the given callback after the + * flush completes and before threads are resumed. Caller must use * dr_redirect_execution() to return to the cache. */ bool -dr_flush_region(app_pc start, size_t size) +dr_flush_region_ex(app_pc start, size_t size, + void (*flush_completion_callback)(void *user_data), void *user_data) { dcontext_t *dcontext = get_thread_private_dcontext(); CLIENT_ASSERT(!standalone_library, "API not supported in standalone mode"); @@ -7198,20 +7200,34 @@ dr_flush_region(app_pc start, size_t size) "dr_flush_region: caller owns a client " "lock or was called from an event callback that doesn't support " "calling this routine; see header file for restrictions."); - CLIENT_ASSERT(size != 0, "dr_flush_region: 0 is invalid size for flush"); + CLIENT_ASSERT(size != 0, "dr_flush_region_ex: 0 is invalid size for flush"); /* release build check of requirements, as many as possible at least */ - if (size == 0 || is_couldbelinking(dcontext)) + if (size == 0 || is_couldbelinking(dcontext)) { + (*flush_completion_callback)(user_data); return false; + } - if (!executable_vm_area_executed_from(start, start + size)) + if (!executable_vm_area_executed_from(start, start + size)) { + (*flush_completion_callback)(user_data); return true; + } - flush_fragments_from_region(dcontext, start, size, true /*force synchall*/); + flush_fragments_from_region(dcontext, start, size, true /*force synchall*/, + flush_completion_callback, user_data); return true; } +DR_API +/* Equivalent to dr_flush_region_ex, without the callback. */ +bool +dr_flush_region(app_pc start, size_t size) +{ + return dr_flush_region_ex(start, size, NULL /*flush_completion_callback*/, + NULL /*user_data*/); +} + DR_API /* Flush all fragments that contain code from the region [start, start+size). * Uses an unlink flush which guarantees that no thread will enter a fragment that was @@ -7259,7 +7275,8 @@ dr_unlink_flush_region(app_pc start, size_t size) if (!executable_vm_area_executed_from(start, start + size)) return true; - flush_fragments_from_region(dcontext, start, size, false /*don't force synchall*/); + flush_fragments_from_region(dcontext, start, size, false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); return true; } diff --git a/core/lib/instrument_api.h b/core/lib/instrument_api.h index 0dd4b883a9d..77e332f74fe 100644 --- a/core/lib/instrument_api.h +++ b/core/lib/instrument_api.h @@ -6228,10 +6228,19 @@ DR_API * \note Use \p size == 1 to flush fragments containing the instruction at address * \p start. A flush of \p size == 0 is not allowed. * + * \note Use flush_completion_callback to specify logic to be executed after the flush + * and before the threads are resumed. Use NULL if not needed. + * * \note As currently implemented, dr_delay_flush_region() with no completion callback * routine specified can be substantially more performant. */ bool +dr_flush_region_ex(app_pc start, size_t size, + void (*flush_completion_callback)(void *user_data), void *user_data); + +DR_API +/** Equivalent to dr_flush_region_ex(start, size, NULL). */ +bool dr_flush_region(app_pc start, size_t size); /* FIXME - get rid of the no locks requirement by making event callbacks !couldbelinking diff --git a/core/unix/os.c b/core/unix/os.c index acfa4f7e2d5..af9923beca9 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -7655,7 +7655,9 @@ pre_system_call(dcontext_t *dcontext) * use synch to ensure other threads see the * new code. */ - false /*don't force synchall*/); + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, + NULL /*user_data*/); break; } # endif /* ARM */ diff --git a/core/win32/callback.c b/core/win32/callback.c index 3e3be8640f0..20d1b2fdf8d 100644 --- a/core/win32/callback.c +++ b/core/win32/callback.c @@ -3906,64 +3906,72 @@ intercept_nt_continue(CONTEXT *cxt, int flag) /* Flush only when debug register value changes. */ if (d_r_debug_register[0] != (app_pc)cxt->Dr0) { d_r_debug_register[0] = (app_pc)cxt->Dr0; - flush_fragments_from_region(dcontext, d_r_debug_register[0], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[0], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); } } else { /* Disable debug register. */ if (d_r_debug_register[0] != NULL) { - flush_fragments_from_region(dcontext, d_r_debug_register[0], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[0], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); d_r_debug_register[0] = NULL; } } if (TESTANY(cxt->Dr7, DEBUG_REGISTERS_FLAG_ENABLE_DR1)) { if (d_r_debug_register[1] != (app_pc)cxt->Dr1) { d_r_debug_register[1] = (app_pc)cxt->Dr1; - flush_fragments_from_region(dcontext, d_r_debug_register[1], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[1], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); } } else { /* Disable debug register. */ if (d_r_debug_register[1] != NULL) { - flush_fragments_from_region(dcontext, d_r_debug_register[1], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[1], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); d_r_debug_register[1] = NULL; } } if (TESTANY(cxt->Dr7, DEBUG_REGISTERS_FLAG_ENABLE_DR2)) { if (d_r_debug_register[2] != (app_pc)cxt->Dr2) { d_r_debug_register[2] = (app_pc)cxt->Dr2; - flush_fragments_from_region(dcontext, d_r_debug_register[2], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[2], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); } } else { /* Disable debug register. */ if (d_r_debug_register[2] != NULL) { - flush_fragments_from_region(dcontext, d_r_debug_register[2], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[2], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); d_r_debug_register[2] = NULL; } } if (TESTANY(cxt->Dr7, DEBUG_REGISTERS_FLAG_ENABLE_DR3)) { if (d_r_debug_register[3] != (app_pc)cxt->Dr3) { d_r_debug_register[3] = (app_pc)cxt->Dr3; - flush_fragments_from_region(dcontext, d_r_debug_register[3], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[3], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); } } else { /* Disable debug register. */ if (d_r_debug_register[3] != NULL) { - flush_fragments_from_region(dcontext, d_r_debug_register[3], - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, d_r_debug_register[3], 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); d_r_debug_register[3] = NULL; } } @@ -5872,9 +5880,10 @@ intercept_exception(app_state_at_intercept_t *state) /* Deletes fragment starting at single step exception * if it exists. */ - flush_fragments_from_region(dcontext, dcontext->next_tag, - 1 /* size */, - false /*don't force synchall*/); + flush_fragments_from_region( + dcontext, dcontext->next_tag, 1 /* size */, + false /*don't force synchall*/, + NULL /*flush_completion_callback*/, NULL /*user_data*/); /* Sets a field so that build_bb_ilist knows when to stop. */ dcontext->single_step_addr = dcontext->next_tag; LOG(THREAD, LOG_ASYNCH, 2, diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index fed65e5d006..c42e95b88d9 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -4069,6 +4069,10 @@ if (UNIX) #tobuild(linux.vfork-fib linux/vfork-fib.c) # runs of other builds with custom DR options + # TODO i#4497: The following two tests need to trigger reset when multiple + # threads are active. But, the current -reset_at_fragment_count value does + # not ensure that. We need to make these tests more robust, perhaps by + # using a different trigger like -reset_at_nth_thread (pending i#4496). torunonly(linux.thread-reset linux.thread linux/thread.c "-enable_reset -reset_at_fragment_count 100" "") torunonly(linux.clone-reset linux.clone linux/clone.c diff --git a/suite/tests/client-interface/flush.dll.c b/suite/tests/client-interface/flush.dll.c index 145736f23bf..f8153997ddd 100644 --- a/suite/tests/client-interface/flush.dll.c +++ b/suite/tests/client-interface/flush.dll.c @@ -177,6 +177,13 @@ flush_event(int flush_id) dr_fprintf(STDERR, "Flush completion id=%d\n", flush_id); } +static void +synch_flush_completion_callback(void *user_data) +{ + dr_fprintf(STDERR, "in synch_flush_completion_callback, user_data=%d\n", + *(int *)user_data); +} + static void callback(void *tag, app_pc next_pc) { @@ -194,7 +201,7 @@ callback(void *tag, app_pc next_pc) dr_delay_flush_region((app_pc)tag - 20, 30, callback_count, flush_event); dr_get_mcontext(dr_get_current_drcontext(), &mcontext); mcontext.pc = next_pc; - dr_flush_region(tag, 1); + dr_flush_region_ex(tag, 1, synch_flush_completion_callback, &callback_count); dr_redirect_execution(&mcontext); *(volatile uint *)NULL = 0; /* ASSERT_NOT_REACHED() */ } else if (use_unlink) { diff --git a/suite/tests/client-interface/flush.template b/suite/tests/client-interface/flush.template index 58c059415b7..41f15ba31f0 100644 --- a/suite/tests/client-interface/flush.template +++ b/suite/tests/client-interface/flush.template @@ -10,8 +10,10 @@ kernel_xfer_event: type 9 Flush completion id=400 #else options =@& +in synch_flush_completion_callback, user_data=200 kernel_xfer_event: type 9 Flush completion id=200 +in synch_flush_completion_callback, user_data=400 kernel_xfer_event: type 9 Flush completion id=400 #endif From e4cf5af20795dc1c3cf7c5d7f0f45c60949b6f6f Mon Sep 17 00:00:00 2001 From: Derek Bruening Date: Fri, 30 Oct 2020 13:31:37 -0400 Subject: [PATCH 08/10] Add gdb scripts for memquery and drsymload (#4505) Adds two gdb python scripts I've developed that may be useful to others: 1) drsymload: loads DR symbols regardless of gdb's current state, which may include having DR symbols at the wrong address. It does this by reading /proc/self/maps and running objdump on libdynamorio.so. Ideally this would be integrated into a revived libdynamorio.so-gdb.py: that's part of #2100. 2) memquery: prints the /proc/self/maps line for a given address. I'm still shocked gdb doesn't provide such a command natively. Issue: #2100 --- tools/gdb-scripts/gdb-drsymload.py | 84 ++++++++++++++++++++++++++++++ tools/gdb-scripts/gdb-memquery.py | 68 ++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 tools/gdb-scripts/gdb-drsymload.py create mode 100644 tools/gdb-scripts/gdb-memquery.py diff --git a/tools/gdb-scripts/gdb-drsymload.py b/tools/gdb-scripts/gdb-drsymload.py new file mode 100644 index 00000000000..e2ad979f989 --- /dev/null +++ b/tools/gdb-scripts/gdb-drsymload.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python + +# ********************************************************** +# Copyright (c) 2020 Google, Inc. All rights reserved. +# ********************************************************** + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Google, Inc. nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +# Loads symbols for libdynamorio.so by looking in /proc/self/maps. +# This clears the symbol table, so run it early/first. +# TODO i#2100: Integrate with a revived libdynamorio.so-gdb.py. +# Usage: +# 1) Place this line into your ~/.gdbinit: +# source /gdb-drsymload.py +# 2) Execute the command in gdb: +# (gdb) drsymload + +try: + import gdb +except ImportError as e: + raise ImportError("This script must be run in GDB: ", str(e)) +import re +import subprocess +from pathlib import Path +import os.path + +class DRSymLoadCommand (gdb.Command): + """Loads symbols for libdynamorio.so""" + def __init__ (self): + super (DRSymLoadCommand, self).__init__ ("drsymload", + gdb.COMMAND_DATA, + gdb.COMPLETE_FILENAME) + def invoke(self, unused_arg, unused_from_tty): + pid = int(gdb.selected_inferior().pid) + exefile = "/proc/%d/exe" % pid + drfile = str(Path(exefile).resolve()) + base = 0 + map_name = "/proc/%d/maps" % pid + with open(map_name,'r') as map: + for line in map: + line = line.rstrip() + if not line: continue + match = re.match(r'^([^-]*)-.*libdynamorio.so', line) + if match: + base = int(match.group(1), 16) + print("libdynamorio base is 0x%x" % base) + break + p = subprocess.Popen(["objdump", "-h", drfile], stdout=subprocess.PIPE) + stdout, _ = p.communicate() + for line in iter(stdout.splitlines()): + match = re.match(r'.*\.text *\w+ *\w+ *\w+ *(\w+)', str(line)) + if match: + offs = match.group(1) + cmd = "add-symbol-file %s 0x%x+0x%s" % (drfile, base, offs) + # First clear the symbols (sometimes gdb has DR syms at the wrong + # load address). + gdb.execute("symbol-file") + print("Running %s" % cmd) + gdb.execute(cmd) +DRSymLoadCommand() diff --git a/tools/gdb-scripts/gdb-memquery.py b/tools/gdb-scripts/gdb-memquery.py new file mode 100644 index 00000000000..55f42740bad --- /dev/null +++ b/tools/gdb-scripts/gdb-memquery.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +# ********************************************************** +# Copyright (c) 2020 Google, Inc. All rights reserved. +# ********************************************************** + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of Google, Inc. nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +# Searches /proc/self/maps for the line containing a given address. +# Usage: +# 1) Place this line into your ~/.gdbinit: +# source /gdb-memquery.py +# 2) Execute the command in gdb: +# (gdb) memquery $rsp +# 7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack] + +try: + import gdb +except ImportError as e: + raise ImportError("This script must be run in GDB: ", str(e)) +import re +from subprocess import check_output + +class MemQueryCommand (gdb.Command): + """Prints memory address properties""" + def __init__ (self): + super (MemQueryCommand, self).__init__ ("memquery", + gdb.COMMAND_DATA, + gdb.COMPLETE_FILENAME) + def invoke(self, arg, unused_from_tty): + addr = gdb.parse_and_eval(arg) + pid = int(gdb.selected_inferior().pid) + map_name = "/proc/%d/maps" % pid + with open(map_name,'r') as map: + for line in map: + line = line.rstrip() + if not line: continue + match = re.match(r'^(\w+)-(\w+)', line) + if match: + start = int(match.group(1), 16) + end = int(match.group(2), 16) + if addr >= start and addr < end: + print(line) +MemQueryCommand() From 8195d8864401949a3e134fe69441ec3d25395293 Mon Sep 17 00:00:00 2001 From: Derek Bruening Date: Fri, 30 Oct 2020 21:45:23 -0400 Subject: [PATCH 09/10] Fix uninitialized var in drmemtrace offline instru (#4506) While investigating #4460 I found that reg_ptr_used in insert_save_addr is uninitialized locally and insert_obtain_addr only writes it when true, leaving it uninitialized for the false case: thus we may re-instate the buffer pointer in cases where we don't need to. I believe this is only a performance issue. Issue: #4460 --- clients/drcachesim/tracer/instru.cpp | 4 ++-- clients/drcachesim/tracer/instru_offline.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/drcachesim/tracer/instru.cpp b/clients/drcachesim/tracer/instru.cpp index d3f7a223813..9f7bbedabc8 100644 --- a/clients/drcachesim/tracer/instru.cpp +++ b/clients/drcachesim/tracer/instru.cpp @@ -279,8 +279,8 @@ instru_t::insert_obtain_addr(void *drcontext, instrlist_t *ilist, instr_t *where dr_fprintf(STDERR, "\n"); DR_ASSERT(ok); } - if (scratch_used != NULL && we_used_scratch) - *scratch_used = true; + if (scratch_used != NULL) + *scratch_used = we_used_scratch; } // Returns -1 on error. It's hard for callers to omit the cpu marker though diff --git a/clients/drcachesim/tracer/instru_offline.cpp b/clients/drcachesim/tracer/instru_offline.cpp index bc92db6ca6f..2d129f0c830 100644 --- a/clients/drcachesim/tracer/instru_offline.cpp +++ b/clients/drcachesim/tracer/instru_offline.cpp @@ -478,7 +478,7 @@ offline_instru_t::insert_save_addr(void *drcontext, instrlist_t *ilist, instr_t res = drreg_reserve_register(drcontext, ilist, where, reg_vector_, ®_addr); DR_ASSERT(res == DRREG_SUCCESS); // Can't recover. reserved = true; - bool reg_ptr_used; + bool reg_ptr_used = false; insert_obtain_addr(drcontext, ilist, where, reg_addr, reg_ptr, ref, ®_ptr_used); if (reg_ptr_used) { From c84871da010db3379a6e702460c57a151a00206c Mon Sep 17 00:00:00 2001 From: Yury Khrustalev Date: Mon, 2 Nov 2020 10:26:57 +0000 Subject: [PATCH 10/10] i#2440: Remove sizes of imm operands from docstings Change-Id: Ia3699cc5eb8074a10d8ce9e6c362c1bffd0cf477 --- core/ir/aarch64/instr_create.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/ir/aarch64/instr_create.h b/core/ir/aarch64/instr_create.h index e837a487b69..066719a8ecb 100644 --- a/core/ir/aarch64/instr_create.h +++ b/core/ir/aarch64/instr_create.h @@ -2569,10 +2569,8 @@ enum { * Creates a CCMN (Conditional Compare Negative) instruction. * \param dc The void * dcontext used to allocate memory for the instr_t. * \param Rn The source register. - * \param Op Either a 5-bit immediate (use opnd_create_immed_uint(val, OPSZ_5b) - * to create the operand) or a source register. - * \param nzcv The 4 bit flag bit specifier - * (use opnd_create_immed_uint(val, OPSZ_4b) to create the operand). + * \param Op Either a 5-bit immediate or a source register. + * \param nzcv The 4 bit flag bit specifier. * \param cond A 4-bit immediate value for condition * (use opnd_create_cond(val) to create the operand). */ @@ -2583,10 +2581,8 @@ enum { * Creates a CCMP (Conditional Compare) instruction. * \param dc The void * dcontext used to allocate memory for the instr_t. * \param Rn The source register. - * \param Op Either a 5-bit immediate (use opnd_create_immed_uint(val, OPSZ_5b) - * to create the operand) or a source register. - * \param nzcv The 4 bit flag bit specifier - * (use opnd_create_immed_uint(val, OPSZ_4b) to create the operand). + * \param Op Either a 5-bit immediate or a source register. + * \param nzcv The 4 bit flag bit specifier. * \param cond A 4-bit immediate value for condition * (use opnd_create_cond(val) to create the operand). */