2
* Tiny Code Generator for QEMU
4
* Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5
* Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6
* Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
8
* Permission is hereby granted, free of charge, to any person obtaining a copy
9
* of this software and associated documentation files (the "Software"), to deal
10
* in the Software without restriction, including without limitation the rights
11
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
* copies of the Software, and to permit persons to whom the Software is
13
* furnished to do so, subject to the following conditions:
15
* The above copyright notice and this permission notice shall be included in
16
* all copies or substantial portions of the Software.
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
#if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28
# define TCG_NEED_BSWAP 0
30
# define TCG_NEED_BSWAP 1
34
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
70
/* check if we really need so many registers :P */
71
static const int tcg_target_reg_alloc_order[] = {
97
static const int tcg_target_call_iarg_regs[4] = {
104
static const int tcg_target_call_oarg_regs[2] = {
109
static uint8_t *tb_ret_addr;
111
static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
113
return target & 0xffff;
116
static inline void reloc_lo16 (void *pc, tcg_target_long target)
118
*(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
119
| reloc_lo16_val(pc, target);
122
static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
124
return (target >> 16) & 0xffff;
127
static inline void reloc_hi16 (void *pc, tcg_target_long target)
129
*(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
130
| reloc_hi16_val(pc, target);
133
static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
137
disp = target - (tcg_target_long) pc - 4;
138
if (disp != (disp << 14) >> 14) {
142
return (disp >> 2) & 0xffff;
145
static inline void reloc_pc16 (void *pc, tcg_target_long target)
147
*(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
148
| reloc_pc16_val(pc, target);
151
static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
153
if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
157
return (target >> 2) & 0x3ffffff;
160
static inline void reloc_pc26 (void *pc, tcg_target_long target)
162
*(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
163
| reloc_26_val(pc, target);
166
static void patch_reloc(uint8_t *code_ptr, int type,
167
tcg_target_long value, tcg_target_long addend)
172
reloc_lo16(code_ptr, value);
175
reloc_hi16(code_ptr, value);
178
reloc_pc16(code_ptr, value);
181
reloc_pc26(code_ptr, value);
188
/* maximum number of register used for input function arguments */
189
static inline int tcg_target_get_call_iarg_regs_count(int flags)
194
/* parse target specific constraints */
195
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
202
ct->ct |= TCG_CT_REG;
203
tcg_regset_set(ct->u.regs, 0xffffffff);
206
ct->ct |= TCG_CT_REG;
207
tcg_regset_clear(ct->u.regs);
208
tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
210
case 'L': /* qemu_ld output arg constraint */
211
ct->ct |= TCG_CT_REG;
212
tcg_regset_set(ct->u.regs, 0xffffffff);
213
tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
215
case 'l': /* qemu_ld input arg constraint */
216
ct->ct |= TCG_CT_REG;
217
tcg_regset_set(ct->u.regs, 0xffffffff);
218
#if defined(CONFIG_SOFTMMU)
219
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
222
case 'S': /* qemu_st constraint */
223
ct->ct |= TCG_CT_REG;
224
tcg_regset_set(ct->u.regs, 0xffffffff);
225
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
226
#if defined(CONFIG_SOFTMMU)
227
# if TARGET_LONG_BITS == 64
228
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
230
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
234
ct->ct |= TCG_CT_CONST_U16;
237
ct->ct |= TCG_CT_CONST_S16;
240
/* We are cheating a bit here, using the fact that the register
241
ZERO is also the register number 0. Hence there is no need
242
to check for const_args in each instruction. */
243
ct->ct |= TCG_CT_CONST_ZERO;
253
/* test if a constant matches the constraint */
254
static inline int tcg_target_const_match(tcg_target_long val,
255
const TCGArgConstraint *arg_ct)
259
if (ct & TCG_CT_CONST)
261
else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
263
else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
265
else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
271
/* instruction opcodes */
273
OPC_BEQ = 0x04 << 26,
274
OPC_BNE = 0x05 << 26,
275
OPC_ADDIU = 0x09 << 26,
276
OPC_SLTI = 0x0A << 26,
277
OPC_SLTIU = 0x0B << 26,
278
OPC_ANDI = 0x0C << 26,
279
OPC_ORI = 0x0D << 26,
280
OPC_XORI = 0x0E << 26,
281
OPC_LUI = 0x0F << 26,
285
OPC_LBU = 0x24 << 26,
286
OPC_LHU = 0x25 << 26,
287
OPC_LWU = 0x27 << 26,
292
OPC_SPECIAL = 0x00 << 26,
293
OPC_SLL = OPC_SPECIAL | 0x00,
294
OPC_SRL = OPC_SPECIAL | 0x02,
295
OPC_SRA = OPC_SPECIAL | 0x03,
296
OPC_SLLV = OPC_SPECIAL | 0x04,
297
OPC_SRLV = OPC_SPECIAL | 0x06,
298
OPC_SRAV = OPC_SPECIAL | 0x07,
299
OPC_JR = OPC_SPECIAL | 0x08,
300
OPC_JALR = OPC_SPECIAL | 0x09,
301
OPC_MFHI = OPC_SPECIAL | 0x10,
302
OPC_MFLO = OPC_SPECIAL | 0x12,
303
OPC_MULT = OPC_SPECIAL | 0x18,
304
OPC_MULTU = OPC_SPECIAL | 0x19,
305
OPC_DIV = OPC_SPECIAL | 0x1A,
306
OPC_DIVU = OPC_SPECIAL | 0x1B,
307
OPC_ADDU = OPC_SPECIAL | 0x21,
308
OPC_SUBU = OPC_SPECIAL | 0x23,
309
OPC_AND = OPC_SPECIAL | 0x24,
310
OPC_OR = OPC_SPECIAL | 0x25,
311
OPC_XOR = OPC_SPECIAL | 0x26,
312
OPC_NOR = OPC_SPECIAL | 0x27,
313
OPC_SLT = OPC_SPECIAL | 0x2A,
314
OPC_SLTU = OPC_SPECIAL | 0x2B,
316
OPC_SPECIAL3 = 0x1f << 26,
317
OPC_SEB = OPC_SPECIAL3 | 0x420,
318
OPC_SEH = OPC_SPECIAL3 | 0x620,
324
static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
329
inst |= (rs & 0x1F) << 21;
330
inst |= (rt & 0x1F) << 16;
331
inst |= (rd & 0x1F) << 11;
338
static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
343
inst |= (rs & 0x1F) << 21;
344
inst |= (rt & 0x1F) << 16;
345
inst |= (imm & 0xffff);
352
static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
354
/* We pay attention here to not modify the branch target by reading
355
the existing value and using it again. This ensure that caches and
356
memory are kept coherent during retranslation. */
357
uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
359
tcg_out_opc_imm(s, opc, rt, rs, offset);
365
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
370
inst |= (rt & 0x1F) << 16;
371
inst |= (rd & 0x1F) << 11;
372
inst |= (sa & 0x1F) << 6;
377
static inline void tcg_out_nop(TCGContext *s)
382
static inline void tcg_out_mov(TCGContext *s, TCGType type,
383
TCGReg ret, TCGReg arg)
385
tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
388
static inline void tcg_out_movi(TCGContext *s, TCGType type,
389
TCGReg reg, tcg_target_long arg)
391
if (arg == (int16_t)arg) {
392
tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
393
} else if (arg == (uint16_t)arg) {
394
tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
396
tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
397
tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
401
static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
403
/* ret and arg can't be register at */
404
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
408
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
409
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
411
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
412
tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
413
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
416
static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
418
/* ret and arg can't be register at */
419
if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
423
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
424
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
426
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
427
tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
428
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
431
static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
433
/* ret and arg must be different and can't be register at */
434
if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
438
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
440
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
441
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
443
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
444
tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
445
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
447
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
448
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
449
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
452
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
454
#ifdef _MIPS_ARCH_MIPS32R2
455
tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
457
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
458
tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
462
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
464
#ifdef _MIPS_ARCH_MIPS32R2
465
tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
467
tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
468
tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
472
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
473
int arg1, tcg_target_long arg2)
475
if (arg2 == (int16_t) arg2) {
476
tcg_out_opc_imm(s, opc, arg, arg1, arg2);
478
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
479
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
480
tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
484
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
485
TCGReg arg1, tcg_target_long arg2)
487
tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
490
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
491
TCGReg arg1, tcg_target_long arg2)
493
tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
496
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
498
if (val == (int16_t)val) {
499
tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
501
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
502
tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
506
static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
507
int arg2, int label_index)
509
TCGLabel *l = &s->labels[label_index];
513
tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
516
tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
519
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
520
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
523
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
524
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
527
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
528
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
531
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
532
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
535
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
536
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
539
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
540
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
543
tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
544
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
547
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
548
tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
555
reloc_pc16(s->code_ptr - 4, l->u.value);
557
tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
562
/* XXX: we implement it at the target level to avoid having to
563
handle cross basic blocks temporaries */
564
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
565
int arg2, int arg3, int arg4, int label_index)
571
tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
572
tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
578
tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
582
tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
586
tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
590
tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
596
label_ptr = s->code_ptr;
597
tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
602
tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
606
tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
610
tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
614
tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
618
tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
624
reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
627
static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
633
tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
634
} else if (arg2 == 0) {
635
tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
637
tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
638
tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
643
tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
644
} else if (arg2 == 0) {
645
tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
647
tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
648
tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
652
tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
655
tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
658
tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
659
tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
662
tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
663
tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
666
tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
667
tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
670
tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
671
tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
674
tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
677
tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
685
/* XXX: we implement it at the target level to avoid having to
686
handle cross basic blocks temporaries */
687
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
688
int arg1, int arg2, int arg3, int arg4)
692
tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
693
tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
694
tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
697
tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
698
tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
699
tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
703
tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
707
tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
711
tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
715
tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
722
tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
727
tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
731
tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
735
tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
739
tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
745
tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
746
tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
749
#if defined(CONFIG_SOFTMMU)
751
#include "../../softmmu_defs.h"
753
static void *qemu_ld_helpers[4] = {
760
static void *qemu_st_helpers[4] = {
768
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
771
int addr_regl, addr_reg1, addr_meml;
772
int data_regl, data_regh, data_reg1, data_reg2;
773
int mem_index, s_bits;
774
#if defined(CONFIG_SOFTMMU)
775
void *label1_ptr, *label2_ptr;
778
#if TARGET_LONG_BITS == 64
779
# if defined(CONFIG_SOFTMMU)
782
int addr_regh, addr_reg2, addr_memh;
790
#if TARGET_LONG_BITS == 64
797
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
798
data_reg1 = data_regh;
799
data_reg2 = data_regl;
801
data_reg1 = data_regl;
802
data_reg2 = data_regh;
805
data_reg1 = data_regl;
808
#if TARGET_LONG_BITS == 64
809
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
810
addr_reg1 = addr_regh;
811
addr_reg2 = addr_regl;
815
addr_reg1 = addr_regl;
816
addr_reg2 = addr_regh;
821
addr_reg1 = addr_regl;
825
#if defined(CONFIG_SOFTMMU)
826
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
827
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
828
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
829
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
830
offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_meml);
831
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
832
tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
834
# if TARGET_LONG_BITS == 64
835
label3_ptr = s->code_ptr;
836
tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
839
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
840
offsetof(CPUState, tlb_table[mem_index][0].addr_read) + addr_memh);
842
label1_ptr = s->code_ptr;
843
tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
846
reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
848
label1_ptr = s->code_ptr;
849
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
854
sp_args = TCG_REG_A0;
855
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
856
# if TARGET_LONG_BITS == 64
857
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
859
tcg_out_movi(s, TCG_TYPE_I32, sp_args++, mem_index);
860
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
861
tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
866
tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
869
tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
872
tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
875
tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
878
tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
881
tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
882
tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
888
label2_ptr = s->code_ptr;
889
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
892
/* label1: fast path */
893
reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
895
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
896
offsetof(CPUState, tlb_table[mem_index][0].addend));
897
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
899
if (GUEST_BASE == (int16_t)GUEST_BASE) {
900
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
902
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
903
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
909
tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
912
tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
915
if (TCG_NEED_BSWAP) {
916
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
917
tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
919
tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
923
if (TCG_NEED_BSWAP) {
924
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
925
tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
927
tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
931
if (TCG_NEED_BSWAP) {
932
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
933
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
935
tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
939
if (TCG_NEED_BSWAP) {
940
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
941
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
942
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
943
tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
945
tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
946
tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
953
#if defined(CONFIG_SOFTMMU)
954
reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
958
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
961
int addr_regl, addr_reg1, addr_meml;
962
int data_regl, data_regh, data_reg1, data_reg2;
963
int mem_index, s_bits;
964
#if defined(CONFIG_SOFTMMU)
965
uint8_t *label1_ptr, *label2_ptr;
968
#if TARGET_LONG_BITS == 64
969
# if defined(CONFIG_SOFTMMU)
972
int addr_regh, addr_reg2, addr_memh;
978
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
979
data_reg1 = data_regh;
980
data_reg2 = data_regl;
982
data_reg1 = data_regl;
983
data_reg2 = data_regh;
986
data_reg1 = data_regl;
991
#if TARGET_LONG_BITS == 64
993
# if defined(TCG_TARGET_WORDS_BIGENDIAN)
994
addr_reg1 = addr_regh;
995
addr_reg2 = addr_regl;
999
addr_reg1 = addr_regl;
1000
addr_reg2 = addr_regh;
1005
addr_reg1 = addr_regl;
1011
#if defined(CONFIG_SOFTMMU)
1012
tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1013
tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1014
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1015
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1016
offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_meml);
1017
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1018
tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1020
# if TARGET_LONG_BITS == 64
1021
label3_ptr = s->code_ptr;
1022
tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1025
tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1026
offsetof(CPUState, tlb_table[mem_index][0].addr_write) + addr_memh);
1028
label1_ptr = s->code_ptr;
1029
tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1032
reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1034
label1_ptr = s->code_ptr;
1035
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1040
sp_args = TCG_REG_A0;
1041
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg1);
1042
# if TARGET_LONG_BITS == 64
1043
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, addr_reg2);
1047
tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xff);
1050
tcg_out_opc_imm(s, OPC_ANDI, sp_args++, data_reg1, 0xffff);
1053
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1056
sp_args = (sp_args + 1) & ~1;
1057
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg1);
1058
tcg_out_mov(s, TCG_TYPE_I32, sp_args++, data_reg2);
1063
if (sp_args > TCG_REG_A3) {
1064
/* Push mem_index on the stack */
1065
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, mem_index);
1066
tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 16);
1068
tcg_out_movi(s, TCG_TYPE_I32, sp_args, mem_index);
1071
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1072
tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1075
label2_ptr = s->code_ptr;
1076
tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1079
/* label1: fast path */
1080
reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1082
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1083
offsetof(CPUState, tlb_table[mem_index][0].addend));
1084
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1086
if (GUEST_BASE == (int16_t)GUEST_BASE) {
1087
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1089
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1090
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1097
tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1100
if (TCG_NEED_BSWAP) {
1101
tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1102
tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1104
tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1108
if (TCG_NEED_BSWAP) {
1109
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1110
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1112
tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1116
if (TCG_NEED_BSWAP) {
1117
tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1118
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1119
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1120
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1122
tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1123
tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1130
#if defined(CONFIG_SOFTMMU)
1131
reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1135
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1136
const TCGArg *args, const int *const_args)
1139
case INDEX_op_exit_tb:
1140
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1141
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1142
tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1145
case INDEX_op_goto_tb:
1146
if (s->tb_jmp_offset) {
1147
/* direct jump method */
1150
/* indirect jump method */
1151
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1152
tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1153
tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1156
s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1159
tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1163
tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1167
tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1170
case INDEX_op_mov_i32:
1171
tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1173
case INDEX_op_movi_i32:
1174
tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1177
case INDEX_op_ld8u_i32:
1178
tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1180
case INDEX_op_ld8s_i32:
1181
tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1183
case INDEX_op_ld16u_i32:
1184
tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1186
case INDEX_op_ld16s_i32:
1187
tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1189
case INDEX_op_ld_i32:
1190
tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1192
case INDEX_op_st8_i32:
1193
tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1195
case INDEX_op_st16_i32:
1196
tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1198
case INDEX_op_st_i32:
1199
tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1202
case INDEX_op_add_i32:
1203
if (const_args[2]) {
1204
tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1206
tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1209
case INDEX_op_add2_i32:
1210
if (const_args[4]) {
1211
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1213
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1215
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1216
if (const_args[5]) {
1217
tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1219
tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1221
tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1222
tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1224
case INDEX_op_sub_i32:
1225
if (const_args[2]) {
1226
tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1228
tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1231
case INDEX_op_sub2_i32:
1232
if (const_args[4]) {
1233
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1235
tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1237
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1238
if (const_args[5]) {
1239
tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1241
tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1243
tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1244
tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1246
case INDEX_op_mul_i32:
1247
tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1248
tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1250
case INDEX_op_mulu2_i32:
1251
tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1252
tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1253
tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1255
case INDEX_op_div_i32:
1256
tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1257
tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1259
case INDEX_op_divu_i32:
1260
tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1261
tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1263
case INDEX_op_rem_i32:
1264
tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1265
tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1267
case INDEX_op_remu_i32:
1268
tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1269
tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1272
case INDEX_op_and_i32:
1273
if (const_args[2]) {
1274
tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1276
tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1279
case INDEX_op_or_i32:
1280
if (const_args[2]) {
1281
tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1283
tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1286
case INDEX_op_nor_i32:
1287
tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1289
case INDEX_op_not_i32:
1290
tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1292
case INDEX_op_xor_i32:
1293
if (const_args[2]) {
1294
tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1296
tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1300
case INDEX_op_sar_i32:
1301
if (const_args[2]) {
1302
tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1304
tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1307
case INDEX_op_shl_i32:
1308
if (const_args[2]) {
1309
tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1311
tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1314
case INDEX_op_shr_i32:
1315
if (const_args[2]) {
1316
tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1318
tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1322
case INDEX_op_ext8s_i32:
1323
tcg_out_ext8s(s, args[0], args[1]);
1325
case INDEX_op_ext16s_i32:
1326
tcg_out_ext16s(s, args[0], args[1]);
1329
case INDEX_op_brcond_i32:
1330
tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1332
case INDEX_op_brcond2_i32:
1333
tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1336
case INDEX_op_setcond_i32:
1337
tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1339
case INDEX_op_setcond2_i32:
1340
tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1343
case INDEX_op_qemu_ld8u:
1344
tcg_out_qemu_ld(s, args, 0);
1346
case INDEX_op_qemu_ld8s:
1347
tcg_out_qemu_ld(s, args, 0 | 4);
1349
case INDEX_op_qemu_ld16u:
1350
tcg_out_qemu_ld(s, args, 1);
1352
case INDEX_op_qemu_ld16s:
1353
tcg_out_qemu_ld(s, args, 1 | 4);
1355
case INDEX_op_qemu_ld32:
1356
tcg_out_qemu_ld(s, args, 2);
1358
case INDEX_op_qemu_ld64:
1359
tcg_out_qemu_ld(s, args, 3);
1361
case INDEX_op_qemu_st8:
1362
tcg_out_qemu_st(s, args, 0);
1364
case INDEX_op_qemu_st16:
1365
tcg_out_qemu_st(s, args, 1);
1367
case INDEX_op_qemu_st32:
1368
tcg_out_qemu_st(s, args, 2);
1370
case INDEX_op_qemu_st64:
1371
tcg_out_qemu_st(s, args, 3);
1379
static const TCGTargetOpDef mips_op_defs[] = {
1380
{ INDEX_op_exit_tb, { } },
1381
{ INDEX_op_goto_tb, { } },
1382
{ INDEX_op_call, { "C" } },
1383
{ INDEX_op_jmp, { "r" } },
1384
{ INDEX_op_br, { } },
1386
{ INDEX_op_mov_i32, { "r", "r" } },
1387
{ INDEX_op_movi_i32, { "r" } },
1388
{ INDEX_op_ld8u_i32, { "r", "r" } },
1389
{ INDEX_op_ld8s_i32, { "r", "r" } },
1390
{ INDEX_op_ld16u_i32, { "r", "r" } },
1391
{ INDEX_op_ld16s_i32, { "r", "r" } },
1392
{ INDEX_op_ld_i32, { "r", "r" } },
1393
{ INDEX_op_st8_i32, { "rZ", "r" } },
1394
{ INDEX_op_st16_i32, { "rZ", "r" } },
1395
{ INDEX_op_st_i32, { "rZ", "r" } },
1397
{ INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
1398
{ INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1399
{ INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1400
{ INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1401
{ INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1402
{ INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1403
{ INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1404
{ INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
1406
{ INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
1407
{ INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1408
{ INDEX_op_not_i32, { "r", "rZ" } },
1409
{ INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1410
{ INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1412
{ INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
1413
{ INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
1414
{ INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
1416
{ INDEX_op_ext8s_i32, { "r", "rZ" } },
1417
{ INDEX_op_ext16s_i32, { "r", "rZ" } },
1419
{ INDEX_op_brcond_i32, { "rZ", "rZ" } },
1420
{ INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1421
{ INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1423
{ INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1424
{ INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
1425
{ INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1427
#if TARGET_LONG_BITS == 32
1428
{ INDEX_op_qemu_ld8u, { "L", "lZ" } },
1429
{ INDEX_op_qemu_ld8s, { "L", "lZ" } },
1430
{ INDEX_op_qemu_ld16u, { "L", "lZ" } },
1431
{ INDEX_op_qemu_ld16s, { "L", "lZ" } },
1432
{ INDEX_op_qemu_ld32, { "L", "lZ" } },
1433
{ INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1435
{ INDEX_op_qemu_st8, { "SZ", "SZ" } },
1436
{ INDEX_op_qemu_st16, { "SZ", "SZ" } },
1437
{ INDEX_op_qemu_st32, { "SZ", "SZ" } },
1438
{ INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1440
{ INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1441
{ INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1442
{ INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1443
{ INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1444
{ INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1445
{ INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1447
{ INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1448
{ INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1449
{ INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1450
{ INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1455
static int tcg_target_callee_save_regs[] = {
1456
TCG_REG_S0, /* used for the global env (TCG_AREG0) */
1466
TCG_REG_RA, /* should be last for ABI compliance */
1469
/* Generate global QEMU prologue and epilogue code */
1470
static void tcg_target_qemu_prologue(TCGContext *s)
1474
/* reserve some stack space */
1475
frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1476
+ TCG_STATIC_CALL_ARGS_SIZE;
1477
frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1478
~(TCG_TARGET_STACK_ALIGN - 1);
1481
tcg_out_addi(s, TCG_REG_SP, -frame_size);
1482
for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1483
tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1484
TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1487
/* Call generated code */
1488
tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1489
tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1490
tb_ret_addr = s->code_ptr;
1493
for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1494
tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1495
TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1498
tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1499
tcg_out_addi(s, TCG_REG_SP, frame_size);
1502
static void tcg_target_init(TCGContext *s)
1504
tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1505
tcg_regset_set(tcg_target_call_clobber_regs,
1522
tcg_regset_clear(s->reserved_regs);
1523
tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1524
tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0); /* kernel use only */
1525
tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1); /* kernel use only */
1526
tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT); /* internal use */
1527
tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0); /* internal use */
1528
tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA); /* return address */
1529
tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */
1531
tcg_add_target_add_op_defs(mips_op_defs);
1532
tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
1533
CPU_TEMP_BUF_NLONGS * sizeof(long));