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