1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 08:49:37 +00:00

Consume operand_flags into Instruction.hpp.

This commit is contained in:
Thomas Harte 2022-05-03 11:09:57 -04:00
parent c61809f0c4
commit b3cf13775b
9 changed files with 94 additions and 246 deletions

View File

@ -13,7 +13,6 @@
#include "Instruction.hpp"
#include "Model.hpp"
#include "Perform.hpp"
#include "Sequence.hpp"
#include "Status.hpp"
namespace InstructionSet {

View File

@ -108,7 +108,7 @@ typename Executor<model, BusHandler>::EffectiveAddress Executor<model, BusHandle
ea.requires_fetch = false;
break;
case AddressingMode::Quick:
ea.value.l = quick(instruction.operation, opcode);
ea.value.l = quick(opcode, instruction.operation);
ea.requires_fetch = false;
break;
case AddressingMode::ImmediateData:

View File

@ -9,9 +9,11 @@
#ifndef InstructionSets_68k_Instruction_hpp
#define InstructionSets_68k_Instruction_hpp
#include <cstdint>
#include "Model.hpp"
#include <cassert>
#include <cstdint>
namespace InstructionSet {
namespace M68k {
@ -224,9 +226,9 @@ constexpr DataSize size(Operation operation) {
}
}
template <Operation op>
constexpr uint32_t quick(uint16_t instruction) {
switch(op) {
template <Operation t_op = Operation::Undefined>
constexpr uint32_t quick(uint16_t instruction, Operation r_op = Operation::Undefined) {
switch((t_op != Operation::Undefined) ? t_op : r_op) {
case Operation::Bccb:
case Operation::BSRb:
case Operation::MOVEl: return uint32_t(int8_t(instruction));
@ -239,16 +241,85 @@ constexpr uint32_t quick(uint16_t instruction) {
}
}
constexpr uint32_t quick(Operation op, uint16_t instruction) {
switch(op) {
case Operation::MOVEl: return quick<Operation::MOVEl>(instruction);
case Operation::Bccb: return quick<Operation::Bccb>(instruction);
case Operation::BSRb: return quick<Operation::BSRb>(instruction);
case Operation::TRAP: return quick<Operation::TRAP>(instruction);
static constexpr uint8_t FetchOp1 = (1 << 0);
static constexpr uint8_t FetchOp2 = (1 << 1);
static constexpr uint8_t StoreOp1 = (1 << 2);
static constexpr uint8_t StoreOp2 = (1 << 3);
/*!
Provides a bitfield with a value in the range 015 indicating which of the provided operation's
operands are accessed via standard fetch and store cycles.
Unusual bus sequences, such as TAS or MOVEM, are not described here.
*/
template <Model model, Operation t_operation = Operation::Undefined> uint8_t operand_flags(Operation r_operation = Operation::Undefined) {
switch((t_operation != Operation::Undefined) ? t_operation : r_operation) {
default:
// ADDw is arbitrary; anything other than those listed above will do.
return quick<Operation::ADDw>(instruction);
assert(false);
//
// No operands are fetched or stored.
//
case Operation::LEA:
case Operation::PEA:
return 0;
//
// Single-operand read.
//
case Operation::MOVEtoSR: case Operation::MOVEtoCCR: case Operation::MOVEtoUSP:
case Operation::ORItoSR: case Operation::ORItoCCR:
case Operation::ANDItoSR: case Operation::ANDItoCCR:
case Operation::EORItoSR: case Operation::EORItoCCR:
return FetchOp1;
//
// Single-operand write.
//
case Operation::MOVEfromSR: case Operation::MOVEfromUSP:
return StoreOp1;
//
// Single-operand read-modify-write.
//
case Operation::NBCD:
case Operation::EXTbtow: case Operation::EXTwtol:
return FetchOp1 | StoreOp1;
//
// Two-operand; read both.
//
case Operation::CMPb: case Operation::CMPw: case Operation::CMPl:
case Operation::CMPAw: case Operation::CMPAl:
return FetchOp1 | FetchOp2;
//
// Two-operand; read source, write dest.
//
case Operation::MOVEb: case Operation::MOVEw: case Operation::MOVEl:
case Operation::MOVEAw: case Operation::MOVEAl:
return FetchOp1 | StoreOp2;
//
// Two-operand; read both, write dest.
//
case Operation::ABCD: case Operation::SBCD:
case Operation::ADDb: case Operation::ADDw: case Operation::ADDl:
case Operation::ADDAw: case Operation::ADDAl:
case Operation::ADDXb: case Operation::ADDXw: case Operation::ADDXl:
case Operation::SUBb: case Operation::SUBw: case Operation::SUBl:
case Operation::SUBAw: case Operation::SUBAl:
case Operation::SUBXb: case Operation::SUBXw: case Operation::SUBXl:
case Operation::ORb: case Operation::ORw: case Operation::ORl:
case Operation::ANDb: case Operation::ANDw: case Operation::ANDl:
case Operation::EORb: case Operation::EORw: case Operation::EORl:
return FetchOp1 | FetchOp2 | StoreOp2;
//
// Two-operand; read both, write both.
//
case Operation::EXG:
return FetchOp1 | FetchOp2 | StoreOp1 | StoreOp2;
}
}

View File

@ -1,114 +0,0 @@
//
// Sequence.cpp
// Clock Signal
//
// Created by Thomas Harte on 29/04/2022.
// Copyright © 2022 Thomas Harte. All rights reserved.
//
#include "Sequence.hpp"
#include <cassert>
using namespace InstructionSet::M68k;
/*
template <Step... T> struct Steps {
static constexpr uint32_t value = 0;
};
template <Step F, Step... T> struct Steps<F, T...> {
static constexpr uint32_t value = uint16_t(F) | uint16_t(Steps<T...>::value << 4);
};
template<Model model> uint32_t Sequence<model>::steps_for(Operation operation) {
switch(operation) {
// This handles a NOP, and not much else.
default: assert(false);
//
// No operands that require fetching.
//
case Operation::LEA:
return Steps<
Step::Perform
>::value;
//
// No logic, custom bus activity required.
//
case Operation::PEA:
return Steps<
Step::SpecificBusActivity
>::value;
//
// Single operand, read.
//
case Operation::MOVEtoSR: case Operation::MOVEtoCCR: case Operation::MOVEtoUSP:
case Operation::ORItoSR: case Operation::ORItoCCR:
case Operation::ANDItoSR: case Operation::ANDItoCCR:
case Operation::EORItoSR: case Operation::EORItoCCR:
return Steps<
Step::FetchOp1,
Step::Perform
>::value;
//
// Single operand, write.
//
case Operation::MOVEfromSR: case Operation::MOVEfromUSP:
return Steps<
Step::Perform,
Step::StoreOp1
>::value;
//
// Single operand, read-modify-write.
//
case Operation::NBCD:
case Operation::EXTbtow: case Operation::EXTwtol:
return Steps<
Step::FetchOp1,
Step::Perform,
Step::StoreOp1
>::value;
//
// Two operand, read-write.
//
case Operation::MOVEb: case Operation::MOVEw: case Operation::MOVEl:
case Operation::MOVEAw: case Operation::MOVEAl:
return Steps<
Step::FetchOp1,
Step::Perform,
Step::StoreOp2
>::value;
//
// Two operand, read-modify-write.
//
case Operation::ABCD: case Operation::SBCD:
case Operation::ADDb: case Operation::ADDw: case Operation::ADDl:
case Operation::ADDAw: case Operation::ADDAl:
case Operation::ADDXb: case Operation::ADDXw: case Operation::ADDXl:
case Operation::SUBb: case Operation::SUBw: case Operation::SUBl:
case Operation::SUBAw: case Operation::SUBAl:
case Operation::SUBXb: case Operation::SUBXw: case Operation::SUBXl:
return Steps<
Step::FetchOp1,
Step::FetchOp2,
Step::Perform,
Step::StoreOp2
>::value;
}
}
template<Model model> Sequence<model>::Sequence(Operation operation) : steps_(steps_for(operation)) {}
template class InstructionSet::M68k::Sequence<Model::M68000>;
template class InstructionSet::M68k::Sequence<Model::M68010>;
template class InstructionSet::M68k::Sequence<Model::M68020>;
template class InstructionSet::M68k::Sequence<Model::M68030>;
template class InstructionSet::M68k::Sequence<Model::M68040>;
*/

View File

@ -1,106 +0,0 @@
//
// Sequencer.hpp
// Clock Signal
//
// Created by Thomas Harte on 29/04/2022.
// Copyright © 2022 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_68k_Sequencer_hpp
#define InstructionSets_68k_Sequencer_hpp
#include "Instruction.hpp"
#include "Model.hpp"
#include <cassert>
namespace InstructionSet {
namespace M68k {
static constexpr uint8_t FetchOp1 = (1 << 0);
static constexpr uint8_t FetchOp2 = (1 << 1);
static constexpr uint8_t StoreOp1 = (1 << 2);
static constexpr uint8_t StoreOp2 = (1 << 3);
/*!
Provides a bitfield with a value in the range 015 indicating which of the provided operation's
operands are accessed via standard fetch and store cycles.
Unusual bus sequences, such as TAS or MOVEM, are not described here.
*/
template <Model model, Operation t_operation = Operation::Undefined> uint8_t operand_flags(Operation r_operation = Operation::Undefined) {
switch((t_operation != Operation::Undefined) ? t_operation : r_operation) {
default:
assert(false);
//
// No operands are fetched or stored.
//
case Operation::LEA:
case Operation::PEA:
return 0;
//
// Single-operand read.
//
case Operation::MOVEtoSR: case Operation::MOVEtoCCR: case Operation::MOVEtoUSP:
case Operation::ORItoSR: case Operation::ORItoCCR:
case Operation::ANDItoSR: case Operation::ANDItoCCR:
case Operation::EORItoSR: case Operation::EORItoCCR:
return FetchOp1;
//
// Single-operand write.
//
case Operation::MOVEfromSR: case Operation::MOVEfromUSP:
return StoreOp1;
//
// Single-operand read-modify-write.
//
case Operation::NBCD:
case Operation::EXTbtow: case Operation::EXTwtol:
return FetchOp1 | StoreOp1;
//
// Two-operand; read both.
//
case Operation::CMPb: case Operation::CMPw: case Operation::CMPl:
case Operation::CMPAw: case Operation::CMPAl:
return FetchOp1 | FetchOp2;
//
// Two-operand; read source, write dest.
//
case Operation::MOVEb: case Operation::MOVEw: case Operation::MOVEl:
case Operation::MOVEAw: case Operation::MOVEAl:
return FetchOp1 | StoreOp2;
//
// Two-operand; read both, write dest.
//
case Operation::ABCD: case Operation::SBCD:
case Operation::ADDb: case Operation::ADDw: case Operation::ADDl:
case Operation::ADDAw: case Operation::ADDAl:
case Operation::ADDXb: case Operation::ADDXw: case Operation::ADDXl:
case Operation::SUBb: case Operation::SUBw: case Operation::SUBl:
case Operation::SUBAw: case Operation::SUBAl:
case Operation::SUBXb: case Operation::SUBXw: case Operation::SUBXl:
case Operation::ORb: case Operation::ORw: case Operation::ORl:
case Operation::ANDb: case Operation::ANDw: case Operation::ANDl:
case Operation::EORb: case Operation::EORw: case Operation::EORl:
return FetchOp1 | FetchOp2 | StoreOp2;
//
// Two-operand; read both, write both.
//
case Operation::EXG:
return FetchOp1 | FetchOp2 | StoreOp1 | StoreOp2;
}
}
}
}
#endif /* InstructionSets_68k_Sequencer_h */

View File

@ -427,8 +427,6 @@
4B7962A02819681F008130F9 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B79629F2819681F008130F9 /* Decoder.cpp */; };
4B7962A12819681F008130F9 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B79629F2819681F008130F9 /* Decoder.cpp */; };
4B7962A22819681F008130F9 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B79629F2819681F008130F9 /* Decoder.cpp */; };
4B7962A5281C32D8008130F9 /* Sequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7962A4281C2EE3008130F9 /* Sequence.cpp */; };
4B7962A6281C32D8008130F9 /* Sequence.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7962A4281C2EE3008130F9 /* Sequence.cpp */; };
4B79A5011FC913C900EEDAD5 /* MSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B79A4FF1FC913C900EEDAD5 /* MSX.cpp */; };
4B79E4441E3AF38600141F11 /* cassette.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B79E4411E3AF38600141F11 /* cassette.png */; };
4B79E4451E3AF38600141F11 /* floppy35.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B79E4421E3AF38600141F11 /* floppy35.png */; };
@ -1427,8 +1425,6 @@
4B79629D2819681F008130F9 /* Model.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Model.hpp; sourceTree = "<group>"; };
4B79629E2819681F008130F9 /* Decoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Decoder.hpp; sourceTree = "<group>"; };
4B79629F2819681F008130F9 /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; };
4B7962A3281C1B76008130F9 /* Sequence.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sequence.hpp; sourceTree = "<group>"; };
4B7962A4281C2EE3008130F9 /* Sequence.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Sequence.cpp; sourceTree = "<group>"; };
4B79A4FE1FC9082300EEDAD5 /* TypedDynamicMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TypedDynamicMachine.hpp; sourceTree = "<group>"; };
4B79A4FF1FC913C900EEDAD5 /* MSX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MSX.cpp; sourceTree = "<group>"; };
4B79A5001FC913C900EEDAD5 /* MSX.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MSX.hpp; sourceTree = "<group>"; };
@ -3167,13 +3163,11 @@
isa = PBXGroup;
children = (
4B79629F2819681F008130F9 /* Decoder.cpp */,
4B7962A4281C2EE3008130F9 /* Sequence.cpp */,
4B79629E2819681F008130F9 /* Decoder.hpp */,
4BB5B99C281C805300522DA9 /* Executor.hpp */,
4B79629C2819681F008130F9 /* Instruction.hpp */,
4B79629D2819681F008130F9 /* Model.hpp */,
4BB5B996281B1E3F00522DA9 /* Perform.hpp */,
4B7962A3281C1B76008130F9 /* Sequence.hpp */,
4BB5B997281B1F7B00522DA9 /* Status.hpp */,
4BB5B999281B244400522DA9 /* Implementation */,
);
@ -5470,7 +5464,6 @@
4BC080CB26A238CC00D03FD8 /* AmigaADF.cpp in Sources */,
4B4B1A3D200198CA00A0F866 /* KonamiSCC.cpp in Sources */,
4B055AC31FAE9AE80060FFFF /* AmstradCPC.cpp in Sources */,
4B7962A5281C32D8008130F9 /* Sequence.cpp in Sources */,
4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */,
4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */,
4B055AB01FAE86070060FFFF /* PulseQueuedTape.cpp in Sources */,
@ -5707,7 +5700,6 @@
4B894518201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
4BCE005A227CFFCA000CA200 /* Macintosh.cpp in Sources */,
4B6AAEA4230E3E1D0078E864 /* MassStorageDevice.cpp in Sources */,
4B7962A6281C32D8008130F9 /* Sequence.cpp in Sources */,
4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BC890D3230F86020025A55A /* DirectAccessDevice.cpp in Sources */,
4B7BA03723CEB86000B98D9E /* BD500.cpp in Sources */,

View File

@ -7,9 +7,9 @@
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
buildConfiguration = "Release"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference

View File

@ -15,6 +15,8 @@
#include <memory>
#include <functional>
#define USE_EXISTING_IMPLEMENTATION
@interface M68000ComparativeTests : XCTestCase
@end
@ -73,7 +75,11 @@
// Perform each dictionary in the array as a test.
for(NSDictionary *test in jsonContents) {
if(![test isKindOfClass:[NSDictionary class]]) continue;
#ifdef USE_EXISTING_IMPLEMENTATION
[self testOperationClassic:test];
#else
[self testOperationExecutor:test];
#endif
}
}

View File

@ -54,7 +54,7 @@ template <int index> NSString *operand(Preinstruction instruction, uint16_t opco
return @"#";
case AddressingMode::Quick:
return [NSString stringWithFormat:@"%d", quick(instruction.operation, opcode)];
return [NSString stringWithFormat:@"%d", quick(opcode, instruction.operation)];
}
}