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 "tcg-be-ldst.h"
26
27#define TCG_CT_CONST_S16 0x100
28#define TCG_CT_CONST_U16 0x200
29#define TCG_CT_CONST_S32 0x400
30#define TCG_CT_CONST_U32 0x800
31#define TCG_CT_CONST_ZERO 0x1000
32#define TCG_CT_CONST_MONE 0x2000
33
34static uint8_t *tb_ret_addr;
35
36#if TARGET_LONG_BITS == 32
37#define LD_ADDR LWZ
38#define CMP_L 0
39#else
40#define LD_ADDR LD
41#define CMP_L (1<<21)
42#endif
43
44#ifndef GUEST_BASE
45#define GUEST_BASE 0
46#endif
47
48#ifdef CONFIG_GETAUXVAL
49#include <sys/auxv.h>
50static bool have_isa_2_06;
51#define HAVE_ISA_2_06 have_isa_2_06
52#define HAVE_ISEL have_isa_2_06
53#else
54#define HAVE_ISA_2_06 0
55#define HAVE_ISEL 0
56#endif
57
58#ifdef CONFIG_USE_GUEST_BASE
59#define TCG_GUEST_BASE_REG 30
60#else
61#define TCG_GUEST_BASE_REG 0
62#endif
63
64#ifndef NDEBUG
65static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
66 "r0",
67 "r1",
68 "r2",
69 "r3",
70 "r4",
71 "r5",
72 "r6",
73 "r7",
74 "r8",
75 "r9",
76 "r10",
77 "r11",
78 "r12",
79 "r13",
80 "r14",
81 "r15",
82 "r16",
83 "r17",
84 "r18",
85 "r19",
86 "r20",
87 "r21",
88 "r22",
89 "r23",
90 "r24",
91 "r25",
92 "r26",
93 "r27",
94 "r28",
95 "r29",
96 "r30",
97 "r31"
98};
99#endif
100
101static const int tcg_target_reg_alloc_order[] = {
102 TCG_REG_R14,
103 TCG_REG_R15,
104 TCG_REG_R16,
105 TCG_REG_R17,
106 TCG_REG_R18,
107 TCG_REG_R19,
108 TCG_REG_R20,
109 TCG_REG_R21,
110 TCG_REG_R22,
111 TCG_REG_R23,
112 TCG_REG_R24,
113 TCG_REG_R25,
114 TCG_REG_R26,
115 TCG_REG_R27,
116 TCG_REG_R28,
117 TCG_REG_R29,
118 TCG_REG_R30,
119 TCG_REG_R31,
120 TCG_REG_R12,
121 TCG_REG_R11,
122 TCG_REG_R10,
123 TCG_REG_R9,
124 TCG_REG_R8,
125 TCG_REG_R7,
126 TCG_REG_R6,
127 TCG_REG_R5,
128 TCG_REG_R4,
129 TCG_REG_R3,
130};
131
132static const int tcg_target_call_iarg_regs[] = {
133 TCG_REG_R3,
134 TCG_REG_R4,
135 TCG_REG_R5,
136 TCG_REG_R6,
137 TCG_REG_R7,
138 TCG_REG_R8,
139 TCG_REG_R9,
140 TCG_REG_R10
141};
142
143static const int tcg_target_call_oarg_regs[] = {
144 TCG_REG_R3
145};
146
147static const int tcg_target_callee_save_regs[] = {
148#ifdef __APPLE__
149 TCG_REG_R11,
150#endif
151 TCG_REG_R14,
152 TCG_REG_R15,
153 TCG_REG_R16,
154 TCG_REG_R17,
155 TCG_REG_R18,
156 TCG_REG_R19,
157 TCG_REG_R20,
158 TCG_REG_R21,
159 TCG_REG_R22,
160 TCG_REG_R23,
161 TCG_REG_R24,
162 TCG_REG_R25,
163 TCG_REG_R26,
164 TCG_REG_R27,
165 TCG_REG_R28,
166 TCG_REG_R29,
167 TCG_REG_R30,
168 TCG_REG_R31
169};
170
171static inline bool in_range_b(tcg_target_long target)
172{
173 return target == sextract64(target, 0, 26);
174}
175
176static uint32_t reloc_pc24_val(void *pc, tcg_target_long target)
177{
178 tcg_target_long disp;
179
180 disp = target - (tcg_target_long)pc;
181 assert(in_range_b(disp));
182
183 return disp & 0x3fffffc;
184}
185
186static void reloc_pc24(void *pc, tcg_target_long target)
187{
188 *(uint32_t *)pc = (*(uint32_t *)pc & ~0x3fffffc)
189 | reloc_pc24_val(pc, target);
190}
191
192static uint16_t reloc_pc14_val(void *pc, tcg_target_long target)
193{
194 tcg_target_long disp;
195
196 disp = target - (tcg_target_long)pc;
197 if (disp != (int16_t) disp) {
198 tcg_abort();
199 }
200
201 return disp & 0xfffc;
202}
203
204static void reloc_pc14(void *pc, tcg_target_long target)
205{
206 *(uint32_t *)pc = (*(uint32_t *)pc & ~0xfffc) | reloc_pc14_val(pc, target);
207}
208
209static inline void tcg_out_b_noaddr(TCGContext *s, int insn)
210{
211 unsigned retrans = *(uint32_t *)s->code_ptr & 0x3fffffc;
212 tcg_out32(s, insn | retrans);
213}
214
215static inline void tcg_out_bc_noaddr(TCGContext *s, int insn)
216{
217 unsigned retrans = *(uint32_t *)s->code_ptr & 0xfffc;
218 tcg_out32(s, insn | retrans);
219}
220
221static void patch_reloc(uint8_t *code_ptr, int type,
222 intptr_t value, intptr_t addend)
223{
224 value += addend;
225 switch (type) {
226 case R_PPC_REL14:
227 reloc_pc14(code_ptr, value);
228 break;
229 case R_PPC_REL24:
230 reloc_pc24(code_ptr, value);
231 break;
232 default:
233 tcg_abort();
234 }
235}
236
237
238static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
239{
240 const char *ct_str;
241
242 ct_str = *pct_str;
243 switch (ct_str[0]) {
244 case 'A': case 'B': case 'C': case 'D':
245 ct->ct |= TCG_CT_REG;
246 tcg_regset_set_reg(ct->u.regs, 3 + ct_str[0] - 'A');
247 break;
248 case 'r':
249 ct->ct |= TCG_CT_REG;
250 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
251 break;
252 case 'L':
253 ct->ct |= TCG_CT_REG;
254 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
255 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
256#ifdef CONFIG_SOFTMMU
257 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
258 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
259#endif
260 break;
261 case 'S':
262 ct->ct |= TCG_CT_REG;
263 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
264 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
265#ifdef CONFIG_SOFTMMU
266 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
267 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
268 tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
269#endif
270 break;
271 case 'I':
272 ct->ct |= TCG_CT_CONST_S16;
273 break;
274 case 'J':
275 ct->ct |= TCG_CT_CONST_U16;
276 break;
277 case 'M':
278 ct->ct |= TCG_CT_CONST_MONE;
279 break;
280 case 'T':
281 ct->ct |= TCG_CT_CONST_S32;
282 break;
283 case 'U':
284 ct->ct |= TCG_CT_CONST_U32;
285 break;
286 case 'Z':
287 ct->ct |= TCG_CT_CONST_ZERO;
288 break;
289 default:
290 return -1;
291 }
292 ct_str++;
293 *pct_str = ct_str;
294 return 0;
295}
296
297
298static int tcg_target_const_match(tcg_target_long val,
299 const TCGArgConstraint *arg_ct)
300{
301 int ct = arg_ct->ct;
302 if (ct & TCG_CT_CONST) {
303 return 1;
304 } else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val) {
305 return 1;
306 } else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val) {
307 return 1;
308 } else if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
309 return 1;
310 } else if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
311 return 1;
312 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
313 return 1;
314 } else if ((ct & TCG_CT_CONST_MONE) && val == -1) {
315 return 1;
316 }
317 return 0;
318}
319
320#define OPCD(opc) ((opc)<<26)
321#define XO19(opc) (OPCD(19)|((opc)<<1))
322#define MD30(opc) (OPCD(30)|((opc)<<2))
323#define MDS30(opc) (OPCD(30)|((opc)<<1))
324#define XO31(opc) (OPCD(31)|((opc)<<1))
325#define XO58(opc) (OPCD(58)|(opc))
326#define XO62(opc) (OPCD(62)|(opc))
327
328#define B OPCD( 18)
329#define BC OPCD( 16)
330#define LBZ OPCD( 34)
331#define LHZ OPCD( 40)
332#define LHA OPCD( 42)
333#define LWZ OPCD( 32)
334#define STB OPCD( 38)
335#define STH OPCD( 44)
336#define STW OPCD( 36)
337
338#define STD XO62( 0)
339#define STDU XO62( 1)
340#define STDX XO31(149)
341
342#define LD XO58( 0)
343#define LDX XO31( 21)
344#define LDU XO58( 1)
345#define LWA XO58( 2)
346#define LWAX XO31(341)
347
348#define ADDIC OPCD( 12)
349#define ADDI OPCD( 14)
350#define ADDIS OPCD( 15)
351#define ORI OPCD( 24)
352#define ORIS OPCD( 25)
353#define XORI OPCD( 26)
354#define XORIS OPCD( 27)
355#define ANDI OPCD( 28)
356#define ANDIS OPCD( 29)
357#define MULLI OPCD( 7)
358#define CMPLI OPCD( 10)
359#define CMPI OPCD( 11)
360#define SUBFIC OPCD( 8)
361
362#define LWZU OPCD( 33)
363#define STWU OPCD( 37)
364
365#define RLWIMI OPCD( 20)
366#define RLWINM OPCD( 21)
367#define RLWNM OPCD( 23)
368
369#define RLDICL MD30( 0)
370#define RLDICR MD30( 1)
371#define RLDIMI MD30( 3)
372#define RLDCL MDS30( 8)
373
374#define BCLR XO19( 16)
375#define BCCTR XO19(528)
376#define CRAND XO19(257)
377#define CRANDC XO19(129)
378#define CRNAND XO19(225)
379#define CROR XO19(449)
380#define CRNOR XO19( 33)
381
382#define EXTSB XO31(954)
383#define EXTSH XO31(922)
384#define EXTSW XO31(986)
385#define ADD XO31(266)
386#define ADDE XO31(138)
387#define ADDME XO31(234)
388#define ADDZE XO31(202)
389#define ADDC XO31( 10)
390#define AND XO31( 28)
391#define SUBF XO31( 40)
392#define SUBFC XO31( 8)
393#define SUBFE XO31(136)
394#define SUBFME XO31(232)
395#define SUBFZE XO31(200)
396#define OR XO31(444)
397#define XOR XO31(316)
398#define MULLW XO31(235)
399#define MULHWU XO31( 11)
400#define DIVW XO31(491)
401#define DIVWU XO31(459)
402#define CMP XO31( 0)
403#define CMPL XO31( 32)
404#define LHBRX XO31(790)
405#define LWBRX XO31(534)
406#define LDBRX XO31(532)
407#define STHBRX XO31(918)
408#define STWBRX XO31(662)
409#define STDBRX XO31(660)
410#define MFSPR XO31(339)
411#define MTSPR XO31(467)
412#define SRAWI XO31(824)
413#define NEG XO31(104)
414#define MFCR XO31( 19)
415#define MFOCRF (MFCR | (1u << 20))
416#define NOR XO31(124)
417#define CNTLZW XO31( 26)
418#define CNTLZD XO31( 58)
419#define ANDC XO31( 60)
420#define ORC XO31(412)
421#define EQV XO31(284)
422#define NAND XO31(476)
423#define ISEL XO31( 15)
424
425#define MULLD XO31(233)
426#define MULHD XO31( 73)
427#define MULHDU XO31( 9)
428#define DIVD XO31(489)
429#define DIVDU XO31(457)
430
431#define LBZX XO31( 87)
432#define LHZX XO31(279)
433#define LHAX XO31(343)
434#define LWZX XO31( 23)
435#define STBX XO31(215)
436#define STHX XO31(407)
437#define STWX XO31(151)
438
439#define SPR(a, b) ((((a)<<5)|(b))<<11)
440#define LR SPR(8, 0)
441#define CTR SPR(9, 0)
442
443#define SLW XO31( 24)
444#define SRW XO31(536)
445#define SRAW XO31(792)
446
447#define SLD XO31( 27)
448#define SRD XO31(539)
449#define SRAD XO31(794)
450#define SRADI XO31(413<<1)
451
452#define TW XO31( 4)
453#define TRAP (TW | TO(31))
454
455#define RT(r) ((r)<<21)
456#define RS(r) ((r)<<21)
457#define RA(r) ((r)<<16)
458#define RB(r) ((r)<<11)
459#define TO(t) ((t)<<21)
460#define SH(s) ((s)<<11)
461#define MB(b) ((b)<<6)
462#define ME(e) ((e)<<1)
463#define BO(o) ((o)<<21)
464#define MB64(b) ((b)<<5)
465#define FXM(b) (1 << (19 - (b)))
466
467#define LK 1
468
469#define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
470#define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
471#define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
472#define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
473
474#define BF(n) ((n)<<23)
475#define BI(n, c) (((c)+((n)*4))<<16)
476#define BT(n, c) (((c)+((n)*4))<<21)
477#define BA(n, c) (((c)+((n)*4))<<16)
478#define BB(n, c) (((c)+((n)*4))<<11)
479#define BC_(n, c) (((c)+((n)*4))<<6)
480
481#define BO_COND_TRUE BO(12)
482#define BO_COND_FALSE BO( 4)
483#define BO_ALWAYS BO(20)
484
485enum {
486 CR_LT,
487 CR_GT,
488 CR_EQ,
489 CR_SO
490};
491
492static const uint32_t tcg_to_bc[] = {
493 [TCG_COND_EQ] = BC | BI(7, CR_EQ) | BO_COND_TRUE,
494 [TCG_COND_NE] = BC | BI(7, CR_EQ) | BO_COND_FALSE,
495 [TCG_COND_LT] = BC | BI(7, CR_LT) | BO_COND_TRUE,
496 [TCG_COND_GE] = BC | BI(7, CR_LT) | BO_COND_FALSE,
497 [TCG_COND_LE] = BC | BI(7, CR_GT) | BO_COND_FALSE,
498 [TCG_COND_GT] = BC | BI(7, CR_GT) | BO_COND_TRUE,
499 [TCG_COND_LTU] = BC | BI(7, CR_LT) | BO_COND_TRUE,
500 [TCG_COND_GEU] = BC | BI(7, CR_LT) | BO_COND_FALSE,
501 [TCG_COND_LEU] = BC | BI(7, CR_GT) | BO_COND_FALSE,
502 [TCG_COND_GTU] = BC | BI(7, CR_GT) | BO_COND_TRUE,
503};
504
505
506static const uint32_t tcg_to_isel[] = {
507 [TCG_COND_EQ] = ISEL | BC_(7, CR_EQ),
508 [TCG_COND_NE] = ISEL | BC_(7, CR_EQ) | 1,
509 [TCG_COND_LT] = ISEL | BC_(7, CR_LT),
510 [TCG_COND_GE] = ISEL | BC_(7, CR_LT) | 1,
511 [TCG_COND_LE] = ISEL | BC_(7, CR_GT) | 1,
512 [TCG_COND_GT] = ISEL | BC_(7, CR_GT),
513 [TCG_COND_LTU] = ISEL | BC_(7, CR_LT),
514 [TCG_COND_GEU] = ISEL | BC_(7, CR_LT) | 1,
515 [TCG_COND_LEU] = ISEL | BC_(7, CR_GT) | 1,
516 [TCG_COND_GTU] = ISEL | BC_(7, CR_GT),
517};
518
519static inline void tcg_out_mov(TCGContext *s, TCGType type,
520 TCGReg ret, TCGReg arg)
521{
522 if (ret != arg) {
523 tcg_out32(s, OR | SAB(arg, ret, arg));
524 }
525}
526
527static inline void tcg_out_rld(TCGContext *s, int op, TCGReg ra, TCGReg rs,
528 int sh, int mb)
529{
530 sh = SH(sh & 0x1f) | (((sh >> 5) & 1) << 1);
531 mb = MB64((mb >> 5) | ((mb << 1) & 0x3f));
532 tcg_out32(s, op | RA(ra) | RS(rs) | sh | mb);
533}
534
535static inline void tcg_out_rlw(TCGContext *s, int op, TCGReg ra, TCGReg rs,
536 int sh, int mb, int me)
537{
538 tcg_out32(s, op | RA(ra) | RS(rs) | SH(sh) | MB(mb) | ME(me));
539}
540
541static inline void tcg_out_ext32u(TCGContext *s, TCGReg dst, TCGReg src)
542{
543 tcg_out_rld(s, RLDICL, dst, src, 0, 32);
544}
545
546static inline void tcg_out_shli64(TCGContext *s, TCGReg dst, TCGReg src, int c)
547{
548 tcg_out_rld(s, RLDICR, dst, src, c, 63 - c);
549}
550
551static inline void tcg_out_shri64(TCGContext *s, TCGReg dst, TCGReg src, int c)
552{
553 tcg_out_rld(s, RLDICL, dst, src, 64 - c, c);
554}
555
556static void tcg_out_movi32(TCGContext *s, TCGReg ret, int32_t arg)
557{
558 if (arg == (int16_t) arg) {
559 tcg_out32(s, ADDI | TAI(ret, 0, arg));
560 } else {
561 tcg_out32(s, ADDIS | TAI(ret, 0, arg >> 16));
562 if (arg & 0xffff) {
563 tcg_out32(s, ORI | SAI(ret, ret, arg));
564 }
565 }
566}
567
568static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
569 tcg_target_long arg)
570{
571 if (type == TCG_TYPE_I32 || arg == (int32_t)arg) {
572 tcg_out_movi32(s, ret, arg);
573 } else if (arg == (uint32_t)arg && !(arg & 0x8000)) {
574 tcg_out32(s, ADDI | TAI(ret, 0, arg));
575 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
576 } else {
577 int32_t high = arg >> 32;
578 tcg_out_movi32(s, ret, high);
579 if (high) {
580 tcg_out_shli64(s, ret, ret, 32);
581 }
582 if (arg & 0xffff0000) {
583 tcg_out32(s, ORIS | SAI(ret, ret, arg >> 16));
584 }
585 if (arg & 0xffff) {
586 tcg_out32(s, ORI | SAI(ret, ret, arg));
587 }
588 }
589}
590
591static bool mask_operand(uint32_t c, int *mb, int *me)
592{
593 uint32_t lsb, test;
594
595
596
597
598
599
600 if (c == 0 || c == -1) {
601 return false;
602 }
603 test = c;
604 lsb = test & -test;
605 test += lsb;
606 if (test & (test - 1)) {
607 return false;
608 }
609
610 *me = clz32(lsb);
611 *mb = test ? clz32(test & -test) + 1 : 0;
612 return true;
613}
614
615static bool mask64_operand(uint64_t c, int *mb, int *me)
616{
617 uint64_t lsb;
618
619 if (c == 0) {
620 return false;
621 }
622
623 lsb = c & -c;
624
625 if (c == -lsb) {
626 *mb = 0;
627 *me = clz64(lsb);
628 return true;
629 }
630
631 if (lsb == 1 && (c & (c + 1)) == 0) {
632 *mb = clz64(c + 1) + 1;
633 *me = 63;
634 return true;
635 }
636 return false;
637}
638
639static void tcg_out_andi32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
640{
641 int mb, me;
642
643 if ((c & 0xffff) == c) {
644 tcg_out32(s, ANDI | SAI(src, dst, c));
645 return;
646 } else if ((c & 0xffff0000) == c) {
647 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
648 return;
649 } else if (mask_operand(c, &mb, &me)) {
650 tcg_out_rlw(s, RLWINM, dst, src, 0, mb, me);
651 } else {
652 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R0, c);
653 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
654 }
655}
656
657static void tcg_out_andi64(TCGContext *s, TCGReg dst, TCGReg src, uint64_t c)
658{
659 int mb, me;
660
661 if ((c & 0xffff) == c) {
662 tcg_out32(s, ANDI | SAI(src, dst, c));
663 return;
664 } else if ((c & 0xffff0000) == c) {
665 tcg_out32(s, ANDIS | SAI(src, dst, c >> 16));
666 return;
667 } else if (mask64_operand(c, &mb, &me)) {
668 if (mb == 0) {
669 tcg_out_rld(s, RLDICR, dst, src, 0, me);
670 } else {
671 tcg_out_rld(s, RLDICL, dst, src, 0, mb);
672 }
673 } else {
674 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, c);
675 tcg_out32(s, AND | SAB(src, dst, TCG_REG_R0));
676 }
677}
678
679static void tcg_out_zori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c,
680 int op_lo, int op_hi)
681{
682 if (c >> 16) {
683 tcg_out32(s, op_hi | SAI(src, dst, c >> 16));
684 src = dst;
685 }
686 if (c & 0xffff) {
687 tcg_out32(s, op_lo | SAI(src, dst, c));
688 src = dst;
689 }
690}
691
692static void tcg_out_ori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
693{
694 tcg_out_zori32(s, dst, src, c, ORI, ORIS);
695}
696
697static void tcg_out_xori32(TCGContext *s, TCGReg dst, TCGReg src, uint32_t c)
698{
699 tcg_out_zori32(s, dst, src, c, XORI, XORIS);
700}
701
702static void tcg_out_b(TCGContext *s, int mask, tcg_target_long target)
703{
704 tcg_target_long disp;
705
706 disp = target - (tcg_target_long)s->code_ptr;
707 if (in_range_b(disp)) {
708 tcg_out32(s, B | (disp & 0x3fffffc) | mask);
709 } else {
710 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, (tcg_target_long)target);
711 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
712 tcg_out32(s, BCCTR | BO_ALWAYS | mask);
713 }
714}
715
716static void tcg_out_call(TCGContext *s, tcg_target_long arg, int const_arg)
717{
718#ifdef __APPLE__
719 if (const_arg) {
720 tcg_out_b(s, LK, arg);
721 } else {
722 tcg_out32(s, MTSPR | RS(arg) | LR);
723 tcg_out32(s, BCLR | BO_ALWAYS | LK);
724 }
725#else
726 TCGReg reg = arg;
727 int ofs = 0;
728
729 if (const_arg) {
730
731
732 intptr_t tgt = ((intptr_t *)arg)[0];
733 intptr_t toc = ((intptr_t *)arg)[1];
734 intptr_t diff = tgt - (intptr_t)s->code_ptr;
735
736 if (in_range_b(diff) && toc == (uint32_t)toc) {
737 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, toc);
738 tcg_out_b(s, LK, tgt);
739 return;
740 }
741
742
743 ofs = (int16_t)arg;
744 if (ofs + 8 < 0x8000) {
745 arg -= ofs;
746 } else {
747 ofs = 0;
748 }
749 reg = TCG_REG_R2;
750 tcg_out_movi(s, TCG_TYPE_I64, reg, arg);
751 }
752
753 tcg_out32(s, LD | TAI(TCG_REG_R0, reg, ofs));
754 tcg_out32(s, MTSPR | RA(TCG_REG_R0) | CTR);
755 tcg_out32(s, LD | TAI(TCG_REG_R2, reg, ofs + 8));
756 tcg_out32(s, BCCTR | BO_ALWAYS | LK);
757#endif
758}
759
760static void tcg_out_mem_long(TCGContext *s, int opi, int opx, TCGReg rt,
761 TCGReg base, tcg_target_long offset)
762{
763 tcg_target_long orig = offset, l0, l1, extra = 0, align = 0;
764 TCGReg rs = TCG_REG_R2;
765
766 assert(rt != TCG_REG_R2 && base != TCG_REG_R2);
767
768 switch (opi) {
769 case LD: case LWA:
770 align = 3;
771
772 default:
773 if (rt != TCG_REG_R0) {
774 rs = rt;
775 }
776 break;
777 case STD:
778 align = 3;
779 break;
780 case STB: case STH: case STW:
781 break;
782 }
783
784
785 if (offset & align || offset != (int32_t)offset) {
786 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R2, orig);
787 tcg_out32(s, opx | TAB(rt, base, TCG_REG_R2));
788 return;
789 }
790
791 l0 = (int16_t)offset;
792 offset = (offset - l0) >> 16;
793 l1 = (int16_t)offset;
794
795 if (l1 < 0 && orig >= 0) {
796 extra = 0x4000;
797 l1 = (int16_t)(offset - 0x4000);
798 }
799 if (l1) {
800 tcg_out32(s, ADDIS | TAI(rs, base, l1));
801 base = rs;
802 }
803 if (extra) {
804 tcg_out32(s, ADDIS | TAI(rs, base, extra));
805 base = rs;
806 }
807 if (opi != ADDI || base != rt || l0 != 0) {
808 tcg_out32(s, opi | TAI(rt, base, l0));
809 }
810}
811
812static const uint32_t qemu_ldx_opc[16] = {
813 [MO_UB] = LBZX,
814 [MO_UW] = LHZX,
815 [MO_UL] = LWZX,
816 [MO_Q] = LDX,
817 [MO_SW] = LHAX,
818 [MO_SL] = LWAX,
819 [MO_BSWAP | MO_UB] = LBZX,
820 [MO_BSWAP | MO_UW] = LHBRX,
821 [MO_BSWAP | MO_UL] = LWBRX,
822 [MO_BSWAP | MO_Q] = LDBRX,
823};
824
825static const uint32_t qemu_stx_opc[16] = {
826 [MO_UB] = STBX,
827 [MO_UW] = STHX,
828 [MO_UL] = STWX,
829 [MO_Q] = STDX,
830 [MO_BSWAP | MO_UB] = STBX,
831 [MO_BSWAP | MO_UW] = STHBRX,
832 [MO_BSWAP | MO_UL] = STWBRX,
833 [MO_BSWAP | MO_Q] = STDBRX,
834};
835
836static const uint32_t qemu_exts_opc[4] = {
837 EXTSB, EXTSH, EXTSW, 0
838};
839
840#if defined (CONFIG_SOFTMMU)
841
842
843
844static const void * const qemu_ld_helpers[16] = {
845 [MO_UB] = helper_ret_ldub_mmu,
846 [MO_LEUW] = helper_le_lduw_mmu,
847 [MO_LEUL] = helper_le_ldul_mmu,
848 [MO_LEQ] = helper_le_ldq_mmu,
849 [MO_BEUW] = helper_be_lduw_mmu,
850 [MO_BEUL] = helper_be_ldul_mmu,
851 [MO_BEQ] = helper_be_ldq_mmu,
852};
853
854
855
856
857static const void * const qemu_st_helpers[16] = {
858 [MO_UB] = helper_ret_stb_mmu,
859 [MO_LEUW] = helper_le_stw_mmu,
860 [MO_LEUL] = helper_le_stl_mmu,
861 [MO_LEQ] = helper_le_stq_mmu,
862 [MO_BEUW] = helper_be_stw_mmu,
863 [MO_BEUL] = helper_be_stl_mmu,
864 [MO_BEQ] = helper_be_stq_mmu,
865};
866
867
868
869
870
871static TCGReg tcg_out_tlb_read(TCGContext *s, TCGMemOp s_bits, TCGReg addr_reg,
872 int mem_index, bool is_read)
873{
874 int cmp_off
875 = (is_read
876 ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
877 : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));
878 int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);
879 TCGReg base = TCG_AREG0;
880
881
882 if (TARGET_LONG_BITS == 32) {
883
884 tcg_out_ext32u(s, TCG_REG_R4, addr_reg);
885 addr_reg = TCG_REG_R4;
886 } else {
887 tcg_out_rld(s, RLDICL, TCG_REG_R3, addr_reg,
888 64 - TARGET_PAGE_BITS, 64 - CPU_TLB_BITS);
889 }
890
891
892 if (add_off >= 0x8000) {
893
894
895
896 QEMU_BUILD_BUG_ON(offsetof(CPUArchState,
897 tlb_table[NB_MMU_MODES - 1][1])
898 > 0x7ff0 + 0x7fff);
899 tcg_out32(s, ADDI | TAI(TCG_REG_R2, base, 0x7ff0));
900 base = TCG_REG_R2;
901 cmp_off -= 0x7ff0;
902 add_off -= 0x7ff0;
903 }
904
905
906 if (TARGET_LONG_BITS == 32) {
907 tcg_out_rlw(s, RLWINM, TCG_REG_R3, addr_reg,
908 32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
909 32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS),
910 31 - CPU_TLB_ENTRY_BITS);
911 } else {
912 tcg_out_shli64(s, TCG_REG_R3, TCG_REG_R3, CPU_TLB_ENTRY_BITS);
913 }
914
915 tcg_out32(s, ADD | TAB(TCG_REG_R3, TCG_REG_R3, base));
916
917
918 tcg_out32(s, LD_ADDR | TAI(TCG_REG_R2, TCG_REG_R3, cmp_off));
919
920
921
922 tcg_out32(s, LD | TAI(TCG_REG_R3, TCG_REG_R3, add_off));
923
924
925 if (TARGET_LONG_BITS == 32) {
926 tcg_out_rlw(s, RLWINM, TCG_REG_R0, addr_reg, 0,
927 (32 - s_bits) & 31, 31 - TARGET_PAGE_BITS);
928 } else if (!s_bits) {
929 tcg_out_rld(s, RLDICR, TCG_REG_R0, addr_reg, 0, 63 - TARGET_PAGE_BITS);
930 } else {
931 tcg_out_rld(s, RLDICL, TCG_REG_R0, addr_reg,
932 64 - TARGET_PAGE_BITS, TARGET_PAGE_BITS - s_bits);
933 tcg_out_rld(s, RLDICL, TCG_REG_R0, TCG_REG_R0, TARGET_PAGE_BITS, 0);
934 }
935
936 tcg_out32(s, CMP | BF(7) | RA(TCG_REG_R0) | RB(TCG_REG_R2) | CMP_L);
937
938 return addr_reg;
939}
940
941
942
943
944static void add_qemu_ldst_label(TCGContext *s, bool is_ld, TCGMemOp opc,
945 int data_reg, int addr_reg, int mem_index,
946 uint8_t *raddr, uint8_t *label_ptr)
947{
948 TCGLabelQemuLdst *label = new_ldst_label(s);
949
950 label->is_ld = is_ld;
951 label->opc = opc;
952 label->datalo_reg = data_reg;
953 label->addrlo_reg = addr_reg;
954 label->mem_index = mem_index;
955 label->raddr = raddr;
956 label->label_ptr[0] = label_ptr;
957}
958
959static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
960{
961 TCGMemOp opc = lb->opc;
962
963 reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
964
965 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_R3, TCG_AREG0);
966
967
968
969 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, lb->addrlo_reg);
970
971 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R5, lb->mem_index);
972 tcg_out32(s, MFSPR | RT(TCG_REG_R6) | LR);
973
974 tcg_out_call(s, (tcg_target_long)qemu_ld_helpers[opc & ~MO_SIGN], 1);
975
976 if (opc & MO_SIGN) {
977 uint32_t insn = qemu_exts_opc[opc & MO_SIZE];
978 tcg_out32(s, insn | RA(lb->datalo_reg) | RS(TCG_REG_R3));
979 } else {
980 tcg_out_mov(s, TCG_TYPE_I64, lb->datalo_reg, TCG_REG_R3);
981 }
982
983 tcg_out_b(s, 0, (uintptr_t)lb->raddr);
984}
985
986static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
987{
988 TCGMemOp opc = lb->opc;
989 TCGMemOp s_bits = opc & MO_SIZE;
990
991 reloc_pc14(lb->label_ptr[0], (uintptr_t)s->code_ptr);
992
993 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, TCG_AREG0);
994
995
996
997 tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R4, lb->addrlo_reg);
998
999 tcg_out_rld(s, RLDICL, TCG_REG_R5, lb->datalo_reg,
1000 0, 64 - (1 << (3 + s_bits)));
1001 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R6, lb->mem_index);
1002 tcg_out32(s, MFSPR | RT(TCG_REG_R7) | LR);
1003
1004 tcg_out_call(s, (tcg_target_long)qemu_st_helpers[opc], 1);
1005
1006 tcg_out_b(s, 0, (uintptr_t)lb->raddr);
1007}
1008#endif
1009
1010static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1011 TCGMemOp opc, int mem_index)
1012{
1013 TCGReg rbase;
1014 uint32_t insn;
1015 TCGMemOp s_bits = opc & MO_SIZE;
1016#ifdef CONFIG_SOFTMMU
1017 void *label_ptr;
1018#endif
1019
1020#ifdef CONFIG_SOFTMMU
1021 addr_reg = tcg_out_tlb_read(s, s_bits, addr_reg, mem_index, true);
1022
1023
1024 label_ptr = s->code_ptr;
1025 tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1026
1027 rbase = TCG_REG_R3;
1028#else
1029 rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1030 if (TARGET_LONG_BITS == 32) {
1031 tcg_out_ext32u(s, TCG_REG_R2, addr_reg);
1032 addr_reg = TCG_REG_R2;
1033 }
1034#endif
1035
1036 insn = qemu_ldx_opc[opc];
1037 if (!HAVE_ISA_2_06 && insn == LDBRX) {
1038 tcg_out32(s, ADDI | TAI(TCG_REG_R0, addr_reg, 4));
1039 tcg_out32(s, LWBRX | TAB(data_reg, rbase, addr_reg));
1040 tcg_out32(s, LWBRX | TAB(TCG_REG_R0, rbase, TCG_REG_R0));
1041 tcg_out_rld(s, RLDIMI, data_reg, TCG_REG_R0, 32, 0);
1042 } else if (insn) {
1043 tcg_out32(s, insn | TAB(data_reg, rbase, addr_reg));
1044 } else {
1045 insn = qemu_ldx_opc[opc & (MO_SIZE | MO_BSWAP)];
1046 tcg_out32(s, insn | TAB(data_reg, rbase, addr_reg));
1047 insn = qemu_exts_opc[s_bits];
1048 tcg_out32(s, insn | RA(data_reg) | RS(data_reg));
1049 }
1050
1051#ifdef CONFIG_SOFTMMU
1052 add_qemu_ldst_label(s, true, opc, data_reg, addr_reg, mem_index,
1053 s->code_ptr, label_ptr);
1054#endif
1055}
1056
1057static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg,
1058 TCGMemOp opc, int mem_index)
1059{
1060 TCGReg rbase;
1061 uint32_t insn;
1062#ifdef CONFIG_SOFTMMU
1063 void *label_ptr;
1064#endif
1065
1066#ifdef CONFIG_SOFTMMU
1067 addr_reg = tcg_out_tlb_read(s, opc & MO_SIZE, addr_reg, mem_index, false);
1068
1069
1070 label_ptr = s->code_ptr;
1071 tcg_out_bc_noaddr(s, BC | BI(7, CR_EQ) | BO_COND_FALSE | LK);
1072
1073 rbase = TCG_REG_R3;
1074#else
1075 rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
1076 if (TARGET_LONG_BITS == 32) {
1077 tcg_out_ext32u(s, TCG_REG_R2, addr_reg);
1078 addr_reg = TCG_REG_R2;
1079 }
1080#endif
1081
1082 insn = qemu_stx_opc[opc];
1083 if (!HAVE_ISA_2_06 && insn == STDBRX) {
1084 tcg_out32(s, STWBRX | SAB(data_reg, rbase, addr_reg));
1085 tcg_out32(s, ADDI | TAI(TCG_REG_R2, addr_reg, 4));
1086 tcg_out_shri64(s, TCG_REG_R0, data_reg, 32);
1087 tcg_out32(s, STWBRX | SAB(TCG_REG_R0, rbase, TCG_REG_R2));
1088 } else {
1089 tcg_out32(s, insn | SAB(data_reg, rbase, addr_reg));
1090 }
1091
1092#ifdef CONFIG_SOFTMMU
1093 add_qemu_ldst_label(s, false, opc, data_reg, addr_reg, mem_index,
1094 s->code_ptr, label_ptr);
1095#endif
1096}
1097
1098#define FRAME_SIZE ((int) \
1099 ((8 \
1100 + 8 \
1101 + 8 \
1102 + 8 \
1103 + 8 \
1104 + 8 \
1105 + TCG_STATIC_CALL_ARGS_SIZE \
1106 + CPU_TEMP_BUF_NLONGS * sizeof(long) \
1107 + ARRAY_SIZE(tcg_target_callee_save_regs) * 8 \
1108 + 15) & ~15))
1109
1110#define REG_SAVE_BOT (FRAME_SIZE - ARRAY_SIZE(tcg_target_callee_save_regs) * 8)
1111
1112static void tcg_target_qemu_prologue(TCGContext *s)
1113{
1114 int i;
1115
1116 tcg_set_frame(s, TCG_REG_CALL_STACK,
1117 REG_SAVE_BOT - CPU_TEMP_BUF_NLONGS * sizeof(long),
1118 CPU_TEMP_BUF_NLONGS * sizeof(long));
1119
1120#ifndef __APPLE__
1121
1122 tcg_out64(s, (uint64_t)s->code_ptr + 24);
1123 s->code_ptr += 16;
1124#endif
1125
1126
1127 tcg_out32(s, MFSPR | RT(TCG_REG_R0) | LR);
1128 tcg_out32(s, STDU | SAI(TCG_REG_R1, TCG_REG_R1, -FRAME_SIZE));
1129 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1130 tcg_out32(s, STD | SAI(tcg_target_callee_save_regs[i], 1,
1131 REG_SAVE_BOT + i * 8));
1132 }
1133 tcg_out32(s, STD | SAI(TCG_REG_R0, TCG_REG_R1, FRAME_SIZE + 16));
1134
1135#ifdef CONFIG_USE_GUEST_BASE
1136 if (GUEST_BASE) {
1137 tcg_out_movi(s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
1138 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1139 }
1140#endif
1141
1142 tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1143 tcg_out32(s, MTSPR | RS(tcg_target_call_iarg_regs[1]) | CTR);
1144 tcg_out32(s, BCCTR | BO_ALWAYS);
1145
1146
1147 tb_ret_addr = s->code_ptr;
1148
1149 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i) {
1150 tcg_out32(s, LD | TAI(tcg_target_callee_save_regs[i], TCG_REG_R1,
1151 REG_SAVE_BOT + i * 8));
1152 }
1153 tcg_out32(s, LD | TAI(TCG_REG_R0, TCG_REG_R1, FRAME_SIZE + 16));
1154 tcg_out32(s, MTSPR | RS(TCG_REG_R0) | LR);
1155 tcg_out32(s, ADDI | TAI(TCG_REG_R1, TCG_REG_R1, FRAME_SIZE));
1156 tcg_out32(s, BCLR | BO_ALWAYS);
1157}
1158
1159static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
1160 TCGReg arg1, intptr_t arg2)
1161{
1162 int opi, opx;
1163
1164 if (type == TCG_TYPE_I32) {
1165 opi = LWZ, opx = LWZX;
1166 } else {
1167 opi = LD, opx = LDX;
1168 }
1169 tcg_out_mem_long(s, opi, opx, ret, arg1, arg2);
1170}
1171
1172static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
1173 TCGReg arg1, intptr_t arg2)
1174{
1175 int opi, opx;
1176
1177 if (type == TCG_TYPE_I32) {
1178 opi = STW, opx = STWX;
1179 } else {
1180 opi = STD, opx = STDX;
1181 }
1182 tcg_out_mem_long(s, opi, opx, arg, arg1, arg2);
1183}
1184
1185static void tcg_out_cmp(TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
1186 int const_arg2, int cr, TCGType type)
1187{
1188 int imm;
1189 uint32_t op;
1190
1191
1192 if (type == TCG_TYPE_I32) {
1193 arg2 = (int32_t)arg2;
1194 }
1195
1196 switch (cond) {
1197 case TCG_COND_EQ:
1198 case TCG_COND_NE:
1199 if (const_arg2) {
1200 if ((int16_t) arg2 == arg2) {
1201 op = CMPI;
1202 imm = 1;
1203 break;
1204 } else if ((uint16_t) arg2 == arg2) {
1205 op = CMPLI;
1206 imm = 1;
1207 break;
1208 }
1209 }
1210 op = CMPL;
1211 imm = 0;
1212 break;
1213
1214 case TCG_COND_LT:
1215 case TCG_COND_GE:
1216 case TCG_COND_LE:
1217 case TCG_COND_GT:
1218 if (const_arg2) {
1219 if ((int16_t) arg2 == arg2) {
1220 op = CMPI;
1221 imm = 1;
1222 break;
1223 }
1224 }
1225 op = CMP;
1226 imm = 0;
1227 break;
1228
1229 case TCG_COND_LTU:
1230 case TCG_COND_GEU:
1231 case TCG_COND_LEU:
1232 case TCG_COND_GTU:
1233 if (const_arg2) {
1234 if ((uint16_t) arg2 == arg2) {
1235 op = CMPLI;
1236 imm = 1;
1237 break;
1238 }
1239 }
1240 op = CMPL;
1241 imm = 0;
1242 break;
1243
1244 default:
1245 tcg_abort();
1246 }
1247 op |= BF(cr) | ((type == TCG_TYPE_I64) << 21);
1248
1249 if (imm) {
1250 tcg_out32(s, op | RA(arg1) | (arg2 & 0xffff));
1251 } else {
1252 if (const_arg2) {
1253 tcg_out_movi(s, type, TCG_REG_R0, arg2);
1254 arg2 = TCG_REG_R0;
1255 }
1256 tcg_out32(s, op | RA(arg1) | RB(arg2));
1257 }
1258}
1259
1260static void tcg_out_setcond_eq0(TCGContext *s, TCGType type,
1261 TCGReg dst, TCGReg src)
1262{
1263 tcg_out32(s, (type == TCG_TYPE_I64 ? CNTLZD : CNTLZW) | RS(src) | RA(dst));
1264 tcg_out_shri64(s, dst, dst, type == TCG_TYPE_I64 ? 6 : 5);
1265}
1266
1267static void tcg_out_setcond_ne0(TCGContext *s, TCGReg dst, TCGReg src)
1268{
1269
1270
1271 if (dst != src) {
1272 tcg_out32(s, ADDIC | TAI(dst, src, -1));
1273 tcg_out32(s, SUBFE | TAB(dst, dst, src));
1274 } else {
1275 tcg_out32(s, ADDIC | TAI(TCG_REG_R0, src, -1));
1276 tcg_out32(s, SUBFE | TAB(dst, TCG_REG_R0, src));
1277 }
1278}
1279
1280static TCGReg tcg_gen_setcond_xor(TCGContext *s, TCGReg arg1, TCGArg arg2,
1281 bool const_arg2)
1282{
1283 if (const_arg2) {
1284 if ((uint32_t)arg2 == arg2) {
1285 tcg_out_xori32(s, TCG_REG_R0, arg1, arg2);
1286 } else {
1287 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R0, arg2);
1288 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, TCG_REG_R0));
1289 }
1290 } else {
1291 tcg_out32(s, XOR | SAB(arg1, TCG_REG_R0, arg2));
1292 }
1293 return TCG_REG_R0;
1294}
1295
1296static void tcg_out_setcond(TCGContext *s, TCGType type, TCGCond cond,
1297 TCGArg arg0, TCGArg arg1, TCGArg arg2,
1298 int const_arg2)
1299{
1300 int crop, sh;
1301
1302
1303 if (type == TCG_TYPE_I32) {
1304 arg2 = (uint32_t)arg2;
1305 }
1306
1307
1308 if (arg2 == 0) {
1309 switch (cond) {
1310 case TCG_COND_EQ:
1311 tcg_out_setcond_eq0(s, type, arg0, arg1);
1312 return;
1313 case TCG_COND_NE:
1314 if (type == TCG_TYPE_I32) {
1315 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1316 arg1 = TCG_REG_R0;
1317 }
1318 tcg_out_setcond_ne0(s, arg0, arg1);
1319 return;
1320 case TCG_COND_GE:
1321 tcg_out32(s, NOR | SAB(arg1, arg0, arg1));
1322 arg1 = arg0;
1323
1324 case TCG_COND_LT:
1325
1326 tcg_out_rld(s, RLDICL, arg0, arg1,
1327 type == TCG_TYPE_I64 ? 1 : 33, 63);
1328 return;
1329 default:
1330 break;
1331 }
1332 }
1333
1334
1335
1336
1337 if (HAVE_ISEL) {
1338 int isel, tab;
1339
1340 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1341
1342 isel = tcg_to_isel[cond];
1343
1344 tcg_out_movi(s, type, arg0, 1);
1345 if (isel & 1) {
1346
1347 tab = TAB(arg0, 0, arg0);
1348 isel &= ~1;
1349 } else {
1350
1351 tcg_out_movi(s, type, TCG_REG_R0, 0);
1352 tab = TAB(arg0, arg0, TCG_REG_R0);
1353 }
1354 tcg_out32(s, isel | tab);
1355 return;
1356 }
1357
1358 switch (cond) {
1359 case TCG_COND_EQ:
1360 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1361 tcg_out_setcond_eq0(s, type, arg0, arg1);
1362 return;
1363
1364 case TCG_COND_NE:
1365 arg1 = tcg_gen_setcond_xor(s, arg1, arg2, const_arg2);
1366
1367 if (type == TCG_TYPE_I32) {
1368 tcg_out_ext32u(s, TCG_REG_R0, arg1);
1369 arg1 = TCG_REG_R0;
1370 }
1371 tcg_out_setcond_ne0(s, arg0, arg1);
1372 return;
1373
1374 case TCG_COND_GT:
1375 case TCG_COND_GTU:
1376 sh = 30;
1377 crop = 0;
1378 goto crtest;
1379
1380 case TCG_COND_LT:
1381 case TCG_COND_LTU:
1382 sh = 29;
1383 crop = 0;
1384 goto crtest;
1385
1386 case TCG_COND_GE:
1387 case TCG_COND_GEU:
1388 sh = 31;
1389 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_LT) | BB(7, CR_LT);
1390 goto crtest;
1391
1392 case TCG_COND_LE:
1393 case TCG_COND_LEU:
1394 sh = 31;
1395 crop = CRNOR | BT(7, CR_EQ) | BA(7, CR_GT) | BB(7, CR_GT);
1396 crtest:
1397 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1398 if (crop) {
1399 tcg_out32(s, crop);
1400 }
1401 tcg_out32(s, MFOCRF | RT(TCG_REG_R0) | FXM(7));
1402 tcg_out_rlw(s, RLWINM, arg0, TCG_REG_R0, sh, 31, 31);
1403 break;
1404
1405 default:
1406 tcg_abort();
1407 }
1408}
1409
1410static void tcg_out_bc(TCGContext *s, int bc, int label_index)
1411{
1412 TCGLabel *l = &s->labels[label_index];
1413
1414 if (l->has_value) {
1415 tcg_out32(s, bc | reloc_pc14_val(s->code_ptr, l->u.value));
1416 } else {
1417 tcg_out_reloc(s, s->code_ptr, R_PPC_REL14, label_index, 0);
1418 tcg_out_bc_noaddr(s, bc);
1419 }
1420}
1421
1422static void tcg_out_brcond(TCGContext *s, TCGCond cond,
1423 TCGArg arg1, TCGArg arg2, int const_arg2,
1424 int label_index, TCGType type)
1425{
1426 tcg_out_cmp(s, cond, arg1, arg2, const_arg2, 7, type);
1427 tcg_out_bc(s, tcg_to_bc[cond], label_index);
1428}
1429
1430static void tcg_out_movcond(TCGContext *s, TCGType type, TCGCond cond,
1431 TCGArg dest, TCGArg c1, TCGArg c2, TCGArg v1,
1432 TCGArg v2, bool const_c2)
1433{
1434
1435 if (v1 == 0 && v2 == 0) {
1436 tcg_out_movi(s, type, dest, 0);
1437 return;
1438 }
1439
1440 tcg_out_cmp(s, cond, c1, c2, const_c2, 7, type);
1441
1442 if (HAVE_ISEL) {
1443 int isel = tcg_to_isel[cond];
1444
1445
1446 if (isel & 1) {
1447 int t = v1;
1448 v1 = v2;
1449 v2 = t;
1450 isel &= ~1;
1451 }
1452
1453 if (v2 == 0) {
1454 tcg_out_movi(s, type, TCG_REG_R0, 0);
1455 }
1456 tcg_out32(s, isel | TAB(dest, v1, v2));
1457 } else {
1458 if (dest == v2) {
1459 cond = tcg_invert_cond(cond);
1460 v2 = v1;
1461 } else if (dest != v1) {
1462 if (v1 == 0) {
1463 tcg_out_movi(s, type, dest, 0);
1464 } else {
1465 tcg_out_mov(s, type, dest, v1);
1466 }
1467 }
1468
1469 tcg_out32(s, tcg_to_bc[cond] | 8);
1470 if (v2 == 0) {
1471 tcg_out_movi(s, type, dest, 0);
1472 } else {
1473 tcg_out_mov(s, type, dest, v2);
1474 }
1475 }
1476}
1477
1478void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr)
1479{
1480 TCGContext s;
1481 unsigned long patch_size;
1482
1483 s.code_ptr = (uint8_t *) jmp_addr;
1484 tcg_out_b(&s, 0, addr);
1485 patch_size = s.code_ptr - (uint8_t *) jmp_addr;
1486 flush_icache_range(jmp_addr, jmp_addr + patch_size);
1487}
1488
1489static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1490 const int *const_args)
1491{
1492 TCGArg a0, a1, a2;
1493 int c;
1494
1495 switch (opc) {
1496 case INDEX_op_exit_tb:
1497 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
1498 tcg_out_b(s, 0, (tcg_target_long)tb_ret_addr);
1499 break;
1500 case INDEX_op_goto_tb:
1501 if (s->tb_jmp_offset) {
1502
1503 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1504 s->code_ptr += 28;
1505 } else {
1506
1507 tcg_abort();
1508 }
1509 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1510 break;
1511 case INDEX_op_br:
1512 {
1513 TCGLabel *l = &s->labels[args[0]];
1514
1515 if (l->has_value) {
1516 tcg_out_b(s, 0, l->u.value);
1517 } else {
1518 tcg_out_reloc(s, s->code_ptr, R_PPC_REL24, args[0], 0);
1519 tcg_out_b_noaddr(s, B);
1520 }
1521 }
1522 break;
1523 case INDEX_op_call:
1524 tcg_out_call(s, args[0], const_args[0]);
1525 break;
1526 case INDEX_op_movi_i32:
1527 tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1528 break;
1529 case INDEX_op_movi_i64:
1530 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1531 break;
1532 case INDEX_op_ld8u_i32:
1533 case INDEX_op_ld8u_i64:
1534 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1535 break;
1536 case INDEX_op_ld8s_i32:
1537 case INDEX_op_ld8s_i64:
1538 tcg_out_mem_long(s, LBZ, LBZX, args[0], args[1], args[2]);
1539 tcg_out32(s, EXTSB | RS(args[0]) | RA(args[0]));
1540 break;
1541 case INDEX_op_ld16u_i32:
1542 case INDEX_op_ld16u_i64:
1543 tcg_out_mem_long(s, LHZ, LHZX, args[0], args[1], args[2]);
1544 break;
1545 case INDEX_op_ld16s_i32:
1546 case INDEX_op_ld16s_i64:
1547 tcg_out_mem_long(s, LHA, LHAX, args[0], args[1], args[2]);
1548 break;
1549 case INDEX_op_ld_i32:
1550 case INDEX_op_ld32u_i64:
1551 tcg_out_mem_long(s, LWZ, LWZX, args[0], args[1], args[2]);
1552 break;
1553 case INDEX_op_ld32s_i64:
1554 tcg_out_mem_long(s, LWA, LWAX, args[0], args[1], args[2]);
1555 break;
1556 case INDEX_op_ld_i64:
1557 tcg_out_mem_long(s, LD, LDX, args[0], args[1], args[2]);
1558 break;
1559 case INDEX_op_st8_i32:
1560 case INDEX_op_st8_i64:
1561 tcg_out_mem_long(s, STB, STBX, args[0], args[1], args[2]);
1562 break;
1563 case INDEX_op_st16_i32:
1564 case INDEX_op_st16_i64:
1565 tcg_out_mem_long(s, STH, STHX, args[0], args[1], args[2]);
1566 break;
1567 case INDEX_op_st_i32:
1568 case INDEX_op_st32_i64:
1569 tcg_out_mem_long(s, STW, STWX, args[0], args[1], args[2]);
1570 break;
1571 case INDEX_op_st_i64:
1572 tcg_out_mem_long(s, STD, STDX, args[0], args[1], args[2]);
1573 break;
1574
1575 case INDEX_op_add_i32:
1576 a0 = args[0], a1 = args[1], a2 = args[2];
1577 if (const_args[2]) {
1578 do_addi_32:
1579 tcg_out_mem_long(s, ADDI, ADD, a0, a1, (int32_t)a2);
1580 } else {
1581 tcg_out32(s, ADD | TAB(a0, a1, a2));
1582 }
1583 break;
1584 case INDEX_op_sub_i32:
1585 a0 = args[0], a1 = args[1], a2 = args[2];
1586 if (const_args[1]) {
1587 if (const_args[2]) {
1588 tcg_out_movi(s, TCG_TYPE_I32, a0, a1 - a2);
1589 } else {
1590 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
1591 }
1592 } else if (const_args[2]) {
1593 a2 = -a2;
1594 goto do_addi_32;
1595 } else {
1596 tcg_out32(s, SUBF | TAB(a0, a2, a1));
1597 }
1598 break;
1599
1600 case INDEX_op_and_i32:
1601 a0 = args[0], a1 = args[1], a2 = args[2];
1602 if (const_args[2]) {
1603 tcg_out_andi32(s, a0, a1, a2);
1604 } else {
1605 tcg_out32(s, AND | SAB(a1, a0, a2));
1606 }
1607 break;
1608 case INDEX_op_and_i64:
1609 a0 = args[0], a1 = args[1], a2 = args[2];
1610 if (const_args[2]) {
1611 tcg_out_andi64(s, a0, a1, a2);
1612 } else {
1613 tcg_out32(s, AND | SAB(a1, a0, a2));
1614 }
1615 break;
1616 case INDEX_op_or_i64:
1617 case INDEX_op_or_i32:
1618 a0 = args[0], a1 = args[1], a2 = args[2];
1619 if (const_args[2]) {
1620 tcg_out_ori32(s, a0, a1, a2);
1621 } else {
1622 tcg_out32(s, OR | SAB(a1, a0, a2));
1623 }
1624 break;
1625 case INDEX_op_xor_i64:
1626 case INDEX_op_xor_i32:
1627 a0 = args[0], a1 = args[1], a2 = args[2];
1628 if (const_args[2]) {
1629 tcg_out_xori32(s, a0, a1, a2);
1630 } else {
1631 tcg_out32(s, XOR | SAB(a1, a0, a2));
1632 }
1633 break;
1634 case INDEX_op_andc_i32:
1635 a0 = args[0], a1 = args[1], a2 = args[2];
1636 if (const_args[2]) {
1637 tcg_out_andi32(s, a0, a1, ~a2);
1638 } else {
1639 tcg_out32(s, ANDC | SAB(a1, a0, a2));
1640 }
1641 break;
1642 case INDEX_op_andc_i64:
1643 a0 = args[0], a1 = args[1], a2 = args[2];
1644 if (const_args[2]) {
1645 tcg_out_andi64(s, a0, a1, ~a2);
1646 } else {
1647 tcg_out32(s, ANDC | SAB(a1, a0, a2));
1648 }
1649 break;
1650 case INDEX_op_orc_i32:
1651 if (const_args[2]) {
1652 tcg_out_ori32(s, args[0], args[1], ~args[2]);
1653 break;
1654 }
1655
1656 case INDEX_op_orc_i64:
1657 tcg_out32(s, ORC | SAB(args[1], args[0], args[2]));
1658 break;
1659 case INDEX_op_eqv_i32:
1660 if (const_args[2]) {
1661 tcg_out_xori32(s, args[0], args[1], ~args[2]);
1662 break;
1663 }
1664
1665 case INDEX_op_eqv_i64:
1666 tcg_out32(s, EQV | SAB(args[1], args[0], args[2]));
1667 break;
1668 case INDEX_op_nand_i32:
1669 case INDEX_op_nand_i64:
1670 tcg_out32(s, NAND | SAB(args[1], args[0], args[2]));
1671 break;
1672 case INDEX_op_nor_i32:
1673 case INDEX_op_nor_i64:
1674 tcg_out32(s, NOR | SAB(args[1], args[0], args[2]));
1675 break;
1676
1677 case INDEX_op_mul_i32:
1678 a0 = args[0], a1 = args[1], a2 = args[2];
1679 if (const_args[2]) {
1680 tcg_out32(s, MULLI | TAI(a0, a1, a2));
1681 } else {
1682 tcg_out32(s, MULLW | TAB(a0, a1, a2));
1683 }
1684 break;
1685
1686 case INDEX_op_div_i32:
1687 tcg_out32(s, DIVW | TAB(args[0], args[1], args[2]));
1688 break;
1689
1690 case INDEX_op_divu_i32:
1691 tcg_out32(s, DIVWU | TAB(args[0], args[1], args[2]));
1692 break;
1693
1694 case INDEX_op_shl_i32:
1695 if (const_args[2]) {
1696 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31 - args[2]);
1697 } else {
1698 tcg_out32(s, SLW | SAB(args[1], args[0], args[2]));
1699 }
1700 break;
1701 case INDEX_op_shr_i32:
1702 if (const_args[2]) {
1703 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], args[2], 31);
1704 } else {
1705 tcg_out32(s, SRW | SAB(args[1], args[0], args[2]));
1706 }
1707 break;
1708 case INDEX_op_sar_i32:
1709 if (const_args[2]) {
1710 tcg_out32(s, SRAWI | RS(args[1]) | RA(args[0]) | SH(args[2]));
1711 } else {
1712 tcg_out32(s, SRAW | SAB(args[1], args[0], args[2]));
1713 }
1714 break;
1715 case INDEX_op_rotl_i32:
1716 if (const_args[2]) {
1717 tcg_out_rlw(s, RLWINM, args[0], args[1], args[2], 0, 31);
1718 } else {
1719 tcg_out32(s, RLWNM | SAB(args[1], args[0], args[2])
1720 | MB(0) | ME(31));
1721 }
1722 break;
1723 case INDEX_op_rotr_i32:
1724 if (const_args[2]) {
1725 tcg_out_rlw(s, RLWINM, args[0], args[1], 32 - args[2], 0, 31);
1726 } else {
1727 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 32));
1728 tcg_out32(s, RLWNM | SAB(args[1], args[0], TCG_REG_R0)
1729 | MB(0) | ME(31));
1730 }
1731 break;
1732
1733 case INDEX_op_brcond_i32:
1734 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1735 args[3], TCG_TYPE_I32);
1736 break;
1737
1738 case INDEX_op_brcond_i64:
1739 tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
1740 args[3], TCG_TYPE_I64);
1741 break;
1742
1743 case INDEX_op_neg_i32:
1744 case INDEX_op_neg_i64:
1745 tcg_out32(s, NEG | RT(args[0]) | RA(args[1]));
1746 break;
1747
1748 case INDEX_op_not_i32:
1749 case INDEX_op_not_i64:
1750 tcg_out32(s, NOR | SAB(args[1], args[0], args[1]));
1751 break;
1752
1753 case INDEX_op_add_i64:
1754 a0 = args[0], a1 = args[1], a2 = args[2];
1755 if (const_args[2]) {
1756 do_addi_64:
1757 tcg_out_mem_long(s, ADDI, ADD, a0, a1, a2);
1758 } else {
1759 tcg_out32(s, ADD | TAB(a0, a1, a2));
1760 }
1761 break;
1762 case INDEX_op_sub_i64:
1763 a0 = args[0], a1 = args[1], a2 = args[2];
1764 if (const_args[1]) {
1765 if (const_args[2]) {
1766 tcg_out_movi(s, TCG_TYPE_I64, a0, a1 - a2);
1767 } else {
1768 tcg_out32(s, SUBFIC | TAI(a0, a2, a1));
1769 }
1770 } else if (const_args[2]) {
1771 a2 = -a2;
1772 goto do_addi_64;
1773 } else {
1774 tcg_out32(s, SUBF | TAB(a0, a2, a1));
1775 }
1776 break;
1777
1778 case INDEX_op_shl_i64:
1779 if (const_args[2]) {
1780 tcg_out_shli64(s, args[0], args[1], args[2]);
1781 } else {
1782 tcg_out32(s, SLD | SAB(args[1], args[0], args[2]));
1783 }
1784 break;
1785 case INDEX_op_shr_i64:
1786 if (const_args[2]) {
1787 tcg_out_shri64(s, args[0], args[1], args[2]);
1788 } else {
1789 tcg_out32(s, SRD | SAB(args[1], args[0], args[2]));
1790 }
1791 break;
1792 case INDEX_op_sar_i64:
1793 if (const_args[2]) {
1794 int sh = SH(args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
1795 tcg_out32(s, SRADI | RA(args[0]) | RS(args[1]) | sh);
1796 } else {
1797 tcg_out32(s, SRAD | SAB(args[1], args[0], args[2]));
1798 }
1799 break;
1800 case INDEX_op_rotl_i64:
1801 if (const_args[2]) {
1802 tcg_out_rld(s, RLDICL, args[0], args[1], args[2], 0);
1803 } else {
1804 tcg_out32(s, RLDCL | SAB(args[1], args[0], args[2]) | MB64(0));
1805 }
1806 break;
1807 case INDEX_op_rotr_i64:
1808 if (const_args[2]) {
1809 tcg_out_rld(s, RLDICL, args[0], args[1], 64 - args[2], 0);
1810 } else {
1811 tcg_out32(s, SUBFIC | TAI(TCG_REG_R0, args[2], 64));
1812 tcg_out32(s, RLDCL | SAB(args[1], args[0], TCG_REG_R0) | MB64(0));
1813 }
1814 break;
1815
1816 case INDEX_op_mul_i64:
1817 a0 = args[0], a1 = args[1], a2 = args[2];
1818 if (const_args[2]) {
1819 tcg_out32(s, MULLI | TAI(a0, a1, a2));
1820 } else {
1821 tcg_out32(s, MULLD | TAB(a0, a1, a2));
1822 }
1823 break;
1824 case INDEX_op_div_i64:
1825 tcg_out32(s, DIVD | TAB(args[0], args[1], args[2]));
1826 break;
1827 case INDEX_op_divu_i64:
1828 tcg_out32(s, DIVDU | TAB(args[0], args[1], args[2]));
1829 break;
1830
1831 case INDEX_op_qemu_ld_i32:
1832 case INDEX_op_qemu_ld_i64:
1833 tcg_out_qemu_ld(s, args[0], args[1], args[2], args[3]);
1834 break;
1835 case INDEX_op_qemu_st_i32:
1836 case INDEX_op_qemu_st_i64:
1837 tcg_out_qemu_st(s, args[0], args[1], args[2], args[3]);
1838 break;
1839
1840 case INDEX_op_ext8s_i32:
1841 case INDEX_op_ext8s_i64:
1842 c = EXTSB;
1843 goto gen_ext;
1844 case INDEX_op_ext16s_i32:
1845 case INDEX_op_ext16s_i64:
1846 c = EXTSH;
1847 goto gen_ext;
1848 case INDEX_op_ext32s_i64:
1849 c = EXTSW;
1850 goto gen_ext;
1851 gen_ext:
1852 tcg_out32(s, c | RS(args[1]) | RA(args[0]));
1853 break;
1854
1855 case INDEX_op_setcond_i32:
1856 tcg_out_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
1857 const_args[2]);
1858 break;
1859 case INDEX_op_setcond_i64:
1860 tcg_out_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
1861 const_args[2]);
1862 break;
1863
1864 case INDEX_op_bswap16_i32:
1865 case INDEX_op_bswap16_i64:
1866 a0 = args[0], a1 = args[1];
1867
1868 if (a0 != a1) {
1869
1870 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
1871
1872 tcg_out_rlw(s, RLWIMI, a0, a1, 8, 16, 23);
1873 } else {
1874
1875 tcg_out_rlw(s, RLWINM, TCG_REG_R0, a1, 8, 16, 23);
1876
1877 tcg_out_rlw(s, RLWINM, a0, a1, 24, 24, 31);
1878
1879 tcg_out32(s, OR | SAB(TCG_REG_R0, a0, a0));
1880 }
1881 break;
1882
1883 case INDEX_op_bswap32_i32:
1884 case INDEX_op_bswap32_i64:
1885
1886 a1 = args[1];
1887 a0 = args[0] == a1 ? TCG_REG_R0 : args[0];
1888
1889
1890
1891 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
1892
1893 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
1894
1895 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
1896
1897 if (a0 == TCG_REG_R0) {
1898 tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1899 }
1900 break;
1901
1902 case INDEX_op_bswap64_i64:
1903 a0 = args[0], a1 = args[1], a2 = TCG_REG_R0;
1904 if (a0 == a1) {
1905 a0 = TCG_REG_R0;
1906 a2 = a1;
1907 }
1908
1909
1910
1911 tcg_out_rlw(s, RLWINM, a0, a1, 8, 0, 31);
1912
1913 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 0, 7);
1914
1915 tcg_out_rlw(s, RLWIMI, a0, a1, 24, 16, 23);
1916
1917
1918
1919 tcg_out_rld(s, RLDICL, a0, a0, 32, 0);
1920 tcg_out_rld(s, RLDICL, a2, a1, 32, 0);
1921
1922
1923 tcg_out_rlw(s, RLWIMI, a0, a2, 8, 0, 31);
1924
1925 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 0, 7);
1926
1927 tcg_out_rlw(s, RLWIMI, a0, a2, 24, 16, 23);
1928
1929 if (a0 == 0) {
1930 tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1931 }
1932 break;
1933
1934 case INDEX_op_deposit_i32:
1935 if (const_args[2]) {
1936 uint32_t mask = ((2u << (args[4] - 1)) - 1) << args[3];
1937 tcg_out_andi32(s, args[0], args[0], ~mask);
1938 } else {
1939 tcg_out_rlw(s, RLWIMI, args[0], args[2], args[3],
1940 32 - args[3] - args[4], 31 - args[3]);
1941 }
1942 break;
1943 case INDEX_op_deposit_i64:
1944 if (const_args[2]) {
1945 uint64_t mask = ((2ull << (args[4] - 1)) - 1) << args[3];
1946 tcg_out_andi64(s, args[0], args[0], ~mask);
1947 } else {
1948 tcg_out_rld(s, RLDIMI, args[0], args[2], args[3],
1949 64 - args[3] - args[4]);
1950 }
1951 break;
1952
1953 case INDEX_op_movcond_i32:
1954 tcg_out_movcond(s, TCG_TYPE_I32, args[5], args[0], args[1], args[2],
1955 args[3], args[4], const_args[2]);
1956 break;
1957 case INDEX_op_movcond_i64:
1958 tcg_out_movcond(s, TCG_TYPE_I64, args[5], args[0], args[1], args[2],
1959 args[3], args[4], const_args[2]);
1960 break;
1961
1962 case INDEX_op_add2_i64:
1963
1964
1965
1966 a0 = args[0], a1 = args[1];
1967 if (a0 == args[3] || (!const_args[5] && a0 == args[5])) {
1968 a0 = TCG_REG_R0;
1969 }
1970 if (const_args[4]) {
1971 tcg_out32(s, ADDIC | TAI(a0, args[2], args[4]));
1972 } else {
1973 tcg_out32(s, ADDC | TAB(a0, args[2], args[4]));
1974 }
1975 if (const_args[5]) {
1976 tcg_out32(s, (args[5] ? ADDME : ADDZE) | RT(a1) | RA(args[3]));
1977 } else {
1978 tcg_out32(s, ADDE | TAB(a1, args[3], args[5]));
1979 }
1980 if (a0 != args[0]) {
1981 tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
1982 }
1983 break;
1984
1985 case INDEX_op_sub2_i64:
1986 a0 = args[0], a1 = args[1];
1987 if (a0 == args[5] || (!const_args[4] && a0 == args[4])) {
1988 a0 = TCG_REG_R0;
1989 }
1990 if (const_args[2]) {
1991 tcg_out32(s, SUBFIC | TAI(a0, args[3], args[2]));
1992 } else {
1993 tcg_out32(s, SUBFC | TAB(a0, args[3], args[2]));
1994 }
1995 if (const_args[4]) {
1996 tcg_out32(s, (args[4] ? SUBFME : SUBFZE) | RT(a1) | RA(args[5]));
1997 } else {
1998 tcg_out32(s, SUBFE | TAB(a1, args[5], args[4]));
1999 }
2000 if (a0 != args[0]) {
2001 tcg_out_mov(s, TCG_TYPE_I64, args[0], a0);
2002 }
2003 break;
2004
2005 case INDEX_op_muluh_i64:
2006 tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
2007 break;
2008 case INDEX_op_mulsh_i64:
2009 tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
2010 break;
2011
2012 default:
2013 tcg_dump_ops(s);
2014 tcg_abort();
2015 }
2016}
2017
2018static const TCGTargetOpDef ppc_op_defs[] = {
2019 { INDEX_op_exit_tb, { } },
2020 { INDEX_op_goto_tb, { } },
2021 { INDEX_op_call, { "ri" } },
2022 { INDEX_op_br, { } },
2023
2024 { INDEX_op_mov_i32, { "r", "r" } },
2025 { INDEX_op_mov_i64, { "r", "r" } },
2026 { INDEX_op_movi_i32, { "r" } },
2027 { INDEX_op_movi_i64, { "r" } },
2028
2029 { INDEX_op_ld8u_i32, { "r", "r" } },
2030 { INDEX_op_ld8s_i32, { "r", "r" } },
2031 { INDEX_op_ld16u_i32, { "r", "r" } },
2032 { INDEX_op_ld16s_i32, { "r", "r" } },
2033 { INDEX_op_ld_i32, { "r", "r" } },
2034 { INDEX_op_ld_i64, { "r", "r" } },
2035 { INDEX_op_st8_i32, { "r", "r" } },
2036 { INDEX_op_st8_i64, { "r", "r" } },
2037 { INDEX_op_st16_i32, { "r", "r" } },
2038 { INDEX_op_st16_i64, { "r", "r" } },
2039 { INDEX_op_st_i32, { "r", "r" } },
2040 { INDEX_op_st_i64, { "r", "r" } },
2041 { INDEX_op_st32_i64, { "r", "r" } },
2042
2043 { INDEX_op_ld8u_i64, { "r", "r" } },
2044 { INDEX_op_ld8s_i64, { "r", "r" } },
2045 { INDEX_op_ld16u_i64, { "r", "r" } },
2046 { INDEX_op_ld16s_i64, { "r", "r" } },
2047 { INDEX_op_ld32u_i64, { "r", "r" } },
2048 { INDEX_op_ld32s_i64, { "r", "r" } },
2049
2050 { INDEX_op_add_i32, { "r", "r", "ri" } },
2051 { INDEX_op_mul_i32, { "r", "r", "rI" } },
2052 { INDEX_op_div_i32, { "r", "r", "r" } },
2053 { INDEX_op_divu_i32, { "r", "r", "r" } },
2054 { INDEX_op_sub_i32, { "r", "rI", "ri" } },
2055 { INDEX_op_and_i32, { "r", "r", "ri" } },
2056 { INDEX_op_or_i32, { "r", "r", "ri" } },
2057 { INDEX_op_xor_i32, { "r", "r", "ri" } },
2058 { INDEX_op_andc_i32, { "r", "r", "ri" } },
2059 { INDEX_op_orc_i32, { "r", "r", "ri" } },
2060 { INDEX_op_eqv_i32, { "r", "r", "ri" } },
2061 { INDEX_op_nand_i32, { "r", "r", "r" } },
2062 { INDEX_op_nor_i32, { "r", "r", "r" } },
2063
2064 { INDEX_op_shl_i32, { "r", "r", "ri" } },
2065 { INDEX_op_shr_i32, { "r", "r", "ri" } },
2066 { INDEX_op_sar_i32, { "r", "r", "ri" } },
2067 { INDEX_op_rotl_i32, { "r", "r", "ri" } },
2068 { INDEX_op_rotr_i32, { "r", "r", "ri" } },
2069
2070 { INDEX_op_brcond_i32, { "r", "ri" } },
2071 { INDEX_op_brcond_i64, { "r", "ri" } },
2072
2073 { INDEX_op_neg_i32, { "r", "r" } },
2074 { INDEX_op_not_i32, { "r", "r" } },
2075
2076 { INDEX_op_add_i64, { "r", "r", "rT" } },
2077 { INDEX_op_sub_i64, { "r", "rI", "rT" } },
2078 { INDEX_op_and_i64, { "r", "r", "ri" } },
2079 { INDEX_op_or_i64, { "r", "r", "rU" } },
2080 { INDEX_op_xor_i64, { "r", "r", "rU" } },
2081 { INDEX_op_andc_i64, { "r", "r", "ri" } },
2082 { INDEX_op_orc_i64, { "r", "r", "r" } },
2083 { INDEX_op_eqv_i64, { "r", "r", "r" } },
2084 { INDEX_op_nand_i64, { "r", "r", "r" } },
2085 { INDEX_op_nor_i64, { "r", "r", "r" } },
2086
2087 { INDEX_op_shl_i64, { "r", "r", "ri" } },
2088 { INDEX_op_shr_i64, { "r", "r", "ri" } },
2089 { INDEX_op_sar_i64, { "r", "r", "ri" } },
2090 { INDEX_op_rotl_i64, { "r", "r", "ri" } },
2091 { INDEX_op_rotr_i64, { "r", "r", "ri" } },
2092
2093 { INDEX_op_mul_i64, { "r", "r", "rI" } },
2094 { INDEX_op_div_i64, { "r", "r", "r" } },
2095 { INDEX_op_divu_i64, { "r", "r", "r" } },
2096
2097 { INDEX_op_neg_i64, { "r", "r" } },
2098 { INDEX_op_not_i64, { "r", "r" } },
2099
2100 { INDEX_op_qemu_ld_i32, { "r", "L" } },
2101 { INDEX_op_qemu_ld_i64, { "r", "L" } },
2102 { INDEX_op_qemu_st_i32, { "S", "S" } },
2103 { INDEX_op_qemu_st_i64, { "S", "S" } },
2104
2105 { INDEX_op_ext8s_i32, { "r", "r" } },
2106 { INDEX_op_ext16s_i32, { "r", "r" } },
2107 { INDEX_op_ext8s_i64, { "r", "r" } },
2108 { INDEX_op_ext16s_i64, { "r", "r" } },
2109 { INDEX_op_ext32s_i64, { "r", "r" } },
2110
2111 { INDEX_op_setcond_i32, { "r", "r", "ri" } },
2112 { INDEX_op_setcond_i64, { "r", "r", "ri" } },
2113 { INDEX_op_movcond_i32, { "r", "r", "ri", "rZ", "rZ" } },
2114 { INDEX_op_movcond_i64, { "r", "r", "ri", "rZ", "rZ" } },
2115
2116 { INDEX_op_bswap16_i32, { "r", "r" } },
2117 { INDEX_op_bswap16_i64, { "r", "r" } },
2118 { INDEX_op_bswap32_i32, { "r", "r" } },
2119 { INDEX_op_bswap32_i64, { "r", "r" } },
2120 { INDEX_op_bswap64_i64, { "r", "r" } },
2121
2122 { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
2123 { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
2124
2125 { INDEX_op_add2_i64, { "r", "r", "r", "r", "rI", "rZM" } },
2126 { INDEX_op_sub2_i64, { "r", "r", "rI", "r", "rZM", "r" } },
2127 { INDEX_op_mulsh_i64, { "r", "r", "r" } },
2128 { INDEX_op_muluh_i64, { "r", "r", "r" } },
2129
2130 { -1 },
2131};
2132
2133static void tcg_target_init(TCGContext *s)
2134{
2135#ifdef CONFIG_GETAUXVAL
2136 unsigned long hwcap = getauxval(AT_HWCAP);
2137 if (hwcap & PPC_FEATURE_ARCH_2_06) {
2138 have_isa_2_06 = true;
2139 }
2140#endif
2141
2142 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
2143 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
2144 tcg_regset_set32(tcg_target_call_clobber_regs, 0,
2145 (1 << TCG_REG_R0) |
2146 (1 << TCG_REG_R2) |
2147 (1 << TCG_REG_R3) |
2148 (1 << TCG_REG_R4) |
2149 (1 << TCG_REG_R5) |
2150 (1 << TCG_REG_R6) |
2151 (1 << TCG_REG_R7) |
2152 (1 << TCG_REG_R8) |
2153 (1 << TCG_REG_R9) |
2154 (1 << TCG_REG_R10) |
2155 (1 << TCG_REG_R11) |
2156 (1 << TCG_REG_R12));
2157
2158 tcg_regset_clear(s->reserved_regs);
2159 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
2160 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);
2161 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R2);
2162#ifdef __APPLE__
2163 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R11);
2164#endif
2165 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
2166
2167 tcg_add_target_add_op_defs(ppc_op_defs);
2168}
2169
2170typedef struct {
2171 DebugFrameCIE cie;
2172 DebugFrameFDEHeader fde;
2173 uint8_t fde_def_cfa[4];
2174 uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2 + 3];
2175} DebugFrame;
2176
2177
2178QEMU_BUILD_BUG_ON(FRAME_SIZE >= (1 << 14));
2179
2180#define ELF_HOST_MACHINE EM_PPC64
2181
2182static DebugFrame debug_frame = {
2183 .cie.len = sizeof(DebugFrameCIE)-4,
2184 .cie.id = -1,
2185 .cie.version = 1,
2186 .cie.code_align = 1,
2187 .cie.data_align = 0x78,
2188 .cie.return_column = 65,
2189
2190
2191 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
2192
2193 .fde_def_cfa = {
2194 12, 1,
2195 (FRAME_SIZE & 0x7f) | 0x80,
2196 (FRAME_SIZE >> 7)
2197 },
2198 .fde_reg_ofs = {
2199 0x11, 65, 0x7e,
2200 }
2201};
2202
2203void tcg_register_jit(void *buf, size_t buf_size)
2204{
2205 uint8_t *p = &debug_frame.fde_reg_ofs[3];
2206 int i;
2207
2208 for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); ++i, p += 2) {
2209 p[0] = 0x80 + tcg_target_callee_save_regs[i];
2210 p[1] = (FRAME_SIZE - (REG_SAVE_BOT + i * 8)) / 8;
2211 }
2212
2213 debug_frame.fde.func_start = (tcg_target_long) buf;
2214 debug_frame.fde.func_len = buf_size;
2215
2216 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
2217}
2218