2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
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
31 static uint8_t *tb_ret_addr
;
35 #if TARGET_LONG_BITS == 32
47 #ifdef CONFIG_USE_GUEST_BASE
48 #define TCG_GUEST_BASE_REG 30
50 #define TCG_GUEST_BASE_REG 0
54 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
90 static const int tcg_target_reg_alloc_order
[] = {
126 static const int tcg_target_call_iarg_regs
[] = {
137 static const int tcg_target_call_oarg_regs
[] = {
141 static const int tcg_target_callee_save_regs
[] = {
158 TCG_REG_R27
, /* currently used for the global env */
165 static uint32_t reloc_pc24_val (void *pc
, tcg_target_long target
)
167 tcg_target_long disp
;
169 disp
= target
- (tcg_target_long
) pc
;
170 if ((disp
<< 38) >> 38 != disp
)
173 return disp
& 0x3fffffc;
176 static void reloc_pc24 (void *pc
, tcg_target_long target
)
178 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0x3fffffc)
179 | reloc_pc24_val (pc
, target
);
182 static uint16_t reloc_pc14_val (void *pc
, tcg_target_long target
)
184 tcg_target_long disp
;
186 disp
= target
- (tcg_target_long
) pc
;
187 if (disp
!= (int16_t) disp
)
190 return disp
& 0xfffc;
193 static void reloc_pc14 (void *pc
, tcg_target_long target
)
195 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0xfffc)
196 | reloc_pc14_val (pc
, target
);
199 static void patch_reloc (uint8_t *code_ptr
, int type
,
200 tcg_target_long value
, tcg_target_long addend
)
205 reloc_pc14 (code_ptr
, value
);
208 reloc_pc24 (code_ptr
, value
);
215 /* parse target specific constraints */
216 static int target_parse_constraint (TCGArgConstraint
*ct
, const char **pct_str
)
222 case 'A': case 'B': case 'C': case 'D':
223 ct
->ct
|= TCG_CT_REG
;
224 tcg_regset_set_reg (ct
->u
.regs
, 3 + ct_str
[0] - 'A');
227 ct
->ct
|= TCG_CT_REG
;
228 tcg_regset_set32 (ct
->u
.regs
, 0, 0xffffffff);
230 case 'L': /* qemu_ld constraint */
231 ct
->ct
|= TCG_CT_REG
;
232 tcg_regset_set32 (ct
->u
.regs
, 0, 0xffffffff);
233 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R3
);
234 #ifdef CONFIG_SOFTMMU
235 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R4
);
236 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R5
);
239 case 'S': /* qemu_st constraint */
240 ct
->ct
|= TCG_CT_REG
;
241 tcg_regset_set32 (ct
->u
.regs
, 0, 0xffffffff);
242 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R3
);
243 #ifdef CONFIG_SOFTMMU
244 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R4
);
245 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R5
);
246 tcg_regset_reset_reg (ct
->u
.regs
, TCG_REG_R6
);
250 ct
->ct
|= TCG_CT_CONST_S16
;
253 ct
->ct
|= TCG_CT_CONST_U16
;
256 ct
->ct
|= TCG_CT_CONST_S32
;
259 ct
->ct
|= TCG_CT_CONST_U32
;
262 ct
->ct
|= TCG_CT_CONST_ZERO
;
272 /* test if a constant matches the constraint */
273 static int tcg_target_const_match (tcg_target_long val
,
274 const TCGArgConstraint
*arg_ct
)
277 if (ct
& TCG_CT_CONST
) {
279 } else if ((ct
& TCG_CT_CONST_S16
) && val
== (int16_t)val
) {
281 } else if ((ct
& TCG_CT_CONST_U16
) && val
== (uint16_t)val
) {
283 } else if ((ct
& TCG_CT_CONST_S32
) && val
== (int32_t)val
) {
285 } else if ((ct
& TCG_CT_CONST_U32
) && val
== (uint32_t)val
) {
287 } else if ((ct
& TCG_CT_CONST_ZERO
) && val
== 0) {
293 #define OPCD(opc) ((opc)<<26)
294 #define XO19(opc) (OPCD(19)|((opc)<<1))
295 #define XO30(opc) (OPCD(30)|((opc)<<2))
296 #define XO31(opc) (OPCD(31)|((opc)<<1))
297 #define XO58(opc) (OPCD(58)|(opc))
298 #define XO62(opc) (OPCD(62)|(opc))
302 #define LBZ OPCD( 34)
303 #define LHZ OPCD( 40)
304 #define LHA OPCD( 42)
305 #define LWZ OPCD( 32)
306 #define STB OPCD( 38)
307 #define STH OPCD( 44)
308 #define STW OPCD( 36)
311 #define STDU XO62( 1)
312 #define STDX XO31(149)
315 #define LDX XO31( 21)
318 #define LWAX XO31(341)
320 #define ADDIC OPCD( 12)
321 #define ADDI OPCD( 14)
322 #define ADDIS OPCD( 15)
323 #define ORI OPCD( 24)
324 #define ORIS OPCD( 25)
325 #define XORI OPCD( 26)
326 #define XORIS OPCD( 27)
327 #define ANDI OPCD( 28)
328 #define ANDIS OPCD( 29)
329 #define MULLI OPCD( 7)
330 #define CMPLI OPCD( 10)
331 #define CMPI OPCD( 11)
332 #define SUBFIC OPCD( 8)
334 #define LWZU OPCD( 33)
335 #define STWU OPCD( 37)
337 #define RLWINM OPCD( 21)
339 #define RLDICL XO30( 0)
340 #define RLDICR XO30( 1)
341 #define RLDIMI XO30( 3)
343 #define BCLR XO19( 16)
344 #define BCCTR XO19(528)
345 #define CRAND XO19(257)
346 #define CRANDC XO19(129)
347 #define CRNAND XO19(225)
348 #define CROR XO19(449)
349 #define CRNOR XO19( 33)
351 #define EXTSB XO31(954)
352 #define EXTSH XO31(922)
353 #define EXTSW XO31(986)
354 #define ADD XO31(266)
355 #define ADDE XO31(138)
356 #define ADDC XO31( 10)
357 #define AND XO31( 28)
358 #define SUBF XO31( 40)
359 #define SUBFC XO31( 8)
360 #define SUBFE XO31(136)
362 #define XOR XO31(316)
363 #define MULLW XO31(235)
364 #define MULHWU XO31( 11)
365 #define DIVW XO31(491)
366 #define DIVWU XO31(459)
368 #define CMPL XO31( 32)
369 #define LHBRX XO31(790)
370 #define LWBRX XO31(534)
371 #define STHBRX XO31(918)
372 #define STWBRX XO31(662)
373 #define MFSPR XO31(339)
374 #define MTSPR XO31(467)
375 #define SRAWI XO31(824)
376 #define NEG XO31(104)
377 #define MFCR XO31( 19)
378 #define NOR XO31(124)
379 #define CNTLZW XO31( 26)
380 #define CNTLZD XO31( 58)
382 #define MULLD XO31(233)
383 #define MULHD XO31( 73)
384 #define MULHDU XO31( 9)
385 #define DIVD XO31(489)
386 #define DIVDU XO31(457)
388 #define LBZX XO31( 87)
389 #define LHZX XO31(279)
390 #define LHAX XO31(343)
391 #define LWZX XO31( 23)
392 #define STBX XO31(215)
393 #define STHX XO31(407)
394 #define STWX XO31(151)
396 #define SPR(a,b) ((((a)<<5)|(b))<<11)
398 #define CTR SPR(9, 0)
400 #define SLW XO31( 24)
401 #define SRW XO31(536)
402 #define SRAW XO31(792)
404 #define SLD XO31( 27)
405 #define SRD XO31(539)
406 #define SRAD XO31(794)
407 #define SRADI XO31(413<<1)
410 #define TRAP (TW | TO (31))
412 #define RT(r) ((r)<<21)
413 #define RS(r) ((r)<<21)
414 #define RA(r) ((r)<<16)
415 #define RB(r) ((r)<<11)
416 #define TO(t) ((t)<<21)
417 #define SH(s) ((s)<<11)
418 #define MB(b) ((b)<<6)
419 #define ME(e) ((e)<<1)
420 #define BO(o) ((o)<<21)
421 #define MB64(b) ((b)<<5)
425 #define TAB(t, a, b) (RT(t) | RA(a) | RB(b))
426 #define SAB(s, a, b) (RS(s) | RA(a) | RB(b))
427 #define TAI(s, a, i) (RT(s) | RA(a) | ((i) & 0xffff))
428 #define SAI(s, a, i) (RS(s) | RA(a) | ((i) & 0xffff))
430 #define BF(n) ((n)<<23)
431 #define BI(n, c) (((c)+((n)*4))<<16)
432 #define BT(n, c) (((c)+((n)*4))<<21)
433 #define BA(n, c) (((c)+((n)*4))<<16)
434 #define BB(n, c) (((c)+((n)*4))<<11)
436 #define BO_COND_TRUE BO (12)
437 #define BO_COND_FALSE BO ( 4)
438 #define BO_ALWAYS BO (20)
447 static const uint32_t tcg_to_bc
[] = {
448 [TCG_COND_EQ
] = BC
| BI (7, CR_EQ
) | BO_COND_TRUE
,
449 [TCG_COND_NE
] = BC
| BI (7, CR_EQ
) | BO_COND_FALSE
,
450 [TCG_COND_LT
] = BC
| BI (7, CR_LT
) | BO_COND_TRUE
,
451 [TCG_COND_GE
] = BC
| BI (7, CR_LT
) | BO_COND_FALSE
,
452 [TCG_COND_LE
] = BC
| BI (7, CR_GT
) | BO_COND_FALSE
,
453 [TCG_COND_GT
] = BC
| BI (7, CR_GT
) | BO_COND_TRUE
,
454 [TCG_COND_LTU
] = BC
| BI (7, CR_LT
) | BO_COND_TRUE
,
455 [TCG_COND_GEU
] = BC
| BI (7, CR_LT
) | BO_COND_FALSE
,
456 [TCG_COND_LEU
] = BC
| BI (7, CR_GT
) | BO_COND_FALSE
,
457 [TCG_COND_GTU
] = BC
| BI (7, CR_GT
) | BO_COND_TRUE
,
460 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
461 TCGReg ret
, TCGReg arg
)
463 tcg_out32 (s
, OR
| SAB (arg
, ret
, arg
));
466 static inline void tcg_out_rld(TCGContext
*s
, int op
, TCGReg ra
, TCGReg rs
,
469 sh
= SH (sh
& 0x1f) | (((sh
>> 5) & 1) << 1);
470 mb
= MB64 ((mb
>> 5) | ((mb
<< 1) & 0x3f));
471 tcg_out32 (s
, op
| RA (ra
) | RS (rs
) | sh
| mb
);
474 static inline void tcg_out_rlw(TCGContext
*s
, int op
, TCGReg ra
, TCGReg rs
,
475 int sh
, int mb
, int me
)
477 tcg_out32(s
, op
| RA(ra
) | RS(rs
) | SH(sh
) | MB(mb
) | ME(me
));
480 static inline void tcg_out_ext32u(TCGContext
*s
, TCGReg dst
, TCGReg src
)
482 tcg_out_rld(s
, RLDICL
, dst
, src
, 0, 32);
485 static inline void tcg_out_shli64(TCGContext
*s
, TCGReg dst
, TCGReg src
, int c
)
487 tcg_out_rld(s
, RLDICR
, dst
, src
, c
, 63 - c
);
490 static inline void tcg_out_shri64(TCGContext
*s
, TCGReg dst
, TCGReg src
, int c
)
492 tcg_out_rld(s
, RLDICL
, dst
, src
, 64 - c
, c
);
495 static void tcg_out_movi32(TCGContext
*s
, TCGReg ret
, int32_t arg
)
497 if (arg
== (int16_t) arg
) {
498 tcg_out32(s
, ADDI
| TAI(ret
, 0, arg
));
500 tcg_out32(s
, ADDIS
| TAI(ret
, 0, arg
>> 16));
502 tcg_out32(s
, ORI
| SAI(ret
, ret
, arg
));
507 static void tcg_out_movi(TCGContext
*s
, TCGType type
, TCGReg ret
,
510 if (type
== TCG_TYPE_I32
|| arg
== (int32_t)arg
) {
511 tcg_out_movi32(s
, ret
, arg
);
512 } else if (arg
== (uint32_t)arg
&& !(arg
& 0x8000)) {
513 tcg_out32(s
, ADDI
| TAI(ret
, 0, arg
));
514 tcg_out32(s
, ORIS
| SAI(ret
, ret
, arg
>> 16));
516 int32_t high
= arg
>> 32;
517 tcg_out_movi32(s
, ret
, high
);
519 tcg_out_shli64(s
, ret
, ret
, 32);
521 if (arg
& 0xffff0000) {
522 tcg_out32(s
, ORIS
| SAI(ret
, ret
, arg
>> 16));
525 tcg_out32(s
, ORI
| SAI(ret
, ret
, arg
));
530 static inline bool mask_operand(uint32_t c
, int *mb
, int *me
)
534 /* Accept a bit pattern like:
538 Keep track of the transitions. */
539 if (c
== 0 || c
== -1) {
545 if (test
& (test
- 1)) {
550 *mb
= test
? clz32(test
& -test
) + 1 : 0;
554 static void tcg_out_andi32(TCGContext
*s
, TCGReg dst
, TCGReg src
, uint32_t c
)
558 if ((c
& 0xffff) == c
) {
559 tcg_out32(s
, ANDI
| SAI(src
, dst
, c
));
561 } else if ((c
& 0xffff0000) == c
) {
562 tcg_out32(s
, ANDIS
| SAI(src
, dst
, c
>> 16));
564 } else if (mask_operand(c
, &mb
, &me
)) {
565 tcg_out_rlw(s
, RLWINM
, dst
, src
, 0, mb
, me
);
567 tcg_out_movi(s
, TCG_TYPE_I32
, 0, c
);
568 tcg_out32(s
, AND
| SAB(src
, dst
, 0));
572 static void tcg_out_zori32(TCGContext
*s
, TCGReg dst
, TCGReg src
, uint32_t c
,
573 int op_lo
, int op_hi
)
576 tcg_out32(s
, op_hi
| SAI(src
, dst
, c
>> 16));
580 tcg_out32(s
, op_lo
| SAI(src
, dst
, c
));
585 static void tcg_out_ori32(TCGContext
*s
, TCGReg dst
, TCGReg src
, uint32_t c
)
587 tcg_out_zori32(s
, dst
, src
, c
, ORI
, ORIS
);
590 static void tcg_out_xori32(TCGContext
*s
, TCGReg dst
, TCGReg src
, uint32_t c
)
592 tcg_out_zori32(s
, dst
, src
, c
, XORI
, XORIS
);
595 static void tcg_out_b (TCGContext
*s
, int mask
, tcg_target_long target
)
597 tcg_target_long disp
;
599 disp
= target
- (tcg_target_long
) s
->code_ptr
;
600 if ((disp
<< 38) >> 38 == disp
)
601 tcg_out32 (s
, B
| (disp
& 0x3fffffc) | mask
);
603 tcg_out_movi (s
, TCG_TYPE_I64
, 0, (tcg_target_long
) target
);
604 tcg_out32 (s
, MTSPR
| RS (0) | CTR
);
605 tcg_out32 (s
, BCCTR
| BO_ALWAYS
| mask
);
609 static void tcg_out_call (TCGContext
*s
, tcg_target_long arg
, int const_arg
)
613 tcg_out_b (s
, LK
, arg
);
616 tcg_out32 (s
, MTSPR
| RS (arg
) | LR
);
617 tcg_out32 (s
, BCLR
| BO_ALWAYS
| LK
);
624 tcg_out_movi (s
, TCG_TYPE_I64
, reg
, arg
);
628 tcg_out32 (s
, LD
| RT (0) | RA (reg
));
629 tcg_out32 (s
, MTSPR
| RA (0) | CTR
);
630 tcg_out32 (s
, LD
| RT (11) | RA (reg
) | 16);
631 tcg_out32 (s
, LD
| RT (2) | RA (reg
) | 8);
632 tcg_out32 (s
, BCCTR
| BO_ALWAYS
| LK
);
636 static void tcg_out_ldst(TCGContext
*s
, TCGReg ret
, TCGReg addr
,
637 int offset
, int op1
, int op2
)
639 if (offset
== (int16_t) offset
) {
640 tcg_out32(s
, op1
| TAI(ret
, addr
, offset
));
642 tcg_out_movi(s
, TCG_TYPE_I64
, 0, offset
);
643 tcg_out32(s
, op2
| TAB(ret
, addr
, 0));
647 static void tcg_out_ldsta(TCGContext
*s
, TCGReg ret
, TCGReg addr
,
648 int offset
, int op1
, int op2
)
650 if (offset
== (int16_t) (offset
& ~3)) {
651 tcg_out32(s
, op1
| TAI(ret
, addr
, offset
));
653 tcg_out_movi(s
, TCG_TYPE_I64
, 0, offset
);
654 tcg_out32(s
, op2
| TAB(ret
, addr
, 0));
658 #if defined (CONFIG_SOFTMMU)
660 #include "exec/softmmu_defs.h"
662 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
664 static const void * const qemu_ld_helpers
[4] = {
671 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
672 uintxx_t val, int mmu_idx) */
673 static const void * const qemu_st_helpers
[4] = {
680 static void tcg_out_tlb_read(TCGContext
*s
, TCGReg r0
, TCGReg r1
, TCGReg r2
,
681 TCGReg addr_reg
, int s_bits
, int offset
)
683 #if TARGET_LONG_BITS == 32
684 tcg_out_ext32u(s
, addr_reg
, addr_reg
);
686 tcg_out_rlw(s
, RLWINM
, r0
, addr_reg
,
687 32 - (TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
),
688 32 - (CPU_TLB_BITS
+ CPU_TLB_ENTRY_BITS
),
689 31 - CPU_TLB_ENTRY_BITS
);
690 tcg_out32(s
, ADD
| TAB(r0
, r0
, TCG_AREG0
));
691 tcg_out32(s
, LWZU
| TAI(r1
, r0
, offset
));
692 tcg_out_rlw(s
, RLWINM
, r2
, addr_reg
, 0,
693 (32 - s_bits
) & 31, 31 - TARGET_PAGE_BITS
);
695 tcg_out_rld (s
, RLDICL
, r0
, addr_reg
,
696 64 - TARGET_PAGE_BITS
,
698 tcg_out_shli64(s
, r0
, r0
, CPU_TLB_ENTRY_BITS
);
700 tcg_out32(s
, ADD
| TAB(r0
, r0
, TCG_AREG0
));
701 tcg_out32(s
, LD_ADDR
| TAI(r1
, r0
, offset
));
704 tcg_out_rld (s
, RLDICR
, r2
, addr_reg
, 0, 63 - TARGET_PAGE_BITS
);
707 tcg_out_rld (s
, RLDICL
, r2
, addr_reg
,
708 64 - TARGET_PAGE_BITS
,
709 TARGET_PAGE_BITS
- s_bits
);
710 tcg_out_rld (s
, RLDICL
, r2
, r2
, TARGET_PAGE_BITS
, 0);
716 static void tcg_out_qemu_ld (TCGContext
*s
, const TCGArg
*args
, int opc
)
718 TCGReg addr_reg
, data_reg
, r0
, r1
, rbase
;
720 #ifdef CONFIG_SOFTMMU
722 int mem_index
, s_bits
;
723 void *label1_ptr
, *label2_ptr
;
729 #ifdef CONFIG_SOFTMMU
738 tcg_out_tlb_read (s
, r0
, r1
, r2
, addr_reg
, s_bits
,
739 offsetof (CPUArchState
, tlb_table
[mem_index
][0].addr_read
));
741 tcg_out32 (s
, CMP
| BF (7) | RA (r2
) | RB (r1
) | CMP_L
);
743 label1_ptr
= s
->code_ptr
;
745 tcg_out32 (s
, BC
| BI (7, CR_EQ
) | BO_COND_TRUE
);
750 tcg_out_mov (s
, TCG_TYPE_I64
, ir
++, TCG_AREG0
);
751 tcg_out_mov (s
, TCG_TYPE_I64
, ir
++, addr_reg
);
752 tcg_out_movi (s
, TCG_TYPE_I64
, ir
++, mem_index
);
754 tcg_out_call (s
, (tcg_target_long
) qemu_ld_helpers
[s_bits
], 1);
758 tcg_out32 (s
, EXTSB
| RA (data_reg
) | RS (3));
761 tcg_out32 (s
, EXTSH
| RA (data_reg
) | RS (3));
764 tcg_out32 (s
, EXTSW
| RA (data_reg
) | RS (3));
771 tcg_out_mov (s
, TCG_TYPE_I64
, data_reg
, 3);
774 label2_ptr
= s
->code_ptr
;
777 /* label1: fast path */
779 reloc_pc14 (label1_ptr
, (tcg_target_long
) s
->code_ptr
);
782 /* r0 now contains &env->tlb_table[mem_index][index].addr_read */
783 tcg_out32(s
, LD
| TAI(r0
, r0
,
784 offsetof(CPUTLBEntry
, addend
)
785 - offsetof(CPUTLBEntry
, addr_read
)));
786 /* r0 = env->tlb_table[mem_index][index].addend */
787 tcg_out32(s
, ADD
| TAB(r0
, r0
, addr_reg
));
788 /* r0 = env->tlb_table[mem_index][index].addend + addr */
790 #else /* !CONFIG_SOFTMMU */
791 #if TARGET_LONG_BITS == 32
792 tcg_out_ext32u(s
, addr_reg
, addr_reg
);
796 rbase
= GUEST_BASE
? TCG_GUEST_BASE_REG
: 0;
799 #ifdef TARGET_WORDS_BIGENDIAN
807 tcg_out32 (s
, LBZX
| TAB (data_reg
, rbase
, r0
));
810 tcg_out32 (s
, LBZX
| TAB (data_reg
, rbase
, r0
));
811 tcg_out32 (s
, EXTSB
| RA (data_reg
) | RS (data_reg
));
815 tcg_out32 (s
, LHBRX
| TAB (data_reg
, rbase
, r0
));
817 tcg_out32 (s
, LHZX
| TAB (data_reg
, rbase
, r0
));
821 tcg_out32 (s
, LHBRX
| TAB (data_reg
, rbase
, r0
));
822 tcg_out32 (s
, EXTSH
| RA (data_reg
) | RS (data_reg
));
824 else tcg_out32 (s
, LHAX
| TAB (data_reg
, rbase
, r0
));
828 tcg_out32 (s
, LWBRX
| TAB (data_reg
, rbase
, r0
));
830 tcg_out32 (s
, LWZX
| TAB (data_reg
, rbase
, r0
));
834 tcg_out32 (s
, LWBRX
| TAB (data_reg
, rbase
, r0
));
835 tcg_out32 (s
, EXTSW
| RA (data_reg
) | RS (data_reg
));
837 else tcg_out32 (s
, LWAX
| TAB (data_reg
, rbase
, r0
));
840 #ifdef CONFIG_USE_GUEST_BASE
842 tcg_out32(s
, ADDI
| TAI(r1
, r0
, 4));
843 tcg_out32 (s
, LWBRX
| TAB (data_reg
, rbase
, r0
));
844 tcg_out32 (s
, LWBRX
| TAB ( r1
, rbase
, r1
));
845 tcg_out_rld (s
, RLDIMI
, data_reg
, r1
, 32, 0);
847 else tcg_out32 (s
, LDX
| TAB (data_reg
, rbase
, r0
));
850 tcg_out_movi32 (s
, 0, 4);
851 tcg_out32 (s
, LWBRX
| RT (data_reg
) | RB (r0
));
852 tcg_out32 (s
, LWBRX
| RT ( r1
) | RA (r0
));
853 tcg_out_rld (s
, RLDIMI
, data_reg
, r1
, 32, 0);
855 else tcg_out32 (s
, LD
| RT (data_reg
) | RA (r0
));
860 #ifdef CONFIG_SOFTMMU
861 reloc_pc24 (label2_ptr
, (tcg_target_long
) s
->code_ptr
);
865 static void tcg_out_qemu_st (TCGContext
*s
, const TCGArg
*args
, int opc
)
867 TCGReg addr_reg
, r0
, r1
, rbase
, data_reg
;
869 #ifdef CONFIG_SOFTMMU
872 void *label1_ptr
, *label2_ptr
;
878 #ifdef CONFIG_SOFTMMU
886 tcg_out_tlb_read (s
, r0
, r1
, r2
, addr_reg
, opc
,
887 offsetof (CPUArchState
, tlb_table
[mem_index
][0].addr_write
));
889 tcg_out32 (s
, CMP
| BF (7) | RA (r2
) | RB (r1
) | CMP_L
);
891 label1_ptr
= s
->code_ptr
;
893 tcg_out32 (s
, BC
| BI (7, CR_EQ
) | BO_COND_TRUE
);
898 tcg_out_mov (s
, TCG_TYPE_I64
, ir
++, TCG_AREG0
);
899 tcg_out_mov (s
, TCG_TYPE_I64
, ir
++, addr_reg
);
900 tcg_out_rld (s
, RLDICL
, ir
++, data_reg
, 0, 64 - (1 << (3 + opc
)));
901 tcg_out_movi (s
, TCG_TYPE_I64
, ir
++, mem_index
);
903 tcg_out_call (s
, (tcg_target_long
) qemu_st_helpers
[opc
], 1);
905 label2_ptr
= s
->code_ptr
;
908 /* label1: fast path */
910 reloc_pc14 (label1_ptr
, (tcg_target_long
) s
->code_ptr
);
916 | (offsetof (CPUTLBEntry
, addend
)
917 - offsetof (CPUTLBEntry
, addr_write
))
919 /* r0 = env->tlb_table[mem_index][index].addend */
920 tcg_out32(s
, ADD
| TAB(r0
, r0
, addr_reg
));
921 /* r0 = env->tlb_table[mem_index][index].addend + addr */
923 #else /* !CONFIG_SOFTMMU */
924 #if TARGET_LONG_BITS == 32
925 tcg_out_ext32u(s
, addr_reg
, addr_reg
);
929 rbase
= GUEST_BASE
? TCG_GUEST_BASE_REG
: 0;
932 #ifdef TARGET_WORDS_BIGENDIAN
939 tcg_out32 (s
, STBX
| SAB (data_reg
, rbase
, r0
));
943 tcg_out32 (s
, STHBRX
| SAB (data_reg
, rbase
, r0
));
945 tcg_out32 (s
, STHX
| SAB (data_reg
, rbase
, r0
));
949 tcg_out32 (s
, STWBRX
| SAB (data_reg
, rbase
, r0
));
951 tcg_out32 (s
, STWX
| SAB (data_reg
, rbase
, r0
));
955 tcg_out32 (s
, STWBRX
| SAB (data_reg
, rbase
, r0
));
956 tcg_out32(s
, ADDI
| TAI(r1
, r0
, 4));
957 tcg_out_shri64(s
, 0, data_reg
, 32);
958 tcg_out32 (s
, STWBRX
| SAB (0, rbase
, r1
));
960 else tcg_out32 (s
, STDX
| SAB (data_reg
, rbase
, r0
));
964 #ifdef CONFIG_SOFTMMU
965 reloc_pc24 (label2_ptr
, (tcg_target_long
) s
->code_ptr
);
969 static void tcg_target_qemu_prologue (TCGContext
*s
)
980 + 8 /* compiler doubleword */
981 + 8 /* link editor doubleword */
982 + 8 /* TOC save area */
983 + TCG_STATIC_CALL_ARGS_SIZE
984 + ARRAY_SIZE (tcg_target_callee_save_regs
) * 8
985 + CPU_TEMP_BUF_NLONGS
* sizeof(long)
987 frame_size
= (frame_size
+ 15) & ~15;
989 tcg_set_frame (s
, TCG_REG_CALL_STACK
, frame_size
990 - CPU_TEMP_BUF_NLONGS
* sizeof (long),
991 CPU_TEMP_BUF_NLONGS
* sizeof (long));
994 /* First emit adhoc function descriptor */
995 addr
= (uint64_t) s
->code_ptr
+ 24;
996 tcg_out32 (s
, addr
>> 32); tcg_out32 (s
, addr
); /* entry point */
997 s
->code_ptr
+= 16; /* skip TOC and environment pointer */
1001 tcg_out32 (s
, MFSPR
| RT (0) | LR
);
1002 tcg_out32 (s
, STDU
| RS (1) | RA (1) | (-frame_size
& 0xffff));
1003 for (i
= 0; i
< ARRAY_SIZE (tcg_target_callee_save_regs
); ++i
)
1005 | RS (tcg_target_callee_save_regs
[i
])
1007 | (i
* 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE
)
1010 tcg_out32 (s
, STD
| RS (0) | RA (1) | (frame_size
+ 16));
1012 #ifdef CONFIG_USE_GUEST_BASE
1014 tcg_out_movi (s
, TCG_TYPE_I64
, TCG_GUEST_BASE_REG
, GUEST_BASE
);
1015 tcg_regset_set_reg (s
->reserved_regs
, TCG_GUEST_BASE_REG
);
1019 tcg_out_mov (s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
1020 tcg_out32 (s
, MTSPR
| RS (tcg_target_call_iarg_regs
[1]) | CTR
);
1021 tcg_out32 (s
, BCCTR
| BO_ALWAYS
);
1024 tb_ret_addr
= s
->code_ptr
;
1026 for (i
= 0; i
< ARRAY_SIZE (tcg_target_callee_save_regs
); ++i
)
1028 | RT (tcg_target_callee_save_regs
[i
])
1030 | (i
* 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE
)
1033 tcg_out32(s
, LD
| TAI(0, 1, frame_size
+ 16));
1034 tcg_out32(s
, MTSPR
| RS(0) | LR
);
1035 tcg_out32(s
, ADDI
| TAI(1, 1, frame_size
));
1036 tcg_out32(s
, BCLR
| BO_ALWAYS
);
1039 static void tcg_out_ld (TCGContext
*s
, TCGType type
, TCGReg ret
, TCGReg arg1
,
1040 tcg_target_long arg2
)
1042 if (type
== TCG_TYPE_I32
)
1043 tcg_out_ldst (s
, ret
, arg1
, arg2
, LWZ
, LWZX
);
1045 tcg_out_ldsta (s
, ret
, arg1
, arg2
, LD
, LDX
);
1048 static void tcg_out_st (TCGContext
*s
, TCGType type
, TCGReg arg
, TCGReg arg1
,
1049 tcg_target_long arg2
)
1051 if (type
== TCG_TYPE_I32
)
1052 tcg_out_ldst (s
, arg
, arg1
, arg2
, STW
, STWX
);
1054 tcg_out_ldsta (s
, arg
, arg1
, arg2
, STD
, STDX
);
1057 static void tcg_out_cmp (TCGContext
*s
, int cond
, TCGArg arg1
, TCGArg arg2
,
1058 int const_arg2
, int cr
, int arch64
)
1067 if ((int16_t) arg2
== arg2
) {
1072 else if ((uint16_t) arg2
== arg2
) {
1087 if ((int16_t) arg2
== arg2
) {
1102 if ((uint16_t) arg2
== arg2
) {
1115 op
|= BF (cr
) | (arch64
<< 21);
1118 tcg_out32 (s
, op
| RA (arg1
) | (arg2
& 0xffff));
1121 tcg_out_movi (s
, TCG_TYPE_I64
, 0, arg2
);
1122 tcg_out32 (s
, op
| RA (arg1
) | RB (0));
1125 tcg_out32 (s
, op
| RA (arg1
) | RB (arg2
));
1130 static void tcg_out_setcond (TCGContext
*s
, TCGType type
, TCGCond cond
,
1131 TCGArg arg0
, TCGArg arg1
, TCGArg arg2
,
1144 if ((uint16_t) arg2
== arg2
) {
1145 tcg_out32(s
, XORI
| SAI(arg1
, 0, arg2
));
1148 tcg_out_movi (s
, type
, 0, arg2
);
1149 tcg_out32 (s
, XOR
| SAB (arg1
, 0, 0));
1155 tcg_out32 (s
, XOR
| SAB (arg1
, 0, arg2
));
1158 if (type
== TCG_TYPE_I64
) {
1159 tcg_out32 (s
, CNTLZD
| RS (arg
) | RA (0));
1160 tcg_out_rld (s
, RLDICL
, arg0
, 0, 58, 6);
1163 tcg_out32 (s
, CNTLZW
| RS (arg
) | RA (0));
1164 tcg_out_rlw(s
, RLWINM
, arg0
, 0, 27, 5, 31);
1175 if ((uint16_t) arg2
== arg2
) {
1176 tcg_out32(s
, XORI
| SAI(arg1
, 0, arg2
));
1178 tcg_out_movi (s
, type
, 0, arg2
);
1179 tcg_out32 (s
, XOR
| SAB (arg1
, 0, 0));
1185 tcg_out32 (s
, XOR
| SAB (arg1
, 0, arg2
));
1188 /* Make sure and discard the high 32-bits of the input. */
1189 if (type
== TCG_TYPE_I32
) {
1190 tcg_out32(s
, EXTSW
| RA(TCG_REG_R0
) | RS(arg
));
1194 if (arg
== arg1
&& arg1
== arg0
) {
1195 tcg_out32(s
, ADDIC
| TAI(0, arg
, -1));
1196 tcg_out32(s
, SUBFE
| TAB(arg0
, 0, arg
));
1199 tcg_out32(s
, ADDIC
| TAI(arg0
, arg
, -1));
1200 tcg_out32(s
, SUBFE
| TAB(arg0
, arg0
, arg
));
1219 crop
= CRNOR
| BT (7, CR_EQ
) | BA (7, CR_LT
) | BB (7, CR_LT
);
1225 crop
= CRNOR
| BT (7, CR_EQ
) | BA (7, CR_GT
) | BB (7, CR_GT
);
1227 tcg_out_cmp (s
, cond
, arg1
, arg2
, const_arg2
, 7, type
== TCG_TYPE_I64
);
1228 if (crop
) tcg_out32 (s
, crop
);
1229 tcg_out32 (s
, MFCR
| RT (0));
1230 tcg_out_rlw(s
, RLWINM
, arg0
, 0, sh
, 31, 31);
1238 static void tcg_out_bc (TCGContext
*s
, int bc
, int label_index
)
1240 TCGLabel
*l
= &s
->labels
[label_index
];
1243 tcg_out32 (s
, bc
| reloc_pc14_val (s
->code_ptr
, l
->u
.value
));
1245 uint16_t val
= *(uint16_t *) &s
->code_ptr
[2];
1247 /* Thanks to Andrzej Zaborowski */
1248 tcg_out32 (s
, bc
| (val
& 0xfffc));
1249 tcg_out_reloc (s
, s
->code_ptr
- 4, R_PPC_REL14
, label_index
, 0);
1253 static void tcg_out_brcond (TCGContext
*s
, TCGCond cond
,
1254 TCGArg arg1
, TCGArg arg2
, int const_arg2
,
1255 int label_index
, int arch64
)
1257 tcg_out_cmp (s
, cond
, arg1
, arg2
, const_arg2
, 7, arch64
);
1258 tcg_out_bc (s
, tcg_to_bc
[cond
], label_index
);
1261 void ppc_tb_set_jmp_target (unsigned long jmp_addr
, unsigned long addr
)
1264 unsigned long patch_size
;
1266 s
.code_ptr
= (uint8_t *) jmp_addr
;
1267 tcg_out_b (&s
, 0, addr
);
1268 patch_size
= s
.code_ptr
- (uint8_t *) jmp_addr
;
1269 flush_icache_range (jmp_addr
, jmp_addr
+ patch_size
);
1272 static void tcg_out_op (TCGContext
*s
, TCGOpcode opc
, const TCGArg
*args
,
1273 const int *const_args
)
1279 case INDEX_op_exit_tb
:
1280 tcg_out_movi (s
, TCG_TYPE_I64
, TCG_REG_R3
, args
[0]);
1281 tcg_out_b (s
, 0, (tcg_target_long
) tb_ret_addr
);
1283 case INDEX_op_goto_tb
:
1284 if (s
->tb_jmp_offset
) {
1285 /* direct jump method */
1287 s
->tb_jmp_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1293 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1297 TCGLabel
*l
= &s
->labels
[args
[0]];
1300 tcg_out_b (s
, 0, l
->u
.value
);
1303 uint32_t val
= *(uint32_t *) s
->code_ptr
;
1305 /* Thanks to Andrzej Zaborowski */
1306 tcg_out32 (s
, B
| (val
& 0x3fffffc));
1307 tcg_out_reloc (s
, s
->code_ptr
- 4, R_PPC_REL24
, args
[0], 0);
1312 tcg_out_call (s
, args
[0], const_args
[0]);
1314 case INDEX_op_movi_i32
:
1315 tcg_out_movi (s
, TCG_TYPE_I32
, args
[0], args
[1]);
1317 case INDEX_op_movi_i64
:
1318 tcg_out_movi (s
, TCG_TYPE_I64
, args
[0], args
[1]);
1320 case INDEX_op_ld8u_i32
:
1321 case INDEX_op_ld8u_i64
:
1322 tcg_out_ldst (s
, args
[0], args
[1], args
[2], LBZ
, LBZX
);
1324 case INDEX_op_ld8s_i32
:
1325 case INDEX_op_ld8s_i64
:
1326 tcg_out_ldst (s
, args
[0], args
[1], args
[2], LBZ
, LBZX
);
1327 tcg_out32 (s
, EXTSB
| RS (args
[0]) | RA (args
[0]));
1329 case INDEX_op_ld16u_i32
:
1330 case INDEX_op_ld16u_i64
:
1331 tcg_out_ldst (s
, args
[0], args
[1], args
[2], LHZ
, LHZX
);
1333 case INDEX_op_ld16s_i32
:
1334 case INDEX_op_ld16s_i64
:
1335 tcg_out_ldst (s
, args
[0], args
[1], args
[2], LHA
, LHAX
);
1337 case INDEX_op_ld_i32
:
1338 case INDEX_op_ld32u_i64
:
1339 tcg_out_ldst (s
, args
[0], args
[1], args
[2], LWZ
, LWZX
);
1341 case INDEX_op_ld32s_i64
:
1342 tcg_out_ldsta (s
, args
[0], args
[1], args
[2], LWA
, LWAX
);
1344 case INDEX_op_ld_i64
:
1345 tcg_out_ldsta (s
, args
[0], args
[1], args
[2], LD
, LDX
);
1347 case INDEX_op_st8_i32
:
1348 case INDEX_op_st8_i64
:
1349 tcg_out_ldst (s
, args
[0], args
[1], args
[2], STB
, STBX
);
1351 case INDEX_op_st16_i32
:
1352 case INDEX_op_st16_i64
:
1353 tcg_out_ldst (s
, args
[0], args
[1], args
[2], STH
, STHX
);
1355 case INDEX_op_st_i32
:
1356 case INDEX_op_st32_i64
:
1357 tcg_out_ldst (s
, args
[0], args
[1], args
[2], STW
, STWX
);
1359 case INDEX_op_st_i64
:
1360 tcg_out_ldsta (s
, args
[0], args
[1], args
[2], STD
, STDX
);
1363 case INDEX_op_add_i32
:
1364 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1365 if (const_args
[2]) {
1371 tcg_out32(s
, ADDIS
| TAI(a0
, a1
, h
>> 16));
1374 if (l
|| a0
!= a1
) {
1375 tcg_out32(s
, ADDI
| TAI(a0
, a1
, l
));
1378 tcg_out32(s
, ADD
| TAB(a0
, a1
, a2
));
1381 case INDEX_op_sub_i32
:
1382 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1383 if (const_args
[1]) {
1384 if (const_args
[2]) {
1385 tcg_out_movi(s
, TCG_TYPE_I32
, a0
, a1
- a2
);
1387 tcg_out32(s
, SUBFIC
| TAI(a0
, a2
, a1
));
1389 } else if (const_args
[2]) {
1393 tcg_out32(s
, SUBF
| TAB(a0
, a2
, a1
));
1397 case INDEX_op_and_i32
:
1398 if (const_args
[2]) {
1399 tcg_out_andi32(s
, args
[0], args
[1], args
[2]);
1401 tcg_out32(s
, AND
| SAB(args
[1], args
[0], args
[2]));
1404 case INDEX_op_and_i64
:
1405 if (const_args
[2]) {
1406 if ((args
[2] & 0xffff) == args
[2]) {
1407 tcg_out32(s
, ANDI
| SAI(args
[1], args
[0], args
[2]));
1408 } else if ((args
[2] & 0xffff0000) == args
[2]) {
1409 tcg_out32(s
, ANDIS
| SAI(args
[1], args
[0], args
[2] >> 16));
1411 tcg_out_movi (s
, (opc
== INDEX_op_and_i32
1415 tcg_out32 (s
, AND
| SAB (args
[1], args
[0], 0));
1419 tcg_out32 (s
, AND
| SAB (args
[1], args
[0], args
[2]));
1421 case INDEX_op_or_i64
:
1422 case INDEX_op_or_i32
:
1423 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1424 if (const_args
[2]) {
1425 tcg_out_ori32(s
, a0
, a1
, a2
);
1427 tcg_out32(s
, OR
| SAB(a1
, a0
, a2
));
1430 case INDEX_op_xor_i64
:
1431 case INDEX_op_xor_i32
:
1432 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1433 if (const_args
[2]) {
1434 tcg_out_xori32(s
, a0
, a1
, a2
);
1436 tcg_out32(s
, XOR
| SAB(a1
, a0
, a2
));
1440 case INDEX_op_mul_i32
:
1441 if (const_args
[2]) {
1442 if (args
[2] == (int16_t) args
[2])
1443 tcg_out32 (s
, MULLI
| RT (args
[0]) | RA (args
[1])
1444 | (args
[2] & 0xffff));
1446 tcg_out_movi (s
, TCG_TYPE_I32
, 0, args
[2]);
1447 tcg_out32 (s
, MULLW
| TAB (args
[0], args
[1], 0));
1451 tcg_out32 (s
, MULLW
| TAB (args
[0], args
[1], args
[2]));
1454 case INDEX_op_div_i32
:
1455 tcg_out32 (s
, DIVW
| TAB (args
[0], args
[1], args
[2]));
1458 case INDEX_op_divu_i32
:
1459 tcg_out32 (s
, DIVWU
| TAB (args
[0], args
[1], args
[2]));
1462 case INDEX_op_rem_i32
:
1463 tcg_out32 (s
, DIVW
| TAB (0, args
[1], args
[2]));
1464 tcg_out32 (s
, MULLW
| TAB (0, 0, args
[2]));
1465 tcg_out32 (s
, SUBF
| TAB (args
[0], 0, args
[1]));
1468 case INDEX_op_remu_i32
:
1469 tcg_out32 (s
, DIVWU
| TAB (0, args
[1], args
[2]));
1470 tcg_out32 (s
, MULLW
| TAB (0, 0, args
[2]));
1471 tcg_out32 (s
, SUBF
| TAB (args
[0], 0, args
[1]));
1474 case INDEX_op_shl_i32
:
1475 if (const_args
[2]) {
1476 tcg_out_rlw(s
, RLWINM
, args
[0], args
[1], args
[2], 0, 31 - args
[2]);
1478 tcg_out32 (s
, SLW
| SAB (args
[1], args
[0], args
[2]));
1481 case INDEX_op_shr_i32
:
1482 if (const_args
[2]) {
1483 tcg_out_rlw(s
, RLWINM
, args
[0], args
[1], 32 - args
[2], args
[2], 31);
1485 tcg_out32 (s
, SRW
| SAB (args
[1], args
[0], args
[2]));
1488 case INDEX_op_sar_i32
:
1490 tcg_out32 (s
, SRAWI
| RS (args
[1]) | RA (args
[0]) | SH (args
[2]));
1492 tcg_out32 (s
, SRAW
| SAB (args
[1], args
[0], args
[2]));
1495 case INDEX_op_brcond_i32
:
1496 tcg_out_brcond (s
, args
[2], args
[0], args
[1], const_args
[1], args
[3], 0);
1499 case INDEX_op_brcond_i64
:
1500 tcg_out_brcond (s
, args
[2], args
[0], args
[1], const_args
[1], args
[3], 1);
1503 case INDEX_op_neg_i32
:
1504 case INDEX_op_neg_i64
:
1505 tcg_out32 (s
, NEG
| RT (args
[0]) | RA (args
[1]));
1508 case INDEX_op_not_i32
:
1509 case INDEX_op_not_i64
:
1510 tcg_out32 (s
, NOR
| SAB (args
[1], args
[0], args
[1]));
1513 case INDEX_op_add_i64
:
1514 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1515 if (const_args
[2]) {
1518 /* We can always split any 32-bit signed constant into 3 pieces.
1519 Note the positive 0x80000000 coming from the sub_i64 path,
1520 handled with the same code we need for eg 0x7fff8000. */
1521 assert(a2
== (int32_t)a2
|| a2
== 0x80000000);
1525 if (h1
< 0 && (int64_t)a2
> 0) {
1529 assert((TCGArg
)h2
+ h1
+ l0
== a2
);
1532 tcg_out32(s
, ADDIS
| TAI(a0
, a1
, h2
>> 16));
1536 tcg_out32(s
, ADDIS
| TAI(a0
, a1
, h1
>> 16));
1539 if (l0
|| a0
!= a1
) {
1540 tcg_out32(s
, ADDI
| TAI(a0
, a1
, l0
));
1543 tcg_out32(s
, ADD
| TAB(a0
, a1
, a2
));
1546 case INDEX_op_sub_i64
:
1547 a0
= args
[0], a1
= args
[1], a2
= args
[2];
1548 if (const_args
[1]) {
1549 if (const_args
[2]) {
1550 tcg_out_movi(s
, TCG_TYPE_I64
, a0
, a1
- a2
);
1552 tcg_out32(s
, SUBFIC
| TAI(a0
, a2
, a1
));
1554 } else if (const_args
[2]) {
1558 tcg_out32(s
, SUBF
| TAB(a0
, a2
, a1
));
1562 case INDEX_op_shl_i64
:
1564 tcg_out_shli64(s
, args
[0], args
[1], args
[2]);
1566 tcg_out32 (s
, SLD
| SAB (args
[1], args
[0], args
[2]));
1568 case INDEX_op_shr_i64
:
1570 tcg_out_shri64(s
, args
[0], args
[1], args
[2]);
1572 tcg_out32 (s
, SRD
| SAB (args
[1], args
[0], args
[2]));
1574 case INDEX_op_sar_i64
:
1575 if (const_args
[2]) {
1576 int sh
= SH (args
[2] & 0x1f) | (((args
[2] >> 5) & 1) << 1);
1577 tcg_out32 (s
, SRADI
| RA (args
[0]) | RS (args
[1]) | sh
);
1580 tcg_out32 (s
, SRAD
| SAB (args
[1], args
[0], args
[2]));
1583 case INDEX_op_mul_i64
:
1584 tcg_out32 (s
, MULLD
| TAB (args
[0], args
[1], args
[2]));
1586 case INDEX_op_div_i64
:
1587 tcg_out32 (s
, DIVD
| TAB (args
[0], args
[1], args
[2]));
1589 case INDEX_op_divu_i64
:
1590 tcg_out32 (s
, DIVDU
| TAB (args
[0], args
[1], args
[2]));
1592 case INDEX_op_rem_i64
:
1593 tcg_out32 (s
, DIVD
| TAB (0, args
[1], args
[2]));
1594 tcg_out32 (s
, MULLD
| TAB (0, 0, args
[2]));
1595 tcg_out32 (s
, SUBF
| TAB (args
[0], 0, args
[1]));
1597 case INDEX_op_remu_i64
:
1598 tcg_out32 (s
, DIVDU
| TAB (0, args
[1], args
[2]));
1599 tcg_out32 (s
, MULLD
| TAB (0, 0, args
[2]));
1600 tcg_out32 (s
, SUBF
| TAB (args
[0], 0, args
[1]));
1603 case INDEX_op_qemu_ld8u
:
1604 tcg_out_qemu_ld (s
, args
, 0);
1606 case INDEX_op_qemu_ld8s
:
1607 tcg_out_qemu_ld (s
, args
, 0 | 4);
1609 case INDEX_op_qemu_ld16u
:
1610 tcg_out_qemu_ld (s
, args
, 1);
1612 case INDEX_op_qemu_ld16s
:
1613 tcg_out_qemu_ld (s
, args
, 1 | 4);
1615 case INDEX_op_qemu_ld32
:
1616 case INDEX_op_qemu_ld32u
:
1617 tcg_out_qemu_ld (s
, args
, 2);
1619 case INDEX_op_qemu_ld32s
:
1620 tcg_out_qemu_ld (s
, args
, 2 | 4);
1622 case INDEX_op_qemu_ld64
:
1623 tcg_out_qemu_ld (s
, args
, 3);
1625 case INDEX_op_qemu_st8
:
1626 tcg_out_qemu_st (s
, args
, 0);
1628 case INDEX_op_qemu_st16
:
1629 tcg_out_qemu_st (s
, args
, 1);
1631 case INDEX_op_qemu_st32
:
1632 tcg_out_qemu_st (s
, args
, 2);
1634 case INDEX_op_qemu_st64
:
1635 tcg_out_qemu_st (s
, args
, 3);
1638 case INDEX_op_ext8s_i32
:
1639 case INDEX_op_ext8s_i64
:
1642 case INDEX_op_ext16s_i32
:
1643 case INDEX_op_ext16s_i64
:
1646 case INDEX_op_ext32s_i64
:
1650 tcg_out32 (s
, c
| RS (args
[1]) | RA (args
[0]));
1653 case INDEX_op_ext32u_i64
:
1654 tcg_out_ext32u(s
, args
[0], args
[1]);
1657 case INDEX_op_setcond_i32
:
1658 tcg_out_setcond (s
, TCG_TYPE_I32
, args
[3], args
[0], args
[1], args
[2],
1661 case INDEX_op_setcond_i64
:
1662 tcg_out_setcond (s
, TCG_TYPE_I64
, args
[3], args
[0], args
[1], args
[2],
1672 static const TCGTargetOpDef ppc_op_defs
[] = {
1673 { INDEX_op_exit_tb
, { } },
1674 { INDEX_op_goto_tb
, { } },
1675 { INDEX_op_call
, { "ri" } },
1676 { INDEX_op_br
, { } },
1678 { INDEX_op_mov_i32
, { "r", "r" } },
1679 { INDEX_op_mov_i64
, { "r", "r" } },
1680 { INDEX_op_movi_i32
, { "r" } },
1681 { INDEX_op_movi_i64
, { "r" } },
1683 { INDEX_op_ld8u_i32
, { "r", "r" } },
1684 { INDEX_op_ld8s_i32
, { "r", "r" } },
1685 { INDEX_op_ld16u_i32
, { "r", "r" } },
1686 { INDEX_op_ld16s_i32
, { "r", "r" } },
1687 { INDEX_op_ld_i32
, { "r", "r" } },
1688 { INDEX_op_ld_i64
, { "r", "r" } },
1689 { INDEX_op_st8_i32
, { "r", "r" } },
1690 { INDEX_op_st8_i64
, { "r", "r" } },
1691 { INDEX_op_st16_i32
, { "r", "r" } },
1692 { INDEX_op_st16_i64
, { "r", "r" } },
1693 { INDEX_op_st_i32
, { "r", "r" } },
1694 { INDEX_op_st_i64
, { "r", "r" } },
1695 { INDEX_op_st32_i64
, { "r", "r" } },
1697 { INDEX_op_ld8u_i64
, { "r", "r" } },
1698 { INDEX_op_ld8s_i64
, { "r", "r" } },
1699 { INDEX_op_ld16u_i64
, { "r", "r" } },
1700 { INDEX_op_ld16s_i64
, { "r", "r" } },
1701 { INDEX_op_ld32u_i64
, { "r", "r" } },
1702 { INDEX_op_ld32s_i64
, { "r", "r" } },
1704 { INDEX_op_add_i32
, { "r", "r", "ri" } },
1705 { INDEX_op_mul_i32
, { "r", "r", "ri" } },
1706 { INDEX_op_div_i32
, { "r", "r", "r" } },
1707 { INDEX_op_divu_i32
, { "r", "r", "r" } },
1708 { INDEX_op_rem_i32
, { "r", "r", "r" } },
1709 { INDEX_op_remu_i32
, { "r", "r", "r" } },
1710 { INDEX_op_sub_i32
, { "r", "rI", "ri" } },
1711 { INDEX_op_and_i32
, { "r", "r", "ri" } },
1712 { INDEX_op_or_i32
, { "r", "r", "ri" } },
1713 { INDEX_op_xor_i32
, { "r", "r", "ri" } },
1715 { INDEX_op_shl_i32
, { "r", "r", "ri" } },
1716 { INDEX_op_shr_i32
, { "r", "r", "ri" } },
1717 { INDEX_op_sar_i32
, { "r", "r", "ri" } },
1719 { INDEX_op_brcond_i32
, { "r", "ri" } },
1720 { INDEX_op_brcond_i64
, { "r", "ri" } },
1722 { INDEX_op_neg_i32
, { "r", "r" } },
1723 { INDEX_op_not_i32
, { "r", "r" } },
1725 { INDEX_op_add_i64
, { "r", "r", "rT" } },
1726 { INDEX_op_sub_i64
, { "r", "rI", "rT" } },
1727 { INDEX_op_and_i64
, { "r", "r", "rU" } },
1728 { INDEX_op_or_i64
, { "r", "r", "rU" } },
1729 { INDEX_op_xor_i64
, { "r", "r", "rU" } },
1731 { INDEX_op_shl_i64
, { "r", "r", "ri" } },
1732 { INDEX_op_shr_i64
, { "r", "r", "ri" } },
1733 { INDEX_op_sar_i64
, { "r", "r", "ri" } },
1735 { INDEX_op_mul_i64
, { "r", "r", "r" } },
1736 { INDEX_op_div_i64
, { "r", "r", "r" } },
1737 { INDEX_op_divu_i64
, { "r", "r", "r" } },
1738 { INDEX_op_rem_i64
, { "r", "r", "r" } },
1739 { INDEX_op_remu_i64
, { "r", "r", "r" } },
1741 { INDEX_op_neg_i64
, { "r", "r" } },
1742 { INDEX_op_not_i64
, { "r", "r" } },
1744 { INDEX_op_qemu_ld8u
, { "r", "L" } },
1745 { INDEX_op_qemu_ld8s
, { "r", "L" } },
1746 { INDEX_op_qemu_ld16u
, { "r", "L" } },
1747 { INDEX_op_qemu_ld16s
, { "r", "L" } },
1748 { INDEX_op_qemu_ld32
, { "r", "L" } },
1749 { INDEX_op_qemu_ld32u
, { "r", "L" } },
1750 { INDEX_op_qemu_ld32s
, { "r", "L" } },
1751 { INDEX_op_qemu_ld64
, { "r", "L" } },
1753 { INDEX_op_qemu_st8
, { "S", "S" } },
1754 { INDEX_op_qemu_st16
, { "S", "S" } },
1755 { INDEX_op_qemu_st32
, { "S", "S" } },
1756 { INDEX_op_qemu_st64
, { "S", "S" } },
1758 { INDEX_op_ext8s_i32
, { "r", "r" } },
1759 { INDEX_op_ext16s_i32
, { "r", "r" } },
1760 { INDEX_op_ext8s_i64
, { "r", "r" } },
1761 { INDEX_op_ext16s_i64
, { "r", "r" } },
1762 { INDEX_op_ext32s_i64
, { "r", "r" } },
1763 { INDEX_op_ext32u_i64
, { "r", "r" } },
1765 { INDEX_op_setcond_i32
, { "r", "r", "ri" } },
1766 { INDEX_op_setcond_i64
, { "r", "r", "ri" } },
1771 static void tcg_target_init (TCGContext
*s
)
1773 tcg_regset_set32 (tcg_target_available_regs
[TCG_TYPE_I32
], 0, 0xffffffff);
1774 tcg_regset_set32 (tcg_target_available_regs
[TCG_TYPE_I64
], 0, 0xffffffff);
1775 tcg_regset_set32 (tcg_target_call_clobber_regs
, 0,
1787 (1 << TCG_REG_R10
) |
1788 (1 << TCG_REG_R11
) |
1792 tcg_regset_clear (s
->reserved_regs
);
1793 tcg_regset_set_reg (s
->reserved_regs
, TCG_REG_R0
);
1794 tcg_regset_set_reg (s
->reserved_regs
, TCG_REG_R1
);
1796 tcg_regset_set_reg (s
->reserved_regs
, TCG_REG_R2
);
1798 tcg_regset_set_reg (s
->reserved_regs
, TCG_REG_R13
);
1800 tcg_add_target_add_op_defs (ppc_op_defs
);