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