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 #include "tcg-be-null.h"
28 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
64 /* Define some temporary registers. T2 is used for constant generation. */
65 #define TCG_REG_T1 TCG_REG_G1
66 #define TCG_REG_T2 TCG_REG_O7
68 #ifdef CONFIG_USE_GUEST_BASE
69 # define TCG_GUEST_BASE_REG TCG_REG_I5
71 # define TCG_GUEST_BASE_REG TCG_REG_G0
74 static const int tcg_target_reg_alloc_order[] = {
104 static const int tcg_target_call_iarg_regs[6] = {
113 static const int tcg_target_call_oarg_regs[] = {
120 #define INSN_OP(x) ((x) << 30)
121 #define INSN_OP2(x) ((x) << 22)
122 #define INSN_OP3(x) ((x) << 19)
123 #define INSN_OPF(x) ((x) << 5)
124 #define INSN_RD(x) ((x) << 25)
125 #define INSN_RS1(x) ((x) << 14)
126 #define INSN_RS2(x) (x)
127 #define INSN_ASI(x) ((x) << 5)
129 #define INSN_IMM10(x) ((1 << 13) | ((x) & 0x3ff))
130 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
131 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
132 #define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
133 #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
134 #define INSN_COND(x) ((x) << 25)
152 #define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
161 #define MOVCC_ICC (1 << 18)
162 #define MOVCC_XCC (1 << 18 | 1 << 12)
165 #define BPCC_XCC (2 << 20)
166 #define BPCC_PT (1 << 19)
168 #define BPCC_A (1 << 29)
170 #define BPR_PT BPCC_PT
172 #define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
173 #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
174 #define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))
175 #define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
176 #define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))
177 #define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
178 #define ARITH_ORN (INSN_OP(2) | INSN_OP3(0x06))
179 #define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03))
180 #define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04))
181 #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
182 #define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x08))
183 #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
184 #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
185 #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
186 #define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
187 #define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
188 #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
189 #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
190 #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
191 #define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f))
193 #define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25))
194 #define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26))
195 #define SHIFT_SRA (INSN_OP(2) | INSN_OP3(0x27))
197 #define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
198 #define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
199 #define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
201 #define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
202 #define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
203 #define JMPL (INSN_OP(2) | INSN_OP3(0x38))
204 #define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
205 #define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
206 #define SETHI (INSN_OP(0) | INSN_OP2(0x4))
207 #define CALL INSN_OP(1)
208 #define LDUB (INSN_OP(3) | INSN_OP3(0x01))
209 #define LDSB (INSN_OP(3) | INSN_OP3(0x09))
210 #define LDUH (INSN_OP(3) | INSN_OP3(0x02))
211 #define LDSH (INSN_OP(3) | INSN_OP3(0x0a))
212 #define LDUW (INSN_OP(3) | INSN_OP3(0x00))
213 #define LDSW (INSN_OP(3) | INSN_OP3(0x08))
214 #define LDX (INSN_OP(3) | INSN_OP3(0x0b))
215 #define STB (INSN_OP(3) | INSN_OP3(0x05))
216 #define STH (INSN_OP(3) | INSN_OP3(0x06))
217 #define STW (INSN_OP(3) | INSN_OP3(0x04))
218 #define STX (INSN_OP(3) | INSN_OP3(0x0e))
219 #define LDUBA (INSN_OP(3) | INSN_OP3(0x11))
220 #define LDSBA (INSN_OP(3) | INSN_OP3(0x19))
221 #define LDUHA (INSN_OP(3) | INSN_OP3(0x12))
222 #define LDSHA (INSN_OP(3) | INSN_OP3(0x1a))
223 #define LDUWA (INSN_OP(3) | INSN_OP3(0x10))
224 #define LDSWA (INSN_OP(3) | INSN_OP3(0x18))
225 #define LDXA (INSN_OP(3) | INSN_OP3(0x1b))
226 #define STBA (INSN_OP(3) | INSN_OP3(0x15))
227 #define STHA (INSN_OP(3) | INSN_OP3(0x16))
228 #define STWA (INSN_OP(3) | INSN_OP3(0x14))
229 #define STXA (INSN_OP(3) | INSN_OP3(0x1e))
231 #ifndef ASI_PRIMARY_LITTLE
232 #define ASI_PRIMARY_LITTLE 0x88
235 #define LDUH_LE (LDUHA | INSN_ASI(ASI_PRIMARY_LITTLE))
236 #define LDSH_LE (LDSHA | INSN_ASI(ASI_PRIMARY_LITTLE))
237 #define LDUW_LE (LDUWA | INSN_ASI(ASI_PRIMARY_LITTLE))
238 #define LDSW_LE (LDSWA | INSN_ASI(ASI_PRIMARY_LITTLE))
239 #define LDX_LE (LDXA | INSN_ASI(ASI_PRIMARY_LITTLE))
241 #define STH_LE (STHA | INSN_ASI(ASI_PRIMARY_LITTLE))
242 #define STW_LE (STWA | INSN_ASI(ASI_PRIMARY_LITTLE))
243 #define STX_LE (STXA | INSN_ASI(ASI_PRIMARY_LITTLE))
245 static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
247 return (val << ((sizeof(tcg_target_long) * 8 - bits))
248 >> (sizeof(tcg_target_long) * 8 - bits)) == val;
251 static inline int check_fit_i32(uint32_t val, unsigned int bits)
253 return ((val << (32 - bits)) >> (32 - bits)) == val;
256 static void patch_reloc(uint8_t *code_ptr, int type,
257 intptr_t value, intptr_t addend)
263 if (value != (uint32_t)value) {
266 *(uint32_t *)code_ptr = value;
268 case R_SPARC_WDISP16:
269 value -= (intptr_t)code_ptr;
270 if (!check_fit_tl(value >> 2, 16)) {
273 insn = *(uint32_t *)code_ptr;
274 insn &= ~INSN_OFF16(-1);
275 insn |= INSN_OFF16(value);
276 *(uint32_t *)code_ptr = insn;
278 case R_SPARC_WDISP19:
279 value -= (intptr_t)code_ptr;
280 if (!check_fit_tl(value >> 2, 19)) {
283 insn = *(uint32_t *)code_ptr;
284 insn &= ~INSN_OFF19(-1);
285 insn |= INSN_OFF19(value);
286 *(uint32_t *)code_ptr = insn;
293 /* parse target specific constraints */
294 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
301 ct->ct |= TCG_CT_REG;
302 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
304 case 'L': /* qemu_ld/st constraint */
305 ct->ct |= TCG_CT_REG;
306 tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
308 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
309 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
310 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
313 ct->ct |= TCG_CT_CONST_S11;
316 ct->ct |= TCG_CT_CONST_S13;
319 ct->ct |= TCG_CT_CONST_ZERO;
329 /* test if a constant matches the constraint */
330 static inline int tcg_target_const_match(tcg_target_long val,
331 const TCGArgConstraint *arg_ct)
335 if (ct & TCG_CT_CONST) {
337 } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
339 } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
341 } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
348 static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
351 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
355 static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
356 uint32_t offset, int op)
358 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
362 static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
363 int val2, int val2const, int op)
365 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
366 | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
369 static inline void tcg_out_mov(TCGContext *s, TCGType type,
370 TCGReg ret, TCGReg arg)
373 tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
377 static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
379 tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
382 static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
384 tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
387 static void tcg_out_movi(TCGContext *s, TCGType type,
388 TCGReg ret, tcg_target_long arg)
390 tcg_target_long hi, lo;
392 /* A 13-bit constant sign-extended to 64-bits. */
393 if (check_fit_tl(arg, 13)) {
394 tcg_out_movi_imm13(s, ret, arg);
398 /* A 32-bit constant, or 32-bit zero-extended to 64-bits. */
399 if (TCG_TARGET_REG_BITS == 32
400 || type == TCG_TYPE_I32
401 || (arg & ~0xffffffffu) == 0) {
402 tcg_out_sethi(s, ret, arg);
404 tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
409 /* A 32-bit constant sign-extended to 64-bits. */
410 if (check_fit_tl(arg, 32)) {
411 tcg_out_sethi(s, ret, ~arg);
412 tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
416 /* A 64-bit constant decomposed into 2 32-bit pieces. */
418 if (check_fit_tl(lo, 13)) {
419 hi = (arg - lo) >> 31 >> 1;
420 tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
421 tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
422 tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
425 tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
426 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
427 tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
428 tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
432 static inline void tcg_out_ldst_rr(TCGContext *s, int data, int a1,
435 tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
438 static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
441 if (check_fit_tl(offset, 13)) {
442 tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
445 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, offset);
446 tcg_out_ldst_rr(s, ret, addr, TCG_REG_T1, op);
450 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
451 TCGReg arg1, intptr_t arg2)
453 tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
456 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
457 TCGReg arg1, intptr_t arg2)
459 tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
462 static inline void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
464 TCGReg base = TCG_REG_G0;
465 if (!check_fit_tl(arg, 10)) {
466 tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
469 tcg_out_ld(s, TCG_TYPE_PTR, ret, base, arg & 0x3ff);
472 static inline void tcg_out_sety(TCGContext *s, int rs)
474 tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
477 static inline void tcg_out_rdy(TCGContext *s, int rd)
479 tcg_out32(s, RDY | INSN_RD(rd));
482 static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
485 if (check_fit_tl(val, 13))
486 tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
488 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, val);
489 tcg_out_arith(s, reg, reg, TCG_REG_T1, ARITH_ADD);
494 static void tcg_out_div32(TCGContext *s, int rd, int rs1,
495 int val2, int val2const, int uns)
497 /* Load Y with the sign/zero extension of RS1 to 64-bits. */
499 tcg_out_sety(s, TCG_REG_G0);
501 tcg_out_arithi(s, TCG_REG_T1, rs1, 31, SHIFT_SRA);
502 tcg_out_sety(s, TCG_REG_T1);
505 tcg_out_arithc(s, rd, rs1, val2, val2const,
506 uns ? ARITH_UDIV : ARITH_SDIV);
509 static inline void tcg_out_nop(TCGContext *s)
511 tcg_out_sethi(s, TCG_REG_G0, 0);
514 static const uint8_t tcg_cond_to_bcond[] = {
515 [TCG_COND_EQ] = COND_E,
516 [TCG_COND_NE] = COND_NE,
517 [TCG_COND_LT] = COND_L,
518 [TCG_COND_GE] = COND_GE,
519 [TCG_COND_LE] = COND_LE,
520 [TCG_COND_GT] = COND_G,
521 [TCG_COND_LTU] = COND_CS,
522 [TCG_COND_GEU] = COND_CC,
523 [TCG_COND_LEU] = COND_LEU,
524 [TCG_COND_GTU] = COND_GU,
527 static const uint8_t tcg_cond_to_rcond[] = {
528 [TCG_COND_EQ] = RCOND_Z,
529 [TCG_COND_NE] = RCOND_NZ,
530 [TCG_COND_LT] = RCOND_LZ,
531 [TCG_COND_GT] = RCOND_GZ,
532 [TCG_COND_LE] = RCOND_LEZ,
533 [TCG_COND_GE] = RCOND_GEZ
536 static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
538 tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
541 static void tcg_out_bpcc(TCGContext *s, int scond, int flags, int label)
543 TCGLabel *l = &s->labels[label];
547 off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
549 /* Make sure to preserve destinations during retranslation. */
550 off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
551 tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label, 0);
553 tcg_out_bpcc0(s, scond, flags, off19);
556 static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
558 tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
561 static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGArg arg1,
562 TCGArg arg2, int const_arg2, int label)
564 tcg_out_cmp(s, arg1, arg2, const_arg2);
565 tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, label);
569 static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGArg ret,
570 TCGArg v1, int v1const)
572 tcg_out32(s, ARITH_MOVCC | cc | INSN_RD(ret)
573 | INSN_RS1(tcg_cond_to_bcond[cond])
574 | (v1const ? INSN_IMM11(v1) : INSN_RS2(v1)));
577 static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
578 TCGArg c1, TCGArg c2, int c2const,
579 TCGArg v1, int v1const)
581 tcg_out_cmp(s, c1, c2, c2const);
582 tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
585 #if TCG_TARGET_REG_BITS == 64
586 static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
587 TCGArg arg2, int const_arg2, int label)
589 /* For 64-bit signed comparisons vs zero, we can avoid the compare. */
590 if (arg2 == 0 && !is_unsigned_cond(cond)) {
591 TCGLabel *l = &s->labels[label];
595 off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr);
597 /* Make sure to preserve destinations during retranslation. */
598 off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1);
599 tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0);
601 tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
602 | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
604 tcg_out_cmp(s, arg1, arg2, const_arg2);
605 tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label);
610 static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGArg ret, TCGArg c1,
611 TCGArg v1, int v1const)
613 tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
614 | (tcg_cond_to_rcond[cond] << 10)
615 | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
618 static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
619 TCGArg c1, TCGArg c2, int c2const,
620 TCGArg v1, int v1const)
622 /* For 64-bit signed comparisons vs zero, we can avoid the compare.
623 Note that the immediate range is one bit smaller, so we must check
625 if (c2 == 0 && !is_unsigned_cond(cond)
626 && (!v1const || check_fit_tl(v1, 10))) {
627 tcg_out_movr(s, cond, ret, c1, v1, v1const);
629 tcg_out_cmp(s, c1, c2, c2const);
630 tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
634 static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
635 TCGArg al, TCGArg ah,
636 TCGArg bl, int blconst,
637 TCGArg bh, int bhconst, int label_dest)
639 int scond, label_next = gen_new_label();
641 tcg_out_cmp(s, ah, bh, bhconst);
643 /* Note that we fill one of the delay slots with the second compare. */
646 tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
647 tcg_out_cmp(s, al, bl, blconst);
648 tcg_out_bpcc(s, COND_E, BPCC_ICC | BPCC_PT, label_dest);
652 tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
653 tcg_out_cmp(s, al, bl, blconst);
654 tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
658 scond = tcg_cond_to_bcond[tcg_high_cond(cond)];
659 tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
661 tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
662 tcg_out_cmp(s, al, bl, blconst);
663 scond = tcg_cond_to_bcond[tcg_unsigned_cond(cond)];
664 tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
669 tcg_out_label(s, label_next, s->code_ptr);
673 static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
674 TCGArg c1, TCGArg c2, int c2const)
676 /* For 32-bit comparisons, we can play games with ADDX/SUBX. */
680 /* The result of the comparison is in the carry bit. */
685 /* For equality, we can transform to inequality vs zero. */
687 tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR);
689 c1 = TCG_REG_G0, c2 = ret, c2const = 0;
690 cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
695 /* If we don't need to load a constant into a register, we can
696 swap the operands on GTU/LEU. There's no benefit to loading
697 the constant into a temporary register. */
698 if (!c2const || c2 == 0) {
703 cond = tcg_swap_cond(cond);
709 tcg_out_cmp(s, c1, c2, c2const);
710 tcg_out_movi_imm13(s, ret, 0);
711 tcg_out_movcc(s, cond, MOVCC_ICC, ret, 1, 1);
715 tcg_out_cmp(s, c1, c2, c2const);
716 if (cond == TCG_COND_LTU) {
717 tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX);
719 tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX);
723 #if TCG_TARGET_REG_BITS == 64
724 static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
725 TCGArg c1, TCGArg c2, int c2const)
727 /* For 64-bit signed comparisons vs zero, we can avoid the compare
728 if the input does not overlap the output. */
729 if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
730 tcg_out_movi_imm13(s, ret, 0);
731 tcg_out_movr(s, cond, ret, c1, 1, 1);
733 tcg_out_cmp(s, c1, c2, c2const);
734 tcg_out_movi_imm13(s, ret, 0);
735 tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
739 static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
740 TCGArg al, TCGArg ah,
741 TCGArg bl, int blconst,
742 TCGArg bh, int bhconst)
744 int tmp = TCG_REG_T1;
746 /* Note that the low parts are fully consumed before tmp is set. */
747 if (ret != ah && (bhconst || ret != bh)) {
754 if (bl == 0 && bh == 0) {
755 if (cond == TCG_COND_EQ) {
756 tcg_out_arith(s, TCG_REG_G0, al, ah, ARITH_ORCC);
757 tcg_out_movi(s, TCG_TYPE_I32, ret, 1);
759 tcg_out_arith(s, ret, al, ah, ARITH_ORCC);
762 tcg_out_setcond_i32(s, cond, tmp, al, bl, blconst);
763 tcg_out_cmp(s, ah, bh, bhconst);
764 tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
766 tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, cond == TCG_COND_NE, 1);
770 /* <= : ah < bh | (ah == bh && al <= bl) */
771 tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), tmp, al, bl, blconst);
772 tcg_out_cmp(s, ah, bh, bhconst);
773 tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
774 tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, 0, 1);
775 tcg_out_movcc(s, tcg_high_cond(cond), MOVCC_ICC, ret, 1, 1);
781 static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
782 TCGArg al, TCGArg ah, TCGArg bl, int blconst,
783 TCGArg bh, int bhconst, int opl, int oph)
785 TCGArg tmp = TCG_REG_T1;
787 /* Note that the low parts are fully consumed before tmp is set. */
788 if (rl != ah && (bhconst || rl != bh)) {
792 tcg_out_arithc(s, tmp, al, bl, blconst, opl);
793 tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
794 tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
797 static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
799 intptr_t disp = dest - (uintptr_t)s->code_ptr;
801 if (disp == (int32_t)disp) {
802 tcg_out32(s, CALL | (uint32_t)disp >> 2);
804 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, dest & ~0xfff);
805 tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, dest & 0xfff, JMPL);
809 #ifdef CONFIG_SOFTMMU
810 static uintptr_t qemu_ld_trampoline[16];
811 static uintptr_t qemu_st_trampoline[16];
813 static void build_trampolines(TCGContext *s)
815 static uintptr_t const qemu_ld_helpers[16] = {
816 [MO_UB] = (uintptr_t)helper_ret_ldub_mmu,
817 [MO_SB] = (uintptr_t)helper_ret_ldsb_mmu,
818 [MO_LEUW] = (uintptr_t)helper_le_lduw_mmu,
819 [MO_LESW] = (uintptr_t)helper_le_ldsw_mmu,
820 [MO_LEUL] = (uintptr_t)helper_le_ldul_mmu,
821 [MO_LEQ] = (uintptr_t)helper_le_ldq_mmu,
822 [MO_BEUW] = (uintptr_t)helper_be_lduw_mmu,
823 [MO_BESW] = (uintptr_t)helper_be_ldsw_mmu,
824 [MO_BEUL] = (uintptr_t)helper_be_ldul_mmu,
825 [MO_BEQ] = (uintptr_t)helper_be_ldq_mmu,
827 static uintptr_t const qemu_st_helpers[16] = {
828 [MO_UB] = (uintptr_t)helper_ret_stb_mmu,
829 [MO_LEUW] = (uintptr_t)helper_le_stw_mmu,
830 [MO_LEUL] = (uintptr_t)helper_le_stl_mmu,
831 [MO_LEQ] = (uintptr_t)helper_le_stq_mmu,
832 [MO_BEUW] = (uintptr_t)helper_be_stw_mmu,
833 [MO_BEUL] = (uintptr_t)helper_be_stl_mmu,
834 [MO_BEQ] = (uintptr_t)helper_be_stq_mmu,
841 for (i = 0; i < 16; ++i) {
842 if (qemu_ld_helpers[i] == 0) {
846 /* May as well align the trampoline. */
847 tramp = (uintptr_t)s->code_ptr;
852 qemu_ld_trampoline[i] = tramp;
854 /* Find the retaddr argument register. */
855 ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
857 /* Set the retaddr operand. */
858 tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
859 /* Set the env operand. */
860 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
862 tcg_out_calli(s, qemu_ld_helpers[i]);
863 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
866 for (i = 0; i < 16; ++i) {
867 if (qemu_st_helpers[i] == 0) {
871 /* May as well align the trampoline. */
872 tramp = (uintptr_t)s->code_ptr;
877 qemu_st_trampoline[i] = tramp;
879 /* Find the retaddr argument. For 32-bit, this may be past the
880 last argument register, and need passing on the stack. */
882 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)
883 + (TCG_TARGET_REG_BITS == 32 && (i & MO_SIZE) == MO_64));
885 /* Set the retaddr operand. */
886 if (ra >= TCG_REG_O6) {
887 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
888 TCG_TARGET_CALL_STACK_OFFSET);
891 tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
892 /* Set the env operand. */
893 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
895 tcg_out_calli(s, qemu_st_helpers[i]);
896 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
901 /* Generate global QEMU prologue and epilogue code */
902 static void tcg_target_qemu_prologue(TCGContext *s)
904 int tmp_buf_size, frame_size;
906 /* The TCG temp buffer is at the top of the frame, immediately
907 below the frame pointer. */
908 tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
909 tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
912 /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
913 otherwise the minimal frame usable by callees. */
914 frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
915 frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
916 frame_size += TCG_TARGET_STACK_ALIGN - 1;
917 frame_size &= -TCG_TARGET_STACK_ALIGN;
918 tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
919 INSN_IMM13(-frame_size));
921 #ifdef CONFIG_USE_GUEST_BASE
922 if (GUEST_BASE != 0) {
923 tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
924 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
928 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
932 /* No epilogue required. We issue ret + restore directly in the TB. */
934 #ifdef CONFIG_SOFTMMU
935 build_trampolines(s);
939 #if defined(CONFIG_SOFTMMU)
940 /* Perform the TLB load and compare.
943 ADDRLO and ADDRHI contain the possible two parts of the address.
945 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
947 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
948 This should be offsetof addr_read or addr_write.
950 The result of the TLB comparison is in %[ix]cc. The sanitized address
951 is in the returned register, maybe %o0. The TLB addend is in %o1. */
953 static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
954 int mem_index, TCGMemOp s_bits, int which)
956 const TCGReg r0 = TCG_REG_O0;
957 const TCGReg r1 = TCG_REG_O1;
958 const TCGReg r2 = TCG_REG_O2;
959 TCGReg addr = addrlo;
962 if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
963 /* Assemble the 64-bit address in R0. */
964 tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
965 tcg_out_arithi(s, r1, addrhi, 32, SHIFT_SLLX);
966 tcg_out_arith(s, r0, r0, r1, ARITH_OR);
970 /* Shift the page number down. */
971 tcg_out_arithi(s, r1, addrlo, TARGET_PAGE_BITS, SHIFT_SRL);
973 /* Mask out the page offset, except for the required alignment. */
974 tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
975 TARGET_PAGE_MASK | ((1 << s_bits) - 1));
977 /* Mask the tlb index. */
978 tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
980 /* Mask page, part 2. */
981 tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
983 /* Shift the tlb index into place. */
984 tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
986 /* Relative to the current ENV. */
987 tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
989 /* Find a base address that can load both tlb comparator and addend. */
990 tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
991 if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
992 tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);
996 /* Load the tlb comparator and the addend. */
997 tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
998 tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
1000 /* subcc arg0, arg2, %g0 */
1001 tcg_out_cmp(s, r0, r2, 0);
1003 /* If the guest address must be zero-extended, do so now. */
1004 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
1005 tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
1010 #endif /* CONFIG_SOFTMMU */
1012 static const int qemu_ld_opc[16] = {
1022 [MO_LEUW] = LDUH_LE,
1023 [MO_LESW] = LDSH_LE,
1024 [MO_LEUL] = LDUW_LE,
1025 [MO_LESL] = LDSW_LE,
1029 static const int qemu_st_opc[16] = {
1041 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
1043 TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
1044 TCGMemOp memop, s_bits;
1045 #if defined(CONFIG_SOFTMMU)
1046 TCGReg addrz, param;
1049 uint32_t *label_ptr[2];
1053 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
1055 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
1057 s_bits = memop & MO_SIZE;
1059 #if defined(CONFIG_SOFTMMU)
1061 addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
1062 offsetof(CPUTLBEntry, addr_read));
1064 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1067 /* bne,pn %[xi]cc, label0 */
1068 label_ptr[0] = (uint32_t *)s->code_ptr;
1069 tcg_out_bpcc0(s, COND_NE, BPCC_PN
1070 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1074 /* Load all 64-bits into an O/G register. */
1075 reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
1076 tcg_out_ldst_rr(s, reg64, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
1078 /* Move the two 32-bit pieces into the destination registers. */
1079 tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
1080 if (reg64 != datalo) {
1081 tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
1085 label_ptr[1] = (uint32_t *)s->code_ptr;
1086 tcg_out_bpcc0(s, COND_A, BPCC_A | BPCC_PT, 0);
1088 /* The fast path is exactly one insn. Thus we can perform the
1089 entire TLB Hit in the (annulled) delay slot of the branch
1090 over the TLB Miss case. */
1092 /* beq,a,pt %[xi]cc, label0 */
1093 label_ptr[0] = NULL;
1094 label_ptr[1] = (uint32_t *)s->code_ptr;
1095 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1096 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1098 tcg_out_ldst_rr(s, datalo, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
1104 *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
1105 (unsigned long)label_ptr[0]);
1109 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1110 tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
1112 tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
1114 /* We use the helpers to extend SB and SW data, leaving the case
1115 of SL needing explicit extending below. */
1116 if ((memop & ~MO_BSWAP) == MO_SL) {
1117 func = qemu_ld_trampoline[memop & ~MO_SIGN];
1119 func = qemu_ld_trampoline[memop];
1122 tcg_out_calli(s, func);
1124 tcg_out_movi(s, TCG_TYPE_I32, param, memi);
1126 switch (memop & ~MO_BSWAP) {
1128 tcg_out_arithi(s, datalo, TCG_REG_O0, 0, SHIFT_SRA);
1131 if (TCG_TARGET_REG_BITS == 32) {
1132 tcg_out_mov(s, TCG_TYPE_REG, datahi, TCG_REG_O0);
1133 tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O1);
1139 tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O0);
1143 *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
1144 (unsigned long)label_ptr[1]);
1146 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
1147 tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
1148 addrlo = TCG_REG_T1;
1150 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1151 int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
1153 tcg_out_ldst_rr(s, reg64, addrlo,
1154 (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1155 qemu_ld_opc[memop]);
1157 tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
1158 if (reg64 != datalo) {
1159 tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
1162 tcg_out_ldst_rr(s, datalo, addrlo,
1163 (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1164 qemu_ld_opc[memop]);
1166 #endif /* CONFIG_SOFTMMU */
1169 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
1171 TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
1172 TCGMemOp memop, s_bits;
1173 #if defined(CONFIG_SOFTMMU)
1174 TCGReg addrz, datafull, param;
1177 uint32_t *label_ptr;
1181 datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
1183 addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
1185 s_bits = memop & MO_SIZE;
1187 #if defined(CONFIG_SOFTMMU)
1189 addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
1190 offsetof(CPUTLBEntry, addr_write));
1193 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1194 /* Reconstruct the full 64-bit value. */
1195 tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
1196 tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
1197 tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
1198 datafull = TCG_REG_O2;
1201 /* The fast path is exactly one insn. Thus we can perform the entire
1202 TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
1203 /* beq,a,pt %[xi]cc, label0 */
1204 label_ptr = (uint32_t *)s->code_ptr;
1205 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1206 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1208 tcg_out_ldst_rr(s, datafull, addrz, TCG_REG_O1, qemu_st_opc[memop]);
1213 if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
1214 tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
1216 tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
1217 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1218 tcg_out_mov(s, TCG_TYPE_REG, param++, datahi);
1220 tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
1222 func = qemu_st_trampoline[memop];
1224 tcg_out_calli(s, func);
1226 tcg_out_movi(s, TCG_TYPE_REG, param, memi);
1228 *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
1229 (unsigned long)label_ptr);
1231 if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
1232 tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
1233 addrlo = TCG_REG_T1;
1235 if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
1236 tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
1237 tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
1238 tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
1239 datalo = TCG_REG_O2;
1241 tcg_out_ldst_rr(s, datalo, addrlo,
1242 (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1243 qemu_st_opc[memop]);
1244 #endif /* CONFIG_SOFTMMU */
1247 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1248 const int *const_args)
1253 case INDEX_op_exit_tb:
1254 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
1255 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, JMPL);
1256 tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
1257 INSN_RS2(TCG_REG_G0));
1259 case INDEX_op_goto_tb:
1260 if (s->tb_jmp_offset) {
1261 /* direct jump method */
1262 uint32_t old_insn = *(uint32_t *)s->code_ptr;
1263 s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1264 /* Make sure to preserve links during retranslation. */
1265 tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
1267 /* indirect jump method */
1268 tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
1269 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
1272 s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1275 if (const_args[0]) {
1276 tcg_out_calli(s, args[0]);
1278 tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
1284 tcg_out_bpcc(s, COND_A, BPCC_PT, args[0]);
1287 case INDEX_op_movi_i32:
1288 tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
1291 #if TCG_TARGET_REG_BITS == 64
1292 #define OP_32_64(x) \
1293 glue(glue(case INDEX_op_, x), _i32): \
1294 glue(glue(case INDEX_op_, x), _i64)
1296 #define OP_32_64(x) \
1297 glue(glue(case INDEX_op_, x), _i32)
1300 tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
1303 tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
1306 tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
1309 tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
1311 case INDEX_op_ld_i32:
1312 #if TCG_TARGET_REG_BITS == 64
1313 case INDEX_op_ld32u_i64:
1315 tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
1318 tcg_out_ldst(s, args[0], args[1], args[2], STB);
1321 tcg_out_ldst(s, args[0], args[1], args[2], STH);
1323 case INDEX_op_st_i32:
1324 #if TCG_TARGET_REG_BITS == 64
1325 case INDEX_op_st32_i64:
1327 tcg_out_ldst(s, args[0], args[1], args[2], STW);
1350 case INDEX_op_shl_i32:
1353 /* Limit immediate shift count lest we create an illegal insn. */
1354 tcg_out_arithc(s, args[0], args[1], args[2] & 31, const_args[2], c);
1356 case INDEX_op_shr_i32:
1359 case INDEX_op_sar_i32:
1362 case INDEX_op_mul_i32:
1373 case INDEX_op_div_i32:
1374 tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
1376 case INDEX_op_divu_i32:
1377 tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
1380 case INDEX_op_brcond_i32:
1381 tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
1384 case INDEX_op_setcond_i32:
1385 tcg_out_setcond_i32(s, args[3], args[0], args[1],
1386 args[2], const_args[2]);
1388 case INDEX_op_movcond_i32:
1389 tcg_out_movcond_i32(s, args[5], args[0], args[1],
1390 args[2], const_args[2], args[3], const_args[3]);
1393 #if TCG_TARGET_REG_BITS == 32
1394 case INDEX_op_brcond2_i32:
1395 tcg_out_brcond2_i32(s, args[4], args[0], args[1],
1396 args[2], const_args[2],
1397 args[3], const_args[3], args[5]);
1399 case INDEX_op_setcond2_i32:
1400 tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
1401 args[3], const_args[3],
1402 args[4], const_args[4]);
1406 case INDEX_op_add2_i32:
1407 tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
1408 args[4], const_args[4], args[5], const_args[5],
1409 ARITH_ADDCC, ARITH_ADDX);
1411 case INDEX_op_sub2_i32:
1412 tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
1413 args[4], const_args[4], args[5], const_args[5],
1414 ARITH_SUBCC, ARITH_SUBX);
1416 case INDEX_op_mulu2_i32:
1417 tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
1419 tcg_out_rdy(s, args[1]);
1422 case INDEX_op_qemu_ld_i32:
1423 tcg_out_qemu_ld(s, args, 0);
1425 case INDEX_op_qemu_ld_i64:
1426 tcg_out_qemu_ld(s, args, 1);
1428 case INDEX_op_qemu_st_i32:
1429 tcg_out_qemu_st(s, args, 0);
1431 case INDEX_op_qemu_st_i64:
1432 tcg_out_qemu_st(s, args, 1);
1435 #if TCG_TARGET_REG_BITS == 64
1436 case INDEX_op_movi_i64:
1437 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1439 case INDEX_op_ld32s_i64:
1440 tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
1442 case INDEX_op_ld_i64:
1443 tcg_out_ldst(s, args[0], args[1], args[2], LDX);
1445 case INDEX_op_st_i64:
1446 tcg_out_ldst(s, args[0], args[1], args[2], STX);
1448 case INDEX_op_shl_i64:
1451 /* Limit immediate shift count lest we create an illegal insn. */
1452 tcg_out_arithc(s, args[0], args[1], args[2] & 63, const_args[2], c);
1454 case INDEX_op_shr_i64:
1457 case INDEX_op_sar_i64:
1460 case INDEX_op_mul_i64:
1463 case INDEX_op_div_i64:
1466 case INDEX_op_divu_i64:
1469 case INDEX_op_ext32s_i64:
1470 tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
1472 case INDEX_op_ext32u_i64:
1473 tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
1476 case INDEX_op_brcond_i64:
1477 tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
1480 case INDEX_op_setcond_i64:
1481 tcg_out_setcond_i64(s, args[3], args[0], args[1],
1482 args[2], const_args[2]);
1484 case INDEX_op_movcond_i64:
1485 tcg_out_movcond_i64(s, args[5], args[0], args[1],
1486 args[2], const_args[2], args[3], const_args[3]);
1490 tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
1494 tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
1498 fprintf(stderr, "unknown opcode 0x%x\n", opc);
1503 static const TCGTargetOpDef sparc_op_defs[] = {
1504 { INDEX_op_exit_tb, { } },
1505 { INDEX_op_goto_tb, { } },
1506 { INDEX_op_call, { "ri" } },
1507 { INDEX_op_br, { } },
1509 { INDEX_op_mov_i32, { "r", "r" } },
1510 { INDEX_op_movi_i32, { "r" } },
1511 { INDEX_op_ld8u_i32, { "r", "r" } },
1512 { INDEX_op_ld8s_i32, { "r", "r" } },
1513 { INDEX_op_ld16u_i32, { "r", "r" } },
1514 { INDEX_op_ld16s_i32, { "r", "r" } },
1515 { INDEX_op_ld_i32, { "r", "r" } },
1516 { INDEX_op_st8_i32, { "rZ", "r" } },
1517 { INDEX_op_st16_i32, { "rZ", "r" } },
1518 { INDEX_op_st_i32, { "rZ", "r" } },
1520 { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1521 { INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
1522 { INDEX_op_div_i32, { "r", "rZ", "rJ" } },
1523 { INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
1524 { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1525 { INDEX_op_and_i32, { "r", "rZ", "rJ" } },
1526 { INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
1527 { INDEX_op_or_i32, { "r", "rZ", "rJ" } },
1528 { INDEX_op_orc_i32, { "r", "rZ", "rJ" } },
1529 { INDEX_op_xor_i32, { "r", "rZ", "rJ" } },
1531 { INDEX_op_shl_i32, { "r", "rZ", "rJ" } },
1532 { INDEX_op_shr_i32, { "r", "rZ", "rJ" } },
1533 { INDEX_op_sar_i32, { "r", "rZ", "rJ" } },
1535 { INDEX_op_neg_i32, { "r", "rJ" } },
1536 { INDEX_op_not_i32, { "r", "rJ" } },
1538 { INDEX_op_brcond_i32, { "rZ", "rJ" } },
1539 { INDEX_op_setcond_i32, { "r", "rZ", "rJ" } },
1540 { INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } },
1542 #if TCG_TARGET_REG_BITS == 32
1543 { INDEX_op_brcond2_i32, { "rZ", "rZ", "rJ", "rJ" } },
1544 { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rJ", "rJ" } },
1547 { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1548 { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1549 { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } },
1551 #if TCG_TARGET_REG_BITS == 64
1552 { INDEX_op_mov_i64, { "r", "r" } },
1553 { INDEX_op_movi_i64, { "r" } },
1554 { INDEX_op_ld8u_i64, { "r", "r" } },
1555 { INDEX_op_ld8s_i64, { "r", "r" } },
1556 { INDEX_op_ld16u_i64, { "r", "r" } },
1557 { INDEX_op_ld16s_i64, { "r", "r" } },
1558 { INDEX_op_ld32u_i64, { "r", "r" } },
1559 { INDEX_op_ld32s_i64, { "r", "r" } },
1560 { INDEX_op_ld_i64, { "r", "r" } },
1561 { INDEX_op_st8_i64, { "rZ", "r" } },
1562 { INDEX_op_st16_i64, { "rZ", "r" } },
1563 { INDEX_op_st32_i64, { "rZ", "r" } },
1564 { INDEX_op_st_i64, { "rZ", "r" } },
1566 { INDEX_op_add_i64, { "r", "rZ", "rJ" } },
1567 { INDEX_op_mul_i64, { "r", "rZ", "rJ" } },
1568 { INDEX_op_div_i64, { "r", "rZ", "rJ" } },
1569 { INDEX_op_divu_i64, { "r", "rZ", "rJ" } },
1570 { INDEX_op_sub_i64, { "r", "rZ", "rJ" } },
1571 { INDEX_op_and_i64, { "r", "rZ", "rJ" } },
1572 { INDEX_op_andc_i64, { "r", "rZ", "rJ" } },
1573 { INDEX_op_or_i64, { "r", "rZ", "rJ" } },
1574 { INDEX_op_orc_i64, { "r", "rZ", "rJ" } },
1575 { INDEX_op_xor_i64, { "r", "rZ", "rJ" } },
1577 { INDEX_op_shl_i64, { "r", "rZ", "rJ" } },
1578 { INDEX_op_shr_i64, { "r", "rZ", "rJ" } },
1579 { INDEX_op_sar_i64, { "r", "rZ", "rJ" } },
1581 { INDEX_op_neg_i64, { "r", "rJ" } },
1582 { INDEX_op_not_i64, { "r", "rJ" } },
1584 { INDEX_op_ext32s_i64, { "r", "r" } },
1585 { INDEX_op_ext32u_i64, { "r", "r" } },
1587 { INDEX_op_brcond_i64, { "rZ", "rJ" } },
1588 { INDEX_op_setcond_i64, { "r", "rZ", "rJ" } },
1589 { INDEX_op_movcond_i64, { "r", "rZ", "rJ", "rI", "0" } },
1592 #if TCG_TARGET_REG_BITS == 64
1593 { INDEX_op_qemu_ld_i32, { "r", "L" } },
1594 { INDEX_op_qemu_ld_i64, { "r", "L" } },
1595 { INDEX_op_qemu_st_i32, { "L", "L" } },
1596 { INDEX_op_qemu_st_i64, { "L", "L" } },
1597 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
1598 { INDEX_op_qemu_ld_i32, { "r", "L" } },
1599 { INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
1600 { INDEX_op_qemu_st_i32, { "L", "L" } },
1601 { INDEX_op_qemu_st_i64, { "L", "L", "L" } },
1603 { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
1604 { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
1605 { INDEX_op_qemu_st_i32, { "L", "L", "L" } },
1606 { INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
1612 static void tcg_target_init(TCGContext *s)
1614 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1615 #if TCG_TARGET_REG_BITS == 64
1616 tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1618 tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1634 tcg_regset_clear(s->reserved_regs);
1635 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
1636 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
1637 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
1638 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
1639 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
1640 tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
1641 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
1642 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
1644 tcg_add_target_add_op_defs(sparc_op_defs);
1647 #if TCG_TARGET_REG_BITS == 64
1648 # define ELF_HOST_MACHINE EM_SPARCV9
1650 # define ELF_HOST_MACHINE EM_SPARC32PLUS
1651 # define ELF_HOST_FLAGS EF_SPARC_32PLUS
1656 DebugFrameFDEHeader fde;
1657 uint8_t fde_def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
1658 uint8_t fde_win_save;
1659 uint8_t fde_ret_save[3];
1662 static DebugFrame debug_frame = {
1663 .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1666 .cie.code_align = 1,
1667 .cie.data_align = -sizeof(void *) & 0x7f,
1668 .cie.return_column = 15, /* o7 */
1670 /* Total FDE size does not include the "len" member. */
1671 .fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, fde.cie_offset),
1674 #if TCG_TARGET_REG_BITS == 64
1675 12, 30, /* DW_CFA_def_cfa i6, 2047 */
1676 (2047 & 0x7f) | 0x80, (2047 >> 7)
1678 13, 30 /* DW_CFA_def_cfa_register i6 */
1681 .fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
1682 .fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
1685 void tcg_register_jit(void *buf, size_t buf_size)
1687 debug_frame.fde.func_start = (uintptr_t)buf;
1688 debug_frame.fde.func_len = buf_size;
1690 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1693 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
1695 uint32_t *ptr = (uint32_t *)jmp_addr;
1696 uintptr_t disp = addr - jmp_addr;
1698 /* We can reach the entire address space for 32-bit. For 64-bit
1699 the code_gen_buffer can't be larger than 2GB. */
1700 assert(disp == (int32_t)disp);
1702 *ptr = CALL | (uint32_t)disp >> 2;
1703 flush_icache_range(jmp_addr, jmp_addr + 4);