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