mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
Cuts a third from the Program
struct.
Observation: [source/destination]_address are always one of the address registers. So you can fit both within a single byte. Net effect: around a 12% reduction in execution costs, given that this reduces the size of the instructions table from 3mb to 2mb.
This commit is contained in:
parent
c300bd17fa
commit
827c4e172a
@ -365,9 +365,9 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
case int(MicroOp::Action::None): break;
|
case int(MicroOp::Action::None): break;
|
||||||
|
|
||||||
#define source() active_program_->source
|
#define source() active_program_->source
|
||||||
#define source_address() active_program_->source_address
|
#define source_address() address_[active_program_->source_dest >> 4]
|
||||||
#define destination() active_program_->destination
|
#define destination() active_program_->destination
|
||||||
#define destination_address() active_program_->destination_address
|
#define destination_address() address_[active_program_->source_dest & 0x0f]
|
||||||
|
|
||||||
case int(MicroOp::Action::PerformOperation):
|
case int(MicroOp::Action::PerformOperation):
|
||||||
#define sub_overflow() ((result ^ destination) & (destination ^ source))
|
#define sub_overflow() ((result ^ destination) & (destination ^ source))
|
||||||
@ -1157,7 +1157,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
const auto mode = (decoded_instruction_.full >> 3) & 7; \
|
const auto mode = (decoded_instruction_.full >> 3) & 7; \
|
||||||
uint32_t start_address; \
|
uint32_t start_address; \
|
||||||
if(mode <= 4) { \
|
if(mode <= 4) { \
|
||||||
start_address = destination_address()->full; \
|
start_address = destination_address().full; \
|
||||||
} else { \
|
} else { \
|
||||||
start_address = effective_address_[1].full; \
|
start_address = effective_address_[1].full; \
|
||||||
} \
|
} \
|
||||||
@ -1996,11 +1996,11 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
#define op_add(x, y) x += y
|
#define op_add(x, y) x += y
|
||||||
#define op_sub(x, y) x -= y
|
#define op_sub(x, y) x -= y
|
||||||
#define Adjust(op, quantity, effect) \
|
#define Adjust(op, quantity, effect) \
|
||||||
case int(op) | MicroOp::SourceMask: effect(source_address()->full, quantity); break; \
|
case int(op) | MicroOp::SourceMask: effect(source_address().full, quantity); break; \
|
||||||
case int(op) | MicroOp::DestinationMask: effect(destination_address()->full, quantity); break; \
|
case int(op) | MicroOp::DestinationMask: effect(destination_address().full, quantity); break; \
|
||||||
case int(op) | MicroOp::SourceMask | MicroOp::DestinationMask: \
|
case int(op) | MicroOp::SourceMask | MicroOp::DestinationMask: \
|
||||||
effect(destination_address()->full, quantity); \
|
effect(destination_address().full, quantity); \
|
||||||
effect(source_address()->full, quantity); \
|
effect(source_address().full, quantity); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Adjust(MicroOp::Action::Decrement1, 1, op_sub);
|
Adjust(MicroOp::Action::Decrement1, 1, op_sub);
|
||||||
@ -2056,16 +2056,16 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask:
|
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask:
|
||||||
effective_address_[0] = u_extend16(prefetch_queue_.halves.low.full) + source_address()->full;
|
effective_address_[0] = u_extend16(prefetch_queue_.halves.low.full) + source_address().full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::DestinationMask:
|
case int(MicroOp::Action::CalcD16An) | MicroOp::DestinationMask:
|
||||||
effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address()->full;
|
effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address().full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask | MicroOp::DestinationMask:
|
case int(MicroOp::Action::CalcD16An) | MicroOp::SourceMask | MicroOp::DestinationMask:
|
||||||
effective_address_[0] = u_extend16(prefetch_queue_.halves.high.full) + source_address()->full;
|
effective_address_[0] = u_extend16(prefetch_queue_.halves.high.full) + source_address().full;
|
||||||
effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address()->full;
|
effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address().full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#define CalculateD8AnXn(data, source, target) {\
|
#define CalculateD8AnXn(data, source, target) {\
|
||||||
@ -2080,16 +2080,16 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask: {
|
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask: {
|
||||||
CalculateD8AnXn(prefetch_queue_.halves.low, source_address()->full, effective_address_[0]);
|
CalculateD8AnXn(prefetch_queue_.halves.low, source_address().full, effective_address_[0]);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::DestinationMask: {
|
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::DestinationMask: {
|
||||||
CalculateD8AnXn(prefetch_queue_.halves.low, destination_address()->full, effective_address_[1]);
|
CalculateD8AnXn(prefetch_queue_.halves.low, destination_address().full, effective_address_[1]);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask | MicroOp::DestinationMask: {
|
case int(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask | MicroOp::DestinationMask: {
|
||||||
CalculateD8AnXn(prefetch_queue_.halves.high, source_address()->full, effective_address_[0]);
|
CalculateD8AnXn(prefetch_queue_.halves.high, source_address().full, effective_address_[0]);
|
||||||
CalculateD8AnXn(prefetch_queue_.halves.low, destination_address()->full, effective_address_[1]);
|
CalculateD8AnXn(prefetch_queue_.halves.low, destination_address().full, effective_address_[1]);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CalcD8PCXn) | MicroOp::SourceMask: {
|
case int(MicroOp::Action::CalcD8PCXn) | MicroOp::SourceMask: {
|
||||||
@ -2140,16 +2140,16 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask:
|
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask:
|
||||||
effective_address_[0] = *active_program_->source_address;
|
effective_address_[0] = source_address();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::DestinationMask:
|
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::DestinationMask:
|
||||||
effective_address_[1] = *active_program_->destination_address;
|
effective_address_[1] = destination_address();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask | MicroOp::DestinationMask:
|
case int(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask | MicroOp::DestinationMask:
|
||||||
effective_address_[0] = *active_program_->source_address;
|
effective_address_[0] = source_address();
|
||||||
effective_address_[1] = *active_program_->destination_address;
|
effective_address_[1] = destination_address();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,10 +862,6 @@ struct ProcessorStorageConstructor {
|
|||||||
// Temporary storage for the Program fields.
|
// Temporary storage for the Program fields.
|
||||||
ProcessorBase::Program program;
|
ProcessorBase::Program program;
|
||||||
|
|
||||||
// if(instruction == 0x4879) {
|
|
||||||
// printf("");
|
|
||||||
// }
|
|
||||||
|
|
||||||
#define dec(n) decrement_action(is_long_word_access, is_byte_access, n)
|
#define dec(n) decrement_action(is_long_word_access, is_byte_access, n)
|
||||||
#define inc(n) increment_action(is_long_word_access, is_byte_access, n)
|
#define inc(n) increment_action(is_long_word_access, is_byte_access, n)
|
||||||
|
|
||||||
@ -2478,7 +2474,7 @@ struct ProcessorStorageConstructor {
|
|||||||
program.set_destination(storage_, An, data_register);
|
program.set_destination(storage_, An, data_register);
|
||||||
|
|
||||||
const int mode = combined_mode(ea_mode, ea_register);
|
const int mode = combined_mode(ea_mode, ea_register);
|
||||||
program.source_address = &storage_.address_[ea_register];
|
program.set_source_address(storage_, ea_register);
|
||||||
program.source =
|
program.source =
|
||||||
(mode == Ind) ?
|
(mode == Ind) ?
|
||||||
&storage_.address_[ea_register] :
|
&storage_.address_[ea_register] :
|
||||||
|
@ -344,29 +344,44 @@ class ProcessorStorage {
|
|||||||
non-pointer fields doesn't seem to be helpful immediately.)
|
non-pointer fields doesn't seem to be helpful immediately.)
|
||||||
*/
|
*/
|
||||||
struct Program {
|
struct Program {
|
||||||
|
Operation operation;
|
||||||
|
uint8_t source_dest = 0;
|
||||||
|
bool requires_supervisor = false;
|
||||||
MicroOp *micro_operations = nullptr;
|
MicroOp *micro_operations = nullptr;
|
||||||
RegisterPair32 *source = nullptr;
|
RegisterPair32 *source = nullptr;
|
||||||
RegisterPair32 *destination = nullptr;
|
RegisterPair32 *destination = nullptr;
|
||||||
RegisterPair32 *source_address = nullptr;
|
|
||||||
RegisterPair32 *destination_address = nullptr;
|
void set_source_address(ProcessorStorage &storage, int index) {
|
||||||
Operation operation;
|
source_dest = uint8_t((source_dest & 0x0f) | (index << 4));
|
||||||
bool requires_supervisor = false;
|
}
|
||||||
|
|
||||||
|
void set_destination_address(ProcessorStorage &storage, int index) {
|
||||||
|
source_dest = uint8_t((source_dest & 0xf0) | index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_source(ProcessorStorage &storage, RegisterPair32 *target) {
|
||||||
|
source = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_destination(ProcessorStorage &storage, RegisterPair32 *target) {
|
||||||
|
destination = target;
|
||||||
|
}
|
||||||
|
|
||||||
void set_source(ProcessorStorage &storage, int mode, int reg) {
|
void set_source(ProcessorStorage &storage, int mode, int reg) {
|
||||||
source_address = &storage.address_[reg];
|
set_source_address(storage, reg);
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case 0: source = &storage.data_[reg]; break;
|
case 0: set_source(storage, &storage.data_[reg]); break;
|
||||||
case 1: source = &storage.address_[reg]; break;
|
case 1: set_source(storage, &storage.address_[reg]); break;
|
||||||
default: source = &storage.source_bus_data_[0]; break;
|
default: set_source(storage, &storage.source_bus_data_[0]); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_destination(ProcessorStorage &storage, int mode, int reg) {
|
void set_destination(ProcessorStorage &storage, int mode, int reg) {
|
||||||
destination_address = &storage.address_[reg];
|
set_destination_address(storage, reg);
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case 0: destination = &storage.data_[reg]; break;
|
case 0: set_destination(storage, &storage.data_[reg]); break;
|
||||||
case 1: destination = &storage.address_[reg]; break;
|
case 1: set_destination(storage, &storage.address_[reg]); break;
|
||||||
default: destination = &storage.destination_bus_data_[0]; break;
|
default: set_destination(storage, &storage.destination_bus_data_[0]); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user