Skip to content

Instantly share code, notes, and snippets.

@jarrodnorwell
Created January 30, 2023 18:56
Show Gist options
  • Save jarrodnorwell/aa2e852971881b4fbe15b9b285ee8a1f to your computer and use it in GitHub Desktop.
Save jarrodnorwell/aa2e852971881b4fbe15b9b285ee8a1f to your computer and use it in GitHub Desktop.
arm11 cpu stuff
enum Mode : uint32_t {
USER,
FIQ,
IRQ,
SUPERVISOR,
ABORT,
SYSTEM,
UNDEFINED
};
enum Flag : uint32_t {
N,
Z,
C,
V,
Q,
J,
GE,
E,
A,
I,
F,
T,
M
};
class ARM11 {
public:
ARM11();
~ARM11() = default;
public:
bool pc_changed;
uint32_t registers[16];
Mode mode;
Flag flag;
uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq, r13_fiq, r14_fiq;
uint32_t r13_svc, r14_svc;
uint32_t r13_abt, r14_abt;
uint32_t r13_irq, r14_irq;
uint32_t r13_und, r14_und;
uint32_t cpsr, sprs_fiq, sprs_svc, sprs_abt, sprs_irq, sprs_und;
public:
uint32_t get_sprs();
void set_sprs(uint32_t value);
Mode get_mode();
void set_mode(uint32_t value);
uint32_t get_ge();
void set_ge(uint32_t value);
uint32_t get_register(uint32_t index);
void set_register(uint32_t index, uint32_t value);
};
ARM11::ARM11() {} // TODO: this
uint32_t ARM11::get_sprs() {
switch (mode) {
case USER:
case SYSTEM:
printf("No sprs for user or system mode");
return 0;
case FIQ:
return sprs_fiq;
case IRQ:
return sprs_irq;
case SUPERVISOR:
return sprs_svc;
case ABORT:
return sprs_abt;
case UNDEFINED:
return sprs_und;
}
}
void ARM11::set_sprs(uint32_t value) {
switch (mode) {
case USER:
case SYSTEM:
printf("No sprs for user or system mode");
break;
case FIQ:
sprs_fiq = value;
break;
case IRQ:
sprs_irq = value;
break;
case SUPERVISOR:
sprs_svc = value;
break;
case ABORT:
sprs_abt = value;
break;
case UNDEFINED:
sprs_und = value;
break;
}
}
Mode ARM11::get_mode() {
return static_cast<Mode>(cpsr & 0x1F);
}
void ARM11::set_mode(uint32_t value) {
cpsr = (cpsr & 0x1F) | value;
}
uint32_t ARM11::get_ge() {
return (cpsr >> 16) & 0xF;
}
void ARM11::set_ge(uint32_t value) {
cpsr = (cpsr & 0xFFF0FFFF) | (value << 16);
}
uint32_t ARM11::get_register(uint32_t index) {
switch (mode) {
case USER:
case SYSTEM:
return registers[index];
case FIQ:
if (index < 8 || index == 15)
return registers[index];
else
switch (index) {
case 8:
return r8_fiq;
case 9:
return r9_fiq;
case 10:
return r10_fiq;
case 11:
return r11_fiq;
case 12:
return r12_fiq;
case 13:
return r13_fiq;
case 14:
return r14_fiq;
}
case IRQ:
if (index < 13 || index == 15)
return registers[index];
else
switch (index) {
case 13:
return r13_irq;
case 14:
return r14_irq;
}
case SUPERVISOR:
if (index < 13 || index == 15)
return registers[index];
else
switch (index) {
case 13:
return r13_svc;
case 14:
return r14_svc;
}
case ABORT:
if (index < 13 || index == 15)
return registers[index];
else
switch (index) {
case 13:
return r13_abt;
case 14:
return r14_abt;
}
case UNDEFINED:
if (index < 13 || index == 15)
return registers[index];
else
switch (index) {
case 13:
return r13_und;
case 14:
return r14_und;
}
}
}
void ARM11::set_register(uint32_t index, uint32_t value) {
switch (mode) {
case USER:
case SYSTEM:
registers[index] = value;
case FIQ:
if (index < 8 || index == 15)
registers[index] = value;
else
switch (index) {
case 8:
r8_fiq = value;
case 9:
r9_fiq = value;
case 10:
r10_fiq = value;
case 11:
r11_fiq = value;
case 12:
r12_fiq = value;
case 13:
r13_fiq = value;
case 14:
r14_fiq = value;
}
case IRQ:
if (index < 13 || index == 15)
registers[index] = value;
else
switch (index) {
case 13:
r13_irq = value;
case 14:
r14_irq = value;
}
case SUPERVISOR:
if (index < 13 || index == 15)
registers[index] = value;
else
switch (index) {
case 13:
r13_svc = value;
case 14:
r14_svc = value;
}
case ABORT:
if (index < 13 || index == 15)
registers[index] = value;
else
switch (index) {
case 13:
r13_abt = value;
case 14:
r14_abt = value;
}
case UNDEFINED:
if (index < 13 || index == 15)
registers[index] = value;
else
switch (index) {
case 13:
r13_und = value;
case 14:
r14_und = value;
}
}
pc_changed = true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment