From 6c6b905322e9d2754bb2b6b5e9565eba550dedfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A4ll=C3=A9n?= Date: Mon, 12 Aug 2024 14:37:25 +0200 Subject: [PATCH] Fix: i8051 rewriter bug reported by @smx-smx --- src/Arch/i8051/BitOperand.cs | 5 - src/Arch/i8051/i8051Rewriter.cs | 116 ++++++++++-------- .../Arch/i8051/i8051RewriterTests.cs | 18 +-- subjects/regression.log | 6 +- 4 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/Arch/i8051/BitOperand.cs b/src/Arch/i8051/BitOperand.cs index 82b76cd358..f563b17d91 100644 --- a/src/Arch/i8051/BitOperand.cs +++ b/src/Arch/i8051/BitOperand.cs @@ -21,11 +21,6 @@ using Reko.Core; using Reko.Core.Machine; using Reko.Core.Types; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Reko.Arch.i8051 { diff --git a/src/Arch/i8051/i8051Rewriter.cs b/src/Arch/i8051/i8051Rewriter.cs index a7aaebbf07..7fd9021646 100644 --- a/src/Arch/i8051/i8051Rewriter.cs +++ b/src/Arch/i8051/i8051Rewriter.cs @@ -313,9 +313,19 @@ private void RewriteLogical(Func fn) private void RewriteMov() { - var dst = OpSrc(instr.Operands[0], arch.DataMemory); var src = OpSrc(instr.Operands[1], arch.DataMemory); - m.Assign(dst, src); + if (instr.Operands[0] is BitOperand bit) + { + var r = binder.EnsureRegister(bit.Register); + m.Assign(r, m.Fn( + CommonOps.WriteBit.MakeInstance(r.DataType, PrimitiveType.Byte), + r, m.Byte((byte)bit.Bit), src)); + } + else + { + var dst = OpSrc(instr.Operands[0], arch.DataMemory); + m.Assign(dst, src); + } } private void RewriteMovc() @@ -449,54 +459,7 @@ private Expression OpSrc(MachineOperand op, RegisterStorage? dataMemory) case AddressOperand addr: return addr.Address; case MemoryOperand mem: - Expression ea; - if (mem.DirectAddress != null) - { - if (mem.Index != null) - { - ea = m.IAdd(mem.DirectAddress, binder.EnsureRegister(mem.Index)); - } - else if (mem.DirectAddress is Constant c) - { - var alias = AliasedSpecialFunctionRegister(c.ToUInt16()); - if (alias != null) - return alias; - ea = c; - } - else - { - ea = mem.DirectAddress; - } - } - else if (mem.Register != null) - { - if (mem.Index != null) - { - var idx = binder.EnsureRegister(mem.Index); - if (mem.Register == Registers.PC) - { - ea = m.IAdd( - instr.Address + instr.Length, idx); - } - else - { - ea = binder.EnsureIdentifier(mem.Register); - ea = m.IAdd(ea, idx); - } - } - else - { - ea = binder.EnsureIdentifier(mem.Register); - } - } - else - { - throw new NotImplementedException(); - } - if (ea.DataType.BitSize < 16) - { - ea = m.Convert(ea, PrimitiveType.Byte, PrimitiveType.Word16); - } + var ea = EffectiveAddress(mem); if (dataMemory != null) { return m.SegMem(mem.Width, binder.EnsureRegister(dataMemory), ea); @@ -524,6 +487,59 @@ private Expression OpSrc(MachineOperand op, RegisterStorage? dataMemory) } } + private Expression EffectiveAddress(MemoryOperand mem) + { + Expression ea; + if (mem.DirectAddress != null) + { + if (mem.Index != null) + { + ea = m.IAdd(mem.DirectAddress, binder.EnsureRegister(mem.Index)); + } + else if (mem.DirectAddress is Constant c) + { + var alias = AliasedSpecialFunctionRegister(c.ToUInt16()); + if (alias != null) + return alias; + ea = c; + } + else + { + ea = mem.DirectAddress; + } + } + else if (mem.Register != null) + { + if (mem.Index != null) + { + var idx = binder.EnsureRegister(mem.Index); + if (mem.Register == Registers.PC) + { + ea = m.IAdd( + instr.Address + instr.Length, idx); + } + else + { + ea = binder.EnsureIdentifier(mem.Register); + ea = m.IAdd(ea, idx); + } + } + else + { + ea = binder.EnsureIdentifier(mem.Register); + } + } + else + { + throw new NotImplementedException(); + } + if (ea.DataType.BitSize < 16) + { + ea = m.Convert(ea, PrimitiveType.Byte, PrimitiveType.Word16); + } + return ea; + } + /// /// Some 8051 registers are aliased to memory addresses. /// diff --git a/src/UnitTests/Arch/i8051/i8051RewriterTests.cs b/src/UnitTests/Arch/i8051/i8051RewriterTests.cs index 3118e0877f..b9f9dc35d3 100644 --- a/src/UnitTests/Arch/i8051/i8051RewriterTests.cs +++ b/src/UnitTests/Arch/i8051/i8051RewriterTests.cs @@ -21,14 +21,7 @@ using NUnit.Framework; using Reko.Arch.i8051; using Reko.Core; -using Reko.Core.Memory; -using Reko.Core.Rtl; -using System; using System.Collections.Generic; -using System.ComponentModel.Design; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Reko.UnitTests.Arch.i8051 { @@ -211,6 +204,17 @@ public void I8051_rw_mov() "1|L--|R7 = A"); } + [Test] + public void I8051_rw_mov_bit_dst() + { + Given_HexString("92 42"); + AssertCode( + "0|L--|0000(2): 1 instructions", + "1|L--|SFR40 = __write_bit(SFR40, 2<8>, C)" + ); + + } + [Test] public void I8051_rw_sjmp() { diff --git a/subjects/regression.log b/subjects/regression.log index a270dfe25a..1823d03b31 100644 --- a/subjects/regression.log +++ b/subjects/regression.log @@ -1135,8 +1135,8 @@ Signature of 'Microsoft Visual C++ 8' detected. *** Elf\AVR32\ls fn00008FF2: error: An error occurred while rewriting procedure to high-level language. Can't collapse fn00008FF2_entry (Tail) => l00008FF0_thunk_fn00008FF2) in procedure fn00008FF2 - at Reko.Structure.StructureAnalysis.CollapseToTailRegion(Region from, Region to, AbsynStatement stm) in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 982 - at Reko.Structure.StructureAnalysis.VirtualizeEdge(VirtualEdge vEdge) in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 932 + at Reko.Structure.StructureAnalysis.CollapseToTailRegion(Region from, Region to, AbsynStatement stm) in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 960 + at Reko.Structure.StructureAnalysis.VirtualizeEdge(VirtualEdge vEdge) in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 906 at Reko.Structure.StructureAnalysis.VirtualizeReturn(Region n) in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 312 at Reko.Structure.StructureAnalysis.ProcessUnresolvedRegions() in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 285 at Reko.Structure.StructureAnalysis.Execute() in c:\dev\uxmal\reko\master\src\Decompiler\Structure\StructureAnalysis.cs:line 172 @@ -2677,4 +2677,4 @@ PE Debug type 14 not supported yet. === PE\x86\VCExeSample\VCExeSample Signature of 'Microsoft Visual C++ 8' detected. -Decompiled 93 binaries in 37.89 seconds. +Decompiled 93 binaries in 38.19 seconds.