diff --git a/arch/arm64/arm64test.py b/arch/arm64/arm64test.py index 0d568f3893..64d0be1246 100755 --- a/arch/arm64/arm64test.py +++ b/arch/arm64/arm64test.py @@ -15,6 +15,21 @@ ATTR_PTR_AUTH = ILInstructionAttribute(8) # enum BNILInstructionAttribute.SrcInstructionUsesPointerAuth from api/binaryninjacore.h +tests_sshll = [ + # sshll v0.2d, v0.2s, #0xf + (b'\x00\xa4\x2f\x0f', 'LLIL_SET_REG.q(v0.d[0],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[0]),LLIL_CONST.b(0x0)),LLIL_CONST.b(0xF))));' + \ + ' LLIL_SET_REG.q(v0.d[1],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[1]),LLIL_CONST.b(0x0)),LLIL_CONST.b(0xF))))'), + # sxtl v0.2d, v0.2s + (b'\x00\xa4\x20\x0f', 'LLIL_SET_REG.q(v0.d[0],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[0]),LLIL_CONST.b(0x0)),LLIL_CONST.b(0x0))));' + \ + ' LLIL_SET_REG.q(v0.d[1],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[1]),LLIL_CONST.b(0x0)),LLIL_CONST.b(0x0))))'), + # sshll2 v0.2d, v0.4s, #0xf + (b'\x00\xa4\x2f\x4f', 'LLIL_SET_REG.q(v0.d[0],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[0]),LLIL_CONST.b(0x40)),LLIL_CONST.b(0xF))));' + \ + ' LLIL_SET_REG.q(v0.d[1],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[1]),LLIL_CONST.b(0x40)),LLIL_CONST.b(0xF))))'), + # sxtl2 v0.2d, v0.2s + (b'\x00\xa4\x20\x4f', 'LLIL_SET_REG.q(v0.d[0],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[0]),LLIL_CONST.b(0x40)),LLIL_CONST.b(0x0))));' + \ + ' LLIL_SET_REG.q(v0.d[1],LLIL_SX.q(LLIL_LSL.q(LLIL_LSR.d(LLIL_REG.d(v0.s[1]),LLIL_CONST.b(0x40)),LLIL_CONST.b(0x0))))'), +] + tests_udf = [ # udf #0 (b'\x00\x00\x00\x00', 'LLIL_TRAP(0)'), @@ -2232,44 +2247,7 @@ ' LLIL_SET_REG.q(x29,LLIL_ADD.q(LLIL_REG.q(x29),LLIL_REG.q(x21)))'), ] -test_cases = \ - tests_udf + \ - tests_pac + \ - tests_load_acquire_store_release + \ - tests_movk + \ - tests_mvni + \ - tests_2791 + \ - tests_ucvtf + \ - tests_ucvtf2 + \ - tests_scvtf + \ - tests_ret + \ - tests_svc_hvc_smc + \ - tests_clrex + \ - tests_xtn_xtn2 + \ - tests_dc + \ - tests_uxtl_uxtl2 + \ - tests_ldadd + \ - tests_swp + \ - tests_dup + \ - tests_stlr + \ - tests_ldnp + \ - tests_stnp + \ - tests_mov + \ - tests_movi + \ - tests_fsub + \ - tests_fadd + \ - tests_fmul + \ - tests_fcvt + \ - tests_fccmp_fccmpe + \ - tests_fcmp_fcmpe + \ - tests_fcsel + \ - tests_fmov + \ - tests_sha + \ - tests_rev + \ - tests_ld1 + \ - tests_ld2 + \ - tests_st1 + \ - [ +tests_grab_bag = [ # some vectors loads/stores that do not fill the entire register # TODO: ld1/st1 with different addressing modes # ld1 {v0.8b, v1.8b}, [x0] @@ -2850,6 +2828,46 @@ (b'\x1F\x20\x03\xD5', 'LLIL_NOP()'), # nop, gets optimized from function ] +test_cases = \ + tests_sshll + \ + tests_udf + \ + tests_pac + \ + tests_load_acquire_store_release + \ + tests_movk + \ + tests_mvni + \ + tests_2791 + \ + tests_ucvtf + \ + tests_ucvtf2 + \ + tests_scvtf + \ + tests_ret + \ + tests_svc_hvc_smc + \ + tests_clrex + \ + tests_xtn_xtn2 + \ + tests_dc + \ + tests_uxtl_uxtl2 + \ + tests_ldadd + \ + tests_swp + \ + tests_dup + \ + tests_stlr + \ + tests_ldnp + \ + tests_stnp + \ + tests_mov + \ + tests_movi + \ + tests_fsub + \ + tests_fadd + \ + tests_fmul + \ + tests_fcvt + \ + tests_fccmp_fccmpe + \ + tests_fcmp_fcmpe + \ + tests_fcsel + \ + tests_fmov + \ + tests_sha + \ + tests_rev + \ + tests_ld1 + \ + tests_ld2 + \ + tests_st1 + \ + tests_grab_bag + def il2str(il): sz_lookup = {1:'.b', 2:'.w', 4:'.d', 8:'.q', 16:'.o'} if isinstance(il, lowlevelil.LowLevelILInstruction): diff --git a/arch/arm64/il.cpp b/arch/arm64/il.cpp index d3c3e94366..bd665601f7 100644 --- a/arch/arm64/il.cpp +++ b/arch/arm64/il.cpp @@ -2217,6 +2217,41 @@ bool GetLowLevelILForInstruction( break; } + case ARM64_SXTL: + case ARM64_SXTL2: + case ARM64_SSHLL: + case ARM64_SSHLL2: + { + Register srcs[16], dsts[16]; + int dst_n = unpack_vector(operand1, dsts); + int src_n = unpack_vector(operand2, srcs); + + // We cannot check that the src and dst counts are the same here + // because the 2 variants use different count arrange specs, e.g. + // sxtl2 v0.2d, v1.4s + + int left_shift = 0; + if (instr.operation == ARM64_SSHLL || instr.operation == ARM64_SSHLL2) + left_shift = IMM_O(operand3); + + int two_variant_shift = 0; + if (instr.operation == ARM64_SXTL2 || instr.operation == ARM64_SSHLL2) + two_variant_shift = 64; + + int dst_size = get_register_size(dsts[0]); + int src_size = get_register_size(srcs[0]); + + for (int i = 0; i < dst_n; ++i) + il.AddInstruction(il.SetRegister(dst_size, dsts[i], + il.SignExtend(dst_size, + il.ShiftLeft(dst_size, + il.LogicalShiftRight(src_size, + il.Register(src_size, srcs[i]), + il.Const(1, two_variant_shift)), + il.Const(1, left_shift))))); + + break; + } case ARM64_ST1: LoadStoreVector(il, false, instr.operands[0], instr.operands[1]); break;