Skip to content

Commit

Permalink
Feature: Padauk architecture (#1236)
Browse files Browse the repository at this point in the history
* Architecture definition for Padauk processor family.
* Disassembler for PDK13,PDK14 and PDK15 instruction sets.
* Support per-MemoryArea granularity.
  • Loading branch information
uxmal committed Jan 13, 2023
1 parent 37eec36 commit 038acf4
Show file tree
Hide file tree
Showing 65 changed files with 20,590 additions and 171 deletions.
2 changes: 1 addition & 1 deletion src/Arch/Cray/CrayYmpArchitecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private InstructionSet CreateInstructionSet()
return new YmpInstructionSet();
}

public override MemoryArea CreateMemoryArea(Address addr, byte[] bytes)
public override MemoryArea CreateCodeMemoryArea(Address addr, byte[] bytes)
{
// NOTE: assumes the bytes are provided in big-endian form.
var words = new ulong[bytes.Length / 8];
Expand Down
5 changes: 3 additions & 2 deletions src/Arch/H8/RegisterListOperand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ public RegisterListOperand(int iReg, int count) : base(PrimitiveType.Byte)

protected override void DoRender(MachineInstructionRenderer renderer, MachineInstructionRendererOptions options)
{
var gpregs = Registers.GpRegisters;
renderer.WriteFormat("({0}-{1})",
Registers.GpRegisters[RegisterNumber],
Registers.GpRegisters[RegisterNumber + Count - 1]);
gpregs[RegisterNumber],
gpregs[(RegisterNumber + Count - 1) % gpregs.Length]);
}
}
}
9 changes: 2 additions & 7 deletions src/Arch/MilStd1750/MilStd1750Architecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,10 @@ public override IEnumerable<MachineInstruction> CreateDisassembler(EndianImageRe
return new MilStd1750Disassembler(this, rdr);
}

public override MemoryArea CreateMemoryArea(Address addr, byte[] bytes)
public override MemoryArea CreateCodeMemoryArea(Address addr, byte[] bytes)
{
// NOTE: assumes the bytes are provided in big-endian form.
var words = new ushort[bytes.Length / 2];
for (int i = 0; i < words.Length; ++i)
{
words[i] = (ushort)((bytes[i * 2] << 8) | bytes[i * 2 + 1]);
}
return new Word16MemoryArea(addr, words);
return Word16MemoryArea.CreateFromBeBytes(addr, bytes);
}

public override IEqualityComparer<MachineInstruction> CreateInstructionComparer(Normalize norm)
Expand Down
46 changes: 46 additions & 0 deletions src/Arch/Padauk/MemoryOperand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#region License
/*
* Copyright (C) 1999-2023 John Källén.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#endregion

using Reko.Core.Machine;
using Reko.Core.Types;

namespace Reko.Arch.Padauk
{
public class MemoryOperand : AbstractMachineOperand
{
public MemoryOperand(PrimitiveType dt) : base(dt)
{
}

public uint Offset { get; set; }
public int? Bit { get; set; }
public bool Indirect { get; set; }

protected override void DoRender(MachineInstructionRenderer renderer, MachineInstructionRendererOptions options)
{
var format = Indirect ? "[[0x{0:X}]]" : "[0x{0:X}]";
renderer.WriteFormat(format, Offset);
if (Bit.HasValue)
{
renderer.WriteFormat(".{0}", Bit.Value);
}
}
}
}
87 changes: 87 additions & 0 deletions src/Arch/Padauk/Mnemonic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#region License
/*
* Copyright (C) 1999-2023 John Källén.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reko.Arch.Padauk
{
public enum Mnemonic
{
Invalid,

add,
addc,
and,
call,
ceqsn,
clear,
cneqsn,
comp,
dec,
disgint,
dzsn,
engint,
@goto,
idxm,
inc,
izsn,
ldspth,
ldsptl,
ldt16,
ldtabh,
ldtabl,
mov,
mul,
nadd,
neg,
nop,
not,
or,
pcadd,
popaf,
pushaf,
reset,
ret,
reti,
set0,
set1,
sl,
slc,
sr,
src,
stopexe,
stopsys,
stt16,
sub,
subc,
swap,
swapc,
t0sn,
t1sn,
trap,
wdreset,
xch,
xor,
}
}
16 changes: 16 additions & 0 deletions src/Arch/Padauk/Padauk.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(ProjectDir)../../Drivers/CommonBuildProperties.items" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Library</OutputType>
<AssemblyName>Reko.Arch.Padauk</AssemblyName>
<RootNamespace>Reko.Arch.Padauk</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\Core\Core.csproj" />
</ItemGroup>

</Project>
170 changes: 170 additions & 0 deletions src/Arch/Padauk/PadaukArchitecture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#region License
/*
* Copyright (C) 1999-2023 John Källén.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#endregion

using Reko.Core;
using Reko.Core.Expressions;
using Reko.Core.Lib;
using Reko.Core.Machine;
using Reko.Core.Memory;
using Reko.Core.Rtl;
using Reko.Core.Types;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;

namespace Reko.Arch.Padauk
{
public class PadaukArchitecture : ProcessorArchitecture
{
public PadaukArchitecture(
IServiceProvider services,
string archId,
Dictionary<string, object> options)
: base(services, archId, options, Registers.RegistersByName, Registers.RegistersByDomain)
{
this.Endianness = EndianServices.Little;
this.CodeMemoryGranularity = 16;
this.MemoryGranularity = 8;
this.CarryFlagMask = (uint) FlagM.CF;
this.FramePointerType = PrimitiveType.Ptr16;
this.InstructionBitSize = 16;
this.PointerType = PrimitiveType.Ptr16;
this.StackRegister = Registers.sp;
this.WordWidth = PrimitiveType.Byte;
}

public override IEnumerable<MachineInstruction> CreateDisassembler(EndianImageReader rdr)
{
return new PadaukDisassembler(this, rdr);
}

public override IEqualityComparer<MachineInstruction>? CreateInstructionComparer(Normalize norm)
{
throw new NotImplementedException();
}

public override MemoryArea CreateCodeMemoryArea(Address addr, byte[] bytes)
{
// NOTE: assumes the bytes are provided in little-endian form.
return Word16MemoryArea.CreateFromLeBytes(addr, bytes);
}

public override IEnumerable<Address> CreatePointerScanner(SegmentMap map, EndianImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags)
{
throw new NotImplementedException();
}

public override ProcessorState CreateProcessorState()
{
return new DefaultProcessorState(this);
}

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

public override FlagGroupStorage GetFlagGroup(RegisterStorage flagRegister, uint grf)
{
var dt = Bits.IsSingleBitSet(grf) ? PrimitiveType.Bool : PrimitiveType.Byte;
var f = new FlagGroupStorage(flagRegister, grf, GrfToString(flagRegister, "", grf), dt);
return f;
}

public override FlagGroupStorage? GetFlagGroup(string name)
{
throw new NotImplementedException();
}

public override SortedList<string, int> GetMnemonicNames()
{
throw new NotImplementedException();
}

public override int? GetMnemonicNumber(string name)
{
throw new NotImplementedException();
}

public override RegisterStorage[] GetRegisters()
{
throw new NotImplementedException();
}

public override IEnumerable<FlagGroupStorage> GetSubFlags(FlagGroupStorage flags)
{
uint grf = flags.FlagGroupBits;
if ((grf & (uint) FlagM.OV) != 0) yield return Registers.V;
if ((grf & (uint) FlagM.AC) != 0) yield return Registers.AC;
if ((grf & (uint) FlagM.ZF) != 0) yield return Registers.Z;
if ((grf & (uint) FlagM.CF) != 0) yield return Registers.C;
}

public override string GrfToString(RegisterStorage flagregister, string prefix, uint grf)
{
StringBuilder s = new StringBuilder();
foreach (var fr in Registers.FlagBits)
{
if ((fr.FlagGroupBits & grf) != 0) s.Append(fr.Name);
}
return s.ToString();
}

public override Address MakeAddressFromConstant(Constant c, bool codeAlign)
{
return Address.Ptr16(c.ToUInt16());
}

public override Address? ReadCodeAddress(int size, EndianImageReader rdr, ProcessorState? state)
{
throw new NotImplementedException();
}

public override bool TryParseAddress(string? txtAddr, [MaybeNullWhen(false)] out Address addr)
{
return Address.TryParse16(txtAddr, out addr);
}

internal PadaukDisassembler.InstructionSet CreateInstructionSet()
{
//$REVIEW: what's a sensible default here?
if (!this.Options.TryGetValue(ProcessorOption.InstructionSet, out var oIsa) ||
oIsa is not string isa)

return new PadaukDisassembler.Pdk13InstructionSet();
switch (isa.ToLower())
{
case "13":
case "pdk13":
return new PadaukDisassembler.Pdk13InstructionSet();
case "14":
case "pdk14":
return new PadaukDisassembler.Pdk14InstructionSet();
case "15":
case "pdk15":
return new PadaukDisassembler.Pdk15InstructionSet();
}
throw new NotImplementedException($"Instruction set {isa} not implemented yet.");
}

public override Dictionary<string, object>? SaveUserOptions() => this.Options;
}
}
Loading

0 comments on commit 038acf4

Please sign in to comment.