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