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