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