]> Git Repo - qemu.git/blob - tcg/sparc/tcg-target.c
tcg-sparc: Use ADDXC in addsub2_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, ret, c1, c2, c2const, ARITH_XOR);
678         }
679         c1 = TCG_REG_G0, c2 = ret, c2const = 0;
680         cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
681         break;
682
683     case TCG_COND_GTU:
684     case TCG_COND_LEU:
685         /* If we don't need to load a constant into a register, we can
686            swap the operands on GTU/LEU.  There's no benefit to loading
687            the constant into a temporary register.  */
688         if (!c2const || c2 == 0) {
689             TCGReg t = c1;
690             c1 = c2;
691             c2 = t;
692             c2const = 0;
693             cond = tcg_swap_cond(cond);
694             break;
695         }
696         /* FALLTHRU */
697
698     default:
699         tcg_out_cmp(s, c1, c2, c2const);
700         tcg_out_movi_imm13(s, ret, 0);
701         tcg_out_movcc(s, cond, MOVCC_ICC, ret, 1, 1);
702         return;
703     }
704
705     tcg_out_cmp(s, c1, c2, c2const);
706     if (cond == TCG_COND_LTU) {
707         tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX);
708     } else {
709         tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX);
710     }
711 }
712
713 static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGReg ret,
714                                 TCGReg c1, int32_t c2, int c2const)
715 {
716     /* For 64-bit signed comparisons vs zero, we can avoid the compare
717        if the input does not overlap the output.  */
718     if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
719         tcg_out_movi_imm13(s, ret, 0);
720         tcg_out_movr(s, cond, ret, c1, 1, 1);
721     } else {
722         tcg_out_cmp(s, c1, c2, c2const);
723         tcg_out_movi_imm13(s, ret, 0);
724         tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
725     }
726 }
727
728 static void tcg_out_addsub2_i32(TCGContext *s, TCGReg rl, TCGReg rh,
729                                 TCGReg al, TCGReg ah, int32_t bl, int blconst,
730                                 int32_t bh, int bhconst, int opl, int oph)
731 {
732     TCGReg tmp = TCG_REG_T1;
733
734     /* Note that the low parts are fully consumed before tmp is set.  */
735     if (rl != ah && (bhconst || rl != bh)) {
736         tmp = rl;
737     }
738
739     tcg_out_arithc(s, tmp, al, bl, blconst, opl);
740     tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
741     tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
742 }
743
744 static void tcg_out_addsub2_i64(TCGContext *s, TCGReg rl, TCGReg rh,
745                                 TCGReg al, TCGReg ah, int32_t bl, int blconst,
746                                 int32_t bh, int bhconst, bool is_sub)
747 {
748     TCGReg tmp = TCG_REG_T1;
749
750     /* Note that the low parts are fully consumed before tmp is set.  */
751     if (rl != ah && (bhconst || rl != bh)) {
752         tmp = rl;
753     }
754
755     tcg_out_arithc(s, tmp, al, bl, blconst, is_sub ? ARITH_SUBCC : ARITH_ADDCC);
756
757     if (use_vis3_instructions && !is_sub) {
758         /* Note that ADDXC doesn't accept immediates.  */
759         if (bhconst && bh != 0) {
760            tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh);
761            bh = TCG_REG_T2;
762         }
763         tcg_out_arith(s, rh, ah, bh, ARITH_ADDXC);
764     } else if (bh == TCG_REG_G0) {
765         /* If we have a zero, we can perform the operation in two insns,
766            with the arithmetic first, and a conditional move into place.  */
767         if (rh == ah) {
768             tcg_out_arithi(s, TCG_REG_T2, ah, 1,
769                            is_sub ? ARITH_SUB : ARITH_ADD);
770             tcg_out_movcc(s, TCG_COND_LTU, MOVCC_XCC, rh, TCG_REG_T2, 0);
771         } else {
772             tcg_out_arithi(s, rh, ah, 1, is_sub ? ARITH_SUB : ARITH_ADD);
773             tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, rh, ah, 0);
774         }
775     } else {
776         /* Otherwise adjust BH as if there is carry into T2 ... */
777         if (bhconst) {
778             tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_T2, bh + (is_sub ? -1 : 1));
779         } else {
780             tcg_out_arithi(s, TCG_REG_T2, bh, 1,
781                            is_sub ? ARITH_SUB : ARITH_ADD);
782         }
783         /* ... smoosh T2 back to original BH if carry is clear ... */
784         tcg_out_movcc(s, TCG_COND_GEU, MOVCC_XCC, TCG_REG_T2, bh, bhconst);
785         /* ... and finally perform the arithmetic with the new operand.  */
786         tcg_out_arith(s, rh, ah, TCG_REG_T2, is_sub ? ARITH_SUB : ARITH_ADD);
787     }
788
789     tcg_out_mov(s, TCG_TYPE_I64, rl, tmp);
790 }
791
792 static void tcg_out_call_nodelay(TCGContext *s, tcg_insn_unit *dest)
793 {
794     ptrdiff_t disp = tcg_pcrel_diff(s, dest);
795
796     if (disp == (int32_t)disp) {
797         tcg_out32(s, CALL | (uint32_t)disp >> 2);
798     } else {
799         uintptr_t desti = (uintptr_t)dest;
800         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, desti & ~0xfff);
801         tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, desti & 0xfff, JMPL);
802     }
803 }
804
805 static void tcg_out_call(TCGContext *s, tcg_insn_unit *dest)
806 {
807     tcg_out_call_nodelay(s, dest);
808     tcg_out_nop(s);
809 }
810
811 #ifdef CONFIG_SOFTMMU
812 static tcg_insn_unit *qemu_ld_trampoline[16];
813 static tcg_insn_unit *qemu_st_trampoline[16];
814
815 static void build_trampolines(TCGContext *s)
816 {
817     static void * const qemu_ld_helpers[16] = {
818         [MO_UB]   = helper_ret_ldub_mmu,
819         [MO_SB]   = helper_ret_ldsb_mmu,
820         [MO_LEUW] = helper_le_lduw_mmu,
821         [MO_LESW] = helper_le_ldsw_mmu,
822         [MO_LEUL] = helper_le_ldul_mmu,
823         [MO_LEQ]  = helper_le_ldq_mmu,
824         [MO_BEUW] = helper_be_lduw_mmu,
825         [MO_BESW] = helper_be_ldsw_mmu,
826         [MO_BEUL] = helper_be_ldul_mmu,
827         [MO_BEQ]  = helper_be_ldq_mmu,
828     };
829     static void * const qemu_st_helpers[16] = {
830         [MO_UB]   = helper_ret_stb_mmu,
831         [MO_LEUW] = helper_le_stw_mmu,
832         [MO_LEUL] = helper_le_stl_mmu,
833         [MO_LEQ]  = helper_le_stq_mmu,
834         [MO_BEUW] = helper_be_stw_mmu,
835         [MO_BEUL] = helper_be_stl_mmu,
836         [MO_BEQ]  = helper_be_stq_mmu,
837     };
838
839     int i;
840     TCGReg ra;
841
842     for (i = 0; i < 16; ++i) {
843         if (qemu_ld_helpers[i] == NULL) {
844             continue;
845         }
846
847         /* May as well align the trampoline.  */
848         while ((uintptr_t)s->code_ptr & 15) {
849             tcg_out_nop(s);
850         }
851         qemu_ld_trampoline[i] = s->code_ptr;
852
853         if (SPARC64 || TARGET_LONG_BITS == 32) {
854             ra = TCG_REG_O3;
855         } else {
856             /* Install the high part of the address.  */
857             tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);
858             ra = TCG_REG_O4;
859         }
860
861         /* Set the retaddr operand.  */
862         tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
863         /* Set the env operand.  */
864         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
865         /* Tail call.  */
866         tcg_out_call_nodelay(s, qemu_ld_helpers[i]);
867         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
868     }
869
870     for (i = 0; i < 16; ++i) {
871         if (qemu_st_helpers[i] == NULL) {
872             continue;
873         }
874
875         /* May as well align the trampoline.  */
876         while ((uintptr_t)s->code_ptr & 15) {
877             tcg_out_nop(s);
878         }
879         qemu_st_trampoline[i] = s->code_ptr;
880
881         if (SPARC64) {
882             ra = TCG_REG_O4;
883         } else {
884             ra = TCG_REG_O1;
885             if (TARGET_LONG_BITS == 64) {
886                 /* Install the high part of the address.  */
887                 tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
888                 ra += 2;
889             } else {
890                 ra += 1;
891             }
892             if ((i & MO_SIZE) == MO_64) {
893                 /* Install the high part of the data.  */
894                 tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);
895                 ra += 2;
896             } else {
897                 ra += 1;
898             }
899             /* Skip the mem_index argument.  */
900             ra += 1;
901         }
902                 
903         /* Set the retaddr operand.  */
904         if (ra >= TCG_REG_O6) {
905             tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
906                        TCG_TARGET_CALL_STACK_OFFSET);
907             ra = TCG_REG_G1;
908         }
909         tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
910         /* Set the env operand.  */
911         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
912         /* Tail call.  */
913         tcg_out_call_nodelay(s, qemu_st_helpers[i]);
914         tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
915     }
916 }
917 #endif
918
919 /* Generate global QEMU prologue and epilogue code */
920 static void tcg_target_qemu_prologue(TCGContext *s)
921 {
922     int tmp_buf_size, frame_size;
923
924     /* The TCG temp buffer is at the top of the frame, immediately
925        below the frame pointer.  */
926     tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
927     tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
928                   tmp_buf_size);
929
930     /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
931        otherwise the minimal frame usable by callees.  */
932     frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
933     frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
934     frame_size += TCG_TARGET_STACK_ALIGN - 1;
935     frame_size &= -TCG_TARGET_STACK_ALIGN;
936     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
937               INSN_IMM13(-frame_size));
938
939 #ifdef CONFIG_USE_GUEST_BASE
940     if (GUEST_BASE != 0) {
941         tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
942         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
943     }
944 #endif
945
946     tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
947     /* delay slot */
948     tcg_out_nop(s);
949
950     /* No epilogue required.  We issue ret + restore directly in the TB.  */
951
952 #ifdef CONFIG_SOFTMMU
953     build_trampolines(s);
954 #endif
955 }
956
957 #if defined(CONFIG_SOFTMMU)
958 /* Perform the TLB load and compare.
959
960    Inputs:
961    ADDRLO and ADDRHI contain the possible two parts of the address.
962
963    MEM_INDEX and S_BITS are the memory context and log2 size of the load.
964
965    WHICH is the offset into the CPUTLBEntry structure of the slot to read.
966    This should be offsetof addr_read or addr_write.
967
968    The result of the TLB comparison is in %[ix]cc.  The sanitized address
969    is in the returned register, maybe %o0.  The TLB addend is in %o1.  */
970
971 static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,
972                                TCGMemOp s_bits, int which)
973 {
974     const TCGReg r0 = TCG_REG_O0;
975     const TCGReg r1 = TCG_REG_O1;
976     const TCGReg r2 = TCG_REG_O2;
977     int tlb_ofs;
978
979     /* Shift the page number down.  */
980     tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);
981
982     /* Mask out the page offset, except for the required alignment.  */
983     tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
984                  TARGET_PAGE_MASK | ((1 << s_bits) - 1));
985
986     /* Mask the tlb index.  */
987     tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
988     
989     /* Mask page, part 2.  */
990     tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
991
992     /* Shift the tlb index into place.  */
993     tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
994
995     /* Relative to the current ENV.  */
996     tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
997
998     /* Find a base address that can load both tlb comparator and addend.  */
999     tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
1000     if (!check_fit_ptr(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
1001         if (tlb_ofs & ~0x3ff) {
1002             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, tlb_ofs & ~0x3ff);
1003             tcg_out_arith(s, r1, r1, TCG_REG_T1, ARITH_ADD);
1004         }
1005         tlb_ofs &= 0x3ff;
1006     }
1007
1008     /* Load the tlb comparator and the addend.  */
1009     tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
1010     tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
1011
1012     /* subcc arg0, arg2, %g0 */
1013     tcg_out_cmp(s, r0, r2, 0);
1014
1015     /* If the guest address must be zero-extended, do so now.  */
1016     if (SPARC64 && TARGET_LONG_BITS == 32) {
1017         tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);
1018         return r0;
1019     }
1020     return addr;
1021 }
1022 #endif /* CONFIG_SOFTMMU */
1023
1024 static const int qemu_ld_opc[16] = {
1025     [MO_UB]   = LDUB,
1026     [MO_SB]   = LDSB,
1027
1028     [MO_BEUW] = LDUH,
1029     [MO_BESW] = LDSH,
1030     [MO_BEUL] = LDUW,
1031     [MO_BESL] = LDSW,
1032     [MO_BEQ]  = LDX,
1033
1034     [MO_LEUW] = LDUH_LE,
1035     [MO_LESW] = LDSH_LE,
1036     [MO_LEUL] = LDUW_LE,
1037     [MO_LESL] = LDSW_LE,
1038     [MO_LEQ]  = LDX_LE,
1039 };
1040
1041 static const int qemu_st_opc[16] = {
1042     [MO_UB]   = STB,
1043
1044     [MO_BEUW] = STH,
1045     [MO_BEUL] = STW,
1046     [MO_BEQ]  = STX,
1047
1048     [MO_LEUW] = STH_LE,
1049     [MO_LEUL] = STW_LE,
1050     [MO_LEQ]  = STX_LE,
1051 };
1052
1053 static void tcg_out_qemu_ld(TCGContext *s, TCGReg data, TCGReg addr,
1054                             TCGMemOp memop, int memi, bool is_64)
1055 {
1056 #ifdef CONFIG_SOFTMMU
1057     TCGMemOp s_bits = memop & MO_SIZE;
1058     TCGReg addrz, param;
1059     tcg_insn_unit *func;
1060     tcg_insn_unit *label_ptr;
1061
1062     addrz = tcg_out_tlb_load(s, addr, memi, s_bits,
1063                              offsetof(CPUTLBEntry, addr_read));
1064
1065     /* The fast path is exactly one insn.  Thus we can perform the
1066        entire TLB Hit in the (annulled) delay slot of the branch
1067        over the TLB Miss case.  */
1068
1069     /* beq,a,pt %[xi]cc, label0 */
1070     label_ptr = s->code_ptr;
1071     tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1072                   | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1073     /* delay slot */
1074     tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
1075
1076     /* TLB Miss.  */
1077
1078     param = TCG_REG_O1;
1079     if (!SPARC64 && TARGET_LONG_BITS == 64) {
1080         /* Skip the high-part; we'll perform the extract in the trampoline.  */
1081         param++;
1082     }
1083     tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
1084
1085     /* We use the helpers to extend SB and SW data, leaving the case
1086        of SL needing explicit extending below.  */
1087     if ((memop & ~MO_BSWAP) == MO_SL) {
1088         func = qemu_ld_trampoline[memop & ~MO_SIGN];
1089     } else {
1090         func = qemu_ld_trampoline[memop];
1091     }
1092     assert(func != NULL);
1093     tcg_out_call_nodelay(s, func);
1094     /* delay slot */
1095     tcg_out_movi(s, TCG_TYPE_I32, param, memi);
1096
1097     /* Recall that all of the helpers return 64-bit results.
1098        Which complicates things for sparcv8plus.  */
1099     if (SPARC64) {
1100         /* We let the helper sign-extend SB and SW, but leave SL for here.  */
1101         if (is_64 && (memop & ~MO_BSWAP) == MO_SL) {
1102             tcg_out_arithi(s, data, TCG_REG_O0, 0, SHIFT_SRA);
1103         } else {
1104             tcg_out_mov(s, TCG_TYPE_REG, data, TCG_REG_O0);
1105         }
1106     } else {
1107         if (s_bits == MO_64) {
1108             tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, 32, SHIFT_SLLX);
1109             tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O1, 0, SHIFT_SRL);
1110             tcg_out_arith(s, data, TCG_REG_O0, TCG_REG_O1, ARITH_OR);
1111         } else if (is_64) {
1112             /* Re-extend from 32-bit rather than reassembling when we
1113                know the high register must be an extension.  */
1114             tcg_out_arithi(s, data, TCG_REG_O1, 0,
1115                            memop & MO_SIGN ? SHIFT_SRA : SHIFT_SRL);
1116         } else {
1117             tcg_out_mov(s, TCG_TYPE_I32, data, TCG_REG_O1);
1118         }
1119     }
1120
1121     *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1122 #else
1123     if (SPARC64 && TARGET_LONG_BITS == 32) {
1124         tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1125         addr = TCG_REG_T1;
1126     }
1127     tcg_out_ldst_rr(s, data, addr,
1128                     (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1129                     qemu_ld_opc[memop]);
1130 #endif /* CONFIG_SOFTMMU */
1131 }
1132
1133 static void tcg_out_qemu_st(TCGContext *s, TCGReg data, TCGReg addr,
1134                             TCGMemOp memop, int memi)
1135 {
1136 #ifdef CONFIG_SOFTMMU
1137     TCGMemOp s_bits = memop & MO_SIZE;
1138     TCGReg addrz, param;
1139     tcg_insn_unit *func;
1140     tcg_insn_unit *label_ptr;
1141
1142     addrz = tcg_out_tlb_load(s, addr, memi, s_bits,
1143                              offsetof(CPUTLBEntry, addr_write));
1144
1145     /* The fast path is exactly one insn.  Thus we can perform the entire
1146        TLB Hit in the (annulled) delay slot of the branch over TLB Miss.  */
1147     /* beq,a,pt %[xi]cc, label0 */
1148     label_ptr = s->code_ptr;
1149     tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
1150                   | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
1151     /* delay slot */
1152     tcg_out_ldst_rr(s, data, addrz, TCG_REG_O1, qemu_st_opc[memop]);
1153
1154     /* TLB Miss.  */
1155
1156     param = TCG_REG_O1;
1157     if (!SPARC64 && TARGET_LONG_BITS == 64) {
1158         /* Skip the high-part; we'll perform the extract in the trampoline.  */
1159         param++;
1160     }
1161     tcg_out_mov(s, TCG_TYPE_REG, param++, addr);
1162     if (!SPARC64 && s_bits == MO_64) {
1163         /* Skip the high-part; we'll perform the extract in the trampoline.  */
1164         param++;
1165     }
1166     tcg_out_mov(s, TCG_TYPE_REG, param++, data);
1167
1168     func = qemu_st_trampoline[memop];
1169     assert(func != NULL);
1170     tcg_out_call_nodelay(s, func);
1171     /* delay slot */
1172     tcg_out_movi(s, TCG_TYPE_REG, param, memi);
1173
1174     *label_ptr |= INSN_OFF19(tcg_ptr_byte_diff(s->code_ptr, label_ptr));
1175 #else
1176     if (SPARC64 && TARGET_LONG_BITS == 32) {
1177         tcg_out_arithi(s, TCG_REG_T1, addr, 0, SHIFT_SRL);
1178         addr = TCG_REG_T1;
1179     }
1180     tcg_out_ldst_rr(s, data, addr,
1181                     (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
1182                     qemu_st_opc[memop]);
1183 #endif /* CONFIG_SOFTMMU */
1184 }
1185
1186 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
1187                        const TCGArg args[TCG_MAX_OP_ARGS],
1188                        const int const_args[TCG_MAX_OP_ARGS])
1189 {
1190     TCGArg a0, a1, a2;
1191     int c, c2;
1192
1193     /* Hoist the loads of the most common arguments.  */
1194     a0 = args[0];
1195     a1 = args[1];
1196     a2 = args[2];
1197     c2 = const_args[2];
1198
1199     switch (opc) {
1200     case INDEX_op_exit_tb:
1201         if (check_fit_ptr(a0, 13)) {
1202             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1203             tcg_out_movi_imm13(s, TCG_REG_O0, a0);
1204         } else {
1205             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, a0 & ~0x3ff);
1206             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, RETURN);
1207             tcg_out_arithi(s, TCG_REG_O0, TCG_REG_O0, a0 & 0x3ff, ARITH_OR);
1208         }
1209         break;
1210     case INDEX_op_goto_tb:
1211         if (s->tb_jmp_offset) {
1212             /* direct jump method */
1213             s->tb_jmp_offset[a0] = tcg_current_code_size(s);
1214             /* Make sure to preserve links during retranslation.  */
1215             tcg_out32(s, CALL | (*s->code_ptr & ~INSN_OP(-1)));
1216         } else {
1217             /* indirect jump method */
1218             tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + a0));
1219             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
1220         }
1221         tcg_out_nop(s);
1222         s->tb_next_offset[a0] = tcg_current_code_size(s);
1223         break;
1224     case INDEX_op_br:
1225         tcg_out_bpcc(s, COND_A, BPCC_PT, a0);
1226         tcg_out_nop(s);
1227         break;
1228
1229 #define OP_32_64(x)                             \
1230         glue(glue(case INDEX_op_, x), _i32):    \
1231         glue(glue(case INDEX_op_, x), _i64)
1232
1233     OP_32_64(ld8u):
1234         tcg_out_ldst(s, a0, a1, a2, LDUB);
1235         break;
1236     OP_32_64(ld8s):
1237         tcg_out_ldst(s, a0, a1, a2, LDSB);
1238         break;
1239     OP_32_64(ld16u):
1240         tcg_out_ldst(s, a0, a1, a2, LDUH);
1241         break;
1242     OP_32_64(ld16s):
1243         tcg_out_ldst(s, a0, a1, a2, LDSH);
1244         break;
1245     case INDEX_op_ld_i32:
1246     case INDEX_op_ld32u_i64:
1247         tcg_out_ldst(s, a0, a1, a2, LDUW);
1248         break;
1249     OP_32_64(st8):
1250         tcg_out_ldst(s, a0, a1, a2, STB);
1251         break;
1252     OP_32_64(st16):
1253         tcg_out_ldst(s, a0, a1, a2, STH);
1254         break;
1255     case INDEX_op_st_i32:
1256     case INDEX_op_st32_i64:
1257         tcg_out_ldst(s, a0, a1, a2, STW);
1258         break;
1259     OP_32_64(add):
1260         c = ARITH_ADD;
1261         goto gen_arith;
1262     OP_32_64(sub):
1263         c = ARITH_SUB;
1264         goto gen_arith;
1265     OP_32_64(and):
1266         c = ARITH_AND;
1267         goto gen_arith;
1268     OP_32_64(andc):
1269         c = ARITH_ANDN;
1270         goto gen_arith;
1271     OP_32_64(or):
1272         c = ARITH_OR;
1273         goto gen_arith;
1274     OP_32_64(orc):
1275         c = ARITH_ORN;
1276         goto gen_arith;
1277     OP_32_64(xor):
1278         c = ARITH_XOR;
1279         goto gen_arith;
1280     case INDEX_op_shl_i32:
1281         c = SHIFT_SLL;
1282     do_shift32:
1283         /* Limit immediate shift count lest we create an illegal insn.  */
1284         tcg_out_arithc(s, a0, a1, a2 & 31, c2, c);
1285         break;
1286     case INDEX_op_shr_i32:
1287         c = SHIFT_SRL;
1288         goto do_shift32;
1289     case INDEX_op_sar_i32:
1290         c = SHIFT_SRA;
1291         goto do_shift32;
1292     case INDEX_op_mul_i32:
1293         c = ARITH_UMUL;
1294         goto gen_arith;
1295
1296     OP_32_64(neg):
1297         c = ARITH_SUB;
1298         goto gen_arith1;
1299     OP_32_64(not):
1300         c = ARITH_ORN;
1301         goto gen_arith1;
1302
1303     case INDEX_op_div_i32:
1304         tcg_out_div32(s, a0, a1, a2, c2, 0);
1305         break;
1306     case INDEX_op_divu_i32:
1307         tcg_out_div32(s, a0, a1, a2, c2, 1);
1308         break;
1309
1310     case INDEX_op_brcond_i32:
1311         tcg_out_brcond_i32(s, a2, a0, a1, const_args[1], args[3]);
1312         break;
1313     case INDEX_op_setcond_i32:
1314         tcg_out_setcond_i32(s, args[3], a0, a1, a2, c2);
1315         break;
1316     case INDEX_op_movcond_i32:
1317         tcg_out_movcond_i32(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1318         break;
1319
1320     case INDEX_op_add2_i32:
1321         tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1322                             args[4], const_args[4], args[5], const_args[5],
1323                             ARITH_ADDCC, ARITH_ADDX);
1324         break;
1325     case INDEX_op_sub2_i32:
1326         tcg_out_addsub2_i32(s, args[0], args[1], args[2], args[3],
1327                             args[4], const_args[4], args[5], const_args[5],
1328                             ARITH_SUBCC, ARITH_SUBX);
1329         break;
1330     case INDEX_op_mulu2_i32:
1331         c = ARITH_UMUL;
1332         goto do_mul2;
1333     case INDEX_op_muls2_i32:
1334         c = ARITH_SMUL;
1335     do_mul2:
1336         /* The 32-bit multiply insns produce a full 64-bit result.  If the
1337            destination register can hold it, we can avoid the slower RDY.  */
1338         tcg_out_arithc(s, a0, a2, args[3], const_args[3], c);
1339         if (SPARC64 || a0 <= TCG_REG_O7) {
1340             tcg_out_arithi(s, a1, a0, 32, SHIFT_SRLX);
1341         } else {
1342             tcg_out_rdy(s, a1);
1343         }
1344         break;
1345
1346     case INDEX_op_qemu_ld_i32:
1347         tcg_out_qemu_ld(s, a0, a1, a2, args[3], false);
1348         break;
1349     case INDEX_op_qemu_ld_i64:
1350         tcg_out_qemu_ld(s, a0, a1, a2, args[3], true);
1351         break;
1352     case INDEX_op_qemu_st_i32:
1353     case INDEX_op_qemu_st_i64:
1354         tcg_out_qemu_st(s, a0, a1, a2, args[3]);
1355         break;
1356
1357     case INDEX_op_ld32s_i64:
1358         tcg_out_ldst(s, a0, a1, a2, LDSW);
1359         break;
1360     case INDEX_op_ld_i64:
1361         tcg_out_ldst(s, a0, a1, a2, LDX);
1362         break;
1363     case INDEX_op_st_i64:
1364         tcg_out_ldst(s, a0, a1, a2, STX);
1365         break;
1366     case INDEX_op_shl_i64:
1367         c = SHIFT_SLLX;
1368     do_shift64:
1369         /* Limit immediate shift count lest we create an illegal insn.  */
1370         tcg_out_arithc(s, a0, a1, a2 & 63, c2, c);
1371         break;
1372     case INDEX_op_shr_i64:
1373         c = SHIFT_SRLX;
1374         goto do_shift64;
1375     case INDEX_op_sar_i64:
1376         c = SHIFT_SRAX;
1377         goto do_shift64;
1378     case INDEX_op_mul_i64:
1379         c = ARITH_MULX;
1380         goto gen_arith;
1381     case INDEX_op_div_i64:
1382         c = ARITH_SDIVX;
1383         goto gen_arith;
1384     case INDEX_op_divu_i64:
1385         c = ARITH_UDIVX;
1386         goto gen_arith;
1387     case INDEX_op_ext32s_i64:
1388         tcg_out_arithi(s, a0, a1, 0, SHIFT_SRA);
1389         break;
1390     case INDEX_op_ext32u_i64:
1391         tcg_out_arithi(s, a0, a1, 0, SHIFT_SRL);
1392         break;
1393     case INDEX_op_trunc_shr_i32:
1394         if (a2 == 0) {
1395             tcg_out_mov(s, TCG_TYPE_I32, a0, a1);
1396         } else {
1397             tcg_out_arithi(s, a0, a1, a2, SHIFT_SRLX);
1398         }
1399         break;
1400
1401     case INDEX_op_brcond_i64:
1402         tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], args[3]);
1403         break;
1404     case INDEX_op_setcond_i64:
1405         tcg_out_setcond_i64(s, args[3], a0, a1, a2, c2);
1406         break;
1407     case INDEX_op_movcond_i64:
1408         tcg_out_movcond_i64(s, args[5], a0, a1, a2, c2, args[3], const_args[3]);
1409         break;
1410     case INDEX_op_add2_i64:
1411         tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1412                             const_args[4], args[5], const_args[5], false);
1413         break;
1414     case INDEX_op_sub2_i64:
1415         tcg_out_addsub2_i64(s, args[0], args[1], args[2], args[3], args[4],
1416                             const_args[4], args[5], const_args[5], true);
1417         break;
1418
1419     gen_arith:
1420         tcg_out_arithc(s, a0, a1, a2, c2, c);
1421         break;
1422
1423     gen_arith1:
1424         tcg_out_arithc(s, a0, TCG_REG_G0, a1, const_args[1], c);
1425         break;
1426
1427     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
1428     case INDEX_op_mov_i64:
1429     case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi.  */
1430     case INDEX_op_movi_i64:
1431     case INDEX_op_call:     /* Always emitted via tcg_out_call.  */
1432     default:
1433         tcg_abort();
1434     }
1435 }
1436
1437 static const TCGTargetOpDef sparc_op_defs[] = {
1438     { INDEX_op_exit_tb, { } },
1439     { INDEX_op_goto_tb, { } },
1440     { INDEX_op_br, { } },
1441
1442     { INDEX_op_ld8u_i32, { "r", "r" } },
1443     { INDEX_op_ld8s_i32, { "r", "r" } },
1444     { INDEX_op_ld16u_i32, { "r", "r" } },
1445     { INDEX_op_ld16s_i32, { "r", "r" } },
1446     { INDEX_op_ld_i32, { "r", "r" } },
1447     { INDEX_op_st8_i32, { "rZ", "r" } },
1448     { INDEX_op_st16_i32, { "rZ", "r" } },
1449     { INDEX_op_st_i32, { "rZ", "r" } },
1450
1451     { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1452     { INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
1453     { INDEX_op_div_i32, { "r", "rZ", "rJ" } },
1454     { INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
1455     { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1456     { INDEX_op_and_i32, { "r", "rZ", "rJ" } },
1457     { INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
1458     { INDEX_op_or_i32, { "r", "rZ", "rJ" } },
1459     { INDEX_op_orc_i32, { "r", "rZ", "rJ" } },
1460     { INDEX_op_xor_i32, { "r", "rZ", "rJ" } },
1461
1462     { INDEX_op_shl_i32, { "r", "rZ", "rJ" } },
1463     { INDEX_op_shr_i32, { "r", "rZ", "rJ" } },
1464     { INDEX_op_sar_i32, { "r", "rZ", "rJ" } },
1465
1466     { INDEX_op_neg_i32, { "r", "rJ" } },
1467     { INDEX_op_not_i32, { "r", "rJ" } },
1468
1469     { INDEX_op_brcond_i32, { "rZ", "rJ" } },
1470     { INDEX_op_setcond_i32, { "r", "rZ", "rJ" } },
1471     { INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } },
1472
1473     { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1474     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1475     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } },
1476     { INDEX_op_muls2_i32, { "r", "r", "rZ", "rJ" } },
1477
1478     { INDEX_op_ld8u_i64, { "R", "r" } },
1479     { INDEX_op_ld8s_i64, { "R", "r" } },
1480     { INDEX_op_ld16u_i64, { "R", "r" } },
1481     { INDEX_op_ld16s_i64, { "R", "r" } },
1482     { INDEX_op_ld32u_i64, { "R", "r" } },
1483     { INDEX_op_ld32s_i64, { "R", "r" } },
1484     { INDEX_op_ld_i64, { "R", "r" } },
1485     { INDEX_op_st8_i64, { "RZ", "r" } },
1486     { INDEX_op_st16_i64, { "RZ", "r" } },
1487     { INDEX_op_st32_i64, { "RZ", "r" } },
1488     { INDEX_op_st_i64, { "RZ", "r" } },
1489
1490     { INDEX_op_add_i64, { "R", "RZ", "RJ" } },
1491     { INDEX_op_mul_i64, { "R", "RZ", "RJ" } },
1492     { INDEX_op_div_i64, { "R", "RZ", "RJ" } },
1493     { INDEX_op_divu_i64, { "R", "RZ", "RJ" } },
1494     { INDEX_op_sub_i64, { "R", "RZ", "RJ" } },
1495     { INDEX_op_and_i64, { "R", "RZ", "RJ" } },
1496     { INDEX_op_andc_i64, { "R", "RZ", "RJ" } },
1497     { INDEX_op_or_i64, { "R", "RZ", "RJ" } },
1498     { INDEX_op_orc_i64, { "R", "RZ", "RJ" } },
1499     { INDEX_op_xor_i64, { "R", "RZ", "RJ" } },
1500
1501     { INDEX_op_shl_i64, { "R", "RZ", "RJ" } },
1502     { INDEX_op_shr_i64, { "R", "RZ", "RJ" } },
1503     { INDEX_op_sar_i64, { "R", "RZ", "RJ" } },
1504
1505     { INDEX_op_neg_i64, { "R", "RJ" } },
1506     { INDEX_op_not_i64, { "R", "RJ" } },
1507
1508     { INDEX_op_ext32s_i64, { "R", "r" } },
1509     { INDEX_op_ext32u_i64, { "R", "r" } },
1510     { INDEX_op_trunc_shr_i32,  { "r", "R" } },
1511
1512     { INDEX_op_brcond_i64, { "RZ", "RJ" } },
1513     { INDEX_op_setcond_i64, { "R", "RZ", "RJ" } },
1514     { INDEX_op_movcond_i64, { "R", "RZ", "RJ", "RI", "0" } },
1515
1516     { INDEX_op_add2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } },
1517     { INDEX_op_sub2_i64, { "R", "R", "RZ", "RZ", "RJ", "RI" } },
1518
1519     { INDEX_op_qemu_ld_i32, { "r", "A" } },
1520     { INDEX_op_qemu_ld_i64, { "R", "A" } },
1521     { INDEX_op_qemu_st_i32, { "sZ", "A" } },
1522     { INDEX_op_qemu_st_i64, { "SZ", "A" } },
1523
1524     { -1 },
1525 };
1526
1527 static void tcg_target_init(TCGContext *s)
1528 {
1529     /* Only probe for the platform and capabilities if we havn't already
1530        determined maximum values at compile time.  */
1531 #ifndef use_vis3_instructions
1532     {
1533         unsigned long hwcap = qemu_getauxval(AT_HWCAP);
1534         use_vis3_instructions = (hwcap & HWCAP_SPARC_VIS3) != 0;
1535     }
1536 #endif
1537
1538     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1539     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, ALL_64);
1540
1541     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1542                      (1 << TCG_REG_G1) |
1543                      (1 << TCG_REG_G2) |
1544                      (1 << TCG_REG_G3) |
1545                      (1 << TCG_REG_G4) |
1546                      (1 << TCG_REG_G5) |
1547                      (1 << TCG_REG_G6) |
1548                      (1 << TCG_REG_G7) |
1549                      (1 << TCG_REG_O0) |
1550                      (1 << TCG_REG_O1) |
1551                      (1 << TCG_REG_O2) |
1552                      (1 << TCG_REG_O3) |
1553                      (1 << TCG_REG_O4) |
1554                      (1 << TCG_REG_O5) |
1555                      (1 << TCG_REG_O7));
1556
1557     tcg_regset_clear(s->reserved_regs);
1558     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
1559     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
1560     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
1561     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
1562     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
1563     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
1564     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
1565     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
1566
1567     tcg_add_target_add_op_defs(sparc_op_defs);
1568 }
1569
1570 #if SPARC64
1571 # define ELF_HOST_MACHINE  EM_SPARCV9
1572 #else
1573 # define ELF_HOST_MACHINE  EM_SPARC32PLUS
1574 # define ELF_HOST_FLAGS    EF_SPARC_32PLUS
1575 #endif
1576
1577 typedef struct {
1578     DebugFrameHeader h;
1579     uint8_t fde_def_cfa[SPARC64 ? 4 : 2];
1580     uint8_t fde_win_save;
1581     uint8_t fde_ret_save[3];
1582 } DebugFrame;
1583
1584 static const DebugFrame debug_frame = {
1585     .h.cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1586     .h.cie.id = -1,
1587     .h.cie.version = 1,
1588     .h.cie.code_align = 1,
1589     .h.cie.data_align = -sizeof(void *) & 0x7f,
1590     .h.cie.return_column = 15,            /* o7 */
1591
1592     /* Total FDE size does not include the "len" member.  */
1593     .h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
1594
1595     .fde_def_cfa = {
1596 #if SPARC64
1597         12, 30,                         /* DW_CFA_def_cfa i6, 2047 */
1598         (2047 & 0x7f) | 0x80, (2047 >> 7)
1599 #else
1600         13, 30                          /* DW_CFA_def_cfa_register i6 */
1601 #endif
1602     },
1603     .fde_win_save = 0x2d,               /* DW_CFA_GNU_window_save */
1604     .fde_ret_save = { 9, 15, 31 },      /* DW_CFA_register o7, i7 */
1605 };
1606
1607 void tcg_register_jit(void *buf, size_t buf_size)
1608 {
1609     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1610 }
1611
1612 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
1613 {
1614     uint32_t *ptr = (uint32_t *)jmp_addr;
1615     uintptr_t disp = addr - jmp_addr;
1616
1617     /* We can reach the entire address space for 32-bit.  For 64-bit
1618        the code_gen_buffer can't be larger than 2GB.  */
1619     assert(disp == (int32_t)disp);
1620
1621     *ptr = CALL | (uint32_t)disp >> 2;
1622     flush_icache_range(jmp_addr, jmp_addr + 4);
1623 }
This page took 0.117147 seconds and 4 git commands to generate.