Statistics
| Branch: | Revision:

root / tcg / sparc / tcg-target.c @ 30c0c76c

History | View | Annotate | Download (48 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 8289b279 blueswir1
static inline void tcg_out_mov(TCGContext *s, 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 1da92db2 blueswir1
static void tcg_out_brcond_i32(TCGContext *s, int 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 1da92db2 blueswir1
static void tcg_out_brcond_i64(TCGContext *s, int 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 56f4927e Richard Henderson
static void tcg_out_brcond2_i32(TCGContext *s, int 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 dbfe80e1 Richard Henderson
static void tcg_out_setcond_i32(TCGContext *s, int 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 dbfe80e1 Richard Henderson
static void tcg_out_setcond_i64(TCGContext *s, int 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 dbfe80e1 Richard Henderson
static void tcg_out_setcond2_i32(TCGContext *s, int 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 7d551702 blueswir1
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 9d0efc88 blueswir1
#if TARGET_PHYS_ADDR_BITS == 32
729 9d0efc88 blueswir1
#define TARGET_ADDEND_LD_OP LDUW
730 9d0efc88 blueswir1
#else
731 9d0efc88 blueswir1
#define TARGET_ADDEND_LD_OP LDX
732 9d0efc88 blueswir1
#endif
733 9d0efc88 blueswir1
734 bffe1431 blueswir1
#ifdef __arch64__
735 bffe1431 blueswir1
#define HOST_LD_OP LDX
736 bffe1431 blueswir1
#define HOST_ST_OP STX
737 bffe1431 blueswir1
#define HOST_SLL_OP SHIFT_SLLX
738 bffe1431 blueswir1
#define HOST_SRA_OP SHIFT_SRAX
739 bffe1431 blueswir1
#else
740 bffe1431 blueswir1
#define HOST_LD_OP LDUW
741 bffe1431 blueswir1
#define HOST_ST_OP STW
742 bffe1431 blueswir1
#define HOST_SLL_OP SHIFT_SLL
743 bffe1431 blueswir1
#define HOST_SRA_OP SHIFT_SRA
744 bffe1431 blueswir1
#endif
745 bffe1431 blueswir1
746 f5ef6aac blueswir1
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
747 f5ef6aac blueswir1
                            int opc)
748 f5ef6aac blueswir1
{
749 56fc64df blueswir1
    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
750 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
751 53c37487 blueswir1
    uint32_t *label1_ptr, *label2_ptr;
752 f5ef6aac blueswir1
#endif
753 f5ef6aac blueswir1
754 f5ef6aac blueswir1
    data_reg = *args++;
755 f5ef6aac blueswir1
    addr_reg = *args++;
756 f5ef6aac blueswir1
    mem_index = *args;
757 f5ef6aac blueswir1
    s_bits = opc & 3;
758 f5ef6aac blueswir1
759 53c37487 blueswir1
    arg0 = TCG_REG_O0;
760 53c37487 blueswir1
    arg1 = TCG_REG_O1;
761 56fc64df blueswir1
    arg2 = TCG_REG_O2;
762 f5ef6aac blueswir1
763 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
764 56fc64df blueswir1
    /* srl addr_reg, x, arg1 */
765 56fc64df blueswir1
    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
766 f5ef6aac blueswir1
                   SHIFT_SRL);
767 56fc64df blueswir1
    /* and addr_reg, x, arg0 */
768 56fc64df blueswir1
    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
769 f5ef6aac blueswir1
                   ARITH_AND);
770 f5ef6aac blueswir1
771 56fc64df blueswir1
    /* and arg1, x, arg1 */
772 56fc64df blueswir1
    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
773 f5ef6aac blueswir1
774 56fc64df blueswir1
    /* add arg1, x, arg1 */
775 56fc64df blueswir1
    tcg_out_addi(s, arg1, offsetof(CPUState,
776 56fc64df blueswir1
                                   tlb_table[mem_index][0].addr_read));
777 53c37487 blueswir1
778 56fc64df blueswir1
    /* add env, arg1, arg1 */
779 56fc64df blueswir1
    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
780 f5ef6aac blueswir1
781 56fc64df blueswir1
    /* ld [arg1], arg2 */
782 bffe1431 blueswir1
    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
783 56fc64df blueswir1
              INSN_RS2(TCG_REG_G0));
784 f5ef6aac blueswir1
785 56fc64df blueswir1
    /* subcc arg0, arg2, %g0 */
786 56fc64df blueswir1
    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
787 f5ef6aac blueswir1
788 f5ef6aac blueswir1
    /* will become:
789 1da92db2 blueswir1
       be label1
790 1da92db2 blueswir1
        or
791 1da92db2 blueswir1
       be,pt %xcc label1 */
792 53c37487 blueswir1
    label1_ptr = (uint32_t *)s->code_ptr;
793 f5ef6aac blueswir1
    tcg_out32(s, 0);
794 f5ef6aac blueswir1
795 53c37487 blueswir1
    /* mov (delay slot) */
796 53c37487 blueswir1
    tcg_out_mov(s, arg0, addr_reg);
797 f5ef6aac blueswir1
798 bffe1431 blueswir1
    /* mov */
799 bffe1431 blueswir1
    tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
800 bffe1431 blueswir1
801 f5ef6aac blueswir1
    /* XXX: move that code at the end of the TB */
802 53c37487 blueswir1
    /* qemu_ld_helper[s_bits](arg0, arg1) */
803 f5ef6aac blueswir1
    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
804 f5ef6aac blueswir1
                           - (tcg_target_ulong)s->code_ptr) >> 2)
805 f5ef6aac blueswir1
                         & 0x3fffffff));
806 bffe1431 blueswir1
    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
807 bffe1431 blueswir1
       global registers */
808 bffe1431 blueswir1
    // delay slot
809 bffe1431 blueswir1
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
810 f843e528 blueswir1
                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
811 f843e528 blueswir1
                 sizeof(long), HOST_ST_OP);
812 bffe1431 blueswir1
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
813 f843e528 blueswir1
                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
814 f843e528 blueswir1
                 sizeof(long), HOST_LD_OP);
815 f5ef6aac blueswir1
816 53c37487 blueswir1
    /* data_reg = sign_extend(arg0) */
817 f5ef6aac blueswir1
    switch(opc) {
818 f5ef6aac blueswir1
    case 0 | 4:
819 53c37487 blueswir1
        /* sll arg0, 24/56, data_reg */
820 56fc64df blueswir1
        tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
821 bffe1431 blueswir1
                       HOST_SLL_OP);
822 53c37487 blueswir1
        /* sra data_reg, 24/56, data_reg */
823 56fc64df blueswir1
        tcg_out_arithi(s, data_reg, data_reg,
824 bffe1431 blueswir1
                       (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
825 f5ef6aac blueswir1
        break;
826 f5ef6aac blueswir1
    case 1 | 4:
827 53c37487 blueswir1
        /* sll arg0, 16/48, data_reg */
828 56fc64df blueswir1
        tcg_out_arithi(s, data_reg, arg0,
829 bffe1431 blueswir1
                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
830 53c37487 blueswir1
        /* sra data_reg, 16/48, data_reg */
831 56fc64df blueswir1
        tcg_out_arithi(s, data_reg, data_reg,
832 bffe1431 blueswir1
                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
833 f5ef6aac blueswir1
        break;
834 f5ef6aac blueswir1
    case 2 | 4:
835 53c37487 blueswir1
        /* sll arg0, 32, data_reg */
836 bffe1431 blueswir1
        tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
837 53c37487 blueswir1
        /* sra data_reg, 32, data_reg */
838 bffe1431 blueswir1
        tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
839 f5ef6aac blueswir1
        break;
840 f5ef6aac blueswir1
    case 0:
841 f5ef6aac blueswir1
    case 1:
842 f5ef6aac blueswir1
    case 2:
843 f5ef6aac blueswir1
    case 3:
844 f5ef6aac blueswir1
    default:
845 f5ef6aac blueswir1
        /* mov */
846 53c37487 blueswir1
        tcg_out_mov(s, data_reg, arg0);
847 f5ef6aac blueswir1
        break;
848 f5ef6aac blueswir1
    }
849 f5ef6aac blueswir1
850 f5ef6aac blueswir1
    /* will become:
851 f5ef6aac blueswir1
       ba label2 */
852 53c37487 blueswir1
    label2_ptr = (uint32_t *)s->code_ptr;
853 f5ef6aac blueswir1
    tcg_out32(s, 0);
854 f5ef6aac blueswir1
855 53c37487 blueswir1
    /* nop (delay slot */
856 53c37487 blueswir1
    tcg_out_nop(s);
857 53c37487 blueswir1
858 f5ef6aac blueswir1
    /* label1: */
859 1da92db2 blueswir1
#if TARGET_LONG_BITS == 32
860 1da92db2 blueswir1
    /* be label1 */
861 53c37487 blueswir1
    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
862 53c37487 blueswir1
                   INSN_OFF22((unsigned long)s->code_ptr -
863 53c37487 blueswir1
                              (unsigned long)label1_ptr));
864 1da92db2 blueswir1
#else
865 1da92db2 blueswir1
    /* be,pt %xcc label1 */
866 1da92db2 blueswir1
    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
867 1da92db2 blueswir1
                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
868 1da92db2 blueswir1
                              (unsigned long)label1_ptr));
869 1da92db2 blueswir1
#endif
870 f5ef6aac blueswir1
871 56fc64df blueswir1
    /* ld [arg1 + x], arg1 */
872 56fc64df blueswir1
    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
873 9d0efc88 blueswir1
                 offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
874 90cbed46 blueswir1
875 90cbed46 blueswir1
#if TARGET_LONG_BITS == 32
876 90cbed46 blueswir1
    /* and addr_reg, x, arg0 */
877 90cbed46 blueswir1
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
878 90cbed46 blueswir1
    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
879 90cbed46 blueswir1
    /* add arg0, arg1, arg0 */
880 90cbed46 blueswir1
    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
881 90cbed46 blueswir1
#else
882 56fc64df blueswir1
    /* add addr_reg, arg1, arg0 */
883 56fc64df blueswir1
    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
884 90cbed46 blueswir1
#endif
885 90cbed46 blueswir1
886 f5ef6aac blueswir1
#else
887 56fc64df blueswir1
    arg0 = addr_reg;
888 f5ef6aac blueswir1
#endif
889 f5ef6aac blueswir1
890 f5ef6aac blueswir1
    switch(opc) {
891 f5ef6aac blueswir1
    case 0:
892 56fc64df blueswir1
        /* ldub [arg0], data_reg */
893 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
894 f5ef6aac blueswir1
        break;
895 f5ef6aac blueswir1
    case 0 | 4:
896 56fc64df blueswir1
        /* ldsb [arg0], data_reg */
897 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
898 f5ef6aac blueswir1
        break;
899 f5ef6aac blueswir1
    case 1:
900 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
901 56fc64df blueswir1
        /* lduh [arg0], data_reg */
902 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
903 8384dd67 blueswir1
#else
904 56fc64df blueswir1
        /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
905 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
906 8384dd67 blueswir1
#endif
907 f5ef6aac blueswir1
        break;
908 f5ef6aac blueswir1
    case 1 | 4:
909 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
910 56fc64df blueswir1
        /* ldsh [arg0], data_reg */
911 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
912 8384dd67 blueswir1
#else
913 56fc64df blueswir1
        /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
914 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
915 8384dd67 blueswir1
#endif
916 f5ef6aac blueswir1
        break;
917 f5ef6aac blueswir1
    case 2:
918 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
919 56fc64df blueswir1
        /* lduw [arg0], data_reg */
920 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
921 8384dd67 blueswir1
#else
922 56fc64df blueswir1
        /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
923 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
924 8384dd67 blueswir1
#endif
925 f5ef6aac blueswir1
        break;
926 f5ef6aac blueswir1
    case 2 | 4:
927 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
928 56fc64df blueswir1
        /* ldsw [arg0], data_reg */
929 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
930 8384dd67 blueswir1
#else
931 56fc64df blueswir1
        /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
932 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
933 8384dd67 blueswir1
#endif
934 f5ef6aac blueswir1
        break;
935 f5ef6aac blueswir1
    case 3:
936 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
937 56fc64df blueswir1
        /* ldx [arg0], data_reg */
938 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, LDX);
939 8384dd67 blueswir1
#else
940 56fc64df blueswir1
        /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
941 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
942 8384dd67 blueswir1
#endif
943 f5ef6aac blueswir1
        break;
944 f5ef6aac blueswir1
    default:
945 f5ef6aac blueswir1
        tcg_abort();
946 f5ef6aac blueswir1
    }
947 f5ef6aac blueswir1
948 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
949 f5ef6aac blueswir1
    /* label2: */
950 9a7f3228 blueswir1
    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
951 53c37487 blueswir1
                   INSN_OFF22((unsigned long)s->code_ptr -
952 53c37487 blueswir1
                              (unsigned long)label2_ptr));
953 f5ef6aac blueswir1
#endif
954 f5ef6aac blueswir1
}
955 f5ef6aac blueswir1
956 f5ef6aac blueswir1
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
957 f5ef6aac blueswir1
                            int opc)
958 f5ef6aac blueswir1
{
959 56fc64df blueswir1
    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
960 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
961 53c37487 blueswir1
    uint32_t *label1_ptr, *label2_ptr;
962 f5ef6aac blueswir1
#endif
963 f5ef6aac blueswir1
964 f5ef6aac blueswir1
    data_reg = *args++;
965 f5ef6aac blueswir1
    addr_reg = *args++;
966 f5ef6aac blueswir1
    mem_index = *args;
967 f5ef6aac blueswir1
968 f5ef6aac blueswir1
    s_bits = opc;
969 f5ef6aac blueswir1
970 53c37487 blueswir1
    arg0 = TCG_REG_O0;
971 53c37487 blueswir1
    arg1 = TCG_REG_O1;
972 53c37487 blueswir1
    arg2 = TCG_REG_O2;
973 f5ef6aac blueswir1
974 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
975 56fc64df blueswir1
    /* srl addr_reg, x, arg1 */
976 56fc64df blueswir1
    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
977 f5ef6aac blueswir1
                   SHIFT_SRL);
978 53c37487 blueswir1
979 56fc64df blueswir1
    /* and addr_reg, x, arg0 */
980 56fc64df blueswir1
    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
981 f5ef6aac blueswir1
                   ARITH_AND);
982 f5ef6aac blueswir1
983 56fc64df blueswir1
    /* and arg1, x, arg1 */
984 56fc64df blueswir1
    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
985 f5ef6aac blueswir1
986 56fc64df blueswir1
    /* add arg1, x, arg1 */
987 56fc64df blueswir1
    tcg_out_addi(s, arg1, offsetof(CPUState,
988 56fc64df blueswir1
                                   tlb_table[mem_index][0].addr_write));
989 f5ef6aac blueswir1
990 56fc64df blueswir1
    /* add env, arg1, arg1 */
991 56fc64df blueswir1
    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
992 f5ef6aac blueswir1
993 56fc64df blueswir1
    /* ld [arg1], arg2 */
994 bffe1431 blueswir1
    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
995 56fc64df blueswir1
              INSN_RS2(TCG_REG_G0));
996 53c37487 blueswir1
997 56fc64df blueswir1
    /* subcc arg0, arg2, %g0 */
998 56fc64df blueswir1
    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
999 f5ef6aac blueswir1
1000 f5ef6aac blueswir1
    /* will become:
1001 1da92db2 blueswir1
       be label1
1002 1da92db2 blueswir1
        or
1003 1da92db2 blueswir1
       be,pt %xcc label1 */
1004 53c37487 blueswir1
    label1_ptr = (uint32_t *)s->code_ptr;
1005 f5ef6aac blueswir1
    tcg_out32(s, 0);
1006 f5ef6aac blueswir1
1007 53c37487 blueswir1
    /* mov (delay slot) */
1008 53c37487 blueswir1
    tcg_out_mov(s, arg0, addr_reg);
1009 53c37487 blueswir1
1010 53c37487 blueswir1
    /* mov */
1011 56fc64df blueswir1
    tcg_out_mov(s, arg1, data_reg);
1012 53c37487 blueswir1
1013 bffe1431 blueswir1
    /* mov */
1014 bffe1431 blueswir1
    tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
1015 bffe1431 blueswir1
1016 53c37487 blueswir1
    /* XXX: move that code at the end of the TB */
1017 53c37487 blueswir1
    /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
1018 f5ef6aac blueswir1
    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
1019 f5ef6aac blueswir1
                           - (tcg_target_ulong)s->code_ptr) >> 2)
1020 f5ef6aac blueswir1
                         & 0x3fffffff));
1021 bffe1431 blueswir1
    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
1022 bffe1431 blueswir1
       global registers */
1023 bffe1431 blueswir1
    // delay slot
1024 bffe1431 blueswir1
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1025 f843e528 blueswir1
                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1026 f843e528 blueswir1
                 sizeof(long), HOST_ST_OP);
1027 bffe1431 blueswir1
    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1028 f843e528 blueswir1
                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1029 f843e528 blueswir1
                 sizeof(long), HOST_LD_OP);
1030 f5ef6aac blueswir1
1031 f5ef6aac blueswir1
    /* will become:
1032 f5ef6aac blueswir1
       ba label2 */
1033 53c37487 blueswir1
    label2_ptr = (uint32_t *)s->code_ptr;
1034 f5ef6aac blueswir1
    tcg_out32(s, 0);
1035 f5ef6aac blueswir1
1036 53c37487 blueswir1
    /* nop (delay slot) */
1037 53c37487 blueswir1
    tcg_out_nop(s);
1038 53c37487 blueswir1
1039 1da92db2 blueswir1
#if TARGET_LONG_BITS == 32
1040 1da92db2 blueswir1
    /* be label1 */
1041 53c37487 blueswir1
    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
1042 53c37487 blueswir1
                   INSN_OFF22((unsigned long)s->code_ptr -
1043 53c37487 blueswir1
                              (unsigned long)label1_ptr));
1044 1da92db2 blueswir1
#else
1045 1da92db2 blueswir1
    /* be,pt %xcc label1 */
1046 1da92db2 blueswir1
    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
1047 1da92db2 blueswir1
                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
1048 1da92db2 blueswir1
                              (unsigned long)label1_ptr));
1049 1da92db2 blueswir1
#endif
1050 f5ef6aac blueswir1
1051 56fc64df blueswir1
    /* ld [arg1 + x], arg1 */
1052 56fc64df blueswir1
    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
1053 9d0efc88 blueswir1
                 offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
1054 53c37487 blueswir1
1055 90cbed46 blueswir1
#if TARGET_LONG_BITS == 32
1056 90cbed46 blueswir1
    /* and addr_reg, x, arg0 */
1057 90cbed46 blueswir1
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
1058 90cbed46 blueswir1
    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
1059 90cbed46 blueswir1
    /* add arg0, arg1, arg0 */
1060 90cbed46 blueswir1
    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
1061 90cbed46 blueswir1
#else
1062 56fc64df blueswir1
    /* add addr_reg, arg1, arg0 */
1063 56fc64df blueswir1
    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
1064 90cbed46 blueswir1
#endif
1065 90cbed46 blueswir1
1066 f5ef6aac blueswir1
#else
1067 56fc64df blueswir1
    arg0 = addr_reg;
1068 f5ef6aac blueswir1
#endif
1069 f5ef6aac blueswir1
1070 f5ef6aac blueswir1
    switch(opc) {
1071 f5ef6aac blueswir1
    case 0:
1072 56fc64df blueswir1
        /* stb data_reg, [arg0] */
1073 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, STB);
1074 f5ef6aac blueswir1
        break;
1075 f5ef6aac blueswir1
    case 1:
1076 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
1077 56fc64df blueswir1
        /* sth data_reg, [arg0] */
1078 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, STH);
1079 8384dd67 blueswir1
#else
1080 56fc64df blueswir1
        /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
1081 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
1082 8384dd67 blueswir1
#endif
1083 f5ef6aac blueswir1
        break;
1084 f5ef6aac blueswir1
    case 2:
1085 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
1086 56fc64df blueswir1
        /* stw data_reg, [arg0] */
1087 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, STW);
1088 8384dd67 blueswir1
#else
1089 56fc64df blueswir1
        /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
1090 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
1091 8384dd67 blueswir1
#endif
1092 f5ef6aac blueswir1
        break;
1093 f5ef6aac blueswir1
    case 3:
1094 8384dd67 blueswir1
#ifdef TARGET_WORDS_BIGENDIAN
1095 56fc64df blueswir1
        /* stx data_reg, [arg0] */
1096 56fc64df blueswir1
        tcg_out_ldst(s, data_reg, arg0, 0, STX);
1097 8384dd67 blueswir1
#else
1098 56fc64df blueswir1
        /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
1099 56fc64df blueswir1
        tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
1100 8384dd67 blueswir1
#endif
1101 f5ef6aac blueswir1
        break;
1102 f5ef6aac blueswir1
    default:
1103 f5ef6aac blueswir1
        tcg_abort();
1104 f5ef6aac blueswir1
    }
1105 f5ef6aac blueswir1
1106 f5ef6aac blueswir1
#if defined(CONFIG_SOFTMMU)
1107 f5ef6aac blueswir1
    /* label2: */
1108 9a7f3228 blueswir1
    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
1109 53c37487 blueswir1
                   INSN_OFF22((unsigned long)s->code_ptr -
1110 53c37487 blueswir1
                              (unsigned long)label2_ptr));
1111 f5ef6aac blueswir1
#endif
1112 f5ef6aac blueswir1
}
1113 f5ef6aac blueswir1
1114 8289b279 blueswir1
static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
1115 8289b279 blueswir1
                              const int *const_args)
1116 8289b279 blueswir1
{
1117 8289b279 blueswir1
    int c;
1118 8289b279 blueswir1
1119 8289b279 blueswir1
    switch (opc) {
1120 8289b279 blueswir1
    case INDEX_op_exit_tb:
1121 b3db8758 blueswir1
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
1122 b3db8758 blueswir1
        tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
1123 8289b279 blueswir1
                  INSN_IMM13(8));
1124 b3db8758 blueswir1
        tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
1125 b3db8758 blueswir1
                      INSN_RS2(TCG_REG_G0));
1126 8289b279 blueswir1
        break;
1127 8289b279 blueswir1
    case INDEX_op_goto_tb:
1128 8289b279 blueswir1
        if (s->tb_jmp_offset) {
1129 8289b279 blueswir1
            /* direct jump method */
1130 26cc915c blueswir1
            tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
1131 cf7c2ca5 blueswir1
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
1132 cf7c2ca5 blueswir1
                      INSN_IMM13((args[0] & 0x1fff)));
1133 8289b279 blueswir1
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
1134 8289b279 blueswir1
        } else {
1135 8289b279 blueswir1
            /* indirect jump method */
1136 b3db8758 blueswir1
            tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
1137 b3db8758 blueswir1
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
1138 b3db8758 blueswir1
                      INSN_RS2(TCG_REG_G0));
1139 8289b279 blueswir1
        }
1140 53cd9273 blueswir1
        tcg_out_nop(s);
1141 8289b279 blueswir1
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1142 8289b279 blueswir1
        break;
1143 8289b279 blueswir1
    case INDEX_op_call:
1144 bffe1431 blueswir1
        if (const_args[0])
1145 bffe1431 blueswir1
            tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
1146 bffe1431 blueswir1
                                   - (tcg_target_ulong)s->code_ptr) >> 2)
1147 bffe1431 blueswir1
                                 & 0x3fffffff));
1148 bffe1431 blueswir1
        else {
1149 bffe1431 blueswir1
            tcg_out_ld_ptr(s, TCG_REG_I5,
1150 bffe1431 blueswir1
                           (tcg_target_long)(s->tb_next + args[0]));
1151 bffe1431 blueswir1
            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
1152 bffe1431 blueswir1
                      INSN_RS2(TCG_REG_G0));
1153 8289b279 blueswir1
        }
1154 bffe1431 blueswir1
        /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
1155 bffe1431 blueswir1
           global registers */
1156 bffe1431 blueswir1
        // delay slot
1157 bffe1431 blueswir1
        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1158 f843e528 blueswir1
                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1159 f843e528 blueswir1
                     sizeof(long), HOST_ST_OP);
1160 bffe1431 blueswir1
        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
1161 f843e528 blueswir1
                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
1162 f843e528 blueswir1
                     sizeof(long), HOST_LD_OP);
1163 8289b279 blueswir1
        break;
1164 8289b279 blueswir1
    case INDEX_op_jmp:
1165 8289b279 blueswir1
    case INDEX_op_br:
1166 1da92db2 blueswir1
        tcg_out_branch_i32(s, COND_A, args[0]);
1167 f5ef6aac blueswir1
        tcg_out_nop(s);
1168 8289b279 blueswir1
        break;
1169 8289b279 blueswir1
    case INDEX_op_movi_i32:
1170 8289b279 blueswir1
        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
1171 8289b279 blueswir1
        break;
1172 8289b279 blueswir1
1173 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1174 8289b279 blueswir1
#define OP_32_64(x)                             \
1175 ba225198 Richard Henderson
        glue(glue(case INDEX_op_, x), _i32):    \
1176 ba225198 Richard Henderson
        glue(glue(case INDEX_op_, x), _i64)
1177 8289b279 blueswir1
#else
1178 8289b279 blueswir1
#define OP_32_64(x)                             \
1179 ba225198 Richard Henderson
        glue(glue(case INDEX_op_, x), _i32)
1180 8289b279 blueswir1
#endif
1181 ba225198 Richard Henderson
    OP_32_64(ld8u):
1182 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDUB);
1183 8289b279 blueswir1
        break;
1184 ba225198 Richard Henderson
    OP_32_64(ld8s):
1185 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDSB);
1186 8289b279 blueswir1
        break;
1187 ba225198 Richard Henderson
    OP_32_64(ld16u):
1188 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDUH);
1189 8289b279 blueswir1
        break;
1190 ba225198 Richard Henderson
    OP_32_64(ld16s):
1191 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDSH);
1192 8289b279 blueswir1
        break;
1193 8289b279 blueswir1
    case INDEX_op_ld_i32:
1194 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1195 53cd9273 blueswir1
    case INDEX_op_ld32u_i64:
1196 8289b279 blueswir1
#endif
1197 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDUW);
1198 8289b279 blueswir1
        break;
1199 ba225198 Richard Henderson
    OP_32_64(st8):
1200 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], STB);
1201 8289b279 blueswir1
        break;
1202 ba225198 Richard Henderson
    OP_32_64(st16):
1203 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], STH);
1204 8289b279 blueswir1
        break;
1205 8289b279 blueswir1
    case INDEX_op_st_i32:
1206 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1207 53cd9273 blueswir1
    case INDEX_op_st32_i64:
1208 8289b279 blueswir1
#endif
1209 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], STW);
1210 8289b279 blueswir1
        break;
1211 ba225198 Richard Henderson
    OP_32_64(add):
1212 53cd9273 blueswir1
        c = ARITH_ADD;
1213 ba225198 Richard Henderson
        goto gen_arith;
1214 ba225198 Richard Henderson
    OP_32_64(sub):
1215 8289b279 blueswir1
        c = ARITH_SUB;
1216 ba225198 Richard Henderson
        goto gen_arith;
1217 ba225198 Richard Henderson
    OP_32_64(and):
1218 8289b279 blueswir1
        c = ARITH_AND;
1219 ba225198 Richard Henderson
        goto gen_arith;
1220 dc69960d Richard Henderson
    OP_32_64(andc):
1221 dc69960d Richard Henderson
        c = ARITH_ANDN;
1222 dc69960d Richard Henderson
        goto gen_arith;
1223 ba225198 Richard Henderson
    OP_32_64(or):
1224 8289b279 blueswir1
        c = ARITH_OR;
1225 ba225198 Richard Henderson
        goto gen_arith;
1226 18c8f7a3 Richard Henderson
    OP_32_64(orc):
1227 18c8f7a3 Richard Henderson
        c = ARITH_ORN;
1228 18c8f7a3 Richard Henderson
        goto gen_arith;
1229 ba225198 Richard Henderson
    OP_32_64(xor):
1230 8289b279 blueswir1
        c = ARITH_XOR;
1231 ba225198 Richard Henderson
        goto gen_arith;
1232 8289b279 blueswir1
    case INDEX_op_shl_i32:
1233 8289b279 blueswir1
        c = SHIFT_SLL;
1234 ba225198 Richard Henderson
        goto gen_arith;
1235 8289b279 blueswir1
    case INDEX_op_shr_i32:
1236 8289b279 blueswir1
        c = SHIFT_SRL;
1237 ba225198 Richard Henderson
        goto gen_arith;
1238 8289b279 blueswir1
    case INDEX_op_sar_i32:
1239 8289b279 blueswir1
        c = SHIFT_SRA;
1240 ba225198 Richard Henderson
        goto gen_arith;
1241 8289b279 blueswir1
    case INDEX_op_mul_i32:
1242 8289b279 blueswir1
        c = ARITH_UMUL;
1243 ba225198 Richard Henderson
        goto gen_arith;
1244 583d1215 Richard Henderson
1245 4b5a85c1 Richard Henderson
    OP_32_64(neg):
1246 4b5a85c1 Richard Henderson
        c = ARITH_SUB;
1247 4b5a85c1 Richard Henderson
        goto gen_arith1;
1248 be6551b1 Richard Henderson
    OP_32_64(not):
1249 be6551b1 Richard Henderson
        c = ARITH_ORN;
1250 be6551b1 Richard Henderson
        goto gen_arith1;
1251 4b5a85c1 Richard Henderson
1252 583d1215 Richard Henderson
    case INDEX_op_div_i32:
1253 583d1215 Richard Henderson
        tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 0);
1254 583d1215 Richard Henderson
        break;
1255 583d1215 Richard Henderson
    case INDEX_op_divu_i32:
1256 583d1215 Richard Henderson
        tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
1257 583d1215 Richard Henderson
        break;
1258 583d1215 Richard Henderson
1259 583d1215 Richard Henderson
    case INDEX_op_rem_i32:
1260 583d1215 Richard Henderson
    case INDEX_op_remu_i32:
1261 583d1215 Richard Henderson
        tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
1262 583d1215 Richard Henderson
                      opc == INDEX_op_remu_i32);
1263 583d1215 Richard Henderson
        tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
1264 583d1215 Richard Henderson
                       ARITH_UMUL);
1265 583d1215 Richard Henderson
        tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
1266 583d1215 Richard Henderson
        break;
1267 8289b279 blueswir1
1268 8289b279 blueswir1
    case INDEX_op_brcond_i32:
1269 1da92db2 blueswir1
        tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
1270 1da92db2 blueswir1
                           args[3]);
1271 8289b279 blueswir1
        break;
1272 dbfe80e1 Richard Henderson
    case INDEX_op_setcond_i32:
1273 dbfe80e1 Richard Henderson
        tcg_out_setcond_i32(s, args[3], args[0], args[1],
1274 dbfe80e1 Richard Henderson
                            args[2], const_args[2]);
1275 dbfe80e1 Richard Henderson
        break;
1276 dbfe80e1 Richard Henderson
1277 56f4927e Richard Henderson
#if TCG_TARGET_REG_BITS == 32
1278 56f4927e Richard Henderson
    case INDEX_op_brcond2_i32:
1279 56f4927e Richard Henderson
        tcg_out_brcond2_i32(s, args[4], args[0], args[1],
1280 56f4927e Richard Henderson
                            args[2], const_args[2],
1281 56f4927e Richard Henderson
                            args[3], const_args[3], args[5]);
1282 56f4927e Richard Henderson
        break;
1283 dbfe80e1 Richard Henderson
    case INDEX_op_setcond2_i32:
1284 dbfe80e1 Richard Henderson
        tcg_out_setcond2_i32(s, args[5], args[0], args[1], args[2],
1285 dbfe80e1 Richard Henderson
                             args[3], const_args[3],
1286 dbfe80e1 Richard Henderson
                             args[4], const_args[4]);
1287 dbfe80e1 Richard Henderson
        break;
1288 7a3766f3 Richard Henderson
    case INDEX_op_add2_i32:
1289 7a3766f3 Richard Henderson
        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
1290 7a3766f3 Richard Henderson
                       ARITH_ADDCC);
1291 7a3766f3 Richard Henderson
        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
1292 7a3766f3 Richard Henderson
                       ARITH_ADDX);
1293 7a3766f3 Richard Henderson
        break;
1294 7a3766f3 Richard Henderson
    case INDEX_op_sub2_i32:
1295 7a3766f3 Richard Henderson
        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
1296 7a3766f3 Richard Henderson
                       ARITH_SUBCC);
1297 7a3766f3 Richard Henderson
        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
1298 7a3766f3 Richard Henderson
                       ARITH_SUBX);
1299 7a3766f3 Richard Henderson
        break;
1300 7a3766f3 Richard Henderson
    case INDEX_op_mulu2_i32:
1301 7a3766f3 Richard Henderson
        tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
1302 7a3766f3 Richard Henderson
                       ARITH_UMUL);
1303 7a3766f3 Richard Henderson
        tcg_out_rdy(s, args[1]);
1304 7a3766f3 Richard Henderson
        break;
1305 56f4927e Richard Henderson
#endif
1306 8289b279 blueswir1
1307 8289b279 blueswir1
    case INDEX_op_qemu_ld8u:
1308 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 0);
1309 8289b279 blueswir1
        break;
1310 8289b279 blueswir1
    case INDEX_op_qemu_ld8s:
1311 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 0 | 4);
1312 8289b279 blueswir1
        break;
1313 8289b279 blueswir1
    case INDEX_op_qemu_ld16u:
1314 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 1);
1315 8289b279 blueswir1
        break;
1316 8289b279 blueswir1
    case INDEX_op_qemu_ld16s:
1317 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 1 | 4);
1318 8289b279 blueswir1
        break;
1319 8289b279 blueswir1
    case INDEX_op_qemu_ld32u:
1320 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 2);
1321 8289b279 blueswir1
        break;
1322 30c0c76c Jay Foad
#if TCG_TARGET_REG_BITS == 64
1323 8289b279 blueswir1
    case INDEX_op_qemu_ld32s:
1324 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 2 | 4);
1325 8289b279 blueswir1
        break;
1326 30c0c76c Jay Foad
#endif
1327 8289b279 blueswir1
    case INDEX_op_qemu_st8:
1328 f5ef6aac blueswir1
        tcg_out_qemu_st(s, args, 0);
1329 8289b279 blueswir1
        break;
1330 8289b279 blueswir1
    case INDEX_op_qemu_st16:
1331 f5ef6aac blueswir1
        tcg_out_qemu_st(s, args, 1);
1332 8289b279 blueswir1
        break;
1333 8289b279 blueswir1
    case INDEX_op_qemu_st32:
1334 f5ef6aac blueswir1
        tcg_out_qemu_st(s, args, 2);
1335 8289b279 blueswir1
        break;
1336 8289b279 blueswir1
1337 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1338 8289b279 blueswir1
    case INDEX_op_movi_i64:
1339 8289b279 blueswir1
        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
1340 8289b279 blueswir1
        break;
1341 53cd9273 blueswir1
    case INDEX_op_ld32s_i64:
1342 53cd9273 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDSW);
1343 53cd9273 blueswir1
        break;
1344 8289b279 blueswir1
    case INDEX_op_ld_i64:
1345 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], LDX);
1346 8289b279 blueswir1
        break;
1347 8289b279 blueswir1
    case INDEX_op_st_i64:
1348 8289b279 blueswir1
        tcg_out_ldst(s, args[0], args[1], args[2], STX);
1349 8289b279 blueswir1
        break;
1350 8289b279 blueswir1
    case INDEX_op_shl_i64:
1351 8289b279 blueswir1
        c = SHIFT_SLLX;
1352 ba225198 Richard Henderson
        goto gen_arith;
1353 8289b279 blueswir1
    case INDEX_op_shr_i64:
1354 8289b279 blueswir1
        c = SHIFT_SRLX;
1355 ba225198 Richard Henderson
        goto gen_arith;
1356 8289b279 blueswir1
    case INDEX_op_sar_i64:
1357 8289b279 blueswir1
        c = SHIFT_SRAX;
1358 ba225198 Richard Henderson
        goto gen_arith;
1359 8289b279 blueswir1
    case INDEX_op_mul_i64:
1360 8289b279 blueswir1
        c = ARITH_MULX;
1361 ba225198 Richard Henderson
        goto gen_arith;
1362 583d1215 Richard Henderson
    case INDEX_op_div_i64:
1363 53cd9273 blueswir1
        c = ARITH_SDIVX;
1364 ba225198 Richard Henderson
        goto gen_arith;
1365 583d1215 Richard Henderson
    case INDEX_op_divu_i64:
1366 8289b279 blueswir1
        c = ARITH_UDIVX;
1367 ba225198 Richard Henderson
        goto gen_arith;
1368 583d1215 Richard Henderson
    case INDEX_op_rem_i64:
1369 583d1215 Richard Henderson
    case INDEX_op_remu_i64:
1370 583d1215 Richard Henderson
        tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
1371 583d1215 Richard Henderson
                       opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
1372 583d1215 Richard Henderson
        tcg_out_arithc(s, TCG_REG_I5, TCG_REG_I5, args[2], const_args[2],
1373 583d1215 Richard Henderson
                       ARITH_MULX);
1374 583d1215 Richard Henderson
        tcg_out_arith(s, args[0], args[1], TCG_REG_I5, ARITH_SUB);
1375 583d1215 Richard Henderson
        break;
1376 cc6dfecf Richard Henderson
    case INDEX_op_ext32s_i64:
1377 cc6dfecf Richard Henderson
        if (const_args[1]) {
1378 cc6dfecf Richard Henderson
            tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
1379 cc6dfecf Richard Henderson
        } else {
1380 cc6dfecf Richard Henderson
            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
1381 cc6dfecf Richard Henderson
        }
1382 cc6dfecf Richard Henderson
        break;
1383 cc6dfecf Richard Henderson
    case INDEX_op_ext32u_i64:
1384 cc6dfecf Richard Henderson
        if (const_args[1]) {
1385 cc6dfecf Richard Henderson
            tcg_out_movi_imm32(s, args[0], args[1]);
1386 cc6dfecf Richard Henderson
        } else {
1387 cc6dfecf Richard Henderson
            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
1388 cc6dfecf Richard Henderson
        }
1389 cc6dfecf Richard Henderson
        break;
1390 8289b279 blueswir1
1391 8289b279 blueswir1
    case INDEX_op_brcond_i64:
1392 1da92db2 blueswir1
        tcg_out_brcond_i64(s, args[2], args[0], args[1], const_args[1],
1393 1da92db2 blueswir1
                           args[3]);
1394 8289b279 blueswir1
        break;
1395 dbfe80e1 Richard Henderson
    case INDEX_op_setcond_i64:
1396 dbfe80e1 Richard Henderson
        tcg_out_setcond_i64(s, args[3], args[0], args[1],
1397 dbfe80e1 Richard Henderson
                            args[2], const_args[2]);
1398 dbfe80e1 Richard Henderson
        break;
1399 dbfe80e1 Richard Henderson
1400 8289b279 blueswir1
    case INDEX_op_qemu_ld64:
1401 f5ef6aac blueswir1
        tcg_out_qemu_ld(s, args, 3);
1402 8289b279 blueswir1
        break;
1403 8289b279 blueswir1
    case INDEX_op_qemu_st64:
1404 f5ef6aac blueswir1
        tcg_out_qemu_st(s, args, 3);
1405 8289b279 blueswir1
        break;
1406 8289b279 blueswir1
1407 8289b279 blueswir1
#endif
1408 ba225198 Richard Henderson
    gen_arith:
1409 ba225198 Richard Henderson
        tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
1410 53cd9273 blueswir1
        break;
1411 53cd9273 blueswir1
1412 4b5a85c1 Richard Henderson
    gen_arith1:
1413 4b5a85c1 Richard Henderson
        tcg_out_arithc(s, args[0], TCG_REG_G0, args[1], const_args[1], c);
1414 4b5a85c1 Richard Henderson
        break;
1415 4b5a85c1 Richard Henderson
1416 8289b279 blueswir1
    default:
1417 8289b279 blueswir1
        fprintf(stderr, "unknown opcode 0x%x\n", opc);
1418 8289b279 blueswir1
        tcg_abort();
1419 8289b279 blueswir1
    }
1420 8289b279 blueswir1
}
1421 8289b279 blueswir1
1422 8289b279 blueswir1
static const TCGTargetOpDef sparc_op_defs[] = {
1423 8289b279 blueswir1
    { INDEX_op_exit_tb, { } },
1424 b3db8758 blueswir1
    { INDEX_op_goto_tb, { } },
1425 8289b279 blueswir1
    { INDEX_op_call, { "ri" } },
1426 8289b279 blueswir1
    { INDEX_op_jmp, { "ri" } },
1427 8289b279 blueswir1
    { INDEX_op_br, { } },
1428 8289b279 blueswir1
1429 8289b279 blueswir1
    { INDEX_op_mov_i32, { "r", "r" } },
1430 8289b279 blueswir1
    { INDEX_op_movi_i32, { "r" } },
1431 8289b279 blueswir1
    { INDEX_op_ld8u_i32, { "r", "r" } },
1432 8289b279 blueswir1
    { INDEX_op_ld8s_i32, { "r", "r" } },
1433 8289b279 blueswir1
    { INDEX_op_ld16u_i32, { "r", "r" } },
1434 8289b279 blueswir1
    { INDEX_op_ld16s_i32, { "r", "r" } },
1435 8289b279 blueswir1
    { INDEX_op_ld_i32, { "r", "r" } },
1436 8289b279 blueswir1
    { INDEX_op_st8_i32, { "r", "r" } },
1437 8289b279 blueswir1
    { INDEX_op_st16_i32, { "r", "r" } },
1438 8289b279 blueswir1
    { INDEX_op_st_i32, { "r", "r" } },
1439 8289b279 blueswir1
1440 53cd9273 blueswir1
    { INDEX_op_add_i32, { "r", "r", "rJ" } },
1441 53cd9273 blueswir1
    { INDEX_op_mul_i32, { "r", "r", "rJ" } },
1442 583d1215 Richard Henderson
    { INDEX_op_div_i32, { "r", "r", "rJ" } },
1443 583d1215 Richard Henderson
    { INDEX_op_divu_i32, { "r", "r", "rJ" } },
1444 583d1215 Richard Henderson
    { INDEX_op_rem_i32, { "r", "r", "rJ" } },
1445 583d1215 Richard Henderson
    { INDEX_op_remu_i32, { "r", "r", "rJ" } },
1446 53cd9273 blueswir1
    { INDEX_op_sub_i32, { "r", "r", "rJ" } },
1447 53cd9273 blueswir1
    { INDEX_op_and_i32, { "r", "r", "rJ" } },
1448 dc69960d Richard Henderson
    { INDEX_op_andc_i32, { "r", "r", "rJ" } },
1449 53cd9273 blueswir1
    { INDEX_op_or_i32, { "r", "r", "rJ" } },
1450 18c8f7a3 Richard Henderson
    { INDEX_op_orc_i32, { "r", "r", "rJ" } },
1451 53cd9273 blueswir1
    { INDEX_op_xor_i32, { "r", "r", "rJ" } },
1452 8289b279 blueswir1
1453 53cd9273 blueswir1
    { INDEX_op_shl_i32, { "r", "r", "rJ" } },
1454 53cd9273 blueswir1
    { INDEX_op_shr_i32, { "r", "r", "rJ" } },
1455 53cd9273 blueswir1
    { INDEX_op_sar_i32, { "r", "r", "rJ" } },
1456 8289b279 blueswir1
1457 4b5a85c1 Richard Henderson
    { INDEX_op_neg_i32, { "r", "rJ" } },
1458 be6551b1 Richard Henderson
    { INDEX_op_not_i32, { "r", "rJ" } },
1459 4b5a85c1 Richard Henderson
1460 56f4927e Richard Henderson
    { INDEX_op_brcond_i32, { "r", "rJ" } },
1461 dbfe80e1 Richard Henderson
    { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
1462 dbfe80e1 Richard Henderson
1463 56f4927e Richard Henderson
#if TCG_TARGET_REG_BITS == 32
1464 56f4927e Richard Henderson
    { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
1465 dbfe80e1 Richard Henderson
    { INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } },
1466 7a3766f3 Richard Henderson
    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
1467 7a3766f3 Richard Henderson
    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
1468 7a3766f3 Richard Henderson
    { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
1469 56f4927e Richard Henderson
#endif
1470 8289b279 blueswir1
1471 8289b279 blueswir1
    { INDEX_op_qemu_ld8u, { "r", "L" } },
1472 8289b279 blueswir1
    { INDEX_op_qemu_ld8s, { "r", "L" } },
1473 8289b279 blueswir1
    { INDEX_op_qemu_ld16u, { "r", "L" } },
1474 8289b279 blueswir1
    { INDEX_op_qemu_ld16s, { "r", "L" } },
1475 8289b279 blueswir1
    { INDEX_op_qemu_ld32u, { "r", "L" } },
1476 30c0c76c Jay Foad
#if TCG_TARGET_REG_BITS == 64
1477 8289b279 blueswir1
    { INDEX_op_qemu_ld32s, { "r", "L" } },
1478 30c0c76c Jay Foad
#endif
1479 8289b279 blueswir1
1480 8289b279 blueswir1
    { INDEX_op_qemu_st8, { "L", "L" } },
1481 8289b279 blueswir1
    { INDEX_op_qemu_st16, { "L", "L" } },
1482 8289b279 blueswir1
    { INDEX_op_qemu_st32, { "L", "L" } },
1483 8289b279 blueswir1
1484 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1485 8289b279 blueswir1
    { INDEX_op_mov_i64, { "r", "r" } },
1486 8289b279 blueswir1
    { INDEX_op_movi_i64, { "r" } },
1487 8289b279 blueswir1
    { INDEX_op_ld8u_i64, { "r", "r" } },
1488 8289b279 blueswir1
    { INDEX_op_ld8s_i64, { "r", "r" } },
1489 8289b279 blueswir1
    { INDEX_op_ld16u_i64, { "r", "r" } },
1490 8289b279 blueswir1
    { INDEX_op_ld16s_i64, { "r", "r" } },
1491 8289b279 blueswir1
    { INDEX_op_ld32u_i64, { "r", "r" } },
1492 8289b279 blueswir1
    { INDEX_op_ld32s_i64, { "r", "r" } },
1493 8289b279 blueswir1
    { INDEX_op_ld_i64, { "r", "r" } },
1494 8289b279 blueswir1
    { INDEX_op_st8_i64, { "r", "r" } },
1495 8289b279 blueswir1
    { INDEX_op_st16_i64, { "r", "r" } },
1496 8289b279 blueswir1
    { INDEX_op_st32_i64, { "r", "r" } },
1497 8289b279 blueswir1
    { INDEX_op_st_i64, { "r", "r" } },
1498 56fc64df blueswir1
    { INDEX_op_qemu_ld64, { "L", "L" } },
1499 56fc64df blueswir1
    { INDEX_op_qemu_st64, { "L", "L" } },
1500 8289b279 blueswir1
1501 53cd9273 blueswir1
    { INDEX_op_add_i64, { "r", "r", "rJ" } },
1502 53cd9273 blueswir1
    { INDEX_op_mul_i64, { "r", "r", "rJ" } },
1503 583d1215 Richard Henderson
    { INDEX_op_div_i64, { "r", "r", "rJ" } },
1504 583d1215 Richard Henderson
    { INDEX_op_divu_i64, { "r", "r", "rJ" } },
1505 583d1215 Richard Henderson
    { INDEX_op_rem_i64, { "r", "r", "rJ" } },
1506 583d1215 Richard Henderson
    { INDEX_op_remu_i64, { "r", "r", "rJ" } },
1507 53cd9273 blueswir1
    { INDEX_op_sub_i64, { "r", "r", "rJ" } },
1508 53cd9273 blueswir1
    { INDEX_op_and_i64, { "r", "r", "rJ" } },
1509 dc69960d Richard Henderson
    { INDEX_op_andc_i64, { "r", "r", "rJ" } },
1510 53cd9273 blueswir1
    { INDEX_op_or_i64, { "r", "r", "rJ" } },
1511 18c8f7a3 Richard Henderson
    { INDEX_op_orc_i64, { "r", "r", "rJ" } },
1512 53cd9273 blueswir1
    { INDEX_op_xor_i64, { "r", "r", "rJ" } },
1513 8289b279 blueswir1
1514 53cd9273 blueswir1
    { INDEX_op_shl_i64, { "r", "r", "rJ" } },
1515 53cd9273 blueswir1
    { INDEX_op_shr_i64, { "r", "r", "rJ" } },
1516 53cd9273 blueswir1
    { INDEX_op_sar_i64, { "r", "r", "rJ" } },
1517 4b5a85c1 Richard Henderson
1518 4b5a85c1 Richard Henderson
    { INDEX_op_neg_i64, { "r", "rJ" } },
1519 be6551b1 Richard Henderson
    { INDEX_op_not_i64, { "r", "rJ" } },
1520 4b5a85c1 Richard Henderson
1521 cc6dfecf Richard Henderson
    { INDEX_op_ext32s_i64, { "r", "ri" } },
1522 cc6dfecf Richard Henderson
    { INDEX_op_ext32u_i64, { "r", "ri" } },
1523 8289b279 blueswir1
1524 56f4927e Richard Henderson
    { INDEX_op_brcond_i64, { "r", "rJ" } },
1525 dbfe80e1 Richard Henderson
    { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
1526 8289b279 blueswir1
#endif
1527 8289b279 blueswir1
    { -1 },
1528 8289b279 blueswir1
};
1529 8289b279 blueswir1
1530 8289b279 blueswir1
void tcg_target_init(TCGContext *s)
1531 8289b279 blueswir1
{
1532 8289b279 blueswir1
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
1533 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1534 8289b279 blueswir1
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
1535 8289b279 blueswir1
#endif
1536 8289b279 blueswir1
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
1537 b3db8758 blueswir1
                     (1 << TCG_REG_G1) |
1538 b3db8758 blueswir1
                     (1 << TCG_REG_G2) |
1539 b3db8758 blueswir1
                     (1 << TCG_REG_G3) |
1540 b3db8758 blueswir1
                     (1 << TCG_REG_G4) |
1541 b3db8758 blueswir1
                     (1 << TCG_REG_G5) |
1542 b3db8758 blueswir1
                     (1 << TCG_REG_G6) |
1543 b3db8758 blueswir1
                     (1 << TCG_REG_G7) |
1544 8289b279 blueswir1
                     (1 << TCG_REG_O0) |
1545 8289b279 blueswir1
                     (1 << TCG_REG_O1) |
1546 8289b279 blueswir1
                     (1 << TCG_REG_O2) |
1547 8289b279 blueswir1
                     (1 << TCG_REG_O3) |
1548 8289b279 blueswir1
                     (1 << TCG_REG_O4) |
1549 8289b279 blueswir1
                     (1 << TCG_REG_O5) |
1550 8289b279 blueswir1
                     (1 << TCG_REG_O7));
1551 8289b279 blueswir1
1552 8289b279 blueswir1
    tcg_regset_clear(s->reserved_regs);
1553 8289b279 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
1554 a212ea75 Richard Henderson
#if TCG_TARGET_REG_BITS == 64
1555 d795eb86 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
1556 d795eb86 blueswir1
#endif
1557 53cd9273 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
1558 8289b279 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
1559 8289b279 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
1560 8289b279 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
1561 8289b279 blueswir1
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
1562 8289b279 blueswir1
    tcg_add_target_add_op_defs(sparc_op_defs);
1563 8289b279 blueswir1
}