Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 56 additions & 38 deletions arch/arm64/arm64test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)'),
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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):
Expand Down
35 changes: 35 additions & 0 deletions arch/arm64/il.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down