32x: drc: dynamicregister allocator
[picodrive.git] / cpu / drc / emit_x86.c
CommitLineData
679af8a3 1#include <stdarg.h>
2
f4bb5d6b 3enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
4
f4bb5d6b 5#define CONTEXT_REG xBP
679af8a3 6
7#define EMIT_PTR(ptr, val, type) \
8 *(type *)(ptr) = val
9
10#define EMIT(val, type) { \
11 EMIT_PTR(tcache_ptr, val, type); \
f4bb5d6b 12 tcache_ptr += sizeof(type); \
679af8a3 13}
14
e898de13 15#define EMIT_OP(op) { \
16 COUNT_OP; \
17 EMIT(op, u8); \
18}
19
679af8a3 20#define EMIT_MODRM(mod,r,rm) \
21 EMIT(((mod)<<6) | ((r)<<3) | (rm), u8)
22
23#define EMIT_OP_MODRM(op,mod,r,rm) { \
e898de13 24 EMIT_OP(op); \
679af8a3 25 EMIT_MODRM(mod, r, rm); \
26}
27
28#define emith_move_r_r(dst, src) \
29 EMIT_OP_MODRM(0x8b, 3, dst, src)
30
31#define emith_move_r_imm(r, imm) { \
e898de13 32 EMIT_OP(0xb8 + (r)); \
679af8a3 33 EMIT(imm, u32); \
34}
35
36#define emith_add_r_imm(r, imm) { \
37 EMIT_OP_MODRM(0x81, 3, 0, r); \
38 EMIT(imm, u32); \
39}
40
41#define emith_sub_r_imm(r, imm) { \
42 EMIT_OP_MODRM(0x81, 3, 5, r); \
43 EMIT(imm, u32); \
44}
45
46// XXX: offs is 8bit only
47#define emith_ctx_read(r, offs) { \
65c75cb0 48 EMIT_OP_MODRM(0x8b, 1, r, xBP); \
679af8a3 49 EMIT(offs, u8); /* mov tmp, [ebp+#offs] */ \
50}
51
52#define emith_ctx_write(r, offs) { \
65c75cb0 53 EMIT_OP_MODRM(0x89, 1, r, xBP); \
679af8a3 54 EMIT(offs, u8); /* mov [ebp+#offs], tmp */ \
55}
56
679af8a3 57#define emith_jump(ptr) { \
58 u32 disp = (u32)ptr - ((u32)tcache_ptr + 5); \
e898de13 59 EMIT_OP(0xe9); \
679af8a3 60 EMIT(disp, u32); \
61}
62
63#define emith_call(ptr) { \
64 u32 disp = (u32)ptr - ((u32)tcache_ptr + 5); \
e898de13 65 EMIT_OP(0xe8); \
679af8a3 66 EMIT(disp, u32); \
67}
68
65c75cb0 69#define EMITH_CONDITIONAL(code, is_nonzero) { \
f4bb5d6b 70 u8 *ptr = tcache_ptr; \
71 tcache_ptr = tcache_ptr + 2; \
679af8a3 72 code; \
73 EMIT_PTR(ptr, ((is_nonzero) ? 0x75 : 0x74), u8); \
f4bb5d6b 74 EMIT_PTR(ptr + 1, (tcache_ptr - (ptr + 2)), u8); \
679af8a3 75}
76
f4bb5d6b 77#define arg2reg(rd, arg) \
78 switch (arg) { \
79 case 0: rd = xAX; break; \
80 case 1: rd = xDX; break; \
81 case 2: rd = xCX; break; \
679af8a3 82 }
83
f4bb5d6b 84#define emith_pass_arg_r(arg, reg) { \
85 int rd = 7; \
86 arg2reg(rd, arg); \
87 emith_move_r_r(rd, reg); \
88}
89
90#define emith_pass_arg_imm(arg, imm) { \
91 int rd = 7; \
92 arg2reg(rd, arg); \
93 emith_move_r_imm(rd, imm); \
679af8a3 94}
95
65c75cb0 96/* SH2 drc specific */
97#define emith_test_t() { \
98 if (reg_map_g2h[SHR_SR] == -1) { \
99 EMIT_OP_MODRM(0xf6, 1, 0, 5); \
100 EMIT(SHR_SR * 4, u8); \
101 EMIT(0x01, u8); /* test [ebp+SHR_SR], byte 1 */ \
102 } else { \
103 EMIT_OP_MODRM(0xf7, 3, 0, reg_map_g2h[SHR_SR]); \
104 EMIT(0x01, u16); /* test <reg>, word 1 */ \
105 } \
106}
107