e898de13 |
1 | int sh2_drc_init(SH2 *sh2); |
2 | void sh2_drc_finish(SH2 *sh2); |
efb6bc7d |
3 | void sh2_drc_wcheck_ram(u32 a, unsigned len, SH2 *sh2); |
4 | void sh2_drc_wcheck_da(u32 a, unsigned len, SH2 *sh2); |
679af8a3 |
5 | |
51d86e55 |
6 | #ifdef DRC_SH2 |
7 | void sh2_drc_mem_setup(SH2 *sh2); |
8 | void sh2_drc_flush_all(void); |
51d86e55 |
9 | #else |
10 | #define sh2_drc_mem_setup(x) |
11 | #define sh2_drc_flush_all() |
12 | #define sh2_drc_frame() |
13 | #endif |
14 | |
ff0eaa11 |
15 | #define BLOCK_INSN_LIMIT 1024 |
00faec9c |
16 | |
bf092a36 |
17 | /* op_flags */ |
e1553677 |
18 | #define OF_DELAY_OP (1 << 0) |
19 | #define OF_BTARGET (1 << 1) |
213b7f42 |
20 | #define OF_LOOP (3 << 2) // NONE, IDLE, DELAY, POLL loop |
6a5b1b36 |
21 | #define OF_B_IN_DS (1 << 4) |
213b7f42 |
22 | #define OF_DELAY_INSN (1 << 5) // DT, (TODO ADD+CMP?) |
23 | #define OF_POLL_INSN (1 << 6) // MOV @(...),Rn (no post increment), TST @(...) |
58a444a2 |
24 | #define OF_BASIC_LOOP (1 << 7) // pinnable loop without any branches in it |
213b7f42 |
25 | |
26 | #define OF_IDLE_LOOP (1 << 2) |
27 | #define OF_DELAY_LOOP (2 << 2) |
28 | #define OF_POLL_LOOP (3 << 2) |
00faec9c |
29 | |
efb6bc7d |
30 | u16 scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc, |
31 | u32 *base_literals, u32 *end_literals); |
ff0eaa11 |
32 | |
6b67b6aa |
33 | #if defined(DRC_SH2) && defined(__GNUC__) && !defined(__clang__) |
a5e51c16 |
34 | // direct access to some host CPU registers used by the DRC if gcc is used. |
35 | // XXX MUST match SHR_SR definitions in cpu/drc/emit_*.c; should be moved there |
36 | // XXX yuck, there's no portable way to determine register size. Use long long |
37 | // if target is 64 bit and data model is ILP32 or LLP64(windows), else long |
e267031a |
38 | #if defined(__arm__) |
f53e166c |
39 | #define DRC_SR_REG "r10" |
a5e51c16 |
40 | #define DRC_REG_LL 0 // 32 bit |
b90e104f |
41 | #elif defined(__aarch64__) |
9bd6706d |
42 | #define DRC_SR_REG "r28" |
a5e51c16 |
43 | #define DRC_REG_LL (__ILP32__ || _WIN32) |
d80a5fd2 |
44 | #elif defined(__mips__) |
9bd6706d |
45 | #define DRC_SR_REG "s6" |
1dee7445 |
46 | #define DRC_REG_LL (_MIPS_SZPTR > _MIPS_SZLONG) // (_MIPS_SIM == _ABIN32) |
e7ee5010 |
47 | #elif defined(__riscv__) || defined(__riscv) |
48 | #define DRC_SR_REG "s11" |
a5e51c16 |
49 | #define DRC_REG_LL 0 // no ABI for (__ILP32__ && __riscv_xlen != 32) |
a5085db3 |
50 | #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) |
8094d336 |
51 | #define DRC_SR_REG "r28" |
8bb48947 |
52 | #define DRC_REG_LL 0 // no ABI for __ILP32__ |
cb4379b3 |
53 | //i386 only has 8 registers and reserving one of them causes too much spilling |
54 | //#elif defined(__i386__) |
55 | //#define DRC_SR_REG "edi" |
56 | //#define DRC_REG_LL 0 // 32 bit |
4f4e9bf3 |
57 | #elif defined(__x86_64__) |
a5e51c16 |
58 | #define DRC_SR_REG "rbx" |
59 | #define DRC_REG_LL (__ILP32__ || _WIN32) |
ff0eaa11 |
60 | #endif |
748b8187 |
61 | #endif |
ff0eaa11 |
62 | |
f133766f |
63 | #ifdef DRC_SR_REG |
a5e51c16 |
64 | // XXX this is more clear but produces too much overhead for slow platforms |
90b1c9db |
65 | extern void REGPARM(1) (*sh2_drc_save_sr)(SH2 *sh2); |
66 | extern void REGPARM(1) (*sh2_drc_restore_sr)(SH2 *sh2); |
67 | |
a5e51c16 |
68 | // NB: sh2_sr MUST have register size if optimizing with -O3 (-fif-conversion) |
69 | #if DRC_REG_LL |
70 | #define DRC_DECLARE_SR register long long _sh2_sr asm(DRC_SR_REG) |
71 | #else |
72 | #define DRC_DECLARE_SR register long _sh2_sr asm(DRC_SR_REG) |
73 | #endif |
ca1b77e6 |
74 | // NB: save/load SR register only when DRC is executing and not in DMA access |
ff0eaa11 |
75 | #define DRC_SAVE_SR(sh2) \ |
ca1b77e6 |
76 | if (likely((sh2->state & (SH2_IN_DRC|SH2_STATE_SLEEP)) == SH2_IN_DRC)) \ |
a5e51c16 |
77 | sh2->sr = (s32)_sh2_sr |
0512a228 |
78 | // host_call(sh2_drc_save_sr, (SH2 *))(sh2) |
ff0eaa11 |
79 | #define DRC_RESTORE_SR(sh2) \ |
ca1b77e6 |
80 | if (likely((sh2->state & (SH2_IN_DRC|SH2_STATE_SLEEP)) == SH2_IN_DRC)) \ |
a5e51c16 |
81 | _sh2_sr = (s32)sh2->sr |
0512a228 |
82 | // host_call(sh2_drc_restore_sr, (SH2 *))(sh2) |
ff0eaa11 |
83 | #else |
84 | #define DRC_DECLARE_SR |
85 | #define DRC_SAVE_SR(sh2) |
86 | #define DRC_RESTORE_SR(sh2) |
87 | #endif |