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