spapr_pci_vfio: Add spapr-pci-vfio-host-bridge to support vfio
[qemu-kvm.git] / tcg / ppc / tcg-target.c
blobc83fd9fdc01c5589e23026048b5325dc1aee9f19
1 /*
2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
25 #include "tcg-be-ldst.h"
27 #if defined _CALL_DARWIN || defined __APPLE__
28 #define TCG_TARGET_CALL_DARWIN
29 #endif
30 #ifdef _CALL_SYSV
31 # define TCG_TARGET_CALL_ALIGN_ARGS 1
32 #endif
34 /* For some memory operations, we need a scratch that isn't R0. For the AIX
35 calling convention, we can re-use the TOC register since we'll be reloading
36 it at every call. Otherwise R12 will do nicely as neither a call-saved
37 register nor a parameter register. */
38 #ifdef _CALL_AIX
39 # define TCG_REG_TMP1 TCG_REG_R2
40 #else
41 # define TCG_REG_TMP1 TCG_REG_R12
42 #endif
44 /* For the 64-bit target, we don't like the 5 insn sequence needed to build
45 full 64-bit addresses. Better to have a base register to which we can
46 apply a 32-bit displacement.
48 There are generally three items of interest:
49 (1) helper functions in the main executable,
50 (2) TranslationBlock data structures,
51 (3) the return address in the epilogue.
53 For user-only, we USE_STATIC_CODE_GEN_BUFFER, so the code_gen_buffer
54 will be inside the main executable, and thus near enough to make a
55 pointer to the epilogue be within 2GB of all helper functions.
57 For softmmu, we'll let the kernel choose the address of code_gen_buffer,
58 and odds are it'll be somewhere close to the main malloc arena, and so
59 a pointer to the epilogue will be within 2GB of the TranslationBlocks.
61 For --enable-pie, everything will be kinda near everything else,
62 somewhere in high memory.
64 Thus we choose to keep the return address in a call-saved register. */
65 #define TCG_REG_RA TCG_REG_R31
66 #define USE_REG_RA (TCG_TARGET_REG_BITS == 64)
68 /* Shorthand for size of a pointer. Avoid promotion to unsigned. */
69 #define SZP ((int)sizeof(void *))
71 /* Shorthand for size of a register. */
72 #define SZR (TCG_TARGET_REG_BITS / 8)
74 #define TCG_CT_CONST_S16 0x100
75 #define TCG_CT_CONST_U16 0x200
76 #define TCG_CT_CONST_S32 0x400
77 #define TCG_CT_CONST_U32 0x800
78 #define TCG_CT_CONST_ZERO 0x1000
79 #define TCG_CT_CONST_MONE 0x2000
81 static tcg_insn_unit *tb_ret_addr;
83 #ifndef GUEST_BASE
84 #define GUEST_BASE 0
85 #endif
87 #include "elf.h"
88 static bool have_isa_2_06;
89 #define HAVE_ISA_2_06 have_isa_2_06
90 #define HAVE_ISEL have_isa_2_06
92 #ifdef CONFIG_USE_GUEST_BASE
93 #define TCG_GUEST_BASE_REG 30
94 #else
95 #define TCG_GUEST_BASE_REG 0
96 #endif
98 #ifndef NDEBUG
99 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
100 "r0",
101 "r1",
102 "r2",
103 "r3",
104 "r4",
105 "r5",
106 "r6",
107 "r7",
108 "r8",
109 "r9",
110 "r10",
111 "r11",
112 "r12",
113 "r13",
114 "r14",
115 "r15",
116 "r16",
117 "r17",
118 "r18",
119 "r19",
120 "r20",
121 "r21",
122 "r22",
123 "r23",
124 "r24",
125 "r25",
126 "r26",
127 "r27",
128 "r28",
129 "r29",
130 "r30",
131 "r31"
133 #endif
135 static const int tcg_target_reg_alloc_order[] = {
136 TCG_REG_R14, /* call saved registers */
137 TCG_REG_R15,
138 TCG_REG_R16,
139 TCG_REG_R17,
140 TCG_REG_R18,
141 TCG_REG_R19,
142 TCG_REG_R20,
143 TCG_REG_R21,
144 TCG_REG_R22,
145 TCG_REG_R23,
146 TCG_REG_R24,
147 TCG_REG_R25,
148 TCG_REG_R26,
149 TCG_REG_R27,
150 TCG_REG_R28,
151 TCG_REG_R29,
152 TCG_REG_R30,
153 TCG_REG_R31,
154 TCG_REG_R12, /* call clobbered, non-arguments */
155 TCG_REG_R11,
156 TCG_REG_R2,
157 TCG_REG_R13,
158 TCG_REG_R10, /* call clobbered, arguments */
159 TCG_REG_R9,
160 TCG_REG_R8,
161 TCG_REG_R7,
162 TCG_REG_R6,
163 TCG_REG_R5,
164 TCG_REG_R4,
165 TCG_REG_R3,
168 static const int tcg_target_call_iarg_regs[] = {
169 TCG_REG_R3,
170 TCG_REG_R4,
171 TCG_REG_R5,
172 TCG_REG_R6,
173 TCG_REG_R7,
174 TCG_REG_R8,
175 TCG_REG_R9,
176 TCG_REG_R10
179 static const int tcg_target_call_oarg_regs[] = {
180 TCG_REG_R3,
181 TCG_REG_R4
184 static const int tcg_target_callee_save_regs[] = {
185 #ifdef TCG_TARGET_CALL_DARWIN
186 TCG_REG_R11,
187 #endif
188 TCG_REG_R14,
189 TCG_REG_R15,
190 TCG_REG_R16,
191 TCG_REG_R17,
192 TCG_REG_R18,
193 TCG_REG_R19,
194 TCG_REG_R20,
195 TCG_REG_R21,
196 TCG_REG_R22,
197 TCG_REG_R23,
198 TCG_REG_R24,
199 TCG_REG_R25,
200 TCG_REG_R26,
201 TCG_REG_R27, /* currently used for the global env */
202 TCG_REG_R28,
203 TCG_REG_R29,
204 TCG_REG_R30,
205 TCG_REG_R31
208 static inline bool in_range_b(tcg_target_long target)
210 return target == sextract64(target, 0, 26);
213 static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
215 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
216 assert(in_range_b(disp));
217 return disp & 0x3fffffc;
220 static void reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
222 *pc = (*pc & ~0x3fffffc) | reloc_pc24_val(pc, target);
225 static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
227 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
228 assert(disp == (int16_t) disp);
229 return disp & 0xfffc;
232 static void reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
234 *pc = (*pc & ~0xfffc) | reloc_pc14_val(pc, target);
237 static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
239 unsigned retrans = *s->code_ptr & 0x3fffffc;
240 tcg_out32(s, insn | retrans);
243 static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
245 unsigned retrans = *s->code_ptr & 0xfffc;
246 tcg_out32(s, insn | retrans);
249 static void patch_reloc(tcg_insn_unit *code_ptr, int type,
250 intptr_t value, intptr_t addend)
252 tcg_insn_unit *target = (tcg_insn_unit *)value;
254 assert(addend == 0);
255 switch (type) {
256 case R_PPC_REL14:
257 reloc_pc14(code_ptr, target);
258 break;
259 case R_PPC_REL24:
260 reloc_pc24(code_ptr, target);
261 break;
262 default:
263 tcg_abort();
267 /* parse target specific constraints */
268 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
270 const char *ct_str;
272 ct_str = *pct_str;
273 switch (ct_str[0]) {
274 case 'A': case 'B': case 'C': case 'D':
275 ct->ct |= TCG_CT_REG;
276 tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
277 break;
278 case 'r':
279 ct->ct |= TCG_CT_REG;
280 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
281 break;
282 case 'L': /* qemu_ld constraint */
283 ct->ct |= TCG_CT_REG;
284 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
285 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
286 #ifdef CONFIG_SOFTMMU
287 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
288 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
289 #endif
290 break;
291 case 'S': /* qemu_st constraint */
292 ct->ct |= TCG_CT_REG;
293 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
294 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
295 #ifdef CONFIG_SOFTMMU
296 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
297 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
298 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
299 #endif
300 break;
301 case 'I':
302 ct->ct |= TCG_CT_CONST_S16;
303 break;
304 case 'J':
305 ct->ct |= TCG_CT_CONST_U16;
306 break;
307 case 'M':
308 ct->ct |= TCG_CT_CONST_MONE;
309 break;
310 case 'T':
311 ct->ct |= TCG_CT_CONST_S32;
312 break;
313 case 'U':
314 ct->ct |= TCG_CT_CONST_U32;
315 break;
316 case 'Z':
317 ct->ct |= TCG_CT_CONST_ZERO;
318 break;
319 default:
320 return -1;
322 ct_str++;
323 *pct_str = ct_str;
324 return 0;
327 /* test if a constant matches the constraint */
328 static int tcg_target_const_match(tcg_target_long val, TCGType type,
329 const TCGArgConstraint *arg_ct)
331 int ct = arg_ct->ct;
332 if (ct & TCG_CT_CONST) {
333 return 1;
336 /* The only 32-bit constraint we use aside from
337 TCG_CT_CONST is TCG_CT_CONST_S16. */
338 if (type == TCG_TYPE_I32) {
339 val = (int32_t)val;
342 if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
343 return 1;
344 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
345 return 1;
346 } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
347 return 1;
348 } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
349 return 1;
350 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
351 return 1;
352 } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
353 return 1;
355 return 0;
358 #define OPCD(opc) ((opc)<<26)
359 #define XO19(opc) (OPCD(19)|((opc)<<1))
360 #define MD30(opc) (OPCD(30)|((opc)<<2))
361 #define MDS30(opc) (OPCD(30)|((opc)<<1))
362 #define XO31(opc) (OPCD(31)|((opc)<<1))
363 #define XO58(opc) (OPCD(58)|(opc))
364 #define XO62(opc) (OPCD(62)|(opc))
366 #define B OPCD( 18)
367 #define BC OPCD( 16)
368 #define LBZ OPCD( 34)
369 #define LHZ OPCD( 40)
370 #define LHA OPCD( 42)
371 #define LWZ OPCD( 32)
372 #define STB OPCD( 38)
373 #define STH OPCD( 44)
374 #define STW OPCD( 36)
376 #define STD XO62( 0)
377 #define STDU XO62( 1)
378 #define STDX XO31(149)
380 #define LD XO58( 0)
381 #define LDX XO31( 21)
382 #define LDU XO58( 1)
383 #define LWA XO58( 2)
384 #define LWAX XO31(341)
386 #define ADDIC OPCD( 12)
387 #define ADDI OPCD( 14)
388 #define ADDIS OPCD( 15)
389 #define ORI OPCD( 24)
390 #define ORIS OPCD( 25)
391 #define XORI OPCD( 26)
392 #define XORIS OPCD( 27)
393 #define ANDI OPCD( 28)
394 #define ANDIS OPCD( 29)
395 #define MULLI OPCD( 7)
396 #define CMPLI OPCD( 10)
397 #define CMPI OPCD( 11)
398 #define SUBFIC OPCD( 8)
400 #define LWZU OPCD( 33)
401 #define STWU OPCD( 37)
403 #define RLWIMI OPCD( 20)
404 #define RLWINM OPCD( 21)
405 #define RLWNM OPCD( 23)
407 #define RLDICL MD30( 0)
408 #define RLDICR MD30( 1)
409 #define RLDIMI MD30( 3)
410 #define RLDCL MDS30( 8)
412 #define BCLR XO19( 16)
413 #define BCCTR XO19(528)
414 #define CRAND XO19(257)
415 #define CRANDC XO19(129)
416 #define CRNAND XO19(225)
417 #define CROR XO19(449)
418 #define CRNOR XO19( 33)
420 #define EXTSB XO31(954)
421 #define EXTSH XO31(922)
422 #define EXTSW XO31(986)
423 #define ADD XO31(266)
424 #define ADDE XO31(138)
425 #define ADDME XO31(234)
426 #define ADDZE XO31(202)
427 #define ADDC XO31( 10)
428 #define AND XO31( 28)
429 #define SUBF XO31( 40)
430 #define SUBFC XO31( 8)
431 #define SUBFE XO31(136)
432 #define SUBFME XO31(232)
433 #define SUBFZE XO31(200)
434 #define OR XO31(444)
435 #define XOR XO31(316)
436 #define MULLW XO31(235)
437 #define MULHW XO31( 75)
438 #define MULHWU XO31( 11)
439 #define DIVW XO31(491)
440 #define DIVWU XO31(459)
441 #define CMP XO31( 0)
442 #define CMPL XO31( 32)
443 #define LHBRX XO31(790)
444 #define LWBRX XO31(534)
445 #define LDBRX XO31(532)
446 #define STHBRX XO31(918)
447 #define STWBRX XO31(662)
448 #define STDBRX XO31(660)
449 #define MFSPR XO31(339)
450 #define MTSPR XO31(467)
451 #define SRAWI XO31(824)
452 #define NEG XO31(104)
453 #define MFCR XO31( 19)
454 #define MFOCRF (MFCR | (1u << 20))
455 #define NOR XO31(124)
456 #define CNTLZW XO31( 26)
457 #define CNTLZD XO31( 58)
458 #define ANDC XO31( 60)
459 #define ORC XO31(412)
460 #define EQV XO31(284)
461 #define NAND XO31(476)
462 #define ISEL XO31( 15)
464 #define MULLD XO31(233)
465 #define MULHD XO31( 73)
466 #define MULHDU XO31( 9)
467 #define DIVD XO31(489)
468 #define DIVDU XO31(457)
470 #define LBZX XO31( 87)
471 #define LHZX XO31(279)
472 #define LHAX XO31(343)
473 #define LWZX XO31( 23)
474 #define STBX XO31(215)
475 #define STHX XO31(407)
476 #define STWX XO31(151)
478 #define SPR(a, b) ((((a)<<5)|(b))<<11)
479 #define LR SPR(8, 0)
480 #define CTR SPR(9, 0)
482 #define SLW XO31( 24)
483 #define SRW XO31(536)
484 #define SRAW XO31(792)
486 #define SLD XO31( 27)
487 #define SRD XO31(539)
488 #define SRAD XO31(794)
489 #define SRADI XO31(413<<1)
491 #define TW XO31( 4)
492 #define TRAP (TW | TO(31))
494 #define NOP ORI /* ori 0,0,0 */
496 #define RT(r) ((r)<<21)
497 #define RS(r) ((r)<<21)
498 #define RA(r) ((r)<<16)
499 #define RB(r) ((r)<<11)
500 #define TO(t) ((t)<<21)
501 #define SH(s) ((s)<<11)
502 #define MB(b) ((b)<<6)
503 #define ME(e) ((e)<<1)
504 #define BO(o) ((o)<<21)
505 #define MB64(b) ((b)<<5)
506 #define FXM(b) (1 << (19 - (b)))
508 #define LK 1
510 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
511 #define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
512 #define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
513 #define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
515 #define BF(n) ((n)<<23)
516 #define BI(n, c) (((c)+((n)*4))<<16)
517 #define BT(n, c) (((c)+((n)*4))<<21)
518 #define BA(n, c) (((c)+((n)*4))<<16)
519 #define BB(n, c) (((c)+((n)*4))<<11)
520 #define BC_(n, c) (((c)+((n)*4))<<6)
522 #define BO_COND_TRUE BO(12)
523 #define BO_COND_FALSE BO( 4)
524 #define BO_ALWAYS BO(20)
526 enum {
527 CR_LT,
528 CR_GT,
529 CR_EQ,
530 CR_SO
533 static const uint32_t tcg_to_bc[] = {
534 [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE,
535 [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE,
536 [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE,
537 [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE,
538 [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE,
539 [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE,
540 [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
541 [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
542 [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
543 [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
546 /* The low bit here is set if the RA and RB fields must be inverted. */
547 static const uint32_t tcg_to_isel[] = {
548 [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ),
549 [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1,
550 [TCG_COND_LT] = ISEL | BC_(7, CR_LT),
551 [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1,
552 [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1,
553 [TCG_COND_GT] = ISEL | BC_(7, CR_GT),
554 [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
555 [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
556 [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
557 [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
560 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
561 TCGReg base, tcg_target_long offset);
563 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
565 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
566 if (ret != arg) {
567 tcg_out32(s, OR | SAB(arg, ret, arg));
571 static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
572 int sh, int mb)
574 assert(TCG_TARGET_REG_BITS == 64);
575 sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
576 mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
577 tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
580 static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
581 int sh, int mb, int me)
583 tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
586 static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
588 tcg_out_rld(s, RLDICL, dst, src, 0, 32);
591 static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
593 tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
596 static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
598 tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
601 static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c)
603 tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31);
606 static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
608 tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
611 static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
613 if (arg == (int16_t) arg) {
614 tcg_out32(s, ADDI | TAI(ret, 0, arg));
615 } else {
616 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
617 if (arg & 0xffff) {
618 tcg_out32(s, ORI | SAI(ret, ret, arg));
623 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
624 tcg_target_long arg)
626 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
627 if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
628 tcg_out_movi32(s, ret, arg);
629 } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
630 tcg_out32(s, ADDI | TAI(ret, 0, arg));
631 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
632 } else {
633 int32_t high;
635 if (USE_REG_RA) {
636 intptr_t diff = arg - (intptr_t)tb_ret_addr;
637 if (diff == (int32_t)diff) {
638 tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_RA, diff);
639 return;
643 high = arg >> 31 >> 1;
644 tcg_out_movi32(s, ret, high);
645 if (high) {
646 tcg_out_shli64(s, ret, ret, 32);
648 if (arg & 0xffff0000) {
649 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
651 if (arg & 0xffff) {
652 tcg_out32(s, ORI | SAI(ret, ret, arg));
657 static bool mask_operand(uint32_t c, int *mb, int *me)
659 uint32_t lsb, test;
661 /* Accept a bit pattern like:
662 0....01....1
663 1....10....0
664 0..01..10..0
665 Keep track of the transitions. */
666 if (c == 0 || c == -1) {
667 return false;
669 test = c;
670 lsb = test & -test;
671 test += lsb;
672 if (test & (test - 1)) {
673 return false;
676 *me = clz32(lsb);
677 *mb = test ? clz32(test & -test) + 1 : 0;
678 return true;
681 static bool mask64_operand(uint64_t c, int *mb, int *me)
683 uint64_t lsb;
685 if (c == 0) {
686 return false;
689 lsb = c & -c;
690 /* Accept 1..10..0. */
691 if (c == -lsb) {
692 *mb = 0;
693 *me = clz64(lsb);
694 return true;
696 /* Accept 0..01..1. */
697 if (lsb == 1 && (c & (c + 1)) == 0) {
698 *mb = clz64(c + 1) + 1;
699 *me = 63;
700 return true;
702 return false;
705 static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
707 int mb, me;
709 if ((c & 0xffff) == c) {
710 tcg_out32(s, ANDI | SAI(src, dst, c));
711 return;
712 } else if ((c & 0xffff0000) == c) {
713 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
714 return;
715 } else if (mask_operand(c, &mb, &me)) {
716 tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
717 } else {
718 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
719 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
723 static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
725 int mb, me;
727 assert(TCG_TARGET_REG_BITS == 64);
728 if ((c & 0xffff) == c) {
729 tcg_out32(s, ANDI | SAI(src, dst, c));
730 return;
731 } else if ((c & 0xffff0000) == c) {
732 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
733 return;
734 } else if (mask64_operand(c, &mb, &me)) {
735 if (mb == 0) {
736 tcg_out_rld(s, RLDICR, dst, src, 0, me);
737 } else {
738 tcg_out_rld(s, RLDICL, dst, src, 0, mb);
740 } else {
741 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
742 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
746 static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
747 int op_lo, int op_hi)
749 if (c >> 16) {
750 tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
751 src = dst;
753 if (c & 0xffff) {
754 tcg_out32(s, op_lo | SAI(src, dst, c));
755 src = dst;
759 static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
761 tcg_out_zori32(s, dst, src, c, ORI, ORIS);
764 static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
766 tcg_out_zori32(s, dst, src, c, XORI, XORIS);
769 static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
771 ptrdiff_t disp = tcg_pcrel_diff(s, target);
772 if (in_range_b(disp)) {
773 tcg_out32(s, B | (disp & 0x3fffffc) | mask);
774 } else {
775 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
776 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
777 tcg_out32(s, BCCTR | BO_ALWAYS | mask);
781 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
782 TCGReg base, tcg_target_long offset)
784 tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
785 bool is_store = false;
786 TCGReg rs = TCG_REG_TMP1;
788 switch (opi) {
789 case LD: case LWA:
790 align = 3;
791 /* FALLTHRU */
792 default:
793 if (rt != TCG_REG_R0) {
794 rs = rt;
795 break;
797 break;
798 case STD:
799 align = 3;
800 /* FALLTHRU */
801 case STB: case STH: case STW:
802 is_store = true;
803 break;
806 /* For unaligned, or very large offsets, use the indexed form. */
807 if (offset & align || offset != (int32_t)offset) {
808 tcg_debug_assert(rs != base && (!is_store || rs != rt));
809 tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
810 tcg_out32(s, opx | TAB(rt, base, rs));
811 return;
814 l0 = (int16_t)offset;
815 offset = (offset - l0) >> 16;
816 l1 = (int16_t)offset;
818 if (l1 < 0 && orig >= 0) {
819 extra = 0x4000;
820 l1 = (int16_t)(offset - 0x4000);
822 if (l1) {
823 tcg_out32(s, ADDIS | TAI(rs, base, l1));
824 base = rs;
826 if (extra) {
827 tcg_out32(s, ADDIS | TAI(rs, base, extra));
828 base = rs;
830 if (opi != ADDI || base != rt || l0 != 0) {
831 tcg_out32(s, opi | TAI(rt, base, l0));
835 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
836 TCGReg arg1, intptr_t arg2)
838 int opi, opx;
840 assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
841 if (type == TCG_TYPE_I32) {
842 opi = LWZ, opx = LWZX;
843 } else {
844 opi = LD, opx = LDX;
846 tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
849 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
850 TCGReg arg1, intptr_t arg2)
852 int opi, opx;
854 assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
855 if (type == TCG_TYPE_I32) {
856 opi = STW, opx = STWX;
857 } else {
858 opi = STD, opx = STDX;
860 tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
863 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
864 int const_arg2, int cr, TCGType type)
866 int imm;
867 uint32_t op;
869 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
871 /* Simplify the comparisons below wrt CMPI. */
872 if (type == TCG_TYPE_I32) {
873 arg2 = (int32_t)arg2;
876 switch (cond) {
877 case TCG_COND_EQ:
878 case TCG_COND_NE:
879 if (const_arg2) {
880 if ((int16_t) arg2 == arg2) {
881 op = CMPI;
882 imm = 1;
883 break;
884 } else if ((uint16_t) arg2 == arg2) {
885 op = CMPLI;
886 imm = 1;
887 break;
890 op = CMPL;
891 imm = 0;
892 break;
894 case TCG_COND_LT:
895 case TCG_COND_GE:
896 case TCG_COND_LE:
897 case TCG_COND_GT:
898 if (const_arg2) {
899 if ((int16_t) arg2 == arg2) {
900 op = CMPI;
901 imm = 1;
902 break;
905 op = CMP;
906 imm = 0;
907 break;
909 case TCG_COND_LTU:
910 case TCG_COND_GEU:
911 case TCG_COND_LEU:
912 case TCG_COND_GTU:
913 if (const_arg2) {
914 if ((uint16_t) arg2 == arg2) {
915 op = CMPLI;
916 imm = 1;
917 break;
920 op = CMPL;
921 imm = 0;
922 break;
924 default:
925 tcg_abort();
927 op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
929 if (imm) {
930 tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
931 } else {
932 if (const_arg2) {
933 tcg_out_movi(s, type, TCG_REG_R0, arg2);
934 arg2 = TCG_REG_R0;
936 tcg_out32(s, op | RA(arg1) | RB(arg2));
940 static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
941 TCGReg dst, TCGReg src)
943 if (type == TCG_TYPE_I32) {
944 tcg_out32(s, CNTLZW | RS(src) | RA(dst));
945 tcg_out_shri32(s, dst, dst, 5);
946 } else {
947 tcg_out32(s, CNTLZD | RS(src) | RA(dst));
948 tcg_out_shri64(s, dst, dst, 6);
952 static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
954 /* X != 0 implies X + -1 generates a carry. Extra addition
955 trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C. */
956 if (dst != src) {
957 tcg_out32(s, ADDIC | TAI(dst, src, -1));
958 tcg_out32(s, SUBFE | TAB(dst, dst, src));
959 } else {
960 tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
961 tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
965 static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
966 bool const_arg2)
968 if (const_arg2) {
969 if ((uint32_t)arg2 == arg2) {
970 tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
971 } else {
972 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
973 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
975 } else {
976 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
978 return TCG_REG_R0;
981 static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
982 TCGArg arg0, TCGArg arg1, TCGArg arg2,
983 int const_arg2)
985 int crop, sh;
987 assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
989 /* Ignore high bits of a potential constant arg2. */
990 if (type == TCG_TYPE_I32) {
991 arg2 = (uint32_t)arg2;
994 /* Handle common and trivial cases before handling anything else. */
995 if (arg2 == 0) {
996 switch (cond) {
997 case TCG_COND_EQ:
998 tcg_out_setcond_eq0(s, type, arg0, arg1);
999 return;
1000 case TCG_COND_NE:
1001 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1002 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1003 arg1 = TCG_REG_R0;
1005 tcg_out_setcond_ne0(s, arg0, arg1);
1006 return;
1007 case TCG_COND_GE:
1008 tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1009 arg1 = arg0;
1010 /* FALLTHRU */
1011 case TCG_COND_LT:
1012 /* Extract the sign bit. */
1013 if (type == TCG_TYPE_I32) {
1014 tcg_out_shri32(s, arg0, arg1, 31);
1015 } else {
1016 tcg_out_shri64(s, arg0, arg1, 63);
1018 return;
1019 default:
1020 break;
1024 /* If we have ISEL, we can implement everything with 3 or 4 insns.
1025 All other cases below are also at least 3 insns, so speed up the
1026 code generator by not considering them and always using ISEL. */
1027 if (HAVE_ISEL) {
1028 int isel, tab;
1030 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1032 isel = tcg_to_isel[cond];
1034 tcg_out_movi(s, type, arg0, 1);
1035 if (isel & 1) {
1036 /* arg0 = (bc ? 0 : 1) */
1037 tab = TAB(arg0, 0, arg0);
1038 isel &= ~1;
1039 } else {
1040 /* arg0 = (bc ? 1 : 0) */
1041 tcg_out_movi(s, type, TCG_REG_R0, 0);
1042 tab = TAB(arg0, arg0, TCG_REG_R0);
1044 tcg_out32(s, isel | tab);
1045 return;
1048 switch (cond) {
1049 case TCG_COND_EQ:
1050 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1051 tcg_out_setcond_eq0(s, type, arg0, arg1);
1052 return;
1054 case TCG_COND_NE:
1055 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1056 /* Discard the high bits only once, rather than both inputs. */
1057 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1058 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1059 arg1 = TCG_REG_R0;
1061 tcg_out_setcond_ne0(s, arg0, arg1);
1062 return;
1064 case TCG_COND_GT:
1065 case TCG_COND_GTU:
1066 sh = 30;
1067 crop = 0;
1068 goto crtest;
1070 case TCG_COND_LT:
1071 case TCG_COND_LTU:
1072 sh = 29;
1073 crop = 0;
1074 goto crtest;
1076 case TCG_COND_GE:
1077 case TCG_COND_GEU:
1078 sh = 31;
1079 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1080 goto crtest;
1082 case TCG_COND_LE:
1083 case TCG_COND_LEU:
1084 sh = 31;
1085 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1086 crtest:
1087 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1088 if (crop) {
1089 tcg_out32(s, crop);
1091 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1092 tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1093 break;
1095 default:
1096 tcg_abort();
1100 static void tcg_out_bc(TCGContext *s, int bc, int label_index)
1102 TCGLabel *l = &s->labels[label_index];
1104 if (l->has_value) {
1105 tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value_ptr));
1106 } else {
1107 tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
1108 tcg_out_bc_noaddr(s, bc);
1112 static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1113 TCGArg arg1, TCGArg arg2, int const_arg2,
1114 int label_index, TCGType type)
1116 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1117 tcg_out_bc(s, tcg_to_bc[cond], label_index);
1120 static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1121 TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1122 TCGArg v2, bool const_c2)
1124 /* If for some reason both inputs are zero, don't produce bad code. */
1125 if (v1 == 0 && v2 == 0) {
1126 tcg_out_movi(s, type, dest, 0);
1127 return;
1130 tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1132 if (HAVE_ISEL) {
1133 int isel = tcg_to_isel[cond];
1135 /* Swap the V operands if the operation indicates inversion. */
1136 if (isel & 1) {
1137 int t = v1;
1138 v1 = v2;
1139 v2 = t;
1140 isel &= ~1;
1142 /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand. */
1143 if (v2 == 0) {
1144 tcg_out_movi(s, type, TCG_REG_R0, 0);
1146 tcg_out32(s, isel | TAB(dest, v1, v2));
1147 } else {
1148 if (dest == v2) {
1149 cond = tcg_invert_cond(cond);
1150 v2 = v1;
1151 } else if (dest != v1) {
1152 if (v1 == 0) {
1153 tcg_out_movi(s, type, dest, 0);
1154 } else {
1155 tcg_out_mov(s, type, dest, v1);
1158 /* Branch forward over one insn */
1159 tcg_out32(s, tcg_to_bc[cond] | 8);
1160 if (v2 == 0) {
1161 tcg_out_movi(s, type, dest, 0);
1162 } else {
1163 tcg_out_mov(s, type, dest, v2);
1168 static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1169 const int *const_args)
1171 static const struct { uint8_t bit1, bit2; } bits[] = {
1172 [TCG_COND_LT ] = { CR_LT, CR_LT },
1173 [TCG_COND_LE ] = { CR_LT, CR_GT },
1174 [TCG_COND_GT ] = { CR_GT, CR_GT },
1175 [TCG_COND_GE ] = { CR_GT, CR_LT },
1176 [TCG_COND_LTU] = { CR_LT, CR_LT },
1177 [TCG_COND_LEU] = { CR_LT, CR_GT },
1178 [TCG_COND_GTU] = { CR_GT, CR_GT },
1179 [TCG_COND_GEU] = { CR_GT, CR_LT },
1182 TCGCond cond = args[4], cond2;
1183 TCGArg al, ah, bl, bh;
1184 int blconst, bhconst;
1185 int op, bit1, bit2;
1187 al = args[0];
1188 ah = args[1];
1189 bl = args[2];
1190 bh = args[3];
1191 blconst = const_args[2];
1192 bhconst = const_args[3];
1194 switch (cond) {
1195 case TCG_COND_EQ:
1196 op = CRAND;
1197 goto do_equality;
1198 case TCG_COND_NE:
1199 op = CRNAND;
1200 do_equality:
1201 tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
1202 tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
1203 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1204 break;
1206 case TCG_COND_LT:
1207 case TCG_COND_LE:
1208 case TCG_COND_GT:
1209 case TCG_COND_GE:
1210 case TCG_COND_LTU:
1211 case TCG_COND_LEU:
1212 case TCG_COND_GTU:
1213 case TCG_COND_GEU:
1214 bit1 = bits[cond].bit1;
1215 bit2 = bits[cond].bit2;
1216 op = (bit1 != bit2 ? CRANDC : CRAND);
1217 cond2 = tcg_unsigned_cond(cond);
1219 tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
1220 tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
1221 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
1222 tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
1223 break;
1225 default:
1226 tcg_abort();
1230 static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
1231 const int *const_args)
1233 tcg_out_cmp2(s, args + 1, const_args + 1);
1234 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1235 tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
1238 static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1239 const int *const_args)
1241 tcg_out_cmp2(s, args, const_args);
1242 tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, args[5]);
1245 void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
1247 TCGContext s;
1249 s.code_buf = s.code_ptr = (tcg_insn_unit *)jmp_addr;
1250 tcg_out_b(&s, 0, (tcg_insn_unit *)addr);
1251 flush_icache_range(jmp_addr, jmp_addr + tcg_current_code_size(&s));
1254 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
1256 #ifdef _CALL_AIX
1257 /* Look through the descriptor. If the branch is in range, and we
1258 don't have to spend too much effort on building the toc. */
1259 void *tgt = ((void **)target)[0];
1260 uintptr_t toc = ((uintptr_t *)target)[1];
1261 intptr_t diff = tcg_pcrel_diff(s, tgt);
1263 if (in_range_b(diff) && toc == (uint32_t)toc) {
1264 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
1265 tcg_out_b(s, LK, tgt);
1266 } else {
1267 /* Fold the low bits of the constant into the addresses below. */
1268 intptr_t arg = (intptr_t)target;
1269 int ofs = (int16_t)arg;
1271 if (ofs + 8 < 0x8000) {
1272 arg -= ofs;
1273 } else {
1274 ofs = 0;
1276 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg);
1277 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
1278 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
1279 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
1280 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1282 #elif defined(_CALL_ELF) && _CALL_ELF == 2
1283 intptr_t diff;
1285 /* In the ELFv2 ABI, we have to set up r12 to contain the destination
1286 address, which the callee uses to compute its TOC address. */
1287 /* FIXME: when the branch is in range, we could avoid r12 load if we
1288 knew that the destination uses the same TOC, and what its local
1289 entry point offset is. */
1290 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target);
1292 diff = tcg_pcrel_diff(s, target);
1293 if (in_range_b(diff)) {
1294 tcg_out_b(s, LK, target);
1295 } else {
1296 tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
1297 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1299 #else
1300 tcg_out_b(s, LK, target);
1301 #endif
1304 static const uint32_t qemu_ldx_opc[16] = {
1305 [MO_UB] = LBZX,
1306 [MO_UW] = LHZX,
1307 [MO_UL] = LWZX,
1308 [MO_Q] = LDX,
1309 [MO_SW] = LHAX,
1310 [MO_SL] = LWAX,
1311 [MO_BSWAP | MO_UB] = LBZX,
1312 [MO_BSWAP | MO_UW] = LHBRX,
1313 [MO_BSWAP | MO_UL] = LWBRX,
1314 [MO_BSWAP | MO_Q] = LDBRX,
1317 static const uint32_t qemu_stx_opc[16] = {
1318 [MO_UB] = STBX,
1319 [MO_UW] = STHX,
1320 [MO_UL] = STWX,
1321 [MO_Q] = STDX,
1322 [MO_BSWAP | MO_UB] = STBX,
1323 [MO_BSWAP | MO_UW] = STHBRX,
1324 [MO_BSWAP | MO_UL] = STWBRX,
1325 [MO_BSWAP | MO_Q] = STDBRX,
1328 static const uint32_t qemu_exts_opc[4] = {
1329 EXTSB, EXTSH, EXTSW, 0
1332 #if defined (CONFIG_SOFTMMU)
1333 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1334 * int mmu_idx, uintptr_t ra)
1336 static void * const qemu_ld_helpers[16] = {
1337 [MO_UB] = helper_ret_ldub_mmu,
1338 [MO_LEUW] = helper_le_lduw_mmu,
1339 [MO_LEUL] = helper_le_ldul_mmu,
1340 [MO_LEQ] = helper_le_ldq_mmu,
1341 [MO_BEUW] = helper_be_lduw_mmu,
1342 [MO_BEUL] = helper_be_ldul_mmu,
1343 [MO_BEQ] = helper_be_ldq_mmu,
1346 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1347 * uintxx_t val, int mmu_idx, uintptr_t ra)
1349 static void * const qemu_st_helpers[16] = {
1350 [MO_UB] = helper_ret_stb_mmu,
1351 [MO_LEUW] = helper_le_stw_mmu,
1352 [MO_LEUL] = helper_le_stl_mmu,
1353 [MO_LEQ] = helper_le_stq_mmu,
1354 [MO_BEUW] = helper_be_stw_mmu,
1355 [MO_BEUL] = helper_be_stl_mmu,
1356 [MO_BEQ] = helper_be_stq_mmu,
1359 /* Perform the TLB load and compare. Places the result of the comparison
1360 in CR7, loads the addend of the TLB into R3, and returns the register
1361 containing the guest address (zero-extended into R4). Clobbers R0 and R2. */
1363 static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits,
1364 TCGReg addrlo, TCGReg addrhi,
1365 int mem_index, bool is_read)
1367 int cmp_off
1368 = (is_read
1369 ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
1370 : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
1371 int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
1372 TCGReg base = TCG_AREG0;
1374 /* Extract the page index, shifted into place for tlb index. */
1375 if (TCG_TARGET_REG_BITS == 64) {
1376 if (TARGET_LONG_BITS == 32) {
1377 /* Zero-extend the address into a place helpful for further use. */
1378 tcg_out_ext32u(s, TCG_REG_R4, addrlo);
1379 addrlo = TCG_REG_R4;
1380 } else {
1381 tcg_out_rld(s, RLDICL, TCG_REG_R3, addrlo,
1382 64 - TARGET_PAGE_BITS, 64 - CPU_TLB_BITS);
1386 /* Compensate for very large offsets. */
1387 if (add_off >= 0x8000) {
1388 /* Most target env are smaller than 32k; none are larger than 64k.
1389 Simplify the logic here merely to offset by 0x7ff0, giving us a
1390 range just shy of 64k. Check this assumption. */
1391 QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
1392 tlb_table[NB_MMU_MODES - 1][1])
1393 > 0x7ff0 + 0x7fff);
1394 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, base, 0x7ff0));
1395 base = TCG_REG_TMP1;
1396 cmp_off -= 0x7ff0;
1397 add_off -= 0x7ff0;
1400 /* Extraction and shifting, part 2. */
1401 if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
1402 tcg_out_rlw(s, RLWINM, TCG_REG_R3, addrlo,
1403 32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
1404 32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS),
1405 31 - CPU_TLB_ENTRY_BITS);
1406 } else {
1407 tcg_out_shli64(s, TCG_REG_R3, TCG_REG_R3, CPU_TLB_ENTRY_BITS);
1410 tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, base));
1412 /* Load the tlb comparator. */
1413 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1414 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off);
1415 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4);
1416 } else {
1417 tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off);
1420 /* Load the TLB addend for use on the fast path. Do this asap
1421 to minimize any load use delay. */
1422 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3, add_off);
1424 /* Clear the non-page, non-alignment bits from the address. */
1425 if (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32) {
1426 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
1427 (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
1428 } else if (!s_bits) {
1429 tcg_out_rld(s, RLDICR, TCG_REG_R0, addrlo,
1430 0, 63 - TARGET_PAGE_BITS);
1431 } else {
1432 tcg_out_rld(s, RLDICL, TCG_REG_R0, addrlo,
1433 64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
1434 tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
1437 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1438 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1439 0, 7, TCG_TYPE_I32);
1440 tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32);
1441 tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1442 } else {
1443 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1444 0, 7, TCG_TYPE_TL);
1447 return addrlo;
1450 /* Record the context of a call to the out of line helper code for the slow
1451 path for a load or store, so that we can later generate the correct
1452 helper code. */
1453 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
1454 TCGReg datalo_reg, TCGReg datahi_reg,
1455 TCGReg addrlo_reg, TCGReg addrhi_reg,
1456 int mem_index, tcg_insn_unit *raddr,
1457 tcg_insn_unit *lptr)
1459 TCGLabelQemuLdst *label = new_ldst_label(s);
1461 label->is_ld = is_ld;
1462 label->opc = opc;
1463 label->datalo_reg = datalo_reg;
1464 label->datahi_reg = datahi_reg;
1465 label->addrlo_reg = addrlo_reg;
1466 label->addrhi_reg = addrhi_reg;
1467 label->mem_index = mem_index;
1468 label->raddr = raddr;
1469 label->label_ptr[0] = lptr;
1472 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1474 TCGMemOp opc = lb->opc;
1475 TCGReg hi, lo, arg = TCG_REG_R3;
1477 reloc_pc14(lb->label_ptr[0], s->code_ptr);
1479 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1481 lo = lb->addrlo_reg;
1482 hi = lb->addrhi_reg;
1483 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1484 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1485 arg |= 1;
1486 #endif
1487 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1488 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1489 } else {
1490 /* If the address needed to be zero-extended, we'll have already
1491 placed it in R4. The only remaining case is 64-bit guest. */
1492 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1495 tcg_out_movi(s, TCG_TYPE_I32, arg++, lb->mem_index);
1496 tcg_out32(s, MFSPR | RT(arg) | LR);
1498 tcg_out_call(s, qemu_ld_helpers[opc & ~MO_SIGN]);
1500 lo = lb->datalo_reg;
1501 hi = lb->datahi_reg;
1502 if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1503 tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
1504 tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
1505 } else if (opc & MO_SIGN) {
1506 uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
1507 tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
1508 } else {
1509 tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
1512 tcg_out_b(s, 0, lb->raddr);
1515 static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1517 TCGMemOp opc = lb->opc;
1518 TCGMemOp s_bits = opc & MO_SIZE;
1519 TCGReg hi, lo, arg = TCG_REG_R3;
1521 reloc_pc14(lb->label_ptr[0], s->code_ptr);
1523 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1525 lo = lb->addrlo_reg;
1526 hi = lb->addrhi_reg;
1527 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1528 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1529 arg |= 1;
1530 #endif
1531 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1532 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1533 } else {
1534 /* If the address needed to be zero-extended, we'll have already
1535 placed it in R4. The only remaining case is 64-bit guest. */
1536 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1539 lo = lb->datalo_reg;
1540 hi = lb->datahi_reg;
1541 if (TCG_TARGET_REG_BITS == 32) {
1542 switch (s_bits) {
1543 case MO_64:
1544 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1545 arg |= 1;
1546 #endif
1547 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1548 /* FALLTHRU */
1549 case MO_32:
1550 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1551 break;
1552 default:
1553 tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
1554 break;
1556 } else {
1557 if (s_bits == MO_64) {
1558 tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
1559 } else {
1560 tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
1564 tcg_out_movi(s, TCG_TYPE_I32, arg++, lb->mem_index);
1565 tcg_out32(s, MFSPR | RT(arg) | LR);
1567 tcg_out_call(s, qemu_st_helpers[opc]);
1569 tcg_out_b(s, 0, lb->raddr);
1571 #endif /* SOFTMMU */
1573 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1575 TCGReg datalo, datahi, addrlo, rbase;
1576 TCGReg addrhi __attribute__((unused));
1577 TCGMemOp opc, s_bits;
1578 #ifdef CONFIG_SOFTMMU
1579 int mem_index;
1580 tcg_insn_unit *label_ptr;
1581 #endif
1583 datalo = *args++;
1584 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1585 addrlo = *args++;
1586 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1587 opc = *args++;
1588 s_bits = opc & MO_SIZE;
1590 #ifdef CONFIG_SOFTMMU
1591 mem_index = *args;
1592 addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, true);
1594 /* Load a pointer into the current opcode w/conditional branch-link. */
1595 label_ptr = s->code_ptr;
1596 tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1598 rbase = TCG_REG_R3;
1599 #else /* !CONFIG_SOFTMMU */
1600 rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1601 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1602 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1603 addrlo = TCG_REG_TMP1;
1605 #endif
1607 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1608 if (opc & MO_BSWAP) {
1609 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1610 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1611 tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0));
1612 } else if (rbase != 0) {
1613 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1614 tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo));
1615 tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0));
1616 } else if (addrlo == datahi) {
1617 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1618 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1619 } else {
1620 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1621 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1623 } else {
1624 uint32_t insn = qemu_ldx_opc[opc];
1625 if (!HAVE_ISA_2_06 && insn == LDBRX) {
1626 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1627 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1628 tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1629 tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0);
1630 } else if (insn) {
1631 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1632 } else {
1633 insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1634 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1635 insn = qemu_exts_opc[s_bits];
1636 tcg_out32(s, insn | RA(datalo) | RS(datalo));
1640 #ifdef CONFIG_SOFTMMU
1641 add_qemu_ldst_label(s, true, opc, datalo, datahi, addrlo, addrhi,
1642 mem_index, s->code_ptr, label_ptr);
1643 #endif
1646 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1648 TCGReg datalo, datahi, addrlo, rbase;
1649 TCGReg addrhi __attribute__((unused));
1650 TCGMemOp opc, s_bits;
1651 #ifdef CONFIG_SOFTMMU
1652 int mem_index;
1653 tcg_insn_unit *label_ptr;
1654 #endif
1656 datalo = *args++;
1657 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1658 addrlo = *args++;
1659 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1660 opc = *args++;
1661 s_bits = opc & MO_SIZE;
1663 #ifdef CONFIG_SOFTMMU
1664 mem_index = *args;
1665 addrlo = tcg_out_tlb_read(s, s_bits, addrlo, addrhi, mem_index, false);
1667 /* Load a pointer into the current opcode w/conditional branch-link. */
1668 label_ptr = s->code_ptr;
1669 tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1671 rbase = TCG_REG_R3;
1672 #else /* !CONFIG_SOFTMMU */
1673 rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1674 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1675 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1676 addrlo = TCG_REG_TMP1;
1678 #endif
1680 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1681 if (opc & MO_BSWAP) {
1682 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1683 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1684 tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));
1685 } else if (rbase != 0) {
1686 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1687 tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));
1688 tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));
1689 } else {
1690 tcg_out32(s, STW | TAI(datahi, addrlo, 0));
1691 tcg_out32(s, STW | TAI(datalo, addrlo, 4));
1693 } else {
1694 uint32_t insn = qemu_stx_opc[opc];
1695 if (!HAVE_ISA_2_06 && insn == STDBRX) {
1696 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1697 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));
1698 tcg_out_shri64(s, TCG_REG_R0, datalo, 32);
1699 tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));
1700 } else {
1701 tcg_out32(s, insn | SAB(datalo, rbase, addrlo));
1705 #ifdef CONFIG_SOFTMMU
1706 add_qemu_ldst_label(s, false, opc, datalo, datahi, addrlo, addrhi,
1707 mem_index, s->code_ptr, label_ptr);
1708 #endif
1711 /* Parameters for function call generation, used in tcg.c. */
1712 #define TCG_TARGET_STACK_ALIGN 16
1713 #define TCG_TARGET_EXTEND_ARGS 1
1715 #ifdef _CALL_AIX
1716 # define LINK_AREA_SIZE (6 * SZR)
1717 # define LR_OFFSET (1 * SZR)
1718 # define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR)
1719 #elif TCG_TARGET_REG_BITS == 64
1720 # if defined(_CALL_ELF) && _CALL_ELF == 2
1721 # define LINK_AREA_SIZE (4 * SZR)
1722 # define LR_OFFSET (1 * SZR)
1723 # endif
1724 #else /* TCG_TARGET_REG_BITS == 32 */
1725 # if defined(_CALL_SYSV)
1726 # define LINK_AREA_SIZE (2 * SZR)
1727 # define LR_OFFSET (1 * SZR)
1728 # elif defined(TCG_TARGET_CALL_DARWIN)
1729 # define LINK_AREA_SIZE 24
1730 # define LR_OFFSET 8
1731 # endif
1732 #endif
1733 #ifndef LR_OFFSET
1734 # error "Unhandled abi"
1735 #endif
1736 #ifndef TCG_TARGET_CALL_STACK_OFFSET
1737 # define TCG_TARGET_CALL_STACK_OFFSET LINK_AREA_SIZE
1738 #endif
1740 #define CPU_TEMP_BUF_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
1741 #define REG_SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR)
1743 #define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET \
1744 + TCG_STATIC_CALL_ARGS_SIZE \
1745 + CPU_TEMP_BUF_SIZE \
1746 + REG_SAVE_SIZE \
1747 + TCG_TARGET_STACK_ALIGN - 1) \
1748 & -TCG_TARGET_STACK_ALIGN)
1750 #define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE)
1752 static void tcg_target_qemu_prologue(TCGContext *s)
1754 int i;
1756 #ifdef _CALL_AIX
1757 void **desc = (void **)s->code_ptr;
1758 desc[0] = desc + 2; /* entry point */
1759 desc[1] = 0; /* environment pointer */
1760 s->code_ptr = (void *)(desc + 2); /* skip over descriptor */
1761 #endif
1763 tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
1764 CPU_TEMP_BUF_SIZE);
1766 /* Prologue */
1767 tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1768 tcg_out32(s, (SZR == 8 ? STDU : STWU)
1769 | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1771 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1772 tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1773 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1775 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1777 #ifdef CONFIG_USE_GUEST_BASE
1778 if (GUEST_BASE) {
1779 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
1780 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1782 #endif
1784 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1785 tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1787 if (USE_REG_RA) {
1788 #ifdef _CALL_AIX
1789 /* Make the caller load the value as the TOC into R2. */
1790 tb_ret_addr = s->code_ptr + 2;
1791 desc[1] = tb_ret_addr;
1792 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_RA, TCG_REG_R2);
1793 tcg_out32(s, BCCTR | BO_ALWAYS);
1794 #elif defined(_CALL_ELF) && _CALL_ELF == 2
1795 /* Compute from the incoming R12 value. */
1796 tb_ret_addr = s->code_ptr + 2;
1797 tcg_out32(s, ADDI | TAI(TCG_REG_RA, TCG_REG_R12,
1798 tcg_ptr_byte_diff(tb_ret_addr, s->code_buf)));
1799 tcg_out32(s, BCCTR | BO_ALWAYS);
1800 #else
1801 /* Reserve max 5 insns for the constant load. */
1802 tb_ret_addr = s->code_ptr + 6;
1803 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RA, (intptr_t)tb_ret_addr);
1804 tcg_out32(s, BCCTR | BO_ALWAYS);
1805 while (s->code_ptr < tb_ret_addr) {
1806 tcg_out32(s, NOP);
1808 #endif
1809 } else {
1810 tcg_out32(s, BCCTR | BO_ALWAYS);
1811 tb_ret_addr = s->code_ptr;
1814 /* Epilogue */
1815 assert(tb_ret_addr == s->code_ptr);
1817 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1818 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1819 tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1820 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1822 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1823 tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1824 tcg_out32(s, BCLR | BO_ALWAYS);
1827 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1828 const int *const_args)
1830 TCGArg a0, a1, a2;
1831 int c;
1833 switch (opc) {
1834 case INDEX_op_exit_tb:
1835 if (USE_REG_RA) {
1836 ptrdiff_t disp = tcg_pcrel_diff(s, tb_ret_addr);
1838 /* If we can use a direct branch, otherwise use the value in RA.
1839 Note that the direct branch is always forward. If it's in
1840 range now, it'll still be in range after the movi. Don't
1841 bother about the 20 bytes where the test here fails but it
1842 would succeed below. */
1843 if (!in_range_b(disp)) {
1844 tcg_out32(s, MTSPR | RS(TCG_REG_RA) | CTR);
1845 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1846 tcg_out32(s, BCCTR | BO_ALWAYS);
1847 break;
1850 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1851 tcg_out_b(s, 0, tb_ret_addr);
1852 break;
1853 case INDEX_op_goto_tb:
1854 if (s->tb_jmp_offset) {
1855 /* Direct jump method. */
1856 s->tb_jmp_offset[args[0]] = tcg_current_code_size(s);
1857 s->code_ptr += 7;
1858 } else {
1859 /* Indirect jump method. */
1860 tcg_abort();
1862 s->tb_next_offset[args[0]] = tcg_current_code_size(s);
1863 break;
1864 case INDEX_op_br:
1866 TCGLabel *l = &s->labels[args[0]];
1868 if (l->has_value) {
1869 tcg_out_b(s, 0, l->u.value_ptr);
1870 } else {
1871 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
1872 tcg_out_b_noaddr(s, B);
1875 break;
1876 case INDEX_op_ld8u_i32:
1877 case INDEX_op_ld8u_i64:
1878 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1879 break;
1880 case INDEX_op_ld8s_i32:
1881 case INDEX_op_ld8s_i64:
1882 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1883 tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
1884 break;
1885 case INDEX_op_ld16u_i32:
1886 case INDEX_op_ld16u_i64:
1887 tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
1888 break;
1889 case INDEX_op_ld16s_i32:
1890 case INDEX_op_ld16s_i64:
1891 tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
1892 break;
1893 case INDEX_op_ld_i32:
1894 case INDEX_op_ld32u_i64:
1895 tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
1896 break;
1897 case INDEX_op_ld32s_i64:
1898 tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
1899 break;
1900 case INDEX_op_ld_i64:
1901 tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
1902 break;
1903 case INDEX_op_st8_i32:
1904 case INDEX_op_st8_i64:
1905 tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
1906 break;
1907 case INDEX_op_st16_i32:
1908 case INDEX_op_st16_i64:
1909 tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
1910 break;
1911 case INDEX_op_st_i32:
1912 case INDEX_op_st32_i64:
1913 tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
1914 break;
1915 case INDEX_op_st_i64:
1916 tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
1917 break;
1919 case INDEX_op_add_i32:
1920 a0 = args[0], a1 = args[1], a2 = args[2];
1921 if (const_args[2]) {
1922 do_addi_32:
1923 tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
1924 } else {
1925 tcg_out32(s, ADD | TAB(a0, a1, a2));
1927 break;
1928 case INDEX_op_sub_i32:
1929 a0 = args[0], a1 = args[1], a2 = args[2];
1930 if (const_args[1]) {
1931 if (const_args[2]) {
1932 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
1933 } else {
1934 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
1936 } else if (const_args[2]) {
1937 a2 = -a2;
1938 goto do_addi_32;
1939 } else {
1940 tcg_out32(s, SUBF | TAB(a0, a2, a1));
1942 break;
1944 case INDEX_op_and_i32:
1945 a0 = args[0], a1 = args[1], a2 = args[2];
1946 if (const_args[2]) {
1947 tcg_out_andi32(s, a0, a1, a2);
1948 } else {
1949 tcg_out32(s, AND | SAB(a1, a0, a2));
1951 break;
1952 case INDEX_op_and_i64:
1953 a0 = args[0], a1 = args[1], a2 = args[2];
1954 if (const_args[2]) {
1955 tcg_out_andi64(s, a0, a1, a2);
1956 } else {
1957 tcg_out32(s, AND | SAB(a1, a0, a2));
1959 break;
1960 case INDEX_op_or_i64:
1961 case INDEX_op_or_i32:
1962 a0 = args[0], a1 = args[1], a2 = args[2];
1963 if (const_args[2]) {
1964 tcg_out_ori32(s, a0, a1, a2);
1965 } else {
1966 tcg_out32(s, OR | SAB(a1, a0, a2));
1968 break;
1969 case INDEX_op_xor_i64:
1970 case INDEX_op_xor_i32:
1971 a0 = args[0], a1 = args[1], a2 = args[2];
1972 if (const_args[2]) {
1973 tcg_out_xori32(s, a0, a1, a2);
1974 } else {
1975 tcg_out32(s, XOR | SAB(a1, a0, a2));
1977 break;
1978 case INDEX_op_andc_i32:
1979 a0 = args[0], a1 = args[1], a2 = args[2];
1980 if (const_args[2]) {
1981 tcg_out_andi32(s, a0, a1, ~a2);
1982 } else {
1983 tcg_out32(s, ANDC | SAB(a1, a0, a2));
1985 break;
1986 case INDEX_op_andc_i64:
1987 a0 = args[0], a1 = args[1], a2 = args[2];
1988 if (const_args[2]) {
1989 tcg_out_andi64(s, a0, a1, ~a2);
1990 } else {
1991 tcg_out32(s, ANDC | SAB(a1, a0, a2));
1993 break;
1994 case INDEX_op_orc_i32:
1995 if (const_args[2]) {
1996 tcg_out_ori32(s, args[0], args[1], ~args[2]);
1997 break;
1999 /* FALLTHRU */
2000 case INDEX_op_orc_i64:
2001 tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
2002 break;
2003 case INDEX_op_eqv_i32:
2004 if (const_args[2]) {
2005 tcg_out_xori32(s, args[0], args[1], ~args[2]);
2006 break;
2008 /* FALLTHRU */
2009 case INDEX_op_eqv_i64:
2010 tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
2011 break;
2012 case INDEX_op_nand_i32:
2013 case INDEX_op_nand_i64:
2014 tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
2015 break;
2016 case INDEX_op_nor_i32:
2017 case INDEX_op_nor_i64:
2018 tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
2019 break;
2021 case INDEX_op_mul_i32:
2022 a0 = args[0], a1 = args[1], a2 = args[2];
2023 if (const_args[2]) {
2024 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2025 } else {
2026 tcg_out32(s, MULLW | TAB(a0, a1, a2));
2028 break;
2030 case INDEX_op_div_i32:
2031 tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
2032 break;
2034 case INDEX_op_divu_i32:
2035 tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
2036 break;
2038 case INDEX_op_shl_i32:
2039 if (const_args[2]) {
2040 tcg_out_shli32(s, args[0], args[1], args[2]);
2041 } else {
2042 tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
2044 break;
2045 case INDEX_op_shr_i32:
2046 if (const_args[2]) {
2047 tcg_out_shri32(s, args[0], args[1], args[2]);
2048 } else {
2049 tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
2051 break;
2052 case INDEX_op_sar_i32:
2053 if (const_args[2]) {
2054 tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
2055 } else {
2056 tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
2058 break;
2059 case INDEX_op_rotl_i32:
2060 if (const_args[2]) {
2061 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
2062 } else {
2063 tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
2064 | MB(0) | ME(31));
2066 break;
2067 case INDEX_op_rotr_i32:
2068 if (const_args[2]) {
2069 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
2070 } else {
2071 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
2072 tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
2073 | MB(0) | ME(31));
2075 break;
2077 case INDEX_op_brcond_i32:
2078 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2079 args[3], TCG_TYPE_I32);
2080 break;
2081 case INDEX_op_brcond_i64:
2082 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2083 args[3], TCG_TYPE_I64);
2084 break;
2085 case INDEX_op_brcond2_i32:
2086 tcg_out_brcond2(s, args, const_args);
2087 break;
2089 case INDEX_op_neg_i32:
2090 case INDEX_op_neg_i64:
2091 tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
2092 break;
2094 case INDEX_op_not_i32:
2095 case INDEX_op_not_i64:
2096 tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
2097 break;
2099 case INDEX_op_add_i64:
2100 a0 = args[0], a1 = args[1], a2 = args[2];
2101 if (const_args[2]) {
2102 do_addi_64:
2103 tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
2104 } else {
2105 tcg_out32(s, ADD | TAB(a0, a1, a2));
2107 break;
2108 case INDEX_op_sub_i64:
2109 a0 = args[0], a1 = args[1], a2 = args[2];
2110 if (const_args[1]) {
2111 if (const_args[2]) {
2112 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
2113 } else {
2114 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2116 } else if (const_args[2]) {
2117 a2 = -a2;
2118 goto do_addi_64;
2119 } else {
2120 tcg_out32(s, SUBF | TAB(a0, a2, a1));
2122 break;
2124 case INDEX_op_shl_i64:
2125 if (const_args[2]) {
2126 tcg_out_shli64(s, args[0], args[1], args[2]);
2127 } else {
2128 tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
2130 break;
2131 case INDEX_op_shr_i64:
2132 if (const_args[2]) {
2133 tcg_out_shri64(s, args[0], args[1], args[2]);
2134 } else {
2135 tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
2137 break;
2138 case INDEX_op_sar_i64:
2139 if (const_args[2]) {
2140 int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
2141 tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
2142 } else {
2143 tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
2145 break;
2146 case INDEX_op_rotl_i64:
2147 if (const_args[2]) {
2148 tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
2149 } else {
2150 tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
2152 break;
2153 case INDEX_op_rotr_i64:
2154 if (const_args[2]) {
2155 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
2156 } else {
2157 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
2158 tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
2160 break;
2162 case INDEX_op_mul_i64:
2163 a0 = args[0], a1 = args[1], a2 = args[2];
2164 if (const_args[2]) {
2165 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2166 } else {
2167 tcg_out32(s, MULLD | TAB(a0, a1, a2));
2169 break;
2170 case INDEX_op_div_i64:
2171 tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
2172 break;
2173 case INDEX_op_divu_i64:
2174 tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
2175 break;
2177 case INDEX_op_qemu_ld_i32:
2178 tcg_out_qemu_ld(s, args, false);
2179 break;
2180 case INDEX_op_qemu_ld_i64:
2181 tcg_out_qemu_ld(s, args, true);
2182 break;
2183 case INDEX_op_qemu_st_i32:
2184 tcg_out_qemu_st(s, args, false);
2185 break;
2186 case INDEX_op_qemu_st_i64:
2187 tcg_out_qemu_st(s, args, true);
2188 break;
2190 case INDEX_op_ext8s_i32:
2191 case INDEX_op_ext8s_i64:
2192 c = EXTSB;
2193 goto gen_ext;
2194 case INDEX_op_ext16s_i32:
2195 case INDEX_op_ext16s_i64:
2196 c = EXTSH;
2197 goto gen_ext;
2198 case INDEX_op_ext32s_i64:
2199 c = EXTSW;
2200 goto gen_ext;
2201 gen_ext:
2202 tcg_out32(s, c | RS(args[1]) | RA(args[0]));
2203 break;
2205 case INDEX_op_setcond_i32:
2206 tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
2207 const_args[2]);
2208 break;
2209 case INDEX_op_setcond_i64:
2210 tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
2211 const_args[2]);
2212 break;
2213 case INDEX_op_setcond2_i32:
2214 tcg_out_setcond2(s, args, const_args);
2215 break;
2217 case INDEX_op_bswap16_i32:
2218 case INDEX_op_bswap16_i64:
2219 a0 = args[0], a1 = args[1];
2220 /* a1 = abcd */
2221 if (a0 != a1) {
2222 /* a0 = (a1 r<< 24) & 0xff # 000c */
2223 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2224 /* a0 = (a0 & ~0xff00) | (a1 r<< 8) & 0xff00 # 00dc */
2225 tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
2226 } else {
2227 /* r0 = (a1 r<< 8) & 0xff00 # 00d0 */
2228 tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
2229 /* a0 = (a1 r<< 24) & 0xff # 000c */
2230 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2231 /* a0 = a0 | r0 # 00dc */
2232 tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
2234 break;
2236 case INDEX_op_bswap32_i32:
2237 case INDEX_op_bswap32_i64:
2238 /* Stolen from gcc's builtin_bswap32 */
2239 a1 = args[1];
2240 a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
2242 /* a1 = args[1] # abcd */
2243 /* a0 = rotate_left (a1, 8) # bcda */
2244 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2245 /* a0 = (a0 & ~0xff000000) | ((a1 r<< 24) & 0xff000000) # dcda */
2246 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2247 /* a0 = (a0 & ~0x0000ff00) | ((a1 r<< 24) & 0x0000ff00) # dcba */
2248 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2250 if (a0 == TCG_REG_R0) {
2251 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2253 break;
2255 case INDEX_op_bswap64_i64:
2256 a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
2257 if (a0 == a1) {
2258 a0 = TCG_REG_R0;
2259 a2 = a1;
2262 /* a1 = # abcd efgh */
2263 /* a0 = rl32(a1, 8) # 0000 fghe */
2264 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2265 /* a0 = dep(a0, rl32(a1, 24), 0xff000000) # 0000 hghe */
2266 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2267 /* a0 = dep(a0, rl32(a1, 24), 0x0000ff00) # 0000 hgfe */
2268 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2270 /* a0 = rl64(a0, 32) # hgfe 0000 */
2271 /* a2 = rl64(a1, 32) # efgh abcd */
2272 tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
2273 tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
2275 /* a0 = dep(a0, rl32(a2, 8), 0xffffffff) # hgfe bcda */
2276 tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
2277 /* a0 = dep(a0, rl32(a2, 24), 0xff000000) # hgfe dcda */
2278 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
2279 /* a0 = dep(a0, rl32(a2, 24), 0x0000ff00) # hgfe dcba */
2280 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
2282 if (a0 == 0) {
2283 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2285 break;
2287 case INDEX_op_deposit_i32:
2288 if (const_args[2]) {
2289 uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
2290 tcg_out_andi32(s, args[0], args[0], ~mask);
2291 } else {
2292 tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
2293 32 - args[3] - args[4], 31 - args[3]);
2295 break;
2296 case INDEX_op_deposit_i64:
2297 if (const_args[2]) {
2298 uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
2299 tcg_out_andi64(s, args[0], args[0], ~mask);
2300 } else {
2301 tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
2302 64 - args[3] - args[4]);
2304 break;
2306 case INDEX_op_movcond_i32:
2307 tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
2308 args[3], args[4], const_args[2]);
2309 break;
2310 case INDEX_op_movcond_i64:
2311 tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
2312 args[3], args[4], const_args[2]);
2313 break;
2315 #if TCG_TARGET_REG_BITS == 64
2316 case INDEX_op_add2_i64:
2317 #else
2318 case INDEX_op_add2_i32:
2319 #endif
2320 /* Note that the CA bit is defined based on the word size of the
2321 environment. So in 64-bit mode it's always carry-out of bit 63.
2322 The fallback code using deposit works just as well for 32-bit. */
2323 a0 = args[0], a1 = args[1];
2324 if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
2325 a0 = TCG_REG_R0;
2327 if (const_args[4]) {
2328 tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
2329 } else {
2330 tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
2332 if (const_args[5]) {
2333 tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
2334 } else {
2335 tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
2337 if (a0 != args[0]) {
2338 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2340 break;
2342 #if TCG_TARGET_REG_BITS == 64
2343 case INDEX_op_sub2_i64:
2344 #else
2345 case INDEX_op_sub2_i32:
2346 #endif
2347 a0 = args[0], a1 = args[1];
2348 if (a0 == args[5] || (!const_args[3] && a0 == args[3])) {
2349 a0 = TCG_REG_R0;
2351 if (const_args[2]) {
2352 tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2]));
2353 } else {
2354 tcg_out32(s, SUBFC | TAB(a0, args[4], args[2]));
2356 if (const_args[3]) {
2357 tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2358 } else {
2359 tcg_out32(s, SUBFE | TAB(a1, args[5], args[3]));
2361 if (a0 != args[0]) {
2362 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2364 break;
2366 case INDEX_op_muluh_i32:
2367 tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2]));
2368 break;
2369 case INDEX_op_mulsh_i32:
2370 tcg_out32(s, MULHW | TAB(args[0], args[1], args[2]));
2371 break;
2372 case INDEX_op_muluh_i64:
2373 tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2374 break;
2375 case INDEX_op_mulsh_i64:
2376 tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2377 break;
2379 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2380 case INDEX_op_mov_i64:
2381 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2382 case INDEX_op_movi_i64:
2383 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2384 default:
2385 tcg_abort();
2389 static const TCGTargetOpDef ppc_op_defs[] = {
2390 { INDEX_op_exit_tb, { } },
2391 { INDEX_op_goto_tb, { } },
2392 { INDEX_op_br, { } },
2394 { INDEX_op_ld8u_i32, { "r", "r" } },
2395 { INDEX_op_ld8s_i32, { "r", "r" } },
2396 { INDEX_op_ld16u_i32, { "r", "r" } },
2397 { INDEX_op_ld16s_i32, { "r", "r" } },
2398 { INDEX_op_ld_i32, { "r", "r" } },
2400 { INDEX_op_st8_i32, { "r", "r" } },
2401 { INDEX_op_st16_i32, { "r", "r" } },
2402 { INDEX_op_st_i32, { "r", "r" } },
2404 { INDEX_op_add_i32, { "r", "r", "ri" } },
2405 { INDEX_op_mul_i32, { "r", "r", "rI" } },
2406 { INDEX_op_div_i32, { "r", "r", "r" } },
2407 { INDEX_op_divu_i32, { "r", "r", "r" } },
2408 { INDEX_op_sub_i32, { "r", "rI", "ri" } },
2409 { INDEX_op_and_i32, { "r", "r", "ri" } },
2410 { INDEX_op_or_i32, { "r", "r", "ri" } },
2411 { INDEX_op_xor_i32, { "r", "r", "ri" } },
2412 { INDEX_op_andc_i32, { "r", "r", "ri" } },
2413 { INDEX_op_orc_i32, { "r", "r", "ri" } },
2414 { INDEX_op_eqv_i32, { "r", "r", "ri" } },
2415 { INDEX_op_nand_i32, { "r", "r", "r" } },
2416 { INDEX_op_nor_i32, { "r", "r", "r" } },
2418 { INDEX_op_shl_i32, { "r", "r", "ri" } },
2419 { INDEX_op_shr_i32, { "r", "r", "ri" } },
2420 { INDEX_op_sar_i32, { "r", "r", "ri" } },
2421 { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2422 { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2424 { INDEX_op_neg_i32, { "r", "r" } },
2425 { INDEX_op_not_i32, { "r", "r" } },
2426 { INDEX_op_ext8s_i32, { "r", "r" } },
2427 { INDEX_op_ext16s_i32, { "r", "r" } },
2428 { INDEX_op_bswap16_i32, { "r", "r" } },
2429 { INDEX_op_bswap32_i32, { "r", "r" } },
2431 { INDEX_op_brcond_i32, { "r", "ri" } },
2432 { INDEX_op_setcond_i32, { "r", "r", "ri" } },
2433 { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } },
2435 { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2437 { INDEX_op_muluh_i32, { "r", "r", "r" } },
2438 { INDEX_op_mulsh_i32, { "r", "r", "r" } },
2440 #if TCG_TARGET_REG_BITS == 64
2441 { INDEX_op_ld8u_i64, { "r", "r" } },
2442 { INDEX_op_ld8s_i64, { "r", "r" } },
2443 { INDEX_op_ld16u_i64, { "r", "r" } },
2444 { INDEX_op_ld16s_i64, { "r", "r" } },
2445 { INDEX_op_ld32u_i64, { "r", "r" } },
2446 { INDEX_op_ld32s_i64, { "r", "r" } },
2447 { INDEX_op_ld_i64, { "r", "r" } },
2449 { INDEX_op_st8_i64, { "r", "r" } },
2450 { INDEX_op_st16_i64, { "r", "r" } },
2451 { INDEX_op_st32_i64, { "r", "r" } },
2452 { INDEX_op_st_i64, { "r", "r" } },
2454 { INDEX_op_add_i64, { "r", "r", "rT" } },
2455 { INDEX_op_sub_i64, { "r", "rI", "rT" } },
2456 { INDEX_op_and_i64, { "r", "r", "ri" } },
2457 { INDEX_op_or_i64, { "r", "r", "rU" } },
2458 { INDEX_op_xor_i64, { "r", "r", "rU" } },
2459 { INDEX_op_andc_i64, { "r", "r", "ri" } },
2460 { INDEX_op_orc_i64, { "r", "r", "r" } },
2461 { INDEX_op_eqv_i64, { "r", "r", "r" } },
2462 { INDEX_op_nand_i64, { "r", "r", "r" } },
2463 { INDEX_op_nor_i64, { "r", "r", "r" } },
2465 { INDEX_op_shl_i64, { "r", "r", "ri" } },
2466 { INDEX_op_shr_i64, { "r", "r", "ri" } },
2467 { INDEX_op_sar_i64, { "r", "r", "ri" } },
2468 { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2469 { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2471 { INDEX_op_mul_i64, { "r", "r", "rI" } },
2472 { INDEX_op_div_i64, { "r", "r", "r" } },
2473 { INDEX_op_divu_i64, { "r", "r", "r" } },
2475 { INDEX_op_neg_i64, { "r", "r" } },
2476 { INDEX_op_not_i64, { "r", "r" } },
2477 { INDEX_op_ext8s_i64, { "r", "r" } },
2478 { INDEX_op_ext16s_i64, { "r", "r" } },
2479 { INDEX_op_ext32s_i64, { "r", "r" } },
2480 { INDEX_op_bswap16_i64, { "r", "r" } },
2481 { INDEX_op_bswap32_i64, { "r", "r" } },
2482 { INDEX_op_bswap64_i64, { "r", "r" } },
2484 { INDEX_op_brcond_i64, { "r", "ri" } },
2485 { INDEX_op_setcond_i64, { "r", "r", "ri" } },
2486 { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } },
2488 { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
2490 { INDEX_op_mulsh_i64, { "r", "r", "r" } },
2491 { INDEX_op_muluh_i64, { "r", "r", "r" } },
2492 #endif
2494 #if TCG_TARGET_REG_BITS == 32
2495 { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
2496 { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
2497 #endif
2499 #if TCG_TARGET_REG_BITS == 64
2500 { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
2501 { INDEX_op_sub2_i64, { "r", "r", "rI", "rZM", "r", "r" } },
2502 #else
2503 { INDEX_op_add2_i32, { "r", "r", "r", "r", "rI", "rZM" } },
2504 { INDEX_op_sub2_i32, { "r", "r", "rI", "rZM", "r", "r" } },
2505 #endif
2507 #if TCG_TARGET_REG_BITS == 64
2508 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2509 { INDEX_op_qemu_st_i32, { "S", "S" } },
2510 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2511 { INDEX_op_qemu_st_i64, { "S", "S" } },
2512 #elif TARGET_LONG_BITS == 32
2513 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2514 { INDEX_op_qemu_st_i32, { "S", "S" } },
2515 { INDEX_op_qemu_ld_i64, { "L", "L", "L" } },
2516 { INDEX_op_qemu_st_i64, { "S", "S", "S" } },
2517 #else
2518 { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
2519 { INDEX_op_qemu_st_i32, { "S", "S", "S" } },
2520 { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
2521 { INDEX_op_qemu_st_i64, { "S", "S", "S", "S" } },
2522 #endif
2524 { -1 },
2527 static void tcg_target_init(TCGContext *s)
2529 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2530 if (hwcap & PPC_FEATURE_ARCH_2_06) {
2531 have_isa_2_06 = true;
2534 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
2535 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
2536 tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2537 (1 << TCG_REG_R0) |
2538 (1 << TCG_REG_R2) |
2539 (1 << TCG_REG_R3) |
2540 (1 << TCG_REG_R4) |
2541 (1 << TCG_REG_R5) |
2542 (1 << TCG_REG_R6) |
2543 (1 << TCG_REG_R7) |
2544 (1 << TCG_REG_R8) |
2545 (1 << TCG_REG_R9) |
2546 (1 << TCG_REG_R10) |
2547 (1 << TCG_REG_R11) |
2548 (1 << TCG_REG_R12));
2550 tcg_regset_clear(s->reserved_regs);
2551 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */
2552 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
2553 #if defined(_CALL_SYSV)
2554 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* toc pointer */
2555 #endif
2556 #if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64
2557 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2558 #endif
2559 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */
2560 if (USE_REG_RA) {
2561 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return addr */
2564 tcg_add_target_add_op_defs(ppc_op_defs);
2567 #ifdef __ELF__
2568 typedef struct {
2569 DebugFrameCIE cie;
2570 DebugFrameFDEHeader fde;
2571 uint8_t fde_def_cfa[4];
2572 uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2573 } DebugFrame;
2575 /* We're expecting a 2 byte uleb128 encoded value. */
2576 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2578 #if TCG_TARGET_REG_BITS == 64
2579 # define ELF_HOST_MACHINE EM_PPC64
2580 #else
2581 # define ELF_HOST_MACHINE EM_PPC
2582 #endif
2584 static DebugFrame debug_frame = {
2585 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2586 .cie.id = -1,
2587 .cie.version = 1,
2588 .cie.code_align = 1,
2589 .cie.data_align = (-SZR & 0x7f), /* sleb128 -SZR */
2590 .cie.return_column = 65,
2592 /* Total FDE size does not include the "len" member. */
2593 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2595 .fde_def_cfa = {
2596 12, TCG_REG_R1, /* DW_CFA_def_cfa r1, ... */
2597 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2598 (FRAME_SIZE >> 7)
2600 .fde_reg_ofs = {
2601 /* DW_CFA_offset_extended_sf, lr, LR_OFFSET */
2602 0x11, 65, (LR_OFFSET / -SZR) & 0x7f,
2606 void tcg_register_jit(void *buf, size_t buf_size)
2608 uint8_t *p = &debug_frame.fde_reg_ofs[3];
2609 int i;
2611 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2612 p[0] = 0x80 + tcg_target_callee_save_regs[i];
2613 p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR;
2616 debug_frame.fde.func_start = (uintptr_t)buf;
2617 debug_frame.fde.func_len = buf_size;
2619 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2621 #endif /* __ELF__ */
2623 static size_t dcache_bsize = 16;
2624 static size_t icache_bsize = 16;
2626 void flush_icache_range(uintptr_t start, uintptr_t stop)
2628 uintptr_t p, start1, stop1;
2629 size_t dsize = dcache_bsize;
2630 size_t isize = icache_bsize;
2632 start1 = start & ~(dsize - 1);
2633 stop1 = (stop + dsize - 1) & ~(dsize - 1);
2634 for (p = start1; p < stop1; p += dsize) {
2635 asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
2637 asm volatile ("sync" : : : "memory");
2639 start &= start & ~(isize - 1);
2640 stop1 = (stop + isize - 1) & ~(isize - 1);
2641 for (p = start1; p < stop1; p += isize) {
2642 asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
2644 asm volatile ("sync" : : : "memory");
2645 asm volatile ("isync" : : : "memory");
2648 #if defined _AIX
2649 #include <sys/systemcfg.h>
2651 static void __attribute__((constructor)) tcg_cache_init(void)
2653 icache_bsize = _system_configuration.icache_line;
2654 dcache_bsize = _system_configuration.dcache_line;
2657 #elif defined __linux__
2658 static void __attribute__((constructor)) tcg_cache_init(void)
2660 unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
2661 unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
2663 if (dsize == 0 || isize == 0) {
2664 if (dsize == 0) {
2665 fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
2667 if (isize == 0) {
2668 fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
2670 exit(1);
2672 dcache_bsize = dsize;
2673 icache_bsize = isize;
2676 #elif defined __APPLE__
2677 #include <stdio.h>
2678 #include <sys/types.h>
2679 #include <sys/sysctl.h>
2681 static void __attribute__((constructor)) tcg_cache_init(void)
2683 size_t len;
2684 unsigned cacheline;
2685 int name[2] = { CTL_HW, HW_CACHELINE };
2687 len = sizeof(cacheline);
2688 if (sysctl(name, 2, &cacheline, &len, NULL, 0)) {
2689 perror("sysctl CTL_HW HW_CACHELINE failed");
2690 exit(1);
2692 dcache_bsize = cacheline;
2693 icache_bsize = cacheline;
2696 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2697 #include <errno.h>
2698 #include <stdio.h>
2699 #include <stdlib.h>
2700 #include <string.h>
2701 #include <sys/types.h>
2702 #include <sys/sysctl.h>
2704 static void __attribute__((constructor)) tcg_cache_init(void)
2706 size_t len = 4;
2707 unsigned cacheline;
2709 if (sysctlbyname ("machdep.cacheline_size", &cacheline, &len, NULL, 0)) {
2710 fprintf(stderr, "sysctlbyname machdep.cacheline_size failed: %s\n",
2711 strerror(errno));
2712 exit(1);
2714 dcache_bsize = cacheline;
2715 icache_bsize = cacheline;
2717 #endif