Start working on ARM2 decoding.

This commit is contained in:
Thomas Harte 2024-02-16 21:35:49 -05:00
parent a758112084
commit bd0a15c054
6 changed files with 187 additions and 3 deletions

View File

@ -0,0 +1,77 @@
//
// Decoder.hpp
// Clock Signal
//
// Created by Thomas Harte on 16/02/2024.
// Copyright © 2024 Thomas Harte. All rights reserved.
//
#pragma once
#include "Model.hpp"
#include "Operation.hpp"
#include <array>
namespace InstructionSet::ARM {
template <Model model>
constexpr std::array<Operation, 256> operation_table() {
std::array<Operation, 256> result{};
for(int c = 0; c < 256; c++) {
const uint32_t opcode = c << 20;
if(((opcode >> 26) & 0b11) == 0b00) {
result[c] = Operation((c >> 21) & 0xf);
continue;
}
if(((opcode >> 25) & 0b111) == 0b101) {
result[c] =
((opcode >> 24) & 1) ? Operation::BranchWithLink : Operation::Branch;
continue;
}
if(((opcode >> 22) & 0b111'111) == 0b000'000) {
result[c] =
((opcode >> 21) & 1) ? Operation::MultiplyWithAccumulate : Operation::Multiply;
continue;
}
if(((opcode >> 26) & 0b11) == 0b01) {
result[c] = Operation::SingleDataTransfer;
continue;
}
if(((opcode >> 25) & 0b111) == 0b100) {
result[c] = Operation::BlockDataTransfer;
continue;
}
if(((opcode >> 24) & 0b1111) == 0b1111) {
result[c] = Operation::SoftwareInterrupt;
continue;
}
if(((opcode >> 24) & 0b1111) == 0b1110) {
result[c] = Operation::CoprocessorDataOperationOrRegisterTransfer;
continue;
}
if(((opcode >> 25) & 0b111) == 0b110) {
result[c] = Operation::CoprocessorDataTransfer;
continue;
}
result[c] = Operation::Undefined;
}
return result;
}
template <Model model>
constexpr Operation operation(uint32_t opcode) {
constexpr std::array<Operation, 256> operations = operation_table<model>();
return operations[(opcode >> 20) & 0xff];
}
}

View File

@ -0,0 +1,31 @@
//
// Instruction.hpp
// Clock Signal
//
// Created by Thomas Harte on 16/02/2024.
// Copyright © 2024 Thomas Harte. All rights reserved.
//
#pragma once
#include "Decoder.hpp"
#include "Model.hpp"
#include "Operation.hpp"
namespace InstructionSet::ARM {
template <Model model>
class Instruction {
public:
constexpr Instruction(uint32_t opcode) noexcept : opcode_(opcode) {}
Condition condition() const { return Condition(opcode_ >> 28); }
Operation operation() const {
return InstructionSet::ARM::operation<model>(opcode_);
}
private:
uint32_t opcode_;
};
}

View File

@ -0,0 +1,17 @@
//
// Model.hpp
// Clock Signal
//
// Created by Thomas Harte on 16/02/2024.
// Copyright © 2024 Thomas Harte. All rights reserved.
//
#pragma once
namespace InstructionSet::ARM {
enum class Model {
ARM2,
};
}

View File

@ -0,0 +1,39 @@
//
// Operation.hpp
// Clock Signal
//
// Created by Thomas Harte on 16/02/2024.
// Copyright © 2024 Thomas Harte. All rights reserved.
//
#pragma once
namespace InstructionSet::ARM {
enum class Operation {
AND, EOR, SUB, RSB,
ADD, ADC, SBC, RSC,
TST, TEQ, CMP, CMN,
ORR, MOV, BIC, MVN,
Branch, BranchWithLink,
Multiply, MultiplyWithAccumulate,
SingleDataTransfer,
BlockDataTransfer,
SoftwareInterrupt,
CoprocessorDataOperationOrRegisterTransfer,
CoprocessorDataTransfer,
Undefined,
};
enum class Condition {
EQ, NE, CS, CC,
MI, PL, VS, VC,
HI, LS, GE, LT,
GT, LE, AL, NV,
};
}

View File

@ -1362,9 +1362,9 @@ struct Instruction {
bool is_supervisor = false;
uint32_t opcode = 0;
Instruction() noexcept {}
Instruction(uint32_t opcode) noexcept : opcode(opcode) {}
Instruction(Operation operation, uint32_t opcode, bool is_supervisor = false) noexcept : operation(operation), is_supervisor(is_supervisor), opcode(opcode) {}
constexpr Instruction() noexcept = default;
constexpr Instruction(uint32_t opcode) noexcept : opcode(opcode) {}
constexpr Instruction(Operation operation, uint32_t opcode, bool is_supervisor = false) noexcept : operation(operation), is_supervisor(is_supervisor), opcode(opcode) {}
// Instruction fields are decoded below; naming is a compromise between
// Motorola's documentation and IBM's.

View File

@ -213,6 +213,7 @@
4B1EC716255398B000A1F44B /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1EC714255398B000A1F44B /* Sound.cpp */; };
4B1EC717255398B000A1F44B /* Sound.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1EC714255398B000A1F44B /* Sound.cpp */; };
4B1EDB451E39A0AC009D6819 /* chip.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B1EDB431E39A0AC009D6819 /* chip.png */; };
4B2005432B804D6400420C5C /* ARMDecoderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2005422B804D6400420C5C /* ARMDecoderTests.mm */; };
4B2130E2273A7A0A008A77B4 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2130E0273A7A0A008A77B4 /* Audio.cpp */; };
4B2130E3273A7A0A008A77B4 /* Audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2130E0273A7A0A008A77B4 /* Audio.cpp */; };
4B228CD524D773B40077EF25 /* CSScanTarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B228CD424D773B30077EF25 /* CSScanTarget.mm */; };
@ -1332,6 +1333,11 @@
4B1EC714255398B000A1F44B /* Sound.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sound.cpp; sourceTree = "<group>"; };
4B1EC715255398B000A1F44B /* Sound.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sound.hpp; sourceTree = "<group>"; };
4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = "<group>"; };
4B20053E2B804A4F00420C5C /* Instruction.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Instruction.hpp; sourceTree = "<group>"; };
4B2005402B804AA300420C5C /* Decoder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Decoder.hpp; sourceTree = "<group>"; };
4B2005422B804D6400420C5C /* ARMDecoderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ARMDecoderTests.mm; sourceTree = "<group>"; };
4B2005442B804DC900420C5C /* Model.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Model.hpp; sourceTree = "<group>"; };
4B2005452B804DF600420C5C /* Operation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Operation.hpp; sourceTree = "<group>"; };
4B2130E0273A7A0A008A77B4 /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = "<group>"; };
4B2130E1273A7A0A008A77B4 /* Audio.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Audio.hpp; sourceTree = "<group>"; };
4B228CD424D773B30077EF25 /* CSScanTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CSScanTarget.mm; sourceTree = "<group>"; };
@ -2752,6 +2758,17 @@
path = Icons;
sourceTree = "<group>";
};
4B20053D2B804A4F00420C5C /* ARM */ = {
isa = PBXGroup;
children = (
4B2005402B804AA300420C5C /* Decoder.hpp */,
4B20053E2B804A4F00420C5C /* Instruction.hpp */,
4B2005442B804DC900420C5C /* Model.hpp */,
4B2005452B804DF600420C5C /* Operation.hpp */,
);
path = ARM;
sourceTree = "<group>";
};
4B228CD324D773B30077EF25 /* ScanTarget */ = {
isa = PBXGroup;
children = (
@ -4471,6 +4488,7 @@
4B9D0C4E22C7E0CF00DE1AD3 /* 68000RollShiftTests.mm */,
4BD388872239E198002D14B5 /* 68000Tests.mm */,
4BF7019F26FFD32300996424 /* AmigaBlitterTests.mm */,
4B2005422B804D6400420C5C /* ARMDecoderTests.mm */,
4B924E981E74D22700B76AF1 /* AtariStaticAnalyserTests.mm */,
4BE34437238389E10058E78F /* AtariSTVideoTests.mm */,
4BB2A9AE1E13367E001A5C23 /* CRCTests.mm */,
@ -5082,6 +5100,7 @@
4BE8EB5425C0E9D40040BC40 /* Disassembler.hpp */,
4BEDA3B625B25563000C2DBD /* README.md */,
4BDA7F7F29C4C179007A10A5 /* 6809 */,
4B20053D2B804A4F00420C5C /* ARM */,
4B79629B2819681F008130F9 /* M68k */,
4BEDA40925B2844B000C2DBD /* M50740 */,
4BEDA3B325B25563000C2DBD /* PowerPC */,
@ -6334,6 +6353,7 @@
4B778F2823A5EEF80000D260 /* Cartridge.cpp in Sources */,
4B7752B528217ED30073E2C5 /* SNA.cpp in Sources */,
4BEDA3C025B25563000C2DBD /* Decoder.cpp in Sources */,
4B2005432B804D6400420C5C /* ARMDecoderTests.mm in Sources */,
4B778F4C23A5F2090000D260 /* StaticAnalyser.cpp in Sources */,
4B778F2623A5EE350000D260 /* Acorn.cpp in Sources */,
4B7752C128217F490073E2C5 /* FAT.cpp in Sources */,