diff options
| author | Galen Williamson <galen@vector35.com> | 2024-06-13 19:39:53 -0400 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2024-06-13 19:39:53 -0400 |
| commit | e01e3b66e1d7e7fb28750e946f3b9e8fd740284b (patch) | |
| tree | 83f313baa148b42d7781950bdd95d1f94f34e111 /arch/arm64/il.cpp | |
| parent | d97e381a59b61cc4ce4fb3f16f2809f204f62fa9 (diff) | |
[arm64] fixed lifting for LDADD*, filled in lifting for alias STADD*, fixed tests for recently added system registers dczid_el0 and ctr_el0; fixes #5603
Diffstat (limited to 'arch/arm64/il.cpp')
| -rw-r--r-- | arch/arm64/il.cpp | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/arch/arm64/il.cpp b/arch/arm64/il.cpp index 8af45d87..e7ff35e8 100644 --- a/arch/arm64/il.cpp +++ b/arch/arm64/il.cpp @@ -890,6 +890,8 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex ExprId tmp; if (load) { + // LLIL_TEMP registers will be reported to have size 0, so override with size + size_t extendSize = REGSZ_O(operand1) ?: size; switch (operand2.operandClass) { case MEM_REG: @@ -897,9 +899,9 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex tmp = il.Operand(1, il.Load(size, ILREG_O(operand2))); if (sign_extend) - tmp = il.SignExtend(REGSZ_O(operand1), tmp); + tmp = il.SignExtend(extendSize, tmp); else - tmp = il.ZeroExtend(REGSZ_O(operand1), tmp); + tmp = il.ZeroExtend(extendSize, tmp); il.AddInstruction(ILSETREG_O(operand1, tmp)); break; @@ -913,9 +915,9 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex tmp = il.Operand(1, il.Load(size, tmp)); if (sign_extend) - tmp = il.SignExtend(REGSZ_O(operand1), tmp); + tmp = il.SignExtend(extendSize, tmp); else - tmp = il.ZeroExtend(REGSZ_O(operand1), tmp); + tmp = il.ZeroExtend(extendSize, tmp); il.AddInstruction(ILSETREG_O(operand1, tmp)); break; @@ -928,9 +930,9 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex tmp = il.Operand(1, il.Load(size, ILREG_O(operand2))); if (sign_extend) - tmp = il.SignExtend(REGSZ_O(operand1), tmp); + tmp = il.SignExtend(extendSize, tmp); else - tmp = il.ZeroExtend(REGSZ_O(operand1), tmp); + tmp = il.ZeroExtend(extendSize, tmp); il.AddInstruction(ILSETREG_O(operand1, tmp)); break; @@ -939,9 +941,9 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex tmp = il.Operand(1, il.Load(size, ILREG_O(operand2))); if (sign_extend) - tmp = il.SignExtend(REGSZ_O(operand1), tmp); + tmp = il.SignExtend(extendSize, tmp); else - tmp = il.ZeroExtend(REGSZ_O(operand1), tmp); + tmp = il.ZeroExtend(extendSize, tmp); il.AddInstruction(ILSETREG_O(operand1, tmp)); // operand2.reg += operand2.imm @@ -955,9 +957,9 @@ static void LoadStoreOperandSize(LowLevelILFunction& il, bool load, bool sign_ex GetShiftedRegister(il, operand2, 1, REGSZ_O(operand2))))); if (sign_extend) - tmp = il.SignExtend(REGSZ_O(operand1), tmp); + tmp = il.SignExtend(extendSize, tmp); else - tmp = il.ZeroExtend(REGSZ_O(operand1), tmp); + tmp = il.ZeroExtend(extendSize, tmp); il.AddInstruction(ILSETREG_O(operand1, tmp)); break; @@ -1832,25 +1834,68 @@ bool GetLowLevelILForInstruction( case ARM64_LDADDA: case ARM64_LDADDL: case ARM64_LDADDAL: - LoadStoreOperand(il, true, operand2, operand3, 0); - il.AddInstruction(il.Store(REGSZ_O(operand3), ILREG_O(operand3), - il.Add(REGSZ_O(operand1), ILREG_O(operand1), ILREG_O(operand2)))); + { + // TODO: represent/annotate (model?) acquire/release memory ordering semantics for all LDADD* instructions + InstructionOperand tmp = { .reg = { (Register) LLIL_TEMP(0) } }; + LoadStoreOperandSize(il, true, false, REGSZ_O(operand2), tmp, operand3); + il.AddInstruction(il.Store(REGSZ_O(operand2), ILREG_O(operand3), + il.Add(REGSZ_O(operand1), + ILREG_O(operand1), + il.ZeroExtend(REGSZ_O(operand2), + il.Register(REGSZ_O(operand2), LLIL_TEMP(0)))))); + if (!(operand2.reg[0] == REG_XZR || operand2.reg[0] == REG_WZR)) + il.AddInstruction(ILSETREG_O(operand2, + il.ZeroExtend(REGSZ_O(operand2), + il.Register(REGSZ_O(operand2), LLIL_TEMP(0))))); + break; + } + case ARM64_STADD: + case ARM64_STADDL: + // STADD* are aliases of the corresponding LDADD*, so group them together + il.AddInstruction(il.Store(REGSZ_O(operand2), ILREG_O(operand2), + il.Add(REGSZ_O(operand1), ILREG_O(operand1), il.Load(REGSZ_O(operand1), ILREG_O(operand2))))); break; case ARM64_LDADDB: case ARM64_LDADDAB: case ARM64_LDADDLB: case ARM64_LDADDALB: - LoadStoreOperand(il, true, operand2, operand3, 1); - il.AddInstruction(il.Store(REGSZ_O(operand3), ILREG_O(operand3), - il.Add(1, il.LowPart(1, ILREG_O(operand1)), il.LowPart(1, ILREG_O(operand2))))); + { + InstructionOperand tmp = { .reg = { (Register) LLIL_TEMP(0) } }; + LoadStoreOperandSize(il, true, false, 1, tmp, operand3); + il.AddInstruction(il.Store(1, ILREG_O(operand3), + il.Add(1, il.LowPart(1, ILREG_O(operand1)), il.LowPart(1, il.Register(1, LLIL_TEMP(0)))))); + if (!(operand2.reg[0] == REG_XZR || operand2.reg[0] == REG_WZR)) + il.AddInstruction(ILSETREG_O(operand2, + il.ZeroExtend(REGSZ_O(operand2), + il.LowPart(1, il.Register(1, LLIL_TEMP(0)))))); + break; + } + case ARM64_STADDB: + case ARM64_STADDLB: + // STADD* are aliases of the corresponding LDADD*, so group them together + il.AddInstruction(il.Store(1, ILREG_O(operand2), + il.Add(1, il.LowPart(1, ILREG_O(operand1)), il.Load(1, ILREG_O(operand2))))); break; case ARM64_LDADDH: case ARM64_LDADDAH: case ARM64_LDADDLH: case ARM64_LDADDALH: - LoadStoreOperand(il, true, operand2, operand3, 2); - il.AddInstruction(il.Store(REGSZ_O(operand3), ILREG_O(operand3), - il.Add(2, il.LowPart(2, ILREG_O(operand1)), il.LowPart(2, ILREG_O(operand2))))); + { + InstructionOperand tmp = { .reg = { (Register) LLIL_TEMP(0) } }; + LoadStoreOperandSize(il, true, false, 2, tmp, operand3); + il.AddInstruction(il.Store(2, ILREG_O(operand3), + il.Add(2, il.LowPart(2, ILREG_O(operand1)), il.LowPart(2, il.Register(2, LLIL_TEMP(0)))))); + if (!(operand2.reg[0] == REG_XZR || operand2.reg[0] == REG_WZR)) + il.AddInstruction(ILSETREG_O(operand2, + il.ZeroExtend(REGSZ_O(operand2), + il.LowPart(2, il.Register(2, LLIL_TEMP(0)))))); + break; + } + case ARM64_STADDH: + case ARM64_STADDLH: + // STADD* are aliases of the corresponding LDADD*, so group them together + il.AddInstruction(il.Store(2, ILREG_O(operand2), + il.Add(2, il.LowPart(2, ILREG_O(operand1)), il.Load(2, ILREG_O(operand2))))); break; case ARM64_LSL: il.AddInstruction(ILSETREG_O(operand1, il.ShiftLeft(REGSZ_O(operand2), ILREG_O(operand2), |
