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