some portability cleanups
[picodrive.git] / cpu / drc / emit_x86.c
1 /*
2  * Basic macros to emit x86 instructions and some utils
3  * Copyright (C) 2008,2009,2010 notaz
4  *
5  * This work is licensed under the terms of MAME license.
6  * See COPYING file in the top-level directory.
7  *
8  * note:
9  *  temp registers must be eax-edx due to use of SETcc and r/w 8/16.
10  * note about silly things like emith_eor_r_r_r:
11  *  these are here because the compiler was designed
12  *  for ARM as it's primary target.
13  */
14 #include <stdarg.h>
15
16 enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI };
17
18 #define CONTEXT_REG xBP
19
20 #define ICOND_JO  0x00
21 #define ICOND_JNO 0x01
22 #define ICOND_JB  0x02
23 #define ICOND_JAE 0x03
24 #define ICOND_JE  0x04
25 #define ICOND_JNE 0x05
26 #define ICOND_JBE 0x06
27 #define ICOND_JA  0x07
28 #define ICOND_JS  0x08
29 #define ICOND_JNS 0x09
30 #define ICOND_JL  0x0c
31 #define ICOND_JGE 0x0d
32 #define ICOND_JLE 0x0e
33 #define ICOND_JG  0x0f
34
35 #define IOP_JMP   0xeb
36
37 // unified conditions (we just use rel8 jump instructions for x86)
38 #define DCOND_EQ ICOND_JE
39 #define DCOND_NE ICOND_JNE
40 #define DCOND_MI ICOND_JS      // MInus
41 #define DCOND_PL ICOND_JNS     // PLus or zero
42 #define DCOND_HI ICOND_JA      // higher (unsigned)
43 #define DCOND_HS ICOND_JAE     // higher || same (unsigned)
44 #define DCOND_LO ICOND_JB      // lower (unsigned)
45 #define DCOND_LS ICOND_JBE     // lower || same (unsigned)
46 #define DCOND_GE ICOND_JGE     // greater || equal (signed)
47 #define DCOND_GT ICOND_JG      // greater (signed)
48 #define DCOND_LE ICOND_JLE     // less || equal (signed)
49 #define DCOND_LT ICOND_JL      // less (signed)
50 #define DCOND_VS ICOND_JO      // oVerflow Set
51 #define DCOND_VC ICOND_JNO     // oVerflow Clear
52
53 #define EMIT_PTR(ptr, val, type) \
54         *(type *)(ptr) = val
55
56 #define EMIT(val, type) { \
57         EMIT_PTR(tcache_ptr, val, type); \
58         tcache_ptr += sizeof(type); \
59 }
60
61 #define EMIT_OP(op) { \
62         COUNT_OP; \
63         EMIT(op, u8); \
64 }
65
66 #define EMIT_MODRM(mod,r,rm) \
67         EMIT(((mod)<<6) | ((r)<<3) | (rm), u8)
68
69 #define EMIT_SIB(scale,index,base) \
70         EMIT(((scale)<<6) | ((index)<<3) | (base), u8)
71
72 #define EMIT_OP_MODRM(op,mod,r,rm) do { \
73         EMIT_OP(op); \
74         EMIT_MODRM(mod, r, rm); \
75 } while (0)
76
77 #define JMP8_POS(ptr) \
78         ptr = tcache_ptr; \
79         tcache_ptr += 2
80
81 #define JMP8_EMIT(op, ptr) \
82         EMIT_PTR(ptr, 0x70|(op), u8); \
83         EMIT_PTR(ptr + 1, (tcache_ptr - (ptr+2)), u8)
84
85 #define JMP8_EMIT_NC(ptr) \
86         EMIT_PTR(ptr, IOP_JMP, u8); \
87         EMIT_PTR(ptr + 1, (tcache_ptr - (ptr+2)), u8)
88
89 // _r_r
90 #define emith_move_r_r(dst, src) \
91         EMIT_OP_MODRM(0x8b, 3, dst, src)
92
93 #define emith_add_r_r(d, s) \
94         EMIT_OP_MODRM(0x01, 3, s, d)
95
96 #define emith_sub_r_r(d, s) \
97         EMIT_OP_MODRM(0x29, 3, s, d)
98
99 #define emith_adc_r_r(d, s) \
100         EMIT_OP_MODRM(0x11, 3, s, d)
101
102 #define emith_sbc_r_r(d, s) \
103         EMIT_OP_MODRM(0x19, 3, s, d) /* SBB */
104
105 #define emith_or_r_r(d, s) \
106         EMIT_OP_MODRM(0x09, 3, s, d)
107
108 #define emith_and_r_r(d, s) \
109         EMIT_OP_MODRM(0x21, 3, s, d)
110
111 #define emith_eor_r_r(d, s) \
112         EMIT_OP_MODRM(0x31, 3, s, d) /* XOR */
113
114 #define emith_tst_r_r(d, s) \
115         EMIT_OP_MODRM(0x85, 3, s, d) /* TEST */
116
117 #define emith_cmp_r_r(d, s) \
118         EMIT_OP_MODRM(0x39, 3, s, d)
119
120 // fake teq - test equivalence - get_flags(d ^ s)
121 #define emith_teq_r_r(d, s) { \
122         emith_push(d); \
123         emith_eor_r_r(d, s); \
124         emith_pop(d); \
125 }
126
127 #define emith_mvn_r_r(d, s) { \
128         if (d != s) \
129                 emith_move_r_r(d, s); \
130         EMIT_OP_MODRM(0xf7, 3, 2, d); /* NOT d */ \
131 }
132
133 #define emith_negc_r_r(d, s) { \
134         int tmp_ = rcache_get_tmp(); \
135         emith_move_r_imm(tmp_, 0); \
136         emith_sbc_r_r(tmp_, s); \
137         emith_move_r_r(d, tmp_); \
138         rcache_free_tmp(tmp_); \
139 }
140
141 #define emith_neg_r_r(d, s) { \
142         if (d != s) \
143                 emith_move_r_r(d, s); \
144         EMIT_OP_MODRM(0xf7, 3, 3, d); /* NEG d */ \
145 }
146
147 // _r_r_r
148 #define emith_add_r_r_r(d, s1, s2) { \
149         if (d == s1) { \
150                 emith_add_r_r(d, s2); \
151         } else if (d == s2) { \
152                 emith_add_r_r(d, s1); \
153         } else { \
154                 emith_move_r_r(d, s1); \
155                 emith_add_r_r(d, s2); \
156         } \
157 }
158
159 #define emith_eor_r_r_r(d, s1, s2) { \
160         if (d == s1) { \
161                 emith_eor_r_r(d, s2); \
162         } else if (d == s2) { \
163                 emith_eor_r_r(d, s1); \
164         } else { \
165                 emith_move_r_r(d, s1); \
166                 emith_eor_r_r(d, s2); \
167         } \
168 }
169
170 // _r_r_shift
171 #define emith_or_r_r_lsl(d, s, lslimm) { \
172         int tmp_ = rcache_get_tmp(); \
173         emith_lsl(tmp_, s, lslimm); \
174         emith_or_r_r(d, tmp_); \
175         rcache_free_tmp(tmp_); \
176 }
177
178 // d != s
179 #define emith_eor_r_r_lsr(d, s, lsrimm) { \
180         emith_push(s); \
181         emith_lsr(s, s, lsrimm); \
182         emith_eor_r_r(d, s); \
183         emith_pop(s); \
184 }
185
186 // _r_imm
187 #define emith_move_r_imm(r, imm) { \
188         EMIT_OP(0xb8 + (r)); \
189         EMIT(imm, u32); \
190 }
191
192 #define emith_move_r_imm_s8(r, imm) \
193         emith_move_r_imm(r, (u32)(signed int)(signed char)(imm))
194
195 #define emith_arith_r_imm(op, r, imm) do { \
196         EMIT_OP_MODRM(0x81, 3, op, r); \
197         EMIT(imm, u32); \
198 } while (0)
199
200 #define emith_add_r_imm(r, imm) \
201         emith_arith_r_imm(0, r, imm)
202
203 #define emith_or_r_imm(r, imm) \
204         emith_arith_r_imm(1, r, imm)
205
206 #define emith_adc_r_imm(r, imm) \
207         emith_arith_r_imm(2, r, imm)
208
209 #define emith_sbc_r_imm(r, imm) \
210         emith_arith_r_imm(3, r, imm) // sbb
211
212 #define emith_and_r_imm(r, imm) \
213         emith_arith_r_imm(4, r, imm)
214
215 #define emith_sub_r_imm(r, imm) \
216         emith_arith_r_imm(5, r, imm)
217
218 #define emith_eor_r_imm(r, imm) \
219         emith_arith_r_imm(6, r, imm)
220
221 #define emith_cmp_r_imm(r, imm) \
222         emith_arith_r_imm(7, r, imm)
223
224 #define emith_tst_r_imm(r, imm) do { \
225         EMIT_OP_MODRM(0xf7, 3, 0, r); \
226         EMIT(imm, u32); \
227 } while (0)
228
229 // fake
230 #define emith_bic_r_imm(r, imm) \
231         emith_arith_r_imm(4, r, ~(imm))
232
233 // fake conditionals (using SJMP instead)
234 #define emith_move_r_imm_c(cond, r, imm) { \
235         (void)(cond); \
236         emith_move_r_imm(r, imm); \
237 }
238
239 #define emith_add_r_imm_c(cond, r, imm) { \
240         (void)(cond); \
241         emith_add_r_imm(r, imm); \
242 }
243
244 #define emith_sub_r_imm_c(cond, r, imm) { \
245         (void)(cond); \
246         emith_sub_r_imm(r, imm); \
247 }
248
249 #define emith_or_r_imm_c(cond, r, imm) \
250         emith_or_r_imm(r, imm)
251 #define emith_eor_r_imm_c(cond, r, imm) \
252         emith_eor_r_imm(r, imm)
253 #define emith_bic_r_imm_c(cond, r, imm) \
254         emith_bic_r_imm(r, imm)
255 #define emith_ror_c(cond, d, s, cnt) \
256         emith_ror(d, s, cnt)
257
258 #define emith_read_r_r_offs_c(cond, r, rs, offs) \
259         emith_read_r_r_offs(r, rs, offs)
260 #define emith_write_r_r_offs_c(cond, r, rs, offs) \
261         emith_write_r_r_offs(r, rs, offs)
262 #define emith_read8_r_r_offs_c(cond, r, rs, offs) \
263         emith_read8_r_r_offs(r, rs, offs)
264 #define emith_write8_r_r_offs_c(cond, r, rs, offs) \
265         emith_write8_r_r_offs(r, rs, offs)
266 #define emith_read16_r_r_offs_c(cond, r, rs, offs) \
267         emith_read16_r_r_offs(r, rs, offs)
268 #define emith_write16_r_r_offs_c(cond, r, rs, offs) \
269         emith_write16_r_r_offs(r, rs, offs)
270 #define emith_jump_reg_c(cond, r) \
271         emith_jump_reg(r)
272 #define emith_jump_ctx_c(cond, offs) \
273         emith_jump_ctx(offs)
274 #define emith_ret_c(cond) \
275         emith_ret()
276
277 // _r_r_imm
278 #define emith_add_r_r_imm(d, s, imm) { \
279         if (d != s) \
280                 emith_move_r_r(d, s); \
281         emith_add_r_imm(d, imm); \
282 }
283
284 #define emith_and_r_r_imm(d, s, imm) { \
285         if (d != s) \
286                 emith_move_r_r(d, s); \
287         emith_and_r_imm(d, imm); \
288 }
289
290 // shift
291 #define emith_shift(op, d, s, cnt) { \
292         if (d != s) \
293                 emith_move_r_r(d, s); \
294         EMIT_OP_MODRM(0xc1, 3, op, d); \
295         EMIT(cnt, u8); \
296 }
297
298 #define emith_lsl(d, s, cnt) \
299         emith_shift(4, d, s, cnt)
300
301 #define emith_lsr(d, s, cnt) \
302         emith_shift(5, d, s, cnt)
303
304 #define emith_asr(d, s, cnt) \
305         emith_shift(7, d, s, cnt)
306
307 #define emith_rol(d, s, cnt) \
308         emith_shift(0, d, s, cnt)
309
310 #define emith_ror(d, s, cnt) \
311         emith_shift(1, d, s, cnt)
312
313 #define emith_rolc(r) \
314         EMIT_OP_MODRM(0xd1, 3, 2, r)
315
316 #define emith_rorc(r) \
317         EMIT_OP_MODRM(0xd1, 3, 3, r)
318
319 // misc
320 #define emith_push(r) \
321         EMIT_OP(0x50 + (r))
322
323 #define emith_push_imm(imm) { \
324         EMIT_OP(0x68); \
325         EMIT(imm, u32); \
326 }
327
328 #define emith_pop(r) \
329         EMIT_OP(0x58 + (r))
330
331 #define emith_neg_r(r) \
332         EMIT_OP_MODRM(0xf7, 3, 3, r)
333
334 #define emith_clear_msb(d, s, count) { \
335         u32 t = (u32)-1; \
336         t >>= count; \
337         if (d != s) \
338                 emith_move_r_r(d, s); \
339         emith_and_r_imm(d, t); \
340 }
341
342 #define emith_clear_msb_c(cond, d, s, count) { \
343         (void)(cond); \
344         emith_clear_msb(d, s, count); \
345 }
346
347 #define emith_sext(d, s, bits) { \
348         emith_lsl(d, s, 32 - (bits)); \
349         emith_asr(d, d, 32 - (bits)); \
350 }
351
352 #define emith_setc(r) { \
353         EMIT_OP(0x0f); \
354         EMIT_OP_MODRM(0x92, 3, 0, r); /* SETC r */ \
355 }
356
357 // XXX: stupid mess
358 #define emith_mul_(op, dlo, dhi, s1, s2) { \
359         int rmr; \
360         if (dlo != xAX && dhi != xAX) \
361                 emith_push(xAX); \
362         if (dlo != xDX && dhi != xDX) \
363                 emith_push(xDX); \
364         if ((s1) == xAX) \
365                 rmr = s2; \
366         else if ((s2) == xAX) \
367                 rmr = s1; \
368         else { \
369                 emith_move_r_r(xAX, s1); \
370                 rmr = s2; \
371         } \
372         EMIT_OP_MODRM(0xf7, 3, op, rmr); /* xMUL rmr */ \
373         /* XXX: using push/pop for the case of edx->eax; eax->edx */ \
374         if (dhi != xDX && dhi != -1) \
375                 emith_push(xDX); \
376         if (dlo != xAX) \
377                 emith_move_r_r(dlo, xAX); \
378         if (dhi != xDX && dhi != -1) \
379                 emith_pop(dhi); \
380         if (dlo != xDX && dhi != xDX) \
381                 emith_pop(xDX); \
382         if (dlo != xAX && dhi != xAX) \
383                 emith_pop(xAX); \
384 }
385
386 #define emith_mul_u64(dlo, dhi, s1, s2) \
387         emith_mul_(4, dlo, dhi, s1, s2) /* MUL */
388
389 #define emith_mul_s64(dlo, dhi, s1, s2) \
390         emith_mul_(5, dlo, dhi, s1, s2) /* IMUL */
391
392 #define emith_mul(d, s1, s2) \
393         emith_mul_(4, d, -1, s1, s2)
394
395 // (dlo,dhi) += signed(s1) * signed(s2)
396 #define emith_mula_s64(dlo, dhi, s1, s2) { \
397         emith_push(dhi); \
398         emith_push(dlo); \
399         emith_mul_(5, dlo, dhi, s1, s2); \
400         EMIT_OP_MODRM(0x03, 0, dlo, 4); \
401         EMIT_SIB(0, 4, 4); /* add dlo, [esp] */ \
402         EMIT_OP_MODRM(0x13, 1, dhi, 4); \
403         EMIT_SIB(0, 4, 4); \
404         EMIT(4, u8); /* adc dhi, [esp+4] */ \
405         emith_add_r_imm(xSP, 4*2); \
406 }
407
408 // "flag" instructions are the same
409 #define emith_subf_r_imm emith_sub_r_imm
410 #define emith_addf_r_r   emith_add_r_r
411 #define emith_subf_r_r   emith_sub_r_r
412 #define emith_adcf_r_r   emith_adc_r_r
413 #define emith_sbcf_r_r   emith_sbc_r_r
414 #define emith_eorf_r_r   emith_eor_r_r
415 #define emith_negcf_r_r  emith_negc_r_r
416
417 #define emith_lslf  emith_lsl
418 #define emith_lsrf  emith_lsr
419 #define emith_asrf  emith_asr
420 #define emith_rolf  emith_rol
421 #define emith_rorf  emith_ror
422 #define emith_rolcf emith_rolc
423 #define emith_rorcf emith_rorc
424
425 #define emith_deref_op(op, r, rs, offs) do { \
426         /* mov r <-> [ebp+#offs] */ \
427         if ((offs) >= 0x80) { \
428                 EMIT_OP_MODRM(op, 2, r, rs); \
429                 EMIT(offs, u32); \
430         } else { \
431                 EMIT_OP_MODRM(op, 1, r, rs); \
432                 EMIT(offs, u8); \
433         } \
434 } while (0)
435
436 #define is_abcdx(r) (xAX <= (r) && (r) <= xDX)
437
438 #define emith_read_r_r_offs(r, rs, offs) \
439         emith_deref_op(0x8b, r, rs, offs)
440
441 #define emith_write_r_r_offs(r, rs, offs) \
442         emith_deref_op(0x89, r, rs, offs)
443
444 // note: don't use prefixes on this
445 #define emith_read8_r_r_offs(r, rs, offs) do { \
446         int r_ = r; \
447         if (!is_abcdx(r)) \
448                 r_ = rcache_get_tmp(); \
449         emith_deref_op(0x8a, r_, rs, offs); \
450         if ((r) != r_) { \
451                 emith_move_r_r(r, r_); \
452                 rcache_free_tmp(r_); \
453         } \
454 } while (0)
455
456 #define emith_write8_r_r_offs(r, rs, offs) do {\
457         int r_ = r; \
458         if (!is_abcdx(r)) { \
459                 r_ = rcache_get_tmp(); \
460                 emith_move_r_r(r_, r); \
461         } \
462         emith_deref_op(0x88, r_, rs, offs); \
463         if ((r) != r_) \
464                 rcache_free_tmp(r_); \
465 } while (0)
466
467 #define emith_read16_r_r_offs(r, rs, offs) { \
468         EMIT(0x66, u8); /* operand override */ \
469         emith_read_r_r_offs(r, rs, offs); \
470 }
471
472 #define emith_write16_r_r_offs(r, rs, offs) { \
473         EMIT(0x66, u8); \
474         emith_write_r_r_offs(r, rs, offs); \
475 }
476
477 #define emith_ctx_read(r, offs) \
478         emith_read_r_r_offs(r, CONTEXT_REG, offs)
479
480 #define emith_ctx_write(r, offs) \
481         emith_write_r_r_offs(r, CONTEXT_REG, offs)
482
483 #define emith_ctx_read_multiple(r, offs, cnt, tmpr) do { \
484         int r_ = r, offs_ = offs, cnt_ = cnt;     \
485         for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
486                 emith_ctx_read(r_, offs_);        \
487 } while (0)
488
489 #define emith_ctx_write_multiple(r, offs, cnt, tmpr) do { \
490         int r_ = r, offs_ = offs, cnt_ = cnt;     \
491         for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
492                 emith_ctx_write(r_, offs_);       \
493 } while (0)
494
495 // assumes EBX is free
496 #define emith_ret_to_ctx(offs) { \
497         emith_pop(xBX); \
498         emith_ctx_write(xBX, offs); \
499 }
500
501 #define emith_jump(ptr) { \
502         u32 disp = (u32)(ptr) - ((u32)tcache_ptr + 5); \
503         EMIT_OP(0xe9); \
504         EMIT(disp, u32); \
505 }
506
507 #define emith_jump_patchable(target) \
508         emith_jump(target)
509
510 #define emith_jump_cond(cond, ptr) { \
511         u32 disp = (u32)(ptr) - ((u32)tcache_ptr + 6); \
512         EMIT(0x0f, u8); \
513         EMIT_OP(0x80 | (cond)); \
514         EMIT(disp, u32); \
515 }
516
517 #define emith_jump_cond_patchable(cond, target) \
518         emith_jump_cond(cond, target)
519
520 #define emith_jump_patch(ptr, target) do { \
521         u32 disp_ = (u32)(target) - ((u32)(ptr) + 4); \
522         u32 offs_ = (*(u8 *)(ptr) == 0x0f) ? 2 : 1; \
523         EMIT_PTR((u8 *)(ptr) + offs_, disp_ - offs_, u32); \
524 } while (0)
525
526 #define emith_jump_at(ptr, target) { \
527         u32 disp_ = (u32)(target) - ((u32)(ptr) + 5); \
528         EMIT_PTR(ptr, 0xe9, u8); \
529         EMIT_PTR((u8 *)(ptr) + 1, disp_, u32); \
530 }
531
532 #define emith_call(ptr) { \
533         u32 disp = (u32)(ptr) - ((u32)tcache_ptr + 5); \
534         EMIT_OP(0xe8); \
535         EMIT(disp, u32); \
536 }
537
538 #define emith_call_cond(cond, ptr) \
539         emith_call(ptr)
540
541 #define emith_call_reg(r) \
542         EMIT_OP_MODRM(0xff, 3, 2, r)
543
544 #define emith_call_ctx(offs) { \
545         EMIT_OP_MODRM(0xff, 2, 2, CONTEXT_REG); \
546         EMIT(offs, u32); \
547 }
548
549 #define emith_ret() \
550         EMIT_OP(0xc3)
551
552 #define emith_jump_reg(r) \
553         EMIT_OP_MODRM(0xff, 3, 4, r)
554
555 #define emith_jump_ctx(offs) { \
556         EMIT_OP_MODRM(0xff, 2, 4, CONTEXT_REG); \
557         EMIT(offs, u32); \
558 }
559
560 #define emith_push_ret()
561
562 #define emith_pop_and_ret() \
563         emith_ret()
564
565 #define EMITH_JMP_START(cond) { \
566         u8 *cond_ptr; \
567         JMP8_POS(cond_ptr)
568
569 #define EMITH_JMP_END(cond) \
570         JMP8_EMIT(cond, cond_ptr); \
571 }
572
573 #define EMITH_JMP3_START(cond) { \
574         u8 *cond_ptr, *else_ptr; \
575         JMP8_POS(cond_ptr)
576
577 #define EMITH_JMP3_MID(cond) \
578         JMP8_POS(else_ptr); \
579         JMP8_EMIT(cond, cond_ptr);
580
581 #define EMITH_JMP3_END() \
582         JMP8_EMIT_NC(else_ptr); \
583 }
584
585 // "simple" jump (no more then a few insns)
586 // ARM will use conditional instructions here
587 #define EMITH_SJMP_START EMITH_JMP_START
588 #define EMITH_SJMP_END EMITH_JMP_END
589
590 #define EMITH_SJMP3_START EMITH_JMP3_START
591 #define EMITH_SJMP3_MID EMITH_JMP3_MID
592 #define EMITH_SJMP3_END EMITH_JMP3_END
593
594 #define emith_pass_arg_r(arg, reg) { \
595         int rd = 7; \
596         host_arg2reg(rd, arg); \
597         emith_move_r_r(rd, reg); \
598 }
599
600 #define emith_pass_arg_imm(arg, imm) { \
601         int rd = 7; \
602         host_arg2reg(rd, arg); \
603         emith_move_r_imm(rd, imm); \
604 }
605
606 #define host_instructions_updated(base, end)
607
608 #define host_arg2reg(rd, arg) \
609         switch (arg) { \
610         case 0: rd = xAX; break; \
611         case 1: rd = xDX; break; \
612         case 2: rd = xCX; break; \
613         }
614
615 /* SH2 drc specific */
616 #define emith_sh2_drc_entry() { \
617         emith_push(xBX);        \
618         emith_push(xBP);        \
619         emith_push(xSI);        \
620         emith_push(xDI);        \
621 }
622
623 #define emith_sh2_drc_exit() {  \
624         emith_pop(xDI);         \
625         emith_pop(xSI);         \
626         emith_pop(xBP);         \
627         emith_pop(xBX);         \
628         emith_ret();            \
629 }
630
631 // assumes EBX is free temporary
632 #define emith_sh2_wcall(a, tab) { \
633         int arg2_; \
634         host_arg2reg(arg2_, 2); \
635         emith_lsr(xBX, a, SH2_WRITE_SHIFT); \
636         EMIT_OP_MODRM(0x8b, 0, xBX, 4); \
637         EMIT_SIB(2, xBX, tab); /* mov ebx, [tab + ebx * 4] */ \
638         emith_move_r_r(arg2_, CONTEXT_REG); \
639         emith_jump_reg(xBX); \
640 }
641
642 #define emith_sh2_dtbf_loop() { \
643         u8 *jmp0; /* negative cycles check */            \
644         u8 *jmp1; /* unsinged overflow check */          \
645         int cr, rn;                                      \
646         int tmp_ = rcache_get_tmp();                     \
647         cr = rcache_get_reg(SHR_SR, RC_GR_RMW);          \
648         rn = rcache_get_reg((op >> 8) & 0x0f, RC_GR_RMW);\
649         emith_sub_r_imm(rn, 1);                          \
650         emith_sub_r_imm(cr, (cycles+1) << 12);           \
651         cycles = 0;                                      \
652         emith_asr(tmp_, cr, 2+12);                       \
653         JMP8_POS(jmp0); /* no negative cycles */         \
654         emith_move_r_imm(tmp_, 0);                       \
655         JMP8_EMIT(ICOND_JNS, jmp0);                      \
656         emith_and_r_imm(cr, 0xffe);                      \
657         emith_subf_r_r(rn, tmp_);                        \
658         JMP8_POS(jmp1); /* no overflow */                \
659         emith_neg_r(rn); /* count left */                \
660         emith_lsl(rn, rn, 2+12);                         \
661         emith_or_r_r(cr, rn);                            \
662         emith_or_r_imm(cr, 1);                           \
663         emith_move_r_imm(rn, 0);                         \
664         JMP8_EMIT(ICOND_JA, jmp1);                       \
665         rcache_free_tmp(tmp_);                           \
666 }
667
668 #define emith_write_sr(sr, srcr) { \
669         int tmp_ = rcache_get_tmp(); \
670         emith_clear_msb(tmp_, srcr, 22); \
671         emith_bic_r_imm(sr, 0x3ff); \
672         emith_or_r_r(sr, tmp_); \
673         rcache_free_tmp(tmp_); \
674 }
675
676 #define emith_tpop_carry(sr, is_sub) \
677         emith_lsr(sr, sr, 1)
678
679 #define emith_tpush_carry(sr, is_sub) \
680         emith_adc_r_r(sr, sr)
681
682 /*
683  * if Q
684  *   t = carry(Rn += Rm)
685  * else
686  *   t = carry(Rn -= Rm)
687  * T ^= t
688  */
689 #define emith_sh2_div1_step(rn, rm, sr) {         \
690         u8 *jmp0, *jmp1;                          \
691         int tmp_ = rcache_get_tmp();              \
692         emith_eor_r_r(tmp_, tmp_);                \
693         emith_tst_r_imm(sr, Q);  /* if (Q ^ M) */ \
694         JMP8_POS(jmp0);          /* je do_sub */  \
695         emith_add_r_r(rn, rm);                    \
696         JMP8_POS(jmp1);          /* jmp done */   \
697         JMP8_EMIT(ICOND_JE, jmp0); /* do_sub: */  \
698         emith_sub_r_r(rn, rm);                    \
699         JMP8_EMIT_NC(jmp1);      /* done: */      \
700         emith_setc(tmp_);                         \
701         EMIT_OP_MODRM(0x31, 3, tmp_, sr); /* T = Q1 ^ Q2 */ \
702         rcache_free_tmp(tmp_);                    \
703 }
704