]> Git Repo - qemu.git/blob - tcg/sparc/tcg-target.c
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
[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 #ifndef NDEBUG
26 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
27     "%g0",
28     "%g1",
29     "%g2",
30     "%g3",
31     "%g4",
32     "%g5",
33     "%g6",
34     "%g7",
35     "%o0",
36     "%o1",
37     "%o2",
38     "%o3",
39     "%o4",
40     "%o5",
41     "%o6",
42     "%o7",
43     "%l0",
44     "%l1",
45     "%l2",
46     "%l3",
47     "%l4",
48     "%l5",
49     "%l6",
50     "%l7",
51     "%i0",
52     "%i1",
53     "%i2",
54     "%i3",
55     "%i4",
56     "%i5",
57     "%i6",
58     "%i7",
59 };
60 #endif
61
62 #ifdef CONFIG_TCG_PASS_AREG0
63 #define ARG_OFFSET 1
64 #else
65 #define ARG_OFFSET 0
66 #endif
67
68 static const int tcg_target_reg_alloc_order[] = {
69     TCG_REG_L0,
70     TCG_REG_L1,
71     TCG_REG_L2,
72     TCG_REG_L3,
73     TCG_REG_L4,
74     TCG_REG_L5,
75     TCG_REG_L6,
76     TCG_REG_L7,
77     TCG_REG_I0,
78     TCG_REG_I1,
79     TCG_REG_I2,
80     TCG_REG_I3,
81     TCG_REG_I4,
82 };
83
84 static const int tcg_target_call_iarg_regs[6] = {
85     TCG_REG_O0,
86     TCG_REG_O1,
87     TCG_REG_O2,
88     TCG_REG_O3,
89     TCG_REG_O4,
90     TCG_REG_O5,
91 };
92
93 static const int tcg_target_call_oarg_regs[] = {
94     TCG_REG_O0,
95     TCG_REG_O1,
96     TCG_REG_O2,
97     TCG_REG_O3,
98 };
99
100 static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
101 {
102     return (val << ((sizeof(tcg_target_long) * 8 - bits))
103             >> (sizeof(tcg_target_long) * 8 - bits)) == val;
104 }
105
106 static inline int check_fit_i32(uint32_t val, unsigned int bits)
107 {
108     return ((val << (32 - bits)) >> (32 - bits)) == val;
109 }
110
111 static void patch_reloc(uint8_t *code_ptr, int type,
112                         tcg_target_long value, tcg_target_long addend)
113 {
114     value += addend;
115     switch (type) {
116     case R_SPARC_32:
117         if (value != (uint32_t)value)
118             tcg_abort();
119         *(uint32_t *)code_ptr = value;
120         break;
121     case R_SPARC_WDISP22:
122         value -= (long)code_ptr;
123         value >>= 2;
124         if (!check_fit_tl(value, 22))
125             tcg_abort();
126         *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
127         break;
128     case R_SPARC_WDISP19:
129         value -= (long)code_ptr;
130         value >>= 2;
131         if (!check_fit_tl(value, 19))
132             tcg_abort();
133         *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x7ffff) | value;
134         break;
135     default:
136         tcg_abort();
137     }
138 }
139
140 /* maximum number of register used for input function arguments */
141 static inline int tcg_target_get_call_iarg_regs_count(int flags)
142 {
143     return 6;
144 }
145
146 /* parse target specific constraints */
147 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
148 {
149     const char *ct_str;
150
151     ct_str = *pct_str;
152     switch (ct_str[0]) {
153     case 'r':
154         ct->ct |= TCG_CT_REG;
155         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
156         break;
157     case 'L': /* qemu_ld/st constraint */
158         ct->ct |= TCG_CT_REG;
159         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
160         // Helper args
161         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
162         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
163         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
164 #ifdef CONFIG_TCG_PASS_AREG0
165         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
166 #endif
167         break;
168     case 'I':
169         ct->ct |= TCG_CT_CONST_S11;
170         break;
171     case 'J':
172         ct->ct |= TCG_CT_CONST_S13;
173         break;
174     default:
175         return -1;
176     }
177     ct_str++;
178     *pct_str = ct_str;
179     return 0;
180 }
181
182 /* test if a constant matches the constraint */
183 static inline int tcg_target_const_match(tcg_target_long val,
184                                          const TCGArgConstraint *arg_ct)
185 {
186     int ct;
187
188     ct = arg_ct->ct;
189     if (ct & TCG_CT_CONST)
190         return 1;
191     else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
192         return 1;
193     else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
194         return 1;
195     else
196         return 0;
197 }
198
199 #define INSN_OP(x)  ((x) << 30)
200 #define INSN_OP2(x) ((x) << 22)
201 #define INSN_OP3(x) ((x) << 19)
202 #define INSN_OPF(x) ((x) << 5)
203 #define INSN_RD(x)  ((x) << 25)
204 #define INSN_RS1(x) ((x) << 14)
205 #define INSN_RS2(x) (x)
206 #define INSN_ASI(x) ((x) << 5)
207
208 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
209 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
210 #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
211 #define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
212
213 #define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
214 #define COND_N     0x0
215 #define COND_E     0x1
216 #define COND_LE    0x2
217 #define COND_L     0x3
218 #define COND_LEU   0x4
219 #define COND_CS    0x5
220 #define COND_NEG   0x6
221 #define COND_VS    0x7
222 #define COND_A     0x8
223 #define COND_NE    0x9
224 #define COND_G     0xa
225 #define COND_GE    0xb
226 #define COND_GU    0xc
227 #define COND_CC    0xd
228 #define COND_POS   0xe
229 #define COND_VC    0xf
230 #define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
231
232 #define MOVCC_ICC  (1 << 18)
233 #define MOVCC_XCC  (1 << 18 | 1 << 12)
234
235 #define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
236 #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
237 #define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
238 #define ARITH_ANDN (INSN_OP(2) | INSN_OP3(0x05))
239 #define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
240 #define ARITH_ORCC (INSN_OP(2) | INSN_OP3(0x12))
241 #define ARITH_ORN  (INSN_OP(2) | INSN_OP3(0x06))
242 #define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
243 #define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
244 #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
245 #define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
246 #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
247 #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
248 #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
249 #define ARITH_SDIV (INSN_OP(2) | INSN_OP3(0x0f))
250 #define ARITH_MULX (INSN_OP(2) | INSN_OP3(0x09))
251 #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
252 #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
253 #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
254
255 #define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
256 #define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
257 #define SHIFT_SRA  (INSN_OP(2) | INSN_OP3(0x27))
258
259 #define SHIFT_SLLX (INSN_OP(2) | INSN_OP3(0x25) | (1 << 12))
260 #define SHIFT_SRLX (INSN_OP(2) | INSN_OP3(0x26) | (1 << 12))
261 #define SHIFT_SRAX (INSN_OP(2) | INSN_OP3(0x27) | (1 << 12))
262
263 #define RDY        (INSN_OP(2) | INSN_OP3(0x28) | INSN_RS1(0))
264 #define WRY        (INSN_OP(2) | INSN_OP3(0x30) | INSN_RD(0))
265 #define JMPL       (INSN_OP(2) | INSN_OP3(0x38))
266 #define SAVE       (INSN_OP(2) | INSN_OP3(0x3c))
267 #define RESTORE    (INSN_OP(2) | INSN_OP3(0x3d))
268 #define SETHI      (INSN_OP(0) | INSN_OP2(0x4))
269 #define CALL       INSN_OP(1)
270 #define LDUB       (INSN_OP(3) | INSN_OP3(0x01))
271 #define LDSB       (INSN_OP(3) | INSN_OP3(0x09))
272 #define LDUH       (INSN_OP(3) | INSN_OP3(0x02))
273 #define LDSH       (INSN_OP(3) | INSN_OP3(0x0a))
274 #define LDUW       (INSN_OP(3) | INSN_OP3(0x00))
275 #define LDSW       (INSN_OP(3) | INSN_OP3(0x08))
276 #define LDX        (INSN_OP(3) | INSN_OP3(0x0b))
277 #define STB        (INSN_OP(3) | INSN_OP3(0x05))
278 #define STH        (INSN_OP(3) | INSN_OP3(0x06))
279 #define STW        (INSN_OP(3) | INSN_OP3(0x04))
280 #define STX        (INSN_OP(3) | INSN_OP3(0x0e))
281 #define LDUBA      (INSN_OP(3) | INSN_OP3(0x11))
282 #define LDSBA      (INSN_OP(3) | INSN_OP3(0x19))
283 #define LDUHA      (INSN_OP(3) | INSN_OP3(0x12))
284 #define LDSHA      (INSN_OP(3) | INSN_OP3(0x1a))
285 #define LDUWA      (INSN_OP(3) | INSN_OP3(0x10))
286 #define LDSWA      (INSN_OP(3) | INSN_OP3(0x18))
287 #define LDXA       (INSN_OP(3) | INSN_OP3(0x1b))
288 #define STBA       (INSN_OP(3) | INSN_OP3(0x15))
289 #define STHA       (INSN_OP(3) | INSN_OP3(0x16))
290 #define STWA       (INSN_OP(3) | INSN_OP3(0x14))
291 #define STXA       (INSN_OP(3) | INSN_OP3(0x1e))
292
293 #ifndef ASI_PRIMARY_LITTLE
294 #define ASI_PRIMARY_LITTLE 0x88
295 #endif
296
297 static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
298                                  int op)
299 {
300     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
301               INSN_RS2(rs2));
302 }
303
304 static inline void tcg_out_arithi(TCGContext *s, int rd, int rs1,
305                                   uint32_t offset, int op)
306 {
307     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1) |
308               INSN_IMM13(offset));
309 }
310
311 static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
312                            int val2, int val2const, int op)
313 {
314     tcg_out32(s, op | INSN_RD(rd) | INSN_RS1(rs1)
315               | (val2const ? INSN_IMM13(val2) : INSN_RS2(val2)));
316 }
317
318 static inline void tcg_out_mov(TCGContext *s, TCGType type,
319                                TCGReg ret, TCGReg arg)
320 {
321     tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
322 }
323
324 static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
325 {
326     tcg_out32(s, SETHI | INSN_RD(ret) | ((arg & 0xfffffc00) >> 10));
327 }
328
329 static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
330 {
331     tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
332 }
333
334 static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
335 {
336     if (check_fit_tl(arg, 13))
337         tcg_out_movi_imm13(s, ret, arg);
338     else {
339         tcg_out_sethi(s, ret, arg);
340         if (arg & 0x3ff)
341             tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
342     }
343 }
344
345 static inline void tcg_out_movi(TCGContext *s, TCGType type,
346                                 TCGReg ret, tcg_target_long arg)
347 {
348     /* All 32-bit constants, as well as 64-bit constants with
349        no high bits set go through movi_imm32.  */
350     if (TCG_TARGET_REG_BITS == 32
351         || type == TCG_TYPE_I32
352         || (arg & ~(tcg_target_long)0xffffffff) == 0) {
353         tcg_out_movi_imm32(s, ret, arg);
354     } else if (check_fit_tl(arg, 13)) {
355         /* A 13-bit constant sign-extended to 64-bits.  */
356         tcg_out_movi_imm13(s, ret, arg);
357     } else if (check_fit_tl(arg, 32)) {
358         /* A 32-bit constant sign-extended to 64-bits.  */
359         tcg_out_sethi(s, ret, ~arg);
360         tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
361     } else {
362         tcg_out_movi_imm32(s, TCG_REG_I4, arg >> (TCG_TARGET_REG_BITS / 2));
363         tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
364         tcg_out_movi_imm32(s, ret, arg);
365         tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
366     }
367 }
368
369 static inline void tcg_out_ld_raw(TCGContext *s, int ret,
370                                   tcg_target_long arg)
371 {
372     tcg_out_sethi(s, ret, arg);
373     tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
374               INSN_IMM13(arg & 0x3ff));
375 }
376
377 static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
378                                   tcg_target_long arg)
379 {
380     if (!check_fit_tl(arg, 10))
381         tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
382     if (TCG_TARGET_REG_BITS == 64) {
383         tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
384                   INSN_IMM13(arg & 0x3ff));
385     } else {
386         tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
387                   INSN_IMM13(arg & 0x3ff));
388     }
389 }
390
391 static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
392 {
393     if (check_fit_tl(offset, 13))
394         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
395                   INSN_IMM13(offset));
396     else {
397         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
398         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
399                   INSN_RS2(addr));
400     }
401 }
402
403 static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
404                                     int offset, int op, int asi)
405 {
406     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
407     tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
408               INSN_ASI(asi) | INSN_RS2(addr));
409 }
410
411 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
412                               TCGReg arg1, tcg_target_long arg2)
413 {
414     if (type == TCG_TYPE_I32)
415         tcg_out_ldst(s, ret, arg1, arg2, LDUW);
416     else
417         tcg_out_ldst(s, ret, arg1, arg2, LDX);
418 }
419
420 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
421                               TCGReg arg1, tcg_target_long arg2)
422 {
423     if (type == TCG_TYPE_I32)
424         tcg_out_ldst(s, arg, arg1, arg2, STW);
425     else
426         tcg_out_ldst(s, arg, arg1, arg2, STX);
427 }
428
429 static inline void tcg_out_sety(TCGContext *s, int rs)
430 {
431     tcg_out32(s, WRY | INSN_RS1(TCG_REG_G0) | INSN_RS2(rs));
432 }
433
434 static inline void tcg_out_rdy(TCGContext *s, int rd)
435 {
436     tcg_out32(s, RDY | INSN_RD(rd));
437 }
438
439 static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
440 {
441     if (val != 0) {
442         if (check_fit_tl(val, 13))
443             tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
444         else {
445             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
446             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
447         }
448     }
449 }
450
451 static inline void tcg_out_andi(TCGContext *s, int reg, tcg_target_long val)
452 {
453     if (val != 0) {
454         if (check_fit_tl(val, 13))
455             tcg_out_arithi(s, reg, reg, val, ARITH_AND);
456         else {
457             tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
458             tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
459         }
460     }
461 }
462
463 static void tcg_out_div32(TCGContext *s, int rd, int rs1,
464                           int val2, int val2const, int uns)
465 {
466     /* Load Y with the sign/zero extension of RS1 to 64-bits.  */
467     if (uns) {
468         tcg_out_sety(s, TCG_REG_G0);
469     } else {
470         tcg_out_arithi(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
471         tcg_out_sety(s, TCG_REG_I5);
472     }
473
474     tcg_out_arithc(s, rd, rs1, val2, val2const,
475                    uns ? ARITH_UDIV : ARITH_SDIV);
476 }
477
478 static inline void tcg_out_nop(TCGContext *s)
479 {
480     tcg_out_sethi(s, TCG_REG_G0, 0);
481 }
482
483 static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
484 {
485     TCGLabel *l = &s->labels[label_index];
486
487     if (l->has_value) {
488         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
489                       | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
490     } else {
491         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
492         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
493     }
494 }
495
496 #if TCG_TARGET_REG_BITS == 64
497 static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
498 {
499     TCGLabel *l = &s->labels[label_index];
500
501     if (l->has_value) {
502         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
503                       (0x5 << 19) |
504                       INSN_OFF19(l->u.value - (unsigned long)s->code_ptr)));
505     } else {
506         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
507         tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
508                       (0x5 << 19) | 0));
509     }
510 }
511 #endif
512
513 static const uint8_t tcg_cond_to_bcond[10] = {
514     [TCG_COND_EQ] = COND_E,
515     [TCG_COND_NE] = COND_NE,
516     [TCG_COND_LT] = COND_L,
517     [TCG_COND_GE] = COND_GE,
518     [TCG_COND_LE] = COND_LE,
519     [TCG_COND_GT] = COND_G,
520     [TCG_COND_LTU] = COND_CS,
521     [TCG_COND_GEU] = COND_CC,
522     [TCG_COND_LEU] = COND_LEU,
523     [TCG_COND_GTU] = COND_GU,
524 };
525
526 static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
527 {
528     tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
529 }
530
531 static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond,
532                                TCGArg arg1, TCGArg arg2, int const_arg2,
533                                int label_index)
534 {
535     tcg_out_cmp(s, arg1, arg2, const_arg2);
536     tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index);
537     tcg_out_nop(s);
538 }
539
540 #if TCG_TARGET_REG_BITS == 64
541 static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
542                                TCGArg arg1, TCGArg arg2, int const_arg2,
543                                int label_index)
544 {
545     tcg_out_cmp(s, arg1, arg2, const_arg2);
546     tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index);
547     tcg_out_nop(s);
548 }
549 #else
550 static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
551                                 TCGArg al, TCGArg ah,
552                                 TCGArg bl, int blconst,
553                                 TCGArg bh, int bhconst, int label_dest)
554 {
555     int cc, label_next = gen_new_label();
556
557     tcg_out_cmp(s, ah, bh, bhconst);
558
559     /* Note that we fill one of the delay slots with the second compare.  */
560     switch (cond) {
561     case TCG_COND_EQ:
562         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
563         tcg_out_branch_i32(s, cc, label_next);
564         tcg_out_cmp(s, al, bl, blconst);
565         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_EQ], 0);
566         tcg_out_branch_i32(s, cc, label_dest);
567         break;
568
569     case TCG_COND_NE:
570         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
571         tcg_out_branch_i32(s, cc, label_dest);
572         tcg_out_cmp(s, al, bl, blconst);
573         tcg_out_branch_i32(s, cc, label_dest);
574         break;
575
576     default:
577         /* ??? One could fairly easily special-case 64-bit unsigned
578            compares against 32-bit zero-extended constants.  For instance,
579            we know that (unsigned)AH < 0 is false and need not emit it.
580            Similarly, (unsigned)AH > 0 being true implies AH != 0, so the
581            second branch will never be taken.  */
582         cc = INSN_COND(tcg_cond_to_bcond[cond], 0);
583         tcg_out_branch_i32(s, cc, label_dest);
584         tcg_out_nop(s);
585         cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
586         tcg_out_branch_i32(s, cc, label_next);
587         tcg_out_cmp(s, al, bl, blconst);
588         cc = INSN_COND(tcg_cond_to_bcond[tcg_unsigned_cond(cond)], 0);
589         tcg_out_branch_i32(s, cc, label_dest);
590         break;
591     }
592     tcg_out_nop(s);
593
594     tcg_out_label(s, label_next, s->code_ptr);
595 }
596 #endif
597
598 static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
599                                 TCGArg c1, TCGArg c2, int c2const)
600 {
601     TCGArg t;
602
603     /* For 32-bit comparisons, we can play games with ADDX/SUBX.  */
604     switch (cond) {
605     case TCG_COND_EQ:
606     case TCG_COND_NE:
607         if (c2 != 0) {
608             tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR);
609         }
610         c1 = TCG_REG_G0, c2 = ret, c2const = 0;
611         cond = (cond == TCG_COND_EQ ? TCG_COND_LEU : TCG_COND_LTU);
612         break;
613
614     case TCG_COND_GTU:
615     case TCG_COND_GEU:
616         if (c2const && c2 != 0) {
617             tcg_out_movi_imm13(s, TCG_REG_I5, c2);
618             c2 = TCG_REG_I5;
619         }
620         t = c1, c1 = c2, c2 = t, c2const = 0;
621         cond = tcg_swap_cond(cond);
622         break;
623
624     case TCG_COND_LTU:
625     case TCG_COND_LEU:
626         break;
627
628     default:
629         tcg_out_cmp(s, c1, c2, c2const);
630 #if defined(__sparc_v9__) || defined(__sparc_v8plus__)
631         tcg_out_movi_imm13(s, ret, 0);
632         tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
633                    | INSN_RS1(tcg_cond_to_bcond[cond])
634                    | MOVCC_ICC | INSN_IMM11(1));
635 #else
636         t = gen_new_label();
637         tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t);
638         tcg_out_movi_imm13(s, ret, 1);
639         tcg_out_movi_imm13(s, ret, 0);
640         tcg_out_label(s, t, s->code_ptr);
641 #endif
642         return;
643     }
644
645     tcg_out_cmp(s, c1, c2, c2const);
646     if (cond == TCG_COND_LTU) {
647         tcg_out_arithi(s, ret, TCG_REG_G0, 0, ARITH_ADDX);
648     } else {
649         tcg_out_arithi(s, ret, TCG_REG_G0, -1, ARITH_SUBX);
650     }
651 }
652
653 #if TCG_TARGET_REG_BITS == 64
654 static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
655                                 TCGArg c1, TCGArg c2, int c2const)
656 {
657     tcg_out_cmp(s, c1, c2, c2const);
658     tcg_out_movi_imm13(s, ret, 0);
659     tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
660                | INSN_RS1(tcg_cond_to_bcond[cond])
661                | MOVCC_XCC | INSN_IMM11(1));
662 }
663 #else
664 static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
665                                  TCGArg al, TCGArg ah,
666                                  TCGArg bl, int blconst,
667                                  TCGArg bh, int bhconst)
668 {
669     int lab;
670
671     switch (cond) {
672     case TCG_COND_EQ:
673         tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst);
674         tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
675         tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND);
676         break;
677
678     case TCG_COND_NE:
679         tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst);
680         tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
681         tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR);
682         break;
683
684     default:
685         lab = gen_new_label();
686
687         tcg_out_cmp(s, ah, bh, bhconst);
688         tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), lab);
689         tcg_out_movi_imm13(s, ret, 1);
690         tcg_out_branch_i32(s, INSN_COND(COND_NE, 1), lab);
691         tcg_out_movi_imm13(s, ret, 0);
692
693         tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), ret, al, bl, blconst);
694
695         tcg_out_label(s, lab, s->code_ptr);
696         break;
697     }
698 }
699 #endif
700
701 /* Generate global QEMU prologue and epilogue code */
702 static void tcg_target_qemu_prologue(TCGContext *s)
703 {
704     tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
705                   CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
706     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
707               INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
708                            CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
709     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
710               INSN_RS2(TCG_REG_G0));
711     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
712 }
713
714 #if defined(CONFIG_SOFTMMU)
715
716 #include "../../softmmu_defs.h"
717
718 #ifdef CONFIG_TCG_PASS_AREG0
719 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
720    int mmu_idx) */
721 static const void * const qemu_ld_helpers[4] = {
722     helper_ldb_mmu,
723     helper_ldw_mmu,
724     helper_ldl_mmu,
725     helper_ldq_mmu,
726 };
727
728 /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
729    uintxx_t val, int mmu_idx) */
730 static const void * const qemu_st_helpers[4] = {
731     helper_stb_mmu,
732     helper_stw_mmu,
733     helper_stl_mmu,
734     helper_stq_mmu,
735 };
736 #else
737 /* legacy helper signature: __ld_mmu(target_ulong addr, int
738    mmu_idx) */
739 static const void * const qemu_ld_helpers[4] = {
740     __ldb_mmu,
741     __ldw_mmu,
742     __ldl_mmu,
743     __ldq_mmu,
744 };
745
746 /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
747    int mmu_idx) */
748 static const void * const qemu_st_helpers[4] = {
749     __stb_mmu,
750     __stw_mmu,
751     __stl_mmu,
752     __stq_mmu,
753 };
754 #endif
755 #endif
756
757 #if TARGET_LONG_BITS == 32
758 #define TARGET_LD_OP LDUW
759 #else
760 #define TARGET_LD_OP LDX
761 #endif
762
763 #if defined(CONFIG_SOFTMMU)
764 #if HOST_LONG_BITS == 32
765 #define TARGET_ADDEND_LD_OP LDUW
766 #else
767 #define TARGET_ADDEND_LD_OP LDX
768 #endif
769 #endif
770
771 #ifdef __arch64__
772 #define HOST_LD_OP LDX
773 #define HOST_ST_OP STX
774 #define HOST_SLL_OP SHIFT_SLLX
775 #define HOST_SRA_OP SHIFT_SRAX
776 #else
777 #define HOST_LD_OP LDUW
778 #define HOST_ST_OP STW
779 #define HOST_SLL_OP SHIFT_SLL
780 #define HOST_SRA_OP SHIFT_SRA
781 #endif
782
783 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
784                             int opc)
785 {
786     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
787 #if defined(CONFIG_SOFTMMU)
788     uint32_t *label1_ptr, *label2_ptr;
789 #endif
790
791     data_reg = *args++;
792     addr_reg = *args++;
793     mem_index = *args;
794     s_bits = opc & 3;
795
796     arg0 = TCG_REG_O0;
797     arg1 = TCG_REG_O1;
798     arg2 = TCG_REG_O2;
799
800 #if defined(CONFIG_SOFTMMU)
801     /* srl addr_reg, x, arg1 */
802     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
803                    SHIFT_SRL);
804     /* and addr_reg, x, arg0 */
805     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
806                    ARITH_AND);
807
808     /* and arg1, x, arg1 */
809     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
810
811     /* add arg1, x, arg1 */
812     tcg_out_addi(s, arg1, offsetof(CPUArchState,
813                                    tlb_table[mem_index][0].addr_read));
814
815     /* add env, arg1, arg1 */
816     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
817
818     /* ld [arg1], arg2 */
819     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
820               INSN_RS2(TCG_REG_G0));
821
822     /* subcc arg0, arg2, %g0 */
823     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
824
825     /* will become:
826        be label1
827         or
828        be,pt %xcc label1 */
829     label1_ptr = (uint32_t *)s->code_ptr;
830     tcg_out32(s, 0);
831
832     /* mov (delay slot) */
833     tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
834
835     /* mov */
836     tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
837 #ifdef CONFIG_TCG_PASS_AREG0
838     /* XXX/FIXME: suboptimal */
839     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
840                 tcg_target_call_iarg_regs[2]);
841     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
842                 tcg_target_call_iarg_regs[1]);
843     tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
844                 tcg_target_call_iarg_regs[0]);
845     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
846                 TCG_AREG0);
847 #endif
848
849     /* XXX: move that code at the end of the TB */
850     /* qemu_ld_helper[s_bits](arg0, arg1) */
851     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
852                            - (tcg_target_ulong)s->code_ptr) >> 2)
853                          & 0x3fffffff));
854     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
855        global registers */
856     // delay slot
857     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
858                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
859                  sizeof(long), HOST_ST_OP);
860     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
861                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
862                  sizeof(long), HOST_LD_OP);
863
864     /* data_reg = sign_extend(arg0) */
865     switch(opc) {
866     case 0 | 4:
867         /* sll arg0, 24/56, data_reg */
868         tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
869                        HOST_SLL_OP);
870         /* sra data_reg, 24/56, data_reg */
871         tcg_out_arithi(s, data_reg, data_reg,
872                        (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
873         break;
874     case 1 | 4:
875         /* sll arg0, 16/48, data_reg */
876         tcg_out_arithi(s, data_reg, arg0,
877                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
878         /* sra data_reg, 16/48, data_reg */
879         tcg_out_arithi(s, data_reg, data_reg,
880                        (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
881         break;
882     case 2 | 4:
883         /* sll arg0, 32, data_reg */
884         tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
885         /* sra data_reg, 32, data_reg */
886         tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
887         break;
888     case 0:
889     case 1:
890     case 2:
891     case 3:
892     default:
893         /* mov */
894         tcg_out_mov(s, TCG_TYPE_REG, data_reg, arg0);
895         break;
896     }
897
898     /* will become:
899        ba label2 */
900     label2_ptr = (uint32_t *)s->code_ptr;
901     tcg_out32(s, 0);
902
903     /* nop (delay slot */
904     tcg_out_nop(s);
905
906     /* label1: */
907 #if TARGET_LONG_BITS == 32
908     /* be label1 */
909     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
910                    INSN_OFF22((unsigned long)s->code_ptr -
911                               (unsigned long)label1_ptr));
912 #else
913     /* be,pt %xcc label1 */
914     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
915                    (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
916                               (unsigned long)label1_ptr));
917 #endif
918
919     /* ld [arg1 + x], arg1 */
920     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
921                  offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
922
923 #if TARGET_LONG_BITS == 32
924     /* and addr_reg, x, arg0 */
925     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
926     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
927     /* add arg0, arg1, arg0 */
928     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
929 #else
930     /* add addr_reg, arg1, arg0 */
931     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
932 #endif
933
934 #else
935     arg0 = addr_reg;
936 #endif
937
938     switch(opc) {
939     case 0:
940         /* ldub [arg0], data_reg */
941         tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
942         break;
943     case 0 | 4:
944         /* ldsb [arg0], data_reg */
945         tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
946         break;
947     case 1:
948 #ifdef TARGET_WORDS_BIGENDIAN
949         /* lduh [arg0], data_reg */
950         tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
951 #else
952         /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
953         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
954 #endif
955         break;
956     case 1 | 4:
957 #ifdef TARGET_WORDS_BIGENDIAN
958         /* ldsh [arg0], data_reg */
959         tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
960 #else
961         /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
962         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
963 #endif
964         break;
965     case 2:
966 #ifdef TARGET_WORDS_BIGENDIAN
967         /* lduw [arg0], data_reg */
968         tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
969 #else
970         /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
971         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
972 #endif
973         break;
974     case 2 | 4:
975 #ifdef TARGET_WORDS_BIGENDIAN
976         /* ldsw [arg0], data_reg */
977         tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
978 #else
979         /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
980         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
981 #endif
982         break;
983     case 3:
984 #ifdef TARGET_WORDS_BIGENDIAN
985         /* ldx [arg0], data_reg */
986         tcg_out_ldst(s, data_reg, arg0, 0, LDX);
987 #else
988         /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
989         tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
990 #endif
991         break;
992     default:
993         tcg_abort();
994     }
995
996 #if defined(CONFIG_SOFTMMU)
997     /* label2: */
998     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
999                    INSN_OFF22((unsigned long)s->code_ptr -
1000                               (unsigned long)label2_ptr));
1001 #endif
1002 }
1003
1004 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1005                             int opc)
1006 {
1007     int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
1008 #if defined(CONFIG_SOFTMMU)
1009     uint32_t *label1_ptr, *label2_ptr;
1010 #endif
1011
1012     data_reg = *args++;
1013     addr_reg = *args++;
1014     mem_index = *args;
1015
1016     s_bits = opc;
1017
1018     arg0 = TCG_REG_O0;
1019     arg1 = TCG_REG_O1;
1020     arg2 = TCG_REG_O2;
1021
1022 #if defined(CONFIG_SOFTMMU)
1023     /* srl addr_reg, x, arg1 */
1024     tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
1025                    SHIFT_SRL);
1026
1027     /* and addr_reg, x, arg0 */
1028     tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
1029                    ARITH_AND);
1030
1031     /* and arg1, x, arg1 */
1032     tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1033
1034     /* add arg1, x, arg1 */
1035     tcg_out_addi(s, arg1, offsetof(CPUArchState,
1036                                    tlb_table[mem_index][0].addr_write));
1037
1038     /* add env, arg1, arg1 */
1039     tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
1040
1041     /* ld [arg1], arg2 */
1042     tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
1043               INSN_RS2(TCG_REG_G0));
1044
1045     /* subcc arg0, arg2, %g0 */
1046     tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
1047
1048     /* will become:
1049        be label1
1050         or
1051        be,pt %xcc label1 */
1052     label1_ptr = (uint32_t *)s->code_ptr;
1053     tcg_out32(s, 0);
1054
1055     /* mov (delay slot) */
1056     tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
1057
1058     /* mov */
1059     tcg_out_mov(s, TCG_TYPE_REG, arg1, data_reg);
1060
1061     /* mov */
1062     tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
1063
1064 #ifdef CONFIG_TCG_PASS_AREG0
1065     /* XXX/FIXME: suboptimal */
1066     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
1067                 tcg_target_call_iarg_regs[2]);
1068     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
1069                 tcg_target_call_iarg_regs[1]);
1070     tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
1071                 tcg_target_call_iarg_regs[0]);
1072     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
1073                 TCG_AREG0);
1074 #endif
1075     /* XXX: move that code at the end of the TB */
1076     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
1077     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
1078                            - (tcg_target_ulong)s->code_ptr) >> 2)
1079                          & 0x3fffffff));
1080     /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
1081        global registers */
1082     // delay slot
1083     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1084                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1085                  sizeof(long), HOST_ST_OP);
1086     tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1087                  TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1088                  sizeof(long), HOST_LD_OP);
1089
1090     /* will become:
1091        ba label2 */
1092     label2_ptr = (uint32_t *)s->code_ptr;
1093     tcg_out32(s, 0);
1094
1095     /* nop (delay slot) */
1096     tcg_out_nop(s);
1097
1098 #if TARGET_LONG_BITS == 32
1099     /* be label1 */
1100     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
1101                    INSN_OFF22((unsigned long)s->code_ptr -
1102                               (unsigned long)label1_ptr));
1103 #else
1104     /* be,pt %xcc label1 */
1105     *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
1106                    (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
1107                               (unsigned long)label1_ptr));
1108 #endif
1109
1110     /* ld [arg1 + x], arg1 */
1111     tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
1112                  offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
1113
1114 #if TARGET_LONG_BITS == 32
1115     /* and addr_reg, x, arg0 */
1116     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
1117     tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
1118     /* add arg0, arg1, arg0 */
1119     tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
1120 #else
1121     /* add addr_reg, arg1, arg0 */
1122     tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
1123 #endif
1124
1125 #else
1126     arg0 = addr_reg;
1127 #endif
1128
1129     switch(opc) {
1130     case 0:
1131         /* stb data_reg, [arg0] */
1132         tcg_out_ldst(s, data_reg, arg0, 0, STB);
1133         break;
1134     case 1:
1135 #ifdef TARGET_WORDS_BIGENDIAN
1136         /* sth data_reg, [arg0] */
1137         tcg_out_ldst(s, data_reg, arg0, 0, STH);
1138 #else
1139         /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
1140         tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
1141 #endif
1142         break;
1143     case 2:
1144 #ifdef TARGET_WORDS_BIGENDIAN
1145         /* stw data_reg, [arg0] */
1146         tcg_out_ldst(s, data_reg, arg0, 0, STW);
1147 #else
1148         /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
1149         tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
1150 #endif
1151         break;
1152     case 3:
1153 #ifdef TARGET_WORDS_BIGENDIAN
1154         /* stx data_reg, [arg0] */
1155         tcg_out_ldst(s, data_reg, arg0, 0, STX);
1156 #else
1157         /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
1158         tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
1159 #endif
1160         break;
1161     default:
1162         tcg_abort();
1163     }
1164
1165 #if defined(CONFIG_SOFTMMU)
1166     /* label2: */
1167     *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
1168                    INSN_OFF22((unsigned long)s->code_ptr -
1169                               (unsigned long)label2_ptr));
1170 #endif
1171 }
1172
1173 static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
1174                               const int *const_args)
1175 {
1176     int c;
1177
1178     switch (opc) {
1179     case INDEX_op_exit_tb:
1180         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
1181         tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
1182                   INSN_IMM13(8));
1183         tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
1184                       INSN_RS2(TCG_REG_G0));
1185         break;
1186     case INDEX_op_goto_tb:
1187         if (s->tb_jmp_offset) {
1188             /* direct jump method */
1189             tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
1190             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
1191                       INSN_IMM13((args[0] & 0x1fff)));
1192             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1193         } else {
1194             /* indirect jump method */
1195             tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
1196             tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
1197                       INSN_RS2(TCG_REG_G0));
1198         }
1199         tcg_out_nop(s);
1200         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1201         break;
1202     case INDEX_op_call:
1203         if (const_args[0])
1204             tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
1205                                    - (tcg_target_ulong)s->code_ptr) >> 2)
1206                                  & 0x3fffffff));
1207         else {
1208             tcg_out_ld_ptr(s, TCG_REG_I5,
1209                            (tcg_target_long)(s->tb_next + args[0]));
1210             tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
1211                       INSN_RS2(TCG_REG_G0));
1212         }
1213         /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
1214            global registers */
1215         // delay slot
1216         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1217                      TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1218                      sizeof(long), HOST_ST_OP);
1219         tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1220                      TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1221                      sizeof(long), HOST_LD_OP);
1222         break;
1223     case INDEX_op_jmp:
1224     case INDEX_op_br:
1225         tcg_out_branch_i32(s, COND_A, args[0]);
1226         tcg_out_nop(s);
1227         break;
1228     case INDEX_op_movi_i32:
1229         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
1230         break;
1231
1232 #if TCG_TARGET_REG_BITS == 64
1233 #define OP_32_64(x)                             \
1234         glue(glue(case INDEX_op_, x), _i32):    \
1235         glue(glue(case INDEX_op_, x), _i64)
1236 #else
1237 #define OP_32_64(x)                             \
1238         glue(glue(case INDEX_op_, x), _i32)
1239 #endif
1240     OP_32_64(ld8u):
1241         tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
1242         break;
1243     OP_32_64(ld8s):
1244         tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
1245         break;
1246     OP_32_64(ld16u):
1247         tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
1248         break;
1249     OP_32_64(ld16s):
1250         tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
1251         break;
1252     case INDEX_op_ld_i32:
1253 #if TCG_TARGET_REG_BITS == 64
1254     case INDEX_op_ld32u_i64:
1255 #endif
1256         tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
1257         break;
1258     OP_32_64(st8):
1259         tcg_out_ldst(s, args[0], args[1], args[2], STB);
1260         break;
1261     OP_32_64(st16):
1262         tcg_out_ldst(s, args[0], args[1], args[2], STH);
1263         break;
1264     case INDEX_op_st_i32:
1265 #if TCG_TARGET_REG_BITS == 64
1266     case INDEX_op_st32_i64:
1267 #endif
1268         tcg_out_ldst(s, args[0], args[1], args[2], STW);
1269         break;
1270     OP_32_64(add):
1271         c = ARITH_ADD;
1272         goto gen_arith;
1273     OP_32_64(sub):
1274         c = ARITH_SUB;
1275         goto gen_arith;
1276     OP_32_64(and):
1277         c = ARITH_AND;
1278         goto gen_arith;
1279     OP_32_64(andc):
1280         c = ARITH_ANDN;
1281         goto gen_arith;
1282     OP_32_64(or):
1283         c = ARITH_OR;
1284         goto gen_arith;
1285     OP_32_64(orc):
1286         c = ARITH_ORN;
1287         goto gen_arith;
1288     OP_32_64(xor):
1289         c = ARITH_XOR;
1290         goto gen_arith;
1291     case INDEX_op_shl_i32:
1292         c = SHIFT_SLL;
1293         goto gen_arith;
1294     case INDEX_op_shr_i32:
1295         c = SHIFT_SRL;
1296         goto gen_arith;
1297     case INDEX_op_sar_i32:
1298         c = SHIFT_SRA;
1299         goto gen_arith;
1300     case INDEX_op_mul_i32:
1301         c = ARITH_UMUL;
1302         goto gen_arith;
1303
1304     OP_32_64(neg):
1305         c = ARITH_SUB;
1306         goto gen_arith1;
1307     OP_32_64(not):
1308         c = ARITH_ORN;
1309         goto gen_arith1;
1310
1311     case INDEX_op_div_i32:
1312         tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
1313         break;
1314     case INDEX_op_divu_i32:
1315         tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
1316         break;
1317
1318     case INDEX_op_rem_i32:
1319     case INDEX_op_remu_i32:
1320         tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
1321                       opc == INDEX_op_remu_i32);
1322         tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
1323                        ARITH_UMUL);
1324         tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
1325         break;
1326
1327     case INDEX_op_brcond_i32:
1328         tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
1329                            args[3]);
1330         break;
1331     case INDEX_op_setcond_i32:
1332         tcg_out_setcond_i32(s, args[3], args[0], args[1],
1333                             args[2], const_args[2]);
1334         break;
1335
1336 #if TCG_TARGET_REG_BITS == 32
1337     case INDEX_op_brcond2_i32:
1338         tcg_out_brcond2_i32(s, args[4], args[0], args[1],
1339                             args[2], const_args[2],
1340                             args[3], const_args[3], args[5]);
1341         break;
1342     case INDEX_op_setcond2_i32:
1343         tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
1344                              args[3], const_args[3],
1345                              args[4], const_args[4]);
1346         break;
1347     case INDEX_op_add2_i32:
1348         tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
1349                        ARITH_ADDCC);
1350         tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
1351                        ARITH_ADDX);
1352         break;
1353     case INDEX_op_sub2_i32:
1354         tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
1355                        ARITH_SUBCC);
1356         tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
1357                        ARITH_SUBX);
1358         break;
1359     case INDEX_op_mulu2_i32:
1360         tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
1361                        ARITH_UMUL);
1362         tcg_out_rdy(s, args[1]);
1363         break;
1364 #endif
1365
1366     case INDEX_op_qemu_ld8u:
1367         tcg_out_qemu_ld(s, args, 0);
1368         break;
1369     case INDEX_op_qemu_ld8s:
1370         tcg_out_qemu_ld(s, args, 0 | 4);
1371         break;
1372     case INDEX_op_qemu_ld16u:
1373         tcg_out_qemu_ld(s, args, 1);
1374         break;
1375     case INDEX_op_qemu_ld16s:
1376         tcg_out_qemu_ld(s, args, 1 | 4);
1377         break;
1378     case INDEX_op_qemu_ld32:
1379 #if TCG_TARGET_REG_BITS == 64
1380     case INDEX_op_qemu_ld32u:
1381 #endif
1382         tcg_out_qemu_ld(s, args, 2);
1383         break;
1384 #if TCG_TARGET_REG_BITS == 64
1385     case INDEX_op_qemu_ld32s:
1386         tcg_out_qemu_ld(s, args, 2 | 4);
1387         break;
1388 #endif
1389     case INDEX_op_qemu_st8:
1390         tcg_out_qemu_st(s, args, 0);
1391         break;
1392     case INDEX_op_qemu_st16:
1393         tcg_out_qemu_st(s, args, 1);
1394         break;
1395     case INDEX_op_qemu_st32:
1396         tcg_out_qemu_st(s, args, 2);
1397         break;
1398
1399 #if TCG_TARGET_REG_BITS == 64
1400     case INDEX_op_movi_i64:
1401         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1402         break;
1403     case INDEX_op_ld32s_i64:
1404         tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
1405         break;
1406     case INDEX_op_ld_i64:
1407         tcg_out_ldst(s, args[0], args[1], args[2], LDX);
1408         break;
1409     case INDEX_op_st_i64:
1410         tcg_out_ldst(s, args[0], args[1], args[2], STX);
1411         break;
1412     case INDEX_op_shl_i64:
1413         c = SHIFT_SLLX;
1414         goto gen_arith;
1415     case INDEX_op_shr_i64:
1416         c = SHIFT_SRLX;
1417         goto gen_arith;
1418     case INDEX_op_sar_i64:
1419         c = SHIFT_SRAX;
1420         goto gen_arith;
1421     case INDEX_op_mul_i64:
1422         c = ARITH_MULX;
1423         goto gen_arith;
1424     case INDEX_op_div_i64:
1425         c = ARITH_SDIVX;
1426         goto gen_arith;
1427     case INDEX_op_divu_i64:
1428         c = ARITH_UDIVX;
1429         goto gen_arith;
1430     case INDEX_op_rem_i64:
1431     case INDEX_op_remu_i64:
1432         tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
1433                        opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
1434         tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
1435                        ARITH_MULX);
1436         tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
1437         break;
1438     case INDEX_op_ext32s_i64:
1439         if (const_args[1]) {
1440             tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
1441         } else {
1442             tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
1443         }
1444         break;
1445     case INDEX_op_ext32u_i64:
1446         if (const_args[1]) {
1447             tcg_out_movi_imm32(s, args[0], args[1]);
1448         } else {
1449             tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
1450         }
1451         break;
1452
1453     case INDEX_op_brcond_i64:
1454         tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
1455                            args[3]);
1456         break;
1457     case INDEX_op_setcond_i64:
1458         tcg_out_setcond_i64(s, args[3], args[0], args[1],
1459                             args[2], const_args[2]);
1460         break;
1461
1462     case INDEX_op_qemu_ld64:
1463         tcg_out_qemu_ld(s, args, 3);
1464         break;
1465     case INDEX_op_qemu_st64:
1466         tcg_out_qemu_st(s, args, 3);
1467         break;
1468
1469 #endif
1470     gen_arith:
1471         tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
1472         break;
1473
1474     gen_arith1:
1475         tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
1476         break;
1477
1478     default:
1479         fprintf(stderr, "unknown opcode 0x%x\n", opc);
1480         tcg_abort();
1481     }
1482 }
1483
1484 static const TCGTargetOpDef sparc_op_defs[] = {
1485     { INDEX_op_exit_tb, { } },
1486     { INDEX_op_goto_tb, { } },
1487     { INDEX_op_call, { "ri" } },
1488     { INDEX_op_jmp, { "ri" } },
1489     { INDEX_op_br, { } },
1490
1491     { INDEX_op_mov_i32, { "r", "r" } },
1492     { INDEX_op_movi_i32, { "r" } },
1493     { INDEX_op_ld8u_i32, { "r", "r" } },
1494     { INDEX_op_ld8s_i32, { "r", "r" } },
1495     { INDEX_op_ld16u_i32, { "r", "r" } },
1496     { INDEX_op_ld16s_i32, { "r", "r" } },
1497     { INDEX_op_ld_i32, { "r", "r" } },
1498     { INDEX_op_st8_i32, { "r", "r" } },
1499     { INDEX_op_st16_i32, { "r", "r" } },
1500     { INDEX_op_st_i32, { "r", "r" } },
1501
1502     { INDEX_op_add_i32, { "r", "r", "rJ" } },
1503     { INDEX_op_mul_i32, { "r", "r", "rJ" } },
1504     { INDEX_op_div_i32, { "r", "r", "rJ" } },
1505     { INDEX_op_divu_i32, { "r", "r", "rJ" } },
1506     { INDEX_op_rem_i32, { "r", "r", "rJ" } },
1507     { INDEX_op_remu_i32, { "r", "r", "rJ" } },
1508     { INDEX_op_sub_i32, { "r", "r", "rJ" } },
1509     { INDEX_op_and_i32, { "r", "r", "rJ" } },
1510     { INDEX_op_andc_i32, { "r", "r", "rJ" } },
1511     { INDEX_op_or_i32, { "r", "r", "rJ" } },
1512     { INDEX_op_orc_i32, { "r", "r", "rJ" } },
1513     { INDEX_op_xor_i32, { "r", "r", "rJ" } },
1514
1515     { INDEX_op_shl_i32, { "r", "r", "rJ" } },
1516     { INDEX_op_shr_i32, { "r", "r", "rJ" } },
1517     { INDEX_op_sar_i32, { "r", "r", "rJ" } },
1518
1519     { INDEX_op_neg_i32, { "r", "rJ" } },
1520     { INDEX_op_not_i32, { "r", "rJ" } },
1521
1522     { INDEX_op_brcond_i32, { "r", "rJ" } },
1523     { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
1524
1525 #if TCG_TARGET_REG_BITS == 32
1526     { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
1527     { INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } },
1528     { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
1529     { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
1530     { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
1531 #endif
1532
1533     { INDEX_op_qemu_ld8u, { "r", "L" } },
1534     { INDEX_op_qemu_ld8s, { "r", "L" } },
1535     { INDEX_op_qemu_ld16u, { "r", "L" } },
1536     { INDEX_op_qemu_ld16s, { "r", "L" } },
1537     { INDEX_op_qemu_ld32, { "r", "L" } },
1538 #if TCG_TARGET_REG_BITS == 64
1539     { INDEX_op_qemu_ld32u, { "r", "L" } },
1540     { INDEX_op_qemu_ld32s, { "r", "L" } },
1541 #endif
1542
1543     { INDEX_op_qemu_st8, { "L", "L" } },
1544     { INDEX_op_qemu_st16, { "L", "L" } },
1545     { INDEX_op_qemu_st32, { "L", "L" } },
1546
1547 #if TCG_TARGET_REG_BITS == 64
1548     { INDEX_op_mov_i64, { "r", "r" } },
1549     { INDEX_op_movi_i64, { "r" } },
1550     { INDEX_op_ld8u_i64, { "r", "r" } },
1551     { INDEX_op_ld8s_i64, { "r", "r" } },
1552     { INDEX_op_ld16u_i64, { "r", "r" } },
1553     { INDEX_op_ld16s_i64, { "r", "r" } },
1554     { INDEX_op_ld32u_i64, { "r", "r" } },
1555     { INDEX_op_ld32s_i64, { "r", "r" } },
1556     { INDEX_op_ld_i64, { "r", "r" } },
1557     { INDEX_op_st8_i64, { "r", "r" } },
1558     { INDEX_op_st16_i64, { "r", "r" } },
1559     { INDEX_op_st32_i64, { "r", "r" } },
1560     { INDEX_op_st_i64, { "r", "r" } },
1561     { INDEX_op_qemu_ld64, { "L", "L" } },
1562     { INDEX_op_qemu_st64, { "L", "L" } },
1563
1564     { INDEX_op_add_i64, { "r", "r", "rJ" } },
1565     { INDEX_op_mul_i64, { "r", "r", "rJ" } },
1566     { INDEX_op_div_i64, { "r", "r", "rJ" } },
1567     { INDEX_op_divu_i64, { "r", "r", "rJ" } },
1568     { INDEX_op_rem_i64, { "r", "r", "rJ" } },
1569     { INDEX_op_remu_i64, { "r", "r", "rJ" } },
1570     { INDEX_op_sub_i64, { "r", "r", "rJ" } },
1571     { INDEX_op_and_i64, { "r", "r", "rJ" } },
1572     { INDEX_op_andc_i64, { "r", "r", "rJ" } },
1573     { INDEX_op_or_i64, { "r", "r", "rJ" } },
1574     { INDEX_op_orc_i64, { "r", "r", "rJ" } },
1575     { INDEX_op_xor_i64, { "r", "r", "rJ" } },
1576
1577     { INDEX_op_shl_i64, { "r", "r", "rJ" } },
1578     { INDEX_op_shr_i64, { "r", "r", "rJ" } },
1579     { INDEX_op_sar_i64, { "r", "r", "rJ" } },
1580
1581     { INDEX_op_neg_i64, { "r", "rJ" } },
1582     { INDEX_op_not_i64, { "r", "rJ" } },
1583
1584     { INDEX_op_ext32s_i64, { "r", "ri" } },
1585     { INDEX_op_ext32u_i64, { "r", "ri" } },
1586
1587     { INDEX_op_brcond_i64, { "r", "rJ" } },
1588     { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
1589 #endif
1590     { -1 },
1591 };
1592
1593 static void tcg_target_init(TCGContext *s)
1594 {
1595     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1596 #if TCG_TARGET_REG_BITS == 64
1597     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1598 #endif
1599     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1600                      (1 << TCG_REG_G1) |
1601                      (1 << TCG_REG_G2) |
1602                      (1 << TCG_REG_G3) |
1603                      (1 << TCG_REG_G4) |
1604                      (1 << TCG_REG_G5) |
1605                      (1 << TCG_REG_G6) |
1606                      (1 << TCG_REG_G7) |
1607                      (1 << TCG_REG_O0) |
1608                      (1 << TCG_REG_O1) |
1609                      (1 << TCG_REG_O2) |
1610                      (1 << TCG_REG_O3) |
1611                      (1 << TCG_REG_O4) |
1612                      (1 << TCG_REG_O5) |
1613                      (1 << TCG_REG_O7));
1614
1615     tcg_regset_clear(s->reserved_regs);
1616     tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
1617 #if TCG_TARGET_REG_BITS == 64
1618     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
1619 #endif
1620     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
1621     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
1622     tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
1623     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
1624     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
1625     tcg_add_target_add_op_defs(sparc_op_defs);
1626 }
1627
1628 #if TCG_TARGET_REG_BITS == 64
1629 # define ELF_HOST_MACHINE  EM_SPARCV9
1630 #elif defined(__sparc_v8plus__)
1631 # define ELF_HOST_MACHINE  EM_SPARC32PLUS
1632 # define ELF_HOST_FLAGS    EF_SPARC_32PLUS
1633 #else
1634 # define ELF_HOST_MACHINE  EM_SPARC
1635 #endif
1636
1637 typedef struct {
1638     uint32_t len __attribute__((aligned((sizeof(void *)))));
1639     uint32_t id;
1640     uint8_t version;
1641     char augmentation[1];
1642     uint8_t code_align;
1643     uint8_t data_align;
1644     uint8_t return_column;
1645 } DebugFrameCIE;
1646
1647 typedef struct {
1648     uint32_t len __attribute__((aligned((sizeof(void *)))));
1649     uint32_t cie_offset;
1650     tcg_target_long func_start __attribute__((packed));
1651     tcg_target_long func_len __attribute__((packed));
1652     uint8_t def_cfa[TCG_TARGET_REG_BITS == 64 ? 4 : 2];
1653     uint8_t win_save;
1654     uint8_t ret_save[3];
1655 } DebugFrameFDE;
1656
1657 typedef struct {
1658     DebugFrameCIE cie;
1659     DebugFrameFDE fde;
1660 } DebugFrame;
1661
1662 static DebugFrame debug_frame = {
1663     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
1664     .cie.id = -1,
1665     .cie.version = 1,
1666     .cie.code_align = 1,
1667     .cie.data_align = -sizeof(void *) & 0x7f,
1668     .cie.return_column = 15,            /* o7 */
1669
1670     .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
1671     .fde.def_cfa = {
1672 #if TCG_TARGET_REG_BITS == 64
1673         12, 30,                         /* DW_CFA_def_cfa i6, 2047 */
1674         (2047 & 0x7f) | 0x80, (2047 >> 7)
1675 #else
1676         13, 30                          /* DW_CFA_def_cfa_register i6 */
1677 #endif
1678     },
1679     .fde.win_save = 0x2d,               /* DW_CFA_GNU_window_save */
1680     .fde.ret_save = { 9, 15, 31 },      /* DW_CFA_register o7, i7 */
1681 };
1682
1683 void tcg_register_jit(void *buf, size_t buf_size)
1684 {
1685     debug_frame.fde.func_start = (tcg_target_long) buf;
1686     debug_frame.fde.func_len = buf_size;
1687
1688     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
1689 }
This page took 0.116426 seconds and 4 git commands to generate.