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