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_U32 0x100
27
static uint8_t *tb_ret_addr;
31
#if TARGET_LONG_BITS == 32
43
#ifdef CONFIG_USE_GUEST_BASE
44
#define TCG_GUEST_BASE_REG 30
46
#define TCG_GUEST_BASE_REG 0
50
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
86
static const int tcg_target_reg_alloc_order[] = {
122
static const int tcg_target_call_iarg_regs[] = {
133
static const int tcg_target_call_oarg_regs[2] = {
137
static const int tcg_target_callee_save_regs[] = {
154
TCG_REG_R27, /* currently used for the global env */
161
static uint32_t reloc_pc24_val (void *pc, tcg_target_long target)
163
tcg_target_long disp;
165
disp = target - (tcg_target_long) pc;
166
if ((disp << 38) >> 38 != disp)
169
return disp & 0x3fffffc;
172
static void reloc_pc24 (void *pc, tcg_target_long target)
174
*(uint32_t *) pc = (*(uint32_t *) pc & ~0x3fffffc)
175
| reloc_pc24_val (pc, target);
178
static uint16_t reloc_pc14_val (void *pc, tcg_target_long target)
180
tcg_target_long disp;
182
disp = target - (tcg_target_long) pc;
183
if (disp != (int16_t) disp)
186
return disp & 0xfffc;
189
static void reloc_pc14 (void *pc, tcg_target_long target)
191
*(uint32_t *) pc = (*(uint32_t *) pc & ~0xfffc)
192
| reloc_pc14_val (pc, target);
195
static void patch_reloc (uint8_t *code_ptr, int type,
196
tcg_target_long value, tcg_target_long addend)
201
reloc_pc14 (code_ptr, value);
204
reloc_pc24 (code_ptr, value);
211
/* maximum number of register used for input function arguments */
212
static int tcg_target_get_call_iarg_regs_count (int flags)
214
return ARRAY_SIZE (tcg_target_call_iarg_regs);
217
/* parse target specific constraints */
218
static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
224
case 'A': case 'B': case 'C': case 'D':
225
ct->ct |= TCG_CT_REG;
226
tcg_regset_set_reg (ct->u.regs, 3 + ct_str[0] - 'A');
229
ct->ct |= TCG_CT_REG;
230
tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
232
case 'L': /* qemu_ld constraint */
233
ct->ct |= TCG_CT_REG;
234
tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
235
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
236
#ifdef CONFIG_SOFTMMU
237
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
240
case 'S': /* qemu_st constraint */
241
ct->ct |= TCG_CT_REG;
242
tcg_regset_set32 (ct->u.regs, 0, 0xffffffff);
243
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
244
#ifdef CONFIG_SOFTMMU
245
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
246
tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
250
ct->ct |= TCG_CT_CONST_U32;
260
/* test if a constant matches the constraint */
261
static int tcg_target_const_match (tcg_target_long val,
262
const TCGArgConstraint *arg_ct)
267
if (ct & TCG_CT_CONST)
269
else if ((ct & TCG_CT_CONST_U32) && (val == (uint32_t) val))
274
#define OPCD(opc) ((opc)<<26)
275
#define XO19(opc) (OPCD(19)|((opc)<<1))
276
#define XO30(opc) (OPCD(30)|((opc)<<2))
277
#define XO31(opc) (OPCD(31)|((opc)<<1))
278
#define XO58(opc) (OPCD(58)|(opc))
279
#define XO62(opc) (OPCD(62)|(opc))
283
#define LBZ OPCD( 34)
284
#define LHZ OPCD( 40)
285
#define LHA OPCD( 42)
286
#define LWZ OPCD( 32)
287
#define STB OPCD( 38)
288
#define STH OPCD( 44)
289
#define STW OPCD( 36)
292
#define STDU XO62( 1)
293
#define STDX XO31(149)
296
#define LDX XO31( 21)
299
#define LWAX XO31(341)
301
#define ADDIC OPCD( 12)
302
#define ADDI OPCD( 14)
303
#define ADDIS OPCD( 15)
304
#define ORI OPCD( 24)
305
#define ORIS OPCD( 25)
306
#define XORI OPCD( 26)
307
#define XORIS OPCD( 27)
308
#define ANDI OPCD( 28)
309
#define ANDIS OPCD( 29)
310
#define MULLI OPCD( 7)
311
#define CMPLI OPCD( 10)
312
#define CMPI OPCD( 11)
314
#define LWZU OPCD( 33)
315
#define STWU OPCD( 37)
317
#define RLWINM OPCD( 21)
319
#define RLDICL XO30( 0)
320
#define RLDICR XO30( 1)
321
#define RLDIMI XO30( 3)
323
#define BCLR XO19( 16)
324
#define BCCTR XO19(528)
325
#define CRAND XO19(257)
326
#define CRANDC XO19(129)
327
#define CRNAND XO19(225)
328
#define CROR XO19(449)
329
#define CRNOR XO19( 33)
331
#define EXTSB XO31(954)
332
#define EXTSH XO31(922)
333
#define EXTSW XO31(986)
334
#define ADD XO31(266)
335
#define ADDE XO31(138)
336
#define ADDC XO31( 10)
337
#define AND XO31( 28)
338
#define SUBF XO31( 40)
339
#define SUBFC XO31( 8)
340
#define SUBFE XO31(136)
342
#define XOR XO31(316)
343
#define MULLW XO31(235)
344
#define MULHWU XO31( 11)
345
#define DIVW XO31(491)
346
#define DIVWU XO31(459)
348
#define CMPL XO31( 32)
349
#define LHBRX XO31(790)
350
#define LWBRX XO31(534)
351
#define STHBRX XO31(918)
352
#define STWBRX XO31(662)
353
#define MFSPR XO31(339)
354
#define MTSPR XO31(467)
355
#define SRAWI XO31(824)
356
#define NEG XO31(104)
357
#define MFCR XO31( 19)
358
#define CNTLZW XO31( 26)
359
#define CNTLZD XO31( 58)
361
#define MULLD XO31(233)
362
#define MULHD XO31( 73)
363
#define MULHDU XO31( 9)
364
#define DIVD XO31(489)
365
#define DIVDU XO31(457)
367
#define LBZX XO31( 87)
368
#define LHZX XO31(279)
369
#define LHAX XO31(343)
370
#define LWZX XO31( 23)
371
#define STBX XO31(215)
372
#define STHX XO31(407)
373
#define STWX XO31(151)
375
#define SPR(a,b) ((((a)<<5)|(b))<<11)
377
#define CTR SPR(9, 0)
379
#define SLW XO31( 24)
380
#define SRW XO31(536)
381
#define SRAW XO31(792)
383
#define SLD XO31( 27)
384
#define SRD XO31(539)
385
#define SRAD XO31(794)
386
#define SRADI XO31(413<<1)
389
#define TRAP (TW | TO (31))
391
#define RT(r) ((r)<<21)
392
#define RS(r) ((r)<<21)
393
#define RA(r) ((r)<<16)
394
#define RB(r) ((r)<<11)
395
#define TO(t) ((t)<<21)
396
#define SH(s) ((s)<<11)
397
#define MB(b) ((b)<<6)
398
#define ME(e) ((e)<<1)
399
#define BO(o) ((o)<<21)
400
#define MB64(b) ((b)<<5)
404
#define TAB(t,a,b) (RT(t) | RA(a) | RB(b))
405
#define SAB(s,a,b) (RS(s) | RA(a) | RB(b))
407
#define BF(n) ((n)<<23)
408
#define BI(n, c) (((c)+((n)*4))<<16)
409
#define BT(n, c) (((c)+((n)*4))<<21)
410
#define BA(n, c) (((c)+((n)*4))<<16)
411
#define BB(n, c) (((c)+((n)*4))<<11)
413
#define BO_COND_TRUE BO (12)
414
#define BO_COND_FALSE BO ( 4)
415
#define BO_ALWAYS BO (20)
424
static const uint32_t tcg_to_bc[10] = {
425
[TCG_COND_EQ] = BC | BI (7, CR_EQ) | BO_COND_TRUE,
426
[TCG_COND_NE] = BC | BI (7, CR_EQ) | BO_COND_FALSE,
427
[TCG_COND_LT] = BC | BI (7, CR_LT) | BO_COND_TRUE,
428
[TCG_COND_GE] = BC | BI (7, CR_LT) | BO_COND_FALSE,
429
[TCG_COND_LE] = BC | BI (7, CR_GT) | BO_COND_FALSE,
430
[TCG_COND_GT] = BC | BI (7, CR_GT) | BO_COND_TRUE,
431
[TCG_COND_LTU] = BC | BI (7, CR_LT) | BO_COND_TRUE,
432
[TCG_COND_GEU] = BC | BI (7, CR_LT) | BO_COND_FALSE,
433
[TCG_COND_LEU] = BC | BI (7, CR_GT) | BO_COND_FALSE,
434
[TCG_COND_GTU] = BC | BI (7, CR_GT) | BO_COND_TRUE,
437
static void tcg_out_mov (TCGContext *s, TCGType type, int ret, int arg)
439
tcg_out32 (s, OR | SAB (arg, ret, arg));
442
static void tcg_out_rld (TCGContext *s, int op, int ra, int rs, int sh, int mb)
444
sh = SH (sh & 0x1f) | (((sh >> 5) & 1) << 1);
445
mb = MB64 ((mb >> 5) | ((mb << 1) & 0x3f));
446
tcg_out32 (s, op | RA (ra) | RS (rs) | sh | mb);
449
static void tcg_out_movi32 (TCGContext *s, int ret, int32_t arg)
451
if (arg == (int16_t) arg)
452
tcg_out32 (s, ADDI | RT (ret) | RA (0) | (arg & 0xffff));
454
tcg_out32 (s, ADDIS | RT (ret) | RA (0) | ((arg >> 16) & 0xffff));
456
tcg_out32 (s, ORI | RS (ret) | RA (ret) | (arg & 0xffff));
460
static void tcg_out_movi (TCGContext *s, TCGType type,
461
int ret, tcg_target_long arg)
464
arg = type == TCG_TYPE_I32 ? arg & 0xffffffff : arg;
467
tcg_out_movi32 (s, ret, arg32);
470
if ((uint64_t) arg >> 32) {
471
uint16_t h16 = arg >> 16;
474
tcg_out_movi32 (s, ret, arg >> 32);
475
tcg_out_rld (s, RLDICR, ret, ret, 32, 31);
476
if (h16) tcg_out32 (s, ORIS | RS (ret) | RA (ret) | h16);
477
if (l16) tcg_out32 (s, ORI | RS (ret) | RA (ret) | l16);
480
tcg_out_movi32 (s, ret, arg32);
482
tcg_out_rld (s, RLDICL, ret, ret, 0, 32);
487
static void tcg_out_b (TCGContext *s, int mask, tcg_target_long target)
489
tcg_target_long disp;
491
disp = target - (tcg_target_long) s->code_ptr;
492
if ((disp << 38) >> 38 == disp)
493
tcg_out32 (s, B | (disp & 0x3fffffc) | mask);
495
tcg_out_movi (s, TCG_TYPE_I64, 0, (tcg_target_long) target);
496
tcg_out32 (s, MTSPR | RS (0) | CTR);
497
tcg_out32 (s, BCCTR | BO_ALWAYS | mask);
501
static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
505
tcg_out_b (s, LK, arg);
508
tcg_out32 (s, MTSPR | RS (arg) | LR);
509
tcg_out32 (s, BCLR | BO_ALWAYS | LK);
516
tcg_out_movi (s, TCG_TYPE_I64, reg, arg);
520
tcg_out32 (s, LD | RT (0) | RA (reg));
521
tcg_out32 (s, MTSPR | RA (0) | CTR);
522
tcg_out32 (s, LD | RT (11) | RA (reg) | 16);
523
tcg_out32 (s, LD | RT (2) | RA (reg) | 8);
524
tcg_out32 (s, BCCTR | BO_ALWAYS | LK);
528
static void tcg_out_ldst (TCGContext *s, int ret, int addr,
529
int offset, int op1, int op2)
531
if (offset == (int16_t) offset)
532
tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
534
tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
535
tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
539
static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
540
int offset, int op1, int op2)
542
if (offset == (int16_t) (offset & ~3))
543
tcg_out32 (s, op1 | RT (ret) | RA (addr) | (offset & 0xffff));
545
tcg_out_movi (s, TCG_TYPE_I64, 0, offset);
546
tcg_out32 (s, op2 | RT (ret) | RA (addr) | RB (0));
550
#if defined (CONFIG_SOFTMMU)
552
#include "../../softmmu_defs.h"
554
static void *qemu_ld_helpers[4] = {
561
static void *qemu_st_helpers[4] = {
568
static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
569
int addr_reg, int s_bits, int offset)
571
#if TARGET_LONG_BITS == 32
572
tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
574
tcg_out32 (s, (RLWINM
577
| SH (32 - (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS))
578
| MB (32 - (CPU_TLB_BITS + CPU_TLB_ENTRY_BITS))
579
| ME (31 - CPU_TLB_ENTRY_BITS)
582
tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (TCG_AREG0));
583
tcg_out32 (s, (LWZU | RT (r1) | RA (r0) | offset));
584
tcg_out32 (s, (RLWINM
588
| MB ((32 - s_bits) & 31)
589
| ME (31 - TARGET_PAGE_BITS)
593
tcg_out_rld (s, RLDICL, r0, addr_reg,
594
64 - TARGET_PAGE_BITS,
596
tcg_out_rld (s, RLDICR, r0, r0,
598
63 - CPU_TLB_ENTRY_BITS);
600
tcg_out32 (s, ADD | TAB (r0, r0, TCG_AREG0));
601
tcg_out32 (s, LD_ADDR | RT (r1) | RA (r0) | offset);
604
tcg_out_rld (s, RLDICR, r2, addr_reg, 0, 63 - TARGET_PAGE_BITS);
607
tcg_out_rld (s, RLDICL, r2, addr_reg,
608
64 - TARGET_PAGE_BITS,
609
TARGET_PAGE_BITS - s_bits);
610
tcg_out_rld (s, RLDICL, r2, r2, TARGET_PAGE_BITS, 0);
616
static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
618
int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
619
#ifdef CONFIG_SOFTMMU
621
void *label1_ptr, *label2_ptr;
629
#ifdef CONFIG_SOFTMMU
635
tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
636
offsetof (CPUState, tlb_table[mem_index][0].addr_read));
638
tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
640
label1_ptr = s->code_ptr;
642
tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
646
tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
647
tcg_out_movi (s, TCG_TYPE_I64, 4, mem_index);
649
tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
653
tcg_out32 (s, EXTSB | RA (data_reg) | RS (3));
656
tcg_out32 (s, EXTSH | RA (data_reg) | RS (3));
659
tcg_out32 (s, EXTSW | RA (data_reg) | RS (3));
666
tcg_out_mov (s, TCG_TYPE_I64, data_reg, 3);
669
label2_ptr = s->code_ptr;
672
/* label1: fast path */
674
reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
677
/* r0 now contains &env->tlb_table[mem_index][index].addr_read */
681
| (offsetof (CPUTLBEntry, addend)
682
- offsetof (CPUTLBEntry, addr_read))
684
/* r0 = env->tlb_table[mem_index][index].addend */
685
tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
686
/* r0 = env->tlb_table[mem_index][index].addend + addr */
688
#else /* !CONFIG_SOFTMMU */
689
#if TARGET_LONG_BITS == 32
690
tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
694
rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
697
#ifdef TARGET_WORDS_BIGENDIAN
705
tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
708
tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
709
tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
713
tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
715
tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
719
tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
720
tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
722
else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
726
tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
728
tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
732
tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
733
tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
735
else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
738
#ifdef CONFIG_USE_GUEST_BASE
740
tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
741
tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
742
tcg_out32 (s, LWBRX | TAB ( r1, rbase, r1));
743
tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
745
else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
748
tcg_out_movi32 (s, 0, 4);
749
tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
750
tcg_out32 (s, LWBRX | RT ( r1) | RA (r0));
751
tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
753
else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
758
#ifdef CONFIG_SOFTMMU
759
reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
763
static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
765
int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
766
#ifdef CONFIG_SOFTMMU
768
void *label1_ptr, *label2_ptr;
775
#ifdef CONFIG_SOFTMMU
781
tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
782
offsetof (CPUState, tlb_table[mem_index][0].addr_write));
784
tcg_out32 (s, CMP | BF (7) | RA (r2) | RB (r1) | CMP_L);
786
label1_ptr = s->code_ptr;
788
tcg_out32 (s, BC | BI (7, CR_EQ) | BO_COND_TRUE);
792
tcg_out_mov (s, TCG_TYPE_I64, 3, addr_reg);
793
tcg_out_rld (s, RLDICL, 4, data_reg, 0, 64 - (1 << (3 + opc)));
794
tcg_out_movi (s, TCG_TYPE_I64, 5, mem_index);
796
tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
798
label2_ptr = s->code_ptr;
801
/* label1: fast path */
803
reloc_pc14 (label1_ptr, (tcg_target_long) s->code_ptr);
809
| (offsetof (CPUTLBEntry, addend)
810
- offsetof (CPUTLBEntry, addr_write))
812
/* r0 = env->tlb_table[mem_index][index].addend */
813
tcg_out32 (s, ADD | RT (r0) | RA (r0) | RB (addr_reg));
814
/* r0 = env->tlb_table[mem_index][index].addend + addr */
816
#else /* !CONFIG_SOFTMMU */
817
#if TARGET_LONG_BITS == 32
818
tcg_out_rld (s, RLDICL, addr_reg, addr_reg, 0, 32);
822
rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
825
#ifdef TARGET_WORDS_BIGENDIAN
832
tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
836
tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
838
tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
842
tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
844
tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
848
tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
849
tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
850
tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
851
tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
853
else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
857
#ifdef CONFIG_SOFTMMU
858
reloc_pc24 (label2_ptr, (tcg_target_long) s->code_ptr);
862
static void tcg_target_qemu_prologue (TCGContext *s)
873
+ 8 /* compiler doubleword */
874
+ 8 /* link editor doubleword */
875
+ 8 /* TOC save area */
876
+ TCG_STATIC_CALL_ARGS_SIZE
877
+ ARRAY_SIZE (tcg_target_callee_save_regs) * 8
878
+ CPU_TEMP_BUF_NLONGS * sizeof(long)
880
frame_size = (frame_size + 15) & ~15;
882
tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size
883
- CPU_TEMP_BUF_NLONGS * sizeof(long),
884
CPU_TEMP_BUF_NLONGS * sizeof(long));
887
/* First emit adhoc function descriptor */
888
addr = (uint64_t) s->code_ptr + 24;
889
tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */
890
s->code_ptr += 16; /* skip TOC and environment pointer */
894
tcg_out32 (s, MFSPR | RT (0) | LR);
895
tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));
896
for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
898
| RS (tcg_target_callee_save_regs[i])
900
| (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
903
tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
905
#ifdef CONFIG_USE_GUEST_BASE
907
tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
908
tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
912
tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
913
tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
914
tcg_out32 (s, BCCTR | BO_ALWAYS);
917
tb_ret_addr = s->code_ptr;
919
for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)
921
| RT (tcg_target_callee_save_regs[i])
923
| (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)
926
tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));
927
tcg_out32 (s, MTSPR | RS (0) | LR);
928
tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);
929
tcg_out32 (s, BCLR | BO_ALWAYS);
932
static void tcg_out_ld (TCGContext *s, TCGType type, int ret, int arg1,
933
tcg_target_long arg2)
935
if (type == TCG_TYPE_I32)
936
tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
938
tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
941
static void tcg_out_st (TCGContext *s, TCGType type, int arg, int arg1,
942
tcg_target_long arg2)
944
if (type == TCG_TYPE_I32)
945
tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
947
tcg_out_ldsta (s, arg, arg1, arg2, STD, STDX);
950
static void ppc_addi32 (TCGContext *s, int rt, int ra, tcg_target_long si)
955
if (si == (int16_t) si)
956
tcg_out32 (s, ADDI | RT (rt) | RA (ra) | (si & 0xffff));
958
uint16_t h = ((si >> 16) & 0xffff) + ((uint16_t) si >> 15);
959
tcg_out32 (s, ADDIS | RT (rt) | RA (ra) | h);
960
tcg_out32 (s, ADDI | RT (rt) | RA (rt) | (si & 0xffff));
964
static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
966
/* XXX: suboptimal */
967
if (si == (int16_t) si
968
|| ((((uint64_t) si >> 31) == 0) && (si & 0x8000) == 0))
969
ppc_addi32 (s, rt, ra, si);
971
tcg_out_movi (s, TCG_TYPE_I64, 0, si);
972
tcg_out32 (s, ADD | RT (rt) | RA (ra));
976
static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
977
int const_arg2, int cr, int arch64)
986
if ((int16_t) arg2 == arg2) {
991
else if ((uint16_t) arg2 == arg2) {
1006
if ((int16_t) arg2 == arg2) {
1021
if ((uint16_t) arg2 == arg2) {
1034
op |= BF (cr) | (arch64 << 21);
1037
tcg_out32 (s, op | RA (arg1) | (arg2 & 0xffff));
1040
tcg_out_movi (s, TCG_TYPE_I64, 0, arg2);
1041
tcg_out32 (s, op | RA (arg1) | RB (0));
1044
tcg_out32 (s, op | RA (arg1) | RB (arg2));
1049
static void tcg_out_setcond (TCGContext *s, TCGType type, TCGCond cond,
1050
TCGArg arg0, TCGArg arg1, TCGArg arg2,
1063
if ((uint16_t) arg2 == arg2) {
1064
tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1067
tcg_out_movi (s, type, 0, arg2);
1068
tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1074
tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1077
if (type == TCG_TYPE_I64) {
1078
tcg_out32 (s, CNTLZD | RS (arg) | RA (0));
1079
tcg_out_rld (s, RLDICL, arg0, 0, 58, 6);
1082
tcg_out32 (s, CNTLZW | RS (arg) | RA (0));
1083
tcg_out32 (s, (RLWINM
1101
if ((uint16_t) arg2 == arg2) {
1102
tcg_out32 (s, XORI | RS (arg1) | RA (0) | arg2);
1105
tcg_out_movi (s, type, 0, arg2);
1106
tcg_out32 (s, XOR | SAB (arg1, 0, 0));
1112
tcg_out32 (s, XOR | SAB (arg1, 0, arg2));
1115
if (arg == arg1 && arg1 == arg0) {
1116
tcg_out32 (s, ADDIC | RT (0) | RA (arg) | 0xffff);
1117
tcg_out32 (s, SUBFE | TAB (arg0, 0, arg));
1120
tcg_out32 (s, ADDIC | RT (arg0) | RA (arg) | 0xffff);
1121
tcg_out32 (s, SUBFE | TAB (arg0, arg0, arg));
1140
crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_LT) | BB (7, CR_LT);
1146
crop = CRNOR | BT (7, CR_EQ) | BA (7, CR_GT) | BB (7, CR_GT);
1148
tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, type == TCG_TYPE_I64);
1149
if (crop) tcg_out32 (s, crop);
1150
tcg_out32 (s, MFCR | RT (0));
1151
tcg_out32 (s, (RLWINM
1166
static void tcg_out_bc (TCGContext *s, int bc, int label_index)
1168
TCGLabel *l = &s->labels[label_index];
1171
tcg_out32 (s, bc | reloc_pc14_val (s->code_ptr, l->u.value));
1173
uint16_t val = *(uint16_t *) &s->code_ptr[2];
1175
/* Thanks to Andrzej Zaborowski */
1176
tcg_out32 (s, bc | (val & 0xfffc));
1177
tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL14, label_index, 0);
1181
static void tcg_out_brcond (TCGContext *s, TCGCond cond,
1182
TCGArg arg1, TCGArg arg2, int const_arg2,
1183
int label_index, int arch64)
1185
tcg_out_cmp (s, cond, arg1, arg2, const_arg2, 7, arch64);
1186
tcg_out_bc (s, tcg_to_bc[cond], label_index);
1189
void ppc_tb_set_jmp_target (unsigned long jmp_addr, unsigned long addr)
1192
unsigned long patch_size;
1194
s.code_ptr = (uint8_t *) jmp_addr;
1195
tcg_out_b (&s, 0, addr);
1196
patch_size = s.code_ptr - (uint8_t *) jmp_addr;
1197
flush_icache_range (jmp_addr, jmp_addr + patch_size);
1200
static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
1201
const int *const_args)
1206
case INDEX_op_exit_tb:
1207
tcg_out_movi (s, TCG_TYPE_I64, TCG_REG_R3, args[0]);
1208
tcg_out_b (s, 0, (tcg_target_long) tb_ret_addr);
1210
case INDEX_op_goto_tb:
1211
if (s->tb_jmp_offset) {
1212
/* direct jump method */
1214
s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1220
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1224
TCGLabel *l = &s->labels[args[0]];
1227
tcg_out_b (s, 0, l->u.value);
1230
uint32_t val = *(uint32_t *) s->code_ptr;
1232
/* Thanks to Andrzej Zaborowski */
1233
tcg_out32 (s, B | (val & 0x3fffffc));
1234
tcg_out_reloc (s, s->code_ptr - 4, R_PPC_REL24, args[0], 0);
1239
tcg_out_call (s, args[0], const_args[0]);
1242
if (const_args[0]) {
1243
tcg_out_b (s, 0, args[0]);
1246
tcg_out32 (s, MTSPR | RS (args[0]) | CTR);
1247
tcg_out32 (s, BCCTR | BO_ALWAYS);
1250
case INDEX_op_movi_i32:
1251
tcg_out_movi (s, TCG_TYPE_I32, args[0], args[1]);
1253
case INDEX_op_movi_i64:
1254
tcg_out_movi (s, TCG_TYPE_I64, args[0], args[1]);
1256
case INDEX_op_ld8u_i32:
1257
case INDEX_op_ld8u_i64:
1258
tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1260
case INDEX_op_ld8s_i32:
1261
case INDEX_op_ld8s_i64:
1262
tcg_out_ldst (s, args[0], args[1], args[2], LBZ, LBZX);
1263
tcg_out32 (s, EXTSB | RS (args[0]) | RA (args[0]));
1265
case INDEX_op_ld16u_i32:
1266
case INDEX_op_ld16u_i64:
1267
tcg_out_ldst (s, args[0], args[1], args[2], LHZ, LHZX);
1269
case INDEX_op_ld16s_i32:
1270
case INDEX_op_ld16s_i64:
1271
tcg_out_ldst (s, args[0], args[1], args[2], LHA, LHAX);
1273
case INDEX_op_ld_i32:
1274
case INDEX_op_ld32u_i64:
1275
tcg_out_ldst (s, args[0], args[1], args[2], LWZ, LWZX);
1277
case INDEX_op_ld32s_i64:
1278
tcg_out_ldsta (s, args[0], args[1], args[2], LWA, LWAX);
1280
case INDEX_op_ld_i64:
1281
tcg_out_ldsta (s, args[0], args[1], args[2], LD, LDX);
1283
case INDEX_op_st8_i32:
1284
case INDEX_op_st8_i64:
1285
tcg_out_ldst (s, args[0], args[1], args[2], STB, STBX);
1287
case INDEX_op_st16_i32:
1288
case INDEX_op_st16_i64:
1289
tcg_out_ldst (s, args[0], args[1], args[2], STH, STHX);
1291
case INDEX_op_st_i32:
1292
case INDEX_op_st32_i64:
1293
tcg_out_ldst (s, args[0], args[1], args[2], STW, STWX);
1295
case INDEX_op_st_i64:
1296
tcg_out_ldsta (s, args[0], args[1], args[2], STD, STDX);
1299
case INDEX_op_add_i32:
1301
ppc_addi32 (s, args[0], args[1], args[2]);
1303
tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1305
case INDEX_op_sub_i32:
1307
ppc_addi32 (s, args[0], args[1], -args[2]);
1309
tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1312
case INDEX_op_and_i64:
1313
case INDEX_op_and_i32:
1314
if (const_args[2]) {
1315
if ((args[2] & 0xffff) == args[2])
1316
tcg_out32 (s, ANDI | RS (args[1]) | RA (args[0]) | args[2]);
1317
else if ((args[2] & 0xffff0000) == args[2])
1318
tcg_out32 (s, ANDIS | RS (args[1]) | RA (args[0])
1319
| ((args[2] >> 16) & 0xffff));
1321
tcg_out_movi (s, (opc == INDEX_op_and_i32
1325
tcg_out32 (s, AND | SAB (args[1], args[0], 0));
1329
tcg_out32 (s, AND | SAB (args[1], args[0], args[2]));
1331
case INDEX_op_or_i64:
1332
case INDEX_op_or_i32:
1333
if (const_args[2]) {
1334
if (args[2] & 0xffff) {
1335
tcg_out32 (s, ORI | RS (args[1]) | RA (args[0])
1336
| (args[2] & 0xffff));
1338
tcg_out32 (s, ORIS | RS (args[0]) | RA (args[0])
1339
| ((args[2] >> 16) & 0xffff));
1342
tcg_out32 (s, ORIS | RS (args[1]) | RA (args[0])
1343
| ((args[2] >> 16) & 0xffff));
1347
tcg_out32 (s, OR | SAB (args[1], args[0], args[2]));
1349
case INDEX_op_xor_i64:
1350
case INDEX_op_xor_i32:
1351
if (const_args[2]) {
1352
if ((args[2] & 0xffff) == args[2])
1353
tcg_out32 (s, XORI | RS (args[1]) | RA (args[0])
1354
| (args[2] & 0xffff));
1355
else if ((args[2] & 0xffff0000) == args[2])
1356
tcg_out32 (s, XORIS | RS (args[1]) | RA (args[0])
1357
| ((args[2] >> 16) & 0xffff));
1359
tcg_out_movi (s, (opc == INDEX_op_and_i32
1363
tcg_out32 (s, XOR | SAB (args[1], args[0], 0));
1367
tcg_out32 (s, XOR | SAB (args[1], args[0], args[2]));
1370
case INDEX_op_mul_i32:
1371
if (const_args[2]) {
1372
if (args[2] == (int16_t) args[2])
1373
tcg_out32 (s, MULLI | RT (args[0]) | RA (args[1])
1374
| (args[2] & 0xffff));
1376
tcg_out_movi (s, TCG_TYPE_I32, 0, args[2]);
1377
tcg_out32 (s, MULLW | TAB (args[0], args[1], 0));
1381
tcg_out32 (s, MULLW | TAB (args[0], args[1], args[2]));
1384
case INDEX_op_div_i32:
1385
tcg_out32 (s, DIVW | TAB (args[0], args[1], args[2]));
1388
case INDEX_op_divu_i32:
1389
tcg_out32 (s, DIVWU | TAB (args[0], args[1], args[2]));
1392
case INDEX_op_rem_i32:
1393
tcg_out32 (s, DIVW | TAB (0, args[1], args[2]));
1394
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1395
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1398
case INDEX_op_remu_i32:
1399
tcg_out32 (s, DIVWU | TAB (0, args[1], args[2]));
1400
tcg_out32 (s, MULLW | TAB (0, 0, args[2]));
1401
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1404
case INDEX_op_shl_i32:
1405
if (const_args[2]) {
1406
tcg_out32 (s, (RLWINM
1416
tcg_out32 (s, SLW | SAB (args[1], args[0], args[2]));
1418
case INDEX_op_shr_i32:
1419
if (const_args[2]) {
1420
tcg_out32 (s, (RLWINM
1430
tcg_out32 (s, SRW | SAB (args[1], args[0], args[2]));
1432
case INDEX_op_sar_i32:
1434
tcg_out32 (s, SRAWI | RS (args[1]) | RA (args[0]) | SH (args[2]));
1436
tcg_out32 (s, SRAW | SAB (args[1], args[0], args[2]));
1439
case INDEX_op_brcond_i32:
1440
tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 0);
1443
case INDEX_op_brcond_i64:
1444
tcg_out_brcond (s, args[2], args[0], args[1], const_args[1], args[3], 1);
1447
case INDEX_op_neg_i32:
1448
case INDEX_op_neg_i64:
1449
tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
1452
case INDEX_op_add_i64:
1454
ppc_addi64 (s, args[0], args[1], args[2]);
1456
tcg_out32 (s, ADD | TAB (args[0], args[1], args[2]));
1458
case INDEX_op_sub_i64:
1460
ppc_addi64 (s, args[0], args[1], -args[2]);
1462
tcg_out32 (s, SUBF | TAB (args[0], args[2], args[1]));
1465
case INDEX_op_shl_i64:
1467
tcg_out_rld (s, RLDICR, args[0], args[1], args[2], 63 - args[2]);
1469
tcg_out32 (s, SLD | SAB (args[1], args[0], args[2]));
1471
case INDEX_op_shr_i64:
1473
tcg_out_rld (s, RLDICL, args[0], args[1], 64 - args[2], args[2]);
1475
tcg_out32 (s, SRD | SAB (args[1], args[0], args[2]));
1477
case INDEX_op_sar_i64:
1478
if (const_args[2]) {
1479
int sh = SH (args[2] & 0x1f) | (((args[2] >> 5) & 1) << 1);
1480
tcg_out32 (s, SRADI | RA (args[0]) | RS (args[1]) | sh);
1483
tcg_out32 (s, SRAD | SAB (args[1], args[0], args[2]));
1486
case INDEX_op_mul_i64:
1487
tcg_out32 (s, MULLD | TAB (args[0], args[1], args[2]));
1489
case INDEX_op_div_i64:
1490
tcg_out32 (s, DIVD | TAB (args[0], args[1], args[2]));
1492
case INDEX_op_divu_i64:
1493
tcg_out32 (s, DIVDU | TAB (args[0], args[1], args[2]));
1495
case INDEX_op_rem_i64:
1496
tcg_out32 (s, DIVD | TAB (0, args[1], args[2]));
1497
tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1498
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1500
case INDEX_op_remu_i64:
1501
tcg_out32 (s, DIVDU | TAB (0, args[1], args[2]));
1502
tcg_out32 (s, MULLD | TAB (0, 0, args[2]));
1503
tcg_out32 (s, SUBF | TAB (args[0], 0, args[1]));
1506
case INDEX_op_qemu_ld8u:
1507
tcg_out_qemu_ld (s, args, 0);
1509
case INDEX_op_qemu_ld8s:
1510
tcg_out_qemu_ld (s, args, 0 | 4);
1512
case INDEX_op_qemu_ld16u:
1513
tcg_out_qemu_ld (s, args, 1);
1515
case INDEX_op_qemu_ld16s:
1516
tcg_out_qemu_ld (s, args, 1 | 4);
1518
case INDEX_op_qemu_ld32:
1519
case INDEX_op_qemu_ld32u:
1520
tcg_out_qemu_ld (s, args, 2);
1522
case INDEX_op_qemu_ld32s:
1523
tcg_out_qemu_ld (s, args, 2 | 4);
1525
case INDEX_op_qemu_ld64:
1526
tcg_out_qemu_ld (s, args, 3);
1528
case INDEX_op_qemu_st8:
1529
tcg_out_qemu_st (s, args, 0);
1531
case INDEX_op_qemu_st16:
1532
tcg_out_qemu_st (s, args, 1);
1534
case INDEX_op_qemu_st32:
1535
tcg_out_qemu_st (s, args, 2);
1537
case INDEX_op_qemu_st64:
1538
tcg_out_qemu_st (s, args, 3);
1541
case INDEX_op_ext8s_i32:
1542
case INDEX_op_ext8s_i64:
1545
case INDEX_op_ext16s_i32:
1546
case INDEX_op_ext16s_i64:
1549
case INDEX_op_ext32s_i64:
1553
tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
1556
case INDEX_op_setcond_i32:
1557
tcg_out_setcond (s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
1560
case INDEX_op_setcond_i64:
1561
tcg_out_setcond (s, TCG_TYPE_I64, args[3], args[0], args[1], args[2],
1566
tcg_dump_ops (s, stderr);
1571
static const TCGTargetOpDef ppc_op_defs[] = {
1572
{ INDEX_op_exit_tb, { } },
1573
{ INDEX_op_goto_tb, { } },
1574
{ INDEX_op_call, { "ri" } },
1575
{ INDEX_op_jmp, { "ri" } },
1576
{ INDEX_op_br, { } },
1578
{ INDEX_op_mov_i32, { "r", "r" } },
1579
{ INDEX_op_mov_i64, { "r", "r" } },
1580
{ INDEX_op_movi_i32, { "r" } },
1581
{ INDEX_op_movi_i64, { "r" } },
1583
{ INDEX_op_ld8u_i32, { "r", "r" } },
1584
{ INDEX_op_ld8s_i32, { "r", "r" } },
1585
{ INDEX_op_ld16u_i32, { "r", "r" } },
1586
{ INDEX_op_ld16s_i32, { "r", "r" } },
1587
{ INDEX_op_ld_i32, { "r", "r" } },
1588
{ INDEX_op_ld_i64, { "r", "r" } },
1589
{ INDEX_op_st8_i32, { "r", "r" } },
1590
{ INDEX_op_st8_i64, { "r", "r" } },
1591
{ INDEX_op_st16_i32, { "r", "r" } },
1592
{ INDEX_op_st16_i64, { "r", "r" } },
1593
{ INDEX_op_st_i32, { "r", "r" } },
1594
{ INDEX_op_st_i64, { "r", "r" } },
1595
{ INDEX_op_st32_i64, { "r", "r" } },
1597
{ INDEX_op_ld8u_i64, { "r", "r" } },
1598
{ INDEX_op_ld8s_i64, { "r", "r" } },
1599
{ INDEX_op_ld16u_i64, { "r", "r" } },
1600
{ INDEX_op_ld16s_i64, { "r", "r" } },
1601
{ INDEX_op_ld32u_i64, { "r", "r" } },
1602
{ INDEX_op_ld32s_i64, { "r", "r" } },
1603
{ INDEX_op_ld_i64, { "r", "r" } },
1605
{ INDEX_op_add_i32, { "r", "r", "ri" } },
1606
{ INDEX_op_mul_i32, { "r", "r", "ri" } },
1607
{ INDEX_op_div_i32, { "r", "r", "r" } },
1608
{ INDEX_op_divu_i32, { "r", "r", "r" } },
1609
{ INDEX_op_rem_i32, { "r", "r", "r" } },
1610
{ INDEX_op_remu_i32, { "r", "r", "r" } },
1611
{ INDEX_op_sub_i32, { "r", "r", "ri" } },
1612
{ INDEX_op_and_i32, { "r", "r", "ri" } },
1613
{ INDEX_op_or_i32, { "r", "r", "ri" } },
1614
{ INDEX_op_xor_i32, { "r", "r", "ri" } },
1616
{ INDEX_op_shl_i32, { "r", "r", "ri" } },
1617
{ INDEX_op_shr_i32, { "r", "r", "ri" } },
1618
{ INDEX_op_sar_i32, { "r", "r", "ri" } },
1620
{ INDEX_op_brcond_i32, { "r", "ri" } },
1621
{ INDEX_op_brcond_i64, { "r", "ri" } },
1623
{ INDEX_op_neg_i32, { "r", "r" } },
1625
{ INDEX_op_add_i64, { "r", "r", "ri" } },
1626
{ INDEX_op_sub_i64, { "r", "r", "ri" } },
1627
{ INDEX_op_and_i64, { "r", "r", "rZ" } },
1628
{ INDEX_op_or_i64, { "r", "r", "rZ" } },
1629
{ INDEX_op_xor_i64, { "r", "r", "rZ" } },
1631
{ INDEX_op_shl_i64, { "r", "r", "ri" } },
1632
{ INDEX_op_shr_i64, { "r", "r", "ri" } },
1633
{ INDEX_op_sar_i64, { "r", "r", "ri" } },
1635
{ INDEX_op_mul_i64, { "r", "r", "r" } },
1636
{ INDEX_op_div_i64, { "r", "r", "r" } },
1637
{ INDEX_op_divu_i64, { "r", "r", "r" } },
1638
{ INDEX_op_rem_i64, { "r", "r", "r" } },
1639
{ INDEX_op_remu_i64, { "r", "r", "r" } },
1641
{ INDEX_op_neg_i64, { "r", "r" } },
1643
{ INDEX_op_qemu_ld8u, { "r", "L" } },
1644
{ INDEX_op_qemu_ld8s, { "r", "L" } },
1645
{ INDEX_op_qemu_ld16u, { "r", "L" } },
1646
{ INDEX_op_qemu_ld16s, { "r", "L" } },
1647
{ INDEX_op_qemu_ld32, { "r", "L" } },
1648
{ INDEX_op_qemu_ld32u, { "r", "L" } },
1649
{ INDEX_op_qemu_ld32s, { "r", "L" } },
1650
{ INDEX_op_qemu_ld64, { "r", "L" } },
1652
{ INDEX_op_qemu_st8, { "S", "S" } },
1653
{ INDEX_op_qemu_st16, { "S", "S" } },
1654
{ INDEX_op_qemu_st32, { "S", "S" } },
1655
{ INDEX_op_qemu_st64, { "S", "S" } },
1657
{ INDEX_op_ext8s_i32, { "r", "r" } },
1658
{ INDEX_op_ext16s_i32, { "r", "r" } },
1659
{ INDEX_op_ext8s_i64, { "r", "r" } },
1660
{ INDEX_op_ext16s_i64, { "r", "r" } },
1661
{ INDEX_op_ext32s_i64, { "r", "r" } },
1663
{ INDEX_op_setcond_i32, { "r", "r", "ri" } },
1664
{ INDEX_op_setcond_i64, { "r", "r", "ri" } },
1669
static void tcg_target_init (TCGContext *s)
1671
tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1672
tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1673
tcg_regset_set32 (tcg_target_call_clobber_regs, 0,
1685
(1 << TCG_REG_R10) |
1686
(1 << TCG_REG_R11) |
1690
tcg_regset_clear (s->reserved_regs);
1691
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R0);
1692
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R1);
1694
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1696
tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
1698
tcg_add_target_add_op_defs (ppc_op_defs);