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