6d2598ea951f7849763bd990eeaff15f7d21aafa
[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  * Copyright (C) 2019-2024 irixxxx
5  *
6  * This work is licensed under the terms of MAME license.
7  * See COPYING file in the top-level directory.
8  *
9  * note:
10  *  temp registers must be eax-edx due to use of SETcc and r/w 8/16.
11  * note about silly things like emith_eor_r_r_r:
12  *  these are here because the compiler was designed
13  *  for ARM as it's primary target.
14  */
15 #include <stdarg.h>
16
17 enum { xAX = 0, xCX, xDX, xBX, xSP, xBP, xSI, xDI,      // x86-64,i386 common
18        xR8, xR9, xR10, xR11, xR12, xR13, xR14, xR15 };  // x86-64 only
19
20 #define CONTEXT_REG     xBP
21 #define RET_REG         xAX
22
23 #define ICOND_JO  0x00
24 #define ICOND_JNO 0x01
25 #define ICOND_JB  0x02
26 #define ICOND_JAE 0x03
27 #define ICOND_JE  0x04
28 #define ICOND_JNE 0x05
29 #define ICOND_JBE 0x06
30 #define ICOND_JA  0x07
31 #define ICOND_JS  0x08
32 #define ICOND_JNS 0x09
33 #define ICOND_JL  0x0c
34 #define ICOND_JGE 0x0d
35 #define ICOND_JLE 0x0e
36 #define ICOND_JG  0x0f
37
38 #define IOP_JMP   0xeb
39
40 // unified conditions (we just use rel8 jump instructions for x86)
41 #define DCOND_EQ ICOND_JE
42 #define DCOND_NE ICOND_JNE
43 #define DCOND_MI ICOND_JS      // MInus
44 #define DCOND_PL ICOND_JNS     // PLus or zero
45 #define DCOND_HI ICOND_JA      // higher (unsigned)
46 #define DCOND_HS ICOND_JAE     // higher || same (unsigned)
47 #define DCOND_LO ICOND_JB      // lower (unsigned)
48 #define DCOND_LS ICOND_JBE     // lower || same (unsigned)
49 #define DCOND_GE ICOND_JGE     // greater || equal (signed)
50 #define DCOND_GT ICOND_JG      // greater (signed)
51 #define DCOND_LE ICOND_JLE     // less || equal (signed)
52 #define DCOND_LT ICOND_JL      // less (signed)
53 #define DCOND_VS ICOND_JO      // oVerflow Set
54 #define DCOND_VC ICOND_JNO     // oVerflow Clear
55
56 #define DCOND_CS ICOND_JB      // carry set
57 #define DCOND_CC ICOND_JAE     // carry clear
58
59 #define EMIT_PTR(ptr, val, type) \
60         *(type *)(ptr) = val
61
62 #define EMIT(val, type) do { \
63         EMIT_PTR(tcache_ptr, val, type); \
64         tcache_ptr += sizeof(type); \
65 } while (0)
66
67 #define EMIT_OP(op) do { \
68         COUNT_OP; \
69         if ((op) > 0xff) EMIT((op) >> 8, u8); \
70         EMIT((u8)(op), u8); \
71 } while (0)
72
73 #define EMIT_MODRM(mod, r, rm) do { \
74         assert((mod) < 4u); \
75         assert((r) < 8u); \
76         assert((rm) < 8u); \
77         EMIT(((mod)<<6) | ((r)<<3) | (rm), u8); \
78 } while (0)
79
80 #define EMIT_SIB(scale, index, base) do { \
81         assert((scale) < 4u); \
82         assert((index) < 8u); \
83         assert((base) < 8u); \
84         EMIT(((scale)<<6) | ((index)<<3) | (base), u8); \
85 } while (0)
86
87 #define EMIT_SIB64(scale, index, base) \
88         EMIT_SIB(scale, (index) & ~8u, (base) & ~8u)
89
90 #define EMIT_REX(w,r,x,b) \
91         EMIT(0x40 | ((w)<<3) | ((r)<<2) | ((x)<<1) | (b), u8)
92
93 #define EMIT_OP_MODRM(op,mod,r,rm) do { \
94         EMIT_OP(op); \
95         EMIT_MODRM(mod, (r), rm); \
96 } while (0)
97
98 // 64bit friendly, rm when everything is converted
99 #define EMIT_OP_MODRM64(op, mod, r, rm) \
100         EMIT_OP_MODRM(op, mod, (r) & ~8u, (rm) & ~8u)
101
102 #define JMP8_POS(ptr) \
103         ptr = tcache_ptr; \
104         tcache_ptr += 2
105
106 #define JMP8_EMIT(op, ptr) \
107         EMIT_PTR(ptr, 0x70|(op), u8); \
108         EMIT_PTR(ptr + 1, (tcache_ptr - (ptr+2)), u8)
109
110 #define JMP8_EMIT_NC(ptr) \
111         EMIT_PTR(ptr, IOP_JMP, u8); \
112         EMIT_PTR(ptr + 1, (tcache_ptr - (ptr+2)), u8)
113
114 // _r_r
115 #define emith_move_r_r(dst, src) do {\
116         EMIT_REX_IF(0, dst, src); \
117         EMIT_OP_MODRM64(0x8b, 3, dst, src); \
118 } while (0)
119
120 #define emith_move_r_r_ptr(dst, src) do { \
121         EMIT_REX_IF(1, dst, src); \
122         EMIT_OP_MODRM64(0x8b, 3, dst, src); \
123 } while (0)
124
125 #define emith_add_r_r(d, s) do { \
126         EMIT_REX_IF(0, s, d); \
127         EMIT_OP_MODRM64(0x01, 3, s, d); \
128 } while (0)
129
130 #define emith_add_r_r_ptr(d, s) do { \
131         EMIT_REX_IF(1, s, d); \
132         EMIT_OP_MODRM64(0x01, 3, s, d); \
133 } while (0)
134
135 #define emith_sub_r_r(d, s) do {\
136         EMIT_REX_IF(0, s, d); \
137         EMIT_OP_MODRM64(0x29, 3, s, d); \
138 } while (0)
139
140 #define emith_adc_r_r(d, s) do { \
141         EMIT_REX_IF(0, s, d); \
142         EMIT_OP_MODRM64(0x11, 3, s, d); \
143 } while (0)
144
145 #define emith_sbc_r_r(d, s) do { \
146         EMIT_REX_IF(0, s, d); \
147         EMIT_OP_MODRM64(0x19, 3, s, d); /* SBB */ \
148 } while (0)
149
150 #define emith_or_r_r(d, s) do { \
151         EMIT_REX_IF(0, s, d); \
152         EMIT_OP_MODRM64(0x09, 3, s, d); \
153 } while (0)
154
155 #define emith_and_r_r(d, s) do { \
156         EMIT_REX_IF(0, s, d); \
157         EMIT_OP_MODRM64(0x21, 3, s, d); \
158 } while (0)
159
160 #define emith_eor_r_r(d, s) do { \
161         EMIT_REX_IF(0, s, d); \
162         EMIT_OP_MODRM64(0x31, 3, s, d); /* XOR */ \
163 } while (0)
164
165 #define emith_tst_r_r(d, s) do { \
166         EMIT_REX_IF(0, s, d); \
167         EMIT_OP_MODRM64(0x85, 3, s, d); /* TEST */ \
168 } while (0)
169
170 #define emith_tst_r_r_ptr(d, s) do { \
171         EMIT_REX_IF(1, s, d); \
172         EMIT_OP_MODRM64(0x85, 3, s, d); /* TEST */ \
173 } while (0)
174
175 #define emith_cmp_r_r(d, s) do { \
176         EMIT_REX_IF(0, s, d); \
177         EMIT_OP_MODRM64(0x39, 3, s, d); \
178 } while (0)
179
180 // fake teq - test equivalence - get_flags(d ^ s)
181 #define emith_teq_r_r(d, s) do { \
182         emith_push(d); \
183         emith_eor_r_r(d, s); \
184         emith_pop(d); \
185 } while (0)
186
187 #define emith_mvn_r_r(d, s) do { \
188         if (d != s) \
189                 emith_move_r_r(d, s); \
190         EMIT_REX_IF(0, 0, d); \
191         EMIT_OP_MODRM64(0xf7, 3, 2, d); /* NOT d */ \
192 } while (0)
193
194 #define emith_negc_r_r(d, s) do { \
195         int tmp_ = rcache_get_tmp(); \
196         emith_move_r_imm(tmp_, 0); \
197         emith_sbc_r_r(tmp_, s); \
198         emith_move_r_r(d, tmp_); \
199         rcache_free_tmp(tmp_); \
200 } while (0)
201
202 #define emith_neg_r_r(d, s) do { \
203         if (d != s) \
204                 emith_move_r_r(d, s); \
205         EMIT_REX_IF(0, 0, d); \
206         EMIT_OP_MODRM64(0xf7, 3, 3, d); /* NEG d */ \
207 } while (0)
208
209 // _r_r_r
210 #define emith_add_r_r_r(d, s1, s2) do { \
211         if (d == s1) { \
212                 emith_add_r_r(d, s2); \
213         } else if (d == s2) { \
214                 emith_add_r_r(d, s1); \
215         } else { \
216                 emith_move_r_r(d, s1); \
217                 emith_add_r_r(d, s2); \
218         } \
219 } while (0)
220
221 #define emith_add_r_r_r_ptr(d, s1, s2) do { \
222         if (d == s1) { \
223                 emith_add_r_r_ptr(d, s2); \
224         } else if (d == s2) { \
225                 emith_add_r_r_ptr(d, s1); \
226         } else { \
227                 emith_move_r_r_ptr(d, s1); \
228                 emith_add_r_r_ptr(d, s2); \
229         } \
230 } while (0)
231
232 #define emith_sub_r_r_r(d, s1, s2) do { \
233         if (d == s1) { \
234                 emith_sub_r_r(d, s2); \
235         } else if (d == s2) { \
236                 emith_sub_r_r(d, s1); \
237         } else { \
238                 emith_move_r_r(d, s1); \
239                 emith_sub_r_r(d, s2); \
240         } \
241 } while (0)
242
243 #define emith_adc_r_r_r(d, s1, s2) do { \
244         if (d == s1) { \
245                 emith_adc_r_r(d, s2); \
246         } else if (d == s2) { \
247                 emith_adc_r_r(d, s1); \
248         } else { \
249                 emith_move_r_r(d, s1); \
250                 emith_adc_r_r(d, s2); \
251         } \
252 } while (0)
253
254 #define emith_sbc_r_r_r(d, s1, s2) do { \
255         if (d == s1) { \
256                 emith_sbc_r_r(d, s2); \
257         } else if (d == s2) { \
258                 emith_sbc_r_r(d, s1); \
259         } else { \
260                 emith_move_r_r(d, s1); \
261                 emith_sbc_r_r(d, s2); \
262         } \
263 } while (0)
264
265 #define emith_and_r_r_r(d, s1, s2) do { \
266         if (d == s1) { \
267                 emith_and_r_r(d, s2); \
268         } else if (d == s2) { \
269                 emith_and_r_r(d, s1); \
270         } else { \
271                 emith_move_r_r(d, s1); \
272                 emith_and_r_r(d, s2); \
273         } \
274 } while (0)
275
276 #define emith_or_r_r_r(d, s1, s2) do { \
277         if (d == s1) { \
278                 emith_or_r_r(d, s2); \
279         } else if (d == s2) { \
280                 emith_or_r_r(d, s1); \
281         } else { \
282                 emith_move_r_r(d, s1); \
283                 emith_or_r_r(d, s2); \
284         } \
285 } while (0)
286
287 #define emith_eor_r_r_r(d, s1, s2) do { \
288         if (d == s1) { \
289                 emith_eor_r_r(d, s2); \
290         } else if (d == s2) { \
291                 emith_eor_r_r(d, s1); \
292         } else { \
293                 emith_move_r_r(d, s1); \
294                 emith_eor_r_r(d, s2); \
295         } \
296 } while (0)
297
298 // _r_r_r_shift
299 #define emith_add_r_r_r_lsl(d, s1, s2, lslimm) do { \
300         if (lslimm) { \
301                 int tmp_ = rcache_get_tmp(); \
302                 emith_lsl(tmp_, s2, lslimm); \
303                 emith_add_r_r_r(d, s1, tmp_); \
304                 rcache_free_tmp(tmp_); \
305         } else  emith_add_r_r_r(d, s1, s2); \
306 } while (0)
307
308 #define emith_add_r_r_r_lsl_ptr(d, s1, s2, lslimm) do { \
309         if (lslimm) { \
310                 int tmp_ = rcache_get_tmp(); \
311                 emith_lsl(tmp_, s2, lslimm); \
312                 emith_add_r_r_r_ptr(d, s1, tmp_); \
313                 rcache_free_tmp(tmp_); \
314         } else  emith_add_r_r_r_ptr(d, s1, s2); \
315 } while (0)
316
317 #define emith_add_r_r_r_lsr(d, s1, s2, lsrimm) do { \
318         if (lsrimm) { \
319                 int tmp_ = rcache_get_tmp(); \
320                 emith_lsr(tmp_, s2, lsrimm); \
321                 emith_add_r_r_r(d, s1, tmp_); \
322                 rcache_free_tmp(tmp_); \
323         } else  emith_add_r_r_r(d, s1, s2); \
324 } while (0)
325
326 #define emith_sub_r_r_r_lsl(d, s1, s2, lslimm) do { \
327         if (lslimm) { \
328                 int tmp_ = rcache_get_tmp(); \
329                 emith_lsl(tmp_, s2, lslimm); \
330                 emith_sub_r_r_r(d, s1, tmp_); \
331                 rcache_free_tmp(tmp_); \
332         } else  emith_sub_r_r_r(d, s1, s2); \
333 } while (0)
334
335 #define emith_or_r_r_r_lsl(d, s1, s2, lslimm) do { \
336         if (lslimm) { \
337                 int tmp_ = rcache_get_tmp(); \
338                 emith_lsl(tmp_, s2, lslimm); \
339                 emith_or_r_r_r(d, s1, tmp_); \
340                 rcache_free_tmp(tmp_); \
341         } else  emith_or_r_r_r(d, s1, s2); \
342 } while (0)
343 #define emith_or_r_r_r_lsr(d, s1, s2, lsrimm) do { \
344         if (lsrimm) { \
345                 int tmp_ = rcache_get_tmp(); \
346                 emith_lsr(tmp_, s2, lsrimm); \
347                 emith_or_r_r_r(d, s1, tmp_); \
348                 rcache_free_tmp(tmp_); \
349         } else  emith_or_r_r_r(d, s1, s2); \
350 } while (0)
351
352 #define emith_eor_r_r_r_lsr(d, s1, s2, lsrimm) do { \
353         if (lsrimm) { \
354                 int tmp_ = rcache_get_tmp(); \
355                 emith_lsr(tmp_, s2, lsrimm); \
356                 emith_eor_r_r_r(d, s1, tmp_); \
357                 rcache_free_tmp(tmp_); \
358         } else  emith_eor_r_r_r(d, s1, s2); \
359 } while (0)
360
361 // _r_r_shift
362 #define emith_or_r_r_lsl(d, s, lslimm) \
363         emith_or_r_r_r_lsl(d, d, s, lslimm)
364 #define emith_or_r_r_lsr(d, s, lsrimm) \
365         emith_or_r_r_r_lsr(d, d, s, lsrimm)
366
367 #define emith_eor_r_r_lsl(d, s, lslimm) do { \
368         if (lslimm) { \
369                 int tmp_ = rcache_get_tmp(); \
370                 emith_lsl(tmp_, s, lslimm); \
371                 emith_eor_r_r(d, tmp_); \
372                 rcache_free_tmp(tmp_); \
373         } else  emith_eor_r_r(d, s); \
374 } while (0)
375 #define emith_eor_r_r_lsr(d, s, lsrimm) do { \
376         if (lsrimm) { \
377                 int tmp_ = rcache_get_tmp(); \
378                 emith_lsr(tmp_, s, lsrimm); \
379                 emith_eor_r_r(d, tmp_); \
380                 rcache_free_tmp(tmp_); \
381         } else  emith_eor_r_r(d, s); \
382 } while (0)
383
384 // _r_imm
385 #define emith_move_r_imm(r, imm) do { \
386         EMIT_REX_IF(0, 0, r); \
387         EMIT_OP(0xb8 + ((r)&7)); \
388         EMIT(imm, u32); \
389 } while (0)
390
391 #define emith_move_r_ptr_imm(r, imm) do { \
392         if ((uintptr_t)(imm) <= UINT32_MAX) \
393                 emith_move_r_imm(r, (uintptr_t)(imm)); \
394         else { \
395                 EMIT_REX_IF(1, 0, r); \
396                 EMIT_OP(0xb8 + ((r)&7)); \
397                 EMIT((uintptr_t)(imm), uint64_t); \
398         } \
399 } while (0)
400
401 #define emith_move_r_imm_s8_patchable(r, imm) do { \
402         EMIT_REX_IF(0, 0, r); \
403         EMIT_OP(0xb8 + ((r)&7)); \
404         EMIT((s8)(imm), u32); \
405 } while (0)
406 #define emith_move_r_imm_s8_patch(ptr, imm) do { \
407         u8 *ptr_ = ptr; \
408         while ((*ptr_ & 0xf8) != 0xb8) ptr_++; \
409         EMIT_PTR(ptr_ + 1, (s8)(imm), u32); \
410 } while (0)
411
412 #define emith_arith_r_imm(op, r, imm) do { \
413         EMIT_REX_IF(0, 0, r); \
414         EMIT_OP_MODRM64(0x81, 3, op, r); \
415         EMIT(imm, u32); \
416 } while (0)
417
418 #define emith_add_r_imm(r, imm) \
419         emith_arith_r_imm(0, r, imm)
420
421 #define emith_or_r_imm(r, imm) \
422         emith_arith_r_imm(1, r, imm)
423
424 #define emith_adc_r_imm(r, imm) \
425         emith_arith_r_imm(2, r, imm)
426
427 #define emith_sbc_r_imm(r, imm) \
428         emith_arith_r_imm(3, r, imm) // sbb
429
430 #define emith_and_r_imm(r, imm) \
431         emith_arith_r_imm(4, r, imm)
432
433 #define emith_sub_r_imm(r, imm) \
434         emith_arith_r_imm(5, r, imm)
435
436 #define emith_eor_r_imm(r, imm) \
437         emith_arith_r_imm(6, r, imm)
438
439 #define emith_cmp_r_imm(r, imm) \
440         emith_arith_r_imm(7, r, imm)
441
442 #define emith_eor_r_imm_ptr(r, imm) do { \
443         EMIT_REX_IF(1, 0, r); \
444         EMIT_OP_MODRM64(0x81, 3, 6, r); \
445         EMIT(imm, u32); \
446 } while (0)
447
448 #define emith_tst_r_imm(r, imm) do { \
449         EMIT_REX_IF(0, 0, r); \
450         EMIT_OP_MODRM64(0xf7, 3, 0, r); \
451         EMIT(imm, u32); \
452 } while (0)
453
454 // fake
455 #define emith_bic_r_imm(r, imm) \
456         emith_arith_r_imm(4, r, ~(imm))
457
458 // fake conditionals (using SJMP instead)
459 #define emith_move_r_imm_c(cond, r, imm) \
460         emith_move_r_imm(r, imm)
461 #define emith_add_r_imm_c(cond, r, imm) \
462         emith_add_r_imm(r, imm)
463 #define emith_sub_r_imm_c(cond, r, imm) \
464         emith_sub_r_imm(r, imm)
465 #define emith_or_r_imm_c(cond, r, imm) \
466         emith_or_r_imm(r, imm)
467 #define emith_eor_r_imm_c(cond, r, imm) \
468         emith_eor_r_imm(r, imm)
469 #define emith_eor_r_imm_ptr_c(cond, r, imm) \
470         emith_eor_r_imm_ptr(r, imm)
471 #define emith_bic_r_imm_c(cond, r, imm) \
472         emith_bic_r_imm(r, imm)
473 #define emith_tst_r_imm_c(cond, r, imm) \
474         emith_tst_r_imm(r, imm)
475 #define emith_move_r_r_ptr_c(cond, d, s) \
476         emith_move_r_r_ptr(d, s)
477 #define emith_ror_c(cond, d, s, cnt) \
478         emith_ror(d, s, cnt)
479 #define emith_and_r_r_c(cond, d, s) \
480         emith_and_r_r(d, s)
481 #define emith_add_r_r_imm_c(cond, d, s, imm) \
482         emith_add_r_r_imm(d, s, imm)
483 #define emith_sub_r_r_imm_c(cond, d, s, imm) \
484         emith_sub_r_r_imm(d, s, imm)
485
486 #define emith_read8_r_r_r_c(cond, r, rs, rm) \
487         emith_read8_r_r_r(r, rs, rm)
488 #define emith_read8s_r_r_r_c(cond, r, rs, rm) \
489         emith_read8s_r_r_r(r, rs, rm)
490 #define emith_read16_r_r_r_c(cond, r, rs, rm) \
491         emith_read16_r_r_r(r, rs, rm)
492 #define emith_read16s_r_r_r_c(cond, r, rs, rm) \
493         emith_read16s_r_r_r(r, rs, rm)
494 #define emith_read_r_r_r_c(cond, r, rs, rm) \
495         emith_read_r_r_r(r, rs, rm)
496
497 #define emith_read_r_r_offs_c(cond, r, rs, offs) \
498         emith_read_r_r_offs(r, rs, offs)
499 #define emith_read_r_r_offs_ptr_c(cond, r, rs, offs) \
500         emith_read_r_r_offs_ptr(r, rs, offs)
501 #define emith_write_r_r_offs_c(cond, r, rs, offs) \
502         emith_write_r_r_offs(r, rs, offs)
503 #define emith_write_r_r_offs_ptr_c(cond, r, rs, offs) \
504         emith_write_r_r_offs_ptr(r, rs, offs)
505 #define emith_read8_r_r_offs_c(cond, r, rs, offs) \
506         emith_read8_r_r_offs(r, rs, offs)
507 #define emith_write8_r_r_offs_c(cond, r, rs, offs) \
508         emith_write8_r_r_offs(r, rs, offs)
509 #define emith_read16_r_r_offs_c(cond, r, rs, offs) \
510         emith_read16_r_r_offs(r, rs, offs)
511 #define emith_write16_r_r_offs_c(cond, r, rs, offs) \
512         emith_write16_r_r_offs(r, rs, offs)
513 #define emith_jump_reg_c(cond, r) \
514         emith_jump_reg(r)
515 #define emith_jump_ctx_c(cond, offs) \
516         emith_jump_ctx(offs)
517 #define emith_ret_c(cond) \
518         emith_ret()
519
520 // _r_r_imm - use lea
521 #define emith_add_r_r_imm(d, s, imm) do { \
522         if (imm == 0) \
523                 emith_move_r_r(d, s); \
524         else { \
525                 EMIT_REX_IF(0, d, s); \
526                 emith_deref_modrm(0x8d, 2, d, s); \
527                 EMIT(imm, s32); \
528         } \
529 } while (0)
530
531 #define emith_add_r_r_ptr_imm(d, s, imm) do { \
532         if (imm == 0) \
533                 emith_move_r_r_ptr(d, s); \
534         else { \
535                 EMIT_REX_IF(1, d, s); \
536                 emith_deref_modrm(0x8d, 2, d, s); \
537                 EMIT(imm, s32); \
538         } \
539 } while (0)
540
541 #define emith_sub_r_r_imm(d, s, imm) do { \
542         if (d != s) \
543                 emith_move_r_r(d, s); \
544         if ((s32)(imm) != 0) \
545                 emith_sub_r_imm(d, imm); \
546 } while (0)
547
548 #define emith_and_r_r_imm(d, s, imm) do { \
549         if (d != s) \
550                 emith_move_r_r(d, s); \
551         if ((s32)(imm) != -1) \
552                 emith_and_r_imm(d, imm); \
553 } while (0)
554
555 #define emith_or_r_r_imm(d, s, imm) do { \
556         if (d != s) \
557                 emith_move_r_r(d, s); \
558         if ((s32)(imm) != 0) \
559                 emith_or_r_imm(d, imm); \
560 } while (0)
561
562 #define emith_eor_r_r_imm(d, s, imm) do { \
563         if (d != s) \
564                 emith_move_r_r(d, s); \
565         if ((s32)(imm) != 0) \
566                 emith_eor_r_imm(d, imm); \
567 } while (0)
568
569 // shift
570 #define emith_shift(op, d, s, cnt) do { \
571         if (d != s) \
572                 emith_move_r_r(d, s); \
573         EMIT_REX_IF(0, 0, d); \
574         EMIT_OP_MODRM64(0xc1, 3, op, d); \
575         EMIT(cnt, u8); \
576 } while (0)
577
578 #define emith_lsl(d, s, cnt) \
579         emith_shift(4, d, s, cnt)
580
581 #define emith_lsr(d, s, cnt) \
582         emith_shift(5, d, s, cnt)
583
584 #define emith_asr(d, s, cnt) \
585         emith_shift(7, d, s, cnt)
586
587 #define emith_rol(d, s, cnt) \
588         emith_shift(0, d, s, cnt)
589
590 #define emith_ror(d, s, cnt) \
591         emith_shift(1, d, s, cnt)
592
593 #define emith_rolc(r) do { \
594         EMIT_REX_IF(0, 0, r); \
595         EMIT_OP_MODRM64(0xd1, 3, 2, r); \
596 } while (0)
597
598 #define emith_rorc(r) do { \
599         EMIT_REX_IF(0, 0, r); \
600         EMIT_OP_MODRM64(0xd1, 3, 3, r); \
601 } while (0)
602
603 // misc
604 #define emith_push(r) do { \
605         EMIT_REX_IF(0, 0, r); \
606         EMIT_OP(0x50 + ((r)&7)); \
607 } while (0)
608
609 #define emith_push_imm(imm) do { \
610         EMIT_OP(0x68); \
611         EMIT(imm, u32); \
612 } while (0)
613
614 #define emith_pop(r) do { \
615         EMIT_REX_IF(0, 0, r); \
616         EMIT_OP(0x58 + ((r)&7)); \
617 } while (0)
618
619 #define emith_neg_r(r) do { \
620         EMIT_REX_IF(0, 0, r); \
621         EMIT_OP_MODRM64(0xf7, 3, 3, r); \
622 } while (0)
623
624 #define emith_clear_msb(d, s, count) do { \
625         u32 t = (u32)-1; \
626         t >>= count; \
627         if (d != s) \
628                 emith_move_r_r(d, s); \
629         if (count) emith_and_r_imm(d, t); \
630 } while (0)
631
632 #define emith_clear_msb_c(cond, d, s, count) do { \
633         (void)(cond); \
634         emith_clear_msb(d, s, count); \
635 } while (0)
636
637 #define emith_sext(d, s, bits) do { \
638         emith_lsl(d, s, 32 - (bits)); \
639         emith_asr(d, d, 32 - (bits)); \
640 } while (0)
641
642 #define emith_uext_ptr(r)       /**/
643
644 #define emith_setc(r) do { \
645         assert(is_abcdx(r)); \
646         EMIT_REX_IF(0, 0, r); \
647         EMIT_OP_MODRM64(0x0f92, 3, 0, r); /* SETC r */ \
648 } while (0)
649
650 // XXX: stupid mess
651 #define emith_mul_(op, dlo, dhi, s1, s2) do { \
652         int rmr; \
653         if (dlo != xAX && dhi != xAX && rcache_is_hreg_used(xAX)) \
654                 emith_push(xAX); \
655         if (dlo != xDX && dhi != xDX && rcache_is_hreg_used(xDX)) \
656                 emith_push(xDX); \
657         if ((s1) == xAX) \
658                 rmr = s2; \
659         else if ((s2) == xAX) \
660                 rmr = s1; \
661         else { \
662                 emith_move_r_r(xAX, s1); \
663                 rmr = s2; \
664         } \
665         EMIT_REX_IF(0, 0, rmr); \
666         EMIT_OP_MODRM64(0xf7, 3, op, rmr); /* xMUL rmr */ \
667         if (dlo != xAX) { \
668                 EMIT_REX_IF(0, 0, dlo); \
669                 EMIT_OP(0x90 + ((dlo)&7)); /* XCHG eax, dlo */ \
670         } \
671         if (dhi != xDX && dhi != -1 && !(dhi == xAX && dlo == xDX)) \
672                 emith_move_r_r(dhi, (dlo == xDX ? xAX : xDX)); \
673         if (dlo != xDX && dhi != xDX && rcache_is_hreg_used(xDX)) \
674                 emith_pop(xDX); \
675         if (dlo != xAX && dhi != xAX && rcache_is_hreg_used(xAX)) \
676                 emith_pop(xAX); \
677 } while (0)
678
679 #define emith_mul_u64(dlo, dhi, s1, s2) \
680         emith_mul_(4, dlo, dhi, s1, s2) /* MUL */
681
682 #define emith_mul_s64(dlo, dhi, s1, s2) \
683         emith_mul_(5, dlo, dhi, s1, s2) /* IMUL */
684
685 #define emith_mul(d, s1, s2) do { \
686         if (d == s1) { \
687                 EMIT_REX_IF(0, d, s2); \
688                 EMIT_OP_MODRM64(0x0faf, 3, d, s2); \
689         } else if (d == s2) { \
690                 EMIT_REX_IF(0, d, s1); \
691                 EMIT_OP_MODRM64(0x0faf, 3, d, s1); \
692         } else { \
693                 emith_move_r_r(d, s1); \
694                 EMIT_REX_IF(0, d, s2); \
695                 EMIT_OP_MODRM64(0x0faf, 3, d, s2); \
696         } \
697 } while (0)
698
699 // (dlo,dhi) += signed(s1) * signed(s2)
700 #define emith_mula_s64(dlo, dhi, s1, s2) do { \
701         emith_push(dhi); \
702         emith_push(dlo); \
703         emith_mul_(5, dlo, dhi, s1, s2); \
704         EMIT_REX_IF(0, dlo, xSP); \
705         emith_deref_modrm(0x03, 0, dlo, xSP); /* add dlo, [xsp] */ \
706         EMIT_REX_IF(0, dhi, xSP); \
707         emith_deref_modrm(0x13, 1, dhi, xSP); /* adc dhi, [xsp+{4,8}] */ \
708         EMIT(sizeof(void *), u8); \
709         emith_add_r_r_ptr_imm(xSP, xSP, sizeof(void *) * 2); \
710 } while (0)
711
712 // "flag" instructions are the same
713 #define emith_adcf_r_imm emith_adc_r_imm
714 #define emith_subf_r_imm emith_sub_r_imm
715 #define emith_addf_r_r   emith_add_r_r
716 #define emith_subf_r_r   emith_sub_r_r
717 #define emith_adcf_r_r   emith_adc_r_r
718 #define emith_sbcf_r_r   emith_sbc_r_r
719 #define emith_eorf_r_r   emith_eor_r_r
720 #define emith_negcf_r_r  emith_negc_r_r
721
722 #define emith_subf_r_r_imm emith_sub_r_r_imm
723 #define emith_addf_r_r_r emith_add_r_r_r
724 #define emith_subf_r_r_r emith_sub_r_r_r
725 #define emith_adcf_r_r_r emith_adc_r_r_r
726 #define emith_sbcf_r_r_r emith_sbc_r_r_r
727 #define emith_eorf_r_r_r emith_eor_r_r_r
728 #define emith_addf_r_r_r_lsr emith_add_r_r_r_lsr
729
730 #define emith_lslf  emith_lsl
731 #define emith_lsrf  emith_lsr
732 #define emith_asrf  emith_asr
733 #define emith_rolf  emith_rol
734 #define emith_rorf  emith_ror
735 #define emith_rolcf emith_rolc
736 #define emith_rorcf emith_rorc
737
738 #define emith_deref_modrm(op, m, r, rs) do { \
739         if (((rs) & 7) == 5 && m == 0) { /* xBP,xR13 not in mod 0, use mod 1 */\
740                 EMIT_OP_MODRM64(op, 1, r, rs); \
741                 EMIT(0, u8); \
742         } else if (((rs) & 7) == 4) { /* xSP,xR12 must use SIB */ \
743                 EMIT_OP_MODRM64(op, m, r, 4); \
744                 EMIT_SIB64(0, 4, rs); \
745         } else \
746                 EMIT_OP_MODRM64(op, m, r, rs); \
747 } while (0)
748
749 #define emith_deref_op(op, r, rs, offs) do { \
750         /* mov r <-> [ebp+#offs] */ \
751         if ((offs) == 0) { \
752                 emith_deref_modrm(op, 0, r, rs); \
753         } else if ((s32)(offs) < -0x80 || (s32)(offs) >= 0x80) { \
754                 emith_deref_modrm(op, 2, r, rs); \
755                 EMIT(offs, u32); \
756         } else { \
757                 emith_deref_modrm(op, 1, r, rs); \
758                 EMIT((u8)offs, u8); \
759         } \
760 } while (0)
761
762 #define is_abcdx(r) !((r) & ~0x3)
763
764 #define emith_read_r_r_offs(r, rs, offs) do { \
765         EMIT_REX_IF(0, r, rs); \
766         emith_deref_op(0x8b, r, rs, offs); \
767 } while (0)
768 #define emith_read_r_r_offs_ptr(r, rs, offs) do { \
769         EMIT_REX_IF(1, r, rs); \
770         emith_deref_op(0x8b, r, rs, offs); \
771 } while (0)
772
773 #define emith_write_r_r_offs(r, rs, offs) do { \
774         EMIT_REX_IF(0, r, rs); \
775         emith_deref_op(0x89, r, rs, offs); \
776 } while (0)
777 #define emith_write_r_r_offs_ptr(r, rs, offs) do { \
778         EMIT_REX_IF(1, r, rs); \
779         emith_deref_op(0x89, r, rs, offs); \
780 } while (0)
781
782 #define emith_read8_r_r_offs(r, rs, offs) do { \
783         EMIT_REX_IF(0, r, rs); \
784         emith_deref_op(0x0fb6, r, rs, offs); \
785 } while (0)
786
787 #define emith_read8s_r_r_offs(r, rs, offs) do { \
788         EMIT_REX_IF(0, r, rs); \
789         emith_deref_op(0x0fbe, r, rs, offs); \
790 } while (0)
791
792 #define emith_write8_r_r_offs(r, rs, offs) do {\
793         EMIT_REX_IF(0, r, rs); \
794         emith_deref_op(0x88, r, rs, offs); \
795 } while (0)
796
797 #define emith_read16_r_r_offs(r, rs, offs) do { \
798         EMIT_REX_IF(0, r, rs); \
799         emith_deref_op(0x0fb7, r, rs, offs); \
800 } while (0)
801
802 #define emith_read16s_r_r_offs(r, rs, offs) do { \
803         EMIT_REX_IF(0, r, rs); \
804         emith_deref_op(0x0fbf, r, rs, offs); \
805 } while (0)
806
807 #define emith_write16_r_r_offs(r, rs, offs) do { \
808         EMIT(0x66, u8); /* Intel SDM Vol 2a: REX must be closest to opcode */ \
809         EMIT_REX_IF(0, r, rs); \
810         emith_deref_op(0x89, r, rs, offs); \
811 } while (0)
812
813 #define emith_read8_r_r_r(r, rs, rm) do { \
814         EMIT_XREX_IF(0, r, rm, rs); \
815         EMIT_OP_MODRM64(0x0fb6, 0, r, 4); \
816         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
817 } while (0)
818
819 #define emith_read8s_r_r_r(r, rs, rm) do { \
820         EMIT_XREX_IF(0, r, rm, rs); \
821         EMIT_OP_MODRM64(0x0fbe, 0, r, 4); \
822         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
823 } while (0)
824
825 #define emith_read16_r_r_r(r, rs, rm) do { \
826         EMIT_XREX_IF(0, r, rm, rs); \
827         EMIT_OP_MODRM64(0x0fb7, 0, r, 4); \
828         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
829 } while (0)
830
831 #define emith_read16s_r_r_r(r, rs, rm) do { \
832         EMIT_XREX_IF(0, r, rm, rs); \
833         EMIT_OP_MODRM64(0x0fbf, 0, r, 4); \
834         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
835 } while (0)
836
837 #define emith_read_r_r_r(r, rs, rm) do { \
838         EMIT_XREX_IF(0, r, rm, rs); \
839         EMIT_OP_MODRM64(0x8b, 0, r, 4); \
840         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
841 } while (0)
842 #define emith_read_r_r_r_ptr(r, rs, rm) do { \
843         EMIT_XREX_IF(1, r, rm, rs); \
844         EMIT_OP_MODRM64(0x8b, 0, r, 4); \
845         EMIT_SIB64(0, rs, rm); /* mov r, [rm + rs * 1] */ \
846 } while (0)
847
848 #define emith_write_r_r_r(r, rs, rm) do { \
849         EMIT_XREX_IF(0, r, rm, rs); \
850         EMIT_OP_MODRM64(0x89, 0, r, 4); \
851         EMIT_SIB64(0, rs, rm); /* mov [rm + rs * 1], r */ \
852 } while (0)
853 #define emith_write_r_r_r_ptr(r, rs, rm) do { \
854         EMIT_XREX_IF(1, r, rm, rs); \
855         EMIT_OP_MODRM64(0x89, 0, r, 4); \
856         EMIT_SIB64(0, rs, rm); /* mov [rm + rs * 1], r */ \
857 } while (0)
858
859 #define emith_ctx_read(r, offs) \
860         emith_read_r_r_offs(r, CONTEXT_REG, offs)
861 #define emith_ctx_read_c(cond, r, offs) \
862         emith_ctx_read(r, offs)
863
864 #define emith_ctx_read_ptr(r, offs) do { \
865         EMIT_REX_IF(1, r, CONTEXT_REG); \
866         emith_deref_op(0x8b, r, CONTEXT_REG, offs); \
867 } while (0)
868
869 #define emith_ctx_write(r, offs) \
870         emith_write_r_r_offs(r, CONTEXT_REG, offs)
871
872 #define emith_ctx_read_multiple(r, offs, cnt, tmpr) do { \
873         int r_ = r, offs_ = offs, cnt_ = cnt;     \
874         for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
875                 emith_ctx_read(r_, offs_);        \
876 } while (0)
877
878 #define emith_ctx_write_multiple(r, offs, cnt, tmpr) do { \
879         int r_ = r, offs_ = offs, cnt_ = cnt;     \
880         for (; cnt_ > 0; r_++, offs_ += 4, cnt_--) \
881                 emith_ctx_write(r_, offs_);       \
882 } while (0)
883
884 #define emith_ret_to_ctx(offs) do { \
885         int tmp_ = rcache_get_tmp(); \
886         emith_pop(tmp_); \
887         emith_ctx_write(tmp_, offs); \
888         rcache_free_tmp(tmp_); \
889 } while (0)
890
891 #define emith_jump(ptr) do { \
892         u32 disp = (u8 *)(ptr) - ((u8 *)tcache_ptr + 5); \
893         EMIT_OP(0xe9); \
894         EMIT(disp, u32); \
895 } while (0)
896
897 #define emith_jump_patchable(target) \
898         emith_jump(target)
899
900 #define emith_jump_cond(cond, ptr) do { \
901         u32 disp = (u8 *)(ptr) - ((u8 *)tcache_ptr + 6); \
902         EMIT_OP(0x0f80 | (cond)); \
903         EMIT(disp, u32); \
904 } while (0)
905 #define emith_jump_cond_inrange(ptr) !0
906
907 #define emith_jump_cond_patchable(cond, target) \
908         emith_jump_cond(cond, target)
909
910 #define emith_jump_patch(ptr, target, pos) do { \
911         u32 disp_ = (u8 *)(target) - ((u8 *)(ptr) + 4); \
912         u32 offs_ = (*(u8 *)(ptr) == 0x0f) ? 2 : 1; \
913         EMIT_PTR((u8 *)(ptr) + offs_, disp_ - offs_, u32); \
914         if ((void *)(pos) != NULL) *(u8 **)(pos) = (u8 *)ptr + offs_; \
915 } while (0)
916 #define emith_jump_patch_size() 4
917 #define emith_jump_patch_inrange(ptr, target) !0
918
919 #define emith_jump_at(ptr, target) do { \
920         u32 disp_ = (u8 *)(target) - ((u8 *)(ptr) + 5); \
921         EMIT_PTR(ptr, 0xe9, u8); \
922         EMIT_PTR((u8 *)(ptr) + 1, disp_, u32); \
923 } while (0)
924 #define emith_jump_at_size() 5
925
926 #define emith_call(ptr) do { \
927         u32 disp = (u8 *)(ptr) - ((u8 *)tcache_ptr + 5); \
928         EMIT_OP(0xe8); \
929         EMIT(disp, u32); \
930 } while (0)
931
932 #define emith_call_cond(cond, ptr) \
933         emith_call(ptr)
934
935 #define emith_call_reg(r) do { \
936         EMIT_REX_IF(0, 0, r); \
937         EMIT_OP_MODRM64(0xff, 3, 2, r); \
938 } while (0)
939
940 #define emith_abicall_ctx(offs) do { \
941         EMIT_REX_IF(0, 0, CONTEXT_REG); \
942         EMIT_OP_MODRM64(0xff, 2, 2, CONTEXT_REG); \
943         EMIT(offs, u32); \
944 } while (0)
945
946 #define emith_call_cleanup() \
947         emith_add_r_r_ptr_imm(xSP, xSP, sizeof(void *)); // remove return addr
948
949 #define emith_ret() \
950         EMIT_OP(0xc3)
951
952 #define emith_add_r_ret(r) do { \
953         EMIT_REX_IF(1, r, xSP); \
954         emith_deref_modrm(0x03, 0, r, xSP); /* add r, [xsp] */ \
955 } while (0)
956
957 #define emith_jump_reg(r) do { \
958         EMIT_REX_IF(0, 0, r); \
959         EMIT_OP_MODRM64(0xff, 3, 4, r); \
960 } while (0)
961
962 #define emith_jump_ctx(offs) do { \
963         EMIT_REX_IF(0, 0, CONTEXT_REG); \
964         EMIT_OP_MODRM64(0xff, 2, 4, CONTEXT_REG); \
965         EMIT(offs, u32); \
966 } while (0)
967
968 #define emith_push_ret(r) do { \
969         int r_ = (r >= 0 ? r : xSI); \
970         emith_push(r_); /* always push to align */ \
971         emith_add_r_r_ptr_imm(xSP, xSP, -8*4); /* args shadow space */ \
972 } while (0)
973
974 #define emith_pop_and_ret(r) do { \
975         int r_ = (r >= 0 ? r : xSI); \
976         emith_add_r_r_ptr_imm(xSP, xSP,  8*4); /* args shadow space */ \
977         emith_pop(r_); \
978         emith_ret(); \
979 } while (0)
980
981 #define emith_abijump_reg(r) \
982         emith_jump_reg(r)
983 #define emith_abijump_reg_c(cond, r) \
984         emith_abijump_reg(r)
985 #define emith_abicall(target) \
986         emith_call(target)
987 #define emith_abicall_cond(cond, target) \
988         emith_abicall(target)
989 #define emith_abicall_reg(r) \
990         emith_call_reg(r)
991
992
993 #define EMITH_JMP_START(cond) { \
994         u8 *cond_ptr; \
995         JMP8_POS(cond_ptr)
996
997 #define EMITH_JMP_END(cond) \
998         JMP8_EMIT(cond, cond_ptr); \
999 }
1000
1001 #define EMITH_JMP3_START(cond) { \
1002         u8 *cond_ptr, *else_ptr; \
1003         JMP8_POS(cond_ptr)
1004
1005 #define EMITH_JMP3_MID(cond) \
1006         JMP8_POS(else_ptr); \
1007         JMP8_EMIT(cond, cond_ptr);
1008
1009 #define EMITH_JMP3_END() \
1010         JMP8_EMIT_NC(else_ptr); \
1011 }
1012
1013 // "simple" jump (no more than a few insns)
1014 // ARM will use conditional instructions here
1015 #define EMITH_SJMP_START EMITH_JMP_START
1016 #define EMITH_SJMP_END EMITH_JMP_END
1017
1018 #define EMITH_SJMP3_START EMITH_JMP3_START
1019 #define EMITH_SJMP3_MID EMITH_JMP3_MID
1020 #define EMITH_SJMP3_END EMITH_JMP3_END
1021
1022 #define EMITH_SJMP2_START(cond) \
1023         EMITH_SJMP3_START(cond)
1024 #define EMITH_SJMP2_MID(cond) \
1025         EMITH_SJMP3_MID(cond)
1026 #define EMITH_SJMP2_END(cond) \
1027         EMITH_SJMP3_END()
1028
1029 #define EMITH_HINT_COND(cond)   /**/
1030
1031 #define emith_pass_arg_r(arg, reg) do { \
1032         int rd = 7; \
1033         host_arg2reg(rd, arg); \
1034         emith_move_r_r_ptr(rd, reg); \
1035 } while (0)
1036
1037 #define emith_pass_arg_imm(arg, imm) do { \
1038         int rd = 7; \
1039         host_arg2reg(rd, arg); \
1040         emith_move_r_ptr_imm(rd, imm); \
1041 } while (0)
1042
1043 #define host_instructions_updated(base, end, force)     (void)(base),(void)(end)
1044 #define emith_update_cache()    /**/
1045
1046 #define emith_rw_offs_max()     0xffffffffU
1047
1048 #define host_call(addr, args) \
1049         addr
1050
1051 #ifdef __x86_64__
1052
1053 #define HOST_REGS 16
1054 #define PTR_SCALE 3
1055
1056 #define EMIT_XREX_IF(w, r, rm, rs) do { \
1057         int xr_ = (r) > 7 ? 1 : 0; \
1058         int xb_ = (rm) > 7 ? 1 : 0; \
1059         int xx_ = (rs) > 7 ? 1 : 0; \
1060         if ((w) | xr_ | xx_ | xb_) \
1061                 EMIT_REX(w, xr_, xx_, xb_); \
1062 } while (0)
1063  
1064 #define EMIT_REX_IF(w, r, rm) \
1065         EMIT_XREX_IF(w, r, rm, 0)
1066
1067 #ifndef _WIN32
1068
1069 // SystemV ABI conventions:
1070 // rbx,rbp,r12-r15 are preserved, rax,rcx,rdx,rsi,rdi,r8-r11 are temporaries
1071 // parameters in rdi,rsi,rdx,rcx,r8,r9, return values in rax,rdx
1072 #define PARAM_REGS      { xDI, xSI, xDX, xCX, xR8, xR9 }
1073 #define PRESERVED_REGS  { xR12, xR13, xR14, xR15, xBX, xBP }
1074 #define TEMPORARY_REGS  { xAX, xR10, xR11 }
1075 #define STATIC_SH2_REGS { SHR_SR,xBX , SHR_R0,xR15 }
1076
1077 #define host_arg2reg(rd, arg) \
1078         switch (arg) { \
1079         case 0: rd = xDI; break; \
1080         case 1: rd = xSI; break; \
1081         case 2: rd = xDX; break; \
1082         default: rd = xCX; break; \
1083         }
1084
1085 #define emith_sh2_drc_entry() do { \
1086         emith_push(xBX); \
1087         emith_push(xBP); \
1088         emith_push(xR12); \
1089         emith_push(xR13); \
1090         emith_push(xR14); \
1091         emith_push(xR15); \
1092         emith_push(xSI); /* to align */ \
1093 } while (0)
1094
1095 #define emith_sh2_drc_exit() do {  \
1096         emith_pop(xSI); \
1097         emith_pop(xR15); \
1098         emith_pop(xR14); \
1099         emith_pop(xR13); \
1100         emith_pop(xR12); \
1101         emith_pop(xBP); \
1102         emith_pop(xBX); \
1103         emith_ret(); \
1104 } while (0)
1105
1106 #else // _WIN32
1107
1108 // M$ ABI conventions:
1109 // rbx,rbp,rsi,rdi,r12-r15 are preserved, rcx,rdx,rax,r8,r9,r10,r11 temporaries
1110 // parameters in rcx,rdx,r8,r9, return values in rax,rdx
1111 #define PARAM_REGS      { xCX, xDX, xR8, xR9 }
1112 #define PRESERVED_REGS  { xSI, xDI, xR12, xR13, xR14, xR15, xBX, xBP }
1113 #define TEMPORARY_REGS  { xAX, xR10, xR11 }
1114 #define STATIC_SH2_REGS { SHR_SR,xBX , SHR_R(0),xR15 , SHR_R(1),xR14 }
1115
1116 #define host_arg2reg(rd, arg) \
1117         switch (arg) { \
1118         case 0: rd = xCX; break; \
1119         case 1: rd = xDX; break; \
1120         case 2: rd = xR8; break; \
1121         default: rd = xR9; break; \
1122         }
1123
1124 #define emith_sh2_drc_entry() do { \
1125         emith_push(xBX); \
1126         emith_push(xBP); \
1127         emith_push(xR12); \
1128         emith_push(xR13); \
1129         emith_push(xR14); \
1130         emith_push(xR15); \
1131         emith_push(xSI); \
1132         emith_push(xDI); \
1133         emith_add_r_r_ptr_imm(xSP, xSP, -8*5); /* align + args shadow space */ \
1134 } while (0)
1135
1136 #define emith_sh2_drc_exit() do {  \
1137         emith_add_r_r_ptr_imm(xSP, xSP, 8*5); \
1138         emith_pop(xDI); \
1139         emith_pop(xSI); \
1140         emith_pop(xR15); \
1141         emith_pop(xR14); \
1142         emith_pop(xR13); \
1143         emith_pop(xR12); \
1144         emith_pop(xBP); \
1145         emith_pop(xBX); \
1146         emith_ret(); \
1147 } while (0)
1148
1149 #endif // _WIN32
1150
1151 #else // !__x86_64__
1152
1153 #define HOST_REGS 8
1154 #define PTR_SCALE 2
1155
1156 #define EMIT_REX_IF(w, r, rm) do { \
1157         assert((u32)(r) < 8u); \
1158         assert((u32)(rm) < 8u); \
1159 } while (0)
1160 #define EMIT_XREX_IF(w, r, rs, rm) do { \
1161         assert((u32)(r) < 8u); \
1162         assert((u32)(rs) < 8u); \
1163         assert((u32)(rm) < 8u); \
1164 } while (0)
1165
1166 // MS/SystemV ABI: ebx,esi,edi,ebp are preserved, eax,ecx,edx are temporaries
1167 // DRC uses REGPARM to pass upto 3 parameters in registers eax,ecx,edx.
1168 // To avoid conflicts with param passing ebx must be declared temp here.
1169 #define PARAM_REGS      { xAX, xDX, xCX }
1170 #define PRESERVED_REGS  { xSI, xDI, xBP }
1171 #define TEMPORARY_REGS  { xBX }
1172 #define STATIC_SH2_REGS { SHR_SR,xDI , SHR_R0,xSI }
1173
1174 #define host_arg2reg(rd, arg) \
1175         switch (arg) { \
1176         case 0: rd = xAX; break; \
1177         case 1: rd = xDX; break; \
1178         case 2: rd = xCX; break; \
1179         default: rd = xBX; break; \
1180         }
1181
1182 #define emith_sh2_drc_entry() do { \
1183         emith_push(xBX);        \
1184         emith_push(xBP);        \
1185         emith_push(xSI);        \
1186         emith_push(xDI);        \
1187 } while (0)
1188
1189 #define emith_sh2_drc_exit() do { \
1190         emith_pop(xDI);         \
1191         emith_pop(xSI);         \
1192         emith_pop(xBP);         \
1193         emith_pop(xBX);         \
1194         emith_ret();            \
1195 } while (0)
1196
1197 #endif
1198
1199 #define emith_save_caller_regs(mask) do { \
1200         int _c; u32 _m = mask & 0xfc7; /* AX, CX, DX, SI, DI, 8, 9, 10, 11 */ \
1201         if (__builtin_parity(_m) == 1) _m |= 0x8; /* BX for ABI align */ \
1202         for (_c = HOST_REGS-1; _m && _c >= 0; _m &= ~(1 << _c), _c--) \
1203                 if (_m & (1 << _c)) emith_push(_c); \
1204 } while (0)
1205
1206 #define emith_restore_caller_regs(mask) do { \
1207         int _c; u32 _m = mask & 0xfc7; \
1208         if (__builtin_parity(_m) == 1) _m |= 0x8; /* BX for ABI align */ \
1209         for (_c = 0; _m && _c < HOST_REGS; _m &= ~(1 << _c), _c++) \
1210                 if (_m & (1 << _c)) emith_pop(_c); \
1211 } while (0)
1212
1213 #define emith_sh2_rcall(a, tab, func, mask) do { \
1214         int scale_ = PTR_SCALE <= 2 ? PTR_SCALE : 2; \
1215         emith_lsr(mask, a, SH2_READ_SHIFT); \
1216         if (PTR_SCALE > scale_) emith_lsl(mask, mask, PTR_SCALE-scale_); \
1217         EMIT_XREX_IF(1, tab, tab, mask); \
1218         EMIT_OP_MODRM64(0x8d, 0, tab, 4); \
1219         EMIT_SIB64(scale_+1, mask, tab); /* lea tab, [tab + mask*(2*scale)] */ \
1220         EMIT_REX_IF(1, func,  tab); \
1221         emith_deref_modrm(0x8b, 0, func, tab); /* mov func, [tab] */ \
1222         EMIT_REX_IF(0, mask, tab); \
1223         emith_deref_modrm(0x8b, 1, mask, tab); \
1224         EMIT(1 << PTR_SCALE, u8); /* mov mask, [tab + {4,8}] */ \
1225         emith_add_r_r_ptr(func, func); \
1226 } while (0)
1227
1228 #define emith_sh2_wcall(a, val, tab, func) do { \
1229         int arg2_; \
1230         host_arg2reg(arg2_, 2); \
1231         emith_lsr(func, a, SH2_WRITE_SHIFT); /* tmp = a >> WRT_SHIFT */ \
1232         EMIT_XREX_IF(1, func, tab, func); \
1233         EMIT_OP_MODRM64(0x8b, 0, func, 4); \
1234         EMIT_SIB64(PTR_SCALE, func, tab); /* mov tmp, [tab + tmp * {4,8}] */ \
1235         emith_move_r_r_ptr(arg2_, CONTEXT_REG); \
1236         emith_abijump_reg(func); \
1237 } while (0)
1238
1239 #define emith_sh2_dtbf_loop() do { \
1240         u8 *jmp0; /* negative cycles check */            \
1241         u8 *jmp1; /* unsinged overflow check */          \
1242         int cr, rn;                                      \
1243         int tmp_ = rcache_get_tmp();                     \
1244         cr = rcache_get_reg(SHR_SR, RC_GR_RMW);          \
1245         rn = rcache_get_reg((op >> 8) & 0x0f, RC_GR_RMW);\
1246         emith_sub_r_imm(rn, 1);                          \
1247         emith_sub_r_imm(cr, (cycles+1) << 12);           \
1248         cycles = 0;                                      \
1249         emith_asr(tmp_, cr, 2+12);                       \
1250         JMP8_POS(jmp0); /* no negative cycles */         \
1251         emith_move_r_imm(tmp_, 0);                       \
1252         JMP8_EMIT(ICOND_JNS, jmp0);                      \
1253         emith_and_r_imm(cr, 0xffe);                      \
1254         emith_subf_r_r(rn, tmp_);                        \
1255         JMP8_POS(jmp1); /* no overflow */                \
1256         emith_neg_r(rn); /* count left */                \
1257         emith_lsl(rn, rn, 2+12);                         \
1258         emith_or_r_r(cr, rn);                            \
1259         emith_or_r_imm(cr, 1);                           \
1260         emith_move_r_imm(rn, 0);                         \
1261         JMP8_EMIT(ICOND_JA, jmp1);                       \
1262         rcache_free_tmp(tmp_);                           \
1263 } while (0)
1264
1265 #define emith_sh2_delay_loop(cycles, reg) do {                  \
1266         int sr = rcache_get_reg(SHR_SR, RC_GR_RMW, NULL);       \
1267         int t1 = rcache_get_tmp();                              \
1268         int t2 = rcache_get_tmp();                              \
1269         int t3 = rcache_get_tmp();                              \
1270         if (t3 == xAX) { t3 = t1; t1 = xAX; } /* for MUL */     \
1271         if (t3 == xDX) { t3 = t2; t2 = xDX; }                   \
1272         /* if (sr < 0) return */                                \
1273         emith_cmp_r_imm(sr, 0);                                 \
1274         EMITH_JMP_START(DCOND_LE);                              \
1275         /* turns = sr.cycles / cycles */                        \
1276         emith_asr(t2, sr, 12);                                  \
1277         emith_move_r_imm(t3, (u32)((1ULL<<32) / (cycles)));     \
1278         emith_mul_u64(t1, t2, t2, t3); /* multiply by 1/x */    \
1279         rcache_free_tmp(t3);                                    \
1280         if (reg >= 0) {                                         \
1281                 /* if (reg <= turns) turns = reg-1 */           \
1282                 t3 = rcache_get_reg(reg, RC_GR_RMW, NULL);      \
1283                 emith_cmp_r_r(t3, t2);                          \
1284                 EMITH_SJMP_START(DCOND_HI);                     \
1285                 emith_sub_r_r_imm_c(DCOND_LS, t2, t3, 1);       \
1286                 EMITH_SJMP_END(DCOND_HI);                       \
1287                 /* if (reg <= 1) turns = 0 */                   \
1288                 emith_cmp_r_imm(t3, 1);                         \
1289                 EMITH_SJMP_START(DCOND_HI);                     \
1290                 emith_move_r_imm_c(DCOND_LS, t2, 0);            \
1291                 EMITH_SJMP_END(DCOND_HI);                       \
1292                 /* reg -= turns */                              \
1293                 emith_sub_r_r(t3, t2);                          \
1294         }                                                       \
1295         /* sr.cycles -= turns * cycles; */                      \
1296         emith_move_r_imm(t1, cycles);                           \
1297         emith_mul_u64(t1, t2, t1, t2);                          \
1298         emith_sub_r_r_r_lsl(sr, sr, t1, 12);                    \
1299         EMITH_JMP_END(DCOND_LE);                                \
1300         rcache_free_tmp(t1);                                    \
1301         rcache_free_tmp(t2);                                    \
1302 } while (0)
1303
1304 #define emith_write_sr(sr, srcr) do { \
1305         int tmp_ = rcache_get_tmp(); \
1306         emith_clear_msb(tmp_, srcr, 22); \
1307         emith_bic_r_imm(sr, 0x3ff); \
1308         emith_or_r_r(sr, tmp_); \
1309         rcache_free_tmp(tmp_); \
1310 } while (0)
1311
1312 #define emith_carry_to_t(sr, is_sub) do { \
1313         emith_rorc(sr); \
1314         emith_rol(sr, sr, 1); \
1315 } while (0)
1316
1317 #define emith_t_to_carry(sr, is_sub) do { \
1318         emith_ror(sr, sr, 1); \
1319         emith_rol(sr, sr, 1); \
1320 } while (0)
1321
1322 #define emith_tpop_carry(sr, is_sub) \
1323         emith_lsr(sr, sr, 1)
1324
1325 #define emith_tpush_carry(sr, is_sub) \
1326         emith_adc_r_r(sr, sr)
1327
1328 /*
1329  * T = carry(Rn = (Rn << 1) | T)
1330  * if Q
1331  *   t = carry(Rn += Rm)
1332  * else
1333  *   t = carry(Rn -= Rm)
1334  * T = !(T ^ t)
1335  */
1336 #define emith_sh2_div1_step(rn, rm, sr) do {      \
1337         u8 *jmp0, *jmp1;                          \
1338         int tmp_ = rcache_get_tmp();              \
1339         emith_tpop_carry(sr, 0); /* Rn = 2*Rn+T */\
1340         emith_adcf_r_r_r(rn, rn, rn);             \
1341         emith_tpush_carry(sr, 0); /* T = C1 */    \
1342         emith_eor_r_r(tmp_, tmp_);                \
1343         emith_tst_r_imm(sr, Q);  /* if (Q ^ M) */ \
1344         JMP8_POS(jmp0);          /* je do_sub */  \
1345         emith_add_r_r(rn, rm);                    \
1346         JMP8_POS(jmp1);          /* jmp done */   \
1347         JMP8_EMIT(ICOND_JE, jmp0); /* do_sub: */  \
1348         emith_sub_r_r(rn, rm);                    \
1349         JMP8_EMIT_NC(jmp1);      /* done: */      \
1350         emith_adc_r_r(tmp_, tmp_);                \
1351         emith_eor_r_r(sr, tmp_);/* T = !(C1^C2) */\
1352         emith_eor_r_imm(sr, T);                   \
1353         rcache_free_tmp(tmp_);                    \
1354 } while (0)
1355
1356 /* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
1357 #define emith_sh2_macl(ml, mh, rn, rm, sr) do {   \
1358         emith_tst_r_imm(sr, S);                   \
1359         EMITH_SJMP_START(DCOND_EQ);               \
1360         /* MACH top 16 bits unused if saturated. sign ext for overfl detect */ \
1361         emith_sext(mh, mh, 16);                   \
1362         EMITH_SJMP_END(DCOND_EQ);                 \
1363         emith_mula_s64(ml, mh, rn, rm);           \
1364         emith_tst_r_imm(sr, S);                   \
1365         EMITH_SJMP_START(DCOND_EQ);               \
1366         /* overflow if top 17 bits of MACH aren't all 1 or 0 */ \
1367         /* to check: add MACH >> 31 to MACH >> 15. this is 0 if no overflow */ \
1368         emith_asr(rn, mh, 15);                    \
1369         emith_lsr(rm, mh, 31);                    \
1370         emith_addf_r_r(rn, rm);                   \
1371         EMITH_SJMP_START(DCOND_EQ); /* sum != 0 -> -ovl */ \
1372         emith_move_r_imm_c(DCOND_NE, ml, 0x00000000); \
1373         emith_move_r_imm_c(DCOND_NE, mh, 0x00008000); \
1374         EMITH_SJMP_START(DCOND_MI); /* sum < 0 -> -ovl */ \
1375         emith_sub_r_imm_c(DCOND_PL, ml, 1); /* 0xffffffff */ \
1376         emith_sub_r_imm_c(DCOND_PL, mh, 1); /* 0x00007fff */ \
1377         EMITH_SJMP_END(DCOND_MI);                 \
1378         EMITH_SJMP_END(DCOND_EQ);                 \
1379         EMITH_SJMP_END(DCOND_EQ);                 \
1380 } while (0)
1381
1382 /* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
1383 #define emith_sh2_macw(ml, mh, rn, rm, sr) do {   \
1384         emith_tst_r_imm(sr, S);                   \
1385         EMITH_SJMP_START(DCOND_EQ);               \
1386         /* XXX: MACH should be untouched when S is set? */ \
1387         emith_asr(mh, ml, 31); /* sign ext MACL to MACH for ovrfl check */ \
1388         EMITH_SJMP_END(DCOND_EQ);                 \
1389         emith_mula_s64(ml, mh, rn, rm);           \
1390         emith_tst_r_imm(sr, S);                   \
1391         EMITH_SJMP_START(DCOND_EQ);               \
1392         /* overflow if top 33 bits of MACH:MACL aren't all 1 or 0 */ \
1393         /* to check: add MACL[31] to MACH. this is 0 if no overflow */ \
1394         emith_lsr(rn, ml, 31);                    \
1395         emith_addf_r_r(rn, mh); /* sum = MACH + ((MACL>>31)&1) */ \
1396         EMITH_SJMP_START(DCOND_EQ); /* sum != 0 -> overflow */ \
1397         /* XXX: LSB signalling only in SH1, or in SH2 too? */ \
1398         emith_move_r_imm_c(DCOND_NE, mh, 0x00000001); /* LSB of MACH */ \
1399         emith_move_r_imm_c(DCOND_NE, ml, 0x80000000); /* -overflow */ \
1400         EMITH_SJMP_START(DCOND_MI); /* sum > 0 -> +overflow */ \
1401         emith_sub_r_imm_c(DCOND_PL, ml, 1); /* 0x7fffffff */ \
1402         EMITH_SJMP_END(DCOND_MI);                 \
1403         EMITH_SJMP_END(DCOND_EQ);                 \
1404         EMITH_SJMP_END(DCOND_EQ);                 \
1405 } while (0)
1406
1407 #define emith_pool_check()      /**/
1408 #define emith_pool_commit(j)    /**/
1409 #define emith_insn_ptr()        ((u8 *)tcache_ptr)
1410 #define emith_flush()           /**/
1411
1412 #ifdef T
1413 // T bit handling
1414 #define emith_invert_cond(cond) \
1415         ((cond) ^ 1)
1416
1417 static void emith_clr_t_cond(int sr)
1418 {
1419   emith_bic_r_imm(sr, T);
1420 }
1421
1422 static void emith_set_t_cond(int sr, int cond)
1423 {
1424   EMITH_SJMP_START(emith_invert_cond(cond));
1425   emith_or_r_imm_c(cond, sr, T);
1426   EMITH_SJMP_END(emith_invert_cond(cond));
1427 }
1428
1429 #define emith_get_t_cond()      -1
1430
1431 #define emith_sync_t(sr)        ((void)sr)
1432
1433 #define emith_invalidate_t()
1434
1435 static void emith_set_t(int sr, int val)
1436 {
1437   if (val) 
1438     emith_or_r_imm(sr, T);
1439   else
1440     emith_bic_r_imm(sr, T);
1441 }
1442
1443 static int emith_tst_t(int sr, int tf)
1444 {
1445   emith_tst_r_imm(sr, T);
1446   return tf ? DCOND_NE: DCOND_EQ;
1447 }
1448 #endif