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