1 /* Declarations for cpu.c */
2 
3 #ifndef CPU_H
4 #define CPU_H
5 
6 #include <stdbool.h>
7 #include <stdint.h>
8 #include <string.h>
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 typedef struct arm_state {  // Remember to update asmcode.S if this gets rearranged
15     uint32_t reg[16];    // Registers for current mode.
16 
17     uint32_t cpsr_low28; // CPSR bits 0-27
18     uint8_t  cpsr_n;     // CPSR bit 31
19     uint8_t  cpsr_z;     // CPSR bit 30
20     uint8_t  cpsr_c;     // CPSR bit 29
21     uint8_t  cpsr_v;     // CPSR bit 28
22 
23     #if defined(__arm__)
24     uint32_t cpsr_flags; // Only used in ARM translations
25     #endif
26 
27     /* CP15 registers */
28     uint32_t control;
29     uint32_t translation_table_base;
30     uint32_t domain_access_control;
31     uint8_t  data_fault_status, instruction_fault_status, pad1, pad2; // pad1 and pad2 for better alignment
32     uint32_t fault_address;
33 
34     uint32_t r8_usr[5], r13_usr[2];
35     uint32_t r8_fiq[5], r13_fiq[2], spsr_fiq;
36     uint32_t r13_irq[2], spsr_irq;
37     uint32_t r13_svc[2], spsr_svc;
38     uint32_t r13_abt[2], spsr_abt;
39     uint32_t r13_und[2], spsr_und;
40 
41     uint8_t  interrupts;
42     uint32_t cpu_events_state; // Only used for suspend and resume!
43 }
44 #ifndef __EMSCRIPTEN__
45 __attribute__((packed))
46 #endif
47 arm_state;
48 extern struct arm_state arm __asm__("arm");
49 
50 #define MODE_USR 0x10
51 #define MODE_FIQ 0x11
52 #define MODE_IRQ 0x12
53 #define MODE_SVC 0x13
54 #define MODE_ABT 0x17
55 #define MODE_UND 0x1B
56 #define MODE_SYS 0x1F
57 #define PRIVILEGED_MODE() (arm.cpsr_low28 & 3)
58 #define USER_MODE()       (!(arm.cpsr_low28 & 3))
59 
60 #define EX_RESET          0
61 #define EX_UNDEFINED      1
62 #define EX_SWI            2
63 #define EX_PREFETCH_ABORT 3
64 #define EX_DATA_ABORT     4
65 #define EX_IRQ            6
66 #define EX_FIQ            7
67 
68 #define current_instr_size ((arm.cpsr_low28 & 0x20) ? 2 /* thumb */ : 4)
69 
70 // Needed for the assembler calling convention
71 #ifdef __i386__
72     #ifdef FASTCALL
73         #undef FASTCALL
74     #endif
75     #define FASTCALL __attribute__((fastcall))
76 #else
77     #define FASTCALL
78 #endif
79 
80 void cpu_int_check();
81 uint32_t get_cpsr() __asm__("get_cpsr");
82 void set_cpsr_full(uint32_t cpsr);
83 void FASTCALL set_cpsr(uint32_t cpsr, uint32_t mask);
84 uint32_t get_spsr();
85 void FASTCALL set_spsr(uint32_t cpsr, uint32_t mask);
86 uint32_t *ptr_spsr();
87 uint32_t get_cpsr_flags();
88 void set_cpsr_flags(uint32_t flags) __asm__("set_cpsr_flags");
89 void cpu_exception(int type);
90 void fix_pc_for_fault();
91 void *try_ptr(uint32_t addr);
92 void cpu_interpret_instruction(uint32_t insn);
93 void cpu_arm_loop();
94 void cpu_thumb_loop();
95 typedef void fault_proc(uint32_t mva, uint8_t status);
96 fault_proc prefetch_abort, data_abort __asm__("data_abort");
97 void undefined_instruction();
98 
99 uint32_t reg(uint8_t i);
100 uint32_t reg_pc(uint8_t i);
101 uint32_t reg_pc_mem(uint8_t i);
102 void set_reg(uint8_t i, uint32_t value);
103 void set_reg_pc(uint8_t i, uint32_t value);
104 void set_reg_bx(uint8_t i, uint32_t value);
105 
106 #ifdef __cplusplus
107 }
108 #endif
109 
110 #endif
111