travis: define all the build matrix entries in one place
[qemu/ar7.git] / tcg / sparc / tcg-target.inc.c
blob55144c437c5baf778cf92cbbbe33223c85b53d57
1 /*
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
22 * THE SOFTWARE.
25 #include "tcg-pool.inc.c"
27 #ifdef CONFIG_DEBUG_TCG
28 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
29 "%g0",
30 "%g1",
31 "%g2",
32 "%g3",
33 "%g4",
34 "%g5",
35 "%g6",
36 "%g7",
37 "%o0",
38 "%o1",
39 "%o2",
40 "%o3",
41 "%o4",
42 "%o5",
43 "%o6",
44 "%o7",
45 "%l0",
46 "%l1",
47 "%l2",
48 "%l3",
49 "%l4",
50 "%l5",
51 "%l6",
52 "%l7",
53 "%i0",
54 "%i1",
55 "%i2",
56 "%i3",
57 "%i4",
58 "%i5",
59 "%i6",
60 "%i7",
62 #endif
64 #ifdef __arch64__
65 # define SPARC64 1
66 #else
67 # define SPARC64 0
68 #endif
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. */
76 #if SPARC64
77 # define ALL_64 0xffffffffu
78 #else
79 # define ALL_64 0xffffu
80 #endif
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
88 #endif
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[] = {
94 TCG_REG_L0,
95 TCG_REG_L1,
96 TCG_REG_L2,
97 TCG_REG_L3,
98 TCG_REG_L4,
99 TCG_REG_L5,
100 TCG_REG_L6,
101 TCG_REG_L7,
103 TCG_REG_I0,
104 TCG_REG_I1,
105 TCG_REG_I2,
106 TCG_REG_I3,
107 TCG_REG_I4,
108 TCG_REG_I5,
110 TCG_REG_G2,
111 TCG_REG_G3,
112 TCG_REG_G4,
113 TCG_REG_G5,
115 TCG_REG_O0,
116 TCG_REG_O1,
117 TCG_REG_O2,
118 TCG_REG_O3,
119 TCG_REG_O4,
120 TCG_REG_O5,
123 static const int tcg_target_call_iarg_regs[6] = {
124 TCG_REG_O0,
125 TCG_REG_O1,
126 TCG_REG_O2,
127 TCG_REG_O3,
128 TCG_REG_O4,
129 TCG_REG_O5,
132 static const int tcg_target_call_oarg_regs[] = {
133 TCG_REG_O0,
134 TCG_REG_O1,
135 TCG_REG_O2,
136 TCG_REG_O3,
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)
155 #define COND_N 0x0
156 #define COND_E 0x1
157 #define COND_LE 0x2
158 #define COND_L 0x3
159 #define COND_LEU 0x4
160 #define COND_CS 0x5
161 #define COND_NEG 0x6
162 #define COND_VS 0x7
163 #define COND_A 0x8
164 #define COND_NE 0x9
165 #define COND_G 0xa
166 #define COND_GE 0xb
167 #define COND_GU 0xc
168 #define COND_CC 0xd
169 #define COND_POS 0xe
170 #define COND_VC 0xf
171 #define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
173 #define RCOND_Z 1
174 #define RCOND_LEZ 2
175 #define RCOND_LZ 3
176 #define RCOND_NZ 5
177 #define RCOND_GZ 6
178 #define RCOND_GEZ 7
180 #define MOVCC_ICC (1 << 18)
181 #define MOVCC_XCC (1 << 18 | 1 << 12)
183 #define BPCC_ICC 0
184 #define BPCC_XCC (2 << 20)
185 #define BPCC_PT (1 << 19)
186 #define BPCC_PN 0
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
261 #endif
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;
275 #endif
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
288 #if SPARC64
289 # define check_fit_ptr check_fit_i64
290 #else
291 # define check_fit_ptr check_fit_i32
292 #endif
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;
298 intptr_t pcrel;
300 value += addend;
301 pcrel = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
303 switch (type) {
304 case R_SPARC_WDISP16:
305 assert(check_fit_ptr(pcrel >> 2, 16));
306 insn &= ~INSN_OFF16(-1);
307 insn |= INSN_OFF16(pcrel);
308 break;
309 case R_SPARC_WDISP19:
310 assert(check_fit_ptr(pcrel >> 2, 19));
311 insn &= ~INSN_OFF19(-1);
312 insn |= INSN_OFF19(pcrel);
313 break;
314 default:
315 g_assert_not_reached();
318 *code_ptr = insn;
319 return true;
322 /* parse target specific constraints */
323 static const char *target_parse_constraint(TCGArgConstraint *ct,
324 const char *ct_str, TCGType type)
326 switch (*ct_str++) {
327 case 'r':
328 ct->ct |= TCG_CT_REG;
329 ct->u.regs = 0xffffffff;
330 break;
331 case 'R':
332 ct->ct |= TCG_CT_REG;
333 ct->u.regs = ALL_64;
334 break;
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;
338 reserve_helpers:
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);
342 break;
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;
349 ct->u.regs = ALL_64;
350 goto reserve_helpers;
351 case 'I':
352 ct->ct |= TCG_CT_CONST_S11;
353 break;
354 case 'J':
355 ct->ct |= TCG_CT_CONST_S13;
356 break;
357 case 'Z':
358 ct->ct |= TCG_CT_CONST_ZERO;
359 break;
360 default:
361 return NULL;
363 return ct_str;
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)
370 int ct = arg_ct->ct;
372 if (ct & TCG_CT_CONST) {
373 return 1;
376 if (type == TCG_TYPE_I32) {
377 val = (int32_t)val;
380 if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
381 return 1;
382 } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
383 return 1;
384 } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
385 return 1;
386 } else {
387 return 0;
391 static inline void tcg_out_arith(TCGContext *s, TCGReg rd, TCGReg rs1,
392 TCGReg rs2, int op)
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)
413 if (ret != 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) {
436 arg = lo;
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);
442 return;
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);
450 return;
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);
457 if (arg & 0x3ff) {
458 tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
460 return;
463 /* A 32-bit constant sign-extended to 64-bits. */
464 if (arg == lo) {
465 tcg_out_sethi(s, ret, ~arg);
466 tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
467 return;
470 /* A 21-bit constant, shifted. */
471 lsb = ctz64(arg);
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);
476 return;
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);
480 return;
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);
489 } else {
490 hi = arg >> 32;
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,
505 TCGReg a2, int op)
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) |
515 INSN_IMM13(offset));
516 } else {
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)
537 if (val == 0) {
538 tcg_out_st(s, type, TCG_REG_G0, base, ofs);
539 return true;
541 return false;
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);
549 return;
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. */
569 if (uns) {
570 tcg_out_sety(s, TCG_REG_G0);
571 } else {
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)
582 tcg_out32(s, NOP);
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)
614 int off19 = 0;
616 if (l->has_value) {
617 off19 = INSN_OFF19(tcg_pcrel_diff(s, l->u.value_ptr));
618 } else {
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);
634 tcg_out_nop(s);
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)) {
658 int off16 = 0;
660 if (l->has_value) {
661 off16 = INSN_OFF16(tcg_pcrel_diff(s, l->u.value_ptr));
662 } else {
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);
667 } else {
668 tcg_out_cmp(s, arg1, arg2, const_arg2);
669 tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
671 tcg_out_nop(s);
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
688 for that as well. */
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);
692 } else {
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. */
702 switch (cond) {
703 case TCG_COND_LTU:
704 case TCG_COND_GEU:
705 /* The result of the comparison is in the carry bit. */
706 break;
708 case TCG_COND_EQ:
709 case TCG_COND_NE:
710 /* For equality, we can transform to inequality vs zero. */
711 if (c2 != 0) {
712 tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_XOR);
713 c2 = TCG_REG_T1;
714 } else {
715 c2 = c1;
717 c1 = TCG_REG_G0, c2const = 0;
718 cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
719 break;
721 case TCG_COND_GTU:
722 case TCG_COND_LEU:
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) {
727 TCGReg t = c1;
728 c1 = c2;
729 c2 = t;
730 c2const = 0;
731 cond = tcg_swap_cond(cond);
732 break;
734 /* FALLTHRU */
736 default:
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);
740 return;
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);
746 } else {
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) {
755 switch (cond) {
756 case TCG_COND_NE:
757 if (c2 != 0) {
758 break;
760 c2 = c1, c2const = 0, c1 = TCG_REG_G0;
761 /* FALLTHRU */
762 case TCG_COND_LTU:
763 tcg_out_cmp(s, c1, c2, c2const);
764 tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC);
765 return;
766 default:
767 break;
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);
776 } else {
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)) {
791 tmp = rl;
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)) {
807 tmp = rl;
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);
816 bh = TCG_REG_T2;
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. */
822 if (rh == ah) {
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);
826 } else {
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);
830 } else {
831 /* Otherwise adjust BH as if there is carry into T2 ... */
832 if (bhconst) {
833 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh + (is_sub ? -1 : 1));
834 } else {
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,
848 bool in_prologue)
850 ptrdiff_t disp = tcg_pcrel_diff(s, dest);
852 if (disp == (int32_t)disp) {
853 tcg_out32(s, CALL | (uint32_t)disp >> 2);
854 } else {
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);
865 tcg_out_nop(s);
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) {
884 case MO_8:
885 tcg_out_arithi(s, r, r, 0xff, ARITH_AND);
886 break;
887 case MO_16:
888 tcg_out_arithi(s, r, r, 16, SHIFT_SLL);
889 tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
890 break;
891 case MO_32:
892 if (SPARC64) {
893 tcg_out_arith(s, r, r, 0, SHIFT_SRL);
895 break;
896 case MO_64:
897 break;
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,
925 int i;
926 TCGReg ra;
928 for (i = 0; i < 16; ++i) {
929 if (qemu_ld_helpers[i] == NULL) {
930 continue;
933 /* May as well align the trampoline. */
934 while ((uintptr_t)s->code_ptr & 15) {
935 tcg_out_nop(s);
937 qemu_ld_trampoline[i] = s->code_ptr;
939 if (SPARC64 || TARGET_LONG_BITS == 32) {
940 ra = TCG_REG_O3;
941 } else {
942 /* Install the high part of the address. */
943 tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
944 ra = TCG_REG_O4;
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);
951 /* Tail call. */
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) {
958 continue;
961 /* May as well align the trampoline. */
962 while ((uintptr_t)s->code_ptr & 15) {
963 tcg_out_nop(s);
965 qemu_st_trampoline[i] = s->code_ptr;
967 if (SPARC64) {
968 emit_extend(s, TCG_REG_O2, i);
969 ra = TCG_REG_O4;
970 } else {
971 ra = TCG_REG_O1;
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);
975 ra += 2;
976 } else {
977 ra += 1;
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);
982 ra += 2;
983 } else {
984 emit_extend(s, ra, i);
985 ra += 1;
987 /* Skip the oi argument. */
988 ra += 1;
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);
995 ra = TCG_REG_G1;
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);
1000 /* Tail call. */
1001 tcg_out_call_nodelay(s, qemu_st_helpers[i], true);
1002 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
1005 #endif
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,
1016 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);
1032 #endif
1034 /* We choose TCG_REG_TB such that no move is required. */
1035 if (USE_REG_TB) {
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);
1041 /* delay slot */
1042 tcg_out_nop(s);
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);
1047 /* delay slot */
1048 tcg_out_movi_imm13(s, TCG_REG_O0, 0);
1050 #ifdef CONFIG_SOFTMMU
1051 build_trampolines(s);
1052 #endif
1055 static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1057 int i;
1058 for (i = 0; i < count; ++i) {
1059 p[i] = NOP;
1063 #if defined(CONFIG_SOFTMMU)
1064 /* Perform the TLB load and compare.
1066 Inputs:
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 static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
1078 TCGMemOp opc, int which)
1080 const TCGReg r0 = TCG_REG_O0;
1081 const TCGReg r1 = TCG_REG_O1;
1082 const TCGReg r2 = TCG_REG_O2;
1083 unsigned s_bits = opc & MO_SIZE;
1084 unsigned a_bits = get_alignment_bits(opc);
1085 int tlb_ofs;
1087 /* Shift the page number down. */
1088 tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);
1090 /* Mask out the page offset, except for the required alignment.
1091 We don't support unaligned accesses. */
1092 if (a_bits < s_bits) {
1093 a_bits = s_bits;
1095 tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
1096 TARGET_PAGE_MASK | ((1 << a_bits) - 1));
1098 /* Mask the tlb index. */
1099 tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
1101 /* Mask page, part 2. */
1102 tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
1104 /* Shift the tlb index into place. */
1105 tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
1107 /* Relative to the current ENV. */
1108 tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
1110 /* Find a base address that can load both tlb comparator and addend. */
1111 tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
1112 if (!check_fit_ptr(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
1113 if (tlb_ofs & ~0x3ff) {
1114 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, tlb_ofs & ~0x3ff);
1115 tcg_out_arith(s, r1, r1, TCG_REG_T1, ARITH_ADD);
1117 tlb_ofs &= 0x3ff;
1120 /* Load the tlb comparator and the addend. */
1121 tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
1122 tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
1124 /* subcc arg0, arg2, %g0 */
1125 tcg_out_cmp(s, r0, r2, 0);
1127 /* If the guest address must be zero-extended, do so now. */
1128 if (SPARC64 && TARGET_LONG_BITS == 32) {
1129 tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
1130 return r0;
1132 return addr;
1134 #endif /* CONFIG_SOFTMMU */
1136 static const int qemu_ld_opc[16] = {
1137 [MO_UB] = LDUB,
1138 [MO_SB] = LDSB,
1140 [MO_BEUW] = LDUH,
1141 [MO_BESW] = LDSH,
1142 [MO_BEUL] = LDUW,
1143 [MO_BESL] = LDSW,
1144 [MO_BEQ] = LDX,
1146 [MO_LEUW] = LDUH_LE,
1147 [MO_LESW] = LDSH_LE,
1148 [MO_LEUL] = LDUW_LE,
1149 [MO_LESL] = LDSW_LE,
1150 [MO_LEQ] = LDX_LE,
1153 static const int qemu_st_opc[16] = {
1154 [MO_UB] = STB,
1156 [MO_BEUW] = STH,
1157 [MO_BEUL] = STW,
1158 [MO_BEQ] = STX,
1160 [MO_LEUW] = STH_LE,
1161 [MO_LEUL] = STW_LE,
1162 [MO_LEQ] = STX_LE,
1165 static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
1166 TCGMemOpIdx oi, bool is_64)
1168 TCGMemOp memop = get_memop(oi);
1169 #ifdef CONFIG_SOFTMMU
1170 unsigned memi = get_mmuidx(oi);
1171 TCGReg addrz, param;
1172 tcg_insn_unit *func;
1173 tcg_insn_unit *label_ptr;
1175 addrz = tcg_out_tlb_load(s, addr, memi, memop,
1176 offsetof(CPUTLBEntry, addr_read));
1178 /* The fast path is exactly one insn. Thus we can perform the
1179 entire TLB Hit in the (annulled) delay slot of the branch
1180 over the TLB Miss case. */
1182 /* beq,a,pt %[xi]cc, label0 */
1183 label_ptr = s->code_ptr;
1184 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1185 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1186 /* delay slot */
1187 tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1188 qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
1190 /* TLB Miss. */
1192 param = TCG_REG_O1;
1193 if (!SPARC64 && TARGET_LONG_BITS == 64) {
1194 /* Skip the high-part; we'll perform the extract in the trampoline. */
1195 param++;
1197 tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
1199 /* We use the helpers to extend SB and SW data, leaving the case
1200 of SL needing explicit extending below. */
1201 if ((memop & MO_SSIZE) == MO_SL) {
1202 func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SIZE)];
1203 } else {
1204 func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SSIZE)];
1206 tcg_debug_assert(func != NULL);
1207 tcg_out_call_nodelay(s, func, false);
1208 /* delay slot */
1209 tcg_out_movi(s, TCG_TYPE_I32, param, oi);
1211 /* Recall that all of the helpers return 64-bit results.
1212 Which complicates things for sparcv8plus. */
1213 if (SPARC64) {
1214 /* We let the helper sign-extend SB and SW, but leave SL for here. */
1215 if (is_64 && (memop & MO_SSIZE) == MO_SL) {
1216 tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
1217 } else {
1218 tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
1220 } else {
1221 if ((memop & MO_SIZE) == MO_64) {
1222 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
1223 tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
1224 tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
1225 } else if (is_64) {
1226 /* Re-extend from 32-bit rather than reassembling when we
1227 know the high register must be an extension. */
1228 tcg_out_arithi(s, data, TCG_REG_O1, 0,
1229 memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
1230 } else {
1231 tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
1235 *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1236 #else
1237 if (SPARC64 && TARGET_LONG_BITS == 32) {
1238 tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1239 addr = TCG_REG_T1;
1241 tcg_out_ldst_rr(s, data, addr,
1242 (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1243 qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
1244 #endif /* CONFIG_SOFTMMU */
1247 static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
1248 TCGMemOpIdx oi)
1250 TCGMemOp memop = get_memop(oi);
1251 #ifdef CONFIG_SOFTMMU
1252 unsigned memi = get_mmuidx(oi);
1253 TCGReg addrz, param;
1254 tcg_insn_unit *func;
1255 tcg_insn_unit *label_ptr;
1257 addrz = tcg_out_tlb_load(s, addr, memi, memop,
1258 offsetof(CPUTLBEntry, addr_write));
1260 /* The fast path is exactly one insn. Thus we can perform the entire
1261 TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
1262 /* beq,a,pt %[xi]cc, label0 */
1263 label_ptr = s->code_ptr;
1264 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1265 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1266 /* delay slot */
1267 tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1268 qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
1270 /* TLB Miss. */
1272 param = TCG_REG_O1;
1273 if (!SPARC64 && TARGET_LONG_BITS == 64) {
1274 /* Skip the high-part; we'll perform the extract in the trampoline. */
1275 param++;
1277 tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
1278 if (!SPARC64 && (memop & MO_SIZE) == MO_64) {
1279 /* Skip the high-part; we'll perform the extract in the trampoline. */
1280 param++;
1282 tcg_out_mov(s, TCG_TYPE_REG, param++, data);
1284 func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
1285 tcg_debug_assert(func != NULL);
1286 tcg_out_call_nodelay(s, func, false);
1287 /* delay slot */
1288 tcg_out_movi(s, TCG_TYPE_I32, param, oi);
1290 *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1291 #else
1292 if (SPARC64 && TARGET_LONG_BITS == 32) {
1293 tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1294 addr = TCG_REG_T1;
1296 tcg_out_ldst_rr(s, data, addr,
1297 (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1298 qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
1299 #endif /* CONFIG_SOFTMMU */
1302 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1303 const TCGArg args[TCG_MAX_OP_ARGS],
1304 const int const_args[TCG_MAX_OP_ARGS])
1306 TCGArg a0, a1, a2;
1307 int c, c2;
1309 /* Hoist the loads of the most common arguments. */
1310 a0 = args[0];
1311 a1 = args[1];
1312 a2 = args[2];
1313 c2 = const_args[2];
1315 switch (opc) {
1316 case INDEX_op_exit_tb:
1317 if (check_fit_ptr(a0, 13)) {
1318 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1319 tcg_out_movi_imm13(s, TCG_REG_O0, a0);
1320 break;
1321 } else if (USE_REG_TB) {
1322 intptr_t tb_diff = a0 - (uintptr_t)s->code_gen_ptr;
1323 if (check_fit_ptr(tb_diff, 13)) {
1324 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1325 /* Note that TCG_REG_TB has been unwound to O1. */
1326 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O1, tb_diff, ARITH_ADD);
1327 break;
1330 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, a0 & ~0x3ff);
1331 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1332 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, a0 & 0x3ff, ARITH_OR);
1333 break;
1334 case INDEX_op_goto_tb:
1335 if (s->tb_jmp_insn_offset) {
1336 /* direct jump method */
1337 if (USE_REG_TB) {
1338 /* make sure the patch is 8-byte aligned. */
1339 if ((intptr_t)s->code_ptr & 4) {
1340 tcg_out_nop(s);
1342 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1343 tcg_out_sethi(s, TCG_REG_T1, 0);
1344 tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
1345 tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
1346 tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
1347 } else {
1348 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1349 tcg_out32(s, CALL);
1350 tcg_out_nop(s);
1352 } else {
1353 /* indirect jump method */
1354 tcg_out_ld_ptr(s, TCG_REG_TB,
1355 (uintptr_t)(s->tb_jmp_target_addr + a0));
1356 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
1357 tcg_out_nop(s);
1359 set_jmp_reset_offset(s, a0);
1361 /* For the unlinked path of goto_tb, we need to reset
1362 TCG_REG_TB to the beginning of this TB. */
1363 if (USE_REG_TB) {
1364 c = -tcg_current_code_size(s);
1365 if (check_fit_i32(c, 13)) {
1366 tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, c, ARITH_ADD);
1367 } else {
1368 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, c);
1369 tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB,
1370 TCG_REG_T1, ARITH_ADD);
1373 break;
1374 case INDEX_op_goto_ptr:
1375 tcg_out_arithi(s, TCG_REG_G0, a0, 0, JMPL);
1376 if (USE_REG_TB) {
1377 tcg_out_arith(s, TCG_REG_TB, a0, TCG_REG_G0, ARITH_OR);
1378 } else {
1379 tcg_out_nop(s);
1381 break;
1382 case INDEX_op_br:
1383 tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(a0));
1384 tcg_out_nop(s);
1385 break;
1387 #define OP_32_64(x) \
1388 glue(glue(case INDEX_op_, x), _i32): \
1389 glue(glue(case INDEX_op_, x), _i64)
1391 OP_32_64(ld8u):
1392 tcg_out_ldst(s, a0, a1, a2, LDUB);
1393 break;
1394 OP_32_64(ld8s):
1395 tcg_out_ldst(s, a0, a1, a2, LDSB);
1396 break;
1397 OP_32_64(ld16u):
1398 tcg_out_ldst(s, a0, a1, a2, LDUH);
1399 break;
1400 OP_32_64(ld16s):
1401 tcg_out_ldst(s, a0, a1, a2, LDSH);
1402 break;
1403 case INDEX_op_ld_i32:
1404 case INDEX_op_ld32u_i64:
1405 tcg_out_ldst(s, a0, a1, a2, LDUW);
1406 break;
1407 OP_32_64(st8):
1408 tcg_out_ldst(s, a0, a1, a2, STB);
1409 break;
1410 OP_32_64(st16):
1411 tcg_out_ldst(s, a0, a1, a2, STH);
1412 break;
1413 case INDEX_op_st_i32:
1414 case INDEX_op_st32_i64:
1415 tcg_out_ldst(s, a0, a1, a2, STW);
1416 break;
1417 OP_32_64(add):
1418 c = ARITH_ADD;
1419 goto gen_arith;
1420 OP_32_64(sub):
1421 c = ARITH_SUB;
1422 goto gen_arith;
1423 OP_32_64(and):
1424 c = ARITH_AND;
1425 goto gen_arith;
1426 OP_32_64(andc):
1427 c = ARITH_ANDN;
1428 goto gen_arith;
1429 OP_32_64(or):
1430 c = ARITH_OR;
1431 goto gen_arith;
1432 OP_32_64(orc):
1433 c = ARITH_ORN;
1434 goto gen_arith;
1435 OP_32_64(xor):
1436 c = ARITH_XOR;
1437 goto gen_arith;
1438 case INDEX_op_shl_i32:
1439 c = SHIFT_SLL;
1440 do_shift32:
1441 /* Limit immediate shift count lest we create an illegal insn. */
1442 tcg_out_arithc(s, a0, a1, a2 & 31, c2, c);
1443 break;
1444 case INDEX_op_shr_i32:
1445 c = SHIFT_SRL;
1446 goto do_shift32;
1447 case INDEX_op_sar_i32:
1448 c = SHIFT_SRA;
1449 goto do_shift32;
1450 case INDEX_op_mul_i32:
1451 c = ARITH_UMUL;
1452 goto gen_arith;
1454 OP_32_64(neg):
1455 c = ARITH_SUB;
1456 goto gen_arith1;
1457 OP_32_64(not):
1458 c = ARITH_ORN;
1459 goto gen_arith1;
1461 case INDEX_op_div_i32:
1462 tcg_out_div32(s, a0, a1, a2, c2, 0);
1463 break;
1464 case INDEX_op_divu_i32:
1465 tcg_out_div32(s, a0, a1, a2, c2, 1);
1466 break;
1468 case INDEX_op_brcond_i32:
1469 tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(args[3]));
1470 break;
1471 case INDEX_op_setcond_i32:
1472 tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
1473 break;
1474 case INDEX_op_movcond_i32:
1475 tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1476 break;
1478 case INDEX_op_add2_i32:
1479 tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1480 args[4], const_args[4], args[5], const_args[5],
1481 ARITH_ADDCC, ARITH_ADDC);
1482 break;
1483 case INDEX_op_sub2_i32:
1484 tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1485 args[4], const_args[4], args[5], const_args[5],
1486 ARITH_SUBCC, ARITH_SUBC);
1487 break;
1488 case INDEX_op_mulu2_i32:
1489 c = ARITH_UMUL;
1490 goto do_mul2;
1491 case INDEX_op_muls2_i32:
1492 c = ARITH_SMUL;
1493 do_mul2:
1494 /* The 32-bit multiply insns produce a full 64-bit result. If the
1495 destination register can hold it, we can avoid the slower RDY. */
1496 tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
1497 if (SPARC64 || a0 <= TCG_REG_O7) {
1498 tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
1499 } else {
1500 tcg_out_rdy(s, a1);
1502 break;
1504 case INDEX_op_qemu_ld_i32:
1505 tcg_out_qemu_ld(s, a0, a1, a2, false);
1506 break;
1507 case INDEX_op_qemu_ld_i64:
1508 tcg_out_qemu_ld(s, a0, a1, a2, true);
1509 break;
1510 case INDEX_op_qemu_st_i32:
1511 case INDEX_op_qemu_st_i64:
1512 tcg_out_qemu_st(s, a0, a1, a2);
1513 break;
1515 case INDEX_op_ld32s_i64:
1516 tcg_out_ldst(s, a0, a1, a2, LDSW);
1517 break;
1518 case INDEX_op_ld_i64:
1519 tcg_out_ldst(s, a0, a1, a2, LDX);
1520 break;
1521 case INDEX_op_st_i64:
1522 tcg_out_ldst(s, a0, a1, a2, STX);
1523 break;
1524 case INDEX_op_shl_i64:
1525 c = SHIFT_SLLX;
1526 do_shift64:
1527 /* Limit immediate shift count lest we create an illegal insn. */
1528 tcg_out_arithc(s, a0, a1, a2 & 63, c2, c);
1529 break;
1530 case INDEX_op_shr_i64:
1531 c = SHIFT_SRLX;
1532 goto do_shift64;
1533 case INDEX_op_sar_i64:
1534 c = SHIFT_SRAX;
1535 goto do_shift64;
1536 case INDEX_op_mul_i64:
1537 c = ARITH_MULX;
1538 goto gen_arith;
1539 case INDEX_op_div_i64:
1540 c = ARITH_SDIVX;
1541 goto gen_arith;
1542 case INDEX_op_divu_i64:
1543 c = ARITH_UDIVX;
1544 goto gen_arith;
1545 case INDEX_op_ext_i32_i64:
1546 case INDEX_op_ext32s_i64:
1547 tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
1548 break;
1549 case INDEX_op_extu_i32_i64:
1550 case INDEX_op_ext32u_i64:
1551 tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
1552 break;
1553 case INDEX_op_extrl_i64_i32:
1554 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1555 break;
1556 case INDEX_op_extrh_i64_i32:
1557 tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX);
1558 break;
1560 case INDEX_op_brcond_i64:
1561 tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
1562 break;
1563 case INDEX_op_setcond_i64:
1564 tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
1565 break;
1566 case INDEX_op_movcond_i64:
1567 tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1568 break;
1569 case INDEX_op_add2_i64:
1570 tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1571 const_args[4], args[5], const_args[5], false);
1572 break;
1573 case INDEX_op_sub2_i64:
1574 tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1575 const_args[4], args[5], const_args[5], true);
1576 break;
1577 case INDEX_op_muluh_i64:
1578 tcg_out_arith(s, args[0], args[1], args[2], ARITH_UMULXHI);
1579 break;
1581 gen_arith:
1582 tcg_out_arithc(s, a0, a1, a2, c2, c);
1583 break;
1585 gen_arith1:
1586 tcg_out_arithc(s, a0, TCG_REG_G0, a1, const_args[1], c);
1587 break;
1589 case INDEX_op_mb:
1590 tcg_out_mb(s, a0);
1591 break;
1593 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
1594 case INDEX_op_mov_i64:
1595 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
1596 case INDEX_op_movi_i64:
1597 case INDEX_op_call: /* Always emitted via tcg_out_call. */
1598 default:
1599 tcg_abort();
1603 static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
1605 static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
1606 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
1607 static const TCGTargetOpDef R_r = { .args_ct_str = { "R", "r" } };
1608 static const TCGTargetOpDef r_R = { .args_ct_str = { "r", "R" } };
1609 static const TCGTargetOpDef R_R = { .args_ct_str = { "R", "R" } };
1610 static const TCGTargetOpDef r_A = { .args_ct_str = { "r", "A" } };
1611 static const TCGTargetOpDef R_A = { .args_ct_str = { "R", "A" } };
1612 static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
1613 static const TCGTargetOpDef RZ_r = { .args_ct_str = { "RZ", "r" } };
1614 static const TCGTargetOpDef sZ_A = { .args_ct_str = { "sZ", "A" } };
1615 static const TCGTargetOpDef SZ_A = { .args_ct_str = { "SZ", "A" } };
1616 static const TCGTargetOpDef rZ_rJ = { .args_ct_str = { "rZ", "rJ" } };
1617 static const TCGTargetOpDef RZ_RJ = { .args_ct_str = { "RZ", "RJ" } };
1618 static const TCGTargetOpDef R_R_R = { .args_ct_str = { "R", "R", "R" } };
1619 static const TCGTargetOpDef r_rZ_rJ
1620 = { .args_ct_str = { "r", "rZ", "rJ" } };
1621 static const TCGTargetOpDef R_RZ_RJ
1622 = { .args_ct_str = { "R", "RZ", "RJ" } };
1623 static const TCGTargetOpDef r_r_rZ_rJ
1624 = { .args_ct_str = { "r", "r", "rZ", "rJ" } };
1625 static const TCGTargetOpDef movc_32
1626 = { .args_ct_str = { "r", "rZ", "rJ", "rI", "0" } };
1627 static const TCGTargetOpDef movc_64
1628 = { .args_ct_str = { "R", "RZ", "RJ", "RI", "0" } };
1629 static const TCGTargetOpDef add2_32
1630 = { .args_ct_str = { "r", "r", "rZ", "rZ", "rJ", "rJ" } };
1631 static const TCGTargetOpDef add2_64
1632 = { .args_ct_str = { "R", "R", "RZ", "RZ", "RJ", "RI" } };
1634 switch (op) {
1635 case INDEX_op_goto_ptr:
1636 return &r;
1638 case INDEX_op_ld8u_i32:
1639 case INDEX_op_ld8s_i32:
1640 case INDEX_op_ld16u_i32:
1641 case INDEX_op_ld16s_i32:
1642 case INDEX_op_ld_i32:
1643 case INDEX_op_neg_i32:
1644 case INDEX_op_not_i32:
1645 return &r_r;
1647 case INDEX_op_st8_i32:
1648 case INDEX_op_st16_i32:
1649 case INDEX_op_st_i32:
1650 return &rZ_r;
1652 case INDEX_op_add_i32:
1653 case INDEX_op_mul_i32:
1654 case INDEX_op_div_i32:
1655 case INDEX_op_divu_i32:
1656 case INDEX_op_sub_i32:
1657 case INDEX_op_and_i32:
1658 case INDEX_op_andc_i32:
1659 case INDEX_op_or_i32:
1660 case INDEX_op_orc_i32:
1661 case INDEX_op_xor_i32:
1662 case INDEX_op_shl_i32:
1663 case INDEX_op_shr_i32:
1664 case INDEX_op_sar_i32:
1665 case INDEX_op_setcond_i32:
1666 return &r_rZ_rJ;
1668 case INDEX_op_brcond_i32:
1669 return &rZ_rJ;
1670 case INDEX_op_movcond_i32:
1671 return &movc_32;
1672 case INDEX_op_add2_i32:
1673 case INDEX_op_sub2_i32:
1674 return &add2_32;
1675 case INDEX_op_mulu2_i32:
1676 case INDEX_op_muls2_i32:
1677 return &r_r_rZ_rJ;
1679 case INDEX_op_ld8u_i64:
1680 case INDEX_op_ld8s_i64:
1681 case INDEX_op_ld16u_i64:
1682 case INDEX_op_ld16s_i64:
1683 case INDEX_op_ld32u_i64:
1684 case INDEX_op_ld32s_i64:
1685 case INDEX_op_ld_i64:
1686 case INDEX_op_ext_i32_i64:
1687 case INDEX_op_extu_i32_i64:
1688 return &R_r;
1690 case INDEX_op_st8_i64:
1691 case INDEX_op_st16_i64:
1692 case INDEX_op_st32_i64:
1693 case INDEX_op_st_i64:
1694 return &RZ_r;
1696 case INDEX_op_add_i64:
1697 case INDEX_op_mul_i64:
1698 case INDEX_op_div_i64:
1699 case INDEX_op_divu_i64:
1700 case INDEX_op_sub_i64:
1701 case INDEX_op_and_i64:
1702 case INDEX_op_andc_i64:
1703 case INDEX_op_or_i64:
1704 case INDEX_op_orc_i64:
1705 case INDEX_op_xor_i64:
1706 case INDEX_op_shl_i64:
1707 case INDEX_op_shr_i64:
1708 case INDEX_op_sar_i64:
1709 case INDEX_op_setcond_i64:
1710 return &R_RZ_RJ;
1712 case INDEX_op_neg_i64:
1713 case INDEX_op_not_i64:
1714 case INDEX_op_ext32s_i64:
1715 case INDEX_op_ext32u_i64:
1716 return &R_R;
1718 case INDEX_op_extrl_i64_i32:
1719 case INDEX_op_extrh_i64_i32:
1720 return &r_R;
1722 case INDEX_op_brcond_i64:
1723 return &RZ_RJ;
1724 case INDEX_op_movcond_i64:
1725 return &movc_64;
1726 case INDEX_op_add2_i64:
1727 case INDEX_op_sub2_i64:
1728 return &add2_64;
1729 case INDEX_op_muluh_i64:
1730 return &R_R_R;
1732 case INDEX_op_qemu_ld_i32:
1733 return &r_A;
1734 case INDEX_op_qemu_ld_i64:
1735 return &R_A;
1736 case INDEX_op_qemu_st_i32:
1737 return &sZ_A;
1738 case INDEX_op_qemu_st_i64:
1739 return &SZ_A;
1741 default:
1742 return NULL;
1746 static void tcg_target_init(TCGContext *s)
1748 /* Only probe for the platform and capabilities if we havn't already
1749 determined maximum values at compile time. */
1750 #ifndef use_vis3_instructions
1752 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
1753 use_vis3_instructions = (hwcap & HWCAP_SPARC_VIS3) != 0;
1755 #endif
1757 tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
1758 tcg_target_available_regs[TCG_TYPE_I64] = ALL_64;
1760 tcg_target_call_clobber_regs = 0;
1761 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);
1762 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G2);
1763 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G3);
1764 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G4);
1765 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G5);
1766 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G6);
1767 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G7);
1768 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O0);
1769 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O1);
1770 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O2);
1771 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O3);
1772 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O4);
1773 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O5);
1774 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O6);
1775 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O7);
1777 s->reserved_regs = 0;
1778 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
1779 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
1780 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
1781 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
1782 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
1783 tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
1784 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
1785 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
1788 #if SPARC64
1789 # define ELF_HOST_MACHINE EM_SPARCV9
1790 #else
1791 # define ELF_HOST_MACHINE EM_SPARC32PLUS
1792 # define ELF_HOST_FLAGS EF_SPARC_32PLUS
1793 #endif
1795 typedef struct {
1796 DebugFrameHeader h;
1797 uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
1798 uint8_t fde_win_save;
1799 uint8_t fde_ret_save[3];
1800 } DebugFrame;
1802 static const DebugFrame debug_frame = {
1803 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1804 .h.cie.id = -1,
1805 .h.cie.version = 1,
1806 .h.cie.code_align = 1,
1807 .h.cie.data_align = -sizeof(void *) & 0x7f,
1808 .h.cie.return_column = 15, /* o7 */
1810 /* Total FDE size does not include the "len" member. */
1811 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
1813 .fde_def_cfa = {
1814 #if SPARC64
1815 12, 30, /* DW_CFA_def_cfa i6, 2047 */
1816 (2047 & 0x7f) | 0x80, (2047 >> 7)
1817 #else
1818 13, 30 /* DW_CFA_def_cfa_register i6 */
1819 #endif
1821 .fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
1822 .fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
1825 void tcg_register_jit(void *buf, size_t buf_size)
1827 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1830 void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
1831 uintptr_t addr)
1833 intptr_t tb_disp = addr - tc_ptr;
1834 intptr_t br_disp = addr - jmp_addr;
1835 tcg_insn_unit i1, i2;
1837 /* We can reach the entire address space for ILP32.
1838 For LP64, the code_gen_buffer can't be larger than 2GB. */
1839 tcg_debug_assert(tb_disp == (int32_t)tb_disp);
1840 tcg_debug_assert(br_disp == (int32_t)br_disp);
1842 if (!USE_REG_TB) {
1843 atomic_set((uint32_t *)jmp_addr, deposit32(CALL, 0, 30, br_disp >> 2));
1844 flush_icache_range(jmp_addr, jmp_addr + 4);
1845 return;
1848 /* This does not exercise the range of the branch, but we do
1849 still need to be able to load the new value of TCG_REG_TB.
1850 But this does still happen quite often. */
1851 if (check_fit_ptr(tb_disp, 13)) {
1852 /* ba,pt %icc, addr */
1853 i1 = (INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
1854 | BPCC_ICC | BPCC_PT | INSN_OFF19(br_disp));
1855 i2 = (ARITH_ADD | INSN_RD(TCG_REG_TB) | INSN_RS1(TCG_REG_TB)
1856 | INSN_IMM13(tb_disp));
1857 } else if (tb_disp >= 0) {
1858 i1 = SETHI | INSN_RD(TCG_REG_T1) | ((tb_disp & 0xfffffc00) >> 10);
1859 i2 = (ARITH_OR | INSN_RD(TCG_REG_T1) | INSN_RS1(TCG_REG_T1)
1860 | INSN_IMM13(tb_disp & 0x3ff));
1861 } else {
1862 i1 = SETHI | INSN_RD(TCG_REG_T1) | ((~tb_disp & 0xfffffc00) >> 10);
1863 i2 = (ARITH_XOR | INSN_RD(TCG_REG_T1) | INSN_RS1(TCG_REG_T1)
1864 | INSN_IMM13((tb_disp & 0x3ff) | -0x400));
1867 atomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1));
1868 flush_icache_range(jmp_addr, jmp_addr + 8);