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