tcg/ppc: Replace HAVE_ISA_2_06
[qemu/ar7.git] / tcg / ppc / tcg-target.inc.c
blob7cb0002c1487fcf72b8778e9cddc18624fe4f812
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 "elf.h"
26 #include "tcg-pool.inc.c"
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 static tcg_insn_unit *tb_ret_addr;
67 TCGPowerISA have_isa;
69 #define HAVE_ISEL have_isa_2_06
71 #ifndef CONFIG_SOFTMMU
72 #define TCG_GUEST_BASE_REG 30
73 #endif
75 #ifdef CONFIG_DEBUG_TCG
76 static const char tcg_target_reg_names[TCG_TARGET_NB_REGS][4] = {
77 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
79 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
80 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
81 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",
82 "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",
83 "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",
84 "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",
86 #endif
88 static const int tcg_target_reg_alloc_order[] = {
89 TCG_REG_R14, /* call saved registers */
90 TCG_REG_R15,
91 TCG_REG_R16,
92 TCG_REG_R17,
93 TCG_REG_R18,
94 TCG_REG_R19,
95 TCG_REG_R20,
96 TCG_REG_R21,
97 TCG_REG_R22,
98 TCG_REG_R23,
99 TCG_REG_R24,
100 TCG_REG_R25,
101 TCG_REG_R26,
102 TCG_REG_R27,
103 TCG_REG_R28,
104 TCG_REG_R29,
105 TCG_REG_R30,
106 TCG_REG_R31,
107 TCG_REG_R12, /* call clobbered, non-arguments */
108 TCG_REG_R11,
109 TCG_REG_R2,
110 TCG_REG_R13,
111 TCG_REG_R10, /* call clobbered, arguments */
112 TCG_REG_R9,
113 TCG_REG_R8,
114 TCG_REG_R7,
115 TCG_REG_R6,
116 TCG_REG_R5,
117 TCG_REG_R4,
118 TCG_REG_R3,
120 /* V0 and V1 reserved as temporaries; V20 - V31 are call-saved */
121 TCG_REG_V2, /* call clobbered, vectors */
122 TCG_REG_V3,
123 TCG_REG_V4,
124 TCG_REG_V5,
125 TCG_REG_V6,
126 TCG_REG_V7,
127 TCG_REG_V8,
128 TCG_REG_V9,
129 TCG_REG_V10,
130 TCG_REG_V11,
131 TCG_REG_V12,
132 TCG_REG_V13,
133 TCG_REG_V14,
134 TCG_REG_V15,
135 TCG_REG_V16,
136 TCG_REG_V17,
137 TCG_REG_V18,
138 TCG_REG_V19,
141 static const int tcg_target_call_iarg_regs[] = {
142 TCG_REG_R3,
143 TCG_REG_R4,
144 TCG_REG_R5,
145 TCG_REG_R6,
146 TCG_REG_R7,
147 TCG_REG_R8,
148 TCG_REG_R9,
149 TCG_REG_R10
152 static const int tcg_target_call_oarg_regs[] = {
153 TCG_REG_R3,
154 TCG_REG_R4
157 static const int tcg_target_callee_save_regs[] = {
158 #ifdef TCG_TARGET_CALL_DARWIN
159 TCG_REG_R11,
160 #endif
161 TCG_REG_R14,
162 TCG_REG_R15,
163 TCG_REG_R16,
164 TCG_REG_R17,
165 TCG_REG_R18,
166 TCG_REG_R19,
167 TCG_REG_R20,
168 TCG_REG_R21,
169 TCG_REG_R22,
170 TCG_REG_R23,
171 TCG_REG_R24,
172 TCG_REG_R25,
173 TCG_REG_R26,
174 TCG_REG_R27, /* currently used for the global env */
175 TCG_REG_R28,
176 TCG_REG_R29,
177 TCG_REG_R30,
178 TCG_REG_R31
181 static inline bool in_range_b(tcg_target_long target)
183 return target == sextract64(target, 0, 26);
186 static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
188 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
189 tcg_debug_assert(in_range_b(disp));
190 return disp & 0x3fffffc;
193 static bool reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
195 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
196 if (in_range_b(disp)) {
197 *pc = (*pc & ~0x3fffffc) | (disp & 0x3fffffc);
198 return true;
200 return false;
203 static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
205 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
206 tcg_debug_assert(disp == (int16_t) disp);
207 return disp & 0xfffc;
210 static bool reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
212 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
213 if (disp == (int16_t) disp) {
214 *pc = (*pc & ~0xfffc) | (disp & 0xfffc);
215 return true;
217 return false;
220 /* parse target specific constraints */
221 static const char *target_parse_constraint(TCGArgConstraint *ct,
222 const char *ct_str, TCGType type)
224 switch (*ct_str++) {
225 case 'A': case 'B': case 'C': case 'D':
226 ct->ct |= TCG_CT_REG;
227 tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
228 break;
229 case 'r':
230 ct->ct |= TCG_CT_REG;
231 ct->u.regs = 0xffffffff;
232 break;
233 case 'L': /* qemu_ld constraint */
234 ct->ct |= TCG_CT_REG;
235 ct->u.regs = 0xffffffff;
236 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
237 #ifdef CONFIG_SOFTMMU
238 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
239 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
240 #endif
241 break;
242 case 'S': /* qemu_st constraint */
243 ct->ct |= TCG_CT_REG;
244 ct->u.regs = 0xffffffff;
245 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
246 #ifdef CONFIG_SOFTMMU
247 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
248 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
249 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
250 #endif
251 break;
252 case 'I':
253 ct->ct |= TCG_CT_CONST_S16;
254 break;
255 case 'J':
256 ct->ct |= TCG_CT_CONST_U16;
257 break;
258 case 'M':
259 ct->ct |= TCG_CT_CONST_MONE;
260 break;
261 case 'T':
262 ct->ct |= TCG_CT_CONST_S32;
263 break;
264 case 'U':
265 ct->ct |= TCG_CT_CONST_U32;
266 break;
267 case 'W':
268 ct->ct |= TCG_CT_CONST_WSZ;
269 break;
270 case 'Z':
271 ct->ct |= TCG_CT_CONST_ZERO;
272 break;
273 default:
274 return NULL;
276 return ct_str;
279 /* test if a constant matches the constraint */
280 static int tcg_target_const_match(tcg_target_long val, TCGType type,
281 const TCGArgConstraint *arg_ct)
283 int ct = arg_ct->ct;
284 if (ct & TCG_CT_CONST) {
285 return 1;
288 /* The only 32-bit constraint we use aside from
289 TCG_CT_CONST is TCG_CT_CONST_S16. */
290 if (type == TCG_TYPE_I32) {
291 val = (int32_t)val;
294 if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
295 return 1;
296 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
297 return 1;
298 } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
299 return 1;
300 } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
301 return 1;
302 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
303 return 1;
304 } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
305 return 1;
306 } else if ((ct & TCG_CT_CONST_WSZ)
307 && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
308 return 1;
310 return 0;
313 #define OPCD(opc) ((opc)<<26)
314 #define XO19(opc) (OPCD(19)|((opc)<<1))
315 #define MD30(opc) (OPCD(30)|((opc)<<2))
316 #define MDS30(opc) (OPCD(30)|((opc)<<1))
317 #define XO31(opc) (OPCD(31)|((opc)<<1))
318 #define XO58(opc) (OPCD(58)|(opc))
319 #define XO62(opc) (OPCD(62)|(opc))
320 #define VX4(opc) (OPCD(4)|(opc))
322 #define B OPCD( 18)
323 #define BC OPCD( 16)
324 #define LBZ OPCD( 34)
325 #define LHZ OPCD( 40)
326 #define LHA OPCD( 42)
327 #define LWZ OPCD( 32)
328 #define LWZUX XO31( 55)
329 #define STB OPCD( 38)
330 #define STH OPCD( 44)
331 #define STW OPCD( 36)
333 #define STD XO62( 0)
334 #define STDU XO62( 1)
335 #define STDX XO31(149)
337 #define LD XO58( 0)
338 #define LDX XO31( 21)
339 #define LDU XO58( 1)
340 #define LDUX XO31( 53)
341 #define LWA XO58( 2)
342 #define LWAX XO31(341)
344 #define ADDIC OPCD( 12)
345 #define ADDI OPCD( 14)
346 #define ADDIS OPCD( 15)
347 #define ORI OPCD( 24)
348 #define ORIS OPCD( 25)
349 #define XORI OPCD( 26)
350 #define XORIS OPCD( 27)
351 #define ANDI OPCD( 28)
352 #define ANDIS OPCD( 29)
353 #define MULLI OPCD( 7)
354 #define CMPLI OPCD( 10)
355 #define CMPI OPCD( 11)
356 #define SUBFIC OPCD( 8)
358 #define LWZU OPCD( 33)
359 #define STWU OPCD( 37)
361 #define RLWIMI OPCD( 20)
362 #define RLWINM OPCD( 21)
363 #define RLWNM OPCD( 23)
365 #define RLDICL MD30( 0)
366 #define RLDICR MD30( 1)
367 #define RLDIMI MD30( 3)
368 #define RLDCL MDS30( 8)
370 #define BCLR XO19( 16)
371 #define BCCTR XO19(528)
372 #define CRAND XO19(257)
373 #define CRANDC XO19(129)
374 #define CRNAND XO19(225)
375 #define CROR XO19(449)
376 #define CRNOR XO19( 33)
378 #define EXTSB XO31(954)
379 #define EXTSH XO31(922)
380 #define EXTSW XO31(986)
381 #define ADD XO31(266)
382 #define ADDE XO31(138)
383 #define ADDME XO31(234)
384 #define ADDZE XO31(202)
385 #define ADDC XO31( 10)
386 #define AND XO31( 28)
387 #define SUBF XO31( 40)
388 #define SUBFC XO31( 8)
389 #define SUBFE XO31(136)
390 #define SUBFME XO31(232)
391 #define SUBFZE XO31(200)
392 #define OR XO31(444)
393 #define XOR XO31(316)
394 #define MULLW XO31(235)
395 #define MULHW XO31( 75)
396 #define MULHWU XO31( 11)
397 #define DIVW XO31(491)
398 #define DIVWU XO31(459)
399 #define CMP XO31( 0)
400 #define CMPL XO31( 32)
401 #define LHBRX XO31(790)
402 #define LWBRX XO31(534)
403 #define LDBRX XO31(532)
404 #define STHBRX XO31(918)
405 #define STWBRX XO31(662)
406 #define STDBRX XO31(660)
407 #define MFSPR XO31(339)
408 #define MTSPR XO31(467)
409 #define SRAWI XO31(824)
410 #define NEG XO31(104)
411 #define MFCR XO31( 19)
412 #define MFOCRF (MFCR | (1u << 20))
413 #define NOR XO31(124)
414 #define CNTLZW XO31( 26)
415 #define CNTLZD XO31( 58)
416 #define CNTTZW XO31(538)
417 #define CNTTZD XO31(570)
418 #define CNTPOPW XO31(378)
419 #define CNTPOPD XO31(506)
420 #define ANDC XO31( 60)
421 #define ORC XO31(412)
422 #define EQV XO31(284)
423 #define NAND XO31(476)
424 #define ISEL XO31( 15)
426 #define MULLD XO31(233)
427 #define MULHD XO31( 73)
428 #define MULHDU XO31( 9)
429 #define DIVD XO31(489)
430 #define DIVDU XO31(457)
432 #define LBZX XO31( 87)
433 #define LHZX XO31(279)
434 #define LHAX XO31(343)
435 #define LWZX XO31( 23)
436 #define STBX XO31(215)
437 #define STHX XO31(407)
438 #define STWX XO31(151)
440 #define EIEIO XO31(854)
441 #define HWSYNC XO31(598)
442 #define LWSYNC (HWSYNC | (1u << 21))
444 #define SPR(a, b) ((((a)<<5)|(b))<<11)
445 #define LR SPR(8, 0)
446 #define CTR SPR(9, 0)
448 #define SLW XO31( 24)
449 #define SRW XO31(536)
450 #define SRAW XO31(792)
452 #define SLD XO31( 27)
453 #define SRD XO31(539)
454 #define SRAD XO31(794)
455 #define SRADI XO31(413<<1)
457 #define TW XO31( 4)
458 #define TRAP (TW | TO(31))
460 #define NOP ORI /* ori 0,0,0 */
462 #define RT(r) ((r)<<21)
463 #define RS(r) ((r)<<21)
464 #define RA(r) ((r)<<16)
465 #define RB(r) ((r)<<11)
466 #define TO(t) ((t)<<21)
467 #define SH(s) ((s)<<11)
468 #define MB(b) ((b)<<6)
469 #define ME(e) ((e)<<1)
470 #define BO(o) ((o)<<21)
471 #define MB64(b) ((b)<<5)
472 #define FXM(b) (1 << (19 - (b)))
474 #define VRT(r) (((r) & 31) << 21)
475 #define VRA(r) (((r) & 31) << 16)
476 #define VRB(r) (((r) & 31) << 11)
477 #define VRC(r) (((r) & 31) << 6)
479 #define LK 1
481 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
482 #define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
483 #define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
484 #define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
486 #define BF(n) ((n)<<23)
487 #define BI(n, c) (((c)+((n)*4))<<16)
488 #define BT(n, c) (((c)+((n)*4))<<21)
489 #define BA(n, c) (((c)+((n)*4))<<16)
490 #define BB(n, c) (((c)+((n)*4))<<11)
491 #define BC_(n, c) (((c)+((n)*4))<<6)
493 #define BO_COND_TRUE BO(12)
494 #define BO_COND_FALSE BO( 4)
495 #define BO_ALWAYS BO(20)
497 enum {
498 CR_LT,
499 CR_GT,
500 CR_EQ,
501 CR_SO
504 static const uint32_t tcg_to_bc[] = {
505 [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE,
506 [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE,
507 [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE,
508 [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE,
509 [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE,
510 [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE,
511 [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
512 [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
513 [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
514 [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
517 /* The low bit here is set if the RA and RB fields must be inverted. */
518 static const uint32_t tcg_to_isel[] = {
519 [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ),
520 [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1,
521 [TCG_COND_LT] = ISEL | BC_(7, CR_LT),
522 [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1,
523 [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1,
524 [TCG_COND_GT] = ISEL | BC_(7, CR_GT),
525 [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
526 [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
527 [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
528 [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
531 static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
532 intptr_t value, intptr_t addend)
534 tcg_insn_unit *target;
536 value += addend;
537 target = (tcg_insn_unit *)value;
539 switch (type) {
540 case R_PPC_REL14:
541 return reloc_pc14(code_ptr, target);
542 case R_PPC_REL24:
543 return reloc_pc24(code_ptr, target);
544 case R_PPC_ADDR16:
546 * We are (slightly) abusing this relocation type. In particular,
547 * assert that the low 2 bits are zero, and do not modify them.
548 * That way we can use this with LD et al that have opcode bits
549 * in the low 2 bits of the insn.
551 if ((value & 3) || value != (int16_t)value) {
552 return false;
554 *code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
555 break;
556 default:
557 g_assert_not_reached();
559 return true;
562 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
563 TCGReg base, tcg_target_long offset);
565 static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
567 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
568 if (ret != arg) {
569 tcg_out32(s, OR | SAB(arg, ret, arg));
571 return true;
574 static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
575 int sh, int mb)
577 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
578 sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
579 mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
580 tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
583 static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
584 int sh, int mb, int me)
586 tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
589 static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
591 tcg_out_rld(s, RLDICL, dst, src, 0, 32);
594 static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
596 tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
599 static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
601 tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
604 static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c)
606 tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31);
609 static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
611 tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
614 /* Emit a move into ret of arg, if it can be done in one insn. */
615 static bool tcg_out_movi_one(TCGContext *s, TCGReg ret, tcg_target_long arg)
617 if (arg == (int16_t)arg) {
618 tcg_out32(s, ADDI | TAI(ret, 0, arg));
619 return true;
621 if (arg == (int32_t)arg && (arg & 0xffff) == 0) {
622 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
623 return true;
625 return false;
628 static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
629 tcg_target_long arg, bool in_prologue)
631 intptr_t tb_diff;
632 tcg_target_long tmp;
633 int shift;
635 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
637 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
638 arg = (int32_t)arg;
641 /* Load 16-bit immediates with one insn. */
642 if (tcg_out_movi_one(s, ret, arg)) {
643 return;
646 /* Load addresses within the TB with one insn. */
647 tb_diff = arg - (intptr_t)s->code_gen_ptr;
648 if (!in_prologue && USE_REG_TB && tb_diff == (int16_t)tb_diff) {
649 tcg_out32(s, ADDI | TAI(ret, TCG_REG_TB, tb_diff));
650 return;
653 /* Load 32-bit immediates with two insns. Note that we've already
654 eliminated bare ADDIS, so we know both insns are required. */
655 if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {
656 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
657 tcg_out32(s, ORI | SAI(ret, ret, arg));
658 return;
660 if (arg == (uint32_t)arg && !(arg & 0x8000)) {
661 tcg_out32(s, ADDI | TAI(ret, 0, arg));
662 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
663 return;
666 /* Load masked 16-bit value. */
667 if (arg > 0 && (arg & 0x8000)) {
668 tmp = arg | 0x7fff;
669 if ((tmp & (tmp + 1)) == 0) {
670 int mb = clz64(tmp + 1) + 1;
671 tcg_out32(s, ADDI | TAI(ret, 0, arg));
672 tcg_out_rld(s, RLDICL, ret, ret, 0, mb);
673 return;
677 /* Load common masks with 2 insns. */
678 shift = ctz64(arg);
679 tmp = arg >> shift;
680 if (tmp == (int16_t)tmp) {
681 tcg_out32(s, ADDI | TAI(ret, 0, tmp));
682 tcg_out_shli64(s, ret, ret, shift);
683 return;
685 shift = clz64(arg);
686 if (tcg_out_movi_one(s, ret, arg << shift)) {
687 tcg_out_shri64(s, ret, ret, shift);
688 return;
691 /* Load addresses within 2GB of TB with 2 (or rarely 3) insns. */
692 if (!in_prologue && USE_REG_TB && tb_diff == (int32_t)tb_diff) {
693 tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_TB, tb_diff);
694 return;
697 /* Use the constant pool, if possible. */
698 if (!in_prologue && USE_REG_TB) {
699 new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
700 -(intptr_t)s->code_gen_ptr);
701 tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
702 return;
705 tmp = arg >> 31 >> 1;
706 tcg_out_movi(s, TCG_TYPE_I32, ret, tmp);
707 if (tmp) {
708 tcg_out_shli64(s, ret, ret, 32);
710 if (arg & 0xffff0000) {
711 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
713 if (arg & 0xffff) {
714 tcg_out32(s, ORI | SAI(ret, ret, arg));
718 static inline void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
719 tcg_target_long arg)
721 tcg_out_movi_int(s, type, ret, arg, false);
724 static bool mask_operand(uint32_t c, int *mb, int *me)
726 uint32_t lsb, test;
728 /* Accept a bit pattern like:
729 0....01....1
730 1....10....0
731 0..01..10..0
732 Keep track of the transitions. */
733 if (c == 0 || c == -1) {
734 return false;
736 test = c;
737 lsb = test & -test;
738 test += lsb;
739 if (test & (test - 1)) {
740 return false;
743 *me = clz32(lsb);
744 *mb = test ? clz32(test & -test) + 1 : 0;
745 return true;
748 static bool mask64_operand(uint64_t c, int *mb, int *me)
750 uint64_t lsb;
752 if (c == 0) {
753 return false;
756 lsb = c & -c;
757 /* Accept 1..10..0. */
758 if (c == -lsb) {
759 *mb = 0;
760 *me = clz64(lsb);
761 return true;
763 /* Accept 0..01..1. */
764 if (lsb == 1 && (c & (c + 1)) == 0) {
765 *mb = clz64(c + 1) + 1;
766 *me = 63;
767 return true;
769 return false;
772 static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
774 int mb, me;
776 if (mask_operand(c, &mb, &me)) {
777 tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
778 } else if ((c & 0xffff) == c) {
779 tcg_out32(s, ANDI | SAI(src, dst, c));
780 return;
781 } else if ((c & 0xffff0000) == c) {
782 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
783 return;
784 } else {
785 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
786 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
790 static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
792 int mb, me;
794 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
795 if (mask64_operand(c, &mb, &me)) {
796 if (mb == 0) {
797 tcg_out_rld(s, RLDICR, dst, src, 0, me);
798 } else {
799 tcg_out_rld(s, RLDICL, dst, src, 0, mb);
801 } else if ((c & 0xffff) == c) {
802 tcg_out32(s, ANDI | SAI(src, dst, c));
803 return;
804 } else if ((c & 0xffff0000) == c) {
805 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
806 return;
807 } else {
808 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
809 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
813 static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
814 int op_lo, int op_hi)
816 if (c >> 16) {
817 tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
818 src = dst;
820 if (c & 0xffff) {
821 tcg_out32(s, op_lo | SAI(src, dst, c));
822 src = dst;
826 static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
828 tcg_out_zori32(s, dst, src, c, ORI, ORIS);
831 static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
833 tcg_out_zori32(s, dst, src, c, XORI, XORIS);
836 static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
838 ptrdiff_t disp = tcg_pcrel_diff(s, target);
839 if (in_range_b(disp)) {
840 tcg_out32(s, B | (disp & 0x3fffffc) | mask);
841 } else {
842 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
843 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
844 tcg_out32(s, BCCTR | BO_ALWAYS | mask);
848 static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
849 TCGReg base, tcg_target_long offset)
851 tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
852 bool is_store = false;
853 TCGReg rs = TCG_REG_TMP1;
855 switch (opi) {
856 case LD: case LWA:
857 align = 3;
858 /* FALLTHRU */
859 default:
860 if (rt != TCG_REG_R0) {
861 rs = rt;
862 break;
864 break;
865 case STD:
866 align = 3;
867 /* FALLTHRU */
868 case STB: case STH: case STW:
869 is_store = true;
870 break;
873 /* For unaligned, or very large offsets, use the indexed form. */
874 if (offset & align || offset != (int32_t)offset) {
875 if (rs == base) {
876 rs = TCG_REG_R0;
878 tcg_debug_assert(!is_store || rs != rt);
879 tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
880 tcg_out32(s, opx | TAB(rt, base, rs));
881 return;
884 l0 = (int16_t)offset;
885 offset = (offset - l0) >> 16;
886 l1 = (int16_t)offset;
888 if (l1 < 0 && orig >= 0) {
889 extra = 0x4000;
890 l1 = (int16_t)(offset - 0x4000);
892 if (l1) {
893 tcg_out32(s, ADDIS | TAI(rs, base, l1));
894 base = rs;
896 if (extra) {
897 tcg_out32(s, ADDIS | TAI(rs, base, extra));
898 base = rs;
900 if (opi != ADDI || base != rt || l0 != 0) {
901 tcg_out32(s, opi | TAI(rt, base, l0));
905 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
906 TCGReg arg1, intptr_t arg2)
908 int opi, opx;
910 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
911 if (type == TCG_TYPE_I32) {
912 opi = LWZ, opx = LWZX;
913 } else {
914 opi = LD, opx = LDX;
916 tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
919 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
920 TCGReg arg1, intptr_t arg2)
922 int opi, opx;
924 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
925 if (type == TCG_TYPE_I32) {
926 opi = STW, opx = STWX;
927 } else {
928 opi = STD, opx = STDX;
930 tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
933 static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
934 TCGReg base, intptr_t ofs)
936 return false;
939 static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
940 int const_arg2, int cr, TCGType type)
942 int imm;
943 uint32_t op;
945 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
947 /* Simplify the comparisons below wrt CMPI. */
948 if (type == TCG_TYPE_I32) {
949 arg2 = (int32_t)arg2;
952 switch (cond) {
953 case TCG_COND_EQ:
954 case TCG_COND_NE:
955 if (const_arg2) {
956 if ((int16_t) arg2 == arg2) {
957 op = CMPI;
958 imm = 1;
959 break;
960 } else if ((uint16_t) arg2 == arg2) {
961 op = CMPLI;
962 imm = 1;
963 break;
966 op = CMPL;
967 imm = 0;
968 break;
970 case TCG_COND_LT:
971 case TCG_COND_GE:
972 case TCG_COND_LE:
973 case TCG_COND_GT:
974 if (const_arg2) {
975 if ((int16_t) arg2 == arg2) {
976 op = CMPI;
977 imm = 1;
978 break;
981 op = CMP;
982 imm = 0;
983 break;
985 case TCG_COND_LTU:
986 case TCG_COND_GEU:
987 case TCG_COND_LEU:
988 case TCG_COND_GTU:
989 if (const_arg2) {
990 if ((uint16_t) arg2 == arg2) {
991 op = CMPLI;
992 imm = 1;
993 break;
996 op = CMPL;
997 imm = 0;
998 break;
1000 default:
1001 tcg_abort();
1003 op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
1005 if (imm) {
1006 tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
1007 } else {
1008 if (const_arg2) {
1009 tcg_out_movi(s, type, TCG_REG_R0, arg2);
1010 arg2 = TCG_REG_R0;
1012 tcg_out32(s, op | RA(arg1) | RB(arg2));
1016 static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
1017 TCGReg dst, TCGReg src)
1019 if (type == TCG_TYPE_I32) {
1020 tcg_out32(s, CNTLZW | RS(src) | RA(dst));
1021 tcg_out_shri32(s, dst, dst, 5);
1022 } else {
1023 tcg_out32(s, CNTLZD | RS(src) | RA(dst));
1024 tcg_out_shri64(s, dst, dst, 6);
1028 static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
1030 /* X != 0 implies X + -1 generates a carry. Extra addition
1031 trickery means: R = X-1 + ~X + C = X-1 + (-X+1) + C = C. */
1032 if (dst != src) {
1033 tcg_out32(s, ADDIC | TAI(dst, src, -1));
1034 tcg_out32(s, SUBFE | TAB(dst, dst, src));
1035 } else {
1036 tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
1037 tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
1041 static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
1042 bool const_arg2)
1044 if (const_arg2) {
1045 if ((uint32_t)arg2 == arg2) {
1046 tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
1047 } else {
1048 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
1049 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
1051 } else {
1052 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
1054 return TCG_REG_R0;
1057 static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
1058 TCGArg arg0, TCGArg arg1, TCGArg arg2,
1059 int const_arg2)
1061 int crop, sh;
1063 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
1065 /* Ignore high bits of a potential constant arg2. */
1066 if (type == TCG_TYPE_I32) {
1067 arg2 = (uint32_t)arg2;
1070 /* Handle common and trivial cases before handling anything else. */
1071 if (arg2 == 0) {
1072 switch (cond) {
1073 case TCG_COND_EQ:
1074 tcg_out_setcond_eq0(s, type, arg0, arg1);
1075 return;
1076 case TCG_COND_NE:
1077 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1078 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1079 arg1 = TCG_REG_R0;
1081 tcg_out_setcond_ne0(s, arg0, arg1);
1082 return;
1083 case TCG_COND_GE:
1084 tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1085 arg1 = arg0;
1086 /* FALLTHRU */
1087 case TCG_COND_LT:
1088 /* Extract the sign bit. */
1089 if (type == TCG_TYPE_I32) {
1090 tcg_out_shri32(s, arg0, arg1, 31);
1091 } else {
1092 tcg_out_shri64(s, arg0, arg1, 63);
1094 return;
1095 default:
1096 break;
1100 /* If we have ISEL, we can implement everything with 3 or 4 insns.
1101 All other cases below are also at least 3 insns, so speed up the
1102 code generator by not considering them and always using ISEL. */
1103 if (HAVE_ISEL) {
1104 int isel, tab;
1106 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1108 isel = tcg_to_isel[cond];
1110 tcg_out_movi(s, type, arg0, 1);
1111 if (isel & 1) {
1112 /* arg0 = (bc ? 0 : 1) */
1113 tab = TAB(arg0, 0, arg0);
1114 isel &= ~1;
1115 } else {
1116 /* arg0 = (bc ? 1 : 0) */
1117 tcg_out_movi(s, type, TCG_REG_R0, 0);
1118 tab = TAB(arg0, arg0, TCG_REG_R0);
1120 tcg_out32(s, isel | tab);
1121 return;
1124 switch (cond) {
1125 case TCG_COND_EQ:
1126 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1127 tcg_out_setcond_eq0(s, type, arg0, arg1);
1128 return;
1130 case TCG_COND_NE:
1131 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1132 /* Discard the high bits only once, rather than both inputs. */
1133 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1134 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1135 arg1 = TCG_REG_R0;
1137 tcg_out_setcond_ne0(s, arg0, arg1);
1138 return;
1140 case TCG_COND_GT:
1141 case TCG_COND_GTU:
1142 sh = 30;
1143 crop = 0;
1144 goto crtest;
1146 case TCG_COND_LT:
1147 case TCG_COND_LTU:
1148 sh = 29;
1149 crop = 0;
1150 goto crtest;
1152 case TCG_COND_GE:
1153 case TCG_COND_GEU:
1154 sh = 31;
1155 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1156 goto crtest;
1158 case TCG_COND_LE:
1159 case TCG_COND_LEU:
1160 sh = 31;
1161 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1162 crtest:
1163 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1164 if (crop) {
1165 tcg_out32(s, crop);
1167 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1168 tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1169 break;
1171 default:
1172 tcg_abort();
1176 static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
1178 if (l->has_value) {
1179 bc |= reloc_pc14_val(s->code_ptr, l->u.value_ptr);
1180 } else {
1181 tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
1183 tcg_out32(s, bc);
1186 static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1187 TCGArg arg1, TCGArg arg2, int const_arg2,
1188 TCGLabel *l, TCGType type)
1190 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1191 tcg_out_bc(s, tcg_to_bc[cond], l);
1194 static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1195 TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1196 TCGArg v2, bool const_c2)
1198 /* If for some reason both inputs are zero, don't produce bad code. */
1199 if (v1 == 0 && v2 == 0) {
1200 tcg_out_movi(s, type, dest, 0);
1201 return;
1204 tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1206 if (HAVE_ISEL) {
1207 int isel = tcg_to_isel[cond];
1209 /* Swap the V operands if the operation indicates inversion. */
1210 if (isel & 1) {
1211 int t = v1;
1212 v1 = v2;
1213 v2 = t;
1214 isel &= ~1;
1216 /* V1 == 0 is handled by isel; V2 == 0 must be handled by hand. */
1217 if (v2 == 0) {
1218 tcg_out_movi(s, type, TCG_REG_R0, 0);
1220 tcg_out32(s, isel | TAB(dest, v1, v2));
1221 } else {
1222 if (dest == v2) {
1223 cond = tcg_invert_cond(cond);
1224 v2 = v1;
1225 } else if (dest != v1) {
1226 if (v1 == 0) {
1227 tcg_out_movi(s, type, dest, 0);
1228 } else {
1229 tcg_out_mov(s, type, dest, v1);
1232 /* Branch forward over one insn */
1233 tcg_out32(s, tcg_to_bc[cond] | 8);
1234 if (v2 == 0) {
1235 tcg_out_movi(s, type, dest, 0);
1236 } else {
1237 tcg_out_mov(s, type, dest, v2);
1242 static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
1243 TCGArg a0, TCGArg a1, TCGArg a2, bool const_a2)
1245 if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) {
1246 tcg_out32(s, opc | RA(a0) | RS(a1));
1247 } else {
1248 tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type);
1249 /* Note that the only other valid constant for a2 is 0. */
1250 if (HAVE_ISEL) {
1251 tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
1252 tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0));
1253 } else if (!const_a2 && a0 == a2) {
1254 tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8);
1255 tcg_out32(s, opc | RA(a0) | RS(a1));
1256 } else {
1257 tcg_out32(s, opc | RA(a0) | RS(a1));
1258 tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8);
1259 if (const_a2) {
1260 tcg_out_movi(s, type, a0, 0);
1261 } else {
1262 tcg_out_mov(s, type, a0, a2);
1268 static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1269 const int *const_args)
1271 static const struct { uint8_t bit1, bit2; } bits[] = {
1272 [TCG_COND_LT ] = { CR_LT, CR_LT },
1273 [TCG_COND_LE ] = { CR_LT, CR_GT },
1274 [TCG_COND_GT ] = { CR_GT, CR_GT },
1275 [TCG_COND_GE ] = { CR_GT, CR_LT },
1276 [TCG_COND_LTU] = { CR_LT, CR_LT },
1277 [TCG_COND_LEU] = { CR_LT, CR_GT },
1278 [TCG_COND_GTU] = { CR_GT, CR_GT },
1279 [TCG_COND_GEU] = { CR_GT, CR_LT },
1282 TCGCond cond = args[4], cond2;
1283 TCGArg al, ah, bl, bh;
1284 int blconst, bhconst;
1285 int op, bit1, bit2;
1287 al = args[0];
1288 ah = args[1];
1289 bl = args[2];
1290 bh = args[3];
1291 blconst = const_args[2];
1292 bhconst = const_args[3];
1294 switch (cond) {
1295 case TCG_COND_EQ:
1296 op = CRAND;
1297 goto do_equality;
1298 case TCG_COND_NE:
1299 op = CRNAND;
1300 do_equality:
1301 tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
1302 tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
1303 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1304 break;
1306 case TCG_COND_LT:
1307 case TCG_COND_LE:
1308 case TCG_COND_GT:
1309 case TCG_COND_GE:
1310 case TCG_COND_LTU:
1311 case TCG_COND_LEU:
1312 case TCG_COND_GTU:
1313 case TCG_COND_GEU:
1314 bit1 = bits[cond].bit1;
1315 bit2 = bits[cond].bit2;
1316 op = (bit1 != bit2 ? CRANDC : CRAND);
1317 cond2 = tcg_unsigned_cond(cond);
1319 tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
1320 tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
1321 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
1322 tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
1323 break;
1325 default:
1326 tcg_abort();
1330 static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
1331 const int *const_args)
1333 tcg_out_cmp2(s, args + 1, const_args + 1);
1334 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1335 tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
1338 static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1339 const int *const_args)
1341 tcg_out_cmp2(s, args, const_args);
1342 tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
1345 static void tcg_out_mb(TCGContext *s, TCGArg a0)
1347 uint32_t insn = HWSYNC;
1348 a0 &= TCG_MO_ALL;
1349 if (a0 == TCG_MO_LD_LD) {
1350 insn = LWSYNC;
1351 } else if (a0 == TCG_MO_ST_ST) {
1352 insn = EIEIO;
1354 tcg_out32(s, insn);
1357 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
1358 uintptr_t addr)
1360 if (TCG_TARGET_REG_BITS == 64) {
1361 tcg_insn_unit i1, i2;
1362 intptr_t tb_diff = addr - tc_ptr;
1363 intptr_t br_diff = addr - (jmp_addr + 4);
1364 uint64_t pair;
1366 /* This does not exercise the range of the branch, but we do
1367 still need to be able to load the new value of TCG_REG_TB.
1368 But this does still happen quite often. */
1369 if (tb_diff == (int16_t)tb_diff) {
1370 i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
1371 i2 = B | (br_diff & 0x3fffffc);
1372 } else {
1373 intptr_t lo = (int16_t)tb_diff;
1374 intptr_t hi = (int32_t)(tb_diff - lo);
1375 assert(tb_diff == hi + lo);
1376 i1 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
1377 i2 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
1379 #ifdef HOST_WORDS_BIGENDIAN
1380 pair = (uint64_t)i1 << 32 | i2;
1381 #else
1382 pair = (uint64_t)i2 << 32 | i1;
1383 #endif
1385 /* As per the enclosing if, this is ppc64. Avoid the _Static_assert
1386 within atomic_set that would fail to build a ppc32 host. */
1387 atomic_set__nocheck((uint64_t *)jmp_addr, pair);
1388 flush_icache_range(jmp_addr, jmp_addr + 8);
1389 } else {
1390 intptr_t diff = addr - jmp_addr;
1391 tcg_debug_assert(in_range_b(diff));
1392 atomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
1393 flush_icache_range(jmp_addr, jmp_addr + 4);
1397 static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
1399 #ifdef _CALL_AIX
1400 /* Look through the descriptor. If the branch is in range, and we
1401 don't have to spend too much effort on building the toc. */
1402 void *tgt = ((void **)target)[0];
1403 uintptr_t toc = ((uintptr_t *)target)[1];
1404 intptr_t diff = tcg_pcrel_diff(s, tgt);
1406 if (in_range_b(diff) && toc == (uint32_t)toc) {
1407 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
1408 tcg_out_b(s, LK, tgt);
1409 } else {
1410 /* Fold the low bits of the constant into the addresses below. */
1411 intptr_t arg = (intptr_t)target;
1412 int ofs = (int16_t)arg;
1414 if (ofs + 8 < 0x8000) {
1415 arg -= ofs;
1416 } else {
1417 ofs = 0;
1419 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg);
1420 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
1421 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
1422 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
1423 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1425 #elif defined(_CALL_ELF) && _CALL_ELF == 2
1426 intptr_t diff;
1428 /* In the ELFv2 ABI, we have to set up r12 to contain the destination
1429 address, which the callee uses to compute its TOC address. */
1430 /* FIXME: when the branch is in range, we could avoid r12 load if we
1431 knew that the destination uses the same TOC, and what its local
1432 entry point offset is. */
1433 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target);
1435 diff = tcg_pcrel_diff(s, target);
1436 if (in_range_b(diff)) {
1437 tcg_out_b(s, LK, target);
1438 } else {
1439 tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
1440 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1442 #else
1443 tcg_out_b(s, LK, target);
1444 #endif
1447 static const uint32_t qemu_ldx_opc[16] = {
1448 [MO_UB] = LBZX,
1449 [MO_UW] = LHZX,
1450 [MO_UL] = LWZX,
1451 [MO_Q] = LDX,
1452 [MO_SW] = LHAX,
1453 [MO_SL] = LWAX,
1454 [MO_BSWAP | MO_UB] = LBZX,
1455 [MO_BSWAP | MO_UW] = LHBRX,
1456 [MO_BSWAP | MO_UL] = LWBRX,
1457 [MO_BSWAP | MO_Q] = LDBRX,
1460 static const uint32_t qemu_stx_opc[16] = {
1461 [MO_UB] = STBX,
1462 [MO_UW] = STHX,
1463 [MO_UL] = STWX,
1464 [MO_Q] = STDX,
1465 [MO_BSWAP | MO_UB] = STBX,
1466 [MO_BSWAP | MO_UW] = STHBRX,
1467 [MO_BSWAP | MO_UL] = STWBRX,
1468 [MO_BSWAP | MO_Q] = STDBRX,
1471 static const uint32_t qemu_exts_opc[4] = {
1472 EXTSB, EXTSH, EXTSW, 0
1475 #if defined (CONFIG_SOFTMMU)
1476 #include "tcg-ldst.inc.c"
1478 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
1479 * int mmu_idx, uintptr_t ra)
1481 static void * const qemu_ld_helpers[16] = {
1482 [MO_UB] = helper_ret_ldub_mmu,
1483 [MO_LEUW] = helper_le_lduw_mmu,
1484 [MO_LEUL] = helper_le_ldul_mmu,
1485 [MO_LEQ] = helper_le_ldq_mmu,
1486 [MO_BEUW] = helper_be_lduw_mmu,
1487 [MO_BEUL] = helper_be_ldul_mmu,
1488 [MO_BEQ] = helper_be_ldq_mmu,
1491 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
1492 * uintxx_t val, int mmu_idx, uintptr_t ra)
1494 static void * const qemu_st_helpers[16] = {
1495 [MO_UB] = helper_ret_stb_mmu,
1496 [MO_LEUW] = helper_le_stw_mmu,
1497 [MO_LEUL] = helper_le_stl_mmu,
1498 [MO_LEQ] = helper_le_stq_mmu,
1499 [MO_BEUW] = helper_be_stw_mmu,
1500 [MO_BEUL] = helper_be_stl_mmu,
1501 [MO_BEQ] = helper_be_stq_mmu,
1504 /* We expect to use a 16-bit negative offset from ENV. */
1505 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1506 QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768);
1508 /* Perform the TLB load and compare. Places the result of the comparison
1509 in CR7, loads the addend of the TLB into R3, and returns the register
1510 containing the guest address (zero-extended into R4). Clobbers R0 and R2. */
1512 static TCGReg tcg_out_tlb_read(TCGContext *s, MemOp opc,
1513 TCGReg addrlo, TCGReg addrhi,
1514 int mem_index, bool is_read)
1516 int cmp_off
1517 = (is_read
1518 ? offsetof(CPUTLBEntry, addr_read)
1519 : offsetof(CPUTLBEntry, addr_write));
1520 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1521 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1522 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1523 unsigned s_bits = opc & MO_SIZE;
1524 unsigned a_bits = get_alignment_bits(opc);
1526 /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
1527 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off);
1528 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off);
1530 /* Extract the page index, shifted into place for tlb index. */
1531 if (TCG_TARGET_REG_BITS == 32) {
1532 tcg_out_shri32(s, TCG_REG_TMP1, addrlo,
1533 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1534 } else {
1535 tcg_out_shri64(s, TCG_REG_TMP1, addrlo,
1536 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1538 tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1));
1540 /* Load the TLB comparator. */
1541 if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
1542 uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32
1543 ? LWZUX : LDUX);
1544 tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4));
1545 } else {
1546 tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4));
1547 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1548 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4);
1549 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off);
1550 } else {
1551 tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off);
1555 /* Load the TLB addend for use on the fast path. Do this asap
1556 to minimize any load use delay. */
1557 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3,
1558 offsetof(CPUTLBEntry, addend));
1560 /* Clear the non-page, non-alignment bits from the address */
1561 if (TCG_TARGET_REG_BITS == 32) {
1562 /* We don't support unaligned accesses on 32-bits.
1563 * Preserve the bottom bits and thus trigger a comparison
1564 * failure on unaligned accesses.
1566 if (a_bits < s_bits) {
1567 a_bits = s_bits;
1569 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
1570 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1571 } else {
1572 TCGReg t = addrlo;
1574 /* If the access is unaligned, we need to make sure we fail if we
1575 * cross a page boundary. The trick is to add the access size-1
1576 * to the address before masking the low bits. That will make the
1577 * address overflow to the next page if we cross a page boundary,
1578 * which will then force a mismatch of the TLB compare.
1580 if (a_bits < s_bits) {
1581 unsigned a_mask = (1 << a_bits) - 1;
1582 unsigned s_mask = (1 << s_bits) - 1;
1583 tcg_out32(s, ADDI | TAI(TCG_REG_R0, t, s_mask - a_mask));
1584 t = TCG_REG_R0;
1587 /* Mask the address for the requested alignment. */
1588 if (TARGET_LONG_BITS == 32) {
1589 tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0,
1590 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1591 /* Zero-extend the address for use in the final address. */
1592 tcg_out_ext32u(s, TCG_REG_R4, addrlo);
1593 addrlo = TCG_REG_R4;
1594 } else if (a_bits == 0) {
1595 tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS);
1596 } else {
1597 tcg_out_rld(s, RLDICL, TCG_REG_R0, t,
1598 64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits);
1599 tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
1603 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1604 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1605 0, 7, TCG_TYPE_I32);
1606 tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32);
1607 tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1608 } else {
1609 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1610 0, 7, TCG_TYPE_TL);
1613 return addrlo;
1616 /* Record the context of a call to the out of line helper code for the slow
1617 path for a load or store, so that we can later generate the correct
1618 helper code. */
1619 static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1620 TCGReg datalo_reg, TCGReg datahi_reg,
1621 TCGReg addrlo_reg, TCGReg addrhi_reg,
1622 tcg_insn_unit *raddr, tcg_insn_unit *lptr)
1624 TCGLabelQemuLdst *label = new_ldst_label(s);
1626 label->is_ld = is_ld;
1627 label->oi = oi;
1628 label->datalo_reg = datalo_reg;
1629 label->datahi_reg = datahi_reg;
1630 label->addrlo_reg = addrlo_reg;
1631 label->addrhi_reg = addrhi_reg;
1632 label->raddr = raddr;
1633 label->label_ptr[0] = lptr;
1636 static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1638 TCGMemOpIdx oi = lb->oi;
1639 MemOp opc = get_memop(oi);
1640 TCGReg hi, lo, arg = TCG_REG_R3;
1642 if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
1643 return false;
1646 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1648 lo = lb->addrlo_reg;
1649 hi = lb->addrhi_reg;
1650 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1651 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1652 arg |= 1;
1653 #endif
1654 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1655 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1656 } else {
1657 /* If the address needed to be zero-extended, we'll have already
1658 placed it in R4. The only remaining case is 64-bit guest. */
1659 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1662 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1663 tcg_out32(s, MFSPR | RT(arg) | LR);
1665 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1667 lo = lb->datalo_reg;
1668 hi = lb->datahi_reg;
1669 if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1670 tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
1671 tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
1672 } else if (opc & MO_SIGN) {
1673 uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
1674 tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
1675 } else {
1676 tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
1679 tcg_out_b(s, 0, lb->raddr);
1680 return true;
1683 static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1685 TCGMemOpIdx oi = lb->oi;
1686 MemOp opc = get_memop(oi);
1687 MemOp s_bits = opc & MO_SIZE;
1688 TCGReg hi, lo, arg = TCG_REG_R3;
1690 if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
1691 return false;
1694 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1696 lo = lb->addrlo_reg;
1697 hi = lb->addrhi_reg;
1698 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1699 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1700 arg |= 1;
1701 #endif
1702 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1703 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1704 } else {
1705 /* If the address needed to be zero-extended, we'll have already
1706 placed it in R4. The only remaining case is 64-bit guest. */
1707 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1710 lo = lb->datalo_reg;
1711 hi = lb->datahi_reg;
1712 if (TCG_TARGET_REG_BITS == 32) {
1713 switch (s_bits) {
1714 case MO_64:
1715 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
1716 arg |= 1;
1717 #endif
1718 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1719 /* FALLTHRU */
1720 case MO_32:
1721 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1722 break;
1723 default:
1724 tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
1725 break;
1727 } else {
1728 if (s_bits == MO_64) {
1729 tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
1730 } else {
1731 tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
1735 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1736 tcg_out32(s, MFSPR | RT(arg) | LR);
1738 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1740 tcg_out_b(s, 0, lb->raddr);
1741 return true;
1743 #endif /* SOFTMMU */
1745 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1747 TCGReg datalo, datahi, addrlo, rbase;
1748 TCGReg addrhi __attribute__((unused));
1749 TCGMemOpIdx oi;
1750 MemOp opc, s_bits;
1751 #ifdef CONFIG_SOFTMMU
1752 int mem_index;
1753 tcg_insn_unit *label_ptr;
1754 #endif
1756 datalo = *args++;
1757 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1758 addrlo = *args++;
1759 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1760 oi = *args++;
1761 opc = get_memop(oi);
1762 s_bits = opc & MO_SIZE;
1764 #ifdef CONFIG_SOFTMMU
1765 mem_index = get_mmuidx(oi);
1766 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true);
1768 /* Load a pointer into the current opcode w/conditional branch-link. */
1769 label_ptr = s->code_ptr;
1770 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1772 rbase = TCG_REG_R3;
1773 #else /* !CONFIG_SOFTMMU */
1774 rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1775 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1776 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1777 addrlo = TCG_REG_TMP1;
1779 #endif
1781 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1782 if (opc & MO_BSWAP) {
1783 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1784 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1785 tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0));
1786 } else if (rbase != 0) {
1787 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1788 tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo));
1789 tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0));
1790 } else if (addrlo == datahi) {
1791 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1792 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1793 } else {
1794 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1795 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1797 } else {
1798 uint32_t insn = qemu_ldx_opc[opc & (MO_BSWAP | MO_SSIZE)];
1799 if (!have_isa_2_06 && insn == LDBRX) {
1800 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1801 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1802 tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1803 tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0);
1804 } else if (insn) {
1805 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1806 } else {
1807 insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1808 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1809 insn = qemu_exts_opc[s_bits];
1810 tcg_out32(s, insn | RA(datalo) | RS(datalo));
1814 #ifdef CONFIG_SOFTMMU
1815 add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
1816 s->code_ptr, label_ptr);
1817 #endif
1820 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1822 TCGReg datalo, datahi, addrlo, rbase;
1823 TCGReg addrhi __attribute__((unused));
1824 TCGMemOpIdx oi;
1825 MemOp opc, s_bits;
1826 #ifdef CONFIG_SOFTMMU
1827 int mem_index;
1828 tcg_insn_unit *label_ptr;
1829 #endif
1831 datalo = *args++;
1832 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1833 addrlo = *args++;
1834 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1835 oi = *args++;
1836 opc = get_memop(oi);
1837 s_bits = opc & MO_SIZE;
1839 #ifdef CONFIG_SOFTMMU
1840 mem_index = get_mmuidx(oi);
1841 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false);
1843 /* Load a pointer into the current opcode w/conditional branch-link. */
1844 label_ptr = s->code_ptr;
1845 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1847 rbase = TCG_REG_R3;
1848 #else /* !CONFIG_SOFTMMU */
1849 rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1850 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1851 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1852 addrlo = TCG_REG_TMP1;
1854 #endif
1856 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1857 if (opc & MO_BSWAP) {
1858 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1859 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1860 tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));
1861 } else if (rbase != 0) {
1862 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1863 tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));
1864 tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));
1865 } else {
1866 tcg_out32(s, STW | TAI(datahi, addrlo, 0));
1867 tcg_out32(s, STW | TAI(datalo, addrlo, 4));
1869 } else {
1870 uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)];
1871 if (!have_isa_2_06 && insn == STDBRX) {
1872 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1873 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));
1874 tcg_out_shri64(s, TCG_REG_R0, datalo, 32);
1875 tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));
1876 } else {
1877 tcg_out32(s, insn | SAB(datalo, rbase, addrlo));
1881 #ifdef CONFIG_SOFTMMU
1882 add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
1883 s->code_ptr, label_ptr);
1884 #endif
1887 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1889 int i;
1890 for (i = 0; i < count; ++i) {
1891 p[i] = NOP;
1895 /* Parameters for function call generation, used in tcg.c. */
1896 #define TCG_TARGET_STACK_ALIGN 16
1897 #define TCG_TARGET_EXTEND_ARGS 1
1899 #ifdef _CALL_AIX
1900 # define LINK_AREA_SIZE (6 * SZR)
1901 # define LR_OFFSET (1 * SZR)
1902 # define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR)
1903 #elif defined(TCG_TARGET_CALL_DARWIN)
1904 # define LINK_AREA_SIZE (6 * SZR)
1905 # define LR_OFFSET (2 * SZR)
1906 #elif TCG_TARGET_REG_BITS == 64
1907 # if defined(_CALL_ELF) && _CALL_ELF == 2
1908 # define LINK_AREA_SIZE (4 * SZR)
1909 # define LR_OFFSET (1 * SZR)
1910 # endif
1911 #else /* TCG_TARGET_REG_BITS == 32 */
1912 # if defined(_CALL_SYSV)
1913 # define LINK_AREA_SIZE (2 * SZR)
1914 # define LR_OFFSET (1 * SZR)
1915 # endif
1916 #endif
1917 #ifndef LR_OFFSET
1918 # error "Unhandled abi"
1919 #endif
1920 #ifndef TCG_TARGET_CALL_STACK_OFFSET
1921 # define TCG_TARGET_CALL_STACK_OFFSET LINK_AREA_SIZE
1922 #endif
1924 #define CPU_TEMP_BUF_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
1925 #define REG_SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR)
1927 #define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET \
1928 + TCG_STATIC_CALL_ARGS_SIZE \
1929 + CPU_TEMP_BUF_SIZE \
1930 + REG_SAVE_SIZE \
1931 + TCG_TARGET_STACK_ALIGN - 1) \
1932 & -TCG_TARGET_STACK_ALIGN)
1934 #define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE)
1936 static void tcg_target_qemu_prologue(TCGContext *s)
1938 int i;
1940 #ifdef _CALL_AIX
1941 void **desc = (void **)s->code_ptr;
1942 desc[0] = desc + 2; /* entry point */
1943 desc[1] = 0; /* environment pointer */
1944 s->code_ptr = (void *)(desc + 2); /* skip over descriptor */
1945 #endif
1947 tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
1948 CPU_TEMP_BUF_SIZE);
1950 /* Prologue */
1951 tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1952 tcg_out32(s, (SZR == 8 ? STDU : STWU)
1953 | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1955 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1956 tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1957 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1959 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1961 #ifndef CONFIG_SOFTMMU
1962 if (guest_base) {
1963 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
1964 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1966 #endif
1968 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1969 tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1970 if (USE_REG_TB) {
1971 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]);
1973 tcg_out32(s, BCCTR | BO_ALWAYS);
1975 /* Epilogue */
1976 s->code_gen_epilogue = tb_ret_addr = s->code_ptr;
1978 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1979 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1980 tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1981 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1983 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1984 tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1985 tcg_out32(s, BCLR | BO_ALWAYS);
1988 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1989 const int *const_args)
1991 TCGArg a0, a1, a2;
1992 int c;
1994 switch (opc) {
1995 case INDEX_op_exit_tb:
1996 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1997 tcg_out_b(s, 0, tb_ret_addr);
1998 break;
1999 case INDEX_op_goto_tb:
2000 if (s->tb_jmp_insn_offset) {
2001 /* Direct jump. */
2002 if (TCG_TARGET_REG_BITS == 64) {
2003 /* Ensure the next insns are 8-byte aligned. */
2004 if ((uintptr_t)s->code_ptr & 7) {
2005 tcg_out32(s, NOP);
2007 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2008 tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2009 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2010 } else {
2011 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2012 tcg_out32(s, B);
2013 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
2014 break;
2016 } else {
2017 /* Indirect jump. */
2018 tcg_debug_assert(s->tb_jmp_insn_offset == NULL);
2019 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, 0,
2020 (intptr_t)(s->tb_jmp_insn_offset + args[0]));
2022 tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
2023 tcg_out32(s, BCCTR | BO_ALWAYS);
2024 set_jmp_reset_offset(s, args[0]);
2025 if (USE_REG_TB) {
2026 /* For the unlinked case, need to reset TCG_REG_TB. */
2027 c = -tcg_current_code_size(s);
2028 assert(c == (int16_t)c);
2029 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, c));
2031 break;
2032 case INDEX_op_goto_ptr:
2033 tcg_out32(s, MTSPR | RS(args[0]) | CTR);
2034 if (USE_REG_TB) {
2035 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, args[0]);
2037 tcg_out32(s, ADDI | TAI(TCG_REG_R3, 0, 0));
2038 tcg_out32(s, BCCTR | BO_ALWAYS);
2039 break;
2040 case INDEX_op_br:
2042 TCGLabel *l = arg_label(args[0]);
2043 uint32_t insn = B;
2045 if (l->has_value) {
2046 insn |= reloc_pc24_val(s->code_ptr, l->u.value_ptr);
2047 } else {
2048 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
2050 tcg_out32(s, insn);
2052 break;
2053 case INDEX_op_ld8u_i32:
2054 case INDEX_op_ld8u_i64:
2055 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2056 break;
2057 case INDEX_op_ld8s_i32:
2058 case INDEX_op_ld8s_i64:
2059 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2060 tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
2061 break;
2062 case INDEX_op_ld16u_i32:
2063 case INDEX_op_ld16u_i64:
2064 tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
2065 break;
2066 case INDEX_op_ld16s_i32:
2067 case INDEX_op_ld16s_i64:
2068 tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
2069 break;
2070 case INDEX_op_ld_i32:
2071 case INDEX_op_ld32u_i64:
2072 tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
2073 break;
2074 case INDEX_op_ld32s_i64:
2075 tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
2076 break;
2077 case INDEX_op_ld_i64:
2078 tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
2079 break;
2080 case INDEX_op_st8_i32:
2081 case INDEX_op_st8_i64:
2082 tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
2083 break;
2084 case INDEX_op_st16_i32:
2085 case INDEX_op_st16_i64:
2086 tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
2087 break;
2088 case INDEX_op_st_i32:
2089 case INDEX_op_st32_i64:
2090 tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
2091 break;
2092 case INDEX_op_st_i64:
2093 tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
2094 break;
2096 case INDEX_op_add_i32:
2097 a0 = args[0], a1 = args[1], a2 = args[2];
2098 if (const_args[2]) {
2099 do_addi_32:
2100 tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
2101 } else {
2102 tcg_out32(s, ADD | TAB(a0, a1, a2));
2104 break;
2105 case INDEX_op_sub_i32:
2106 a0 = args[0], a1 = args[1], a2 = args[2];
2107 if (const_args[1]) {
2108 if (const_args[2]) {
2109 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
2110 } else {
2111 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2113 } else if (const_args[2]) {
2114 a2 = -a2;
2115 goto do_addi_32;
2116 } else {
2117 tcg_out32(s, SUBF | TAB(a0, a2, a1));
2119 break;
2121 case INDEX_op_and_i32:
2122 a0 = args[0], a1 = args[1], a2 = args[2];
2123 if (const_args[2]) {
2124 tcg_out_andi32(s, a0, a1, a2);
2125 } else {
2126 tcg_out32(s, AND | SAB(a1, a0, a2));
2128 break;
2129 case INDEX_op_and_i64:
2130 a0 = args[0], a1 = args[1], a2 = args[2];
2131 if (const_args[2]) {
2132 tcg_out_andi64(s, a0, a1, a2);
2133 } else {
2134 tcg_out32(s, AND | SAB(a1, a0, a2));
2136 break;
2137 case INDEX_op_or_i64:
2138 case INDEX_op_or_i32:
2139 a0 = args[0], a1 = args[1], a2 = args[2];
2140 if (const_args[2]) {
2141 tcg_out_ori32(s, a0, a1, a2);
2142 } else {
2143 tcg_out32(s, OR | SAB(a1, a0, a2));
2145 break;
2146 case INDEX_op_xor_i64:
2147 case INDEX_op_xor_i32:
2148 a0 = args[0], a1 = args[1], a2 = args[2];
2149 if (const_args[2]) {
2150 tcg_out_xori32(s, a0, a1, a2);
2151 } else {
2152 tcg_out32(s, XOR | SAB(a1, a0, a2));
2154 break;
2155 case INDEX_op_andc_i32:
2156 a0 = args[0], a1 = args[1], a2 = args[2];
2157 if (const_args[2]) {
2158 tcg_out_andi32(s, a0, a1, ~a2);
2159 } else {
2160 tcg_out32(s, ANDC | SAB(a1, a0, a2));
2162 break;
2163 case INDEX_op_andc_i64:
2164 a0 = args[0], a1 = args[1], a2 = args[2];
2165 if (const_args[2]) {
2166 tcg_out_andi64(s, a0, a1, ~a2);
2167 } else {
2168 tcg_out32(s, ANDC | SAB(a1, a0, a2));
2170 break;
2171 case INDEX_op_orc_i32:
2172 if (const_args[2]) {
2173 tcg_out_ori32(s, args[0], args[1], ~args[2]);
2174 break;
2176 /* FALLTHRU */
2177 case INDEX_op_orc_i64:
2178 tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
2179 break;
2180 case INDEX_op_eqv_i32:
2181 if (const_args[2]) {
2182 tcg_out_xori32(s, args[0], args[1], ~args[2]);
2183 break;
2185 /* FALLTHRU */
2186 case INDEX_op_eqv_i64:
2187 tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
2188 break;
2189 case INDEX_op_nand_i32:
2190 case INDEX_op_nand_i64:
2191 tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
2192 break;
2193 case INDEX_op_nor_i32:
2194 case INDEX_op_nor_i64:
2195 tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
2196 break;
2198 case INDEX_op_clz_i32:
2199 tcg_out_cntxz(s, TCG_TYPE_I32, CNTLZW, args[0], args[1],
2200 args[2], const_args[2]);
2201 break;
2202 case INDEX_op_ctz_i32:
2203 tcg_out_cntxz(s, TCG_TYPE_I32, CNTTZW, args[0], args[1],
2204 args[2], const_args[2]);
2205 break;
2206 case INDEX_op_ctpop_i32:
2207 tcg_out32(s, CNTPOPW | SAB(args[1], args[0], 0));
2208 break;
2210 case INDEX_op_clz_i64:
2211 tcg_out_cntxz(s, TCG_TYPE_I64, CNTLZD, args[0], args[1],
2212 args[2], const_args[2]);
2213 break;
2214 case INDEX_op_ctz_i64:
2215 tcg_out_cntxz(s, TCG_TYPE_I64, CNTTZD, args[0], args[1],
2216 args[2], const_args[2]);
2217 break;
2218 case INDEX_op_ctpop_i64:
2219 tcg_out32(s, CNTPOPD | SAB(args[1], args[0], 0));
2220 break;
2222 case INDEX_op_mul_i32:
2223 a0 = args[0], a1 = args[1], a2 = args[2];
2224 if (const_args[2]) {
2225 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2226 } else {
2227 tcg_out32(s, MULLW | TAB(a0, a1, a2));
2229 break;
2231 case INDEX_op_div_i32:
2232 tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
2233 break;
2235 case INDEX_op_divu_i32:
2236 tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
2237 break;
2239 case INDEX_op_shl_i32:
2240 if (const_args[2]) {
2241 tcg_out_shli32(s, args[0], args[1], args[2]);
2242 } else {
2243 tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
2245 break;
2246 case INDEX_op_shr_i32:
2247 if (const_args[2]) {
2248 tcg_out_shri32(s, args[0], args[1], args[2]);
2249 } else {
2250 tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
2252 break;
2253 case INDEX_op_sar_i32:
2254 if (const_args[2]) {
2255 tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
2256 } else {
2257 tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
2259 break;
2260 case INDEX_op_rotl_i32:
2261 if (const_args[2]) {
2262 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
2263 } else {
2264 tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
2265 | MB(0) | ME(31));
2267 break;
2268 case INDEX_op_rotr_i32:
2269 if (const_args[2]) {
2270 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
2271 } else {
2272 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
2273 tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
2274 | MB(0) | ME(31));
2276 break;
2278 case INDEX_op_brcond_i32:
2279 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2280 arg_label(args[3]), TCG_TYPE_I32);
2281 break;
2282 case INDEX_op_brcond_i64:
2283 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2284 arg_label(args[3]), TCG_TYPE_I64);
2285 break;
2286 case INDEX_op_brcond2_i32:
2287 tcg_out_brcond2(s, args, const_args);
2288 break;
2290 case INDEX_op_neg_i32:
2291 case INDEX_op_neg_i64:
2292 tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
2293 break;
2295 case INDEX_op_not_i32:
2296 case INDEX_op_not_i64:
2297 tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
2298 break;
2300 case INDEX_op_add_i64:
2301 a0 = args[0], a1 = args[1], a2 = args[2];
2302 if (const_args[2]) {
2303 do_addi_64:
2304 tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
2305 } else {
2306 tcg_out32(s, ADD | TAB(a0, a1, a2));
2308 break;
2309 case INDEX_op_sub_i64:
2310 a0 = args[0], a1 = args[1], a2 = args[2];
2311 if (const_args[1]) {
2312 if (const_args[2]) {
2313 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
2314 } else {
2315 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2317 } else if (const_args[2]) {
2318 a2 = -a2;
2319 goto do_addi_64;
2320 } else {
2321 tcg_out32(s, SUBF | TAB(a0, a2, a1));
2323 break;
2325 case INDEX_op_shl_i64:
2326 if (const_args[2]) {
2327 tcg_out_shli64(s, args[0], args[1], args[2]);
2328 } else {
2329 tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
2331 break;
2332 case INDEX_op_shr_i64:
2333 if (const_args[2]) {
2334 tcg_out_shri64(s, args[0], args[1], args[2]);
2335 } else {
2336 tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
2338 break;
2339 case INDEX_op_sar_i64:
2340 if (const_args[2]) {
2341 int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
2342 tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
2343 } else {
2344 tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
2346 break;
2347 case INDEX_op_rotl_i64:
2348 if (const_args[2]) {
2349 tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
2350 } else {
2351 tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
2353 break;
2354 case INDEX_op_rotr_i64:
2355 if (const_args[2]) {
2356 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
2357 } else {
2358 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
2359 tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
2361 break;
2363 case INDEX_op_mul_i64:
2364 a0 = args[0], a1 = args[1], a2 = args[2];
2365 if (const_args[2]) {
2366 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2367 } else {
2368 tcg_out32(s, MULLD | TAB(a0, a1, a2));
2370 break;
2371 case INDEX_op_div_i64:
2372 tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
2373 break;
2374 case INDEX_op_divu_i64:
2375 tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
2376 break;
2378 case INDEX_op_qemu_ld_i32:
2379 tcg_out_qemu_ld(s, args, false);
2380 break;
2381 case INDEX_op_qemu_ld_i64:
2382 tcg_out_qemu_ld(s, args, true);
2383 break;
2384 case INDEX_op_qemu_st_i32:
2385 tcg_out_qemu_st(s, args, false);
2386 break;
2387 case INDEX_op_qemu_st_i64:
2388 tcg_out_qemu_st(s, args, true);
2389 break;
2391 case INDEX_op_ext8s_i32:
2392 case INDEX_op_ext8s_i64:
2393 c = EXTSB;
2394 goto gen_ext;
2395 case INDEX_op_ext16s_i32:
2396 case INDEX_op_ext16s_i64:
2397 c = EXTSH;
2398 goto gen_ext;
2399 case INDEX_op_ext_i32_i64:
2400 case INDEX_op_ext32s_i64:
2401 c = EXTSW;
2402 goto gen_ext;
2403 gen_ext:
2404 tcg_out32(s, c | RS(args[1]) | RA(args[0]));
2405 break;
2406 case INDEX_op_extu_i32_i64:
2407 tcg_out_ext32u(s, args[0], args[1]);
2408 break;
2410 case INDEX_op_setcond_i32:
2411 tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
2412 const_args[2]);
2413 break;
2414 case INDEX_op_setcond_i64:
2415 tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
2416 const_args[2]);
2417 break;
2418 case INDEX_op_setcond2_i32:
2419 tcg_out_setcond2(s, args, const_args);
2420 break;
2422 case INDEX_op_bswap16_i32:
2423 case INDEX_op_bswap16_i64:
2424 a0 = args[0], a1 = args[1];
2425 /* a1 = abcd */
2426 if (a0 != a1) {
2427 /* a0 = (a1 r<< 24) & 0xff # 000c */
2428 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2429 /* a0 = (a0 & ~0xff00) | (a1 r<< 8) & 0xff00 # 00dc */
2430 tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
2431 } else {
2432 /* r0 = (a1 r<< 8) & 0xff00 # 00d0 */
2433 tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
2434 /* a0 = (a1 r<< 24) & 0xff # 000c */
2435 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2436 /* a0 = a0 | r0 # 00dc */
2437 tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
2439 break;
2441 case INDEX_op_bswap32_i32:
2442 case INDEX_op_bswap32_i64:
2443 /* Stolen from gcc's builtin_bswap32 */
2444 a1 = args[1];
2445 a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
2447 /* a1 = args[1] # abcd */
2448 /* a0 = rotate_left (a1, 8) # bcda */
2449 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2450 /* a0 = (a0 & ~0xff000000) | ((a1 r<< 24) & 0xff000000) # dcda */
2451 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2452 /* a0 = (a0 & ~0x0000ff00) | ((a1 r<< 24) & 0x0000ff00) # dcba */
2453 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2455 if (a0 == TCG_REG_R0) {
2456 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2458 break;
2460 case INDEX_op_bswap64_i64:
2461 a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
2462 if (a0 == a1) {
2463 a0 = TCG_REG_R0;
2464 a2 = a1;
2467 /* a1 = # abcd efgh */
2468 /* a0 = rl32(a1, 8) # 0000 fghe */
2469 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2470 /* a0 = dep(a0, rl32(a1, 24), 0xff000000) # 0000 hghe */
2471 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2472 /* a0 = dep(a0, rl32(a1, 24), 0x0000ff00) # 0000 hgfe */
2473 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2475 /* a0 = rl64(a0, 32) # hgfe 0000 */
2476 /* a2 = rl64(a1, 32) # efgh abcd */
2477 tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
2478 tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
2480 /* a0 = dep(a0, rl32(a2, 8), 0xffffffff) # hgfe bcda */
2481 tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
2482 /* a0 = dep(a0, rl32(a2, 24), 0xff000000) # hgfe dcda */
2483 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
2484 /* a0 = dep(a0, rl32(a2, 24), 0x0000ff00) # hgfe dcba */
2485 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
2487 if (a0 == 0) {
2488 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2490 break;
2492 case INDEX_op_deposit_i32:
2493 if (const_args[2]) {
2494 uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
2495 tcg_out_andi32(s, args[0], args[0], ~mask);
2496 } else {
2497 tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
2498 32 - args[3] - args[4], 31 - args[3]);
2500 break;
2501 case INDEX_op_deposit_i64:
2502 if (const_args[2]) {
2503 uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
2504 tcg_out_andi64(s, args[0], args[0], ~mask);
2505 } else {
2506 tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
2507 64 - args[3] - args[4]);
2509 break;
2511 case INDEX_op_extract_i32:
2512 tcg_out_rlw(s, RLWINM, args[0], args[1],
2513 32 - args[2], 32 - args[3], 31);
2514 break;
2515 case INDEX_op_extract_i64:
2516 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]);
2517 break;
2519 case INDEX_op_movcond_i32:
2520 tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
2521 args[3], args[4], const_args[2]);
2522 break;
2523 case INDEX_op_movcond_i64:
2524 tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
2525 args[3], args[4], const_args[2]);
2526 break;
2528 #if TCG_TARGET_REG_BITS == 64
2529 case INDEX_op_add2_i64:
2530 #else
2531 case INDEX_op_add2_i32:
2532 #endif
2533 /* Note that the CA bit is defined based on the word size of the
2534 environment. So in 64-bit mode it's always carry-out of bit 63.
2535 The fallback code using deposit works just as well for 32-bit. */
2536 a0 = args[0], a1 = args[1];
2537 if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
2538 a0 = TCG_REG_R0;
2540 if (const_args[4]) {
2541 tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
2542 } else {
2543 tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
2545 if (const_args[5]) {
2546 tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
2547 } else {
2548 tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
2550 if (a0 != args[0]) {
2551 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2553 break;
2555 #if TCG_TARGET_REG_BITS == 64
2556 case INDEX_op_sub2_i64:
2557 #else
2558 case INDEX_op_sub2_i32:
2559 #endif
2560 a0 = args[0], a1 = args[1];
2561 if (a0 == args[5] || (!const_args[3] && a0 == args[3])) {
2562 a0 = TCG_REG_R0;
2564 if (const_args[2]) {
2565 tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2]));
2566 } else {
2567 tcg_out32(s, SUBFC | TAB(a0, args[4], args[2]));
2569 if (const_args[3]) {
2570 tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2571 } else {
2572 tcg_out32(s, SUBFE | TAB(a1, args[5], args[3]));
2574 if (a0 != args[0]) {
2575 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2577 break;
2579 case INDEX_op_muluh_i32:
2580 tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2]));
2581 break;
2582 case INDEX_op_mulsh_i32:
2583 tcg_out32(s, MULHW | TAB(args[0], args[1], args[2]));
2584 break;
2585 case INDEX_op_muluh_i64:
2586 tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2587 break;
2588 case INDEX_op_mulsh_i64:
2589 tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2590 break;
2592 case INDEX_op_mb:
2593 tcg_out_mb(s, args[0]);
2594 break;
2596 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
2597 case INDEX_op_mov_i64:
2598 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
2599 case INDEX_op_movi_i64:
2600 case INDEX_op_call: /* Always emitted via tcg_out_call. */
2601 default:
2602 tcg_abort();
2606 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2608 static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
2609 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
2610 static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
2611 static const TCGTargetOpDef S_S = { .args_ct_str = { "S", "S" } };
2612 static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
2613 static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
2614 static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
2615 static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
2616 static const TCGTargetOpDef S_S_S = { .args_ct_str = { "S", "S", "S" } };
2617 static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
2618 static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
2619 static const TCGTargetOpDef r_r_rT = { .args_ct_str = { "r", "r", "rT" } };
2620 static const TCGTargetOpDef r_r_rU = { .args_ct_str = { "r", "r", "rU" } };
2621 static const TCGTargetOpDef r_rI_ri
2622 = { .args_ct_str = { "r", "rI", "ri" } };
2623 static const TCGTargetOpDef r_rI_rT
2624 = { .args_ct_str = { "r", "rI", "rT" } };
2625 static const TCGTargetOpDef r_r_rZW
2626 = { .args_ct_str = { "r", "r", "rZW" } };
2627 static const TCGTargetOpDef L_L_L_L
2628 = { .args_ct_str = { "L", "L", "L", "L" } };
2629 static const TCGTargetOpDef S_S_S_S
2630 = { .args_ct_str = { "S", "S", "S", "S" } };
2631 static const TCGTargetOpDef movc
2632 = { .args_ct_str = { "r", "r", "ri", "rZ", "rZ" } };
2633 static const TCGTargetOpDef dep
2634 = { .args_ct_str = { "r", "0", "rZ" } };
2635 static const TCGTargetOpDef br2
2636 = { .args_ct_str = { "r", "r", "ri", "ri" } };
2637 static const TCGTargetOpDef setc2
2638 = { .args_ct_str = { "r", "r", "r", "ri", "ri" } };
2639 static const TCGTargetOpDef add2
2640 = { .args_ct_str = { "r", "r", "r", "r", "rI", "rZM" } };
2641 static const TCGTargetOpDef sub2
2642 = { .args_ct_str = { "r", "r", "rI", "rZM", "r", "r" } };
2644 switch (op) {
2645 case INDEX_op_goto_ptr:
2646 return &r;
2648 case INDEX_op_ld8u_i32:
2649 case INDEX_op_ld8s_i32:
2650 case INDEX_op_ld16u_i32:
2651 case INDEX_op_ld16s_i32:
2652 case INDEX_op_ld_i32:
2653 case INDEX_op_st8_i32:
2654 case INDEX_op_st16_i32:
2655 case INDEX_op_st_i32:
2656 case INDEX_op_ctpop_i32:
2657 case INDEX_op_neg_i32:
2658 case INDEX_op_not_i32:
2659 case INDEX_op_ext8s_i32:
2660 case INDEX_op_ext16s_i32:
2661 case INDEX_op_bswap16_i32:
2662 case INDEX_op_bswap32_i32:
2663 case INDEX_op_extract_i32:
2664 case INDEX_op_ld8u_i64:
2665 case INDEX_op_ld8s_i64:
2666 case INDEX_op_ld16u_i64:
2667 case INDEX_op_ld16s_i64:
2668 case INDEX_op_ld32u_i64:
2669 case INDEX_op_ld32s_i64:
2670 case INDEX_op_ld_i64:
2671 case INDEX_op_st8_i64:
2672 case INDEX_op_st16_i64:
2673 case INDEX_op_st32_i64:
2674 case INDEX_op_st_i64:
2675 case INDEX_op_ctpop_i64:
2676 case INDEX_op_neg_i64:
2677 case INDEX_op_not_i64:
2678 case INDEX_op_ext8s_i64:
2679 case INDEX_op_ext16s_i64:
2680 case INDEX_op_ext32s_i64:
2681 case INDEX_op_ext_i32_i64:
2682 case INDEX_op_extu_i32_i64:
2683 case INDEX_op_bswap16_i64:
2684 case INDEX_op_bswap32_i64:
2685 case INDEX_op_bswap64_i64:
2686 case INDEX_op_extract_i64:
2687 return &r_r;
2689 case INDEX_op_add_i32:
2690 case INDEX_op_and_i32:
2691 case INDEX_op_or_i32:
2692 case INDEX_op_xor_i32:
2693 case INDEX_op_andc_i32:
2694 case INDEX_op_orc_i32:
2695 case INDEX_op_eqv_i32:
2696 case INDEX_op_shl_i32:
2697 case INDEX_op_shr_i32:
2698 case INDEX_op_sar_i32:
2699 case INDEX_op_rotl_i32:
2700 case INDEX_op_rotr_i32:
2701 case INDEX_op_setcond_i32:
2702 case INDEX_op_and_i64:
2703 case INDEX_op_andc_i64:
2704 case INDEX_op_shl_i64:
2705 case INDEX_op_shr_i64:
2706 case INDEX_op_sar_i64:
2707 case INDEX_op_rotl_i64:
2708 case INDEX_op_rotr_i64:
2709 case INDEX_op_setcond_i64:
2710 return &r_r_ri;
2711 case INDEX_op_mul_i32:
2712 case INDEX_op_mul_i64:
2713 return &r_r_rI;
2714 case INDEX_op_div_i32:
2715 case INDEX_op_divu_i32:
2716 case INDEX_op_nand_i32:
2717 case INDEX_op_nor_i32:
2718 case INDEX_op_muluh_i32:
2719 case INDEX_op_mulsh_i32:
2720 case INDEX_op_orc_i64:
2721 case INDEX_op_eqv_i64:
2722 case INDEX_op_nand_i64:
2723 case INDEX_op_nor_i64:
2724 case INDEX_op_div_i64:
2725 case INDEX_op_divu_i64:
2726 case INDEX_op_mulsh_i64:
2727 case INDEX_op_muluh_i64:
2728 return &r_r_r;
2729 case INDEX_op_sub_i32:
2730 return &r_rI_ri;
2731 case INDEX_op_add_i64:
2732 return &r_r_rT;
2733 case INDEX_op_or_i64:
2734 case INDEX_op_xor_i64:
2735 return &r_r_rU;
2736 case INDEX_op_sub_i64:
2737 return &r_rI_rT;
2738 case INDEX_op_clz_i32:
2739 case INDEX_op_ctz_i32:
2740 case INDEX_op_clz_i64:
2741 case INDEX_op_ctz_i64:
2742 return &r_r_rZW;
2744 case INDEX_op_brcond_i32:
2745 case INDEX_op_brcond_i64:
2746 return &r_ri;
2748 case INDEX_op_movcond_i32:
2749 case INDEX_op_movcond_i64:
2750 return &movc;
2751 case INDEX_op_deposit_i32:
2752 case INDEX_op_deposit_i64:
2753 return &dep;
2754 case INDEX_op_brcond2_i32:
2755 return &br2;
2756 case INDEX_op_setcond2_i32:
2757 return &setc2;
2758 case INDEX_op_add2_i64:
2759 case INDEX_op_add2_i32:
2760 return &add2;
2761 case INDEX_op_sub2_i64:
2762 case INDEX_op_sub2_i32:
2763 return &sub2;
2765 case INDEX_op_qemu_ld_i32:
2766 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2767 ? &r_L : &r_L_L);
2768 case INDEX_op_qemu_st_i32:
2769 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2770 ? &S_S : &S_S_S);
2771 case INDEX_op_qemu_ld_i64:
2772 return (TCG_TARGET_REG_BITS == 64 ? &r_L
2773 : TARGET_LONG_BITS == 32 ? &L_L_L : &L_L_L_L);
2774 case INDEX_op_qemu_st_i64:
2775 return (TCG_TARGET_REG_BITS == 64 ? &S_S
2776 : TARGET_LONG_BITS == 32 ? &S_S_S : &S_S_S_S);
2778 default:
2779 return NULL;
2783 static void tcg_target_init(TCGContext *s)
2785 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2786 unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2);
2788 have_isa = tcg_isa_base;
2789 if (hwcap & PPC_FEATURE_ARCH_2_06) {
2790 have_isa = tcg_isa_2_06;
2792 #ifdef PPC_FEATURE2_ARCH_3_00
2793 if (hwcap2 & PPC_FEATURE2_ARCH_3_00) {
2794 have_isa = tcg_isa_3_00;
2796 #endif
2798 tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
2799 tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
2801 tcg_target_call_clobber_regs = 0;
2802 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2803 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2804 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2805 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2806 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2807 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2808 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R7);
2809 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2810 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2811 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2812 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2813 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12);
2815 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V0);
2816 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V1);
2817 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V2);
2818 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V3);
2819 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V4);
2820 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V5);
2821 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V6);
2822 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V7);
2823 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V8);
2824 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V9);
2825 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V10);
2826 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V11);
2827 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V12);
2828 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V13);
2829 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V14);
2830 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V15);
2831 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V16);
2832 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V17);
2833 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V18);
2834 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_V19);
2836 s->reserved_regs = 0;
2837 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0); /* tcg temp */
2838 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1); /* stack pointer */
2839 #if defined(_CALL_SYSV)
2840 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2); /* toc pointer */
2841 #endif
2842 #if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64
2843 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
2844 #endif
2845 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1); /* mem temp */
2846 tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP1);
2847 tcg_regset_set_reg(s->reserved_regs, TCG_VEC_TMP2);
2848 if (USE_REG_TB) {
2849 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB); /* tb->tc_ptr */
2853 #ifdef __ELF__
2854 typedef struct {
2855 DebugFrameCIE cie;
2856 DebugFrameFDEHeader fde;
2857 uint8_t fde_def_cfa[4];
2858 uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2859 } DebugFrame;
2861 /* We're expecting a 2 byte uleb128 encoded value. */
2862 QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2864 #if TCG_TARGET_REG_BITS == 64
2865 # define ELF_HOST_MACHINE EM_PPC64
2866 #else
2867 # define ELF_HOST_MACHINE EM_PPC
2868 #endif
2870 static DebugFrame debug_frame = {
2871 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
2872 .cie.id = -1,
2873 .cie.version = 1,
2874 .cie.code_align = 1,
2875 .cie.data_align = (-SZR & 0x7f), /* sleb128 -SZR */
2876 .cie.return_column = 65,
2878 /* Total FDE size does not include the "len" member. */
2879 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2881 .fde_def_cfa = {
2882 12, TCG_REG_R1, /* DW_CFA_def_cfa r1, ... */
2883 (FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
2884 (FRAME_SIZE >> 7)
2886 .fde_reg_ofs = {
2887 /* DW_CFA_offset_extended_sf, lr, LR_OFFSET */
2888 0x11, 65, (LR_OFFSET / -SZR) & 0x7f,
2892 void tcg_register_jit(void *buf, size_t buf_size)
2894 uint8_t *p = &debug_frame.fde_reg_ofs[3];
2895 int i;
2897 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2898 p[0] = 0x80 + tcg_target_callee_save_regs[i];
2899 p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR;
2902 debug_frame.fde.func_start = (uintptr_t)buf;
2903 debug_frame.fde.func_len = buf_size;
2905 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2907 #endif /* __ELF__ */
2909 void flush_icache_range(uintptr_t start, uintptr_t stop)
2911 uintptr_t p, start1, stop1;
2912 size_t dsize = qemu_dcache_linesize;
2913 size_t isize = qemu_icache_linesize;
2915 start1 = start & ~(dsize - 1);
2916 stop1 = (stop + dsize - 1) & ~(dsize - 1);
2917 for (p = start1; p < stop1; p += dsize) {
2918 asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
2920 asm volatile ("sync" : : : "memory");
2922 start &= start & ~(isize - 1);
2923 stop1 = (stop + isize - 1) & ~(isize - 1);
2924 for (p = start1; p < stop1; p += isize) {
2925 asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
2927 asm volatile ("sync" : : : "memory");
2928 asm volatile ("isync" : : : "memory");