a4b339efe9925c43915062cf339492f4cc9632d3
[qemu] / tcg / ppc64 / 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 static uint8_t *tb_ret_addr;
26
27 #define FAST_PATH
28
29 #if TARGET_PHYS_ADDR_BITS == 32
30 #define LD_ADDEND LWZ
31 #else
32 #define LD_ADDEND LD
33 #endif
34
35 #if TARGET_LONG_BITS == 32
36 #define LD_ADDR LWZU
37 #else
38 #define LD_ADDR LDU
39 #endif
40
41 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
42     "r0",
43     "r1",
44     "rp",
45     "r3",
46     "r4",
47     "r5",
48     "r6",
49     "r7",
50     "r8",
51     "r9",
52     "r10",
53     "r11",
54     "r12",
55     "r13",
56     "r14",
57     "r15",
58     "r16",
59     "r17",
60     "r18",
61     "r19",
62     "r20",
63     "r21",
64     "r22",
65     "r23",
66     "r24",
67     "r25",
68     "r26",
69     "r27",
70     "r28",
71     "r29",
72     "r30",
73     "r31"
74 };
75
76 static const int tcg_target_reg_alloc_order[] = {
77     TCG_REG_R14,
78     TCG_REG_R15,
79     TCG_REG_R16,
80     TCG_REG_R17,
81     TCG_REG_R18,
82     TCG_REG_R19,
83     TCG_REG_R20,
84     TCG_REG_R21,
85     TCG_REG_R22,
86     TCG_REG_R23,
87     TCG_REG_R28,
88     TCG_REG_R29,
89     TCG_REG_R30,
90     TCG_REG_R31,
91     TCG_REG_R3,
92     TCG_REG_R4,
93     TCG_REG_R5,
94     TCG_REG_R6,
95     TCG_REG_R7,
96     TCG_REG_R8,
97     TCG_REG_R9,
98     TCG_REG_R10,
99     TCG_REG_R11,
100     TCG_REG_R12,
101     TCG_REG_R13,
102     TCG_REG_R0,
103     TCG_REG_R1,
104     TCG_REG_R2,
105     TCG_REG_R24,
106     TCG_REG_R25,
107     TCG_REG_R26,
108     TCG_REG_R27
109 };
110
111 static const int tcg_target_call_iarg_regs[] = {
112     TCG_REG_R3,
113     TCG_REG_R4,
114     TCG_REG_R5,
115     TCG_REG_R6,
116     TCG_REG_R7,
117     TCG_REG_R8,
118     TCG_REG_R9,
119     TCG_REG_R10
120 };
121
122 static const int tcg_target_call_oarg_regs[2] = {
123     TCG_REG_R3
124 };
125
126 static const int tcg_target_callee_save_regs[] = {
127     TCG_REG_R14,
128     TCG_REG_R15,
129     TCG_REG_R16,
130     TCG_REG_R17,
131     TCG_REG_R18,
132     TCG_REG_R19,
133     TCG_REG_R20,
134     TCG_REG_R21,
135     TCG_REG_R22,
136     TCG_REG_R23,
137     TCG_REG_R28,
138     TCG_REG_R29,
139     TCG_REG_R30,
140     TCG_REG_R31
141 };
142
143 static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
144 {
145     tcg_target_long disp;
146
147     disp = target - (tcg_target_long) pc;
148     if ((disp << 38) >> 38 != disp)
149         tcg_abort ();
150
151     return disp & 0x3fffffc;
152 }
153
154 static void reloc_pc24 (void *pc, tcg_target_long target)
155 {
156     *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
157         | reloc_pc24_val (pc, target);
158 }
159
160 static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
161 {
162     tcg_target_long disp;
163
164     disp = target - (tcg_target_long) pc;
165     if (disp != (int16_t) disp)
166         tcg_abort ();
167
168     return disp & 0xfffc;
169 }
170
171 static void reloc_pc14 (void *pc, tcg_target_long target)
172 {
173     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
174         | reloc_pc14_val (pc, target);
175 }
176
177 static void patch_reloc (uint8_t *code_ptr, int type,
178                          tcg_target_long value, tcg_target_long addend)
179 {
180     value += addend;
181     switch (type) {
182     case R_PPC_REL14:
183         reloc_pc14 (code_ptr, value);
184         break;
185     case R_PPC_REL24:
186         reloc_pc24 (code_ptr, value);
187         break;
188     default:
189         tcg_abort ();
190     }
191 }
192
193 /* maximum number of register used for input function arguments */
194 static int tcg_target_get_call_iarg_regs_count (int flags)
195 {
196     return sizeof (tcg_target_call_iarg_regs) / sizeof (tcg_target_call_iarg_regs[0]);
197 }
198
199 /* parse target specific constraints */
200 static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
201 {
202     const char *ct_str;
203
204     ct_str = *pct_str;
205     switch (ct_str[0]) {
206     case 'A': case 'B': case 'C': case 'D':
207         ct->ct |= TCG_CT_REG;
208         tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
209         break;
210     case 'r':
211         ct->ct |= TCG_CT_REG;
212         tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
213         break;
214     case 'L':                   /* qemu_ld constraint */
215         ct->ct |= TCG_CT_REG;
216         tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
217         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
218         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
219         break;
220     case 'K':                   /* qemu_st[8..32] constraint */
221         ct->ct |= TCG_CT_REG;
222         tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
223         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
224         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
225         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
226 #if TARGET_LONG_BITS == 64
227         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R6);
228 #endif
229         break;
230     case 'M':                   /* qemu_st64 constraint */
231         ct->ct |= TCG_CT_REG;
232         tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
233         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
234         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
235         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
236         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R6);
237         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R7);
238         break;
239     default:
240         return -1;
241     }
242     ct_str++;
243     *pct_str = ct_str;
244     return 0;
245 }
246
247 /* test if a constant matches the constraint */
248 static int tcg_target_const_match (tcg_target_long val,
249                                    const TCGArgConstraint *arg_ct)
250 {
251     int ct;
252
253     ct = arg_ct->ct;
254     if (ct & TCG_CT_CONST)
255         return 1;
256     return 0;
257 }
258
259 #define OPCD(opc) ((opc)<<26)
260 #define XO19(opc) (OPCD(19)|((opc)<<1))
261 #define XO30(opc) (OPCD(30)|((opc)<<2))
262 #define XO31(opc) (OPCD(31)|((opc)<<1))
263 #define XO58(opc) (OPCD(58)|(opc))
264 #define XO62(opc) (OPCD(62)|(opc))
265
266 #define B      OPCD( 18)
267 #define BC     OPCD( 16)
268 #define LBZ    OPCD( 34)
269 #define LHZ    OPCD( 40)
270 #define LHA    OPCD( 42)
271 #define LWZ    OPCD( 32)
272 #define STB    OPCD( 38)
273 #define STH    OPCD( 44)
274 #define STW    OPCD( 36)
275
276 #define STD    XO62(  0)
277 #define STDU   XO62(  1)
278 #define STDX   XO31(149)
279
280 #define LD     XO58(  0)
281 #define LDX    XO31( 21)
282 #define LDU    XO58(  1)
283 #define LWA    XO58( 10)
284 #define LWAX   XO31(341)
285
286 #define ADDI   OPCD( 14)
287 #define ADDIS  OPCD( 15)
288 #define ORI    OPCD( 24)
289 #define ORIS   OPCD( 25)
290 #define XORI   OPCD( 26)
291 #define XORIS  OPCD( 27)
292 #define ANDI   OPCD( 28)
293 #define ANDIS  OPCD( 29)
294 #define MULLI  OPCD(  7)
295 #define CMPLI  OPCD( 10)
296 #define CMPI   OPCD( 11)
297
298 #define LWZU   OPCD( 33)
299 #define STWU   OPCD( 37)
300
301 #define RLWINM OPCD( 21)
302
303 #define RLDICL XO30(  0)
304 #define RLDICR XO30(  1)
305
306 #define BCLR   XO19( 16)
307 #define BCCTR  XO19(528)
308 #define CRAND  XO19(257)
309 #define CRANDC XO19(129)
310 #define CRNAND XO19(225)
311 #define CROR   XO19(449)
312
313 #define EXTSB  XO31(954)
314 #define EXTSH  XO31(922)
315 #define EXTSW  XO31(986)
316 #define ADD    XO31(266)
317 #define ADDE   XO31(138)
318 #define ADDC   XO31( 10)
319 #define AND    XO31( 28)
320 #define SUBF   XO31( 40)
321 #define SUBFC  XO31(  8)
322 #define SUBFE  XO31(136)
323 #define OR     XO31(444)
324 #define XOR    XO31(316)
325 #define MULLW  XO31(235)
326 #define MULHWU XO31( 11)
327 #define DIVW   XO31(491)
328 #define DIVWU  XO31(459)
329 #define CMP    XO31(  0)
330 #define CMPL   XO31( 32)
331 #define LHBRX  XO31(790)
332 #define LWBRX  XO31(534)
333 #define STHBRX XO31(918)
334 #define STWBRX XO31(662)
335 #define MFSPR  XO31(339)
336 #define MTSPR  XO31(467)
337 #define SRAWI  XO31(824)
338 #define NEG    XO31(104)
339
340 #define MULLD  XO31(233)
341 #define MULHD  XO31( 73)
342 #define MULHDU XO31(  9)
343 #define DIVD   XO31(489)
344 #define DIVDU  XO31(457)
345
346 #define LBZX   XO31( 87)
347 #define LHZX   XO31(276)
348 #define LHAX   XO31(343)
349 #define LWZX   XO31( 23)
350 #define STBX   XO31(215)
351 #define STHX   XO31(407)
352 #define STWX   XO31(151)
353
354 #define SPR(a,b) ((((a)<<5)|(b))<<11)
355 #define LR     SPR(8, 0)
356 #define CTR    SPR(9, 0)
357
358 #define SLW    XO31( 24)
359 #define SRW    XO31(536)
360 #define SRAW   XO31(792)
361
362 #define SLD    XO31( 27)
363 #define SRD    XO31(539)
364 #define SRAD   XO31(794)
365
366 #define LMW    OPCD( 46)
367 #define STMW   OPCD( 47)
368
369 #define TW     XO31( 4)
370 #define TRAP   (TW | TO (31))
371
372 #define RT(r) ((r)<<21)
373 #define RS(r) ((r)<<21)
374 #define RA(r) ((r)<<16)
375 #define RB(r) ((r)<<11)
376 #define TO(t) ((t)<<21)
377 #define SH(s) ((s)<<11)
378 #define MB(b) ((b)<<6)
379 #define ME(e) ((e)<<1)
380 #define BO(o) ((o)<<21)
381 #define MB64(b) ((b)<<5)
382
383 #define LK    1
384
385 #define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
386 #define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
387
388 #define BF(n)    ((n)<<23)
389 #define BI(n, c) (((c)+((n)*4))<<16)
390 #define BT(n, c) (((c)+((n)*4))<<21)
391 #define BA(n, c) (((c)+((n)*4))<<16)
392 #define BB(n, c) (((c)+((n)*4))<<11)
393
394 #define BO_COND_TRUE  BO (12)
395 #define BO_COND_FALSE BO ( 4)
396 #define BO_ALWAYS     BO (20)
397
398 enum {
399     CR_LT,
400     CR_GT,
401     CR_EQ,
402     CR_SO
403 };
404
405 static const uint32_t tcg_to_bc[10] = {
406     [TCG_COND_EQ]  = BC | BI (7, CR_EQ) | BO_COND_TRUE,
407     [TCG_COND_NE]  = BC | BI (7, CR_EQ) | BO_COND_FALSE,
408     [TCG_COND_LT]  = BC | BI (7, CR_LT) | BO_COND_TRUE,
409     [TCG_COND_GE]  = BC | BI (7, CR_LT) | BO_COND_FALSE,
410     [TCG_COND_LE]  = BC | BI (7, CR_GT) | BO_COND_FALSE,
411     [TCG_COND_GT]  = BC | BI (7, CR_GT) | BO_COND_TRUE,
412     [TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
413     [TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
414     [TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
415     [TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
416 };
417
418 static void tcg_out_mov (TCGContext *s, int ret, int arg)
419 {
420     tcg_out32 (s, OR | SAB (arg, ret, arg));
421 }
422
423 static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
424 {
425     sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
426     mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
427     tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
428 }
429
430 static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
431 {
432     if (arg == (int16_t) arg)
433         tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
434     else {
435         tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
436         if (arg & 0xffff)
437             tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
438     }
439 }
440
441 static void tcg_out_movi (TCGContext *s, TCGType type,
442                           int ret, tcg_target_long arg)
443 {
444     int32_t arg32 = arg;
445
446     if (type == TCG_TYPE_I32 || arg == arg32) {
447         tcg_out_movi32 (s, ret, arg32);
448     }
449     else {
450         if ((uint64_t) arg >> 32) {
451             tcg_out_movi32 (s, ret, (arg >> 32) + (arg32 < 0));
452             tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
453             if (arg32) {
454                 tcg_out_movi32 (s, 0, arg32);
455                 tcg_out32 (s, ADD | TAB (ret, ret, 0));
456             }
457         }
458         else {
459             tcg_out_movi32 (s, ret, arg32);
460         }
461     }
462 }
463
464 static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
465 {
466     int reg;
467
468     if (const_arg) {
469         reg = 2;
470         tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
471     }
472     else reg = arg;
473
474     tcg_out32 (s, LD | RT (0) | RA (reg));
475     tcg_out32 (s, MTSPR | RA (0) | CTR);
476     tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
477     tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
478     tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
479 }
480
481 static void tcg_out_ldst (TCGContext *s, int ret, int addr,
482                           int offset, int op1, int op2)
483 {
484     if (offset == (int16_t) offset)
485         tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
486     else {
487         tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
488         tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
489     }
490 }
491
492 static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
493 {
494     tcg_target_long disp;
495
496     disp = target - (tcg_target_long) s->code_ptr;
497     if ((disp << 38) >> 38 == disp)
498         tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
499     else {
500         tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
501         tcg_out32 (s, MTSPR | RS (0) | CTR);
502         tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
503     }
504 }
505
506 #if defined (CONFIG_SOFTMMU)
507 extern void __ldb_mmu(void);
508 extern void __ldw_mmu(void);
509 extern void __ldl_mmu(void);
510 extern void __ldq_mmu(void);
511
512 extern void __stb_mmu(void);
513 extern void __stw_mmu(void);
514 extern void __stl_mmu(void);
515 extern void __stq_mmu(void);
516
517 static void *qemu_ld_helpers[4] = {
518     __ldb_mmu,
519     __ldw_mmu,
520     __ldl_mmu,
521     __ldq_mmu,
522 };
523
524 static void *qemu_st_helpers[4] = {
525     __stb_mmu,
526     __stw_mmu,
527     __stl_mmu,
528     __stq_mmu,
529 };
530 #endif
531
532 static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
533                               int addr_reg, int s_bits, int offset)
534 {
535 #if TARGET_LONG_BITS == 32
536     tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
537 #endif
538
539     tcg_out_rld (s, RLDICL, r0, addr_reg,
540                  64 - TARGET_PAGE_BITS,
541                  64 - CPU_TLB_BITS);
542     tcg_out_rld (s, RLDICR, r0, r0,
543                  CPU_TLB_ENTRY_BITS,
544                  63 - CPU_TLB_ENTRY_BITS);
545
546     tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
547     tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
548
549     tcg_out_rld (s, RLDICL, r2, addr_reg,
550                  64 - TARGET_PAGE_BITS,
551                  TARGET_PAGE_BITS - s_bits);
552     tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
553 }
554
555 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
556 {
557     int addr_reg, data_reg, r0, mem_index, s_bits, bswap;
558 #ifdef CONFIG_SOFTMMU
559     int r1, r2;
560     void *label1_ptr, *label2_ptr;
561 #endif
562
563     data_reg = *args++;
564     addr_reg = *args++;
565     mem_index = *args;
566     s_bits = opc & 3;
567
568 #ifdef CONFIG_SOFTMMU
569     r0 = 3;
570     r1 = 4;
571     r2 = 0;
572
573     tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
574                       offsetof (CPUState, tlb_table[mem_index][0].addr_read));
575
576     tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
577
578     label1_ptr = s->code_ptr;
579 #ifdef FAST_PATH
580     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
581 #endif
582
583     /* slow path */
584     tcg_out_mov (s, 3, addr_reg);
585     tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
586
587     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
588
589     switch (opc) {
590     case 0|4:
591         tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
592         break;
593     case 1|4:
594         tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
595         break;
596     case 2|4:
597         tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
598         break;
599     case 0:
600     case 1:
601     case 2:
602     case 3:
603         if (data_reg != 3)
604             tcg_out_mov (s, data_reg, 3);
605         break;
606     }
607     label2_ptr = s->code_ptr;
608     tcg_out32 (s, B);
609
610     /* label1: fast path */
611 #ifdef FAST_PATH
612     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
613 #endif
614
615     /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
616     tcg_out32 (s, (LD_ADDEND
617                    | RT (r0)
618                    | RA (r0)
619                    | (offsetof (CPUTLBEntry, addend)
620                       - offsetof (CPUTLBEntry, addr_read))
621                    ));
622     /* r0 = env->tlb_table[mem_index][index].addend */
623     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
624     /* r0 = env->tlb_table[mem_index][index].addend + addr */
625
626 #else  /* !CONFIG_SOFTMMU */
627     r0 = addr_reg;
628 #endif
629
630 #ifdef TARGET_WORDS_BIGENDIAN
631     bswap = 0;
632 #else
633     bswap = 1;
634 #endif
635     switch (opc) {
636     default:
637     case 0:
638         tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
639         break;
640     case 0|4:
641         tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
642         tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
643         break;
644     case 1:
645         if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
646         else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
647         break;
648     case 1|4:
649         if (bswap) {
650             tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
651             tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
652         }
653         else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
654         break;
655     case 2:
656         if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
657         else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
658         break;
659     case 2|4:
660         if (bswap) {
661             tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
662             tcg_out32 (s, EXTSW | RT (data_reg) | RS (data_reg));
663         }
664         else tcg_out32 (s, LWA | RT (data_reg)| RA (r0));
665         break;
666     case 3:
667         if (bswap) {
668             tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
669             tcg_out32 (s, ADDI | RT (r0) | RA (r0) | 4);
670             tcg_out32 (s, LWBRX | RT (r0) | RB (r0));
671             tcg_out_rld (s, RLDICR, r0, r0, 32, 31);
672             tcg_out32 (s, OR | SAB (r0, data_reg, data_reg));
673         }
674         else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
675         break;
676     }
677
678 #ifdef CONFIG_SOFTMMU
679     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
680 #endif
681 }
682
683 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
684 {
685     int addr_reg, r0, r1, data_reg, mem_index, bswap;
686 #ifdef CONFIG_SOFTMMU
687     int r2;
688     void *label1_ptr, *label2_ptr;
689 #endif
690
691     data_reg = *args++;
692     addr_reg = *args++;
693     mem_index = *args;
694
695 #ifdef CONFIG_SOFTMMU
696     r0 = 3;
697     r1 = 4;
698     r2 = 0;
699
700     tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
701                       offsetof (CPUState, tlb_table[mem_index][0].addr_write));
702
703     tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1));
704
705     label1_ptr = s->code_ptr;
706 #ifdef FAST_PATH
707     tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
708 #endif
709
710     /* slow path */
711     tcg_out_mov (s, 3, addr_reg);
712     tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
713     tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
714
715     tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
716
717     label2_ptr = s->code_ptr;
718     tcg_out32 (s, B);
719
720     /* label1: fast path */
721 #ifdef FAST_PATH
722     reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
723 #endif
724
725     tcg_out32 (s, (LD_ADDEND
726                    | RT (r0)
727                    | RA (r0)
728                    | (offsetof (CPUTLBEntry, addend)
729                       - offsetof (CPUTLBEntry, addr_write))
730                    ));
731     /* r0 = env->tlb_table[mem_index][index].addend */
732     tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
733     /* r0 = env->tlb_table[mem_index][index].addend + addr */
734
735 #else  /* !CONFIG_SOFTMMU */
736     r1 = 4;
737     r0 = addr_reg;
738 #endif
739
740 #ifdef TARGET_WORDS_BIGENDIAN
741     bswap = 0;
742 #else
743     bswap = 1;
744 #endif
745     switch (opc) {
746     case 0:
747         tcg_out32 (s, STB | RS (data_reg) | RA (r0));
748         break;
749     case 1:
750         if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
751         else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
752         break;
753     case 2:
754         if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
755         else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
756         break;
757     case 3:
758         if (bswap) {
759             tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
760             tcg_out32 (s, ADDI | RT (r0) | RA (r0) | 4);
761             tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
762             tcg_out32 (s, STWBRX | RS (0) | RA (0) | RB (r0));
763         }
764         else tcg_out32 (s, STD | RS (data_reg) | RA (r0));
765         break;
766     }
767
768 #ifdef CONFIG_SOFTMMU
769     reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
770 #endif
771 }
772
773 void tcg_target_qemu_prologue (TCGContext *s)
774 {
775     int i, frame_size;
776     uint64_t addr;
777
778     frame_size = 0
779         + 8                     /* back chain */
780         + 8                     /* CR */
781         + 8                     /* LR */
782         + 8                     /* compiler doubleword */
783         + 8                     /* link editor doubleword */
784         + 8                     /* TOC save area */
785         + TCG_STATIC_CALL_ARGS_SIZE
786         + ARRAY_SIZE (tcg_target_callee_save_regs) * 8
787         ;
788     frame_size = (frame_size + 15) & ~15;
789
790     /* First emit adhoc function descriptor */
791     addr = (uint64_t) s->code_ptr + 24;
792     tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
793     s->code_ptr += 16;          /* skip TOC and environment pointer */
794
795     /* Prologue */
796     tcg_out32 (s, MFSPR | RT (0) | LR);
797     tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
798     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
799         tcg_out32 (s, (STD
800                        | RS (tcg_target_callee_save_regs[i])
801                        | RA (1)
802                        | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
803                        )
804             );
805     tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 20));
806
807     tcg_out32 (s, MTSPR | RS (3) | CTR);
808     tcg_out32 (s, BCCTR | BO_ALWAYS);
809
810     /* Epilogue */
811     tb_ret_addr = s->code_ptr;
812
813     for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
814         tcg_out32 (s, (LD
815                        | RT (tcg_target_callee_save_regs[i])
816                        | RA (1)
817                        | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
818                        )
819             );
820     tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 20));
821     tcg_out32 (s, MTSPR | RS (0) | LR);
822     tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
823     tcg_out32 (s, BCLR | BO_ALWAYS);
824 }
825
826 static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
827                         tcg_target_long arg2)
828 {
829     if (type == TCG_TYPE_I32)
830         tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
831     else
832         tcg_out_ldst (s, ret, arg1, arg2, LD, LDX);
833 }
834
835 static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
836                         tcg_target_long arg2)
837 {
838     if (type == TCG_TYPE_I32)
839         tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
840     else
841         tcg_out_ldst (s, arg, arg1, arg2, STD, STDX);
842 }
843
844 static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
845 {
846     if (!si && rt == ra)
847         return;
848
849     if (si == (int16_t) si)
850         tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
851     else {
852         uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
853         tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
854         tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
855     }
856 }
857
858 static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
859 {
860     tcg_out_movi (s, TCG_TYPE_I64, 0, si);
861     tcg_out32 (s, ADD | RT (rt) | RA (ra));
862 }
863
864 static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val)
865 {
866     ppc_addi64 (s, reg, reg, val);
867 }
868
869 static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
870                          int const_arg2, int cr)
871 {
872     int imm;
873     uint32_t op;
874
875     switch (cond) {
876     case TCG_COND_EQ:
877     case TCG_COND_NE:
878         if (const_arg2) {
879             if ((int16_t) arg2 == arg2) {
880                 op = CMPI;
881                 imm = 1;
882                 break;
883             }
884             else if ((uint16_t) arg2 == arg2) {
885                 op = CMPLI;
886                 imm = 1;
887                 break;
888             }
889         }
890         op = CMPL;
891         imm = 0;
892         break;
893
894     case TCG_COND_LT:
895     case TCG_COND_GE:
896     case TCG_COND_LE:
897     case TCG_COND_GT:
898         if (const_arg2) {
899             if ((int16_t) arg2 == arg2) {
900                 op = CMPI;
901                 imm = 1;
902                 break;
903             }
904         }
905         op = CMP;
906         imm = 0;
907         break;
908
909     case TCG_COND_LTU:
910     case TCG_COND_GEU:
911     case TCG_COND_LEU:
912     case TCG_COND_GTU:
913         if (const_arg2) {
914             if ((uint16_t) arg2 == arg2) {
915                 op = CMPLI;
916                 imm = 1;
917                 break;
918             }
919         }
920         op = CMPL;
921         imm = 0;
922         break;
923
924     default:
925         tcg_abort ();
926     }
927     op |= BF (cr);
928
929     if (imm)
930         tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
931     else {
932         if (const_arg2) {
933             tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
934             tcg_out32 (s, op | RA (arg1) | RB (0));
935         }
936         else
937             tcg_out32 (s, op | RA (arg1) | RB (arg2));
938     }
939
940 }
941
942 static void tcg_out_bc (TCGContext *s, int bc, int label_index)
943 {
944     TCGLabel *l = &s->labels[label_index];
945
946     if (l->has_value)
947         tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
948     else {
949         uint16_t val = *(uint16_t *) &s->code_ptr[2];
950
951         /* Thanks to Andrzej Zaborowski */
952         tcg_out32 (s, bc | (val & 0xfffc));
953         tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
954     }
955 }
956
957 static void tcg_out_brcond (TCGContext *s, int cond,
958                             TCGArg arg1, TCGArg arg2, int const_arg2,
959                             int label_index)
960 {
961     tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7);
962     tcg_out_bc (s, tcg_to_bc[cond], label_index);
963 }
964
965 void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
966 {
967     TCGContext s;
968     unsigned long patch_size;
969
970     s.code_ptr = (uint8_t *) jmp_addr;
971     tcg_out_b (&s, 0, addr);
972     patch_size = s.code_ptr - (uint8_t *) jmp_addr;
973     flush_icache_range (jmp_addr, jmp_addr + patch_size);
974 }
975
976 static void tcg_out_op (TCGContext *s, int opc, const TCGArg *args,
977                         const int *const_args)
978 {
979     int c;
980
981     switch (opc) {
982     case INDEX_op_exit_tb:
983         tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
984         tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
985         break;
986     case INDEX_op_goto_tb:
987         if (s->tb_jmp_offset) {
988             /* direct jump method */
989
990             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
991             s->code_ptr += 32;
992         }
993         else {
994             tcg_abort ();
995         }
996         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
997         break;
998     case INDEX_op_br:
999         {
1000             TCGLabel *l = &s->labels[args[0]];
1001
1002             if (l->has_value) {
1003                 tcg_out_b (s, 0, l->u.value);
1004             }
1005             else {
1006                 uint32_t val = *(uint32_t *) s->code_ptr;
1007
1008                 /* Thanks to Andrzej Zaborowski */
1009                 tcg_out32 (s, B | (val & 0x3fffffc));
1010                 tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1011             }
1012         }
1013         break;
1014     case INDEX_op_call:
1015         tcg_out_call (s, args[0], const_args[0]);
1016         break;
1017     case INDEX_op_jmp:
1018         if (const_args[0]) {
1019             tcg_out_b (s, 0, args[0]);
1020         }
1021         else {
1022             tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
1023             tcg_out32 (s, BCCTR | BO_ALWAYS);
1024         }
1025         break;
1026     case INDEX_op_movi_i32:
1027         tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
1028         break;
1029     case INDEX_op_movi_i64:
1030         tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
1031         break;
1032     case INDEX_op_ld8u_i32:
1033     case INDEX_op_ld8u_i64:
1034         tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1035         break;
1036     case INDEX_op_ld8s_i32:
1037     case INDEX_op_ld8s_i64:
1038         tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1039         tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1040         break;
1041     case INDEX_op_ld16u_i32:
1042     case INDEX_op_ld16u_i64:
1043         tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1044         break;
1045     case INDEX_op_ld16s_i32:
1046     case INDEX_op_ld16s_i64:
1047         tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1048         break;
1049     case INDEX_op_ld_i32:
1050     case INDEX_op_ld32u_i64:
1051         tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1052         break;
1053     case INDEX_op_ld32s_i64:
1054         tcg_out_ldst (s, args[0], args[1], args[2], LWA, LWAX);
1055         break;
1056     case INDEX_op_ld_i64:
1057         tcg_out_ldst (s, args[0], args[1], args[2], LD, LDX);
1058         break;
1059     case INDEX_op_st8_i32:
1060     case INDEX_op_st8_i64:
1061         tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1062         break;
1063     case INDEX_op_st16_i32:
1064     case INDEX_op_st16_i64:
1065         tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1066         break;
1067     case INDEX_op_st_i32:
1068     case INDEX_op_st32_i64:
1069         tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1070         break;
1071     case INDEX_op_st_i64:
1072         tcg_out_ldst (s, args[0], args[1], args[2], STD, STDX);
1073         break;
1074
1075     case INDEX_op_add_i32:
1076         if (const_args[2])
1077             ppc_addi32 (s, args[0], args[1], args[2]);
1078         else
1079             tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1080         break;
1081     case INDEX_op_sub_i32:
1082         if (const_args[2])
1083             ppc_addi32 (s, args[0], args[1], -args[2]);
1084         else
1085             tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1086         break;
1087
1088     case INDEX_op_and_i32:
1089         if (const_args[2]) {
1090             if (!args[2])
1091                 tcg_out_movi (s, TCG_TYPE_I32, args[0], 0);
1092             else {
1093                 if ((args[2] & 0xffff) == args[2])
1094                     tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
1095                 else if ((args[2] & 0xffff0000) == args[2])
1096                     tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1097                                | ((args[2] >> 16) & 0xffff));
1098                 else if (args[2] == 0xffffffff) {
1099                     if (args[0] != args[1])
1100                         tcg_out_mov (s, args[0], args[1]);
1101                 }
1102                 else {
1103                     tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1104                     tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1105                 }
1106             }
1107         }
1108         else
1109             tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1110         break;
1111     case INDEX_op_or_i32:
1112         if (const_args[2]) {
1113             if (args[2]) {
1114                 if (args[2] & 0xffff) {
1115                     tcg_out32 (s, ORI | RS (args[1])  | RA (args[0])
1116                                | (args[2] & 0xffff));
1117                     if (args[2] >> 16)
1118                         tcg_out32 (s, ORIS | RS (args[0])  | RA (args[0])
1119                                    | ((args[2] >> 16) & 0xffff));
1120                 }
1121                 else {
1122                     tcg_out32 (s, ORIS | RS (args[1])  | RA (args[0])
1123                                | ((args[2] >> 16) & 0xffff));
1124                 }
1125             }
1126             else {
1127                 if (args[0] != args[1])
1128                     tcg_out_mov (s, args[0], args[1]);
1129             }
1130         }
1131         else
1132             tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1133         break;
1134     case INDEX_op_xor_i32:
1135         if (const_args[2]) {
1136             if (args[2]) {
1137                 if ((args[2] & 0xffff) == args[2])
1138                     tcg_out32 (s, XORI | RS (args[1])  | RA (args[0])
1139                                | (args[2] & 0xffff));
1140                 else if ((args[2] & 0xffff0000) == args[2])
1141                     tcg_out32 (s, XORIS | RS (args[1])  | RA (args[0])
1142                                | ((args[2] >> 16) & 0xffff));
1143                 else {
1144                     tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1145                     tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1146                 }
1147             }
1148             else {
1149                 if (args[0] != args[1])
1150                     tcg_out_mov (s, args[0], args[1]);
1151             }
1152         }
1153         else
1154             tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1155         break;
1156
1157     case INDEX_op_mul_i32:
1158         if (const_args[2]) {
1159             if (args[2] == (int16_t) args[2])
1160                 tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1161                            | (args[2] & 0xffff));
1162             else {
1163                 tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1164                 tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1165             }
1166         }
1167         else
1168             tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1169         break;
1170
1171     case INDEX_op_div_i32:
1172         tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1173         break;
1174
1175     case INDEX_op_divu_i32:
1176         tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1177         break;
1178
1179     case INDEX_op_rem_i32:
1180         tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1181         tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1182         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1183         break;
1184
1185     case INDEX_op_remu_i32:
1186         tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1187         tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1188         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1189         break;
1190
1191     case INDEX_op_shl_i32:
1192         if (const_args[2]) {
1193             if (args[2])
1194                 tcg_out32 (s, (RLWINM
1195                                | RA (args[0])
1196                                | RS (args[1])
1197                                | SH (args[2])
1198                                | MB (0)
1199                                | ME (31 - args[2])
1200                                )
1201                     );
1202             else
1203                 tcg_out_mov (s, args[0], args[1]);
1204         }
1205         else
1206             tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1207         break;
1208     case INDEX_op_shr_i32:
1209         if (const_args[2]) {
1210             if (args[2])
1211                 tcg_out32 (s, (RLWINM
1212                                | RA (args[0])
1213                                | RS (args[1])
1214                                | SH (32 - args[2])
1215                                | MB (args[2])
1216                                | ME (31)
1217                                )
1218                     );
1219             else
1220                 tcg_out_mov (s, args[0], args[1]);
1221         }
1222         else
1223             tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1224         break;
1225     case INDEX_op_sar_i32:
1226         if (const_args[2])
1227             tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1228         else
1229             tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1230         break;
1231
1232     case INDEX_op_brcond_i32:
1233     case INDEX_op_brcond_i64:
1234         tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3]);
1235         break;
1236
1237     case INDEX_op_neg_i32:
1238     case INDEX_op_neg_i64:
1239         tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1240         break;
1241
1242     case INDEX_op_add_i64:
1243         tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1244         break;
1245     case INDEX_op_sub_i64:
1246         tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1247         break;
1248
1249     case INDEX_op_and_i64:
1250         tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1251         break;
1252     case INDEX_op_or_i64:
1253         tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1254         break;
1255     case INDEX_op_xor_i64:
1256         tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1257         break;
1258
1259     case INDEX_op_shl_i64:
1260         tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
1261         break;
1262     case INDEX_op_shr_i64:
1263         tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
1264         break;
1265     case INDEX_op_sar_i64:
1266         tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
1267         break;
1268
1269     case INDEX_op_mul_i64:
1270         tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
1271         break;
1272     case INDEX_op_div_i64:
1273         tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
1274         break;
1275     case INDEX_op_divu_i64:
1276         tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
1277         break;
1278     case INDEX_op_rem_i64:
1279         tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
1280         tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1281         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1282         break;
1283     case INDEX_op_remu_i64:
1284         tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
1285         tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1286         tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1287         break;
1288
1289     case INDEX_op_qemu_ld8u:
1290         tcg_out_qemu_ld (s, args, 0);
1291         break;
1292     case INDEX_op_qemu_ld8s:
1293         tcg_out_qemu_ld (s, args, 0 | 4);
1294         break;
1295     case INDEX_op_qemu_ld16u:
1296         tcg_out_qemu_ld (s, args, 1);
1297         break;
1298     case INDEX_op_qemu_ld16s:
1299         tcg_out_qemu_ld (s, args, 1 | 4);
1300         break;
1301     case INDEX_op_qemu_ld32u:
1302         tcg_out_qemu_ld (s, args, 2);
1303         break;
1304     case INDEX_op_qemu_ld32s:
1305         tcg_out_qemu_ld (s, args, 2 | 4);
1306         break;
1307     case INDEX_op_qemu_ld64:
1308         tcg_out_qemu_ld (s, args, 3);
1309         break;
1310     case INDEX_op_qemu_st8:
1311         tcg_out_qemu_st (s, args, 0);
1312         break;
1313     case INDEX_op_qemu_st16:
1314         tcg_out_qemu_st (s, args, 1);
1315         break;
1316     case INDEX_op_qemu_st32:
1317         tcg_out_qemu_st (s, args, 2);
1318         break;
1319     case INDEX_op_qemu_st64:
1320         tcg_out_qemu_st (s, args, 3);
1321         break;
1322
1323     case INDEX_op_ext8s_i32:
1324     case INDEX_op_ext8s_i64:
1325         c = EXTSB;
1326         goto gen_ext;
1327     case INDEX_op_ext16s_i32:
1328     case INDEX_op_ext16s_i64:
1329         c = EXTSH;
1330         goto gen_ext;
1331     case INDEX_op_ext32s_i64:
1332         c = EXTSW;
1333         goto gen_ext;
1334     gen_ext:
1335         tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
1336         break;
1337
1338     default:
1339         tcg_dump_ops (s, stderr);
1340         tcg_abort ();
1341     }
1342 }
1343
1344 static const TCGTargetOpDef ppc_op_defs[] = {
1345     { INDEX_op_exit_tb, { } },
1346     { INDEX_op_goto_tb, { } },
1347     { INDEX_op_call, { "ri" } },
1348     { INDEX_op_jmp, { "ri" } },
1349     { INDEX_op_br, { } },
1350
1351     { INDEX_op_mov_i32, { "r", "r" } },
1352     { INDEX_op_mov_i64, { "r", "r" } },
1353     { INDEX_op_movi_i32, { "r" } },
1354     { INDEX_op_movi_i64, { "r" } },
1355
1356     { INDEX_op_ld8u_i32, { "r", "r" } },
1357     { INDEX_op_ld8s_i32, { "r", "r" } },
1358     { INDEX_op_ld16u_i32, { "r", "r" } },
1359     { INDEX_op_ld16s_i32, { "r", "r" } },
1360     { INDEX_op_ld_i32, { "r", "r" } },
1361     { INDEX_op_ld_i64, { "r", "r" } },
1362     { INDEX_op_st8_i32, { "r", "r" } },
1363     { INDEX_op_st8_i64, { "r", "r" } },
1364     { INDEX_op_st16_i32, { "r", "r" } },
1365     { INDEX_op_st16_i64, { "r", "r" } },
1366     { INDEX_op_st_i32, { "r", "r" } },
1367     { INDEX_op_st_i64, { "r", "r" } },
1368     { INDEX_op_st32_i64, { "r", "r" } },
1369
1370     { INDEX_op_ld8u_i64, { "r", "r" } },
1371     { INDEX_op_ld8s_i64, { "r", "r" } },
1372     { INDEX_op_ld16u_i64, { "r", "r" } },
1373     { INDEX_op_ld16s_i64, { "r", "r" } },
1374     { INDEX_op_ld32u_i64, { "r", "r" } },
1375     { INDEX_op_ld32s_i64, { "r", "r" } },
1376     { INDEX_op_ld_i64, { "r", "r" } },
1377
1378     { INDEX_op_add_i32, { "r", "r", "ri" } },
1379     { INDEX_op_mul_i32, { "r", "r", "ri" } },
1380     { INDEX_op_div_i32, { "r", "r", "r" } },
1381     { INDEX_op_divu_i32, { "r", "r", "r" } },
1382     { INDEX_op_rem_i32, { "r", "r", "r" } },
1383     { INDEX_op_remu_i32, { "r", "r", "r" } },
1384     { INDEX_op_sub_i32, { "r", "r", "ri" } },
1385     { INDEX_op_and_i32, { "r", "r", "ri" } },
1386     { INDEX_op_or_i32, { "r", "r", "ri" } },
1387     { INDEX_op_xor_i32, { "r", "r", "ri" } },
1388
1389     { INDEX_op_shl_i32, { "r", "r", "ri" } },
1390     { INDEX_op_shr_i32, { "r", "r", "ri" } },
1391     { INDEX_op_sar_i32, { "r", "r", "ri" } },
1392
1393     { INDEX_op_brcond_i32, { "r", "ri" } },
1394     { INDEX_op_brcond_i64, { "r", "ri" } },
1395
1396     { INDEX_op_neg_i32, { "r", "r" } },
1397
1398     { INDEX_op_add_i64, { "r", "r", "r" } },
1399     { INDEX_op_sub_i64, { "r", "r", "r" } },
1400     { INDEX_op_and_i64, { "r", "r", "r" } },
1401     { INDEX_op_or_i64, { "r", "r", "r" } },
1402     { INDEX_op_xor_i64, { "r", "r", "r" } },
1403
1404     { INDEX_op_shl_i64, { "r", "r", "r" } },
1405     { INDEX_op_shr_i64, { "r", "r", "r" } },
1406     { INDEX_op_sar_i64, { "r", "r", "r" } },
1407
1408     { INDEX_op_mul_i64, { "r", "r", "r" } },
1409     { INDEX_op_div_i64, { "r", "r", "r" } },
1410     { INDEX_op_divu_i64, { "r", "r", "r" } },
1411     { INDEX_op_rem_i64, { "r", "r", "r" } },
1412     { INDEX_op_remu_i64, { "r", "r", "r" } },
1413
1414     { INDEX_op_neg_i64, { "r", "r" } },
1415
1416     { INDEX_op_qemu_ld8u, { "r", "L" } },
1417     { INDEX_op_qemu_ld8s, { "r", "L" } },
1418     { INDEX_op_qemu_ld16u, { "r", "L" } },
1419     { INDEX_op_qemu_ld16s, { "r", "L" } },
1420     { INDEX_op_qemu_ld32u, { "r", "L" } },
1421     { INDEX_op_qemu_ld32s, { "r", "L" } },
1422     { INDEX_op_qemu_ld64, { "r", "r", "L" } },
1423
1424     { INDEX_op_qemu_st8, { "K", "K" } },
1425     { INDEX_op_qemu_st16, { "K", "K" } },
1426     { INDEX_op_qemu_st32, { "K", "K" } },
1427     { INDEX_op_qemu_st64, { "M", "M", "M" } },
1428
1429     { INDEX_op_ext8s_i32, { "r", "r" } },
1430     { INDEX_op_ext16s_i32, { "r", "r" } },
1431     { INDEX_op_ext8s_i64, { "r", "r" } },
1432     { INDEX_op_ext16s_i64, { "r", "r" } },
1433     { INDEX_op_ext32s_i64, { "r", "r" } },
1434
1435     { -1 },
1436 };
1437
1438 void tcg_target_init (TCGContext *s)
1439 {
1440     tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1441     tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1442     tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
1443                      (1 << TCG_REG_R0) |
1444                      (1 << TCG_REG_R3) |
1445                      (1 << TCG_REG_R4) |
1446                      (1 << TCG_REG_R5) |
1447                      (1 << TCG_REG_R6) |
1448                      (1 << TCG_REG_R7) |
1449                      (1 << TCG_REG_R8) |
1450                      (1 << TCG_REG_R9) |
1451                      (1 << TCG_REG_R10) |
1452                      (1 << TCG_REG_R11) |
1453                      (1 << TCG_REG_R12)
1454         );
1455
1456     tcg_regset_clear (s->reserved_regs);
1457     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
1458     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
1459     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1460     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
1461
1462     tcg_add_target_add_op_defs (ppc_op_defs);
1463 }