comparison m68k_to_x86.c @ 567:8e395210f50f

Refactor gen_x86 to use an interface more like gen_arm and to remove the need for the caller to decide whether an 8-bit or 32-bit displacement is needed in the rdisp functions. Update m68k_to_x86 to use the new version of the gen_x86 functions and do some minor refactoring there in the process
author Michael Pavone <pavone@retrodev.com>
date Sun, 02 Mar 2014 14:45:36 -0800
parents dc9f178085a0
children 9b7fcf748be0
comparison
equal deleted inserted replaced
566:624dd5106060 567:8e395210f50f
41 41
42 void m68k_invalid(); 42 void m68k_invalid();
43 void bcd_add(); 43 void bcd_add();
44 void bcd_sub(); 44 void bcd_sub();
45 45
46 code_ptr cycles(code_ptr dst, uint32_t num) 46
47 { 47 void set_flag(x86_68k_options * opts, uint8_t val, uint8_t flag)
48 dst = add_ir(dst, num, CYCLES, SZ_D);
49 return dst;
50 }
51
52 code_ptr check_cycles_int(code_ptr dst, uint32_t address, x86_68k_options * opts)
53 {
54 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
55 code_ptr jmp_off = dst+1;
56 dst = jcc(dst, CC_NC, dst + 7);
57 dst = mov_ir(dst, address, SCRATCH1, SZ_D);
58 dst = call(dst, opts->gen.handle_cycle_limit_int);
59 *jmp_off = dst - (jmp_off+1);
60 return dst;
61 }
62
63 code_ptr check_cycles(code_ptr dst, cpu_options * opts)
64 {
65 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D);
66 code_ptr jmp_off = dst+1;
67 dst = jcc(dst, CC_NC, dst + 7);
68 dst = call(dst, opts->handle_cycle_limit);
69 *jmp_off = dst - (jmp_off+1);
70 return dst;
71 }
72
73 code_ptr set_flag(code_ptr dst, uint8_t val, uint8_t flag, x86_68k_options * opts)
74 { 48 {
75 if (opts->flag_regs[flag] >= 0) { 49 if (opts->flag_regs[flag] >= 0) {
76 dst = mov_ir(dst, val, opts->flag_regs[flag], SZ_B); 50 mov_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B);
77 } else { 51 } else {
78 int8_t offset = offsetof(m68k_context, flags) + flag; 52 int8_t offset = offsetof(m68k_context, flags) + flag;
79 if (offset) { 53 if (offset) {
80 dst = mov_irdisp8(dst, val, CONTEXT, offset, SZ_B); 54 mov_irdisp(&opts->gen.code, val, opts->gen.context_reg, offset, SZ_B);
81 } else { 55 } else {
82 dst = mov_irind(dst, val, CONTEXT, SZ_B); 56 mov_irind(&opts->gen.code, val, opts->gen.context_reg, SZ_B);
83 } 57 }
84 } 58 }
85 59 }
86 return dst; 60
87 } 61 void set_flag_cond(x86_68k_options *opts, uint8_t cond, uint8_t flag)
88
89 code_ptr set_flag_cond(code_ptr dst, uint8_t cond, uint8_t flag, x86_68k_options *opts)
90 { 62 {
91 if (opts->flag_regs[flag] >= 0) { 63 if (opts->flag_regs[flag] >= 0) {
92 dst = setcc_r(dst, cond, opts->flag_regs[flag]); 64 setcc_r(&opts->gen.code, cond, opts->flag_regs[flag]);
93 } else { 65 } else {
94 int8_t offset = offsetof(m68k_context, flags) + flag; 66 int8_t offset = offsetof(m68k_context, flags) + flag;
95 if (offset) { 67 if (offset) {
96 dst = setcc_rdisp8(dst, cond, CONTEXT, offset); 68 setcc_rdisp(&opts->gen.code, cond, opts->gen.context_reg, offset);
97 } else { 69 } else {
98 dst = setcc_rind(dst, cond, CONTEXT); 70 setcc_rind(&opts->gen.code, cond, opts->gen.context_reg);
99 } 71 }
100 } 72 }
101 73 }
102 return dst; 74
103 } 75 void check_flag(x86_68k_options *opts, uint8_t flag)
104
105 code_ptr check_flag(code_ptr dst, uint8_t flag, x86_68k_options *opts)
106 { 76 {
107 if (opts->flag_regs[flag] >= 0) { 77 if (opts->flag_regs[flag] >= 0) {
108 dst = cmp_ir(dst, 0, opts->flag_regs[flag], SZ_B); 78 cmp_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B);
109 } else { 79 } else {
110 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 80 cmp_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B);
111 } 81 }
112 return dst; 82 }
113 } 83
114 84 void flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg)
115 code_ptr flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
116 { 85 {
117 if (opts->flag_regs[flag] >= 0) { 86 if (opts->flag_regs[flag] >= 0) {
118 dst = mov_rr(dst, opts->flag_regs[flag], reg, SZ_B); 87 mov_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B);
119 } else { 88 } else {
120 int8_t offset = offsetof(m68k_context, flags) + flag; 89 int8_t offset = offsetof(m68k_context, flags) + flag;
121 if (offset) { 90 if (offset) {
122 dst = mov_rdisp8r(dst, CONTEXT, offset, reg, SZ_B); 91 mov_rdispr(&opts->gen.code, opts->gen.context_reg, offset, reg, SZ_B);
123 } else { 92 } else {
124 dst = mov_rindr(dst, CONTEXT, reg, SZ_B); 93 mov_rindr(&opts->gen.code, opts->gen.context_reg, reg, SZ_B);
125 } 94 }
126 } 95 }
127 return dst; 96 }
128 } 97
129 98 void reg_to_flag(x86_68k_options *opts, uint8_t reg, uint8_t flag)
130 code_ptr reg_to_flag(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
131 { 99 {
132 if (opts->flag_regs[flag] >= 0) { 100 if (opts->flag_regs[flag] >= 0) {
133 dst = mov_rr(dst, reg, opts->flag_regs[flag], SZ_B); 101 mov_rr(&opts->gen.code, reg, opts->flag_regs[flag], SZ_B);
134 } else { 102 } else {
135 int8_t offset = offsetof(m68k_context, flags) + flag; 103 int8_t offset = offsetof(m68k_context, flags) + flag;
136 if (offset) { 104 if (offset) {
137 dst = mov_rrdisp8(dst, reg, CONTEXT, offset, SZ_B); 105 mov_rrdisp(&opts->gen.code, reg, opts->gen.context_reg, offset, SZ_B);
138 } else { 106 } else {
139 dst = mov_rrind(dst, reg, CONTEXT, SZ_B); 107 mov_rrind(&opts->gen.code, reg, opts->gen.context_reg, SZ_B);
140 } 108 }
141 } 109 }
142 return dst; 110 }
143 } 111
144 112 void flag_to_flag(x86_68k_options *opts, uint8_t flag1, uint8_t flag2)
145 code_ptr flag_to_flag(code_ptr dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts) 113 {
146 { 114 code_info *code = &opts->gen.code;
147 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { 115 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
148 dst = mov_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); 116 mov_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
149 } else if(opts->flag_regs[flag1] >= 0) { 117 } else if(opts->flag_regs[flag1] >= 0) {
150 dst = mov_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B); 118 mov_rrdisp(code, opts->flag_regs[flag1], opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B);
151 } else if (opts->flag_regs[flag2] >= 0) { 119 } else if (opts->flag_regs[flag2] >= 0) {
152 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, opts->flag_regs[flag2], SZ_B); 120 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag1, opts->flag_regs[flag2], SZ_B);
153 } else { 121 } else {
154 dst = push_r(dst, SCRATCH1); 122 push_r(code, opts->gen.scratch1);
155 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, SCRATCH1, SZ_B); 123 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag1, opts->gen.scratch1, SZ_B);
156 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B); 124 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B);
157 dst = pop_r(dst, SCRATCH1); 125 pop_r(code, opts->gen.scratch1);
158 } 126 }
159 return dst; 127 }
160 } 128
161 129 void flag_to_carry(x86_68k_options * opts, uint8_t flag)
162 code_ptr flag_to_carry(code_ptr dst, uint8_t flag, x86_68k_options * opts)
163 { 130 {
164 if (opts->flag_regs[flag] >= 0) { 131 if (opts->flag_regs[flag] >= 0) {
165 dst = bt_ir(dst, 0, opts->flag_regs[flag], SZ_B); 132 bt_ir(&opts->gen.code, 0, opts->flag_regs[flag], SZ_B);
166 } else { 133 } else {
167 dst = bt_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 134 bt_irdisp(&opts->gen.code, 0, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B);
168 } 135 }
169 return dst; 136 }
170 } 137
171 138 void or_flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg)
172 code_ptr or_flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
173 { 139 {
174 if (opts->flag_regs[flag] >= 0) { 140 if (opts->flag_regs[flag] >= 0) {
175 dst = or_rr(dst, opts->flag_regs[flag], reg, SZ_B); 141 or_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B);
176 } else { 142 } else {
177 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B); 143 or_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B);
178 } 144 }
179 return dst; 145 }
180 } 146
181 147 void xor_flag_to_reg(x86_68k_options *opts, uint8_t flag, uint8_t reg)
182 code_ptr xor_flag_to_reg(code_ptr dst, uint8_t flag, uint8_t reg, x86_68k_options *opts)
183 { 148 {
184 if (opts->flag_regs[flag] >= 0) { 149 if (opts->flag_regs[flag] >= 0) {
185 dst = xor_rr(dst, opts->flag_regs[flag], reg, SZ_B); 150 xor_rr(&opts->gen.code, opts->flag_regs[flag], reg, SZ_B);
186 } else { 151 } else {
187 dst = xor_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, reg, SZ_B); 152 xor_rdispr(&opts->gen.code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, reg, SZ_B);
188 } 153 }
189 return dst; 154 }
190 } 155
191 156 void xor_flag(x86_68k_options *opts, uint8_t val, uint8_t flag)
192 code_ptr xor_flag(code_ptr dst, uint8_t val, uint8_t flag, x86_68k_options *opts)
193 { 157 {
194 if (opts->flag_regs[flag] >= 0) { 158 if (opts->flag_regs[flag] >= 0) {
195 dst = xor_ir(dst, val, opts->flag_regs[flag], SZ_B); 159 xor_ir(&opts->gen.code, val, opts->flag_regs[flag], SZ_B);
196 } else { 160 } else {
197 dst = xor_irdisp8(dst, val, CONTEXT, offsetof(m68k_context, flags) + flag, SZ_B); 161 xor_irdisp(&opts->gen.code, val, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, SZ_B);
198 } 162 }
199 return dst; 163 }
200 } 164
201 165 void cmp_flags(x86_68k_options *opts, uint8_t flag1, uint8_t flag2)
202 code_ptr cmp_flags(code_ptr dst, uint8_t flag1, uint8_t flag2, x86_68k_options *opts) 166 {
203 { 167 code_info *code = &opts->gen.code;
204 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) { 168 if (opts->flag_regs[flag1] >= 0 && opts->flag_regs[flag2] >= 0) {
205 dst = cmp_rr(dst, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B); 169 cmp_rr(code, opts->flag_regs[flag1], opts->flag_regs[flag2], SZ_B);
206 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) { 170 } else if(opts->flag_regs[flag1] >= 0 || opts->flag_regs[flag2] >= 0) {
207 if (opts->flag_regs[flag2] >= 0) { 171 if (opts->flag_regs[flag2] >= 0) {
208 uint8_t tmp = flag1; 172 uint8_t tmp = flag1;
209 flag1 = flag2; 173 flag1 = flag2;
210 flag2 = tmp; 174 flag2 = tmp;
211 } 175 }
212 dst = cmp_rrdisp8(dst, opts->flag_regs[flag1], CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B); 176 cmp_rrdisp(code, opts->flag_regs[flag1], opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B);
213 } else { 177 } else {
214 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag1, SCRATCH1, SZ_B); 178 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag1, opts->gen.scratch1, SZ_B);
215 dst = cmp_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, flags) + flag2, SZ_B); 179 cmp_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, flags) + flag2, SZ_B);
216 } 180 }
217 return dst;
218 } 181 }
219 182
220 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts) 183 int8_t native_reg(m68k_op_info * op, x86_68k_options * opts)
221 { 184 {
222 if (op->addr_mode == MODE_REG) { 185 if (op->addr_mode == MODE_REG) {
247 printf("a%d: %X\n", i, context->aregs[i]); 210 printf("a%d: %X\n", i, context->aregs[i]);
248 } 211 }
249 exit(0); 212 exit(0);
250 } 213 }
251 214
252 code_ptr translate_m68k_src(m68kinst * inst, x86_ea * ea, code_ptr out, x86_68k_options * opts) 215 void m68k_read_size(x86_68k_options *opts, uint8_t size)
253 { 216 {
217 switch (size)
218 {
219 case OPSIZE_BYTE:
220 call(&opts->gen.code, opts->read_8);
221 break;
222 case OPSIZE_WORD:
223 call(&opts->gen.code, opts->read_16);
224 break;
225 case OPSIZE_LONG:
226 call(&opts->gen.code, opts->read_32);
227 break;
228 }
229 }
230
231 void m68k_write_size(x86_68k_options *opts, uint8_t size)
232 {
233 switch (size)
234 {
235 case OPSIZE_BYTE:
236 call(&opts->gen.code, opts->write_8);
237 break;
238 case OPSIZE_WORD:
239 call(&opts->gen.code, opts->write_16);
240 break;
241 case OPSIZE_LONG:
242 call(&opts->gen.code, opts->write_32_highfirst);
243 break;
244 }
245 }
246
247 void translate_m68k_src(m68kinst * inst, x86_ea * ea, x86_68k_options * opts)
248 {
249 code_info *code = &opts->gen.code;
254 int8_t reg = native_reg(&(inst->src), opts); 250 int8_t reg = native_reg(&(inst->src), opts);
255 uint8_t sec_reg; 251 uint8_t sec_reg;
256 int32_t dec_amount,inc_amount; 252 int32_t dec_amount,inc_amount;
257 if (reg >= 0) { 253 if (reg >= 0) {
258 ea->mode = MODE_REG_DIRECT; 254 ea->mode = MODE_REG_DIRECT;
259 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 255 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) {
260 out = movsx_rr(out, reg, SCRATCH1, SZ_W, SZ_D); 256 movsx_rr(code, reg, opts->gen.scratch1, SZ_W, SZ_D);
261 ea->base = SCRATCH1; 257 ea->base = opts->gen.scratch1;
262 } else { 258 } else {
263 ea->base = reg; 259 ea->base = reg;
264 } 260 }
265 return out; 261 return;
266 } 262 }
267 switch (inst->src.addr_mode) 263 switch (inst->src.addr_mode)
268 { 264 {
269 case MODE_REG: 265 case MODE_REG:
270 case MODE_AREG: 266 case MODE_AREG:
273 reg = native_reg(&(inst->dst), opts); 269 reg = native_reg(&(inst->dst), opts);
274 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) 270 if (reg >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)
275 || inst->op == M68K_EXG) { 271 || inst->op == M68K_EXG) {
276 272
277 ea->mode = MODE_REG_DISPLACE8; 273 ea->mode = MODE_REG_DISPLACE8;
278 ea->base = CONTEXT; 274 ea->base = opts->gen.context_reg;
279 ea->disp = reg_offset(&(inst->src)); 275 ea->disp = reg_offset(&(inst->src));
280 } else { 276 } else {
281 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 277 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) {
282 out = movsx_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_W, SZ_D); 278 movsx_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_W, SZ_D);
283 } else { 279 } else {
284 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, inst->extra.size); 280 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, inst->extra.size);
285 } 281 }
286 ea->mode = MODE_REG_DIRECT; 282 ea->mode = MODE_REG_DIRECT;
287 ea->base = SCRATCH1; 283 ea->base = opts->gen.scratch1;
288 //we're explicitly handling the areg dest here, so we exit immediately 284 //we're explicitly handling the areg dest here, so we exit immediately
289 return out; 285 return;
290 } 286 }
291 break; 287 break;
292 case MODE_AREG_PREDEC: 288 case MODE_AREG_PREDEC:
293 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 :1)); 289 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 :1));
294 out = cycles(out, PREDEC_PENALTY); 290 cycles(&opts->gen, PREDEC_PENALTY);
295 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 291 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
296 out = sub_ir(out, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); 292 sub_ir(code, dec_amount, opts->aregs[inst->src.params.regs.pri], SZ_D);
297 } else { 293 } else {
298 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); 294 sub_irdisp(code, dec_amount, opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D);
299 } 295 }
300 case MODE_AREG_INDIRECT: 296 case MODE_AREG_INDIRECT:
301 case MODE_AREG_POSTINC: 297 case MODE_AREG_POSTINC:
302 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 298 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
303 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 299 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
304 } else { 300 } else {
305 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 301 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
306 } 302 }
307 switch (inst->extra.size) 303 m68k_read_size(opts, inst->extra.size);
308 {
309 case OPSIZE_BYTE:
310 out = call(out, opts->read_8);
311 break;
312 case OPSIZE_WORD:
313 out = call(out, opts->read_16);
314 break;
315 case OPSIZE_LONG:
316 out = call(out, opts->read_32);
317 break;
318 }
319 304
320 if (inst->src.addr_mode == MODE_AREG_POSTINC) { 305 if (inst->src.addr_mode == MODE_AREG_POSTINC) {
321 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1)); 306 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->src.params.regs.pri == 7 ? 2 : 1));
322 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 307 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
323 out = add_ir(out, inc_amount, opts->aregs[inst->src.params.regs.pri], SZ_D); 308 add_ir(code, inc_amount, opts->aregs[inst->src.params.regs.pri], SZ_D);
324 } else { 309 } else {
325 out = add_irdisp8(out, inc_amount, CONTEXT, reg_offset(&(inst->src)), SZ_D); 310 add_irdisp(code, inc_amount, opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D);
326 } 311 }
327 } 312 }
328 ea->mode = MODE_REG_DIRECT; 313 ea->mode = MODE_REG_DIRECT;
329 ea->base = (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) ? SCRATCH2 : SCRATCH1; 314 ea->base = (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) ? opts->gen.scratch2 : opts->gen.scratch1;
330 break; 315 break;
331 case MODE_AREG_DISPLACE: 316 case MODE_AREG_DISPLACE:
332 out = cycles(out, BUS); 317 cycles(&opts->gen, BUS);
333 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 318 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
334 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 319 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
335 } else { 320 } else {
336 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 321 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
337 } 322 }
338 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 323 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
339 switch (inst->extra.size) 324 m68k_read_size(opts, inst->extra.size);
340 { 325
341 case OPSIZE_BYTE:
342 out = call(out, opts->read_8);
343 break;
344 case OPSIZE_WORD:
345 out = call(out, opts->read_16);
346 break;
347 case OPSIZE_LONG:
348 out = call(out, opts->read_32);
349 break;
350 }
351 ea->mode = MODE_REG_DIRECT; 326 ea->mode = MODE_REG_DIRECT;
352 ea->base = SCRATCH1; 327 ea->base = opts->gen.scratch1;
353 break; 328 break;
354 case MODE_AREG_INDEX_DISP8: 329 case MODE_AREG_INDEX_DISP8:
355 out = cycles(out, 6); 330 cycles(&opts->gen, 6);
356 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 331 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
357 out = mov_rr(out, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 332 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
358 } else { 333 } else {
359 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 334 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
360 } 335 }
361 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 336 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
362 if (inst->src.params.regs.sec & 1) { 337 if (inst->src.params.regs.sec & 1) {
363 if (inst->src.params.regs.sec & 0x10) { 338 if (inst->src.params.regs.sec & 0x10) {
364 if (opts->aregs[sec_reg] >= 0) { 339 if (opts->aregs[sec_reg] >= 0) {
365 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); 340 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
366 } else { 341 } else {
367 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 342 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
368 } 343 }
369 } else { 344 } else {
370 if (opts->dregs[sec_reg] >= 0) { 345 if (opts->dregs[sec_reg] >= 0) {
371 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); 346 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
372 } else { 347 } else {
373 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 348 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
374 } 349 }
375 } 350 }
376 } else { 351 } else {
377 if (inst->src.params.regs.sec & 0x10) { 352 if (inst->src.params.regs.sec & 0x10) {
378 if (opts->aregs[sec_reg] >= 0) { 353 if (opts->aregs[sec_reg] >= 0) {
379 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 354 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
380 } else { 355 } else {
381 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 356 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
382 } 357 }
383 } else { 358 } else {
384 if (opts->dregs[sec_reg] >= 0) { 359 if (opts->dregs[sec_reg] >= 0) {
385 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 360 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
386 } else { 361 } else {
387 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 362 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
388 } 363 }
389 } 364 }
390 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); 365 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
391 } 366 }
392 if (inst->src.params.regs.displacement) { 367 if (inst->src.params.regs.displacement) {
393 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 368 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
394 } 369 }
395 switch (inst->extra.size) 370 m68k_read_size(opts, inst->extra.size);
396 { 371
397 case OPSIZE_BYTE:
398 out = call(out, opts->read_8);
399 break;
400 case OPSIZE_WORD:
401 out = call(out, opts->read_16);
402 break;
403 case OPSIZE_LONG:
404 out = call(out, opts->read_32);
405 break;
406 }
407 ea->mode = MODE_REG_DIRECT; 372 ea->mode = MODE_REG_DIRECT;
408 ea->base = SCRATCH1; 373 ea->base = opts->gen.scratch1;
409 break; 374 break;
410 case MODE_PC_DISPLACE: 375 case MODE_PC_DISPLACE:
411 out = cycles(out, BUS); 376 cycles(&opts->gen, BUS);
412 out = mov_ir(out, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); 377 mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D);
413 switch (inst->extra.size) 378 m68k_read_size(opts, inst->extra.size);
414 { 379
415 case OPSIZE_BYTE:
416 out = call(out, opts->read_8);
417 break;
418 case OPSIZE_WORD:
419 out = call(out, opts->read_16);
420 break;
421 case OPSIZE_LONG:
422 out = call(out, opts->read_32);
423 break;
424 }
425 ea->mode = MODE_REG_DIRECT; 380 ea->mode = MODE_REG_DIRECT;
426 ea->base = SCRATCH1; 381 ea->base = opts->gen.scratch1;
427 break; 382 break;
428 case MODE_PC_INDEX_DISP8: 383 case MODE_PC_INDEX_DISP8:
429 out = cycles(out, 6); 384 cycles(&opts->gen, 6);
430 out = mov_ir(out, inst->address+2, SCRATCH1, SZ_D); 385 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
431 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 386 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
432 if (inst->src.params.regs.sec & 1) { 387 if (inst->src.params.regs.sec & 1) {
433 if (inst->src.params.regs.sec & 0x10) { 388 if (inst->src.params.regs.sec & 0x10) {
434 if (opts->aregs[sec_reg] >= 0) { 389 if (opts->aregs[sec_reg] >= 0) {
435 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); 390 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
436 } else { 391 } else {
437 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 392 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
438 } 393 }
439 } else { 394 } else {
440 if (opts->dregs[sec_reg] >= 0) { 395 if (opts->dregs[sec_reg] >= 0) {
441 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); 396 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
442 } else { 397 } else {
443 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 398 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
444 } 399 }
445 } 400 }
446 } else { 401 } else {
447 if (inst->src.params.regs.sec & 0x10) { 402 if (inst->src.params.regs.sec & 0x10) {
448 if (opts->aregs[sec_reg] >= 0) { 403 if (opts->aregs[sec_reg] >= 0) {
449 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 404 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
450 } else { 405 } else {
451 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 406 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
452 } 407 }
453 } else { 408 } else {
454 if (opts->dregs[sec_reg] >= 0) { 409 if (opts->dregs[sec_reg] >= 0) {
455 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 410 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
456 } else { 411 } else {
457 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 412 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
458 } 413 }
459 } 414 }
460 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); 415 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
461 } 416 }
462 if (inst->src.params.regs.displacement) { 417 if (inst->src.params.regs.displacement) {
463 out = add_ir(out, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 418 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
464 } 419 }
465 switch (inst->extra.size) 420 m68k_read_size(opts, inst->extra.size);
466 { 421
467 case OPSIZE_BYTE:
468 out = call(out, opts->read_8);
469 break;
470 case OPSIZE_WORD:
471 out = call(out, opts->read_16);
472 break;
473 case OPSIZE_LONG:
474 out = call(out, opts->read_32);
475 break;
476 }
477 ea->mode = MODE_REG_DIRECT; 422 ea->mode = MODE_REG_DIRECT;
478 ea->base = SCRATCH1; 423 ea->base = opts->gen.scratch1;
479 break; 424 break;
480 case MODE_ABSOLUTE: 425 case MODE_ABSOLUTE:
481 case MODE_ABSOLUTE_SHORT: 426 case MODE_ABSOLUTE_SHORT:
482 if (inst->src.addr_mode == MODE_ABSOLUTE) { 427 cycles(&opts->gen, inst->src.addr_mode == MODE_ABSOLUTE ? BUS*2 : BUS);
483 out = cycles(out, BUS*2); 428 mov_ir(code, inst->src.params.immed, opts->gen.scratch1, SZ_D);
484 } else { 429 m68k_read_size(opts, inst->extra.size);
485 out = cycles(out, BUS); 430
486 }
487 out = mov_ir(out, inst->src.params.immed, SCRATCH1, SZ_D);
488 switch (inst->extra.size)
489 {
490 case OPSIZE_BYTE:
491 out = call(out, opts->read_8);
492 break;
493 case OPSIZE_WORD:
494 out = call(out, opts->read_16);
495 break;
496 case OPSIZE_LONG:
497 out = call(out, opts->read_32);
498 break;
499 }
500 ea->mode = MODE_REG_DIRECT; 431 ea->mode = MODE_REG_DIRECT;
501 ea->base = SCRATCH1; 432 ea->base = opts->gen.scratch1;
502 break; 433 break;
503 case MODE_IMMEDIATE: 434 case MODE_IMMEDIATE:
504 case MODE_IMMEDIATE_WORD: 435 case MODE_IMMEDIATE_WORD:
505 if (inst->variant != VAR_QUICK) { 436 if (inst->variant != VAR_QUICK) {
506 out = cycles(out, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS); 437 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG && inst->src.addr_mode == MODE_IMMEDIATE) ? BUS*2 : BUS);
507 } 438 }
508 ea->mode = MODE_IMMED; 439 ea->mode = MODE_IMMED;
509 ea->disp = inst->src.params.immed; 440 ea->disp = inst->src.params.immed;
510 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD && ea->disp & 0x8000) { 441 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD && ea->disp & 0x8000) {
511 ea->disp |= 0xFFFF0000; 442 ea->disp |= 0xFFFF0000;
512 } 443 }
513 return out; 444 return;
514 default: 445 default:
515 m68k_disasm(inst, disasm_buf); 446 m68k_disasm(inst, disasm_buf);
516 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode); 447 printf("%X: %s\naddress mode %d not implemented (src)\n", inst->address, disasm_buf, inst->src.addr_mode);
517 exit(1); 448 exit(1);
518 } 449 }
519 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) { 450 if (inst->dst.addr_mode == MODE_AREG && inst->extra.size == OPSIZE_WORD) {
520 if (ea->mode == MODE_REG_DIRECT) { 451 if (ea->mode == MODE_REG_DIRECT) {
521 out = movsx_rr(out, ea->base, SCRATCH1, SZ_W, SZ_D); 452 movsx_rr(code, ea->base, opts->gen.scratch1, SZ_W, SZ_D);
522 } else { 453 } else {
523 out = movsx_rdisp8r(out, ea->base, ea->disp, SCRATCH1, SZ_W, SZ_D); 454 movsx_rdispr(code, ea->base, ea->disp, opts->gen.scratch1, SZ_W, SZ_D);
524 ea->mode = MODE_REG_DIRECT; 455 ea->mode = MODE_REG_DIRECT;
525 } 456 }
526 ea->base = SCRATCH1; 457 ea->base = opts->gen.scratch1;
527 } 458 }
528 return out; 459 }
529 } 460
530 461 void translate_m68k_dst(m68kinst * inst, x86_ea * ea, x86_68k_options * opts, uint8_t fake_read)
531 code_ptr translate_m68k_dst(m68kinst * inst, x86_ea * ea, code_ptr out, x86_68k_options * opts, uint8_t fake_read) 462 {
532 { 463 code_info *code = &opts->gen.code;
533 int8_t reg = native_reg(&(inst->dst), opts), sec_reg; 464 int8_t reg = native_reg(&(inst->dst), opts), sec_reg;
534 int32_t dec_amount, inc_amount; 465 int32_t dec_amount, inc_amount;
535 if (reg >= 0) { 466 if (reg >= 0) {
536 ea->mode = MODE_REG_DIRECT; 467 ea->mode = MODE_REG_DIRECT;
537 ea->base = reg; 468 ea->base = reg;
538 return out; 469 return;
539 } 470 }
540 switch (inst->dst.addr_mode) 471 switch (inst->dst.addr_mode)
541 { 472 {
542 case MODE_REG: 473 case MODE_REG:
543 case MODE_AREG: 474 case MODE_AREG:
544 ea->mode = MODE_REG_DISPLACE8; 475 ea->mode = MODE_REG_DISPLACE8;
545 ea->base = CONTEXT; 476 ea->base = opts->gen.context_reg;
546 ea->disp = reg_offset(&(inst->dst)); 477 ea->disp = reg_offset(&(inst->dst));
547 break; 478 break;
548 case MODE_AREG_PREDEC: 479 case MODE_AREG_PREDEC:
549 if (inst->src.addr_mode == MODE_AREG_PREDEC) { 480 if (inst->src.addr_mode == MODE_AREG_PREDEC) {
550 out = push_r(out, SCRATCH1); 481 push_r(code, opts->gen.scratch1);
551 } 482 }
552 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 483 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
553 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 484 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
554 out = sub_ir(out, dec_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); 485 sub_ir(code, dec_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D);
555 } else { 486 } else {
556 out = sub_irdisp8(out, dec_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 487 sub_irdisp(code, dec_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
557 } 488 }
558 case MODE_AREG_INDIRECT: 489 case MODE_AREG_INDIRECT:
559 case MODE_AREG_POSTINC: 490 case MODE_AREG_POSTINC:
560 if (fake_read) { 491 if (fake_read) {
561 out = cycles(out, inst->extra.size == OPSIZE_LONG ? 8 : 4); 492 cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 4);
562 } else { 493 } else {
563 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 494 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
564 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH1, SZ_D); 495 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch1, SZ_D);
565 } else { 496 } else {
566 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH1, SZ_D); 497 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch1, SZ_D);
567 } 498 }
568 switch (inst->extra.size) 499 m68k_read_size(opts, inst->extra.size);
569 {
570 case OPSIZE_BYTE:
571 out = call(out, opts->read_8);
572 break;
573 case OPSIZE_WORD:
574 out = call(out, opts->read_16);
575 break;
576 case OPSIZE_LONG:
577 out = call(out, opts->read_32);
578 break;
579 }
580 } 500 }
581 if (inst->src.addr_mode == MODE_AREG_PREDEC) { 501 if (inst->src.addr_mode == MODE_AREG_PREDEC) {
582 //restore src operand to SCRATCH2 502 //restore src operand to opts->gen.scratch2
583 out =pop_r(out, SCRATCH2); 503 pop_r(code, opts->gen.scratch2);
584 } else { 504 } else {
585 //save reg value in SCRATCH2 so we can use it to save the result in memory later 505 //save reg value in opts->gen.scratch2 so we can use it to save the result in memory later
586 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 506 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
587 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 507 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
588 } else { 508 } else {
589 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 509 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
590 } 510 }
591 } 511 }
592 512
593 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 513 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
594 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 514 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
595 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 515 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
596 out = add_ir(out, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); 516 add_ir(code, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D);
597 } else { 517 } else {
598 out = add_irdisp8(out, inc_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 518 add_irdisp(code, inc_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
599 } 519 }
600 } 520 }
601 ea->mode = MODE_REG_DIRECT; 521 ea->mode = MODE_REG_DIRECT;
602 ea->base = SCRATCH1; 522 ea->base = opts->gen.scratch1;
603 break; 523 break;
604 case MODE_AREG_DISPLACE: 524 case MODE_AREG_DISPLACE:
605 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); 525 cycles(&opts->gen, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS);
606 reg = fake_read ? SCRATCH2 : SCRATCH1; 526 reg = fake_read ? opts->gen.scratch2 : opts->gen.scratch1;
607 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 527 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
608 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], reg, SZ_D); 528 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], reg, SZ_D);
609 } else { 529 } else {
610 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), reg, SZ_D); 530 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), reg, SZ_D);
611 } 531 }
612 out = add_ir(out, inst->dst.params.regs.displacement, reg, SZ_D); 532 add_ir(code, inst->dst.params.regs.displacement, reg, SZ_D);
613 if (!fake_read) { 533 if (!fake_read) {
614 out = push_r(out, SCRATCH1); 534 push_r(code, opts->gen.scratch1);
615 switch (inst->extra.size) 535 m68k_read_size(opts, inst->extra.size);
616 { 536 pop_r(code, opts->gen.scratch2);
617 case OPSIZE_BYTE:
618 out = call(out, opts->read_8);
619 break;
620 case OPSIZE_WORD:
621 out = call(out, opts->read_16);
622 break;
623 case OPSIZE_LONG:
624 out = call(out, opts->read_32);
625 break;
626 }
627 out = pop_r(out, SCRATCH2);
628 } 537 }
629 ea->mode = MODE_REG_DIRECT; 538 ea->mode = MODE_REG_DIRECT;
630 ea->base = SCRATCH1; 539 ea->base = opts->gen.scratch1;
631 break; 540 break;
632 case MODE_AREG_INDEX_DISP8: 541 case MODE_AREG_INDEX_DISP8:
633 out = cycles(out, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6); 542 cycles(&opts->gen, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6);
634 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 543 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
635 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH1, SZ_D); 544 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch1, SZ_D);
636 } else { 545 } else {
637 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH1, SZ_D); 546 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch1, SZ_D);
638 } 547 }
639 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 548 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
640 if (inst->dst.params.regs.sec & 1) { 549 if (inst->dst.params.regs.sec & 1) {
641 if (inst->dst.params.regs.sec & 0x10) { 550 if (inst->dst.params.regs.sec & 0x10) {
642 if (opts->aregs[sec_reg] >= 0) { 551 if (opts->aregs[sec_reg] >= 0) {
643 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); 552 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
644 } else { 553 } else {
645 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 554 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
646 } 555 }
647 } else { 556 } else {
648 if (opts->dregs[sec_reg] >= 0) { 557 if (opts->dregs[sec_reg] >= 0) {
649 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); 558 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
650 } else { 559 } else {
651 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 560 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
652 } 561 }
653 } 562 }
654 } else { 563 } else {
655 if (inst->dst.params.regs.sec & 0x10) { 564 if (inst->dst.params.regs.sec & 0x10) {
656 if (opts->aregs[sec_reg] >= 0) { 565 if (opts->aregs[sec_reg] >= 0) {
657 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 566 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
658 } else { 567 } else {
659 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 568 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
660 } 569 }
661 } else { 570 } else {
662 if (opts->dregs[sec_reg] >= 0) { 571 if (opts->dregs[sec_reg] >= 0) {
663 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 572 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
664 } else { 573 } else {
665 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 574 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
666 } 575 }
667 } 576 }
668 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); 577 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
669 } 578 }
670 if (inst->dst.params.regs.displacement) { 579 if (inst->dst.params.regs.displacement) {
671 out = add_ir(out, inst->dst.params.regs.displacement, SCRATCH1, SZ_D); 580 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch1, SZ_D);
672 } 581 }
673 if (fake_read) { 582 if (fake_read) {
674 out = mov_rr(out, SCRATCH1, SCRATCH2, SZ_D); 583 mov_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
675 } else { 584 } else {
676 out = push_r(out, SCRATCH1); 585 push_r(code, opts->gen.scratch1);
677 switch (inst->extra.size) 586 m68k_read_size(opts, inst->extra.size);
678 { 587 pop_r(code, opts->gen.scratch2);
679 case OPSIZE_BYTE:
680 out = call(out, opts->read_8);
681 break;
682 case OPSIZE_WORD:
683 out = call(out, opts->read_16);
684 break;
685 case OPSIZE_LONG:
686 out = call(out, opts->read_32);
687 break;
688 }
689 out = pop_r(out, SCRATCH2);
690 } 588 }
691 ea->mode = MODE_REG_DIRECT; 589 ea->mode = MODE_REG_DIRECT;
692 ea->base = SCRATCH1; 590 ea->base = opts->gen.scratch1;
693 break; 591 break;
694 case MODE_PC_DISPLACE: 592 case MODE_PC_DISPLACE:
695 out = cycles(out, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS); 593 cycles(&opts->gen, fake_read ? BUS+(inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : BUS);
696 out = mov_ir(out, inst->dst.params.regs.displacement + inst->address+2, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); 594 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, fake_read ? opts->gen.scratch2 : opts->gen.scratch1, SZ_D);
697 if (!fake_read) { 595 if (!fake_read) {
698 out = push_r(out, SCRATCH1); 596 push_r(code, opts->gen.scratch1);
699 switch (inst->extra.size) 597 m68k_read_size(opts, inst->extra.size);
700 { 598 pop_r(code, opts->gen.scratch2);
701 case OPSIZE_BYTE:
702 out = call(out, opts->read_8);
703 break;
704 case OPSIZE_WORD:
705 out = call(out, opts->read_16);
706 break;
707 case OPSIZE_LONG:
708 out = call(out, opts->read_32);
709 break;
710 }
711 out = pop_r(out, SCRATCH2);
712 } 599 }
713 ea->mode = MODE_REG_DIRECT; 600 ea->mode = MODE_REG_DIRECT;
714 ea->base = SCRATCH1; 601 ea->base = opts->gen.scratch1;
715 break; 602 break;
716 case MODE_PC_INDEX_DISP8: 603 case MODE_PC_INDEX_DISP8:
717 out = cycles(out, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6); 604 cycles(&opts->gen, fake_read ? (6 + inst->extra.size == OPSIZE_LONG ? 8 : 4) : 6);
718 out = mov_ir(out, inst->address+2, SCRATCH1, SZ_D); 605 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
719 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 606 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
720 if (inst->dst.params.regs.sec & 1) { 607 if (inst->dst.params.regs.sec & 1) {
721 if (inst->dst.params.regs.sec & 0x10) { 608 if (inst->dst.params.regs.sec & 0x10) {
722 if (opts->aregs[sec_reg] >= 0) { 609 if (opts->aregs[sec_reg] >= 0) {
723 out = add_rr(out, opts->aregs[sec_reg], SCRATCH1, SZ_D); 610 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
724 } else { 611 } else {
725 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 612 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
726 } 613 }
727 } else { 614 } else {
728 if (opts->dregs[sec_reg] >= 0) { 615 if (opts->dregs[sec_reg] >= 0) {
729 out = add_rr(out, opts->dregs[sec_reg], SCRATCH1, SZ_D); 616 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
730 } else { 617 } else {
731 out = add_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 618 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
732 } 619 }
733 } 620 }
734 } else { 621 } else {
735 if (inst->dst.params.regs.sec & 0x10) { 622 if (inst->dst.params.regs.sec & 0x10) {
736 if (opts->aregs[sec_reg] >= 0) { 623 if (opts->aregs[sec_reg] >= 0) {
737 out = movsx_rr(out, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 624 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
738 } else { 625 } else {
739 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 626 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
740 } 627 }
741 } else { 628 } else {
742 if (opts->dregs[sec_reg] >= 0) { 629 if (opts->dregs[sec_reg] >= 0) {
743 out = movsx_rr(out, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 630 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
744 } else { 631 } else {
745 out = movsx_rdisp8r(out, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 632 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
746 } 633 }
747 } 634 }
748 out = add_rr(out, SCRATCH2, SCRATCH1, SZ_D); 635 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
749 } 636 }
750 if (inst->dst.params.regs.displacement) { 637 if (inst->dst.params.regs.displacement) {
751 out = add_ir(out, inst->dst.params.regs.displacement, SCRATCH1, SZ_D); 638 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch1, SZ_D);
752 } 639 }
753 if (fake_read) { 640 if (fake_read) {
754 out = mov_rr(out, SCRATCH1, SCRATCH2, SZ_D); 641 mov_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
755 } else { 642 } else {
756 out = push_r(out, SCRATCH1); 643 push_r(code, opts->gen.scratch1);
757 switch (inst->extra.size) 644 m68k_read_size(opts, inst->extra.size);
758 { 645 pop_r(code, opts->gen.scratch2);
759 case OPSIZE_BYTE:
760 out = call(out, opts->read_8);
761 break;
762 case OPSIZE_WORD:
763 out = call(out, opts->read_16);
764 break;
765 case OPSIZE_LONG:
766 out = call(out, opts->read_32);
767 break;
768 }
769 out = pop_r(out, SCRATCH2);
770 } 646 }
771 ea->mode = MODE_REG_DIRECT; 647 ea->mode = MODE_REG_DIRECT;
772 ea->base = SCRATCH1; 648 ea->base = opts->gen.scratch1;
773 break; 649 break;
774 case MODE_ABSOLUTE: 650 case MODE_ABSOLUTE:
775 case MODE_ABSOLUTE_SHORT: 651 case MODE_ABSOLUTE_SHORT:
776 //Add cycles for reading address from instruction stream 652 //Add cycles for reading address from instruction stream
777 out = cycles(out, (inst->dst.addr_mode == MODE_ABSOLUTE ? BUS*2 : BUS) + (fake_read ? (inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : 0)); 653 cycles(&opts->gen, (inst->dst.addr_mode == MODE_ABSOLUTE ? BUS*2 : BUS) + (fake_read ? (inst->extra.size == OPSIZE_LONG ? BUS*2 : BUS) : 0));
778 out = mov_ir(out, inst->dst.params.immed, fake_read ? SCRATCH2 : SCRATCH1, SZ_D); 654 mov_ir(code, inst->dst.params.immed, fake_read ? opts->gen.scratch2 : opts->gen.scratch1, SZ_D);
779 if (!fake_read) { 655 if (!fake_read) {
780 out = push_r(out, SCRATCH1); 656 push_r(code, opts->gen.scratch1);
781 switch (inst->extra.size) 657 m68k_read_size(opts, inst->extra.size);
782 { 658 pop_r(code, opts->gen.scratch2);
783 case OPSIZE_BYTE:
784 out = call(out, opts->read_8);
785 break;
786 case OPSIZE_WORD:
787 out = call(out, opts->read_16);
788 break;
789 case OPSIZE_LONG:
790 out = call(out, opts->read_32);
791 break;
792 }
793 out = pop_r(out, SCRATCH2);
794 } 659 }
795 ea->mode = MODE_REG_DIRECT; 660 ea->mode = MODE_REG_DIRECT;
796 ea->base = SCRATCH1; 661 ea->base = opts->gen.scratch1;
797 break; 662 break;
798 default: 663 default:
799 m68k_disasm(inst, disasm_buf); 664 m68k_disasm(inst, disasm_buf);
800 printf("%X: %s\naddress mode %d not implemented (dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); 665 printf("%X: %s\naddress mode %d not implemented (dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
801 exit(1); 666 exit(1);
802 } 667 }
803 return out; 668 }
804 } 669
805 670 void m68k_save_result(m68kinst * inst, x86_68k_options * opts)
806 code_ptr m68k_save_result(m68kinst * inst, code_ptr out, x86_68k_options * opts) 671 {
807 { 672 code_info *code = &opts->gen.code;
808 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { 673 if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) {
809 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { 674 if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) {
810 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 675 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
811 out = mov_rr(out, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 676 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
812 } else { 677 } else {
813 out = mov_rdisp8r(out, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 678 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
814 } 679 }
815 } 680 }
816 switch (inst->extra.size) 681 switch (inst->extra.size)
817 { 682 {
818 case OPSIZE_BYTE: 683 case OPSIZE_BYTE:
819 out = call(out, opts->write_8); 684 call(code, opts->write_8);
820 break; 685 break;
821 case OPSIZE_WORD: 686 case OPSIZE_WORD:
822 out = call(out, opts->write_16); 687 call(code, opts->write_16);
823 break; 688 break;
824 case OPSIZE_LONG: 689 case OPSIZE_LONG:
825 out = call(out, opts->write_32_lowfirst); 690 call(code, opts->write_32_lowfirst);
826 break; 691 break;
827 } 692 }
828 } 693 }
829 return out;
830 } 694 }
831 695
832 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address) 696 code_ptr get_native_address(native_map_slot * native_code_map, uint32_t address)
833 { 697 {
834 address &= 0xFFFFFF; 698 address &= 0xFFFFFF;
913 } 777 }
914 uint32_t slot = (address & 0xFFFF)/1024; 778 uint32_t slot = (address & 0xFFFF)/1024;
915 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512]; 779 return opts->gen.ram_inst_sizes[slot][((address & 0xFFFF)/2)%512];
916 } 780 }
917 781
918 code_ptr translate_m68k_move(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 782 void translate_m68k_move(x86_68k_options * opts, m68kinst * inst)
919 { 783 {
784 code_info *code = &opts->gen.code;
920 int8_t reg, flags_reg, sec_reg; 785 int8_t reg, flags_reg, sec_reg;
921 uint8_t dir = 0; 786 uint8_t dir = 0;
922 int32_t offset; 787 int32_t offset;
923 int32_t inc_amount, dec_amount; 788 int32_t inc_amount, dec_amount;
924 x86_ea src; 789 x86_ea src;
925 dst = translate_m68k_src(inst, &src, dst, opts); 790 translate_m68k_src(inst, &src, opts);
926 reg = native_reg(&(inst->dst), opts); 791 reg = native_reg(&(inst->dst), opts);
927 if (inst->dst.addr_mode != MODE_AREG) { 792 if (inst->dst.addr_mode != MODE_AREG) {
928 //update statically set flags 793 //update statically set flags
929 dst = set_flag(dst, 0, FLAG_V, opts); 794 set_flag(opts, 0, FLAG_V);
930 dst = set_flag(dst, 0, FLAG_C, opts); 795 set_flag(opts, 0, FLAG_C);
931 } 796 }
932 797
933 if (inst->dst.addr_mode != MODE_AREG) { 798 if (inst->dst.addr_mode != MODE_AREG) {
934 if (src.mode == MODE_REG_DIRECT) { 799 if (src.mode == MODE_REG_DIRECT) {
935 flags_reg = src.base; 800 flags_reg = src.base;
936 } else { 801 } else {
937 if (reg >= 0) { 802 if (reg >= 0) {
938 flags_reg = reg; 803 flags_reg = reg;
939 } else { 804 } else {
940 if(src.mode == MODE_REG_DISPLACE8) { 805 if(src.mode == MODE_REG_DISPLACE8) {
941 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 806 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
942 } else { 807 } else {
943 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 808 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
944 } 809 }
945 src.mode = MODE_REG_DIRECT; 810 src.mode = MODE_REG_DIRECT;
946 flags_reg = src.base = SCRATCH1; 811 flags_reg = src.base = opts->gen.scratch1;
947 } 812 }
948 } 813 }
949 } 814 }
950 uint8_t size = inst->extra.size; 815 uint8_t size = inst->extra.size;
951 switch(inst->dst.addr_mode) 816 switch(inst->dst.addr_mode)
953 case MODE_AREG: 818 case MODE_AREG:
954 size = OPSIZE_LONG; 819 size = OPSIZE_LONG;
955 case MODE_REG: 820 case MODE_REG:
956 if (reg >= 0) { 821 if (reg >= 0) {
957 if (src.mode == MODE_REG_DIRECT) { 822 if (src.mode == MODE_REG_DIRECT) {
958 dst = mov_rr(dst, src.base, reg, size); 823 mov_rr(code, src.base, reg, size);
959 } else if (src.mode == MODE_REG_DISPLACE8) { 824 } else if (src.mode == MODE_REG_DISPLACE8) {
960 dst = mov_rdisp8r(dst, src.base, src.disp, reg, size); 825 mov_rdispr(code, src.base, src.disp, reg, size);
961 } else { 826 } else {
962 dst = mov_ir(dst, src.disp, reg, size); 827 mov_ir(code, src.disp, reg, size);
963 } 828 }
964 } else if(src.mode == MODE_REG_DIRECT) { 829 } else if(src.mode == MODE_REG_DIRECT) {
965 dst = mov_rrdisp8(dst, src.base, CONTEXT, reg_offset(&(inst->dst)), size); 830 mov_rrdisp(code, src.base, opts->gen.context_reg, reg_offset(&(inst->dst)), size);
966 } else { 831 } else {
967 dst = mov_irdisp8(dst, src.disp, CONTEXT, reg_offset(&(inst->dst)), size); 832 mov_irdisp(code, src.disp, opts->gen.context_reg, reg_offset(&(inst->dst)), size);
968 } 833 }
969 if (inst->dst.addr_mode != MODE_AREG) { 834 if (inst->dst.addr_mode != MODE_AREG) {
970 dst = cmp_ir(dst, 0, flags_reg, size); 835 cmp_ir(code, 0, flags_reg, size);
971 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 836 set_flag_cond(opts, CC_Z, FLAG_Z);
972 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 837 set_flag_cond(opts, CC_S, FLAG_N);
973 } 838 }
974 break; 839 break;
975 case MODE_AREG_PREDEC: 840 case MODE_AREG_PREDEC:
976 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 841 dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
977 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 842 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
978 dst = sub_ir(dst, dec_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); 843 sub_ir(code, dec_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D);
979 } else { 844 } else {
980 dst = sub_irdisp8(dst, dec_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 845 sub_irdisp(code, dec_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
981 } 846 }
982 case MODE_AREG_INDIRECT: 847 case MODE_AREG_INDIRECT:
983 case MODE_AREG_POSTINC: 848 case MODE_AREG_POSTINC:
984 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 849 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
985 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 850 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
986 } else { 851 } else {
987 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 852 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
988 } 853 }
989 if (src.mode == MODE_REG_DIRECT) { 854 if (src.mode == MODE_REG_DIRECT) {
990 if (src.base != SCRATCH1) { 855 if (src.base != opts->gen.scratch1) {
991 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 856 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
992 } 857 }
993 } else if (src.mode == MODE_REG_DISPLACE8) { 858 } else if (src.mode == MODE_REG_DISPLACE8) {
994 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 859 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
995 } else { 860 } else {
996 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 861 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
997 } 862 }
998 if (inst->dst.addr_mode != MODE_AREG) { 863 if (inst->dst.addr_mode != MODE_AREG) {
999 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 864 cmp_ir(code, 0, flags_reg, inst->extra.size);
1000 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 865 set_flag_cond(opts, CC_Z, FLAG_Z);
1001 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 866 set_flag_cond(opts, CC_S, FLAG_N);
1002 } 867 }
1003 switch (inst->extra.size) 868 m68k_write_size(opts, inst->extra.size);
1004 { 869
1005 case OPSIZE_BYTE:
1006 dst = call(dst, opts->write_8);
1007 break;
1008 case OPSIZE_WORD:
1009 dst = call(dst, opts->write_16);
1010 break;
1011 case OPSIZE_LONG:
1012 dst = call(dst, opts->write_32_highfirst);
1013 break;
1014 }
1015 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 870 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
1016 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); 871 inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1));
1017 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 872 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1018 dst = add_ir(dst, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); 873 add_ir(code, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D);
1019 } else { 874 } else {
1020 dst = add_irdisp8(dst, inc_amount, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 875 add_irdisp(code, inc_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1021 } 876 }
1022 } 877 }
1023 break; 878 break;
1024 case MODE_AREG_DISPLACE: 879 case MODE_AREG_DISPLACE:
1025 dst = cycles(dst, BUS); 880 cycles(&opts->gen, BUS);
1026 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 881 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1027 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 882 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
1028 } else { 883 } else {
1029 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 884 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
1030 } 885 }
1031 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 886 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1032 if (src.mode == MODE_REG_DIRECT) { 887 if (src.mode == MODE_REG_DIRECT) {
1033 if (src.base != SCRATCH1) { 888 if (src.base != opts->gen.scratch1) {
1034 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 889 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
1035 } 890 }
1036 } else if (src.mode == MODE_REG_DISPLACE8) { 891 } else if (src.mode == MODE_REG_DISPLACE8) {
1037 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 892 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
1038 } else { 893 } else {
1039 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 894 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
1040 } 895 }
1041 if (inst->dst.addr_mode != MODE_AREG) { 896 if (inst->dst.addr_mode != MODE_AREG) {
1042 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 897 cmp_ir(code, 0, flags_reg, inst->extra.size);
1043 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 898 set_flag_cond(opts, CC_Z, FLAG_Z);
1044 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 899 set_flag_cond(opts, CC_S, FLAG_N);
1045 } 900 }
1046 switch (inst->extra.size) 901 m68k_write_size(opts, inst->extra.size);
1047 {
1048 case OPSIZE_BYTE:
1049 dst = call(dst, opts->write_8);
1050 break;
1051 case OPSIZE_WORD:
1052 dst = call(dst, opts->write_16);
1053 break;
1054 case OPSIZE_LONG:
1055 dst = call(dst, opts->write_32_highfirst);
1056 break;
1057 }
1058 break; 902 break;
1059 case MODE_AREG_INDEX_DISP8: 903 case MODE_AREG_INDEX_DISP8:
1060 dst = cycles(dst, 6);//TODO: Check to make sure this is correct 904 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct
1061 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 905 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1062 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 906 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
1063 } else { 907 } else {
1064 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 908 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
1065 } 909 }
1066 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 910 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
1067 if (inst->dst.params.regs.sec & 1) { 911 if (inst->dst.params.regs.sec & 1) {
1068 if (inst->dst.params.regs.sec & 0x10) { 912 if (inst->dst.params.regs.sec & 0x10) {
1069 if (opts->aregs[sec_reg] >= 0) { 913 if (opts->aregs[sec_reg] >= 0) {
1070 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); 914 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D);
1071 } else { 915 } else {
1072 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 916 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1073 } 917 }
1074 } else { 918 } else {
1075 if (opts->dregs[sec_reg] >= 0) { 919 if (opts->dregs[sec_reg] >= 0) {
1076 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); 920 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D);
1077 } else { 921 } else {
1078 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 922 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1079 } 923 }
1080 } 924 }
1081 } else { 925 } else {
1082 if (src.base == SCRATCH1) { 926 if (src.base == opts->gen.scratch1) {
1083 dst = push_r(dst, SCRATCH1); 927 push_r(code, opts->gen.scratch1);
1084 } 928 }
1085 if (inst->dst.params.regs.sec & 0x10) { 929 if (inst->dst.params.regs.sec & 0x10) {
1086 if (opts->aregs[sec_reg] >= 0) { 930 if (opts->aregs[sec_reg] >= 0) {
1087 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 931 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1088 } else { 932 } else {
1089 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 933 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1090 } 934 }
1091 } else { 935 } else {
1092 if (opts->dregs[sec_reg] >= 0) { 936 if (opts->dregs[sec_reg] >= 0) {
1093 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 937 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1094 } else { 938 } else {
1095 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 939 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1096 } 940 }
1097 } 941 }
1098 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); 942 add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1099 if (src.base == SCRATCH1) { 943 if (src.base == opts->gen.scratch1) {
1100 dst = pop_r(dst, SCRATCH1); 944 pop_r(code, opts->gen.scratch1);
1101 } 945 }
1102 } 946 }
1103 if (inst->dst.params.regs.displacement) { 947 if (inst->dst.params.regs.displacement) {
1104 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 948 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1105 } 949 }
1106 if (src.mode == MODE_REG_DIRECT) { 950 if (src.mode == MODE_REG_DIRECT) {
1107 if (src.base != SCRATCH1) { 951 if (src.base != opts->gen.scratch1) {
1108 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 952 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
1109 } 953 }
1110 } else if (src.mode == MODE_REG_DISPLACE8) { 954 } else if (src.mode == MODE_REG_DISPLACE8) {
1111 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 955 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
1112 } else { 956 } else {
1113 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 957 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
1114 } 958 }
1115 if (inst->dst.addr_mode != MODE_AREG) { 959 if (inst->dst.addr_mode != MODE_AREG) {
1116 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 960 cmp_ir(code, 0, flags_reg, inst->extra.size);
1117 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 961 set_flag_cond(opts, CC_Z, FLAG_Z);
1118 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 962 set_flag_cond(opts, CC_S, FLAG_N);
1119 } 963 }
1120 switch (inst->extra.size) 964 m68k_write_size(opts, inst->extra.size);
1121 {
1122 case OPSIZE_BYTE:
1123 dst = call(dst, opts->write_8);
1124 break;
1125 case OPSIZE_WORD:
1126 dst = call(dst, opts->write_16);
1127 break;
1128 case OPSIZE_LONG:
1129 dst = call(dst, opts->write_32_highfirst);
1130 break;
1131 }
1132 break; 965 break;
1133 case MODE_PC_DISPLACE: 966 case MODE_PC_DISPLACE:
1134 dst = cycles(dst, BUS); 967 cycles(&opts->gen, BUS);
1135 dst = mov_ir(dst, inst->dst.params.regs.displacement + inst->address+2, SCRATCH2, SZ_D); 968 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D);
1136 if (src.mode == MODE_REG_DIRECT) { 969 if (src.mode == MODE_REG_DIRECT) {
1137 if (src.base != SCRATCH1) { 970 if (src.base != opts->gen.scratch1) {
1138 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 971 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
1139 } 972 }
1140 } else if (src.mode == MODE_REG_DISPLACE8) { 973 } else if (src.mode == MODE_REG_DISPLACE8) {
1141 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 974 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
1142 } else { 975 } else {
1143 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 976 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
1144 } 977 }
1145 if (inst->dst.addr_mode != MODE_AREG) { 978 if (inst->dst.addr_mode != MODE_AREG) {
1146 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 979 cmp_ir(code, 0, flags_reg, inst->extra.size);
1147 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 980 set_flag_cond(opts, CC_Z, FLAG_Z);
1148 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 981 set_flag_cond(opts, CC_S, FLAG_N);
1149 } 982 }
1150 switch (inst->extra.size) 983 m68k_write_size(opts, inst->extra.size);
1151 {
1152 case OPSIZE_BYTE:
1153 dst = call(dst, opts->write_8);
1154 break;
1155 case OPSIZE_WORD:
1156 dst = call(dst, opts->write_16);
1157 break;
1158 case OPSIZE_LONG:
1159 dst = call(dst, opts->write_32_highfirst);
1160 break;
1161 }
1162 break; 984 break;
1163 case MODE_PC_INDEX_DISP8: 985 case MODE_PC_INDEX_DISP8:
1164 dst = cycles(dst, 6);//TODO: Check to make sure this is correct 986 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct
1165 dst = mov_ir(dst, inst->address, SCRATCH2, SZ_D); 987 mov_ir(code, inst->address, opts->gen.scratch2, SZ_D);
1166 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 988 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
1167 if (inst->dst.params.regs.sec & 1) { 989 if (inst->dst.params.regs.sec & 1) {
1168 if (inst->dst.params.regs.sec & 0x10) { 990 if (inst->dst.params.regs.sec & 0x10) {
1169 if (opts->aregs[sec_reg] >= 0) { 991 if (opts->aregs[sec_reg] >= 0) {
1170 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); 992 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D);
1171 } else { 993 } else {
1172 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 994 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1173 } 995 }
1174 } else { 996 } else {
1175 if (opts->dregs[sec_reg] >= 0) { 997 if (opts->dregs[sec_reg] >= 0) {
1176 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); 998 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D);
1177 } else { 999 } else {
1178 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1000 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1179 } 1001 }
1180 } 1002 }
1181 } else { 1003 } else {
1182 if (src.base == SCRATCH1) { 1004 if (src.base == opts->gen.scratch1) {
1183 dst = push_r(dst, SCRATCH1); 1005 push_r(code, opts->gen.scratch1);
1184 } 1006 }
1185 if (inst->dst.params.regs.sec & 0x10) { 1007 if (inst->dst.params.regs.sec & 0x10) {
1186 if (opts->aregs[sec_reg] >= 0) { 1008 if (opts->aregs[sec_reg] >= 0) {
1187 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1009 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1188 } else { 1010 } else {
1189 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1011 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1190 } 1012 }
1191 } else { 1013 } else {
1192 if (opts->dregs[sec_reg] >= 0) { 1014 if (opts->dregs[sec_reg] >= 0) {
1193 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1015 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1194 } else { 1016 } else {
1195 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1017 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1196 } 1018 }
1197 } 1019 }
1198 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); 1020 add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1199 if (src.base == SCRATCH1) { 1021 if (src.base == opts->gen.scratch1) {
1200 dst = pop_r(dst, SCRATCH1); 1022 pop_r(code, opts->gen.scratch1);
1201 } 1023 }
1202 } 1024 }
1203 if (inst->dst.params.regs.displacement) { 1025 if (inst->dst.params.regs.displacement) {
1204 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 1026 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1205 } 1027 }
1206 if (src.mode == MODE_REG_DIRECT) { 1028 if (src.mode == MODE_REG_DIRECT) {
1207 if (src.base != SCRATCH1) { 1029 if (src.base != opts->gen.scratch1) {
1208 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 1030 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
1209 } 1031 }
1210 } else if (src.mode == MODE_REG_DISPLACE8) { 1032 } else if (src.mode == MODE_REG_DISPLACE8) {
1211 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 1033 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
1212 } else { 1034 } else {
1213 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1035 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
1214 } 1036 }
1215 if (inst->dst.addr_mode != MODE_AREG) { 1037 if (inst->dst.addr_mode != MODE_AREG) {
1216 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1038 cmp_ir(code, 0, flags_reg, inst->extra.size);
1217 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 1039 set_flag_cond(opts, CC_Z, FLAG_Z);
1218 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 1040 set_flag_cond(opts, CC_S, FLAG_N);
1219 } 1041 }
1220 switch (inst->extra.size) 1042 m68k_write_size(opts, inst->extra.size);
1221 {
1222 case OPSIZE_BYTE:
1223 dst = call(dst, opts->write_8);
1224 break;
1225 case OPSIZE_WORD:
1226 dst = call(dst, opts->write_16);
1227 break;
1228 case OPSIZE_LONG:
1229 dst = call(dst, opts->write_32_highfirst);
1230 break;
1231 }
1232 break; 1043 break;
1233 case MODE_ABSOLUTE: 1044 case MODE_ABSOLUTE:
1234 case MODE_ABSOLUTE_SHORT: 1045 case MODE_ABSOLUTE_SHORT:
1235 if (src.mode == MODE_REG_DIRECT) { 1046 if (src.mode == MODE_REG_DIRECT) {
1236 if (src.base != SCRATCH1) { 1047 if (src.base != opts->gen.scratch1) {
1237 dst = mov_rr(dst, src.base, SCRATCH1, inst->extra.size); 1048 mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size);
1238 } 1049 }
1239 } else if (src.mode == MODE_REG_DISPLACE8) { 1050 } else if (src.mode == MODE_REG_DISPLACE8) {
1240 dst = mov_rdisp8r(dst, src.base, src.disp, SCRATCH1, inst->extra.size); 1051 mov_rdispr(code, src.base, src.disp, opts->gen.scratch1, inst->extra.size);
1241 } else { 1052 } else {
1242 dst = mov_ir(dst, src.disp, SCRATCH1, inst->extra.size); 1053 mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size);
1243 } 1054 }
1244 if (inst->dst.addr_mode == MODE_ABSOLUTE) { 1055 if (inst->dst.addr_mode == MODE_ABSOLUTE) {
1245 dst = cycles(dst, BUS*2); 1056 cycles(&opts->gen, BUS*2);
1246 } else { 1057 } else {
1247 dst = cycles(dst, BUS); 1058 cycles(&opts->gen, BUS);
1248 } 1059 }
1249 dst = mov_ir(dst, inst->dst.params.immed, SCRATCH2, SZ_D); 1060 mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D);
1250 if (inst->dst.addr_mode != MODE_AREG) { 1061 if (inst->dst.addr_mode != MODE_AREG) {
1251 dst = cmp_ir(dst, 0, flags_reg, inst->extra.size); 1062 cmp_ir(code, 0, flags_reg, inst->extra.size);
1252 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 1063 set_flag_cond(opts, CC_Z, FLAG_Z);
1253 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 1064 set_flag_cond(opts, CC_S, FLAG_N);
1254 } 1065 }
1255 switch (inst->extra.size) 1066 m68k_write_size(opts, inst->extra.size);
1256 {
1257 case OPSIZE_BYTE:
1258 dst = call(dst, opts->write_8);
1259 break;
1260 case OPSIZE_WORD:
1261 dst = call(dst, opts->write_16);
1262 break;
1263 case OPSIZE_LONG:
1264 dst = call(dst, opts->write_32_highfirst);
1265 break;
1266 }
1267 break; 1067 break;
1268 default: 1068 default:
1269 m68k_disasm(inst, disasm_buf); 1069 m68k_disasm(inst, disasm_buf);
1270 printf("%X: %s\naddress mode %d not implemented (move dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); 1070 printf("%X: %s\naddress mode %d not implemented (move dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
1271 exit(1); 1071 exit(1);
1272 } 1072 }
1273 1073
1274 //add cycles for prefetch 1074 //add cycles for prefetch
1275 dst = cycles(dst, BUS); 1075 cycles(&opts->gen, BUS);
1276 return dst; 1076 }
1277 } 1077
1278 1078 void translate_m68k_movem(x86_68k_options * opts, m68kinst * inst)
1279 code_ptr translate_m68k_movem(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1079 {
1280 { 1080 code_info *code = &opts->gen.code;
1281 int8_t bit,reg,sec_reg; 1081 int8_t bit,reg,sec_reg;
1282 uint8_t early_cycles; 1082 uint8_t early_cycles;
1283 if(inst->src.addr_mode == MODE_REG) { 1083 if(inst->src.addr_mode == MODE_REG) {
1284 //reg to mem 1084 //reg to mem
1285 early_cycles = 8; 1085 early_cycles = 8;
1287 switch (inst->dst.addr_mode) 1087 switch (inst->dst.addr_mode)
1288 { 1088 {
1289 case MODE_AREG_INDIRECT: 1089 case MODE_AREG_INDIRECT:
1290 case MODE_AREG_PREDEC: 1090 case MODE_AREG_PREDEC:
1291 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 1091 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1292 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 1092 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
1293 } else { 1093 } else {
1294 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 1094 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
1295 } 1095 }
1296 break; 1096 break;
1297 case MODE_AREG_DISPLACE: 1097 case MODE_AREG_DISPLACE:
1298 early_cycles += BUS; 1098 early_cycles += BUS;
1299 reg = SCRATCH2; 1099 reg = opts->gen.scratch2;
1300 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 1100 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1301 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 1101 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
1302 } else { 1102 } else {
1303 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 1103 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
1304 } 1104 }
1305 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 1105 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1306 break; 1106 break;
1307 case MODE_AREG_INDEX_DISP8: 1107 case MODE_AREG_INDEX_DISP8:
1308 early_cycles += 6; 1108 early_cycles += 6;
1309 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 1109 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1310 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 1110 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
1311 } else { 1111 } else {
1312 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 1112 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
1313 } 1113 }
1314 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 1114 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
1315 if (inst->dst.params.regs.sec & 1) { 1115 if (inst->dst.params.regs.sec & 1) {
1316 if (inst->dst.params.regs.sec & 0x10) { 1116 if (inst->dst.params.regs.sec & 0x10) {
1317 if (opts->aregs[sec_reg] >= 0) { 1117 if (opts->aregs[sec_reg] >= 0) {
1318 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); 1118 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D);
1319 } else { 1119 } else {
1320 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1120 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1321 } 1121 }
1322 } else { 1122 } else {
1323 if (opts->dregs[sec_reg] >= 0) { 1123 if (opts->dregs[sec_reg] >= 0) {
1324 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); 1124 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D);
1325 } else { 1125 } else {
1326 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1126 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1327 } 1127 }
1328 } 1128 }
1329 } else { 1129 } else {
1330 if (inst->dst.params.regs.sec & 0x10) { 1130 if (inst->dst.params.regs.sec & 0x10) {
1331 if (opts->aregs[sec_reg] >= 0) { 1131 if (opts->aregs[sec_reg] >= 0) {
1332 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1132 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1333 } else { 1133 } else {
1334 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1134 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1335 } 1135 }
1336 } else { 1136 } else {
1337 if (opts->dregs[sec_reg] >= 0) { 1137 if (opts->dregs[sec_reg] >= 0) {
1338 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1138 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1339 } else { 1139 } else {
1340 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1140 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1341 } 1141 }
1342 } 1142 }
1343 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); 1143 add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1344 } 1144 }
1345 if (inst->dst.params.regs.displacement) { 1145 if (inst->dst.params.regs.displacement) {
1346 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 1146 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1347 } 1147 }
1348 break; 1148 break;
1349 case MODE_PC_DISPLACE: 1149 case MODE_PC_DISPLACE:
1350 early_cycles += BUS; 1150 early_cycles += BUS;
1351 dst = mov_ir(dst, inst->dst.params.regs.displacement + inst->address+2, SCRATCH2, SZ_D); 1151 mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D);
1352 break; 1152 break;
1353 case MODE_PC_INDEX_DISP8: 1153 case MODE_PC_INDEX_DISP8:
1354 early_cycles += 6; 1154 early_cycles += 6;
1355 dst = mov_ir(dst, inst->address+2, SCRATCH2, SZ_D); 1155 mov_ir(code, inst->address+2, opts->gen.scratch2, SZ_D);
1356 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; 1156 sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7;
1357 if (inst->dst.params.regs.sec & 1) { 1157 if (inst->dst.params.regs.sec & 1) {
1358 if (inst->dst.params.regs.sec & 0x10) { 1158 if (inst->dst.params.regs.sec & 0x10) {
1359 if (opts->aregs[sec_reg] >= 0) { 1159 if (opts->aregs[sec_reg] >= 0) {
1360 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); 1160 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D);
1361 } else { 1161 } else {
1362 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1162 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1363 } 1163 }
1364 } else { 1164 } else {
1365 if (opts->dregs[sec_reg] >= 0) { 1165 if (opts->dregs[sec_reg] >= 0) {
1366 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); 1166 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D);
1367 } else { 1167 } else {
1368 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1168 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1369 } 1169 }
1370 } 1170 }
1371 } else { 1171 } else {
1372 if (inst->dst.params.regs.sec & 0x10) { 1172 if (inst->dst.params.regs.sec & 0x10) {
1373 if (opts->aregs[sec_reg] >= 0) { 1173 if (opts->aregs[sec_reg] >= 0) {
1374 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1174 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1375 } else { 1175 } else {
1376 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1176 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1377 } 1177 }
1378 } else { 1178 } else {
1379 if (opts->dregs[sec_reg] >= 0) { 1179 if (opts->dregs[sec_reg] >= 0) {
1380 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1180 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1381 } else { 1181 } else {
1382 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1182 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1383 } 1183 }
1384 } 1184 }
1385 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); 1185 add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1386 } 1186 }
1387 if (inst->dst.params.regs.displacement) { 1187 if (inst->dst.params.regs.displacement) {
1388 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 1188 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
1389 } 1189 }
1390 break; 1190 break;
1391 case MODE_ABSOLUTE: 1191 case MODE_ABSOLUTE:
1392 early_cycles += 4; 1192 early_cycles += 4;
1393 case MODE_ABSOLUTE_SHORT: 1193 case MODE_ABSOLUTE_SHORT:
1394 early_cycles += 4; 1194 early_cycles += 4;
1395 dst = mov_ir(dst, inst->dst.params.immed, SCRATCH2, SZ_D); 1195 mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D);
1396 break; 1196 break;
1397 default: 1197 default:
1398 m68k_disasm(inst, disasm_buf); 1198 m68k_disasm(inst, disasm_buf);
1399 printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode); 1199 printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
1400 exit(1); 1200 exit(1);
1404 dir = -1; 1204 dir = -1;
1405 } else { 1205 } else {
1406 reg = 0; 1206 reg = 0;
1407 dir = 1; 1207 dir = 1;
1408 } 1208 }
1409 dst = cycles(dst, early_cycles); 1209 cycles(&opts->gen, early_cycles);
1410 for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) { 1210 for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) {
1411 if (inst->src.params.immed & (1 << bit)) { 1211 if (inst->src.params.immed & (1 << bit)) {
1412 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { 1212 if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
1413 dst = sub_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH2, SZ_D); 1213 sub_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D);
1414 } 1214 }
1415 dst = push_r(dst, SCRATCH2); 1215 push_r(code, opts->gen.scratch2);
1416 if (reg > 7) { 1216 if (reg > 7) {
1417 if (opts->aregs[reg-8] >= 0) { 1217 if (opts->aregs[reg-8] >= 0) {
1418 dst = mov_rr(dst, opts->aregs[reg-8], SCRATCH1, inst->extra.size); 1218 mov_rr(code, opts->aregs[reg-8], opts->gen.scratch1, inst->extra.size);
1419 } else { 1219 } else {
1420 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), SCRATCH1, inst->extra.size); 1220 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), opts->gen.scratch1, inst->extra.size);
1421 } 1221 }
1422 } else { 1222 } else {
1423 if (opts->dregs[reg] >= 0) { 1223 if (opts->dregs[reg] >= 0) {
1424 dst = mov_rr(dst, opts->dregs[reg], SCRATCH1, inst->extra.size); 1224 mov_rr(code, opts->dregs[reg], opts->gen.scratch1, inst->extra.size);
1425 } else { 1225 } else {
1426 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SCRATCH1, inst->extra.size); 1226 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), opts->gen.scratch1, inst->extra.size);
1427 } 1227 }
1428 } 1228 }
1429 if (inst->extra.size == OPSIZE_LONG) { 1229 if (inst->extra.size == OPSIZE_LONG) {
1430 dst = call(dst, opts->write_32_lowfirst); 1230 call(code, opts->write_32_lowfirst);
1431 } else { 1231 } else {
1432 dst = call(dst, opts->write_16); 1232 call(code, opts->write_16);
1433 } 1233 }
1434 dst = pop_r(dst, SCRATCH2); 1234 pop_r(code, opts->gen.scratch2);
1435 if (inst->dst.addr_mode != MODE_AREG_PREDEC) { 1235 if (inst->dst.addr_mode != MODE_AREG_PREDEC) {
1436 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH2, SZ_D); 1236 add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D);
1437 } 1237 }
1438 } 1238 }
1439 } 1239 }
1440 if (inst->dst.addr_mode == MODE_AREG_PREDEC) { 1240 if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
1441 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 1241 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
1442 dst = mov_rr(dst, SCRATCH2, opts->aregs[inst->dst.params.regs.pri], SZ_D); 1242 mov_rr(code, opts->gen.scratch2, opts->aregs[inst->dst.params.regs.pri], SZ_D);
1443 } else { 1243 } else {
1444 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1244 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1445 } 1245 }
1446 } 1246 }
1447 } else { 1247 } else {
1448 //mem to reg 1248 //mem to reg
1449 early_cycles = 4; 1249 early_cycles = 4;
1450 switch (inst->src.addr_mode) 1250 switch (inst->src.addr_mode)
1451 { 1251 {
1452 case MODE_AREG_INDIRECT: 1252 case MODE_AREG_INDIRECT:
1453 case MODE_AREG_POSTINC: 1253 case MODE_AREG_POSTINC:
1454 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1254 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1455 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1255 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1456 } else { 1256 } else {
1457 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1257 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1458 } 1258 }
1459 break; 1259 break;
1460 case MODE_AREG_DISPLACE: 1260 case MODE_AREG_DISPLACE:
1461 early_cycles += BUS; 1261 early_cycles += BUS;
1462 reg = SCRATCH2; 1262 reg = opts->gen.scratch2;
1463 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1263 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1464 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1264 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1465 } else { 1265 } else {
1466 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1266 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1467 } 1267 }
1468 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1268 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1469 break; 1269 break;
1470 case MODE_AREG_INDEX_DISP8: 1270 case MODE_AREG_INDEX_DISP8:
1471 early_cycles += 6; 1271 early_cycles += 6;
1472 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1272 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1473 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1273 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1474 } else { 1274 } else {
1475 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1275 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1476 } 1276 }
1477 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1277 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1478 if (inst->src.params.regs.sec & 1) { 1278 if (inst->src.params.regs.sec & 1) {
1479 if (inst->src.params.regs.sec & 0x10) { 1279 if (inst->src.params.regs.sec & 0x10) {
1480 if (opts->aregs[sec_reg] >= 0) { 1280 if (opts->aregs[sec_reg] >= 0) {
1481 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); 1281 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
1482 } else { 1282 } else {
1483 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1283 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1484 } 1284 }
1485 } else { 1285 } else {
1486 if (opts->dregs[sec_reg] >= 0) { 1286 if (opts->dregs[sec_reg] >= 0) {
1487 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); 1287 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
1488 } else { 1288 } else {
1489 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1289 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1490 } 1290 }
1491 } 1291 }
1492 } else { 1292 } else {
1493 if (inst->src.params.regs.sec & 0x10) { 1293 if (inst->src.params.regs.sec & 0x10) {
1494 if (opts->aregs[sec_reg] >= 0) { 1294 if (opts->aregs[sec_reg] >= 0) {
1495 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1295 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1496 } else { 1296 } else {
1497 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1297 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1498 } 1298 }
1499 } else { 1299 } else {
1500 if (opts->dregs[sec_reg] >= 0) { 1300 if (opts->dregs[sec_reg] >= 0) {
1501 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1301 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1502 } else { 1302 } else {
1503 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1303 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1504 } 1304 }
1505 } 1305 }
1506 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 1306 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
1507 } 1307 }
1508 if (inst->src.params.regs.displacement) { 1308 if (inst->src.params.regs.displacement) {
1509 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1309 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1510 } 1310 }
1511 break; 1311 break;
1512 case MODE_PC_DISPLACE: 1312 case MODE_PC_DISPLACE:
1513 early_cycles += BUS; 1313 early_cycles += BUS;
1514 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); 1314 mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D);
1515 break; 1315 break;
1516 case MODE_PC_INDEX_DISP8: 1316 case MODE_PC_INDEX_DISP8:
1517 early_cycles += 6; 1317 early_cycles += 6;
1518 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 1318 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
1519 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1319 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1520 if (inst->src.params.regs.sec & 1) { 1320 if (inst->src.params.regs.sec & 1) {
1521 if (inst->src.params.regs.sec & 0x10) { 1321 if (inst->src.params.regs.sec & 0x10) {
1522 if (opts->aregs[sec_reg] >= 0) { 1322 if (opts->aregs[sec_reg] >= 0) {
1523 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); 1323 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
1524 } else { 1324 } else {
1525 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1325 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1526 } 1326 }
1527 } else { 1327 } else {
1528 if (opts->dregs[sec_reg] >= 0) { 1328 if (opts->dregs[sec_reg] >= 0) {
1529 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); 1329 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
1530 } else { 1330 } else {
1531 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1331 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1532 } 1332 }
1533 } 1333 }
1534 } else { 1334 } else {
1535 if (inst->src.params.regs.sec & 0x10) { 1335 if (inst->src.params.regs.sec & 0x10) {
1536 if (opts->aregs[sec_reg] >= 0) { 1336 if (opts->aregs[sec_reg] >= 0) {
1537 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1337 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1538 } else { 1338 } else {
1539 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1339 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1540 } 1340 }
1541 } else { 1341 } else {
1542 if (opts->dregs[sec_reg] >= 0) { 1342 if (opts->dregs[sec_reg] >= 0) {
1543 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1343 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1544 } else { 1344 } else {
1545 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1345 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1546 } 1346 }
1547 } 1347 }
1548 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 1348 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
1549 } 1349 }
1550 if (inst->src.params.regs.displacement) { 1350 if (inst->src.params.regs.displacement) {
1551 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1351 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1552 } 1352 }
1553 break; 1353 break;
1554 case MODE_ABSOLUTE: 1354 case MODE_ABSOLUTE:
1555 early_cycles += 4; 1355 early_cycles += 4;
1556 case MODE_ABSOLUTE_SHORT: 1356 case MODE_ABSOLUTE_SHORT:
1557 early_cycles += 4; 1357 early_cycles += 4;
1558 dst = mov_ir(dst, inst->src.params.immed, SCRATCH1, SZ_D); 1358 mov_ir(code, inst->src.params.immed, opts->gen.scratch1, SZ_D);
1559 break; 1359 break;
1560 default: 1360 default:
1561 m68k_disasm(inst, disasm_buf); 1361 m68k_disasm(inst, disasm_buf);
1562 printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode); 1362 printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode);
1563 exit(1); 1363 exit(1);
1564 } 1364 }
1565 dst = cycles(dst, early_cycles); 1365 cycles(&opts->gen, early_cycles);
1566 for(reg = 0; reg < 16; reg ++) { 1366 for(reg = 0; reg < 16; reg ++) {
1567 if (inst->dst.params.immed & (1 << reg)) { 1367 if (inst->dst.params.immed & (1 << reg)) {
1568 dst = push_r(dst, SCRATCH1); 1368 push_r(code, opts->gen.scratch1);
1569 if (inst->extra.size == OPSIZE_LONG) { 1369 if (inst->extra.size == OPSIZE_LONG) {
1570 dst = call(dst, opts->read_32); 1370 call(code, opts->read_32);
1571 } else { 1371 } else {
1572 dst = call(dst, opts->read_16); 1372 call(code, opts->read_16);
1573 } 1373 }
1574 if (inst->extra.size == OPSIZE_WORD) { 1374 if (inst->extra.size == OPSIZE_WORD) {
1575 dst = movsx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); 1375 movsx_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_W, SZ_D);
1576 } 1376 }
1577 if (reg > 7) { 1377 if (reg > 7) {
1578 if (opts->aregs[reg-8] >= 0) { 1378 if (opts->aregs[reg-8] >= 0) {
1579 dst = mov_rr(dst, SCRATCH1, opts->aregs[reg-8], SZ_D); 1379 mov_rr(code, opts->gen.scratch1, opts->aregs[reg-8], SZ_D);
1580 } else { 1380 } else {
1581 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), SZ_D); 1381 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), SZ_D);
1582 } 1382 }
1583 } else { 1383 } else {
1584 if (opts->dregs[reg] >= 0) { 1384 if (opts->dregs[reg] >= 0) {
1585 dst = mov_rr(dst, SCRATCH1, opts->dregs[reg], SZ_D); 1385 mov_rr(code, opts->gen.scratch1, opts->dregs[reg], SZ_D);
1586 } else { 1386 } else {
1587 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SZ_D); 1387 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SZ_D);
1588 } 1388 }
1589 } 1389 }
1590 dst = pop_r(dst, SCRATCH1); 1390 pop_r(code, opts->gen.scratch1);
1591 dst = add_ir(dst, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, SCRATCH1, SZ_D); 1391 add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1, SZ_D);
1592 } 1392 }
1593 } 1393 }
1594 if (inst->src.addr_mode == MODE_AREG_POSTINC) { 1394 if (inst->src.addr_mode == MODE_AREG_POSTINC) {
1595 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1395 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1596 dst = mov_rr(dst, SCRATCH1, opts->aregs[inst->src.params.regs.pri], SZ_D); 1396 mov_rr(code, opts->gen.scratch1, opts->aregs[inst->src.params.regs.pri], SZ_D);
1597 } else { 1397 } else {
1598 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->src)), SZ_D); 1398 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D);
1599 } 1399 }
1600 } 1400 }
1601 } 1401 }
1602 //prefetch 1402 //prefetch
1603 dst = cycles(dst, 4); 1403 cycles(&opts->gen, 4);
1604 return dst; 1404 }
1605 } 1405
1606 1406 void translate_m68k_clr(x86_68k_options * opts, m68kinst * inst)
1607 code_ptr translate_m68k_clr(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1407 {
1608 { 1408 code_info *code = &opts->gen.code;
1609 dst = set_flag(dst, 0, FLAG_N, opts); 1409 set_flag(opts, 0, FLAG_N);
1610 dst = set_flag(dst, 0, FLAG_V, opts); 1410 set_flag(opts, 0, FLAG_V);
1611 dst = set_flag(dst, 0, FLAG_C, opts); 1411 set_flag(opts, 0, FLAG_C);
1612 dst = set_flag(dst, 1, FLAG_Z, opts); 1412 set_flag(opts, 1, FLAG_Z);
1613 int8_t reg = native_reg(&(inst->dst), opts); 1413 int8_t reg = native_reg(&(inst->dst), opts);
1614 if (reg >= 0) { 1414 if (reg >= 0) {
1615 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 6 : 4)); 1415 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 6 : 4));
1616 return xor_rr(dst, reg, reg, inst->extra.size); 1416 xor_rr(code, reg, reg, inst->extra.size);
1417 return;
1617 } 1418 }
1618 x86_ea dst_op; 1419 x86_ea dst_op;
1619 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 1); 1420 translate_m68k_dst(inst, &dst_op, opts, 1);
1620 if (dst_op.mode == MODE_REG_DIRECT) { 1421 if (dst_op.mode == MODE_REG_DIRECT) {
1621 dst = xor_rr(dst, dst_op.base, dst_op.base, inst->extra.size); 1422 xor_rr(code, dst_op.base, dst_op.base, inst->extra.size);
1622 } else { 1423 } else {
1623 dst = mov_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 1424 mov_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
1624 } 1425 }
1625 dst = m68k_save_result(inst, dst, opts); 1426 m68k_save_result(inst, opts);
1626 return dst; 1427 }
1627 } 1428
1628 1429 void translate_m68k_ext(x86_68k_options * opts, m68kinst * inst)
1629 code_ptr translate_m68k_ext(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1430 {
1630 { 1431 code_info *code = &opts->gen.code;
1631 x86_ea dst_op; 1432 x86_ea dst_op;
1632 uint8_t dst_size = inst->extra.size; 1433 uint8_t dst_size = inst->extra.size;
1633 inst->extra.size--; 1434 inst->extra.size--;
1634 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); 1435 translate_m68k_dst(inst, &dst_op, opts, 0);
1635 if (dst_op.mode == MODE_REG_DIRECT) { 1436 if (dst_op.mode == MODE_REG_DIRECT) {
1636 dst = movsx_rr(dst, dst_op.base, dst_op.base, inst->extra.size, dst_size); 1437 movsx_rr(code, dst_op.base, dst_op.base, inst->extra.size, dst_size);
1637 dst = cmp_ir(dst, 0, dst_op.base, dst_size); 1438 cmp_ir(code, 0, dst_op.base, dst_size);
1638 } else { 1439 } else {
1639 dst = movsx_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size, dst_size); 1440 movsx_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, inst->extra.size, dst_size);
1640 dst = cmp_ir(dst, 0, SCRATCH1, dst_size); 1441 cmp_ir(code, 0, opts->gen.scratch1, dst_size);
1641 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, dst_size); 1442 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, dst_size);
1642 } 1443 }
1643 inst->extra.size = dst_size; 1444 inst->extra.size = dst_size;
1644 dst = set_flag(dst, 0, FLAG_V, opts); 1445 set_flag(opts, 0, FLAG_V);
1645 dst = set_flag(dst, 0, FLAG_C, opts); 1446 set_flag(opts, 0, FLAG_C);
1646 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 1447 set_flag_cond(opts, CC_Z, FLAG_Z);
1647 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 1448 set_flag_cond(opts, CC_S, FLAG_N);
1648 //M68K EXT only operates on registers so no need for a call to save result here 1449 //M68K EXT only operates on registers so no need for a call to save result here
1649 return dst; 1450 }
1650 } 1451
1651 1452 void translate_m68k_lea(x86_68k_options * opts, m68kinst * inst)
1652 code_ptr translate_m68k_lea(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1453 {
1653 { 1454 code_info *code = &opts->gen.code;
1654 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg; 1455 int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg;
1655 switch(inst->src.addr_mode) 1456 switch(inst->src.addr_mode)
1656 { 1457 {
1657 case MODE_AREG_INDIRECT: 1458 case MODE_AREG_INDIRECT:
1658 dst = cycles(dst, BUS); 1459 cycles(&opts->gen, BUS);
1659 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1460 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1660 if (dst_reg >= 0) { 1461 if (dst_reg >= 0) {
1661 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D); 1462 mov_rr(code, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D);
1662 } else { 1463 } else {
1663 dst = mov_rrdisp8(dst, opts->aregs[inst->src.params.regs.pri], CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); 1464 mov_rrdisp(code, opts->aregs[inst->src.params.regs.pri], opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D);
1664 } 1465 }
1665 } else { 1466 } else {
1666 if (dst_reg >= 0) { 1467 if (dst_reg >= 0) {
1667 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, dst_reg, SZ_D); 1468 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, dst_reg, SZ_D);
1668 } else { 1469 } else {
1669 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1470 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D);
1670 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); 1471 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D);
1671 } 1472 }
1672 } 1473 }
1673 break; 1474 break;
1674 case MODE_AREG_DISPLACE: 1475 case MODE_AREG_DISPLACE:
1675 dst = cycles(dst, 8); 1476 cycles(&opts->gen, 8);
1676 if (dst_reg >= 0) { 1477 if (dst_reg >= 0) {
1677 if (inst->src.params.regs.pri != inst->dst.params.regs.pri) { 1478 if (inst->src.params.regs.pri != inst->dst.params.regs.pri) {
1678 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1479 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1679 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D); 1480 mov_rr(code, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D);
1680 } else { 1481 } else {
1681 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), dst_reg, SZ_D); 1482 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), dst_reg, SZ_D);
1682 } 1483 }
1683 } 1484 }
1684 dst = add_ir(dst, inst->src.params.regs.displacement, dst_reg, SZ_D); 1485 add_ir(code, inst->src.params.regs.displacement, dst_reg, SZ_D);
1685 } else { 1486 } else {
1686 if (inst->src.params.regs.pri != inst->dst.params.regs.pri) { 1487 if (inst->src.params.regs.pri != inst->dst.params.regs.pri) {
1687 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1488 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1688 dst = mov_rrdisp8(dst, opts->aregs[inst->src.params.regs.pri], CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1489 mov_rrdisp(code, opts->aregs[inst->src.params.regs.pri], opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1689 } else { 1490 } else {
1690 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1491 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1691 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1492 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1692 } 1493 }
1693 } 1494 }
1694 dst = add_irdisp8(dst, inst->src.params.regs.displacement, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1495 add_irdisp(code, inst->src.params.regs.displacement, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1695 } 1496 }
1696 break; 1497 break;
1697 case MODE_AREG_INDEX_DISP8: 1498 case MODE_AREG_INDEX_DISP8:
1698 dst = cycles(dst, 12); 1499 cycles(&opts->gen, 12);
1699 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1500 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1700 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH2, SZ_D); 1501 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch2, SZ_D);
1701 } else { 1502 } else {
1702 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH2, SZ_D); 1503 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch2, SZ_D);
1703 } 1504 }
1704 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1505 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1705 if (inst->src.params.regs.sec & 1) { 1506 if (inst->src.params.regs.sec & 1) {
1706 if (inst->src.params.regs.sec & 0x10) { 1507 if (inst->src.params.regs.sec & 0x10) {
1707 if (opts->aregs[sec_reg] >= 0) { 1508 if (opts->aregs[sec_reg] >= 0) {
1708 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_D); 1509 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D);
1709 } else { 1510 } else {
1710 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1511 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1711 } 1512 }
1712 } else { 1513 } else {
1713 if (opts->dregs[sec_reg] >= 0) { 1514 if (opts->dregs[sec_reg] >= 0) {
1714 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_D); 1515 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D);
1715 } else { 1516 } else {
1716 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_D); 1517 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D);
1717 } 1518 }
1718 } 1519 }
1719 } else { 1520 } else {
1720 if (inst->src.params.regs.sec & 0x10) { 1521 if (inst->src.params.regs.sec & 0x10) {
1721 if (opts->aregs[sec_reg] >= 0) { 1522 if (opts->aregs[sec_reg] >= 0) {
1722 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1523 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1723 } else { 1524 } else {
1724 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1525 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1725 } 1526 }
1726 } else { 1527 } else {
1727 if (opts->dregs[sec_reg] >= 0) { 1528 if (opts->dregs[sec_reg] >= 0) {
1728 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_W, SZ_D); 1529 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D);
1729 } else { 1530 } else {
1730 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_W, SZ_D); 1531 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D);
1731 } 1532 }
1732 } 1533 }
1733 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_D); 1534 add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1734 } 1535 }
1735 if (inst->src.params.regs.displacement) { 1536 if (inst->src.params.regs.displacement) {
1736 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH2, SZ_D); 1537 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch2, SZ_D);
1737 } 1538 }
1738 if (dst_reg >= 0) { 1539 if (dst_reg >= 0) {
1739 dst = mov_rr(dst, SCRATCH2, dst_reg, SZ_D); 1540 mov_rr(code, opts->gen.scratch2, dst_reg, SZ_D);
1740 } else { 1541 } else {
1741 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1542 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1742 } 1543 }
1743 break; 1544 break;
1744 case MODE_PC_DISPLACE: 1545 case MODE_PC_DISPLACE:
1745 dst = cycles(dst, 8); 1546 cycles(&opts->gen, 8);
1746 if (dst_reg >= 0) { 1547 if (dst_reg >= 0) {
1747 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address+2, dst_reg, SZ_D); 1548 mov_ir(code, inst->src.params.regs.displacement + inst->address+2, dst_reg, SZ_D);
1748 } else { 1549 } else {
1749 dst = mov_irdisp8(dst, inst->src.params.regs.displacement + inst->address+2, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); 1550 mov_irdisp(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D);
1750 } 1551 }
1751 break; 1552 break;
1752 case MODE_PC_INDEX_DISP8: 1553 case MODE_PC_INDEX_DISP8:
1753 dst = cycles(dst, BUS*3); 1554 cycles(&opts->gen, BUS*3);
1754 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 1555 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
1755 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1556 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1756 if (inst->src.params.regs.sec & 1) { 1557 if (inst->src.params.regs.sec & 1) {
1757 if (inst->src.params.regs.sec & 0x10) { 1558 if (inst->src.params.regs.sec & 0x10) {
1758 if (opts->aregs[sec_reg] >= 0) { 1559 if (opts->aregs[sec_reg] >= 0) {
1759 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); 1560 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
1760 } else { 1561 } else {
1761 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1562 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1762 } 1563 }
1763 } else { 1564 } else {
1764 if (opts->dregs[sec_reg] >= 0) { 1565 if (opts->dregs[sec_reg] >= 0) {
1765 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); 1566 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
1766 } else { 1567 } else {
1767 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1568 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1768 } 1569 }
1769 } 1570 }
1770 } else { 1571 } else {
1771 if (inst->src.params.regs.sec & 0x10) { 1572 if (inst->src.params.regs.sec & 0x10) {
1772 if (opts->aregs[sec_reg] >= 0) { 1573 if (opts->aregs[sec_reg] >= 0) {
1773 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1574 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1774 } else { 1575 } else {
1775 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1576 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1776 } 1577 }
1777 } else { 1578 } else {
1778 if (opts->dregs[sec_reg] >= 0) { 1579 if (opts->dregs[sec_reg] >= 0) {
1779 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1580 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1780 } else { 1581 } else {
1781 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1582 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1782 } 1583 }
1783 } 1584 }
1784 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 1585 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
1785 } 1586 }
1786 if (inst->src.params.regs.displacement) { 1587 if (inst->src.params.regs.displacement) {
1787 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1588 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1788 } 1589 }
1789 if (dst_reg >= 0) { 1590 if (dst_reg >= 0) {
1790 dst = mov_rr(dst, SCRATCH1, dst_reg, SZ_D); 1591 mov_rr(code, opts->gen.scratch1, dst_reg, SZ_D);
1791 } else { 1592 } else {
1792 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1593 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1793 } 1594 }
1794 break; 1595 break;
1795 case MODE_ABSOLUTE: 1596 case MODE_ABSOLUTE:
1796 case MODE_ABSOLUTE_SHORT: 1597 case MODE_ABSOLUTE_SHORT:
1797 dst = cycles(dst, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); 1598 cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2);
1798 if (dst_reg >= 0) { 1599 if (dst_reg >= 0) {
1799 dst = mov_ir(dst, inst->src.params.immed, dst_reg, SZ_D); 1600 mov_ir(code, inst->src.params.immed, dst_reg, SZ_D);
1800 } else { 1601 } else {
1801 dst = mov_irdisp8(dst, inst->src.params.immed, CONTEXT, reg_offset(&(inst->dst)), SZ_D); 1602 mov_irdisp(code, inst->src.params.immed, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D);
1802 } 1603 }
1803 break; 1604 break;
1804 default: 1605 default:
1805 m68k_disasm(inst, disasm_buf); 1606 m68k_disasm(inst, disasm_buf);
1806 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); 1607 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode);
1807 exit(1); 1608 exit(1);
1808 } 1609 }
1809 return dst; 1610 }
1810 } 1611
1811 1612 void translate_m68k_pea(x86_68k_options * opts, m68kinst * inst)
1812 code_ptr translate_m68k_pea(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1613 {
1813 { 1614 code_info *code = &opts->gen.code;
1814 uint8_t sec_reg; 1615 uint8_t sec_reg;
1815 switch(inst->src.addr_mode) 1616 switch(inst->src.addr_mode)
1816 { 1617 {
1817 case MODE_AREG_INDIRECT: 1618 case MODE_AREG_INDIRECT:
1818 dst = cycles(dst, BUS); 1619 cycles(&opts->gen, BUS);
1819 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1620 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1820 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1621 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1821 } else { 1622 } else {
1822 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1623 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D);
1823 } 1624 }
1824 break; 1625 break;
1825 case MODE_AREG_DISPLACE: 1626 case MODE_AREG_DISPLACE:
1826 dst = cycles(dst, 8); 1627 cycles(&opts->gen, 8);
1827 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1628 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1828 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1629 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1829 } else { 1630 } else {
1830 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1631 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1831 } 1632 }
1832 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1633 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1833 break; 1634 break;
1834 case MODE_AREG_INDEX_DISP8: 1635 case MODE_AREG_INDEX_DISP8:
1835 dst = cycles(dst, 6);//TODO: Check to make sure this is correct 1636 cycles(&opts->gen, 6);//TODO: Check to make sure this is correct
1836 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1637 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1837 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1638 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
1838 } else { 1639 } else {
1839 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1640 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
1840 } 1641 }
1841 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1642 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1842 if (inst->src.params.regs.sec & 1) { 1643 if (inst->src.params.regs.sec & 1) {
1843 if (inst->src.params.regs.sec & 0x10) { 1644 if (inst->src.params.regs.sec & 0x10) {
1844 if (opts->aregs[sec_reg] >= 0) { 1645 if (opts->aregs[sec_reg] >= 0) {
1845 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); 1646 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
1846 } else { 1647 } else {
1847 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1648 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1848 } 1649 }
1849 } else { 1650 } else {
1850 if (opts->dregs[sec_reg] >= 0) { 1651 if (opts->dregs[sec_reg] >= 0) {
1851 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); 1652 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
1852 } else { 1653 } else {
1853 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1654 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1854 } 1655 }
1855 } 1656 }
1856 } else { 1657 } else {
1857 if (inst->src.params.regs.sec & 0x10) { 1658 if (inst->src.params.regs.sec & 0x10) {
1858 if (opts->aregs[sec_reg] >= 0) { 1659 if (opts->aregs[sec_reg] >= 0) {
1859 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1660 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1860 } else { 1661 } else {
1861 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1662 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1862 } 1663 }
1863 } else { 1664 } else {
1864 if (opts->dregs[sec_reg] >= 0) { 1665 if (opts->dregs[sec_reg] >= 0) {
1865 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1666 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1866 } else { 1667 } else {
1867 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1668 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1868 } 1669 }
1869 } 1670 }
1870 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 1671 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
1871 } 1672 }
1872 if (inst->src.params.regs.displacement) { 1673 if (inst->src.params.regs.displacement) {
1873 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1674 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1874 } 1675 }
1875 break; 1676 break;
1876 case MODE_PC_DISPLACE: 1677 case MODE_PC_DISPLACE:
1877 dst = cycles(dst, 8); 1678 cycles(&opts->gen, 8);
1878 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); 1679 mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D);
1879 break; 1680 break;
1880 case MODE_ABSOLUTE: 1681 case MODE_ABSOLUTE:
1881 case MODE_ABSOLUTE_SHORT: 1682 case MODE_ABSOLUTE_SHORT:
1882 dst = cycles(dst, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); 1683 cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2);
1883 dst = mov_ir(dst, inst->src.params.immed, SCRATCH1, SZ_D); 1684 mov_ir(code, inst->src.params.immed, opts->gen.scratch1, SZ_D);
1884 break; 1685 break;
1885 default: 1686 default:
1886 m68k_disasm(inst, disasm_buf); 1687 m68k_disasm(inst, disasm_buf);
1887 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); 1688 printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode);
1888 exit(1); 1689 exit(1);
1889 } 1690 }
1890 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1691 sub_ir(code, 4, opts->aregs[7], SZ_D);
1891 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1692 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1892 dst = call(dst, opts->write_32_lowfirst); 1693 call(code, opts->write_32_lowfirst);
1893 return dst; 1694 }
1894 } 1695
1895 1696 void translate_m68k_bsr(x86_68k_options * opts, m68kinst * inst)
1896 code_ptr translate_m68k_bsr(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1697 {
1897 { 1698 code_info *code = &opts->gen.code;
1898 int32_t disp = inst->src.params.immed; 1699 int32_t disp = inst->src.params.immed;
1899 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); 1700 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4);
1900 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1701 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1901 dst = cycles(dst, 10); 1702 cycles(&opts->gen, 10);
1902 dst = mov_ir(dst, after, SCRATCH1, SZ_D); 1703 mov_ir(code, after, opts->gen.scratch1, SZ_D);
1903 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1704 sub_ir(code, 4, opts->aregs[7], SZ_D);
1904 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1705 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1905 dst = call(dst, opts->write_32_highfirst); 1706 call(code, opts->write_32_highfirst);
1906 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, (inst->address+2) + disp); 1707 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, (inst->address+2) + disp);
1907 if (!dest_addr) { 1708 if (!dest_addr) {
1908 opts->gen.deferred = defer_address(opts->gen.deferred, (inst->address+2) + disp, dst + 1); 1709 opts->gen.deferred = defer_address(opts->gen.deferred, (inst->address+2) + disp, code->cur + 1);
1909 //dummy address to be replaced later 1710 //dummy address to be replaced later
1910 dest_addr = dst + 256; 1711 dest_addr = code->cur + 256;
1911 } 1712 }
1912 dst = jmp(dst, (char *)dest_addr); 1713 jmp(code, dest_addr);
1913 return dst; 1714 }
1914 } 1715
1915 1716 uint8_t m68k_eval_cond(x86_68k_options * opts, uint8_t cc)
1916 code_ptr translate_m68k_bcc(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1717 {
1917 { 1718 uint8_t cond = CC_NZ;
1918 dst = cycles(dst, 10);//TODO: Adjust this for branch not taken case 1719 switch (cc)
1720 {
1721 case COND_HIGH:
1722 cond = CC_Z;
1723 case COND_LOW_SAME:
1724 flag_to_reg(opts, FLAG_Z, opts->gen.scratch1);
1725 or_flag_to_reg(opts, FLAG_C, opts->gen.scratch1);
1726 break;
1727 case COND_CARRY_CLR:
1728 cond = CC_Z;
1729 case COND_CARRY_SET:
1730 check_flag(opts, FLAG_C);
1731 break;
1732 case COND_NOT_EQ:
1733 cond = CC_Z;
1734 case COND_EQ:
1735 check_flag(opts, FLAG_Z);
1736 break;
1737 case COND_OVERF_CLR:
1738 cond = CC_Z;
1739 case COND_OVERF_SET:
1740 check_flag(opts, FLAG_V);
1741 break;
1742 case COND_PLUS:
1743 cond = CC_Z;
1744 case COND_MINUS:
1745 check_flag(opts, FLAG_N);
1746 break;
1747 case COND_GREATER_EQ:
1748 cond = CC_Z;
1749 case COND_LESS:
1750 cmp_flags(opts, FLAG_N, FLAG_V);
1751 break;
1752 case COND_GREATER:
1753 cond = CC_Z;
1754 case COND_LESS_EQ:
1755 flag_to_reg(opts, FLAG_V, opts->gen.scratch1);
1756 xor_flag_to_reg(opts, FLAG_N, opts->gen.scratch1);
1757 or_flag_to_reg(opts, FLAG_Z, opts->gen.scratch1);
1758 break;
1759 }
1760 return cond;
1761 }
1762
1763 void translate_m68k_bcc(x86_68k_options * opts, m68kinst * inst)
1764 {
1765 code_info *code = &opts->gen.code;
1766 cycles(&opts->gen, 10);//TODO: Adjust this for branch not taken case
1919 int32_t disp = inst->src.params.immed; 1767 int32_t disp = inst->src.params.immed;
1920 uint32_t after = inst->address + 2; 1768 uint32_t after = inst->address + 2;
1921 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp); 1769 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp);
1922 if (inst->extra.cond == COND_TRUE) { 1770 if (inst->extra.cond == COND_TRUE) {
1923 if (!dest_addr) { 1771 if (!dest_addr) {
1924 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, dst + 1); 1772 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 1);
1925 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1773 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1926 dest_addr = dst + 256; 1774 dest_addr = code->cur + 256;
1927 } 1775 }
1928 dst = jmp(dst, dest_addr); 1776 jmp(code, dest_addr);
1929 } else { 1777 } else {
1930 uint8_t cond = CC_NZ; 1778 uint8_t cond = m68k_eval_cond(opts, inst->extra.cond);
1931 switch (inst->extra.cond)
1932 {
1933 case COND_HIGH:
1934 cond = CC_Z;
1935 case COND_LOW_SAME:
1936 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1937 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
1938 break;
1939 case COND_CARRY_CLR:
1940 cond = CC_Z;
1941 case COND_CARRY_SET:
1942 dst = check_flag(dst, FLAG_C, opts);
1943 break;
1944 case COND_NOT_EQ:
1945 cond = CC_Z;
1946 case COND_EQ:
1947 dst = check_flag(dst, FLAG_Z, opts);
1948 break;
1949 case COND_OVERF_CLR:
1950 cond = CC_Z;
1951 case COND_OVERF_SET:
1952 dst = check_flag(dst, FLAG_V, opts);
1953 break;
1954 case COND_PLUS:
1955 cond = CC_Z;
1956 case COND_MINUS:
1957 dst = check_flag(dst, FLAG_N, opts);
1958 break;
1959 case COND_GREATER_EQ:
1960 cond = CC_Z;
1961 case COND_LESS:
1962 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
1963 break;
1964 case COND_GREATER:
1965 cond = CC_Z;
1966 case COND_LESS_EQ:
1967 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
1968 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
1969 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
1970 break;
1971 }
1972 if (!dest_addr) { 1779 if (!dest_addr) {
1973 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, dst + 2); 1780 opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 2);
1974 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1781 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1975 dest_addr = dst + 256; 1782 dest_addr = code->cur + 256;
1976 } 1783 }
1977 dst = jcc(dst, cond, dest_addr); 1784 jcc(code, cond, dest_addr);
1978 } 1785 }
1979 return dst; 1786 }
1980 } 1787
1981 1788 void translate_m68k_scc(x86_68k_options * opts, m68kinst * inst)
1982 code_ptr translate_m68k_scc(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1789 {
1983 { 1790 code_info *code = &opts->gen.code;
1984 uint8_t cond = inst->extra.cond; 1791 uint8_t cond = inst->extra.cond;
1985 x86_ea dst_op; 1792 x86_ea dst_op;
1986 inst->extra.size = OPSIZE_BYTE; 1793 inst->extra.size = OPSIZE_BYTE;
1987 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 1); 1794 translate_m68k_dst(inst, &dst_op, opts, 1);
1988 if (cond == COND_TRUE || cond == COND_FALSE) { 1795 if (cond == COND_TRUE || cond == COND_FALSE) {
1989 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) && inst->extra.cond == COND_TRUE) { 1796 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) && inst->extra.cond == COND_TRUE) {
1990 dst = cycles(dst, 6); 1797 cycles(&opts->gen, 6);
1991 } else { 1798 } else {
1992 dst = cycles(dst, BUS); 1799 cycles(&opts->gen, BUS);
1993 } 1800 }
1994 if (dst_op.mode == MODE_REG_DIRECT) { 1801 if (dst_op.mode == MODE_REG_DIRECT) {
1995 dst = mov_ir(dst, cond == COND_TRUE ? 0xFF : 0, dst_op.base, SZ_B); 1802 mov_ir(code, cond == COND_TRUE ? 0xFF : 0, dst_op.base, SZ_B);
1996 } else { 1803 } else {
1997 dst = mov_irdisp8(dst, cond == COND_TRUE ? 0xFF : 0, dst_op.base, dst_op.disp, SZ_B); 1804 mov_irdisp(code, cond == COND_TRUE ? 0xFF : 0, dst_op.base, dst_op.disp, SZ_B);
1998 } 1805 }
1999 } else { 1806 } else {
2000 uint8_t cc = CC_NZ; 1807 uint8_t cc = m68k_eval_cond(opts, cond);
2001 switch (cond) 1808 check_alloc_code(code, 6*MAX_INST_LEN);
2002 { 1809 code_ptr true_off = code->cur + 1;
2003 case COND_HIGH: 1810 jcc(code, cc, code->cur+2);
2004 cc = CC_Z; 1811 cycles(&opts->gen, BUS);
2005 case COND_LOW_SAME:
2006 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2007 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
2008 break;
2009 case COND_CARRY_CLR:
2010 cc = CC_Z;
2011 case COND_CARRY_SET:
2012 dst = check_flag(dst, FLAG_C, opts);
2013 break;
2014 case COND_NOT_EQ:
2015 cc = CC_Z;
2016 case COND_EQ:
2017 dst = check_flag(dst, FLAG_Z, opts);
2018 break;
2019 case COND_OVERF_CLR:
2020 cc = CC_Z;
2021 case COND_OVERF_SET:
2022 dst = check_flag(dst, FLAG_V, opts);
2023 break;
2024 case COND_PLUS:
2025 cc = CC_Z;
2026 case COND_MINUS:
2027 dst = check_flag(dst, FLAG_N, opts);
2028 break;
2029 case COND_GREATER_EQ:
2030 cc = CC_Z;
2031 case COND_LESS:
2032 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
2033 break;
2034 case COND_GREATER:
2035 cc = CC_Z;
2036 case COND_LESS_EQ:
2037 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
2038 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
2039 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2040 break;
2041 }
2042 code_ptr true_off = dst + 1;
2043 dst = jcc(dst, cc, dst+2);
2044 dst = cycles(dst, BUS);
2045 if (dst_op.mode == MODE_REG_DIRECT) { 1812 if (dst_op.mode == MODE_REG_DIRECT) {
2046 dst = mov_ir(dst, 0, dst_op.base, SZ_B); 1813 mov_ir(code, 0, dst_op.base, SZ_B);
2047 } else { 1814 } else {
2048 dst = mov_irdisp8(dst, 0, dst_op.base, dst_op.disp, SZ_B); 1815 mov_irdisp(code, 0, dst_op.base, dst_op.disp, SZ_B);
2049 } 1816 }
2050 code_ptr end_off = dst+1; 1817 code_ptr end_off = code->cur+1;
2051 dst = jmp(dst, dst+2); 1818 jmp(code, code->cur+2);
2052 *true_off = dst - (true_off+1); 1819 *true_off = code->cur - (true_off+1);
2053 dst = cycles(dst, 6); 1820 cycles(&opts->gen, 6);
2054 if (dst_op.mode == MODE_REG_DIRECT) { 1821 if (dst_op.mode == MODE_REG_DIRECT) {
2055 dst = mov_ir(dst, 0xFF, dst_op.base, SZ_B); 1822 mov_ir(code, 0xFF, dst_op.base, SZ_B);
2056 } else { 1823 } else {
2057 dst = mov_irdisp8(dst, 0xFF, dst_op.base, dst_op.disp, SZ_B); 1824 mov_irdisp(code, 0xFF, dst_op.base, dst_op.disp, SZ_B);
2058 } 1825 }
2059 *end_off = dst - (end_off+1); 1826 *end_off = code->cur - (end_off+1);
2060 } 1827 }
2061 dst = m68k_save_result(inst, dst, opts); 1828 m68k_save_result(inst, opts);
2062 return dst; 1829 }
2063 } 1830
2064 1831 void translate_m68k_jmp_jsr(x86_68k_options * opts, m68kinst * inst)
2065 code_ptr translate_m68k_jmp(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 1832 {
2066 { 1833 uint8_t is_jsr = inst->op == M68K_JSR;
2067 code_ptr dest_addr; 1834 code_info *code = &opts->gen.code;
2068 uint8_t sec_reg;
2069 uint32_t m68k_addr;
2070 switch(inst->src.addr_mode)
2071 {
2072 case MODE_AREG_INDIRECT:
2073 dst = cycles(dst, BUS*2);
2074 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2075 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2076 } else {
2077 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
2078 }
2079 dst = call(dst, opts->native_addr);
2080 dst = jmp_r(dst, SCRATCH1);
2081 break;
2082 case MODE_AREG_INDEX_DISP8:
2083 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
2084 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2085 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
2086 } else {
2087 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D);
2088 }
2089 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2090 if (inst->src.params.regs.sec & 1) {
2091 //32-bit index register
2092 if (inst->src.params.regs.sec & 0x10) {
2093 if (opts->aregs[sec_reg] >= 0) {
2094 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
2095 } else {
2096 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2097 }
2098 } else {
2099 if (opts->dregs[sec_reg] >= 0) {
2100 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
2101 } else {
2102 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2103 }
2104 }
2105 } else {
2106 //16-bit index register
2107 if (inst->src.params.regs.sec & 0x10) {
2108 if (opts->aregs[sec_reg] >= 0) {
2109 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2110 } else {
2111 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2112 }
2113 } else {
2114 if (opts->dregs[sec_reg] >= 0) {
2115 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2116 } else {
2117 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2118 }
2119 }
2120 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
2121 }
2122 if (inst->src.params.regs.displacement) {
2123 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2124 }
2125 dst = call(dst, opts->native_addr);
2126 dst = jmp_r(dst, SCRATCH1);
2127 break;
2128 case MODE_PC_DISPLACE:
2129 dst = cycles(dst, 10);
2130 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2131 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2132 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2133 if (!dest_addr) {
2134 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2135 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2136 dest_addr = dst + 256;
2137 }
2138 dst = jmp(dst, dest_addr);
2139 } else {
2140 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
2141 dst = call(dst, opts->native_addr);
2142 dst = jmp_r(dst, SCRATCH1);
2143 }
2144 break;
2145 case MODE_PC_INDEX_DISP8:
2146 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
2147 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
2148 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2149 if (inst->src.params.regs.sec & 1) {
2150 if (inst->src.params.regs.sec & 0x10) {
2151 if (opts->aregs[sec_reg] >= 0) {
2152 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
2153 } else {
2154 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2155 }
2156 } else {
2157 if (opts->dregs[sec_reg] >= 0) {
2158 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
2159 } else {
2160 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2161 }
2162 }
2163 } else {
2164 if (inst->src.params.regs.sec & 0x10) {
2165 if (opts->aregs[sec_reg] >= 0) {
2166 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2167 } else {
2168 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2169 }
2170 } else {
2171 if (opts->dregs[sec_reg] >= 0) {
2172 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2173 } else {
2174 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2175 }
2176 }
2177 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
2178 }
2179 if (inst->src.params.regs.displacement) {
2180 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2181 }
2182 dst = call(dst, opts->native_addr);
2183 dst = jmp_r(dst, SCRATCH1);
2184 break;
2185 case MODE_ABSOLUTE:
2186 case MODE_ABSOLUTE_SHORT:
2187 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
2188 m68k_addr = inst->src.params.immed;
2189 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2190 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2191 if (!dest_addr) {
2192 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2193 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2194 dest_addr = dst + 256;
2195 }
2196 dst = jmp(dst, dest_addr);
2197 } else {
2198 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
2199 dst = call(dst, opts->native_addr);
2200 dst = jmp_r(dst, SCRATCH1);
2201 }
2202 break;
2203 default:
2204 m68k_disasm(inst, disasm_buf);
2205 printf("%s\naddress mode %d not yet supported (jmp)\n", disasm_buf, inst->src.addr_mode);
2206 exit(1);
2207 }
2208 return dst;
2209 }
2210
2211 code_ptr translate_m68k_jsr(code_ptr dst, m68kinst * inst, x86_68k_options * opts)
2212 {
2213 code_ptr dest_addr; 1835 code_ptr dest_addr;
2214 uint8_t sec_reg; 1836 uint8_t sec_reg;
2215 uint32_t after; 1837 uint32_t after;
2216 uint32_t m68k_addr; 1838 uint32_t m68k_addr;
2217 switch(inst->src.addr_mode) 1839 switch(inst->src.addr_mode)
2218 { 1840 {
2219 case MODE_AREG_INDIRECT: 1841 case MODE_AREG_INDIRECT:
2220 dst = cycles(dst, BUS*2); 1842 cycles(&opts->gen, BUS*2);
2221 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D); 1843 if (is_jsr) {
2222 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1844 mov_ir(code, inst->address + 2, opts->gen.scratch1, SZ_D);
2223 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1845 sub_ir(code, 4, opts->aregs[7], SZ_D);
2224 dst = call(dst, opts->write_32_highfirst); 1846 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1847 call(code, opts->write_32_highfirst);
1848 }
2225 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1849 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2226 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1850 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
2227 } else { 1851 } else {
2228 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1852 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D);
2229 } 1853 }
2230 dst = call(dst, opts->native_addr); 1854 call(code, opts->native_addr);
2231 dst = jmp_r(dst, SCRATCH1); 1855 jmp_r(code, opts->gen.scratch1);
2232 break; 1856 break;
2233 case MODE_AREG_DISPLACE: 1857 case MODE_AREG_DISPLACE:
2234 dst = cycles(dst, BUS*2); 1858 cycles(&opts->gen, BUS*2);
2235 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 1859 if (is_jsr) {
2236 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1860 mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D);
2237 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1861 sub_ir(code, 4, opts->aregs[7], SZ_D);
2238 dst = call(dst, opts->write_32_highfirst); 1862 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1863 call(code, opts->write_32_highfirst);
1864 }
2239 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1865 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2240 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1866 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
2241 } else { 1867 } else {
2242 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1868 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D);
2243 } 1869 }
2244 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1870 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
2245 dst = call(dst, opts->native_addr); 1871 call(code, opts->native_addr);
2246 dst = jmp_r(dst, SCRATCH1); 1872 jmp_r(code, opts->gen.scratch1);
2247 break; 1873 break;
2248 case MODE_AREG_INDEX_DISP8: 1874 case MODE_AREG_INDEX_DISP8:
2249 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct 1875 cycles(&opts->gen, BUS*3);//TODO: CHeck that this is correct
2250 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 1876 if (is_jsr) {
2251 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1877 mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D);
2252 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1878 sub_ir(code, 4, opts->aregs[7], SZ_D);
2253 dst = call(dst, opts->write_32_highfirst); 1879 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1880 call(code, opts->write_32_highfirst);
1881 }
2254 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1882 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2255 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1883 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
2256 } else { 1884 } else {
2257 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 1885 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
2258 } 1886 }
1887 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1888 if (inst->src.params.regs.sec & 1) {
1889 //32-bit index register
1890 if (inst->src.params.regs.sec & 0x10) {
1891 if (opts->aregs[sec_reg] >= 0) {
1892 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
1893 } else {
1894 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1895 }
1896 } else {
1897 if (opts->dregs[sec_reg] >= 0) {
1898 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
1899 } else {
1900 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
1901 }
1902 }
1903 } else {
1904 //16-bit index register
1905 if (inst->src.params.regs.sec & 0x10) {
1906 if (opts->aregs[sec_reg] >= 0) {
1907 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1908 } else {
1909 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1910 }
1911 } else {
1912 if (opts->dregs[sec_reg] >= 0) {
1913 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
1914 } else {
1915 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
1916 }
1917 }
1918 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
1919 }
1920 if (inst->src.params.regs.displacement) {
1921 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
1922 }
1923 call(code, opts->native_addr);
1924 jmp_r(code, opts->gen.scratch1);
1925 break;
1926 case MODE_PC_DISPLACE:
1927 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1928 cycles(&opts->gen, 10);
1929 if (is_jsr) {
1930 mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D);
1931 sub_ir(code, 4, opts->aregs[7], SZ_D);
1932 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1933 call(code, opts->write_32_highfirst);
1934 }
1935 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
1936 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
1937 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
1938 if (!dest_addr) {
1939 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, code->cur + 1);
1940 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1941 dest_addr = code->cur + 256;
1942 }
1943 jmp(code, dest_addr);
1944 } else {
1945 mov_ir(code, m68k_addr, opts->gen.scratch1, SZ_D);
1946 call(code, opts->native_addr);
1947 jmp_r(code, opts->gen.scratch1);
1948 }
1949 break;
1950 case MODE_PC_INDEX_DISP8:
1951 cycles(&opts->gen, BUS*3);//TODO: CHeck that this is correct
1952 if (is_jsr) {
1953 mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D);
1954 sub_ir(code, 4, opts->aregs[7], SZ_D);
1955 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
1956 call(code, opts->write_32_highfirst);
1957 }
1958 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
2259 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1959 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2260 if (inst->src.params.regs.sec & 1) { 1960 if (inst->src.params.regs.sec & 1) {
2261 if (inst->src.params.regs.sec & 0x10) { 1961 if (inst->src.params.regs.sec & 0x10) {
2262 if (opts->aregs[sec_reg] >= 0) { 1962 if (opts->aregs[sec_reg] >= 0) {
2263 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); 1963 add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D);
2264 } else { 1964 } else {
2265 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1965 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
2266 } 1966 }
2267 } else { 1967 } else {
2268 if (opts->dregs[sec_reg] >= 0) { 1968 if (opts->dregs[sec_reg] >= 0) {
2269 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); 1969 add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D);
2270 } else { 1970 } else {
2271 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); 1971 add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D);
2272 } 1972 }
2273 } 1973 }
2274 } else { 1974 } else {
2275 if (inst->src.params.regs.sec & 0x10) { 1975 if (inst->src.params.regs.sec & 0x10) {
2276 if (opts->aregs[sec_reg] >= 0) { 1976 if (opts->aregs[sec_reg] >= 0) {
2277 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1977 movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
2278 } else { 1978 } else {
2279 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1979 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
2280 } 1980 }
2281 } else { 1981 } else {
2282 if (opts->dregs[sec_reg] >= 0) { 1982 if (opts->dregs[sec_reg] >= 0) {
2283 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); 1983 movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D);
2284 } else { 1984 } else {
2285 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); 1985 movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D);
2286 } 1986 }
2287 } 1987 }
2288 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 1988 add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
2289 } 1989 }
2290 if (inst->src.params.regs.displacement) { 1990 if (inst->src.params.regs.displacement) {
2291 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1991 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
2292 } 1992 }
2293 dst = call(dst, opts->native_addr); 1993 call(code, opts->native_addr);
2294 dst = jmp_r(dst, SCRATCH1); 1994 jmp_r(code, opts->gen.scratch1);
2295 break;
2296 case MODE_PC_DISPLACE:
2297 //TODO: Add cycles in the right place relative to pushing the return address on the stack
2298 dst = cycles(dst, 10);
2299 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2300 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2301 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2302 dst = call(dst, opts->write_32_highfirst);
2303 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
2304 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2305 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2306 if (!dest_addr) {
2307 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1);
2308 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2309 dest_addr = dst + 256;
2310 }
2311 dst = jmp(dst, dest_addr);
2312 } else {
2313 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
2314 dst = call(dst, opts->native_addr);
2315 dst = jmp_r(dst, SCRATCH1);
2316 }
2317 break;
2318 case MODE_PC_INDEX_DISP8:
2319 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
2320 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
2321 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
2322 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
2323 dst = call(dst, opts->write_32_highfirst);
2324 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
2325 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
2326 if (inst->src.params.regs.sec & 1) {
2327 if (inst->src.params.regs.sec & 0x10) {
2328 if (opts->aregs[sec_reg] >= 0) {
2329 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D);
2330 } else {
2331 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2332 }
2333 } else {
2334 if (opts->dregs[sec_reg] >= 0) {
2335 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D);
2336 } else {
2337 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D);
2338 }
2339 }
2340 } else {
2341 if (inst->src.params.regs.sec & 0x10) {
2342 if (opts->aregs[sec_reg] >= 0) {
2343 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2344 } else {
2345 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2346 }
2347 } else {
2348 if (opts->dregs[sec_reg] >= 0) {
2349 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D);
2350 } else {
2351 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D);
2352 }
2353 }
2354 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D);
2355 }
2356 if (inst->src.params.regs.displacement) {
2357 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
2358 }
2359 dst = call(dst, opts->native_addr);
2360 dst = jmp_r(dst, SCRATCH1);
2361 break; 1995 break;
2362 case MODE_ABSOLUTE: 1996 case MODE_ABSOLUTE:
2363 case MODE_ABSOLUTE_SHORT: 1997 case MODE_ABSOLUTE_SHORT:
2364 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1998 //TODO: Add cycles in the right place relative to pushing the return address on the stack
2365 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 1999 cycles(&opts->gen, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
2366 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D); 2000 if (is_jsr) {
2367 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2001 mov_ir(code, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), opts->gen.scratch1, SZ_D);
2368 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2002 sub_ir(code, 4, opts->aregs[7], SZ_D);
2369 dst = call(dst, opts->write_32_highfirst); 2003 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
2004 call(code, opts->write_32_highfirst);
2005 }
2370 m68k_addr = inst->src.params.immed; 2006 m68k_addr = inst->src.params.immed;
2371 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 2007 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
2372 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr); 2008 dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr);
2373 if (!dest_addr) { 2009 if (!dest_addr) {
2374 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, dst + 1); 2010 opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, code->cur + 1);
2375 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2011 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2376 dest_addr = dst + 256; 2012 dest_addr = code->cur + 256;
2377 } 2013 }
2378 dst = jmp(dst, dest_addr); 2014 jmp(code, dest_addr);
2379 } else { 2015 } else {
2380 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 2016 mov_ir(code, m68k_addr, opts->gen.scratch1, SZ_D);
2381 dst = call(dst, opts->native_addr); 2017 call(code, opts->native_addr);
2382 dst = jmp_r(dst, SCRATCH1); 2018 jmp_r(code, opts->gen.scratch1);
2383 } 2019 }
2384 break; 2020 break;
2385 default: 2021 default:
2386 m68k_disasm(inst, disasm_buf); 2022 m68k_disasm(inst, disasm_buf);
2387 printf("%s\naddress mode %d not yet supported (jsr)\n", disasm_buf, inst->src.addr_mode); 2023 printf("%s\naddress mode %d not yet supported (%s)\n", disasm_buf, inst->src.addr_mode, is_jsr ? "jsr" : "jmp");
2388 exit(1); 2024 exit(1);
2389 } 2025 }
2390 return dst; 2026 }
2391 } 2027
2392 2028 void translate_m68k_rts(x86_68k_options * opts, m68kinst * inst)
2393 code_ptr translate_m68k_rts(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2029 {
2394 { 2030 code_info *code = &opts->gen.code;
2395 //TODO: Add cycles 2031 //TODO: Add cycles
2396 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 2032 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
2397 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 2033 add_ir(code, 4, opts->aregs[7], SZ_D);
2398 dst = call(dst, opts->read_32); 2034 call(code, opts->read_32);
2399 dst = call(dst, opts->native_addr); 2035 call(code, opts->native_addr);
2400 dst = jmp_r(dst, SCRATCH1); 2036 jmp_r(code, opts->gen.scratch1);
2401 return dst; 2037 }
2402 } 2038
2403 2039 void translate_m68k_dbcc(x86_68k_options * opts, m68kinst * inst)
2404 code_ptr translate_m68k_dbcc(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2040 {
2405 { 2041 code_info *code = &opts->gen.code;
2406 //best case duration 2042 //best case duration
2407 dst = cycles(dst, 10); 2043 cycles(&opts->gen, 10);
2408 code_ptr skip_loc = NULL; 2044 code_ptr skip_loc = NULL;
2409 //TODO: Check if COND_TRUE technically valid here even though 2045 //TODO: Check if COND_TRUE technically valid here even though
2410 //it's basically a slow NOP 2046 //it's basically a slow NOP
2411 if (inst->extra.cond != COND_FALSE) { 2047 if (inst->extra.cond != COND_FALSE) {
2412 uint8_t cond = CC_NZ; 2048 uint8_t cond = m68k_eval_cond(opts, inst->extra.cond);
2413 switch (inst->extra.cond) 2049 check_alloc_code(code, 6*MAX_INST_LEN);
2414 { 2050 skip_loc = code->cur + 1;
2415 case COND_HIGH: 2051 jcc(code, cond, code->cur + 2);
2416 cond = CC_Z;
2417 case COND_LOW_SAME:
2418 dst = flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2419 dst = or_flag_to_reg(dst, FLAG_C, SCRATCH1, opts);
2420 break;
2421 case COND_CARRY_CLR:
2422 cond = CC_Z;
2423 case COND_CARRY_SET:
2424 dst = check_flag(dst, FLAG_C, opts);
2425 break;
2426 case COND_NOT_EQ:
2427 cond = CC_Z;
2428 case COND_EQ:
2429 dst = check_flag(dst, FLAG_Z, opts);
2430 break;
2431 case COND_OVERF_CLR:
2432 cond = CC_Z;
2433 case COND_OVERF_SET:
2434 dst = check_flag(dst, FLAG_V, opts);
2435 break;
2436 case COND_PLUS:
2437 cond = CC_Z;
2438 case COND_MINUS:
2439 dst = check_flag(dst, FLAG_N, opts);
2440 break;
2441 case COND_GREATER_EQ:
2442 cond = CC_Z;
2443 case COND_LESS:
2444 dst = cmp_flags(dst, FLAG_N, FLAG_V, opts);
2445 break;
2446 case COND_GREATER:
2447 cond = CC_Z;
2448 case COND_LESS_EQ:
2449 dst = flag_to_reg(dst, FLAG_V, SCRATCH1, opts);
2450 dst = xor_flag_to_reg(dst, FLAG_N, SCRATCH1, opts);
2451 dst = or_flag_to_reg(dst, FLAG_Z, SCRATCH1, opts);
2452 break;
2453 }
2454 skip_loc = dst + 1;
2455 dst = jcc(dst, cond, dst + 2);
2456 } 2052 }
2457 if (opts->dregs[inst->dst.params.regs.pri] >= 0) { 2053 if (opts->dregs[inst->dst.params.regs.pri] >= 0) {
2458 dst = sub_ir(dst, 1, opts->dregs[inst->dst.params.regs.pri], SZ_W); 2054 sub_ir(code, 1, opts->dregs[inst->dst.params.regs.pri], SZ_W);
2459 dst = cmp_ir(dst, -1, opts->dregs[inst->dst.params.regs.pri], SZ_W); 2055 cmp_ir(code, -1, opts->dregs[inst->dst.params.regs.pri], SZ_W);
2460 } else { 2056 } else {
2461 dst = sub_irdisp8(dst, 1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W); 2057 sub_irdisp(code, 1, opts->gen.context_reg, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W);
2462 dst = cmp_irdisp8(dst, -1, CONTEXT, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W); 2058 cmp_irdisp(code, -1, opts->gen.context_reg, offsetof(m68k_context, dregs) + 4 * inst->dst.params.regs.pri, SZ_W);
2463 } 2059 }
2464 code_ptr loop_end_loc = dst+1; 2060 code_ptr loop_end_loc = code->cur + 1;
2465 dst = jcc(dst, CC_Z, dst+2); 2061 jcc(code, CC_Z, code->cur + 2);
2466 uint32_t after = inst->address + 2; 2062 uint32_t after = inst->address + 2;
2467 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + inst->src.params.immed); 2063 code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + inst->src.params.immed);
2468 if (!dest_addr) { 2064 if (!dest_addr) {
2469 opts->gen.deferred = defer_address(opts->gen.deferred, after + inst->src.params.immed, dst + 1); 2065 opts->gen.deferred = defer_address(opts->gen.deferred, after + inst->src.params.immed, code->cur + 1);
2470 //dummy address to be replaced later, make sure it generates a 4-byte displacement 2066 //dummy address to be replaced later, make sure it generates a 4-byte displacement
2471 dest_addr = dst + 256; 2067 dest_addr = code->cur + 256;
2472 } 2068 }
2473 dst = jmp(dst, dest_addr); 2069 jmp(code, dest_addr);
2474 *loop_end_loc = dst - (loop_end_loc+1); 2070 *loop_end_loc = code->cur - (loop_end_loc+1);
2475 if (skip_loc) { 2071 if (skip_loc) {
2476 dst = cycles(dst, 2); 2072 cycles(&opts->gen, 2);
2477 *skip_loc = dst - (skip_loc+1); 2073 *skip_loc = code->cur - (skip_loc+1);
2478 dst = cycles(dst, 2); 2074 cycles(&opts->gen, 2);
2479 } else { 2075 } else {
2480 dst = cycles(dst, 4); 2076 cycles(&opts->gen, 4);
2481 } 2077 }
2482 return dst; 2078 }
2483 } 2079
2484 2080 void translate_m68k_link(x86_68k_options * opts, m68kinst * inst)
2485 code_ptr translate_m68k_link(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2081 {
2486 { 2082 code_info *code = &opts->gen.code;
2487 int8_t reg = native_reg(&(inst->src), opts); 2083 int8_t reg = native_reg(&(inst->src), opts);
2488 //compensate for displacement word 2084 //compensate for displacement word
2489 dst = cycles(dst, BUS); 2085 cycles(&opts->gen, BUS);
2490 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 2086 sub_ir(code, 4, opts->aregs[7], SZ_D);
2491 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 2087 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
2492 if (reg >= 0) { 2088 if (reg >= 0) {
2493 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2089 mov_rr(code, reg, opts->gen.scratch1, SZ_D);
2494 } else { 2090 } else {
2495 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 2091 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
2496 } 2092 }
2497 dst = call(dst, opts->write_32_highfirst); 2093 call(code, opts->write_32_highfirst);
2498 if (reg >= 0) { 2094 if (reg >= 0) {
2499 dst = mov_rr(dst, opts->aregs[7], reg, SZ_D); 2095 mov_rr(code, opts->aregs[7], reg, SZ_D);
2500 } else { 2096 } else {
2501 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, reg_offset(&(inst->src)), SZ_D); 2097 mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D);
2502 } 2098 }
2503 dst = add_ir(dst, inst->dst.params.immed, opts->aregs[7], SZ_D); 2099 add_ir(code, inst->dst.params.immed, opts->aregs[7], SZ_D);
2504 //prefetch 2100 //prefetch
2505 dst = cycles(dst, BUS); 2101 cycles(&opts->gen, BUS);
2506 return dst; 2102 }
2507 } 2103
2508 2104 void translate_m68k_movep(x86_68k_options * opts, m68kinst * inst)
2509 code_ptr translate_m68k_movep(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2105 {
2510 { 2106 code_info *code = &opts->gen.code;
2511 int8_t reg; 2107 int8_t reg;
2512 dst = cycles(dst, BUS*2); 2108 cycles(&opts->gen, BUS*2);
2513 if (inst->src.addr_mode == MODE_REG) { 2109 if (inst->src.addr_mode == MODE_REG) {
2514 if (opts->aregs[inst->dst.params.regs.pri] >= 0) { 2110 if (opts->aregs[inst->dst.params.regs.pri] >= 0) {
2515 dst = mov_rr(dst, opts->aregs[inst->dst.params.regs.pri], SCRATCH2, SZ_D); 2111 mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D);
2516 } else { 2112 } else {
2517 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->dst)), SCRATCH2, SZ_D); 2113 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D);
2518 } 2114 }
2519 if (inst->dst.params.regs.displacement) { 2115 if (inst->dst.params.regs.displacement) {
2520 dst = add_ir(dst, inst->dst.params.regs.displacement, SCRATCH2, SZ_D); 2116 add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D);
2521 } 2117 }
2522 reg = native_reg(&(inst->src), opts); 2118 reg = native_reg(&(inst->src), opts);
2523 if (inst->extra.size == OPSIZE_LONG) { 2119 if (inst->extra.size == OPSIZE_LONG) {
2524 if (reg >= 0) { 2120 if (reg >= 0) {
2525 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2121 mov_rr(code, reg, opts->gen.scratch1, SZ_D);
2526 dst = shr_ir(dst, 24, SCRATCH1, SZ_D); 2122 shr_ir(code, 24, opts->gen.scratch1, SZ_D);
2527 dst = push_r(dst, SCRATCH2); 2123 push_r(code, opts->gen.scratch2);
2528 dst = call(dst, opts->write_8); 2124 call(code, opts->write_8);
2529 dst = pop_r(dst, SCRATCH2); 2125 pop_r(code, opts->gen.scratch2);
2530 dst = mov_rr(dst, reg, SCRATCH1, SZ_D); 2126 mov_rr(code, reg, opts->gen.scratch1, SZ_D);
2531 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 2127 shr_ir(code, 16, opts->gen.scratch1, SZ_D);
2532 2128
2533 } else { 2129 } else {
2534 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+3, SCRATCH1, SZ_B); 2130 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src))+3, opts->gen.scratch1, SZ_B);
2535 dst = push_r(dst, SCRATCH2); 2131 push_r(code, opts->gen.scratch2);
2536 dst = call(dst, opts->write_8); 2132 call(code, opts->write_8);
2537 dst = pop_r(dst, SCRATCH2); 2133 pop_r(code, opts->gen.scratch2);
2538 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+2, SCRATCH1, SZ_B); 2134 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src))+2, opts->gen.scratch1, SZ_B);
2539 } 2135 }
2540 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2136 add_ir(code, 2, opts->gen.scratch2, SZ_D);
2541 dst = push_r(dst, SCRATCH2); 2137 push_r(code, opts->gen.scratch2);
2542 dst = call(dst, opts->write_8); 2138 call(code, opts->write_8);
2543 dst = pop_r(dst, SCRATCH2); 2139 pop_r(code, opts->gen.scratch2);
2544 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2140 add_ir(code, 2, opts->gen.scratch2, SZ_D);
2545 } 2141 }
2546 if (reg >= 0) { 2142 if (reg >= 0) {
2547 dst = mov_rr(dst, reg, SCRATCH1, SZ_W); 2143 mov_rr(code, reg, opts->gen.scratch1, SZ_W);
2548 dst = shr_ir(dst, 8, SCRATCH1, SZ_W); 2144 shr_ir(code, 8, opts->gen.scratch1, SZ_W);
2549 dst = push_r(dst, SCRATCH2); 2145 push_r(code, opts->gen.scratch2);
2550 dst = call(dst, opts->write_8); 2146 call(code, opts->write_8);
2551 dst = pop_r(dst, SCRATCH2); 2147 pop_r(code, opts->gen.scratch2);
2552 dst = mov_rr(dst, reg, SCRATCH1, SZ_W); 2148 mov_rr(code, reg, opts->gen.scratch1, SZ_W);
2553 } else { 2149 } else {
2554 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src))+1, SCRATCH1, SZ_B); 2150 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src))+1, opts->gen.scratch1, SZ_B);
2555 dst = push_r(dst, SCRATCH2); 2151 push_r(code, opts->gen.scratch2);
2556 dst = call(dst, opts->write_8); 2152 call(code, opts->write_8);
2557 dst = pop_r(dst, SCRATCH2); 2153 pop_r(code, opts->gen.scratch2);
2558 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_B); 2154 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_B);
2559 } 2155 }
2560 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 2156 add_ir(code, 2, opts->gen.scratch2, SZ_D);
2561 dst = call(dst, opts->write_8); 2157 call(code, opts->write_8);
2562 } else { 2158 } else {
2563 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 2159 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
2564 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 2160 mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D);
2565 } else { 2161 } else {
2566 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); 2162 mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D);
2567 } 2163 }
2568 if (inst->src.params.regs.displacement) { 2164 if (inst->src.params.regs.displacement) {
2569 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 2165 add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D);
2570 } 2166 }
2571 reg = native_reg(&(inst->dst), opts); 2167 reg = native_reg(&(inst->dst), opts);
2572 if (inst->extra.size == OPSIZE_LONG) { 2168 if (inst->extra.size == OPSIZE_LONG) {
2573 if (reg >= 0) { 2169 if (reg >= 0) {
2574 dst = push_r(dst, SCRATCH1); 2170 push_r(code, opts->gen.scratch1);
2575 dst = call(dst, opts->read_8); 2171 call(code, opts->read_8);
2576 dst = shl_ir(dst, 24, SCRATCH1, SZ_D); 2172 shl_ir(code, 24, opts->gen.scratch1, SZ_D);
2577 dst = mov_rr(dst, SCRATCH1, reg, SZ_D); 2173 mov_rr(code, opts->gen.scratch1, reg, SZ_D);
2578 dst = pop_r(dst, SCRATCH1); 2174 pop_r(code, opts->gen.scratch1);
2579 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2175 add_ir(code, 2, opts->gen.scratch1, SZ_D);
2580 dst = push_r(dst, SCRATCH1); 2176 push_r(code, opts->gen.scratch1);
2581 dst = call(dst, opts->read_8); 2177 call(code, opts->read_8);
2582 dst = shl_ir(dst, 16, SCRATCH1, SZ_D); 2178 shl_ir(code, 16, opts->gen.scratch1, SZ_D);
2583 dst = or_rr(dst, SCRATCH1, reg, SZ_D); 2179 or_rr(code, opts->gen.scratch1, reg, SZ_D);
2584 } else { 2180 } else {
2585 dst = push_r(dst, SCRATCH1); 2181 push_r(code, opts->gen.scratch1);
2586 dst = call(dst, opts->read_8); 2182 call(code, opts->read_8);
2587 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+3, SZ_B); 2183 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst))+3, SZ_B);
2588 dst = pop_r(dst, SCRATCH1); 2184 pop_r(code, opts->gen.scratch1);
2589 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2185 add_ir(code, 2, opts->gen.scratch1, SZ_D);
2590 dst = push_r(dst, SCRATCH1); 2186 push_r(code, opts->gen.scratch1);
2591 dst = call(dst, opts->read_8); 2187 call(code, opts->read_8);
2592 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+2, SZ_B); 2188 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst))+2, SZ_B);
2593 } 2189 }
2594 dst = pop_r(dst, SCRATCH1); 2190 pop_r(code, opts->gen.scratch1);
2595 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2191 add_ir(code, 2, opts->gen.scratch1, SZ_D);
2596 } 2192 }
2597 dst = push_r(dst, SCRATCH1); 2193 push_r(code, opts->gen.scratch1);
2598 dst = call(dst, opts->read_8); 2194 call(code, opts->read_8);
2599 if (reg >= 0) { 2195 if (reg >= 0) {
2600 2196
2601 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); 2197 shl_ir(code, 8, opts->gen.scratch1, SZ_W);
2602 dst = mov_rr(dst, SCRATCH1, reg, SZ_W); 2198 mov_rr(code, opts->gen.scratch1, reg, SZ_W);
2603 dst = pop_r(dst, SCRATCH1); 2199 pop_r(code, opts->gen.scratch1);
2604 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2200 add_ir(code, 2, opts->gen.scratch1, SZ_D);
2605 dst = call(dst, opts->read_8); 2201 call(code, opts->read_8);
2606 dst = mov_rr(dst, SCRATCH1, reg, SZ_B); 2202 mov_rr(code, opts->gen.scratch1, reg, SZ_B);
2607 } else { 2203 } else {
2608 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst))+1, SZ_B); 2204 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst))+1, SZ_B);
2609 dst = pop_r(dst, SCRATCH1); 2205 pop_r(code, opts->gen.scratch1);
2610 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 2206 add_ir(code, 2, opts->gen.scratch1, SZ_D);
2611 dst = call(dst, opts->read_8); 2207 call(code, opts->read_8);
2612 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, reg_offset(&(inst->dst)), SZ_B); 2208 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_B);
2613 } 2209 }
2614 } 2210 }
2615 return dst; 2211 }
2616 } 2212
2617 2213 void translate_m68k_cmp(x86_68k_options * opts, m68kinst * inst)
2618 code_ptr translate_m68k_cmp(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2214 {
2619 { 2215 code_info *code = &opts->gen.code;
2620 uint8_t size = inst->extra.size; 2216 uint8_t size = inst->extra.size;
2621 x86_ea src_op, dst_op; 2217 x86_ea src_op, dst_op;
2622 dst = translate_m68k_src(inst, &src_op, dst, opts); 2218 translate_m68k_src(inst, &src_op, opts);
2623 if (inst->dst.addr_mode == MODE_AREG_POSTINC) { 2219 if (inst->dst.addr_mode == MODE_AREG_POSTINC) {
2624 dst = push_r(dst, SCRATCH1); 2220 push_r(code, opts->gen.scratch1);
2625 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); 2221 translate_m68k_dst(inst, &dst_op, opts, 0);
2626 dst = pop_r(dst, SCRATCH2); 2222 pop_r(code, opts->gen.scratch2);
2627 src_op.base = SCRATCH2; 2223 src_op.base = opts->gen.scratch2;
2628 } else { 2224 } else {
2629 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); 2225 translate_m68k_dst(inst, &dst_op, opts, 0);
2630 if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) { 2226 if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) {
2631 size = OPSIZE_LONG; 2227 size = OPSIZE_LONG;
2632 } 2228 }
2633 } 2229 }
2634 dst = cycles(dst, BUS); 2230 cycles(&opts->gen, BUS);
2635 if (src_op.mode == MODE_REG_DIRECT) { 2231 if (src_op.mode == MODE_REG_DIRECT) {
2636 if (dst_op.mode == MODE_REG_DIRECT) { 2232 if (dst_op.mode == MODE_REG_DIRECT) {
2637 dst = cmp_rr(dst, src_op.base, dst_op.base, size); 2233 cmp_rr(code, src_op.base, dst_op.base, size);
2638 } else { 2234 } else {
2639 dst = cmp_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2235 cmp_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
2640 } 2236 }
2641 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2237 } else if (src_op.mode == MODE_REG_DISPLACE8) {
2642 dst = cmp_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); 2238 cmp_rdispr(code, src_op.base, src_op.disp, dst_op.base, size);
2643 } else { 2239 } else {
2644 if (dst_op.mode == MODE_REG_DIRECT) { 2240 if (dst_op.mode == MODE_REG_DIRECT) {
2645 dst = cmp_ir(dst, src_op.disp, dst_op.base, size); 2241 cmp_ir(code, src_op.disp, dst_op.base, size);
2646 } else { 2242 } else {
2647 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 2243 cmp_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
2648 } 2244 }
2649 } 2245 }
2650 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2246 set_flag_cond(opts, CC_C, FLAG_C);
2651 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2247 set_flag_cond(opts, CC_Z, FLAG_Z);
2652 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2248 set_flag_cond(opts, CC_S, FLAG_N);
2653 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2249 set_flag_cond(opts, CC_O, FLAG_V);
2654 return dst; 2250 }
2655 } 2251
2656 2252 typedef void (*shift_ir_t)(code_info *code, uint8_t val, uint8_t dst, uint8_t size);
2657 typedef code_ptr (*shift_ir_t)(code_ptr out, uint8_t val, uint8_t dst, uint8_t size); 2253 typedef void (*shift_irdisp_t)(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size);
2658 typedef code_ptr (*shift_irdisp8_t)(code_ptr out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size); 2254 typedef void (*shift_clr_t)(code_info *code, uint8_t dst, uint8_t size);
2659 typedef code_ptr (*shift_clr_t)(code_ptr out, uint8_t dst, uint8_t size); 2255 typedef void (*shift_clrdisp_t)(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size);
2660 typedef code_ptr (*shift_clrdisp8_t)(code_ptr out, uint8_t dst_base, int8_t disp, uint8_t size); 2256
2661 2257 void translate_shift(x86_68k_options * opts, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, shift_ir_t shift_ir, shift_irdisp_t shift_irdisp, shift_clr_t shift_clr, shift_clrdisp_t shift_clrdisp, shift_ir_t special, shift_irdisp_t special_disp)
2662 code_ptr translate_shift(code_ptr dst, m68kinst * inst, x86_ea *src_op, x86_ea * dst_op, x86_68k_options * opts, shift_ir_t shift_ir, shift_irdisp8_t shift_irdisp8, shift_clr_t shift_clr, shift_clrdisp8_t shift_clrdisp8, shift_ir_t special, shift_irdisp8_t special_disp8) 2258 {
2663 { 2259 code_info *code = &opts->gen.code;
2664 code_ptr end_off = NULL; 2260 code_ptr end_off = NULL;
2665 code_ptr nz_off = NULL; 2261 code_ptr nz_off = NULL;
2666 code_ptr z_off = NULL; 2262 code_ptr z_off = NULL;
2667 if (inst->src.addr_mode == MODE_UNUSED) { 2263 if (inst->src.addr_mode == MODE_UNUSED) {
2668 dst = cycles(dst, BUS); 2264 cycles(&opts->gen, BUS);
2669 //Memory shift 2265 //Memory shift
2670 dst = shift_ir(dst, 1, dst_op->base, SZ_W); 2266 shift_ir(code, 1, dst_op->base, SZ_W);
2671 } else { 2267 } else {
2672 dst = cycles(dst, inst->extra.size == OPSIZE_LONG ? 8 : 6); 2268 cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6);
2673 if (src_op->mode == MODE_IMMED) { 2269 if (src_op->mode == MODE_IMMED) {
2674 if (src_op->disp != 1 && inst->op == M68K_ASL) { 2270 if (src_op->disp != 1 && inst->op == M68K_ASL) {
2675 dst = set_flag(dst, 0, FLAG_V, opts); 2271 set_flag(opts, 0, FLAG_V);
2676 for (int i = 0; i < src_op->disp; i++) { 2272 for (int i = 0; i < src_op->disp; i++) {
2677 if (dst_op->mode == MODE_REG_DIRECT) { 2273 if (dst_op->mode == MODE_REG_DIRECT) {
2678 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2274 shift_ir(code, 1, dst_op->base, inst->extra.size);
2679 } else { 2275 } else {
2680 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2276 shift_irdisp(code, 1, dst_op->base, dst_op->disp, inst->extra.size);
2681 } 2277 }
2682 //dst = setcc_r(dst, CC_O, FLAG_V); 2278 check_alloc_code(code, 2*MAX_INST_LEN);
2683 code_ptr after_flag_set = dst+1; 2279 code_ptr after_flag_set = code->cur + 1;
2684 dst = jcc(dst, CC_NO, dst+2); 2280 jcc(code, CC_NO, code->cur + 2);
2685 dst = set_flag(dst, 1, FLAG_V, opts); 2281 set_flag(opts, 1, FLAG_V);
2686 *after_flag_set = dst - (after_flag_set+1); 2282 *after_flag_set = code->cur - (after_flag_set+1);
2687 } 2283 }
2688 } else { 2284 } else {
2689 if (dst_op->mode == MODE_REG_DIRECT) { 2285 if (dst_op->mode == MODE_REG_DIRECT) {
2690 dst = shift_ir(dst, src_op->disp, dst_op->base, inst->extra.size); 2286 shift_ir(code, src_op->disp, dst_op->base, inst->extra.size);
2691 } else { 2287 } else {
2692 dst = shift_irdisp8(dst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); 2288 shift_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size);
2693 } 2289 }
2694 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2290 set_flag_cond(opts, CC_O, FLAG_V);
2695 } 2291 }
2696 } else { 2292 } else {
2697 if (src_op->base != RCX) { 2293 if (src_op->base != RCX) {
2698 if (src_op->mode == MODE_REG_DIRECT) { 2294 if (src_op->mode == MODE_REG_DIRECT) {
2699 dst = mov_rr(dst, src_op->base, RCX, SZ_B); 2295 mov_rr(code, src_op->base, RCX, SZ_B);
2700 } else { 2296 } else {
2701 dst = mov_rdisp8r(dst, src_op->base, src_op->disp, RCX, SZ_B); 2297 mov_rdispr(code, src_op->base, src_op->disp, RCX, SZ_B);
2702 } 2298 }
2703 2299
2704 } 2300 }
2705 dst = and_ir(dst, 63, RCX, SZ_D); 2301 and_ir(code, 63, RCX, SZ_D);
2706 nz_off = dst+1; 2302 check_alloc_code(code, 7*MAX_INST_LEN);
2707 dst = jcc(dst, CC_NZ, dst+2); 2303 nz_off = code->cur + 1;
2304 jcc(code, CC_NZ, code->cur + 2);
2708 //Flag behavior for shift count of 0 is different for x86 than 68K 2305 //Flag behavior for shift count of 0 is different for x86 than 68K
2709 if (dst_op->mode == MODE_REG_DIRECT) { 2306 if (dst_op->mode == MODE_REG_DIRECT) {
2710 dst = cmp_ir(dst, 0, dst_op->base, inst->extra.size); 2307 cmp_ir(code, 0, dst_op->base, inst->extra.size);
2711 } else { 2308 } else {
2712 dst = cmp_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size); 2309 cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size);
2713 } 2310 }
2714 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2311 set_flag_cond(opts, CC_Z, FLAG_Z);
2715 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2312 set_flag_cond(opts, CC_S, FLAG_N);
2716 dst = set_flag(dst, 0, FLAG_C, opts); 2313 set_flag(opts, 0, FLAG_C);
2717 //For other instructions, this flag will be set below 2314 //For other instructions, this flag will be set below
2718 if (inst->op == M68K_ASL) { 2315 if (inst->op == M68K_ASL) {
2719 dst = set_flag(dst, 0, FLAG_V, opts); 2316 set_flag(opts, 0, FLAG_V);
2720 } 2317 }
2721 z_off = dst+1; 2318 z_off = code->cur + 1;
2722 dst = jmp(dst, dst+2); 2319 jmp(code, code->cur + 2);
2723 *nz_off = dst - (nz_off + 1); 2320 *nz_off = code->cur - (nz_off + 1);
2724 //add 2 cycles for every bit shifted 2321 //add 2 cycles for every bit shifted
2725 dst = add_rr(dst, RCX, CYCLES, SZ_D); 2322 add_rr(code, RCX, CYCLES, SZ_D);
2726 dst = add_rr(dst, RCX, CYCLES, SZ_D); 2323 add_rr(code, RCX, CYCLES, SZ_D);
2727 if (inst->op == M68K_ASL) { 2324 if (inst->op == M68K_ASL) {
2728 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB 2325 //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB
2729 //Easiest way to deal with this is to shift one bit at a time 2326 //Easiest way to deal with this is to shift one bit at a time
2730 dst = set_flag(dst, 0, FLAG_V, opts); 2327 set_flag(opts, 0, FLAG_V);
2731 code_ptr loop_start = dst; 2328 check_alloc_code(code, 5*MAX_INST_LEN);
2329 code_ptr loop_start = code->cur;
2732 if (dst_op->mode == MODE_REG_DIRECT) { 2330 if (dst_op->mode == MODE_REG_DIRECT) {
2733 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2331 shift_ir(code, 1, dst_op->base, inst->extra.size);
2734 } else { 2332 } else {
2735 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2333 shift_irdisp(code, 1, dst_op->base, dst_op->disp, inst->extra.size);
2736 } 2334 }
2737 //dst = setcc_r(dst, CC_O, FLAG_V); 2335 code_ptr after_flag_set = code->cur + 1;
2738 code_ptr after_flag_set = dst+1; 2336 jcc(code, CC_NO, code->cur + 2);
2739 dst = jcc(dst, CC_NO, dst+2); 2337 set_flag(opts, 1, FLAG_V);
2740 dst = set_flag(dst, 1, FLAG_V, opts); 2338 *after_flag_set = code->cur - (after_flag_set+1);
2741 *after_flag_set = dst - (after_flag_set+1); 2339 loop(code, loop_start);
2742 dst = loop(dst, loop_start);
2743 } else { 2340 } else {
2744 //x86 shifts modulo 32 for operand sizes less than 64-bits 2341 //x86 shifts modulo 32 for operand sizes less than 64-bits
2745 //but M68K shifts modulo 64, so we need to check for large shifts here 2342 //but M68K shifts modulo 64, so we need to check for large shifts here
2746 dst = cmp_ir(dst, 32, RCX, SZ_B); 2343 cmp_ir(code, 32, RCX, SZ_B);
2747 code_ptr norm_shift_off = dst + 1; 2344 check_alloc_code(code, 14*MAX_INST_LEN);
2748 dst = jcc(dst, CC_L, dst+2); 2345 code_ptr norm_shift_off = code->cur + 1;
2346 jcc(code, CC_L, code->cur + 2);
2749 if (special) { 2347 if (special) {
2750 code_ptr after_flag_set = NULL; 2348 code_ptr after_flag_set = NULL;
2751 if (inst->extra.size == OPSIZE_LONG) { 2349 if (inst->extra.size == OPSIZE_LONG) {
2752 code_ptr neq_32_off = dst + 1; 2350 code_ptr neq_32_off = code->cur + 1;
2753 dst = jcc(dst, CC_NZ, dst+2); 2351 jcc(code, CC_NZ, code->cur + 2);
2754 2352
2755 //set the carry bit to the lsb 2353 //set the carry bit to the lsb
2756 if (dst_op->mode == MODE_REG_DIRECT) { 2354 if (dst_op->mode == MODE_REG_DIRECT) {
2757 dst = special(dst, 1, dst_op->base, SZ_D); 2355 special(code, 1, dst_op->base, SZ_D);
2758 } else { 2356 } else {
2759 dst = special_disp8(dst, 1, dst_op->base, dst_op->disp, SZ_D); 2357 special_disp(code, 1, dst_op->base, dst_op->disp, SZ_D);
2760 } 2358 }
2761 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2359 set_flag_cond(opts, CC_C, FLAG_C);
2762 after_flag_set = dst+1; 2360 after_flag_set = code->cur + 1;
2763 dst = jmp(dst, dst+2); 2361 jmp(code, code->cur + 2);
2764 *neq_32_off = dst - (neq_32_off+1); 2362 *neq_32_off = code->cur - (neq_32_off+1);
2765 } 2363 }
2766 dst = set_flag(dst, 0, FLAG_C, opts); 2364 set_flag(opts, 0, FLAG_C);
2767 if (after_flag_set) { 2365 if (after_flag_set) {
2768 *after_flag_set = dst - (after_flag_set+1); 2366 *after_flag_set = code->cur - (after_flag_set+1);
2769 } 2367 }
2770 dst = set_flag(dst, 1, FLAG_Z, opts); 2368 set_flag(opts, 1, FLAG_Z);
2771 dst = set_flag(dst, 0, FLAG_N, opts); 2369 set_flag(opts, 0, FLAG_N);
2772 if (dst_op->mode == MODE_REG_DIRECT) { 2370 if (dst_op->mode == MODE_REG_DIRECT) {
2773 dst = xor_rr(dst, dst_op->base, dst_op->base, inst->extra.size); 2371 xor_rr(code, dst_op->base, dst_op->base, inst->extra.size);
2774 } else { 2372 } else {
2775 dst = mov_irdisp8(dst, 0, dst_op->base, dst_op->disp, inst->extra.size); 2373 mov_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size);
2776 } 2374 }
2777 } else { 2375 } else {
2778 if (dst_op->mode == MODE_REG_DIRECT) { 2376 if (dst_op->mode == MODE_REG_DIRECT) {
2779 dst = shift_ir(dst, 31, dst_op->base, inst->extra.size); 2377 shift_ir(code, 31, dst_op->base, inst->extra.size);
2780 dst = shift_ir(dst, 1, dst_op->base, inst->extra.size); 2378 shift_ir(code, 1, dst_op->base, inst->extra.size);
2781 } else { 2379 } else {
2782 dst = shift_irdisp8(dst, 31, dst_op->base, dst_op->disp, inst->extra.size); 2380 shift_irdisp(code, 31, dst_op->base, dst_op->disp, inst->extra.size);
2783 dst = shift_irdisp8(dst, 1, dst_op->base, dst_op->disp, inst->extra.size); 2381 shift_irdisp(code, 1, dst_op->base, dst_op->disp, inst->extra.size);
2784 } 2382 }
2785 2383
2786 } 2384 }
2787 end_off = dst+1; 2385 end_off = code->cur + 1;
2788 dst = jmp(dst, dst+2); 2386 jmp(code, code->cur + 2);
2789 *norm_shift_off = dst - (norm_shift_off+1); 2387 *norm_shift_off = code->cur - (norm_shift_off+1);
2790 if (dst_op->mode == MODE_REG_DIRECT) { 2388 if (dst_op->mode == MODE_REG_DIRECT) {
2791 dst = shift_clr(dst, dst_op->base, inst->extra.size); 2389 shift_clr(code, dst_op->base, inst->extra.size);
2792 } else { 2390 } else {
2793 dst = shift_clrdisp8(dst, dst_op->base, dst_op->disp, inst->extra.size); 2391 shift_clrdisp(code, dst_op->base, dst_op->disp, inst->extra.size);
2794 } 2392 }
2795 } 2393 }
2796 } 2394 }
2797 2395
2798 } 2396 }
2799 if (!special && end_off) { 2397 if (!special && end_off) {
2800 *end_off = dst - (end_off + 1); 2398 *end_off = code->cur - (end_off + 1);
2801 } 2399 }
2802 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2400 set_flag_cond(opts, CC_C, FLAG_C);
2803 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2401 set_flag_cond(opts, CC_Z, FLAG_Z);
2804 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2402 set_flag_cond(opts, CC_S, FLAG_N);
2805 if (special && end_off) { 2403 if (special && end_off) {
2806 *end_off = dst - (end_off + 1); 2404 *end_off = code->cur - (end_off + 1);
2807 } 2405 }
2808 //set X flag to same as C flag 2406 //set X flag to same as C flag
2809 if (opts->flag_regs[FLAG_C] >= 0) { 2407 if (opts->flag_regs[FLAG_C] >= 0) {
2810 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 2408 flag_to_flag(opts, FLAG_C, FLAG_X);
2811 } else { 2409 } else {
2812 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 2410 set_flag_cond(opts, CC_C, FLAG_X);
2813 } 2411 }
2814 if (z_off) { 2412 if (z_off) {
2815 *z_off = dst - (z_off + 1); 2413 *z_off = code->cur - (z_off + 1);
2816 } 2414 }
2817 if (inst->op != M68K_ASL) { 2415 if (inst->op != M68K_ASL) {
2818 dst = set_flag(dst, 0, FLAG_V, opts); 2416 set_flag(opts, 0, FLAG_V);
2819 } 2417 }
2820 if (inst->src.addr_mode == MODE_UNUSED) { 2418 if (inst->src.addr_mode == MODE_UNUSED) {
2821 dst = m68k_save_result(inst, dst, opts); 2419 m68k_save_result(inst, opts);
2822 } 2420 }
2823 return dst;
2824 } 2421 }
2825 2422
2826 #define BIT_SUPERVISOR 5 2423 #define BIT_SUPERVISOR 5
2827 2424
2828 code_ptr translate_m68k(code_ptr dst, m68kinst * inst, x86_68k_options * opts) 2425 void translate_m68k(x86_68k_options * opts, m68kinst * inst)
2829 { 2426 {
2830 code_ptr end_off, zero_off, norm_off; 2427 code_ptr end_off, zero_off, norm_off;
2831 uint8_t dst_reg; 2428 uint8_t dst_reg;
2832 dst = check_cycles_int(dst, inst->address, opts); 2429 code_info *code = &opts->gen.code;
2430 check_cycles_int(&opts->gen, inst->address);
2833 if (inst->op == M68K_MOVE) { 2431 if (inst->op == M68K_MOVE) {
2834 return translate_m68k_move(dst, inst, opts); 2432 return translate_m68k_move(opts, inst);
2835 } else if(inst->op == M68K_LEA) { 2433 } else if(inst->op == M68K_LEA) {
2836 return translate_m68k_lea(dst, inst, opts); 2434 return translate_m68k_lea(opts, inst);
2837 } else if(inst->op == M68K_PEA) { 2435 } else if(inst->op == M68K_PEA) {
2838 return translate_m68k_pea(dst, inst, opts); 2436 return translate_m68k_pea(opts, inst);
2839 } else if(inst->op == M68K_BSR) { 2437 } else if(inst->op == M68K_BSR) {
2840 return translate_m68k_bsr(dst, inst, opts); 2438 return translate_m68k_bsr(opts, inst);
2841 } else if(inst->op == M68K_BCC) { 2439 } else if(inst->op == M68K_BCC) {
2842 return translate_m68k_bcc(dst, inst, opts); 2440 return translate_m68k_bcc(opts, inst);
2843 } else if(inst->op == M68K_JMP) { 2441 } else if(inst->op == M68K_JMP) {
2844 return translate_m68k_jmp(dst, inst, opts); 2442 return translate_m68k_jmp_jsr(opts, inst);
2845 } else if(inst->op == M68K_JSR) { 2443 } else if(inst->op == M68K_JSR) {
2846 return translate_m68k_jsr(dst, inst, opts); 2444 return translate_m68k_jmp_jsr(opts, inst);
2847 } else if(inst->op == M68K_RTS) { 2445 } else if(inst->op == M68K_RTS) {
2848 return translate_m68k_rts(dst, inst, opts); 2446 return translate_m68k_rts(opts, inst);
2849 } else if(inst->op == M68K_DBCC) { 2447 } else if(inst->op == M68K_DBCC) {
2850 return translate_m68k_dbcc(dst, inst, opts); 2448 return translate_m68k_dbcc(opts, inst);
2851 } else if(inst->op == M68K_CLR) { 2449 } else if(inst->op == M68K_CLR) {
2852 return translate_m68k_clr(dst, inst, opts); 2450 return translate_m68k_clr(opts, inst);
2853 } else if(inst->op == M68K_MOVEM) { 2451 } else if(inst->op == M68K_MOVEM) {
2854 return translate_m68k_movem(dst, inst, opts); 2452 return translate_m68k_movem(opts, inst);
2855 } else if(inst->op == M68K_LINK) { 2453 } else if(inst->op == M68K_LINK) {
2856 return translate_m68k_link(dst, inst, opts); 2454 return translate_m68k_link(opts, inst);
2857 } else if(inst->op == M68K_EXT) { 2455 } else if(inst->op == M68K_EXT) {
2858 return translate_m68k_ext(dst, inst, opts); 2456 return translate_m68k_ext(opts, inst);
2859 } else if(inst->op == M68K_SCC) { 2457 } else if(inst->op == M68K_SCC) {
2860 return translate_m68k_scc(dst, inst, opts); 2458 return translate_m68k_scc(opts, inst);
2861 } else if(inst->op == M68K_MOVEP) { 2459 } else if(inst->op == M68K_MOVEP) {
2862 return translate_m68k_movep(dst, inst, opts); 2460 return translate_m68k_movep(opts, inst);
2863 } else if(inst->op == M68K_INVALID) { 2461 } else if(inst->op == M68K_INVALID) {
2864 if (inst->src.params.immed == 0x7100) { 2462 if (inst->src.params.immed == 0x7100) {
2865 return retn(dst); 2463 return retn(code);
2866 } 2464 }
2867 dst = mov_ir(dst, inst->address, SCRATCH1, SZ_D); 2465 mov_ir(code, inst->address, opts->gen.scratch1, SZ_D);
2868 return call(dst, (code_ptr)m68k_invalid); 2466 return call(code, (code_ptr)m68k_invalid);
2869 } else if(inst->op == M68K_CMP) { 2467 } else if(inst->op == M68K_CMP) {
2870 return translate_m68k_cmp(dst, inst, opts); 2468 return translate_m68k_cmp(opts, inst);
2871 } 2469 }
2872 x86_ea src_op, dst_op; 2470 x86_ea src_op, dst_op;
2873 if (inst->src.addr_mode != MODE_UNUSED) { 2471 if (inst->src.addr_mode != MODE_UNUSED) {
2874 dst = translate_m68k_src(inst, &src_op, dst, opts); 2472 translate_m68k_src(inst, &src_op, opts);
2875 } 2473 }
2876 if (inst->dst.addr_mode != MODE_UNUSED) { 2474 if (inst->dst.addr_mode != MODE_UNUSED) {
2877 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 0); 2475 translate_m68k_dst(inst, &dst_op, opts, 0);
2878 } 2476 }
2879 uint8_t size; 2477 uint8_t size;
2880 switch(inst->op) 2478 switch(inst->op)
2881 { 2479 {
2882 case M68K_ABCD: 2480 case M68K_ABCD:
2883 if (src_op.base != SCRATCH2) { 2481 if (src_op.base != opts->gen.scratch2) {
2884 if (src_op.mode == MODE_REG_DIRECT) { 2482 if (src_op.mode == MODE_REG_DIRECT) {
2885 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B); 2483 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B);
2886 } else { 2484 } else {
2887 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); 2485 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B);
2888 } 2486 }
2889 } 2487 }
2890 if (dst_op.base != SCRATCH1) { 2488 if (dst_op.base != opts->gen.scratch1) {
2891 if (dst_op.mode == MODE_REG_DIRECT) { 2489 if (dst_op.mode == MODE_REG_DIRECT) {
2892 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B); 2490 mov_rr(code, dst_op.base, opts->gen.scratch1, SZ_B);
2893 } else { 2491 } else {
2894 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B); 2492 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B);
2895 } 2493 }
2896 } 2494 }
2897 dst = flag_to_carry(dst, FLAG_X, opts); 2495 flag_to_carry(opts, FLAG_X);
2898 dst = jcc(dst, CC_NC, dst+5); 2496 jcc(code, CC_NC, code->cur + 5);
2899 dst = add_ir(dst, 1, SCRATCH1, SZ_B); 2497 add_ir(code, 1, opts->gen.scratch1, SZ_B);
2900 dst = call(dst, (code_ptr)bcd_add); 2498 call(code, (code_ptr)bcd_add);
2901 dst = reg_to_flag(dst, CH, FLAG_C, opts); 2499 reg_to_flag(opts, CH, FLAG_C);
2902 dst = reg_to_flag(dst, CH, FLAG_X, opts); 2500 reg_to_flag(opts, CH, FLAG_X);
2903 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 2501 cmp_ir(code, 0, opts->gen.scratch1, SZ_B);
2904 dst = jcc(dst, CC_Z, dst+4); 2502 jcc(code, CC_Z, code->cur + 4);
2905 dst = set_flag(dst, 0, FLAG_Z, opts); 2503 set_flag(opts, 0, FLAG_Z);
2906 if (dst_op.base != SCRATCH1) { 2504 if (dst_op.base != opts->gen.scratch1) {
2907 if (dst_op.mode == MODE_REG_DIRECT) { 2505 if (dst_op.mode == MODE_REG_DIRECT) {
2908 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B); 2506 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B);
2909 } else { 2507 } else {
2910 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B); 2508 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B);
2911 } 2509 }
2912 } 2510 }
2913 dst = m68k_save_result(inst, dst, opts); 2511 m68k_save_result(inst, opts);
2914 break; 2512 break;
2915 case M68K_ADD: 2513 case M68K_ADD:
2916 dst = cycles(dst, BUS); 2514 cycles(&opts->gen, BUS);
2917 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; 2515 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size;
2918 if (src_op.mode == MODE_REG_DIRECT) { 2516 if (src_op.mode == MODE_REG_DIRECT) {
2919 if (dst_op.mode == MODE_REG_DIRECT) { 2517 if (dst_op.mode == MODE_REG_DIRECT) {
2920 dst = add_rr(dst, src_op.base, dst_op.base, size); 2518 add_rr(code, src_op.base, dst_op.base, size);
2921 } else { 2519 } else {
2922 dst = add_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2520 add_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
2923 } 2521 }
2924 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2522 } else if (src_op.mode == MODE_REG_DISPLACE8) {
2925 dst = add_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); 2523 add_rdispr(code, src_op.base, src_op.disp, dst_op.base, size);
2926 } else { 2524 } else {
2927 if (dst_op.mode == MODE_REG_DIRECT) { 2525 if (dst_op.mode == MODE_REG_DIRECT) {
2928 dst = add_ir(dst, src_op.disp, dst_op.base, size); 2526 add_ir(code, src_op.disp, dst_op.base, size);
2929 } else { 2527 } else {
2930 dst = add_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 2528 add_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
2931 } 2529 }
2932 } 2530 }
2933 if (inst->dst.addr_mode != MODE_AREG) { 2531 if (inst->dst.addr_mode != MODE_AREG) {
2934 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2532 set_flag_cond(opts, CC_C, FLAG_C);
2935 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2533 set_flag_cond(opts, CC_Z, FLAG_Z);
2936 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2534 set_flag_cond(opts, CC_S, FLAG_N);
2937 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2535 set_flag_cond(opts, CC_O, FLAG_V);
2938 if (opts->flag_regs[FLAG_C] >= 0) { 2536 if (opts->flag_regs[FLAG_C] >= 0) {
2939 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 2537 flag_to_flag(opts, FLAG_C, FLAG_X);
2940 } else { 2538 } else {
2941 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 2539 set_flag_cond(opts, CC_C, FLAG_X);
2942 } 2540 }
2943 } 2541 }
2944 dst = m68k_save_result(inst, dst, opts); 2542 m68k_save_result(inst, opts);
2945 break; 2543 break;
2946 case M68K_ADDX: { 2544 case M68K_ADDX: {
2947 dst = cycles(dst, BUS); 2545 cycles(&opts->gen, BUS);
2948 dst = flag_to_carry(dst, FLAG_X, opts); 2546 flag_to_carry(opts, FLAG_X);
2949 if (src_op.mode == MODE_REG_DIRECT) { 2547 if (src_op.mode == MODE_REG_DIRECT) {
2950 if (dst_op.mode == MODE_REG_DIRECT) { 2548 if (dst_op.mode == MODE_REG_DIRECT) {
2951 dst = adc_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2549 adc_rr(code, src_op.base, dst_op.base, inst->extra.size);
2952 } else { 2550 } else {
2953 dst = adc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 2551 adc_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
2954 } 2552 }
2955 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2553 } else if (src_op.mode == MODE_REG_DISPLACE8) {
2956 dst = adc_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 2554 adc_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
2957 } else { 2555 } else {
2958 if (dst_op.mode == MODE_REG_DIRECT) { 2556 if (dst_op.mode == MODE_REG_DIRECT) {
2959 dst = adc_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2557 adc_ir(code, src_op.disp, dst_op.base, inst->extra.size);
2960 } else { 2558 } else {
2961 dst = adc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2559 adc_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2962 } 2560 }
2963 } 2561 }
2964 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 2562 set_flag_cond(opts, CC_C, FLAG_C);
2965 2563
2966 code_ptr after_flag_set = dst+1; 2564 check_alloc_code(code, 2*MAX_INST_LEN);
2967 dst = jcc(dst, CC_Z, dst+2); 2565 code_ptr after_flag_set = code->cur + 1;
2968 dst = set_flag(dst, 0, FLAG_Z, opts); 2566 jcc(code, CC_Z, code->cur + 2);
2969 *after_flag_set = dst - (after_flag_set+1); 2567 set_flag(opts, 0, FLAG_Z);
2970 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2568 *after_flag_set = code->cur - (after_flag_set+1);
2971 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 2569 set_flag_cond(opts, CC_S, FLAG_N);
2570 set_flag_cond(opts, CC_O, FLAG_V);
2972 if (opts->flag_regs[FLAG_C] >= 0) { 2571 if (opts->flag_regs[FLAG_C] >= 0) {
2973 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 2572 flag_to_flag(opts, FLAG_C, FLAG_X);
2974 } else { 2573 } else {
2975 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 2574 set_flag_cond(opts, CC_C, FLAG_X);
2976 } 2575 }
2977 dst = m68k_save_result(inst, dst, opts); 2576 m68k_save_result(inst, opts);
2978 break; 2577 break;
2979 } 2578 }
2980 case M68K_AND: 2579 case M68K_AND:
2981 dst = cycles(dst, BUS); 2580 cycles(&opts->gen, BUS);
2982 if (src_op.mode == MODE_REG_DIRECT) { 2581 if (src_op.mode == MODE_REG_DIRECT) {
2983 if (dst_op.mode == MODE_REG_DIRECT) { 2582 if (dst_op.mode == MODE_REG_DIRECT) {
2984 dst = and_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2583 and_rr(code, src_op.base, dst_op.base, inst->extra.size);
2985 } else { 2584 } else {
2986 dst = and_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 2585 and_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
2987 } 2586 }
2988 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2587 } else if (src_op.mode == MODE_REG_DISPLACE8) {
2989 dst = and_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 2588 and_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
2990 } else { 2589 } else {
2991 if (dst_op.mode == MODE_REG_DIRECT) { 2590 if (dst_op.mode == MODE_REG_DIRECT) {
2992 dst = and_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2591 and_ir(code, src_op.disp, dst_op.base, inst->extra.size);
2993 } else { 2592 } else {
2994 dst = and_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2593 and_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
2995 } 2594 }
2996 } 2595 }
2997 dst = set_flag(dst, 0, FLAG_C, opts); 2596 set_flag(opts, 0, FLAG_C);
2998 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2597 set_flag_cond(opts, CC_Z, FLAG_Z);
2999 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2598 set_flag_cond(opts, CC_S, FLAG_N);
3000 dst = set_flag(dst, 0, FLAG_V, opts); 2599 set_flag(opts, 0, FLAG_V);
3001 dst = m68k_save_result(inst, dst, opts); 2600 m68k_save_result(inst, opts);
3002 break; 2601 break;
3003 case M68K_ANDI_CCR: 2602 case M68K_ANDI_CCR:
3004 case M68K_ANDI_SR: 2603 case M68K_ANDI_SR:
3005 dst = cycles(dst, 20); 2604 cycles(&opts->gen, 20);
3006 //TODO: If ANDI to SR, trap if not in supervisor mode 2605 //TODO: If ANDI to SR, trap if not in supervisor mode
3007 if (!(inst->src.params.immed & 0x1)) { 2606 if (!(inst->src.params.immed & 0x1)) {
3008 dst = set_flag(dst, 0, FLAG_C, opts); 2607 set_flag(opts, 0, FLAG_C);
3009 } 2608 }
3010 if (!(inst->src.params.immed & 0x2)) { 2609 if (!(inst->src.params.immed & 0x2)) {
3011 dst = set_flag(dst, 0, FLAG_V, opts); 2610 set_flag(opts, 0, FLAG_V);
3012 } 2611 }
3013 if (!(inst->src.params.immed & 0x4)) { 2612 if (!(inst->src.params.immed & 0x4)) {
3014 dst = set_flag(dst, 0, FLAG_Z, opts); 2613 set_flag(opts, 0, FLAG_Z);
3015 } 2614 }
3016 if (!(inst->src.params.immed & 0x8)) { 2615 if (!(inst->src.params.immed & 0x8)) {
3017 dst = set_flag(dst, 0, FLAG_N, opts); 2616 set_flag(opts, 0, FLAG_N);
3018 } 2617 }
3019 if (!(inst->src.params.immed & 0x10)) { 2618 if (!(inst->src.params.immed & 0x10)) {
3020 dst = set_flag(dst, 0, FLAG_X, opts); 2619 set_flag(opts, 0, FLAG_X);
3021 } 2620 }
3022 if (inst->op == M68K_ANDI_SR) { 2621 if (inst->op == M68K_ANDI_SR) {
3023 dst = and_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 2622 and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3024 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 2623 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3025 //leave supervisor mode 2624 //leave supervisor mode
3026 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_B); 2625 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_B);
3027 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B); 2626 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_B);
3028 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B); 2627 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B);
3029 } 2628 }
3030 if (inst->src.params.immed & 0x700) { 2629 if (inst->src.params.immed & 0x700) {
3031 dst = call(dst, opts->do_sync); 2630 call(code, opts->do_sync);
3032 } 2631 }
3033 } 2632 }
3034 break; 2633 break;
3035 case M68K_ASL: 2634 case M68K_ASL:
3036 case M68K_LSL: 2635 case M68K_LSL:
3037 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shl_ir, shl_irdisp8, shl_clr, shl_clrdisp8, shr_ir, shr_irdisp8); 2636 translate_shift(opts, inst, &src_op, &dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp);
3038 break; 2637 break;
3039 case M68K_ASR: 2638 case M68K_ASR:
3040 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, sar_ir, sar_irdisp8, sar_clr, sar_clrdisp8, NULL, NULL); 2639 translate_shift(opts, inst, &src_op, &dst_op, sar_ir, sar_irdisp, sar_clr, sar_clrdisp, NULL, NULL);
3041 break; 2640 break;
3042 case M68K_LSR: 2641 case M68K_LSR:
3043 dst = translate_shift(dst, inst, &src_op, &dst_op, opts, shr_ir, shr_irdisp8, shr_clr, shr_clrdisp8, shl_ir, shl_irdisp8); 2642 translate_shift(opts, inst, &src_op, &dst_op, shr_ir, shr_irdisp, shr_clr, shr_clrdisp, shl_ir, shl_irdisp);
3044 break; 2643 break;
3045 case M68K_BCHG: 2644 case M68K_BCHG:
3046 case M68K_BCLR: 2645 case M68K_BCLR:
3047 case M68K_BSET: 2646 case M68K_BSET:
3048 case M68K_BTST: 2647 case M68K_BTST:
3049 dst = cycles(dst, inst->extra.size == OPSIZE_BYTE ? 4 : ( 2648 cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? 4 : (
3050 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8)) 2649 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8))
3051 ); 2650 );
3052 if (src_op.mode == MODE_IMMED) { 2651 if (src_op.mode == MODE_IMMED) {
3053 if (inst->extra.size == OPSIZE_BYTE) { 2652 if (inst->extra.size == OPSIZE_BYTE) {
3054 src_op.disp &= 0x7; 2653 src_op.disp &= 0x7;
3055 } 2654 }
3056 if (inst->op == M68K_BTST) { 2655 if (inst->op == M68K_BTST) {
3057 if (dst_op.mode == MODE_REG_DIRECT) { 2656 if (dst_op.mode == MODE_REG_DIRECT) {
3058 dst = bt_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2657 bt_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3059 } else { 2658 } else {
3060 dst = bt_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2659 bt_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3061 } 2660 }
3062 } else if (inst->op == M68K_BSET) { 2661 } else if (inst->op == M68K_BSET) {
3063 if (dst_op.mode == MODE_REG_DIRECT) { 2662 if (dst_op.mode == MODE_REG_DIRECT) {
3064 dst = bts_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2663 bts_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3065 } else { 2664 } else {
3066 dst = bts_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2665 bts_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3067 } 2666 }
3068 } else if (inst->op == M68K_BCLR) { 2667 } else if (inst->op == M68K_BCLR) {
3069 if (dst_op.mode == MODE_REG_DIRECT) { 2668 if (dst_op.mode == MODE_REG_DIRECT) {
3070 dst = btr_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2669 btr_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3071 } else { 2670 } else {
3072 dst = btr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2671 btr_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3073 } 2672 }
3074 } else { 2673 } else {
3075 if (dst_op.mode == MODE_REG_DIRECT) { 2674 if (dst_op.mode == MODE_REG_DIRECT) {
3076 dst = btc_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2675 btc_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3077 } else { 2676 } else {
3078 dst = btc_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2677 btc_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3079 } 2678 }
3080 } 2679 }
3081 } else { 2680 } else {
3082 if (src_op.mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op.base != SCRATCH1 && src_op.base != SCRATCH2)) { 2681 if (src_op.mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op.base != opts->gen.scratch1 && src_op.base != opts->gen.scratch2)) {
3083 if (dst_op.base == SCRATCH1) { 2682 if (dst_op.base == opts->gen.scratch1) {
3084 dst = push_r(dst, SCRATCH2); 2683 push_r(code, opts->gen.scratch2);
3085 if (src_op.mode == MODE_REG_DIRECT) { 2684 if (src_op.mode == MODE_REG_DIRECT) {
3086 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B); 2685 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B);
3087 } else { 2686 } else {
3088 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); 2687 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B);
3089 } 2688 }
3090 src_op.base = SCRATCH2; 2689 src_op.base = opts->gen.scratch2;
3091 } else { 2690 } else {
3092 if (src_op.mode == MODE_REG_DIRECT) { 2691 if (src_op.mode == MODE_REG_DIRECT) {
3093 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); 2692 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_B);
3094 } else { 2693 } else {
3095 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); 2694 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B);
3096 } 2695 }
3097 src_op.base = SCRATCH1; 2696 src_op.base = opts->gen.scratch1;
3098 } 2697 }
3099 } 2698 }
3100 uint8_t size = inst->extra.size; 2699 uint8_t size = inst->extra.size;
3101 if (dst_op.mode == MODE_REG_DISPLACE8) { 2700 if (dst_op.mode == MODE_REG_DISPLACE8) {
3102 if (src_op.base != SCRATCH1 && src_op.base != SCRATCH2) { 2701 if (src_op.base != opts->gen.scratch1 && src_op.base != opts->gen.scratch2) {
3103 if (src_op.mode == MODE_REG_DIRECT) { 2702 if (src_op.mode == MODE_REG_DIRECT) {
3104 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_D); 2703 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_D);
3105 } else { 2704 } else {
3106 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D); 2705 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_D);
3107 src_op.mode = MODE_REG_DIRECT; 2706 src_op.mode = MODE_REG_DIRECT;
3108 } 2707 }
3109 src_op.base = SCRATCH1; 2708 src_op.base = opts->gen.scratch1;
3110 } 2709 }
3111 //b### with register destination is modulo 32 2710 //b### with register destination is modulo 32
3112 //x86 with a memory destination isn't modulo anything 2711 //x86 with a memory destination isn't modulo anything
3113 //so use an and here to force the value to be modulo 32 2712 //so use an and here to force the value to be modulo 32
3114 dst = and_ir(dst, 31, SCRATCH1, SZ_D); 2713 and_ir(code, 31, opts->gen.scratch1, SZ_D);
3115 } else if(inst->dst.addr_mode != MODE_REG) { 2714 } else if(inst->dst.addr_mode != MODE_REG) {
3116 //b### with memory destination is modulo 8 2715 //b### with memory destination is modulo 8
3117 //x86-64 doesn't support 8-bit bit operations 2716 //x86-64 doesn't support 8-bit bit operations
3118 //so we fake it by forcing the bit number to be modulo 8 2717 //so we fake it by forcing the bit number to be modulo 8
3119 dst = and_ir(dst, 7, src_op.base, SZ_D); 2718 and_ir(code, 7, src_op.base, SZ_D);
3120 size = SZ_D; 2719 size = SZ_D;
3121 } 2720 }
3122 if (inst->op == M68K_BTST) { 2721 if (inst->op == M68K_BTST) {
3123 if (dst_op.mode == MODE_REG_DIRECT) { 2722 if (dst_op.mode == MODE_REG_DIRECT) {
3124 dst = bt_rr(dst, src_op.base, dst_op.base, size); 2723 bt_rr(code, src_op.base, dst_op.base, size);
3125 } else { 2724 } else {
3126 dst = bt_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2725 bt_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
3127 } 2726 }
3128 } else if (inst->op == M68K_BSET) { 2727 } else if (inst->op == M68K_BSET) {
3129 if (dst_op.mode == MODE_REG_DIRECT) { 2728 if (dst_op.mode == MODE_REG_DIRECT) {
3130 dst = bts_rr(dst, src_op.base, dst_op.base, size); 2729 bts_rr(code, src_op.base, dst_op.base, size);
3131 } else { 2730 } else {
3132 dst = bts_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2731 bts_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
3133 } 2732 }
3134 } else if (inst->op == M68K_BCLR) { 2733 } else if (inst->op == M68K_BCLR) {
3135 if (dst_op.mode == MODE_REG_DIRECT) { 2734 if (dst_op.mode == MODE_REG_DIRECT) {
3136 dst = btr_rr(dst, src_op.base, dst_op.base, size); 2735 btr_rr(code, src_op.base, dst_op.base, size);
3137 } else { 2736 } else {
3138 dst = btr_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2737 btr_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
3139 } 2738 }
3140 } else { 2739 } else {
3141 if (dst_op.mode == MODE_REG_DIRECT) { 2740 if (dst_op.mode == MODE_REG_DIRECT) {
3142 dst = btc_rr(dst, src_op.base, dst_op.base, size); 2741 btc_rr(code, src_op.base, dst_op.base, size);
3143 } else { 2742 } else {
3144 dst = btc_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 2743 btc_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
3145 } 2744 }
3146 } 2745 }
3147 if (src_op.base == SCRATCH2) { 2746 if (src_op.base == opts->gen.scratch2) {
3148 dst = pop_r(dst, SCRATCH2); 2747 pop_r(code, opts->gen.scratch2);
3149 } 2748 }
3150 } 2749 }
3151 //x86 sets the carry flag to the value of the bit tested 2750 //x86 sets the carry flag to the value of the bit tested
3152 //68K sets the zero flag to the complement of the bit tested 2751 //68K sets the zero flag to the complement of the bit tested
3153 dst = set_flag_cond(dst, CC_NC, FLAG_Z, opts); 2752 set_flag_cond(opts, CC_NC, FLAG_Z);
3154 if (inst->op != M68K_BTST) { 2753 if (inst->op != M68K_BTST) {
3155 dst = m68k_save_result(inst, dst, opts); 2754 m68k_save_result(inst, opts);
3156 } 2755 }
3157 break; 2756 break;
3158 case M68K_CHK: 2757 case M68K_CHK:
3159 { 2758 {
3160 dst = cycles(dst, 6); 2759 cycles(&opts->gen, 6);
3161 if (dst_op.mode == MODE_REG_DIRECT) { 2760 if (dst_op.mode == MODE_REG_DIRECT) {
3162 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 2761 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3163 } else { 2762 } else {
3164 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 2763 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
3165 } 2764 }
3166 uint32_t isize; 2765 uint32_t isize;
3167 switch(inst->src.addr_mode) 2766 switch(inst->src.addr_mode)
3168 { 2767 {
3169 case MODE_AREG_DISPLACE: 2768 case MODE_AREG_DISPLACE:
3178 isize = 6; 2777 isize = 6;
3179 break; 2778 break;
3180 default: 2779 default:
3181 isize = 2; 2780 isize = 2;
3182 } 2781 }
3183 code_ptr passed = dst+1; 2782 //make sure we won't start a new chunk in the middle of these branches
3184 dst = jcc(dst, CC_GE, dst+2); 2783 check_alloc_code(code, MAX_INST_LEN * 11);
3185 dst = set_flag(dst, 1, FLAG_N, opts); 2784 code_ptr passed = code->cur + 1;
3186 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 2785 jcc(code, CC_GE, code->cur + 2);
3187 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 2786 set_flag(opts, 1, FLAG_N);
3188 dst = jmp(dst, opts->trap); 2787 mov_ir(code, VECTOR_CHK, opts->gen.scratch2, SZ_D);
3189 *passed = dst - (passed+1); 2788 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D);
2789 jmp(code, opts->trap);
2790 *passed = code->cur - (passed+1);
3190 if (dst_op.mode == MODE_REG_DIRECT) { 2791 if (dst_op.mode == MODE_REG_DIRECT) {
3191 if (src_op.mode == MODE_REG_DIRECT) { 2792 if (src_op.mode == MODE_REG_DIRECT) {
3192 dst = cmp_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2793 cmp_rr(code, src_op.base, dst_op.base, inst->extra.size);
3193 } else if(src_op.mode == MODE_REG_DISPLACE8) { 2794 } else if(src_op.mode == MODE_REG_DISPLACE8) {
3194 dst = cmp_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 2795 cmp_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
3195 } else { 2796 } else {
3196 dst = cmp_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2797 cmp_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3197 } 2798 }
3198 } else if(dst_op.mode == MODE_REG_DISPLACE8) { 2799 } else if(dst_op.mode == MODE_REG_DISPLACE8) {
3199 if (src_op.mode == MODE_REG_DIRECT) { 2800 if (src_op.mode == MODE_REG_DIRECT) {
3200 dst = cmp_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 2801 cmp_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
3201 } else { 2802 } else {
3202 dst = cmp_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2803 cmp_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3203 } 2804 }
3204 } 2805 }
3205 passed = dst+1; 2806 passed = code->cur + 1;
3206 dst = jcc(dst, CC_LE, dst+2); 2807 jcc(code, CC_LE, code->cur + 2);
3207 dst = set_flag(dst, 0, FLAG_N, opts); 2808 set_flag(opts, 0, FLAG_N);
3208 dst = mov_ir(dst, VECTOR_CHK, SCRATCH2, SZ_D); 2809 mov_ir(code, VECTOR_CHK, opts->gen.scratch2, SZ_D);
3209 dst = mov_ir(dst, inst->address+isize, SCRATCH1, SZ_D); 2810 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D);
3210 dst = jmp(dst, opts->trap); 2811 jmp(code, opts->trap);
3211 *passed = dst - (passed+1); 2812 *passed = code->cur - (passed+1);
3212 dst = cycles(dst, 4); 2813 cycles(&opts->gen, 4);
3213 break; 2814 break;
3214 } 2815 }
3215 case M68K_DIVS: 2816 case M68K_DIVS:
3216 case M68K_DIVU: 2817 case M68K_DIVU:
3217 { 2818 {
2819 check_alloc_code(code, MAX_NATIVE_SIZE);
3218 //TODO: cycle exact division 2820 //TODO: cycle exact division
3219 dst = cycles(dst, inst->op == M68K_DIVS ? 158 : 140); 2821 cycles(&opts->gen, inst->op == M68K_DIVS ? 158 : 140);
3220 dst = set_flag(dst, 0, FLAG_C, opts); 2822 set_flag(opts, 0, FLAG_C);
3221 dst = push_r(dst, RDX); 2823 push_r(code, RDX);
3222 dst = push_r(dst, RAX); 2824 push_r(code, RAX);
3223 if (dst_op.mode == MODE_REG_DIRECT) { 2825 if (dst_op.mode == MODE_REG_DIRECT) {
3224 dst = mov_rr(dst, dst_op.base, RAX, SZ_D); 2826 mov_rr(code, dst_op.base, RAX, SZ_D);
3225 } else { 2827 } else {
3226 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, RAX, SZ_D); 2828 mov_rdispr(code, dst_op.base, dst_op.disp, RAX, SZ_D);
3227 } 2829 }
3228 if (src_op.mode == MODE_IMMED) { 2830 if (src_op.mode == MODE_IMMED) {
3229 dst = mov_ir(dst, (src_op.disp & 0x8000) && inst->op == M68K_DIVS ? src_op.disp | 0xFFFF0000 : src_op.disp, SCRATCH2, SZ_D); 2831 mov_ir(code, (src_op.disp & 0x8000) && inst->op == M68K_DIVS ? src_op.disp | 0xFFFF0000 : src_op.disp, opts->gen.scratch2, SZ_D);
3230 } else if (src_op.mode == MODE_REG_DIRECT) { 2832 } else if (src_op.mode == MODE_REG_DIRECT) {
3231 if (inst->op == M68K_DIVS) { 2833 if (inst->op == M68K_DIVS) {
3232 dst = movsx_rr(dst, src_op.base, SCRATCH2, SZ_W, SZ_D); 2834 movsx_rr(code, src_op.base, opts->gen.scratch2, SZ_W, SZ_D);
3233 } else { 2835 } else {
3234 dst = movzx_rr(dst, src_op.base, SCRATCH2, SZ_W, SZ_D); 2836 movzx_rr(code, src_op.base, opts->gen.scratch2, SZ_W, SZ_D);
3235 } 2837 }
3236 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2838 } else if (src_op.mode == MODE_REG_DISPLACE8) {
3237 if (inst->op == M68K_DIVS) { 2839 if (inst->op == M68K_DIVS) {
3238 dst = movsx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_W, SZ_D); 2840 movsx_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_W, SZ_D);
3239 } else { 2841 } else {
3240 dst = movzx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_W, SZ_D); 2842 movzx_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_W, SZ_D);
3241 } 2843 }
3242 } 2844 }
3243 dst = cmp_ir(dst, 0, SCRATCH2, SZ_D); 2845 cmp_ir(code, 0, opts->gen.scratch2, SZ_D);
3244 code_ptr not_zero = dst+1; 2846 check_alloc_code(code, 6*MAX_INST_LEN);
3245 dst = jcc(dst, CC_NZ, dst+2); 2847 code_ptr not_zero = code->cur + 1;
3246 dst = pop_r(dst, RAX); 2848 jcc(code, CC_NZ, code->cur + 2);
3247 dst = pop_r(dst, RDX); 2849 pop_r(code, RAX);
3248 dst = mov_ir(dst, VECTOR_INT_DIV_ZERO, SCRATCH2, SZ_D); 2850 pop_r(code, RDX);
3249 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 2851 mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D);
3250 dst = jmp(dst, opts->trap); 2852 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
3251 *not_zero = dst - (not_zero+1); 2853 jmp(code, opts->trap);
2854 *not_zero = code->cur - (not_zero+1);
3252 if (inst->op == M68K_DIVS) { 2855 if (inst->op == M68K_DIVS) {
3253 dst = cdq(dst); 2856 cdq(code);
3254 } else { 2857 } else {
3255 dst = xor_rr(dst, RDX, RDX, SZ_D); 2858 xor_rr(code, RDX, RDX, SZ_D);
3256 } 2859 }
3257 if (inst->op == M68K_DIVS) { 2860 if (inst->op == M68K_DIVS) {
3258 dst = idiv_r(dst, SCRATCH2, SZ_D); 2861 idiv_r(code, opts->gen.scratch2, SZ_D);
3259 } else { 2862 } else {
3260 dst = div_r(dst, SCRATCH2, SZ_D); 2863 div_r(code, opts->gen.scratch2, SZ_D);
3261 } 2864 }
3262 code_ptr skip_sec_check; 2865 code_ptr skip_sec_check;
3263 if (inst->op == M68K_DIVS) { 2866 if (inst->op == M68K_DIVS) {
3264 dst = cmp_ir(dst, 0x8000, RAX, SZ_D); 2867 cmp_ir(code, 0x8000, RAX, SZ_D);
3265 skip_sec_check = dst + 1; 2868 skip_sec_check = code->cur + 1;
3266 dst = jcc(dst, CC_GE, dst+2); 2869 jcc(code, CC_GE, code->cur + 2);
3267 dst = cmp_ir(dst, -0x8000, RAX, SZ_D); 2870 cmp_ir(code, -0x8000, RAX, SZ_D);
3268 norm_off = dst+1; 2871 norm_off = code->cur + 1;
3269 dst = jcc(dst, CC_L, dst+2); 2872 jcc(code, CC_L, code->cur + 2);
3270 } else { 2873 } else {
3271 dst = cmp_ir(dst, 0x10000, RAX, SZ_D); 2874 cmp_ir(code, 0x10000, RAX, SZ_D);
3272 norm_off = dst+1; 2875 norm_off = code->cur + 1;
3273 dst = jcc(dst, CC_NC, dst+2); 2876 jcc(code, CC_NC, code->cur + 2);
3274 } 2877 }
3275 if (dst_op.mode == MODE_REG_DIRECT) { 2878 if (dst_op.mode == MODE_REG_DIRECT) {
3276 dst = mov_rr(dst, RDX, dst_op.base, SZ_W); 2879 mov_rr(code, RDX, dst_op.base, SZ_W);
3277 dst = shl_ir(dst, 16, dst_op.base, SZ_D); 2880 shl_ir(code, 16, dst_op.base, SZ_D);
3278 dst = mov_rr(dst, RAX, dst_op.base, SZ_W); 2881 mov_rr(code, RAX, dst_op.base, SZ_W);
3279 } else { 2882 } else {
3280 dst = mov_rrdisp8(dst, RDX, dst_op.base, dst_op.disp, SZ_W); 2883 mov_rrdisp(code, RDX, dst_op.base, dst_op.disp, SZ_W);
3281 dst = shl_irdisp8(dst, 16, dst_op.base, dst_op.disp, SZ_D); 2884 shl_irdisp(code, 16, dst_op.base, dst_op.disp, SZ_D);
3282 dst = mov_rrdisp8(dst, RAX, dst_op.base, dst_op.disp, SZ_W); 2885 mov_rrdisp(code, RAX, dst_op.base, dst_op.disp, SZ_W);
3283 } 2886 }
3284 dst = cmp_ir(dst, 0, RAX, SZ_W); 2887 cmp_ir(code, 0, RAX, SZ_W);
3285 dst = pop_r(dst, RAX); 2888 pop_r(code, RAX);
3286 dst = pop_r(dst, RDX); 2889 pop_r(code, RDX);
3287 dst = set_flag(dst, 0, FLAG_V, opts); 2890 set_flag(opts, 0, FLAG_V);
3288 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2891 set_flag_cond(opts, CC_Z, FLAG_Z);
3289 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2892 set_flag_cond(opts, CC_S, FLAG_N);
3290 end_off = dst+1; 2893 end_off = code->cur + 1;
3291 dst = jmp(dst, dst+2); 2894 jmp(code, code->cur + 2);
3292 *norm_off = dst - (norm_off + 1); 2895 *norm_off = code->cur - (norm_off + 1);
3293 if (inst->op == M68K_DIVS) { 2896 if (inst->op == M68K_DIVS) {
3294 *skip_sec_check = dst - (skip_sec_check+1); 2897 *skip_sec_check = code->cur - (skip_sec_check+1);
3295 } 2898 }
3296 dst = pop_r(dst, RAX); 2899 pop_r(code, RAX);
3297 dst = pop_r(dst, RDX); 2900 pop_r(code, RDX);
3298 dst = set_flag(dst, 1, FLAG_V, opts); 2901 set_flag(opts, 1, FLAG_V);
3299 *end_off = dst - (end_off + 1); 2902 *end_off = code->cur - (end_off + 1);
3300 break; 2903 break;
3301 } 2904 }
3302 case M68K_EOR: 2905 case M68K_EOR:
3303 dst = cycles(dst, BUS); 2906 cycles(&opts->gen, BUS);
3304 if (src_op.mode == MODE_REG_DIRECT) { 2907 if (src_op.mode == MODE_REG_DIRECT) {
3305 if (dst_op.mode == MODE_REG_DIRECT) { 2908 if (dst_op.mode == MODE_REG_DIRECT) {
3306 dst = xor_rr(dst, src_op.base, dst_op.base, inst->extra.size); 2909 xor_rr(code, src_op.base, dst_op.base, inst->extra.size);
3307 } else { 2910 } else {
3308 dst = xor_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 2911 xor_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
3309 } 2912 }
3310 } else if (src_op.mode == MODE_REG_DISPLACE8) { 2913 } else if (src_op.mode == MODE_REG_DISPLACE8) {
3311 dst = xor_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 2914 xor_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
3312 } else { 2915 } else {
3313 if (dst_op.mode == MODE_REG_DIRECT) { 2916 if (dst_op.mode == MODE_REG_DIRECT) {
3314 dst = xor_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 2917 xor_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3315 } else { 2918 } else {
3316 dst = xor_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 2919 xor_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3317 } 2920 }
3318 } 2921 }
3319 dst = set_flag(dst, 0, FLAG_C, opts); 2922 set_flag(opts, 0, FLAG_C);
3320 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 2923 set_flag_cond(opts, CC_Z, FLAG_Z);
3321 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 2924 set_flag_cond(opts, CC_S, FLAG_N);
3322 dst = set_flag(dst, 0, FLAG_V, opts); 2925 set_flag(opts, 0, FLAG_V);
3323 dst = m68k_save_result(inst, dst, opts); 2926 m68k_save_result(inst, opts);
3324 break; 2927 break;
3325 case M68K_EORI_CCR: 2928 case M68K_EORI_CCR:
3326 case M68K_EORI_SR: 2929 case M68K_EORI_SR:
3327 dst = cycles(dst, 20); 2930 cycles(&opts->gen, 20);
3328 //TODO: If ANDI to SR, trap if not in supervisor mode 2931 //TODO: If ANDI to SR, trap if not in supervisor mode
3329 if (inst->src.params.immed & 0x1) { 2932 if (inst->src.params.immed & 0x1) {
3330 dst = xor_flag(dst, 1, FLAG_C, opts); 2933 xor_flag(opts, 1, FLAG_C);
3331 } 2934 }
3332 if (inst->src.params.immed & 0x2) { 2935 if (inst->src.params.immed & 0x2) {
3333 dst = xor_flag(dst, 1, FLAG_V, opts); 2936 xor_flag(opts, 1, FLAG_V);
3334 } 2937 }
3335 if (inst->src.params.immed & 0x4) { 2938 if (inst->src.params.immed & 0x4) {
3336 dst = xor_flag(dst, 1, FLAG_Z, opts); 2939 xor_flag(opts, 1, FLAG_Z);
3337 } 2940 }
3338 if (inst->src.params.immed & 0x8) { 2941 if (inst->src.params.immed & 0x8) {
3339 dst = xor_flag(dst, 1, FLAG_N, opts); 2942 xor_flag(opts, 1, FLAG_N);
3340 } 2943 }
3341 if (inst->src.params.immed & 0x10) { 2944 if (inst->src.params.immed & 0x10) {
3342 dst = xor_flag(dst, 1, FLAG_X, opts); 2945 xor_flag(opts, 1, FLAG_X);
3343 } 2946 }
3344 if (inst->op == M68K_ORI_SR) { 2947 if (inst->op == M68K_ORI_SR) {
3345 dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 2948 xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3346 if (inst->src.params.immed & 0x700) { 2949 if (inst->src.params.immed & 0x700) {
3347 dst = call(dst, opts->do_sync); 2950 call(code, opts->do_sync);
3348 } 2951 }
3349 } 2952 }
3350 break; 2953 break;
3351 case M68K_EXG: 2954 case M68K_EXG:
3352 dst = cycles(dst, 6); 2955 cycles(&opts->gen, 6);
3353 if (dst_op.mode == MODE_REG_DIRECT) { 2956 if (dst_op.mode == MODE_REG_DIRECT) {
3354 dst = mov_rr(dst, dst_op.base, SCRATCH2, SZ_D); 2957 mov_rr(code, dst_op.base, opts->gen.scratch2, SZ_D);
3355 if (src_op.mode == MODE_REG_DIRECT) { 2958 if (src_op.mode == MODE_REG_DIRECT) {
3356 dst = mov_rr(dst, src_op.base, dst_op.base, SZ_D); 2959 mov_rr(code, src_op.base, dst_op.base, SZ_D);
3357 dst = mov_rr(dst, SCRATCH2, src_op.base, SZ_D); 2960 mov_rr(code, opts->gen.scratch2, src_op.base, SZ_D);
3358 } else { 2961 } else {
3359 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, SZ_D); 2962 mov_rdispr(code, src_op.base, src_op.disp, dst_op.base, SZ_D);
3360 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); 2963 mov_rrdisp(code, opts->gen.scratch2, src_op.base, src_op.disp, SZ_D);
3361 } 2964 }
3362 } else { 2965 } else {
3363 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH2, SZ_D); 2966 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, SZ_D);
3364 if (src_op.mode == MODE_REG_DIRECT) { 2967 if (src_op.mode == MODE_REG_DIRECT) {
3365 dst = mov_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, SZ_D); 2968 mov_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, SZ_D);
3366 dst = mov_rr(dst, SCRATCH2, src_op.base, SZ_D); 2969 mov_rr(code, opts->gen.scratch2, src_op.base, SZ_D);
3367 } else { 2970 } else {
3368 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D); 2971 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_D);
3369 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D); 2972 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_D);
3370 dst = mov_rrdisp8(dst, SCRATCH2, src_op.base, src_op.disp, SZ_D); 2973 mov_rrdisp(code, opts->gen.scratch2, src_op.base, src_op.disp, SZ_D);
3371 } 2974 }
3372 } 2975 }
3373 break; 2976 break;
3374 case M68K_ILLEGAL: 2977 case M68K_ILLEGAL:
3375 dst = call(dst, opts->gen.save_context); 2978 call(code, opts->gen.save_context);
3376 #ifdef X86_64 2979 #ifdef X86_64
3377 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 2980 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
3378 #else 2981 #else
3379 dst = push_r(dst, CONTEXT); 2982 push_r(code, opts->gen.context_reg);
3380 #endif 2983 #endif
3381 dst = call(dst, (code_ptr)print_regs_exit); 2984 call(code, (code_ptr)print_regs_exit);
3382 break; 2985 break;
3383 case M68K_MOVE_FROM_SR: 2986 case M68K_MOVE_FROM_SR:
3384 //TODO: Trap if not in system mode 2987 //TODO: Trap if not in system mode
3385 dst = call(dst, opts->get_sr); 2988 call(code, opts->get_sr);
3386 if (dst_op.mode == MODE_REG_DIRECT) { 2989 if (dst_op.mode == MODE_REG_DIRECT) {
3387 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W); 2990 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_W);
3388 } else { 2991 } else {
3389 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_W); 2992 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_W);
3390 } 2993 }
3391 dst = m68k_save_result(inst, dst, opts); 2994 m68k_save_result(inst, opts);
3392 break; 2995 break;
3393 case M68K_MOVE_CCR: 2996 case M68K_MOVE_CCR:
3394 case M68K_MOVE_SR: 2997 case M68K_MOVE_SR:
3395 //TODO: Privilege check for MOVE to SR 2998 //TODO: Privilege check for MOVE to SR
3396 if (src_op.mode == MODE_IMMED) { 2999 if (src_op.mode == MODE_IMMED) {
3397 dst = set_flag(dst, src_op.disp & 0x1, FLAG_C, opts); 3000 set_flag(opts, src_op.disp & 0x1, FLAG_C);
3398 dst = set_flag(dst, (src_op.disp >> 1) & 0x1, FLAG_V, opts); 3001 set_flag(opts, (src_op.disp >> 1) & 0x1, FLAG_V);
3399 dst = set_flag(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, opts); 3002 set_flag(opts, (src_op.disp >> 2) & 0x1, FLAG_Z);
3400 dst = set_flag(dst, (src_op.disp >> 3) & 0x1, FLAG_N, opts); 3003 set_flag(opts, (src_op.disp >> 3) & 0x1, FLAG_N);
3401 dst = set_flag(dst, (src_op.disp >> 4) & 0x1, FLAG_X, opts); 3004 set_flag(opts, (src_op.disp >> 4) & 0x1, FLAG_X);
3402 if (inst->op == M68K_MOVE_SR) { 3005 if (inst->op == M68K_MOVE_SR) {
3403 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B); 3006 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3404 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 3007 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3405 //leave supervisor mode 3008 //leave supervisor mode
3406 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3009 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3407 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3010 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3408 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3011 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3409 } 3012 }
3410 dst = call(dst, opts->do_sync); 3013 call(code, opts->do_sync);
3411 } 3014 }
3412 dst = cycles(dst, 12); 3015 cycles(&opts->gen, 12);
3413 } else { 3016 } else {
3414 if (src_op.base != SCRATCH1) { 3017 if (src_op.base != opts->gen.scratch1) {
3415 if (src_op.mode == MODE_REG_DIRECT) { 3018 if (src_op.mode == MODE_REG_DIRECT) {
3416 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_W); 3019 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_W);
3417 } else { 3020 } else {
3418 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); 3021 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_W);
3419 } 3022 }
3420 } 3023 }
3421 dst = call(dst, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); 3024 call(code, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr);
3422 dst = cycles(dst, 12); 3025 cycles(&opts->gen, 12);
3423 3026
3424 } 3027 }
3425 break; 3028 break;
3426 case M68K_MOVE_USP: 3029 case M68K_MOVE_USP:
3427 dst = cycles(dst, BUS); 3030 cycles(&opts->gen, BUS);
3428 //TODO: Trap if not in supervisor mode 3031 //TODO: Trap if not in supervisor mode
3429 //dst = bt_irdisp8(dst, BIT_SUPERVISOR, CONTEXT, offsetof(m68k_context, status), SZ_B); 3032 //bt_irdisp(code, BIT_SUPERVISOR, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3430 if (inst->src.addr_mode == MODE_UNUSED) { 3033 if (inst->src.addr_mode == MODE_UNUSED) {
3431 if (dst_op.mode == MODE_REG_DIRECT) { 3034 if (dst_op.mode == MODE_REG_DIRECT) {
3432 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, dst_op.base, SZ_D); 3035 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, dst_op.base, SZ_D);
3433 } else { 3036 } else {
3434 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH1, SZ_D); 3037 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch1, SZ_D);
3435 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D); 3038 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_D);
3436 } 3039 }
3437 } else { 3040 } else {
3438 if (src_op.mode == MODE_REG_DIRECT) { 3041 if (src_op.mode == MODE_REG_DIRECT) {
3439 dst = mov_rrdisp8(dst, src_op.base, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3042 mov_rrdisp(code, src_op.base, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3440 } else { 3043 } else {
3441 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_D); 3044 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_D);
3442 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3045 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3443 } 3046 }
3444 } 3047 }
3445 break; 3048 break;
3446 //case M68K_MOVEP: 3049 //case M68K_MOVEP:
3447 case M68K_MULS: 3050 case M68K_MULS:
3448 case M68K_MULU: 3051 case M68K_MULU:
3449 dst = cycles(dst, 70); //TODO: Calculate the actual value based on the value of the <ea> parameter 3052 cycles(&opts->gen, 70); //TODO: Calculate the actual value based on the value of the <ea> parameter
3450 if (src_op.mode == MODE_IMMED) { 3053 if (src_op.mode == MODE_IMMED) {
3451 dst = mov_ir(dst, inst->op == M68K_MULU ? (src_op.disp & 0xFFFF) : ((src_op.disp & 0x8000) ? src_op.disp | 0xFFFF0000 : src_op.disp), SCRATCH1, SZ_D); 3054 mov_ir(code, inst->op == M68K_MULU ? (src_op.disp & 0xFFFF) : ((src_op.disp & 0x8000) ? src_op.disp | 0xFFFF0000 : src_op.disp), opts->gen.scratch1, SZ_D);
3452 } else if (src_op.mode == MODE_REG_DIRECT) { 3055 } else if (src_op.mode == MODE_REG_DIRECT) {
3453 if (inst->op == M68K_MULS) { 3056 if (inst->op == M68K_MULS) {
3454 dst = movsx_rr(dst, src_op.base, SCRATCH1, SZ_W, SZ_D); 3057 movsx_rr(code, src_op.base, opts->gen.scratch1, SZ_W, SZ_D);
3455 } else { 3058 } else {
3456 dst = movzx_rr(dst, src_op.base, SCRATCH1, SZ_W, SZ_D); 3059 movzx_rr(code, src_op.base, opts->gen.scratch1, SZ_W, SZ_D);
3457 } 3060 }
3458 } else { 3061 } else {
3459 if (inst->op == M68K_MULS) { 3062 if (inst->op == M68K_MULS) {
3460 dst = movsx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W, SZ_D); 3063 movsx_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_W, SZ_D);
3461 } else { 3064 } else {
3462 dst = movzx_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W, SZ_D); 3065 movzx_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_W, SZ_D);
3463 } 3066 }
3464 } 3067 }
3465 if (dst_op.mode == MODE_REG_DIRECT) { 3068 if (dst_op.mode == MODE_REG_DIRECT) {
3466 dst_reg = dst_op.base; 3069 dst_reg = dst_op.base;
3467 if (inst->op == M68K_MULS) { 3070 if (inst->op == M68K_MULS) {
3468 dst = movsx_rr(dst, dst_reg, dst_reg, SZ_W, SZ_D); 3071 movsx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D);
3469 } else { 3072 } else {
3470 dst = movzx_rr(dst, dst_reg, dst_reg, SZ_W, SZ_D); 3073 movzx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D);
3471 } 3074 }
3472 } else { 3075 } else {
3473 dst_reg = SCRATCH2; 3076 dst_reg = opts->gen.scratch2;
3474 if (inst->op == M68K_MULS) { 3077 if (inst->op == M68K_MULS) {
3475 dst = movsx_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH2, SZ_W, SZ_D); 3078 movsx_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, SZ_W, SZ_D);
3476 } else { 3079 } else {
3477 dst = movzx_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH2, SZ_W, SZ_D); 3080 movzx_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch2, SZ_W, SZ_D);
3478 } 3081 }
3479 } 3082 }
3480 dst = imul_rr(dst, SCRATCH1, dst_reg, SZ_D); 3083 imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D);
3481 if (dst_op.mode == MODE_REG_DISPLACE8) { 3084 if (dst_op.mode == MODE_REG_DISPLACE8) {
3482 dst = mov_rrdisp8(dst, dst_reg, dst_op.base, dst_op.disp, SZ_D); 3085 mov_rrdisp(code, dst_reg, dst_op.base, dst_op.disp, SZ_D);
3483 } 3086 }
3484 dst = set_flag(dst, 0, FLAG_V, opts); 3087 set_flag(opts, 0, FLAG_V);
3485 dst = set_flag(dst, 0, FLAG_C, opts); 3088 set_flag(opts, 0, FLAG_C);
3486 dst = cmp_ir(dst, 0, dst_reg, SZ_D); 3089 cmp_ir(code, 0, dst_reg, SZ_D);
3487 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3090 set_flag_cond(opts, CC_Z, FLAG_Z);
3488 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3091 set_flag_cond(opts, CC_S, FLAG_N);
3489 break; 3092 break;
3490 //case M68K_NBCD: 3093 //case M68K_NBCD:
3491 case M68K_NEG: 3094 case M68K_NEG:
3492 dst = cycles(dst, BUS); 3095 cycles(&opts->gen, BUS);
3493 if (dst_op.mode == MODE_REG_DIRECT) { 3096 if (dst_op.mode == MODE_REG_DIRECT) {
3494 dst = neg_r(dst, dst_op.base, inst->extra.size); 3097 neg_r(code, dst_op.base, inst->extra.size);
3495 } else { 3098 } else {
3496 dst = neg_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3099 neg_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3497 } 3100 }
3498 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3101 set_flag_cond(opts, CC_C, FLAG_C);
3499 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3102 set_flag_cond(opts, CC_Z, FLAG_Z);
3500 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3103 set_flag_cond(opts, CC_S, FLAG_N);
3501 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 3104 set_flag_cond(opts, CC_O, FLAG_V);
3502 if (opts->flag_regs[FLAG_C] >= 0) { 3105 if (opts->flag_regs[FLAG_C] >= 0) {
3503 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3106 flag_to_flag(opts, FLAG_C, FLAG_X);
3504 } else { 3107 } else {
3505 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3108 set_flag_cond(opts, CC_C, FLAG_X);
3506 } 3109 }
3507 dst = m68k_save_result(inst, dst, opts); 3110 m68k_save_result(inst, opts);
3508 break; 3111 break;
3509 case M68K_NEGX: { 3112 case M68K_NEGX: {
3510 dst = cycles(dst, BUS); 3113 cycles(&opts->gen, BUS);
3511 if (dst_op.mode == MODE_REG_DIRECT) { 3114 if (dst_op.mode == MODE_REG_DIRECT) {
3512 if (dst_op.base == SCRATCH1) { 3115 if (dst_op.base == opts->gen.scratch1) {
3513 dst = push_r(dst, SCRATCH2); 3116 push_r(code, opts->gen.scratch2);
3514 dst = xor_rr(dst, SCRATCH2, SCRATCH2, inst->extra.size); 3117 xor_rr(code, opts->gen.scratch2, opts->gen.scratch2, inst->extra.size);
3515 dst = flag_to_carry(dst, FLAG_X, opts); 3118 flag_to_carry(opts, FLAG_X);
3516 dst = sbb_rr(dst, dst_op.base, SCRATCH2, inst->extra.size); 3119 sbb_rr(code, dst_op.base, opts->gen.scratch2, inst->extra.size);
3517 dst = mov_rr(dst, SCRATCH2, dst_op.base, inst->extra.size); 3120 mov_rr(code, opts->gen.scratch2, dst_op.base, inst->extra.size);
3518 dst = pop_r(dst, SCRATCH2); 3121 pop_r(code, opts->gen.scratch2);
3519 } else { 3122 } else {
3520 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size); 3123 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size);
3521 dst = flag_to_carry(dst, FLAG_X, opts); 3124 flag_to_carry(opts, FLAG_X);
3522 dst = sbb_rr(dst, dst_op.base, SCRATCH1, inst->extra.size); 3125 sbb_rr(code, dst_op.base, opts->gen.scratch1, inst->extra.size);
3523 dst = mov_rr(dst, SCRATCH1, dst_op.base, inst->extra.size); 3126 mov_rr(code, opts->gen.scratch1, dst_op.base, inst->extra.size);
3524 } 3127 }
3525 } else { 3128 } else {
3526 dst = xor_rr(dst, SCRATCH1, SCRATCH1, inst->extra.size); 3129 xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size);
3527 dst = flag_to_carry(dst, FLAG_X, opts); 3130 flag_to_carry(opts, FLAG_X);
3528 dst = sbb_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, inst->extra.size); 3131 sbb_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, inst->extra.size);
3529 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, inst->extra.size); 3132 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, inst->extra.size);
3530 } 3133 }
3531 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3134 set_flag_cond(opts, CC_C, FLAG_C);
3532 code_ptr after_flag_set = dst+1; 3135 code_ptr after_flag_set = code->cur + 1;
3533 dst = jcc(dst, CC_Z, dst+2); 3136 jcc(code, CC_Z, code->cur + 2);
3534 dst = set_flag(dst, 0, FLAG_Z, opts); 3137 set_flag(opts, 0, FLAG_Z);
3535 *after_flag_set = dst - (after_flag_set+1); 3138 *after_flag_set = code->cur - (after_flag_set+1);
3536 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3139 set_flag_cond(opts, CC_S, FLAG_N);
3537 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 3140 set_flag_cond(opts, CC_O, FLAG_V);
3538 if (opts->flag_regs[FLAG_C] >= 0) { 3141 if (opts->flag_regs[FLAG_C] >= 0) {
3539 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3142 flag_to_flag(opts, FLAG_C, FLAG_X);
3540 } else { 3143 } else {
3541 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3144 set_flag_cond(opts, CC_C, FLAG_X);
3542 } 3145 }
3543 dst = m68k_save_result(inst, dst, opts); 3146 m68k_save_result(inst, opts);
3544 break; 3147 break;
3545 } 3148 }
3546 case M68K_NOP: 3149 case M68K_NOP:
3547 dst = cycles(dst, BUS); 3150 cycles(&opts->gen, BUS);
3548 break; 3151 break;
3549 case M68K_NOT: 3152 case M68K_NOT:
3550 if (dst_op.mode == MODE_REG_DIRECT) { 3153 if (dst_op.mode == MODE_REG_DIRECT) {
3551 dst = not_r(dst, dst_op.base, inst->extra.size); 3154 not_r(code, dst_op.base, inst->extra.size);
3552 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3155 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3553 } else { 3156 } else {
3554 dst = not_rdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3157 not_rdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3555 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3158 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
3556 } 3159 }
3557 3160
3558 dst = set_flag(dst, 0, FLAG_C, opts); 3161 set_flag(opts, 0, FLAG_C);
3559 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3162 set_flag_cond(opts, CC_Z, FLAG_Z);
3560 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3163 set_flag_cond(opts, CC_S, FLAG_N);
3561 dst = set_flag(dst, 0, FLAG_V, opts); 3164 set_flag(opts, 0, FLAG_V);
3562 dst = m68k_save_result(inst, dst, opts); 3165 m68k_save_result(inst, opts);
3563 break; 3166 break;
3564 case M68K_OR: 3167 case M68K_OR:
3565 dst = cycles(dst, BUS); 3168 cycles(&opts->gen, BUS);
3566 if (src_op.mode == MODE_REG_DIRECT) { 3169 if (src_op.mode == MODE_REG_DIRECT) {
3567 if (dst_op.mode == MODE_REG_DIRECT) { 3170 if (dst_op.mode == MODE_REG_DIRECT) {
3568 dst = or_rr(dst, src_op.base, dst_op.base, inst->extra.size); 3171 or_rr(code, src_op.base, dst_op.base, inst->extra.size);
3569 } else { 3172 } else {
3570 dst = or_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 3173 or_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
3571 } 3174 }
3572 } else if (src_op.mode == MODE_REG_DISPLACE8) { 3175 } else if (src_op.mode == MODE_REG_DISPLACE8) {
3573 dst = or_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 3176 or_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
3574 } else { 3177 } else {
3575 if (dst_op.mode == MODE_REG_DIRECT) { 3178 if (dst_op.mode == MODE_REG_DIRECT) {
3576 dst = or_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3179 or_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3577 } else { 3180 } else {
3578 dst = or_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3181 or_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3579 } 3182 }
3580 } 3183 }
3581 dst = set_flag(dst, 0, FLAG_C, opts); 3184 set_flag(opts, 0, FLAG_C);
3582 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3185 set_flag_cond(opts, CC_Z, FLAG_Z);
3583 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3186 set_flag_cond(opts, CC_S, FLAG_N);
3584 dst = set_flag(dst, 0, FLAG_V, opts); 3187 set_flag(opts, 0, FLAG_V);
3585 dst = m68k_save_result(inst, dst, opts); 3188 m68k_save_result(inst, opts);
3586 break; 3189 break;
3587 case M68K_ORI_CCR: 3190 case M68K_ORI_CCR:
3588 case M68K_ORI_SR: 3191 case M68K_ORI_SR:
3589 dst = cycles(dst, 20); 3192 cycles(&opts->gen, 20);
3590 //TODO: If ANDI to SR, trap if not in supervisor mode 3193 //TODO: If ANDI to SR, trap if not in supervisor mode
3591 if (inst->src.params.immed & 0x1) { 3194 if (inst->src.params.immed & 0x1) {
3592 dst = set_flag(dst, 1, FLAG_C, opts); 3195 set_flag(opts, 1, FLAG_C);
3593 } 3196 }
3594 if (inst->src.params.immed & 0x2) { 3197 if (inst->src.params.immed & 0x2) {
3595 dst = set_flag(dst, 1, FLAG_V, opts); 3198 set_flag(opts, 1, FLAG_V);
3596 } 3199 }
3597 if (inst->src.params.immed & 0x4) { 3200 if (inst->src.params.immed & 0x4) {
3598 dst = set_flag(dst, 1, FLAG_Z, opts); 3201 set_flag(opts, 1, FLAG_Z);
3599 } 3202 }
3600 if (inst->src.params.immed & 0x8) { 3203 if (inst->src.params.immed & 0x8) {
3601 dst = set_flag(dst, 1, FLAG_N, opts); 3204 set_flag(opts, 1, FLAG_N);
3602 } 3205 }
3603 if (inst->src.params.immed & 0x10) { 3206 if (inst->src.params.immed & 0x10) {
3604 dst = set_flag(dst, 1, FLAG_X, opts); 3207 set_flag(opts, 1, FLAG_X);
3605 } 3208 }
3606 if (inst->op == M68K_ORI_SR) { 3209 if (inst->op == M68K_ORI_SR) {
3607 dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); 3210 or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3608 if (inst->src.params.immed & 0x700) { 3211 if (inst->src.params.immed & 0x700) {
3609 dst = call(dst, opts->do_sync); 3212 call(code, opts->do_sync);
3610 } 3213 }
3611 } 3214 }
3612 break; 3215 break;
3613 case M68K_RESET: 3216 case M68K_RESET:
3614 dst = call(dst, opts->gen.save_context); 3217 call(code, opts->gen.save_context);
3615 #ifdef X86_64 3218 #ifdef X86_64
3616 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 3219 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
3617 #else 3220 #else
3618 dst = push_r(dst, CONTEXT); 3221 push_r(code, opts->gen.context_reg);
3619 #endif 3222 #endif
3620 dst = call(dst, (code_ptr)print_regs_exit); 3223 call(code, (code_ptr)print_regs_exit);
3621 break; 3224 break;
3622 case M68K_ROL: 3225 case M68K_ROL:
3623 case M68K_ROR: 3226 case M68K_ROR:
3624 dst = set_flag(dst, 0, FLAG_V, opts); 3227 set_flag(opts, 0, FLAG_V);
3625 if (inst->src.addr_mode == MODE_UNUSED) { 3228 if (inst->src.addr_mode == MODE_UNUSED) {
3626 dst = cycles(dst, BUS); 3229 cycles(&opts->gen, BUS);
3627 //Memory rotate 3230 //Memory rotate
3628 if (inst->op == M68K_ROL) { 3231 if (inst->op == M68K_ROL) {
3629 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size); 3232 rol_ir(code, 1, dst_op.base, inst->extra.size);
3630 } else { 3233 } else {
3631 dst = ror_ir(dst, 1, dst_op.base, inst->extra.size); 3234 ror_ir(code, 1, dst_op.base, inst->extra.size);
3632 } 3235 }
3633 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3236 set_flag_cond(opts, CC_C, FLAG_C);
3634 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3237 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3635 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3238 set_flag_cond(opts, CC_Z, FLAG_Z);
3636 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3239 set_flag_cond(opts, CC_S, FLAG_N);
3637 dst = m68k_save_result(inst, dst, opts); 3240 m68k_save_result(inst, opts);
3638 } else { 3241 } else {
3639 if (src_op.mode == MODE_IMMED) { 3242 if (src_op.mode == MODE_IMMED) {
3640 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2); 3243 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2);
3641 if (dst_op.mode == MODE_REG_DIRECT) { 3244 if (dst_op.mode == MODE_REG_DIRECT) {
3642 if (inst->op == M68K_ROL) { 3245 if (inst->op == M68K_ROL) {
3643 dst = rol_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3246 rol_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3644 } else { 3247 } else {
3645 dst = ror_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3248 ror_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3646 } 3249 }
3647 } else { 3250 } else {
3648 if (inst->op == M68K_ROL) { 3251 if (inst->op == M68K_ROL) {
3649 dst = rol_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3252 rol_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3650 } else { 3253 } else {
3651 dst = ror_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3254 ror_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3652 } 3255 }
3653 } 3256 }
3654 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3257 set_flag_cond(opts, CC_C, FLAG_C);
3655 } else { 3258 } else {
3656 if (src_op.mode == MODE_REG_DIRECT) { 3259 if (src_op.mode == MODE_REG_DIRECT) {
3657 if (src_op.base != SCRATCH1) { 3260 if (src_op.base != opts->gen.scratch1) {
3658 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); 3261 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_B);
3659 } 3262 }
3660 } else { 3263 } else {
3661 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); 3264 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B);
3662 } 3265 }
3663 dst = and_ir(dst, 63, SCRATCH1, SZ_D); 3266 and_ir(code, 63, opts->gen.scratch1, SZ_D);
3664 zero_off = dst+1; 3267 zero_off = code->cur + 1;
3665 dst = jcc(dst, CC_Z, dst+2); 3268 jcc(code, CC_Z, code->cur + 2);
3666 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3269 add_rr(code, opts->gen.scratch1, CYCLES, SZ_D);
3667 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3270 add_rr(code, opts->gen.scratch1, CYCLES, SZ_D);
3668 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B); 3271 cmp_ir(code, 32, opts->gen.scratch1, SZ_B);
3669 norm_off = dst+1; 3272 norm_off = code->cur + 1;
3670 dst = jcc(dst, CC_L, dst+2); 3273 jcc(code, CC_L, code->cur + 2);
3671 dst = sub_ir(dst, 32, SCRATCH1, SZ_B); 3274 sub_ir(code, 32, opts->gen.scratch1, SZ_B);
3672 if (dst_op.mode == MODE_REG_DIRECT) { 3275 if (dst_op.mode == MODE_REG_DIRECT) {
3673 if (inst->op == M68K_ROL) { 3276 if (inst->op == M68K_ROL) {
3674 dst = rol_ir(dst, 31, dst_op.base, inst->extra.size); 3277 rol_ir(code, 31, dst_op.base, inst->extra.size);
3675 dst = rol_ir(dst, 1, dst_op.base, inst->extra.size); 3278 rol_ir(code, 1, dst_op.base, inst->extra.size);
3676 } else { 3279 } else {
3677 dst = ror_ir(dst, 31, dst_op.base, inst->extra.size); 3280 ror_ir(code, 31, dst_op.base, inst->extra.size);
3678 dst = ror_ir(dst, 1, dst_op.base, inst->extra.size); 3281 ror_ir(code, 1, dst_op.base, inst->extra.size);
3679 } 3282 }
3680 } else { 3283 } else {
3681 if (inst->op == M68K_ROL) { 3284 if (inst->op == M68K_ROL) {
3682 dst = rol_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3285 rol_irdisp(code, 31, dst_op.base, dst_op.disp, inst->extra.size);
3683 dst = rol_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3286 rol_irdisp(code, 1, dst_op.base, dst_op.disp, inst->extra.size);
3684 } else { 3287 } else {
3685 dst = ror_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3288 ror_irdisp(code, 31, dst_op.base, dst_op.disp, inst->extra.size);
3686 dst = ror_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3289 ror_irdisp(code, 1, dst_op.base, dst_op.disp, inst->extra.size);
3687 } 3290 }
3688 } 3291 }
3689 *norm_off = dst - (norm_off+1); 3292 *norm_off = code->cur - (norm_off+1);
3690 if (dst_op.mode == MODE_REG_DIRECT) { 3293 if (dst_op.mode == MODE_REG_DIRECT) {
3691 if (inst->op == M68K_ROL) { 3294 if (inst->op == M68K_ROL) {
3692 dst = rol_clr(dst, dst_op.base, inst->extra.size); 3295 rol_clr(code, dst_op.base, inst->extra.size);
3693 } else { 3296 } else {
3694 dst = ror_clr(dst, dst_op.base, inst->extra.size); 3297 ror_clr(code, dst_op.base, inst->extra.size);
3695 } 3298 }
3696 } else { 3299 } else {
3697 if (inst->op == M68K_ROL) { 3300 if (inst->op == M68K_ROL) {
3698 dst = rol_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3301 rol_clrdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3699 } else { 3302 } else {
3700 dst = ror_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3303 ror_clrdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3701 } 3304 }
3702 } 3305 }
3703 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3306 set_flag_cond(opts, CC_C, FLAG_C);
3704 end_off = dst + 1; 3307 end_off = code->cur + 1;
3705 dst = jmp(dst, dst+2); 3308 jmp(code, code->cur + 2);
3706 *zero_off = dst - (zero_off+1); 3309 *zero_off = code->cur - (zero_off+1);
3707 dst = set_flag(dst, 0, FLAG_C, opts); 3310 set_flag(opts, 0, FLAG_C);
3708 *end_off = dst - (end_off+1); 3311 *end_off = code->cur - (end_off+1);
3709 } 3312 }
3710 if (dst_op.mode == MODE_REG_DIRECT) { 3313 if (dst_op.mode == MODE_REG_DIRECT) {
3711 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3314 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3712 } else { 3315 } else {
3713 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3316 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
3714 } 3317 }
3715 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3318 set_flag_cond(opts, CC_Z, FLAG_Z);
3716 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3319 set_flag_cond(opts, CC_S, FLAG_N);
3717 } 3320 }
3718 break; 3321 break;
3719 case M68K_ROXL: 3322 case M68K_ROXL:
3720 case M68K_ROXR: 3323 case M68K_ROXR:
3721 dst = set_flag(dst, 0, FLAG_V, opts); 3324 set_flag(opts, 0, FLAG_V);
3722 if (inst->src.addr_mode == MODE_UNUSED) { 3325 if (inst->src.addr_mode == MODE_UNUSED) {
3723 dst = cycles(dst, BUS); 3326 cycles(&opts->gen, BUS);
3724 //Memory rotate 3327 //Memory rotate
3725 dst = flag_to_carry(dst, FLAG_X, opts); 3328 flag_to_carry(opts, FLAG_X);
3726 if (inst->op == M68K_ROXL) { 3329 if (inst->op == M68K_ROXL) {
3727 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size); 3330 rcl_ir(code, 1, dst_op.base, inst->extra.size);
3728 } else { 3331 } else {
3729 dst = rcr_ir(dst, 1, dst_op.base, inst->extra.size); 3332 rcr_ir(code, 1, dst_op.base, inst->extra.size);
3730 } 3333 }
3731 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3334 set_flag_cond(opts, CC_C, FLAG_C);
3732 if (opts->flag_regs[FLAG_C] < 0) { 3335 if (opts->flag_regs[FLAG_C] < 0) {
3733 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3336 set_flag_cond(opts, CC_C, FLAG_X);
3734 } 3337 }
3735 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3338 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3736 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3339 set_flag_cond(opts, CC_Z, FLAG_Z);
3737 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3340 set_flag_cond(opts, CC_S, FLAG_N);
3738 if (opts->flag_regs[FLAG_C] >= 0) { 3341 if (opts->flag_regs[FLAG_C] >= 0) {
3739 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3342 flag_to_flag(opts, FLAG_C, FLAG_X);
3740 } 3343 }
3741 dst = m68k_save_result(inst, dst, opts); 3344 m68k_save_result(inst, opts);
3742 } else { 3345 } else {
3743 if (src_op.mode == MODE_IMMED) { 3346 if (src_op.mode == MODE_IMMED) {
3744 dst = cycles(dst, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2); 3347 cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op.disp*2);
3745 dst = flag_to_carry(dst, FLAG_X, opts); 3348 flag_to_carry(opts, FLAG_X);
3746 if (dst_op.mode == MODE_REG_DIRECT) { 3349 if (dst_op.mode == MODE_REG_DIRECT) {
3747 if (inst->op == M68K_ROXL) { 3350 if (inst->op == M68K_ROXL) {
3748 dst = rcl_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3351 rcl_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3749 } else { 3352 } else {
3750 dst = rcr_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3353 rcr_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3751 } 3354 }
3752 } else { 3355 } else {
3753 if (inst->op == M68K_ROXL) { 3356 if (inst->op == M68K_ROXL) {
3754 dst = rcl_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3357 rcl_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3755 } else { 3358 } else {
3756 dst = rcr_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3359 rcr_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3757 } 3360 }
3758 } 3361 }
3759 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3362 set_flag_cond(opts, CC_C, FLAG_C);
3760 if (opts->flag_regs[FLAG_C] >= 0) { 3363 if (opts->flag_regs[FLAG_C] >= 0) {
3761 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3364 flag_to_flag(opts, FLAG_C, FLAG_X);
3762 } else { 3365 } else {
3763 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3366 set_flag_cond(opts, CC_C, FLAG_X);
3764 } 3367 }
3765 } else { 3368 } else {
3766 if (src_op.mode == MODE_REG_DIRECT) { 3369 if (src_op.mode == MODE_REG_DIRECT) {
3767 if (src_op.base != SCRATCH1) { 3370 if (src_op.base != opts->gen.scratch1) {
3768 dst = mov_rr(dst, src_op.base, SCRATCH1, SZ_B); 3371 mov_rr(code, src_op.base, opts->gen.scratch1, SZ_B);
3769 } 3372 }
3770 } else { 3373 } else {
3771 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_B); 3374 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_B);
3772 } 3375 }
3773 dst = and_ir(dst, 63, SCRATCH1, SZ_D); 3376 and_ir(code, 63, opts->gen.scratch1, SZ_D);
3774 zero_off = dst+1; 3377 zero_off = code->cur + 1;
3775 dst = jcc(dst, CC_Z, dst+2); 3378 jcc(code, CC_Z, code->cur + 2);
3776 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3379 add_rr(code, opts->gen.scratch1, CYCLES, SZ_D);
3777 dst = add_rr(dst, SCRATCH1, CYCLES, SZ_D); 3380 add_rr(code, opts->gen.scratch1, CYCLES, SZ_D);
3778 dst = cmp_ir(dst, 32, SCRATCH1, SZ_B); 3381 cmp_ir(code, 32, opts->gen.scratch1, SZ_B);
3779 norm_off = dst+1; 3382 norm_off = code->cur + 1;
3780 dst = jcc(dst, CC_L, dst+2); 3383 jcc(code, CC_L, code->cur + 2);
3781 dst = flag_to_carry(dst, FLAG_X, opts); 3384 flag_to_carry(opts, FLAG_X);
3782 if (dst_op.mode == MODE_REG_DIRECT) { 3385 if (dst_op.mode == MODE_REG_DIRECT) {
3783 if (inst->op == M68K_ROXL) { 3386 if (inst->op == M68K_ROXL) {
3784 dst = rcl_ir(dst, 31, dst_op.base, inst->extra.size); 3387 rcl_ir(code, 31, dst_op.base, inst->extra.size);
3785 dst = rcl_ir(dst, 1, dst_op.base, inst->extra.size); 3388 rcl_ir(code, 1, dst_op.base, inst->extra.size);
3786 } else { 3389 } else {
3787 dst = rcr_ir(dst, 31, dst_op.base, inst->extra.size); 3390 rcr_ir(code, 31, dst_op.base, inst->extra.size);
3788 dst = rcr_ir(dst, 1, dst_op.base, inst->extra.size); 3391 rcr_ir(code, 1, dst_op.base, inst->extra.size);
3789 } 3392 }
3790 } else { 3393 } else {
3791 if (inst->op == M68K_ROXL) { 3394 if (inst->op == M68K_ROXL) {
3792 dst = rcl_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3395 rcl_irdisp(code, 31, dst_op.base, dst_op.disp, inst->extra.size);
3793 dst = rcl_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3396 rcl_irdisp(code, 1, dst_op.base, dst_op.disp, inst->extra.size);
3794 } else { 3397 } else {
3795 dst = rcr_irdisp8(dst, 31, dst_op.base, dst_op.disp, inst->extra.size); 3398 rcr_irdisp(code, 31, dst_op.base, dst_op.disp, inst->extra.size);
3796 dst = rcr_irdisp8(dst, 1, dst_op.base, dst_op.disp, inst->extra.size); 3399 rcr_irdisp(code, 1, dst_op.base, dst_op.disp, inst->extra.size);
3797 } 3400 }
3798 } 3401 }
3799 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3402 set_flag_cond(opts, CC_C, FLAG_X);
3800 dst = sub_ir(dst, 32, SCRATCH1, SZ_B); 3403 sub_ir(code, 32, opts->gen.scratch1, SZ_B);
3801 *norm_off = dst - (norm_off+1); 3404 *norm_off = code->cur - (norm_off+1);
3802 dst = flag_to_carry(dst, FLAG_X, opts); 3405 flag_to_carry(opts, FLAG_X);
3803 if (dst_op.mode == MODE_REG_DIRECT) { 3406 if (dst_op.mode == MODE_REG_DIRECT) {
3804 if (inst->op == M68K_ROXL) { 3407 if (inst->op == M68K_ROXL) {
3805 dst = rcl_clr(dst, dst_op.base, inst->extra.size); 3408 rcl_clr(code, dst_op.base, inst->extra.size);
3806 } else { 3409 } else {
3807 dst = rcr_clr(dst, dst_op.base, inst->extra.size); 3410 rcr_clr(code, dst_op.base, inst->extra.size);
3808 } 3411 }
3809 } else { 3412 } else {
3810 if (inst->op == M68K_ROXL) { 3413 if (inst->op == M68K_ROXL) {
3811 dst = rcl_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3414 rcl_clrdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3812 } else { 3415 } else {
3813 dst = rcr_clrdisp8(dst, dst_op.base, dst_op.disp, inst->extra.size); 3416 rcr_clrdisp(code, dst_op.base, dst_op.disp, inst->extra.size);
3814 } 3417 }
3815 } 3418 }
3816 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3419 set_flag_cond(opts, CC_C, FLAG_C);
3817 if (opts->flag_regs[FLAG_C] >= 0) { 3420 if (opts->flag_regs[FLAG_C] >= 0) {
3818 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3421 flag_to_flag(opts, FLAG_C, FLAG_X);
3819 } else { 3422 } else {
3820 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3423 set_flag_cond(opts, CC_C, FLAG_X);
3821 } 3424 }
3822 end_off = dst + 1; 3425 end_off = code->cur + 1;
3823 dst = jmp(dst, dst+2); 3426 jmp(code, code->cur + 2);
3824 *zero_off = dst - (zero_off+1); 3427 *zero_off = code->cur - (zero_off+1);
3825 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL 3428 //Carry flag is set to X flag when count is 0, this is different from ROR/ROL
3826 dst = flag_to_flag(dst, FLAG_X, FLAG_C, opts); 3429 flag_to_flag(opts, FLAG_X, FLAG_C);
3827 *end_off = dst - (end_off+1); 3430 *end_off = code->cur - (end_off+1);
3828 } 3431 }
3829 if (dst_op.mode == MODE_REG_DIRECT) { 3432 if (dst_op.mode == MODE_REG_DIRECT) {
3830 dst = cmp_ir(dst, 0, dst_op.base, inst->extra.size); 3433 cmp_ir(code, 0, dst_op.base, inst->extra.size);
3831 } else { 3434 } else {
3832 dst = cmp_irdisp8(dst, 0, dst_op.base, dst_op.disp, inst->extra.size); 3435 cmp_irdisp(code, 0, dst_op.base, dst_op.disp, inst->extra.size);
3833 } 3436 }
3834 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3437 set_flag_cond(opts, CC_Z, FLAG_Z);
3835 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3438 set_flag_cond(opts, CC_S, FLAG_N);
3836 } 3439 }
3837 break; 3440 break;
3838 case M68K_RTE: 3441 case M68K_RTE:
3839 //TODO: Trap if not in system mode 3442 //TODO: Trap if not in system mode
3840 //Read saved SR 3443 //Read saved SR
3841 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3444 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3842 dst = call(dst, opts->read_16); 3445 call(code, opts->read_16);
3843 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3446 add_ir(code, 2, opts->aregs[7], SZ_D);
3844 dst = call(dst, opts->set_sr); 3447 call(code, opts->set_sr);
3845 //Read saved PC 3448 //Read saved PC
3846 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3449 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3847 dst = call(dst, opts->read_32); 3450 call(code, opts->read_32);
3848 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3451 add_ir(code, 4, opts->aregs[7], SZ_D);
3849 //Check if we've switched to user mode and swap stack pointers if needed 3452 //Check if we've switched to user mode and swap stack pointers if needed
3850 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 3453 bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3851 end_off = dst+1; 3454 end_off = code->cur + 1;
3852 dst = jcc(dst, CC_C, dst+2); 3455 jcc(code, CC_C, code->cur + 2);
3853 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 3456 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
3854 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3457 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3855 dst = mov_rrdisp8(dst, SCRATCH2, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3458 mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3856 *end_off = dst - (end_off+1); 3459 *end_off = code->cur - (end_off+1);
3857 //Get native address, sync components, recalculate integer points and jump to returned address 3460 //Get native address, sync components, recalculate integer points and jump to returned address
3858 dst = call(dst, opts->native_addr_and_sync); 3461 call(code, opts->native_addr_and_sync);
3859 dst = jmp_r(dst, SCRATCH1); 3462 jmp_r(code, opts->gen.scratch1);
3860 break; 3463 break;
3861 case M68K_RTR: 3464 case M68K_RTR:
3862 //Read saved CCR 3465 //Read saved CCR
3863 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3466 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3864 dst = call(dst, opts->read_16); 3467 call(code, opts->read_16);
3865 dst = add_ir(dst, 2, opts->aregs[7], SZ_D); 3468 add_ir(code, 2, opts->aregs[7], SZ_D);
3866 dst = call(dst, opts->set_ccr); 3469 call(code, opts->set_ccr);
3867 //Read saved PC 3470 //Read saved PC
3868 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3471 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3869 dst = call(dst, opts->read_32); 3472 call(code, opts->read_32);
3870 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3473 add_ir(code, 4, opts->aregs[7], SZ_D);
3871 //Get native address and jump to it 3474 //Get native address and jump to it
3872 dst = call(dst, opts->native_addr); 3475 call(code, opts->native_addr);
3873 dst = jmp_r(dst, SCRATCH1); 3476 jmp_r(code, opts->gen.scratch1);
3874 break; 3477 break;
3875 case M68K_SBCD: { 3478 case M68K_SBCD: {
3876 if (src_op.base != SCRATCH2) { 3479 if (src_op.base != opts->gen.scratch2) {
3877 if (src_op.mode == MODE_REG_DIRECT) { 3480 if (src_op.mode == MODE_REG_DIRECT) {
3878 dst = mov_rr(dst, src_op.base, SCRATCH2, SZ_B); 3481 mov_rr(code, src_op.base, opts->gen.scratch2, SZ_B);
3879 } else { 3482 } else {
3880 dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH2, SZ_B); 3483 mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch2, SZ_B);
3881 } 3484 }
3882 } 3485 }
3883 if (dst_op.base != SCRATCH1) { 3486 if (dst_op.base != opts->gen.scratch1) {
3884 if (dst_op.mode == MODE_REG_DIRECT) { 3487 if (dst_op.mode == MODE_REG_DIRECT) {
3885 dst = mov_rr(dst, dst_op.base, SCRATCH1, SZ_B); 3488 mov_rr(code, dst_op.base, opts->gen.scratch1, SZ_B);
3886 } else { 3489 } else {
3887 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, SCRATCH1, SZ_B); 3490 mov_rdispr(code, dst_op.base, dst_op.disp, opts->gen.scratch1, SZ_B);
3888 } 3491 }
3889 } 3492 }
3890 dst = flag_to_carry(dst, FLAG_X, opts); 3493 flag_to_carry(opts, FLAG_X);
3891 dst = jcc(dst, CC_NC, dst+5); 3494 jcc(code, CC_NC, code->cur + 5);
3892 dst = sub_ir(dst, 1, SCRATCH1, SZ_B); 3495 sub_ir(code, 1, opts->gen.scratch1, SZ_B);
3893 dst = call(dst, (code_ptr)bcd_sub); 3496 call(code, (code_ptr)bcd_sub);
3894 dst = reg_to_flag(dst, CH, FLAG_C, opts); 3497 reg_to_flag(opts, CH, FLAG_C);
3895 dst = reg_to_flag(dst, CH, FLAG_X, opts); 3498 reg_to_flag(opts, CH, FLAG_X);
3896 dst = cmp_ir(dst, 0, SCRATCH1, SZ_B); 3499 cmp_ir(code, 0, opts->gen.scratch1, SZ_B);
3897 code_ptr after_flag_set = dst+1; 3500 code_ptr after_flag_set = code->cur+1;
3898 dst = jcc(dst, CC_Z, dst+2); 3501 jcc(code, CC_Z, code->cur + 2);
3899 dst = set_flag(dst, 0, FLAG_Z, opts); 3502 set_flag(opts, 0, FLAG_Z);
3900 *after_flag_set = dst - (after_flag_set+1); 3503 *after_flag_set = code->cur - (after_flag_set+1);
3901 if (dst_op.base != SCRATCH1) { 3504 if (dst_op.base != opts->gen.scratch1) {
3902 if (dst_op.mode == MODE_REG_DIRECT) { 3505 if (dst_op.mode == MODE_REG_DIRECT) {
3903 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_B); 3506 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_B);
3904 } else { 3507 } else {
3905 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_B); 3508 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_B);
3906 } 3509 }
3907 } 3510 }
3908 dst = m68k_save_result(inst, dst, opts); 3511 m68k_save_result(inst, opts);
3909 break; 3512 break;
3910 } 3513 }
3911 case M68K_STOP: { 3514 case M68K_STOP: {
3912 //TODO: Trap if not in system mode 3515 //TODO: Trap if not in system mode
3913 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction 3516 //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction
3914 //possibly even 12 since that's how long MOVE to SR takes 3517 //possibly even 12 since that's how long MOVE to SR takes
3915 dst = cycles(dst, BUS*2); 3518 cycles(&opts->gen, BUS*2);
3916 dst = set_flag(dst, src_op.disp & 0x1, FLAG_C, opts); 3519 set_flag(opts, src_op.disp & 0x1, FLAG_C);
3917 dst = set_flag(dst, (src_op.disp >> 1) & 0x1, FLAG_V, opts); 3520 set_flag(opts, (src_op.disp >> 1) & 0x1, FLAG_V);
3918 dst = set_flag(dst, (src_op.disp >> 2) & 0x1, FLAG_Z, opts); 3521 set_flag(opts, (src_op.disp >> 2) & 0x1, FLAG_Z);
3919 dst = set_flag(dst, (src_op.disp >> 3) & 0x1, FLAG_N, opts); 3522 set_flag(opts, (src_op.disp >> 3) & 0x1, FLAG_N);
3920 dst = set_flag(dst, (src_op.disp >> 4) & 0x1, FLAG_X, opts); 3523 set_flag(opts, (src_op.disp >> 4) & 0x1, FLAG_X);
3921 dst = mov_irdisp8(dst, (src_op.disp >> 8), CONTEXT, offsetof(m68k_context, status), SZ_B); 3524 mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
3922 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { 3525 if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) {
3923 //leave supervisor mode 3526 //leave supervisor mode
3924 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3527 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
3925 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); 3528 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D);
3926 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 3529 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
3927 } 3530 }
3928 code_ptr loop_top = dst; 3531 code_ptr loop_top = code->cur;
3929 dst = call(dst, opts->do_sync); 3532 call(code, opts->do_sync);
3930 dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); 3533 cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
3931 code_ptr normal_cycle_up = dst + 1; 3534 code_ptr normal_cycle_up = code->cur + 1;
3932 dst = jcc(dst, CC_A, dst+2); 3535 jcc(code, CC_A, code->cur + 2);
3933 dst = cycles(dst, BUS); 3536 cycles(&opts->gen, BUS);
3934 code_ptr after_cycle_up = dst + 1; 3537 code_ptr after_cycle_up = code->cur + 1;
3935 dst = jmp(dst, dst+2); 3538 jmp(code, code->cur + 2);
3936 *normal_cycle_up = dst - (normal_cycle_up + 1); 3539 *normal_cycle_up = code->cur - (normal_cycle_up + 1);
3937 dst = mov_rr(dst, LIMIT, CYCLES, SZ_D); 3540 mov_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D);
3938 *after_cycle_up = dst - (after_cycle_up+1); 3541 *after_cycle_up = code->cur - (after_cycle_up+1);
3939 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 3542 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D);
3940 dst = jcc(dst, CC_C, loop_top); 3543 jcc(code, CC_C, loop_top);
3941 break; 3544 break;
3942 } 3545 }
3943 case M68K_SUB: 3546 case M68K_SUB:
3944 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; 3547 size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size;
3945 dst = cycles(dst, BUS); 3548 cycles(&opts->gen, BUS);
3946 if (src_op.mode == MODE_REG_DIRECT) { 3549 if (src_op.mode == MODE_REG_DIRECT) {
3947 if (dst_op.mode == MODE_REG_DIRECT) { 3550 if (dst_op.mode == MODE_REG_DIRECT) {
3948 dst = sub_rr(dst, src_op.base, dst_op.base, size); 3551 sub_rr(code, src_op.base, dst_op.base, size);
3949 } else { 3552 } else {
3950 dst = sub_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, size); 3553 sub_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size);
3951 } 3554 }
3952 } else if (src_op.mode == MODE_REG_DISPLACE8) { 3555 } else if (src_op.mode == MODE_REG_DISPLACE8) {
3953 dst = sub_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, size); 3556 sub_rdispr(code, src_op.base, src_op.disp, dst_op.base, size);
3954 } else { 3557 } else {
3955 if (dst_op.mode == MODE_REG_DIRECT) { 3558 if (dst_op.mode == MODE_REG_DIRECT) {
3956 dst = sub_ir(dst, src_op.disp, dst_op.base, size); 3559 sub_ir(code, src_op.disp, dst_op.base, size);
3957 } else { 3560 } else {
3958 dst = sub_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, size); 3561 sub_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, size);
3959 } 3562 }
3960 } 3563 }
3961 if (inst->dst.addr_mode != MODE_AREG) { 3564 if (inst->dst.addr_mode != MODE_AREG) {
3962 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3565 set_flag_cond(opts, CC_C, FLAG_C);
3963 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3566 set_flag_cond(opts, CC_Z, FLAG_Z);
3964 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3567 set_flag_cond(opts, CC_S, FLAG_N);
3965 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 3568 set_flag_cond(opts, CC_O, FLAG_V);
3966 if (opts->flag_regs[FLAG_C] >= 0) { 3569 if (opts->flag_regs[FLAG_C] >= 0) {
3967 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3570 flag_to_flag(opts, FLAG_C, FLAG_X);
3968 } else { 3571 } else {
3969 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3572 set_flag_cond(opts, CC_C, FLAG_X);
3970 } 3573 }
3971 } 3574 }
3972 dst = m68k_save_result(inst, dst, opts); 3575 m68k_save_result(inst, opts);
3973 break; 3576 break;
3974 case M68K_SUBX: { 3577 case M68K_SUBX: {
3975 dst = cycles(dst, BUS); 3578 cycles(&opts->gen, BUS);
3976 dst = flag_to_carry(dst, FLAG_X, opts); 3579 flag_to_carry(opts, FLAG_X);
3977 if (src_op.mode == MODE_REG_DIRECT) { 3580 if (src_op.mode == MODE_REG_DIRECT) {
3978 if (dst_op.mode == MODE_REG_DIRECT) { 3581 if (dst_op.mode == MODE_REG_DIRECT) {
3979 dst = sbb_rr(dst, src_op.base, dst_op.base, inst->extra.size); 3582 sbb_rr(code, src_op.base, dst_op.base, inst->extra.size);
3980 } else { 3583 } else {
3981 dst = sbb_rrdisp8(dst, src_op.base, dst_op.base, dst_op.disp, inst->extra.size); 3584 sbb_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, inst->extra.size);
3982 } 3585 }
3983 } else if (src_op.mode == MODE_REG_DISPLACE8) { 3586 } else if (src_op.mode == MODE_REG_DISPLACE8) {
3984 dst = sbb_rdisp8r(dst, src_op.base, src_op.disp, dst_op.base, inst->extra.size); 3587 sbb_rdispr(code, src_op.base, src_op.disp, dst_op.base, inst->extra.size);
3985 } else { 3588 } else {
3986 if (dst_op.mode == MODE_REG_DIRECT) { 3589 if (dst_op.mode == MODE_REG_DIRECT) {
3987 dst = sbb_ir(dst, src_op.disp, dst_op.base, inst->extra.size); 3590 sbb_ir(code, src_op.disp, dst_op.base, inst->extra.size);
3988 } else { 3591 } else {
3989 dst = sbb_irdisp8(dst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); 3592 sbb_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size);
3990 } 3593 }
3991 } 3594 }
3992 dst = set_flag_cond(dst, CC_C, FLAG_C, opts); 3595 set_flag_cond(opts, CC_C, FLAG_C);
3993 if (opts->flag_regs[FLAG_C] < 0) { 3596 if (opts->flag_regs[FLAG_C] < 0) {
3994 dst = set_flag_cond(dst, CC_C, FLAG_X, opts); 3597 set_flag_cond(opts, CC_C, FLAG_X);
3995 } 3598 }
3996 code_ptr after_flag_set = dst+1; 3599 code_ptr after_flag_set = code->cur + 1;
3997 dst = jcc(dst, CC_Z, dst+2); 3600 jcc(code, CC_Z, code->cur + 2);
3998 dst = set_flag(dst, 0, FLAG_Z, opts); 3601 set_flag(opts, 0, FLAG_Z);
3999 *after_flag_set = dst - (after_flag_set+1); 3602 *after_flag_set = code->cur - (after_flag_set+1);
4000 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3603 set_flag_cond(opts, CC_S, FLAG_N);
4001 dst = set_flag_cond(dst, CC_O, FLAG_V, opts); 3604 set_flag_cond(opts, CC_O, FLAG_V);
4002 if (opts->flag_regs[FLAG_C] >= 0) { 3605 if (opts->flag_regs[FLAG_C] >= 0) {
4003 dst = flag_to_flag(dst, FLAG_C, FLAG_X, opts); 3606 flag_to_flag(opts, FLAG_C, FLAG_X);
4004 } 3607 }
4005 dst = m68k_save_result(inst, dst, opts); 3608 m68k_save_result(inst, opts);
4006 break; 3609 break;
4007 } 3610 }
4008 case M68K_SWAP: 3611 case M68K_SWAP:
4009 dst = cycles(dst, BUS); 3612 cycles(&opts->gen, BUS);
4010 if (src_op.mode == MODE_REG_DIRECT) { 3613 if (src_op.mode == MODE_REG_DIRECT) {
4011 dst = rol_ir(dst, 16, src_op.base, SZ_D); 3614 rol_ir(code, 16, src_op.base, SZ_D);
4012 dst = cmp_ir(dst, 0, src_op.base, SZ_D); 3615 cmp_ir(code, 0, src_op.base, SZ_D);
4013 } else{ 3616 } else{
4014 dst = rol_irdisp8(dst, 16, src_op.base, src_op.disp, SZ_D); 3617 rol_irdisp(code, 16, src_op.base, src_op.disp, SZ_D);
4015 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, SZ_D); 3618 cmp_irdisp(code, 0, src_op.base, src_op.disp, SZ_D);
4016 } 3619 }
4017 3620
4018 dst = set_flag(dst, 0, FLAG_C, opts); 3621 set_flag(opts, 0, FLAG_C);
4019 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3622 set_flag_cond(opts, CC_Z, FLAG_Z);
4020 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3623 set_flag_cond(opts, CC_S, FLAG_N);
4021 dst = set_flag(dst, 0, FLAG_V, opts); 3624 set_flag(opts, 0, FLAG_V);
4022 break; 3625 break;
4023 //case M68K_TAS: 3626 //case M68K_TAS:
4024 case M68K_TRAP: 3627 case M68K_TRAP:
4025 dst = mov_ir(dst, src_op.disp + VECTOR_TRAP_0, SCRATCH2, SZ_D); 3628 mov_ir(code, src_op.disp + VECTOR_TRAP_0, opts->gen.scratch2, SZ_D);
4026 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 3629 mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
4027 dst = jmp(dst, opts->trap); 3630 jmp(code, opts->trap);
4028 break; 3631 break;
4029 //case M68K_TRAPV: 3632 //case M68K_TRAPV:
4030 case M68K_TST: 3633 case M68K_TST:
4031 dst = cycles(dst, BUS); 3634 cycles(&opts->gen, BUS);
4032 if (src_op.mode == MODE_REG_DIRECT) { 3635 if (src_op.mode == MODE_REG_DIRECT) {
4033 dst = cmp_ir(dst, 0, src_op.base, inst->extra.size); 3636 cmp_ir(code, 0, src_op.base, inst->extra.size);
4034 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8 3637 } else { //M68000 doesn't support immedate operand for tst, so this must be MODE_REG_DISPLACE8
4035 dst = cmp_irdisp8(dst, 0, src_op.base, src_op.disp, inst->extra.size); 3638 cmp_irdisp(code, 0, src_op.base, src_op.disp, inst->extra.size);
4036 } 3639 }
4037 dst = set_flag(dst, 0, FLAG_C, opts); 3640 set_flag(opts, 0, FLAG_C);
4038 dst = set_flag_cond(dst, CC_Z, FLAG_Z, opts); 3641 set_flag_cond(opts, CC_Z, FLAG_Z);
4039 dst = set_flag_cond(dst, CC_S, FLAG_N, opts); 3642 set_flag_cond(opts, CC_S, FLAG_N);
4040 dst = set_flag(dst, 0, FLAG_V, opts); 3643 set_flag(opts, 0, FLAG_V);
4041 break; 3644 break;
4042 case M68K_UNLK: 3645 case M68K_UNLK:
4043 dst = cycles(dst, BUS); 3646 cycles(&opts->gen, BUS);
4044 if (dst_op.mode == MODE_REG_DIRECT) { 3647 if (dst_op.mode == MODE_REG_DIRECT) {
4045 dst = mov_rr(dst, dst_op.base, opts->aregs[7], SZ_D); 3648 mov_rr(code, dst_op.base, opts->aregs[7], SZ_D);
4046 } else { 3649 } else {
4047 dst = mov_rdisp8r(dst, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D); 3650 mov_rdispr(code, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D);
4048 } 3651 }
4049 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 3652 mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D);
4050 dst = call(dst, opts->read_32); 3653 call(code, opts->read_32);
4051 if (dst_op.mode == MODE_REG_DIRECT) { 3654 if (dst_op.mode == MODE_REG_DIRECT) {
4052 dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_D); 3655 mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_D);
4053 } else { 3656 } else {
4054 dst = mov_rrdisp8(dst, SCRATCH1, dst_op.base, dst_op.disp, SZ_D); 3657 mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_D);
4055 } 3658 }
4056 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 3659 add_ir(code, 4, opts->aregs[7], SZ_D);
4057 break; 3660 break;
4058 default: 3661 default:
4059 m68k_disasm(inst, disasm_buf); 3662 m68k_disasm(inst, disasm_buf);
4060 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op); 3663 printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op);
4061 exit(1); 3664 exit(1);
4062 } 3665 }
4063 return dst;
4064 } 3666 }
4065 3667
4066 uint8_t m68k_is_terminal(m68kinst * inst) 3668 uint8_t m68k_is_terminal(m68kinst * inst)
4067 { 3669 {
4068 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP 3670 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP
4077 if (opts->gen.deferred) { 3679 if (opts->gen.deferred) {
4078 translate_m68k_stream(opts->gen.deferred->address, context); 3680 translate_m68k_stream(opts->gen.deferred->address, context);
4079 } 3681 }
4080 } 3682 }
4081 3683
4082 code_ptr translate_m68k_stream(uint32_t address, m68k_context * context) 3684 void translate_m68k_stream(uint32_t address, m68k_context * context)
4083 { 3685 {
4084 m68kinst instbuf; 3686 m68kinst instbuf;
4085 x86_68k_options * opts = context->options; 3687 x86_68k_options * opts = context->options;
4086 code_ptr dst = opts->gen.cur_code; 3688 code_info *code = &opts->gen.code;
4087 code_ptr dst_end = opts->gen.code_end;
4088 address &= 0xFFFFFF; 3689 address &= 0xFFFFFF;
4089 if(get_native_address(opts->gen.native_code_map, address)) { 3690 if(get_native_address(opts->gen.native_code_map, address)) {
4090 return dst; 3691 return;
4091 } 3692 }
4092 char disbuf[1024]; 3693 char disbuf[1024];
4093 uint16_t *encoded, *next; 3694 uint16_t *encoded, *next;
4094 if ((address & 0xFFFFFF) < 0x400000) { 3695 if ((address & 0xFFFFFF) < 0x400000) {
4095 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; 3696 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2;
4102 do { 3703 do {
4103 if (opts->address_log) { 3704 if (opts->address_log) {
4104 fprintf(opts->address_log, "%X\n", address); 3705 fprintf(opts->address_log, "%X\n", address);
4105 } 3706 }
4106 do { 3707 do {
4107 if (dst_end-dst < MAX_NATIVE_SIZE) {
4108 if (dst_end-dst < 5) {
4109 puts("out of code memory, not enough space for jmp to next chunk");
4110 exit(1);
4111 }
4112 size_t size = 1024*1024;
4113 opts->gen.cur_code = alloc_code(&size);
4114 opts->gen.code_end = opts->gen.cur_code + size;
4115 jmp(dst, opts->gen.cur_code);
4116 dst = opts->gen.cur_code;
4117 dst_end = opts->gen.code_end;
4118 }
4119 if (address >= 0x400000 && address < 0xE00000) { 3708 if (address >= 0x400000 && address < 0xE00000) {
4120 dst = xor_rr(dst, RDI, RDI, SZ_D); 3709 xor_rr(code, RDI, RDI, SZ_D);
4121 #ifdef X86_32 3710 #ifdef X86_32
4122 dst = push_r(dst, RDI); 3711 push_r(code, RDI);
4123 #endif 3712 #endif
4124 dst = call(dst, (code_ptr)exit); 3713 call(code, (code_ptr)exit);
4125 break; 3714 break;
4126 } 3715 }
4127 code_ptr existing = get_native_address(opts->gen.native_code_map, address); 3716 code_ptr existing = get_native_address(opts->gen.native_code_map, address);
4128 if (existing) { 3717 if (existing) {
4129 dst = jmp(dst, existing); 3718 jmp(code, existing);
4130 break; 3719 break;
4131 } 3720 }
4132 next = m68k_decode(encoded, &instbuf, address); 3721 next = m68k_decode(encoded, &instbuf, address);
4133 if (instbuf.op == M68K_INVALID) { 3722 if (instbuf.op == M68K_INVALID) {
4134 instbuf.src.params.immed = *encoded; 3723 instbuf.src.params.immed = *encoded;
4136 uint16_t m68k_size = (next-encoded)*2; 3725 uint16_t m68k_size = (next-encoded)*2;
4137 address += m68k_size; 3726 address += m68k_size;
4138 encoded = next; 3727 encoded = next;
4139 //m68k_disasm(&instbuf, disbuf); 3728 //m68k_disasm(&instbuf, disbuf);
4140 //printf("%X: %s\n", instbuf.address, disbuf); 3729 //printf("%X: %s\n", instbuf.address, disbuf);
4141 code_ptr after = translate_m68k(dst, &instbuf, opts); 3730
4142 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); 3731 //make sure the beginning of the code for an instruction is contiguous
4143 dst = after; 3732 check_alloc_code(code, MAX_INST_LEN*4);
3733 code_ptr start = code->cur;
3734 translate_m68k(opts, &instbuf);
3735 code_ptr after = code->cur;
3736 map_native_address(context, instbuf.address, start, m68k_size, after-start);
3737 after;
4144 } while(!m68k_is_terminal(&instbuf)); 3738 } while(!m68k_is_terminal(&instbuf));
4145 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context); 3739 process_deferred(&opts->gen.deferred, context, (native_addr_func)get_native_from_context);
4146 if (opts->gen.deferred) { 3740 if (opts->gen.deferred) {
4147 address = opts->gen.deferred->address; 3741 address = opts->gen.deferred->address;
4148 if ((address & 0xFFFFFF) < 0x400000) { 3742 if ((address & 0xFFFFFF) < 0x400000) {
4155 } 3749 }
4156 } else { 3750 } else {
4157 encoded = NULL; 3751 encoded = NULL;
4158 } 3752 }
4159 } while(encoded != NULL); 3753 } while(encoded != NULL);
4160 opts->gen.cur_code = dst;
4161 return dst;
4162 } 3754 }
4163 3755
4164 code_ptr get_native_address_trans(m68k_context * context, uint32_t address) 3756 code_ptr get_native_address_trans(m68k_context * context, uint32_t address)
4165 { 3757 {
4166 address &= 0xFFFFFF; 3758 address &= 0xFFFFFF;
4173 } 3765 }
4174 3766
4175 void * m68k_retranslate_inst(uint32_t address, m68k_context * context) 3767 void * m68k_retranslate_inst(uint32_t address, m68k_context * context)
4176 { 3768 {
4177 x86_68k_options * opts = context->options; 3769 x86_68k_options * opts = context->options;
3770 code_info *code = &opts->gen.code;
4178 uint8_t orig_size = get_native_inst_size(opts, address); 3771 uint8_t orig_size = get_native_inst_size(opts, address);
4179 code_ptr orig_start = get_native_address(context->native_code_map, address); 3772 code_ptr orig_start = get_native_address(context->native_code_map, address);
4180 uint32_t orig = address; 3773 uint32_t orig = address;
3774 code_info orig_code;
3775 orig_code.cur = orig_start;
3776 orig_code.last = orig_start + orig_size + 5;
4181 address &= 0xFFFF; 3777 address &= 0xFFFF;
4182 code_ptr dst = opts->gen.cur_code;
4183 code_ptr dst_end = opts->gen.code_end;
4184 uint16_t *after, *inst = context->mem_pointers[1] + address/2; 3778 uint16_t *after, *inst = context->mem_pointers[1] + address/2;
4185 m68kinst instbuf; 3779 m68kinst instbuf;
4186 after = m68k_decode(inst, &instbuf, orig); 3780 after = m68k_decode(inst, &instbuf, orig);
4187 if (orig_size != MAX_NATIVE_SIZE) { 3781 if (orig_size != MAX_NATIVE_SIZE) {
4188 if (dst_end - dst < 128) {
4189 size_t size = 1024*1024;
4190 dst = alloc_code(&size);
4191 opts->gen.code_end = dst_end = dst + size;
4192 opts->gen.cur_code = dst;
4193 }
4194 deferred_addr * orig_deferred = opts->gen.deferred; 3782 deferred_addr * orig_deferred = opts->gen.deferred;
4195 code_ptr native_end = translate_m68k(dst, &instbuf, opts); 3783
3784 //make sure the beginning of the code for an instruction is contiguous
3785 check_alloc_code(code, MAX_INST_LEN*4);
3786 code_ptr native_start = code->cur;
3787 translate_m68k(opts, &instbuf);
3788 code_ptr native_end = code->cur;
4196 uint8_t is_terminal = m68k_is_terminal(&instbuf); 3789 uint8_t is_terminal = m68k_is_terminal(&instbuf);
4197 if ((native_end - dst) <= orig_size) { 3790 if ((native_end - native_start) <= orig_size) {
4198 code_ptr native_next; 3791 code_ptr native_next;
4199 if (!is_terminal) { 3792 if (!is_terminal) {
4200 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2); 3793 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2);
4201 } 3794 }
4202 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5))) { 3795 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - native_start)) > 5))) {
4203 remove_deferred_until(&opts->gen.deferred, orig_deferred); 3796 remove_deferred_until(&opts->gen.deferred, orig_deferred);
4204 native_end = translate_m68k(orig_start, &instbuf, opts); 3797 code_info tmp;
3798 tmp.cur = code->cur;
3799 tmp.last = code->last;
3800 code->cur = orig_code.cur;
3801 code->last = orig_code.last;
3802 translate_m68k(opts, &instbuf);
3803 native_end = orig_code.cur = code->cur;
3804 code->cur = tmp.cur;
3805 code->last = tmp.last;
4205 if (!is_terminal) { 3806 if (!is_terminal) {
4206 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) { 3807 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) {
4207 while (native_end < orig_start + orig_size) { 3808 while (orig_code.cur < orig_start + orig_size) {
4208 *(native_end++) = 0x90; //NOP 3809 *(orig_code.cur++) = 0x90; //NOP
4209 } 3810 }
4210 } else { 3811 } else {
4211 jmp(native_end, native_next); 3812 jmp(&orig_code, native_next);
4212 } 3813 }
4213 } 3814 }
4214 m68k_handle_deferred(context); 3815 m68k_handle_deferred(context);
4215 return orig_start; 3816 return orig_start;
4216 } 3817 }
4217 } 3818 }
4218 3819
4219 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); 3820 map_native_address(context, instbuf.address, native_start, (after-inst)*2, MAX_NATIVE_SIZE);
4220 opts->gen.cur_code = dst+MAX_NATIVE_SIZE; 3821
4221 jmp(orig_start, dst); 3822 jmp(&orig_code, native_start);
4222 if (!m68k_is_terminal(&instbuf)) { 3823 if (!m68k_is_terminal(&instbuf)) {
4223 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); 3824 code_ptr native_end = code->cur;
3825 code->cur = native_start + MAX_NATIVE_SIZE;
3826 code_ptr rest = get_native_address_trans(context, orig + (after-inst)*2);
3827 code_ptr tmp = code->cur;
3828 code->cur = native_end;
3829 jmp(code, rest);
3830 code->cur = tmp;
3831 } else {
3832 code->cur = native_start + MAX_NATIVE_SIZE;
4224 } 3833 }
4225 m68k_handle_deferred(context); 3834 m68k_handle_deferred(context);
4226 return dst; 3835 return native_start;
4227 } else { 3836 } else {
4228 dst = translate_m68k(orig_start, &instbuf, opts); 3837 code_info tmp;
3838 tmp.cur = code->cur;
3839 tmp.last = code->last;
3840 code->cur = orig_code.cur;
3841 code->last = orig_code.last;
3842 translate_m68k(opts, &instbuf);
4229 if (!m68k_is_terminal(&instbuf)) { 3843 if (!m68k_is_terminal(&instbuf)) {
4230 dst = jmp(dst, get_native_address_trans(context, orig + (after-inst)*2)); 3844 jmp(code, get_native_address_trans(context, orig + (after-inst)*2));
4231 } 3845 }
3846 code->cur = tmp.cur;
3847 code->last = tmp.last;
4232 m68k_handle_deferred(context); 3848 m68k_handle_deferred(context);
4233 return orig_start; 3849 return orig_start;
4234 } 3850 }
4235 } 3851 }
4236 3852
4237 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) 3853 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context)
4238 { 3854 {
4239 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000); 3855 uint32_t inst_start = get_instruction_start(context->native_code_map, address | 0xFF0000);
4240 if (inst_start) { 3856 if (inst_start) {
3857 x86_68k_options * options = context->options;
3858 code_info *code = &options->gen.code;
4241 code_ptr dst = get_native_address(context->native_code_map, inst_start); 3859 code_ptr dst = get_native_address(context->native_code_map, inst_start);
4242 dst = mov_ir(dst, inst_start, SCRATCH2, SZ_D); 3860 code_info orig;
4243 x86_68k_options * options = context->options; 3861 orig.cur = dst;
3862 orig.last = dst + 128;
3863 mov_ir(&orig, inst_start, options->gen.scratch2, SZ_D);
3864
4244 if (!options->retrans_stub) { 3865 if (!options->retrans_stub) {
4245 if (options->gen.code_end - options->gen.cur_code < 32) { 3866 options->retrans_stub = code->cur;
4246 size_t size = 1024*1024; 3867 call(code, options->gen.save_context);
4247 options->gen.cur_code = alloc_code(&size); 3868 push_r(code, options->gen.context_reg);
4248 options->gen.code_end = options->gen.cur_code + size;
4249 }
4250 code_ptr rdst = options->retrans_stub = options->gen.cur_code;
4251 rdst = call(rdst, options->gen.save_context);
4252 rdst = push_r(rdst, CONTEXT);
4253 #ifdef X86_32 3869 #ifdef X86_32
4254 rdst = push_r(rdst, CONTEXT); 3870 push_r(code, options->gen.context_reg);
4255 rdst = push_r(rdst, SCRATCH2); 3871 push_r(code, options->gen.scratch2);
4256 #endif 3872 #endif
4257 rdst = call(rdst, (code_ptr)m68k_retranslate_inst); 3873 call(code, (code_ptr)m68k_retranslate_inst);
4258 #ifdef X86_32 3874 #ifdef X86_32
4259 rdst = add_ir(rdst, 8, RSP, SZ_D); 3875 add_ir(code, 8, RSP, SZ_D);
4260 #endif 3876 #endif
4261 rdst = pop_r(rdst, CONTEXT); 3877 pop_r(code, options->gen.context_reg);
4262 rdst = mov_rr(rdst, RAX, SCRATCH1, SZ_PTR); 3878 mov_rr(code, RAX, options->gen.scratch1, SZ_PTR);
4263 rdst = call(rdst, options->gen.load_context); 3879 call(code, options->gen.load_context);
4264 rdst = jmp_r(rdst, SCRATCH1); 3880 jmp_r(code, options->gen.scratch1);
4265 options->gen.cur_code = rdst; 3881 }
4266 } 3882 jmp(&orig, options->retrans_stub);
4267 dst = jmp(dst, options->retrans_stub);
4268 } 3883 }
4269 return context; 3884 return context;
4270 } 3885 }
4271 3886
4272 void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_handler) 3887 void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_handler)
4273 { 3888 {
4274 static code_ptr bp_stub = NULL; 3889 static code_ptr bp_stub = NULL;
4275 code_ptr native = get_native_address_trans(context, address); 3890 x86_68k_options * opts = context->options;
4276 code_ptr start_native = native; 3891 code_info native;
4277 native = mov_ir(native, address, SCRATCH1, SZ_D); 3892 native.cur = get_native_address_trans(context, address);
3893 native.last = native.cur + 128;
3894 code_ptr start_native = native.cur;
3895 mov_ir(&native, address, opts->gen.scratch1, SZ_D);
4278 if (!bp_stub) { 3896 if (!bp_stub) {
4279 x86_68k_options * opts = context->options; 3897 code_info *code = &opts->gen.code;
4280 code_ptr dst = opts->gen.cur_code; 3898 check_alloc_code(code, 5);
4281 code_ptr dst_end = opts->gen.code_end; 3899 bp_stub = code->cur;
4282 if (dst_end - dst < 128) { 3900 call(&native, bp_stub);
4283 size_t size = 1024*1024;
4284 dst = alloc_code(&size);
4285 opts->gen.code_end = dst_end = dst + size;
4286 }
4287 bp_stub = dst;
4288 native = call(native, bp_stub);
4289 3901
4290 //Calculate length of prologue 3902 //Calculate length of prologue
4291 dst = check_cycles_int(dst, address, opts); 3903 check_cycles_int(&opts->gen, address);
4292 int check_int_size = dst-bp_stub; 3904 int check_int_size = code->cur-bp_stub;
4293 dst = bp_stub; 3905 code->cur = bp_stub;
4294 3906
4295 //Save context and call breakpoint handler 3907 //Save context and call breakpoint handler
4296 dst = call(dst, opts->gen.save_context); 3908 call(code, opts->gen.save_context);
4297 dst = push_r(dst, SCRATCH1); 3909 push_r(code, opts->gen.scratch1);
4298 #ifdef X86_64 3910 #ifdef X86_64
4299 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 3911 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
4300 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 3912 mov_rr(code, opts->gen.scratch1, RSI, SZ_D);
4301 #else 3913 #else
4302 dst = push_r(dst, SCRATCH1); 3914 push_r(code, opts->gen.scratch1);
4303 dst = push_r(dst, CONTEXT); 3915 push_r(code, opts->gen.context_reg);
4304 #endif 3916 #endif
4305 dst = call(dst, bp_handler); 3917 call(code, bp_handler);
4306 #ifdef X86_32 3918 #ifdef X86_32
4307 dst = add_ir(dst, 8, RSP, SZ_D); 3919 add_ir(code, 8, RSP, SZ_D);
4308 #endif 3920 #endif
4309 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 3921 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
4310 //Restore context 3922 //Restore context
4311 dst = call(dst, opts->gen.load_context); 3923 call(code, opts->gen.load_context);
4312 dst = pop_r(dst, SCRATCH1); 3924 pop_r(code, opts->gen.scratch1);
4313 //do prologue stuff 3925 //do prologue stuff
4314 dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); 3926 cmp_rr(code, opts->gen.cycles, opts->gen.limit, SZ_D);
4315 code_ptr jmp_off = dst+1; 3927 code_ptr jmp_off = code->cur + 1;
4316 dst = jcc(dst, CC_NC, dst + 7); 3928 jcc(code, CC_NC, code->cur + 7);
4317 dst = call(dst, opts->gen.handle_cycle_limit_int); 3929 call(code, opts->gen.handle_cycle_limit_int);
4318 *jmp_off = dst - (jmp_off+1); 3930 *jmp_off = code->cur - (jmp_off+1);
4319 //jump back to body of translated instruction 3931 //jump back to body of translated instruction
4320 dst = pop_r(dst, SCRATCH1); 3932 pop_r(code, opts->gen.scratch1);
4321 dst = add_ir(dst, check_int_size - (native-start_native), SCRATCH1, SZ_PTR); 3933 add_ir(code, check_int_size - (native.cur-start_native), opts->gen.scratch1, SZ_PTR);
4322 dst = jmp_r(dst, SCRATCH1); 3934 jmp_r(code, opts->gen.scratch1);
4323 opts->gen.cur_code = dst;
4324 } else { 3935 } else {
4325 native = call(native, bp_stub); 3936 call(&native, bp_stub);
4326 } 3937 }
4327 } 3938 }
4328 3939
4329 void remove_breakpoint(m68k_context * context, uint32_t address) 3940 void remove_breakpoint(m68k_context * context, uint32_t address)
4330 { 3941 {
4331 code_ptr native = get_native_address(context->native_code_map, address); 3942 code_ptr native = get_native_address(context->native_code_map, address);
4332 check_cycles_int(native, address, context->options); 3943 check_cycles_int(context->options, address);
4333 } 3944 }
4334 3945
4335 void start_68k_context(m68k_context * context, uint32_t address) 3946 void start_68k_context(m68k_context * context, uint32_t address)
4336 { 3947 {
4337 code_ptr addr = get_native_address_trans(context, address); 3948 code_ptr addr = get_native_address_trans(context, address);
4347 start_68k_context(context, address); 3958 start_68k_context(context, address);
4348 } 3959 }
4349 3960
4350 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type) 3961 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk * memmap, uint32_t num_chunks, ftype fun_type)
4351 { 3962 {
4352 code_ptr dst = opts->cur_code; 3963 code_info *code = &opts->code;
4353 code_ptr start = dst; 3964 code_ptr start = code->cur;
4354 dst = check_cycles(dst, opts); 3965 check_cycles(opts);
4355 dst = cycles(dst, BUS); 3966 cycles(opts, BUS);
4356 dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); 3967 and_ir(code, 0xFFFFFF, opts->scratch1, SZ_D);
4357 code_ptr lb_jcc = NULL, ub_jcc = NULL; 3968 code_ptr lb_jcc = NULL, ub_jcc = NULL;
4358 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8; 3969 uint8_t is_write = fun_type == WRITE_16 || fun_type == WRITE_8;
4359 uint8_t adr_reg = is_write ? SCRATCH2 : SCRATCH1; 3970 uint8_t adr_reg = is_write ? opts->scratch2 : opts->scratch1;
4360 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ; 3971 uint16_t access_flag = is_write ? MMAP_WRITE : MMAP_READ;
4361 uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B; 3972 uint8_t size = (fun_type == READ_16 || fun_type == WRITE_16) ? SZ_W : SZ_B;
4362 for (uint32_t chunk = 0; chunk < num_chunks; chunk++) 3973 for (uint32_t chunk = 0; chunk < num_chunks; chunk++)
4363 { 3974 {
4364 if (memmap[chunk].start > 0) { 3975 if (memmap[chunk].start > 0) {
4365 dst = cmp_ir(dst, memmap[chunk].start, adr_reg, SZ_D); 3976 cmp_ir(code, memmap[chunk].start, adr_reg, SZ_D);
4366 lb_jcc = dst + 1; 3977 lb_jcc = code->cur + 1;
4367 dst = jcc(dst, CC_C, dst+2); 3978 jcc(code, CC_C, code->cur + 2);
4368 } 3979 }
4369 if (memmap[chunk].end < 0x1000000) { 3980 if (memmap[chunk].end < 0x1000000) {
4370 dst = cmp_ir(dst, memmap[chunk].end, adr_reg, SZ_D); 3981 cmp_ir(code, memmap[chunk].end, adr_reg, SZ_D);
4371 ub_jcc = dst + 1; 3982 ub_jcc = code->cur + 1;
4372 dst = jcc(dst, CC_NC, dst+2); 3983 jcc(code, CC_NC, code->cur + 2);
4373 } 3984 }
4374 3985
4375 if (memmap[chunk].mask != 0xFFFFFF) { 3986 if (memmap[chunk].mask != 0xFFFFFF) {
4376 dst = and_ir(dst, memmap[chunk].mask, adr_reg, SZ_D); 3987 and_ir(code, memmap[chunk].mask, adr_reg, SZ_D);
4377 } 3988 }
4378 void * cfun; 3989 void * cfun;
4379 switch (fun_type) 3990 switch (fun_type)
4380 { 3991 {
4381 case READ_16: 3992 case READ_16:
4394 cfun = NULL; 4005 cfun = NULL;
4395 } 4006 }
4396 if(memmap[chunk].buffer && memmap[chunk].flags & access_flag) { 4007 if(memmap[chunk].buffer && memmap[chunk].flags & access_flag) {
4397 if (memmap[chunk].flags & MMAP_PTR_IDX) { 4008 if (memmap[chunk].flags & MMAP_PTR_IDX) {
4398 if (memmap[chunk].flags & MMAP_FUNC_NULL) { 4009 if (memmap[chunk].flags & MMAP_FUNC_NULL) {
4399 dst = cmp_irdisp8(dst, 0, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_PTR); 4010 cmp_irdisp(code, 0, opts->context_reg, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, SZ_PTR);
4400 code_ptr not_null = dst+1; 4011 code_ptr not_null = code->cur + 1;
4401 dst = jcc(dst, CC_NZ, dst+2); 4012 jcc(code, CC_NZ, code->cur + 2);
4402 dst = call(dst, opts->save_context); 4013 call(code, opts->save_context);
4403 #ifdef X86_64 4014 #ifdef X86_64
4404 if (is_write) { 4015 if (is_write) {
4405 if (SCRATCH2 != RDI) { 4016 if (opts->scratch2 != RDI) {
4406 dst = mov_rr(dst, SCRATCH2, RDI, SZ_D); 4017 mov_rr(code, opts->scratch2, RDI, SZ_D);
4407 } 4018 }
4408 dst = mov_rr(dst, SCRATCH1, RDX, size); 4019 mov_rr(code, opts->scratch1, RDX, size);
4409 } else { 4020 } else {
4410 dst = push_r(dst, CONTEXT); 4021 push_r(code, opts->context_reg);
4411 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4022 mov_rr(code, opts->scratch1, RDI, SZ_D);
4412 } 4023 }
4413 dst = test_ir(dst, 8, RSP, SZ_D); 4024 test_ir(code, 8, RSP, SZ_D);
4414 code_ptr adjust_rsp = dst+1; 4025 code_ptr adjust_rsp = code->cur + 1;
4415 dst = jcc(dst, CC_NZ, dst+2); 4026 jcc(code, CC_NZ, code->cur + 2);
4416 dst = call(dst, cfun); 4027 call(code, cfun);
4417 code_ptr no_adjust = dst+1; 4028 code_ptr no_adjust = code->cur + 1;
4418 dst = jmp(dst, dst+2); 4029 jmp(code, code->cur + 2);
4419 *adjust_rsp = dst - (adjust_rsp + 1); 4030 *adjust_rsp = code->cur - (adjust_rsp + 1);
4420 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4031 sub_ir(code, 8, RSP, SZ_PTR);
4421 dst = call(dst, cfun); 4032 call(code, cfun);
4422 dst = add_ir(dst, 8, RSP, SZ_PTR); 4033 add_ir(code, 8, RSP, SZ_PTR);
4423 *no_adjust = dst - (no_adjust + 1); 4034 *no_adjust = code->cur - (no_adjust + 1);
4424 #else 4035 #else
4425 if (is_write) { 4036 if (is_write) {
4426 dst = push_r(dst, SCRATCH1); 4037 push_r(code, opts->scratch1);
4427 } else { 4038 } else {
4428 dst = push_r(dst, CONTEXT);//save CONTEXT for later 4039 push_r(code, opts->context_reg);//save opts->context_reg for later
4429 } 4040 }
4430 dst = push_r(dst, CONTEXT); 4041 push_r(code, opts->context_reg);
4431 dst = push_r(dst, is_write ? SCRATCH2 : SCRATCH1); 4042 push_r(code, is_write ? opts->scratch2 : opts->scratch1);
4432 dst = call(dst, cfun); 4043 call(code, cfun);
4433 dst = add_ir(dst, is_write ? 12 : 8, RSP, SZ_D); 4044 add_ir(code, is_write ? 12 : 8, RSP, SZ_D);
4434 #endif 4045 #endif
4435 if (is_write) { 4046 if (is_write) {
4436 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4047 mov_rr(code, RAX, opts->context_reg, SZ_PTR);
4437 } else { 4048 } else {
4438 dst = pop_r(dst, CONTEXT); 4049 pop_r(code, opts->context_reg);
4439 dst = mov_rr(dst, RAX, SCRATCH1, size); 4050 mov_rr(code, RAX, opts->scratch1, size);
4440 } 4051 }
4441 dst = jmp(dst, opts->load_context); 4052 jmp(code, opts->load_context);
4442 4053
4443 *not_null = dst - (not_null + 1); 4054 *not_null = code->cur - (not_null + 1);
4444 } 4055 }
4445 if (size == SZ_B) { 4056 if (size == SZ_B) {
4446 dst = xor_ir(dst, 1, adr_reg, SZ_D); 4057 xor_ir(code, 1, adr_reg, SZ_D);
4447 } 4058 }
4448 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_PTR); 4059 add_rdispr(code, opts->context_reg, offsetof(m68k_context, mem_pointers) + sizeof(void*) * memmap[chunk].ptr_index, adr_reg, SZ_PTR);
4449 if (is_write) { 4060 if (is_write) {
4450 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, size); 4061 mov_rrind(code, opts->scratch1, opts->scratch2, size);
4451 4062
4452 } else { 4063 } else {
4453 dst = mov_rindr(dst, SCRATCH1, SCRATCH1, size); 4064 mov_rindr(code, opts->scratch1, opts->scratch1, size);
4454 } 4065 }
4455 } else { 4066 } else {
4456 uint8_t tmp_size = size; 4067 uint8_t tmp_size = size;
4457 if (size == SZ_B) { 4068 if (size == SZ_B) {
4458 if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) { 4069 if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
4459 dst = bt_ir(dst, 0, adr_reg, SZ_D); 4070 bt_ir(code, 0, adr_reg, SZ_D);
4460 code_ptr good_addr = dst + 1; 4071 code_ptr good_addr = code->cur + 1;
4461 dst = jcc(dst, (memmap[chunk].flags & MMAP_ONLY_ODD) ? CC_C : CC_NC, dst+2); 4072 jcc(code, (memmap[chunk].flags & MMAP_ONLY_ODD) ? CC_C : CC_NC, code->cur + 2);
4462 if (!is_write) { 4073 if (!is_write) {
4463 dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B); 4074 mov_ir(code, 0xFF, opts->scratch1, SZ_B);
4464 } 4075 }
4465 dst = retn(dst); 4076 retn(code);
4466 *good_addr = dst - (good_addr + 1); 4077 *good_addr = code->cur - (good_addr + 1);
4467 dst = shr_ir(dst, 1, adr_reg, SZ_D); 4078 shr_ir(code, 1, adr_reg, SZ_D);
4468 } else { 4079 } else {
4469 dst = xor_ir(dst, 1, adr_reg, SZ_D); 4080 xor_ir(code, 1, adr_reg, SZ_D);
4470 } 4081 }
4471 } else if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) { 4082 } else if ((memmap[chunk].flags & MMAP_ONLY_ODD) || (memmap[chunk].flags & MMAP_ONLY_EVEN)) {
4472 tmp_size = SZ_B; 4083 tmp_size = SZ_B;
4473 dst = shr_ir(dst, 1, adr_reg, SZ_D); 4084 shr_ir(code, 1, adr_reg, SZ_D);
4474 if ((memmap[chunk].flags & MMAP_ONLY_EVEN) && is_write) { 4085 if ((memmap[chunk].flags & MMAP_ONLY_EVEN) && is_write) {
4475 dst = shr_ir(dst, 8, SCRATCH1, SZ_W); 4086 shr_ir(code, 8, opts->scratch1, SZ_W);
4476 } 4087 }
4477 } 4088 }
4478 if ((intptr_t)memmap[chunk].buffer <= 0x7FFFFFFF && (intptr_t)memmap[chunk].buffer >= -2147483648) { 4089 if ((intptr_t)memmap[chunk].buffer <= 0x7FFFFFFF && (intptr_t)memmap[chunk].buffer >= -2147483648) {
4479 if (is_write) { 4090 if (is_write) {
4480 dst = mov_rrdisp32(dst, SCRATCH1, SCRATCH2, (intptr_t)memmap[chunk].buffer, tmp_size); 4091 mov_rrdisp(code, opts->scratch1, opts->scratch2, (intptr_t)memmap[chunk].buffer, tmp_size);
4481 } else { 4092 } else {
4482 dst = mov_rdisp32r(dst, SCRATCH1, (intptr_t)memmap[chunk].buffer, SCRATCH1, tmp_size); 4093 mov_rdispr(code, opts->scratch1, (intptr_t)memmap[chunk].buffer, opts->scratch1, tmp_size);
4483 } 4094 }
4484 } else { 4095 } else {
4485 if (is_write) { 4096 if (is_write) {
4486 dst = push_r(dst, SCRATCH1); 4097 push_r(code, opts->scratch1);
4487 dst = mov_ir(dst, (intptr_t)memmap[chunk].buffer, SCRATCH1, SZ_PTR); 4098 mov_ir(code, (intptr_t)memmap[chunk].buffer, opts->scratch1, SZ_PTR);
4488 dst = add_rr(dst, SCRATCH1, SCRATCH2, SZ_PTR); 4099 add_rr(code, opts->scratch1, opts->scratch2, SZ_PTR);
4489 dst = pop_r(dst, SCRATCH1); 4100 pop_r(code, opts->scratch1);
4490 dst = mov_rrind(dst, SCRATCH1, SCRATCH2, tmp_size); 4101 mov_rrind(code, opts->scratch1, opts->scratch2, tmp_size);
4491 } else { 4102 } else {
4492 dst = mov_ir(dst, (intptr_t)memmap[chunk].buffer, SCRATCH2, SZ_PTR); 4103 mov_ir(code, (intptr_t)memmap[chunk].buffer, opts->scratch2, SZ_PTR);
4493 dst = mov_rindexr(dst, SCRATCH2, SCRATCH1, 1, SCRATCH1, tmp_size); 4104 mov_rindexr(code, opts->scratch2, opts->scratch1, 1, opts->scratch1, tmp_size);
4494 } 4105 }
4495 } 4106 }
4496 if (size != tmp_size && !is_write) { 4107 if (size != tmp_size && !is_write) {
4497 if (memmap[chunk].flags & MMAP_ONLY_EVEN) { 4108 if (memmap[chunk].flags & MMAP_ONLY_EVEN) {
4498 dst = shl_ir(dst, 8, SCRATCH1, SZ_W); 4109 shl_ir(code, 8, opts->scratch1, SZ_W);
4499 dst = mov_ir(dst, 0xFF, SCRATCH1, SZ_B); 4110 mov_ir(code, 0xFF, opts->scratch1, SZ_B);
4500 } else { 4111 } else {
4501 dst = or_ir(dst, 0xFF00, SCRATCH1, SZ_W); 4112 or_ir(code, 0xFF00, opts->scratch1, SZ_W);
4502 } 4113 }
4503 } 4114 }
4504 } 4115 }
4505 if (is_write && (memmap[chunk].flags & MMAP_CODE)) { 4116 if (is_write && (memmap[chunk].flags & MMAP_CODE)) {
4506 dst = mov_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 4117 mov_rr(code, opts->scratch2, opts->scratch1, SZ_D);
4507 dst = shr_ir(dst, 11, SCRATCH1, SZ_D); 4118 shr_ir(code, 11, opts->scratch1, SZ_D);
4508 dst = bt_rrdisp32(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, ram_code_flags), SZ_D); 4119 bt_rrdisp(code, opts->scratch1, opts->context_reg, offsetof(m68k_context, ram_code_flags), SZ_D);
4509 code_ptr not_code = dst+1; 4120 code_ptr not_code = code->cur + 1;
4510 dst = jcc(dst, CC_NC, dst+2); 4121 jcc(code, CC_NC, code->cur + 2);
4511 dst = call(dst, opts->save_context); 4122 call(code, opts->save_context);
4512 #ifdef X86_32 4123 #ifdef X86_32
4513 dst = push_r(dst, CONTEXT); 4124 push_r(code, opts->context_reg);
4514 dst = push_r(dst, SCRATCH2); 4125 push_r(code, opts->scratch2);
4515 #endif 4126 #endif
4516 dst = call(dst, (code_ptr)m68k_handle_code_write); 4127 call(code, (code_ptr)m68k_handle_code_write);
4517 #ifdef X86_32 4128 #ifdef X86_32
4518 dst = add_ir(dst, 8, RSP, SZ_D); 4129 add_ir(code, 8, RSP, SZ_D);
4519 #endif 4130 #endif
4520 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4131 mov_rr(code, RAX, opts->context_reg, SZ_PTR);
4521 dst = call(dst, opts->load_context); 4132 call(code, opts->load_context);
4522 *not_code = dst - (not_code+1); 4133 *not_code = code->cur - (not_code+1);
4523 } 4134 }
4524 dst = retn(dst); 4135 retn(code);
4525 } else if (cfun) { 4136 } else if (cfun) {
4526 dst = call(dst, opts->save_context); 4137 call(code, opts->save_context);
4527 #ifdef X86_64 4138 #ifdef X86_64
4528 if (is_write) { 4139 if (is_write) {
4529 if (SCRATCH2 != RDI) { 4140 if (opts->scratch2 != RDI) {
4530 dst = mov_rr(dst, SCRATCH2, RDI, SZ_D); 4141 mov_rr(code, opts->scratch2, RDI, SZ_D);
4531 } 4142 }
4532 dst = mov_rr(dst, SCRATCH1, RDX, size); 4143 mov_rr(code, opts->scratch1, RDX, size);
4533 } else { 4144 } else {
4534 dst = push_r(dst, CONTEXT); 4145 push_r(code, opts->context_reg);
4535 dst = mov_rr(dst, SCRATCH1, RDI, SZ_D); 4146 mov_rr(code, opts->scratch1, RDI, SZ_D);
4536 } 4147 }
4537 dst = test_ir(dst, 8, RSP, SZ_D); 4148 test_ir(code, 8, RSP, SZ_D);
4538 code_ptr adjust_rsp = dst+1; 4149 code_ptr adjust_rsp = code->cur + 1;
4539 dst = jcc(dst, CC_NZ, dst+2); 4150 jcc(code, CC_NZ, code->cur + 2);
4540 dst = call(dst, cfun); 4151 call(code, cfun);
4541 code_ptr no_adjust = dst+1; 4152 code_ptr no_adjust = code->cur + 1;
4542 dst = jmp(dst, dst+2); 4153 jmp(code, code->cur + 2);
4543 *adjust_rsp = dst - (adjust_rsp + 1); 4154 *adjust_rsp = code->cur - (adjust_rsp + 1);
4544 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4155 sub_ir(code, 8, RSP, SZ_PTR);
4545 dst = call(dst, cfun); 4156 call(code, cfun);
4546 dst = add_ir(dst, 8, RSP, SZ_PTR); 4157 add_ir(code, 8, RSP, SZ_PTR);
4547 *no_adjust = dst - (no_adjust+1); 4158 *no_adjust = code->cur - (no_adjust+1);
4548 #else 4159 #else
4549 if (is_write) { 4160 if (is_write) {
4550 dst = push_r(dst, SCRATCH1); 4161 push_r(code, opts->scratch1);
4551 } else { 4162 } else {
4552 dst = push_r(dst, CONTEXT);//save CONTEXT for later 4163 push_r(code, opts->context_reg);//save opts->context_reg for later
4553 } 4164 }
4554 dst = push_r(dst, CONTEXT); 4165 push_r(code, opts->context_reg);
4555 dst = push_r(dst, is_write ? SCRATCH2 : SCRATCH1); 4166 push_r(code, is_write ? opts->scratch2 : opts->scratch1);
4556 dst = call(dst, cfun); 4167 call(code, cfun);
4557 dst = add_ir(dst, is_write ? 12 : 8, RSP, SZ_D); 4168 add_ir(code, is_write ? 12 : 8, RSP, SZ_D);
4558 #endif 4169 #endif
4559 if (is_write) { 4170 if (is_write) {
4560 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4171 mov_rr(code, RAX, opts->context_reg, SZ_PTR);
4561 } else { 4172 } else {
4562 dst = pop_r(dst, CONTEXT); 4173 pop_r(code, opts->context_reg);
4563 dst = mov_rr(dst, RAX, SCRATCH1, size); 4174 mov_rr(code, RAX, opts->scratch1, size);
4564 } 4175 }
4565 dst = jmp(dst, opts->load_context); 4176 jmp(code, opts->load_context);
4566 } else { 4177 } else {
4567 //Not sure the best course of action here 4178 //Not sure the best course of action here
4568 if (!is_write) { 4179 if (!is_write) {
4569 dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); 4180 mov_ir(code, size == SZ_B ? 0xFF : 0xFFFF, opts->scratch1, size);
4570 } 4181 }
4571 dst = retn(dst); 4182 retn(code);
4572 } 4183 }
4573 if (lb_jcc) { 4184 if (lb_jcc) {
4574 *lb_jcc = dst - (lb_jcc+1); 4185 *lb_jcc = code->cur - (lb_jcc+1);
4575 lb_jcc = NULL; 4186 lb_jcc = NULL;
4576 } 4187 }
4577 if (ub_jcc) { 4188 if (ub_jcc) {
4578 *ub_jcc = dst - (ub_jcc+1); 4189 *ub_jcc = code->cur - (ub_jcc+1);
4579 ub_jcc = NULL; 4190 ub_jcc = NULL;
4580 } 4191 }
4581 } 4192 }
4582 if (!is_write) { 4193 if (!is_write) {
4583 dst = mov_ir(dst, size == SZ_B ? 0xFF : 0xFFFF, SCRATCH1, size); 4194 mov_ir(code, size == SZ_B ? 0xFF : 0xFFFF, opts->scratch1, size);
4584 } 4195 }
4585 dst = retn(dst); 4196 retn(code);
4586 opts->cur_code = dst;
4587 return start; 4197 return start;
4588 } 4198 }
4589 4199
4590 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) 4200 void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks)
4591 { 4201 {
4592 memset(opts, 0, sizeof(*opts)); 4202 memset(opts, 0, sizeof(*opts));
4593 for (int i = 0; i < 8; i++) 4203 for (int i = 0; i < 8; i++)
4204 {
4594 opts->dregs[i] = opts->aregs[i] = -1; 4205 opts->dregs[i] = opts->aregs[i] = -1;
4206 }
4595 #ifdef X86_64 4207 #ifdef X86_64
4596 opts->dregs[0] = R10; 4208 opts->dregs[0] = R10;
4597 opts->dregs[1] = R11; 4209 opts->dregs[1] = R11;
4598 opts->dregs[2] = R12; 4210 opts->dregs[2] = R12;
4599 opts->dregs[3] = R8; 4211 opts->dregs[3] = R8;
4605 opts->flag_regs[0] = -1; 4217 opts->flag_regs[0] = -1;
4606 opts->flag_regs[1] = RBX; 4218 opts->flag_regs[1] = RBX;
4607 opts->flag_regs[2] = RDX; 4219 opts->flag_regs[2] = RDX;
4608 opts->flag_regs[3] = BH; 4220 opts->flag_regs[3] = BH;
4609 opts->flag_regs[4] = DH; 4221 opts->flag_regs[4] = DH;
4222
4223 opts->gen.scratch2 = RDI;
4610 #else 4224 #else
4611 opts->dregs[0] = RDX; 4225 opts->dregs[0] = RDX;
4612 opts->aregs[7] = RDI; 4226 opts->aregs[7] = RDI;
4613 4227
4614 for (int i = 0; i < 5; i++) 4228 for (int i = 0; i < 5; i++)
4229 {
4615 opts->flag_regs[i] = -1; 4230 opts->flag_regs[i] = -1;
4231 }
4232 opts->gen.scratch2 = RBX;
4616 #endif 4233 #endif
4234 opts->gen.context_reg = RSI;
4235 opts->gen.cycles = RAX;
4236 opts->gen.limit = RBP;
4237 opts->gen.scratch1 = RCX;
4617 4238
4618 4239
4619 opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 4240 opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
4620 memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); 4241 memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS);
4621 opts->gen.deferred = NULL; 4242 opts->gen.deferred = NULL;
4622 size_t size = 1024 * 1024; 4243 opts->gen.ram_inst_sizes = malloc(sizeof(uint8_t *) * 64);
4623 opts->gen.cur_code = alloc_code(&size); 4244 memset(opts->gen.ram_inst_sizes, 0, sizeof(uint8_t *) * 64);
4624 opts->gen.code_end = opts->gen.cur_code + size; 4245
4625 opts->gen.ram_inst_sizes = malloc(sizeof(code_ptr) * 64); 4246 code_info *code = &opts->gen.code;
4626 memset(opts->gen.ram_inst_sizes, 0, sizeof(code_ptr) * 64); 4247 init_code_info(code);
4627 4248
4628 code_ptr dst = opts->gen.cur_code; 4249 opts->gen.save_context = code->cur;
4629
4630 opts->gen.save_context = dst;
4631 for (int i = 0; i < 5; i++) 4250 for (int i = 0; i < 5; i++)
4632 if (opts->flag_regs[i] >= 0) { 4251 if (opts->flag_regs[i] >= 0) {
4633 dst = mov_rrdisp8(dst, opts->flag_regs[i], CONTEXT, offsetof(m68k_context, flags) + i, SZ_B); 4252 mov_rrdisp(code, opts->flag_regs[i], opts->gen.context_reg, offsetof(m68k_context, flags) + i, SZ_B);
4634 } 4253 }
4635 for (int i = 0; i < 8; i++) 4254 for (int i = 0; i < 8; i++)
4636 { 4255 {
4637 if (opts->dregs[i] >= 0) { 4256 if (opts->dregs[i] >= 0) {
4638 dst = mov_rrdisp8(dst, opts->dregs[i], CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, SZ_D); 4257 mov_rrdisp(code, opts->dregs[i], opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, SZ_D);
4639 } 4258 }
4640 if (opts->aregs[i] >= 0) { 4259 if (opts->aregs[i] >= 0) {
4641 dst = mov_rrdisp8(dst, opts->aregs[i], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D); 4260 mov_rrdisp(code, opts->aregs[i], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, SZ_D);
4642 } 4261 }
4643 } 4262 }
4644 dst = mov_rrdisp8(dst, CYCLES, CONTEXT, offsetof(m68k_context, current_cycle), SZ_D); 4263 mov_rrdisp(code, opts->gen.cycles, opts->gen.context_reg, offsetof(m68k_context, current_cycle), SZ_D);
4645 dst = retn(dst); 4264 retn(code);
4646 4265
4647 opts->gen.load_context = dst; 4266 opts->gen.load_context = code->cur;
4648 for (int i = 0; i < 5; i++) 4267 for (int i = 0; i < 5; i++)
4649 if (opts->flag_regs[i] >= 0) { 4268 if (opts->flag_regs[i] >= 0) {
4650 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B); 4269 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B);
4651 } 4270 }
4652 for (int i = 0; i < 8; i++) 4271 for (int i = 0; i < 8; i++)
4653 { 4272 {
4654 if (opts->dregs[i] >= 0) { 4273 if (opts->dregs[i] >= 0) {
4655 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, opts->dregs[i], SZ_D); 4274 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * i, opts->dregs[i], SZ_D);
4656 } 4275 }
4657 if (opts->aregs[i] >= 0) { 4276 if (opts->aregs[i] >= 0) {
4658 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D); 4277 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D);
4659 } 4278 }
4660 } 4279 }
4661 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, current_cycle), CYCLES, SZ_D); 4280 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, current_cycle), CYCLES, SZ_D);
4662 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, target_cycle), LIMIT, SZ_D); 4281 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, target_cycle), LIMIT, SZ_D);
4663 dst = retn(dst); 4282 retn(code);
4664 4283
4665 opts->start_context = (start_fun)dst; 4284 opts->start_context = (start_fun)code->cur;
4666 #ifdef X86_64 4285 #ifdef X86_64
4667 if (SCRATCH2 != RDI) { 4286 if (opts->gen.scratch2 != RDI) {
4668 dst = mov_rr(dst, RDI, SCRATCH2, SZ_PTR); 4287 mov_rr(code, RDI, opts->gen.scratch2, SZ_PTR);
4669 } 4288 }
4670 //save callee save registers 4289 //save callee save registers
4671 dst = push_r(dst, RBP); 4290 push_r(code, RBP);
4672 dst = push_r(dst, R12); 4291 push_r(code, R12);
4673 dst = push_r(dst, R13); 4292 push_r(code, R13);
4674 dst = push_r(dst, R14); 4293 push_r(code, R14);
4675 dst = push_r(dst, R15); 4294 push_r(code, R15);
4676 #else 4295 #else
4677 //save callee save registers 4296 //save callee save registers
4678 dst = push_r(dst, RBP); 4297 push_r(code, RBP);
4679 dst = push_r(dst, RBX); 4298 push_r(code, RBX);
4680 dst = push_r(dst, RSI); 4299 push_r(code, RSI);
4681 dst = push_r(dst, RDI); 4300 push_r(code, RDI);
4682 4301
4683 dst = mov_rdisp8r(dst, RSP, 20, SCRATCH2, SZ_D); 4302 mov_rdispr(code, RSP, 20, opts->gen.scratch2, SZ_D);
4684 dst = mov_rdisp8r(dst, RSP, 24, CONTEXT, SZ_D); 4303 mov_rdispr(code, RSP, 24, opts->gen.context_reg, SZ_D);
4685 #endif 4304 #endif
4686 dst = call(dst, opts->gen.load_context); 4305 call(code, opts->gen.load_context);
4687 dst = call_r(dst, SCRATCH2); 4306 call_r(code, opts->gen.scratch2);
4688 dst = call(dst, opts->gen.save_context); 4307 call(code, opts->gen.save_context);
4689 #ifdef X86_64 4308 #ifdef X86_64
4690 //restore callee save registers 4309 //restore callee save registers
4691 dst = pop_r(dst, R15); 4310 pop_r(code, R15);
4692 dst = pop_r(dst, R14); 4311 pop_r(code, R14);
4693 dst = pop_r(dst, R13); 4312 pop_r(code, R13);
4694 dst = pop_r(dst, R12); 4313 pop_r(code, R12);
4695 dst = pop_r(dst, RBP); 4314 pop_r(code, RBP);
4696 #else 4315 #else
4697 dst = pop_r(dst, RDI); 4316 pop_r(code, RDI);
4698 dst = pop_r(dst, RSI); 4317 pop_r(code, RSI);
4699 dst = pop_r(dst, RBX); 4318 pop_r(code, RBX);
4700 dst = pop_r(dst, RBP); 4319 pop_r(code, RBP);
4701 #endif 4320 #endif
4702 dst = retn(dst); 4321 retn(code);
4703 4322
4704 opts->native_addr = dst; 4323 opts->native_addr = code->cur;
4705 dst = call(dst, opts->gen.save_context); 4324 call(code, opts->gen.save_context);
4706 dst = push_r(dst, CONTEXT); 4325 push_r(code, opts->gen.context_reg);
4707 #ifdef X86_64 4326 #ifdef X86_64
4708 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); //move context to 1st arg reg 4327 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); //move context to 1st arg reg
4709 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); //move address to 2nd arg reg 4328 mov_rr(code, opts->gen.scratch1, RSI, SZ_D); //move address to 2nd arg reg
4710 #else 4329 #else
4711 dst = push_r(dst, SCRATCH1); 4330 push_r(code, opts->gen.scratch1);
4712 dst = push_r(dst, CONTEXT); 4331 push_r(code, opts->gen.context_reg);
4713 #endif 4332 #endif
4714 dst = call(dst, (code_ptr)get_native_address_trans); 4333 call(code, (code_ptr)get_native_address_trans);
4715 #ifdef X86_32 4334 #ifdef X86_32
4716 dst = add_ir(dst, 8, RSP, SZ_D); 4335 add_ir(code, 8, RSP, SZ_D);
4717 #endif 4336 #endif
4718 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg 4337 mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); //move result to scratch reg
4719 dst = pop_r(dst, CONTEXT); 4338 pop_r(code, opts->gen.context_reg);
4720 dst = call(dst, opts->gen.load_context); 4339 call(code, opts->gen.load_context);
4721 dst = retn(dst); 4340 retn(code);
4722 4341
4723 opts->native_addr_and_sync = dst; 4342 opts->native_addr_and_sync = code->cur;
4724 dst = call(dst, opts->gen.save_context); 4343 call(code, opts->gen.save_context);
4725 dst = push_r(dst, SCRATCH1); 4344 push_r(code, opts->gen.scratch1);
4726 #ifdef X86_64 4345 #ifdef X86_64
4727 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4346 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
4728 dst = xor_rr(dst, RSI, RSI, SZ_D); 4347 xor_rr(code, RSI, RSI, SZ_D);
4729 dst = test_ir(dst, 8, RSP, SZ_PTR); //check stack alignment 4348 test_ir(code, 8, RSP, SZ_PTR); //check stack alignment
4730 code_ptr do_adjust_rsp = dst+1; 4349 code_ptr do_adjust_rsp = code->cur + 1;
4731 dst = jcc(dst, CC_NZ, dst+2); 4350 jcc(code, CC_NZ, code->cur + 2);
4732 dst = call(dst, (code_ptr)sync_components); 4351 call(code, (code_ptr)sync_components);
4733 code_ptr no_adjust_rsp = dst+1; 4352 code_ptr no_adjust_rsp = code->cur + 1;
4734 dst = jmp(dst, dst+2); 4353 jmp(code, code->cur + 2);
4735 *do_adjust_rsp = dst - (do_adjust_rsp+1); 4354 *do_adjust_rsp = code->cur - (do_adjust_rsp+1);
4736 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4355 sub_ir(code, 8, RSP, SZ_PTR);
4737 dst = call(dst, (code_ptr)sync_components); 4356 call(code, (code_ptr)sync_components);
4738 dst = add_ir(dst, 8, RSP, SZ_PTR); 4357 add_ir(code, 8, RSP, SZ_PTR);
4739 *no_adjust_rsp = dst - (no_adjust_rsp+1); 4358 *no_adjust_rsp = code->cur - (no_adjust_rsp+1);
4740 dst = pop_r(dst, RSI); 4359 pop_r(code, RSI);
4741 dst = push_r(dst, RAX); 4360 push_r(code, RAX);
4742 dst = mov_rr(dst, RAX, RDI, SZ_PTR); 4361 mov_rr(code, RAX, RDI, SZ_PTR);
4743 dst = call(dst, (code_ptr)get_native_address_trans); 4362 call(code, (code_ptr)get_native_address_trans);
4744 #else 4363 #else
4745 //TODO: Add support for pushing a constant in gen_x86 4364 //TODO: Add support for pushing a constant in gen_x86
4746 dst = xor_rr(dst, RAX, RAX, SZ_D); 4365 xor_rr(code, RAX, RAX, SZ_D);
4747 dst = push_r(dst, RAX); 4366 push_r(code, RAX);
4748 dst = push_r(dst, CONTEXT); 4367 push_r(code, opts->gen.context_reg);
4749 dst = call(dst, (code_ptr)sync_components); 4368 call(code, (code_ptr)sync_components);
4750 dst = add_ir(dst, 8, RSP, SZ_D); 4369 add_ir(code, 8, RSP, SZ_D);
4751 dst = pop_r(dst, RSI); //restore saved address from SCRATCH1 4370 pop_r(code, RSI); //restore saved address from opts->gen.scratch1
4752 dst = push_r(dst, RAX); //save context pointer for later 4371 push_r(code, RAX); //save context pointer for later
4753 dst = push_r(dst, RSI); //2nd arg -- address 4372 push_r(code, RSI); //2nd arg -- address
4754 dst = push_r(dst, RAX); //1st arg -- context pointer 4373 push_r(code, RAX); //1st arg -- context pointer
4755 dst = call(dst, (code_ptr)get_native_address_trans); 4374 call(code, (code_ptr)get_native_address_trans);
4756 dst = add_ir(dst, 8, RSP, SZ_D); 4375 add_ir(code, 8, RSP, SZ_D);
4757 #endif 4376 #endif
4758 4377
4759 dst = mov_rr(dst, RAX, SCRATCH1, SZ_PTR); //move result to scratch reg 4378 mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); //move result to scratch reg
4760 dst = pop_r(dst, CONTEXT); 4379 pop_r(code, opts->gen.context_reg);
4761 dst = call(dst, opts->gen.load_context); 4380 call(code, opts->gen.load_context);
4762 dst = retn(dst); 4381 retn(code);
4763 4382
4764 opts->gen.handle_cycle_limit = dst; 4383 opts->gen.handle_cycle_limit = code->cur;
4765 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4384 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4766 code_ptr skip_sync = dst+1; 4385 code_ptr skip_sync = code->cur + 1;
4767 dst = jcc(dst, CC_C, dst+2); 4386 jcc(code, CC_C, code->cur + 2);
4768 opts->do_sync = dst; 4387 opts->do_sync = code->cur;
4769 dst = push_r(dst, SCRATCH1); 4388 push_r(code, opts->gen.scratch1);
4770 dst = push_r(dst, SCRATCH2); 4389 push_r(code, opts->gen.scratch2);
4771 dst = call(dst, opts->gen.save_context); 4390 call(code, opts->gen.save_context);
4772 #ifdef X86_64 4391 #ifdef X86_64
4773 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4392 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
4774 dst = xor_rr(dst, RSI, RSI, SZ_D); 4393 xor_rr(code, RSI, RSI, SZ_D);
4775 dst = test_ir(dst, 8, RSP, SZ_D); 4394 test_ir(code, 8, RSP, SZ_D);
4776 code_ptr adjust_rsp = dst+1; 4395 code_ptr adjust_rsp = code->cur + 1;
4777 dst = jcc(dst, CC_NZ, dst+2); 4396 jcc(code, CC_NZ, code->cur + 2);
4778 dst = call(dst, (code_ptr)sync_components); 4397 call(code, (code_ptr)sync_components);
4779 code_ptr no_adjust = dst+1; 4398 code_ptr no_adjust = code->cur + 1;
4780 dst = jmp(dst, dst+2); 4399 jmp(code, code->cur + 2);
4781 *adjust_rsp = dst - (adjust_rsp + 1); 4400 *adjust_rsp = code->cur - (adjust_rsp + 1);
4782 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4401 sub_ir(code, 8, RSP, SZ_PTR);
4783 dst = call(dst, (code_ptr)sync_components); 4402 call(code, (code_ptr)sync_components);
4784 dst = add_ir(dst, 8, RSP, SZ_PTR); 4403 add_ir(code, 8, RSP, SZ_PTR);
4785 *no_adjust = dst - (no_adjust+1); 4404 *no_adjust = code->cur - (no_adjust+1);
4786 #else 4405 #else
4787 //TODO: Add support for pushing a constant in gen_x86 4406 //TODO: Add support for pushing a constant in gen_x86
4788 dst = xor_rr(dst, RAX, RAX, SZ_D); 4407 xor_rr(code, RAX, RAX, SZ_D);
4789 dst = push_r(dst, RAX); 4408 push_r(code, RAX);
4790 dst = push_r(dst, CONTEXT); 4409 push_r(code, opts->gen.context_reg);
4791 dst = call(dst, (code_ptr)sync_components); 4410 call(code, (code_ptr)sync_components);
4792 dst = add_ir(dst, 8, RSP, SZ_D); 4411 add_ir(code, 8, RSP, SZ_D);
4793 #endif 4412 #endif
4794 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4413 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
4795 dst = call(dst, opts->gen.load_context); 4414 call(code, opts->gen.load_context);
4796 dst = pop_r(dst, SCRATCH2); 4415 pop_r(code, opts->gen.scratch2);
4797 dst = pop_r(dst, SCRATCH1); 4416 pop_r(code, opts->gen.scratch1);
4798 *skip_sync = dst - (skip_sync+1); 4417 *skip_sync = code->cur - (skip_sync+1);
4799 dst = retn(dst); 4418 retn(code);
4800
4801 opts->gen.cur_code = dst;
4802 4419
4803 opts->read_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_16); 4420 opts->read_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_16);
4804 opts->read_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_8); 4421 opts->read_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_8);
4805 opts->write_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_16); 4422 opts->write_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_16);
4806 opts->write_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_8); 4423 opts->write_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_8);
4807 4424
4808 dst = opts->gen.cur_code; 4425 opts->read_32 = code->cur;
4809 4426 push_r(code, opts->gen.scratch1);
4810 opts->read_32 = dst; 4427 call(code, opts->read_16);
4811 dst = push_r(dst, SCRATCH1); 4428 mov_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_W);
4812 dst = call(dst, opts->read_16); 4429 pop_r(code, opts->gen.scratch1);
4813 dst = mov_rr(dst, SCRATCH1, SCRATCH2, SZ_W); 4430 push_r(code, opts->gen.scratch2);
4814 dst = pop_r(dst, SCRATCH1); 4431 add_ir(code, 2, opts->gen.scratch1, SZ_D);
4815 dst = push_r(dst, SCRATCH2); 4432 call(code, opts->read_16);
4816 dst = add_ir(dst, 2, SCRATCH1, SZ_D); 4433 pop_r(code, opts->gen.scratch2);
4817 dst = call(dst, opts->read_16); 4434 movzx_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_W, SZ_D);
4818 dst = pop_r(dst, SCRATCH2); 4435 shl_ir(code, 16, opts->gen.scratch2, SZ_D);
4819 dst = movzx_rr(dst, SCRATCH1, SCRATCH1, SZ_W, SZ_D); 4436 or_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D);
4820 dst = shl_ir(dst, 16, SCRATCH2, SZ_D); 4437 retn(code);
4821 dst = or_rr(dst, SCRATCH2, SCRATCH1, SZ_D); 4438
4822 dst = retn(dst); 4439 opts->write_32_lowfirst = code->cur;
4823 4440 push_r(code, opts->gen.scratch2);
4824 opts->write_32_lowfirst = dst; 4441 push_r(code, opts->gen.scratch1);
4825 dst = push_r(dst, SCRATCH2); 4442 add_ir(code, 2, opts->gen.scratch2, SZ_D);
4826 dst = push_r(dst, SCRATCH1); 4443 call(code, opts->write_16);
4827 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 4444 pop_r(code, opts->gen.scratch1);
4828 dst = call(dst, opts->write_16); 4445 pop_r(code, opts->gen.scratch2);
4829 dst = pop_r(dst, SCRATCH1); 4446 shr_ir(code, 16, opts->gen.scratch1, SZ_D);
4830 dst = pop_r(dst, SCRATCH2); 4447 jmp(code, opts->write_16);
4831 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 4448
4832 dst = jmp(dst, opts->write_16); 4449 opts->write_32_highfirst = code->cur;
4833 4450 push_r(code, opts->gen.scratch1);
4834 opts->write_32_highfirst = dst; 4451 push_r(code, opts->gen.scratch2);
4835 dst = push_r(dst, SCRATCH1); 4452 shr_ir(code, 16, opts->gen.scratch1, SZ_D);
4836 dst = push_r(dst, SCRATCH2); 4453 call(code, opts->write_16);
4837 dst = shr_ir(dst, 16, SCRATCH1, SZ_D); 4454 pop_r(code, opts->gen.scratch2);
4838 dst = call(dst, opts->write_16); 4455 pop_r(code, opts->gen.scratch1);
4839 dst = pop_r(dst, SCRATCH2); 4456 add_ir(code, 2, opts->gen.scratch2, SZ_D);
4840 dst = pop_r(dst, SCRATCH1); 4457 jmp(code, opts->write_16);
4841 dst = add_ir(dst, 2, SCRATCH2, SZ_D); 4458
4842 dst = jmp(dst, opts->write_16); 4459 opts->get_sr = code->cur;
4843 4460 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, status), opts->gen.scratch1, SZ_B);
4844 opts->get_sr = dst; 4461 shl_ir(code, 8, opts->gen.scratch1, SZ_W);
4845 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, status), SCRATCH1, SZ_B);
4846 dst = shl_ir(dst, 8, SCRATCH1, SZ_W);
4847 if (opts->flag_regs[FLAG_X] >= 0) { 4462 if (opts->flag_regs[FLAG_X] >= 0) {
4848 dst = mov_rr(dst, opts->flag_regs[FLAG_X], SCRATCH1, SZ_B); 4463 mov_rr(code, opts->flag_regs[FLAG_X], opts->gen.scratch1, SZ_B);
4849 } else { 4464 } else {
4850 int8_t offset = offsetof(m68k_context, flags); 4465 int8_t offset = offsetof(m68k_context, flags);
4851 if (offset) { 4466 if (offset) {
4852 dst = mov_rdisp8r(dst, CONTEXT, offset, SCRATCH1, SZ_B); 4467 mov_rdispr(code, opts->gen.context_reg, offset, opts->gen.scratch1, SZ_B);
4853 } else { 4468 } else {
4854 dst = mov_rindr(dst, CONTEXT, SCRATCH1, SZ_B); 4469 mov_rindr(code, opts->gen.context_reg, opts->gen.scratch1, SZ_B);
4855 } 4470 }
4856 } 4471 }
4857 for (int flag = FLAG_N; flag <= FLAG_C; flag++) 4472 for (int flag = FLAG_N; flag <= FLAG_C; flag++)
4858 { 4473 {
4859 dst = shl_ir(dst, 1, SCRATCH1, SZ_B); 4474 shl_ir(code, 1, opts->gen.scratch1, SZ_B);
4860 if (opts->flag_regs[flag] >= 0) { 4475 if (opts->flag_regs[flag] >= 0) {
4861 dst = or_rr(dst, opts->flag_regs[flag], SCRATCH1, SZ_B); 4476 or_rr(code, opts->flag_regs[flag], opts->gen.scratch1, SZ_B);
4862 } else { 4477 } else {
4863 dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, SCRATCH1, SZ_B); 4478 or_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + flag, opts->gen.scratch1, SZ_B);
4864 } 4479 }
4865 } 4480 }
4866 dst = retn(dst); 4481 retn(code);
4867 4482
4868 opts->set_sr = dst; 4483 opts->set_sr = code->cur;
4869 for (int flag = FLAG_C; flag >= FLAG_X; flag--) 4484 for (int flag = FLAG_C; flag >= FLAG_X; flag--)
4870 { 4485 {
4871 dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); 4486 rcr_ir(code, 1, opts->gen.scratch1, SZ_B);
4872 if (opts->flag_regs[flag] >= 0) { 4487 if (opts->flag_regs[flag] >= 0) {
4873 dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); 4488 setcc_r(code, CC_C, opts->flag_regs[flag]);
4874 } else { 4489 } else {
4875 int8_t offset = offsetof(m68k_context, flags) + flag; 4490 int8_t offset = offsetof(m68k_context, flags) + flag;
4876 if (offset) { 4491 if (offset) {
4877 dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); 4492 setcc_rdisp(code, CC_C, opts->gen.context_reg, offset);
4878 } else { 4493 } else {
4879 dst = setcc_rind(dst, CC_C, CONTEXT); 4494 setcc_rind(code, CC_C, opts->gen.context_reg);
4880 } 4495 }
4881 } 4496 }
4882 } 4497 }
4883 dst = shr_ir(dst, 8, SCRATCH1, SZ_W); 4498 shr_ir(code, 8, opts->gen.scratch1, SZ_W);
4884 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B); 4499 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4885 dst = retn(dst); 4500 retn(code);
4886 4501
4887 opts->set_ccr = dst; 4502 opts->set_ccr = code->cur;
4888 for (int flag = FLAG_C; flag >= FLAG_X; flag--) 4503 for (int flag = FLAG_C; flag >= FLAG_X; flag--)
4889 { 4504 {
4890 dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); 4505 rcr_ir(code, 1, opts->gen.scratch1, SZ_B);
4891 if (opts->flag_regs[flag] >= 0) { 4506 if (opts->flag_regs[flag] >= 0) {
4892 dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); 4507 setcc_r(code, CC_C, opts->flag_regs[flag]);
4893 } else { 4508 } else {
4894 int8_t offset = offsetof(m68k_context, flags) + flag; 4509 int8_t offset = offsetof(m68k_context, flags) + flag;
4895 if (offset) { 4510 if (offset) {
4896 dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); 4511 setcc_rdisp(code, CC_C, opts->gen.context_reg, offset);
4897 } else { 4512 } else {
4898 dst = setcc_rind(dst, CC_C, CONTEXT); 4513 setcc_rind(code, CC_C, opts->gen.context_reg);
4899 } 4514 }
4900 } 4515 }
4901 } 4516 }
4902 dst = retn(dst); 4517 retn(code);
4903 4518
4904 opts->gen.handle_cycle_limit_int = dst; 4519 opts->gen.handle_cycle_limit_int = code->cur;
4905 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); 4520 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), CYCLES, SZ_D);
4906 code_ptr do_int = dst+1; 4521 code_ptr do_int = code->cur + 1;
4907 dst = jcc(dst, CC_NC, dst+2); 4522 jcc(code, CC_NC, code->cur + 2);
4908 dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); 4523 cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D);
4909 skip_sync = dst+1; 4524 skip_sync = code->cur + 1;
4910 dst = jcc(dst, CC_C, dst+2); 4525 jcc(code, CC_C, code->cur + 2);
4911 dst = call(dst, opts->gen.save_context); 4526 call(code, opts->gen.save_context);
4912 #ifdef X86_64 4527 #ifdef X86_64
4913 dst = mov_rr(dst, CONTEXT, RDI, SZ_PTR); 4528 mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR);
4914 dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); 4529 mov_rr(code, opts->gen.scratch1, RSI, SZ_D);
4915 dst = test_ir(dst, 8, RSP, SZ_D); 4530 test_ir(code, 8, RSP, SZ_D);
4916 adjust_rsp = dst+1; 4531 adjust_rsp = code->cur + 1;
4917 dst = jcc(dst, CC_NZ, dst+2); 4532 jcc(code, CC_NZ, code->cur + 2);
4918 dst = call(dst, (code_ptr)sync_components); 4533 call(code, (code_ptr)sync_components);
4919 no_adjust = dst+1; 4534 no_adjust = code->cur + 1;
4920 dst = jmp(dst, dst+2); 4535 jmp(code, code->cur + 2);
4921 *adjust_rsp = dst - (adjust_rsp + 1); 4536 *adjust_rsp = code->cur - (adjust_rsp + 1);
4922 dst = sub_ir(dst, 8, RSP, SZ_PTR); 4537 sub_ir(code, 8, RSP, SZ_PTR);
4923 dst = call(dst, (code_ptr)sync_components); 4538 call(code, (code_ptr)sync_components);
4924 dst = add_ir(dst, 8, RSP, SZ_PTR); 4539 add_ir(code, 8, RSP, SZ_PTR);
4925 *no_adjust = dst - (no_adjust+1); 4540 *no_adjust = code->cur - (no_adjust+1);
4926 #else 4541 #else
4927 dst = push_r(dst, SCRATCH1); 4542 push_r(code, opts->gen.scratch1);
4928 dst = push_r(dst, CONTEXT); 4543 push_r(code, opts->gen.context_reg);
4929 dst = call(dst, (code_ptr)sync_components); 4544 call(code, (code_ptr)sync_components);
4930 dst = add_ir(dst, 8, RSP, SZ_D); 4545 add_ir(code, 8, RSP, SZ_D);
4931 #endif 4546 #endif
4932 dst = mov_rr(dst, RAX, CONTEXT, SZ_PTR); 4547 mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
4933 dst = jmp(dst, opts->gen.load_context); 4548 jmp(code, opts->gen.load_context);
4934 *skip_sync = dst - (skip_sync+1); 4549 *skip_sync = code->cur - (skip_sync+1);
4935 dst = retn(dst); 4550 retn(code);
4936 *do_int = dst - (do_int+1); 4551 *do_int = code->cur - (do_int+1);
4937 //set target cycle to sync cycle 4552 //set target cycle to sync cycle
4938 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); 4553 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D);
4939 //swap USP and SSP if not already in supervisor mode 4554 //swap USP and SSP if not already in supervisor mode
4940 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 4555 bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4941 code_ptr already_supervisor = dst+1; 4556 code_ptr already_supervisor = code->cur + 1;
4942 dst = jcc(dst, CC_C, dst+2); 4557 jcc(code, CC_C, code->cur + 2);
4943 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D); 4558 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch2, SZ_D);
4944 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 4559 mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
4945 dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D); 4560 mov_rr(code, opts->gen.scratch2, opts->aregs[7], SZ_D);
4946 *already_supervisor = dst - (already_supervisor+1); 4561 *already_supervisor = code->cur - (already_supervisor+1);
4947 //save PC 4562 //save PC
4948 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 4563 sub_ir(code, 4, opts->aregs[7], SZ_D);
4949 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4564 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
4950 dst = call(dst, opts->write_32_lowfirst); 4565 call(code, opts->write_32_lowfirst);
4951 //save status register 4566 //save status register
4952 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); 4567 sub_ir(code, 2, opts->aregs[7], SZ_D);
4953 dst = call(dst, opts->get_sr); 4568 call(code, opts->get_sr);
4954 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4569 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
4955 dst = call(dst, opts->write_16); 4570 call(code, opts->write_16);
4956 //update status register 4571 //update status register
4957 dst = and_irdisp8(dst, 0xF8, CONTEXT, offsetof(m68k_context, status), SZ_B); 4572 and_irdisp(code, 0xF8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4958 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_B); 4573 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_B);
4959 dst = or_ir(dst, 0x20, SCRATCH1, SZ_B); 4574 or_ir(code, 0x20, opts->gen.scratch1, SZ_B);
4960 dst = or_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B); 4575 or_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4961 //calculate interrupt vector address 4576 //calculate interrupt vector address
4962 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_num), SCRATCH1, SZ_D); 4577 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_num), opts->gen.scratch1, SZ_D);
4963 dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, int_ack), SZ_W); 4578 mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, int_ack), SZ_W);
4964 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); 4579 shl_ir(code, 2, opts->gen.scratch1, SZ_D);
4965 dst = add_ir(dst, 0x60, SCRATCH1, SZ_D); 4580 add_ir(code, 0x60, opts->gen.scratch1, SZ_D);
4966 dst = call(dst, opts->read_32); 4581 call(code, opts->read_32);
4967 dst = call(dst, opts->native_addr_and_sync); 4582 call(code, opts->native_addr_and_sync);
4968 dst = cycles(dst, 24); 4583 cycles(&opts->gen, 24);
4969 //discard function return address 4584 //discard function return address
4970 dst = pop_r(dst, SCRATCH2); 4585 pop_r(code, opts->gen.scratch2);
4971 dst = jmp_r(dst, SCRATCH1); 4586 jmp_r(code, opts->gen.scratch1);
4972 4587
4973 opts->trap = dst; 4588 opts->trap = code->cur;
4974 dst = push_r(dst, SCRATCH2); 4589 push_r(code, opts->gen.scratch2);
4975 //swap USP and SSP if not already in supervisor mode 4590 //swap USP and SSP if not already in supervisor mode
4976 dst = bt_irdisp8(dst, 5, CONTEXT, offsetof(m68k_context, status), SZ_B); 4591 bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4977 already_supervisor = dst+1; 4592 already_supervisor = code->cur + 1;
4978 dst = jcc(dst, CC_C, dst+2); 4593 jcc(code, CC_C, code->cur + 2);
4979 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SCRATCH2, SZ_D); 4594 mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch2, SZ_D);
4980 dst = mov_rrdisp8(dst, opts->aregs[7], CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); 4595 mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D);
4981 dst = mov_rr(dst, SCRATCH2, opts->aregs[7], SZ_D); 4596 mov_rr(code, opts->gen.scratch2, opts->aregs[7], SZ_D);
4982 *already_supervisor = dst - (already_supervisor+1); 4597 *already_supervisor = code->cur - (already_supervisor+1);
4983 //save PC 4598 //save PC
4984 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 4599 sub_ir(code, 4, opts->aregs[7], SZ_D);
4985 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4600 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
4986 dst = call(dst, opts->write_32_lowfirst); 4601 call(code, opts->write_32_lowfirst);
4987 //save status register 4602 //save status register
4988 dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); 4603 sub_ir(code, 2, opts->aregs[7], SZ_D);
4989 dst = call(dst, opts->get_sr); 4604 call(code, opts->get_sr);
4990 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 4605 mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D);
4991 dst = call(dst, opts->write_16); 4606 call(code, opts->write_16);
4992 //set supervisor bit 4607 //set supervisor bit
4993 dst = or_irdisp8(dst, 0x20, CONTEXT, offsetof(m68k_context, status), SZ_B); 4608 or_irdisp(code, 0x20, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B);
4994 //calculate vector address 4609 //calculate vector address
4995 dst = pop_r(dst, SCRATCH1); 4610 pop_r(code, opts->gen.scratch1);
4996 dst = shl_ir(dst, 2, SCRATCH1, SZ_D); 4611 shl_ir(code, 2, opts->gen.scratch1, SZ_D);
4997 dst = call(dst, opts->read_32); 4612 call(code, opts->read_32);
4998 dst = call(dst, opts->native_addr_and_sync); 4613 call(code, opts->native_addr_and_sync);
4999 dst = cycles(dst, 18); 4614 cycles(&opts->gen, 18);
5000 dst = jmp_r(dst, SCRATCH1); 4615 jmp_r(code, opts->gen.scratch1);
5001
5002 opts->gen.cur_code = dst;
5003 } 4616 }
5004 4617
5005 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) 4618 void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts)
5006 { 4619 {
5007 memset(context, 0, sizeof(m68k_context)); 4620 memset(context, 0, sizeof(m68k_context));