2012-03-19 11:19:53 +00:00
|
|
|
struct GPR {
|
Update to v097r14 release.
byuu says:
This is a few days old, but oh well.
This WIP changes nall,hiro,ruby,icarus back to (u)int(8,16,32,64)_t.
I'm slowly pushing for (u)int(8,16,32,64) to use my custom
Integer<Size>/Natural<Size> classes instead. But it's going to be one
hell of a struggle to get that into higan.
2016-02-16 09:11:58 +00:00
|
|
|
inline operator uint32_t() const { return data; }
|
|
|
|
inline auto operator=(uint32_t n) { data = n; if(modify) modify(); return *this; }
|
2015-06-24 13:21:24 +00:00
|
|
|
inline auto operator=(const GPR& source) { return operator=(source.data); }
|
|
|
|
|
Update to v097r14 release.
byuu says:
This is a few days old, but oh well.
This WIP changes nall,hiro,ruby,icarus back to (u)int(8,16,32,64)_t.
I'm slowly pushing for (u)int(8,16,32,64) to use my custom
Integer<Size>/Natural<Size> classes instead. But it's going to be one
hell of a struggle to get that into higan.
2016-02-16 09:11:58 +00:00
|
|
|
inline auto operator &=(uint32_t n) { return operator=(data & n); }
|
|
|
|
inline auto operator |=(uint32_t n) { return operator=(data | n); }
|
|
|
|
inline auto operator ^=(uint32_t n) { return operator=(data ^ n); }
|
|
|
|
inline auto operator +=(uint32_t n) { return operator=(data + n); }
|
|
|
|
inline auto operator -=(uint32_t n) { return operator=(data - n); }
|
|
|
|
inline auto operator *=(uint32_t n) { return operator=(data * n); }
|
|
|
|
inline auto operator /=(uint32_t n) { return operator=(data / n); }
|
|
|
|
inline auto operator %=(uint32_t n) { return operator=(data % n); }
|
|
|
|
inline auto operator<<=(uint32_t n) { return operator=(data << n); }
|
|
|
|
inline auto operator>>=(uint32_t n) { return operator=(data >> n); }
|
|
|
|
|
|
|
|
uint32_t data = 0;
|
2015-06-27 02:38:08 +00:00
|
|
|
function<auto () -> void> modify;
|
2012-03-19 11:19:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct PSR {
|
2016-06-08 22:26:35 +00:00
|
|
|
union {
|
|
|
|
uint32_t data = 0;
|
|
|
|
BitField<uint32_t, 31> n; //negative
|
|
|
|
BitField<uint32_t, 30> z; //zero
|
|
|
|
BitField<uint32_t, 29> c; //carry
|
|
|
|
BitField<uint32_t, 28> v; //overflow
|
|
|
|
BitField<uint32_t, 7> i; //irq
|
|
|
|
BitField<uint32_t, 6> f; //fiq
|
|
|
|
BitField<uint32_t, 5> t; //thumb
|
|
|
|
BitField<uint32_t, 4, 0> m; //mode
|
|
|
|
};
|
|
|
|
|
|
|
|
PSR() = default;
|
|
|
|
PSR(const PSR& value) { data = value.data; }
|
|
|
|
|
|
|
|
inline operator uint() const { return data & 0xf00000ff; }
|
|
|
|
inline auto& operator=(uint value) { return data = value, *this; }
|
|
|
|
inline auto& operator=(const PSR& value) { return data = value.data, *this; }
|
2012-03-19 11:19:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Pipeline {
|
2015-06-27 02:38:08 +00:00
|
|
|
bool reload = false;
|
2015-07-01 10:58:42 +00:00
|
|
|
bool nonsequential = false;
|
2012-03-21 11:08:16 +00:00
|
|
|
|
2012-03-19 11:19:53 +00:00
|
|
|
struct Instruction {
|
2015-06-27 02:38:08 +00:00
|
|
|
uint32 address = 0;
|
|
|
|
uint32 instruction = 0;
|
2012-03-19 11:19:53 +00:00
|
|
|
};
|
2012-03-21 11:08:16 +00:00
|
|
|
|
2012-03-19 11:19:53 +00:00
|
|
|
Instruction execute;
|
|
|
|
Instruction decode;
|
|
|
|
Instruction fetch;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Processor {
|
|
|
|
enum class Mode : unsigned {
|
|
|
|
USR = 0x10, //user
|
|
|
|
FIQ = 0x11, //fast interrupt request
|
|
|
|
IRQ = 0x12, //interrupt request
|
|
|
|
SVC = 0x13, //supervisor (software interrupt)
|
|
|
|
ABT = 0x17, //abort
|
|
|
|
UND = 0x1b, //undefined
|
|
|
|
SYS = 0x1f, //system
|
|
|
|
};
|
|
|
|
|
|
|
|
GPR r0, r1, r2, r3, r4, r5, r6, r7;
|
|
|
|
|
|
|
|
struct USR {
|
|
|
|
GPR r8, r9, r10, r11, r12, sp, lr;
|
|
|
|
} usr;
|
|
|
|
|
|
|
|
struct FIQ {
|
|
|
|
GPR r8, r9, r10, r11, r12, sp, lr;
|
|
|
|
PSR spsr;
|
|
|
|
} fiq;
|
|
|
|
|
|
|
|
struct IRQ {
|
|
|
|
GPR sp, lr;
|
|
|
|
PSR spsr;
|
|
|
|
} irq;
|
|
|
|
|
|
|
|
struct SVC {
|
|
|
|
GPR sp, lr;
|
|
|
|
PSR spsr;
|
|
|
|
} svc;
|
|
|
|
|
|
|
|
struct ABT {
|
|
|
|
GPR sp, lr;
|
|
|
|
PSR spsr;
|
|
|
|
} abt;
|
|
|
|
|
|
|
|
struct UND {
|
|
|
|
GPR sp, lr;
|
|
|
|
PSR spsr;
|
|
|
|
} und;
|
|
|
|
|
|
|
|
GPR pc;
|
|
|
|
PSR cpsr;
|
2015-06-27 02:38:08 +00:00
|
|
|
bool carryout = false;
|
|
|
|
bool irqline = false;
|
2012-03-19 11:19:53 +00:00
|
|
|
|
2015-06-27 02:38:08 +00:00
|
|
|
GPR* r[16] = {nullptr};
|
|
|
|
PSR* spsr = nullptr;
|
2012-03-19 11:19:53 +00:00
|
|
|
|
2015-06-24 13:21:24 +00:00
|
|
|
auto power() -> void;
|
|
|
|
auto setMode(Mode) -> void;
|
2012-03-19 11:19:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Processor processor;
|
|
|
|
Pipeline pipeline;
|
2015-06-27 02:38:08 +00:00
|
|
|
bool crash = false;
|
2015-06-24 13:21:24 +00:00
|
|
|
|
Update to v097r14 release.
byuu says:
This is a few days old, but oh well.
This WIP changes nall,hiro,ruby,icarus back to (u)int(8,16,32,64)_t.
I'm slowly pushing for (u)int(8,16,32,64) to use my custom
Integer<Size>/Natural<Size> classes instead. But it's going to be one
hell of a struggle to get that into higan.
2016-02-16 09:11:58 +00:00
|
|
|
alwaysinline auto r(uint n) -> GPR& { return *processor.r[n]; }
|
2015-06-24 13:21:24 +00:00
|
|
|
alwaysinline auto cpsr() -> PSR& { return processor.cpsr; }
|
|
|
|
alwaysinline auto spsr() -> PSR& { return *processor.spsr; }
|
|
|
|
alwaysinline auto carryout() -> bool& { return processor.carryout; }
|
|
|
|
alwaysinline auto instruction() -> uint32 { return pipeline.execute.instruction; }
|
2016-06-08 22:26:35 +00:00
|
|
|
alwaysinline auto mode() -> Processor::Mode { return (Processor::Mode)(uint)processor.cpsr.m; }
|
|
|
|
alwaysinline auto privilegedMode() const -> bool { return (Processor::Mode)(uint)processor.cpsr.m != Processor::Mode::USR; }
|
|
|
|
alwaysinline auto exceptionMode() const -> bool { return privilegedMode() && (Processor::Mode)(uint)processor.cpsr.m != Processor::Mode::SYS; }
|