]> git.proxmox.com Git - mirror_qemu.git/blame - tcg/sparc/tcg-target.inc.c
target/sparc: Remove the constant pool
[mirror_qemu.git] / tcg / sparc / tcg-target.inc.c
CommitLineData
8289b279
BS
1/*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
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.
23 */
24
e9823b4c
RH
25#include "tcg-pool.inc.c"
26
8d8fdbae 27#ifdef CONFIG_DEBUG_TCG
8289b279
BS
28static 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",
61};
d4a9eb1f 62#endif
8289b279 63
9f44adc5
RH
64#ifdef __arch64__
65# define SPARC64 1
66#else
67# define SPARC64 0
68#endif
69
34b1a49c
RH
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
81
375816f8
RH
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
85
4cbea598 86#ifndef CONFIG_SOFTMMU
375816f8 87# define TCG_GUEST_BASE_REG TCG_REG_I5
c6f7e4fb 88#endif
e141ab52 89
ab20bdc1
RH
90#define TCG_REG_TB TCG_REG_I1
91#define USE_REG_TB (sizeof(void *) > 4)
92
0954d0d9 93static const int tcg_target_reg_alloc_order[] = {
8289b279
BS
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,
26adfb75 102
8289b279
BS
103 TCG_REG_I0,
104 TCG_REG_I1,
105 TCG_REG_I2,
106 TCG_REG_I3,
107 TCG_REG_I4,
375816f8 108 TCG_REG_I5,
26adfb75
RH
109
110 TCG_REG_G2,
111 TCG_REG_G3,
112 TCG_REG_G4,
113 TCG_REG_G5,
114
115 TCG_REG_O0,
116 TCG_REG_O1,
117 TCG_REG_O2,
118 TCG_REG_O3,
119 TCG_REG_O4,
120 TCG_REG_O5,
8289b279
BS
121};
122
123static 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,
130};
131
26a74ae3 132static const int tcg_target_call_oarg_regs[] = {
8289b279 133 TCG_REG_O0,
e141ab52
BS
134 TCG_REG_O1,
135 TCG_REG_O2,
136 TCG_REG_O3,
8289b279
BS
137};
138
8289b279
BS
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)
8384dd67 146#define INSN_ASI(x) ((x) << 5)
8289b279 147
203342d8 148#define INSN_IMM10(x) ((1 << 13) | ((x) & 0x3ff))
dbfe80e1 149#define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
8289b279 150#define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
ab1339b9 151#define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
1da92db2 152#define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
a115f3ea 153#define INSN_COND(x) ((x) << 25)
8289b279 154
cf7c2ca5
BS
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
b3db8758 163#define COND_A 0x8
cf7c2ca5
BS
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
a115f3ea 171#define BA (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
8289b279 172
ab1339b9
RH
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
179
dbfe80e1
RH
180#define MOVCC_ICC (1 << 18)
181#define MOVCC_XCC (1 << 18 | 1 << 12)
182
a115f3ea
RH
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)
188
ab1339b9
RH
189#define BPR_PT BPCC_PT
190
8289b279 191#define ARITH_ADD (INSN_OP(2) | INSN_OP3(0x00))
7a3766f3 192#define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
8289b279 193#define ARITH_AND (INSN_OP(2) | INSN_OP3(0x01))
dc69960d 194#define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
8289b279 195#define ARITH_OR (INSN_OP(2) | INSN_OP3(0x02))
9a7f3228 196#define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
be6551b1 197#define ARITH_ORN (INSN_OP(2) | INSN_OP3(0x06))
8289b279 198#define ARITH_XOR (INSN_OP(2) | INSN_OP3(0x03))
f5ef6aac
BS
199#define ARITH_SUB (INSN_OP(2) | INSN_OP3(0x04))
200#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
c470b663
RH
201#define ARITH_ADDC (INSN_OP(2) | INSN_OP3(0x08))
202#define ARITH_SUBC (INSN_OP(2) | INSN_OP3(0x0c))
8289b279 203#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
f4c16661 204#define ARITH_SMUL (INSN_OP(2) | INSN_OP3(0x0b))
8289b279
BS
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))
dbfe80e1 210#define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
203342d8 211#define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f))
8289b279 212
90379ca8 213#define ARITH_ADDXC (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x11))
de8301e5 214#define ARITH_UMULXHI (INSN_OP(2) | INSN_OP3(0x36) | INSN_OPF(0x16))
90379ca8 215
8289b279
BS
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))
219
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))
223
7a3766f3 224#define RDY (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
583d1215 225#define WRY (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
8289b279 226#define JMPL (INSN_OP(2) | INSN_OP3(0x38))
8b66eefe 227#define RETURN (INSN_OP(2) | INSN_OP3(0x39))
8289b279
BS
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))
8384dd67
BS
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))
254
f8f03b37
PK
255#define MEMBAR (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(15) | (1 << 13))
256
ab20bdc1
RH
257#define NOP (SETHI | INSN_RD(TCG_REG_G0) | 0)
258
8384dd67
BS
259#ifndef ASI_PRIMARY_LITTLE
260#define ASI_PRIMARY_LITTLE 0x88
261#endif
8289b279 262
a0ce341a
RH
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))
268
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))
272
90379ca8
RH
273#ifndef use_vis3_instructions
274bool use_vis3_instructions;
275#endif
276
425532d7 277static inline int check_fit_i64(int64_t val, unsigned int bits)
a115f3ea 278{
425532d7 279 return val == sextract64(val, 0, bits);
a115f3ea
RH
280}
281
425532d7 282static inline int check_fit_i32(int32_t val, unsigned int bits)
a115f3ea 283{
425532d7 284 return val == sextract32(val, 0, bits);
a115f3ea
RH
285}
286
425532d7
RH
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
293
abce5964 294static void patch_reloc(tcg_insn_unit *code_ptr, int type,
2ba7fae2 295 intptr_t value, intptr_t addend)
a115f3ea 296{
e9823b4c
RH
297 uint32_t insn = *code_ptr;
298 intptr_t pcrel;
abce5964 299
e9823b4c
RH
300 value += addend;
301 pcrel = tcg_ptr_byte_diff((tcg_insn_unit *)value, code_ptr);
abce5964 302
a115f3ea 303 switch (type) {
ab1339b9 304 case R_SPARC_WDISP16:
e9823b4c 305 assert(check_fit_ptr(pcrel >> 2, 16));
ab1339b9 306 insn &= ~INSN_OFF16(-1);
e9823b4c 307 insn |= INSN_OFF16(pcrel);
ab1339b9 308 break;
a115f3ea 309 case R_SPARC_WDISP19:
e9823b4c 310 assert(check_fit_ptr(pcrel >> 2, 19));
a115f3ea 311 insn &= ~INSN_OFF19(-1);
e9823b4c
RH
312 insn |= INSN_OFF19(pcrel);
313 break;
a115f3ea 314 default:
e9823b4c 315 g_assert_not_reached();
a115f3ea 316 }
e9823b4c
RH
317
318 *code_ptr = insn;
a115f3ea
RH
319}
320
321/* parse target specific constraints */
069ea736
RH
322static const char *target_parse_constraint(TCGArgConstraint *ct,
323 const char *ct_str, TCGType type)
a115f3ea 324{
069ea736 325 switch (*ct_str++) {
a115f3ea
RH
326 case 'r':
327 ct->ct |= TCG_CT_REG;
f46934df 328 ct->u.regs = 0xffffffff;
a115f3ea 329 break;
34b1a49c 330 case 'R':
a115f3ea 331 ct->ct |= TCG_CT_REG;
f46934df 332 ct->u.regs = ALL_64;
34b1a49c
RH
333 break;
334 case 'A': /* qemu_ld/st address constraint */
335 ct->ct |= TCG_CT_REG;
f46934df 336 ct->u.regs = TARGET_LONG_BITS == 64 ? ALL_64 : 0xffffffff;
34b1a49c 337 reserve_helpers:
a115f3ea
RH
338 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
339 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
340 tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
341 break;
34b1a49c
RH
342 case 's': /* qemu_st data 32-bit constraint */
343 ct->ct |= TCG_CT_REG;
f46934df 344 ct->u.regs = 0xffffffff;
34b1a49c
RH
345 goto reserve_helpers;
346 case 'S': /* qemu_st data 64-bit constraint */
347 ct->ct |= TCG_CT_REG;
f46934df 348 ct->u.regs = ALL_64;
34b1a49c 349 goto reserve_helpers;
a115f3ea
RH
350 case 'I':
351 ct->ct |= TCG_CT_CONST_S11;
352 break;
353 case 'J':
354 ct->ct |= TCG_CT_CONST_S13;
355 break;
356 case 'Z':
357 ct->ct |= TCG_CT_CONST_ZERO;
358 break;
359 default:
069ea736 360 return NULL;
a115f3ea 361 }
069ea736 362 return ct_str;
a115f3ea
RH
363}
364
365/* test if a constant matches the constraint */
f6c6afc1 366static inline int tcg_target_const_match(tcg_target_long val, TCGType type,
a115f3ea
RH
367 const TCGArgConstraint *arg_ct)
368{
369 int ct = arg_ct->ct;
370
371 if (ct & TCG_CT_CONST) {
372 return 1;
4b304cfa
RH
373 }
374
375 if (type == TCG_TYPE_I32) {
376 val = (int32_t)val;
377 }
378
379 if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
a115f3ea
RH
380 return 1;
381 } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
382 return 1;
383 } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
384 return 1;
385 } else {
386 return 0;
387 }
388}
389
35e2da15
RH
390static inline void tcg_out_arith(TCGContext *s, TCGReg rd, TCGReg rs1,
391 TCGReg rs2, int op)
26cc915c 392{
35e2da15 393 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_RS2(rs2));
26cc915c
BS
394}
395
35e2da15
RH
396static inline void tcg_out_arithi(TCGContext *s, TCGReg rd, TCGReg rs1,
397 int32_t offset, int op)
26cc915c 398{
35e2da15 399 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) | INSN_IMM13(offset));
26cc915c
BS
400}
401
35e2da15
RH
402static void tcg_out_arithc(TCGContext *s, TCGReg rd, TCGReg rs1,
403 int32_t val2, int val2const, int op)
ba225198
RH
404{
405 tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
406 | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
407}
408
2a534aff
RH
409static inline void tcg_out_mov(TCGContext *s, TCGType type,
410 TCGReg ret, TCGReg arg)
8289b279 411{
dda73c78
RH
412 if (ret != arg) {
413 tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
414 }
26cc915c
BS
415}
416
35e2da15 417static inline void tcg_out_sethi(TCGContext *s, TCGReg ret, uint32_t arg)
26cc915c
BS
418{
419 tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
8289b279
BS
420}
421
35e2da15 422static inline void tcg_out_movi_imm13(TCGContext *s, TCGReg ret, int32_t arg)
b101234a
BS
423{
424 tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
425}
426
ab20bdc1
RH
427static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
428 tcg_target_long arg, bool in_prologue)
8289b279 429{
425532d7 430 tcg_target_long hi, lo = (int32_t)arg;
ab20bdc1 431 tcg_target_long test, lsb;
a9c7d27b 432
035b2398
RH
433 /* Make sure we test 32-bit constants for imm13 properly. */
434 if (type == TCG_TYPE_I32) {
435 arg = lo;
436 }
437
a9c7d27b
RH
438 /* A 13-bit constant sign-extended to 64-bits. */
439 if (check_fit_tl(arg, 13)) {
b101234a 440 tcg_out_movi_imm13(s, ret, arg);
a9c7d27b 441 return;
8289b279 442 }
8289b279 443
f6823cbe
RH
444 /* A 13-bit constant relative to the TB. */
445 if (!in_prologue && USE_REG_TB) {
446 test = arg - (uintptr_t)s->code_gen_ptr;
447 if (check_fit_ptr(test, 13)) {
448 tcg_out_arithi(s, ret, TCG_REG_TB, test, ARITH_ADD);
449 return;
450 }
451 }
452
a9c7d27b 453 /* A 32-bit constant, or 32-bit zero-extended to 64-bits. */
34b1a49c 454 if (type == TCG_TYPE_I32 || arg == (uint32_t)arg) {
a9c7d27b
RH
455 tcg_out_sethi(s, ret, arg);
456 if (arg & 0x3ff) {
457 tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
458 }
459 return;
460 }
461
462 /* A 32-bit constant sign-extended to 64-bits. */
425532d7 463 if (arg == lo) {
43172207
RH
464 tcg_out_sethi(s, ret, ~arg);
465 tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
a9c7d27b
RH
466 return;
467 }
468
ab20bdc1
RH
469 /* A 21-bit constant, shifted. */
470 lsb = ctz64(arg);
471 test = (tcg_target_long)arg >> lsb;
472 if (check_fit_tl(test, 13)) {
473 tcg_out_movi_imm13(s, ret, test);
474 tcg_out_arithi(s, ret, ret, lsb, SHIFT_SLLX);
475 return;
476 } else if (lsb > 10 && test == extract64(test, 0, 21)) {
477 tcg_out_sethi(s, ret, test << 10);
478 tcg_out_arithi(s, ret, ret, lsb - 10, SHIFT_SLLX);
479 return;
480 }
481
a9c7d27b 482 /* A 64-bit constant decomposed into 2 32-bit pieces. */
425532d7 483 if (check_fit_i32(lo, 13)) {
34b1a49c 484 hi = (arg - lo) >> 32;
a9c7d27b
RH
485 tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
486 tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
487 tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
43172207 488 } else {
34b1a49c 489 hi = arg >> 32;
a9c7d27b
RH
490 tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
491 tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
375816f8 492 tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
375816f8 493 tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
6f41b777 494 }
b101234a
BS
495}
496
ab20bdc1
RH
497static inline void tcg_out_movi(TCGContext *s, TCGType type,
498 TCGReg ret, tcg_target_long arg)
499{
500 tcg_out_movi_int(s, type, ret, arg, false);
501}
502
35e2da15
RH
503static inline void tcg_out_ldst_rr(TCGContext *s, TCGReg data, TCGReg a1,
504 TCGReg a2, int op)
8289b279 505{
a0ce341a 506 tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
8289b279
BS
507}
508
35e2da15
RH
509static void tcg_out_ldst(TCGContext *s, TCGReg ret, TCGReg addr,
510 intptr_t offset, int op)
8289b279 511{
425532d7 512 if (check_fit_ptr(offset, 13)) {
8289b279
BS
513 tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
514 INSN_IMM13(offset));
a0ce341a 515 } else {
375816f8
RH
516 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, offset);
517 tcg_out_ldst_rr(s, ret, addr, TCG_REG_T1, op);
cf7c2ca5 518 }
8289b279
BS
519}
520
2a534aff 521static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
a05b5b9b 522 TCGReg arg1, intptr_t arg2)
8289b279 523{
a0ce341a 524 tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
8289b279
BS
525}
526
2a534aff 527static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
a05b5b9b 528 TCGReg arg1, intptr_t arg2)
8289b279 529{
a0ce341a
RH
530 tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
531}
532
59d7c14e
RH
533static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
534 TCGReg base, intptr_t ofs)
535{
536 if (val == 0) {
537 tcg_out_st(s, type, TCG_REG_G0, base, ofs);
538 return true;
539 }
540 return false;
541}
542
35e2da15 543static void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
a0ce341a 544{
ab20bdc1
RH
545 intptr_t diff = arg - (uintptr_t)s->code_gen_ptr;
546 if (USE_REG_TB && check_fit_ptr(diff, 13)) {
547 tcg_out_ld(s, TCG_TYPE_PTR, ret, TCG_REG_TB, diff);
548 return;
549 }
35e2da15
RH
550 tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
551 tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
8289b279
BS
552}
553
35e2da15 554static inline void tcg_out_sety(TCGContext *s, TCGReg rs)
8289b279 555{
583d1215 556 tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
8289b279
BS
557}
558
35e2da15 559static inline void tcg_out_rdy(TCGContext *s, TCGReg rd)
7a3766f3
RH
560{
561 tcg_out32(s, RDY | INSN_RD(rd));
562}
563
35e2da15
RH
564static void tcg_out_div32(TCGContext *s, TCGReg rd, TCGReg rs1,
565 int32_t val2, int val2const, int uns)
583d1215
RH
566{
567 /* Load Y with the sign/zero extension of RS1 to 64-bits. */
568 if (uns) {
569 tcg_out_sety(s, TCG_REG_G0);
570 } else {
375816f8
RH
571 tcg_out_arithi(s, TCG_REG_T1, rs1, 31, SHIFT_SRA);
572 tcg_out_sety(s, TCG_REG_T1);
583d1215
RH
573 }
574
575 tcg_out_arithc(s, rd, rs1, val2, val2const,
576 uns ? ARITH_UDIV : ARITH_SDIV);
577}
578
8289b279
BS
579static inline void tcg_out_nop(TCGContext *s)
580{
ab20bdc1 581 tcg_out32(s, NOP);
8289b279
BS
582}
583
0aed257f 584static const uint8_t tcg_cond_to_bcond[] = {
cf7c2ca5
BS
585 [TCG_COND_EQ] = COND_E,
586 [TCG_COND_NE] = COND_NE,
587 [TCG_COND_LT] = COND_L,
588 [TCG_COND_GE] = COND_GE,
589 [TCG_COND_LE] = COND_LE,
590 [TCG_COND_GT] = COND_G,
591 [TCG_COND_LTU] = COND_CS,
592 [TCG_COND_GEU] = COND_CC,
593 [TCG_COND_LEU] = COND_LEU,
594 [TCG_COND_GTU] = COND_GU,
595};
596
ab1339b9
RH
597static const uint8_t tcg_cond_to_rcond[] = {
598 [TCG_COND_EQ] = RCOND_Z,
599 [TCG_COND_NE] = RCOND_NZ,
600 [TCG_COND_LT] = RCOND_LZ,
601 [TCG_COND_GT] = RCOND_GZ,
602 [TCG_COND_LE] = RCOND_LEZ,
603 [TCG_COND_GE] = RCOND_GEZ
604};
605
a115f3ea
RH
606static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
607{
608 tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
609}
610
bec16311 611static void tcg_out_bpcc(TCGContext *s, int scond, int flags, TCGLabel *l)
a115f3ea 612{
a115f3ea
RH
613 int off19;
614
615 if (l->has_value) {
abce5964 616 off19 = INSN_OFF19(tcg_pcrel_diff(s, l->u.value_ptr));
a115f3ea
RH
617 } else {
618 /* Make sure to preserve destinations during retranslation. */
abce5964 619 off19 = *s->code_ptr & INSN_OFF19(-1);
bec16311 620 tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, l, 0);
a115f3ea
RH
621 }
622 tcg_out_bpcc0(s, scond, flags, off19);
623}
624
35e2da15 625static void tcg_out_cmp(TCGContext *s, TCGReg c1, int32_t c2, int c2const)
56f4927e 626{
ba225198 627 tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
56f4927e
RH
628}
629
35e2da15 630static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGReg arg1,
bec16311 631 int32_t arg2, int const_arg2, TCGLabel *l)
cf7c2ca5 632{
56f4927e 633 tcg_out_cmp(s, arg1, arg2, const_arg2);
bec16311 634 tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, l);
cf7c2ca5
BS
635 tcg_out_nop(s);
636}
637
35e2da15
RH
638static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGReg ret,
639 int32_t v1, int v1const)
ded37f0d
RH
640{
641 tcg_out32(s, ARITH_MOVCC | cc | INSN_RD(ret)
642 | INSN_RS1(tcg_cond_to_bcond[cond])
643 | (v1const ? INSN_IMM11(v1) : INSN_RS2(v1)));
644}
645
35e2da15
RH
646static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
647 TCGReg c1, int32_t c2, int c2const,
648 int32_t v1, int v1const)
ded37f0d
RH
649{
650 tcg_out_cmp(s, c1, c2, c2const);
651 tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
652}
653
35e2da15 654static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGReg arg1,
bec16311 655 int32_t arg2, int const_arg2, TCGLabel *l)
1da92db2 656{
ab1339b9
RH
657 /* For 64-bit signed comparisons vs zero, we can avoid the compare. */
658 if (arg2 == 0 && !is_unsigned_cond(cond)) {
ab1339b9
RH
659 int off16;
660
661 if (l->has_value) {
abce5964 662 off16 = INSN_OFF16(tcg_pcrel_diff(s, l->u.value_ptr));
ab1339b9
RH
663 } else {
664 /* Make sure to preserve destinations during retranslation. */
abce5964 665 off16 = *s->code_ptr & INSN_OFF16(-1);
bec16311 666 tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, l, 0);
ab1339b9
RH
667 }
668 tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
669 | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
670 } else {
671 tcg_out_cmp(s, arg1, arg2, const_arg2);
bec16311 672 tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, l);
ab1339b9 673 }
1da92db2
BS
674 tcg_out_nop(s);
675}
ded37f0d 676
35e2da15
RH
677static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGReg ret, TCGReg c1,
678 int32_t v1, int v1const)
203342d8
RH
679{
680 tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
681 | (tcg_cond_to_rcond[cond] << 10)
682 | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
683}
684
35e2da15
RH
685static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
686 TCGReg c1, int32_t c2, int c2const,
687 int32_t v1, int v1const)
ded37f0d 688{
203342d8
RH
689 /* For 64-bit signed comparisons vs zero, we can avoid the compare.
690 Note that the immediate range is one bit smaller, so we must check
691 for that as well. */
692 if (c2 == 0 && !is_unsigned_cond(cond)
35e2da15 693 && (!v1const || check_fit_i32(v1, 10))) {
203342d8
RH
694 tcg_out_movr(s, cond, ret, c1, v1, v1const);
695 } else {
696 tcg_out_cmp(s, c1, c2, c2const);
697 tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
698 }
ded37f0d 699}
1da92db2 700
35e2da15
RH
701static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGReg ret,
702 TCGReg c1, int32_t c2, int c2const)
dbfe80e1 703{
c470b663 704 /* For 32-bit comparisons, we can play games with ADDC/SUBC. */
dbfe80e1 705 switch (cond) {
7d458a75
RH
706 case TCG_COND_LTU:
707 case TCG_COND_GEU:
708 /* The result of the comparison is in the carry bit. */
709 break;
710
dbfe80e1
RH
711 case TCG_COND_EQ:
712 case TCG_COND_NE:
7d458a75 713 /* For equality, we can transform to inequality vs zero. */
dbfe80e1 714 if (c2 != 0) {
321b6c05
RH
715 tcg_out_arithc(s, TCG_REG_T1, c1, c2, c2const, ARITH_XOR);
716 c2 = TCG_REG_T1;
717 } else {
718 c2 = c1;
dbfe80e1 719 }
321b6c05 720 c1 = TCG_REG_G0, c2const = 0;
7d458a75 721 cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
dbfe80e1
RH
722 break;
723
724 case TCG_COND_GTU:
dbfe80e1 725 case TCG_COND_LEU:
7d458a75
RH
726 /* If we don't need to load a constant into a register, we can
727 swap the operands on GTU/LEU. There's no benefit to loading
728 the constant into a temporary register. */
729 if (!c2const || c2 == 0) {
35e2da15 730 TCGReg t = c1;
7d458a75
RH
731 c1 = c2;
732 c2 = t;
733 c2const = 0;
734 cond = tcg_swap_cond(cond);
735 break;
736 }
737 /* FALLTHRU */
dbfe80e1
RH
738
739 default:
740 tcg_out_cmp(s, c1, c2, c2const);
dbfe80e1 741 tcg_out_movi_imm13(s, ret, 0);
ded37f0d 742 tcg_out_movcc(s, cond, MOVCC_ICC, ret, 1, 1);
dbfe80e1
RH
743 return;
744 }
745
746 tcg_out_cmp(s, c1, c2, c2const);
747 if (cond == TCG_COND_LTU) {
c470b663 748 tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDC);
dbfe80e1 749 } else {
c470b663 750 tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBC);
dbfe80e1
RH
751 }
752}
753
35e2da15
RH
754static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
755 TCGReg c1, int32_t c2, int c2const)
dbfe80e1 756{
9d6a7a85
RH
757 if (use_vis3_instructions) {
758 switch (cond) {
759 case TCG_COND_NE:
760 if (c2 != 0) {
761 break;
762 }
763 c2 = c1, c2const = 0, c1 = TCG_REG_G0;
764 /* FALLTHRU */
765 case TCG_COND_LTU:
766 tcg_out_cmp(s, c1, c2, c2const);
767 tcg_out_arith(s, ret, TCG_REG_G0, TCG_REG_G0, ARITH_ADDXC);
768 return;
769 default:
770 break;
771 }
772 }
773
203342d8
RH
774 /* For 64-bit signed comparisons vs zero, we can avoid the compare
775 if the input does not overlap the output. */
776 if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
777 tcg_out_movi_imm13(s, ret, 0);
778 tcg_out_movr(s, cond, ret, c1, 1, 1);
779 } else {
780 tcg_out_cmp(s, c1, c2, c2const);
781 tcg_out_movi_imm13(s, ret, 0);
782 tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
783 }
dbfe80e1 784}
4ec28e25 785
609ac1e1
RH
786static void tcg_out_addsub2_i32(TCGContext *s, TCGReg rl, TCGReg rh,
787 TCGReg al, TCGReg ah, int32_t bl, int blconst,
788 int32_t bh, int bhconst, int opl, int oph)
4ec28e25 789{
35e2da15 790 TCGReg tmp = TCG_REG_T1;
4ec28e25
RH
791
792 /* Note that the low parts are fully consumed before tmp is set. */
793 if (rl != ah && (bhconst || rl != bh)) {
794 tmp = rl;
795 }
796
797 tcg_out_arithc(s, tmp, al, bl, blconst, opl);
798 tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
799 tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
800}
dbfe80e1 801
609ac1e1
RH
802static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh,
803 TCGReg al, TCGReg ah, int32_t bl, int blconst,
804 int32_t bh, int bhconst, bool is_sub)
805{
806 TCGReg tmp = TCG_REG_T1;
807
808 /* Note that the low parts are fully consumed before tmp is set. */
809 if (rl != ah && (bhconst || rl != bh)) {
810 tmp = rl;
811 }
812
813 tcg_out_arithc(s, tmp, al, bl, blconst, is_sub ? ARITH_SUBCC : ARITH_ADDCC);
814
90379ca8
RH
815 if (use_vis3_instructions && !is_sub) {
816 /* Note that ADDXC doesn't accept immediates. */
817 if (bhconst && bh != 0) {
818 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh);
819 bh = TCG_REG_T2;
820 }
821 tcg_out_arith(s, rh, ah, bh, ARITH_ADDXC);
822 } else if (bh == TCG_REG_G0) {
609ac1e1
RH
823 /* If we have a zero, we can perform the operation in two insns,
824 with the arithmetic first, and a conditional move into place. */
825 if (rh == ah) {
826 tcg_out_arithi(s, TCG_REG_T2, ah, 1,
827 is_sub ? ARITH_SUB : ARITH_ADD);
828 tcg_out_movcc(s, TCG_COND_LTU, MOVCC_XCC, rh, TCG_REG_T2, 0);
829 } else {
830 tcg_out_arithi(s, rh, ah, 1, is_sub ? ARITH_SUB : ARITH_ADD);
831 tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, rh, ah, 0);
832 }
833 } else {
834 /* Otherwise adjust BH as if there is carry into T2 ... */
835 if (bhconst) {
836 tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh + (is_sub ? -1 : 1));
837 } else {
838 tcg_out_arithi(s, TCG_REG_T2, bh, 1,
839 is_sub ? ARITH_SUB : ARITH_ADD);
840 }
841 /* ... smoosh T2 back to original BH if carry is clear ... */
842 tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, TCG_REG_T2, bh, bhconst);
843 /* ... and finally perform the arithmetic with the new operand. */
844 tcg_out_arith(s, rh, ah, TCG_REG_T2, is_sub ? ARITH_SUB : ARITH_ADD);
845 }
846
847 tcg_out_mov(s, TCG_TYPE_I64, rl, tmp);
848}
849
ab20bdc1
RH
850static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest,
851 bool in_prologue)
aad2f06a 852{
abce5964 853 ptrdiff_t disp = tcg_pcrel_diff(s, dest);
aad2f06a
RH
854
855 if (disp == (int32_t)disp) {
856 tcg_out32(s, CALL | (uint32_t)disp >> 2);
857 } else {
abce5964 858 uintptr_t desti = (uintptr_t)dest;
ab20bdc1
RH
859 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_REG_T1,
860 desti & ~0xfff, in_prologue);
abce5964 861 tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, desti & 0xfff, JMPL);
aad2f06a
RH
862 }
863}
864
4e9cf840
RH
865static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
866{
ab20bdc1 867 tcg_out_call_nodelay(s, dest, false);
4e9cf840
RH
868 tcg_out_nop(s);
869}
870
f8f03b37
PK
871static void tcg_out_mb(TCGContext *s, TCGArg a0)
872{
873 /* Note that the TCG memory order constants mirror the Sparc MEMBAR. */
874 tcg_out32(s, MEMBAR | (a0 & TCG_MO_ALL));
875}
876
7ea5d725 877#ifdef CONFIG_SOFTMMU
abce5964
RH
878static tcg_insn_unit *qemu_ld_trampoline[16];
879static tcg_insn_unit *qemu_st_trampoline[16];
7ea5d725 880
709a340d
PM
881static void emit_extend(TCGContext *s, TCGReg r, int op)
882{
883 /* Emit zero extend of 8, 16 or 32 bit data as
884 * required by the MO_* value op; do nothing for 64 bit.
885 */
886 switch (op & MO_SIZE) {
887 case MO_8:
888 tcg_out_arithi(s, r, r, 0xff, ARITH_AND);
889 break;
890 case MO_16:
891 tcg_out_arithi(s, r, r, 16, SHIFT_SLL);
892 tcg_out_arithi(s, r, r, 16, SHIFT_SRL);
893 break;
894 case MO_32:
895 if (SPARC64) {
896 tcg_out_arith(s, r, r, 0, SHIFT_SRL);
897 }
898 break;
899 case MO_64:
900 break;
901 }
902}
903
7ea5d725
RH
904static void build_trampolines(TCGContext *s)
905{
abce5964
RH
906 static void * const qemu_ld_helpers[16] = {
907 [MO_UB] = helper_ret_ldub_mmu,
908 [MO_SB] = helper_ret_ldsb_mmu,
909 [MO_LEUW] = helper_le_lduw_mmu,
910 [MO_LESW] = helper_le_ldsw_mmu,
911 [MO_LEUL] = helper_le_ldul_mmu,
912 [MO_LEQ] = helper_le_ldq_mmu,
913 [MO_BEUW] = helper_be_lduw_mmu,
914 [MO_BESW] = helper_be_ldsw_mmu,
915 [MO_BEUL] = helper_be_ldul_mmu,
916 [MO_BEQ] = helper_be_ldq_mmu,
7ea5d725 917 };
abce5964
RH
918 static void * const qemu_st_helpers[16] = {
919 [MO_UB] = helper_ret_stb_mmu,
920 [MO_LEUW] = helper_le_stw_mmu,
921 [MO_LEUL] = helper_le_stl_mmu,
922 [MO_LEQ] = helper_le_stq_mmu,
923 [MO_BEUW] = helper_be_stw_mmu,
924 [MO_BEUL] = helper_be_stl_mmu,
925 [MO_BEQ] = helper_be_stq_mmu,
7ea5d725
RH
926 };
927
928 int i;
929 TCGReg ra;
7ea5d725
RH
930
931 for (i = 0; i < 16; ++i) {
abce5964 932 if (qemu_ld_helpers[i] == NULL) {
7ea5d725
RH
933 continue;
934 }
935
936 /* May as well align the trampoline. */
abce5964 937 while ((uintptr_t)s->code_ptr & 15) {
7ea5d725 938 tcg_out_nop(s);
7ea5d725 939 }
abce5964 940 qemu_ld_trampoline[i] = s->code_ptr;
7ea5d725 941
34b1a49c
RH
942 if (SPARC64 || TARGET_LONG_BITS == 32) {
943 ra = TCG_REG_O3;
944 } else {
945 /* Install the high part of the address. */
946 tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
947 ra = TCG_REG_O4;
948 }
7ea5d725
RH
949
950 /* Set the retaddr operand. */
951 tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
952 /* Set the env operand. */
953 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
954 /* Tail call. */
ab20bdc1 955 tcg_out_call_nodelay(s, qemu_ld_helpers[i], true);
7ea5d725
RH
956 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
957 }
958
959 for (i = 0; i < 16; ++i) {
abce5964 960 if (qemu_st_helpers[i] == NULL) {
7ea5d725
RH
961 continue;
962 }
963
964 /* May as well align the trampoline. */
abce5964 965 while ((uintptr_t)s->code_ptr & 15) {
7ea5d725 966 tcg_out_nop(s);
7ea5d725 967 }
abce5964 968 qemu_st_trampoline[i] = s->code_ptr;
7ea5d725 969
34b1a49c 970 if (SPARC64) {
709a340d 971 emit_extend(s, TCG_REG_O2, i);
34b1a49c
RH
972 ra = TCG_REG_O4;
973 } else {
974 ra = TCG_REG_O1;
975 if (TARGET_LONG_BITS == 64) {
976 /* Install the high part of the address. */
977 tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
978 ra += 2;
979 } else {
980 ra += 1;
981 }
982 if ((i & MO_SIZE) == MO_64) {
983 /* Install the high part of the data. */
984 tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
985 ra += 2;
986 } else {
709a340d 987 emit_extend(s, ra, i);
34b1a49c
RH
988 ra += 1;
989 }
3972ef6f 990 /* Skip the oi argument. */
34b1a49c
RH
991 ra += 1;
992 }
993
7ea5d725
RH
994 /* Set the retaddr operand. */
995 if (ra >= TCG_REG_O6) {
996 tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
997 TCG_TARGET_CALL_STACK_OFFSET);
998 ra = TCG_REG_G1;
999 }
1000 tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
1001 /* Set the env operand. */
1002 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
1003 /* Tail call. */
ab20bdc1 1004 tcg_out_call_nodelay(s, qemu_st_helpers[i], true);
7ea5d725
RH
1005 tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
1006 }
1007}
1008#endif
1009
7d551702 1010/* Generate global QEMU prologue and epilogue code */
e4d58b41 1011static void tcg_target_qemu_prologue(TCGContext *s)
b3db8758 1012{
4c3204cb
RH
1013 int tmp_buf_size, frame_size;
1014
1015 /* The TCG temp buffer is at the top of the frame, immediately
1016 below the frame pointer. */
1017 tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
1018 tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
1019 tmp_buf_size);
1020
1021 /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
1022 otherwise the minimal frame usable by callees. */
1023 frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
1024 frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
1025 frame_size += TCG_TARGET_STACK_ALIGN - 1;
1026 frame_size &= -TCG_TARGET_STACK_ALIGN;
b3db8758 1027 tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
4c3204cb 1028 INSN_IMM13(-frame_size));
c6f7e4fb 1029
4cbea598 1030#ifndef CONFIG_SOFTMMU
b76f21a7 1031 if (guest_base != 0) {
ab20bdc1 1032 tcg_out_movi_int(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base, true);
c6f7e4fb
RH
1033 tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
1034 }
1035#endif
1036
ab20bdc1
RH
1037 /* We choose TCG_REG_TB such that no move is required. */
1038 if (USE_REG_TB) {
1039 QEMU_BUILD_BUG_ON(TCG_REG_TB != TCG_REG_I1);
1040 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TB);
1041 }
1042
aad2f06a 1043 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
0c554161
RH
1044 /* delay slot */
1045 tcg_out_nop(s);
4c3204cb 1046
38f81dc5
RH
1047 /* Epilogue for goto_ptr. */
1048 s->code_gen_epilogue = s->code_ptr;
1049 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1050 /* delay slot */
1051 tcg_out_movi_imm13(s, TCG_REG_O0, 0);
7ea5d725
RH
1052
1053#ifdef CONFIG_SOFTMMU
1054 build_trampolines(s);
1055#endif
b3db8758
BS
1056}
1057
e9823b4c
RH
1058static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
1059{
1060 int i;
1061 for (i = 0; i < count; ++i) {
1062 p[i] = NOP;
1063 }
1064}
1065
f5ef6aac 1066#if defined(CONFIG_SOFTMMU)
a0ce341a 1067/* Perform the TLB load and compare.
bffe1431 1068
a0ce341a 1069 Inputs:
a8b12c10 1070 ADDRLO and ADDRHI contain the possible two parts of the address.
a0ce341a
RH
1071
1072 MEM_INDEX and S_BITS are the memory context and log2 size of the load.
1073
1074 WHICH is the offset into the CPUTLBEntry structure of the slot to read.
1075 This should be offsetof addr_read or addr_write.
1076
1077 The result of the TLB comparison is in %[ix]cc. The sanitized address
1078 is in the returned register, maybe %o0. The TLB addend is in %o1. */
1079
34b1a49c 1080static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
85aa8081 1081 TCGMemOp opc, int which)
a0ce341a 1082{
a8b12c10
RH
1083 const TCGReg r0 = TCG_REG_O0;
1084 const TCGReg r1 = TCG_REG_O1;
1085 const TCGReg r2 = TCG_REG_O2;
85aa8081
RH
1086 unsigned s_bits = opc & MO_SIZE;
1087 unsigned a_bits = get_alignment_bits(opc);
a0ce341a
RH
1088 int tlb_ofs;
1089
d801a8f2 1090 /* Shift the page number down. */
34b1a49c 1091 tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);
a0ce341a 1092
85aa8081
RH
1093 /* Mask out the page offset, except for the required alignment.
1094 We don't support unaligned accesses. */
1095 if (a_bits < s_bits) {
1096 a_bits = s_bits;
1097 }
d801a8f2 1098 tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
85aa8081 1099 TARGET_PAGE_MASK | ((1 << a_bits) - 1));
d801a8f2
RH
1100
1101 /* Mask the tlb index. */
1102 tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
1103
1104 /* Mask page, part 2. */
1105 tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
a0ce341a 1106
d801a8f2
RH
1107 /* Shift the tlb index into place. */
1108 tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
a0ce341a
RH
1109
1110 /* Relative to the current ENV. */
1111 tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
1112
1113 /* Find a base address that can load both tlb comparator and addend. */
1114 tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
425532d7 1115 if (!check_fit_ptr(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
35e2da15
RH
1116 if (tlb_ofs & ~0x3ff) {
1117 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, tlb_ofs & ~0x3ff);
1118 tcg_out_arith(s, r1, r1, TCG_REG_T1, ARITH_ADD);
1119 }
d801a8f2 1120 tlb_ofs &= 0x3ff;
a0ce341a
RH
1121 }
1122
1123 /* Load the tlb comparator and the addend. */
1124 tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
1125 tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
1126
1127 /* subcc arg0, arg2, %g0 */
1128 tcg_out_cmp(s, r0, r2, 0);
1129
1130 /* If the guest address must be zero-extended, do so now. */
9f44adc5 1131 if (SPARC64 && TARGET_LONG_BITS == 32) {
34b1a49c 1132 tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
a0ce341a
RH
1133 return r0;
1134 }
34b1a49c 1135 return addr;
a0ce341a
RH
1136}
1137#endif /* CONFIG_SOFTMMU */
1138
eef0d9e7
RH
1139static const int qemu_ld_opc[16] = {
1140 [MO_UB] = LDUB,
1141 [MO_SB] = LDSB,
1142
1143 [MO_BEUW] = LDUH,
1144 [MO_BESW] = LDSH,
1145 [MO_BEUL] = LDUW,
1146 [MO_BESL] = LDSW,
1147 [MO_BEQ] = LDX,
1148
1149 [MO_LEUW] = LDUH_LE,
1150 [MO_LESW] = LDSH_LE,
1151 [MO_LEUL] = LDUW_LE,
1152 [MO_LESL] = LDSW_LE,
1153 [MO_LEQ] = LDX_LE,
a0ce341a 1154};
9d0efc88 1155
eef0d9e7
RH
1156static const int qemu_st_opc[16] = {
1157 [MO_UB] = STB,
1158
1159 [MO_BEUW] = STH,
1160 [MO_BEUL] = STW,
1161 [MO_BEQ] = STX,
1162
1163 [MO_LEUW] = STH_LE,
1164 [MO_LEUL] = STW_LE,
1165 [MO_LEQ] = STX_LE,
a0ce341a 1166};
bffe1431 1167
34b1a49c 1168static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
59227d5d 1169 TCGMemOpIdx oi, bool is_64)
f5ef6aac 1170{
59227d5d 1171 TCGMemOp memop = get_memop(oi);
34b1a49c 1172#ifdef CONFIG_SOFTMMU
59227d5d 1173 unsigned memi = get_mmuidx(oi);
cab0a7ea 1174 TCGReg addrz, param;
abce5964
RH
1175 tcg_insn_unit *func;
1176 tcg_insn_unit *label_ptr;
f5ef6aac 1177
85aa8081 1178 addrz = tcg_out_tlb_load(s, addr, memi, memop,
cab0a7ea 1179 offsetof(CPUTLBEntry, addr_read));
a0ce341a 1180
34b1a49c
RH
1181 /* The fast path is exactly one insn. Thus we can perform the
1182 entire TLB Hit in the (annulled) delay slot of the branch
1183 over the TLB Miss case. */
a0ce341a 1184
34b1a49c 1185 /* beq,a,pt %[xi]cc, label0 */
abce5964 1186 label_ptr = s->code_ptr;
34b1a49c
RH
1187 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1188 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1189 /* delay slot */
2b7ec66f
RH
1190 tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1191 qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
53c37487 1192
a0ce341a 1193 /* TLB Miss. */
f5ef6aac 1194
7ea5d725 1195 param = TCG_REG_O1;
34b1a49c
RH
1196 if (!SPARC64 && TARGET_LONG_BITS == 64) {
1197 /* Skip the high-part; we'll perform the extract in the trampoline. */
1198 param++;
a0ce341a 1199 }
5c32be5b 1200 tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
f5ef6aac 1201
7ea5d725
RH
1202 /* We use the helpers to extend SB and SW data, leaving the case
1203 of SL needing explicit extending below. */
2b7ec66f
RH
1204 if ((memop & MO_SSIZE) == MO_SL) {
1205 func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SIZE)];
7ea5d725 1206 } else {
2b7ec66f 1207 func = qemu_ld_trampoline[memop & (MO_BSWAP | MO_SSIZE)];
7ea5d725 1208 }
eabb7b91 1209 tcg_debug_assert(func != NULL);
ab20bdc1 1210 tcg_out_call_nodelay(s, func, false);
a0ce341a 1211 /* delay slot */
3972ef6f 1212 tcg_out_movi(s, TCG_TYPE_I32, param, oi);
7ea5d725 1213
34b1a49c
RH
1214 /* Recall that all of the helpers return 64-bit results.
1215 Which complicates things for sparcv8plus. */
1216 if (SPARC64) {
1217 /* We let the helper sign-extend SB and SW, but leave SL for here. */
2b7ec66f 1218 if (is_64 && (memop & MO_SSIZE) == MO_SL) {
34b1a49c
RH
1219 tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
1220 } else {
1221 tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
1222 }
1223 } else {
2b7ec66f 1224 if ((memop & MO_SIZE) == MO_64) {
34b1a49c
RH
1225 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
1226 tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
1227 tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
1228 } else if (is_64) {
1229 /* Re-extend from 32-bit rather than reassembling when we
1230 know the high register must be an extension. */
1231 tcg_out_arithi(s, data, TCG_REG_O1, 0,
1232 memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
1233 } else {
1234 tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
a0ce341a 1235 }
f5ef6aac
BS
1236 }
1237
abce5964 1238 *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
90cbed46 1239#else
9f44adc5 1240 if (SPARC64 && TARGET_LONG_BITS == 32) {
34b1a49c
RH
1241 tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1242 addr = TCG_REG_T1;
f5ef6aac 1243 }
34b1a49c 1244 tcg_out_ldst_rr(s, data, addr,
b76f21a7 1245 (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
2b7ec66f 1246 qemu_ld_opc[memop & (MO_BSWAP | MO_SSIZE)]);
a0ce341a 1247#endif /* CONFIG_SOFTMMU */
f5ef6aac
BS
1248}
1249
34b1a49c 1250static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
59227d5d 1251 TCGMemOpIdx oi)
f5ef6aac 1252{
59227d5d 1253 TCGMemOp memop = get_memop(oi);
34b1a49c 1254#ifdef CONFIG_SOFTMMU
59227d5d 1255 unsigned memi = get_mmuidx(oi);
34b1a49c 1256 TCGReg addrz, param;
abce5964
RH
1257 tcg_insn_unit *func;
1258 tcg_insn_unit *label_ptr;
f5ef6aac 1259
85aa8081 1260 addrz = tcg_out_tlb_load(s, addr, memi, memop,
cab0a7ea 1261 offsetof(CPUTLBEntry, addr_write));
a0ce341a 1262
a0ce341a
RH
1263 /* The fast path is exactly one insn. Thus we can perform the entire
1264 TLB Hit in the (annulled) delay slot of the branch over TLB Miss. */
1265 /* beq,a,pt %[xi]cc, label0 */
abce5964 1266 label_ptr = s->code_ptr;
a115f3ea
RH
1267 tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1268 | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
a0ce341a 1269 /* delay slot */
2b7ec66f
RH
1270 tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1,
1271 qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
a0ce341a
RH
1272
1273 /* TLB Miss. */
1274
7ea5d725 1275 param = TCG_REG_O1;
34b1a49c
RH
1276 if (!SPARC64 && TARGET_LONG_BITS == 64) {
1277 /* Skip the high-part; we'll perform the extract in the trampoline. */
1278 param++;
a0ce341a 1279 }
5c32be5b 1280 tcg_out_mov(s, TCG_TYPE_REG, param++, addrz);
2b7ec66f 1281 if (!SPARC64 && (memop & MO_SIZE) == MO_64) {
34b1a49c
RH
1282 /* Skip the high-part; we'll perform the extract in the trampoline. */
1283 param++;
a0ce341a 1284 }
34b1a49c 1285 tcg_out_mov(s, TCG_TYPE_REG, param++, data);
53c37487 1286
2b7ec66f 1287 func = qemu_st_trampoline[memop & (MO_BSWAP | MO_SIZE)];
eabb7b91 1288 tcg_debug_assert(func != NULL);
ab20bdc1 1289 tcg_out_call_nodelay(s, func, false);
a0ce341a 1290 /* delay slot */
3972ef6f 1291 tcg_out_movi(s, TCG_TYPE_I32, param, oi);
f5ef6aac 1292
abce5964 1293 *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
8384dd67 1294#else
9f44adc5 1295 if (SPARC64 && TARGET_LONG_BITS == 32) {
34b1a49c
RH
1296 tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1297 addr = TCG_REG_T1;
a0ce341a 1298 }
34b1a49c 1299 tcg_out_ldst_rr(s, data, addr,
b76f21a7 1300 (guest_base ? TCG_GUEST_BASE_REG : TCG_REG_G0),
2b7ec66f 1301 qemu_st_opc[memop & (MO_BSWAP | MO_SIZE)]);
a0ce341a 1302#endif /* CONFIG_SOFTMMU */
f5ef6aac
BS
1303}
1304
b357f902
RH
1305static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1306 const TCGArg args[TCG_MAX_OP_ARGS],
1307 const int const_args[TCG_MAX_OP_ARGS])
8289b279 1308{
b357f902
RH
1309 TCGArg a0, a1, a2;
1310 int c, c2;
1311
1312 /* Hoist the loads of the most common arguments. */
1313 a0 = args[0];
1314 a1 = args[1];
1315 a2 = args[2];
1316 c2 = const_args[2];
8289b279
BS
1317
1318 switch (opc) {
1319 case INDEX_op_exit_tb:
b357f902 1320 if (check_fit_ptr(a0, 13)) {
8b66eefe 1321 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
b357f902 1322 tcg_out_movi_imm13(s, TCG_REG_O0, a0);
ab20bdc1
RH
1323 break;
1324 } else if (USE_REG_TB) {
1325 intptr_t tb_diff = a0 - (uintptr_t)s->code_gen_ptr;
1326 if (check_fit_ptr(tb_diff, 13)) {
1327 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1328 /* Note that TCG_REG_TB has been unwound to O1. */
1329 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O1, tb_diff, ARITH_ADD);
1330 break;
1331 }
8b66eefe 1332 }
ab20bdc1
RH
1333 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, a0 & ~0x3ff);
1334 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1335 tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, a0 & 0x3ff, ARITH_OR);
8289b279
BS
1336 break;
1337 case INDEX_op_goto_tb:
f309101c 1338 if (s->tb_jmp_insn_offset) {
8289b279 1339 /* direct jump method */
ab20bdc1
RH
1340 if (USE_REG_TB) {
1341 /* make sure the patch is 8-byte aligned. */
1342 if ((intptr_t)s->code_ptr & 4) {
1343 tcg_out_nop(s);
1344 }
1345 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1346 tcg_out_sethi(s, TCG_REG_T1, 0);
1347 tcg_out_arithi(s, TCG_REG_T1, TCG_REG_T1, 0, ARITH_OR);
1348 tcg_out_arith(s, TCG_REG_G0, TCG_REG_TB, TCG_REG_T1, JMPL);
1349 tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB, TCG_REG_T1, ARITH_ADD);
1350 } else {
1351 s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);
1352 tcg_out32(s, CALL);
1353 tcg_out_nop(s);
1354 }
8289b279
BS
1355 } else {
1356 /* indirect jump method */
ab20bdc1 1357 tcg_out_ld_ptr(s, TCG_REG_TB,
f309101c 1358 (uintptr_t)(s->tb_jmp_target_addr + a0));
ab20bdc1
RH
1359 tcg_out_arithi(s, TCG_REG_G0, TCG_REG_TB, 0, JMPL);
1360 tcg_out_nop(s);
1361 }
9f754620 1362 set_jmp_reset_offset(s, a0);
ab20bdc1
RH
1363
1364 /* For the unlinked path of goto_tb, we need to reset
1365 TCG_REG_TB to the beginning of this TB. */
1366 if (USE_REG_TB) {
9f754620 1367 c = -tcg_current_code_size(s);
ab20bdc1
RH
1368 if (check_fit_i32(c, 13)) {
1369 tcg_out_arithi(s, TCG_REG_TB, TCG_REG_TB, c, ARITH_ADD);
1370 } else {
1371 tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, c);
1372 tcg_out_arith(s, TCG_REG_TB, TCG_REG_TB,
1373 TCG_REG_T1, ARITH_ADD);
1374 }
8289b279 1375 }
8289b279 1376 break;
38f81dc5
RH
1377 case INDEX_op_goto_ptr:
1378 tcg_out_arithi(s, TCG_REG_G0, a0, 0, JMPL);
ab20bdc1
RH
1379 if (USE_REG_TB) {
1380 tcg_out_arith(s, TCG_REG_TB, a0, TCG_REG_G0, ARITH_OR);
1381 } else {
1382 tcg_out_nop(s);
1383 }
38f81dc5 1384 break;
8289b279 1385 case INDEX_op_br:
bec16311 1386 tcg_out_bpcc(s, COND_A, BPCC_PT, arg_label(a0));
f5ef6aac 1387 tcg_out_nop(s);
8289b279 1388 break;
8289b279 1389
8289b279 1390#define OP_32_64(x) \
ba225198
RH
1391 glue(glue(case INDEX_op_, x), _i32): \
1392 glue(glue(case INDEX_op_, x), _i64)
34b1a49c 1393
ba225198 1394 OP_32_64(ld8u):
b357f902 1395 tcg_out_ldst(s, a0, a1, a2, LDUB);
8289b279 1396 break;
ba225198 1397 OP_32_64(ld8s):
b357f902 1398 tcg_out_ldst(s, a0, a1, a2, LDSB);
8289b279 1399 break;
ba225198 1400 OP_32_64(ld16u):
b357f902 1401 tcg_out_ldst(s, a0, a1, a2, LDUH);
8289b279 1402 break;
ba225198 1403 OP_32_64(ld16s):
b357f902 1404 tcg_out_ldst(s, a0, a1, a2, LDSH);
8289b279
BS
1405 break;
1406 case INDEX_op_ld_i32:
53cd9273 1407 case INDEX_op_ld32u_i64:
b357f902 1408 tcg_out_ldst(s, a0, a1, a2, LDUW);
8289b279 1409 break;
ba225198 1410 OP_32_64(st8):
b357f902 1411 tcg_out_ldst(s, a0, a1, a2, STB);
8289b279 1412 break;
ba225198 1413 OP_32_64(st16):
b357f902 1414 tcg_out_ldst(s, a0, a1, a2, STH);
8289b279
BS
1415 break;
1416 case INDEX_op_st_i32:
53cd9273 1417 case INDEX_op_st32_i64:
b357f902 1418 tcg_out_ldst(s, a0, a1, a2, STW);
8289b279 1419 break;
ba225198 1420 OP_32_64(add):
53cd9273 1421 c = ARITH_ADD;
ba225198
RH
1422 goto gen_arith;
1423 OP_32_64(sub):
8289b279 1424 c = ARITH_SUB;
ba225198
RH
1425 goto gen_arith;
1426 OP_32_64(and):
8289b279 1427 c = ARITH_AND;
ba225198 1428 goto gen_arith;
dc69960d
RH
1429 OP_32_64(andc):
1430 c = ARITH_ANDN;
1431 goto gen_arith;
ba225198 1432 OP_32_64(or):
8289b279 1433 c = ARITH_OR;
ba225198 1434 goto gen_arith;
18c8f7a3
RH
1435 OP_32_64(orc):
1436 c = ARITH_ORN;
1437 goto gen_arith;
ba225198 1438 OP_32_64(xor):
8289b279 1439 c = ARITH_XOR;
ba225198 1440 goto gen_arith;
8289b279
BS
1441 case INDEX_op_shl_i32:
1442 c = SHIFT_SLL;
1fd95946
RH
1443 do_shift32:
1444 /* Limit immediate shift count lest we create an illegal insn. */
b357f902 1445 tcg_out_arithc(s, a0, a1, a2 & 31, c2, c);
1fd95946 1446 break;
8289b279
BS
1447 case INDEX_op_shr_i32:
1448 c = SHIFT_SRL;
1fd95946 1449 goto do_shift32;
8289b279
BS
1450 case INDEX_op_sar_i32:
1451 c = SHIFT_SRA;
1fd95946 1452 goto do_shift32;
8289b279
BS
1453 case INDEX_op_mul_i32:
1454 c = ARITH_UMUL;
ba225198 1455 goto gen_arith;
583d1215 1456
4b5a85c1
RH
1457 OP_32_64(neg):
1458 c = ARITH_SUB;
1459 goto gen_arith1;
be6551b1
RH
1460 OP_32_64(not):
1461 c = ARITH_ORN;
1462 goto gen_arith1;
4b5a85c1 1463
583d1215 1464 case INDEX_op_div_i32:
b357f902 1465 tcg_out_div32(s, a0, a1, a2, c2, 0);
583d1215
RH
1466 break;
1467 case INDEX_op_divu_i32:
b357f902 1468 tcg_out_div32(s, a0, a1, a2, c2, 1);
583d1215
RH
1469 break;
1470
8289b279 1471 case INDEX_op_brcond_i32:
bec16311 1472 tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], arg_label(args[3]));
8289b279 1473 break;
dbfe80e1 1474 case INDEX_op_setcond_i32:
b357f902 1475 tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
dbfe80e1 1476 break;
ded37f0d 1477 case INDEX_op_movcond_i32:
b357f902 1478 tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
ded37f0d 1479 break;
dbfe80e1 1480
7a3766f3 1481 case INDEX_op_add2_i32:
609ac1e1
RH
1482 tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1483 args[4], const_args[4], args[5], const_args[5],
c470b663 1484 ARITH_ADDCC, ARITH_ADDC);
7a3766f3
RH
1485 break;
1486 case INDEX_op_sub2_i32:
609ac1e1
RH
1487 tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1488 args[4], const_args[4], args[5], const_args[5],
c470b663 1489 ARITH_SUBCC, ARITH_SUBC);
7a3766f3
RH
1490 break;
1491 case INDEX_op_mulu2_i32:
f4c16661
RH
1492 c = ARITH_UMUL;
1493 goto do_mul2;
1494 case INDEX_op_muls2_i32:
1495 c = ARITH_SMUL;
1496 do_mul2:
1497 /* The 32-bit multiply insns produce a full 64-bit result. If the
1498 destination register can hold it, we can avoid the slower RDY. */
b357f902
RH
1499 tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
1500 if (SPARC64 || a0 <= TCG_REG_O7) {
1501 tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
f4c16661 1502 } else {
b357f902 1503 tcg_out_rdy(s, a1);
f4c16661 1504 }
7a3766f3 1505 break;
8289b279 1506
cab0a7ea 1507 case INDEX_op_qemu_ld_i32:
59227d5d 1508 tcg_out_qemu_ld(s, a0, a1, a2, false);
8289b279 1509 break;
cab0a7ea 1510 case INDEX_op_qemu_ld_i64:
59227d5d 1511 tcg_out_qemu_ld(s, a0, a1, a2, true);
8289b279 1512 break;
cab0a7ea 1513 case INDEX_op_qemu_st_i32:
cab0a7ea 1514 case INDEX_op_qemu_st_i64:
59227d5d 1515 tcg_out_qemu_st(s, a0, a1, a2);
a0ce341a 1516 break;
8289b279 1517
53cd9273 1518 case INDEX_op_ld32s_i64:
b357f902 1519 tcg_out_ldst(s, a0, a1, a2, LDSW);
53cd9273 1520 break;
8289b279 1521 case INDEX_op_ld_i64:
b357f902 1522 tcg_out_ldst(s, a0, a1, a2, LDX);
8289b279
BS
1523 break;
1524 case INDEX_op_st_i64:
b357f902 1525 tcg_out_ldst(s, a0, a1, a2, STX);
8289b279
BS
1526 break;
1527 case INDEX_op_shl_i64:
1528 c = SHIFT_SLLX;
1fd95946
RH
1529 do_shift64:
1530 /* Limit immediate shift count lest we create an illegal insn. */
b357f902 1531 tcg_out_arithc(s, a0, a1, a2 & 63, c2, c);
1fd95946 1532 break;
8289b279
BS
1533 case INDEX_op_shr_i64:
1534 c = SHIFT_SRLX;
1fd95946 1535 goto do_shift64;
8289b279
BS
1536 case INDEX_op_sar_i64:
1537 c = SHIFT_SRAX;
1fd95946 1538 goto do_shift64;
8289b279
BS
1539 case INDEX_op_mul_i64:
1540 c = ARITH_MULX;
ba225198 1541 goto gen_arith;
583d1215 1542 case INDEX_op_div_i64:
53cd9273 1543 c = ARITH_SDIVX;
ba225198 1544 goto gen_arith;
583d1215 1545 case INDEX_op_divu_i64:
8289b279 1546 c = ARITH_UDIVX;
ba225198 1547 goto gen_arith;
4f2331e5 1548 case INDEX_op_ext_i32_i64:
cc6dfecf 1549 case INDEX_op_ext32s_i64:
b357f902 1550 tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
cc6dfecf 1551 break;
4f2331e5 1552 case INDEX_op_extu_i32_i64:
cc6dfecf 1553 case INDEX_op_ext32u_i64:
b357f902 1554 tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
cc6dfecf 1555 break;
609ad705
RH
1556 case INDEX_op_extrl_i64_i32:
1557 tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1558 break;
1559 case INDEX_op_extrh_i64_i32:
1560 tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX);
a24fba93 1561 break;
8289b279
BS
1562
1563 case INDEX_op_brcond_i64:
bec16311 1564 tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
8289b279 1565 break;
dbfe80e1 1566 case INDEX_op_setcond_i64:
b357f902 1567 tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
dbfe80e1 1568 break;
ded37f0d 1569 case INDEX_op_movcond_i64:
b357f902 1570 tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
ded37f0d 1571 break;
609ac1e1
RH
1572 case INDEX_op_add2_i64:
1573 tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1574 const_args[4], args[5], const_args[5], false);
1575 break;
1576 case INDEX_op_sub2_i64:
1577 tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1578 const_args[4], args[5], const_args[5], true);
1579 break;
de8301e5
RH
1580 case INDEX_op_muluh_i64:
1581 tcg_out_arith(s, args[0], args[1], args[2], ARITH_UMULXHI);
1582 break;
34b1a49c 1583
ba225198 1584 gen_arith:
b357f902 1585 tcg_out_arithc(s, a0, a1, a2, c2, c);
53cd9273
BS
1586 break;
1587
4b5a85c1 1588 gen_arith1:
b357f902 1589 tcg_out_arithc(s, a0, TCG_REG_G0, a1, const_args[1], c);
4b5a85c1
RH
1590 break;
1591
f8f03b37
PK
1592 case INDEX_op_mb:
1593 tcg_out_mb(s, a0);
1594 break;
1595
96d0ee7f 1596 case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
98b90bab 1597 case INDEX_op_mov_i64:
96d0ee7f 1598 case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
98b90bab 1599 case INDEX_op_movi_i64:
96d0ee7f 1600 case INDEX_op_call: /* Always emitted via tcg_out_call. */
8289b279 1601 default:
8289b279
BS
1602 tcg_abort();
1603 }
1604}
1605
f69d277e
RH
1606static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
1607{
9be44a16
RH
1608 static const TCGTargetOpDef r = { .args_ct_str = { "r" } };
1609 static const TCGTargetOpDef r_r = { .args_ct_str = { "r", "r" } };
1610 static const TCGTargetOpDef R_r = { .args_ct_str = { "R", "r" } };
1611 static const TCGTargetOpDef r_R = { .args_ct_str = { "r", "R" } };
1612 static const TCGTargetOpDef R_R = { .args_ct_str = { "R", "R" } };
1613 static const TCGTargetOpDef r_A = { .args_ct_str = { "r", "A" } };
1614 static const TCGTargetOpDef R_A = { .args_ct_str = { "R", "A" } };
1615 static const TCGTargetOpDef rZ_r = { .args_ct_str = { "rZ", "r" } };
1616 static const TCGTargetOpDef RZ_r = { .args_ct_str = { "RZ", "r" } };
1617 static const TCGTargetOpDef sZ_A = { .args_ct_str = { "sZ", "A" } };
1618 static const TCGTargetOpDef SZ_A = { .args_ct_str = { "SZ", "A" } };
1619 static const TCGTargetOpDef rZ_rJ = { .args_ct_str = { "rZ", "rJ" } };
1620 static const TCGTargetOpDef RZ_RJ = { .args_ct_str = { "RZ", "RJ" } };
1621 static const TCGTargetOpDef R_R_R = { .args_ct_str = { "R", "R", "R" } };
1622 static const TCGTargetOpDef r_rZ_rJ
1623 = { .args_ct_str = { "r", "rZ", "rJ" } };
1624 static const TCGTargetOpDef R_RZ_RJ
1625 = { .args_ct_str = { "R", "RZ", "RJ" } };
1626 static const TCGTargetOpDef r_r_rZ_rJ
1627 = { .args_ct_str = { "r", "r", "rZ", "rJ" } };
1628 static const TCGTargetOpDef movc_32
1629 = { .args_ct_str = { "r", "rZ", "rJ", "rI", "0" } };
1630 static const TCGTargetOpDef movc_64
1631 = { .args_ct_str = { "R", "RZ", "RJ", "RI", "0" } };
1632 static const TCGTargetOpDef add2_32
1633 = { .args_ct_str = { "r", "r", "rZ", "rZ", "rJ", "rJ" } };
1634 static const TCGTargetOpDef add2_64
1635 = { .args_ct_str = { "R", "R", "RZ", "RZ", "RJ", "RI" } };
1636
1637 switch (op) {
1638 case INDEX_op_goto_ptr:
1639 return &r;
f69d277e 1640
9be44a16
RH
1641 case INDEX_op_ld8u_i32:
1642 case INDEX_op_ld8s_i32:
1643 case INDEX_op_ld16u_i32:
1644 case INDEX_op_ld16s_i32:
1645 case INDEX_op_ld_i32:
1646 case INDEX_op_neg_i32:
1647 case INDEX_op_not_i32:
1648 return &r_r;
1649
1650 case INDEX_op_st8_i32:
1651 case INDEX_op_st16_i32:
1652 case INDEX_op_st_i32:
1653 return &rZ_r;
1654
1655 case INDEX_op_add_i32:
1656 case INDEX_op_mul_i32:
1657 case INDEX_op_div_i32:
1658 case INDEX_op_divu_i32:
1659 case INDEX_op_sub_i32:
1660 case INDEX_op_and_i32:
1661 case INDEX_op_andc_i32:
1662 case INDEX_op_or_i32:
1663 case INDEX_op_orc_i32:
1664 case INDEX_op_xor_i32:
1665 case INDEX_op_shl_i32:
1666 case INDEX_op_shr_i32:
1667 case INDEX_op_sar_i32:
1668 case INDEX_op_setcond_i32:
1669 return &r_rZ_rJ;
1670
1671 case INDEX_op_brcond_i32:
1672 return &rZ_rJ;
1673 case INDEX_op_movcond_i32:
1674 return &movc_32;
1675 case INDEX_op_add2_i32:
1676 case INDEX_op_sub2_i32:
1677 return &add2_32;
1678 case INDEX_op_mulu2_i32:
1679 case INDEX_op_muls2_i32:
1680 return &r_r_rZ_rJ;
1681
1682 case INDEX_op_ld8u_i64:
1683 case INDEX_op_ld8s_i64:
1684 case INDEX_op_ld16u_i64:
1685 case INDEX_op_ld16s_i64:
1686 case INDEX_op_ld32u_i64:
1687 case INDEX_op_ld32s_i64:
1688 case INDEX_op_ld_i64:
1689 case INDEX_op_ext_i32_i64:
1690 case INDEX_op_extu_i32_i64:
1691 return &R_r;
1692
1693 case INDEX_op_st8_i64:
1694 case INDEX_op_st16_i64:
1695 case INDEX_op_st32_i64:
1696 case INDEX_op_st_i64:
1697 return &RZ_r;
1698
1699 case INDEX_op_add_i64:
1700 case INDEX_op_mul_i64:
1701 case INDEX_op_div_i64:
1702 case INDEX_op_divu_i64:
1703 case INDEX_op_sub_i64:
1704 case INDEX_op_and_i64:
1705 case INDEX_op_andc_i64:
1706 case INDEX_op_or_i64:
1707 case INDEX_op_orc_i64:
1708 case INDEX_op_xor_i64:
1709 case INDEX_op_shl_i64:
1710 case INDEX_op_shr_i64:
1711 case INDEX_op_sar_i64:
1712 case INDEX_op_setcond_i64:
1713 return &R_RZ_RJ;
1714
1715 case INDEX_op_neg_i64:
1716 case INDEX_op_not_i64:
1717 case INDEX_op_ext32s_i64:
1718 case INDEX_op_ext32u_i64:
1719 return &R_R;
1720
1721 case INDEX_op_extrl_i64_i32:
1722 case INDEX_op_extrh_i64_i32:
1723 return &r_R;
1724
1725 case INDEX_op_brcond_i64:
1726 return &RZ_RJ;
1727 case INDEX_op_movcond_i64:
1728 return &movc_64;
1729 case INDEX_op_add2_i64:
1730 case INDEX_op_sub2_i64:
1731 return &add2_64;
1732 case INDEX_op_muluh_i64:
1733 return &R_R_R;
1734
1735 case INDEX_op_qemu_ld_i32:
1736 return &r_A;
1737 case INDEX_op_qemu_ld_i64:
1738 return &R_A;
1739 case INDEX_op_qemu_st_i32:
1740 return &sZ_A;
1741 case INDEX_op_qemu_st_i64:
1742 return &SZ_A;
1743
1744 default:
1745 return NULL;
f69d277e 1746 }
f69d277e
RH
1747}
1748
e4d58b41 1749static void tcg_target_init(TCGContext *s)
8289b279 1750{
90379ca8
RH
1751 /* Only probe for the platform and capabilities if we havn't already
1752 determined maximum values at compile time. */
1753#ifndef use_vis3_instructions
1754 {
1755 unsigned long hwcap = qemu_getauxval(AT_HWCAP);
1756 use_vis3_instructions = (hwcap & HWCAP_SPARC_VIS3) != 0;
1757 }
1758#endif
1759
f46934df
RH
1760 tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
1761 tcg_target_available_regs[TCG_TYPE_I64] = ALL_64;
1762
1763 tcg_target_call_clobber_regs = 0;
1764 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G1);
1765 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G2);
1766 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G3);
1767 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G4);
1768 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G5);
1769 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G6);
1770 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_G7);
1771 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O0);
1772 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O1);
1773 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O2);
1774 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O3);
1775 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O4);
1776 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O5);
1777 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O6);
1778 tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_O7);
8289b279 1779
ccb1bb66 1780 s->reserved_regs = 0;
375816f8
RH
1781 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
1782 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
1783 tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
1784 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
1785 tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
1786 tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
1787 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
1788 tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
8289b279 1789}
cb1977d3 1790
9f44adc5 1791#if SPARC64
cb1977d3 1792# define ELF_HOST_MACHINE EM_SPARCV9
9b9c37c3 1793#else
cb1977d3
RH
1794# define ELF_HOST_MACHINE EM_SPARC32PLUS
1795# define ELF_HOST_FLAGS EF_SPARC_32PLUS
cb1977d3
RH
1796#endif
1797
cb1977d3 1798typedef struct {
ae18b28d 1799 DebugFrameHeader h;
9f44adc5 1800 uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
497a22eb
RH
1801 uint8_t fde_win_save;
1802 uint8_t fde_ret_save[3];
cb1977d3
RH
1803} DebugFrame;
1804
ae18b28d
RH
1805static const DebugFrame debug_frame = {
1806 .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1807 .h.cie.id = -1,
1808 .h.cie.version = 1,
1809 .h.cie.code_align = 1,
1810 .h.cie.data_align = -sizeof(void *) & 0x7f,
1811 .h.cie.return_column = 15, /* o7 */
cb1977d3 1812
497a22eb 1813 /* Total FDE size does not include the "len" member. */
ae18b28d 1814 .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
497a22eb
RH
1815
1816 .fde_def_cfa = {
9f44adc5 1817#if SPARC64
cb1977d3
RH
1818 12, 30, /* DW_CFA_def_cfa i6, 2047 */
1819 (2047 & 0x7f) | 0x80, (2047 >> 7)
1820#else
1821 13, 30 /* DW_CFA_def_cfa_register i6 */
1822#endif
1823 },
497a22eb
RH
1824 .fde_win_save = 0x2d, /* DW_CFA_GNU_window_save */
1825 .fde_ret_save = { 9, 15, 31 }, /* DW_CFA_register o7, i7 */
cb1977d3
RH
1826};
1827
1828void tcg_register_jit(void *buf, size_t buf_size)
1829{
cb1977d3
RH
1830 tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1831}
5bbd2cae 1832
a8583393
RH
1833void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,
1834 uintptr_t addr)
5bbd2cae 1835{
ab20bdc1
RH
1836 intptr_t tb_disp = addr - tc_ptr;
1837 intptr_t br_disp = addr - jmp_addr;
1838 tcg_insn_unit i1, i2;
1839
1840 /* We can reach the entire address space for ILP32.
1841 For LP64, the code_gen_buffer can't be larger than 2GB. */
1842 tcg_debug_assert(tb_disp == (int32_t)tb_disp);
1843 tcg_debug_assert(br_disp == (int32_t)br_disp);
1844
1845 if (!USE_REG_TB) {
1846 atomic_set((uint32_t *)jmp_addr, deposit32(CALL, 0, 30, br_disp >> 2));
1847 flush_icache_range(jmp_addr, jmp_addr + 4);
1848 return;
1849 }
5bbd2cae 1850
ab20bdc1
RH
1851 /* This does not exercise the range of the branch, but we do
1852 still need to be able to load the new value of TCG_REG_TB.
1853 But this does still happen quite often. */
1854 if (check_fit_ptr(tb_disp, 13)) {
1855 /* ba,pt %icc, addr */
1856 i1 = (INSN_OP(0) | INSN_OP2(1) | INSN_COND(COND_A)
1857 | BPCC_ICC | BPCC_PT | INSN_OFF19(br_disp));
1858 i2 = (ARITH_ADD | INSN_RD(TCG_REG_TB) | INSN_RS1(TCG_REG_TB)
1859 | INSN_IMM13(tb_disp));
1860 } else if (tb_disp >= 0) {
1861 i1 = SETHI | INSN_RD(TCG_REG_T1) | ((tb_disp & 0xfffffc00) >> 10);
1862 i2 = (ARITH_OR | INSN_RD(TCG_REG_T1) | INSN_RS1(TCG_REG_T1)
1863 | INSN_IMM13(tb_disp & 0x3ff));
1864 } else {
1865 i1 = SETHI | INSN_RD(TCG_REG_T1) | ((~tb_disp & 0xfffffc00) >> 10);
1866 i2 = (ARITH_XOR | INSN_RD(TCG_REG_T1) | INSN_RS1(TCG_REG_T1)
1867 | INSN_IMM13((tb_disp & 0x3ff) | -0x400));
1868 }
5bbd2cae 1869
ab20bdc1
RH
1870 atomic_set((uint64_t *)jmp_addr, deposit64(i2, 32, 32, i1));
1871 flush_icache_range(jmp_addr, jmp_addr + 8);
5bbd2cae 1872}