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