Merge commit 'origin/upstream' into juha-devel
[qemu] / tcg / x86_64 / tcg-target.c
1 /*
2  * Tiny Code Generator for QEMU
3  *
4  * Copyright (c) 2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 #ifndef NDEBUG
26 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
27     "%rax",
28     "%rcx",
29     "%rdx",
30     "%rbx",
31     "%rsp",
32     "%rbp",
33     "%rsi",
34     "%rdi",
35     "%r8",
36     "%r9",
37     "%r10",
38     "%r11",
39     "%r12",
40     "%r13",
41     "%r14",
42     "%r15",
43 };
44 #endif
45
46 static const int tcg_target_reg_alloc_order[] = {
47     TCG_REG_RDI,
48     TCG_REG_RSI,
49     TCG_REG_RDX,
50     TCG_REG_RCX,
51     TCG_REG_R8,
52     TCG_REG_R9,
53     TCG_REG_RAX,
54     TCG_REG_R10,
55     TCG_REG_R11,
56
57     TCG_REG_RBP,
58     TCG_REG_RBX,
59     TCG_REG_R12,
60     TCG_REG_R13,
61     TCG_REG_R14,
62     TCG_REG_R15,
63 };
64
65 static const int tcg_target_call_iarg_regs[6] = {
66     TCG_REG_RDI,
67     TCG_REG_RSI,
68     TCG_REG_RDX,
69     TCG_REG_RCX,
70     TCG_REG_R8,
71     TCG_REG_R9,
72 };
73
74 static const int tcg_target_call_oarg_regs[2] = {
75     TCG_REG_RAX, 
76     TCG_REG_RDX 
77 };
78
79 static uint8_t *tb_ret_addr;
80
81 static void patch_reloc(uint8_t *code_ptr, int type, 
82                         tcg_target_long value, tcg_target_long addend)
83 {
84     value += addend;
85     switch(type) {
86     case R_X86_64_32:
87         if (value != (uint32_t)value)
88             tcg_abort();
89         *(uint32_t *)code_ptr = value;
90         break;
91     case R_X86_64_32S:
92         if (value != (int32_t)value)
93             tcg_abort();
94         *(uint32_t *)code_ptr = value;
95         break;
96     case R_386_PC32:
97         value -= (long)code_ptr;
98         if (value != (int32_t)value)
99             tcg_abort();
100         *(uint32_t *)code_ptr = value;
101         break;
102     default:
103         tcg_abort();
104     }
105 }
106
107 /* maximum number of register used for input function arguments */
108 static inline int tcg_target_get_call_iarg_regs_count(int flags)
109 {
110     return 6;
111 }
112
113 /* parse target specific constraints */
114 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
115 {
116     const char *ct_str;
117
118     ct_str = *pct_str;
119     switch(ct_str[0]) {
120     case 'a':
121         ct->ct |= TCG_CT_REG;
122         tcg_regset_set_reg(ct->u.regs, TCG_REG_RAX);
123         break;
124     case 'b':
125         ct->ct |= TCG_CT_REG;
126         tcg_regset_set_reg(ct->u.regs, TCG_REG_RBX);
127         break;
128     case 'c':
129         ct->ct |= TCG_CT_REG;
130         tcg_regset_set_reg(ct->u.regs, TCG_REG_RCX);
131         break;
132     case 'd':
133         ct->ct |= TCG_CT_REG;
134         tcg_regset_set_reg(ct->u.regs, TCG_REG_RDX);
135         break;
136     case 'S':
137         ct->ct |= TCG_CT_REG;
138         tcg_regset_set_reg(ct->u.regs, TCG_REG_RSI);
139         break;
140     case 'D':
141         ct->ct |= TCG_CT_REG;
142         tcg_regset_set_reg(ct->u.regs, TCG_REG_RDI);
143         break;
144     case 'q':
145         ct->ct |= TCG_CT_REG;
146         tcg_regset_set32(ct->u.regs, 0, 0xf);
147         break;
148     case 'r':
149         ct->ct |= TCG_CT_REG;
150         tcg_regset_set32(ct->u.regs, 0, 0xffff);
151         break;
152     case 'L': /* qemu_ld/st constraint */
153         ct->ct |= TCG_CT_REG;
154         tcg_regset_set32(ct->u.regs, 0, 0xffff);
155         tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
156         tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
157         break;
158     case 'e':
159         ct->ct |= TCG_CT_CONST_S32;
160         break;
161     case 'Z':
162         ct->ct |= TCG_CT_CONST_U32;
163         break;
164     default:
165         return -1;
166     }
167     ct_str++;
168     *pct_str = ct_str;
169     return 0;
170 }
171
172 /* test if a constant matches the constraint */
173 static inline int tcg_target_const_match(tcg_target_long val,
174                                          const TCGArgConstraint *arg_ct)
175 {
176     int ct;
177     ct = arg_ct->ct;
178     if (ct & TCG_CT_CONST)
179         return 1;
180     else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val)
181         return 1;
182     else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val)
183         return 1;
184     else
185         return 0;
186 }
187
188 #define ARITH_ADD 0
189 #define ARITH_OR  1
190 #define ARITH_ADC 2
191 #define ARITH_SBB 3
192 #define ARITH_AND 4
193 #define ARITH_SUB 5
194 #define ARITH_XOR 6
195 #define ARITH_CMP 7
196
197 #define SHIFT_ROL 0
198 #define SHIFT_ROR 1
199 #define SHIFT_SHL 4
200 #define SHIFT_SHR 5
201 #define SHIFT_SAR 7
202
203 #define JCC_JMP (-1)
204 #define JCC_JO  0x0
205 #define JCC_JNO 0x1
206 #define JCC_JB  0x2
207 #define JCC_JAE 0x3
208 #define JCC_JE  0x4
209 #define JCC_JNE 0x5
210 #define JCC_JBE 0x6
211 #define JCC_JA  0x7
212 #define JCC_JS  0x8
213 #define JCC_JNS 0x9
214 #define JCC_JP  0xa
215 #define JCC_JNP 0xb
216 #define JCC_JL  0xc
217 #define JCC_JGE 0xd
218 #define JCC_JLE 0xe
219 #define JCC_JG  0xf
220
221 #define P_EXT   0x100 /* 0x0f opcode prefix */
222 #define P_REXW  0x200 /* set rex.w = 1 */
223 #define P_REXB  0x400 /* force rex use for byte registers */
224                                   
225 static const uint8_t tcg_cond_to_jcc[10] = {
226     [TCG_COND_EQ] = JCC_JE,
227     [TCG_COND_NE] = JCC_JNE,
228     [TCG_COND_LT] = JCC_JL,
229     [TCG_COND_GE] = JCC_JGE,
230     [TCG_COND_LE] = JCC_JLE,
231     [TCG_COND_GT] = JCC_JG,
232     [TCG_COND_LTU] = JCC_JB,
233     [TCG_COND_GEU] = JCC_JAE,
234     [TCG_COND_LEU] = JCC_JBE,
235     [TCG_COND_GTU] = JCC_JA,
236 };
237
238 static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
239 {
240     int rex;
241     rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) | 
242         ((x >> 2) & 2) | ((rm >> 3) & 1);
243     if (rex || (opc & P_REXB)) {
244         tcg_out8(s, rex | 0x40);
245     }
246     if (opc & P_EXT)
247         tcg_out8(s, 0x0f);
248     tcg_out8(s, opc & 0xff);
249 }
250
251 static inline void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
252 {
253     tcg_out_opc(s, opc, r, rm, 0);
254     tcg_out8(s, 0xc0 | ((r & 7) << 3) | (rm & 7));
255 }
256
257 /* rm < 0 means no register index plus (-rm - 1 immediate bytes) */
258 static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r, int rm, 
259                                         tcg_target_long offset)
260 {
261     if (rm < 0) {
262         tcg_target_long val;
263         tcg_out_opc(s, opc, r, 0, 0);
264         val = offset - ((tcg_target_long)s->code_ptr + 5 + (-rm - 1));
265         if (val == (int32_t)val) {
266             /* eip relative */
267             tcg_out8(s, 0x05 | ((r & 7) << 3));
268             tcg_out32(s, val);
269         } else if (offset == (int32_t)offset) {
270             tcg_out8(s, 0x04 | ((r & 7) << 3));
271             tcg_out8(s, 0x25); /* sib */
272             tcg_out32(s, offset);
273         } else {
274             tcg_abort();
275         }
276     } else if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
277         tcg_out_opc(s, opc, r, rm, 0);
278         if ((rm & 7) == TCG_REG_RSP) {
279             tcg_out8(s, 0x04 | ((r & 7) << 3));
280             tcg_out8(s, 0x24);
281         } else {
282             tcg_out8(s, 0x00 | ((r & 7) << 3) | (rm & 7));
283         }
284     } else if ((int8_t)offset == offset) {
285         tcg_out_opc(s, opc, r, rm, 0);
286         if ((rm & 7) == TCG_REG_RSP) {
287             tcg_out8(s, 0x44 | ((r & 7) << 3));
288             tcg_out8(s, 0x24);
289         } else {
290             tcg_out8(s, 0x40 | ((r & 7) << 3) | (rm & 7));
291         }
292         tcg_out8(s, offset);
293     } else {
294         tcg_out_opc(s, opc, r, rm, 0);
295         if ((rm & 7) == TCG_REG_RSP) {
296             tcg_out8(s, 0x84 | ((r & 7) << 3));
297             tcg_out8(s, 0x24);
298         } else {
299             tcg_out8(s, 0x80 | ((r & 7) << 3) | (rm & 7));
300         }
301         tcg_out32(s, offset);
302     }
303 }
304
305 #if defined(CONFIG_SOFTMMU)
306 /* XXX: incomplete. index must be different from ESP */
307 static void tcg_out_modrm_offset2(TCGContext *s, int opc, int r, int rm, 
308                                   int index, int shift,
309                                   tcg_target_long offset)
310 {
311     int mod;
312     if (rm == -1)
313         tcg_abort();
314     if (offset == 0 && (rm & 7) != TCG_REG_RBP) {
315         mod = 0;
316     } else if (offset == (int8_t)offset) {
317         mod = 0x40;
318     } else if (offset == (int32_t)offset) {
319         mod = 0x80;
320     } else {
321         tcg_abort();
322     }
323     if (index == -1) {
324         tcg_out_opc(s, opc, r, rm, 0);
325         if ((rm & 7) == TCG_REG_RSP) {
326             tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
327             tcg_out8(s, 0x04 | (rm & 7));
328         } else {
329             tcg_out8(s, mod | ((r & 7) << 3) | (rm & 7));
330         }
331     } else {
332         tcg_out_opc(s, opc, r, rm, index);
333         tcg_out8(s, mod | ((r & 7) << 3) | 0x04);
334         tcg_out8(s, (shift << 6) | ((index & 7) << 3) | (rm & 7));
335     }
336     if (mod == 0x40) {
337         tcg_out8(s, offset);
338     } else if (mod == 0x80) {
339         tcg_out32(s, offset);
340     }
341 }
342 #endif
343
344 static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
345 {
346     tcg_out_modrm(s, 0x8b | P_REXW, ret, arg);
347 }
348
349 static inline void tcg_out_movi(TCGContext *s, TCGType type, 
350                                 int ret, tcg_target_long arg)
351 {
352     if (arg == 0) {
353         tcg_out_modrm(s, 0x01 | (ARITH_XOR << 3), ret, ret); /* xor r0,r0 */
354     } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
355         tcg_out_opc(s, 0xb8 + (ret & 7), 0, ret, 0);
356         tcg_out32(s, arg);
357     } else if (arg == (int32_t)arg) {
358         tcg_out_modrm(s, 0xc7 | P_REXW, 0, ret);
359         tcg_out32(s, arg);
360     } else {
361         tcg_out_opc(s, (0xb8 + (ret & 7)) | P_REXW, 0, ret, 0);
362         tcg_out32(s, arg);
363         tcg_out32(s, arg >> 32);
364     }
365 }
366
367 static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
368                               int arg1, tcg_target_long arg2)
369 {
370     if (type == TCG_TYPE_I32)
371         tcg_out_modrm_offset(s, 0x8b, ret, arg1, arg2); /* movl */
372     else
373         tcg_out_modrm_offset(s, 0x8b | P_REXW, ret, arg1, arg2); /* movq */
374 }
375
376 static inline void tcg_out_st(TCGContext *s, TCGType type, int arg,
377                               int arg1, tcg_target_long arg2)
378 {
379     if (type == TCG_TYPE_I32)
380         tcg_out_modrm_offset(s, 0x89, arg, arg1, arg2); /* movl */
381     else
382         tcg_out_modrm_offset(s, 0x89 | P_REXW, arg, arg1, arg2); /* movq */
383 }
384
385 static inline void tgen_arithi32(TCGContext *s, int c, int r0, int32_t val)
386 {
387     if (val == (int8_t)val) {
388         tcg_out_modrm(s, 0x83, c, r0);
389         tcg_out8(s, val);
390     } else if (c == ARITH_AND && val == 0xffu) {
391         /* movzbl */
392         tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, r0, r0);
393     } else if (c == ARITH_AND && val == 0xffffu) {
394         /* movzwl */
395         tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0);
396     } else {
397         tcg_out_modrm(s, 0x81, c, r0);
398         tcg_out32(s, val);
399     }
400 }
401
402 static inline void tgen_arithi64(TCGContext *s, int c, int r0, int64_t val)
403 {
404     if (val == (int8_t)val) {
405         tcg_out_modrm(s, 0x83 | P_REXW, c, r0);
406         tcg_out8(s, val);
407     } else if (c == ARITH_AND && val == 0xffu) {
408         /* movzbl */
409         tcg_out_modrm(s, 0xb6 | P_EXT | P_REXW, r0, r0);
410     } else if (c == ARITH_AND && val == 0xffffu) {
411         /* movzwl */
412         tcg_out_modrm(s, 0xb7 | P_EXT | P_REXW, r0, r0);
413     } else if (c == ARITH_AND && val == 0xffffffffu) {
414         /* 32-bit mov zero extends */
415         tcg_out_modrm(s, 0x8b, r0, r0);
416     } else if (val == (int32_t)val) {
417         tcg_out_modrm(s, 0x81 | P_REXW, c, r0);
418         tcg_out32(s, val);
419     } else if (c == ARITH_AND && val == (uint32_t)val) {
420         tcg_out_modrm(s, 0x81, c, r0);
421         tcg_out32(s, val);
422     } else {
423         tcg_abort();
424     }
425 }
426
427 static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
428 {
429     if (val != 0)
430         tgen_arithi64(s, ARITH_ADD, reg, val);
431 }
432
433 static void tcg_out_jxx(TCGContext *s, int opc, int label_index)
434 {
435     int32_t val, val1;
436     TCGLabel *l = &s->labels[label_index];
437     
438     if (l->has_value) {
439         val = l->u.value - (tcg_target_long)s->code_ptr;
440         val1 = val - 2;
441         if ((int8_t)val1 == val1) {
442             if (opc == -1)
443                 tcg_out8(s, 0xeb);
444             else
445                 tcg_out8(s, 0x70 + opc);
446             tcg_out8(s, val1);
447         } else {
448             if (opc == -1) {
449                 tcg_out8(s, 0xe9);
450                 tcg_out32(s, val - 5);
451             } else {
452                 tcg_out8(s, 0x0f);
453                 tcg_out8(s, 0x80 + opc);
454                 tcg_out32(s, val - 6);
455             }
456         }
457     } else {
458         if (opc == -1) {
459             tcg_out8(s, 0xe9);
460         } else {
461             tcg_out8(s, 0x0f);
462             tcg_out8(s, 0x80 + opc);
463         }
464         tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
465         s->code_ptr += 4;
466     }
467 }
468
469 static void tcg_out_brcond(TCGContext *s, int cond, 
470                            TCGArg arg1, TCGArg arg2, int const_arg2,
471                            int label_index, int rexw)
472 {
473     if (const_arg2) {
474         if (arg2 == 0) {
475             /* test r, r */
476             tcg_out_modrm(s, 0x85 | rexw, arg1, arg1);
477         } else {
478             if (rexw)
479                 tgen_arithi64(s, ARITH_CMP, arg1, arg2);
480             else
481                 tgen_arithi32(s, ARITH_CMP, arg1, arg2);
482         }
483     } else {
484         tcg_out_modrm(s, 0x01 | (ARITH_CMP << 3) | rexw, arg2, arg1);
485     }
486     tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index);
487 }
488
489 #if defined(CONFIG_SOFTMMU)
490
491 #include "../../softmmu_defs.h"
492
493 static void *qemu_ld_helpers[4] = {
494     __ldb_mmu,
495     __ldw_mmu,
496     __ldl_mmu,
497     __ldq_mmu,
498 };
499
500 static void *qemu_st_helpers[4] = {
501     __stb_mmu,
502     __stw_mmu,
503     __stl_mmu,
504     __stq_mmu,
505 };
506 #endif
507
508 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
509                             int opc)
510 {
511     int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
512 #if defined(CONFIG_SOFTMMU)
513     uint8_t *label1_ptr, *label2_ptr;
514 #endif
515
516     data_reg = *args++;
517     addr_reg = *args++;
518     mem_index = *args;
519     s_bits = opc & 3;
520
521     r0 = TCG_REG_RDI;
522     r1 = TCG_REG_RSI;
523
524 #if TARGET_LONG_BITS == 32
525     rexw = 0;
526 #else
527     rexw = P_REXW;
528 #endif
529 #if defined(CONFIG_SOFTMMU)
530     /* mov */
531     tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
532
533     /* mov */
534     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
535  
536     tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
537     tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
538     
539     tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
540     tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
541     
542     tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
543     tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
544
545     /* lea offset(r1, env), r1 */
546     tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
547                           offsetof(CPUState, tlb_table[mem_index][0].addr_read));
548
549     /* cmp 0(r1), r0 */
550     tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
551     
552     /* mov */
553     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
554     
555     /* je label1 */
556     tcg_out8(s, 0x70 + JCC_JE);
557     label1_ptr = s->code_ptr;
558     s->code_ptr++;
559
560     /* XXX: move that code at the end of the TB */
561     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RSI, mem_index);
562     tcg_out8(s, 0xe8);
563     tcg_out32(s, (tcg_target_long)qemu_ld_helpers[s_bits] - 
564               (tcg_target_long)s->code_ptr - 4);
565
566     switch(opc) {
567     case 0 | 4:
568         /* movsbq */
569         tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
570         break;
571     case 1 | 4:
572         /* movswq */
573         tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
574         break;
575     case 2 | 4:
576         /* movslq */
577         tcg_out_modrm(s, 0x63 | P_REXW, data_reg, TCG_REG_RAX);
578         break;
579     case 0:
580         /* movzbq */
581         tcg_out_modrm(s, 0xb6 | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
582         break;
583     case 1:
584         /* movzwq */
585         tcg_out_modrm(s, 0xb7 | P_EXT | P_REXW, data_reg, TCG_REG_RAX);
586         break;
587     case 2:
588     default:
589         /* movl */
590         tcg_out_modrm(s, 0x8b, data_reg, TCG_REG_RAX);
591         break;
592     case 3:
593         tcg_out_mov(s, data_reg, TCG_REG_RAX);
594         break;
595     }
596
597     /* jmp label2 */
598     tcg_out8(s, 0xeb);
599     label2_ptr = s->code_ptr;
600     s->code_ptr++;
601     
602     /* label1: */
603     *label1_ptr = s->code_ptr - label1_ptr - 1;
604
605     /* add x(r1), r0 */
606     tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - 
607                          offsetof(CPUTLBEntry, addr_read));
608 #elif defined(CONFIG_USE_GUEST_BASE)
609     /*
610      * Add guest_base to all loads.
611      */
612     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); /* movq addr_reg, r0 */
613     tcg_out_addi(s, r0, GUEST_BASE);             /* addq $GUEST_BASE, r0 */
614 #else
615     r0 = addr_reg;
616 #endif    
617
618 #ifdef TARGET_WORDS_BIGENDIAN
619     bswap = 1;
620 #else
621     bswap = 0;
622 #endif
623     switch(opc) {
624     case 0:
625         /* movzbl */
626         tcg_out_modrm_offset(s, 0xb6 | P_EXT, data_reg, r0, 0);
627         break;
628     case 0 | 4:
629         /* movsbX */
630         tcg_out_modrm_offset(s, 0xbe | P_EXT | rexw, data_reg, r0, 0);
631         break;
632     case 1:
633         /* movzwl */
634         tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
635         if (bswap) {
636             /* rolw $8, data_reg */
637             tcg_out8(s, 0x66); 
638             tcg_out_modrm(s, 0xc1, 0, data_reg);
639             tcg_out8(s, 8);
640         }
641         break;
642     case 1 | 4:
643         if (bswap) {
644             /* movzwl */
645             tcg_out_modrm_offset(s, 0xb7 | P_EXT, data_reg, r0, 0);
646             /* rolw $8, data_reg */
647             tcg_out8(s, 0x66); 
648             tcg_out_modrm(s, 0xc1, 0, data_reg);
649             tcg_out8(s, 8);
650
651             /* movswX data_reg, data_reg */
652             tcg_out_modrm(s, 0xbf | P_EXT | rexw, data_reg, data_reg);
653         } else {
654             /* movswX */
655             tcg_out_modrm_offset(s, 0xbf | P_EXT | rexw, data_reg, r0, 0);
656         }
657         break;
658     case 2:
659         /* movl (r0), data_reg */
660         tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
661         if (bswap) {
662             /* bswap */
663             tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
664         }
665         break;
666     case 2 | 4:
667         if (bswap) {
668             /* movl (r0), data_reg */
669             tcg_out_modrm_offset(s, 0x8b, data_reg, r0, 0);
670             /* bswap */
671             tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT, 0, data_reg, 0);
672             /* movslq */
673             tcg_out_modrm(s, 0x63 | P_REXW, data_reg, data_reg);
674         } else {
675             /* movslq */
676             tcg_out_modrm_offset(s, 0x63 | P_REXW, data_reg, r0, 0);
677         }
678         break;
679     case 3:
680         /* movq (r0), data_reg */
681         tcg_out_modrm_offset(s, 0x8b | P_REXW, data_reg, r0, 0);
682         if (bswap) {
683             /* bswap */
684             tcg_out_opc(s, (0xc8 + (data_reg & 7)) | P_EXT | P_REXW, 0, data_reg, 0);
685         }
686         break;
687     default:
688         tcg_abort();
689     }
690
691 #if defined(CONFIG_SOFTMMU)
692     /* label2: */
693     *label2_ptr = s->code_ptr - label2_ptr - 1;
694 #endif
695 }
696
697 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
698                             int opc)
699 {
700     int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, rexw;
701 #if defined(CONFIG_SOFTMMU)
702     uint8_t *label1_ptr, *label2_ptr;
703 #endif
704
705     data_reg = *args++;
706     addr_reg = *args++;
707     mem_index = *args;
708
709     s_bits = opc;
710
711     r0 = TCG_REG_RDI;
712     r1 = TCG_REG_RSI;
713
714 #if TARGET_LONG_BITS == 32
715     rexw = 0;
716 #else
717     rexw = P_REXW;
718 #endif
719 #if defined(CONFIG_SOFTMMU)
720     /* mov */
721     tcg_out_modrm(s, 0x8b | rexw, r1, addr_reg);
722
723     /* mov */
724     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
725  
726     tcg_out_modrm(s, 0xc1 | rexw, 5, r1); /* shr $x, r1 */
727     tcg_out8(s, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); 
728     
729     tcg_out_modrm(s, 0x81 | rexw, 4, r0); /* andl $x, r0 */
730     tcg_out32(s, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
731     
732     tcg_out_modrm(s, 0x81, 4, r1); /* andl $x, r1 */
733     tcg_out32(s, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
734
735     /* lea offset(r1, env), r1 */
736     tcg_out_modrm_offset2(s, 0x8d | P_REXW, r1, r1, TCG_AREG0, 0,
737                           offsetof(CPUState, tlb_table[mem_index][0].addr_write));
738
739     /* cmp 0(r1), r0 */
740     tcg_out_modrm_offset(s, 0x3b | rexw, r0, r1, 0);
741     
742     /* mov */
743     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg);
744     
745     /* je label1 */
746     tcg_out8(s, 0x70 + JCC_JE);
747     label1_ptr = s->code_ptr;
748     s->code_ptr++;
749
750     /* XXX: move that code at the end of the TB */
751     switch(opc) {
752     case 0:
753         /* movzbl */
754         tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg);
755         break;
756     case 1:
757         /* movzwl */
758         tcg_out_modrm(s, 0xb7 | P_EXT, TCG_REG_RSI, data_reg);
759         break;
760     case 2:
761         /* movl */
762         tcg_out_modrm(s, 0x8b, TCG_REG_RSI, data_reg);
763         break;
764     default:
765     case 3:
766         tcg_out_mov(s, TCG_REG_RSI, data_reg);
767         break;
768     }
769     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
770     tcg_out8(s, 0xe8);
771     tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] - 
772               (tcg_target_long)s->code_ptr - 4);
773
774     /* jmp label2 */
775     tcg_out8(s, 0xeb);
776     label2_ptr = s->code_ptr;
777     s->code_ptr++;
778     
779     /* label1: */
780     *label1_ptr = s->code_ptr - label1_ptr - 1;
781
782     /* add x(r1), r0 */
783     tcg_out_modrm_offset(s, 0x03 | P_REXW, r0, r1, offsetof(CPUTLBEntry, addend) - 
784                          offsetof(CPUTLBEntry, addr_write));
785 #elif defined(CONFIG_USE_GUEST_BASE)
786     /*
787      * Add guest_base to all stores.
788      */
789     tcg_out_modrm(s, 0x8b | rexw, r0, addr_reg); /* movq addr_reg, r0 */
790     tcg_out_addi(s, r0, GUEST_BASE);             /* addq $GUEST_BASE, r0 */
791 #else
792     r0 = addr_reg;
793 #endif
794
795 #ifdef TARGET_WORDS_BIGENDIAN
796     bswap = 1;
797 #else
798     bswap = 0;
799 #endif
800     switch(opc) {
801     case 0:
802         /* movb */
803         tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, 0);
804         break;
805     case 1:
806         if (bswap) {
807             tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
808             tcg_out8(s, 0x66); /* rolw $8, %ecx */
809             tcg_out_modrm(s, 0xc1, 0, r1);
810             tcg_out8(s, 8);
811             data_reg = r1;
812         }
813         /* movw */
814         tcg_out8(s, 0x66);
815         tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
816         break;
817     case 2:
818         if (bswap) {
819             tcg_out_modrm(s, 0x8b, r1, data_reg); /* movl */
820             /* bswap data_reg */
821             tcg_out_opc(s, (0xc8 + r1) | P_EXT, 0, r1, 0);
822             data_reg = r1;
823         }
824         /* movl */
825         tcg_out_modrm_offset(s, 0x89, data_reg, r0, 0);
826         break;
827     case 3:
828         if (bswap) {
829             tcg_out_mov(s, r1, data_reg);
830             /* bswap data_reg */
831             tcg_out_opc(s, (0xc8 + r1) | P_EXT | P_REXW, 0, r1, 0);
832             data_reg = r1;
833         }
834         /* movq */
835         tcg_out_modrm_offset(s, 0x89 | P_REXW, data_reg, r0, 0);
836         break;
837     default:
838         tcg_abort();
839     }
840
841 #if defined(CONFIG_SOFTMMU)
842     /* label2: */
843     *label2_ptr = s->code_ptr - label2_ptr - 1;
844 #endif
845 }
846
847 static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
848                               const int *const_args)
849 {
850     int c;
851     
852     switch(opc) {
853     case INDEX_op_exit_tb:
854         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, args[0]);
855         tcg_out8(s, 0xe9); /* jmp tb_ret_addr */
856         tcg_out32(s, tb_ret_addr - s->code_ptr - 4);
857         break;
858     case INDEX_op_goto_tb:
859         if (s->tb_jmp_offset) {
860             /* direct jump method */
861             tcg_out8(s, 0xe9); /* jmp im */
862             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
863             tcg_out32(s, 0);
864         } else {
865             /* indirect jump method */
866             /* jmp Ev */
867             tcg_out_modrm_offset(s, 0xff, 4, -1, 
868                                  (tcg_target_long)(s->tb_next + 
869                                                    args[0]));
870         }
871         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
872         break;
873     case INDEX_op_call:
874         if (const_args[0]) {
875             tcg_out8(s, 0xe8);
876             tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
877         } else {
878             tcg_out_modrm(s, 0xff, 2, args[0]);
879         }
880         break;
881     case INDEX_op_jmp:
882         if (const_args[0]) {
883             tcg_out8(s, 0xe9);
884             tcg_out32(s, args[0] - (tcg_target_long)s->code_ptr - 4);
885         } else {
886             tcg_out_modrm(s, 0xff, 4, args[0]);
887         }
888         break;
889     case INDEX_op_br:
890         tcg_out_jxx(s, JCC_JMP, args[0]);
891         break;
892     case INDEX_op_movi_i32:
893         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
894         break;
895     case INDEX_op_movi_i64:
896         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
897         break;
898     case INDEX_op_ld8u_i32:
899     case INDEX_op_ld8u_i64:
900         /* movzbl */
901         tcg_out_modrm_offset(s, 0xb6 | P_EXT, args[0], args[1], args[2]);
902         break;
903     case INDEX_op_ld8s_i32:
904         /* movsbl */
905         tcg_out_modrm_offset(s, 0xbe | P_EXT, args[0], args[1], args[2]);
906         break;
907     case INDEX_op_ld8s_i64:
908         /* movsbq */
909         tcg_out_modrm_offset(s, 0xbe | P_EXT | P_REXW, args[0], args[1], args[2]);
910         break;
911     case INDEX_op_ld16u_i32:
912     case INDEX_op_ld16u_i64:
913         /* movzwl */
914         tcg_out_modrm_offset(s, 0xb7 | P_EXT, args[0], args[1], args[2]);
915         break;
916     case INDEX_op_ld16s_i32:
917         /* movswl */
918         tcg_out_modrm_offset(s, 0xbf | P_EXT, args[0], args[1], args[2]);
919         break;
920     case INDEX_op_ld16s_i64:
921         /* movswq */
922         tcg_out_modrm_offset(s, 0xbf | P_EXT | P_REXW, args[0], args[1], args[2]);
923         break;
924     case INDEX_op_ld_i32:
925     case INDEX_op_ld32u_i64:
926         /* movl */
927         tcg_out_modrm_offset(s, 0x8b, args[0], args[1], args[2]);
928         break;
929     case INDEX_op_ld32s_i64:
930         /* movslq */
931         tcg_out_modrm_offset(s, 0x63 | P_REXW, args[0], args[1], args[2]);
932         break;
933     case INDEX_op_ld_i64:
934         /* movq */
935         tcg_out_modrm_offset(s, 0x8b | P_REXW, args[0], args[1], args[2]);
936         break;
937         
938     case INDEX_op_st8_i32:
939     case INDEX_op_st8_i64:
940         /* movb */
941         tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]);
942         break;
943     case INDEX_op_st16_i32:
944     case INDEX_op_st16_i64:
945         /* movw */
946         tcg_out8(s, 0x66);
947         tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
948         break;
949     case INDEX_op_st_i32:
950     case INDEX_op_st32_i64:
951         /* movl */
952         tcg_out_modrm_offset(s, 0x89, args[0], args[1], args[2]);
953         break;
954     case INDEX_op_st_i64:
955         /* movq */
956         tcg_out_modrm_offset(s, 0x89 | P_REXW, args[0], args[1], args[2]);
957         break;
958
959     case INDEX_op_sub_i32:
960         c = ARITH_SUB;
961         goto gen_arith32;
962     case INDEX_op_and_i32:
963         c = ARITH_AND;
964         goto gen_arith32;
965     case INDEX_op_or_i32:
966         c = ARITH_OR;
967         goto gen_arith32;
968     case INDEX_op_xor_i32:
969         c = ARITH_XOR;
970         goto gen_arith32;
971     case INDEX_op_add_i32:
972         c = ARITH_ADD;
973     gen_arith32:
974         if (const_args[2]) {
975             tgen_arithi32(s, c, args[0], args[2]);
976         } else {
977             tcg_out_modrm(s, 0x01 | (c << 3), args[2], args[0]);
978         }
979         break;
980
981     case INDEX_op_sub_i64:
982         c = ARITH_SUB;
983         goto gen_arith64;
984     case INDEX_op_and_i64:
985         c = ARITH_AND;
986         goto gen_arith64;
987     case INDEX_op_or_i64:
988         c = ARITH_OR;
989         goto gen_arith64;
990     case INDEX_op_xor_i64:
991         c = ARITH_XOR;
992         goto gen_arith64;
993     case INDEX_op_add_i64:
994         c = ARITH_ADD;
995     gen_arith64:
996         if (const_args[2]) {
997             tgen_arithi64(s, c, args[0], args[2]);
998         } else {
999             tcg_out_modrm(s, 0x01 | (c << 3) | P_REXW, args[2], args[0]);
1000         }
1001         break;
1002
1003     case INDEX_op_mul_i32:
1004         if (const_args[2]) {
1005             int32_t val;
1006             val = args[2];
1007             if (val == (int8_t)val) {
1008                 tcg_out_modrm(s, 0x6b, args[0], args[0]);
1009                 tcg_out8(s, val);
1010             } else {
1011                 tcg_out_modrm(s, 0x69, args[0], args[0]);
1012                 tcg_out32(s, val);
1013             }
1014         } else {
1015             tcg_out_modrm(s, 0xaf | P_EXT, args[0], args[2]);
1016         }
1017         break;
1018     case INDEX_op_mul_i64:
1019         if (const_args[2]) {
1020             int32_t val;
1021             val = args[2];
1022             if (val == (int8_t)val) {
1023                 tcg_out_modrm(s, 0x6b | P_REXW, args[0], args[0]);
1024                 tcg_out8(s, val);
1025             } else {
1026                 tcg_out_modrm(s, 0x69 | P_REXW, args[0], args[0]);
1027                 tcg_out32(s, val);
1028             }
1029         } else {
1030             tcg_out_modrm(s, 0xaf | P_EXT | P_REXW, args[0], args[2]);
1031         }
1032         break;
1033     case INDEX_op_div2_i32:
1034         tcg_out_modrm(s, 0xf7, 7, args[4]);
1035         break;
1036     case INDEX_op_divu2_i32:
1037         tcg_out_modrm(s, 0xf7, 6, args[4]);
1038         break;
1039     case INDEX_op_div2_i64:
1040         tcg_out_modrm(s, 0xf7 | P_REXW, 7, args[4]);
1041         break;
1042     case INDEX_op_divu2_i64:
1043         tcg_out_modrm(s, 0xf7 | P_REXW, 6, args[4]);
1044         break;
1045
1046     case INDEX_op_shl_i32:
1047         c = SHIFT_SHL;
1048     gen_shift32:
1049         if (const_args[2]) {
1050             if (args[2] == 1) {
1051                 tcg_out_modrm(s, 0xd1, c, args[0]);
1052             } else {
1053                 tcg_out_modrm(s, 0xc1, c, args[0]);
1054                 tcg_out8(s, args[2]);
1055             }
1056         } else {
1057             tcg_out_modrm(s, 0xd3, c, args[0]);
1058         }
1059         break;
1060     case INDEX_op_shr_i32:
1061         c = SHIFT_SHR;
1062         goto gen_shift32;
1063     case INDEX_op_sar_i32:
1064         c = SHIFT_SAR;
1065         goto gen_shift32;
1066     case INDEX_op_rotl_i32:
1067         c = SHIFT_ROL;
1068         goto gen_shift32;
1069     case INDEX_op_rotr_i32:
1070         c = SHIFT_ROR;
1071         goto gen_shift32;
1072
1073     case INDEX_op_shl_i64:
1074         c = SHIFT_SHL;
1075     gen_shift64:
1076         if (const_args[2]) {
1077             if (args[2] == 1) {
1078                 tcg_out_modrm(s, 0xd1 | P_REXW, c, args[0]);
1079             } else {
1080                 tcg_out_modrm(s, 0xc1 | P_REXW, c, args[0]);
1081                 tcg_out8(s, args[2]);
1082             }
1083         } else {
1084             tcg_out_modrm(s, 0xd3 | P_REXW, c, args[0]);
1085         }
1086         break;
1087     case INDEX_op_shr_i64:
1088         c = SHIFT_SHR;
1089         goto gen_shift64;
1090     case INDEX_op_sar_i64:
1091         c = SHIFT_SAR;
1092         goto gen_shift64;
1093     case INDEX_op_rotl_i64:
1094         c = SHIFT_ROL;
1095         goto gen_shift64;
1096     case INDEX_op_rotr_i64:
1097         c = SHIFT_ROR;
1098         goto gen_shift64;
1099
1100     case INDEX_op_brcond_i32:
1101         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], 
1102                        args[3], 0);
1103         break;
1104     case INDEX_op_brcond_i64:
1105         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1], 
1106                        args[3], P_REXW);
1107         break;
1108
1109     case INDEX_op_bswap16_i32:
1110     case INDEX_op_bswap16_i64:
1111         tcg_out8(s, 0x66);
1112         tcg_out_modrm(s, 0xc1, SHIFT_ROL, args[0]);
1113         tcg_out8(s, 8);
1114         break;
1115     case INDEX_op_bswap32_i32:
1116     case INDEX_op_bswap32_i64:
1117         tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT, 0, args[0], 0);
1118         break;
1119     case INDEX_op_bswap64_i64:
1120         tcg_out_opc(s, (0xc8 + (args[0] & 7)) | P_EXT | P_REXW, 0, args[0], 0);
1121         break;
1122
1123     case INDEX_op_neg_i32:
1124         tcg_out_modrm(s, 0xf7, 3, args[0]);
1125         break;
1126     case INDEX_op_neg_i64:
1127         tcg_out_modrm(s, 0xf7 | P_REXW, 3, args[0]);
1128         break;
1129
1130     case INDEX_op_not_i32:
1131         tcg_out_modrm(s, 0xf7, 2, args[0]);
1132         break;
1133     case INDEX_op_not_i64:
1134         tcg_out_modrm(s, 0xf7 | P_REXW, 2, args[0]);
1135         break;
1136
1137     case INDEX_op_ext8s_i32:
1138         tcg_out_modrm(s, 0xbe | P_EXT | P_REXB, args[0], args[1]);
1139         break;
1140     case INDEX_op_ext16s_i32:
1141         tcg_out_modrm(s, 0xbf | P_EXT, args[0], args[1]);
1142         break;
1143     case INDEX_op_ext8s_i64:
1144         tcg_out_modrm(s, 0xbe | P_EXT | P_REXW, args[0], args[1]);
1145         break;
1146     case INDEX_op_ext16s_i64:
1147         tcg_out_modrm(s, 0xbf | P_EXT | P_REXW, args[0], args[1]);
1148         break;
1149     case INDEX_op_ext32s_i64:
1150         tcg_out_modrm(s, 0x63 | P_REXW, args[0], args[1]);
1151         break;
1152
1153     case INDEX_op_qemu_ld8u:
1154         tcg_out_qemu_ld(s, args, 0);
1155         break;
1156     case INDEX_op_qemu_ld8s:
1157         tcg_out_qemu_ld(s, args, 0 | 4);
1158         break;
1159     case INDEX_op_qemu_ld16u:
1160         tcg_out_qemu_ld(s, args, 1);
1161         break;
1162     case INDEX_op_qemu_ld16s:
1163         tcg_out_qemu_ld(s, args, 1 | 4);
1164         break;
1165     case INDEX_op_qemu_ld32u:
1166         tcg_out_qemu_ld(s, args, 2);
1167         break;
1168     case INDEX_op_qemu_ld32s:
1169         tcg_out_qemu_ld(s, args, 2 | 4);
1170         break;
1171     case INDEX_op_qemu_ld64:
1172         tcg_out_qemu_ld(s, args, 3);
1173         break;
1174         
1175     case INDEX_op_qemu_st8:
1176         tcg_out_qemu_st(s, args, 0);
1177         break;
1178     case INDEX_op_qemu_st16:
1179         tcg_out_qemu_st(s, args, 1);
1180         break;
1181     case INDEX_op_qemu_st32:
1182         tcg_out_qemu_st(s, args, 2);
1183         break;
1184     case INDEX_op_qemu_st64:
1185         tcg_out_qemu_st(s, args, 3);
1186         break;
1187
1188     default:
1189         tcg_abort();
1190     }
1191 }
1192
1193 static int tcg_target_callee_save_regs[] = {
1194     TCG_REG_RBP,
1195     TCG_REG_RBX,
1196     TCG_REG_R12,
1197     TCG_REG_R13,
1198     /*    TCG_REG_R14, */ /* currently used for the global env, so no
1199                              need to save */
1200     TCG_REG_R15,
1201 };
1202
1203 static inline void tcg_out_push(TCGContext *s, int reg)
1204 {
1205     tcg_out_opc(s, (0x50 + (reg & 7)), 0, reg, 0);
1206 }
1207
1208 static inline void tcg_out_pop(TCGContext *s, int reg)
1209 {
1210     tcg_out_opc(s, (0x58 + (reg & 7)), 0, reg, 0);
1211 }
1212
1213 /* Generate global QEMU prologue and epilogue code */
1214 void tcg_target_qemu_prologue(TCGContext *s)
1215 {
1216     int i, frame_size, push_size, stack_addend;
1217
1218     /* TB prologue */
1219     /* save all callee saved registers */
1220     for(i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
1221         tcg_out_push(s, tcg_target_callee_save_regs[i]);
1222
1223     }
1224     /* reserve some stack space */
1225     push_size = 8 + ARRAY_SIZE(tcg_target_callee_save_regs) * 8;
1226     frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
1227     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & 
1228         ~(TCG_TARGET_STACK_ALIGN - 1);
1229     stack_addend = frame_size - push_size;
1230     tcg_out_addi(s, TCG_REG_RSP, -stack_addend);
1231
1232     tcg_out_modrm(s, 0xff, 4, TCG_REG_RDI); /* jmp *%rdi */
1233     
1234     /* TB epilogue */
1235     tb_ret_addr = s->code_ptr;
1236     tcg_out_addi(s, TCG_REG_RSP, stack_addend);
1237     for(i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1238         tcg_out_pop(s, tcg_target_callee_save_regs[i]);
1239     }
1240     tcg_out8(s, 0xc3); /* ret */
1241 }
1242
1243 static const TCGTargetOpDef x86_64_op_defs[] = {
1244     { INDEX_op_exit_tb, { } },
1245     { INDEX_op_goto_tb, { } },
1246     { INDEX_op_call, { "ri" } }, /* XXX: might need a specific constant constraint */
1247     { INDEX_op_jmp, { "ri" } }, /* XXX: might need a specific constant constraint */
1248     { INDEX_op_br, { } },
1249
1250     { INDEX_op_mov_i32, { "r", "r" } },
1251     { INDEX_op_movi_i32, { "r" } },
1252     { INDEX_op_ld8u_i32, { "r", "r" } },
1253     { INDEX_op_ld8s_i32, { "r", "r" } },
1254     { INDEX_op_ld16u_i32, { "r", "r" } },
1255     { INDEX_op_ld16s_i32, { "r", "r" } },
1256     { INDEX_op_ld_i32, { "r", "r" } },
1257     { INDEX_op_st8_i32, { "r", "r" } },
1258     { INDEX_op_st16_i32, { "r", "r" } },
1259     { INDEX_op_st_i32, { "r", "r" } },
1260
1261     { INDEX_op_add_i32, { "r", "0", "ri" } },
1262     { INDEX_op_mul_i32, { "r", "0", "ri" } },
1263     { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
1264     { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
1265     { INDEX_op_sub_i32, { "r", "0", "ri" } },
1266     { INDEX_op_and_i32, { "r", "0", "ri" } },
1267     { INDEX_op_or_i32, { "r", "0", "ri" } },
1268     { INDEX_op_xor_i32, { "r", "0", "ri" } },
1269
1270     { INDEX_op_shl_i32, { "r", "0", "ci" } },
1271     { INDEX_op_shr_i32, { "r", "0", "ci" } },
1272     { INDEX_op_sar_i32, { "r", "0", "ci" } },
1273     { INDEX_op_rotl_i32, { "r", "0", "ci" } },
1274     { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1275
1276     { INDEX_op_brcond_i32, { "r", "ri" } },
1277
1278     { INDEX_op_mov_i64, { "r", "r" } },
1279     { INDEX_op_movi_i64, { "r" } },
1280     { INDEX_op_ld8u_i64, { "r", "r" } },
1281     { INDEX_op_ld8s_i64, { "r", "r" } },
1282     { INDEX_op_ld16u_i64, { "r", "r" } },
1283     { INDEX_op_ld16s_i64, { "r", "r" } },
1284     { INDEX_op_ld32u_i64, { "r", "r" } },
1285     { INDEX_op_ld32s_i64, { "r", "r" } },
1286     { INDEX_op_ld_i64, { "r", "r" } },
1287     { INDEX_op_st8_i64, { "r", "r" } },
1288     { INDEX_op_st16_i64, { "r", "r" } },
1289     { INDEX_op_st32_i64, { "r", "r" } },
1290     { INDEX_op_st_i64, { "r", "r" } },
1291
1292     { INDEX_op_add_i64, { "r", "0", "re" } },
1293     { INDEX_op_mul_i64, { "r", "0", "re" } },
1294     { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
1295     { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
1296     { INDEX_op_sub_i64, { "r", "0", "re" } },
1297     { INDEX_op_and_i64, { "r", "0", "reZ" } },
1298     { INDEX_op_or_i64, { "r", "0", "re" } },
1299     { INDEX_op_xor_i64, { "r", "0", "re" } },
1300
1301     { INDEX_op_shl_i64, { "r", "0", "ci" } },
1302     { INDEX_op_shr_i64, { "r", "0", "ci" } },
1303     { INDEX_op_sar_i64, { "r", "0", "ci" } },
1304     { INDEX_op_rotl_i64, { "r", "0", "ci" } },
1305     { INDEX_op_rotr_i64, { "r", "0", "ci" } },
1306
1307     { INDEX_op_brcond_i64, { "r", "re" } },
1308
1309     { INDEX_op_bswap16_i32, { "r", "0" } },
1310     { INDEX_op_bswap16_i64, { "r", "0" } },
1311     { INDEX_op_bswap32_i32, { "r", "0" } },
1312     { INDEX_op_bswap32_i64, { "r", "0" } },
1313     { INDEX_op_bswap64_i64, { "r", "0" } },
1314
1315     { INDEX_op_neg_i32, { "r", "0" } },
1316     { INDEX_op_neg_i64, { "r", "0" } },
1317
1318     { INDEX_op_not_i32, { "r", "0" } },
1319     { INDEX_op_not_i64, { "r", "0" } },
1320
1321     { INDEX_op_ext8s_i32, { "r", "r"} },
1322     { INDEX_op_ext16s_i32, { "r", "r"} },
1323     { INDEX_op_ext8s_i64, { "r", "r"} },
1324     { INDEX_op_ext16s_i64, { "r", "r"} },
1325     { INDEX_op_ext32s_i64, { "r", "r"} },
1326
1327     { INDEX_op_qemu_ld8u, { "r", "L" } },
1328     { INDEX_op_qemu_ld8s, { "r", "L" } },
1329     { INDEX_op_qemu_ld16u, { "r", "L" } },
1330     { INDEX_op_qemu_ld16s, { "r", "L" } },
1331     { INDEX_op_qemu_ld32u, { "r", "L" } },
1332     { INDEX_op_qemu_ld32s, { "r", "L" } },
1333     { INDEX_op_qemu_ld64, { "r", "L" } },
1334
1335     { INDEX_op_qemu_st8, { "L", "L" } },
1336     { INDEX_op_qemu_st16, { "L", "L" } },
1337     { INDEX_op_qemu_st32, { "L", "L" } },
1338     { INDEX_op_qemu_st64, { "L", "L", "L" } },
1339
1340     { -1 },
1341 };
1342
1343 void tcg_target_init(TCGContext *s)
1344 {
1345     /* fail safe */
1346     if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
1347         tcg_abort();
1348
1349     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
1350     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
1351     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1352                      (1 << TCG_REG_RDI) | 
1353                      (1 << TCG_REG_RSI) | 
1354                      (1 << TCG_REG_RDX) |
1355                      (1 << TCG_REG_RCX) |
1356                      (1 << TCG_REG_R8) |
1357                      (1 << TCG_REG_R9) |
1358                      (1 << TCG_REG_RAX) |
1359                      (1 << TCG_REG_R10) |
1360                      (1 << TCG_REG_R11));
1361     
1362     tcg_regset_clear(s->reserved_regs);
1363     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RSP);
1364
1365     tcg_add_target_add_op_defs(x86_64_op_defs);
1366 }