target/arm: Restrict v7A TCG cpus to TCG accel
[qemu/ar7.git] / tcg / ppc / tcg-target.c.inc
blob4377d15d623f3e0e571b44b66cffc0c73d8f9a95
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  */
25 #include "elf.h"
26 #include "../tcg-pool.c.inc"
28 #if defined _CALL_DARWIN || defined __APPLE__
29 #define TCG_TARGET_CALL_DARWIN
30 #endif
31 #ifdef _CALL_SYSV
32 # define TCG_TARGET_CALL_ALIGN_ARGS   1
33 #endif
35 /* For some memory operations, we need a scratch that isn't R0.  For the AIX
36    calling convention, we can re-use the TOC register since we'll be reloading
37    it at every call.  Otherwise R12 will do nicely as neither a call-saved
38    register nor a parameter register.  */
39 #ifdef _CALL_AIX
40 # define TCG_REG_TMP1   TCG_REG_R2
41 #else
42 # define TCG_REG_TMP1   TCG_REG_R12
43 #endif
45 #define TCG_VEC_TMP1    TCG_REG_V0
46 #define TCG_VEC_TMP2    TCG_REG_V1
48 #define TCG_REG_TB     TCG_REG_R31
49 #define USE_REG_TB     (TCG_TARGET_REG_BITS == 64)
51 /* Shorthand for size of a pointer.  Avoid promotion to unsigned.  */
52 #define SZP  ((int)sizeof(void *))
54 /* Shorthand for size of a register.  */
55 #define SZR  (TCG_TARGET_REG_BITS / 8)
57 #define TCG_CT_CONST_S16  0x100
58 #define TCG_CT_CONST_U16  0x200
59 #define TCG_CT_CONST_S32  0x400
60 #define TCG_CT_CONST_U32  0x800
61 #define TCG_CT_CONST_ZERO 0x1000
62 #define TCG_CT_CONST_MONE 0x2000
63 #define TCG_CT_CONST_WSZ  0x4000
65 #define ALL_GENERAL_REGS  0xffffffffu
66 #define ALL_VECTOR_REGS   0xffffffff00000000ull
68 #ifdef CONFIG_SOFTMMU
69 #define ALL_QLOAD_REGS \
70     (ALL_GENERAL_REGS & \
71      ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | (1 << TCG_REG_R5)))
72 #define ALL_QSTORE_REGS \
73     (ALL_GENERAL_REGS & ~((1 << TCG_REG_R3) | (1 << TCG_REG_R4) | \
74                           (1 << TCG_REG_R5) | (1 << TCG_REG_R6)))
75 #else
76 #define ALL_QLOAD_REGS  (ALL_GENERAL_REGS & ~(1 << TCG_REG_R3))
77 #define ALL_QSTORE_REGS ALL_QLOAD_REGS
78 #endif
80 TCGPowerISA have_isa;
81 static bool have_isel;
82 bool have_altivec;
83 bool have_vsx;
85 #ifndef CONFIG_SOFTMMU
86 #define TCG_GUEST_BASE_REG 30
87 #endif
89 #ifdef CONFIG_DEBUG_TCG
90 static const char tcg_target_reg_names[TCG_TARGET_NB_REGS][4] = {
91     "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
92     "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
93     "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
94     "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
95     "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
96     "v8",  "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
97     "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
98     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
100 #endif
102 static const int tcg_target_reg_alloc_order[] = {
103     TCG_REG_R14,  /* call saved registers */
104     TCG_REG_R15,
105     TCG_REG_R16,
106     TCG_REG_R17,
107     TCG_REG_R18,
108     TCG_REG_R19,
109     TCG_REG_R20,
110     TCG_REG_R21,
111     TCG_REG_R22,
112     TCG_REG_R23,
113     TCG_REG_R24,
114     TCG_REG_R25,
115     TCG_REG_R26,
116     TCG_REG_R27,
117     TCG_REG_R28,
118     TCG_REG_R29,
119     TCG_REG_R30,
120     TCG_REG_R31,
121     TCG_REG_R12,  /* call clobbered, non-arguments */
122     TCG_REG_R11,
123     TCG_REG_R2,
124     TCG_REG_R13,
125     TCG_REG_R10,  /* call clobbered, arguments */
126     TCG_REG_R9,
127     TCG_REG_R8,
128     TCG_REG_R7,
129     TCG_REG_R6,
130     TCG_REG_R5,
131     TCG_REG_R4,
132     TCG_REG_R3,
134     /* V0 and V1 reserved as temporaries; V20 - V31 are call-saved */
135     TCG_REG_V2,   /* call clobbered, vectors */
136     TCG_REG_V3,
137     TCG_REG_V4,
138     TCG_REG_V5,
139     TCG_REG_V6,
140     TCG_REG_V7,
141     TCG_REG_V8,
142     TCG_REG_V9,
143     TCG_REG_V10,
144     TCG_REG_V11,
145     TCG_REG_V12,
146     TCG_REG_V13,
147     TCG_REG_V14,
148     TCG_REG_V15,
149     TCG_REG_V16,
150     TCG_REG_V17,
151     TCG_REG_V18,
152     TCG_REG_V19,
155 static const int tcg_target_call_iarg_regs[] = {
156     TCG_REG_R3,
157     TCG_REG_R4,
158     TCG_REG_R5,
159     TCG_REG_R6,
160     TCG_REG_R7,
161     TCG_REG_R8,
162     TCG_REG_R9,
163     TCG_REG_R10
166 static const int tcg_target_call_oarg_regs[] = {
167     TCG_REG_R3,
168     TCG_REG_R4
171 static const int tcg_target_callee_save_regs[] = {
172 #ifdef TCG_TARGET_CALL_DARWIN
173     TCG_REG_R11,
174 #endif
175     TCG_REG_R14,
176     TCG_REG_R15,
177     TCG_REG_R16,
178     TCG_REG_R17,
179     TCG_REG_R18,
180     TCG_REG_R19,
181     TCG_REG_R20,
182     TCG_REG_R21,
183     TCG_REG_R22,
184     TCG_REG_R23,
185     TCG_REG_R24,
186     TCG_REG_R25,
187     TCG_REG_R26,
188     TCG_REG_R27, /* currently used for the global env */
189     TCG_REG_R28,
190     TCG_REG_R29,
191     TCG_REG_R30,
192     TCG_REG_R31
195 static inline bool in_range_b(tcg_target_long target)
197     return target == sextract64(target, 0, 26);
200 static uint32_t reloc_pc24_val(const tcg_insn_unit *pc,
201                                const tcg_insn_unit *target)
203     ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
204     tcg_debug_assert(in_range_b(disp));
205     return disp & 0x3fffffc;
208 static bool reloc_pc24(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
210     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
211     ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx);
213     if (in_range_b(disp)) {
214         *src_rw = (*src_rw & ~0x3fffffc) | (disp & 0x3fffffc);
215         return true;
216     }
217     return false;
220 static uint16_t reloc_pc14_val(const tcg_insn_unit *pc,
221                                const tcg_insn_unit *target)
223     ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
224     tcg_debug_assert(disp == (int16_t) disp);
225     return disp & 0xfffc;
228 static bool reloc_pc14(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
230     const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
231     ptrdiff_t disp = tcg_ptr_byte_diff(target, src_rx);
233     if (disp == (int16_t) disp) {
234         *src_rw = (*src_rw & ~0xfffc) | (disp & 0xfffc);
235         return true;
236     }
237     return false;
240 /* test if a constant matches the constraint */
241 static int tcg_target_const_match(tcg_target_long val, TCGType type,
242                                   const TCGArgConstraint *arg_ct)
244     int ct = arg_ct->ct;
245     if (ct & TCG_CT_CONST) {
246         return 1;
247     }
249     /* The only 32-bit constraint we use aside from
250        TCG_CT_CONST is TCG_CT_CONST_S16.  */
251     if (type == TCG_TYPE_I32) {
252         val = (int32_t)val;
253     }
255     if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
256         return 1;
257     } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
258         return 1;
259     } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
260         return 1;
261     } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
262         return 1;
263     } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
264         return 1;
265     } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
266         return 1;
267     } else if ((ct & TCG_CT_CONST_WSZ)
268                && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
269         return 1;
270     }
271     return 0;
274 #define OPCD(opc) ((opc)<<26)
275 #define XO19(opc) (OPCD(19)|((opc)<<1))
276 #define MD30(opc) (OPCD(30)|((opc)<<2))
277 #define MDS30(opc) (OPCD(30)|((opc)<<1))
278 #define XO31(opc) (OPCD(31)|((opc)<<1))
279 #define XO58(opc) (OPCD(58)|(opc))
280 #define XO62(opc) (OPCD(62)|(opc))
281 #define VX4(opc)  (OPCD(4)|(opc))
283 #define B      OPCD( 18)
284 #define BC     OPCD( 16)
285 #define LBZ    OPCD( 34)
286 #define LHZ    OPCD( 40)
287 #define LHA    OPCD( 42)
288 #define LWZ    OPCD( 32)
289 #define LWZUX  XO31( 55)
290 #define STB    OPCD( 38)
291 #define STH    OPCD( 44)
292 #define STW    OPCD( 36)
294 #define STD    XO62(  0)
295 #define STDU   XO62(  1)
296 #define STDX   XO31(149)
298 #define LD     XO58(  0)
299 #define LDX    XO31( 21)
300 #define LDU    XO58(  1)
301 #define LDUX   XO31( 53)
302 #define LWA    XO58(  2)
303 #define LWAX   XO31(341)
305 #define ADDIC  OPCD( 12)
306 #define ADDI   OPCD( 14)
307 #define ADDIS  OPCD( 15)
308 #define ORI    OPCD( 24)
309 #define ORIS   OPCD( 25)
310 #define XORI   OPCD( 26)
311 #define XORIS  OPCD( 27)
312 #define ANDI   OPCD( 28)
313 #define ANDIS  OPCD( 29)
314 #define MULLI  OPCD(  7)
315 #define CMPLI  OPCD( 10)
316 #define CMPI   OPCD( 11)
317 #define SUBFIC OPCD( 8)
319 #define LWZU   OPCD( 33)
320 #define STWU   OPCD( 37)
322 #define RLWIMI OPCD( 20)
323 #define RLWINM OPCD( 21)
324 #define RLWNM  OPCD( 23)
326 #define RLDICL MD30(  0)
327 #define RLDICR MD30(  1)
328 #define RLDIMI MD30(  3)
329 #define RLDCL  MDS30( 8)
331 #define BCLR   XO19( 16)
332 #define BCCTR  XO19(528)
333 #define CRAND  XO19(257)
334 #define CRANDC XO19(129)
335 #define CRNAND XO19(225)
336 #define CROR   XO19(449)
337 #define CRNOR  XO19( 33)
339 #define EXTSB  XO31(954)
340 #define EXTSH  XO31(922)
341 #define EXTSW  XO31(986)
342 #define ADD    XO31(266)
343 #define ADDE   XO31(138)
344 #define ADDME  XO31(234)
345 #define ADDZE  XO31(202)
346 #define ADDC   XO31( 10)
347 #define AND    XO31( 28)
348 #define SUBF   XO31( 40)
349 #define SUBFC  XO31(  8)
350 #define SUBFE  XO31(136)
351 #define SUBFME XO31(232)
352 #define SUBFZE XO31(200)
353 #define OR     XO31(444)
354 #define XOR    XO31(316)
355 #define MULLW  XO31(235)
356 #define MULHW  XO31( 75)
357 #define MULHWU XO31( 11)
358 #define DIVW   XO31(491)
359 #define DIVWU  XO31(459)
360 #define CMP    XO31(  0)
361 #define CMPL   XO31( 32)
362 #define LHBRX  XO31(790)
363 #define LWBRX  XO31(534)
364 #define LDBRX  XO31(532)
365 #define STHBRX XO31(918)
366 #define STWBRX XO31(662)
367 #define STDBRX XO31(660)
368 #define MFSPR  XO31(339)
369 #define MTSPR  XO31(467)
370 #define SRAWI  XO31(824)
371 #define NEG    XO31(104)
372 #define MFCR   XO31( 19)
373 #define MFOCRF (MFCR | (1u << 20))
374 #define NOR    XO31(124)
375 #define CNTLZW XO31( 26)
376 #define CNTLZD XO31( 58)
377 #define CNTTZW XO31(538)
378 #define CNTTZD XO31(570)
379 #define CNTPOPW XO31(378)
380 #define CNTPOPD XO31(506)
381 #define ANDC   XO31( 60)
382 #define ORC    XO31(412)
383 #define EQV    XO31(284)
384 #define NAND   XO31(476)
385 #define ISEL   XO31( 15)
387 #define MULLD  XO31(233)
388 #define MULHD  XO31( 73)
389 #define MULHDU XO31(  9)
390 #define DIVD   XO31(489)
391 #define DIVDU  XO31(457)
393 #define LBZX   XO31( 87)
394 #define LHZX   XO31(279)
395 #define LHAX   XO31(343)
396 #define LWZX   XO31( 23)
397 #define STBX   XO31(215)
398 #define STHX   XO31(407)
399 #define STWX   XO31(151)
401 #define EIEIO  XO31(854)
402 #define HWSYNC XO31(598)
403 #define LWSYNC (HWSYNC | (1u << 21))
405 #define SPR(a, b) ((((a)<<5)|(b))<<11)
406 #define LR     SPR(8, 0)
407 #define CTR    SPR(9, 0)
409 #define SLW    XO31( 24)
410 #define SRW    XO31(536)
411 #define SRAW   XO31(792)
413 #define SLD    XO31( 27)
414 #define SRD    XO31(539)
415 #define SRAD   XO31(794)
416 #define SRADI  XO31(413<<1)
418 #define TW     XO31( 4)
419 #define TRAP   (TW | TO(31))
421 #define NOP    ORI  /* ori 0,0,0 */
423 #define LVX        XO31(103)
424 #define LVEBX      XO31(7)
425 #define LVEHX      XO31(39)
426 #define LVEWX      XO31(71)
427 #define LXSDX      (XO31(588) | 1)  /* v2.06, force tx=1 */
428 #define LXVDSX     (XO31(332) | 1)  /* v2.06, force tx=1 */
429 #define LXSIWZX    (XO31(12) | 1)   /* v2.07, force tx=1 */
430 #define LXV        (OPCD(61) | 8 | 1)  /* v3.00, force tx=1 */
431 #define LXSD       (OPCD(57) | 2)   /* v3.00 */
432 #define LXVWSX     (XO31(364) | 1)  /* v3.00, force tx=1 */
434 #define STVX       XO31(231)
435 #define STVEWX     XO31(199)
436 #define STXSDX     (XO31(716) | 1)  /* v2.06, force sx=1 */
437 #define STXSIWX    (XO31(140) | 1)  /* v2.07, force sx=1 */
438 #define STXV       (OPCD(61) | 8 | 5) /* v3.00, force sx=1 */
439 #define STXSD      (OPCD(61) | 2)   /* v3.00 */
441 #define VADDSBS    VX4(768)
442 #define VADDUBS    VX4(512)
443 #define VADDUBM    VX4(0)
444 #define VADDSHS    VX4(832)
445 #define VADDUHS    VX4(576)
446 #define VADDUHM    VX4(64)
447 #define VADDSWS    VX4(896)
448 #define VADDUWS    VX4(640)
449 #define VADDUWM    VX4(128)
450 #define VADDUDM    VX4(192)       /* v2.07 */
452 #define VSUBSBS    VX4(1792)
453 #define VSUBUBS    VX4(1536)
454 #define VSUBUBM    VX4(1024)
455 #define VSUBSHS    VX4(1856)
456 #define VSUBUHS    VX4(1600)
457 #define VSUBUHM    VX4(1088)
458 #define VSUBSWS    VX4(1920)
459 #define VSUBUWS    VX4(1664)
460 #define VSUBUWM    VX4(1152)
461 #define VSUBUDM    VX4(1216)      /* v2.07 */
463 #define VNEGW      (VX4(1538) | (6 << 16))  /* v3.00 */
464 #define VNEGD      (VX4(1538) | (7 << 16))  /* v3.00 */
466 #define VMAXSB     VX4(258)
467 #define VMAXSH     VX4(322)
468 #define VMAXSW     VX4(386)
469 #define VMAXSD     VX4(450)       /* v2.07 */
470 #define VMAXUB     VX4(2)
471 #define VMAXUH     VX4(66)
472 #define VMAXUW     VX4(130)
473 #define VMAXUD     VX4(194)       /* v2.07 */
474 #define VMINSB     VX4(770)
475 #define VMINSH     VX4(834)
476 #define VMINSW     VX4(898)
477 #define VMINSD     VX4(962)       /* v2.07 */
478 #define VMINUB     VX4(514)
479 #define VMINUH     VX4(578)
480 #define VMINUW     VX4(642)
481 #define VMINUD     VX4(706)       /* v2.07 */
483 #define VCMPEQUB   VX4(6)
484 #define VCMPEQUH   VX4(70)
485 #define VCMPEQUW   VX4(134)
486 #define VCMPEQUD   VX4(199)       /* v2.07 */
487 #define VCMPGTSB   VX4(774)
488 #define VCMPGTSH   VX4(838)
489 #define VCMPGTSW   VX4(902)
490 #define VCMPGTSD   VX4(967)       /* v2.07 */
491 #define VCMPGTUB   VX4(518)
492 #define VCMPGTUH   VX4(582)
493 #define VCMPGTUW   VX4(646)
494 #define VCMPGTUD   VX4(711)       /* v2.07 */
495 #define VCMPNEB    VX4(7)         /* v3.00 */
496 #define VCMPNEH    VX4(71)        /* v3.00 */
497 #define VCMPNEW    VX4(135)       /* v3.00 */
499 #define VSLB       VX4(260)
500 #define VSLH       VX4(324)
501 #define VSLW       VX4(388)
502 #define VSLD       VX4(1476)      /* v2.07 */
503 #define VSRB       VX4(516)
504 #define VSRH       VX4(580)
505 #define VSRW       VX4(644)
506 #define VSRD       VX4(1732)      /* v2.07 */
507 #define VSRAB      VX4(772)
508 #define VSRAH      VX4(836)
509 #define VSRAW      VX4(900)
510 #define VSRAD      VX4(964)       /* v2.07 */
511 #define VRLB       VX4(4)
512 #define VRLH       VX4(68)
513 #define VRLW       VX4(132)
514 #define VRLD       VX4(196)       /* v2.07 */
516 #define VMULEUB    VX4(520)
517 #define VMULEUH    VX4(584)
518 #define VMULEUW    VX4(648)       /* v2.07 */
519 #define VMULOUB    VX4(8)
520 #define VMULOUH    VX4(72)
521 #define VMULOUW    VX4(136)       /* v2.07 */
522 #define VMULUWM    VX4(137)       /* v2.07 */
523 #define VMULLD     VX4(457)       /* v3.10 */
524 #define VMSUMUHM   VX4(38)
526 #define VMRGHB     VX4(12)
527 #define VMRGHH     VX4(76)
528 #define VMRGHW     VX4(140)
529 #define VMRGLB     VX4(268)
530 #define VMRGLH     VX4(332)
531 #define VMRGLW     VX4(396)
533 #define VPKUHUM    VX4(14)
534 #define VPKUWUM    VX4(78)
536 #define VAND       VX4(1028)
537 #define VANDC      VX4(1092)
538 #define VNOR       VX4(1284)
539 #define VOR        VX4(1156)
540 #define VXOR       VX4(1220)
541 #define VEQV       VX4(1668)      /* v2.07 */
542 #define VNAND      VX4(1412)      /* v2.07 */
543 #define VORC       VX4(1348)      /* v2.07 */
545 #define VSPLTB     VX4(524)
546 #define VSPLTH     VX4(588)
547 #define VSPLTW     VX4(652)
548 #define VSPLTISB   VX4(780)
549 #define VSPLTISH   VX4(844)
550 #define VSPLTISW   VX4(908)
552 #define VSLDOI     VX4(44)
554 #define XXPERMDI   (OPCD(60) | (10 << 3) | 7)  /* v2.06, force ax=bx=tx=1 */
555 #define XXSEL      (OPCD(60) | (3 << 4) | 0xf) /* v2.06, force ax=bx=cx=tx=1 */
556 #define XXSPLTIB   (OPCD(60) | (360 << 1) | 1) /* v3.00, force tx=1 */
558 #define MFVSRD     (XO31(51) | 1)   /* v2.07, force sx=1 */
559 #define MFVSRWZ    (XO31(115) | 1)  /* v2.07, force sx=1 */
560 #define MTVSRD     (XO31(179) | 1)  /* v2.07, force tx=1 */
561 #define MTVSRWZ    (XO31(243) | 1)  /* v2.07, force tx=1 */
562 #define MTVSRDD    (XO31(435) | 1)  /* v3.00, force tx=1 */
563 #define MTVSRWS    (XO31(403) | 1)  /* v3.00, force tx=1 */
565 #define RT(r) ((r)<<21)
566 #define RS(r) ((r)<<21)
567 #define RA(r) ((r)<<16)
568 #define RB(r) ((r)<<11)
569 #define TO(t) ((t)<<21)
570 #define SH(s) ((s)<<11)
571 #define MB(b) ((b)<<6)
572 #define ME(e) ((e)<<1)
573 #define BO(o) ((o)<<21)
574 #define MB64(b) ((b)<<5)
575 #define FXM(b) (1 << (19 - (b)))
577 #define VRT(r)  (((r) & 31) << 21)
578 #define VRA(r)  (((r) & 31) << 16)
579 #define VRB(r)  (((r) & 31) << 11)
580 #define VRC(r)  (((r) & 31) <<  6)
582 #define LK    1
584 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
585 #define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
586 #define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
587 #define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
589 #define BF(n)    ((n)<<23)
590 #define BI(n, c) (((c)+((n)*4))<<16)
591 #define BT(n, c) (((c)+((n)*4))<<21)
592 #define BA(n, c) (((c)+((n)*4))<<16)
593 #define BB(n, c) (((c)+((n)*4))<<11)
594 #define BC_(n, c) (((c)+((n)*4))<<6)
596 #define BO_COND_TRUE  BO(12)
597 #define BO_COND_FALSE BO( 4)
598 #define BO_ALWAYS     BO(20)
600 enum {
601     CR_LT,
602     CR_GT,
603     CR_EQ,
604     CR_SO
607 static const uint32_t tcg_to_bc[] = {
608     [TCG_COND_EQ]  = BC | BI(7, CR_EQ) | BO_COND_TRUE,
609     [TCG_COND_NE]  = BC | BI(7, CR_EQ) | BO_COND_FALSE,
610     [TCG_COND_LT]  = BC | BI(7, CR_LT) | BO_COND_TRUE,
611     [TCG_COND_GE]  = BC | BI(7, CR_LT) | BO_COND_FALSE,
612     [TCG_COND_LE]  = BC | BI(7, CR_GT) | BO_COND_FALSE,
613     [TCG_COND_GT]  = BC | BI(7, CR_GT) | BO_COND_TRUE,
614     [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
615     [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
616     [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
617     [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
620 /* The low bit here is set if the RA and RB fields must be inverted.  */
621 static const uint32_t tcg_to_isel[] = {
622     [TCG_COND_EQ]  = ISEL | BC_(7, CR_EQ),
623     [TCG_COND_NE]  = ISEL | BC_(7, CR_EQ) | 1,
624     [TCG_COND_LT]  = ISEL | BC_(7, CR_LT),
625     [TCG_COND_GE]  = ISEL | BC_(7, CR_LT) | 1,
626     [TCG_COND_LE]  = ISEL | BC_(7, CR_GT) | 1,
627     [TCG_COND_GT]  = ISEL | BC_(7, CR_GT),
628     [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
629     [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
630     [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
631     [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
634 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
635                         intptr_t value, intptr_t addend)
637     const tcg_insn_unit *target;
638     int16_t lo;
639     int32_t hi;
641     value += addend;
642     target = (const tcg_insn_unit *)value;
644     switch (type) {
645     case R_PPC_REL14:
646         return reloc_pc14(code_ptr, target);
647     case R_PPC_REL24:
648         return reloc_pc24(code_ptr, target);
649     case R_PPC_ADDR16:
650         /*
651          * We are (slightly) abusing this relocation type.  In particular,
652          * assert that the low 2 bits are zero, and do not modify them.
653          * That way we can use this with LD et al that have opcode bits
654          * in the low 2 bits of the insn.
655          */
656         if ((value & 3) || value != (int16_t)value) {
657             return false;
658         }
659         *code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
660         break;
661     case R_PPC_ADDR32:
662         /*
663          * We are abusing this relocation type.  Again, this points to
664          * a pair of insns, lis + load.  This is an absolute address
665          * relocation for PPC32 so the lis cannot be removed.
666          */
667         lo = value;
668         hi = value - lo;
669         if (hi + lo != value) {
670             return false;
671         }
672         code_ptr[0] = deposit32(code_ptr[0], 0, 16, hi >> 16);
673         code_ptr[1] = deposit32(code_ptr[1], 0, 16, lo);
674         break;
675     default:
676         g_assert_not_reached();
677     }
678     return true;
681 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
682                              TCGReg base, tcg_target_long offset);
684 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
686     if (ret == arg) {
687         return true;
688     }
689     switch (type) {
690     case TCG_TYPE_I64:
691         tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
692         /* fallthru */
693     case TCG_TYPE_I32:
694         if (ret < TCG_REG_V0) {
695             if (arg < TCG_REG_V0) {
696                 tcg_out32(s, OR | SAB(arg, ret, arg));
697                 break;
698             } else if (have_isa_2_07) {
699                 tcg_out32(s, (type == TCG_TYPE_I32 ? MFVSRWZ : MFVSRD)
700                           | VRT(arg) | RA(ret));
701                 break;
702             } else {
703                 /* Altivec does not support vector->integer moves.  */
704                 return false;
705             }
706         } else if (arg < TCG_REG_V0) {
707             if (have_isa_2_07) {
708                 tcg_out32(s, (type == TCG_TYPE_I32 ? MTVSRWZ : MTVSRD)
709                           | VRT(ret) | RA(arg));
710                 break;
711             } else {
712                 /* Altivec does not support integer->vector moves.  */
713                 return false;
714             }
715         }
716         /* fallthru */
717     case TCG_TYPE_V64:
718     case TCG_TYPE_V128:
719         tcg_debug_assert(ret >= TCG_REG_V0 && arg >= TCG_REG_V0);
720         tcg_out32(s, VOR | VRT(ret) | VRA(arg) | VRB(arg));
721         break;
722     default:
723         g_assert_not_reached();
724     }
725     return true;
728 static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
729                                int sh, int mb)
731     tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
732     sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
733     mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
734     tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
737 static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
738                                int sh, int mb, int me)
740     tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
743 static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
745     tcg_out_rld(s, RLDICL, dst, src, 0, 32);
748 static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
750     tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
753 static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
755     tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
758 static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c)
760     tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31);
763 static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
765     tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
768 /* Emit a move into ret of arg, if it can be done in one insn.  */
769 static bool tcg_out_movi_one(TCGContext *s, TCGReg ret, tcg_target_long arg)
771     if (arg == (int16_t)arg) {
772         tcg_out32(s, ADDI | TAI(ret, 0, arg));
773         return true;
774     }
775     if (arg == (int32_t)arg && (arg & 0xffff) == 0) {
776         tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
777         return true;
778     }
779     return false;
782 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
783                              tcg_target_long arg, bool in_prologue)
785     intptr_t tb_diff;
786     tcg_target_long tmp;
787     int shift;
789     tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
791     if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
792         arg = (int32_t)arg;
793     }
795     /* Load 16-bit immediates with one insn.  */
796     if (tcg_out_movi_one(s, ret, arg)) {
797         return;
798     }
800     /* Load addresses within the TB with one insn.  */
801     tb_diff = tcg_tbrel_diff(s, (void *)arg);
802     if (!in_prologue && USE_REG_TB && tb_diff == (int16_t)tb_diff) {
803         tcg_out32(s, ADDI | TAI(ret, TCG_REG_TB, tb_diff));
804         return;
805     }
807     /* Load 32-bit immediates with two insns.  Note that we've already
808        eliminated bare ADDIS, so we know both insns are required.  */
809     if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {
810         tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
811         tcg_out32(s, ORI | SAI(ret, ret, arg));
812         return;
813     }
814     if (arg == (uint32_t)arg && !(arg & 0x8000)) {
815         tcg_out32(s, ADDI | TAI(ret, 0, arg));
816         tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
817         return;
818     }
820     /* Load masked 16-bit value.  */
821     if (arg > 0 && (arg & 0x8000)) {
822         tmp = arg | 0x7fff;
823         if ((tmp & (tmp + 1)) == 0) {
824             int mb = clz64(tmp + 1) + 1;
825             tcg_out32(s, ADDI | TAI(ret, 0, arg));
826             tcg_out_rld(s, RLDICL, ret, ret, 0, mb);
827             return;
828         }
829     }
831     /* Load common masks with 2 insns.  */
832     shift = ctz64(arg);
833     tmp = arg >> shift;
834     if (tmp == (int16_t)tmp) {
835         tcg_out32(s, ADDI | TAI(ret, 0, tmp));
836         tcg_out_shli64(s, ret, ret, shift);
837         return;
838     }
839     shift = clz64(arg);
840     if (tcg_out_movi_one(s, ret, arg << shift)) {
841         tcg_out_shri64(s, ret, ret, shift);
842         return;
843     }
845     /* Load addresses within 2GB of TB with 2 (or rarely 3) insns.  */
846     if (!in_prologue && USE_REG_TB && tb_diff == (int32_t)tb_diff) {
847         tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_TB, tb_diff);
848         return;
849     }
851     /* Use the constant pool, if possible.  */
852     if (!in_prologue && USE_REG_TB) {
853         new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
854                        tcg_tbrel_diff(s, NULL));
855         tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
856         return;
857     }
859     tmp = arg >> 31 >> 1;
860     tcg_out_movi(s, TCG_TYPE_I32, ret, tmp);
861     if (tmp) {
862         tcg_out_shli64(s, ret, ret, 32);
863     }
864     if (arg & 0xffff0000) {
865         tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
866     }
867     if (arg & 0xffff) {
868         tcg_out32(s, ORI | SAI(ret, ret, arg));
869     }
872 static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
873                              TCGReg ret, int64_t val)
875     uint32_t load_insn;
876     int rel, low;
877     intptr_t add;
879     switch (vece) {
880     case MO_8:
881         low = (int8_t)val;
882         if (low >= -16 && low < 16) {
883             tcg_out32(s, VSPLTISB | VRT(ret) | ((val & 31) << 16));
884             return;
885         }
886         if (have_isa_3_00) {
887             tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11));
888             return;
889         }
890         break;
892     case MO_16:
893         low = (int16_t)val;
894         if (low >= -16 && low < 16) {
895             tcg_out32(s, VSPLTISH | VRT(ret) | ((val & 31) << 16));
896             return;
897         }
898         break;
900     case MO_32:
901         low = (int32_t)val;
902         if (low >= -16 && low < 16) {
903             tcg_out32(s, VSPLTISW | VRT(ret) | ((val & 31) << 16));
904             return;
905         }
906         break;
907     }
909     /*
910      * Otherwise we must load the value from the constant pool.
911      */
912     if (USE_REG_TB) {
913         rel = R_PPC_ADDR16;
914         add = tcg_tbrel_diff(s, NULL);
915     } else {
916         rel = R_PPC_ADDR32;
917         add = 0;
918     }
920     if (have_vsx) {
921         load_insn = type == TCG_TYPE_V64 ? LXSDX : LXVDSX;
922         load_insn |= VRT(ret) | RB(TCG_REG_TMP1);
923         if (TCG_TARGET_REG_BITS == 64) {
924             new_pool_label(s, val, rel, s->code_ptr, add);
925         } else {
926             new_pool_l2(s, rel, s->code_ptr, add, val >> 32, val);
927         }
928     } else {
929         load_insn = LVX | VRT(ret) | RB(TCG_REG_TMP1);
930         if (TCG_TARGET_REG_BITS == 64) {
931             new_pool_l2(s, rel, s->code_ptr, add, val, val);
932         } else {
933             new_pool_l4(s, rel, s->code_ptr, add,
934                         val >> 32, val, val >> 32, val);
935         }
936     }
938     if (USE_REG_TB) {
939         tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, 0, 0));
940         load_insn |= RA(TCG_REG_TB);
941     } else {
942         tcg_out32(s, ADDIS | TAI(TCG_REG_TMP1, 0, 0));
943         tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, TCG_REG_TMP1, 0));
944     }
945     tcg_out32(s, load_insn);
948 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
949                          tcg_target_long arg)
951     switch (type) {
952     case TCG_TYPE_I32:
953     case TCG_TYPE_I64:
954         tcg_debug_assert(ret < TCG_REG_V0);
955         tcg_out_movi_int(s, type, ret, arg, false);
956         break;
958     default:
959         g_assert_not_reached();
960     }
963 static bool mask_operand(uint32_t c, int *mb, int *me)
965     uint32_t lsb, test;
967     /* Accept a bit pattern like:
968            0....01....1
969            1....10....0
970            0..01..10..0
971        Keep track of the transitions.  */
972     if (c == 0 || c == -1) {
973         return false;
974     }
975     test = c;
976     lsb = test & -test;
977     test += lsb;
978     if (test & (test - 1)) {
979         return false;
980     }
982     *me = clz32(lsb);
983     *mb = test ? clz32(test & -test) + 1 : 0;
984     return true;
987 static bool mask64_operand(uint64_t c, int *mb, int *me)
989     uint64_t lsb;
991     if (c == 0) {
992         return false;
993     }
995     lsb = c & -c;
996     /* Accept 1..10..0.  */
997     if (c == -lsb) {
998         *mb = 0;
999         *me = clz64(lsb);
1000         return true;
1001     }
1002     /* Accept 0..01..1.  */
1003     if (lsb == 1 && (c & (c + 1)) == 0) {
1004         *mb = clz64(c + 1) + 1;
1005         *me = 63;
1006         return true;
1007     }
1008     return false;
1011 static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
1013     int mb, me;
1015     if (mask_operand(c, &mb, &me)) {
1016         tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
1017     } else if ((c & 0xffff) == c) {
1018         tcg_out32(s, ANDI | SAI(src, dst, c));
1019         return;
1020     } else if ((c & 0xffff0000) == c) {
1021         tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
1022         return;
1023     } else {
1024         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
1025         tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
1026     }
1029 static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
1031     int mb, me;
1033     tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
1034     if (mask64_operand(c, &mb, &me)) {
1035         if (mb == 0) {
1036             tcg_out_rld(s, RLDICR, dst, src, 0, me);
1037         } else {
1038             tcg_out_rld(s, RLDICL, dst, src, 0, mb);
1039         }
1040     } else if ((c & 0xffff) == c) {
1041         tcg_out32(s, ANDI | SAI(src, dst, c));
1042         return;
1043     } else if ((c & 0xffff0000) == c) {
1044         tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
1045         return;
1046     } else {
1047         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
1048         tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
1049     }
1052 static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
1053                            int op_lo, int op_hi)
1055     if (c >> 16) {
1056         tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
1057         src = dst;
1058     }
1059     if (c & 0xffff) {
1060         tcg_out32(s, op_lo | SAI(src, dst, c));
1061         src = dst;
1062     }
1065 static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
1067     tcg_out_zori32(s, dst, src, c, ORI, ORIS);
1070 static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
1072     tcg_out_zori32(s, dst, src, c, XORI, XORIS);
1075 static void tcg_out_b(TCGContext *s, int mask, const tcg_insn_unit *target)
1077     ptrdiff_t disp = tcg_pcrel_diff(s, target);
1078     if (in_range_b(disp)) {
1079         tcg_out32(s, B | (disp & 0x3fffffc) | mask);
1080     } else {
1081         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
1082         tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
1083         tcg_out32(s, BCCTR | BO_ALWAYS | mask);
1084     }
1087 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
1088                              TCGReg base, tcg_target_long offset)
1090     tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
1091     bool is_int_store = false;
1092     TCGReg rs = TCG_REG_TMP1;
1094     switch (opi) {
1095     case LD: case LWA:
1096         align = 3;
1097         /* FALLTHRU */
1098     default:
1099         if (rt > TCG_REG_R0 && rt < TCG_REG_V0) {
1100             rs = rt;
1101             break;
1102         }
1103         break;
1104     case LXSD:
1105     case STXSD:
1106         align = 3;
1107         break;
1108     case LXV:
1109     case STXV:
1110         align = 15;
1111         break;
1112     case STD:
1113         align = 3;
1114         /* FALLTHRU */
1115     case STB: case STH: case STW:
1116         is_int_store = true;
1117         break;
1118     }
1120     /* For unaligned, or very large offsets, use the indexed form.  */
1121     if (offset & align || offset != (int32_t)offset || opi == 0) {
1122         if (rs == base) {
1123             rs = TCG_REG_R0;
1124         }
1125         tcg_debug_assert(!is_int_store || rs != rt);
1126         tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
1127         tcg_out32(s, opx | TAB(rt & 31, base, rs));
1128         return;
1129     }
1131     l0 = (int16_t)offset;
1132     offset = (offset - l0) >> 16;
1133     l1 = (int16_t)offset;
1135     if (l1 < 0 && orig >= 0) {
1136         extra = 0x4000;
1137         l1 = (int16_t)(offset - 0x4000);
1138     }
1139     if (l1) {
1140         tcg_out32(s, ADDIS | TAI(rs, base, l1));
1141         base = rs;
1142     }
1143     if (extra) {
1144         tcg_out32(s, ADDIS | TAI(rs, base, extra));
1145         base = rs;
1146     }
1147     if (opi != ADDI || base != rt || l0 != 0) {
1148         tcg_out32(s, opi | TAI(rt & 31, base, l0));
1149     }
1152 static void tcg_out_vsldoi(TCGContext *s, TCGReg ret,
1153                            TCGReg va, TCGReg vb, int shb)
1155     tcg_out32(s, VSLDOI | VRT(ret) | VRA(va) | VRB(vb) | (shb << 6));
1158 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
1159                        TCGReg base, intptr_t offset)
1161     int shift;
1163     switch (type) {
1164     case TCG_TYPE_I32:
1165         if (ret < TCG_REG_V0) {
1166             tcg_out_mem_long(s, LWZ, LWZX, ret, base, offset);
1167             break;
1168         }
1169         if (have_isa_2_07 && have_vsx) {
1170             tcg_out_mem_long(s, 0, LXSIWZX, ret, base, offset);
1171             break;
1172         }
1173         tcg_debug_assert((offset & 3) == 0);
1174         tcg_out_mem_long(s, 0, LVEWX, ret, base, offset);
1175         shift = (offset - 4) & 0xc;
1176         if (shift) {
1177             tcg_out_vsldoi(s, ret, ret, ret, shift);
1178         }
1179         break;
1180     case TCG_TYPE_I64:
1181         if (ret < TCG_REG_V0) {
1182             tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
1183             tcg_out_mem_long(s, LD, LDX, ret, base, offset);
1184             break;
1185         }
1186         /* fallthru */
1187     case TCG_TYPE_V64:
1188         tcg_debug_assert(ret >= TCG_REG_V0);
1189         if (have_vsx) {
1190             tcg_out_mem_long(s, have_isa_3_00 ? LXSD : 0, LXSDX,
1191                              ret, base, offset);
1192             break;
1193         }
1194         tcg_debug_assert((offset & 7) == 0);
1195         tcg_out_mem_long(s, 0, LVX, ret, base, offset & -16);
1196         if (offset & 8) {
1197             tcg_out_vsldoi(s, ret, ret, ret, 8);
1198         }
1199         break;
1200     case TCG_TYPE_V128:
1201         tcg_debug_assert(ret >= TCG_REG_V0);
1202         tcg_debug_assert((offset & 15) == 0);
1203         tcg_out_mem_long(s, have_isa_3_00 ? LXV : 0,
1204                          LVX, ret, base, offset);
1205         break;
1206     default:
1207         g_assert_not_reached();
1208     }
1211 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1212                               TCGReg base, intptr_t offset)
1214     int shift;
1216     switch (type) {
1217     case TCG_TYPE_I32:
1218         if (arg < TCG_REG_V0) {
1219             tcg_out_mem_long(s, STW, STWX, arg, base, offset);
1220             break;
1221         }
1222         if (have_isa_2_07 && have_vsx) {
1223             tcg_out_mem_long(s, 0, STXSIWX, arg, base, offset);
1224             break;
1225         }
1226         assert((offset & 3) == 0);
1227         tcg_debug_assert((offset & 3) == 0);
1228         shift = (offset - 4) & 0xc;
1229         if (shift) {
1230             tcg_out_vsldoi(s, TCG_VEC_TMP1, arg, arg, shift);
1231             arg = TCG_VEC_TMP1;
1232         }
1233         tcg_out_mem_long(s, 0, STVEWX, arg, base, offset);
1234         break;
1235     case TCG_TYPE_I64:
1236         if (arg < TCG_REG_V0) {
1237             tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
1238             tcg_out_mem_long(s, STD, STDX, arg, base, offset);
1239             break;
1240         }
1241         /* fallthru */
1242     case TCG_TYPE_V64:
1243         tcg_debug_assert(arg >= TCG_REG_V0);
1244         if (have_vsx) {
1245             tcg_out_mem_long(s, have_isa_3_00 ? STXSD : 0,
1246                              STXSDX, arg, base, offset);
1247             break;
1248         }
1249         tcg_debug_assert((offset & 7) == 0);
1250         if (offset & 8) {
1251             tcg_out_vsldoi(s, TCG_VEC_TMP1, arg, arg, 8);
1252             arg = TCG_VEC_TMP1;
1253         }
1254         tcg_out_mem_long(s, 0, STVEWX, arg, base, offset);
1255         tcg_out_mem_long(s, 0, STVEWX, arg, base, offset + 4);
1256         break;
1257     case TCG_TYPE_V128:
1258         tcg_debug_assert(arg >= TCG_REG_V0);
1259         tcg_out_mem_long(s, have_isa_3_00 ? STXV : 0,
1260                          STVX, arg, base, offset);
1261         break;
1262     default:
1263         g_assert_not_reached();
1264     }
1267 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
1268                                TCGReg base, intptr_t ofs)
1270     return false;
1273 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
1274                         int const_arg2, int cr, TCGType type)
1276     int imm;
1277     uint32_t op;
1279     tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
1281     /* Simplify the comparisons below wrt CMPI.  */
1282     if (type == TCG_TYPE_I32) {
1283         arg2 = (int32_t)arg2;
1284     }
1286     switch (cond) {
1287     case TCG_COND_EQ:
1288     case TCG_COND_NE:
1289         if (const_arg2) {
1290             if ((int16_t) arg2 == arg2) {
1291                 op = CMPI;
1292                 imm = 1;
1293                 break;
1294             } else if ((uint16_t) arg2 == arg2) {
1295                 op = CMPLI;
1296                 imm = 1;
1297                 break;
1298             }
1299         }
1300         op = CMPL;
1301         imm = 0;
1302         break;
1304     case TCG_COND_LT:
1305     case TCG_COND_GE:
1306     case TCG_COND_LE:
1307     case TCG_COND_GT:
1308         if (const_arg2) {
1309             if ((int16_t) arg2 == arg2) {
1310                 op = CMPI;
1311                 imm = 1;
1312                 break;
1313             }
1314         }
1315         op = CMP;
1316         imm = 0;
1317         break;
1319     case TCG_COND_LTU:
1320     case TCG_COND_GEU:
1321     case TCG_COND_LEU:
1322     case TCG_COND_GTU:
1323         if (const_arg2) {
1324             if ((uint16_t) arg2 == arg2) {
1325                 op = CMPLI;
1326                 imm = 1;
1327                 break;
1328             }
1329         }
1330         op = CMPL;
1331         imm = 0;
1332         break;
1334     default:
1335         tcg_abort();
1336     }
1337     op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
1339     if (imm) {
1340         tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
1341     } else {
1342         if (const_arg2) {
1343             tcg_out_movi(s, type, TCG_REG_R0, arg2);
1344             arg2 = TCG_REG_R0;
1345         }
1346         tcg_out32(s, op | RA(arg1) | RB(arg2));
1347     }
1350 static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
1351                                 TCGReg dst, TCGReg src)
1353     if (type == TCG_TYPE_I32) {
1354         tcg_out32(s, CNTLZW | RS(src) | RA(dst));
1355         tcg_out_shri32(s, dst, dst, 5);
1356     } else {
1357         tcg_out32(s, CNTLZD | RS(src) | RA(dst));
1358         tcg_out_shri64(s, dst, dst, 6);
1359     }
1362 static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
1364     /* X != 0 implies X + -1 generates a carry.  Extra addition
1365        trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C.  */
1366     if (dst != src) {
1367         tcg_out32(s, ADDIC | TAI(dst, src, -1));
1368         tcg_out32(s, SUBFE | TAB(dst, dst, src));
1369     } else {
1370         tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
1371         tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
1372     }
1375 static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
1376                                   bool const_arg2)
1378     if (const_arg2) {
1379         if ((uint32_t)arg2 == arg2) {
1380             tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
1381         } else {
1382             tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
1383             tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
1384         }
1385     } else {
1386         tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
1387     }
1388     return TCG_REG_R0;
1391 static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
1392                             TCGArg arg0, TCGArg arg1, TCGArg arg2,
1393                             int const_arg2)
1395     int crop, sh;
1397     tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
1399     /* Ignore high bits of a potential constant arg2.  */
1400     if (type == TCG_TYPE_I32) {
1401         arg2 = (uint32_t)arg2;
1402     }
1404     /* Handle common and trivial cases before handling anything else.  */
1405     if (arg2 == 0) {
1406         switch (cond) {
1407         case TCG_COND_EQ:
1408             tcg_out_setcond_eq0(s, type, arg0, arg1);
1409             return;
1410         case TCG_COND_NE:
1411             if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1412                 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1413                 arg1 = TCG_REG_R0;
1414             }
1415             tcg_out_setcond_ne0(s, arg0, arg1);
1416             return;
1417         case TCG_COND_GE:
1418             tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1419             arg1 = arg0;
1420             /* FALLTHRU */
1421         case TCG_COND_LT:
1422             /* Extract the sign bit.  */
1423             if (type == TCG_TYPE_I32) {
1424                 tcg_out_shri32(s, arg0, arg1, 31);
1425             } else {
1426                 tcg_out_shri64(s, arg0, arg1, 63);
1427             }
1428             return;
1429         default:
1430             break;
1431         }
1432     }
1434     /* If we have ISEL, we can implement everything with 3 or 4 insns.
1435        All other cases below are also at least 3 insns, so speed up the
1436        code generator by not considering them and always using ISEL.  */
1437     if (have_isel) {
1438         int isel, tab;
1440         tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1442         isel = tcg_to_isel[cond];
1444         tcg_out_movi(s, type, arg0, 1);
1445         if (isel & 1) {
1446             /* arg0 = (bc ? 0 : 1) */
1447             tab = TAB(arg0, 0, arg0);
1448             isel &= ~1;
1449         } else {
1450             /* arg0 = (bc ? 1 : 0) */
1451             tcg_out_movi(s, type, TCG_REG_R0, 0);
1452             tab = TAB(arg0, arg0, TCG_REG_R0);
1453         }
1454         tcg_out32(s, isel | tab);
1455         return;
1456     }
1458     switch (cond) {
1459     case TCG_COND_EQ:
1460         arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1461         tcg_out_setcond_eq0(s, type, arg0, arg1);
1462         return;
1464     case TCG_COND_NE:
1465         arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1466         /* Discard the high bits only once, rather than both inputs.  */
1467         if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1468             tcg_out_ext32u(s, TCG_REG_R0, arg1);
1469             arg1 = TCG_REG_R0;
1470         }
1471         tcg_out_setcond_ne0(s, arg0, arg1);
1472         return;
1474     case TCG_COND_GT:
1475     case TCG_COND_GTU:
1476         sh = 30;
1477         crop = 0;
1478         goto crtest;
1480     case TCG_COND_LT:
1481     case TCG_COND_LTU:
1482         sh = 29;
1483         crop = 0;
1484         goto crtest;
1486     case TCG_COND_GE:
1487     case TCG_COND_GEU:
1488         sh = 31;
1489         crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1490         goto crtest;
1492     case TCG_COND_LE:
1493     case TCG_COND_LEU:
1494         sh = 31;
1495         crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1496     crtest:
1497         tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1498         if (crop) {
1499             tcg_out32(s, crop);
1500         }
1501         tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1502         tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1503         break;
1505     default:
1506         tcg_abort();
1507     }
1510 static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
1512     if (l->has_value) {
1513         bc |= reloc_pc14_val(tcg_splitwx_to_rx(s->code_ptr), l->u.value_ptr);
1514     } else {
1515         tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
1516     }
1517     tcg_out32(s, bc);
1520 static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1521                            TCGArg arg1, TCGArg arg2, int const_arg2,
1522                            TCGLabel *l, TCGType type)
1524     tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1525     tcg_out_bc(s, tcg_to_bc[cond], l);
1528 static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1529                             TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1530                             TCGArg v2, bool const_c2)
1532     /* If for some reason both inputs are zero, don't produce bad code.  */
1533     if (v1 == 0 && v2 == 0) {
1534         tcg_out_movi(s, type, dest, 0);
1535         return;
1536     }
1538     tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1540     if (have_isel) {
1541         int isel = tcg_to_isel[cond];
1543         /* Swap the V operands if the operation indicates inversion.  */
1544         if (isel & 1) {
1545             int t = v1;
1546             v1 = v2;
1547             v2 = t;
1548             isel &= ~1;
1549         }
1550         /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand.  */
1551         if (v2 == 0) {
1552             tcg_out_movi(s, type, TCG_REG_R0, 0);
1553         }
1554         tcg_out32(s, isel | TAB(dest, v1, v2));
1555     } else {
1556         if (dest == v2) {
1557             cond = tcg_invert_cond(cond);
1558             v2 = v1;
1559         } else if (dest != v1) {
1560             if (v1 == 0) {
1561                 tcg_out_movi(s, type, dest, 0);
1562             } else {
1563                 tcg_out_mov(s, type, dest, v1);
1564             }
1565         }
1566         /* Branch forward over one insn */
1567         tcg_out32(s, tcg_to_bc[cond] | 8);
1568         if (v2 == 0) {
1569             tcg_out_movi(s, type, dest, 0);
1570         } else {
1571             tcg_out_mov(s, type, dest, v2);
1572         }
1573     }
1576 static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
1577                           TCGArg a0, TCGArg a1, TCGArg a2, bool const_a2)
1579     if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) {
1580         tcg_out32(s, opc | RA(a0) | RS(a1));
1581     } else {
1582         tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type);
1583         /* Note that the only other valid constant for a2 is 0.  */
1584         if (have_isel) {
1585             tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
1586             tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0));
1587         } else if (!const_a2 && a0 == a2) {
1588             tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8);
1589             tcg_out32(s, opc | RA(a0) | RS(a1));
1590         } else {
1591             tcg_out32(s, opc | RA(a0) | RS(a1));
1592             tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8);
1593             if (const_a2) {
1594                 tcg_out_movi(s, type, a0, 0);
1595             } else {
1596                 tcg_out_mov(s, type, a0, a2);
1597             }
1598         }
1599     }
1602 static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1603                          const int *const_args)
1605     static const struct { uint8_t bit1, bit2; } bits[] = {
1606         [TCG_COND_LT ] = { CR_LT, CR_LT },
1607         [TCG_COND_LE ] = { CR_LT, CR_GT },
1608         [TCG_COND_GT ] = { CR_GT, CR_GT },
1609         [TCG_COND_GE ] = { CR_GT, CR_LT },
1610         [TCG_COND_LTU] = { CR_LT, CR_LT },
1611         [TCG_COND_LEU] = { CR_LT, CR_GT },
1612         [TCG_COND_GTU] = { CR_GT, CR_GT },
1613         [TCG_COND_GEU] = { CR_GT, CR_LT },
1614     };
1616     TCGCond cond = args[4], cond2;
1617     TCGArg al, ah, bl, bh;
1618     int blconst, bhconst;
1619     int op, bit1, bit2;
1621     al = args[0];
1622     ah = args[1];
1623     bl = args[2];
1624     bh = args[3];
1625     blconst = const_args[2];
1626     bhconst = const_args[3];
1628     switch (cond) {
1629     case TCG_COND_EQ:
1630         op = CRAND;
1631         goto do_equality;
1632     case TCG_COND_NE:
1633         op = CRNAND;
1634     do_equality:
1635         tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
1636         tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
1637         tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1638         break;
1640     case TCG_COND_LT:
1641     case TCG_COND_LE:
1642     case TCG_COND_GT:
1643     case TCG_COND_GE:
1644     case TCG_COND_LTU:
1645     case TCG_COND_LEU:
1646     case TCG_COND_GTU:
1647     case TCG_COND_GEU:
1648         bit1 = bits[cond].bit1;
1649         bit2 = bits[cond].bit2;
1650         op = (bit1 != bit2 ? CRANDC : CRAND);
1651         cond2 = tcg_unsigned_cond(cond);
1653         tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
1654         tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
1655         tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
1656         tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
1657         break;
1659     default:
1660         tcg_abort();
1661     }
1664 static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
1665                              const int *const_args)
1667     tcg_out_cmp2(s, args + 1, const_args + 1);
1668     tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1669     tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
1672 static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1673                              const int *const_args)
1675     tcg_out_cmp2(s, args, const_args);
1676     tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
1679 static void tcg_out_mb(TCGContext *s, TCGArg a0)
1681     uint32_t insn = HWSYNC;
1682     a0 &= TCG_MO_ALL;
1683     if (a0 == TCG_MO_LD_LD) {
1684         insn = LWSYNC;
1685     } else if (a0 == TCG_MO_ST_ST) {
1686         insn = EIEIO;
1687     }
1688     tcg_out32(s, insn);
1691 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_rx,
1692                               uintptr_t jmp_rw, uintptr_t addr)
1694     if (TCG_TARGET_REG_BITS == 64) {
1695         tcg_insn_unit i1, i2;
1696         intptr_t tb_diff = addr - tc_ptr;
1697         intptr_t br_diff = addr - (jmp_rx + 4);
1698         uint64_t pair;
1700         /* This does not exercise the range of the branch, but we do
1701            still need to be able to load the new value of TCG_REG_TB.
1702            But this does still happen quite often.  */
1703         if (tb_diff == (int16_t)tb_diff) {
1704             i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
1705             i2 = B | (br_diff & 0x3fffffc);
1706         } else {
1707             intptr_t lo = (int16_t)tb_diff;
1708             intptr_t hi = (int32_t)(tb_diff - lo);
1709             assert(tb_diff == hi + lo);
1710             i1 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
1711             i2 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
1712         }
1713 #ifdef HOST_WORDS_BIGENDIAN
1714         pair = (uint64_t)i1 << 32 | i2;
1715 #else
1716         pair = (uint64_t)i2 << 32 | i1;
1717 #endif
1719         /* As per the enclosing if, this is ppc64.  Avoid the _Static_assert
1720            within qatomic_set that would fail to build a ppc32 host.  */
1721         qatomic_set__nocheck((uint64_t *)jmp_rw, pair);
1722         flush_idcache_range(jmp_rx, jmp_rw, 8);
1723     } else {
1724         intptr_t diff = addr - jmp_rx;
1725         tcg_debug_assert(in_range_b(diff));
1726         qatomic_set((uint32_t *)jmp_rw, B | (diff & 0x3fffffc));
1727         flush_idcache_range(jmp_rx, jmp_rw, 4);
1728     }
1731 static void tcg_out_call(TCGContext *s, const tcg_insn_unit *target)
1733 #ifdef _CALL_AIX
1734     /* Look through the descriptor.  If the branch is in range, and we
1735        don't have to spend too much effort on building the toc.  */
1736     const void *tgt = ((const void * const *)target)[0];
1737     uintptr_t toc = ((const uintptr_t *)target)[1];
1738     intptr_t diff = tcg_pcrel_diff(s, tgt);
1740     if (in_range_b(diff) && toc == (uint32_t)toc) {
1741         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
1742         tcg_out_b(s, LK, tgt);
1743     } else {
1744         /* Fold the low bits of the constant into the addresses below.  */
1745         intptr_t arg = (intptr_t)target;
1746         int ofs = (int16_t)arg;
1748         if (ofs + 8 < 0x8000) {
1749             arg -= ofs;
1750         } else {
1751             ofs = 0;
1752         }
1753         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg);
1754         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
1755         tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
1756         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
1757         tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1758     }
1759 #elif defined(_CALL_ELF) && _CALL_ELF == 2
1760     intptr_t diff;
1762     /* In the ELFv2 ABI, we have to set up r12 to contain the destination
1763        address, which the callee uses to compute its TOC address.  */
1764     /* FIXME: when the branch is in range, we could avoid r12 load if we
1765        knew that the destination uses the same TOC, and what its local
1766        entry point offset is.  */
1767     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target);
1769     diff = tcg_pcrel_diff(s, target);
1770     if (in_range_b(diff)) {
1771         tcg_out_b(s, LK, target);
1772     } else {
1773         tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
1774         tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1775     }
1776 #else
1777     tcg_out_b(s, LK, target);
1778 #endif
1781 static const uint32_t qemu_ldx_opc[16] = {
1782     [MO_UB] = LBZX,
1783     [MO_UW] = LHZX,
1784     [MO_UL] = LWZX,
1785     [MO_Q]  = LDX,
1786     [MO_SW] = LHAX,
1787     [MO_SL] = LWAX,
1788     [MO_BSWAP | MO_UB] = LBZX,
1789     [MO_BSWAP | MO_UW] = LHBRX,
1790     [MO_BSWAP | MO_UL] = LWBRX,
1791     [MO_BSWAP | MO_Q]  = LDBRX,
1794 static const uint32_t qemu_stx_opc[16] = {
1795     [MO_UB] = STBX,
1796     [MO_UW] = STHX,
1797     [MO_UL] = STWX,
1798     [MO_Q]  = STDX,
1799     [MO_BSWAP | MO_UB] = STBX,
1800     [MO_BSWAP | MO_UW] = STHBRX,
1801     [MO_BSWAP | MO_UL] = STWBRX,
1802     [MO_BSWAP | MO_Q]  = STDBRX,
1805 static const uint32_t qemu_exts_opc[4] = {
1806     EXTSB, EXTSH, EXTSW, 0
1809 #if defined (CONFIG_SOFTMMU)
1810 #include "../tcg-ldst.c.inc"
1812 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1813  *                                 int mmu_idx, uintptr_t ra)
1814  */
1815 static void * const qemu_ld_helpers[16] = {
1816     [MO_UB]   = helper_ret_ldub_mmu,
1817     [MO_LEUW] = helper_le_lduw_mmu,
1818     [MO_LEUL] = helper_le_ldul_mmu,
1819     [MO_LEQ]  = helper_le_ldq_mmu,
1820     [MO_BEUW] = helper_be_lduw_mmu,
1821     [MO_BEUL] = helper_be_ldul_mmu,
1822     [MO_BEQ]  = helper_be_ldq_mmu,
1825 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1826  *                                 uintxx_t val, int mmu_idx, uintptr_t ra)
1827  */
1828 static void * const qemu_st_helpers[16] = {
1829     [MO_UB]   = helper_ret_stb_mmu,
1830     [MO_LEUW] = helper_le_stw_mmu,
1831     [MO_LEUL] = helper_le_stl_mmu,
1832     [MO_LEQ]  = helper_le_stq_mmu,
1833     [MO_BEUW] = helper_be_stw_mmu,
1834     [MO_BEUL] = helper_be_stl_mmu,
1835     [MO_BEQ]  = helper_be_stq_mmu,
1838 /* We expect to use a 16-bit negative offset from ENV.  */
1839 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1840 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768);
1842 /* Perform the TLB load and compare.  Places the result of the comparison
1843    in CR7, loads the addend of the TLB into R3, and returns the register
1844    containing the guest address (zero-extended into R4).  Clobbers R0 and R2. */
1846 static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc,
1847                                TCGReg addrlo, TCGReg addrhi,
1848                                int mem_index, bool is_read)
1850     int cmp_off
1851         = (is_read
1852            ? offsetof(CPUTLBEntry, addr_read)
1853            : offsetof(CPUTLBEntry, addr_write));
1854     int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1855     int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1856     int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1857     unsigned s_bits = opc & MO_SIZE;
1858     unsigned a_bits = get_alignment_bits(opc);
1860     /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx].  */
1861     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off);
1862     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off);
1864     /* Extract the page index, shifted into place for tlb index.  */
1865     if (TCG_TARGET_REG_BITS == 32) {
1866         tcg_out_shri32(s, TCG_REG_TMP1, addrlo,
1867                        TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1868     } else {
1869         tcg_out_shri64(s, TCG_REG_TMP1, addrlo,
1870                        TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1871     }
1872     tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1));
1874     /* Load the TLB comparator.  */
1875     if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
1876         uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32
1877                         ? LWZUX : LDUX);
1878         tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4));
1879     } else {
1880         tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4));
1881         if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1882             tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4);
1883             tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off);
1884         } else {
1885             tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off);
1886         }
1887     }
1889     /* Load the TLB addend for use on the fast path.  Do this asap
1890        to minimize any load use delay.  */
1891     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3,
1892                offsetof(CPUTLBEntry, addend));
1894     /* Clear the non-page, non-alignment bits from the address */
1895     if (TCG_TARGET_REG_BITS == 32) {
1896         /* We don't support unaligned accesses on 32-bits.
1897          * Preserve the bottom bits and thus trigger a comparison
1898          * failure on unaligned accesses.
1899          */
1900         if (a_bits < s_bits) {
1901             a_bits = s_bits;
1902         }
1903         tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
1904                     (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1905     } else {
1906         TCGReg t = addrlo;
1908         /* If the access is unaligned, we need to make sure we fail if we
1909          * cross a page boundary.  The trick is to add the access size-1
1910          * to the address before masking the low bits.  That will make the
1911          * address overflow to the next page if we cross a page boundary,
1912          * which will then force a mismatch of the TLB compare.
1913          */
1914         if (a_bits < s_bits) {
1915             unsigned a_mask = (1 << a_bits) - 1;
1916             unsigned s_mask = (1 << s_bits) - 1;
1917             tcg_out32(s, ADDI | TAI(TCG_REG_R0, t, s_mask - a_mask));
1918             t = TCG_REG_R0;
1919         }
1921         /* Mask the address for the requested alignment.  */
1922         if (TARGET_LONG_BITS == 32) {
1923             tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0,
1924                         (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1925             /* Zero-extend the address for use in the final address.  */
1926             tcg_out_ext32u(s, TCG_REG_R4, addrlo);
1927             addrlo = TCG_REG_R4;
1928         } else if (a_bits == 0) {
1929             tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS);
1930         } else {
1931             tcg_out_rld(s, RLDICL, TCG_REG_R0, t,
1932                         64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits);
1933             tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
1934         }
1935     }
1937     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1938         tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1939                     0, 7, TCG_TYPE_I32);
1940         tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32);
1941         tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1942     } else {
1943         tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1944                     0, 7, TCG_TYPE_TL);
1945     }
1947     return addrlo;
1950 /* Record the context of a call to the out of line helper code for the slow
1951    path for a load or store, so that we can later generate the correct
1952    helper code.  */
1953 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1954                                 TCGReg datalo_reg, TCGReg datahi_reg,
1955                                 TCGReg addrlo_reg, TCGReg addrhi_reg,
1956                                 tcg_insn_unit *raddr, tcg_insn_unit *lptr)
1958     TCGLabelQemuLdst *label = new_ldst_label(s);
1960     label->is_ld = is_ld;
1961     label->oi = oi;
1962     label->datalo_reg = datalo_reg;
1963     label->datahi_reg = datahi_reg;
1964     label->addrlo_reg = addrlo_reg;
1965     label->addrhi_reg = addrhi_reg;
1966     label->raddr = tcg_splitwx_to_rx(raddr);
1967     label->label_ptr[0] = lptr;
1970 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1972     TCGMemOpIdx oi = lb->oi;
1973     MemOp opc = get_memop(oi);
1974     TCGReg hi, lo, arg = TCG_REG_R3;
1976     if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
1977         return false;
1978     }
1980     tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1982     lo = lb->addrlo_reg;
1983     hi = lb->addrhi_reg;
1984     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1985 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1986         arg |= 1;
1987 #endif
1988         tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1989         tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1990     } else {
1991         /* If the address needed to be zero-extended, we'll have already
1992            placed it in R4.  The only remaining case is 64-bit guest.  */
1993         tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1994     }
1996     tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1997     tcg_out32(s, MFSPR | RT(arg) | LR);
1999     tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
2001     lo = lb->datalo_reg;
2002     hi = lb->datahi_reg;
2003     if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
2004         tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
2005         tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
2006     } else if (opc & MO_SIGN) {
2007         uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
2008         tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
2009     } else {
2010         tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
2011     }
2013     tcg_out_b(s, 0, lb->raddr);
2014     return true;
2017 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
2019     TCGMemOpIdx oi = lb->oi;
2020     MemOp opc = get_memop(oi);
2021     MemOp s_bits = opc & MO_SIZE;
2022     TCGReg hi, lo, arg = TCG_REG_R3;
2024     if (!reloc_pc14(lb->label_ptr[0], tcg_splitwx_to_rx(s->code_ptr))) {
2025         return false;
2026     }
2028     tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
2030     lo = lb->addrlo_reg;
2031     hi = lb->addrhi_reg;
2032     if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
2033 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
2034         arg |= 1;
2035 #endif
2036         tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
2037         tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
2038     } else {
2039         /* If the address needed to be zero-extended, we'll have already
2040            placed it in R4.  The only remaining case is 64-bit guest.  */
2041         tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
2042     }
2044     lo = lb->datalo_reg;
2045     hi = lb->datahi_reg;
2046     if (TCG_TARGET_REG_BITS == 32) {
2047         switch (s_bits) {
2048         case MO_64:
2049 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
2050             arg |= 1;
2051 #endif
2052             tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
2053             /* FALLTHRU */
2054         case MO_32:
2055             tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
2056             break;
2057         default:
2058             tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
2059             break;
2060         }
2061     } else {
2062         if (s_bits == MO_64) {
2063             tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
2064         } else {
2065             tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
2066         }
2067     }
2069     tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
2070     tcg_out32(s, MFSPR | RT(arg) | LR);
2072     tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
2074     tcg_out_b(s, 0, lb->raddr);
2075     return true;
2077 #endif /* SOFTMMU */
2079 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
2081     TCGReg datalo, datahi, addrlo, rbase;
2082     TCGReg addrhi __attribute__((unused));
2083     TCGMemOpIdx oi;
2084     MemOp opc, s_bits;
2085 #ifdef CONFIG_SOFTMMU
2086     int mem_index;
2087     tcg_insn_unit *label_ptr;
2088 #endif
2090     datalo = *args++;
2091     datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
2092     addrlo = *args++;
2093     addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
2094     oi = *args++;
2095     opc = get_memop(oi);
2096     s_bits = opc & MO_SIZE;
2098 #ifdef CONFIG_SOFTMMU
2099     mem_index = get_mmuidx(oi);
2100     addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true);
2102     /* Load a pointer into the current opcode w/conditional branch-link. */
2103     label_ptr = s->code_ptr;
2104     tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
2106     rbase = TCG_REG_R3;
2107 #else  /* !CONFIG_SOFTMMU */
2108     rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
2109     if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
2110         tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
2111         addrlo = TCG_REG_TMP1;
2112     }
2113 #endif
2115     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
2116         if (opc & MO_BSWAP) {
2117             tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
2118             tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
2119             tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0));
2120         } else if (rbase != 0) {
2121             tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
2122             tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo));
2123             tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0));
2124         } else if (addrlo == datahi) {
2125             tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
2126             tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
2127         } else {
2128             tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
2129             tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
2130         }
2131     } else {
2132         uint32_t insn = qemu_ldx_opc[opc & (MO_BSWAP | MO_SSIZE)];
2133         if (!have_isa_2_06 && insn == LDBRX) {
2134             tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
2135             tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
2136             tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
2137             tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0);
2138         } else if (insn) {
2139             tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
2140         } else {
2141             insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
2142             tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
2143             insn = qemu_exts_opc[s_bits];
2144             tcg_out32(s, insn | RA(datalo) | RS(datalo));
2145         }
2146     }
2148 #ifdef CONFIG_SOFTMMU
2149     add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
2150                         s->code_ptr, label_ptr);
2151 #endif
2154 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
2156     TCGReg datalo, datahi, addrlo, rbase;
2157     TCGReg addrhi __attribute__((unused));
2158     TCGMemOpIdx oi;
2159     MemOp opc, s_bits;
2160 #ifdef CONFIG_SOFTMMU
2161     int mem_index;
2162     tcg_insn_unit *label_ptr;
2163 #endif
2165     datalo = *args++;
2166     datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
2167     addrlo = *args++;
2168     addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
2169     oi = *args++;
2170     opc = get_memop(oi);
2171     s_bits = opc & MO_SIZE;
2173 #ifdef CONFIG_SOFTMMU
2174     mem_index = get_mmuidx(oi);
2175     addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false);
2177     /* Load a pointer into the current opcode w/conditional branch-link. */
2178     label_ptr = s->code_ptr;
2179     tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
2181     rbase = TCG_REG_R3;
2182 #else  /* !CONFIG_SOFTMMU */
2183     rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
2184     if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
2185         tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
2186         addrlo = TCG_REG_TMP1;
2187     }
2188 #endif
2190     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
2191         if (opc & MO_BSWAP) {
2192             tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
2193             tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
2194             tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));
2195         } else if (rbase != 0) {
2196             tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
2197             tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));
2198             tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));
2199         } else {
2200             tcg_out32(s, STW | TAI(datahi, addrlo, 0));
2201             tcg_out32(s, STW | TAI(datalo, addrlo, 4));
2202         }
2203     } else {
2204         uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)];
2205         if (!have_isa_2_06 && insn == STDBRX) {
2206             tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
2207             tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));
2208             tcg_out_shri64(s, TCG_REG_R0, datalo, 32);
2209             tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));
2210         } else {
2211             tcg_out32(s, insn | SAB(datalo, rbase, addrlo));
2212         }
2213     }
2215 #ifdef CONFIG_SOFTMMU
2216     add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
2217                         s->code_ptr, label_ptr);
2218 #endif
2221 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
2223     int i;
2224     for (i = 0; i < count; ++i) {
2225         p[i] = NOP;
2226     }
2229 /* Parameters for function call generation, used in tcg.c.  */
2230 #define TCG_TARGET_STACK_ALIGN       16
2231 #define TCG_TARGET_EXTEND_ARGS       1
2233 #ifdef _CALL_AIX
2234 # define LINK_AREA_SIZE                (6 * SZR)
2235 # define LR_OFFSET                     (1 * SZR)
2236 # define TCG_TARGET_CALL_STACK_OFFSET  (LINK_AREA_SIZE + 8 * SZR)
2237 #elif defined(TCG_TARGET_CALL_DARWIN)
2238 # define LINK_AREA_SIZE                (6 * SZR)
2239 # define LR_OFFSET                     (2 * SZR)
2240 #elif TCG_TARGET_REG_BITS == 64
2241 # if defined(_CALL_ELF) && _CALL_ELF == 2
2242 #  define LINK_AREA_SIZE               (4 * SZR)
2243 #  define LR_OFFSET                    (1 * SZR)
2244 # endif
2245 #else /* TCG_TARGET_REG_BITS == 32 */
2246 # if defined(_CALL_SYSV)
2247 #  define LINK_AREA_SIZE               (2 * SZR)
2248 #  define LR_OFFSET                    (1 * SZR)
2249 # endif
2250 #endif
2251 #ifndef LR_OFFSET
2252 # error "Unhandled abi"
2253 #endif
2254 #ifndef TCG_TARGET_CALL_STACK_OFFSET
2255 # define TCG_TARGET_CALL_STACK_OFFSET  LINK_AREA_SIZE
2256 #endif
2258 #define CPU_TEMP_BUF_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
2259 #define REG_SAVE_SIZE      ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR)
2261 #define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET   \
2262                      + TCG_STATIC_CALL_ARGS_SIZE    \
2263                      + CPU_TEMP_BUF_SIZE            \
2264                      + REG_SAVE_SIZE                \
2265                      + TCG_TARGET_STACK_ALIGN - 1)  \
2266                     & -TCG_TARGET_STACK_ALIGN)
2268 #define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE)
2270 static void tcg_target_qemu_prologue(TCGContext *s)
2272     int i;
2274 #ifdef _CALL_AIX
2275     const void **desc = (const void **)s->code_ptr;
2276     desc[0] = tcg_splitwx_to_rx(desc + 2);  /* entry point */
2277     desc[1] = 0;                            /* environment pointer */
2278     s->code_ptr = (void *)(desc + 2);       /* skip over descriptor */
2279 #endif
2281     tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
2282                   CPU_TEMP_BUF_SIZE);
2284     /* Prologue */
2285     tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
2286     tcg_out32(s, (SZR == 8 ? STDU : STWU)
2287               | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
2289     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
2290         tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2291                    TCG_REG_R1, REG_SAVE_BOT + i * SZR);
2292     }
2293     tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
2295 #ifndef CONFIG_SOFTMMU
2296     if (guest_base) {
2297         tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
2298         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
2299     }
2300 #endif
2302     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
2303     tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
2304     if (USE_REG_TB) {
2305         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]);
2306     }
2307     tcg_out32(s, BCCTR | BO_ALWAYS);
2309     /* Epilogue */
2310     tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
2312     tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
2313     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
2314         tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
2315                    TCG_REG_R1, REG_SAVE_BOT + i * SZR);
2316     }
2317     tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
2318     tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
2319     tcg_out32(s, BCLR | BO_ALWAYS);
2322 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
2323                        const int *const_args)
2325     TCGArg a0, a1, a2;
2326     int c;
2328     switch (opc) {
2329     case INDEX_op_exit_tb:
2330         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
2331         tcg_out_b(s, 0, tcg_code_gen_epilogue);
2332         break;
2333     case INDEX_op_goto_tb:
2334         if (s->tb_jmp_insn_offset) {
2335             /* Direct jump. */
2336             if (TCG_TARGET_REG_BITS == 64) {
2337                 /* Ensure the next insns are 8-byte aligned. */
2338                 if ((uintptr_t)s->code_ptr & 7) {
2339                     tcg_out32(s, NOP);
2340                 }
2341                 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2342                 tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2343                 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2344             } else {
2345                 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2346                 tcg_out32(s, B);
2347                 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
2348                 break;
2349             }
2350         } else {
2351             /* Indirect jump. */
2352             tcg_debug_assert(s->tb_jmp_insn_offset == NULL);
2353             tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, 0,
2354                        (intptr_t)(s->tb_jmp_insn_offset + args[0]));
2355         }
2356         tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
2357         tcg_out32(s, BCCTR | BO_ALWAYS);
2358         set_jmp_reset_offset(s, args[0]);
2359         if (USE_REG_TB) {
2360             /* For the unlinked case, need to reset TCG_REG_TB.  */
2361             tcg_out_mem_long(s, ADDI, ADD, TCG_REG_TB, TCG_REG_TB,
2362                              -tcg_current_code_size(s));
2363         }
2364         break;
2365     case INDEX_op_goto_ptr:
2366         tcg_out32(s, MTSPR | RS(args[0]) | CTR);
2367         if (USE_REG_TB) {
2368             tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, args[0]);
2369         }
2370         tcg_out32(s, ADDI | TAI(TCG_REG_R3, 0, 0));
2371         tcg_out32(s, BCCTR | BO_ALWAYS);
2372         break;
2373     case INDEX_op_br:
2374         {
2375             TCGLabel *l = arg_label(args[0]);
2376             uint32_t insn = B;
2378             if (l->has_value) {
2379                 insn |= reloc_pc24_val(tcg_splitwx_to_rx(s->code_ptr),
2380                                        l->u.value_ptr);
2381             } else {
2382                 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
2383             }
2384             tcg_out32(s, insn);
2385         }
2386         break;
2387     case INDEX_op_ld8u_i32:
2388     case INDEX_op_ld8u_i64:
2389         tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2390         break;
2391     case INDEX_op_ld8s_i32:
2392     case INDEX_op_ld8s_i64:
2393         tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2394         tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
2395         break;
2396     case INDEX_op_ld16u_i32:
2397     case INDEX_op_ld16u_i64:
2398         tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
2399         break;
2400     case INDEX_op_ld16s_i32:
2401     case INDEX_op_ld16s_i64:
2402         tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
2403         break;
2404     case INDEX_op_ld_i32:
2405     case INDEX_op_ld32u_i64:
2406         tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
2407         break;
2408     case INDEX_op_ld32s_i64:
2409         tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
2410         break;
2411     case INDEX_op_ld_i64:
2412         tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
2413         break;
2414     case INDEX_op_st8_i32:
2415     case INDEX_op_st8_i64:
2416         tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
2417         break;
2418     case INDEX_op_st16_i32:
2419     case INDEX_op_st16_i64:
2420         tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
2421         break;
2422     case INDEX_op_st_i32:
2423     case INDEX_op_st32_i64:
2424         tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
2425         break;
2426     case INDEX_op_st_i64:
2427         tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
2428         break;
2430     case INDEX_op_add_i32:
2431         a0 = args[0], a1 = args[1], a2 = args[2];
2432         if (const_args[2]) {
2433         do_addi_32:
2434             tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
2435         } else {
2436             tcg_out32(s, ADD | TAB(a0, a1, a2));
2437         }
2438         break;
2439     case INDEX_op_sub_i32:
2440         a0 = args[0], a1 = args[1], a2 = args[2];
2441         if (const_args[1]) {
2442             if (const_args[2]) {
2443                 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
2444             } else {
2445                 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2446             }
2447         } else if (const_args[2]) {
2448             a2 = -a2;
2449             goto do_addi_32;
2450         } else {
2451             tcg_out32(s, SUBF | TAB(a0, a2, a1));
2452         }
2453         break;
2455     case INDEX_op_and_i32:
2456         a0 = args[0], a1 = args[1], a2 = args[2];
2457         if (const_args[2]) {
2458             tcg_out_andi32(s, a0, a1, a2);
2459         } else {
2460             tcg_out32(s, AND | SAB(a1, a0, a2));
2461         }
2462         break;
2463     case INDEX_op_and_i64:
2464         a0 = args[0], a1 = args[1], a2 = args[2];
2465         if (const_args[2]) {
2466             tcg_out_andi64(s, a0, a1, a2);
2467         } else {
2468             tcg_out32(s, AND | SAB(a1, a0, a2));
2469         }
2470         break;
2471     case INDEX_op_or_i64:
2472     case INDEX_op_or_i32:
2473         a0 = args[0], a1 = args[1], a2 = args[2];
2474         if (const_args[2]) {
2475             tcg_out_ori32(s, a0, a1, a2);
2476         } else {
2477             tcg_out32(s, OR | SAB(a1, a0, a2));
2478         }
2479         break;
2480     case INDEX_op_xor_i64:
2481     case INDEX_op_xor_i32:
2482         a0 = args[0], a1 = args[1], a2 = args[2];
2483         if (const_args[2]) {
2484             tcg_out_xori32(s, a0, a1, a2);
2485         } else {
2486             tcg_out32(s, XOR | SAB(a1, a0, a2));
2487         }
2488         break;
2489     case INDEX_op_andc_i32:
2490         a0 = args[0], a1 = args[1], a2 = args[2];
2491         if (const_args[2]) {
2492             tcg_out_andi32(s, a0, a1, ~a2);
2493         } else {
2494             tcg_out32(s, ANDC | SAB(a1, a0, a2));
2495         }
2496         break;
2497     case INDEX_op_andc_i64:
2498         a0 = args[0], a1 = args[1], a2 = args[2];
2499         if (const_args[2]) {
2500             tcg_out_andi64(s, a0, a1, ~a2);
2501         } else {
2502             tcg_out32(s, ANDC | SAB(a1, a0, a2));
2503         }
2504         break;
2505     case INDEX_op_orc_i32:
2506         if (const_args[2]) {
2507             tcg_out_ori32(s, args[0], args[1], ~args[2]);
2508             break;
2509         }
2510         /* FALLTHRU */
2511     case INDEX_op_orc_i64:
2512         tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
2513         break;
2514     case INDEX_op_eqv_i32:
2515         if (const_args[2]) {
2516             tcg_out_xori32(s, args[0], args[1], ~args[2]);
2517             break;
2518         }
2519         /* FALLTHRU */
2520     case INDEX_op_eqv_i64:
2521         tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
2522         break;
2523     case INDEX_op_nand_i32:
2524     case INDEX_op_nand_i64:
2525         tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
2526         break;
2527     case INDEX_op_nor_i32:
2528     case INDEX_op_nor_i64:
2529         tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
2530         break;
2532     case INDEX_op_clz_i32:
2533         tcg_out_cntxz(s, TCG_TYPE_I32, CNTLZW, args[0], args[1],
2534                       args[2], const_args[2]);
2535         break;
2536     case INDEX_op_ctz_i32:
2537         tcg_out_cntxz(s, TCG_TYPE_I32, CNTTZW, args[0], args[1],
2538                       args[2], const_args[2]);
2539         break;
2540     case INDEX_op_ctpop_i32:
2541         tcg_out32(s, CNTPOPW | SAB(args[1], args[0], 0));
2542         break;
2544     case INDEX_op_clz_i64:
2545         tcg_out_cntxz(s, TCG_TYPE_I64, CNTLZD, args[0], args[1],
2546                       args[2], const_args[2]);
2547         break;
2548     case INDEX_op_ctz_i64:
2549         tcg_out_cntxz(s, TCG_TYPE_I64, CNTTZD, args[0], args[1],
2550                       args[2], const_args[2]);
2551         break;
2552     case INDEX_op_ctpop_i64:
2553         tcg_out32(s, CNTPOPD | SAB(args[1], args[0], 0));
2554         break;
2556     case INDEX_op_mul_i32:
2557         a0 = args[0], a1 = args[1], a2 = args[2];
2558         if (const_args[2]) {
2559             tcg_out32(s, MULLI | TAI(a0, a1, a2));
2560         } else {
2561             tcg_out32(s, MULLW | TAB(a0, a1, a2));
2562         }
2563         break;
2565     case INDEX_op_div_i32:
2566         tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
2567         break;
2569     case INDEX_op_divu_i32:
2570         tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
2571         break;
2573     case INDEX_op_shl_i32:
2574         if (const_args[2]) {
2575             /* Limit immediate shift count lest we create an illegal insn.  */
2576             tcg_out_shli32(s, args[0], args[1], args[2] & 31);
2577         } else {
2578             tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
2579         }
2580         break;
2581     case INDEX_op_shr_i32:
2582         if (const_args[2]) {
2583             /* Limit immediate shift count lest we create an illegal insn.  */
2584             tcg_out_shri32(s, args[0], args[1], args[2] & 31);
2585         } else {
2586             tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
2587         }
2588         break;
2589     case INDEX_op_sar_i32:
2590         if (const_args[2]) {
2591             /* Limit immediate shift count lest we create an illegal insn.  */
2592             tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2] & 31));
2593         } else {
2594             tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
2595         }
2596         break;
2597     case INDEX_op_rotl_i32:
2598         if (const_args[2]) {
2599             tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
2600         } else {
2601             tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
2602                          | MB(0) | ME(31));
2603         }
2604         break;
2605     case INDEX_op_rotr_i32:
2606         if (const_args[2]) {
2607             tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
2608         } else {
2609             tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
2610             tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
2611                          | MB(0) | ME(31));
2612         }
2613         break;
2615     case INDEX_op_brcond_i32:
2616         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2617                        arg_label(args[3]), TCG_TYPE_I32);
2618         break;
2619     case INDEX_op_brcond_i64:
2620         tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2621                        arg_label(args[3]), TCG_TYPE_I64);
2622         break;
2623     case INDEX_op_brcond2_i32:
2624         tcg_out_brcond2(s, args, const_args);
2625         break;
2627     case INDEX_op_neg_i32:
2628     case INDEX_op_neg_i64:
2629         tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
2630         break;
2632     case INDEX_op_not_i32:
2633     case INDEX_op_not_i64:
2634         tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
2635         break;
2637     case INDEX_op_add_i64:
2638         a0 = args[0], a1 = args[1], a2 = args[2];
2639         if (const_args[2]) {
2640         do_addi_64:
2641             tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
2642         } else {
2643             tcg_out32(s, ADD | TAB(a0, a1, a2));
2644         }
2645         break;
2646     case INDEX_op_sub_i64:
2647         a0 = args[0], a1 = args[1], a2 = args[2];
2648         if (const_args[1]) {
2649             if (const_args[2]) {
2650                 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
2651             } else {
2652                 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2653             }
2654         } else if (const_args[2]) {
2655             a2 = -a2;
2656             goto do_addi_64;
2657         } else {
2658             tcg_out32(s, SUBF | TAB(a0, a2, a1));
2659         }
2660         break;
2662     case INDEX_op_shl_i64:
2663         if (const_args[2]) {
2664             /* Limit immediate shift count lest we create an illegal insn.  */
2665             tcg_out_shli64(s, args[0], args[1], args[2] & 63);
2666         } else {
2667             tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
2668         }
2669         break;
2670     case INDEX_op_shr_i64:
2671         if (const_args[2]) {
2672             /* Limit immediate shift count lest we create an illegal insn.  */
2673             tcg_out_shri64(s, args[0], args[1], args[2] & 63);
2674         } else {
2675             tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
2676         }
2677         break;
2678     case INDEX_op_sar_i64:
2679         if (const_args[2]) {
2680             int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
2681             tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
2682         } else {
2683             tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
2684         }
2685         break;
2686     case INDEX_op_rotl_i64:
2687         if (const_args[2]) {
2688             tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
2689         } else {
2690             tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
2691         }
2692         break;
2693     case INDEX_op_rotr_i64:
2694         if (const_args[2]) {
2695             tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
2696         } else {
2697             tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
2698             tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
2699         }
2700         break;
2702     case INDEX_op_mul_i64:
2703         a0 = args[0], a1 = args[1], a2 = args[2];
2704         if (const_args[2]) {
2705             tcg_out32(s, MULLI | TAI(a0, a1, a2));
2706         } else {
2707             tcg_out32(s, MULLD | TAB(a0, a1, a2));
2708         }
2709         break;
2710     case INDEX_op_div_i64:
2711         tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
2712         break;
2713     case INDEX_op_divu_i64:
2714         tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
2715         break;
2717     case INDEX_op_qemu_ld_i32:
2718         tcg_out_qemu_ld(s, args, false);
2719         break;
2720     case INDEX_op_qemu_ld_i64:
2721         tcg_out_qemu_ld(s, args, true);
2722         break;
2723     case INDEX_op_qemu_st_i32:
2724         tcg_out_qemu_st(s, args, false);
2725         break;
2726     case INDEX_op_qemu_st_i64:
2727         tcg_out_qemu_st(s, args, true);
2728         break;
2730     case INDEX_op_ext8s_i32:
2731     case INDEX_op_ext8s_i64:
2732         c = EXTSB;
2733         goto gen_ext;
2734     case INDEX_op_ext16s_i32:
2735     case INDEX_op_ext16s_i64:
2736         c = EXTSH;
2737         goto gen_ext;
2738     case INDEX_op_ext_i32_i64:
2739     case INDEX_op_ext32s_i64:
2740         c = EXTSW;
2741         goto gen_ext;
2742     gen_ext:
2743         tcg_out32(s, c | RS(args[1]) | RA(args[0]));
2744         break;
2745     case INDEX_op_extu_i32_i64:
2746         tcg_out_ext32u(s, args[0], args[1]);
2747         break;
2749     case INDEX_op_setcond_i32:
2750         tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
2751                         const_args[2]);
2752         break;
2753     case INDEX_op_setcond_i64:
2754         tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
2755                         const_args[2]);
2756         break;
2757     case INDEX_op_setcond2_i32:
2758         tcg_out_setcond2(s, args, const_args);
2759         break;
2761     case INDEX_op_bswap16_i32:
2762     case INDEX_op_bswap16_i64:
2763         a0 = args[0], a1 = args[1];
2764         /* a1 = abcd */
2765         if (a0 != a1) {
2766             /* a0 = (a1 r<< 24) & 0xff # 000c */
2767             tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2768             /* a0 = (a0 & ~0xff00) | (a1 r<< 8) & 0xff00 # 00dc */
2769             tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
2770         } else {
2771             /* r0 = (a1 r<< 8) & 0xff00 # 00d0 */
2772             tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
2773             /* a0 = (a1 r<< 24) & 0xff # 000c */
2774             tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2775             /* a0 = a0 | r0 # 00dc */
2776             tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
2777         }
2778         break;
2780     case INDEX_op_bswap32_i32:
2781     case INDEX_op_bswap32_i64:
2782         /* Stolen from gcc's builtin_bswap32 */
2783         a1 = args[1];
2784         a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
2786         /* a1 = args[1] # abcd */
2787         /* a0 = rotate_left (a1, 8) # bcda */
2788         tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2789         /* a0 = (a0 & ~0xff000000) | ((a1 r<< 24) & 0xff000000) # dcda */
2790         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2791         /* a0 = (a0 & ~0x0000ff00) | ((a1 r<< 24) & 0x0000ff00) # dcba */
2792         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2794         if (a0 == TCG_REG_R0) {
2795             tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2796         }
2797         break;
2799     case INDEX_op_bswap64_i64:
2800         a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
2801         if (a0 == a1) {
2802             a0 = TCG_REG_R0;
2803             a2 = a1;
2804         }
2806         /* a1 = # abcd efgh */
2807         /* a0 = rl32(a1, 8) # 0000 fghe */
2808         tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2809         /* a0 = dep(a0, rl32(a1, 24), 0xff000000) # 0000 hghe */
2810         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2811         /* a0 = dep(a0, rl32(a1, 24), 0x0000ff00) # 0000 hgfe */
2812         tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2814         /* a0 = rl64(a0, 32) # hgfe 0000 */
2815         /* a2 = rl64(a1, 32) # efgh abcd */
2816         tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
2817         tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
2819         /* a0 = dep(a0, rl32(a2, 8), 0xffffffff)  # hgfe bcda */
2820         tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
2821         /* a0 = dep(a0, rl32(a2, 24), 0xff000000) # hgfe dcda */
2822         tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
2823         /* a0 = dep(a0, rl32(a2, 24), 0x0000ff00) # hgfe dcba */
2824         tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
2826         if (a0 == 0) {
2827             tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2828         }
2829         break;
2831     case INDEX_op_deposit_i32:
2832         if (const_args[2]) {
2833             uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
2834             tcg_out_andi32(s, args[0], args[0], ~mask);
2835         } else {
2836             tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
2837                         32 - args[3] - args[4], 31 - args[3]);
2838         }
2839         break;
2840     case INDEX_op_deposit_i64:
2841         if (const_args[2]) {
2842             uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
2843             tcg_out_andi64(s, args[0], args[0], ~mask);
2844         } else {
2845             tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
2846                         64 - args[3] - args[4]);
2847         }
2848         break;
2850     case INDEX_op_extract_i32:
2851         tcg_out_rlw(s, RLWINM, args[0], args[1],
2852                     32 - args[2], 32 - args[3], 31);
2853         break;
2854     case INDEX_op_extract_i64:
2855         tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]);
2856         break;
2858     case INDEX_op_movcond_i32:
2859         tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
2860                         args[3], args[4], const_args[2]);
2861         break;
2862     case INDEX_op_movcond_i64:
2863         tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
2864                         args[3], args[4], const_args[2]);
2865         break;
2867 #if TCG_TARGET_REG_BITS == 64
2868     case INDEX_op_add2_i64:
2869 #else
2870     case INDEX_op_add2_i32:
2871 #endif
2872         /* Note that the CA bit is defined based on the word size of the
2873            environment.  So in 64-bit mode it's always carry-out of bit 63.
2874            The fallback code using deposit works just as well for 32-bit.  */
2875         a0 = args[0], a1 = args[1];
2876         if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
2877             a0 = TCG_REG_R0;
2878         }
2879         if (const_args[4]) {
2880             tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
2881         } else {
2882             tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
2883         }
2884         if (const_args[5]) {
2885             tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
2886         } else {
2887             tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
2888         }
2889         if (a0 != args[0]) {
2890             tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2891         }
2892         break;
2894 #if TCG_TARGET_REG_BITS == 64
2895     case INDEX_op_sub2_i64:
2896 #else
2897     case INDEX_op_sub2_i32:
2898 #endif
2899         a0 = args[0], a1 = args[1];
2900         if (a0 == args[5] || (!const_args[3] && a0 == args[3])) {
2901             a0 = TCG_REG_R0;
2902         }
2903         if (const_args[2]) {
2904             tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2]));
2905         } else {
2906             tcg_out32(s, SUBFC | TAB(a0, args[4], args[2]));
2907         }
2908         if (const_args[3]) {
2909             tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2910         } else {
2911             tcg_out32(s, SUBFE | TAB(a1, args[5], args[3]));
2912         }
2913         if (a0 != args[0]) {
2914             tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2915         }
2916         break;
2918     case INDEX_op_muluh_i32:
2919         tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2]));
2920         break;
2921     case INDEX_op_mulsh_i32:
2922         tcg_out32(s, MULHW | TAB(args[0], args[1], args[2]));
2923         break;
2924     case INDEX_op_muluh_i64:
2925         tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2926         break;
2927     case INDEX_op_mulsh_i64:
2928         tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2929         break;
2931     case INDEX_op_mb:
2932         tcg_out_mb(s, args[0]);
2933         break;
2935     case INDEX_op_mov_i32:   /* Always emitted via tcg_out_mov.  */
2936     case INDEX_op_mov_i64:
2937     case INDEX_op_call:      /* Always emitted via tcg_out_call.  */
2938     default:
2939         tcg_abort();
2940     }
2943 int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
2945     switch (opc) {
2946     case INDEX_op_and_vec:
2947     case INDEX_op_or_vec:
2948     case INDEX_op_xor_vec:
2949     case INDEX_op_andc_vec:
2950     case INDEX_op_not_vec:
2951         return 1;
2952     case INDEX_op_orc_vec:
2953         return have_isa_2_07;
2954     case INDEX_op_add_vec:
2955     case INDEX_op_sub_vec:
2956     case INDEX_op_smax_vec:
2957     case INDEX_op_smin_vec:
2958     case INDEX_op_umax_vec:
2959     case INDEX_op_umin_vec:
2960     case INDEX_op_shlv_vec:
2961     case INDEX_op_shrv_vec:
2962     case INDEX_op_sarv_vec:
2963     case INDEX_op_rotlv_vec:
2964         return vece <= MO_32 || have_isa_2_07;
2965     case INDEX_op_ssadd_vec:
2966     case INDEX_op_sssub_vec:
2967     case INDEX_op_usadd_vec:
2968     case INDEX_op_ussub_vec:
2969         return vece <= MO_32;
2970     case INDEX_op_cmp_vec:
2971     case INDEX_op_shli_vec:
2972     case INDEX_op_shri_vec:
2973     case INDEX_op_sari_vec:
2974     case INDEX_op_rotli_vec:
2975         return vece <= MO_32 || have_isa_2_07 ? -1 : 0;
2976     case INDEX_op_neg_vec:
2977         return vece >= MO_32 && have_isa_3_00;
2978     case INDEX_op_mul_vec:
2979         switch (vece) {
2980         case MO_8:
2981         case MO_16:
2982             return -1;
2983         case MO_32:
2984             return have_isa_2_07 ? 1 : -1;
2985         case MO_64:
2986             return have_isa_3_10;
2987         }
2988         return 0;
2989     case INDEX_op_bitsel_vec:
2990         return have_vsx;
2991     case INDEX_op_rotrv_vec:
2992         return -1;
2993     default:
2994         return 0;
2995     }
2998 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
2999                             TCGReg dst, TCGReg src)
3001     tcg_debug_assert(dst >= TCG_REG_V0);
3003     /* Splat from integer reg allowed via constraints for v3.00.  */
3004     if (src < TCG_REG_V0) {
3005         tcg_debug_assert(have_isa_3_00);
3006         switch (vece) {
3007         case MO_64:
3008             tcg_out32(s, MTVSRDD | VRT(dst) | RA(src) | RB(src));
3009             return true;
3010         case MO_32:
3011             tcg_out32(s, MTVSRWS | VRT(dst) | RA(src));
3012             return true;
3013         default:
3014             /* Fail, so that we fall back on either dupm or mov+dup.  */
3015             return false;
3016         }
3017     }
3019     /*
3020      * Recall we use (or emulate) VSX integer loads, so the integer is
3021      * right justified within the left (zero-index) double-word.
3022      */
3023     switch (vece) {
3024     case MO_8:
3025         tcg_out32(s, VSPLTB | VRT(dst) | VRB(src) | (7 << 16));
3026         break;
3027     case MO_16:
3028         tcg_out32(s, VSPLTH | VRT(dst) | VRB(src) | (3 << 16));
3029         break;
3030     case MO_32:
3031         tcg_out32(s, VSPLTW | VRT(dst) | VRB(src) | (1 << 16));
3032         break;
3033     case MO_64:
3034         if (have_vsx) {
3035             tcg_out32(s, XXPERMDI | VRT(dst) | VRA(src) | VRB(src));
3036             break;
3037         }
3038         tcg_out_vsldoi(s, TCG_VEC_TMP1, src, src, 8);
3039         tcg_out_vsldoi(s, dst, TCG_VEC_TMP1, src, 8);
3040         break;
3041     default:
3042         g_assert_not_reached();
3043     }
3044     return true;
3047 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
3048                              TCGReg out, TCGReg base, intptr_t offset)
3050     int elt;
3052     tcg_debug_assert(out >= TCG_REG_V0);
3053     switch (vece) {
3054     case MO_8:
3055         if (have_isa_3_00) {
3056             tcg_out_mem_long(s, LXV, LVX, out, base, offset & -16);
3057         } else {
3058             tcg_out_mem_long(s, 0, LVEBX, out, base, offset);
3059         }
3060         elt = extract32(offset, 0, 4);
3061 #ifndef HOST_WORDS_BIGENDIAN
3062         elt ^= 15;
3063 #endif
3064         tcg_out32(s, VSPLTB | VRT(out) | VRB(out) | (elt << 16));
3065         break;
3066     case MO_16:
3067         tcg_debug_assert((offset & 1) == 0);
3068         if (have_isa_3_00) {
3069             tcg_out_mem_long(s, LXV | 8, LVX, out, base, offset & -16);
3070         } else {
3071             tcg_out_mem_long(s, 0, LVEHX, out, base, offset);
3072         }
3073         elt = extract32(offset, 1, 3);
3074 #ifndef HOST_WORDS_BIGENDIAN
3075         elt ^= 7;
3076 #endif
3077         tcg_out32(s, VSPLTH | VRT(out) | VRB(out) | (elt << 16));
3078         break;
3079     case MO_32:
3080         if (have_isa_3_00) {
3081             tcg_out_mem_long(s, 0, LXVWSX, out, base, offset);
3082             break;
3083         }
3084         tcg_debug_assert((offset & 3) == 0);
3085         tcg_out_mem_long(s, 0, LVEWX, out, base, offset);
3086         elt = extract32(offset, 2, 2);
3087 #ifndef HOST_WORDS_BIGENDIAN
3088         elt ^= 3;
3089 #endif
3090         tcg_out32(s, VSPLTW | VRT(out) | VRB(out) | (elt << 16));
3091         break;
3092     case MO_64:
3093         if (have_vsx) {
3094             tcg_out_mem_long(s, 0, LXVDSX, out, base, offset);
3095             break;
3096         }
3097         tcg_debug_assert((offset & 7) == 0);
3098         tcg_out_mem_long(s, 0, LVX, out, base, offset & -16);
3099         tcg_out_vsldoi(s, TCG_VEC_TMP1, out, out, 8);
3100         elt = extract32(offset, 3, 1);
3101 #ifndef HOST_WORDS_BIGENDIAN
3102         elt = !elt;
3103 #endif
3104         if (elt) {
3105             tcg_out_vsldoi(s, out, out, TCG_VEC_TMP1, 8);
3106         } else {
3107             tcg_out_vsldoi(s, out, TCG_VEC_TMP1, out, 8);
3108         }
3109         break;
3110     default:
3111         g_assert_not_reached();
3112     }
3113     return true;
3116 static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
3117                            unsigned vecl, unsigned vece,
3118                            const TCGArg *args, const int *const_args)
3120     static const uint32_t
3121         add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM },
3122         sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM },
3123         mul_op[4] = { 0, 0, VMULUWM, VMULLD },
3124         neg_op[4] = { 0, 0, VNEGW, VNEGD },
3125         eq_op[4]  = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD },
3126         ne_op[4]  = { VCMPNEB, VCMPNEH, VCMPNEW, 0 },
3127         gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD },
3128         gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD },
3129         ssadd_op[4] = { VADDSBS, VADDSHS, VADDSWS, 0 },
3130         usadd_op[4] = { VADDUBS, VADDUHS, VADDUWS, 0 },
3131         sssub_op[4] = { VSUBSBS, VSUBSHS, VSUBSWS, 0 },
3132         ussub_op[4] = { VSUBUBS, VSUBUHS, VSUBUWS, 0 },
3133         umin_op[4] = { VMINUB, VMINUH, VMINUW, VMINUD },
3134         smin_op[4] = { VMINSB, VMINSH, VMINSW, VMINSD },
3135         umax_op[4] = { VMAXUB, VMAXUH, VMAXUW, VMAXUD },
3136         smax_op[4] = { VMAXSB, VMAXSH, VMAXSW, VMAXSD },
3137         shlv_op[4] = { VSLB, VSLH, VSLW, VSLD },
3138         shrv_op[4] = { VSRB, VSRH, VSRW, VSRD },
3139         sarv_op[4] = { VSRAB, VSRAH, VSRAW, VSRAD },
3140         mrgh_op[4] = { VMRGHB, VMRGHH, VMRGHW, 0 },
3141         mrgl_op[4] = { VMRGLB, VMRGLH, VMRGLW, 0 },
3142         muleu_op[4] = { VMULEUB, VMULEUH, VMULEUW, 0 },
3143         mulou_op[4] = { VMULOUB, VMULOUH, VMULOUW, 0 },
3144         pkum_op[4] = { VPKUHUM, VPKUWUM, 0, 0 },
3145         rotl_op[4] = { VRLB, VRLH, VRLW, VRLD };
3147     TCGType type = vecl + TCG_TYPE_V64;
3148     TCGArg a0 = args[0], a1 = args[1], a2 = args[2];
3149     uint32_t insn;
3151     switch (opc) {
3152     case INDEX_op_ld_vec:
3153         tcg_out_ld(s, type, a0, a1, a2);
3154         return;
3155     case INDEX_op_st_vec:
3156         tcg_out_st(s, type, a0, a1, a2);
3157         return;
3158     case INDEX_op_dupm_vec:
3159         tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
3160         return;
3162     case INDEX_op_add_vec:
3163         insn = add_op[vece];
3164         break;
3165     case INDEX_op_sub_vec:
3166         insn = sub_op[vece];
3167         break;
3168     case INDEX_op_neg_vec:
3169         insn = neg_op[vece];
3170         a2 = a1;
3171         a1 = 0;
3172         break;
3173     case INDEX_op_mul_vec:
3174         insn = mul_op[vece];
3175         break;
3176     case INDEX_op_ssadd_vec:
3177         insn = ssadd_op[vece];
3178         break;
3179     case INDEX_op_sssub_vec:
3180         insn = sssub_op[vece];
3181         break;
3182     case INDEX_op_usadd_vec:
3183         insn = usadd_op[vece];
3184         break;
3185     case INDEX_op_ussub_vec:
3186         insn = ussub_op[vece];
3187         break;
3188     case INDEX_op_smin_vec:
3189         insn = smin_op[vece];
3190         break;
3191     case INDEX_op_umin_vec:
3192         insn = umin_op[vece];
3193         break;
3194     case INDEX_op_smax_vec:
3195         insn = smax_op[vece];
3196         break;
3197     case INDEX_op_umax_vec:
3198         insn = umax_op[vece];
3199         break;
3200     case INDEX_op_shlv_vec:
3201         insn = shlv_op[vece];
3202         break;
3203     case INDEX_op_shrv_vec:
3204         insn = shrv_op[vece];
3205         break;
3206     case INDEX_op_sarv_vec:
3207         insn = sarv_op[vece];
3208         break;
3209     case INDEX_op_and_vec:
3210         insn = VAND;
3211         break;
3212     case INDEX_op_or_vec:
3213         insn = VOR;
3214         break;
3215     case INDEX_op_xor_vec:
3216         insn = VXOR;
3217         break;
3218     case INDEX_op_andc_vec:
3219         insn = VANDC;
3220         break;
3221     case INDEX_op_not_vec:
3222         insn = VNOR;
3223         a2 = a1;
3224         break;
3225     case INDEX_op_orc_vec:
3226         insn = VORC;
3227         break;
3229     case INDEX_op_cmp_vec:
3230         switch (args[3]) {
3231         case TCG_COND_EQ:
3232             insn = eq_op[vece];
3233             break;
3234         case TCG_COND_NE:
3235             insn = ne_op[vece];
3236             break;
3237         case TCG_COND_GT:
3238             insn = gts_op[vece];
3239             break;
3240         case TCG_COND_GTU:
3241             insn = gtu_op[vece];
3242             break;
3243         default:
3244             g_assert_not_reached();
3245         }
3246         break;
3248     case INDEX_op_bitsel_vec:
3249         tcg_out32(s, XXSEL | VRT(a0) | VRC(a1) | VRB(a2) | VRA(args[3]));
3250         return;
3252     case INDEX_op_dup2_vec:
3253         assert(TCG_TARGET_REG_BITS == 32);
3254         /* With inputs a1 = xLxx, a2 = xHxx  */
3255         tcg_out32(s, VMRGHW | VRT(a0) | VRA(a2) | VRB(a1));  /* a0  = xxHL */
3256         tcg_out_vsldoi(s, TCG_VEC_TMP1, a0, a0, 8);          /* tmp = HLxx */
3257         tcg_out_vsldoi(s, a0, a0, TCG_VEC_TMP1, 8);          /* a0  = HLHL */
3258         return;
3260     case INDEX_op_ppc_mrgh_vec:
3261         insn = mrgh_op[vece];
3262         break;
3263     case INDEX_op_ppc_mrgl_vec:
3264         insn = mrgl_op[vece];
3265         break;
3266     case INDEX_op_ppc_muleu_vec:
3267         insn = muleu_op[vece];
3268         break;
3269     case INDEX_op_ppc_mulou_vec:
3270         insn = mulou_op[vece];
3271         break;
3272     case INDEX_op_ppc_pkum_vec:
3273         insn = pkum_op[vece];
3274         break;
3275     case INDEX_op_rotlv_vec:
3276         insn = rotl_op[vece];
3277         break;
3278     case INDEX_op_ppc_msum_vec:
3279         tcg_debug_assert(vece == MO_16);
3280         tcg_out32(s, VMSUMUHM | VRT(a0) | VRA(a1) | VRB(a2) | VRC(args[3]));
3281         return;
3283     case INDEX_op_mov_vec:  /* Always emitted via tcg_out_mov.  */
3284     case INDEX_op_dup_vec:  /* Always emitted via tcg_out_dup_vec.  */
3285     default:
3286         g_assert_not_reached();
3287     }
3289     tcg_debug_assert(insn != 0);
3290     tcg_out32(s, insn | VRT(a0) | VRA(a1) | VRB(a2));
3293 static void expand_vec_shi(TCGType type, unsigned vece, TCGv_vec v0,
3294                            TCGv_vec v1, TCGArg imm, TCGOpcode opci)
3296     TCGv_vec t1;
3298     if (vece == MO_32) {
3299         /*
3300          * Only 5 bits are significant, and VSPLTISB can represent -16..15.
3301          * So using negative numbers gets us the 4th bit easily.
3302          */
3303         imm = sextract32(imm, 0, 5);
3304     } else {
3305         imm &= (8 << vece) - 1;
3306     }
3308     /* Splat w/bytes for xxspltib when 2.07 allows MO_64. */
3309     t1 = tcg_constant_vec(type, MO_8, imm);
3310     vec_gen_3(opci, type, vece, tcgv_vec_arg(v0),
3311               tcgv_vec_arg(v1), tcgv_vec_arg(t1));
3314 static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
3315                            TCGv_vec v1, TCGv_vec v2, TCGCond cond)
3317     bool need_swap = false, need_inv = false;
3319     tcg_debug_assert(vece <= MO_32 || have_isa_2_07);
3321     switch (cond) {
3322     case TCG_COND_EQ:
3323     case TCG_COND_GT:
3324     case TCG_COND_GTU:
3325         break;
3326     case TCG_COND_NE:
3327         if (have_isa_3_00 && vece <= MO_32) {
3328             break;
3329         }
3330         /* fall through */
3331     case TCG_COND_LE:
3332     case TCG_COND_LEU:
3333         need_inv = true;
3334         break;
3335     case TCG_COND_LT:
3336     case TCG_COND_LTU:
3337         need_swap = true;
3338         break;
3339     case TCG_COND_GE:
3340     case TCG_COND_GEU:
3341         need_swap = need_inv = true;
3342         break;
3343     default:
3344         g_assert_not_reached();
3345     }
3347     if (need_inv) {
3348         cond = tcg_invert_cond(cond);
3349     }
3350     if (need_swap) {
3351         TCGv_vec t1;
3352         t1 = v1, v1 = v2, v2 = t1;
3353         cond = tcg_swap_cond(cond);
3354     }
3356     vec_gen_4(INDEX_op_cmp_vec, type, vece, tcgv_vec_arg(v0),
3357               tcgv_vec_arg(v1), tcgv_vec_arg(v2), cond);
3359     if (need_inv) {
3360         tcg_gen_not_vec(vece, v0, v0);
3361     }
3364 static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0,
3365                            TCGv_vec v1, TCGv_vec v2)
3367     TCGv_vec t1 = tcg_temp_new_vec(type);
3368     TCGv_vec t2 = tcg_temp_new_vec(type);
3369     TCGv_vec c0, c16;
3371     switch (vece) {
3372     case MO_8:
3373     case MO_16:
3374         vec_gen_3(INDEX_op_ppc_muleu_vec, type, vece, tcgv_vec_arg(t1),
3375                   tcgv_vec_arg(v1), tcgv_vec_arg(v2));
3376         vec_gen_3(INDEX_op_ppc_mulou_vec, type, vece, tcgv_vec_arg(t2),
3377                   tcgv_vec_arg(v1), tcgv_vec_arg(v2));
3378         vec_gen_3(INDEX_op_ppc_mrgh_vec, type, vece + 1, tcgv_vec_arg(v0),
3379                   tcgv_vec_arg(t1), tcgv_vec_arg(t2));
3380         vec_gen_3(INDEX_op_ppc_mrgl_vec, type, vece + 1, tcgv_vec_arg(t1),
3381                   tcgv_vec_arg(t1), tcgv_vec_arg(t2));
3382         vec_gen_3(INDEX_op_ppc_pkum_vec, type, vece, tcgv_vec_arg(v0),
3383                   tcgv_vec_arg(v0), tcgv_vec_arg(t1));
3384         break;
3386     case MO_32:
3387         tcg_debug_assert(!have_isa_2_07);
3388         /*
3389          * Only 5 bits are significant, and VSPLTISB can represent -16..15.
3390          * So using -16 is a quick way to represent 16.
3391          */
3392         c16 = tcg_constant_vec(type, MO_8, -16);
3393         c0 = tcg_constant_vec(type, MO_8, 0);
3395         vec_gen_3(INDEX_op_rotlv_vec, type, MO_32, tcgv_vec_arg(t1),
3396                   tcgv_vec_arg(v2), tcgv_vec_arg(c16));
3397         vec_gen_3(INDEX_op_ppc_mulou_vec, type, MO_16, tcgv_vec_arg(t2),
3398                   tcgv_vec_arg(v1), tcgv_vec_arg(v2));
3399         vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t1),
3400                   tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(c0));
3401         vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t1),
3402                   tcgv_vec_arg(t1), tcgv_vec_arg(c16));
3403         tcg_gen_add_vec(MO_32, v0, t1, t2);
3404         break;
3406     default:
3407         g_assert_not_reached();
3408     }
3409     tcg_temp_free_vec(t1);
3410     tcg_temp_free_vec(t2);
3413 void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
3414                        TCGArg a0, ...)
3416     va_list va;
3417     TCGv_vec v0, v1, v2, t0;
3418     TCGArg a2;
3420     va_start(va, a0);
3421     v0 = temp_tcgv_vec(arg_temp(a0));
3422     v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
3423     a2 = va_arg(va, TCGArg);
3425     switch (opc) {
3426     case INDEX_op_shli_vec:
3427         expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_shlv_vec);
3428         break;
3429     case INDEX_op_shri_vec:
3430         expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_shrv_vec);
3431         break;
3432     case INDEX_op_sari_vec:
3433         expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_sarv_vec);
3434         break;
3435     case INDEX_op_rotli_vec:
3436         expand_vec_shi(type, vece, v0, v1, a2, INDEX_op_rotlv_vec);
3437         break;
3438     case INDEX_op_cmp_vec:
3439         v2 = temp_tcgv_vec(arg_temp(a2));
3440         expand_vec_cmp(type, vece, v0, v1, v2, va_arg(va, TCGArg));
3441         break;
3442     case INDEX_op_mul_vec:
3443         v2 = temp_tcgv_vec(arg_temp(a2));
3444         expand_vec_mul(type, vece, v0, v1, v2);
3445         break;
3446     case INDEX_op_rotlv_vec:
3447         v2 = temp_tcgv_vec(arg_temp(a2));
3448         t0 = tcg_temp_new_vec(type);
3449         tcg_gen_neg_vec(vece, t0, v2);
3450         tcg_gen_rotlv_vec(vece, v0, v1, t0);
3451         tcg_temp_free_vec(t0);
3452         break;
3453     default:
3454         g_assert_not_reached();
3455     }
3456     va_end(va);
3459 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
3461     switch (op) {
3462     case INDEX_op_goto_ptr:
3463         return C_O0_I1(r);
3465     case INDEX_op_ld8u_i32:
3466     case INDEX_op_ld8s_i32:
3467     case INDEX_op_ld16u_i32:
3468     case INDEX_op_ld16s_i32:
3469     case INDEX_op_ld_i32:
3470     case INDEX_op_ctpop_i32:
3471     case INDEX_op_neg_i32:
3472     case INDEX_op_not_i32:
3473     case INDEX_op_ext8s_i32:
3474     case INDEX_op_ext16s_i32:
3475     case INDEX_op_bswap16_i32:
3476     case INDEX_op_bswap32_i32:
3477     case INDEX_op_extract_i32:
3478     case INDEX_op_ld8u_i64:
3479     case INDEX_op_ld8s_i64:
3480     case INDEX_op_ld16u_i64:
3481     case INDEX_op_ld16s_i64:
3482     case INDEX_op_ld32u_i64:
3483     case INDEX_op_ld32s_i64:
3484     case INDEX_op_ld_i64:
3485     case INDEX_op_ctpop_i64:
3486     case INDEX_op_neg_i64:
3487     case INDEX_op_not_i64:
3488     case INDEX_op_ext8s_i64:
3489     case INDEX_op_ext16s_i64:
3490     case INDEX_op_ext32s_i64:
3491     case INDEX_op_ext_i32_i64:
3492     case INDEX_op_extu_i32_i64:
3493     case INDEX_op_bswap16_i64:
3494     case INDEX_op_bswap32_i64:
3495     case INDEX_op_bswap64_i64:
3496     case INDEX_op_extract_i64:
3497         return C_O1_I1(r, r);
3499     case INDEX_op_st8_i32:
3500     case INDEX_op_st16_i32:
3501     case INDEX_op_st_i32:
3502     case INDEX_op_st8_i64:
3503     case INDEX_op_st16_i64:
3504     case INDEX_op_st32_i64:
3505     case INDEX_op_st_i64:
3506         return C_O0_I2(r, r);
3508     case INDEX_op_add_i32:
3509     case INDEX_op_and_i32:
3510     case INDEX_op_or_i32:
3511     case INDEX_op_xor_i32:
3512     case INDEX_op_andc_i32:
3513     case INDEX_op_orc_i32:
3514     case INDEX_op_eqv_i32:
3515     case INDEX_op_shl_i32:
3516     case INDEX_op_shr_i32:
3517     case INDEX_op_sar_i32:
3518     case INDEX_op_rotl_i32:
3519     case INDEX_op_rotr_i32:
3520     case INDEX_op_setcond_i32:
3521     case INDEX_op_and_i64:
3522     case INDEX_op_andc_i64:
3523     case INDEX_op_shl_i64:
3524     case INDEX_op_shr_i64:
3525     case INDEX_op_sar_i64:
3526     case INDEX_op_rotl_i64:
3527     case INDEX_op_rotr_i64:
3528     case INDEX_op_setcond_i64:
3529         return C_O1_I2(r, r, ri);
3531     case INDEX_op_mul_i32:
3532     case INDEX_op_mul_i64:
3533         return C_O1_I2(r, r, rI);
3535     case INDEX_op_div_i32:
3536     case INDEX_op_divu_i32:
3537     case INDEX_op_nand_i32:
3538     case INDEX_op_nor_i32:
3539     case INDEX_op_muluh_i32:
3540     case INDEX_op_mulsh_i32:
3541     case INDEX_op_orc_i64:
3542     case INDEX_op_eqv_i64:
3543     case INDEX_op_nand_i64:
3544     case INDEX_op_nor_i64:
3545     case INDEX_op_div_i64:
3546     case INDEX_op_divu_i64:
3547     case INDEX_op_mulsh_i64:
3548     case INDEX_op_muluh_i64:
3549         return C_O1_I2(r, r, r);
3551     case INDEX_op_sub_i32:
3552         return C_O1_I2(r, rI, ri);
3553     case INDEX_op_add_i64:
3554         return C_O1_I2(r, r, rT);
3555     case INDEX_op_or_i64:
3556     case INDEX_op_xor_i64:
3557         return C_O1_I2(r, r, rU);
3558     case INDEX_op_sub_i64:
3559         return C_O1_I2(r, rI, rT);
3560     case INDEX_op_clz_i32:
3561     case INDEX_op_ctz_i32:
3562     case INDEX_op_clz_i64:
3563     case INDEX_op_ctz_i64:
3564         return C_O1_I2(r, r, rZW);
3566     case INDEX_op_brcond_i32:
3567     case INDEX_op_brcond_i64:
3568         return C_O0_I2(r, ri);
3570     case INDEX_op_movcond_i32:
3571     case INDEX_op_movcond_i64:
3572         return C_O1_I4(r, r, ri, rZ, rZ);
3573     case INDEX_op_deposit_i32:
3574     case INDEX_op_deposit_i64:
3575         return C_O1_I2(r, 0, rZ);
3576     case INDEX_op_brcond2_i32:
3577         return C_O0_I4(r, r, ri, ri);
3578     case INDEX_op_setcond2_i32:
3579         return C_O1_I4(r, r, r, ri, ri);
3580     case INDEX_op_add2_i64:
3581     case INDEX_op_add2_i32:
3582         return C_O2_I4(r, r, r, r, rI, rZM);
3583     case INDEX_op_sub2_i64:
3584     case INDEX_op_sub2_i32:
3585         return C_O2_I4(r, r, rI, rZM, r, r);
3587     case INDEX_op_qemu_ld_i32:
3588         return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
3589                 ? C_O1_I1(r, L)
3590                 : C_O1_I2(r, L, L));
3592     case INDEX_op_qemu_st_i32:
3593         return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
3594                 ? C_O0_I2(S, S)
3595                 : C_O0_I3(S, S, S));
3597     case INDEX_op_qemu_ld_i64:
3598         return (TCG_TARGET_REG_BITS == 64 ? C_O1_I1(r, L)
3599                 : TARGET_LONG_BITS == 32 ? C_O2_I1(L, L, L)
3600                 : C_O2_I2(L, L, L, L));
3602     case INDEX_op_qemu_st_i64:
3603         return (TCG_TARGET_REG_BITS == 64 ? C_O0_I2(S, S)
3604                 : TARGET_LONG_BITS == 32 ? C_O0_I3(S, S, S)
3605                 : C_O0_I4(S, S, S, S));
3607     case INDEX_op_add_vec:
3608     case INDEX_op_sub_vec:
3609     case INDEX_op_mul_vec:
3610     case INDEX_op_and_vec:
3611     case INDEX_op_or_vec:
3612     case INDEX_op_xor_vec:
3613     case INDEX_op_andc_vec:
3614     case INDEX_op_orc_vec:
3615     case INDEX_op_cmp_vec:
3616     case INDEX_op_ssadd_vec:
3617     case INDEX_op_sssub_vec:
3618     case INDEX_op_usadd_vec:
3619     case INDEX_op_ussub_vec:
3620     case INDEX_op_smax_vec:
3621     case INDEX_op_smin_vec:
3622     case INDEX_op_umax_vec:
3623     case INDEX_op_umin_vec:
3624     case INDEX_op_shlv_vec:
3625     case INDEX_op_shrv_vec:
3626     case INDEX_op_sarv_vec:
3627     case INDEX_op_rotlv_vec:
3628     case INDEX_op_rotrv_vec:
3629     case INDEX_op_ppc_mrgh_vec:
3630     case INDEX_op_ppc_mrgl_vec:
3631     case INDEX_op_ppc_muleu_vec:
3632     case INDEX_op_ppc_mulou_vec:
3633     case INDEX_op_ppc_pkum_vec:
3634     case INDEX_op_dup2_vec:
3635         return C_O1_I2(v, v, v);
3637     case INDEX_op_not_vec:
3638     case INDEX_op_neg_vec:
3639         return C_O1_I1(v, v);
3641     case INDEX_op_dup_vec:
3642         return have_isa_3_00 ? C_O1_I1(v, vr) : C_O1_I1(v, v);
3644     case INDEX_op_ld_vec:
3645     case INDEX_op_dupm_vec:
3646         return C_O1_I1(v, r);
3648     case INDEX_op_st_vec:
3649         return C_O0_I2(v, r);
3651     case INDEX_op_bitsel_vec:
3652     case INDEX_op_ppc_msum_vec:
3653         return C_O1_I3(v, v, v, v);
3655     default:
3656         g_assert_not_reached();
3657     }
3660 static void tcg_target_init(TCGContext *s)
3662     unsigned long hwcap = qemu_getauxval(AT_HWCAP);
3663     unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2);
3665     have_isa = tcg_isa_base;
3666     if (hwcap & PPC_FEATURE_ARCH_2_06) {
3667         have_isa = tcg_isa_2_06;
3668     }
3669 #ifdef PPC_FEATURE2_ARCH_2_07
3670     if (hwcap2 & PPC_FEATURE2_ARCH_2_07) {
3671         have_isa = tcg_isa_2_07;
3672     }
3673 #endif
3674 #ifdef PPC_FEATURE2_ARCH_3_00
3675     if (hwcap2 & PPC_FEATURE2_ARCH_3_00) {
3676         have_isa = tcg_isa_3_00;
3677     }
3678 #endif
3679 #ifdef PPC_FEATURE2_ARCH_3_10
3680     if (hwcap2 & PPC_FEATURE2_ARCH_3_10) {
3681         have_isa = tcg_isa_3_10;
3682     }
3683 #endif
3685 #ifdef PPC_FEATURE2_HAS_ISEL
3686     /* Prefer explicit instruction from the kernel. */
3687     have_isel = (hwcap2 & PPC_FEATURE2_HAS_ISEL) != 0;
3688 #else
3689     /* Fall back to knowing Power7 (2.06) has ISEL. */
3690     have_isel = have_isa_2_06;
3691 #endif
3693     if (hwcap & PPC_FEATURE_HAS_ALTIVEC) {
3694         have_altivec = true;
3695         /* We only care about the portion of VSX that overlaps Altivec. */
3696         if (hwcap & PPC_FEATURE_HAS_VSX) {
3697             have_vsx = true;
3698         }
3699     }
3701     tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
3702     tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
3703     if (have_altivec) {
3704         tcg_target_available_regs[TCG_TYPE_V64] = 0xffffffff00000000ull;
3705         tcg_target_available_regs[TCG_TYPE_V128] = 0xffffffff00000000ull;
3706     }
3708     tcg_target_call_clobber_regs = 0;
3709     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
3710     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
3711     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
3712     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
3713     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
3714     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
3715     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R7);
3716     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
3717     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
3718     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
3719     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
3720     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12);
3722     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
3723     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
3724     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V2);
3725     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V3);
3726     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V4);
3727     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V5);
3728     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V6);
3729     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V7);
3730     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V8);
3731     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V9);
3732     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V10);
3733     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V11);
3734     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V12);
3735     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V13);
3736     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V14);
3737     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V15);
3738     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V16);
3739     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V17);
3740     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V18);
3741     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V19);
3743     s->reserved_regs = 0;
3744     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */
3745     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
3746 #if defined(_CALL_SYSV)
3747     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* toc pointer */
3748 #endif
3749 #if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64
3750     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
3751 #endif
3752     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */
3753     tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP1);
3754     tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP2);
3755     if (USE_REG_TB) {
3756         tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);  /* tb->tc_ptr */
3757     }
3760 #ifdef __ELF__
3761 typedef struct {
3762     DebugFrameCIE cie;
3763     DebugFrameFDEHeader fde;
3764     uint8_t fde_def_cfa[4];
3765     uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
3766 } DebugFrame;
3768 /* We're expecting a 2 byte uleb128 encoded value.  */
3769 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
3771 #if TCG_TARGET_REG_BITS == 64
3772 # define ELF_HOST_MACHINE EM_PPC64
3773 #else
3774 # define ELF_HOST_MACHINE EM_PPC
3775 #endif
3777 static DebugFrame debug_frame = {
3778     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
3779     .cie.id = -1,
3780     .cie.version = 1,
3781     .cie.code_align = 1,
3782     .cie.data_align = (-SZR & 0x7f),         /* sleb128 -SZR */
3783     .cie.return_column = 65,
3785     /* Total FDE size does not include the "len" member.  */
3786     .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
3788     .fde_def_cfa = {
3789         12, TCG_REG_R1,                 /* DW_CFA_def_cfa r1, ... */
3790         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
3791         (FRAME_SIZE >> 7)
3792     },
3793     .fde_reg_ofs = {
3794         /* DW_CFA_offset_extended_sf, lr, LR_OFFSET */
3795         0x11, 65, (LR_OFFSET / -SZR) & 0x7f,
3796     }
3799 void tcg_register_jit(const void *buf, size_t buf_size)
3801     uint8_t *p = &debug_frame.fde_reg_ofs[3];
3802     int i;
3804     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
3805         p[0] = 0x80 + tcg_target_callee_save_regs[i];
3806         p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR;
3807     }
3809     debug_frame.fde.func_start = (uintptr_t)buf;
3810     debug_frame.fde.func_len = buf_size;
3812     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
3814 #endif /* __ELF__ */