Skip to content

Commit

Permalink
Feature: support for PDP-11 mfpt and spl instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Aug 28, 2024
1 parent 77ba222 commit 6d7309b
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 32 deletions.
8 changes: 0 additions & 8 deletions src/Arch/Padauk/Pdk14InstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,9 @@

using Reko.Core;
using Reko.Core.Machine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;

namespace Reko.Arch.Padauk
{
using Decoder = Reko.Core.Machine.Decoder<PadaukDisassembler, Mnemonic, PadaukInstruction>;

partial class PadaukDisassembler
{
internal class Pdk14InstructionSet : InstructionSet
Expand Down
1 change: 1 addition & 0 deletions src/Arch/Pdp/Pdp11/Mnemonic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,6 @@ public enum Mnemonic
ldexp,
ldcid,
ldcfd,
mfpt,
}
}
31 changes: 20 additions & 11 deletions src/Arch/Pdp/Pdp11/Pdp11Disassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private static bool w(uint uInstr, Pdp11Disassembler dasm)
private static bool E(uint wOpcode, Pdp11Disassembler dasm)
{
var op = dasm.DecodeOperand(wOpcode);
if (op == null)
if (op is null)
return false;
dasm.ops.Add(op);
return true;
Expand Down Expand Up @@ -157,6 +157,15 @@ private static bool Ib(uint wOpcode, Pdp11Disassembler dasm)
return true;
}

/// <summary>
/// Low order 3 bits of instruction word.
/// </summary>
private static bool I3(uint wOpcode, Pdp11Disassembler dasm)
{
var op = ImmediateOperand.Byte((byte) (wOpcode & 0x07));
dasm.ops.Add(op);
return true;
}
// I4 - low order 4 bits.
private static bool I4(uint wOpcode, Pdp11Disassembler dasm)
{
Expand Down Expand Up @@ -226,26 +235,26 @@ static Pdp11Disassembler()
(0x04, Instr(Mnemonic.iot)),
(0x05, Instr(Mnemonic.reset, InstrClass.Transfer)),
(0x06, Instr(Mnemonic.rtt, InstrClass.Transfer | InstrClass.Return)),
(0x07, illegal))),
(0x07, Instr(Mnemonic.mfpt)))),
(0x001, Instr(Mnemonic.jmp, InstrClass.Transfer, E)),
(0x002, Mask(3, 3, " 002",
Instr(Mnemonic.rts, InstrClass.Transfer | InstrClass.Return, R0),
Instr(Mnemonic.spl, E),
illegal,
illegal,
Instr(Mnemonic.spl, I3),
condCode,
condCode,
condCode,
condCode)),
(0x003, Instr(Mnemonic.swab, E)),
(0x020, jsr),
(0x021, jsr),
(0x022, jsr),
(0x023, jsr),
(0x024, jsr),
(0x025, jsr),
(0x026, jsr),
(0x027, jsr),
(0x020, jsr),
(0x021, jsr),
(0x022, jsr),
(0x023, jsr),
(0x024, jsr),
(0x025, jsr),
(0x026, jsr),
(0x027, jsr),

(0x220, emt),
(0x221, emt),
Expand Down
6 changes: 6 additions & 0 deletions src/Arch/Pdp/Pdp11/Pdp11Rewriter.Alu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ private void RewriteMfpi()
SetFalse(Registers.V);
}

private void RewriteMfpt()
{
var r0 = binder.EnsureRegister(Registers.r0);
m.Assign(r0, m.Fn(mfpt_intrinsic));
}

private void RewriteMtpi()
{
var src = RewriteSrc(instr.Operands[0]);
Expand Down
5 changes: 5 additions & 0 deletions src/Arch/Pdp/Pdp11/Pdp11Rewriter.Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ private void RewriteSob()
}
}

private void RewriteSpl()
{
m.SideEffect(m.Fn(spl_intrinsic, this.RewriteSrc(instr.Operands[0])));
}

private void RewriteTrap()
{
this.iclass = InstrClass.Transfer;
Expand Down
25 changes: 21 additions & 4 deletions src/Arch/Pdp/Pdp11/Pdp11Rewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@
using Reko.Core.Expressions;
using Reko.Core.Intrinsics;
using Reko.Core.Machine;
using Reko.Core.Memory;
using Reko.Core.Rtl;
using Reko.Core.Serialization;
using Reko.Core.Services;
using Reko.Core.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Reko.Arch.Pdp.Pdp11
{
public partial class Pdp11Rewriter : IEnumerable<RtlInstructionCluster>
{
private readonly Pdp11Architecture arch;
private readonly EndianImageReader rdr;
private readonly IStorageBinder binder;
private readonly IRewriterHost host;
private readonly IEnumerator<Pdp11Instruction> dasm;
Expand All @@ -45,12 +46,13 @@ public partial class Pdp11Rewriter : IEnumerable<RtlInstructionCluster>

public Pdp11Rewriter(
Pdp11Architecture arch,
IEnumerable<Pdp11Instruction> instrs,
EndianImageReader rdr,
IStorageBinder binder,
IRewriterHost host)
{
this.arch = arch;
this.dasm = instrs.GetEnumerator();
this.rdr = rdr;
this.dasm = new Pdp11Disassembler(rdr, arch).GetEnumerator();
this.binder = binder;
this.host = host;
this.rtlInstructions = new List<RtlInstruction>();
Expand All @@ -71,6 +73,7 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
instr.Address,
"PDP-11 instruction {0} is not supported yet.",
instr.Mnemonic);
EmitUnitTest();
iclass = InstrClass.Invalid;
m.Invalid();
break;
Expand Down Expand Up @@ -125,6 +128,7 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.mark: RewriteMark(); break;
case Mnemonic.mfpd: RewriteMfpd(); break;
case Mnemonic.mfpi: RewriteMfpi(); break;
case Mnemonic.mfpt: RewriteMfpt(); break;
case Mnemonic.mov: RewriteMov(); break;
case Mnemonic.movb: RewriteMov(); break;
case Mnemonic.mtpi: RewriteMtpi(); break;
Expand All @@ -145,6 +149,7 @@ public IEnumerator<RtlInstructionCluster> GetEnumerator()
case Mnemonic.setflags: RewriteClrSetFlags(Constant.True); break;
case Mnemonic.stcdi: RewriteStcdi(); break;
case Mnemonic.sob: RewriteSob(); break;
case Mnemonic.spl: RewriteSpl(); break;
case Mnemonic.stexp: RewriteStexp(); break;
case Mnemonic.sub: RewriteSub(); break;
case Mnemonic.swab: RewriteSwab(); break;
Expand All @@ -165,6 +170,13 @@ IEnumerator IEnumerable.GetEnumerator()
return GetEnumerator();
}

private void EmitUnitTest()
{
var testGenSvc = arch.Services.GetService<ITestGenerationService>();
testGenSvc?.ReportMissingRewriter("Pdp11Rw", instr, instr.Mnemonic.ToString(), rdr, "");
}


private void SetFlags(Expression? e, FlagGroupStorage changed)
{
if (e == null)
Expand Down Expand Up @@ -623,6 +635,8 @@ private void Invalid()
static readonly IntrinsicProcedure mfpi_intrinsic = new IntrinsicBuilder("__mfpi", true)
.Param(PrimitiveType.Word16)
.Returns(PrimitiveType.Word16);
static readonly IntrinsicProcedure mfpt_intrinsic = new IntrinsicBuilder("__mfpt", true)
.Returns(PrimitiveType.Word16);
static readonly IntrinsicProcedure mtpi_intrinsic = new IntrinsicBuilder("__mtpi", true)
.Param(PrimitiveType.Word16)
.Param(PrimitiveType.Word16)
Expand All @@ -634,6 +648,9 @@ private void Invalid()
.Param("TValue")
.Param("TShift")
.Returns("TValue");
static readonly IntrinsicProcedure spl_intrinsic = new IntrinsicBuilder("__set_priority_level", true)
.Param(PrimitiveType.Byte)
.Void();
static readonly IntrinsicProcedure stexp_intrinsic = new IntrinsicBuilder("__stexp", true)
.GenericTypes("T")
.Param("T")
Expand Down
2 changes: 1 addition & 1 deletion src/Arch/Pdp/Pdp11Architecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public override string GrfToString(RegisterStorage flagregister, string prefix,

public override IEnumerable<RtlInstructionCluster> CreateRewriter(EndianImageReader rdr, ProcessorState state, IStorageBinder binder, IRewriterHost host)
{
return new Pdp11Rewriter(this, new Pdp11Disassembler(rdr, this), binder, host);
return new Pdp11Rewriter(this, rdr, binder, host);
}

public override Address MakeAddressFromConstant(Constant c, bool codeAlign)
Expand Down
10 changes: 3 additions & 7 deletions src/Arch/PowerPC/PowerPcRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,15 @@

using Reko.Core;
using Reko.Core.Expressions;
using Reko.Core.Operators;
using Reko.Core.Intrinsics;
using Reko.Core.Machine;
using Reko.Core.Memory;
using Reko.Core.Rtl;
using Reko.Core.Services;
using Reko.Core.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Reko.Core.Services;
using Reko.Core.Memory;
using Reko.Core.Intrinsics;

namespace Reko.Arch.PowerPC
{
Expand Down
13 changes: 13 additions & 0 deletions src/UnitTests/Arch/Pdp/Pdp11/DisassemblerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class DisassemblerTests
public void Setup()
{
this.options = MachineInstructionRendererOptions.Default;
Reko.Core.Machine.Decoder.trace.Level = System.Diagnostics.TraceLevel.Verbose;
}

private void RunTest(string expected, params ushort[] words)
Expand Down Expand Up @@ -196,6 +197,12 @@ public void Pdp11dis_bis()
RunTest("bis\t#2000,@#0024", 0x55DF, 0x2000, 0x0024);
}

[Test]
public void Pdp11dis_mfpt()
{
RunTest("mfpt", 0x0007);
}

[Test]
public void Pdp11dis_setflags()
{
Expand All @@ -208,6 +215,12 @@ public void Pdp11dis_mul2()
RunTest("mul\tr0,r3", 0xF0C0);
}

[Test]
public void Pdp11dis_spl()
{
RunTest("spl\t#04", 0x009C);
}

[Test]
public void Pdp11dis_stcdi()
{
Expand Down
20 changes: 19 additions & 1 deletion src/UnitTests/Arch/Pdp/Pdp11/RewriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ public void Pdp11Rw_add()
"2|L--|NZVC = cond(r2)");
}

[Test]
public void Pdp11Rw_spl()
{
Given_HexString("9A00");
AssertCode( // spl #2
"0|L--|03E0(2): 1 instructions",
"1|L--|@@@");
}

[Test]
public void Pdp11Rw_sub()
{
Expand Down Expand Up @@ -560,7 +569,7 @@ public void Pdp11Rw_swab()
}

[Test]
public void Pdp11Rw_Sob()
public void Pdp11Rw_sob()
{
Given_UInt16s(0x7E44); // sob r0,..
AssertCode(
Expand Down Expand Up @@ -645,6 +654,15 @@ public void Pdp11Rw_jmp_deferred()
"1|T--|goto 00DC");
}

[Test]
public void Pdp11rw_mfpt()
{
Given_UInt16s(0x0007);
AssertCode( // mfpt
"0|L--|0200(2): 1 instructions",
"1|L--|r0 = __mfpt()");
}

[Test]
public void Pdp11rw_mov_absolute()
{
Expand Down

0 comments on commit 6d7309b

Please sign in to comment.