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