Statistics
| Branch: | Revision:

root / tcg / sparc / tcg-target.c @ 06ea77bc

History | View | Annotate | Download (48.3 kB)

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