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 #include "tcg-be-null.h"
29 #if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
30 # define TCG_NEED_BSWAP 0
32 # define TCG_NEED_BSWAP 1
36 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
72 /* check if we really need so many registers :P */
73 static const TCGReg tcg_target_reg_alloc_order
[] = {
99 static const TCGReg tcg_target_call_iarg_regs
[4] = {
106 static const TCGReg tcg_target_call_oarg_regs
[2] = {
111 static uint8_t *tb_ret_addr
;
113 static inline uint32_t reloc_lo16_val(void *pc
, intptr_t target
)
115 return target
& 0xffff;
118 static inline void reloc_lo16(void *pc
, intptr_t target
)
120 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0xffff)
121 | reloc_lo16_val(pc
, target
);
124 static inline uint32_t reloc_hi16_val(void *pc
, intptr_t target
)
126 return (target
>> 16) & 0xffff;
129 static inline void reloc_hi16(void *pc
, intptr_t target
)
131 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0xffff)
132 | reloc_hi16_val(pc
, target
);
135 static inline uint32_t reloc_pc16_val(void *pc
, intptr_t target
)
139 disp
= target
- (intptr_t)pc
- 4;
140 if (disp
!= (disp
<< 14) >> 14) {
144 return (disp
>> 2) & 0xffff;
147 static inline void reloc_pc16 (void *pc
, tcg_target_long target
)
149 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0xffff)
150 | reloc_pc16_val(pc
, target
);
153 static inline uint32_t reloc_26_val (void *pc
, tcg_target_long target
)
155 if ((((tcg_target_long
)pc
+ 4) & 0xf0000000) != (target
& 0xf0000000)) {
159 return (target
>> 2) & 0x3ffffff;
162 static inline void reloc_pc26(void *pc
, intptr_t target
)
164 *(uint32_t *) pc
= (*(uint32_t *) pc
& ~0x3ffffff)
165 | reloc_26_val(pc
, target
);
168 static void patch_reloc(uint8_t *code_ptr
, int type
,
169 intptr_t value
, intptr_t addend
)
174 reloc_lo16(code_ptr
, value
);
177 reloc_hi16(code_ptr
, value
);
180 reloc_pc16(code_ptr
, value
);
183 reloc_pc26(code_ptr
, value
);
190 /* parse target specific constraints */
191 static int target_parse_constraint(TCGArgConstraint
*ct
, const char **pct_str
)
198 ct
->ct
|= TCG_CT_REG
;
199 tcg_regset_set(ct
->u
.regs
, 0xffffffff);
202 ct
->ct
|= TCG_CT_REG
;
203 tcg_regset_clear(ct
->u
.regs
);
204 tcg_regset_set_reg(ct
->u
.regs
, TCG_REG_T9
);
206 case 'L': /* qemu_ld output arg constraint */
207 ct
->ct
|= TCG_CT_REG
;
208 tcg_regset_set(ct
->u
.regs
, 0xffffffff);
209 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_V0
);
211 case 'l': /* qemu_ld input arg constraint */
212 ct
->ct
|= TCG_CT_REG
;
213 tcg_regset_set(ct
->u
.regs
, 0xffffffff);
214 #if defined(CONFIG_SOFTMMU)
215 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A0
);
216 # if (TARGET_LONG_BITS == 64)
217 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A2
);
221 case 'S': /* qemu_st constraint */
222 ct
->ct
|= TCG_CT_REG
;
223 tcg_regset_set(ct
->u
.regs
, 0xffffffff);
224 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A0
);
225 #if defined(CONFIG_SOFTMMU)
226 # if (TARGET_LONG_BITS == 32)
227 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A1
);
229 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A2
);
230 # if TARGET_LONG_BITS == 64
231 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_A3
);
236 ct
->ct
|= TCG_CT_CONST_U16
;
239 ct
->ct
|= TCG_CT_CONST_S16
;
242 /* We are cheating a bit here, using the fact that the register
243 ZERO is also the register number 0. Hence there is no need
244 to check for const_args in each instruction. */
245 ct
->ct
|= TCG_CT_CONST_ZERO
;
255 /* test if a constant matches the constraint */
256 static inline int tcg_target_const_match(tcg_target_long val
,
257 const TCGArgConstraint
*arg_ct
)
261 if (ct
& TCG_CT_CONST
)
263 else if ((ct
& TCG_CT_CONST_ZERO
) && val
== 0)
265 else if ((ct
& TCG_CT_CONST_U16
) && val
== (uint16_t)val
)
267 else if ((ct
& TCG_CT_CONST_S16
) && val
== (int16_t)val
)
273 /* instruction opcodes */
275 OPC_BEQ
= 0x04 << 26,
276 OPC_BNE
= 0x05 << 26,
277 OPC_BLEZ
= 0x06 << 26,
278 OPC_BGTZ
= 0x07 << 26,
279 OPC_ADDIU
= 0x09 << 26,
280 OPC_SLTI
= 0x0A << 26,
281 OPC_SLTIU
= 0x0B << 26,
282 OPC_ANDI
= 0x0C << 26,
283 OPC_ORI
= 0x0D << 26,
284 OPC_XORI
= 0x0E << 26,
285 OPC_LUI
= 0x0F << 26,
289 OPC_LBU
= 0x24 << 26,
290 OPC_LHU
= 0x25 << 26,
291 OPC_LWU
= 0x27 << 26,
296 OPC_SPECIAL
= 0x00 << 26,
297 OPC_SLL
= OPC_SPECIAL
| 0x00,
298 OPC_SRL
= OPC_SPECIAL
| 0x02,
299 OPC_ROTR
= OPC_SPECIAL
| (0x01 << 21) | 0x02,
300 OPC_SRA
= OPC_SPECIAL
| 0x03,
301 OPC_SLLV
= OPC_SPECIAL
| 0x04,
302 OPC_SRLV
= OPC_SPECIAL
| 0x06,
303 OPC_ROTRV
= OPC_SPECIAL
| (0x01 << 6) | 0x06,
304 OPC_SRAV
= OPC_SPECIAL
| 0x07,
305 OPC_JR
= OPC_SPECIAL
| 0x08,
306 OPC_JALR
= OPC_SPECIAL
| 0x09,
307 OPC_MOVZ
= OPC_SPECIAL
| 0x0A,
308 OPC_MOVN
= OPC_SPECIAL
| 0x0B,
309 OPC_MFHI
= OPC_SPECIAL
| 0x10,
310 OPC_MFLO
= OPC_SPECIAL
| 0x12,
311 OPC_MULT
= OPC_SPECIAL
| 0x18,
312 OPC_MULTU
= OPC_SPECIAL
| 0x19,
313 OPC_DIV
= OPC_SPECIAL
| 0x1A,
314 OPC_DIVU
= OPC_SPECIAL
| 0x1B,
315 OPC_ADDU
= OPC_SPECIAL
| 0x21,
316 OPC_SUBU
= OPC_SPECIAL
| 0x23,
317 OPC_AND
= OPC_SPECIAL
| 0x24,
318 OPC_OR
= OPC_SPECIAL
| 0x25,
319 OPC_XOR
= OPC_SPECIAL
| 0x26,
320 OPC_NOR
= OPC_SPECIAL
| 0x27,
321 OPC_SLT
= OPC_SPECIAL
| 0x2A,
322 OPC_SLTU
= OPC_SPECIAL
| 0x2B,
324 OPC_REGIMM
= 0x01 << 26,
325 OPC_BLTZ
= OPC_REGIMM
| (0x00 << 16),
326 OPC_BGEZ
= OPC_REGIMM
| (0x01 << 16),
328 OPC_SPECIAL2
= 0x1c << 26,
329 OPC_MUL
= OPC_SPECIAL2
| 0x002,
331 OPC_SPECIAL3
= 0x1f << 26,
332 OPC_INS
= OPC_SPECIAL3
| 0x004,
333 OPC_WSBH
= OPC_SPECIAL3
| 0x0a0,
334 OPC_SEB
= OPC_SPECIAL3
| 0x420,
335 OPC_SEH
= OPC_SPECIAL3
| 0x620,
341 static inline void tcg_out_opc_reg(TCGContext
*s
, int opc
,
342 TCGReg rd
, TCGReg rs
, TCGReg rt
)
347 inst
|= (rs
& 0x1F) << 21;
348 inst
|= (rt
& 0x1F) << 16;
349 inst
|= (rd
& 0x1F) << 11;
356 static inline void tcg_out_opc_imm(TCGContext
*s
, int opc
,
357 TCGReg rt
, TCGReg rs
, TCGArg imm
)
362 inst
|= (rs
& 0x1F) << 21;
363 inst
|= (rt
& 0x1F) << 16;
364 inst
|= (imm
& 0xffff);
371 static inline void tcg_out_opc_br(TCGContext
*s
, int opc
,
372 TCGReg rt
, TCGReg rs
)
374 /* We pay attention here to not modify the branch target by reading
375 the existing value and using it again. This ensure that caches and
376 memory are kept coherent during retranslation. */
377 uint16_t offset
= (uint16_t)(*(uint32_t *) s
->code_ptr
);
379 tcg_out_opc_imm(s
, opc
, rt
, rs
, offset
);
385 static inline void tcg_out_opc_sa(TCGContext
*s
, int opc
,
386 TCGReg rd
, TCGReg rt
, TCGArg sa
)
391 inst
|= (rt
& 0x1F) << 16;
392 inst
|= (rd
& 0x1F) << 11;
393 inst
|= (sa
& 0x1F) << 6;
398 static inline void tcg_out_nop(TCGContext
*s
)
403 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
404 TCGReg ret
, TCGReg arg
)
406 /* Simple reg-reg move, optimising out the 'do nothing' case */
408 tcg_out_opc_reg(s
, OPC_ADDU
, ret
, arg
, TCG_REG_ZERO
);
412 static inline void tcg_out_movi(TCGContext
*s
, TCGType type
,
413 TCGReg reg
, tcg_target_long arg
)
415 if (arg
== (int16_t)arg
) {
416 tcg_out_opc_imm(s
, OPC_ADDIU
, reg
, TCG_REG_ZERO
, arg
);
417 } else if (arg
== (uint16_t)arg
) {
418 tcg_out_opc_imm(s
, OPC_ORI
, reg
, TCG_REG_ZERO
, arg
);
420 tcg_out_opc_imm(s
, OPC_LUI
, reg
, 0, arg
>> 16);
421 tcg_out_opc_imm(s
, OPC_ORI
, reg
, reg
, arg
& 0xffff);
425 static inline void tcg_out_bswap16(TCGContext
*s
, TCGReg ret
, TCGReg arg
)
427 if (use_mips32r2_instructions
) {
428 tcg_out_opc_reg(s
, OPC_WSBH
, ret
, 0, arg
);
430 /* ret and arg can't be register at */
431 if (ret
== TCG_REG_AT
|| arg
== TCG_REG_AT
) {
435 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_AT
, arg
, 8);
436 tcg_out_opc_sa(s
, OPC_SLL
, ret
, arg
, 8);
437 tcg_out_opc_imm(s
, OPC_ANDI
, ret
, ret
, 0xff00);
438 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
442 static inline void tcg_out_bswap16s(TCGContext
*s
, TCGReg ret
, TCGReg arg
)
444 if (use_mips32r2_instructions
) {
445 tcg_out_opc_reg(s
, OPC_WSBH
, ret
, 0, arg
);
446 tcg_out_opc_reg(s
, OPC_SEH
, ret
, 0, ret
);
448 /* ret and arg can't be register at */
449 if (ret
== TCG_REG_AT
|| arg
== TCG_REG_AT
) {
453 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_AT
, arg
, 8);
454 tcg_out_opc_sa(s
, OPC_SLL
, ret
, arg
, 24);
455 tcg_out_opc_sa(s
, OPC_SRA
, ret
, ret
, 16);
456 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
460 static inline void tcg_out_bswap32(TCGContext
*s
, TCGReg ret
, TCGReg arg
)
462 if (use_mips32r2_instructions
) {
463 tcg_out_opc_reg(s
, OPC_WSBH
, ret
, 0, arg
);
464 tcg_out_opc_sa(s
, OPC_ROTR
, ret
, ret
, 16);
466 /* ret and arg must be different and can't be register at */
467 if (ret
== arg
|| ret
== TCG_REG_AT
|| arg
== TCG_REG_AT
) {
471 tcg_out_opc_sa(s
, OPC_SLL
, ret
, arg
, 24);
473 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_AT
, arg
, 24);
474 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
476 tcg_out_opc_imm(s
, OPC_ANDI
, TCG_REG_AT
, arg
, 0xff00);
477 tcg_out_opc_sa(s
, OPC_SLL
, TCG_REG_AT
, TCG_REG_AT
, 8);
478 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
480 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_AT
, arg
, 8);
481 tcg_out_opc_imm(s
, OPC_ANDI
, TCG_REG_AT
, TCG_REG_AT
, 0xff00);
482 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
486 static inline void tcg_out_ext8s(TCGContext
*s
, TCGReg ret
, TCGReg arg
)
488 if (use_mips32r2_instructions
) {
489 tcg_out_opc_reg(s
, OPC_SEB
, ret
, 0, arg
);
491 tcg_out_opc_sa(s
, OPC_SLL
, ret
, arg
, 24);
492 tcg_out_opc_sa(s
, OPC_SRA
, ret
, ret
, 24);
496 static inline void tcg_out_ext16s(TCGContext
*s
, TCGReg ret
, TCGReg arg
)
498 if (use_mips32r2_instructions
) {
499 tcg_out_opc_reg(s
, OPC_SEH
, ret
, 0, arg
);
501 tcg_out_opc_sa(s
, OPC_SLL
, ret
, arg
, 16);
502 tcg_out_opc_sa(s
, OPC_SRA
, ret
, ret
, 16);
506 static inline void tcg_out_ldst(TCGContext
*s
, int opc
, TCGArg arg
,
507 TCGReg arg1
, TCGArg arg2
)
509 if (arg2
== (int16_t) arg2
) {
510 tcg_out_opc_imm(s
, opc
, arg
, arg1
, arg2
);
512 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_AT
, arg2
);
513 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_AT
, TCG_REG_AT
, arg1
);
514 tcg_out_opc_imm(s
, opc
, arg
, TCG_REG_AT
, 0);
518 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg arg
,
519 TCGReg arg1
, intptr_t arg2
)
521 tcg_out_ldst(s
, OPC_LW
, arg
, arg1
, arg2
);
524 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
525 TCGReg arg1
, intptr_t arg2
)
527 tcg_out_ldst(s
, OPC_SW
, arg
, arg1
, arg2
);
530 static inline void tcg_out_addi(TCGContext
*s
, TCGReg reg
, TCGArg val
)
532 if (val
== (int16_t)val
) {
533 tcg_out_opc_imm(s
, OPC_ADDIU
, reg
, reg
, val
);
535 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_AT
, val
);
536 tcg_out_opc_reg(s
, OPC_ADDU
, reg
, reg
, TCG_REG_AT
);
540 /* Helper routines for marshalling helper function arguments into
541 * the correct registers and stack.
542 * arg_num is where we want to put this argument, and is updated to be ready
543 * for the next call. arg is the argument itself. Note that arg_num 0..3 is
544 * real registers, 4+ on stack.
546 * We provide routines for arguments which are: immediate, 32 bit
547 * value in register, 16 and 8 bit values in register (which must be zero
548 * extended before use) and 64 bit value in a lo:hi register pair.
550 #define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM) \
551 static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM) \
553 if (*arg_num < 4) { \
554 DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
556 DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT); \
557 tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num)); \
561 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
562 tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
563 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8
, TCGReg arg
)
564 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
565 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
566 tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
567 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16
, TCGReg arg
)
568 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
569 #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
570 tcg_out_movi(s, TCG_TYPE_I32, A, arg);
571 DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32
, TCGArg arg
)
572 #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
574 /* We don't use the macro for this one to avoid an unnecessary reg-reg
575 move when storing to the stack. */
576 static inline void tcg_out_call_iarg_reg32(TCGContext
*s
, int *arg_num
,
580 tcg_out_mov(s
, TCG_TYPE_I32
, tcg_target_call_iarg_regs
[*arg_num
], arg
);
582 tcg_out_st(s
, TCG_TYPE_I32
, arg
, TCG_REG_SP
, 4 * (*arg_num
));
587 static inline void tcg_out_call_iarg_reg64(TCGContext
*s
, int *arg_num
,
588 TCGReg arg_low
, TCGReg arg_high
)
590 (*arg_num
) = (*arg_num
+ 1) & ~1;
592 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
593 tcg_out_call_iarg_reg32(s
, arg_num
, arg_high
);
594 tcg_out_call_iarg_reg32(s
, arg_num
, arg_low
);
596 tcg_out_call_iarg_reg32(s
, arg_num
, arg_low
);
597 tcg_out_call_iarg_reg32(s
, arg_num
, arg_high
);
601 static void tcg_out_brcond(TCGContext
*s
, TCGCond cond
, TCGArg arg1
,
602 TCGArg arg2
, int label_index
)
604 TCGLabel
*l
= &s
->labels
[label_index
];
608 tcg_out_opc_br(s
, OPC_BEQ
, arg1
, arg2
);
611 tcg_out_opc_br(s
, OPC_BNE
, arg1
, arg2
);
615 tcg_out_opc_br(s
, OPC_BLTZ
, 0, arg1
);
617 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, arg1
, arg2
);
618 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_AT
, TCG_REG_ZERO
);
622 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, arg1
, arg2
);
623 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_AT
, TCG_REG_ZERO
);
627 tcg_out_opc_br(s
, OPC_BGEZ
, 0, arg1
);
629 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, arg1
, arg2
);
630 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_AT
, TCG_REG_ZERO
);
634 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, arg1
, arg2
);
635 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_AT
, TCG_REG_ZERO
);
639 tcg_out_opc_br(s
, OPC_BLEZ
, 0, arg1
);
641 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, arg2
, arg1
);
642 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_AT
, TCG_REG_ZERO
);
646 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, arg2
, arg1
);
647 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_AT
, TCG_REG_ZERO
);
651 tcg_out_opc_br(s
, OPC_BGTZ
, 0, arg1
);
653 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, arg2
, arg1
);
654 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_AT
, TCG_REG_ZERO
);
658 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, arg2
, arg1
);
659 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_AT
, TCG_REG_ZERO
);
666 reloc_pc16(s
->code_ptr
- 4, l
->u
.value
);
668 tcg_out_reloc(s
, s
->code_ptr
- 4, R_MIPS_PC16
, label_index
, 0);
673 /* XXX: we implement it at the target level to avoid having to
674 handle cross basic blocks temporaries */
675 static void tcg_out_brcond2(TCGContext
*s
, TCGCond cond
, TCGArg arg1
,
676 TCGArg arg2
, TCGArg arg3
, TCGArg arg4
,
683 tcg_out_brcond(s
, TCG_COND_NE
, arg2
, arg4
, label_index
);
684 tcg_out_brcond(s
, TCG_COND_NE
, arg1
, arg3
, label_index
);
690 tcg_out_brcond(s
, TCG_COND_LT
, arg2
, arg4
, label_index
);
694 tcg_out_brcond(s
, TCG_COND_GT
, arg2
, arg4
, label_index
);
698 tcg_out_brcond(s
, TCG_COND_LTU
, arg2
, arg4
, label_index
);
702 tcg_out_brcond(s
, TCG_COND_GTU
, arg2
, arg4
, label_index
);
708 label_ptr
= s
->code_ptr
;
709 tcg_out_opc_br(s
, OPC_BNE
, arg2
, arg4
);
714 tcg_out_brcond(s
, TCG_COND_EQ
, arg1
, arg3
, label_index
);
718 tcg_out_brcond(s
, TCG_COND_LTU
, arg1
, arg3
, label_index
);
722 tcg_out_brcond(s
, TCG_COND_LEU
, arg1
, arg3
, label_index
);
726 tcg_out_brcond(s
, TCG_COND_GTU
, arg1
, arg3
, label_index
);
730 tcg_out_brcond(s
, TCG_COND_GEU
, arg1
, arg3
, label_index
);
736 reloc_pc16(label_ptr
, (tcg_target_long
) s
->code_ptr
);
739 static void tcg_out_movcond(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
740 TCGArg c1
, TCGArg c2
, TCGArg v
)
745 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, c2
);
746 } else if (c2
== 0) {
747 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, c1
);
749 tcg_out_opc_reg(s
, OPC_XOR
, TCG_REG_AT
, c1
, c2
);
750 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, TCG_REG_AT
);
755 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, c2
);
756 } else if (c2
== 0) {
757 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, c1
);
759 tcg_out_opc_reg(s
, OPC_XOR
, TCG_REG_AT
, c1
, c2
);
760 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, TCG_REG_AT
);
764 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, c1
, c2
);
765 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, TCG_REG_AT
);
768 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, c1
, c2
);
769 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, TCG_REG_AT
);
772 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, c1
, c2
);
773 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, TCG_REG_AT
);
776 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, c1
, c2
);
777 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, TCG_REG_AT
);
780 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, c2
, c1
);
781 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, TCG_REG_AT
);
784 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, c2
, c1
);
785 tcg_out_opc_reg(s
, OPC_MOVZ
, ret
, v
, TCG_REG_AT
);
788 tcg_out_opc_reg(s
, OPC_SLT
, TCG_REG_AT
, c2
, c1
);
789 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, TCG_REG_AT
);
792 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_AT
, c2
, c1
);
793 tcg_out_opc_reg(s
, OPC_MOVN
, ret
, v
, TCG_REG_AT
);
801 static void tcg_out_setcond(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
802 TCGArg arg1
, TCGArg arg2
)
807 tcg_out_opc_imm(s
, OPC_SLTIU
, ret
, arg2
, 1);
808 } else if (arg2
== 0) {
809 tcg_out_opc_imm(s
, OPC_SLTIU
, ret
, arg1
, 1);
811 tcg_out_opc_reg(s
, OPC_XOR
, ret
, arg1
, arg2
);
812 tcg_out_opc_imm(s
, OPC_SLTIU
, ret
, ret
, 1);
817 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, TCG_REG_ZERO
, arg2
);
818 } else if (arg2
== 0) {
819 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, TCG_REG_ZERO
, arg1
);
821 tcg_out_opc_reg(s
, OPC_XOR
, ret
, arg1
, arg2
);
822 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, TCG_REG_ZERO
, ret
);
826 tcg_out_opc_reg(s
, OPC_SLT
, ret
, arg1
, arg2
);
829 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, arg1
, arg2
);
832 tcg_out_opc_reg(s
, OPC_SLT
, ret
, arg1
, arg2
);
833 tcg_out_opc_imm(s
, OPC_XORI
, ret
, ret
, 1);
836 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, arg1
, arg2
);
837 tcg_out_opc_imm(s
, OPC_XORI
, ret
, ret
, 1);
840 tcg_out_opc_reg(s
, OPC_SLT
, ret
, arg2
, arg1
);
841 tcg_out_opc_imm(s
, OPC_XORI
, ret
, ret
, 1);
844 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, arg2
, arg1
);
845 tcg_out_opc_imm(s
, OPC_XORI
, ret
, ret
, 1);
848 tcg_out_opc_reg(s
, OPC_SLT
, ret
, arg2
, arg1
);
851 tcg_out_opc_reg(s
, OPC_SLTU
, ret
, arg2
, arg1
);
859 /* XXX: we implement it at the target level to avoid having to
860 handle cross basic blocks temporaries */
861 static void tcg_out_setcond2(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
862 TCGArg arg1
, TCGArg arg2
, TCGArg arg3
, TCGArg arg4
)
866 tcg_out_setcond(s
, TCG_COND_EQ
, TCG_REG_AT
, arg2
, arg4
);
867 tcg_out_setcond(s
, TCG_COND_EQ
, TCG_REG_T0
, arg1
, arg3
);
868 tcg_out_opc_reg(s
, OPC_AND
, ret
, TCG_REG_AT
, TCG_REG_T0
);
871 tcg_out_setcond(s
, TCG_COND_NE
, TCG_REG_AT
, arg2
, arg4
);
872 tcg_out_setcond(s
, TCG_COND_NE
, TCG_REG_T0
, arg1
, arg3
);
873 tcg_out_opc_reg(s
, OPC_OR
, ret
, TCG_REG_AT
, TCG_REG_T0
);
877 tcg_out_setcond(s
, TCG_COND_LT
, TCG_REG_AT
, arg2
, arg4
);
881 tcg_out_setcond(s
, TCG_COND_GT
, TCG_REG_AT
, arg2
, arg4
);
885 tcg_out_setcond(s
, TCG_COND_LTU
, TCG_REG_AT
, arg2
, arg4
);
889 tcg_out_setcond(s
, TCG_COND_GTU
, TCG_REG_AT
, arg2
, arg4
);
896 tcg_out_setcond(s
, TCG_COND_EQ
, TCG_REG_T0
, arg2
, arg4
);
901 tcg_out_setcond(s
, TCG_COND_LTU
, ret
, arg1
, arg3
);
905 tcg_out_setcond(s
, TCG_COND_LEU
, ret
, arg1
, arg3
);
909 tcg_out_setcond(s
, TCG_COND_GTU
, ret
, arg1
, arg3
);
913 tcg_out_setcond(s
, TCG_COND_GEU
, ret
, arg1
, arg3
);
919 tcg_out_opc_reg(s
, OPC_AND
, ret
, ret
, TCG_REG_T0
);
920 tcg_out_opc_reg(s
, OPC_OR
, ret
, ret
, TCG_REG_AT
);
923 #if defined(CONFIG_SOFTMMU)
924 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
926 static const void * const qemu_ld_helpers
[4] = {
933 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
934 uintxx_t val, int mmu_idx) */
935 static const void * const qemu_st_helpers
[4] = {
943 static void tcg_out_qemu_ld(TCGContext
*s
, const TCGArg
*args
,
946 TCGReg addr_regl
, data_regl
, data_regh
, data_reg1
, data_reg2
;
947 #if defined(CONFIG_SOFTMMU)
948 void *label1_ptr
, *label2_ptr
;
950 int mem_index
, s_bits
;
952 # if TARGET_LONG_BITS == 64
964 #if defined(CONFIG_SOFTMMU)
965 # if TARGET_LONG_BITS == 64
967 # if defined(TCG_TARGET_WORDS_BIGENDIAN)
982 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
983 data_reg1
= data_regh
;
984 data_reg2
= data_regl
;
986 data_reg1
= data_regl
;
987 data_reg2
= data_regh
;
990 data_reg1
= data_regl
;
993 #if defined(CONFIG_SOFTMMU)
994 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_A0
, addr_regl
, TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
995 tcg_out_opc_imm(s
, OPC_ANDI
, TCG_REG_A0
, TCG_REG_A0
, (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
996 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_A0
, TCG_REG_A0
, TCG_AREG0
);
997 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_AT
, TCG_REG_A0
,
998 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
) + addr_meml
);
999 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_T0
, TARGET_PAGE_MASK
| ((1 << s_bits
) - 1));
1000 tcg_out_opc_reg(s
, OPC_AND
, TCG_REG_T0
, TCG_REG_T0
, addr_regl
);
1002 # if TARGET_LONG_BITS == 64
1003 label3_ptr
= s
->code_ptr
;
1004 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_T0
, TCG_REG_AT
);
1007 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_AT
, TCG_REG_A0
,
1008 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_read
) + addr_memh
);
1010 label1_ptr
= s
->code_ptr
;
1011 tcg_out_opc_br(s
, OPC_BEQ
, addr_regh
, TCG_REG_AT
);
1014 reloc_pc16(label3_ptr
, (tcg_target_long
) s
->code_ptr
);
1016 label1_ptr
= s
->code_ptr
;
1017 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_T0
, TCG_REG_AT
);
1023 tcg_out_call_iarg_reg32(s
, &arg_num
, TCG_AREG0
);
1024 # if TARGET_LONG_BITS == 64
1025 tcg_out_call_iarg_reg64(s
, &arg_num
, addr_regl
, addr_regh
);
1027 tcg_out_call_iarg_reg32(s
, &arg_num
, addr_regl
);
1029 tcg_out_call_iarg_imm32(s
, &arg_num
, mem_index
);
1030 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_T9
, (tcg_target_long
)qemu_ld_helpers
[s_bits
]);
1031 tcg_out_opc_reg(s
, OPC_JALR
, TCG_REG_RA
, TCG_REG_T9
, 0);
1036 tcg_out_opc_imm(s
, OPC_ANDI
, data_reg1
, TCG_REG_V0
, 0xff);
1039 tcg_out_ext8s(s
, data_reg1
, TCG_REG_V0
);
1042 tcg_out_opc_imm(s
, OPC_ANDI
, data_reg1
, TCG_REG_V0
, 0xffff);
1045 tcg_out_ext16s(s
, data_reg1
, TCG_REG_V0
);
1048 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg1
, TCG_REG_V0
);
1051 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg2
, TCG_REG_V1
);
1052 tcg_out_mov(s
, TCG_TYPE_I32
, data_reg1
, TCG_REG_V0
);
1058 label2_ptr
= s
->code_ptr
;
1059 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_ZERO
, TCG_REG_ZERO
);
1062 /* label1: fast path */
1063 reloc_pc16(label1_ptr
, (tcg_target_long
) s
->code_ptr
);
1065 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_A0
, TCG_REG_A0
,
1066 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
));
1067 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_V0
, TCG_REG_A0
, addr_regl
);
1069 if (GUEST_BASE
== (int16_t)GUEST_BASE
) {
1070 tcg_out_opc_imm(s
, OPC_ADDIU
, TCG_REG_V0
, addr_regl
, GUEST_BASE
);
1072 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_V0
, GUEST_BASE
);
1073 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_V0
, TCG_REG_V0
, addr_regl
);
1079 tcg_out_opc_imm(s
, OPC_LBU
, data_reg1
, TCG_REG_V0
, 0);
1082 tcg_out_opc_imm(s
, OPC_LB
, data_reg1
, TCG_REG_V0
, 0);
1085 if (TCG_NEED_BSWAP
) {
1086 tcg_out_opc_imm(s
, OPC_LHU
, TCG_REG_T0
, TCG_REG_V0
, 0);
1087 tcg_out_bswap16(s
, data_reg1
, TCG_REG_T0
);
1089 tcg_out_opc_imm(s
, OPC_LHU
, data_reg1
, TCG_REG_V0
, 0);
1093 if (TCG_NEED_BSWAP
) {
1094 tcg_out_opc_imm(s
, OPC_LHU
, TCG_REG_T0
, TCG_REG_V0
, 0);
1095 tcg_out_bswap16s(s
, data_reg1
, TCG_REG_T0
);
1097 tcg_out_opc_imm(s
, OPC_LH
, data_reg1
, TCG_REG_V0
, 0);
1101 if (TCG_NEED_BSWAP
) {
1102 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_T0
, TCG_REG_V0
, 0);
1103 tcg_out_bswap32(s
, data_reg1
, TCG_REG_T0
);
1105 tcg_out_opc_imm(s
, OPC_LW
, data_reg1
, TCG_REG_V0
, 0);
1109 if (TCG_NEED_BSWAP
) {
1110 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_T0
, TCG_REG_V0
, 4);
1111 tcg_out_bswap32(s
, data_reg1
, TCG_REG_T0
);
1112 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_T0
, TCG_REG_V0
, 0);
1113 tcg_out_bswap32(s
, data_reg2
, TCG_REG_T0
);
1115 tcg_out_opc_imm(s
, OPC_LW
, data_reg1
, TCG_REG_V0
, 0);
1116 tcg_out_opc_imm(s
, OPC_LW
, data_reg2
, TCG_REG_V0
, 4);
1123 #if defined(CONFIG_SOFTMMU)
1124 reloc_pc16(label2_ptr
, (tcg_target_long
) s
->code_ptr
);
1128 static void tcg_out_qemu_st(TCGContext
*s
, const TCGArg
*args
,
1131 TCGReg addr_regl
, data_regl
, data_regh
, data_reg1
, data_reg2
;
1132 #if defined(CONFIG_SOFTMMU)
1133 uint8_t *label1_ptr
, *label2_ptr
;
1135 int mem_index
, s_bits
;
1138 #if TARGET_LONG_BITS == 64
1139 # if defined(CONFIG_SOFTMMU)
1140 uint8_t *label3_ptr
;
1145 data_regl
= *args
++;
1147 data_regh
= *args
++;
1151 addr_regl
= *args
++;
1152 #if defined(CONFIG_SOFTMMU)
1153 # if TARGET_LONG_BITS == 64
1154 addr_regh
= *args
++;
1155 # if defined(TCG_TARGET_WORDS_BIGENDIAN)
1170 #if defined(TCG_TARGET_WORDS_BIGENDIAN)
1171 data_reg1
= data_regh
;
1172 data_reg2
= data_regl
;
1174 data_reg1
= data_regl
;
1175 data_reg2
= data_regh
;
1178 data_reg1
= data_regl
;
1182 #if defined(CONFIG_SOFTMMU)
1183 tcg_out_opc_sa(s
, OPC_SRL
, TCG_REG_A0
, addr_regl
, TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
);
1184 tcg_out_opc_imm(s
, OPC_ANDI
, TCG_REG_A0
, TCG_REG_A0
, (CPU_TLB_SIZE
- 1) << CPU_TLB_ENTRY_BITS
);
1185 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_A0
, TCG_REG_A0
, TCG_AREG0
);
1186 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_AT
, TCG_REG_A0
,
1187 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
) + addr_meml
);
1188 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_T0
, TARGET_PAGE_MASK
| ((1 << s_bits
) - 1));
1189 tcg_out_opc_reg(s
, OPC_AND
, TCG_REG_T0
, TCG_REG_T0
, addr_regl
);
1191 # if TARGET_LONG_BITS == 64
1192 label3_ptr
= s
->code_ptr
;
1193 tcg_out_opc_br(s
, OPC_BNE
, TCG_REG_T0
, TCG_REG_AT
);
1196 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_AT
, TCG_REG_A0
,
1197 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addr_write
) + addr_memh
);
1199 label1_ptr
= s
->code_ptr
;
1200 tcg_out_opc_br(s
, OPC_BEQ
, addr_regh
, TCG_REG_AT
);
1203 reloc_pc16(label3_ptr
, (tcg_target_long
) s
->code_ptr
);
1205 label1_ptr
= s
->code_ptr
;
1206 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_T0
, TCG_REG_AT
);
1212 tcg_out_call_iarg_reg32(s
, &arg_num
, TCG_AREG0
);
1213 # if TARGET_LONG_BITS == 64
1214 tcg_out_call_iarg_reg64(s
, &arg_num
, addr_regl
, addr_regh
);
1216 tcg_out_call_iarg_reg32(s
, &arg_num
, addr_regl
);
1220 tcg_out_call_iarg_reg8(s
, &arg_num
, data_regl
);
1223 tcg_out_call_iarg_reg16(s
, &arg_num
, data_regl
);
1226 tcg_out_call_iarg_reg32(s
, &arg_num
, data_regl
);
1229 tcg_out_call_iarg_reg64(s
, &arg_num
, data_regl
, data_regh
);
1234 tcg_out_call_iarg_imm32(s
, &arg_num
, mem_index
);
1235 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_T9
, (tcg_target_long
)qemu_st_helpers
[s_bits
]);
1236 tcg_out_opc_reg(s
, OPC_JALR
, TCG_REG_RA
, TCG_REG_T9
, 0);
1239 label2_ptr
= s
->code_ptr
;
1240 tcg_out_opc_br(s
, OPC_BEQ
, TCG_REG_ZERO
, TCG_REG_ZERO
);
1243 /* label1: fast path */
1244 reloc_pc16(label1_ptr
, (tcg_target_long
) s
->code_ptr
);
1246 tcg_out_opc_imm(s
, OPC_LW
, TCG_REG_A0
, TCG_REG_A0
,
1247 offsetof(CPUArchState
, tlb_table
[mem_index
][0].addend
));
1248 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_A0
, TCG_REG_A0
, addr_regl
);
1250 if (GUEST_BASE
== (int16_t)GUEST_BASE
) {
1251 tcg_out_opc_imm(s
, OPC_ADDIU
, TCG_REG_A0
, addr_regl
, GUEST_BASE
);
1253 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_A0
, GUEST_BASE
);
1254 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_A0
, TCG_REG_A0
, addr_regl
);
1261 tcg_out_opc_imm(s
, OPC_SB
, data_reg1
, TCG_REG_A0
, 0);
1264 if (TCG_NEED_BSWAP
) {
1265 tcg_out_opc_imm(s
, OPC_ANDI
, TCG_REG_T0
, data_reg1
, 0xffff);
1266 tcg_out_bswap16(s
, TCG_REG_T0
, TCG_REG_T0
);
1267 tcg_out_opc_imm(s
, OPC_SH
, TCG_REG_T0
, TCG_REG_A0
, 0);
1269 tcg_out_opc_imm(s
, OPC_SH
, data_reg1
, TCG_REG_A0
, 0);
1273 if (TCG_NEED_BSWAP
) {
1274 tcg_out_bswap32(s
, TCG_REG_T0
, data_reg1
);
1275 tcg_out_opc_imm(s
, OPC_SW
, TCG_REG_T0
, TCG_REG_A0
, 0);
1277 tcg_out_opc_imm(s
, OPC_SW
, data_reg1
, TCG_REG_A0
, 0);
1281 if (TCG_NEED_BSWAP
) {
1282 tcg_out_bswap32(s
, TCG_REG_T0
, data_reg2
);
1283 tcg_out_opc_imm(s
, OPC_SW
, TCG_REG_T0
, TCG_REG_A0
, 0);
1284 tcg_out_bswap32(s
, TCG_REG_T0
, data_reg1
);
1285 tcg_out_opc_imm(s
, OPC_SW
, TCG_REG_T0
, TCG_REG_A0
, 4);
1287 tcg_out_opc_imm(s
, OPC_SW
, data_reg1
, TCG_REG_A0
, 0);
1288 tcg_out_opc_imm(s
, OPC_SW
, data_reg2
, TCG_REG_A0
, 4);
1295 #if defined(CONFIG_SOFTMMU)
1296 reloc_pc16(label2_ptr
, (tcg_target_long
) s
->code_ptr
);
1300 static inline void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1301 const TCGArg
*args
, const int *const_args
)
1304 case INDEX_op_exit_tb
:
1305 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_V0
, args
[0]);
1306 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_AT
, (tcg_target_long
)tb_ret_addr
);
1307 tcg_out_opc_reg(s
, OPC_JR
, 0, TCG_REG_AT
, 0);
1310 case INDEX_op_goto_tb
:
1311 if (s
->tb_jmp_offset
) {
1312 /* direct jump method */
1315 /* indirect jump method */
1316 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_AT
, (tcg_target_long
)(s
->tb_next
+ args
[0]));
1317 tcg_out_ld(s
, TCG_TYPE_PTR
, TCG_REG_AT
, TCG_REG_AT
, 0);
1318 tcg_out_opc_reg(s
, OPC_JR
, 0, TCG_REG_AT
, 0);
1321 s
->tb_next_offset
[args
[0]] = s
->code_ptr
- s
->code_buf
;
1324 tcg_out_opc_reg(s
, OPC_JALR
, TCG_REG_RA
, args
[0], 0);
1328 tcg_out_brcond(s
, TCG_COND_EQ
, TCG_REG_ZERO
, TCG_REG_ZERO
, args
[0]);
1331 case INDEX_op_mov_i32
:
1332 tcg_out_mov(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1334 case INDEX_op_movi_i32
:
1335 tcg_out_movi(s
, TCG_TYPE_I32
, args
[0], args
[1]);
1338 case INDEX_op_ld8u_i32
:
1339 tcg_out_ldst(s
, OPC_LBU
, args
[0], args
[1], args
[2]);
1341 case INDEX_op_ld8s_i32
:
1342 tcg_out_ldst(s
, OPC_LB
, args
[0], args
[1], args
[2]);
1344 case INDEX_op_ld16u_i32
:
1345 tcg_out_ldst(s
, OPC_LHU
, args
[0], args
[1], args
[2]);
1347 case INDEX_op_ld16s_i32
:
1348 tcg_out_ldst(s
, OPC_LH
, args
[0], args
[1], args
[2]);
1350 case INDEX_op_ld_i32
:
1351 tcg_out_ldst(s
, OPC_LW
, args
[0], args
[1], args
[2]);
1353 case INDEX_op_st8_i32
:
1354 tcg_out_ldst(s
, OPC_SB
, args
[0], args
[1], args
[2]);
1356 case INDEX_op_st16_i32
:
1357 tcg_out_ldst(s
, OPC_SH
, args
[0], args
[1], args
[2]);
1359 case INDEX_op_st_i32
:
1360 tcg_out_ldst(s
, OPC_SW
, args
[0], args
[1], args
[2]);
1363 case INDEX_op_add_i32
:
1364 if (const_args
[2]) {
1365 tcg_out_opc_imm(s
, OPC_ADDIU
, args
[0], args
[1], args
[2]);
1367 tcg_out_opc_reg(s
, OPC_ADDU
, args
[0], args
[1], args
[2]);
1370 case INDEX_op_add2_i32
:
1371 if (const_args
[4]) {
1372 tcg_out_opc_imm(s
, OPC_ADDIU
, TCG_REG_AT
, args
[2], args
[4]);
1374 tcg_out_opc_reg(s
, OPC_ADDU
, TCG_REG_AT
, args
[2], args
[4]);
1376 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_T0
, TCG_REG_AT
, args
[2]);
1377 if (const_args
[5]) {
1378 tcg_out_opc_imm(s
, OPC_ADDIU
, args
[1], args
[3], args
[5]);
1380 tcg_out_opc_reg(s
, OPC_ADDU
, args
[1], args
[3], args
[5]);
1382 tcg_out_opc_reg(s
, OPC_ADDU
, args
[1], args
[1], TCG_REG_T0
);
1383 tcg_out_mov(s
, TCG_TYPE_I32
, args
[0], TCG_REG_AT
);
1385 case INDEX_op_sub_i32
:
1386 if (const_args
[2]) {
1387 tcg_out_opc_imm(s
, OPC_ADDIU
, args
[0], args
[1], -args
[2]);
1389 tcg_out_opc_reg(s
, OPC_SUBU
, args
[0], args
[1], args
[2]);
1392 case INDEX_op_sub2_i32
:
1393 if (const_args
[4]) {
1394 tcg_out_opc_imm(s
, OPC_ADDIU
, TCG_REG_AT
, args
[2], -args
[4]);
1396 tcg_out_opc_reg(s
, OPC_SUBU
, TCG_REG_AT
, args
[2], args
[4]);
1398 tcg_out_opc_reg(s
, OPC_SLTU
, TCG_REG_T0
, args
[2], TCG_REG_AT
);
1399 if (const_args
[5]) {
1400 tcg_out_opc_imm(s
, OPC_ADDIU
, args
[1], args
[3], -args
[5]);
1402 tcg_out_opc_reg(s
, OPC_SUBU
, args
[1], args
[3], args
[5]);
1404 tcg_out_opc_reg(s
, OPC_SUBU
, args
[1], args
[1], TCG_REG_T0
);
1405 tcg_out_mov(s
, TCG_TYPE_I32
, args
[0], TCG_REG_AT
);
1407 case INDEX_op_mul_i32
:
1408 if (use_mips32_instructions
) {
1409 tcg_out_opc_reg(s
, OPC_MUL
, args
[0], args
[1], args
[2]);
1411 tcg_out_opc_reg(s
, OPC_MULT
, 0, args
[1], args
[2]);
1412 tcg_out_opc_reg(s
, OPC_MFLO
, args
[0], 0, 0);
1415 case INDEX_op_muls2_i32
:
1416 tcg_out_opc_reg(s
, OPC_MULT
, 0, args
[2], args
[3]);
1417 tcg_out_opc_reg(s
, OPC_MFLO
, args
[0], 0, 0);
1418 tcg_out_opc_reg(s
, OPC_MFHI
, args
[1], 0, 0);
1420 case INDEX_op_mulu2_i32
:
1421 tcg_out_opc_reg(s
, OPC_MULTU
, 0, args
[2], args
[3]);
1422 tcg_out_opc_reg(s
, OPC_MFLO
, args
[0], 0, 0);
1423 tcg_out_opc_reg(s
, OPC_MFHI
, args
[1], 0, 0);
1425 case INDEX_op_mulsh_i32
:
1426 tcg_out_opc_reg(s
, OPC_MULT
, 0, args
[1], args
[2]);
1427 tcg_out_opc_reg(s
, OPC_MFHI
, args
[0], 0, 0);
1429 case INDEX_op_muluh_i32
:
1430 tcg_out_opc_reg(s
, OPC_MULTU
, 0, args
[1], args
[2]);
1431 tcg_out_opc_reg(s
, OPC_MFHI
, args
[0], 0, 0);
1433 case INDEX_op_div_i32
:
1434 tcg_out_opc_reg(s
, OPC_DIV
, 0, args
[1], args
[2]);
1435 tcg_out_opc_reg(s
, OPC_MFLO
, args
[0], 0, 0);
1437 case INDEX_op_divu_i32
:
1438 tcg_out_opc_reg(s
, OPC_DIVU
, 0, args
[1], args
[2]);
1439 tcg_out_opc_reg(s
, OPC_MFLO
, args
[0], 0, 0);
1441 case INDEX_op_rem_i32
:
1442 tcg_out_opc_reg(s
, OPC_DIV
, 0, args
[1], args
[2]);
1443 tcg_out_opc_reg(s
, OPC_MFHI
, args
[0], 0, 0);
1445 case INDEX_op_remu_i32
:
1446 tcg_out_opc_reg(s
, OPC_DIVU
, 0, args
[1], args
[2]);
1447 tcg_out_opc_reg(s
, OPC_MFHI
, args
[0], 0, 0);
1450 case INDEX_op_and_i32
:
1451 if (const_args
[2]) {
1452 tcg_out_opc_imm(s
, OPC_ANDI
, args
[0], args
[1], args
[2]);
1454 tcg_out_opc_reg(s
, OPC_AND
, args
[0], args
[1], args
[2]);
1457 case INDEX_op_or_i32
:
1458 if (const_args
[2]) {
1459 tcg_out_opc_imm(s
, OPC_ORI
, args
[0], args
[1], args
[2]);
1461 tcg_out_opc_reg(s
, OPC_OR
, args
[0], args
[1], args
[2]);
1464 case INDEX_op_nor_i32
:
1465 tcg_out_opc_reg(s
, OPC_NOR
, args
[0], args
[1], args
[2]);
1467 case INDEX_op_not_i32
:
1468 tcg_out_opc_reg(s
, OPC_NOR
, args
[0], TCG_REG_ZERO
, args
[1]);
1470 case INDEX_op_xor_i32
:
1471 if (const_args
[2]) {
1472 tcg_out_opc_imm(s
, OPC_XORI
, args
[0], args
[1], args
[2]);
1474 tcg_out_opc_reg(s
, OPC_XOR
, args
[0], args
[1], args
[2]);
1478 case INDEX_op_sar_i32
:
1479 if (const_args
[2]) {
1480 tcg_out_opc_sa(s
, OPC_SRA
, args
[0], args
[1], args
[2]);
1482 tcg_out_opc_reg(s
, OPC_SRAV
, args
[0], args
[2], args
[1]);
1485 case INDEX_op_shl_i32
:
1486 if (const_args
[2]) {
1487 tcg_out_opc_sa(s
, OPC_SLL
, args
[0], args
[1], args
[2]);
1489 tcg_out_opc_reg(s
, OPC_SLLV
, args
[0], args
[2], args
[1]);
1492 case INDEX_op_shr_i32
:
1493 if (const_args
[2]) {
1494 tcg_out_opc_sa(s
, OPC_SRL
, args
[0], args
[1], args
[2]);
1496 tcg_out_opc_reg(s
, OPC_SRLV
, args
[0], args
[2], args
[1]);
1499 case INDEX_op_rotl_i32
:
1500 if (const_args
[2]) {
1501 tcg_out_opc_sa(s
, OPC_ROTR
, args
[0], args
[1], 0x20 - args
[2]);
1503 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_AT
, 32);
1504 tcg_out_opc_reg(s
, OPC_SUBU
, TCG_REG_AT
, TCG_REG_AT
, args
[2]);
1505 tcg_out_opc_reg(s
, OPC_ROTRV
, args
[0], TCG_REG_AT
, args
[1]);
1508 case INDEX_op_rotr_i32
:
1509 if (const_args
[2]) {
1510 tcg_out_opc_sa(s
, OPC_ROTR
, args
[0], args
[1], args
[2]);
1512 tcg_out_opc_reg(s
, OPC_ROTRV
, args
[0], args
[2], args
[1]);
1516 case INDEX_op_bswap16_i32
:
1517 tcg_out_opc_reg(s
, OPC_WSBH
, args
[0], 0, args
[1]);
1519 case INDEX_op_bswap32_i32
:
1520 tcg_out_opc_reg(s
, OPC_WSBH
, args
[0], 0, args
[1]);
1521 tcg_out_opc_sa(s
, OPC_ROTR
, args
[0], args
[0], 16);
1524 case INDEX_op_ext8s_i32
:
1525 tcg_out_opc_reg(s
, OPC_SEB
, args
[0], 0, args
[1]);
1527 case INDEX_op_ext16s_i32
:
1528 tcg_out_opc_reg(s
, OPC_SEH
, args
[0], 0, args
[1]);
1531 case INDEX_op_deposit_i32
:
1532 tcg_out_opc_imm(s
, OPC_INS
, args
[0], args
[2],
1533 ((args
[3] + args
[4] - 1) << 11) | (args
[3] << 6));
1536 case INDEX_op_brcond_i32
:
1537 tcg_out_brcond(s
, args
[2], args
[0], args
[1], args
[3]);
1539 case INDEX_op_brcond2_i32
:
1540 tcg_out_brcond2(s
, args
[4], args
[0], args
[1], args
[2], args
[3], args
[5]);
1543 case INDEX_op_movcond_i32
:
1544 tcg_out_movcond(s
, args
[5], args
[0], args
[1], args
[2], args
[3]);
1547 case INDEX_op_setcond_i32
:
1548 tcg_out_setcond(s
, args
[3], args
[0], args
[1], args
[2]);
1550 case INDEX_op_setcond2_i32
:
1551 tcg_out_setcond2(s
, args
[5], args
[0], args
[1], args
[2], args
[3], args
[4]);
1554 case INDEX_op_qemu_ld8u
:
1555 tcg_out_qemu_ld(s
, args
, 0);
1557 case INDEX_op_qemu_ld8s
:
1558 tcg_out_qemu_ld(s
, args
, 0 | 4);
1560 case INDEX_op_qemu_ld16u
:
1561 tcg_out_qemu_ld(s
, args
, 1);
1563 case INDEX_op_qemu_ld16s
:
1564 tcg_out_qemu_ld(s
, args
, 1 | 4);
1566 case INDEX_op_qemu_ld32
:
1567 tcg_out_qemu_ld(s
, args
, 2);
1569 case INDEX_op_qemu_ld64
:
1570 tcg_out_qemu_ld(s
, args
, 3);
1572 case INDEX_op_qemu_st8
:
1573 tcg_out_qemu_st(s
, args
, 0);
1575 case INDEX_op_qemu_st16
:
1576 tcg_out_qemu_st(s
, args
, 1);
1578 case INDEX_op_qemu_st32
:
1579 tcg_out_qemu_st(s
, args
, 2);
1581 case INDEX_op_qemu_st64
:
1582 tcg_out_qemu_st(s
, args
, 3);
1590 static const TCGTargetOpDef mips_op_defs
[] = {
1591 { INDEX_op_exit_tb
, { } },
1592 { INDEX_op_goto_tb
, { } },
1593 { INDEX_op_call
, { "C" } },
1594 { INDEX_op_br
, { } },
1596 { INDEX_op_mov_i32
, { "r", "r" } },
1597 { INDEX_op_movi_i32
, { "r" } },
1598 { INDEX_op_ld8u_i32
, { "r", "r" } },
1599 { INDEX_op_ld8s_i32
, { "r", "r" } },
1600 { INDEX_op_ld16u_i32
, { "r", "r" } },
1601 { INDEX_op_ld16s_i32
, { "r", "r" } },
1602 { INDEX_op_ld_i32
, { "r", "r" } },
1603 { INDEX_op_st8_i32
, { "rZ", "r" } },
1604 { INDEX_op_st16_i32
, { "rZ", "r" } },
1605 { INDEX_op_st_i32
, { "rZ", "r" } },
1607 { INDEX_op_add_i32
, { "r", "rZ", "rJ" } },
1608 { INDEX_op_mul_i32
, { "r", "rZ", "rZ" } },
1609 { INDEX_op_muls2_i32
, { "r", "r", "rZ", "rZ" } },
1610 { INDEX_op_mulu2_i32
, { "r", "r", "rZ", "rZ" } },
1611 { INDEX_op_mulsh_i32
, { "r", "rZ", "rZ" } },
1612 { INDEX_op_muluh_i32
, { "r", "rZ", "rZ" } },
1613 { INDEX_op_div_i32
, { "r", "rZ", "rZ" } },
1614 { INDEX_op_divu_i32
, { "r", "rZ", "rZ" } },
1615 { INDEX_op_rem_i32
, { "r", "rZ", "rZ" } },
1616 { INDEX_op_remu_i32
, { "r", "rZ", "rZ" } },
1617 { INDEX_op_sub_i32
, { "r", "rZ", "rJ" } },
1619 { INDEX_op_and_i32
, { "r", "rZ", "rI" } },
1620 { INDEX_op_nor_i32
, { "r", "rZ", "rZ" } },
1621 { INDEX_op_not_i32
, { "r", "rZ" } },
1622 { INDEX_op_or_i32
, { "r", "rZ", "rIZ" } },
1623 { INDEX_op_xor_i32
, { "r", "rZ", "rIZ" } },
1625 { INDEX_op_shl_i32
, { "r", "rZ", "ri" } },
1626 { INDEX_op_shr_i32
, { "r", "rZ", "ri" } },
1627 { INDEX_op_sar_i32
, { "r", "rZ", "ri" } },
1628 { INDEX_op_rotr_i32
, { "r", "rZ", "ri" } },
1629 { INDEX_op_rotl_i32
, { "r", "rZ", "ri" } },
1631 { INDEX_op_bswap16_i32
, { "r", "r" } },
1632 { INDEX_op_bswap32_i32
, { "r", "r" } },
1634 { INDEX_op_ext8s_i32
, { "r", "rZ" } },
1635 { INDEX_op_ext16s_i32
, { "r", "rZ" } },
1637 { INDEX_op_deposit_i32
, { "r", "0", "rZ" } },
1639 { INDEX_op_brcond_i32
, { "rZ", "rZ" } },
1640 { INDEX_op_movcond_i32
, { "r", "rZ", "rZ", "rZ", "0" } },
1641 { INDEX_op_setcond_i32
, { "r", "rZ", "rZ" } },
1642 { INDEX_op_setcond2_i32
, { "r", "rZ", "rZ", "rZ", "rZ" } },
1644 { INDEX_op_add2_i32
, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1645 { INDEX_op_sub2_i32
, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1646 { INDEX_op_brcond2_i32
, { "rZ", "rZ", "rZ", "rZ" } },
1648 #if TARGET_LONG_BITS == 32
1649 { INDEX_op_qemu_ld8u
, { "L", "lZ" } },
1650 { INDEX_op_qemu_ld8s
, { "L", "lZ" } },
1651 { INDEX_op_qemu_ld16u
, { "L", "lZ" } },
1652 { INDEX_op_qemu_ld16s
, { "L", "lZ" } },
1653 { INDEX_op_qemu_ld32
, { "L", "lZ" } },
1654 { INDEX_op_qemu_ld64
, { "L", "L", "lZ" } },
1656 { INDEX_op_qemu_st8
, { "SZ", "SZ" } },
1657 { INDEX_op_qemu_st16
, { "SZ", "SZ" } },
1658 { INDEX_op_qemu_st32
, { "SZ", "SZ" } },
1659 { INDEX_op_qemu_st64
, { "SZ", "SZ", "SZ" } },
1661 { INDEX_op_qemu_ld8u
, { "L", "lZ", "lZ" } },
1662 { INDEX_op_qemu_ld8s
, { "L", "lZ", "lZ" } },
1663 { INDEX_op_qemu_ld16u
, { "L", "lZ", "lZ" } },
1664 { INDEX_op_qemu_ld16s
, { "L", "lZ", "lZ" } },
1665 { INDEX_op_qemu_ld32
, { "L", "lZ", "lZ" } },
1666 { INDEX_op_qemu_ld64
, { "L", "L", "lZ", "lZ" } },
1668 { INDEX_op_qemu_st8
, { "SZ", "SZ", "SZ" } },
1669 { INDEX_op_qemu_st16
, { "SZ", "SZ", "SZ" } },
1670 { INDEX_op_qemu_st32
, { "SZ", "SZ", "SZ" } },
1671 { INDEX_op_qemu_st64
, { "SZ", "SZ", "SZ", "SZ" } },
1676 static int tcg_target_callee_save_regs
[] = {
1677 TCG_REG_S0
, /* used for the global env (TCG_AREG0) */
1686 TCG_REG_RA
, /* should be last for ABI compliance */
1689 /* The Linux kernel doesn't provide any information about the available
1690 instruction set. Probe it using a signal handler. */
1694 #ifndef use_movnz_instructions
1695 bool use_movnz_instructions
= false;
1698 #ifndef use_mips32_instructions
1699 bool use_mips32_instructions
= false;
1702 #ifndef use_mips32r2_instructions
1703 bool use_mips32r2_instructions
= false;
1706 static volatile sig_atomic_t got_sigill
;
1708 static void sigill_handler(int signo
, siginfo_t
*si
, void *data
)
1710 /* Skip the faulty instruction */
1711 ucontext_t
*uc
= (ucontext_t
*)data
;
1712 uc
->uc_mcontext
.pc
+= 4;
1717 static void tcg_target_detect_isa(void)
1719 struct sigaction sa_old
, sa_new
;
1721 memset(&sa_new
, 0, sizeof(sa_new
));
1722 sa_new
.sa_flags
= SA_SIGINFO
;
1723 sa_new
.sa_sigaction
= sigill_handler
;
1724 sigaction(SIGILL
, &sa_new
, &sa_old
);
1726 /* Probe for movn/movz, necessary to implement movcond. */
1727 #ifndef use_movnz_instructions
1729 asm volatile(".set push\n"
1731 "movn $zero, $zero, $zero\n"
1732 "movz $zero, $zero, $zero\n"
1735 use_movnz_instructions
= !got_sigill
;
1738 /* Probe for MIPS32 instructions. As no subsetting is allowed
1739 by the specification, it is only necessary to probe for one
1740 of the instructions. */
1741 #ifndef use_mips32_instructions
1743 asm volatile(".set push\n"
1745 "mul $zero, $zero\n"
1748 use_mips32_instructions
= !got_sigill
;
1751 /* Probe for MIPS32r2 instructions if MIPS32 instructions are
1752 available. As no subsetting is allowed by the specification,
1753 it is only necessary to probe for one of the instructions. */
1754 #ifndef use_mips32r2_instructions
1755 if (use_mips32_instructions
) {
1757 asm volatile(".set push\n"
1759 "seb $zero, $zero\n"
1762 use_mips32r2_instructions
= !got_sigill
;
1766 sigaction(SIGILL
, &sa_old
, NULL
);
1769 /* Generate global QEMU prologue and epilogue code */
1770 static void tcg_target_qemu_prologue(TCGContext
*s
)
1774 /* reserve some stack space, also for TCG temps. */
1775 frame_size
= ARRAY_SIZE(tcg_target_callee_save_regs
) * 4
1776 + TCG_STATIC_CALL_ARGS_SIZE
1777 + CPU_TEMP_BUF_NLONGS
* sizeof(long);
1778 frame_size
= (frame_size
+ TCG_TARGET_STACK_ALIGN
- 1) &
1779 ~(TCG_TARGET_STACK_ALIGN
- 1);
1780 tcg_set_frame(s
, TCG_REG_SP
, ARRAY_SIZE(tcg_target_callee_save_regs
) * 4
1781 + TCG_STATIC_CALL_ARGS_SIZE
,
1782 CPU_TEMP_BUF_NLONGS
* sizeof(long));
1785 tcg_out_addi(s
, TCG_REG_SP
, -frame_size
);
1786 for(i
= 0 ; i
< ARRAY_SIZE(tcg_target_callee_save_regs
) ; i
++) {
1787 tcg_out_st(s
, TCG_TYPE_I32
, tcg_target_callee_save_regs
[i
],
1788 TCG_REG_SP
, TCG_STATIC_CALL_ARGS_SIZE
+ i
* 4);
1791 /* Call generated code */
1792 tcg_out_opc_reg(s
, OPC_JR
, 0, tcg_target_call_iarg_regs
[1], 0);
1793 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_AREG0
, tcg_target_call_iarg_regs
[0]);
1794 tb_ret_addr
= s
->code_ptr
;
1797 for(i
= 0 ; i
< ARRAY_SIZE(tcg_target_callee_save_regs
) ; i
++) {
1798 tcg_out_ld(s
, TCG_TYPE_I32
, tcg_target_callee_save_regs
[i
],
1799 TCG_REG_SP
, TCG_STATIC_CALL_ARGS_SIZE
+ i
* 4);
1802 tcg_out_opc_reg(s
, OPC_JR
, 0, TCG_REG_RA
, 0);
1803 tcg_out_addi(s
, TCG_REG_SP
, frame_size
);
1806 static void tcg_target_init(TCGContext
*s
)
1808 tcg_target_detect_isa();
1809 tcg_regset_set(tcg_target_available_regs
[TCG_TYPE_I32
], 0xffffffff);
1810 tcg_regset_set(tcg_target_call_clobber_regs
,
1827 tcg_regset_clear(s
->reserved_regs
);
1828 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_ZERO
); /* zero register */
1829 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_K0
); /* kernel use only */
1830 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_K1
); /* kernel use only */
1831 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_AT
); /* internal use */
1832 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_T0
); /* internal use */
1833 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_RA
); /* return address */
1834 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_SP
); /* stack pointer */
1835 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_GP
); /* global pointer */
1837 tcg_add_target_add_op_defs(mips_op_defs
);