From e28a0d039a618cc69b10a59fa53f3c6b482f0ca2 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sun, 27 Aug 2023 16:27:58 -0500 Subject: [PATCH] Optimize register extension to skip some, if the width already matches. --- librz/analysis/arch/arm/arm_il64.c | 31 +++++++++++++++++++----------- test/db/asm/arm_64 | 18 ++++++++--------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/librz/analysis/arch/arm/arm_il64.c b/librz/analysis/arch/arm/arm_il64.c index 476097f3cdb..fe8c1c38956 100644 --- a/librz/analysis/arch/arm/arm_il64.c +++ b/librz/analysis/arch/arm/arm_il64.c @@ -267,9 +267,9 @@ static RzILOpBitVector *adjust_unsigned(ut32 bits, RZ_OWN RzILOpBitVector *v) { return v; } -static RzILOpBitVector *extend(ut32 dst_bits, CS_aarch64_extender() ext, RZ_OWN RzILOpBitVector *v, ut32 v_bits) { +static RzILOpBitVector *reg_extend(ut32 dst_bits, CS_aarch64_extender() ext, RZ_OWN RzILOpBitVector *reg, ut32 v_bits) { bool is_signed = false; - ut32 src_bits; + ut32 src_bits = v_bits; switch (ext) { case CS_AARCH64(_EXT_SXTB): is_signed = true; @@ -300,15 +300,24 @@ static RzILOpBitVector *extend(ut32 dst_bits, CS_aarch64_extender() ext, RZ_OWN break; default: - if (dst_bits == v_bits) { - return v; - } else { - return adjust_unsigned(dst_bits, v); + break; + } + if (dst_bits < src_bits && src_bits <= v_bits) { + // Just cast it down once. + if (reg->code == RZ_IL_OP_CAST) { + // Already a casted down register. Set new width. + reg->op.cast.length = dst_bits; + return reg; } + return UNSIGNED(dst_bits, reg); } - - v = adjust_unsigned(src_bits, v); - return is_signed ? SIGNED(dst_bits, v) : UNSIGNED(dst_bits, v); + if (src_bits != v_bits) { + reg = adjust_unsigned(src_bits, reg); + } + if (dst_bits != src_bits) { + return is_signed ? SIGNED(dst_bits, reg) : UNSIGNED(dst_bits, reg); + } + return is_signed ? SIGNED(dst_bits, reg) : reg; } static RzILOpBitVector *apply_shift(CS_aarch64_shifter() sft, ut32 dist, RZ_OWN RzILOpBitVector *v) { @@ -353,7 +362,7 @@ static RzILOpBitVector *arg_mem(RzILOpBitVector *base_plus_disp, CS_aarch64_op() return base_plus_disp; } RzILOpBitVector *index = read_reg(op->mem.index); - index = extend(64, op->ext, index, reg_bits(op->mem.index)); + index = reg_extend(64, op->ext, index, reg_bits(op->mem.index)); index = apply_shift(op->shift.type, op->shift.value, index); return ADD(base_plus_disp, index); } @@ -382,7 +391,7 @@ static RzILOpBitVector *arg(RZ_BORROW cs_insn *insn, size_t n, RZ_OUT ut32 *bits if (!r) { return NULL; } - return apply_shift(op->shift.type, op->shift.value, extend(bits_requested, op->ext, r, REGBITS(n))); + return apply_shift(op->shift.type, op->shift.value, reg_extend(bits_requested, op->ext, r, REGBITS(n))); } case CS_AARCH64(_OP_IMM): { if (!bits_requested) { diff --git a/test/db/asm/arm_64 b/test/db/asm/arm_64 index 206f58b1b45..c1ebe8e28f3 100644 --- a/test/db/asm/arm_64 +++ b/test/db/asm/arm_64 @@ -402,21 +402,21 @@ d "add x27, x28, w29, uxtb" 9b033d8b 0x0 (set x27 (+ (var x28) (cast 64 false (c d "add x27, x28, w29, uxtb 3" 9b0f3d8b 0x0 (set x27 (+ (var x28) (<< (cast 64 false (cast 8 false (var x29))) (bv 6 0x3) false))) d "add x27, x28, w29, uxth" 9b233d8b 0x0 (set x27 (+ (var x28) (cast 64 false (cast 16 false (var x29))))) d "add x27, x28, w29, uxtw" 9b433d8b 0x0 (set x27 (+ (var x28) (cast 64 false (cast 32 false (var x29))))) -d "add x27, x28, x29, uxtx" 9b633d8b 0x0 (set x27 (+ (var x28) (cast 64 false (cast 64 false (var x29))))) -d "add x27, x28, x29, uxtx 2" 9b6b3d8b 0x0 (set x27 (+ (var x28) (<< (cast 64 false (cast 64 false (var x29))) (bv 6 0x2) false))) +d "add x27, x28, x29, uxtx" 9b633d8b 0x0 (set x27 (+ (var x28) (var x29))) +d "add x27, x28, x29, uxtx 2" 9b6b3d8b 0x0 (set x27 (+ (var x28) (<< (var x29) (bv 6 0x2) false))) d "add x1, x2, w3, sxtb" 4180238b 0x0 (set x1 (+ (var x2) (cast 64 (msb (cast 8 false (var x3))) (cast 8 false (var x3))))) d "add x1, x2, w3, sxtb 1" 4184238b 0x0 (set x1 (+ (var x2) (<< (cast 64 (msb (cast 8 false (var x3))) (cast 8 false (var x3))) (bv 6 0x1) false))) d "add x1, x2, w3, sxth" 41a0238b 0x0 (set x1 (+ (var x2) (cast 64 (msb (cast 16 false (var x3))) (cast 16 false (var x3))))) d "add x1, x2, w3, sxtw" 41c0238b 0x0 (set x1 (+ (var x2) (cast 64 (msb (cast 32 false (var x3))) (cast 32 false (var x3))))) -d "add x1, x2, x3, sxtx" 41e0238b 0x0 (set x1 (+ (var x2) (cast 64 (msb (cast 64 false (var x3))) (cast 64 false (var x3))))) -d "add x1, x2, x3, sxtx 4" 41f0238b 0x0 (set x1 (+ (var x2) (<< (cast 64 (msb (cast 64 false (var x3))) (cast 64 false (var x3))) (bv 6 0x4) false))) +d "add x1, x2, x3, sxtx" 41e0238b 0x0 (set x1 (+ (var x2) (cast 64 (msb (var x3)) (var x3)))) +d "add x1, x2, x3, sxtx 4" 41f0238b 0x0 (set x1 (+ (var x2) (<< (cast 64 (msb (var x3)) (var x3)) (bv 6 0x4) false))) d "add x1, sp, x3, lsl 2" e16b238b 0x0 (set x1 (+ (var sp) (<< (var x3) (bv 6 0x2) false))) d "add x1, sp, x3" e163238b 0x0 (set x1 (+ (var sp) (var x3))) d "add w27, w28, w29, uxtb" 9b033d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (cast 32 false (cast 8 false (var x29)))))) d "add w27, w28, w29, uxtb 2" 9b0b3d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (<< (cast 32 false (cast 8 false (var x29))) (bv 6 0x2) false)))) d "add w27, w28, w29, uxth" 9b233d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (cast 32 false (cast 16 false (var x29)))))) -d "add w27, w28, w29, uxtw" 9b433d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (cast 32 false (cast 32 false (var x29)))))) -d "add w27, w28, w29, uxtw 1" 9b473d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (<< (cast 32 false (cast 32 false (var x29))) (bv 6 0x1) false)))) +d "add w27, w28, w29, uxtw" 9b433d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (cast 32 false (var x29))))) +d "add w27, w28, w29, uxtw 1" 9b473d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (<< (cast 32 false (var x29)) (bv 6 0x1) false)))) d "add w27, w28, w29, uxtx" 9b633d0b 0x0 (set x27 (cast 64 false (+ (cast 32 false (var x28)) (cast 32 false (cast 64 false (var x29)))))) d "add w30, w1, w2, sxtb" 3e80220b 0x0 (set x30 (cast 64 false (+ (cast 32 false (var x1)) (cast 32 (msb (cast 8 false (var x2))) (cast 8 false (var x2)))))) d "add w30, w1, w2, sxth" 3ea0220b 0x0 (set x30 (cast 64 false (+ (cast 32 false (var x1)) (cast 32 (msb (cast 16 false (var x2))) (cast 16 false (var x2)))))) @@ -552,7 +552,7 @@ d "ldr x8, [x25, x8, lsl 3]" 287b68f8 0x0 (set x8 (loadw 0 64 (+ (var x25) (<< ( d "ldr x0, [x1, w2, uxtw]" 204862f8 0x0 (set x0 (loadw 0 64 (+ (var x1) (cast 64 false (cast 32 false (var x2)))))) d "ldr x0, [x1, w2, sxtw]" 20c862f8 0x0 (set x0 (loadw 0 64 (+ (var x1) (cast 64 (msb (cast 32 false (var x2))) (cast 32 false (var x2)))))) d "ldr x0, [x1, w2, sxtw 3]" 20d862f8 0x0 (set x0 (loadw 0 64 (+ (var x1) (<< (cast 64 (msb (cast 32 false (var x2))) (cast 32 false (var x2))) (bv 6 0x3) false)))) -d "ldr x0, [x1, x2, sxtx]" 20e862f8 0x0 (set x0 (loadw 0 64 (+ (var x1) (cast 64 (msb (cast 64 false (var x2))) (cast 64 false (var x2)))))) +d "ldr x0, [x1, x2, sxtx]" 20e862f8 0x0 (set x0 (loadw 0 64 (+ (var x1) (cast 64 (msb (var x2)) (var x2))))) d "ldrsb x0, [x1]" 20008039 0x0 (set x0 (cast 64 (msb (load 0 (var x1))) (load 0 (var x1)))) d "ldrsh x0, [x1]" 20008079 0x0 (set x0 (cast 64 (msb (loadw 0 16 (var x1))) (loadw 0 16 (var x1)))) d "ldrsw x0, [x1]" 200080b9 0x0 (set x0 (cast 64 (msb (loadw 0 32 (var x1))) (loadw 0 32 (var x1)))) @@ -733,9 +733,9 @@ d "uxtb w1, w2" 411c0053 0x0 (set x1 (cast 64 false (cast 32 false (cast 8 false d "uxtb w1, w2" 411c0053 0x0 (set x1 (cast 64 false (cast 32 false (cast 8 false (var x2))))) d "uxth w1, w2" 413c0053 0x0 (set x1 (cast 64 false (cast 32 false (cast 16 false (var x2))))) d "uxth w1, w2" 413c0053 0x0 (set x1 (cast 64 false (cast 32 false (cast 16 false (var x2))))) -d "tbz w1, 0xd, 0x100100" 01086836 0x100000 (branch (lsb (>> (cast 64 false (var x1)) (bv 6 0xd) false)) nop (jmp (bv 64 0x100100))) +d "tbz w1, 0xd, 0x100100" 01086836 0x100000 (branch (lsb (>> (cast 64 false (cast 32 false (var x1))) (bv 6 0xd) false)) nop (jmp (bv 64 0x100100))) d "tbz x1, 0x2a, 0x100100" 010850b6 0x100000 (branch (lsb (>> (var x1) (bv 6 0x2a) false)) nop (jmp (bv 64 0x100100))) -d "tbnz w1, 0xd, 0x100100" 01086837 0x100000 (branch (lsb (>> (cast 64 false (var x1)) (bv 6 0xd) false)) (jmp (bv 64 0x100100)) nop) +d "tbnz w1, 0xd, 0x100100" 01086837 0x100000 (branch (lsb (>> (cast 64 false (cast 32 false (var x1))) (bv 6 0xd) false)) (jmp (bv 64 0x100100)) nop) d "tbnz x1, 0x2a, 0x100100" 010850b7 0x100000 (branch (lsb (>> (var x1) (bv 6 0x2a) false)) (jmp (bv 64 0x100100)) nop) d "tst x0, 6" 1f047ff2 0x0 (seq (set zf (is_zero (& (var x0) (bv 64 0x6)))) (set nf (msb (& (var x0) (bv 64 0x6)))) (set cf false) (set vf false)) d "tst w0, 6" 1f041f72 0x0 (seq (set zf (is_zero (& (cast 32 false (var x0)) (bv 32 0x6)))) (set nf (msb (& (cast 32 false (var x0)) (bv 32 0x6)))) (set cf false) (set vf false))