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