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