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

Deal with conditionality up front.

This commit is contained in:
Thomas Harte 2024-02-26 21:36:23 -05:00
parent 16e827bb2c
commit 4255283e33
2 changed files with 28 additions and 11 deletions

View File

@ -356,10 +356,22 @@ private:
/// Operation mapper; use the free function @c dispatch as defined below. /// Operation mapper; use the free function @c dispatch as defined below.
struct OperationMapper { struct OperationMapper {
template <int i, typename SchedulerT> void dispatch(uint32_t instruction, SchedulerT &scheduler) { static Condition condition(uint32_t instruction) {
constexpr auto partial = uint32_t(i << 20); return Condition(instruction >> 28);
}
template <int i, typename SchedulerT>
static void dispatch(uint32_t instruction, SchedulerT &scheduler) {
// Legacy: grab condition. This'll be eliminated.
// TODO: eliminate.
const auto condition = Condition(instruction >> 28); const auto condition = Condition(instruction >> 28);
// Put the 8-bit segment of instruction back into its proper place;
// this allows all the tests below to be written so as to coordinate
// properly with the data sheet, and since it's all compile-time work
// it doesn't cost anything.
constexpr auto partial = uint32_t(i << 20);
// Cf. the ARM2 datasheet, p.45. Tests below match its ordering // Cf. the ARM2 datasheet, p.45. Tests below match its ordering
// other than that 'undefined' is the fallthrough case. More specific // other than that 'undefined' is the fallthrough case. More specific
// page references are provided were more detailed versions of the // page references are provided were more detailed versions of the
@ -367,10 +379,7 @@ struct OperationMapper {
// Data processing; cf. p.17. // Data processing; cf. p.17.
if constexpr (((partial >> 26) & 0b11) == 0b00) { if constexpr (((partial >> 26) & 0b11) == 0b00) {
scheduler.template perform<i>( scheduler.template perform<i>(DataProcessing(instruction));
condition,
DataProcessing(instruction)
);
return; return;
} }
@ -478,7 +487,7 @@ struct SampleScheduler {
// (1) Condition, indicating the condition code associated with this operation; and // (1) Condition, indicating the condition code associated with this operation; and
// (2) An operation-specific encapsulation of the operation code for decoding of fields that didn't // (2) An operation-specific encapsulation of the operation code for decoding of fields that didn't
// fit into the template parameters. // fit into the template parameters.
template <Flags> void perform(Condition, DataProcessing); template <Flags> void perform(DataProcessing);
template <Operation, Flags> void perform(Condition, Multiply); template <Operation, Flags> void perform(Condition, Multiply);
template <Operation, Flags> void perform(Condition, SingleDataTransfer); template <Operation, Flags> void perform(Condition, SingleDataTransfer);
template <Operation, Flags> void perform(Condition, BlockDataTransfer); template <Operation, Flags> void perform(Condition, BlockDataTransfer);
@ -497,6 +506,14 @@ struct SampleScheduler {
/// In lieue of C++20, see the sample definition of SampleScheduler above for the expected interface. /// In lieue of C++20, see the sample definition of SampleScheduler above for the expected interface.
template <typename SchedulerT> void dispatch(uint32_t instruction, SchedulerT &scheduler) { template <typename SchedulerT> void dispatch(uint32_t instruction, SchedulerT &scheduler) {
OperationMapper mapper; OperationMapper mapper;
// Test condition.
const auto condition = mapper.condition(instruction);
if(!scheduler.should_schedule(condition)) {
return;
}
// Dispatch body.
Reflection::dispatch(mapper, (instruction >> FlagsStartBit) & 0xff, instruction, scheduler); Reflection::dispatch(mapper, (instruction >> FlagsStartBit) & 0xff, instruction, scheduler);
} }

View File

@ -56,11 +56,11 @@ void shift(ShiftType type, uint32_t &source, uint32_t amount, uint32_t *carry) {
struct Scheduler { struct Scheduler {
template <Flags f> void perform(Condition condition, DataProcessing fields) { bool should_schedule(Condition condition) {
if(!status.test(condition)) { return status.test(condition);
return;
} }
template <Flags f> void perform(DataProcessing fields) {
// TODO: how does register 15 fit into all of below? As an operand or as a target? // TODO: how does register 15 fit into all of below? As an operand or as a target?
constexpr DataProcessingFlags flags(f); constexpr DataProcessingFlags flags(f);