1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "elf.h"
26#include "tcg-pool.inc.c"
27
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
34
35
36
37
38
39#ifdef _CALL_AIX
40# define TCG_REG_TMP1 TCG_REG_R2
41#else
42# define TCG_REG_TMP1 TCG_REG_R12
43#endif
44
45#define TCG_REG_TB TCG_REG_R31
46#define USE_REG_TB (TCG_TARGET_REG_BITS == 64)
47
48
49#define SZP ((int)sizeof(void *))
50
51
52#define SZR (TCG_TARGET_REG_BITS / 8)
53
54#define TCG_CT_CONST_S16 0x100
55#define TCG_CT_CONST_U16 0x200
56#define TCG_CT_CONST_S32 0x400
57#define TCG_CT_CONST_U32 0x800
58#define TCG_CT_CONST_ZERO 0x1000
59#define TCG_CT_CONST_MONE 0x2000
60#define TCG_CT_CONST_WSZ 0x4000
61
62static tcg_insn_unit *tb_ret_addr;
63
64bool have_isa_2_06;
65bool have_isa_3_00;
66
67#define HAVE_ISA_2_06 have_isa_2_06
68#define HAVE_ISEL have_isa_2_06
69
70#ifndef CONFIG_SOFTMMU
71#define TCG_GUEST_BASE_REG 30
72#endif
73
74#ifdef CONFIG_DEBUG_TCG
75static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
76 "r0",
77 "r1",
78 "r2",
79 "r3",
80 "r4",
81 "r5",
82 "r6",
83 "r7",
84 "r8",
85 "r9",
86 "r10",
87 "r11",
88 "r12",
89 "r13",
90 "r14",
91 "r15",
92 "r16",
93 "r17",
94 "r18",
95 "r19",
96 "r20",
97 "r21",
98 "r22",
99 "r23",
100 "r24",
101 "r25",
102 "r26",
103 "r27",
104 "r28",
105 "r29",
106 "r30",
107 "r31"
108};
109#endif
110
111static const int tcg_target_reg_alloc_order[] = {
112 TCG_REG_R14,
113 TCG_REG_R15,
114 TCG_REG_R16,
115 TCG_REG_R17,
116 TCG_REG_R18,
117 TCG_REG_R19,
118 TCG_REG_R20,
119 TCG_REG_R21,
120 TCG_REG_R22,
121 TCG_REG_R23,
122 TCG_REG_R24,
123 TCG_REG_R25,
124 TCG_REG_R26,
125 TCG_REG_R27,
126 TCG_REG_R28,
127 TCG_REG_R29,
128 TCG_REG_R30,
129 TCG_REG_R31,
130 TCG_REG_R12,
131 TCG_REG_R11,
132 TCG_REG_R2,
133 TCG_REG_R13,
134 TCG_REG_R10,
135 TCG_REG_R9,
136 TCG_REG_R8,
137 TCG_REG_R7,
138 TCG_REG_R6,
139 TCG_REG_R5,
140 TCG_REG_R4,
141 TCG_REG_R3,
142};
143
144static const int tcg_target_call_iarg_regs[] = {
145 TCG_REG_R3,
146 TCG_REG_R4,
147 TCG_REG_R5,
148 TCG_REG_R6,
149 TCG_REG_R7,
150 TCG_REG_R8,
151 TCG_REG_R9,
152 TCG_REG_R10
153};
154
155static const int tcg_target_call_oarg_regs[] = {
156 TCG_REG_R3,
157 TCG_REG_R4
158};
159
160static const int tcg_target_callee_save_regs[] = {
161#ifdef TCG_TARGET_CALL_DARWIN
162 TCG_REG_R11,
163#endif
164 TCG_REG_R14,
165 TCG_REG_R15,
166 TCG_REG_R16,
167 TCG_REG_R17,
168 TCG_REG_R18,
169 TCG_REG_R19,
170 TCG_REG_R20,
171 TCG_REG_R21,
172 TCG_REG_R22,
173 TCG_REG_R23,
174 TCG_REG_R24,
175 TCG_REG_R25,
176 TCG_REG_R26,
177 TCG_REG_R27,
178 TCG_REG_R28,
179 TCG_REG_R29,
180 TCG_REG_R30,
181 TCG_REG_R31
182};
183
184static inline bool in_range_b(tcg_target_long target)
185{
186 return target == sextract64(target, 0, 26);
187}
188
189static uint32_t reloc_pc24_val(tcg_insn_unit *pc, tcg_insn_unit *target)
190{
191 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
192 tcg_debug_assert(in_range_b(disp));
193 return disp & 0x3fffffc;
194}
195
196static bool reloc_pc24(tcg_insn_unit *pc, tcg_insn_unit *target)
197{
198 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
199 if (in_range_b(disp)) {
200 *pc = (*pc & ~0x3fffffc) | (disp & 0x3fffffc);
201 return true;
202 }
203 return false;
204}
205
206static uint16_t reloc_pc14_val(tcg_insn_unit *pc, tcg_insn_unit *target)
207{
208 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
209 tcg_debug_assert(disp == (int16_t) disp);
210 return disp & 0xfffc;
211}
212
213static bool reloc_pc14(tcg_insn_unit *pc, tcg_insn_unit *target)
214{
215 ptrdiff_t disp = tcg_ptr_byte_diff(target, pc);
216 if (disp == (int16_t) disp) {
217 *pc = (*pc & ~0xfffc) | (disp & 0xfffc);
218 return true;
219 }
220 return false;
221}
222
223
224static const char *target_parse_constraint(TCGArgConstraint *ct,
225 const char *ct_str, TCGType type)
226{
227 switch (*ct_str++) {
228 case 'A': case 'B': case 'C': case 'D':
229 ct->ct |= TCG_CT_REG;
230 tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
231 break;
232 case 'r':
233 ct->ct |= TCG_CT_REG;
234 ct->u.regs = 0xffffffff;
235 break;
236 case 'L':
237 ct->ct |= TCG_CT_REG;
238 ct->u.regs = 0xffffffff;
239 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
240#ifdef CONFIG_SOFTMMU
241 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
242 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
243#endif
244 break;
245 case 'S':
246 ct->ct |= TCG_CT_REG;
247 ct->u.regs = 0xffffffff;
248 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
249#ifdef CONFIG_SOFTMMU
250 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
251 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
252 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
253#endif
254 break;
255 case 'I':
256 ct->ct |= TCG_CT_CONST_S16;
257 break;
258 case 'J':
259 ct->ct |= TCG_CT_CONST_U16;
260 break;
261 case 'M':
262 ct->ct |= TCG_CT_CONST_MONE;
263 break;
264 case 'T':
265 ct->ct |= TCG_CT_CONST_S32;
266 break;
267 case 'U':
268 ct->ct |= TCG_CT_CONST_U32;
269 break;
270 case 'W':
271 ct->ct |= TCG_CT_CONST_WSZ;
272 break;
273 case 'Z':
274 ct->ct |= TCG_CT_CONST_ZERO;
275 break;
276 default:
277 return NULL;
278 }
279 return ct_str;
280}
281
282
283static int tcg_target_const_match(tcg_target_long val, TCGType type,
284 const TCGArgConstraint *arg_ct)
285{
286 int ct = arg_ct->ct;
287 if (ct & TCG_CT_CONST) {
288 return 1;
289 }
290
291
292
293 if (type == TCG_TYPE_I32) {
294 val = (int32_t)val;
295 }
296
297 if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
298 return 1;
299 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
300 return 1;
301 } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
302 return 1;
303 } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
304 return 1;
305 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
306 return 1;
307 } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
308 return 1;
309 } else if ((ct & TCG_CT_CONST_WSZ)
310 && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
311 return 1;
312 }
313 return 0;
314}
315
316#define OPCD(opc) ((opc)<<26)
317#define XO19(opc) (OPCD(19)|((opc)<<1))
318#define MD30(opc) (OPCD(30)|((opc)<<2))
319#define MDS30(opc) (OPCD(30)|((opc)<<1))
320#define XO31(opc) (OPCD(31)|((opc)<<1))
321#define XO58(opc) (OPCD(58)|(opc))
322#define XO62(opc) (OPCD(62)|(opc))
323
324#define B OPCD( 18)
325#define BC OPCD( 16)
326#define LBZ OPCD( 34)
327#define LHZ OPCD( 40)
328#define LHA OPCD( 42)
329#define LWZ OPCD( 32)
330#define LWZUX XO31( 55)
331#define STB OPCD( 38)
332#define STH OPCD( 44)
333#define STW OPCD( 36)
334
335#define STD XO62( 0)
336#define STDU XO62( 1)
337#define STDX XO31(149)
338
339#define LD XO58( 0)
340#define LDX XO31( 21)
341#define LDU XO58( 1)
342#define LDUX XO31( 53)
343#define LWA XO58( 2)
344#define LWAX XO31(341)
345
346#define ADDIC OPCD( 12)
347#define ADDI OPCD( 14)
348#define ADDIS OPCD( 15)
349#define ORI OPCD( 24)
350#define ORIS OPCD( 25)
351#define XORI OPCD( 26)
352#define XORIS OPCD( 27)
353#define ANDI OPCD( 28)
354#define ANDIS OPCD( 29)
355#define MULLI OPCD( 7)
356#define CMPLI OPCD( 10)
357#define CMPI OPCD( 11)
358#define SUBFIC OPCD( 8)
359
360#define LWZU OPCD( 33)
361#define STWU OPCD( 37)
362
363#define RLWIMI OPCD( 20)
364#define RLWINM OPCD( 21)
365#define RLWNM OPCD( 23)
366
367#define RLDICL MD30( 0)
368#define RLDICR MD30( 1)
369#define RLDIMI MD30( 3)
370#define RLDCL MDS30( 8)
371
372#define BCLR XO19( 16)
373#define BCCTR XO19(528)
374#define CRAND XO19(257)
375#define CRANDC XO19(129)
376#define CRNAND XO19(225)
377#define CROR XO19(449)
378#define CRNOR XO19( 33)
379
380#define EXTSB XO31(954)
381#define EXTSH XO31(922)
382#define EXTSW XO31(986)
383#define ADD XO31(266)
384#define ADDE XO31(138)
385#define ADDME XO31(234)
386#define ADDZE XO31(202)
387#define ADDC XO31( 10)
388#define AND XO31( 28)
389#define SUBF XO31( 40)
390#define SUBFC XO31( 8)
391#define SUBFE XO31(136)
392#define SUBFME XO31(232)
393#define SUBFZE XO31(200)
394#define OR XO31(444)
395#define XOR XO31(316)
396#define MULLW XO31(235)
397#define MULHW XO31( 75)
398#define MULHWU XO31( 11)
399#define DIVW XO31(491)
400#define DIVWU XO31(459)
401#define CMP XO31( 0)
402#define CMPL XO31( 32)
403#define LHBRX XO31(790)
404#define LWBRX XO31(534)
405#define LDBRX XO31(532)
406#define STHBRX XO31(918)
407#define STWBRX XO31(662)
408#define STDBRX XO31(660)
409#define MFSPR XO31(339)
410#define MTSPR XO31(467)
411#define SRAWI XO31(824)
412#define NEG XO31(104)
413#define MFCR XO31( 19)
414#define MFOCRF (MFCR | (1u << 20))
415#define NOR XO31(124)
416#define CNTLZW XO31( 26)
417#define CNTLZD XO31( 58)
418#define CNTTZW XO31(538)
419#define CNTTZD XO31(570)
420#define CNTPOPW XO31(378)
421#define CNTPOPD XO31(506)
422#define ANDC XO31( 60)
423#define ORC XO31(412)
424#define EQV XO31(284)
425#define NAND XO31(476)
426#define ISEL XO31( 15)
427
428#define MULLD XO31(233)
429#define MULHD XO31( 73)
430#define MULHDU XO31( 9)
431#define DIVD XO31(489)
432#define DIVDU XO31(457)
433
434#define LBZX XO31( 87)
435#define LHZX XO31(279)
436#define LHAX XO31(343)
437#define LWZX XO31( 23)
438#define STBX XO31(215)
439#define STHX XO31(407)
440#define STWX XO31(151)
441
442#define EIEIO XO31(854)
443#define HWSYNC XO31(598)
444#define LWSYNC (HWSYNC | (1u << 21))
445
446#define SPR(a, b) ((((a)<<5)|(b))<<11)
447#define LR SPR(8, 0)
448#define CTR SPR(9, 0)
449
450#define SLW XO31( 24)
451#define SRW XO31(536)
452#define SRAW XO31(792)
453
454#define SLD XO31( 27)
455#define SRD XO31(539)
456#define SRAD XO31(794)
457#define SRADI XO31(413<<1)
458
459#define TW XO31( 4)
460#define TRAP (TW | TO(31))
461
462#define NOP ORI
463
464#define RT(r) ((r)<<21)
465#define RS(r) ((r)<<21)
466#define RA(r) ((r)<<16)
467#define RB(r) ((r)<<11)
468#define TO(t) ((t)<<21)
469#define SH(s) ((s)<<11)
470#define MB(b) ((b)<<6)
471#define ME(e) ((e)<<1)
472#define BO(o) ((o)<<21)
473#define MB64(b) ((b)<<5)
474#define FXM(b) (1 << (19 - (b)))
475
476#define LK 1
477
478#define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
479#define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
480#define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
481#define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
482
483#define BF(n) ((n)<<23)
484#define BI(n, c) (((c)+((n)*4))<<16)
485#define BT(n, c) (((c)+((n)*4))<<21)
486#define BA(n, c) (((c)+((n)*4))<<16)
487#define BB(n, c) (((c)+((n)*4))<<11)
488#define BC_(n, c) (((c)+((n)*4))<<6)
489
490#define BO_COND_TRUE BO(12)
491#define BO_COND_FALSE BO( 4)
492#define BO_ALWAYS BO(20)
493
494enum {
495 CR_LT,
496 CR_GT,
497 CR_EQ,
498 CR_SO
499};
500
501static const uint32_t tcg_to_bc[] = {
502 [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE,
503 [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE,
504 [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE,
505 [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE,
506 [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE,
507 [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE,
508 [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
509 [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
510 [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
511 [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
512};
513
514
515static const uint32_t tcg_to_isel[] = {
516 [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ),
517 [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1,
518 [TCG_COND_LT] = ISEL | BC_(7, CR_LT),
519 [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1,
520 [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1,
521 [TCG_COND_GT] = ISEL | BC_(7, CR_GT),
522 [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
523 [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
524 [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
525 [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
526};
527
528static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
529 intptr_t value, intptr_t addend)
530{
531 tcg_insn_unit *target;
532
533 value += addend;
534 target = (tcg_insn_unit *)value;
535
536 switch (type) {
537 case R_PPC_REL14:
538 return reloc_pc14(code_ptr, target);
539 case R_PPC_REL24:
540 return reloc_pc24(code_ptr, target);
541 case R_PPC_ADDR16:
542
543
544
545
546
547
548 if ((value & 3) || value != (int16_t)value) {
549 return false;
550 }
551 *code_ptr = (*code_ptr & ~0xfffc) | (value & 0xfffc);
552 break;
553 default:
554 g_assert_not_reached();
555 }
556 return true;
557}
558
559static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
560 TCGReg base, tcg_target_long offset);
561
562static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
563{
564 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
565 if (ret != arg) {
566 tcg_out32(s, OR | SAB(arg, ret, arg));
567 }
568 return true;
569}
570
571static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
572 int sh, int mb)
573{
574 tcg_debug_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);
578}
579
580static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
581 int sh, int mb, int me)
582{
583 tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
584}
585
586static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
587{
588 tcg_out_rld(s, RLDICL, dst, src, 0, 32);
589}
590
591static inline void tcg_out_shli32(TCGContext *s, TCGReg dst, TCGReg src, int c)
592{
593 tcg_out_rlw(s, RLWINM, dst, src, c, 0, 31 - c);
594}
595
596static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
597{
598 tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
599}
600
601static inline void tcg_out_shri32(TCGContext *s, TCGReg dst, TCGReg src, int c)
602{
603 tcg_out_rlw(s, RLWINM, dst, src, 32 - c, c, 31);
604}
605
606static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
607{
608 tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
609}
610
611
612static bool tcg_out_movi_one(TCGContext *s, TCGReg ret, tcg_target_long arg)
613{
614 if (arg == (int16_t)arg) {
615 tcg_out32(s, ADDI | TAI(ret, 0, arg));
616 return true;
617 }
618 if (arg == (int32_t)arg && (arg & 0xffff) == 0) {
619 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
620 return true;
621 }
622 return false;
623}
624
625static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
626 tcg_target_long arg, bool in_prologue)
627{
628 intptr_t tb_diff;
629 tcg_target_long tmp;
630 int shift;
631
632 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
633
634 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
635 arg = (int32_t)arg;
636 }
637
638
639 if (tcg_out_movi_one(s, ret, arg)) {
640 return;
641 }
642
643
644 tb_diff = arg - (intptr_t)s->code_gen_ptr;
645 if (!in_prologue && USE_REG_TB && tb_diff == (int16_t)tb_diff) {
646 tcg_out32(s, ADDI | TAI(ret, TCG_REG_TB, tb_diff));
647 return;
648 }
649
650
651
652 if (TCG_TARGET_REG_BITS == 32 || arg == (int32_t)arg) {
653 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
654 tcg_out32(s, ORI | SAI(ret, ret, arg));
655 return;
656 }
657 if (arg == (uint32_t)arg && !(arg & 0x8000)) {
658 tcg_out32(s, ADDI | TAI(ret, 0, arg));
659 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
660 return;
661 }
662
663
664 if (arg > 0 && (arg & 0x8000)) {
665 tmp = arg | 0x7fff;
666 if ((tmp & (tmp + 1)) == 0) {
667 int mb = clz64(tmp + 1) + 1;
668 tcg_out32(s, ADDI | TAI(ret, 0, arg));
669 tcg_out_rld(s, RLDICL, ret, ret, 0, mb);
670 return;
671 }
672 }
673
674
675 shift = ctz64(arg);
676 tmp = arg >> shift;
677 if (tmp == (int16_t)tmp) {
678 tcg_out32(s, ADDI | TAI(ret, 0, tmp));
679 tcg_out_shli64(s, ret, ret, shift);
680 return;
681 }
682 shift = clz64(arg);
683 if (tcg_out_movi_one(s, ret, arg << shift)) {
684 tcg_out_shri64(s, ret, ret, shift);
685 return;
686 }
687
688
689 if (!in_prologue && USE_REG_TB && tb_diff == (int32_t)tb_diff) {
690 tcg_out_mem_long(s, ADDI, ADD, ret, TCG_REG_TB, tb_diff);
691 return;
692 }
693
694
695 if (!in_prologue && USE_REG_TB) {
696 new_pool_label(s, arg, R_PPC_ADDR16, s->code_ptr,
697 -(intptr_t)s->code_gen_ptr);
698 tcg_out32(s, LD | TAI(ret, TCG_REG_TB, 0));
699 return;
700 }
701
702 tmp = arg >> 31 >> 1;
703 tcg_out_movi(s, TCG_TYPE_I32, ret, tmp);
704 if (tmp) {
705 tcg_out_shli64(s, ret, ret, 32);
706 }
707 if (arg & 0xffff0000) {
708 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
709 }
710 if (arg & 0xffff) {
711 tcg_out32(s, ORI | SAI(ret, ret, arg));
712 }
713}
714
715static inline void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
716 tcg_target_long arg)
717{
718 tcg_out_movi_int(s, type, ret, arg, false);
719}
720
721static bool mask_operand(uint32_t c, int *mb, int *me)
722{
723 uint32_t lsb, test;
724
725
726
727
728
729
730 if (c == 0 || c == -1) {
731 return false;
732 }
733 test = c;
734 lsb = test & -test;
735 test += lsb;
736 if (test & (test - 1)) {
737 return false;
738 }
739
740 *me = clz32(lsb);
741 *mb = test ? clz32(test & -test) + 1 : 0;
742 return true;
743}
744
745static bool mask64_operand(uint64_t c, int *mb, int *me)
746{
747 uint64_t lsb;
748
749 if (c == 0) {
750 return false;
751 }
752
753 lsb = c & -c;
754
755 if (c == -lsb) {
756 *mb = 0;
757 *me = clz64(lsb);
758 return true;
759 }
760
761 if (lsb == 1 && (c & (c + 1)) == 0) {
762 *mb = clz64(c + 1) + 1;
763 *me = 63;
764 return true;
765 }
766 return false;
767}
768
769static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
770{
771 int mb, me;
772
773 if (mask_operand(c, &mb, &me)) {
774 tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
775 } else if ((c & 0xffff) == c) {
776 tcg_out32(s, ANDI | SAI(src, dst, c));
777 return;
778 } else if ((c & 0xffff0000) == c) {
779 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
780 return;
781 } else {
782 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
783 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
784 }
785}
786
787static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
788{
789 int mb, me;
790
791 tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
792 if (mask64_operand(c, &mb, &me)) {
793 if (mb == 0) {
794 tcg_out_rld(s, RLDICR, dst, src, 0, me);
795 } else {
796 tcg_out_rld(s, RLDICL, dst, src, 0, mb);
797 }
798 } else if ((c & 0xffff) == c) {
799 tcg_out32(s, ANDI | SAI(src, dst, c));
800 return;
801 } else if ((c & 0xffff0000) == c) {
802 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
803 return;
804 } else {
805 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
806 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
807 }
808}
809
810static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
811 int op_lo, int op_hi)
812{
813 if (c >> 16) {
814 tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
815 src = dst;
816 }
817 if (c & 0xffff) {
818 tcg_out32(s, op_lo | SAI(src, dst, c));
819 src = dst;
820 }
821}
822
823static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
824{
825 tcg_out_zori32(s, dst, src, c, ORI, ORIS);
826}
827
828static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
829{
830 tcg_out_zori32(s, dst, src, c, XORI, XORIS);
831}
832
833static void tcg_out_b(TCGContext *s, int mask, tcg_insn_unit *target)
834{
835 ptrdiff_t disp = tcg_pcrel_diff(s, target);
836 if (in_range_b(disp)) {
837 tcg_out32(s, B | (disp & 0x3fffffc) | mask);
838 } else {
839 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R0, (uintptr_t)target);
840 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
841 tcg_out32(s, BCCTR | BO_ALWAYS | mask);
842 }
843}
844
845static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
846 TCGReg base, tcg_target_long offset)
847{
848 tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
849 bool is_store = false;
850 TCGReg rs = TCG_REG_TMP1;
851
852 switch (opi) {
853 case LD: case LWA:
854 align = 3;
855
856 default:
857 if (rt != TCG_REG_R0) {
858 rs = rt;
859 break;
860 }
861 break;
862 case STD:
863 align = 3;
864
865 case STB: case STH: case STW:
866 is_store = true;
867 break;
868 }
869
870
871 if (offset & align || offset != (int32_t)offset) {
872 if (rs == base) {
873 rs = TCG_REG_R0;
874 }
875 tcg_debug_assert(!is_store || rs != rt);
876 tcg_out_movi(s, TCG_TYPE_PTR, rs, orig);
877 tcg_out32(s, opx | TAB(rt, base, rs));
878 return;
879 }
880
881 l0 = (int16_t)offset;
882 offset = (offset - l0) >> 16;
883 l1 = (int16_t)offset;
884
885 if (l1 < 0 && orig >= 0) {
886 extra = 0x4000;
887 l1 = (int16_t)(offset - 0x4000);
888 }
889 if (l1) {
890 tcg_out32(s, ADDIS | TAI(rs, base, l1));
891 base = rs;
892 }
893 if (extra) {
894 tcg_out32(s, ADDIS | TAI(rs, base, extra));
895 base = rs;
896 }
897 if (opi != ADDI || base != rt || l0 != 0) {
898 tcg_out32(s, opi | TAI(rt, base, l0));
899 }
900}
901
902static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
903 TCGReg arg1, intptr_t arg2)
904{
905 int opi, opx;
906
907 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
908 if (type == TCG_TYPE_I32) {
909 opi = LWZ, opx = LWZX;
910 } else {
911 opi = LD, opx = LDX;
912 }
913 tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
914}
915
916static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
917 TCGReg arg1, intptr_t arg2)
918{
919 int opi, opx;
920
921 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
922 if (type == TCG_TYPE_I32) {
923 opi = STW, opx = STWX;
924 } else {
925 opi = STD, opx = STDX;
926 }
927 tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
928}
929
930static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
931 TCGReg base, intptr_t ofs)
932{
933 return false;
934}
935
936static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
937 int const_arg2, int cr, TCGType type)
938{
939 int imm;
940 uint32_t op;
941
942 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
943
944
945 if (type == TCG_TYPE_I32) {
946 arg2 = (int32_t)arg2;
947 }
948
949 switch (cond) {
950 case TCG_COND_EQ:
951 case TCG_COND_NE:
952 if (const_arg2) {
953 if ((int16_t) arg2 == arg2) {
954 op = CMPI;
955 imm = 1;
956 break;
957 } else if ((uint16_t) arg2 == arg2) {
958 op = CMPLI;
959 imm = 1;
960 break;
961 }
962 }
963 op = CMPL;
964 imm = 0;
965 break;
966
967 case TCG_COND_LT:
968 case TCG_COND_GE:
969 case TCG_COND_LE:
970 case TCG_COND_GT:
971 if (const_arg2) {
972 if ((int16_t) arg2 == arg2) {
973 op = CMPI;
974 imm = 1;
975 break;
976 }
977 }
978 op = CMP;
979 imm = 0;
980 break;
981
982 case TCG_COND_LTU:
983 case TCG_COND_GEU:
984 case TCG_COND_LEU:
985 case TCG_COND_GTU:
986 if (const_arg2) {
987 if ((uint16_t) arg2 == arg2) {
988 op = CMPLI;
989 imm = 1;
990 break;
991 }
992 }
993 op = CMPL;
994 imm = 0;
995 break;
996
997 default:
998 tcg_abort();
999 }
1000 op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
1001
1002 if (imm) {
1003 tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
1004 } else {
1005 if (const_arg2) {
1006 tcg_out_movi(s, type, TCG_REG_R0, arg2);
1007 arg2 = TCG_REG_R0;
1008 }
1009 tcg_out32(s, op | RA(arg1) | RB(arg2));
1010 }
1011}
1012
1013static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
1014 TCGReg dst, TCGReg src)
1015{
1016 if (type == TCG_TYPE_I32) {
1017 tcg_out32(s, CNTLZW | RS(src) | RA(dst));
1018 tcg_out_shri32(s, dst, dst, 5);
1019 } else {
1020 tcg_out32(s, CNTLZD | RS(src) | RA(dst));
1021 tcg_out_shri64(s, dst, dst, 6);
1022 }
1023}
1024
1025static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
1026{
1027
1028
1029 if (dst != src) {
1030 tcg_out32(s, ADDIC | TAI(dst, src, -1));
1031 tcg_out32(s, SUBFE | TAB(dst, dst, src));
1032 } else {
1033 tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
1034 tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
1035 }
1036}
1037
1038static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
1039 bool const_arg2)
1040{
1041 if (const_arg2) {
1042 if ((uint32_t)arg2 == arg2) {
1043 tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
1044 } else {
1045 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
1046 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
1047 }
1048 } else {
1049 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
1050 }
1051 return TCG_REG_R0;
1052}
1053
1054static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
1055 TCGArg arg0, TCGArg arg1, TCGArg arg2,
1056 int const_arg2)
1057{
1058 int crop, sh;
1059
1060 tcg_debug_assert(TCG_TARGET_REG_BITS == 64 || type == TCG_TYPE_I32);
1061
1062
1063 if (type == TCG_TYPE_I32) {
1064 arg2 = (uint32_t)arg2;
1065 }
1066
1067
1068 if (arg2 == 0) {
1069 switch (cond) {
1070 case TCG_COND_EQ:
1071 tcg_out_setcond_eq0(s, type, arg0, arg1);
1072 return;
1073 case TCG_COND_NE:
1074 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1075 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1076 arg1 = TCG_REG_R0;
1077 }
1078 tcg_out_setcond_ne0(s, arg0, arg1);
1079 return;
1080 case TCG_COND_GE:
1081 tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1082 arg1 = arg0;
1083
1084 case TCG_COND_LT:
1085
1086 if (type == TCG_TYPE_I32) {
1087 tcg_out_shri32(s, arg0, arg1, 31);
1088 } else {
1089 tcg_out_shri64(s, arg0, arg1, 63);
1090 }
1091 return;
1092 default:
1093 break;
1094 }
1095 }
1096
1097
1098
1099
1100 if (HAVE_ISEL) {
1101 int isel, tab;
1102
1103 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1104
1105 isel = tcg_to_isel[cond];
1106
1107 tcg_out_movi(s, type, arg0, 1);
1108 if (isel & 1) {
1109
1110 tab = TAB(arg0, 0, arg0);
1111 isel &= ~1;
1112 } else {
1113
1114 tcg_out_movi(s, type, TCG_REG_R0, 0);
1115 tab = TAB(arg0, arg0, TCG_REG_R0);
1116 }
1117 tcg_out32(s, isel | tab);
1118 return;
1119 }
1120
1121 switch (cond) {
1122 case TCG_COND_EQ:
1123 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1124 tcg_out_setcond_eq0(s, type, arg0, arg1);
1125 return;
1126
1127 case TCG_COND_NE:
1128 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1129
1130 if (TCG_TARGET_REG_BITS == 64 && type == TCG_TYPE_I32) {
1131 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1132 arg1 = TCG_REG_R0;
1133 }
1134 tcg_out_setcond_ne0(s, arg0, arg1);
1135 return;
1136
1137 case TCG_COND_GT:
1138 case TCG_COND_GTU:
1139 sh = 30;
1140 crop = 0;
1141 goto crtest;
1142
1143 case TCG_COND_LT:
1144 case TCG_COND_LTU:
1145 sh = 29;
1146 crop = 0;
1147 goto crtest;
1148
1149 case TCG_COND_GE:
1150 case TCG_COND_GEU:
1151 sh = 31;
1152 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1153 goto crtest;
1154
1155 case TCG_COND_LE:
1156 case TCG_COND_LEU:
1157 sh = 31;
1158 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1159 crtest:
1160 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1161 if (crop) {
1162 tcg_out32(s, crop);
1163 }
1164 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1165 tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1166 break;
1167
1168 default:
1169 tcg_abort();
1170 }
1171}
1172
1173static void tcg_out_bc(TCGContext *s, int bc, TCGLabel *l)
1174{
1175 if (l->has_value) {
1176 bc |= reloc_pc14_val(s->code_ptr, l->u.value_ptr);
1177 } else {
1178 tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, l, 0);
1179 }
1180 tcg_out32(s, bc);
1181}
1182
1183static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1184 TCGArg arg1, TCGArg arg2, int const_arg2,
1185 TCGLabel *l, TCGType type)
1186{
1187 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1188 tcg_out_bc(s, tcg_to_bc[cond], l);
1189}
1190
1191static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1192 TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1193 TCGArg v2, bool const_c2)
1194{
1195
1196 if (v1 == 0 && v2 == 0) {
1197 tcg_out_movi(s, type, dest, 0);
1198 return;
1199 }
1200
1201 tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1202
1203 if (HAVE_ISEL) {
1204 int isel = tcg_to_isel[cond];
1205
1206
1207 if (isel & 1) {
1208 int t = v1;
1209 v1 = v2;
1210 v2 = t;
1211 isel &= ~1;
1212 }
1213
1214 if (v2 == 0) {
1215 tcg_out_movi(s, type, TCG_REG_R0, 0);
1216 }
1217 tcg_out32(s, isel | TAB(dest, v1, v2));
1218 } else {
1219 if (dest == v2) {
1220 cond = tcg_invert_cond(cond);
1221 v2 = v1;
1222 } else if (dest != v1) {
1223 if (v1 == 0) {
1224 tcg_out_movi(s, type, dest, 0);
1225 } else {
1226 tcg_out_mov(s, type, dest, v1);
1227 }
1228 }
1229
1230 tcg_out32(s, tcg_to_bc[cond] | 8);
1231 if (v2 == 0) {
1232 tcg_out_movi(s, type, dest, 0);
1233 } else {
1234 tcg_out_mov(s, type, dest, v2);
1235 }
1236 }
1237}
1238
1239static void tcg_out_cntxz(TCGContext *s, TCGType type, uint32_t opc,
1240 TCGArg a0, TCGArg a1, TCGArg a2, bool const_a2)
1241{
1242 if (const_a2 && a2 == (type == TCG_TYPE_I32 ? 32 : 64)) {
1243 tcg_out32(s, opc | RA(a0) | RS(a1));
1244 } else {
1245 tcg_out_cmp(s, TCG_COND_EQ, a1, 0, 1, 7, type);
1246
1247 if (HAVE_ISEL) {
1248 tcg_out32(s, opc | RA(TCG_REG_R0) | RS(a1));
1249 tcg_out32(s, tcg_to_isel[TCG_COND_EQ] | TAB(a0, a2, TCG_REG_R0));
1250 } else if (!const_a2 && a0 == a2) {
1251 tcg_out32(s, tcg_to_bc[TCG_COND_EQ] | 8);
1252 tcg_out32(s, opc | RA(a0) | RS(a1));
1253 } else {
1254 tcg_out32(s, opc | RA(a0) | RS(a1));
1255 tcg_out32(s, tcg_to_bc[TCG_COND_NE] | 8);
1256 if (const_a2) {
1257 tcg_out_movi(s, type, a0, 0);
1258 } else {
1259 tcg_out_mov(s, type, a0, a2);
1260 }
1261 }
1262 }
1263}
1264
1265static void tcg_out_cmp2(TCGContext *s, const TCGArg *args,
1266 const int *const_args)
1267{
1268 static const struct { uint8_t bit1, bit2; } bits[] = {
1269 [TCG_COND_LT ] = { CR_LT, CR_LT },
1270 [TCG_COND_LE ] = { CR_LT, CR_GT },
1271 [TCG_COND_GT ] = { CR_GT, CR_GT },
1272 [TCG_COND_GE ] = { CR_GT, CR_LT },
1273 [TCG_COND_LTU] = { CR_LT, CR_LT },
1274 [TCG_COND_LEU] = { CR_LT, CR_GT },
1275 [TCG_COND_GTU] = { CR_GT, CR_GT },
1276 [TCG_COND_GEU] = { CR_GT, CR_LT },
1277 };
1278
1279 TCGCond cond = args[4], cond2;
1280 TCGArg al, ah, bl, bh;
1281 int blconst, bhconst;
1282 int op, bit1, bit2;
1283
1284 al = args[0];
1285 ah = args[1];
1286 bl = args[2];
1287 bh = args[3];
1288 blconst = const_args[2];
1289 bhconst = const_args[3];
1290
1291 switch (cond) {
1292 case TCG_COND_EQ:
1293 op = CRAND;
1294 goto do_equality;
1295 case TCG_COND_NE:
1296 op = CRNAND;
1297 do_equality:
1298 tcg_out_cmp(s, cond, al, bl, blconst, 6, TCG_TYPE_I32);
1299 tcg_out_cmp(s, cond, ah, bh, bhconst, 7, TCG_TYPE_I32);
1300 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1301 break;
1302
1303 case TCG_COND_LT:
1304 case TCG_COND_LE:
1305 case TCG_COND_GT:
1306 case TCG_COND_GE:
1307 case TCG_COND_LTU:
1308 case TCG_COND_LEU:
1309 case TCG_COND_GTU:
1310 case TCG_COND_GEU:
1311 bit1 = bits[cond].bit1;
1312 bit2 = bits[cond].bit2;
1313 op = (bit1 != bit2 ? CRANDC : CRAND);
1314 cond2 = tcg_unsigned_cond(cond);
1315
1316 tcg_out_cmp(s, cond, ah, bh, bhconst, 6, TCG_TYPE_I32);
1317 tcg_out_cmp(s, cond2, al, bl, blconst, 7, TCG_TYPE_I32);
1318 tcg_out32(s, op | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, bit2));
1319 tcg_out32(s, CROR | BT(7, CR_EQ) | BA(6, bit1) | BB(7, CR_EQ));
1320 break;
1321
1322 default:
1323 tcg_abort();
1324 }
1325}
1326
1327static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
1328 const int *const_args)
1329{
1330 tcg_out_cmp2(s, args + 1, const_args + 1);
1331 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1332 tcg_out_rlw(s, RLWINM, args[0], TCG_REG_R0, 31, 31, 31);
1333}
1334
1335static void tcg_out_brcond2 (TCGContext *s, const TCGArg *args,
1336 const int *const_args)
1337{
1338 tcg_out_cmp2(s, args, const_args);
1339 tcg_out_bc(s, BC | BI(7, CR_EQ) | BO_COND_TRUE, arg_label(args[5]));
1340}
1341
1342static void tcg_out_mb(TCGContext *s, TCGArg a0)
1343{
1344 uint32_t insn = HWSYNC;
1345 a0 &= TCG_MO_ALL;
1346 if (a0 == TCG_MO_LD_LD) {
1347 insn = LWSYNC;
1348 } else if (a0 == TCG_MO_ST_ST) {
1349 insn = EIEIO;
1350 }
1351 tcg_out32(s, insn);
1352}
1353
1354void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
1355 uintptr_t addr)
1356{
1357 if (TCG_TARGET_REG_BITS == 64) {
1358 tcg_insn_unit i1, i2;
1359 intptr_t tb_diff = addr - tc_ptr;
1360 intptr_t br_diff = addr - (jmp_addr + 4);
1361 uint64_t pair;
1362
1363
1364
1365
1366 if (tb_diff == (int16_t)tb_diff) {
1367 i1 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, tb_diff);
1368 i2 = B | (br_diff & 0x3fffffc);
1369 } else {
1370 intptr_t lo = (int16_t)tb_diff;
1371 intptr_t hi = (int32_t)(tb_diff - lo);
1372 assert(tb_diff == hi + lo);
1373 i1 = ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, hi >> 16);
1374 i2 = ADDI | TAI(TCG_REG_TB, TCG_REG_TB, lo);
1375 }
1376#ifdef HOST_WORDS_BIGENDIAN
1377 pair = (uint64_t)i1 << 32 | i2;
1378#else
1379 pair = (uint64_t)i2 << 32 | i1;
1380#endif
1381
1382
1383
1384 atomic_set__nocheck((uint64_t *)jmp_addr, pair);
1385 flush_icache_range(jmp_addr, jmp_addr + 8);
1386 } else {
1387 intptr_t diff = addr - jmp_addr;
1388 tcg_debug_assert(in_range_b(diff));
1389 atomic_set((uint32_t *)jmp_addr, B | (diff & 0x3fffffc));
1390 flush_icache_range(jmp_addr, jmp_addr + 4);
1391 }
1392}
1393
1394static void tcg_out_call(TCGContext *s, tcg_insn_unit *target)
1395{
1396#ifdef _CALL_AIX
1397
1398
1399 void *tgt = ((void **)target)[0];
1400 uintptr_t toc = ((uintptr_t *)target)[1];
1401 intptr_t diff = tcg_pcrel_diff(s, tgt);
1402
1403 if (in_range_b(diff) && toc == (uint32_t)toc) {
1404 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, toc);
1405 tcg_out_b(s, LK, tgt);
1406 } else {
1407
1408 intptr_t arg = (intptr_t)target;
1409 int ofs = (int16_t)arg;
1410
1411 if (ofs + 8 < 0x8000) {
1412 arg -= ofs;
1413 } else {
1414 ofs = 0;
1415 }
1416 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP1, arg);
1417 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_TMP1, ofs);
1418 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
1419 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R2, TCG_REG_TMP1, ofs + SZP);
1420 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1421 }
1422#elif defined(_CALL_ELF) && _CALL_ELF == 2
1423 intptr_t diff;
1424
1425
1426
1427
1428
1429
1430 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R12, (intptr_t)target);
1431
1432 diff = tcg_pcrel_diff(s, target);
1433 if (in_range_b(diff)) {
1434 tcg_out_b(s, LK, target);
1435 } else {
1436 tcg_out32(s, MTSPR | RS(TCG_REG_R12) | CTR);
1437 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
1438 }
1439#else
1440 tcg_out_b(s, LK, target);
1441#endif
1442}
1443
1444static const uint32_t qemu_ldx_opc[16] = {
1445 [MO_UB] = LBZX,
1446 [MO_UW] = LHZX,
1447 [MO_UL] = LWZX,
1448 [MO_Q] = LDX,
1449 [MO_SW] = LHAX,
1450 [MO_SL] = LWAX,
1451 [MO_BSWAP | MO_UB] = LBZX,
1452 [MO_BSWAP | MO_UW] = LHBRX,
1453 [MO_BSWAP | MO_UL] = LWBRX,
1454 [MO_BSWAP | MO_Q] = LDBRX,
1455};
1456
1457static const uint32_t qemu_stx_opc[16] = {
1458 [MO_UB] = STBX,
1459 [MO_UW] = STHX,
1460 [MO_UL] = STWX,
1461 [MO_Q] = STDX,
1462 [MO_BSWAP | MO_UB] = STBX,
1463 [MO_BSWAP | MO_UW] = STHBRX,
1464 [MO_BSWAP | MO_UL] = STWBRX,
1465 [MO_BSWAP | MO_Q] = STDBRX,
1466};
1467
1468static const uint32_t qemu_exts_opc[4] = {
1469 EXTSB, EXTSH, EXTSW, 0
1470};
1471
1472#if defined (CONFIG_SOFTMMU)
1473#include "tcg-ldst.inc.c"
1474
1475
1476
1477
1478static void * const qemu_ld_helpers[16] = {
1479 [MO_UB] = helper_ret_ldub_mmu,
1480 [MO_LEUW] = helper_le_lduw_mmu,
1481 [MO_LEUL] = helper_le_ldul_mmu,
1482 [MO_LEQ] = helper_le_ldq_mmu,
1483 [MO_BEUW] = helper_be_lduw_mmu,
1484 [MO_BEUL] = helper_be_ldul_mmu,
1485 [MO_BEQ] = helper_be_ldq_mmu,
1486};
1487
1488
1489
1490
1491static void * const qemu_st_helpers[16] = {
1492 [MO_UB] = helper_ret_stb_mmu,
1493 [MO_LEUW] = helper_le_stw_mmu,
1494 [MO_LEUL] = helper_le_stl_mmu,
1495 [MO_LEQ] = helper_le_stq_mmu,
1496 [MO_BEUW] = helper_be_stw_mmu,
1497 [MO_BEUL] = helper_be_stl_mmu,
1498 [MO_BEQ] = helper_be_stq_mmu,
1499};
1500
1501
1502QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
1503QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -32768);
1504
1505
1506
1507
1508
1509static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp opc,
1510 TCGReg addrlo, TCGReg addrhi,
1511 int mem_index, bool is_read)
1512{
1513 int cmp_off
1514 = (is_read
1515 ? offsetof(CPUTLBEntry, addr_read)
1516 : offsetof(CPUTLBEntry, addr_write));
1517 int fast_off = TLB_MASK_TABLE_OFS(mem_index);
1518 int mask_off = fast_off + offsetof(CPUTLBDescFast, mask);
1519 int table_off = fast_off + offsetof(CPUTLBDescFast, table);
1520 unsigned s_bits = opc & MO_SIZE;
1521 unsigned a_bits = get_alignment_bits(opc);
1522
1523
1524 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0, mask_off);
1525 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R4, TCG_AREG0, table_off);
1526
1527
1528 if (TCG_TARGET_REG_BITS == 32) {
1529 tcg_out_shri32(s, TCG_REG_TMP1, addrlo,
1530 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1531 } else {
1532 tcg_out_shri64(s, TCG_REG_TMP1, addrlo,
1533 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1534 }
1535 tcg_out32(s, AND | SAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_TMP1));
1536
1537
1538 if (cmp_off == 0 && TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) {
1539 uint32_t lxu = (TCG_TARGET_REG_BITS == 32 || TARGET_LONG_BITS == 32
1540 ? LWZUX : LDUX);
1541 tcg_out32(s, lxu | TAB(TCG_REG_TMP1, TCG_REG_R3, TCG_REG_R4));
1542 } else {
1543 tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, TCG_REG_R4));
1544 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1545 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_TMP1, TCG_REG_R3, cmp_off + 4);
1546 tcg_out_ld(s, TCG_TYPE_I32, TCG_REG_R4, TCG_REG_R3, cmp_off);
1547 } else {
1548 tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP1, TCG_REG_R3, cmp_off);
1549 }
1550 }
1551
1552
1553
1554 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_REG_R3,
1555 offsetof(CPUTLBEntry, addend));
1556
1557
1558 if (TCG_TARGET_REG_BITS == 32) {
1559
1560
1561
1562
1563 if (a_bits < s_bits) {
1564 a_bits = s_bits;
1565 }
1566 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addrlo, 0,
1567 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1568 } else {
1569 TCGReg t = addrlo;
1570
1571
1572
1573
1574
1575
1576
1577 if (a_bits < s_bits) {
1578 unsigned a_mask = (1 << a_bits) - 1;
1579 unsigned s_mask = (1 << s_bits) - 1;
1580 tcg_out32(s, ADDI | TAI(TCG_REG_R0, t, s_mask - a_mask));
1581 t = TCG_REG_R0;
1582 }
1583
1584
1585 if (TARGET_LONG_BITS == 32) {
1586 tcg_out_rlw(s, RLWINM, TCG_REG_R0, t, 0,
1587 (32 - a_bits) & 31, 31 - TARGET_PAGE_BITS);
1588
1589 tcg_out_ext32u(s, TCG_REG_R4, addrlo);
1590 addrlo = TCG_REG_R4;
1591 } else if (a_bits == 0) {
1592 tcg_out_rld(s, RLDICR, TCG_REG_R0, t, 0, 63 - TARGET_PAGE_BITS);
1593 } else {
1594 tcg_out_rld(s, RLDICL, TCG_REG_R0, t,
1595 64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - a_bits);
1596 tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
1597 }
1598 }
1599
1600 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1601 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1602 0, 7, TCG_TYPE_I32);
1603 tcg_out_cmp(s, TCG_COND_EQ, addrhi, TCG_REG_R4, 0, 6, TCG_TYPE_I32);
1604 tcg_out32(s, CRAND | BT(7, CR_EQ) | BA(6, CR_EQ) | BB(7, CR_EQ));
1605 } else {
1606 tcg_out_cmp(s, TCG_COND_EQ, TCG_REG_R0, TCG_REG_TMP1,
1607 0, 7, TCG_TYPE_TL);
1608 }
1609
1610 return addrlo;
1611}
1612
1613
1614
1615
1616static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOpIdx oi,
1617 TCGReg datalo_reg, TCGReg datahi_reg,
1618 TCGReg addrlo_reg, TCGReg addrhi_reg,
1619 tcg_insn_unit *raddr, tcg_insn_unit *lptr)
1620{
1621 TCGLabelQemuLdst *label = new_ldst_label(s);
1622
1623 label->is_ld = is_ld;
1624 label->oi = oi;
1625 label->datalo_reg = datalo_reg;
1626 label->datahi_reg = datahi_reg;
1627 label->addrlo_reg = addrlo_reg;
1628 label->addrhi_reg = addrhi_reg;
1629 label->raddr = raddr;
1630 label->label_ptr[0] = lptr;
1631}
1632
1633static bool tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1634{
1635 TCGMemOpIdx oi = lb->oi;
1636 TCGMemOp opc = get_memop(oi);
1637 TCGReg hi, lo, arg = TCG_REG_R3;
1638
1639 if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
1640 return false;
1641 }
1642
1643 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1644
1645 lo = lb->addrlo_reg;
1646 hi = lb->addrhi_reg;
1647 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1648#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1649 arg |= 1;
1650#endif
1651 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1652 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1653 } else {
1654
1655
1656 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1657 }
1658
1659 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1660 tcg_out32(s, MFSPR | RT(arg) | LR);
1661
1662 tcg_out_call(s, qemu_ld_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1663
1664 lo = lb->datalo_reg;
1665 hi = lb->datahi_reg;
1666 if (TCG_TARGET_REG_BITS == 32 && (opc & MO_SIZE) == MO_64) {
1667 tcg_out_mov(s, TCG_TYPE_I32, lo, TCG_REG_R4);
1668 tcg_out_mov(s, TCG_TYPE_I32, hi, TCG_REG_R3);
1669 } else if (opc & MO_SIGN) {
1670 uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
1671 tcg_out32(s, insn | RA(lo) | RS(TCG_REG_R3));
1672 } else {
1673 tcg_out_mov(s, TCG_TYPE_REG, lo, TCG_REG_R3);
1674 }
1675
1676 tcg_out_b(s, 0, lb->raddr);
1677 return true;
1678}
1679
1680static bool tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
1681{
1682 TCGMemOpIdx oi = lb->oi;
1683 TCGMemOp opc = get_memop(oi);
1684 TCGMemOp s_bits = opc & MO_SIZE;
1685 TCGReg hi, lo, arg = TCG_REG_R3;
1686
1687 if (!reloc_pc14(lb->label_ptr[0], s->code_ptr)) {
1688 return false;
1689 }
1690
1691 tcg_out_mov(s, TCG_TYPE_PTR, arg++, TCG_AREG0);
1692
1693 lo = lb->addrlo_reg;
1694 hi = lb->addrhi_reg;
1695 if (TCG_TARGET_REG_BITS < TARGET_LONG_BITS) {
1696#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1697 arg |= 1;
1698#endif
1699 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1700 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1701 } else {
1702
1703
1704 tcg_out_mov(s, TCG_TYPE_TL, arg++, lo);
1705 }
1706
1707 lo = lb->datalo_reg;
1708 hi = lb->datahi_reg;
1709 if (TCG_TARGET_REG_BITS == 32) {
1710 switch (s_bits) {
1711 case MO_64:
1712#ifdef TCG_TARGET_CALL_ALIGN_ARGS
1713 arg |= 1;
1714#endif
1715 tcg_out_mov(s, TCG_TYPE_I32, arg++, hi);
1716
1717 case MO_32:
1718 tcg_out_mov(s, TCG_TYPE_I32, arg++, lo);
1719 break;
1720 default:
1721 tcg_out_rlw(s, RLWINM, arg++, lo, 0, 32 - (8 << s_bits), 31);
1722 break;
1723 }
1724 } else {
1725 if (s_bits == MO_64) {
1726 tcg_out_mov(s, TCG_TYPE_I64, arg++, lo);
1727 } else {
1728 tcg_out_rld(s, RLDICL, arg++, lo, 0, 64 - (8 << s_bits));
1729 }
1730 }
1731
1732 tcg_out_movi(s, TCG_TYPE_I32, arg++, oi);
1733 tcg_out32(s, MFSPR | RT(arg) | LR);
1734
1735 tcg_out_call(s, qemu_st_helpers[opc & (MO_BSWAP | MO_SIZE)]);
1736
1737 tcg_out_b(s, 0, lb->raddr);
1738 return true;
1739}
1740#endif
1741
1742static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
1743{
1744 TCGReg datalo, datahi, addrlo, rbase;
1745 TCGReg addrhi __attribute__((unused));
1746 TCGMemOpIdx oi;
1747 TCGMemOp opc, s_bits;
1748#ifdef CONFIG_SOFTMMU
1749 int mem_index;
1750 tcg_insn_unit *label_ptr;
1751#endif
1752
1753 datalo = *args++;
1754 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1755 addrlo = *args++;
1756 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1757 oi = *args++;
1758 opc = get_memop(oi);
1759 s_bits = opc & MO_SIZE;
1760
1761#ifdef CONFIG_SOFTMMU
1762 mem_index = get_mmuidx(oi);
1763 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, true);
1764
1765
1766 label_ptr = s->code_ptr;
1767 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1768
1769 rbase = TCG_REG_R3;
1770#else
1771 rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1772 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1773 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1774 addrlo = TCG_REG_TMP1;
1775 }
1776#endif
1777
1778 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1779 if (opc & MO_BSWAP) {
1780 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1781 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1782 tcg_out32(s, LWBRX | TAB(datahi, rbase, TCG_REG_R0));
1783 } else if (rbase != 0) {
1784 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1785 tcg_out32(s, LWZX | TAB(datahi, rbase, addrlo));
1786 tcg_out32(s, LWZX | TAB(datalo, rbase, TCG_REG_R0));
1787 } else if (addrlo == datahi) {
1788 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1789 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1790 } else {
1791 tcg_out32(s, LWZ | TAI(datahi, addrlo, 0));
1792 tcg_out32(s, LWZ | TAI(datalo, addrlo, 4));
1793 }
1794 } else {
1795 uint32_t insn = qemu_ldx_opc[opc & (MO_BSWAP | MO_SSIZE)];
1796 if (!HAVE_ISA_2_06 && insn == LDBRX) {
1797 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1798 tcg_out32(s, LWBRX | TAB(datalo, rbase, addrlo));
1799 tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1800 tcg_out_rld(s, RLDIMI, datalo, TCG_REG_R0, 32, 0);
1801 } else if (insn) {
1802 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1803 } else {
1804 insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1805 tcg_out32(s, insn | TAB(datalo, rbase, addrlo));
1806 insn = qemu_exts_opc[s_bits];
1807 tcg_out32(s, insn | RA(datalo) | RS(datalo));
1808 }
1809 }
1810
1811#ifdef CONFIG_SOFTMMU
1812 add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
1813 s->code_ptr, label_ptr);
1814#endif
1815}
1816
1817static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
1818{
1819 TCGReg datalo, datahi, addrlo, rbase;
1820 TCGReg addrhi __attribute__((unused));
1821 TCGMemOpIdx oi;
1822 TCGMemOp opc, s_bits;
1823#ifdef CONFIG_SOFTMMU
1824 int mem_index;
1825 tcg_insn_unit *label_ptr;
1826#endif
1827
1828 datalo = *args++;
1829 datahi = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
1830 addrlo = *args++;
1831 addrhi = (TCG_TARGET_REG_BITS < TARGET_LONG_BITS ? *args++ : 0);
1832 oi = *args++;
1833 opc = get_memop(oi);
1834 s_bits = opc & MO_SIZE;
1835
1836#ifdef CONFIG_SOFTMMU
1837 mem_index = get_mmuidx(oi);
1838 addrlo = tcg_out_tlb_read(s, opc, addrlo, addrhi, mem_index, false);
1839
1840
1841 label_ptr = s->code_ptr;
1842 tcg_out32(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1843
1844 rbase = TCG_REG_R3;
1845#else
1846 rbase = guest_base ? TCG_GUEST_BASE_REG : 0;
1847 if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
1848 tcg_out_ext32u(s, TCG_REG_TMP1, addrlo);
1849 addrlo = TCG_REG_TMP1;
1850 }
1851#endif
1852
1853 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1854 if (opc & MO_BSWAP) {
1855 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1856 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1857 tcg_out32(s, STWBRX | SAB(datahi, rbase, TCG_REG_R0));
1858 } else if (rbase != 0) {
1859 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addrlo, 4));
1860 tcg_out32(s, STWX | SAB(datahi, rbase, addrlo));
1861 tcg_out32(s, STWX | SAB(datalo, rbase, TCG_REG_R0));
1862 } else {
1863 tcg_out32(s, STW | TAI(datahi, addrlo, 0));
1864 tcg_out32(s, STW | TAI(datalo, addrlo, 4));
1865 }
1866 } else {
1867 uint32_t insn = qemu_stx_opc[opc & (MO_BSWAP | MO_SIZE)];
1868 if (!HAVE_ISA_2_06 && insn == STDBRX) {
1869 tcg_out32(s, STWBRX | SAB(datalo, rbase, addrlo));
1870 tcg_out32(s, ADDI | TAI(TCG_REG_TMP1, addrlo, 4));
1871 tcg_out_shri64(s, TCG_REG_R0, datalo, 32);
1872 tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_TMP1));
1873 } else {
1874 tcg_out32(s, insn | SAB(datalo, rbase, addrlo));
1875 }
1876 }
1877
1878#ifdef CONFIG_SOFTMMU
1879 add_qemu_ldst_label(s, false, oi, datalo, datahi, addrlo, addrhi,
1880 s->code_ptr, label_ptr);
1881#endif
1882}
1883
1884static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1885{
1886 int i;
1887 for (i = 0; i < count; ++i) {
1888 p[i] = NOP;
1889 }
1890}
1891
1892
1893#define TCG_TARGET_STACK_ALIGN 16
1894#define TCG_TARGET_EXTEND_ARGS 1
1895
1896#ifdef _CALL_AIX
1897# define LINK_AREA_SIZE (6 * SZR)
1898# define LR_OFFSET (1 * SZR)
1899# define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR)
1900#elif defined(TCG_TARGET_CALL_DARWIN)
1901# define LINK_AREA_SIZE (6 * SZR)
1902# define LR_OFFSET (2 * SZR)
1903#elif TCG_TARGET_REG_BITS == 64
1904# if defined(_CALL_ELF) && _CALL_ELF == 2
1905# define LINK_AREA_SIZE (4 * SZR)
1906# define LR_OFFSET (1 * SZR)
1907# endif
1908#else
1909# if defined(_CALL_SYSV)
1910# define LINK_AREA_SIZE (2 * SZR)
1911# define LR_OFFSET (1 * SZR)
1912# endif
1913#endif
1914#ifndef LR_OFFSET
1915# error "Unhandled abi"
1916#endif
1917#ifndef TCG_TARGET_CALL_STACK_OFFSET
1918# define TCG_TARGET_CALL_STACK_OFFSET LINK_AREA_SIZE
1919#endif
1920
1921#define CPU_TEMP_BUF_SIZE (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
1922#define REG_SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * SZR)
1923
1924#define FRAME_SIZE ((TCG_TARGET_CALL_STACK_OFFSET \
1925 + TCG_STATIC_CALL_ARGS_SIZE \
1926 + CPU_TEMP_BUF_SIZE \
1927 + REG_SAVE_SIZE \
1928 + TCG_TARGET_STACK_ALIGN - 1) \
1929 & -TCG_TARGET_STACK_ALIGN)
1930
1931#define REG_SAVE_BOT (FRAME_SIZE - REG_SAVE_SIZE)
1932
1933static void tcg_target_qemu_prologue(TCGContext *s)
1934{
1935 int i;
1936
1937#ifdef _CALL_AIX
1938 void **desc = (void **)s->code_ptr;
1939 desc[0] = desc + 2;
1940 desc[1] = 0;
1941 s->code_ptr = (void *)(desc + 2);
1942#endif
1943
1944 tcg_set_frame(s, TCG_REG_CALL_STACK, REG_SAVE_BOT - CPU_TEMP_BUF_SIZE,
1945 CPU_TEMP_BUF_SIZE);
1946
1947
1948 tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1949 tcg_out32(s, (SZR == 8 ? STDU : STWU)
1950 | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1951
1952 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1953 tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1954 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1955 }
1956 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1957
1958#ifndef CONFIG_SOFTMMU
1959 if (guest_base) {
1960 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
1961 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1962 }
1963#endif
1964
1965 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1966 tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1967 if (USE_REG_TB) {
1968 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]);
1969 }
1970 tcg_out32(s, BCCTR | BO_ALWAYS);
1971
1972
1973 s->code_gen_epilogue = tb_ret_addr = s->code_ptr;
1974
1975 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R0, TCG_REG_R1, FRAME_SIZE+LR_OFFSET);
1976 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1977 tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
1978 TCG_REG_R1, REG_SAVE_BOT + i * SZR);
1979 }
1980 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1981 tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1982 tcg_out32(s, BCLR | BO_ALWAYS);
1983}
1984
1985static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1986 const int *const_args)
1987{
1988 TCGArg a0, a1, a2;
1989 int c;
1990
1991 switch (opc) {
1992 case INDEX_op_exit_tb:
1993 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R3, args[0]);
1994 tcg_out_b(s, 0, tb_ret_addr);
1995 break;
1996 case INDEX_op_goto_tb:
1997 if (s->tb_jmp_insn_offset) {
1998
1999 if (TCG_TARGET_REG_BITS == 64) {
2000
2001 if ((uintptr_t)s->code_ptr & 7) {
2002 tcg_out32(s, NOP);
2003 }
2004 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2005 tcg_out32(s, ADDIS | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2006 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, 0));
2007 } else {
2008 s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
2009 tcg_out32(s, B);
2010 s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
2011 break;
2012 }
2013 } else {
2014
2015 tcg_debug_assert(s->tb_jmp_insn_offset == NULL);
2016 tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TB, 0,
2017 (intptr_t)(s->tb_jmp_insn_offset + args[0]));
2018 }
2019 tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
2020 tcg_out32(s, BCCTR | BO_ALWAYS);
2021 set_jmp_reset_offset(s, args[0]);
2022 if (USE_REG_TB) {
2023
2024 c = -tcg_current_code_size(s);
2025 assert(c == (int16_t)c);
2026 tcg_out32(s, ADDI | TAI(TCG_REG_TB, TCG_REG_TB, c));
2027 }
2028 break;
2029 case INDEX_op_goto_ptr:
2030 tcg_out32(s, MTSPR | RS(args[0]) | CTR);
2031 if (USE_REG_TB) {
2032 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, args[0]);
2033 }
2034 tcg_out32(s, ADDI | TAI(TCG_REG_R3, 0, 0));
2035 tcg_out32(s, BCCTR | BO_ALWAYS);
2036 break;
2037 case INDEX_op_br:
2038 {
2039 TCGLabel *l = arg_label(args[0]);
2040 uint32_t insn = B;
2041
2042 if (l->has_value) {
2043 insn |= reloc_pc24_val(s->code_ptr, l->u.value_ptr);
2044 } else {
2045 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, l, 0);
2046 }
2047 tcg_out32(s, insn);
2048 }
2049 break;
2050 case INDEX_op_ld8u_i32:
2051 case INDEX_op_ld8u_i64:
2052 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2053 break;
2054 case INDEX_op_ld8s_i32:
2055 case INDEX_op_ld8s_i64:
2056 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
2057 tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
2058 break;
2059 case INDEX_op_ld16u_i32:
2060 case INDEX_op_ld16u_i64:
2061 tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
2062 break;
2063 case INDEX_op_ld16s_i32:
2064 case INDEX_op_ld16s_i64:
2065 tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
2066 break;
2067 case INDEX_op_ld_i32:
2068 case INDEX_op_ld32u_i64:
2069 tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
2070 break;
2071 case INDEX_op_ld32s_i64:
2072 tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
2073 break;
2074 case INDEX_op_ld_i64:
2075 tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
2076 break;
2077 case INDEX_op_st8_i32:
2078 case INDEX_op_st8_i64:
2079 tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
2080 break;
2081 case INDEX_op_st16_i32:
2082 case INDEX_op_st16_i64:
2083 tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
2084 break;
2085 case INDEX_op_st_i32:
2086 case INDEX_op_st32_i64:
2087 tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
2088 break;
2089 case INDEX_op_st_i64:
2090 tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
2091 break;
2092
2093 case INDEX_op_add_i32:
2094 a0 = args[0], a1 = args[1], a2 = args[2];
2095 if (const_args[2]) {
2096 do_addi_32:
2097 tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
2098 } else {
2099 tcg_out32(s, ADD | TAB(a0, a1, a2));
2100 }
2101 break;
2102 case INDEX_op_sub_i32:
2103 a0 = args[0], a1 = args[1], a2 = args[2];
2104 if (const_args[1]) {
2105 if (const_args[2]) {
2106 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
2107 } else {
2108 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2109 }
2110 } else if (const_args[2]) {
2111 a2 = -a2;
2112 goto do_addi_32;
2113 } else {
2114 tcg_out32(s, SUBF | TAB(a0, a2, a1));
2115 }
2116 break;
2117
2118 case INDEX_op_and_i32:
2119 a0 = args[0], a1 = args[1], a2 = args[2];
2120 if (const_args[2]) {
2121 tcg_out_andi32(s, a0, a1, a2);
2122 } else {
2123 tcg_out32(s, AND | SAB(a1, a0, a2));
2124 }
2125 break;
2126 case INDEX_op_and_i64:
2127 a0 = args[0], a1 = args[1], a2 = args[2];
2128 if (const_args[2]) {
2129 tcg_out_andi64(s, a0, a1, a2);
2130 } else {
2131 tcg_out32(s, AND | SAB(a1, a0, a2));
2132 }
2133 break;
2134 case INDEX_op_or_i64:
2135 case INDEX_op_or_i32:
2136 a0 = args[0], a1 = args[1], a2 = args[2];
2137 if (const_args[2]) {
2138 tcg_out_ori32(s, a0, a1, a2);
2139 } else {
2140 tcg_out32(s, OR | SAB(a1, a0, a2));
2141 }
2142 break;
2143 case INDEX_op_xor_i64:
2144 case INDEX_op_xor_i32:
2145 a0 = args[0], a1 = args[1], a2 = args[2];
2146 if (const_args[2]) {
2147 tcg_out_xori32(s, a0, a1, a2);
2148 } else {
2149 tcg_out32(s, XOR | SAB(a1, a0, a2));
2150 }
2151 break;
2152 case INDEX_op_andc_i32:
2153 a0 = args[0], a1 = args[1], a2 = args[2];
2154 if (const_args[2]) {
2155 tcg_out_andi32(s, a0, a1, ~a2);
2156 } else {
2157 tcg_out32(s, ANDC | SAB(a1, a0, a2));
2158 }
2159 break;
2160 case INDEX_op_andc_i64:
2161 a0 = args[0], a1 = args[1], a2 = args[2];
2162 if (const_args[2]) {
2163 tcg_out_andi64(s, a0, a1, ~a2);
2164 } else {
2165 tcg_out32(s, ANDC | SAB(a1, a0, a2));
2166 }
2167 break;
2168 case INDEX_op_orc_i32:
2169 if (const_args[2]) {
2170 tcg_out_ori32(s, args[0], args[1], ~args[2]);
2171 break;
2172 }
2173
2174 case INDEX_op_orc_i64:
2175 tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
2176 break;
2177 case INDEX_op_eqv_i32:
2178 if (const_args[2]) {
2179 tcg_out_xori32(s, args[0], args[1], ~args[2]);
2180 break;
2181 }
2182
2183 case INDEX_op_eqv_i64:
2184 tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
2185 break;
2186 case INDEX_op_nand_i32:
2187 case INDEX_op_nand_i64:
2188 tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
2189 break;
2190 case INDEX_op_nor_i32:
2191 case INDEX_op_nor_i64:
2192 tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
2193 break;
2194
2195 case INDEX_op_clz_i32:
2196 tcg_out_cntxz(s, TCG_TYPE_I32, CNTLZW, args[0], args[1],
2197 args[2], const_args[2]);
2198 break;
2199 case INDEX_op_ctz_i32:
2200 tcg_out_cntxz(s, TCG_TYPE_I32, CNTTZW, args[0], args[1],
2201 args[2], const_args[2]);
2202 break;
2203 case INDEX_op_ctpop_i32:
2204 tcg_out32(s, CNTPOPW | SAB(args[1], args[0], 0));
2205 break;
2206
2207 case INDEX_op_clz_i64:
2208 tcg_out_cntxz(s, TCG_TYPE_I64, CNTLZD, args[0], args[1],
2209 args[2], const_args[2]);
2210 break;
2211 case INDEX_op_ctz_i64:
2212 tcg_out_cntxz(s, TCG_TYPE_I64, CNTTZD, args[0], args[1],
2213 args[2], const_args[2]);
2214 break;
2215 case INDEX_op_ctpop_i64:
2216 tcg_out32(s, CNTPOPD | SAB(args[1], args[0], 0));
2217 break;
2218
2219 case INDEX_op_mul_i32:
2220 a0 = args[0], a1 = args[1], a2 = args[2];
2221 if (const_args[2]) {
2222 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2223 } else {
2224 tcg_out32(s, MULLW | TAB(a0, a1, a2));
2225 }
2226 break;
2227
2228 case INDEX_op_div_i32:
2229 tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
2230 break;
2231
2232 case INDEX_op_divu_i32:
2233 tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
2234 break;
2235
2236 case INDEX_op_shl_i32:
2237 if (const_args[2]) {
2238 tcg_out_shli32(s, args[0], args[1], args[2]);
2239 } else {
2240 tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
2241 }
2242 break;
2243 case INDEX_op_shr_i32:
2244 if (const_args[2]) {
2245 tcg_out_shri32(s, args[0], args[1], args[2]);
2246 } else {
2247 tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
2248 }
2249 break;
2250 case INDEX_op_sar_i32:
2251 if (const_args[2]) {
2252 tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
2253 } else {
2254 tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
2255 }
2256 break;
2257 case INDEX_op_rotl_i32:
2258 if (const_args[2]) {
2259 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
2260 } else {
2261 tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
2262 | MB(0) | ME(31));
2263 }
2264 break;
2265 case INDEX_op_rotr_i32:
2266 if (const_args[2]) {
2267 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
2268 } else {
2269 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
2270 tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
2271 | MB(0) | ME(31));
2272 }
2273 break;
2274
2275 case INDEX_op_brcond_i32:
2276 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2277 arg_label(args[3]), TCG_TYPE_I32);
2278 break;
2279 case INDEX_op_brcond_i64:
2280 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
2281 arg_label(args[3]), TCG_TYPE_I64);
2282 break;
2283 case INDEX_op_brcond2_i32:
2284 tcg_out_brcond2(s, args, const_args);
2285 break;
2286
2287 case INDEX_op_neg_i32:
2288 case INDEX_op_neg_i64:
2289 tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
2290 break;
2291
2292 case INDEX_op_not_i32:
2293 case INDEX_op_not_i64:
2294 tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
2295 break;
2296
2297 case INDEX_op_add_i64:
2298 a0 = args[0], a1 = args[1], a2 = args[2];
2299 if (const_args[2]) {
2300 do_addi_64:
2301 tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
2302 } else {
2303 tcg_out32(s, ADD | TAB(a0, a1, a2));
2304 }
2305 break;
2306 case INDEX_op_sub_i64:
2307 a0 = args[0], a1 = args[1], a2 = args[2];
2308 if (const_args[1]) {
2309 if (const_args[2]) {
2310 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
2311 } else {
2312 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
2313 }
2314 } else if (const_args[2]) {
2315 a2 = -a2;
2316 goto do_addi_64;
2317 } else {
2318 tcg_out32(s, SUBF | TAB(a0, a2, a1));
2319 }
2320 break;
2321
2322 case INDEX_op_shl_i64:
2323 if (const_args[2]) {
2324 tcg_out_shli64(s, args[0], args[1], args[2]);
2325 } else {
2326 tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
2327 }
2328 break;
2329 case INDEX_op_shr_i64:
2330 if (const_args[2]) {
2331 tcg_out_shri64(s, args[0], args[1], args[2]);
2332 } else {
2333 tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
2334 }
2335 break;
2336 case INDEX_op_sar_i64:
2337 if (const_args[2]) {
2338 int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
2339 tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
2340 } else {
2341 tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
2342 }
2343 break;
2344 case INDEX_op_rotl_i64:
2345 if (const_args[2]) {
2346 tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
2347 } else {
2348 tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
2349 }
2350 break;
2351 case INDEX_op_rotr_i64:
2352 if (const_args[2]) {
2353 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
2354 } else {
2355 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
2356 tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
2357 }
2358 break;
2359
2360 case INDEX_op_mul_i64:
2361 a0 = args[0], a1 = args[1], a2 = args[2];
2362 if (const_args[2]) {
2363 tcg_out32(s, MULLI | TAI(a0, a1, a2));
2364 } else {
2365 tcg_out32(s, MULLD | TAB(a0, a1, a2));
2366 }
2367 break;
2368 case INDEX_op_div_i64:
2369 tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
2370 break;
2371 case INDEX_op_divu_i64:
2372 tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
2373 break;
2374
2375 case INDEX_op_qemu_ld_i32:
2376 tcg_out_qemu_ld(s, args, false);
2377 break;
2378 case INDEX_op_qemu_ld_i64:
2379 tcg_out_qemu_ld(s, args, true);
2380 break;
2381 case INDEX_op_qemu_st_i32:
2382 tcg_out_qemu_st(s, args, false);
2383 break;
2384 case INDEX_op_qemu_st_i64:
2385 tcg_out_qemu_st(s, args, true);
2386 break;
2387
2388 case INDEX_op_ext8s_i32:
2389 case INDEX_op_ext8s_i64:
2390 c = EXTSB;
2391 goto gen_ext;
2392 case INDEX_op_ext16s_i32:
2393 case INDEX_op_ext16s_i64:
2394 c = EXTSH;
2395 goto gen_ext;
2396 case INDEX_op_ext_i32_i64:
2397 case INDEX_op_ext32s_i64:
2398 c = EXTSW;
2399 goto gen_ext;
2400 gen_ext:
2401 tcg_out32(s, c | RS(args[1]) | RA(args[0]));
2402 break;
2403 case INDEX_op_extu_i32_i64:
2404 tcg_out_ext32u(s, args[0], args[1]);
2405 break;
2406
2407 case INDEX_op_setcond_i32:
2408 tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
2409 const_args[2]);
2410 break;
2411 case INDEX_op_setcond_i64:
2412 tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
2413 const_args[2]);
2414 break;
2415 case INDEX_op_setcond2_i32:
2416 tcg_out_setcond2(s, args, const_args);
2417 break;
2418
2419 case INDEX_op_bswap16_i32:
2420 case INDEX_op_bswap16_i64:
2421 a0 = args[0], a1 = args[1];
2422
2423 if (a0 != a1) {
2424
2425 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2426
2427 tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
2428 } else {
2429
2430 tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
2431
2432 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
2433
2434 tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
2435 }
2436 break;
2437
2438 case INDEX_op_bswap32_i32:
2439 case INDEX_op_bswap32_i64:
2440
2441 a1 = args[1];
2442 a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
2443
2444
2445
2446 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2447
2448 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2449
2450 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2451
2452 if (a0 == TCG_REG_R0) {
2453 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2454 }
2455 break;
2456
2457 case INDEX_op_bswap64_i64:
2458 a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
2459 if (a0 == a1) {
2460 a0 = TCG_REG_R0;
2461 a2 = a1;
2462 }
2463
2464
2465
2466 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
2467
2468 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
2469
2470 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
2471
2472
2473
2474 tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
2475 tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
2476
2477
2478 tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
2479
2480 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
2481
2482 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
2483
2484 if (a0 == 0) {
2485 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2486 }
2487 break;
2488
2489 case INDEX_op_deposit_i32:
2490 if (const_args[2]) {
2491 uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
2492 tcg_out_andi32(s, args[0], args[0], ~mask);
2493 } else {
2494 tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
2495 32 - args[3] - args[4], 31 - args[3]);
2496 }
2497 break;
2498 case INDEX_op_deposit_i64:
2499 if (const_args[2]) {
2500 uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
2501 tcg_out_andi64(s, args[0], args[0], ~mask);
2502 } else {
2503 tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
2504 64 - args[3] - args[4]);
2505 }
2506 break;
2507
2508 case INDEX_op_extract_i32:
2509 tcg_out_rlw(s, RLWINM, args[0], args[1],
2510 32 - args[2], 32 - args[3], 31);
2511 break;
2512 case INDEX_op_extract_i64:
2513 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 64 - args[3]);
2514 break;
2515
2516 case INDEX_op_movcond_i32:
2517 tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
2518 args[3], args[4], const_args[2]);
2519 break;
2520 case INDEX_op_movcond_i64:
2521 tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
2522 args[3], args[4], const_args[2]);
2523 break;
2524
2525#if TCG_TARGET_REG_BITS == 64
2526 case INDEX_op_add2_i64:
2527#else
2528 case INDEX_op_add2_i32:
2529#endif
2530
2531
2532
2533 a0 = args[0], a1 = args[1];
2534 if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
2535 a0 = TCG_REG_R0;
2536 }
2537 if (const_args[4]) {
2538 tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
2539 } else {
2540 tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
2541 }
2542 if (const_args[5]) {
2543 tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
2544 } else {
2545 tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
2546 }
2547 if (a0 != args[0]) {
2548 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2549 }
2550 break;
2551
2552#if TCG_TARGET_REG_BITS == 64
2553 case INDEX_op_sub2_i64:
2554#else
2555 case INDEX_op_sub2_i32:
2556#endif
2557 a0 = args[0], a1 = args[1];
2558 if (a0 == args[5] || (!const_args[3] && a0 == args[3])) {
2559 a0 = TCG_REG_R0;
2560 }
2561 if (const_args[2]) {
2562 tcg_out32(s, SUBFIC | TAI(a0, args[4], args[2]));
2563 } else {
2564 tcg_out32(s, SUBFC | TAB(a0, args[4], args[2]));
2565 }
2566 if (const_args[3]) {
2567 tcg_out32(s, (args[3] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
2568 } else {
2569 tcg_out32(s, SUBFE | TAB(a1, args[5], args[3]));
2570 }
2571 if (a0 != args[0]) {
2572 tcg_out_mov(s, TCG_TYPE_REG, args[0], a0);
2573 }
2574 break;
2575
2576 case INDEX_op_muluh_i32:
2577 tcg_out32(s, MULHWU | TAB(args[0], args[1], args[2]));
2578 break;
2579 case INDEX_op_mulsh_i32:
2580 tcg_out32(s, MULHW | TAB(args[0], args[1], args[2]));
2581 break;
2582 case INDEX_op_muluh_i64:
2583 tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2584 break;
2585 case INDEX_op_mulsh_i64:
2586 tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2587 break;
2588
2589 case INDEX_op_mb:
2590 tcg_out_mb(s, args[0]);
2591 break;
2592
2593 case INDEX_op_mov_i32:
2594 case INDEX_op_mov_i64:
2595 case INDEX_op_movi_i32:
2596 case INDEX_op_movi_i64:
2597 case INDEX_op_call:
2598 default:
2599 tcg_abort();
2600 }
2601}
2602
2603static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
2604{
2605 static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
2606 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
2607 static const TCGTargetOpDef r_L = { .args_ct_str = { "r", "L" } };
2608 static const TCGTargetOpDef S_S = { .args_ct_str = { "S", "S" } };
2609 static const TCGTargetOpDef r_ri = { .args_ct_str = { "r", "ri" } };
2610 static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
2611 static const TCGTargetOpDef r_L_L = { .args_ct_str = { "r", "L", "L" } };
2612 static const TCGTargetOpDef L_L_L = { .args_ct_str = { "L", "L", "L" } };
2613 static const TCGTargetOpDef S_S_S = { .args_ct_str = { "S", "S", "S" } };
2614 static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
2615 static const TCGTargetOpDef r_r_rI = { .args_ct_str = { "r", "r", "rI" } };
2616 static const TCGTargetOpDef r_r_rT = { .args_ct_str = { "r", "r", "rT" } };
2617 static const TCGTargetOpDef r_r_rU = { .args_ct_str = { "r", "r", "rU" } };
2618 static const TCGTargetOpDef r_rI_ri
2619 = { .args_ct_str = { "r", "rI", "ri" } };
2620 static const TCGTargetOpDef r_rI_rT
2621 = { .args_ct_str = { "r", "rI", "rT" } };
2622 static const TCGTargetOpDef r_r_rZW
2623 = { .args_ct_str = { "r", "r", "rZW" } };
2624 static const TCGTargetOpDef L_L_L_L
2625 = { .args_ct_str = { "L", "L", "L", "L" } };
2626 static const TCGTargetOpDef S_S_S_S
2627 = { .args_ct_str = { "S", "S", "S", "S" } };
2628 static const TCGTargetOpDef movc
2629 = { .args_ct_str = { "r", "r", "ri", "rZ", "rZ" } };
2630 static const TCGTargetOpDef dep
2631 = { .args_ct_str = { "r", "0", "rZ" } };
2632 static const TCGTargetOpDef br2
2633 = { .args_ct_str = { "r", "r", "ri", "ri" } };
2634 static const TCGTargetOpDef setc2
2635 = { .args_ct_str = { "r", "r", "r", "ri", "ri" } };
2636 static const TCGTargetOpDef add2
2637 = { .args_ct_str = { "r", "r", "r", "r", "rI", "rZM" } };
2638 static const TCGTargetOpDef sub2
2639 = { .args_ct_str = { "r", "r", "rI", "rZM", "r", "r" } };
2640
2641 switch (op) {
2642 case INDEX_op_goto_ptr:
2643 return &r;
2644
2645 case INDEX_op_ld8u_i32:
2646 case INDEX_op_ld8s_i32:
2647 case INDEX_op_ld16u_i32:
2648 case INDEX_op_ld16s_i32:
2649 case INDEX_op_ld_i32:
2650 case INDEX_op_st8_i32:
2651 case INDEX_op_st16_i32:
2652 case INDEX_op_st_i32:
2653 case INDEX_op_ctpop_i32:
2654 case INDEX_op_neg_i32:
2655 case INDEX_op_not_i32:
2656 case INDEX_op_ext8s_i32:
2657 case INDEX_op_ext16s_i32:
2658 case INDEX_op_bswap16_i32:
2659 case INDEX_op_bswap32_i32:
2660 case INDEX_op_extract_i32:
2661 case INDEX_op_ld8u_i64:
2662 case INDEX_op_ld8s_i64:
2663 case INDEX_op_ld16u_i64:
2664 case INDEX_op_ld16s_i64:
2665 case INDEX_op_ld32u_i64:
2666 case INDEX_op_ld32s_i64:
2667 case INDEX_op_ld_i64:
2668 case INDEX_op_st8_i64:
2669 case INDEX_op_st16_i64:
2670 case INDEX_op_st32_i64:
2671 case INDEX_op_st_i64:
2672 case INDEX_op_ctpop_i64:
2673 case INDEX_op_neg_i64:
2674 case INDEX_op_not_i64:
2675 case INDEX_op_ext8s_i64:
2676 case INDEX_op_ext16s_i64:
2677 case INDEX_op_ext32s_i64:
2678 case INDEX_op_ext_i32_i64:
2679 case INDEX_op_extu_i32_i64:
2680 case INDEX_op_bswap16_i64:
2681 case INDEX_op_bswap32_i64:
2682 case INDEX_op_bswap64_i64:
2683 case INDEX_op_extract_i64:
2684 return &r_r;
2685
2686 case INDEX_op_add_i32:
2687 case INDEX_op_and_i32:
2688 case INDEX_op_or_i32:
2689 case INDEX_op_xor_i32:
2690 case INDEX_op_andc_i32:
2691 case INDEX_op_orc_i32:
2692 case INDEX_op_eqv_i32:
2693 case INDEX_op_shl_i32:
2694 case INDEX_op_shr_i32:
2695 case INDEX_op_sar_i32:
2696 case INDEX_op_rotl_i32:
2697 case INDEX_op_rotr_i32:
2698 case INDEX_op_setcond_i32:
2699 case INDEX_op_and_i64:
2700 case INDEX_op_andc_i64:
2701 case INDEX_op_shl_i64:
2702 case INDEX_op_shr_i64:
2703 case INDEX_op_sar_i64:
2704 case INDEX_op_rotl_i64:
2705 case INDEX_op_rotr_i64:
2706 case INDEX_op_setcond_i64:
2707 return &r_r_ri;
2708 case INDEX_op_mul_i32:
2709 case INDEX_op_mul_i64:
2710 return &r_r_rI;
2711 case INDEX_op_div_i32:
2712 case INDEX_op_divu_i32:
2713 case INDEX_op_nand_i32:
2714 case INDEX_op_nor_i32:
2715 case INDEX_op_muluh_i32:
2716 case INDEX_op_mulsh_i32:
2717 case INDEX_op_orc_i64:
2718 case INDEX_op_eqv_i64:
2719 case INDEX_op_nand_i64:
2720 case INDEX_op_nor_i64:
2721 case INDEX_op_div_i64:
2722 case INDEX_op_divu_i64:
2723 case INDEX_op_mulsh_i64:
2724 case INDEX_op_muluh_i64:
2725 return &r_r_r;
2726 case INDEX_op_sub_i32:
2727 return &r_rI_ri;
2728 case INDEX_op_add_i64:
2729 return &r_r_rT;
2730 case INDEX_op_or_i64:
2731 case INDEX_op_xor_i64:
2732 return &r_r_rU;
2733 case INDEX_op_sub_i64:
2734 return &r_rI_rT;
2735 case INDEX_op_clz_i32:
2736 case INDEX_op_ctz_i32:
2737 case INDEX_op_clz_i64:
2738 case INDEX_op_ctz_i64:
2739 return &r_r_rZW;
2740
2741 case INDEX_op_brcond_i32:
2742 case INDEX_op_brcond_i64:
2743 return &r_ri;
2744
2745 case INDEX_op_movcond_i32:
2746 case INDEX_op_movcond_i64:
2747 return &movc;
2748 case INDEX_op_deposit_i32:
2749 case INDEX_op_deposit_i64:
2750 return &dep;
2751 case INDEX_op_brcond2_i32:
2752 return &br2;
2753 case INDEX_op_setcond2_i32:
2754 return &setc2;
2755 case INDEX_op_add2_i64:
2756 case INDEX_op_add2_i32:
2757 return &add2;
2758 case INDEX_op_sub2_i64:
2759 case INDEX_op_sub2_i32:
2760 return &sub2;
2761
2762 case INDEX_op_qemu_ld_i32:
2763 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2764 ? &r_L : &r_L_L);
2765 case INDEX_op_qemu_st_i32:
2766 return (TCG_TARGET_REG_BITS == 64 || TARGET_LONG_BITS == 32
2767 ? &S_S : &S_S_S);
2768 case INDEX_op_qemu_ld_i64:
2769 return (TCG_TARGET_REG_BITS == 64 ? &r_L
2770 : TARGET_LONG_BITS == 32 ? &L_L_L : &L_L_L_L);
2771 case INDEX_op_qemu_st_i64:
2772 return (TCG_TARGET_REG_BITS == 64 ? &S_S
2773 : TARGET_LONG_BITS == 32 ? &S_S_S : &S_S_S_S);
2774
2775 default:
2776 return NULL;
2777 }
2778}
2779
2780static void tcg_target_init(TCGContext *s)
2781{
2782 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
2783 unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2);
2784
2785 if (hwcap & PPC_FEATURE_ARCH_2_06) {
2786 have_isa_2_06 = true;
2787 }
2788#ifdef PPC_FEATURE2_ARCH_3_00
2789 if (hwcap2 & PPC_FEATURE2_ARCH_3_00) {
2790 have_isa_3_00 = true;
2791 }
2792#endif
2793
2794 tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
2795 tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
2796
2797 tcg_target_call_clobber_regs = 0;
2798 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
2799 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
2800 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
2801 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
2802 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
2803 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R6);
2804 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R7);
2805 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
2806 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
2807 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
2808 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
2809 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R12);
2810
2811 s->reserved_regs = 0;
2812 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2813 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
2814#if defined(_CALL_SYSV)
2815 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
2816#endif
2817#if defined(_CALL_SYSV) || TCG_TARGET_REG_BITS == 64
2818 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
2819#endif
2820 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
2821 if (USE_REG_TB) {
2822 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
2823 }
2824}
2825
2826#ifdef __ELF__
2827typedef struct {
2828 DebugFrameCIE cie;
2829 DebugFrameFDEHeader fde;
2830 uint8_t fde_def_cfa[4];
2831 uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2832} DebugFrame;
2833
2834
2835QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2836
2837#if TCG_TARGET_REG_BITS == 64
2838# define ELF_HOST_MACHINE EM_PPC64
2839#else
2840# define ELF_HOST_MACHINE EM_PPC
2841#endif
2842
2843static DebugFrame debug_frame = {
2844 .cie.len = sizeof(DebugFrameCIE)-4,
2845 .cie.id = -1,
2846 .cie.version = 1,
2847 .cie.code_align = 1,
2848 .cie.data_align = (-SZR & 0x7f),
2849 .cie.return_column = 65,
2850
2851
2852 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2853
2854 .fde_def_cfa = {
2855 12, TCG_REG_R1,
2856 (FRAME_SIZE & 0x7f) | 0x80,
2857 (FRAME_SIZE >> 7)
2858 },
2859 .fde_reg_ofs = {
2860
2861 0x11, 65, (LR_OFFSET / -SZR) & 0x7f,
2862 }
2863};
2864
2865void tcg_register_jit(void *buf, size_t buf_size)
2866{
2867 uint8_t *p = &debug_frame.fde_reg_ofs[3];
2868 int i;
2869
2870 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2871 p[0] = 0x80 + tcg_target_callee_save_regs[i];
2872 p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * SZR)) / SZR;
2873 }
2874
2875 debug_frame.fde.func_start = (uintptr_t)buf;
2876 debug_frame.fde.func_len = buf_size;
2877
2878 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2879}
2880#endif
2881
2882void flush_icache_range(uintptr_t start, uintptr_t stop)
2883{
2884 uintptr_t p, start1, stop1;
2885 size_t dsize = qemu_dcache_linesize;
2886 size_t isize = qemu_icache_linesize;
2887
2888 start1 = start & ~(dsize - 1);
2889 stop1 = (stop + dsize - 1) & ~(dsize - 1);
2890 for (p = start1; p < stop1; p += dsize) {
2891 asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
2892 }
2893 asm volatile ("sync" : : : "memory");
2894
2895 start &= start & ~(isize - 1);
2896 stop1 = (stop + isize - 1) & ~(isize - 1);
2897 for (p = start1; p < stop1; p += isize) {
2898 asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
2899 }
2900 asm volatile ("sync" : : : "memory");
2901 asm volatile ("isync" : : : "memory");
2902}
2903