Mercurial > repos > blastem
comparison m68k_to_x86.c @ 14:2bdad0f52f42
x86 code gen, initial work on translator
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 27 Nov 2012 09:28:13 -0800 |
parents | |
children | 3e7bfde7606e |
comparison
equal
deleted
inserted
replaced
13:168b1a873895 | 14:2bdad0f52f42 |
---|---|
1 #include "gen_x86.h" | |
2 #include "m68k_to_x86.h" | |
3 | |
4 | |
5 #define BUS 4 | |
6 #define CYCLES RAX | |
7 #define LIMIT RBP | |
8 #define SCRATCH RCX | |
9 #define CONTEXT RSI | |
10 | |
11 #define FLAG_N RBX | |
12 #define FLAG_V BH | |
13 #define FLAG_Z RDX | |
14 #define FLAG_C DH | |
15 | |
16 typedef struct { | |
17 int32_t disp; | |
18 uint8_t mode; | |
19 uint8_t base; | |
20 uint8_t index; | |
21 uint8_t cycles; | |
22 } x86_ea; | |
23 | |
24 void handle_cycle_limit(); | |
25 | |
26 uint8_t * cycles(uint8_t * dst, uint32_t num) | |
27 { | |
28 dst = add_i32r(dst, num, CYCLES); | |
29 } | |
30 | |
31 uint8_t * check_cycles(uint8_t * dst) Ivds | |
32 { | |
33 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); | |
34 dst = jcc(dst, CC_G, 5); | |
35 dst = call(dst, (char *)handle_cycle_limit); | |
36 } | |
37 | |
38 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) | |
39 { | |
40 if (op->addr_mode == MODE_REG) { | |
41 return opts->dregs[op->params.regs.pri]; | |
42 } | |
43 if (op->addr_mode == MODE_AREG) { | |
44 return opts->aregs[op->params.regs.pri]; | |
45 } | |
46 return -1; | |
47 } | |
48 | |
49 uint8_t * translate_m68k_ea(m68k_op_info * op, x86_ea * dst, uint8_t * out, x86_68k_options * opts) | |
50 { | |
51 int8_t reg = native_reg(op, opts); | |
52 if (reg >= 0) { | |
53 dst->mode = MODE_REG_DIRECT; | |
54 dst->base = reg; | |
55 return; | |
56 } | |
57 switch (op->addr_mode) | |
58 { | |
59 case MODE_REG: | |
60 case MODE_AREG: | |
61 dst->mode = MODE_DISPLACE8; | |
62 dst->base = CONTEXT; | |
63 dst->disp = (op->addr_mode = MODE_REG ? offsetof(m68k_context, dregs) : offsetof(m68k_context, aregs)) + 4 * op->params.regs.pri; | |
64 break; | |
65 case MODE_AREG_INDIRECT: | |
66 | |
67 break; | |
68 } | |
69 } | |
70 | |
71 uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | |
72 { | |
73 int8_t reg_a, reg_b, flags_reg; | |
74 uint8_t dir = 0; | |
75 int32_t offset; | |
76 switch(inst->op) | |
77 { | |
78 case M68K_ABCD: | |
79 case M68K_ADD: | |
80 case M68K_ADDX: | |
81 case M68K_AND: | |
82 case M68K_ANDI_CCR: | |
83 case M68K_ANDI_SR: | |
84 case M68K_ASL: | |
85 case M68K_ASR: | |
86 case M68K_BCC: | |
87 case M68K_BCHG: | |
88 case M68K_BCLR: | |
89 case M68K_BSET: | |
90 case M68K_BSR: | |
91 case M68K_BTST: | |
92 case M68K_CHK: | |
93 case M68K_CLR: | |
94 case M68K_CMP: | |
95 case M68K_DBCC: | |
96 case M68K_DIVS: | |
97 case M68K_DIVU: | |
98 case M68K_EOR: | |
99 case M68K_EORI_CCR: | |
100 case M68K_EORI_SR: | |
101 case M68K_EXG: | |
102 case M68K_EXT: | |
103 case M68K_ILLEGAL: | |
104 case M68K_JMP: | |
105 case M68K_JSR: | |
106 case M68K_LEA: | |
107 case M68K_LINK: | |
108 case M68K_LSL: | |
109 case M68K_LSR: | |
110 case M68K_MOVE: | |
111 | |
112 if ((inst->src.addr_mode == MODE_REG || inst->src.addr_mode == MODE_AREG || (inst->src.addr_mode == MODE_IMMEDIATE && inst->src.variant == VAR_QUICK)) && (inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) { | |
113 dst = cycles(dst, BUS); | |
114 reg_a = native_reg(&(inst->src), opts); | |
115 reg_b = native_reg(&(inst->dst), opts); | |
116 dst = cycles(dst, BUS); | |
117 if (reg_a >= 0 && reg_b >= 0) { | |
118 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size); | |
119 flags_reg = reg_b; | |
120 } else if(reg_a >= 0) { | |
121 offset = inst->dst.addr_mode == MODE_REG ? offsetof(m68k_context, dregs) : offsetof(m68k_context, aregs); | |
122 dst = mov_rrdisp8(dst, reg_a, CONTEXT, offset + 4 * inst->dst.params.regs.pri, inst->extra.size); | |
123 flags_reg = reg_a; | |
124 } else if(reg_b >= 0) { | |
125 if (inst->src.addr_mode == MODE_REG) { | |
126 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->src.params.regs.pri, reg_b, inst->extra.size); | |
127 } else if(inst->src.addr_mode == MODE_AREG) { | |
128 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, reg_b, inst->extra.size); | |
129 } else { | |
130 dst = mov_i32r(dst, inst->src.params.u32, reg_b); | |
131 } | |
132 flags_reg = reg_b; | |
133 } else { | |
134 | |
135 } | |
136 dst = mov_i8r(dst, 0, FLAG_V); | |
137 dst = mov_i8r(dst, 0, FLAG_C); | |
138 switch (inst->extra.size) | |
139 { | |
140 case OPSIZE_BYTE: | |
141 dst = cmp_i8r(dst, 0, reg_b, SZ_B); | |
142 break; | |
143 case OPSIZE_WORD: | |
144 dst = cmp_i8r(dst, 0, reg_b, SZ_W); | |
145 break; | |
146 case OPSIZE_LONG: | |
147 dst = cmp_i8r(dst, 0, reg_b, SZ_D); | |
148 break; | |
149 } | |
150 dst = setcc_r(dst, CC_Z, FLAG_Z); | |
151 dst = setcc_r(dst, CC_S, FLAG_N); | |
152 dst = check_cycles(dst); | |
153 } | |
154 | |
155 if (reg_a >= 0 && reg_b >= 0) { | |
156 dst = cycles(dst, BUS); | |
157 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size); | |
158 dst = mov_i8r(dst, 0, FLAG_V); | |
159 dst = mov_i8r(dst, 0, FLAG_C); | |
160 switch (inst->extra.size) | |
161 { | |
162 case OPSIZE_BYTE: | |
163 dst = cmp_i8r(dst, 0, reg_b, SZ_B); | |
164 break; | |
165 case OPSIZE_WORD: | |
166 dst = cmp_i8r(dst, 0, reg_b, SZ_W); | |
167 break; | |
168 case OPSIZE_LONG: | |
169 dst = cmp_i8r(dst, 0, reg_b, SZ_D); | |
170 break; | |
171 } | |
172 dst = setcc_r(dst, CC_Z, FLAG_Z); | |
173 dst = setcc_r(dst, CC_S, FLAG_N); | |
174 dst = check_cycles(dst); | |
175 } else if(reg_a >= 0 || reg_b >= 0) { | |
176 if (reg_a >= 0) { | |
177 switch (inst->dst.addr_mode) | |
178 { | |
179 case MODE_REG: | |
180 dst = cycles(dst, BUS); | |
181 dst = mov_rr(dst, reg_a, reg_b, inst->extra.size); | |
182 dst = check_cycles(dst); | |
183 break; | |
184 case MODE_AREG: | |
185 break; | |
186 } | |
187 } else { | |
188 } | |
189 } | |
190 break; | |
191 case M68K_MOVE_CCR: | |
192 case M68K_MOVE_FROM_SR: | |
193 case M68K_MOVE_SR: | |
194 case M68K_MOVE_USP: | |
195 case M68K_MOVEM: | |
196 case M68K_MOVEP: | |
197 case M68K_MULS: | |
198 case M68K_MULU: | |
199 case M68K_NBCD: | |
200 case M68K_NEG: | |
201 case M68K_NEGX: | |
202 case M68K_NOP: | |
203 case M68K_NOT: | |
204 case M68K_OR: | |
205 case M68K_ORI_CCR: | |
206 case M68K_ORI_SR: | |
207 case M68K_PEA: | |
208 case M68K_RESET: | |
209 case M68K_ROL: | |
210 case M68K_ROR: | |
211 case M68K_ROXL: | |
212 case M68K_ROXR: | |
213 case M68K_RTE: | |
214 case M68K_RTR: | |
215 case M68K_RTS: | |
216 case M68K_SBCD: | |
217 case M68K_SCC: | |
218 case M68K_STOP: | |
219 case M68K_SUB: | |
220 case M68K_SUBX: | |
221 case M68K_SWAP: | |
222 case M68K_TAS: | |
223 case M68K_TRAP: | |
224 case M68K_TRAPV: | |
225 case M68K_TST: | |
226 case M68K_UNLK: | |
227 case M68K_INVALID: | |
228 break; | |
229 } | |
230 } | |
231 |