Skip to content

Commit

Permalink
Fix: i8051 rewriter bug reported by @smx-smx
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Aug 12, 2024
1 parent 9e665d4 commit 6c6b905
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 65 deletions.
5 changes: 0 additions & 5 deletions src/Arch/i8051/BitOperand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
116 changes: 66 additions & 50 deletions src/Arch/i8051/i8051Rewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,19 @@ private void RewriteLogical(Func<Expression, Expression, Expression> 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()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

/// <summary>
/// Some 8051 registers are aliased to memory addresses.
/// </summary>
Expand Down
18 changes: 11 additions & 7 deletions src/UnitTests/Arch/i8051/i8051RewriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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<byte,byte>(SFR40, 2<8>, C)"
);

}

[Test]
public void I8051_rw_sjmp()
{
Expand Down
6 changes: 3 additions & 3 deletions subjects/regression.log

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6c6b905

Please sign in to comment.