]> Git Repo - qemu.git/blob - tcg/ppc64/tcg-target.c
Merge remote-tracking branch 'remotes/kraxel/tags/pull-sdl-2' into staging
[qemu.git] / 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 #include "tcg-be-ldst.h"
26
27 #define TCG_CT_CONST_S16  0x100
28 #define TCG_CT_CONST_U16  0x200
29 #define TCG_CT_CONST_S32  0x400
30 #define TCG_CT_CONST_U32  0x800
31 #define TCG_CT_CONST_ZERO 0x1000
32 #define TCG_CT_CONST_MONE 0x2000
33
34 static uint8_t *tb_ret_addr;
35
36 #if TARGET_LONG_BITS == 32
37 #define LD_ADDR LWZ
38 #define CMP_L 0
39 #else
40 #define LD_ADDR LD
41 #define CMP_L (1<<21)
42 #endif
43
44 #ifndef GUEST_BASE
45 #define GUEST_BASE 0
46 #endif
47
48 #include "elf.h"
49 static bool have_isa_2_06;
50 #define HAVE_ISA_2_06  have_isa_2_06
51 #define HAVE_ISEL      have_isa_2_06
52
53 #ifdef CONFIG_USE_GUEST_BASE
54 #define TCG_GUEST_BASE_REG 30
55 #else
56 #define TCG_GUEST_BASE_REG 0
57 #endif
58
59 #ifndef NDEBUG
60 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
61     "r0",
62     "r1",
63     "r2",
64     "r3",
65     "r4",
66     "r5",
67     "r6",
68     "r7",
69     "r8",
70     "r9",
71     "r10",
72     "r11",
73     "r12",
74     "r13",
75     "r14",
76     "r15",
77     "r16",
78     "r17",
79     "r18",
80     "r19",
81     "r20",
82     "r21",
83     "r22",
84     "r23",
85     "r24",
86     "r25",
87     "r26",
88     "r27",
89     "r28",
90     "r29",
91     "r30",
92     "r31"
93 };
94 #endif
95
96 static const int tcg_target_reg_alloc_order[] = {
97     TCG_REG_R14,  /* call saved registers */
98     TCG_REG_R15,
99     TCG_REG_R16,
100     TCG_REG_R17,
101     TCG_REG_R18,
102     TCG_REG_R19,
103     TCG_REG_R20,
104     TCG_REG_R21,
105     TCG_REG_R22,
106     TCG_REG_R23,
107     TCG_REG_R24,
108     TCG_REG_R25,
109     TCG_REG_R26,
110     TCG_REG_R27,
111     TCG_REG_R28,
112     TCG_REG_R29,
113     TCG_REG_R30,
114     TCG_REG_R31,
115     TCG_REG_R12,  /* call clobbered, non-arguments */
116     TCG_REG_R11,
117     TCG_REG_R10,  /* call clobbered, arguments */
118     TCG_REG_R9,
119     TCG_REG_R8,
120     TCG_REG_R7,
121     TCG_REG_R6,
122     TCG_REG_R5,
123     TCG_REG_R4,
124     TCG_REG_R3,
125 };
126
127 static const int tcg_target_call_iarg_regs[] = {
128     TCG_REG_R3,
129     TCG_REG_R4,
130     TCG_REG_R5,
131     TCG_REG_R6,
132     TCG_REG_R7,
133     TCG_REG_R8,
134     TCG_REG_R9,
135     TCG_REG_R10
136 };
137
138 static const int tcg_target_call_oarg_regs[] = {
139     TCG_REG_R3
140 };
141
142 static const int tcg_target_callee_save_regs[] = {
143 #ifdef __APPLE__
144     TCG_REG_R11,
145 #endif
146     TCG_REG_R14,
147     TCG_REG_R15,
148     TCG_REG_R16,
149     TCG_REG_R17,
150     TCG_REG_R18,
151     TCG_REG_R19,
152     TCG_REG_R20,
153     TCG_REG_R21,
154     TCG_REG_R22,
155     TCG_REG_R23,
156     TCG_REG_R24,
157     TCG_REG_R25,
158     TCG_REG_R26,
159     TCG_REG_R27, /* currently used for the global env */
160     TCG_REG_R28,
161     TCG_REG_R29,
162     TCG_REG_R30,
163     TCG_REG_R31
164 };
165
166 static inline bool in_range_b(tcg_target_long target)
167 {
168     return target == sextract64(target, 0, 26);
169 }
170
171 static uint32_t reloc_pc24_val(void *pc, tcg_target_long target)
172 {
173     tcg_target_long disp;
174
175     disp = target - (tcg_target_long)pc;
176     assert(in_range_b(disp));
177
178     return disp & 0x3fffffc;
179 }
180
181 static void reloc_pc24(void *pc, tcg_target_long target)
182 {
183     *(uint32_t *)pc = (*(uint32_t *)pc & ~0x3fffffc)
184         | reloc_pc24_val(pc, target);
185 }
186
187 static uint16_t reloc_pc14_val(void *pc, tcg_target_long target)
188 {
189     tcg_target_long disp;
190
191     disp = target - (tcg_target_long)pc;
192     if (disp != (int16_t) disp) {
193         tcg_abort();
194     }
195
196     return disp & 0xfffc;
197 }
198
199 static void reloc_pc14(void *pc, tcg_target_long target)
200 {
201     *(uint32_t *)pc = (*(uint32_t *)pc & ~0xfffc) | reloc_pc14_val(pc, target);
202 }
203
204 static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
205 {
206     unsigned retrans = *(uint32_t *)s->code_ptr & 0x3fffffc;
207     tcg_out32(s, insn | retrans);
208 }
209
210 static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
211 {
212     unsigned retrans = *(uint32_t *)s->code_ptr & 0xfffc;
213     tcg_out32(s, insn | retrans);
214 }
215
216 static void patch_reloc(uint8_t *code_ptr, int type,
217                         intptr_t value, intptr_t addend)
218 {
219     value += addend;
220     switch (type) {
221     case R_PPC_REL14:
222         reloc_pc14(code_ptr, value);
223         break;
224     case R_PPC_REL24:
225         reloc_pc24(code_ptr, value);
226         break;
227     default:
228         tcg_abort();
229     }
230 }
231
232 /* parse target specific constraints */
233 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
234 {
235     const char *ct_str;
236
237     ct_str = *pct_str;
238     switch (ct_str[0]) {
239     case 'A': case 'B': case 'C': case 'D':
240         ct->ct |= TCG_CT_REG;
241         tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
242         break;
243     case 'r':
244         ct->ct |= TCG_CT_REG;
245         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
246         break;
247     case 'L':                   /* qemu_ld constraint */
248         ct->ct |= TCG_CT_REG;
249         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
250         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
251 #ifdef CONFIG_SOFTMMU
252         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
253         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
254 #endif
255         break;
256     case 'S':                   /* qemu_st constraint */
257         ct->ct |= TCG_CT_REG;
258         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
259         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
260 #ifdef CONFIG_SOFTMMU
261         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
262         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
263         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
264 #endif
265         break;
266     case 'I':
267         ct->ct |= TCG_CT_CONST_S16;
268         break;
269     case 'J':
270         ct->ct |= TCG_CT_CONST_U16;
271         break;
272     case 'M':
273         ct->ct |= TCG_CT_CONST_MONE;
274         break;
275     case 'T':
276         ct->ct |= TCG_CT_CONST_S32;
277         break;
278     case 'U':
279         ct->ct |= TCG_CT_CONST_U32;
280         break;
281     case 'Z':
282         ct->ct |= TCG_CT_CONST_ZERO;
283         break;
284     default:
285         return -1;
286     }
287     ct_str++;
288     *pct_str = ct_str;
289     return 0;
290 }
291
292 /* test if a constant matches the constraint */
293 static int tcg_target_const_match(tcg_target_long val, TCGType type,
294                                   const TCGArgConstraint *arg_ct)
295 {
296     int ct = arg_ct->ct;
297     if (ct & TCG_CT_CONST) {
298         return 1;
299     }
300
301     /* The only 32-bit constraint we use aside from
302        TCG_CT_CONST is TCG_CT_CONST_S16.  */
303     if (type == TCG_TYPE_I32) {
304         val = (int32_t)val;
305     }
306
307     if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
308         return 1;
309     } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
310         return 1;
311     } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
312         return 1;
313     } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
314         return 1;
315     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
316         return 1;
317     } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
318         return 1;
319     }
320     return 0;
321 }
322
323 #define OPCD(opc) ((opc)<<26)
324 #define XO19(opc) (OPCD(19)|((opc)<<1))
325 #define MD30(opc) (OPCD(30)|((opc)<<2))
326 #define MDS30(opc) (OPCD(30)|((opc)<<1))
327 #define XO31(opc) (OPCD(31)|((opc)<<1))
328 #define XO58(opc) (OPCD(58)|(opc))
329 #define XO62(opc) (OPCD(62)|(opc))
330
331 #define B      OPCD( 18)
332 #define BC     OPCD( 16)
333 #define LBZ    OPCD( 34)
334 #define LHZ    OPCD( 40)
335 #define LHA    OPCD( 42)
336 #define LWZ    OPCD( 32)
337 #define STB    OPCD( 38)
338 #define STH    OPCD( 44)
339 #define STW    OPCD( 36)
340
341 #define STD    XO62(  0)
342 #define STDU   XO62(  1)
343 #define STDX   XO31(149)
344
345 #define LD     XO58(  0)
346 #define LDX    XO31( 21)
347 #define LDU    XO58(  1)
348 #define LWA    XO58(  2)
349 #define LWAX   XO31(341)
350
351 #define ADDIC  OPCD( 12)
352 #define ADDI   OPCD( 14)
353 #define ADDIS  OPCD( 15)
354 #define ORI    OPCD( 24)
355 #define ORIS   OPCD( 25)
356 #define XORI   OPCD( 26)
357 #define XORIS  OPCD( 27)
358 #define ANDI   OPCD( 28)
359 #define ANDIS  OPCD( 29)
360 #define MULLI  OPCD(  7)
361 #define CMPLI  OPCD( 10)
362 #define CMPI   OPCD( 11)
363 #define SUBFIC OPCD( 8)
364
365 #define LWZU   OPCD( 33)
366 #define STWU   OPCD( 37)
367
368 #define RLWIMI OPCD( 20)
369 #define RLWINM OPCD( 21)
370 #define RLWNM  OPCD( 23)
371
372 #define RLDICL MD30(  0)
373 #define RLDICR MD30(  1)
374 #define RLDIMI MD30(  3)
375 #define RLDCL  MDS30( 8)
376
377 #define BCLR   XO19( 16)
378 #define BCCTR  XO19(528)
379 #define CRAND  XO19(257)
380 #define CRANDC XO19(129)
381 #define CRNAND XO19(225)
382 #define CROR   XO19(449)
383 #define CRNOR  XO19( 33)
384
385 #define EXTSB  XO31(954)
386 #define EXTSH  XO31(922)
387 #define EXTSW  XO31(986)
388 #define ADD    XO31(266)
389 #define ADDE   XO31(138)
390 #define ADDME  XO31(234)
391 #define ADDZE  XO31(202)
392 #define ADDC   XO31( 10)
393 #define AND    XO31( 28)
394 #define SUBF   XO31( 40)
395 #define SUBFC  XO31(  8)
396 #define SUBFE  XO31(136)
397 #define SUBFME XO31(232)
398 #define SUBFZE XO31(200)
399 #define OR     XO31(444)
400 #define XOR    XO31(316)
401 #define MULLW  XO31(235)
402 #define MULHWU XO31( 11)
403 #define DIVW   XO31(491)
404 #define DIVWU  XO31(459)
405 #define CMP    XO31(  0)
406 #define CMPL   XO31( 32)
407 #define LHBRX  XO31(790)
408 #define LWBRX  XO31(534)
409 #define LDBRX  XO31(532)
410 #define STHBRX XO31(918)
411 #define STWBRX XO31(662)
412 #define STDBRX XO31(660)
413 #define MFSPR  XO31(339)
414 #define MTSPR  XO31(467)
415 #define SRAWI  XO31(824)
416 #define NEG    XO31(104)
417 #define MFCR   XO31( 19)
418 #define MFOCRF (MFCR | (1u << 20))
419 #define NOR    XO31(124)
420 #define CNTLZW XO31( 26)
421 #define CNTLZD XO31( 58)
422 #define ANDC   XO31( 60)
423 #define ORC    XO31(412)
424 #define EQV    XO31(284)
425 #define NAND   XO31(476)
426 #define ISEL   XO31( 15)
427
428 #define MULLD  XO31(233)
429 #define MULHD  XO31( 73)
430 #define MULHDU XO31(  9)
431 #define DIVD   XO31(489)
432 #define DIVDU  XO31(457)
433
434 #define LBZX   XO31( 87)
435 #define LHZX   XO31(279)
436 #define LHAX   XO31(343)
437 #define LWZX   XO31( 23)
438 #define STBX   XO31(215)
439 #define STHX   XO31(407)
440 #define STWX   XO31(151)
441
442 #define SPR(a, b) ((((a)<<5)|(b))<<11)
443 #define LR     SPR(8, 0)
444 #define CTR    SPR(9, 0)
445
446 #define SLW    XO31( 24)
447 #define SRW    XO31(536)
448 #define SRAW   XO31(792)
449
450 #define SLD    XO31( 27)
451 #define SRD    XO31(539)
452 #define SRAD   XO31(794)
453 #define SRADI  XO31(413<<1)
454
455 #define TW     XO31( 4)
456 #define TRAP   (TW | TO(31))
457
458 #define RT(r) ((r)<<21)
459 #define RS(r) ((r)<<21)
460 #define RA(r) ((r)<<16)
461 #define RB(r) ((r)<<11)
462 #define TO(t) ((t)<<21)
463 #define SH(s) ((s)<<11)
464 #define MB(b) ((b)<<6)
465 #define ME(e) ((e)<<1)
466 #define BO(o) ((o)<<21)
467 #define MB64(b) ((b)<<5)
468 #define FXM(b) (1 << (19 - (b)))
469
470 #define LK    1
471
472 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
473 #define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
474 #define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
475 #define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
476
477 #define BF(n)    ((n)<<23)
478 #define BI(n, c) (((c)+((n)*4))<<16)
479 #define BT(n, c) (((c)+((n)*4))<<21)
480 #define BA(n, c) (((c)+((n)*4))<<16)
481 #define BB(n, c) (((c)+((n)*4))<<11)
482 #define BC_(n, c) (((c)+((n)*4))<<6)
483
484 #define BO_COND_TRUE  BO(12)
485 #define BO_COND_FALSE BO( 4)
486 #define BO_ALWAYS     BO(20)
487
488 enum {
489     CR_LT,
490     CR_GT,
491     CR_EQ,
492     CR_SO
493 };
494
495 static const uint32_t tcg_to_bc[] = {
496     [TCG_COND_EQ]  = BC | BI(7, CR_EQ) | BO_COND_TRUE,
497     [TCG_COND_NE]  = BC | BI(7, CR_EQ) | BO_COND_FALSE,
498     [TCG_COND_LT]  = BC | BI(7, CR_LT) | BO_COND_TRUE,
499     [TCG_COND_GE]  = BC | BI(7, CR_LT) | BO_COND_FALSE,
500     [TCG_COND_LE]  = BC | BI(7, CR_GT) | BO_COND_FALSE,
501     [TCG_COND_GT]  = BC | BI(7, CR_GT) | BO_COND_TRUE,
502     [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
503     [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
504     [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
505     [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
506 };
507
508 /* The low bit here is set if the RA and RB fields must be inverted.  */
509 static const uint32_t tcg_to_isel[] = {
510     [TCG_COND_EQ]  = ISEL | BC_(7, CR_EQ),
511     [TCG_COND_NE]  = ISEL | BC_(7, CR_EQ) | 1,
512     [TCG_COND_LT]  = ISEL | BC_(7, CR_LT),
513     [TCG_COND_GE]  = ISEL | BC_(7, CR_LT) | 1,
514     [TCG_COND_LE]  = ISEL | BC_(7, CR_GT) | 1,
515     [TCG_COND_GT]  = ISEL | BC_(7, CR_GT),
516     [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
517     [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
518     [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
519     [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
520 };
521
522 static inline void tcg_out_mov(TCGContext *s, TCGType type,
523                                TCGReg ret, TCGReg arg)
524 {
525     if (ret != arg) {
526         tcg_out32(s, OR | SAB(arg, ret, arg));
527     }
528 }
529
530 static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
531                                int sh, int mb)
532 {
533     sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
534     mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
535     tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
536 }
537
538 static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
539                                int sh, int mb, int me)
540 {
541     tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
542 }
543
544 static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
545 {
546     tcg_out_rld(s, RLDICL, dst, src, 0, 32);
547 }
548
549 static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
550 {
551     tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
552 }
553
554 static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
555 {
556     tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
557 }
558
559 static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
560 {
561     if (arg == (int16_t) arg) {
562         tcg_out32(s, ADDI | TAI(ret, 0, arg));
563     } else {
564         tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
565         if (arg & 0xffff) {
566             tcg_out32(s, ORI | SAI(ret, ret, arg));
567         }
568     }
569 }
570
571 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
572                          tcg_target_long arg)
573 {
574     if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
575         tcg_out_movi32(s, ret, arg);
576     } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
577         tcg_out32(s, ADDI | TAI(ret, 0, arg));
578         tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
579     } else {
580         int32_t high = arg >> 32;
581         tcg_out_movi32(s, ret, high);
582         if (high) {
583             tcg_out_shli64(s, ret, ret, 32);
584         }
585         if (arg & 0xffff0000) {
586             tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
587         }
588         if (arg & 0xffff) {
589             tcg_out32(s, ORI | SAI(ret, ret, arg));
590         }
591     }
592 }
593
594 static bool mask_operand(uint32_t c, int *mb, int *me)
595 {
596     uint32_t lsb, test;
597
598     /* Accept a bit pattern like:
599            0....01....1
600            1....10....0
601            0..01..10..0
602        Keep track of the transitions.  */
603     if (c == 0 || c == -1) {
604         return false;
605     }
606     test = c;
607     lsb = test & -test;
608     test += lsb;
609     if (test & (test - 1)) {
610         return false;
611     }
612
613     *me = clz32(lsb);
614     *mb = test ? clz32(test & -test) + 1 : 0;
615     return true;
616 }
617
618 static bool mask64_operand(uint64_t c, int *mb, int *me)
619 {
620     uint64_t lsb;
621
622     if (c == 0) {
623         return false;
624     }
625
626     lsb = c & -c;
627     /* Accept 1..10..0.  */
628     if (c == -lsb) {
629         *mb = 0;
630         *me = clz64(lsb);
631         return true;
632     }
633     /* Accept 0..01..1.  */
634     if (lsb == 1 && (c & (c + 1)) == 0) {
635         *mb = clz64(c + 1) + 1;
636         *me = 63;
637         return true;
638     }
639     return false;
640 }
641
642 static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
643 {
644     int mb, me;
645
646     if ((c & 0xffff) == c) {
647         tcg_out32(s, ANDI | SAI(src, dst, c));
648         return;
649     } else if ((c & 0xffff0000) == c) {
650         tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
651         return;
652     } else if (mask_operand(c, &mb, &me)) {
653         tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
654     } else {
655         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
656         tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
657     }
658 }
659
660 static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
661 {
662     int mb, me;
663
664     if ((c & 0xffff) == c) {
665         tcg_out32(s, ANDI | SAI(src, dst, c));
666         return;
667     } else if ((c & 0xffff0000) == c) {
668         tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
669         return;
670     } else if (mask64_operand(c, &mb, &me)) {
671         if (mb == 0) {
672             tcg_out_rld(s, RLDICR, dst, src, 0, me);
673         } else {
674             tcg_out_rld(s, RLDICL, dst, src, 0, mb);
675         }
676     } else {
677         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
678         tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
679     }
680 }
681
682 static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
683                            int op_lo, int op_hi)
684 {
685     if (c >> 16) {
686         tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
687         src = dst;
688     }
689     if (c & 0xffff) {
690         tcg_out32(s, op_lo | SAI(src, dst, c));
691         src = dst;
692     }
693 }
694
695 static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
696 {
697     tcg_out_zori32(s, dst, src, c, ORI, ORIS);
698 }
699
700 static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
701 {
702     tcg_out_zori32(s, dst, src, c, XORI, XORIS);
703 }
704
705 static void tcg_out_b(TCGContext *s, int mask, tcg_target_long target)
706 {
707     tcg_target_long disp;
708
709     disp = target - (tcg_target_long)s->code_ptr;
710     if (in_range_b(disp)) {
711         tcg_out32(s, B | (disp & 0x3fffffc) | mask);
712     } else {
713         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, (tcg_target_long)target);
714         tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
715         tcg_out32(s, BCCTR | BO_ALWAYS | mask);
716     }
717 }
718
719 static void tcg_out_call(TCGContext *s, tcg_target_long arg, int const_arg)
720 {
721 #ifdef __APPLE__
722     if (const_arg) {
723         tcg_out_b(s, LK, arg);
724     } else {
725         tcg_out32(s, MTSPR | RS(arg) | LR);
726         tcg_out32(s, BCLR | BO_ALWAYS | LK);
727     }
728 #else
729     TCGReg reg = arg;
730     int ofs = 0;
731
732     if (const_arg) {
733         /* Look through the descriptor.  If the branch is in range, and we
734            don't have to spend too much effort on building the toc.  */
735         intptr_t tgt = ((intptr_t *)arg)[0];
736         intptr_t toc = ((intptr_t *)arg)[1];
737         intptr_t diff = tgt - (intptr_t)s->code_ptr;
738
739         if (in_range_b(diff) && toc == (uint32_t)toc) {
740             tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, toc);
741             tcg_out_b(s, LK, tgt);
742             return;
743         }
744
745         /* Fold the low bits of the constant into the addresses below.  */
746         ofs = (int16_t)arg;
747         if (ofs + 8 < 0x8000) {
748             arg -= ofs;
749         } else {
750             ofs = 0;
751         }
752         reg = TCG_REG_R2;
753         tcg_out_movi(s, TCG_TYPE_I64, reg, arg);
754     }
755
756     tcg_out32(s, LD | TAI(TCG_REG_R0, reg, ofs));
757     tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
758     tcg_out32(s, LD | TAI(TCG_REG_R2, reg, ofs + 8));
759     tcg_out32(s, BCCTR | BO_ALWAYS | LK);
760 #endif
761 }
762
763 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
764                              TCGReg base, tcg_target_long offset)
765 {
766     tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
767     TCGReg rs = TCG_REG_R2;
768
769     assert(rt != TCG_REG_R2 && base != TCG_REG_R2);
770
771     switch (opi) {
772     case LD: case LWA:
773         align = 3;
774         /* FALLTHRU */
775     default:
776         if (rt != TCG_REG_R0) {
777             rs = rt;
778         }
779         break;
780     case STD:
781         align = 3;
782         break;
783     case STB: case STH: case STW:
784         break;
785     }
786
787     /* For unaligned, or very large offsets, use the indexed form.  */
788     if (offset & align || offset != (int32_t)offset) {
789         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, orig);
790         tcg_out32(s, opx | TAB(rt, base, TCG_REG_R2));
791         return;
792     }
793
794     l0 = (int16_t)offset;
795     offset = (offset - l0) >> 16;
796     l1 = (int16_t)offset;
797
798     if (l1 < 0 && orig >= 0) {
799         extra = 0x4000;
800         l1 = (int16_t)(offset - 0x4000);
801     }
802     if (l1) {
803         tcg_out32(s, ADDIS | TAI(rs, base, l1));
804         base = rs;
805     }
806     if (extra) {
807         tcg_out32(s, ADDIS | TAI(rs, base, extra));
808         base = rs;
809     }
810     if (opi != ADDI || base != rt || l0 != 0) {
811         tcg_out32(s, opi | TAI(rt, base, l0));
812     }
813 }
814
815 static const uint32_t qemu_ldx_opc[16] = {
816     [MO_UB] = LBZX,
817     [MO_UW] = LHZX,
818     [MO_UL] = LWZX,
819     [MO_Q]  = LDX,
820     [MO_SW] = LHAX,
821     [MO_SL] = LWAX,
822     [MO_BSWAP | MO_UB] = LBZX,
823     [MO_BSWAP | MO_UW] = LHBRX,
824     [MO_BSWAP | MO_UL] = LWBRX,
825     [MO_BSWAP | MO_Q]  = LDBRX,
826 };
827
828 static const uint32_t qemu_stx_opc[16] = {
829     [MO_UB] = STBX,
830     [MO_UW] = STHX,
831     [MO_UL] = STWX,
832     [MO_Q]  = STDX,
833     [MO_BSWAP | MO_UB] = STBX,
834     [MO_BSWAP | MO_UW] = STHBRX,
835     [MO_BSWAP | MO_UL] = STWBRX,
836     [MO_BSWAP | MO_Q]  = STDBRX,
837 };
838
839 static const uint32_t qemu_exts_opc[4] = {
840     EXTSB, EXTSH, EXTSW, 0
841 };
842
843 #if defined (CONFIG_SOFTMMU)
844 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
845  *                                 int mmu_idx, uintptr_t ra)
846  */
847 static const void * const qemu_ld_helpers[16] = {
848     [MO_UB]   = helper_ret_ldub_mmu,
849     [MO_LEUW] = helper_le_lduw_mmu,
850     [MO_LEUL] = helper_le_ldul_mmu,
851     [MO_LEQ]  = helper_le_ldq_mmu,
852     [MO_BEUW] = helper_be_lduw_mmu,
853     [MO_BEUL] = helper_be_ldul_mmu,
854     [MO_BEQ]  = helper_be_ldq_mmu,
855 };
856
857 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
858  *                                 uintxx_t val, int mmu_idx, uintptr_t ra)
859  */
860 static const void * const qemu_st_helpers[16] = {
861     [MO_UB]   = helper_ret_stb_mmu,
862     [MO_LEUW] = helper_le_stw_mmu,
863     [MO_LEUL] = helper_le_stl_mmu,
864     [MO_LEQ]  = helper_le_stq_mmu,
865     [MO_BEUW] = helper_be_stw_mmu,
866     [MO_BEUL] = helper_be_stl_mmu,
867     [MO_BEQ]  = helper_be_stq_mmu,
868 };
869
870 /* Perform the TLB load and compare.  Places the result of the comparison
871    in CR7, loads the addend of the TLB into R3, and returns the register
872    containing the guest address (zero-extended into R4).  Clobbers R0 and R2. */
873
874 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits, TCGReg addr_reg,
875                                int mem_index, bool is_read)
876 {
877     int cmp_off
878         = (is_read
879            ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
880            : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
881     int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
882     TCGReg base = TCG_AREG0;
883
884     /* Extract the page index, shifted into place for tlb index.  */
885     if (TARGET_LONG_BITS == 32) {
886         /* Zero-extend the address into a place helpful for further use.  */
887         tcg_out_ext32u(s, TCG_REG_R4, addr_reg);
888         addr_reg = TCG_REG_R4;
889     } else {
890         tcg_out_rld(s, RLDICL, TCG_REG_R3, addr_reg,
891                     64 - TARGET_PAGE_BITS, 64 - CPU_TLB_BITS);
892     }
893
894     /* Compensate for very large offsets.  */
895     if (add_off >= 0x8000) {
896         /* Most target env are smaller than 32k; none are larger than 64k.
897            Simplify the logic here merely to offset by 0x7ff0, giving us a
898            range just shy of 64k.  Check this assumption.  */
899         QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
900                                    tlb_table[NB_MMU_MODES - 1][1])
901                           > 0x7ff0 + 0x7fff);
902         tcg_out32(s, ADDI | TAI(TCG_REG_R2, base, 0x7ff0));
903         base = TCG_REG_R2;
904         cmp_off -= 0x7ff0;
905         add_off -= 0x7ff0;
906     }
907
908     /* Extraction and shifting, part 2.  */
909     if (TARGET_LONG_BITS == 32) {
910         tcg_out_rlw(s, RLWINM, TCG_REG_R3, addr_reg,
911                     32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
912                     32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS),
913                     31 - CPU_TLB_ENTRY_BITS);
914     } else {
915         tcg_out_shli64(s, TCG_REG_R3, TCG_REG_R3, CPU_TLB_ENTRY_BITS);
916     }
917
918     tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, base));
919
920     /* Load the tlb comparator.  */
921     tcg_out32(s, LD_ADDR | TAI(TCG_REG_R2, TCG_REG_R3, cmp_off));
922
923     /* Load the TLB addend for use on the fast path.  Do this asap
924        to minimize any load use delay.  */
925     tcg_out32(s, LD | TAI(TCG_REG_R3, TCG_REG_R3, add_off));
926
927     /* Clear the non-page, non-alignment bits from the address.  */
928     if (TARGET_LONG_BITS == 32) {
929         tcg_out_rlw(s, RLWINM, TCG_REG_R0, addr_reg, 0,
930                     (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
931     } else if (!s_bits) {
932         tcg_out_rld(s, RLDICR, TCG_REG_R0, addr_reg, 0, 63 - TARGET_PAGE_BITS);
933     } else {
934         tcg_out_rld(s, RLDICL, TCG_REG_R0, addr_reg,
935                     64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
936         tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
937     }
938
939     tcg_out32(s, CMP | BF(7) | RA(TCG_REG_R0) | RB(TCG_REG_R2) | CMP_L);
940
941     return addr_reg;
942 }
943
944 /* Record the context of a call to the out of line helper code for the slow
945    path for a load or store, so that we can later generate the correct
946    helper code.  */
947 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
948                                 int data_reg, int addr_reg, int mem_index,
949                                 uint8_t *raddr, uint8_t *label_ptr)
950 {
951     TCGLabelQemuLdst *label = new_ldst_label(s);
952
953     label->is_ld = is_ld;
954     label->opc = opc;
955     label->datalo_reg = data_reg;
956     label->addrlo_reg = addr_reg;
957     label->mem_index = mem_index;
958     label->raddr = raddr;
959     label->label_ptr[0] = label_ptr;
960 }
961
962 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
963 {
964     TCGMemOp opc = lb->opc;
965
966     reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
967
968     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0);
969
970     /* If the address needed to be zero-extended, we'll have already
971        placed it in R4.  The only remaining case is 64-bit guest.  */
972     tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, lb->addrlo_reg);
973
974     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, lb->mem_index);
975     tcg_out32(s, MFSPR | RT(TCG_REG_R6) | LR);
976
977     tcg_out_call(s, (tcg_target_long)qemu_ld_helpers[opc & ~MO_SIGN], 1);
978
979     if (opc & MO_SIGN) {
980         uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
981         tcg_out32(s, insn | RA(lb->datalo_reg) | RS(TCG_REG_R3));
982     } else {
983         tcg_out_mov(s, TCG_TYPE_I64, lb->datalo_reg, TCG_REG_R3);
984     }
985
986     tcg_out_b(s, 0, (uintptr_t)lb->raddr);
987 }
988
989 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
990 {
991     TCGMemOp opc = lb->opc;
992     TCGMemOp s_bits = opc & MO_SIZE;
993
994     reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
995
996     tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, TCG_AREG0);
997
998     /* If the address needed to be zero-extended, we'll have already
999        placed it in R4.  The only remaining case is 64-bit guest.  */
1000     tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, lb->addrlo_reg);
1001
1002     tcg_out_rld(s, RLDICL, TCG_REG_R5, lb->datalo_reg,
1003                 0, 64 - (1 << (3 + s_bits)));
1004     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R6, lb->mem_index);
1005     tcg_out32(s, MFSPR | RT(TCG_REG_R7) | LR);
1006
1007     tcg_out_call(s, (tcg_target_long)qemu_st_helpers[opc], 1);
1008
1009     tcg_out_b(s, 0, (uintptr_t)lb->raddr);
1010 }
1011 #endif /* SOFTMMU */
1012
1013 static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1014                             TCGMemOp opc, int mem_index)
1015 {
1016     TCGReg rbase;
1017     uint32_t insn;
1018     TCGMemOp s_bits = opc & MO_SIZE;
1019 #ifdef CONFIG_SOFTMMU
1020     void *label_ptr;
1021 #endif
1022
1023 #ifdef CONFIG_SOFTMMU
1024     addr_reg = tcg_out_tlb_read(s, s_bits, addr_reg, mem_index, true);
1025
1026     /* Load a pointer into the current opcode w/conditional branch-link. */
1027     label_ptr = s->code_ptr;
1028     tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1029
1030     rbase = TCG_REG_R3;
1031 #else  /* !CONFIG_SOFTMMU */
1032     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1033     if (TARGET_LONG_BITS == 32) {
1034         tcg_out_ext32u(s, TCG_REG_R2, addr_reg);
1035         addr_reg = TCG_REG_R2;
1036     }
1037 #endif
1038
1039     insn = qemu_ldx_opc[opc];
1040     if (!HAVE_ISA_2_06 && insn == LDBRX) {
1041         tcg_out32(s, ADDI | TAI(TCG_REG_R0, addr_reg, 4));
1042         tcg_out32(s, LWBRX | TAB(data_reg, rbase, addr_reg));
1043         tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1044         tcg_out_rld(s, RLDIMI, data_reg, TCG_REG_R0, 32, 0);
1045     } else if (insn) {
1046         tcg_out32(s, insn | TAB(data_reg, rbase, addr_reg));
1047     } else {
1048         insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1049         tcg_out32(s, insn | TAB(data_reg, rbase, addr_reg));
1050         insn = qemu_exts_opc[s_bits];
1051         tcg_out32(s, insn | RA(data_reg) | RS(data_reg));
1052     }
1053
1054 #ifdef CONFIG_SOFTMMU
1055     add_qemu_ldst_label(s, true, opc, data_reg, addr_reg, mem_index,
1056                         s->code_ptr, label_ptr);
1057 #endif
1058 }
1059
1060 static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1061                             TCGMemOp opc, int mem_index)
1062 {
1063     TCGReg rbase;
1064     uint32_t insn;
1065 #ifdef CONFIG_SOFTMMU
1066     void *label_ptr;
1067 #endif
1068
1069 #ifdef CONFIG_SOFTMMU
1070     addr_reg = tcg_out_tlb_read(s, opc & MO_SIZE, addr_reg, mem_index, false);
1071
1072     /* Load a pointer into the current opcode w/conditional branch-link. */
1073     label_ptr = s->code_ptr;
1074     tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1075
1076     rbase = TCG_REG_R3;
1077 #else  /* !CONFIG_SOFTMMU */
1078     rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1079     if (TARGET_LONG_BITS == 32) {
1080         tcg_out_ext32u(s, TCG_REG_R2, addr_reg);
1081         addr_reg = TCG_REG_R2;
1082     }
1083 #endif
1084
1085     insn = qemu_stx_opc[opc];
1086     if (!HAVE_ISA_2_06 && insn == STDBRX) {
1087         tcg_out32(s, STWBRX | SAB(data_reg, rbase, addr_reg));
1088         tcg_out32(s, ADDI | TAI(TCG_REG_R2, addr_reg, 4));
1089         tcg_out_shri64(s, TCG_REG_R0, data_reg, 32);
1090         tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_R2));
1091     } else {
1092         tcg_out32(s, insn | SAB(data_reg, rbase, addr_reg));
1093     }
1094
1095 #ifdef CONFIG_SOFTMMU
1096     add_qemu_ldst_label(s, false, opc, data_reg, addr_reg, mem_index,
1097                         s->code_ptr, label_ptr);
1098 #endif
1099 }
1100
1101 #define FRAME_SIZE ((int) \
1102     ((8                     /* back chain */              \
1103       + 8                   /* CR */                      \
1104       + 8                   /* LR */                      \
1105       + 8                   /* compiler doubleword */     \
1106       + 8                   /* link editor doubleword */  \
1107       + 8                   /* TOC save area */           \
1108       + TCG_STATIC_CALL_ARGS_SIZE                         \
1109       + CPU_TEMP_BUF_NLONGS * sizeof(long)                \
1110       + ARRAY_SIZE(tcg_target_callee_save_regs) * 8       \
1111       + 15) & ~15))
1112
1113 #define REG_SAVE_BOT (FRAME_SIZE - ARRAY_SIZE(tcg_target_callee_save_regs) * 8)
1114
1115 static void tcg_target_qemu_prologue(TCGContext *s)
1116 {
1117     int i;
1118
1119     tcg_set_frame(s, TCG_REG_CALL_STACK,
1120                   REG_SAVE_BOT - CPU_TEMP_BUF_NLONGS * sizeof(long),
1121                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1122
1123 #ifndef __APPLE__
1124     /* First emit adhoc function descriptor */
1125     tcg_out64(s, (uint64_t)s->code_ptr + 24); /* entry point */
1126     s->code_ptr += 16;          /* skip TOC and environment pointer */
1127 #endif
1128
1129     /* Prologue */
1130     tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1131     tcg_out32(s, STDU | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1132     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1133         tcg_out32(s, STD | SAI(tcg_target_callee_save_regs[i], 1, 
1134                                REG_SAVE_BOT + i * 8));
1135     }
1136     tcg_out32(s, STD | SAI(TCG_REG_R0, TCG_REG_R1, FRAME_SIZE + 16));
1137
1138 #ifdef CONFIG_USE_GUEST_BASE
1139     if (GUEST_BASE) {
1140         tcg_out_movi(s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
1141         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1142     }
1143 #endif
1144
1145     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1146     tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1147     tcg_out32(s, BCCTR | BO_ALWAYS);
1148
1149     /* Epilogue */
1150     tb_ret_addr = s->code_ptr;
1151
1152     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1153         tcg_out32(s, LD | TAI(tcg_target_callee_save_regs[i], TCG_REG_R1,
1154                               REG_SAVE_BOT + i * 8));
1155     }
1156     tcg_out32(s, LD | TAI(TCG_REG_R0, TCG_REG_R1, FRAME_SIZE + 16));
1157     tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1158     tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1159     tcg_out32(s, BCLR | BO_ALWAYS);
1160 }
1161
1162 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
1163                               TCGReg arg1, intptr_t arg2)
1164 {
1165     int opi, opx;
1166
1167     if (type == TCG_TYPE_I32) {
1168         opi = LWZ, opx = LWZX;
1169     } else {
1170         opi = LD, opx = LDX;
1171     }
1172     tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
1173 }
1174
1175 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1176                               TCGReg arg1, intptr_t arg2)
1177 {
1178     int opi, opx;
1179
1180     if (type == TCG_TYPE_I32) {
1181         opi = STW, opx = STWX;
1182     } else {
1183         opi = STD, opx = STDX;
1184     }
1185     tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
1186 }
1187
1188 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
1189                         int const_arg2, int cr, TCGType type)
1190 {
1191     int imm;
1192     uint32_t op;
1193
1194     /* Simplify the comparisons below wrt CMPI.  */
1195     if (type == TCG_TYPE_I32) {
1196         arg2 = (int32_t)arg2;
1197     }
1198
1199     switch (cond) {
1200     case TCG_COND_EQ:
1201     case TCG_COND_NE:
1202         if (const_arg2) {
1203             if ((int16_t) arg2 == arg2) {
1204                 op = CMPI;
1205                 imm = 1;
1206                 break;
1207             } else if ((uint16_t) arg2 == arg2) {
1208                 op = CMPLI;
1209                 imm = 1;
1210                 break;
1211             }
1212         }
1213         op = CMPL;
1214         imm = 0;
1215         break;
1216
1217     case TCG_COND_LT:
1218     case TCG_COND_GE:
1219     case TCG_COND_LE:
1220     case TCG_COND_GT:
1221         if (const_arg2) {
1222             if ((int16_t) arg2 == arg2) {
1223                 op = CMPI;
1224                 imm = 1;
1225                 break;
1226             }
1227         }
1228         op = CMP;
1229         imm = 0;
1230         break;
1231
1232     case TCG_COND_LTU:
1233     case TCG_COND_GEU:
1234     case TCG_COND_LEU:
1235     case TCG_COND_GTU:
1236         if (const_arg2) {
1237             if ((uint16_t) arg2 == arg2) {
1238                 op = CMPLI;
1239                 imm = 1;
1240                 break;
1241             }
1242         }
1243         op = CMPL;
1244         imm = 0;
1245         break;
1246
1247     default:
1248         tcg_abort();
1249     }
1250     op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
1251
1252     if (imm) {
1253         tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
1254     } else {
1255         if (const_arg2) {
1256             tcg_out_movi(s, type, TCG_REG_R0, arg2);
1257             arg2 = TCG_REG_R0;
1258         }
1259         tcg_out32(s, op | RA(arg1) | RB(arg2));
1260     }
1261 }
1262
1263 static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
1264                                 TCGReg dst, TCGReg src)
1265 {
1266     tcg_out32(s, (type == TCG_TYPE_I64 ? CNTLZD : CNTLZW) | RS(src) | RA(dst));
1267     tcg_out_shri64(s, dst, dst, type == TCG_TYPE_I64 ? 6 : 5);
1268 }
1269
1270 static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
1271 {
1272     /* X != 0 implies X + -1 generates a carry.  Extra addition
1273        trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C.  */
1274     if (dst != src) {
1275         tcg_out32(s, ADDIC | TAI(dst, src, -1));
1276         tcg_out32(s, SUBFE | TAB(dst, dst, src));
1277     } else {
1278         tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
1279         tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
1280     }
1281 }
1282
1283 static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
1284                                   bool const_arg2)
1285 {
1286     if (const_arg2) {
1287         if ((uint32_t)arg2 == arg2) {
1288             tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
1289         } else {
1290             tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
1291             tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
1292         }
1293     } else {
1294         tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
1295     }
1296     return TCG_REG_R0;
1297 }
1298
1299 static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
1300                             TCGArg arg0, TCGArg arg1, TCGArg arg2,
1301                             int const_arg2)
1302 {
1303     int crop, sh;
1304
1305     /* Ignore high bits of a potential constant arg2.  */
1306     if (type == TCG_TYPE_I32) {
1307         arg2 = (uint32_t)arg2;
1308     }
1309
1310     /* Handle common and trivial cases before handling anything else.  */
1311     if (arg2 == 0) {
1312         switch (cond) {
1313         case TCG_COND_EQ:
1314             tcg_out_setcond_eq0(s, type, arg0, arg1);
1315             return;
1316         case TCG_COND_NE:
1317             if (type == TCG_TYPE_I32) {
1318                 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1319                 arg1 = TCG_REG_R0;
1320             }
1321             tcg_out_setcond_ne0(s, arg0, arg1);
1322             return;
1323         case TCG_COND_GE:
1324             tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1325             arg1 = arg0;
1326             /* FALLTHRU */
1327         case TCG_COND_LT:
1328             /* Extract the sign bit.  */
1329             tcg_out_rld(s, RLDICL, arg0, arg1,
1330                         type == TCG_TYPE_I64 ? 1 : 33, 63);
1331             return;
1332         default:
1333             break;
1334         }
1335     }
1336
1337     /* If we have ISEL, we can implement everything with 3 or 4 insns.
1338        All other cases below are also at least 3 insns, so speed up the
1339        code generator by not considering them and always using ISEL.  */
1340     if (HAVE_ISEL) {
1341         int isel, tab;
1342
1343         tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1344
1345         isel = tcg_to_isel[cond];
1346
1347         tcg_out_movi(s, type, arg0, 1);
1348         if (isel & 1) {
1349             /* arg0 = (bc ? 0 : 1) */
1350             tab = TAB(arg0, 0, arg0);
1351             isel &= ~1;
1352         } else {
1353             /* arg0 = (bc ? 1 : 0) */
1354             tcg_out_movi(s, type, TCG_REG_R0, 0);
1355             tab = TAB(arg0, arg0, TCG_REG_R0);
1356         }
1357         tcg_out32(s, isel | tab);
1358         return;
1359     }
1360
1361     switch (cond) {
1362     case TCG_COND_EQ:
1363         arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1364         tcg_out_setcond_eq0(s, type, arg0, arg1);
1365         return;
1366
1367     case TCG_COND_NE:
1368         arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1369         /* Discard the high bits only once, rather than both inputs.  */
1370         if (type == TCG_TYPE_I32) {
1371             tcg_out_ext32u(s, TCG_REG_R0, arg1);
1372             arg1 = TCG_REG_R0;
1373         }
1374         tcg_out_setcond_ne0(s, arg0, arg1);
1375         return;
1376
1377     case TCG_COND_GT:
1378     case TCG_COND_GTU:
1379         sh = 30;
1380         crop = 0;
1381         goto crtest;
1382
1383     case TCG_COND_LT:
1384     case TCG_COND_LTU:
1385         sh = 29;
1386         crop = 0;
1387         goto crtest;
1388
1389     case TCG_COND_GE:
1390     case TCG_COND_GEU:
1391         sh = 31;
1392         crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1393         goto crtest;
1394
1395     case TCG_COND_LE:
1396     case TCG_COND_LEU:
1397         sh = 31;
1398         crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1399     crtest:
1400         tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1401         if (crop) {
1402             tcg_out32(s, crop);
1403         }
1404         tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1405         tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1406         break;
1407
1408     default:
1409         tcg_abort();
1410     }
1411 }
1412
1413 static void tcg_out_bc(TCGContext *s, int bc, int label_index)
1414 {
1415     TCGLabel *l = &s->labels[label_index];
1416
1417     if (l->has_value) {
1418         tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value));
1419     } else {
1420         tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
1421         tcg_out_bc_noaddr(s, bc);
1422     }
1423 }
1424
1425 static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1426                            TCGArg arg1, TCGArg arg2, int const_arg2,
1427                            int label_index, TCGType type)
1428 {
1429     tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1430     tcg_out_bc(s, tcg_to_bc[cond], label_index);
1431 }
1432
1433 static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1434                             TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1435                             TCGArg v2, bool const_c2)
1436 {
1437     /* If for some reason both inputs are zero, don't produce bad code.  */
1438     if (v1 == 0 && v2 == 0) {
1439         tcg_out_movi(s, type, dest, 0);
1440         return;
1441     }
1442
1443     tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1444
1445     if (HAVE_ISEL) {
1446         int isel = tcg_to_isel[cond];
1447
1448         /* Swap the V operands if the operation indicates inversion.  */
1449         if (isel & 1) {
1450             int t = v1;
1451             v1 = v2;
1452             v2 = t;
1453             isel &= ~1;
1454         }
1455         /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand.  */
1456         if (v2 == 0) {
1457             tcg_out_movi(s, type, TCG_REG_R0, 0);
1458         }
1459         tcg_out32(s, isel | TAB(dest, v1, v2));
1460     } else {
1461         if (dest == v2) {
1462             cond = tcg_invert_cond(cond);
1463             v2 = v1;
1464         } else if (dest != v1) {
1465             if (v1 == 0) {
1466                 tcg_out_movi(s, type, dest, 0);
1467             } else {
1468                 tcg_out_mov(s, type, dest, v1);
1469             }
1470         }
1471         /* Branch forward over one insn */
1472         tcg_out32(s, tcg_to_bc[cond] | 8);
1473         if (v2 == 0) {
1474             tcg_out_movi(s, type, dest, 0);
1475         } else {
1476             tcg_out_mov(s, type, dest, v2);
1477         }
1478     }
1479 }
1480
1481 void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr)
1482 {
1483     TCGContext s;
1484     unsigned long patch_size;
1485
1486     s.code_ptr = (uint8_t *) jmp_addr;
1487     tcg_out_b(&s, 0, addr);
1488     patch_size = s.code_ptr - (uint8_t *) jmp_addr;
1489     flush_icache_range(jmp_addr, jmp_addr + patch_size);
1490 }
1491
1492 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1493                        const int *const_args)
1494 {
1495     TCGArg a0, a1, a2;
1496     int c;
1497
1498     switch (opc) {
1499     case INDEX_op_exit_tb:
1500         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
1501         tcg_out_b(s, 0, (tcg_target_long)tb_ret_addr);
1502         break;
1503     case INDEX_op_goto_tb:
1504         if (s->tb_jmp_offset) {
1505             /* Direct jump method.  */
1506             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1507             s->code_ptr += 28;
1508         } else {
1509             /* Indirect jump method.  */
1510             tcg_abort();
1511         }
1512         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1513         break;
1514     case INDEX_op_br:
1515         {
1516             TCGLabel *l = &s->labels[args[0]];
1517
1518             if (l->has_value) {
1519                 tcg_out_b(s, 0, l->u.value);
1520             } else {
1521                 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
1522                 tcg_out_b_noaddr(s, B);
1523             }
1524         }
1525         break;
1526     case INDEX_op_call:
1527         tcg_out_call(s, args[0], const_args[0]);
1528         break;
1529     case INDEX_op_movi_i32:
1530         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1531         break;
1532     case INDEX_op_movi_i64:
1533         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1534         break;
1535     case INDEX_op_ld8u_i32:
1536     case INDEX_op_ld8u_i64:
1537         tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1538         break;
1539     case INDEX_op_ld8s_i32:
1540     case INDEX_op_ld8s_i64:
1541         tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1542         tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
1543         break;
1544     case INDEX_op_ld16u_i32:
1545     case INDEX_op_ld16u_i64:
1546         tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
1547         break;
1548     case INDEX_op_ld16s_i32:
1549     case INDEX_op_ld16s_i64:
1550         tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
1551         break;
1552     case INDEX_op_ld_i32:
1553     case INDEX_op_ld32u_i64:
1554         tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
1555         break;
1556     case INDEX_op_ld32s_i64:
1557         tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
1558         break;
1559     case INDEX_op_ld_i64:
1560         tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
1561         break;
1562     case INDEX_op_st8_i32:
1563     case INDEX_op_st8_i64:
1564         tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
1565         break;
1566     case INDEX_op_st16_i32:
1567     case INDEX_op_st16_i64:
1568         tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
1569         break;
1570     case INDEX_op_st_i32:
1571     case INDEX_op_st32_i64:
1572         tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
1573         break;
1574     case INDEX_op_st_i64:
1575         tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
1576         break;
1577
1578     case INDEX_op_add_i32:
1579         a0 = args[0], a1 = args[1], a2 = args[2];
1580         if (const_args[2]) {
1581         do_addi_32:
1582             tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
1583         } else {
1584             tcg_out32(s, ADD | TAB(a0, a1, a2));
1585         }
1586         break;
1587     case INDEX_op_sub_i32:
1588         a0 = args[0], a1 = args[1], a2 = args[2];
1589         if (const_args[1]) {
1590             if (const_args[2]) {
1591                 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
1592             } else {
1593                 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
1594             }
1595         } else if (const_args[2]) {
1596             a2 = -a2;
1597             goto do_addi_32;
1598         } else {
1599             tcg_out32(s, SUBF | TAB(a0, a2, a1));
1600         }
1601         break;
1602
1603     case INDEX_op_and_i32:
1604         a0 = args[0], a1 = args[1], a2 = args[2];
1605         if (const_args[2]) {
1606             tcg_out_andi32(s, a0, a1, a2);
1607         } else {
1608             tcg_out32(s, AND | SAB(a1, a0, a2));
1609         }
1610         break;
1611     case INDEX_op_and_i64:
1612         a0 = args[0], a1 = args[1], a2 = args[2];
1613         if (const_args[2]) {
1614             tcg_out_andi64(s, a0, a1, a2);
1615         } else {
1616             tcg_out32(s, AND | SAB(a1, a0, a2));
1617         }
1618         break;
1619     case INDEX_op_or_i64:
1620     case INDEX_op_or_i32:
1621         a0 = args[0], a1 = args[1], a2 = args[2];
1622         if (const_args[2]) {
1623             tcg_out_ori32(s, a0, a1, a2);
1624         } else {
1625             tcg_out32(s, OR | SAB(a1, a0, a2));
1626         }
1627         break;
1628     case INDEX_op_xor_i64:
1629     case INDEX_op_xor_i32:
1630         a0 = args[0], a1 = args[1], a2 = args[2];
1631         if (const_args[2]) {
1632             tcg_out_xori32(s, a0, a1, a2);
1633         } else {
1634             tcg_out32(s, XOR | SAB(a1, a0, a2));
1635         }
1636         break;
1637     case INDEX_op_andc_i32:
1638         a0 = args[0], a1 = args[1], a2 = args[2];
1639         if (const_args[2]) {
1640             tcg_out_andi32(s, a0, a1, ~a2);
1641         } else {
1642             tcg_out32(s, ANDC | SAB(a1, a0, a2));
1643         }
1644         break;
1645     case INDEX_op_andc_i64:
1646         a0 = args[0], a1 = args[1], a2 = args[2];
1647         if (const_args[2]) {
1648             tcg_out_andi64(s, a0, a1, ~a2);
1649         } else {
1650             tcg_out32(s, ANDC | SAB(a1, a0, a2));
1651         }
1652         break;
1653     case INDEX_op_orc_i32:
1654         if (const_args[2]) {
1655             tcg_out_ori32(s, args[0], args[1], ~args[2]);
1656             break;
1657         }
1658         /* FALLTHRU */
1659     case INDEX_op_orc_i64:
1660         tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
1661         break;
1662     case INDEX_op_eqv_i32:
1663         if (const_args[2]) {
1664             tcg_out_xori32(s, args[0], args[1], ~args[2]);
1665             break;
1666         }
1667         /* FALLTHRU */
1668     case INDEX_op_eqv_i64:
1669         tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
1670         break;
1671     case INDEX_op_nand_i32:
1672     case INDEX_op_nand_i64:
1673         tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
1674         break;
1675     case INDEX_op_nor_i32:
1676     case INDEX_op_nor_i64:
1677         tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
1678         break;
1679
1680     case INDEX_op_mul_i32:
1681         a0 = args[0], a1 = args[1], a2 = args[2];
1682         if (const_args[2]) {
1683             tcg_out32(s, MULLI | TAI(a0, a1, a2));
1684         } else {
1685             tcg_out32(s, MULLW | TAB(a0, a1, a2));
1686         }
1687         break;
1688
1689     case INDEX_op_div_i32:
1690         tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
1691         break;
1692
1693     case INDEX_op_divu_i32:
1694         tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
1695         break;
1696
1697     case INDEX_op_shl_i32:
1698         if (const_args[2]) {
1699             tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]);
1700         } else {
1701             tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
1702         }
1703         break;
1704     case INDEX_op_shr_i32:
1705         if (const_args[2]) {
1706             tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], args[2], 31);
1707         } else {
1708             tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
1709         }
1710         break;
1711     case INDEX_op_sar_i32:
1712         if (const_args[2]) {
1713             tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
1714         } else {
1715             tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
1716         }
1717         break;
1718     case INDEX_op_rotl_i32:
1719         if (const_args[2]) {
1720             tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
1721         } else {
1722             tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
1723                          | MB(0) | ME(31));
1724         }
1725         break;
1726     case INDEX_op_rotr_i32:
1727         if (const_args[2]) {
1728             tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
1729         } else {
1730             tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
1731             tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
1732                          | MB(0) | ME(31));
1733         }
1734         break;
1735
1736     case INDEX_op_brcond_i32:
1737         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1738                        args[3], TCG_TYPE_I32);
1739         break;
1740
1741     case INDEX_op_brcond_i64:
1742         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1743                        args[3], TCG_TYPE_I64);
1744         break;
1745
1746     case INDEX_op_neg_i32:
1747     case INDEX_op_neg_i64:
1748         tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
1749         break;
1750
1751     case INDEX_op_not_i32:
1752     case INDEX_op_not_i64:
1753         tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
1754         break;
1755
1756     case INDEX_op_add_i64:
1757         a0 = args[0], a1 = args[1], a2 = args[2];
1758         if (const_args[2]) {
1759         do_addi_64:
1760             tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
1761         } else {
1762             tcg_out32(s, ADD | TAB(a0, a1, a2));
1763         }
1764         break;
1765     case INDEX_op_sub_i64:
1766         a0 = args[0], a1 = args[1], a2 = args[2];
1767         if (const_args[1]) {
1768             if (const_args[2]) {
1769                 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
1770             } else {
1771                 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
1772             }
1773         } else if (const_args[2]) {
1774             a2 = -a2;
1775             goto do_addi_64;
1776         } else {
1777             tcg_out32(s, SUBF | TAB(a0, a2, a1));
1778         }
1779         break;
1780
1781     case INDEX_op_shl_i64:
1782         if (const_args[2]) {
1783             tcg_out_shli64(s, args[0], args[1], args[2]);
1784         } else {
1785             tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
1786         }
1787         break;
1788     case INDEX_op_shr_i64:
1789         if (const_args[2]) {
1790             tcg_out_shri64(s, args[0], args[1], args[2]);
1791         } else {
1792             tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
1793         }
1794         break;
1795     case INDEX_op_sar_i64:
1796         if (const_args[2]) {
1797             int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
1798             tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
1799         } else {
1800             tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
1801         }
1802         break;
1803     case INDEX_op_rotl_i64:
1804         if (const_args[2]) {
1805             tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
1806         } else {
1807             tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
1808         }
1809         break;
1810     case INDEX_op_rotr_i64:
1811         if (const_args[2]) {
1812             tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
1813         } else {
1814             tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
1815             tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
1816         }
1817         break;
1818
1819     case INDEX_op_mul_i64:
1820         a0 = args[0], a1 = args[1], a2 = args[2];
1821         if (const_args[2]) {
1822             tcg_out32(s, MULLI | TAI(a0, a1, a2));
1823         } else {
1824             tcg_out32(s, MULLD | TAB(a0, a1, a2));
1825         }
1826         break;
1827     case INDEX_op_div_i64:
1828         tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
1829         break;
1830     case INDEX_op_divu_i64:
1831         tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
1832         break;
1833
1834     case INDEX_op_qemu_ld_i32:
1835     case INDEX_op_qemu_ld_i64:
1836         tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3]);
1837         break;
1838     case INDEX_op_qemu_st_i32:
1839     case INDEX_op_qemu_st_i64:
1840         tcg_out_qemu_st(s, args[0], args[1], args[2], args[3]);
1841         break;
1842
1843     case INDEX_op_ext8s_i32:
1844     case INDEX_op_ext8s_i64:
1845         c = EXTSB;
1846         goto gen_ext;
1847     case INDEX_op_ext16s_i32:
1848     case INDEX_op_ext16s_i64:
1849         c = EXTSH;
1850         goto gen_ext;
1851     case INDEX_op_ext32s_i64:
1852         c = EXTSW;
1853         goto gen_ext;
1854     gen_ext:
1855         tcg_out32(s, c | RS(args[1]) | RA(args[0]));
1856         break;
1857
1858     case INDEX_op_setcond_i32:
1859         tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
1860                         const_args[2]);
1861         break;
1862     case INDEX_op_setcond_i64:
1863         tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
1864                         const_args[2]);
1865         break;
1866
1867     case INDEX_op_bswap16_i32:
1868     case INDEX_op_bswap16_i64:
1869         a0 = args[0], a1 = args[1];
1870         /* a1 = abcd */
1871         if (a0 != a1) {
1872             /* a0 = (a1 r<< 24) & 0xff # 000c */
1873             tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
1874             /* a0 = (a0 & ~0xff00) | (a1 r<< 8) & 0xff00 # 00dc */
1875             tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
1876         } else {
1877             /* r0 = (a1 r<< 8) & 0xff00 # 00d0 */
1878             tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
1879             /* a0 = (a1 r<< 24) & 0xff # 000c */
1880             tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
1881             /* a0 = a0 | r0 # 00dc */
1882             tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
1883         }
1884         break;
1885
1886     case INDEX_op_bswap32_i32:
1887     case INDEX_op_bswap32_i64:
1888         /* Stolen from gcc's builtin_bswap32 */
1889         a1 = args[1];
1890         a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
1891
1892         /* a1 = args[1] # abcd */
1893         /* a0 = rotate_left (a1, 8) # bcda */
1894         tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
1895         /* a0 = (a0 & ~0xff000000) | ((a1 r<< 24) & 0xff000000) # dcda */
1896         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
1897         /* a0 = (a0 & ~0x0000ff00) | ((a1 r<< 24) & 0x0000ff00) # dcba */
1898         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
1899
1900         if (a0 == TCG_REG_R0) {
1901             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1902         }
1903         break;
1904
1905     case INDEX_op_bswap64_i64:
1906         a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
1907         if (a0 == a1) {
1908             a0 = TCG_REG_R0;
1909             a2 = a1;
1910         }
1911
1912         /* a1 = # abcd efgh */
1913         /* a0 = rl32(a1, 8) # 0000 fghe */
1914         tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
1915         /* a0 = dep(a0, rl32(a1, 24), 0xff000000) # 0000 hghe */
1916         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
1917         /* a0 = dep(a0, rl32(a1, 24), 0x0000ff00) # 0000 hgfe */
1918         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
1919
1920         /* a0 = rl64(a0, 32) # hgfe 0000 */
1921         /* a2 = rl64(a1, 32) # efgh abcd */
1922         tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
1923         tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
1924
1925         /* a0 = dep(a0, rl32(a2, 8), 0xffffffff)  # hgfe bcda */
1926         tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
1927         /* a0 = dep(a0, rl32(a2, 24), 0xff000000) # hgfe dcda */
1928         tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
1929         /* a0 = dep(a0, rl32(a2, 24), 0x0000ff00) # hgfe dcba */
1930         tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
1931
1932         if (a0 == 0) {
1933             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1934         }
1935         break;
1936
1937     case INDEX_op_deposit_i32:
1938         if (const_args[2]) {
1939             uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
1940             tcg_out_andi32(s, args[0], args[0], ~mask);
1941         } else {
1942             tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
1943                         32 - args[3] - args[4], 31 - args[3]);
1944         }
1945         break;
1946     case INDEX_op_deposit_i64:
1947         if (const_args[2]) {
1948             uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
1949             tcg_out_andi64(s, args[0], args[0], ~mask);
1950         } else {
1951             tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
1952                         64 - args[3] - args[4]);
1953         }
1954         break;
1955
1956     case INDEX_op_movcond_i32:
1957         tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
1958                         args[3], args[4], const_args[2]);
1959         break;
1960     case INDEX_op_movcond_i64:
1961         tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
1962                         args[3], args[4], const_args[2]);
1963         break;
1964
1965     case INDEX_op_add2_i64:
1966         /* Note that the CA bit is defined based on the word size of the
1967            environment.  So in 64-bit mode it's always carry-out of bit 63.
1968            The fallback code using deposit works just as well for 32-bit.  */
1969         a0 = args[0], a1 = args[1];
1970         if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
1971             a0 = TCG_REG_R0;
1972         }
1973         if (const_args[4]) {
1974             tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
1975         } else {
1976             tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
1977         }
1978         if (const_args[5]) {
1979             tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
1980         } else {
1981             tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
1982         }
1983         if (a0 != args[0]) {
1984             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1985         }
1986         break;
1987
1988     case INDEX_op_sub2_i64:
1989         a0 = args[0], a1 = args[1];
1990         if (a0 == args[5] || (!const_args[4] && a0 == args[4])) {
1991             a0 = TCG_REG_R0;
1992         }
1993         if (const_args[2]) {
1994             tcg_out32(s, SUBFIC | TAI(a0, args[3], args[2]));
1995         } else {
1996             tcg_out32(s, SUBFC | TAB(a0, args[3], args[2]));
1997         }
1998         if (const_args[4]) {
1999             tcg_out32(s, (args[4] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2000         } else {
2001             tcg_out32(s, SUBFE | TAB(a1, args[5], args[4]));
2002         }
2003         if (a0 != args[0]) {
2004             tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
2005         }
2006         break;
2007
2008     case INDEX_op_muluh_i64:
2009         tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2010         break;
2011     case INDEX_op_mulsh_i64:
2012         tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2013         break;
2014
2015     default:
2016         tcg_dump_ops(s);
2017         tcg_abort();
2018     }
2019 }
2020
2021 static const TCGTargetOpDef ppc_op_defs[] = {
2022     { INDEX_op_exit_tb, { } },
2023     { INDEX_op_goto_tb, { } },
2024     { INDEX_op_call, { "ri" } },
2025     { INDEX_op_br, { } },
2026
2027     { INDEX_op_mov_i32, { "r", "r" } },
2028     { INDEX_op_mov_i64, { "r", "r" } },
2029     { INDEX_op_movi_i32, { "r" } },
2030     { INDEX_op_movi_i64, { "r" } },
2031
2032     { INDEX_op_ld8u_i32, { "r", "r" } },
2033     { INDEX_op_ld8s_i32, { "r", "r" } },
2034     { INDEX_op_ld16u_i32, { "r", "r" } },
2035     { INDEX_op_ld16s_i32, { "r", "r" } },
2036     { INDEX_op_ld_i32, { "r", "r" } },
2037     { INDEX_op_ld_i64, { "r", "r" } },
2038     { INDEX_op_st8_i32, { "r", "r" } },
2039     { INDEX_op_st8_i64, { "r", "r" } },
2040     { INDEX_op_st16_i32, { "r", "r" } },
2041     { INDEX_op_st16_i64, { "r", "r" } },
2042     { INDEX_op_st_i32, { "r", "r" } },
2043     { INDEX_op_st_i64, { "r", "r" } },
2044     { INDEX_op_st32_i64, { "r", "r" } },
2045
2046     { INDEX_op_ld8u_i64, { "r", "r" } },
2047     { INDEX_op_ld8s_i64, { "r", "r" } },
2048     { INDEX_op_ld16u_i64, { "r", "r" } },
2049     { INDEX_op_ld16s_i64, { "r", "r" } },
2050     { INDEX_op_ld32u_i64, { "r", "r" } },
2051     { INDEX_op_ld32s_i64, { "r", "r" } },
2052
2053     { INDEX_op_add_i32, { "r", "r", "ri" } },
2054     { INDEX_op_mul_i32, { "r", "r", "rI" } },
2055     { INDEX_op_div_i32, { "r", "r", "r" } },
2056     { INDEX_op_divu_i32, { "r", "r", "r" } },
2057     { INDEX_op_sub_i32, { "r", "rI", "ri" } },
2058     { INDEX_op_and_i32, { "r", "r", "ri" } },
2059     { INDEX_op_or_i32, { "r", "r", "ri" } },
2060     { INDEX_op_xor_i32, { "r", "r", "ri" } },
2061     { INDEX_op_andc_i32, { "r", "r", "ri" } },
2062     { INDEX_op_orc_i32, { "r", "r", "ri" } },
2063     { INDEX_op_eqv_i32, { "r", "r", "ri" } },
2064     { INDEX_op_nand_i32, { "r", "r", "r" } },
2065     { INDEX_op_nor_i32, { "r", "r", "r" } },
2066
2067     { INDEX_op_shl_i32, { "r", "r", "ri" } },
2068     { INDEX_op_shr_i32, { "r", "r", "ri" } },
2069     { INDEX_op_sar_i32, { "r", "r", "ri" } },
2070     { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2071     { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2072
2073     { INDEX_op_brcond_i32, { "r", "ri" } },
2074     { INDEX_op_brcond_i64, { "r", "ri" } },
2075
2076     { INDEX_op_neg_i32, { "r", "r" } },
2077     { INDEX_op_not_i32, { "r", "r" } },
2078
2079     { INDEX_op_add_i64, { "r", "r", "rT" } },
2080     { INDEX_op_sub_i64, { "r", "rI", "rT" } },
2081     { INDEX_op_and_i64, { "r", "r", "ri" } },
2082     { INDEX_op_or_i64, { "r", "r", "rU" } },
2083     { INDEX_op_xor_i64, { "r", "r", "rU" } },
2084     { INDEX_op_andc_i64, { "r", "r", "ri" } },
2085     { INDEX_op_orc_i64, { "r", "r", "r" } },
2086     { INDEX_op_eqv_i64, { "r", "r", "r" } },
2087     { INDEX_op_nand_i64, { "r", "r", "r" } },
2088     { INDEX_op_nor_i64, { "r", "r", "r" } },
2089
2090     { INDEX_op_shl_i64, { "r", "r", "ri" } },
2091     { INDEX_op_shr_i64, { "r", "r", "ri" } },
2092     { INDEX_op_sar_i64, { "r", "r", "ri" } },
2093     { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2094     { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2095
2096     { INDEX_op_mul_i64, { "r", "r", "rI" } },
2097     { INDEX_op_div_i64, { "r", "r", "r" } },
2098     { INDEX_op_divu_i64, { "r", "r", "r" } },
2099
2100     { INDEX_op_neg_i64, { "r", "r" } },
2101     { INDEX_op_not_i64, { "r", "r" } },
2102
2103     { INDEX_op_qemu_ld_i32, { "r", "L" } },
2104     { INDEX_op_qemu_ld_i64, { "r", "L" } },
2105     { INDEX_op_qemu_st_i32, { "S", "S" } },
2106     { INDEX_op_qemu_st_i64, { "S", "S" } },
2107
2108     { INDEX_op_ext8s_i32, { "r", "r" } },
2109     { INDEX_op_ext16s_i32, { "r", "r" } },
2110     { INDEX_op_ext8s_i64, { "r", "r" } },
2111     { INDEX_op_ext16s_i64, { "r", "r" } },
2112     { INDEX_op_ext32s_i64, { "r", "r" } },
2113
2114     { INDEX_op_setcond_i32, { "r", "r", "ri" } },
2115     { INDEX_op_setcond_i64, { "r", "r", "ri" } },
2116     { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } },
2117     { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } },
2118
2119     { INDEX_op_bswap16_i32, { "r", "r" } },
2120     { INDEX_op_bswap16_i64, { "r", "r" } },
2121     { INDEX_op_bswap32_i32, { "r", "r" } },
2122     { INDEX_op_bswap32_i64, { "r", "r" } },
2123     { INDEX_op_bswap64_i64, { "r", "r" } },
2124
2125     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2126     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
2127
2128     { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
2129     { INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } },
2130     { INDEX_op_mulsh_i64, { "r", "r", "r" } },
2131     { INDEX_op_muluh_i64, { "r", "r", "r" } },
2132
2133     { -1 },
2134 };
2135
2136 static void tcg_target_init(TCGContext *s)
2137 {
2138     unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2139     if (hwcap & PPC_FEATURE_ARCH_2_06) {
2140         have_isa_2_06 = true;
2141     }
2142
2143     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
2144     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
2145     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2146                      (1 << TCG_REG_R0) |
2147                      (1 << TCG_REG_R2) |
2148                      (1 << TCG_REG_R3) |
2149                      (1 << TCG_REG_R4) |
2150                      (1 << TCG_REG_R5) |
2151                      (1 << TCG_REG_R6) |
2152                      (1 << TCG_REG_R7) |
2153                      (1 << TCG_REG_R8) |
2154                      (1 << TCG_REG_R9) |
2155                      (1 << TCG_REG_R10) |
2156                      (1 << TCG_REG_R11) |
2157                      (1 << TCG_REG_R12));
2158
2159     tcg_regset_clear(s->reserved_regs);
2160     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */
2161     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
2162     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* mem temp */
2163 #ifdef __APPLE__
2164     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R11); /* ??? */
2165 #endif
2166     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2167
2168     tcg_add_target_add_op_defs(ppc_op_defs);
2169 }
2170
2171 typedef struct {
2172     DebugFrameCIE cie;
2173     DebugFrameFDEHeader fde;
2174     uint8_t fde_def_cfa[4];
2175     uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2176 } DebugFrame;
2177
2178 /* We're expecting a 2 byte uleb128 encoded value.  */
2179 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2180
2181 #define ELF_HOST_MACHINE EM_PPC64
2182
2183 static DebugFrame debug_frame = {
2184     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2185     .cie.id = -1,
2186     .cie.version = 1,
2187     .cie.code_align = 1,
2188     .cie.data_align = 0x78,             /* sleb128 -8 */
2189     .cie.return_column = 65,
2190
2191     /* Total FDE size does not include the "len" member.  */
2192     .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2193
2194     .fde_def_cfa = {
2195         12, 1,                          /* DW_CFA_def_cfa r1, ... */
2196         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
2197         (FRAME_SIZE >> 7)
2198     },
2199     .fde_reg_ofs = {
2200         0x11, 65, 0x7e,                 /* DW_CFA_offset_extended_sf, lr, 16 */
2201     }
2202 };
2203
2204 void tcg_register_jit(void *buf, size_t buf_size)
2205 {
2206     uint8_t *p = &debug_frame.fde_reg_ofs[3];
2207     int i;
2208
2209     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2210         p[0] = 0x80 + tcg_target_callee_save_regs[i];
2211         p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * 8)) / 8;
2212     }
2213
2214     debug_frame.fde.func_start = (tcg_target_long) buf;
2215     debug_frame.fde.func_len = buf_size;
2216
2217     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2218 }
This page took 0.142246 seconds and 4 git commands to generate.