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-pool.inc.c"
27 #ifdef CONFIG_DEBUG_TCG
28 static const char * const tcg_target_reg_names
[TCG_TARGET_NB_REGS
] = {
70 /* Note that sparcv8plus can only hold 64 bit quantities in %g and %o
71 registers. These are saved manually by the kernel in full 64-bit
72 slots. The %i and %l registers are saved by the register window
73 mechanism, which only allocates space for 32 bits. Given that this
74 window spill/fill can happen on any signal, we must consider the
75 high bits of the %i and %l registers garbage at all times. */
77 # define ALL_64 0xffffffffu
79 # define ALL_64 0xffffu
82 /* Define some temporary registers. T2 is used for constant generation. */
83 #define TCG_REG_T1 TCG_REG_G1
84 #define TCG_REG_T2 TCG_REG_O7
86 #ifndef CONFIG_SOFTMMU
87 # define TCG_GUEST_BASE_REG TCG_REG_I5
90 #define TCG_REG_TB TCG_REG_I1
91 #define USE_REG_TB (sizeof(void *) > 4)
93 static const int tcg_target_reg_alloc_order
[] = {
123 static const int tcg_target_call_iarg_regs
[6] = {
132 static const int tcg_target_call_oarg_regs
[] = {
139 #define INSN_OP(x) ((x) << 30)
140 #define INSN_OP2(x) ((x) << 22)
141 #define INSN_OP3(x) ((x) << 19)
142 #define INSN_OPF(x) ((x) << 5)
143 #define INSN_RD(x) ((x) << 25)
144 #define INSN_RS1(x) ((x) << 14)
145 #define INSN_RS2(x) (x)
146 #define INSN_ASI(x) ((x) << 5)
148 #define INSN_IMM10(x) ((1 << 13) | ((x) & 0x3ff))
149 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
150 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
151 #define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
152 #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
153 #define INSN_COND(x) ((x) << 25)
171 #define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
180 #define MOVCC_ICC (1 << 18)
181 #define MOVCC_XCC (1 << 18 | 1 << 12)
184 #define BPCC_XCC (2 << 20)
185 #define BPCC_PT (1 << 19)
187 #define BPCC_A (1 << 29)
189 #define BPR_PT BPCC_PT
191 #define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
192 #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
193 #define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))
194 #define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
195 #define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))
196 #define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
197 #define ARITH_ORN (INSN_OP(2) | INSN_OP3(0x06))
198 #define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03))
199 #define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04))
200 #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
201 #define ARITH_ADDC (INSN_OP(2) | INSN_OP3(0x08))
202 #define ARITH_SUBC (INSN_OP(2) | INSN_OP3(0x0c))
203 #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
204 #define ARITH_SMUL (INSN_OP(2) | INSN_OP3(0x0b))
205 #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
206 #define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
207 #define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
208 #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
209 #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
210 #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
211 #define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f))
213 #define ARITH_ADDXC (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x11))
214 #define ARITH_UMULXHI (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x16))
216 #define SHIFT_SLL (INSN_OP(2) | INSN_OP3(0x25))
217 #define SHIFT_SRL (INSN_OP(2) | INSN_OP3(0x26))
218 #define SHIFT_SRA (INSN_OP(2) | INSN_OP3(0x27))
220 #define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
221 #define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
222 #define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
224 #define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
225 #define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
226 #define JMPL (INSN_OP(2) | INSN_OP3(0x38))
227 #define RETURN (INSN_OP(2) | INSN_OP3(0x39))
228 #define SAVE (INSN_OP(2) | INSN_OP3(0x3c))
229 #define RESTORE (INSN_OP(2) | INSN_OP3(0x3d))
230 #define SETHI (INSN_OP(0) | INSN_OP2(0x4))
231 #define CALL INSN_OP(1)
232 #define LDUB (INSN_OP(3) | INSN_OP3(0x01))
233 #define LDSB (INSN_OP(3) | INSN_OP3(0x09))
234 #define LDUH (INSN_OP(3) | INSN_OP3(0x02))
235 #define LDSH (INSN_OP(3) | INSN_OP3(0x0a))
236 #define LDUW (INSN_OP(3) | INSN_OP3(0x00))
237 #define LDSW (INSN_OP(3) | INSN_OP3(0x08))
238 #define LDX (INSN_OP(3) | INSN_OP3(0x0b))
239 #define STB (INSN_OP(3) | INSN_OP3(0x05))
240 #define STH (INSN_OP(3) | INSN_OP3(0x06))
241 #define STW (INSN_OP(3) | INSN_OP3(0x04))
242 #define STX (INSN_OP(3) | INSN_OP3(0x0e))
243 #define LDUBA (INSN_OP(3) | INSN_OP3(0x11))
244 #define LDSBA (INSN_OP(3) | INSN_OP3(0x19))
245 #define LDUHA (INSN_OP(3) | INSN_OP3(0x12))
246 #define LDSHA (INSN_OP(3) | INSN_OP3(0x1a))
247 #define LDUWA (INSN_OP(3) | INSN_OP3(0x10))
248 #define LDSWA (INSN_OP(3) | INSN_OP3(0x18))
249 #define LDXA (INSN_OP(3) | INSN_OP3(0x1b))
250 #define STBA (INSN_OP(3) | INSN_OP3(0x15))
251 #define STHA (INSN_OP(3) | INSN_OP3(0x16))
252 #define STWA (INSN_OP(3) | INSN_OP3(0x14))
253 #define STXA (INSN_OP(3) | INSN_OP3(0x1e))
255 #define MEMBAR (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(15) | (1 << 13))
257 #define NOP (SETHI | INSN_RD(TCG_REG_G0) | 0)
259 #ifndef ASI_PRIMARY_LITTLE
260 #define ASI_PRIMARY_LITTLE 0x88
263 #define LDUH_LE (LDUHA | INSN_ASI(ASI_PRIMARY_LITTLE))
264 #define LDSH_LE (LDSHA | INSN_ASI(ASI_PRIMARY_LITTLE))
265 #define LDUW_LE (LDUWA | INSN_ASI(ASI_PRIMARY_LITTLE))
266 #define LDSW_LE (LDSWA | INSN_ASI(ASI_PRIMARY_LITTLE))
267 #define LDX_LE (LDXA | INSN_ASI(ASI_PRIMARY_LITTLE))
269 #define STH_LE (STHA | INSN_ASI(ASI_PRIMARY_LITTLE))
270 #define STW_LE (STWA | INSN_ASI(ASI_PRIMARY_LITTLE))
271 #define STX_LE (STXA | INSN_ASI(ASI_PRIMARY_LITTLE))
273 #ifndef use_vis3_instructions
274 bool use_vis3_instructions
;
277 static inline int check_fit_i64(int64_t val
, unsigned int bits
)
279 return val
== sextract64(val
, 0, bits
);
282 static inline int check_fit_i32(int32_t val
, unsigned int bits
)
284 return val
== sextract32(val
, 0, bits
);
287 #define check_fit_tl check_fit_i64
289 # define check_fit_ptr check_fit_i64
291 # define check_fit_ptr check_fit_i32
294 static bool patch_reloc(tcg_insn_unit
*code_ptr
, int type
,
295 intptr_t value
, intptr_t addend
)
297 uint32_t insn
= *code_ptr
;
301 pcrel
= tcg_ptr_byte_diff((tcg_insn_unit
*)value
, code_ptr
);
304 case R_SPARC_WDISP16
:
305 assert(check_fit_ptr(pcrel
>> 2, 16));
306 insn
&= ~INSN_OFF16(-1);
307 insn
|= INSN_OFF16(pcrel
);
309 case R_SPARC_WDISP19
:
310 assert(check_fit_ptr(pcrel
>> 2, 19));
311 insn
&= ~INSN_OFF19(-1);
312 insn
|= INSN_OFF19(pcrel
);
315 g_assert_not_reached();
322 /* parse target specific constraints */
323 static const char *target_parse_constraint(TCGArgConstraint
*ct
,
324 const char *ct_str
, TCGType type
)
328 ct
->ct
|= TCG_CT_REG
;
329 ct
->u
.regs
= 0xffffffff;
332 ct
->ct
|= TCG_CT_REG
;
335 case 'A': /* qemu_ld/st address constraint */
336 ct
->ct
|= TCG_CT_REG
;
337 ct
->u
.regs
= TARGET_LONG_BITS
== 64 ? ALL_64
: 0xffffffff;
339 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_O0
);
340 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_O1
);
341 tcg_regset_reset_reg(ct
->u
.regs
, TCG_REG_O2
);
343 case 's': /* qemu_st data 32-bit constraint */
344 ct
->ct
|= TCG_CT_REG
;
345 ct
->u
.regs
= 0xffffffff;
346 goto reserve_helpers
;
347 case 'S': /* qemu_st data 64-bit constraint */
348 ct
->ct
|= TCG_CT_REG
;
350 goto reserve_helpers
;
352 ct
->ct
|= TCG_CT_CONST_S11
;
355 ct
->ct
|= TCG_CT_CONST_S13
;
358 ct
->ct
|= TCG_CT_CONST_ZERO
;
366 /* test if a constant matches the constraint */
367 static inline int tcg_target_const_match(tcg_target_long val
, TCGType type
,
368 const TCGArgConstraint
*arg_ct
)
372 if (ct
& TCG_CT_CONST
) {
376 if (type
== TCG_TYPE_I32
) {
380 if ((ct
& TCG_CT_CONST_ZERO
) && val
== 0) {
382 } else if ((ct
& TCG_CT_CONST_S11
) && check_fit_tl(val
, 11)) {
384 } else if ((ct
& TCG_CT_CONST_S13
) && check_fit_tl(val
, 13)) {
391 static inline void tcg_out_arith(TCGContext
*s
, TCGReg rd
, TCGReg rs1
,
394 tcg_out32(s
, op
| INSN_RD(rd
) | INSN_RS1(rs1
) | INSN_RS2(rs2
));
397 static inline void tcg_out_arithi(TCGContext
*s
, TCGReg rd
, TCGReg rs1
,
398 int32_t offset
, int op
)
400 tcg_out32(s
, op
| INSN_RD(rd
) | INSN_RS1(rs1
) | INSN_IMM13(offset
));
403 static void tcg_out_arithc(TCGContext
*s
, TCGReg rd
, TCGReg rs1
,
404 int32_t val2
, int val2const
, int op
)
406 tcg_out32(s
, op
| INSN_RD(rd
) | INSN_RS1(rs1
)
407 | (val2const
? INSN_IMM13(val2
) : INSN_RS2(val2
)));
410 static inline void tcg_out_mov(TCGContext
*s
, TCGType type
,
411 TCGReg ret
, TCGReg arg
)
414 tcg_out_arith(s
, ret
, arg
, TCG_REG_G0
, ARITH_OR
);
418 static inline void tcg_out_sethi(TCGContext
*s
, TCGReg ret
, uint32_t arg
)
420 tcg_out32(s
, SETHI
| INSN_RD(ret
) | ((arg
& 0xfffffc00) >> 10));
423 static inline void tcg_out_movi_imm13(TCGContext
*s
, TCGReg ret
, int32_t arg
)
425 tcg_out_arithi(s
, ret
, TCG_REG_G0
, arg
, ARITH_OR
);
428 static void tcg_out_movi_int(TCGContext
*s
, TCGType type
, TCGReg ret
,
429 tcg_target_long arg
, bool in_prologue
)
431 tcg_target_long hi
, lo
= (int32_t)arg
;
432 tcg_target_long test
, lsb
;
434 /* Make sure we test 32-bit constants for imm13 properly. */
435 if (type
== TCG_TYPE_I32
) {
439 /* A 13-bit constant sign-extended to 64-bits. */
440 if (check_fit_tl(arg
, 13)) {
441 tcg_out_movi_imm13(s
, ret
, arg
);
445 /* A 13-bit constant relative to the TB. */
446 if (!in_prologue
&& USE_REG_TB
) {
447 test
= arg
- (uintptr_t)s
->code_gen_ptr
;
448 if (check_fit_ptr(test
, 13)) {
449 tcg_out_arithi(s
, ret
, TCG_REG_TB
, test
, ARITH_ADD
);
454 /* A 32-bit constant, or 32-bit zero-extended to 64-bits. */
455 if (type
== TCG_TYPE_I32
|| arg
== (uint32_t)arg
) {
456 tcg_out_sethi(s
, ret
, arg
);
458 tcg_out_arithi(s
, ret
, ret
, arg
& 0x3ff, ARITH_OR
);
463 /* A 32-bit constant sign-extended to 64-bits. */
465 tcg_out_sethi(s
, ret
, ~arg
);
466 tcg_out_arithi(s
, ret
, ret
, (arg
& 0x3ff) | -0x400, ARITH_XOR
);
470 /* A 21-bit constant, shifted. */
472 test
= (tcg_target_long
)arg
>> lsb
;
473 if (check_fit_tl(test
, 13)) {
474 tcg_out_movi_imm13(s
, ret
, test
);
475 tcg_out_arithi(s
, ret
, ret
, lsb
, SHIFT_SLLX
);
477 } else if (lsb
> 10 && test
== extract64(test
, 0, 21)) {
478 tcg_out_sethi(s
, ret
, test
<< 10);
479 tcg_out_arithi(s
, ret
, ret
, lsb
- 10, SHIFT_SLLX
);
483 /* A 64-bit constant decomposed into 2 32-bit pieces. */
484 if (check_fit_i32(lo
, 13)) {
485 hi
= (arg
- lo
) >> 32;
486 tcg_out_movi(s
, TCG_TYPE_I32
, ret
, hi
);
487 tcg_out_arithi(s
, ret
, ret
, 32, SHIFT_SLLX
);
488 tcg_out_arithi(s
, ret
, ret
, lo
, ARITH_ADD
);
491 tcg_out_movi(s
, TCG_TYPE_I32
, ret
, hi
);
492 tcg_out_movi(s
, TCG_TYPE_I32
, TCG_REG_T2
, lo
);
493 tcg_out_arithi(s
, ret
, ret
, 32, SHIFT_SLLX
);
494 tcg_out_arith(s
, ret
, ret
, TCG_REG_T2
, ARITH_OR
);
498 static inline void tcg_out_movi(TCGContext
*s
, TCGType type
,
499 TCGReg ret
, tcg_target_long arg
)
501 tcg_out_movi_int(s
, type
, ret
, arg
, false);
504 static inline void tcg_out_ldst_rr(TCGContext
*s
, TCGReg data
, TCGReg a1
,
507 tcg_out32(s
, op
| INSN_RD(data
) | INSN_RS1(a1
) | INSN_RS2(a2
));
510 static void tcg_out_ldst(TCGContext
*s
, TCGReg ret
, TCGReg addr
,
511 intptr_t offset
, int op
)
513 if (check_fit_ptr(offset
, 13)) {
514 tcg_out32(s
, op
| INSN_RD(ret
) | INSN_RS1(addr
) |
517 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_T1
, offset
);
518 tcg_out_ldst_rr(s
, ret
, addr
, TCG_REG_T1
, op
);
522 static inline void tcg_out_ld(TCGContext
*s
, TCGType type
, TCGReg ret
,
523 TCGReg arg1
, intptr_t arg2
)
525 tcg_out_ldst(s
, ret
, arg1
, arg2
, (type
== TCG_TYPE_I32
? LDUW
: LDX
));
528 static inline void tcg_out_st(TCGContext
*s
, TCGType type
, TCGReg arg
,
529 TCGReg arg1
, intptr_t arg2
)
531 tcg_out_ldst(s
, arg
, arg1
, arg2
, (type
== TCG_TYPE_I32
? STW
: STX
));
534 static inline bool tcg_out_sti(TCGContext
*s
, TCGType type
, TCGArg val
,
535 TCGReg base
, intptr_t ofs
)
538 tcg_out_st(s
, type
, TCG_REG_G0
, base
, ofs
);
544 static void tcg_out_ld_ptr(TCGContext
*s
, TCGReg ret
, uintptr_t arg
)
546 intptr_t diff
= arg
- (uintptr_t)s
->code_gen_ptr
;
547 if (USE_REG_TB
&& check_fit_ptr(diff
, 13)) {
548 tcg_out_ld(s
, TCG_TYPE_PTR
, ret
, TCG_REG_TB
, diff
);
551 tcg_out_movi(s
, TCG_TYPE_PTR
, ret
, arg
& ~0x3ff);
552 tcg_out_ld(s
, TCG_TYPE_PTR
, ret
, ret
, arg
& 0x3ff);
555 static inline void tcg_out_sety(TCGContext
*s
, TCGReg rs
)
557 tcg_out32(s
, WRY
| INSN_RS1(TCG_REG_G0
) | INSN_RS2(rs
));
560 static inline void tcg_out_rdy(TCGContext
*s
, TCGReg rd
)
562 tcg_out32(s
, RDY
| INSN_RD(rd
));
565 static void tcg_out_div32(TCGContext
*s
, TCGReg rd
, TCGReg rs1
,
566 int32_t val2
, int val2const
, int uns
)
568 /* Load Y with the sign/zero extension of RS1 to 64-bits. */
570 tcg_out_sety(s
, TCG_REG_G0
);
572 tcg_out_arithi(s
, TCG_REG_T1
, rs1
, 31, SHIFT_SRA
);
573 tcg_out_sety(s
, TCG_REG_T1
);
576 tcg_out_arithc(s
, rd
, rs1
, val2
, val2const
,
577 uns
? ARITH_UDIV
: ARITH_SDIV
);
580 static inline void tcg_out_nop(TCGContext
*s
)
585 static const uint8_t tcg_cond_to_bcond
[] = {
586 [TCG_COND_EQ
] = COND_E
,
587 [TCG_COND_NE
] = COND_NE
,
588 [TCG_COND_LT
] = COND_L
,
589 [TCG_COND_GE
] = COND_GE
,
590 [TCG_COND_LE
] = COND_LE
,
591 [TCG_COND_GT
] = COND_G
,
592 [TCG_COND_LTU
] = COND_CS
,
593 [TCG_COND_GEU
] = COND_CC
,
594 [TCG_COND_LEU
] = COND_LEU
,
595 [TCG_COND_GTU
] = COND_GU
,
598 static const uint8_t tcg_cond_to_rcond
[] = {
599 [TCG_COND_EQ
] = RCOND_Z
,
600 [TCG_COND_NE
] = RCOND_NZ
,
601 [TCG_COND_LT
] = RCOND_LZ
,
602 [TCG_COND_GT
] = RCOND_GZ
,
603 [TCG_COND_LE
] = RCOND_LEZ
,
604 [TCG_COND_GE
] = RCOND_GEZ
607 static void tcg_out_bpcc0(TCGContext
*s
, int scond
, int flags
, int off19
)
609 tcg_out32(s
, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond
) | flags
| off19
);
612 static void tcg_out_bpcc(TCGContext
*s
, int scond
, int flags
, TCGLabel
*l
)
617 off19
= INSN_OFF19(tcg_pcrel_diff(s
, l
->u
.value_ptr
));
619 tcg_out_reloc(s
, s
->code_ptr
, R_SPARC_WDISP19
, l
, 0);
621 tcg_out_bpcc0(s
, scond
, flags
, off19
);
624 static void tcg_out_cmp(TCGContext
*s
, TCGReg c1
, int32_t c2
, int c2const
)
626 tcg_out_arithc(s
, TCG_REG_G0
, c1
, c2
, c2const
, ARITH_SUBCC
);
629 static void tcg_out_brcond_i32(TCGContext
*s
, TCGCond cond
, TCGReg arg1
,
630 int32_t arg2
, int const_arg2
, TCGLabel
*l
)
632 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
);
633 tcg_out_bpcc(s
, tcg_cond_to_bcond
[cond
], BPCC_ICC
| BPCC_PT
, l
);
637 static void tcg_out_movcc(TCGContext
*s
, TCGCond cond
, int cc
, TCGReg ret
,
638 int32_t v1
, int v1const
)
640 tcg_out32(s
, ARITH_MOVCC
| cc
| INSN_RD(ret
)
641 | INSN_RS1(tcg_cond_to_bcond
[cond
])
642 | (v1const
? INSN_IMM11(v1
) : INSN_RS2(v1
)));
645 static void tcg_out_movcond_i32(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
646 TCGReg c1
, int32_t c2
, int c2const
,
647 int32_t v1
, int v1const
)
649 tcg_out_cmp(s
, c1
, c2
, c2const
);
650 tcg_out_movcc(s
, cond
, MOVCC_ICC
, ret
, v1
, v1const
);
653 static void tcg_out_brcond_i64(TCGContext
*s
, TCGCond cond
, TCGReg arg1
,
654 int32_t arg2
, int const_arg2
, TCGLabel
*l
)
656 /* For 64-bit signed comparisons vs zero, we can avoid the compare. */
657 if (arg2
== 0 && !is_unsigned_cond(cond
)) {
661 off16
= INSN_OFF16(tcg_pcrel_diff(s
, l
->u
.value_ptr
));
663 tcg_out_reloc(s
, s
->code_ptr
, R_SPARC_WDISP16
, l
, 0);
665 tcg_out32(s
, INSN_OP(0) | INSN_OP2(3) | BPR_PT
| INSN_RS1(arg1
)
666 | INSN_COND(tcg_cond_to_rcond
[cond
]) | off16
);
668 tcg_out_cmp(s
, arg1
, arg2
, const_arg2
);
669 tcg_out_bpcc(s
, tcg_cond_to_bcond
[cond
], BPCC_XCC
| BPCC_PT
, l
);
674 static void tcg_out_movr(TCGContext
*s
, TCGCond cond
, TCGReg ret
, TCGReg c1
,
675 int32_t v1
, int v1const
)
677 tcg_out32(s
, ARITH_MOVR
| INSN_RD(ret
) | INSN_RS1(c1
)
678 | (tcg_cond_to_rcond
[cond
] << 10)
679 | (v1const
? INSN_IMM10(v1
) : INSN_RS2(v1
)));
682 static void tcg_out_movcond_i64(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
683 TCGReg c1
, int32_t c2
, int c2const
,
684 int32_t v1
, int v1const
)
686 /* For 64-bit signed comparisons vs zero, we can avoid the compare.
687 Note that the immediate range is one bit smaller, so we must check
689 if (c2
== 0 && !is_unsigned_cond(cond
)
690 && (!v1const
|| check_fit_i32(v1
, 10))) {
691 tcg_out_movr(s
, cond
, ret
, c1
, v1
, v1const
);
693 tcg_out_cmp(s
, c1
, c2
, c2const
);
694 tcg_out_movcc(s
, cond
, MOVCC_XCC
, ret
, v1
, v1const
);
698 static void tcg_out_setcond_i32(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
699 TCGReg c1
, int32_t c2
, int c2const
)
701 /* For 32-bit comparisons, we can play games with ADDC/SUBC. */
705 /* The result of the comparison is in the carry bit. */
710 /* For equality, we can transform to inequality vs zero. */
712 tcg_out_arithc(s
, TCG_REG_T1
, c1
, c2
, c2const
, ARITH_XOR
);
717 c1
= TCG_REG_G0
, c2const
= 0;
718 cond
= (cond
== TCG_COND_EQ
? TCG_COND_GEU
: TCG_COND_LTU
);
723 /* If we don't need to load a constant into a register, we can
724 swap the operands on GTU/LEU. There's no benefit to loading
725 the constant into a temporary register. */
726 if (!c2const
|| c2
== 0) {
731 cond
= tcg_swap_cond(cond
);
737 tcg_out_cmp(s
, c1
, c2
, c2const
);
738 tcg_out_movi_imm13(s
, ret
, 0);
739 tcg_out_movcc(s
, cond
, MOVCC_ICC
, ret
, 1, 1);
743 tcg_out_cmp(s
, c1
, c2
, c2const
);
744 if (cond
== TCG_COND_LTU
) {
745 tcg_out_arithi(s
, ret
, TCG_REG_G0
, 0, ARITH_ADDC
);
747 tcg_out_arithi(s
, ret
, TCG_REG_G0
, -1, ARITH_SUBC
);
751 static void tcg_out_setcond_i64(TCGContext
*s
, TCGCond cond
, TCGReg ret
,
752 TCGReg c1
, int32_t c2
, int c2const
)
754 if (use_vis3_instructions
) {
760 c2
= c1
, c2const
= 0, c1
= TCG_REG_G0
;
763 tcg_out_cmp(s
, c1
, c2
, c2const
);
764 tcg_out_arith(s
, ret
, TCG_REG_G0
, TCG_REG_G0
, ARITH_ADDXC
);
771 /* For 64-bit signed comparisons vs zero, we can avoid the compare
772 if the input does not overlap the output. */
773 if (c2
== 0 && !is_unsigned_cond(cond
) && c1
!= ret
) {
774 tcg_out_movi_imm13(s
, ret
, 0);
775 tcg_out_movr(s
, cond
, ret
, c1
, 1, 1);
777 tcg_out_cmp(s
, c1
, c2
, c2const
);
778 tcg_out_movi_imm13(s
, ret
, 0);
779 tcg_out_movcc(s
, cond
, MOVCC_XCC
, ret
, 1, 1);
783 static void tcg_out_addsub2_i32(TCGContext
*s
, TCGReg rl
, TCGReg rh
,
784 TCGReg al
, TCGReg ah
, int32_t bl
, int blconst
,
785 int32_t bh
, int bhconst
, int opl
, int oph
)
787 TCGReg tmp
= TCG_REG_T1
;
789 /* Note that the low parts are fully consumed before tmp is set. */
790 if (rl
!= ah
&& (bhconst
|| rl
!= bh
)) {
794 tcg_out_arithc(s
, tmp
, al
, bl
, blconst
, opl
);
795 tcg_out_arithc(s
, rh
, ah
, bh
, bhconst
, oph
);
796 tcg_out_mov(s
, TCG_TYPE_I32
, rl
, tmp
);
799 static void tcg_out_addsub2_i64(TCGContext
*s
, TCGReg rl
, TCGReg rh
,
800 TCGReg al
, TCGReg ah
, int32_t bl
, int blconst
,
801 int32_t bh
, int bhconst
, bool is_sub
)
803 TCGReg tmp
= TCG_REG_T1
;
805 /* Note that the low parts are fully consumed before tmp is set. */
806 if (rl
!= ah
&& (bhconst
|| rl
!= bh
)) {
810 tcg_out_arithc(s
, tmp
, al
, bl
, blconst
, is_sub
? ARITH_SUBCC
: ARITH_ADDCC
);
812 if (use_vis3_instructions
&& !is_sub
) {
813 /* Note that ADDXC doesn't accept immediates. */
814 if (bhconst
&& bh
!= 0) {
815 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_T2
, bh
);
818 tcg_out_arith(s
, rh
, ah
, bh
, ARITH_ADDXC
);
819 } else if (bh
== TCG_REG_G0
) {
820 /* If we have a zero, we can perform the operation in two insns,
821 with the arithmetic first, and a conditional move into place. */
823 tcg_out_arithi(s
, TCG_REG_T2
, ah
, 1,
824 is_sub
? ARITH_SUB
: ARITH_ADD
);
825 tcg_out_movcc(s
, TCG_COND_LTU
, MOVCC_XCC
, rh
, TCG_REG_T2
, 0);
827 tcg_out_arithi(s
, rh
, ah
, 1, is_sub
? ARITH_SUB
: ARITH_ADD
);
828 tcg_out_movcc(s
, TCG_COND_GEU
, MOVCC_XCC
, rh
, ah
, 0);
831 /* Otherwise adjust BH as if there is carry into T2 ... */
833 tcg_out_movi(s
, TCG_TYPE_I64
, TCG_REG_T2
, bh
+ (is_sub
? -1 : 1));
835 tcg_out_arithi(s
, TCG_REG_T2
, bh
, 1,
836 is_sub
? ARITH_SUB
: ARITH_ADD
);
838 /* ... smoosh T2 back to original BH if carry is clear ... */
839 tcg_out_movcc(s
, TCG_COND_GEU
, MOVCC_XCC
, TCG_REG_T2
, bh
, bhconst
);
840 /* ... and finally perform the arithmetic with the new operand. */
841 tcg_out_arith(s
, rh
, ah
, TCG_REG_T2
, is_sub
? ARITH_SUB
: ARITH_ADD
);
844 tcg_out_mov(s
, TCG_TYPE_I64
, rl
, tmp
);
847 static void tcg_out_call_nodelay(TCGContext
*s
, tcg_insn_unit
*dest
,
850 ptrdiff_t disp
= tcg_pcrel_diff(s
, dest
);
852 if (disp
== (int32_t)disp
) {
853 tcg_out32(s
, CALL
| (uint32_t)disp
>> 2);
855 uintptr_t desti
= (uintptr_t)dest
;
856 tcg_out_movi_int(s
, TCG_TYPE_PTR
, TCG_REG_T1
,
857 desti
& ~0xfff, in_prologue
);
858 tcg_out_arithi(s
, TCG_REG_O7
, TCG_REG_T1
, desti
& 0xfff, JMPL
);
862 static void tcg_out_call(TCGContext
*s
, tcg_insn_unit
*dest
)
864 tcg_out_call_nodelay(s
, dest
, false);
868 static void tcg_out_mb(TCGContext
*s
, TCGArg a0
)
870 /* Note that the TCG memory order constants mirror the Sparc MEMBAR. */
871 tcg_out32(s
, MEMBAR
| (a0
& TCG_MO_ALL
));
874 #ifdef CONFIG_SOFTMMU
875 static tcg_insn_unit
*qemu_ld_trampoline
[16];
876 static tcg_insn_unit
*qemu_st_trampoline
[16];
878 static void emit_extend(TCGContext
*s
, TCGReg r
, int op
)
880 /* Emit zero extend of 8, 16 or 32 bit data as
881 * required by the MO_* value op; do nothing for 64 bit.
883 switch (op
& MO_SIZE
) {
885 tcg_out_arithi(s
, r
, r
, 0xff, ARITH_AND
);
888 tcg_out_arithi(s
, r
, r
, 16, SHIFT_SLL
);
889 tcg_out_arithi(s
, r
, r
, 16, SHIFT_SRL
);
893 tcg_out_arith(s
, r
, r
, 0, SHIFT_SRL
);
901 static void build_trampolines(TCGContext
*s
)
903 static void * const qemu_ld_helpers
[16] = {
904 [MO_UB
] = helper_ret_ldub_mmu
,
905 [MO_SB
] = helper_ret_ldsb_mmu
,
906 [MO_LEUW
] = helper_le_lduw_mmu
,
907 [MO_LESW
] = helper_le_ldsw_mmu
,
908 [MO_LEUL
] = helper_le_ldul_mmu
,
909 [MO_LEQ
] = helper_le_ldq_mmu
,
910 [MO_BEUW
] = helper_be_lduw_mmu
,
911 [MO_BESW
] = helper_be_ldsw_mmu
,
912 [MO_BEUL
] = helper_be_ldul_mmu
,
913 [MO_BEQ
] = helper_be_ldq_mmu
,
915 static void * const qemu_st_helpers
[16] = {
916 [MO_UB
] = helper_ret_stb_mmu
,
917 [MO_LEUW
] = helper_le_stw_mmu
,
918 [MO_LEUL
] = helper_le_stl_mmu
,
919 [MO_LEQ
] = helper_le_stq_mmu
,
920 [MO_BEUW
] = helper_be_stw_mmu
,
921 [MO_BEUL
] = helper_be_stl_mmu
,
922 [MO_BEQ
] = helper_be_stq_mmu
,
928 for (i
= 0; i
< 16; ++i
) {
929 if (qemu_ld_helpers
[i
] == NULL
) {
933 /* May as well align the trampoline. */
934 while ((uintptr_t)s
->code_ptr
& 15) {
937 qemu_ld_trampoline
[i
] = s
->code_ptr
;
939 if (SPARC64
|| TARGET_LONG_BITS
== 32) {
942 /* Install the high part of the address. */
943 tcg_out_arithi(s
, TCG_REG_O1
, TCG_REG_O2
, 32, SHIFT_SRLX
);
947 /* Set the retaddr operand. */
948 tcg_out_mov(s
, TCG_TYPE_PTR
, ra
, TCG_REG_O7
);
949 /* Set the env operand. */
950 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_O0
, TCG_AREG0
);
952 tcg_out_call_nodelay(s
, qemu_ld_helpers
[i
], true);
953 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_O7
, ra
);
956 for (i
= 0; i
< 16; ++i
) {
957 if (qemu_st_helpers
[i
] == NULL
) {
961 /* May as well align the trampoline. */
962 while ((uintptr_t)s
->code_ptr
& 15) {
965 qemu_st_trampoline
[i
] = s
->code_ptr
;
968 emit_extend(s
, TCG_REG_O2
, i
);
972 if (TARGET_LONG_BITS
== 64) {
973 /* Install the high part of the address. */
974 tcg_out_arithi(s
, ra
, ra
+ 1, 32, SHIFT_SRLX
);
979 if ((i
& MO_SIZE
) == MO_64
) {
980 /* Install the high part of the data. */
981 tcg_out_arithi(s
, ra
, ra
+ 1, 32, SHIFT_SRLX
);
984 emit_extend(s
, ra
, i
);
987 /* Skip the oi argument. */
991 /* Set the retaddr operand. */
992 if (ra
>= TCG_REG_O6
) {
993 tcg_out_st(s
, TCG_TYPE_PTR
, TCG_REG_O7
, TCG_REG_CALL_STACK
,
994 TCG_TARGET_CALL_STACK_OFFSET
);
997 tcg_out_mov(s
, TCG_TYPE_PTR
, ra
, TCG_REG_O7
);
998 /* Set the env operand. */
999 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_O0
, TCG_AREG0
);
1001 tcg_out_call_nodelay(s
, qemu_st_helpers
[i
], true);
1002 tcg_out_mov(s
, TCG_TYPE_PTR
, TCG_REG_O7
, ra
);
1007 /* Generate global QEMU prologue and epilogue code */
1008 static void tcg_target_qemu_prologue(TCGContext
*s
)
1010 int tmp_buf_size
, frame_size
;
1012 /* The TCG temp buffer is at the top of the frame, immediately
1013 below the frame pointer. */
1014 tmp_buf_size
= CPU_TEMP_BUF_NLONGS
* (int)sizeof(long);
1015 tcg_set_frame(s
, TCG_REG_I6
, TCG_TARGET_STACK_BIAS
- tmp_buf_size
,
1018 /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
1019 otherwise the minimal frame usable by callees. */
1020 frame_size
= TCG_TARGET_CALL_STACK_OFFSET
- TCG_TARGET_STACK_BIAS
;
1021 frame_size
+= TCG_STATIC_CALL_ARGS_SIZE
+ tmp_buf_size
;
1022 frame_size
+= TCG_TARGET_STACK_ALIGN
- 1;
1023 frame_size
&= -TCG_TARGET_STACK_ALIGN
;
1024 tcg_out32(s
, SAVE
| INSN_RD(TCG_REG_O6
) | INSN_RS1(TCG_REG_O6
) |
1025 INSN_IMM13(-frame_size
));
1027 #ifndef CONFIG_SOFTMMU
1028 if (guest_base
!= 0) {
1029 tcg_out_movi_int(s
, TCG_TYPE_PTR
, TCG_GUEST_BASE_REG
, guest_base
, true);
1030 tcg_regset_set_reg(s
->reserved_regs
, TCG_GUEST_BASE_REG
);
1034 /* We choose TCG_REG_TB such that no move is required. */
1036 QEMU_BUILD_BUG_ON(TCG_REG_TB
!= TCG_REG_I1
);
1037 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_TB
);
1040 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_I1
, 0, JMPL
);
1044 /* Epilogue for goto_ptr. */
1045 s
->code_gen_epilogue
= s
->code_ptr
;
1046 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_I7
, 8, RETURN
);
1048 tcg_out_movi_imm13(s
, TCG_REG_O0
, 0);
1050 #ifdef CONFIG_SOFTMMU
1051 build_trampolines(s
);
1055 static void tcg_out_nop_fill(tcg_insn_unit
*p
, int count
)
1058 for (i
= 0; i
< count
; ++i
) {
1063 #if defined(CONFIG_SOFTMMU)
1064 /* Perform the TLB load and compare.
1067 ADDRLO and ADDRHI contain the possible two parts of the address.
1069 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1071 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1072 This should be offsetof addr_read or addr_write.
1074 The result of the TLB comparison is in %[ix]cc. The sanitized address
1075 is in the returned register, maybe %o0. The TLB addend is in %o1. */
1077 /* We expect tlb_mask to be before tlb_table. */
1078 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
) <
1079 offsetof(CPUArchState
, tlb_mask
));
1081 /* We expect tlb_mask to be "near" tlb_table. */
1082 QEMU_BUILD_BUG_ON(offsetof(CPUArchState
, tlb_table
) -
1083 offsetof(CPUArchState
, tlb_mask
) >= (1 << 13));
1085 static TCGReg
tcg_out_tlb_load(TCGContext
*s
, TCGReg addr
, int mem_index
,
1086 TCGMemOp opc
, int which
)
1088 int mask_off
= offsetof(CPUArchState
, tlb_mask
[mem_index
]);
1089 int table_off
= offsetof(CPUArchState
, tlb_table
[mem_index
]);
1090 TCGReg base
= TCG_AREG0
;
1091 const TCGReg r0
= TCG_REG_O0
;
1092 const TCGReg r1
= TCG_REG_O1
;
1093 const TCGReg r2
= TCG_REG_O2
;
1094 unsigned s_bits
= opc
& MO_SIZE
;
1095 unsigned a_bits
= get_alignment_bits(opc
);
1096 tcg_target_long compare_mask
;
1098 if (!check_fit_i32(table_off
, 13)) {
1102 if (table_off
<= 2 * 0xfff) {
1104 tcg_out_arithi(s
, base
, TCG_AREG0
, table_hi
, ARITH_ADD
);
1106 table_hi
= table_off
& ~0x3ff;
1107 tcg_out_sethi(s
, base
, table_hi
);
1108 tcg_out_arith(s
, base
, TCG_AREG0
, base
, ARITH_ADD
);
1110 mask_off
-= table_hi
;
1111 table_off
-= table_hi
;
1112 tcg_debug_assert(check_fit_i32(mask_off
, 13));
1115 /* Load tlb_mask[mmu_idx] and tlb_table[mmu_idx]. */
1116 tcg_out_ld(s
, TCG_TYPE_PTR
, r0
, base
, mask_off
);
1117 tcg_out_ld(s
, TCG_TYPE_PTR
, r1
, base
, table_off
);
1119 /* Extract the page index, shifted into place for tlb index. */
1120 tcg_out_arithi(s
, r2
, addr
, TARGET_PAGE_BITS
- CPU_TLB_ENTRY_BITS
,
1122 tcg_out_arith(s
, r2
, r2
, r0
, ARITH_AND
);
1124 /* Add the tlb_table pointer, creating the CPUTLBEntry address into R2. */
1125 tcg_out_arith(s
, r2
, r2
, r1
, ARITH_ADD
);
1127 /* Load the tlb comparator and the addend. */
1128 tcg_out_ld(s
, TCG_TYPE_TL
, r0
, r2
, which
);
1129 tcg_out_ld(s
, TCG_TYPE_PTR
, r1
, r2
, offsetof(CPUTLBEntry
, addend
));
1131 /* Mask out the page offset, except for the required alignment.
1132 We don't support unaligned accesses. */
1133 if (a_bits
< s_bits
) {
1136 compare_mask
= (tcg_target_ulong
)TARGET_PAGE_MASK
| ((1 << a_bits
) - 1);
1137 if (check_fit_tl(compare_mask
, 13)) {
1138 tcg_out_arithi(s
, r2
, addr
, compare_mask
, ARITH_AND
);
1140 tcg_out_movi(s
, TCG_TYPE_TL
, r2
, compare_mask
);
1141 tcg_out_arith(s
, r2
, addr
, r2
, ARITH_AND
);
1143 tcg_out_cmp(s
, r0
, r2
, 0);
1145 /* If the guest address must be zero-extended, do so now. */
1146 if (SPARC64
&& TARGET_LONG_BITS
== 32) {
1147 tcg_out_arithi(s
, r0
, addr
, 0, SHIFT_SRL
);
1152 #endif /* CONFIG_SOFTMMU */
1154 static const int qemu_ld_opc
[16] = {
1164 [MO_LEUW
] = LDUH_LE
,
1165 [MO_LESW
] = LDSH_LE
,
1166 [MO_LEUL
] = LDUW_LE
,
1167 [MO_LESL
] = LDSW_LE
,
1171 static const int qemu_st_opc
[16] = {
1183 static void tcg_out_qemu_ld(TCGContext
*s
, TCGReg data
, TCGReg addr
,
1184 TCGMemOpIdx oi
, bool is_64
)
1186 TCGMemOp memop
= get_memop(oi
);
1187 #ifdef CONFIG_SOFTMMU
1188 unsigned memi
= get_mmuidx(oi
);
1189 TCGReg addrz
, param
;
1190 tcg_insn_unit
*func
;
1191 tcg_insn_unit
*label_ptr
;
1193 addrz
= tcg_out_tlb_load(s
, addr
, memi
, memop
,
1194 offsetof(CPUTLBEntry
, addr_read
));
1196 /* The fast path is exactly one insn. Thus we can perform the
1197 entire TLB Hit in the (annulled) delay slot of the branch
1198 over the TLB Miss case. */
1200 /* beq,a,pt %[xi]cc, label0 */
1201 label_ptr
= s
->code_ptr
;
1202 tcg_out_bpcc0(s
, COND_E
, BPCC_A
| BPCC_PT
1203 | (TARGET_LONG_BITS
== 64 ? BPCC_XCC
: BPCC_ICC
), 0);
1205 tcg_out_ldst_rr(s
, data
, addrz
, TCG_REG_O1
,
1206 qemu_ld_opc
[memop
& (MO_BSWAP
| MO_SSIZE
)]);
1211 if (!SPARC64
&& TARGET_LONG_BITS
== 64) {
1212 /* Skip the high-part; we'll perform the extract in the trampoline. */
1215 tcg_out_mov(s
, TCG_TYPE_REG
, param
++, addrz
);
1217 /* We use the helpers to extend SB and SW data, leaving the case
1218 of SL needing explicit extending below. */
1219 if ((memop
& MO_SSIZE
) == MO_SL
) {
1220 func
= qemu_ld_trampoline
[memop
& (MO_BSWAP
| MO_SIZE
)];
1222 func
= qemu_ld_trampoline
[memop
& (MO_BSWAP
| MO_SSIZE
)];
1224 tcg_debug_assert(func
!= NULL
);
1225 tcg_out_call_nodelay(s
, func
, false);
1227 tcg_out_movi(s
, TCG_TYPE_I32
, param
, oi
);
1229 /* Recall that all of the helpers return 64-bit results.
1230 Which complicates things for sparcv8plus. */
1232 /* We let the helper sign-extend SB and SW, but leave SL for here. */
1233 if (is_64
&& (memop
& MO_SSIZE
) == MO_SL
) {
1234 tcg_out_arithi(s
, data
, TCG_REG_O0
, 0, SHIFT_SRA
);
1236 tcg_out_mov(s
, TCG_TYPE_REG
, data
, TCG_REG_O0
);
1239 if ((memop
& MO_SIZE
) == MO_64
) {
1240 tcg_out_arithi(s
, TCG_REG_O0
, TCG_REG_O0
, 32, SHIFT_SLLX
);
1241 tcg_out_arithi(s
, TCG_REG_O1
, TCG_REG_O1
, 0, SHIFT_SRL
);
1242 tcg_out_arith(s
, data
, TCG_REG_O0
, TCG_REG_O1
, ARITH_OR
);
1244 /* Re-extend from 32-bit rather than reassembling when we
1245 know the high register must be an extension. */
1246 tcg_out_arithi(s
, data
, TCG_REG_O1
, 0,
1247 memop
& MO_SIGN
? SHIFT_SRA
: SHIFT_SRL
);
1249 tcg_out_mov(s
, TCG_TYPE_I32
, data
, TCG_REG_O1
);
1253 *label_ptr
|= INSN_OFF19(tcg_ptr_byte_diff(s
->code_ptr
, label_ptr
));
1255 if (SPARC64
&& TARGET_LONG_BITS
== 32) {
1256 tcg_out_arithi(s
, TCG_REG_T1
, addr
, 0, SHIFT_SRL
);
1259 tcg_out_ldst_rr(s
, data
, addr
,
1260 (guest_base
? TCG_GUEST_BASE_REG
: TCG_REG_G0
),
1261 qemu_ld_opc
[memop
& (MO_BSWAP
| MO_SSIZE
)]);
1262 #endif /* CONFIG_SOFTMMU */
1265 static void tcg_out_qemu_st(TCGContext
*s
, TCGReg data
, TCGReg addr
,
1268 TCGMemOp memop
= get_memop(oi
);
1269 #ifdef CONFIG_SOFTMMU
1270 unsigned memi
= get_mmuidx(oi
);
1271 TCGReg addrz
, param
;
1272 tcg_insn_unit
*func
;
1273 tcg_insn_unit
*label_ptr
;
1275 addrz
= tcg_out_tlb_load(s
, addr
, memi
, memop
,
1276 offsetof(CPUTLBEntry
, addr_write
));
1278 /* The fast path is exactly one insn. Thus we can perform the entire
1279 TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
1280 /* beq,a,pt %[xi]cc, label0 */
1281 label_ptr
= s
->code_ptr
;
1282 tcg_out_bpcc0(s
, COND_E
, BPCC_A
| BPCC_PT
1283 | (TARGET_LONG_BITS
== 64 ? BPCC_XCC
: BPCC_ICC
), 0);
1285 tcg_out_ldst_rr(s
, data
, addrz
, TCG_REG_O1
,
1286 qemu_st_opc
[memop
& (MO_BSWAP
| MO_SIZE
)]);
1291 if (!SPARC64
&& TARGET_LONG_BITS
== 64) {
1292 /* Skip the high-part; we'll perform the extract in the trampoline. */
1295 tcg_out_mov(s
, TCG_TYPE_REG
, param
++, addrz
);
1296 if (!SPARC64
&& (memop
& MO_SIZE
) == MO_64
) {
1297 /* Skip the high-part; we'll perform the extract in the trampoline. */
1300 tcg_out_mov(s
, TCG_TYPE_REG
, param
++, data
);
1302 func
= qemu_st_trampoline
[memop
& (MO_BSWAP
| MO_SIZE
)];
1303 tcg_debug_assert(func
!= NULL
);
1304 tcg_out_call_nodelay(s
, func
, false);
1306 tcg_out_movi(s
, TCG_TYPE_I32
, param
, oi
);
1308 *label_ptr
|= INSN_OFF19(tcg_ptr_byte_diff(s
->code_ptr
, label_ptr
));
1310 if (SPARC64
&& TARGET_LONG_BITS
== 32) {
1311 tcg_out_arithi(s
, TCG_REG_T1
, addr
, 0, SHIFT_SRL
);
1314 tcg_out_ldst_rr(s
, data
, addr
,
1315 (guest_base
? TCG_GUEST_BASE_REG
: TCG_REG_G0
),
1316 qemu_st_opc
[memop
& (MO_BSWAP
| MO_SIZE
)]);
1317 #endif /* CONFIG_SOFTMMU */
1320 static void tcg_out_op(TCGContext
*s
, TCGOpcode opc
,
1321 const TCGArg args
[TCG_MAX_OP_ARGS
],
1322 const int const_args
[TCG_MAX_OP_ARGS
])
1327 /* Hoist the loads of the most common arguments. */
1334 case INDEX_op_exit_tb
:
1335 if (check_fit_ptr(a0
, 13)) {
1336 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_I7
, 8, RETURN
);
1337 tcg_out_movi_imm13(s
, TCG_REG_O0
, a0
);
1339 } else if (USE_REG_TB
) {
1340 intptr_t tb_diff
= a0
- (uintptr_t)s
->code_gen_ptr
;
1341 if (check_fit_ptr(tb_diff
, 13)) {
1342 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_I7
, 8, RETURN
);
1343 /* Note that TCG_REG_TB has been unwound to O1. */
1344 tcg_out_arithi(s
, TCG_REG_O0
, TCG_REG_O1
, tb_diff
, ARITH_ADD
);
1348 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_I0
, a0
& ~0x3ff);
1349 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_I7
, 8, RETURN
);
1350 tcg_out_arithi(s
, TCG_REG_O0
, TCG_REG_O0
, a0
& 0x3ff, ARITH_OR
);
1352 case INDEX_op_goto_tb
:
1353 if (s
->tb_jmp_insn_offset
) {
1354 /* direct jump method */
1356 /* make sure the patch is 8-byte aligned. */
1357 if ((intptr_t)s
->code_ptr
& 4) {
1360 s
->tb_jmp_insn_offset
[a0
] = tcg_current_code_size(s
);
1361 tcg_out_sethi(s
, TCG_REG_T1
, 0);
1362 tcg_out_arithi(s
, TCG_REG_T1
, TCG_REG_T1
, 0, ARITH_OR
);
1363 tcg_out_arith(s
, TCG_REG_G0
, TCG_REG_TB
, TCG_REG_T1
, JMPL
);
1364 tcg_out_arith(s
, TCG_REG_TB
, TCG_REG_TB
, TCG_REG_T1
, ARITH_ADD
);
1366 s
->tb_jmp_insn_offset
[a0
] = tcg_current_code_size(s
);
1371 /* indirect jump method */
1372 tcg_out_ld_ptr(s
, TCG_REG_TB
,
1373 (uintptr_t)(s
->tb_jmp_target_addr
+ a0
));
1374 tcg_out_arithi(s
, TCG_REG_G0
, TCG_REG_TB
, 0, JMPL
);
1377 set_jmp_reset_offset(s
, a0
);
1379 /* For the unlinked path of goto_tb, we need to reset
1380 TCG_REG_TB to the beginning of this TB. */
1382 c
= -tcg_current_code_size(s
);
1383 if (check_fit_i32(c
, 13)) {
1384 tcg_out_arithi(s
, TCG_REG_TB
, TCG_REG_TB
, c
, ARITH_ADD
);
1386 tcg_out_movi(s
, TCG_TYPE_PTR
, TCG_REG_T1
, c
);
1387 tcg_out_arith(s
, TCG_REG_TB
, TCG_REG_TB
,
1388 TCG_REG_T1
, ARITH_ADD
);
1392 case INDEX_op_goto_ptr
:
1393 tcg_out_arithi(s
, TCG_REG_G0
, a0
, 0, JMPL
);
1395 tcg_out_arith(s
, TCG_REG_TB
, a0
, TCG_REG_G0
, ARITH_OR
);
1401 tcg_out_bpcc(s
, COND_A
, BPCC_PT
, arg_label(a0
));
1405 #define OP_32_64(x) \
1406 glue(glue(case INDEX_op_, x), _i32): \
1407 glue(glue(case INDEX_op_, x), _i64)
1410 tcg_out_ldst(s
, a0
, a1
, a2
, LDUB
);
1413 tcg_out_ldst(s
, a0
, a1
, a2
, LDSB
);
1416 tcg_out_ldst(s
, a0
, a1
, a2
, LDUH
);
1419 tcg_out_ldst(s
, a0
, a1
, a2
, LDSH
);
1421 case INDEX_op_ld_i32
:
1422 case INDEX_op_ld32u_i64
:
1423 tcg_out_ldst(s
, a0
, a1
, a2
, LDUW
);
1426 tcg_out_ldst(s
, a0
, a1
, a2
, STB
);
1429 tcg_out_ldst(s
, a0
, a1
, a2
, STH
);
1431 case INDEX_op_st_i32
:
1432 case INDEX_op_st32_i64
:
1433 tcg_out_ldst(s
, a0
, a1
, a2
, STW
);
1456 case INDEX_op_shl_i32
:
1459 /* Limit immediate shift count lest we create an illegal insn. */
1460 tcg_out_arithc(s
, a0
, a1
, a2
& 31, c2
, c
);
1462 case INDEX_op_shr_i32
:
1465 case INDEX_op_sar_i32
:
1468 case INDEX_op_mul_i32
:
1479 case INDEX_op_div_i32
:
1480 tcg_out_div32(s
, a0
, a1
, a2
, c2
, 0);
1482 case INDEX_op_divu_i32
:
1483 tcg_out_div32(s
, a0
, a1
, a2
, c2
, 1);
1486 case INDEX_op_brcond_i32
:
1487 tcg_out_brcond_i32(s
, a2
, a0
, a1
, const_args
[1], arg_label(args
[3]));
1489 case INDEX_op_setcond_i32
:
1490 tcg_out_setcond_i32(s
, args
[3], a0
, a1
, a2
, c2
);
1492 case INDEX_op_movcond_i32
:
1493 tcg_out_movcond_i32(s
, args
[5], a0
, a1
, a2
, c2
, args
[3], const_args
[3]);
1496 case INDEX_op_add2_i32
:
1497 tcg_out_addsub2_i32(s
, args
[0], args
[1], args
[2], args
[3],
1498 args
[4], const_args
[4], args
[5], const_args
[5],
1499 ARITH_ADDCC
, ARITH_ADDC
);
1501 case INDEX_op_sub2_i32
:
1502 tcg_out_addsub2_i32(s
, args
[0], args
[1], args
[2], args
[3],
1503 args
[4], const_args
[4], args
[5], const_args
[5],
1504 ARITH_SUBCC
, ARITH_SUBC
);
1506 case INDEX_op_mulu2_i32
:
1509 case INDEX_op_muls2_i32
:
1512 /* The 32-bit multiply insns produce a full 64-bit result. If the
1513 destination register can hold it, we can avoid the slower RDY. */
1514 tcg_out_arithc(s
, a0
, a2
, args
[3], const_args
[3], c
);
1515 if (SPARC64
|| a0
<= TCG_REG_O7
) {
1516 tcg_out_arithi(s
, a1
, a0
, 32, SHIFT_SRLX
);
1522 case INDEX_op_qemu_ld_i32
:
1523 tcg_out_qemu_ld(s
, a0
, a1
, a2
, false);
1525 case INDEX_op_qemu_ld_i64
:
1526 tcg_out_qemu_ld(s
, a0
, a1
, a2
, true);
1528 case INDEX_op_qemu_st_i32
:
1529 case INDEX_op_qemu_st_i64
:
1530 tcg_out_qemu_st(s
, a0
, a1
, a2
);
1533 case INDEX_op_ld32s_i64
:
1534 tcg_out_ldst(s
, a0
, a1
, a2
, LDSW
);
1536 case INDEX_op_ld_i64
:
1537 tcg_out_ldst(s
, a0
, a1
, a2
, LDX
);
1539 case INDEX_op_st_i64
:
1540 tcg_out_ldst(s
, a0
, a1
, a2
, STX
);
1542 case INDEX_op_shl_i64
:
1545 /* Limit immediate shift count lest we create an illegal insn. */
1546 tcg_out_arithc(s
, a0
, a1
, a2
& 63, c2
, c
);
1548 case INDEX_op_shr_i64
:
1551 case INDEX_op_sar_i64
:
1554 case INDEX_op_mul_i64
:
1557 case INDEX_op_div_i64
:
1560 case INDEX_op_divu_i64
:
1563 case INDEX_op_ext_i32_i64
:
1564 case INDEX_op_ext32s_i64
:
1565 tcg_out_arithi(s
, a0
, a1
, 0, SHIFT_SRA
);
1567 case INDEX_op_extu_i32_i64
:
1568 case INDEX_op_ext32u_i64
:
1569 tcg_out_arithi(s
, a0
, a1
, 0, SHIFT_SRL
);
1571 case INDEX_op_extrl_i64_i32
:
1572 tcg_out_mov(s
, TCG_TYPE_I32
, a0
, a1
);
1574 case INDEX_op_extrh_i64_i32
:
1575 tcg_out_arithi(s
, a0
, a1
, 32, SHIFT_SRLX
);
1578 case INDEX_op_brcond_i64
:
1579 tcg_out_brcond_i64(s
, a2
, a0
, a1
, const_args
[1], arg_label(args
[3]));
1581 case INDEX_op_setcond_i64
:
1582 tcg_out_setcond_i64(s
, args
[3], a0
, a1
, a2
, c2
);
1584 case INDEX_op_movcond_i64
:
1585 tcg_out_movcond_i64(s
, args
[5], a0
, a1
, a2
, c2
, args
[3], const_args
[3]);
1587 case INDEX_op_add2_i64
:
1588 tcg_out_addsub2_i64(s
, args
[0], args
[1], args
[2], args
[3], args
[4],
1589 const_args
[4], args
[5], const_args
[5], false);
1591 case INDEX_op_sub2_i64
:
1592 tcg_out_addsub2_i64(s
, args
[0], args
[1], args
[2], args
[3], args
[4],
1593 const_args
[4], args
[5], const_args
[5], true);
1595 case INDEX_op_muluh_i64
:
1596 tcg_out_arith(s
, args
[0], args
[1], args
[2], ARITH_UMULXHI
);
1600 tcg_out_arithc(s
, a0
, a1
, a2
, c2
, c
);
1604 tcg_out_arithc(s
, a0
, TCG_REG_G0
, a1
, const_args
[1], c
);
1611 case INDEX_op_mov_i32
: /* Always emitted via tcg_out_mov. */
1612 case INDEX_op_mov_i64
:
1613 case INDEX_op_movi_i32
: /* Always emitted via tcg_out_movi. */
1614 case INDEX_op_movi_i64
:
1615 case INDEX_op_call
: /* Always emitted via tcg_out_call. */
1621 static const TCGTargetOpDef
*tcg_target_op_def(TCGOpcode op
)
1623 static const TCGTargetOpDef r
= { .args_ct_str
= { "r" } };
1624 static const TCGTargetOpDef r_r
= { .args_ct_str
= { "r", "r" } };
1625 static const TCGTargetOpDef R_r
= { .args_ct_str
= { "R", "r" } };
1626 static const TCGTargetOpDef r_R
= { .args_ct_str
= { "r", "R" } };
1627 static const TCGTargetOpDef R_R
= { .args_ct_str
= { "R", "R" } };
1628 static const TCGTargetOpDef r_A
= { .args_ct_str
= { "r", "A" } };
1629 static const TCGTargetOpDef R_A
= { .args_ct_str
= { "R", "A" } };
1630 static const TCGTargetOpDef rZ_r
= { .args_ct_str
= { "rZ", "r" } };
1631 static const TCGTargetOpDef RZ_r
= { .args_ct_str
= { "RZ", "r" } };
1632 static const TCGTargetOpDef sZ_A
= { .args_ct_str
= { "sZ", "A" } };
1633 static const TCGTargetOpDef SZ_A
= { .args_ct_str
= { "SZ", "A" } };
1634 static const TCGTargetOpDef rZ_rJ
= { .args_ct_str
= { "rZ", "rJ" } };
1635 static const TCGTargetOpDef RZ_RJ
= { .args_ct_str
= { "RZ", "RJ" } };
1636 static const TCGTargetOpDef R_R_R
= { .args_ct_str
= { "R", "R", "R" } };
1637 static const TCGTargetOpDef r_rZ_rJ
1638 = { .args_ct_str
= { "r", "rZ", "rJ" } };
1639 static const TCGTargetOpDef R_RZ_RJ
1640 = { .args_ct_str
= { "R", "RZ", "RJ" } };
1641 static const TCGTargetOpDef r_r_rZ_rJ
1642 = { .args_ct_str
= { "r", "r", "rZ", "rJ" } };
1643 static const TCGTargetOpDef movc_32
1644 = { .args_ct_str
= { "r", "rZ", "rJ", "rI", "0" } };
1645 static const TCGTargetOpDef movc_64
1646 = { .args_ct_str
= { "R", "RZ", "RJ", "RI", "0" } };
1647 static const TCGTargetOpDef add2_32
1648 = { .args_ct_str
= { "r", "r", "rZ", "rZ", "rJ", "rJ" } };
1649 static const TCGTargetOpDef add2_64
1650 = { .args_ct_str
= { "R", "R", "RZ", "RZ", "RJ", "RI" } };
1653 case INDEX_op_goto_ptr
:
1656 case INDEX_op_ld8u_i32
:
1657 case INDEX_op_ld8s_i32
:
1658 case INDEX_op_ld16u_i32
:
1659 case INDEX_op_ld16s_i32
:
1660 case INDEX_op_ld_i32
:
1661 case INDEX_op_neg_i32
:
1662 case INDEX_op_not_i32
:
1665 case INDEX_op_st8_i32
:
1666 case INDEX_op_st16_i32
:
1667 case INDEX_op_st_i32
:
1670 case INDEX_op_add_i32
:
1671 case INDEX_op_mul_i32
:
1672 case INDEX_op_div_i32
:
1673 case INDEX_op_divu_i32
:
1674 case INDEX_op_sub_i32
:
1675 case INDEX_op_and_i32
:
1676 case INDEX_op_andc_i32
:
1677 case INDEX_op_or_i32
:
1678 case INDEX_op_orc_i32
:
1679 case INDEX_op_xor_i32
:
1680 case INDEX_op_shl_i32
:
1681 case INDEX_op_shr_i32
:
1682 case INDEX_op_sar_i32
:
1683 case INDEX_op_setcond_i32
:
1686 case INDEX_op_brcond_i32
:
1688 case INDEX_op_movcond_i32
:
1690 case INDEX_op_add2_i32
:
1691 case INDEX_op_sub2_i32
:
1693 case INDEX_op_mulu2_i32
:
1694 case INDEX_op_muls2_i32
:
1697 case INDEX_op_ld8u_i64
:
1698 case INDEX_op_ld8s_i64
:
1699 case INDEX_op_ld16u_i64
:
1700 case INDEX_op_ld16s_i64
:
1701 case INDEX_op_ld32u_i64
:
1702 case INDEX_op_ld32s_i64
:
1703 case INDEX_op_ld_i64
:
1704 case INDEX_op_ext_i32_i64
:
1705 case INDEX_op_extu_i32_i64
:
1708 case INDEX_op_st8_i64
:
1709 case INDEX_op_st16_i64
:
1710 case INDEX_op_st32_i64
:
1711 case INDEX_op_st_i64
:
1714 case INDEX_op_add_i64
:
1715 case INDEX_op_mul_i64
:
1716 case INDEX_op_div_i64
:
1717 case INDEX_op_divu_i64
:
1718 case INDEX_op_sub_i64
:
1719 case INDEX_op_and_i64
:
1720 case INDEX_op_andc_i64
:
1721 case INDEX_op_or_i64
:
1722 case INDEX_op_orc_i64
:
1723 case INDEX_op_xor_i64
:
1724 case INDEX_op_shl_i64
:
1725 case INDEX_op_shr_i64
:
1726 case INDEX_op_sar_i64
:
1727 case INDEX_op_setcond_i64
:
1730 case INDEX_op_neg_i64
:
1731 case INDEX_op_not_i64
:
1732 case INDEX_op_ext32s_i64
:
1733 case INDEX_op_ext32u_i64
:
1736 case INDEX_op_extrl_i64_i32
:
1737 case INDEX_op_extrh_i64_i32
:
1740 case INDEX_op_brcond_i64
:
1742 case INDEX_op_movcond_i64
:
1744 case INDEX_op_add2_i64
:
1745 case INDEX_op_sub2_i64
:
1747 case INDEX_op_muluh_i64
:
1750 case INDEX_op_qemu_ld_i32
:
1752 case INDEX_op_qemu_ld_i64
:
1754 case INDEX_op_qemu_st_i32
:
1756 case INDEX_op_qemu_st_i64
:
1764 static void tcg_target_init(TCGContext
*s
)
1766 /* Only probe for the platform and capabilities if we havn't already
1767 determined maximum values at compile time. */
1768 #ifndef use_vis3_instructions
1770 unsigned long hwcap
= qemu_getauxval(AT_HWCAP
);
1771 use_vis3_instructions
= (hwcap
& HWCAP_SPARC_VIS3
) != 0;
1775 tcg_target_available_regs
[TCG_TYPE_I32
] = 0xffffffff;
1776 tcg_target_available_regs
[TCG_TYPE_I64
] = ALL_64
;
1778 tcg_target_call_clobber_regs
= 0;
1779 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G1
);
1780 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G2
);
1781 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G3
);
1782 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G4
);
1783 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G5
);
1784 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G6
);
1785 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_G7
);
1786 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O0
);
1787 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O1
);
1788 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O2
);
1789 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O3
);
1790 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O4
);
1791 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O5
);
1792 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O6
);
1793 tcg_regset_set_reg(tcg_target_call_clobber_regs
, TCG_REG_O7
);
1795 s
->reserved_regs
= 0;
1796 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_G0
); /* zero */
1797 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_G6
); /* reserved for os */
1798 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_G7
); /* thread pointer */
1799 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_I6
); /* frame pointer */
1800 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_I7
); /* return address */
1801 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_O6
); /* stack pointer */
1802 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_T1
); /* for internal use */
1803 tcg_regset_set_reg(s
->reserved_regs
, TCG_REG_T2
); /* for internal use */
1807 # define ELF_HOST_MACHINE EM_SPARCV9
1809 # define ELF_HOST_MACHINE EM_SPARC32PLUS
1810 # define ELF_HOST_FLAGS EF_SPARC_32PLUS
1815 uint8_t fde_def_cfa
[SPARC64
? 4 : 2];
1816 uint8_t fde_win_save
;
1817 uint8_t fde_ret_save
[3];
1820 static const DebugFrame debug_frame
= {
1821 .h
.cie
.len
= sizeof(DebugFrameCIE
)-4, /* length after .len member */
1824 .h
.cie
.code_align
= 1,
1825 .h
.cie
.data_align
= -sizeof(void *) & 0x7f,
1826 .h
.cie
.return_column
= 15, /* o7 */
1828 /* Total FDE size does not include the "len" member. */
1829 .h
.fde
.len
= sizeof(DebugFrame
) - offsetof(DebugFrame
, h
.fde
.cie_offset
),
1833 12, 30, /* DW_CFA_def_cfa i6, 2047 */
1834 (2047 & 0x7f) | 0x80, (2047 >> 7)
1836 13, 30 /* DW_CFA_def_cfa_register i6 */
1839 .fde_win_save
= 0x2d, /* DW_CFA_GNU_window_save */
1840 .fde_ret_save
= { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
1843 void tcg_register_jit(void *buf
, size_t buf_size
)
1845 tcg_register_jit_int(buf
, buf_size
, &debug_frame
, sizeof(debug_frame
));
1848 void tb_target_set_jmp_target(uintptr_t tc_ptr
, uintptr_t jmp_addr
,
1851 intptr_t tb_disp
= addr
- tc_ptr
;
1852 intptr_t br_disp
= addr
- jmp_addr
;
1853 tcg_insn_unit i1
, i2
;
1855 /* We can reach the entire address space for ILP32.
1856 For LP64, the code_gen_buffer can't be larger than 2GB. */
1857 tcg_debug_assert(tb_disp
== (int32_t)tb_disp
);
1858 tcg_debug_assert(br_disp
== (int32_t)br_disp
);
1861 atomic_set((uint32_t *)jmp_addr
, deposit32(CALL
, 0, 30, br_disp
>> 2));
1862 flush_icache_range(jmp_addr
, jmp_addr
+ 4);
1866 /* This does not exercise the range of the branch, but we do
1867 still need to be able to load the new value of TCG_REG_TB.
1868 But this does still happen quite often. */
1869 if (check_fit_ptr(tb_disp
, 13)) {
1870 /* ba,pt %icc, addr */
1871 i1
= (INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A
)
1872 | BPCC_ICC
| BPCC_PT
| INSN_OFF19(br_disp
));
1873 i2
= (ARITH_ADD
| INSN_RD(TCG_REG_TB
) | INSN_RS1(TCG_REG_TB
)
1874 | INSN_IMM13(tb_disp
));
1875 } else if (tb_disp
>= 0) {
1876 i1
= SETHI
| INSN_RD(TCG_REG_T1
) | ((tb_disp
& 0xfffffc00) >> 10);
1877 i2
= (ARITH_OR
| INSN_RD(TCG_REG_T1
) | INSN_RS1(TCG_REG_T1
)
1878 | INSN_IMM13(tb_disp
& 0x3ff));
1880 i1
= SETHI
| INSN_RD(TCG_REG_T1
) | ((~tb_disp
& 0xfffffc00) >> 10);
1881 i2
= (ARITH_XOR
| INSN_RD(TCG_REG_T1
) | INSN_RS1(TCG_REG_T1
)
1882 | INSN_IMM13((tb_disp
& 0x3ff) | -0x400));
1885 atomic_set((uint64_t *)jmp_addr
, deposit64(i2
, 32, 32, i1
));
1886 flush_icache_range(jmp_addr
, jmp_addr
+ 8);