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