Statistics
| Branch: | Revision:

root / tcg / mips / tcg-target.c @ 0834c9ea

History | View | Annotate | Download (48.5 kB)

1 afa05235 Aurelien Jarno
/*
2 afa05235 Aurelien Jarno
 * Tiny Code Generator for QEMU
3 afa05235 Aurelien Jarno
 *
4 afa05235 Aurelien Jarno
 * Copyright (c) 2008-2009 Arnaud Patard <arnaud.patard@rtp-net.org>
5 afa05235 Aurelien Jarno
 * Copyright (c) 2009 Aurelien Jarno <aurelien@aurel32.net>
6 afa05235 Aurelien Jarno
 * Based on i386/tcg-target.c - Copyright (c) 2008 Fabrice Bellard
7 afa05235 Aurelien Jarno
 *
8 afa05235 Aurelien Jarno
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 afa05235 Aurelien Jarno
 * of this software and associated documentation files (the "Software"), to deal
10 afa05235 Aurelien Jarno
 * in the Software without restriction, including without limitation the rights
11 afa05235 Aurelien Jarno
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 afa05235 Aurelien Jarno
 * copies of the Software, and to permit persons to whom the Software is
13 afa05235 Aurelien Jarno
 * furnished to do so, subject to the following conditions:
14 afa05235 Aurelien Jarno
 *
15 afa05235 Aurelien Jarno
 * The above copyright notice and this permission notice shall be included in
16 afa05235 Aurelien Jarno
 * all copies or substantial portions of the Software.
17 afa05235 Aurelien Jarno
 *
18 afa05235 Aurelien Jarno
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 afa05235 Aurelien Jarno
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 afa05235 Aurelien Jarno
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 afa05235 Aurelien Jarno
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 afa05235 Aurelien Jarno
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 afa05235 Aurelien Jarno
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 afa05235 Aurelien Jarno
 * THE SOFTWARE.
25 afa05235 Aurelien Jarno
 */
26 afa05235 Aurelien Jarno
27 afa05235 Aurelien Jarno
#if defined(TCG_TARGET_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28 afa05235 Aurelien Jarno
# define TCG_NEED_BSWAP 0
29 afa05235 Aurelien Jarno
#else
30 afa05235 Aurelien Jarno
# define TCG_NEED_BSWAP 1
31 afa05235 Aurelien Jarno
#endif
32 afa05235 Aurelien Jarno
33 afa05235 Aurelien Jarno
#ifndef NDEBUG
34 afa05235 Aurelien Jarno
static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
35 afa05235 Aurelien Jarno
    "zero",
36 afa05235 Aurelien Jarno
    "at",
37 afa05235 Aurelien Jarno
    "v0",
38 afa05235 Aurelien Jarno
    "v1",
39 afa05235 Aurelien Jarno
    "a0",
40 afa05235 Aurelien Jarno
    "a1",
41 afa05235 Aurelien Jarno
    "a2",
42 afa05235 Aurelien Jarno
    "a3",
43 afa05235 Aurelien Jarno
    "t0",
44 afa05235 Aurelien Jarno
    "t1",
45 afa05235 Aurelien Jarno
    "t2",
46 afa05235 Aurelien Jarno
    "t3",
47 afa05235 Aurelien Jarno
    "t4",
48 afa05235 Aurelien Jarno
    "t5",
49 afa05235 Aurelien Jarno
    "t6",
50 afa05235 Aurelien Jarno
    "t7",
51 afa05235 Aurelien Jarno
    "s0",
52 afa05235 Aurelien Jarno
    "s1",
53 afa05235 Aurelien Jarno
    "s2",
54 afa05235 Aurelien Jarno
    "s3",
55 afa05235 Aurelien Jarno
    "s4",
56 afa05235 Aurelien Jarno
    "s5",
57 afa05235 Aurelien Jarno
    "s6",
58 afa05235 Aurelien Jarno
    "s7",
59 afa05235 Aurelien Jarno
    "t8",
60 afa05235 Aurelien Jarno
    "t9",
61 afa05235 Aurelien Jarno
    "k0",
62 afa05235 Aurelien Jarno
    "k1",
63 afa05235 Aurelien Jarno
    "gp",
64 afa05235 Aurelien Jarno
    "sp",
65 afa05235 Aurelien Jarno
    "fp",
66 afa05235 Aurelien Jarno
    "ra",
67 afa05235 Aurelien Jarno
};
68 afa05235 Aurelien Jarno
#endif
69 afa05235 Aurelien Jarno
70 afa05235 Aurelien Jarno
/* check if we really need so many registers :P */
71 afa05235 Aurelien Jarno
static const int tcg_target_reg_alloc_order[] = {
72 afa05235 Aurelien Jarno
    TCG_REG_S0,
73 afa05235 Aurelien Jarno
    TCG_REG_S1,
74 afa05235 Aurelien Jarno
    TCG_REG_S2,
75 afa05235 Aurelien Jarno
    TCG_REG_S3,
76 afa05235 Aurelien Jarno
    TCG_REG_S4,
77 afa05235 Aurelien Jarno
    TCG_REG_S5,
78 afa05235 Aurelien Jarno
    TCG_REG_S6,
79 afa05235 Aurelien Jarno
    TCG_REG_S7,
80 afa05235 Aurelien Jarno
    TCG_REG_T1,
81 afa05235 Aurelien Jarno
    TCG_REG_T2,
82 afa05235 Aurelien Jarno
    TCG_REG_T3,
83 afa05235 Aurelien Jarno
    TCG_REG_T4,
84 afa05235 Aurelien Jarno
    TCG_REG_T5,
85 afa05235 Aurelien Jarno
    TCG_REG_T6,
86 afa05235 Aurelien Jarno
    TCG_REG_T7,
87 afa05235 Aurelien Jarno
    TCG_REG_T8,
88 afa05235 Aurelien Jarno
    TCG_REG_T9,
89 afa05235 Aurelien Jarno
    TCG_REG_A0,
90 afa05235 Aurelien Jarno
    TCG_REG_A1,
91 afa05235 Aurelien Jarno
    TCG_REG_A2,
92 afa05235 Aurelien Jarno
    TCG_REG_A3,
93 afa05235 Aurelien Jarno
    TCG_REG_V0,
94 afa05235 Aurelien Jarno
    TCG_REG_V1
95 afa05235 Aurelien Jarno
};
96 afa05235 Aurelien Jarno
97 afa05235 Aurelien Jarno
static const int tcg_target_call_iarg_regs[4] = {
98 afa05235 Aurelien Jarno
    TCG_REG_A0,
99 afa05235 Aurelien Jarno
    TCG_REG_A1,
100 afa05235 Aurelien Jarno
    TCG_REG_A2,
101 afa05235 Aurelien Jarno
    TCG_REG_A3
102 afa05235 Aurelien Jarno
};
103 afa05235 Aurelien Jarno
104 afa05235 Aurelien Jarno
static const int tcg_target_call_oarg_regs[2] = {
105 afa05235 Aurelien Jarno
    TCG_REG_V0,
106 afa05235 Aurelien Jarno
    TCG_REG_V1
107 afa05235 Aurelien Jarno
};
108 afa05235 Aurelien Jarno
109 afa05235 Aurelien Jarno
static uint8_t *tb_ret_addr;
110 afa05235 Aurelien Jarno
111 afa05235 Aurelien Jarno
static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
112 afa05235 Aurelien Jarno
{
113 afa05235 Aurelien Jarno
    return target & 0xffff;
114 afa05235 Aurelien Jarno
}
115 afa05235 Aurelien Jarno
116 afa05235 Aurelien Jarno
static inline void reloc_lo16 (void *pc, tcg_target_long target)
117 afa05235 Aurelien Jarno
{
118 afa05235 Aurelien Jarno
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
119 afa05235 Aurelien Jarno
                       | reloc_lo16_val(pc, target);
120 afa05235 Aurelien Jarno
}
121 afa05235 Aurelien Jarno
122 afa05235 Aurelien Jarno
static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
123 afa05235 Aurelien Jarno
{
124 afa05235 Aurelien Jarno
    return (target >> 16) & 0xffff;
125 afa05235 Aurelien Jarno
}
126 afa05235 Aurelien Jarno
127 afa05235 Aurelien Jarno
static inline void reloc_hi16 (void *pc, tcg_target_long target)
128 afa05235 Aurelien Jarno
{
129 afa05235 Aurelien Jarno
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
130 afa05235 Aurelien Jarno
                       | reloc_hi16_val(pc, target);
131 afa05235 Aurelien Jarno
}
132 afa05235 Aurelien Jarno
133 afa05235 Aurelien Jarno
static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
134 afa05235 Aurelien Jarno
{
135 afa05235 Aurelien Jarno
    int32_t disp;
136 afa05235 Aurelien Jarno
137 afa05235 Aurelien Jarno
    disp = target - (tcg_target_long) pc - 4;
138 afa05235 Aurelien Jarno
    if (disp != (disp << 14) >> 14) {
139 afa05235 Aurelien Jarno
        tcg_abort ();
140 afa05235 Aurelien Jarno
    }
141 afa05235 Aurelien Jarno
142 afa05235 Aurelien Jarno
    return (disp >> 2) & 0xffff;
143 afa05235 Aurelien Jarno
}
144 afa05235 Aurelien Jarno
145 afa05235 Aurelien Jarno
static inline void reloc_pc16 (void *pc, tcg_target_long target)
146 afa05235 Aurelien Jarno
{
147 afa05235 Aurelien Jarno
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
148 afa05235 Aurelien Jarno
                       | reloc_pc16_val(pc, target);
149 afa05235 Aurelien Jarno
}
150 afa05235 Aurelien Jarno
151 afa05235 Aurelien Jarno
static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
152 afa05235 Aurelien Jarno
{
153 afa05235 Aurelien Jarno
    if ((((tcg_target_long)pc + 4) & 0xf0000000) != (target & 0xf0000000)) {
154 afa05235 Aurelien Jarno
        tcg_abort ();
155 afa05235 Aurelien Jarno
    }
156 afa05235 Aurelien Jarno
157 afa05235 Aurelien Jarno
    return (target >> 2) & 0x3ffffff;
158 afa05235 Aurelien Jarno
}
159 afa05235 Aurelien Jarno
160 afa05235 Aurelien Jarno
static inline void reloc_pc26 (void *pc, tcg_target_long target)
161 afa05235 Aurelien Jarno
{
162 afa05235 Aurelien Jarno
    *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
163 afa05235 Aurelien Jarno
                       | reloc_26_val(pc, target);
164 afa05235 Aurelien Jarno
}
165 afa05235 Aurelien Jarno
166 afa05235 Aurelien Jarno
static void patch_reloc(uint8_t *code_ptr, int type,
167 afa05235 Aurelien Jarno
                        tcg_target_long value, tcg_target_long addend)
168 afa05235 Aurelien Jarno
{
169 afa05235 Aurelien Jarno
    value += addend;
170 afa05235 Aurelien Jarno
    switch(type) {
171 afa05235 Aurelien Jarno
    case R_MIPS_LO16:
172 afa05235 Aurelien Jarno
        reloc_lo16(code_ptr, value);
173 afa05235 Aurelien Jarno
        break;
174 afa05235 Aurelien Jarno
    case R_MIPS_HI16:
175 afa05235 Aurelien Jarno
        reloc_hi16(code_ptr, value);
176 afa05235 Aurelien Jarno
        break;
177 afa05235 Aurelien Jarno
    case R_MIPS_PC16:
178 afa05235 Aurelien Jarno
        reloc_pc16(code_ptr, value);
179 afa05235 Aurelien Jarno
        break;
180 afa05235 Aurelien Jarno
    case R_MIPS_26:
181 afa05235 Aurelien Jarno
        reloc_pc26(code_ptr, value);
182 afa05235 Aurelien Jarno
        break;
183 afa05235 Aurelien Jarno
    default:
184 afa05235 Aurelien Jarno
        tcg_abort();
185 afa05235 Aurelien Jarno
    }
186 afa05235 Aurelien Jarno
}
187 afa05235 Aurelien Jarno
188 afa05235 Aurelien Jarno
/* maximum number of register used for input function arguments */
189 afa05235 Aurelien Jarno
static inline int tcg_target_get_call_iarg_regs_count(int flags)
190 afa05235 Aurelien Jarno
{
191 afa05235 Aurelien Jarno
    return 4;
192 afa05235 Aurelien Jarno
}
193 afa05235 Aurelien Jarno
194 afa05235 Aurelien Jarno
/* parse target specific constraints */
195 afa05235 Aurelien Jarno
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
196 afa05235 Aurelien Jarno
{
197 afa05235 Aurelien Jarno
    const char *ct_str;
198 afa05235 Aurelien Jarno
199 afa05235 Aurelien Jarno
    ct_str = *pct_str;
200 afa05235 Aurelien Jarno
    switch(ct_str[0]) {
201 afa05235 Aurelien Jarno
    case 'r':
202 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_REG;
203 afa05235 Aurelien Jarno
        tcg_regset_set(ct->u.regs, 0xffffffff);
204 afa05235 Aurelien Jarno
        break;
205 afa05235 Aurelien Jarno
    case 'C':
206 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_REG;
207 afa05235 Aurelien Jarno
        tcg_regset_clear(ct->u.regs);
208 afa05235 Aurelien Jarno
        tcg_regset_set_reg(ct->u.regs, TCG_REG_T9);
209 afa05235 Aurelien Jarno
        break;
210 afa05235 Aurelien Jarno
    case 'L': /* qemu_ld output arg constraint */
211 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_REG;
212 afa05235 Aurelien Jarno
        tcg_regset_set(ct->u.regs, 0xffffffff);
213 afa05235 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_V0);
214 afa05235 Aurelien Jarno
        break;
215 afa05235 Aurelien Jarno
    case 'l': /* qemu_ld input arg constraint */
216 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_REG;
217 afa05235 Aurelien Jarno
        tcg_regset_set(ct->u.regs, 0xffffffff);
218 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
219 afa05235 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
220 89c33337 Blue Swirl
# if (TARGET_LONG_BITS == 64)
221 18fec301 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
222 18fec301 Aurelien Jarno
# endif
223 afa05235 Aurelien Jarno
#endif
224 afa05235 Aurelien Jarno
        break;
225 afa05235 Aurelien Jarno
    case 'S': /* qemu_st constraint */
226 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_REG;
227 afa05235 Aurelien Jarno
        tcg_regset_set(ct->u.regs, 0xffffffff);
228 afa05235 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
229 cc01cc8e Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
230 89c33337 Blue Swirl
# if (TARGET_LONG_BITS == 32)
231 afa05235 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
232 afa05235 Aurelien Jarno
# endif
233 afa05235 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
234 89c33337 Blue Swirl
# if TARGET_LONG_BITS == 64
235 18fec301 Aurelien Jarno
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
236 18fec301 Aurelien Jarno
# endif
237 afa05235 Aurelien Jarno
#endif
238 afa05235 Aurelien Jarno
        break;
239 afa05235 Aurelien Jarno
    case 'I':
240 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_CONST_U16;
241 afa05235 Aurelien Jarno
        break;
242 afa05235 Aurelien Jarno
    case 'J':
243 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_CONST_S16;
244 afa05235 Aurelien Jarno
        break;
245 afa05235 Aurelien Jarno
    case 'Z':
246 afa05235 Aurelien Jarno
        /* We are cheating a bit here, using the fact that the register
247 afa05235 Aurelien Jarno
           ZERO is also the register number 0. Hence there is no need
248 afa05235 Aurelien Jarno
           to check for const_args in each instruction. */
249 afa05235 Aurelien Jarno
        ct->ct |= TCG_CT_CONST_ZERO;
250 afa05235 Aurelien Jarno
        break;
251 afa05235 Aurelien Jarno
    default:
252 afa05235 Aurelien Jarno
        return -1;
253 afa05235 Aurelien Jarno
    }
254 afa05235 Aurelien Jarno
    ct_str++;
255 afa05235 Aurelien Jarno
    *pct_str = ct_str;
256 afa05235 Aurelien Jarno
    return 0;
257 afa05235 Aurelien Jarno
}
258 afa05235 Aurelien Jarno
259 afa05235 Aurelien Jarno
/* test if a constant matches the constraint */
260 afa05235 Aurelien Jarno
static inline int tcg_target_const_match(tcg_target_long val,
261 afa05235 Aurelien Jarno
                                         const TCGArgConstraint *arg_ct)
262 afa05235 Aurelien Jarno
{
263 afa05235 Aurelien Jarno
    int ct;
264 afa05235 Aurelien Jarno
    ct = arg_ct->ct;
265 afa05235 Aurelien Jarno
    if (ct & TCG_CT_CONST)
266 afa05235 Aurelien Jarno
        return 1;
267 afa05235 Aurelien Jarno
    else if ((ct & TCG_CT_CONST_ZERO) && val == 0)
268 afa05235 Aurelien Jarno
        return 1;
269 afa05235 Aurelien Jarno
    else if ((ct & TCG_CT_CONST_U16) && val == (uint16_t)val)
270 afa05235 Aurelien Jarno
        return 1;
271 afa05235 Aurelien Jarno
    else if ((ct & TCG_CT_CONST_S16) && val == (int16_t)val)
272 afa05235 Aurelien Jarno
        return 1;
273 afa05235 Aurelien Jarno
    else
274 afa05235 Aurelien Jarno
        return 0;
275 afa05235 Aurelien Jarno
}
276 afa05235 Aurelien Jarno
277 afa05235 Aurelien Jarno
/* instruction opcodes */
278 afa05235 Aurelien Jarno
enum {
279 afa05235 Aurelien Jarno
    OPC_BEQ      = 0x04 << 26,
280 afa05235 Aurelien Jarno
    OPC_BNE      = 0x05 << 26,
281 afa05235 Aurelien Jarno
    OPC_ADDIU    = 0x09 << 26,
282 4cb26382 Aurelien Jarno
    OPC_SLTI     = 0x0A << 26,
283 4cb26382 Aurelien Jarno
    OPC_SLTIU    = 0x0B << 26,
284 afa05235 Aurelien Jarno
    OPC_ANDI     = 0x0C << 26,
285 afa05235 Aurelien Jarno
    OPC_ORI      = 0x0D << 26,
286 afa05235 Aurelien Jarno
    OPC_XORI     = 0x0E << 26,
287 afa05235 Aurelien Jarno
    OPC_LUI      = 0x0F << 26,
288 afa05235 Aurelien Jarno
    OPC_LB       = 0x20 << 26,
289 afa05235 Aurelien Jarno
    OPC_LH       = 0x21 << 26,
290 afa05235 Aurelien Jarno
    OPC_LW       = 0x23 << 26,
291 afa05235 Aurelien Jarno
    OPC_LBU      = 0x24 << 26,
292 afa05235 Aurelien Jarno
    OPC_LHU      = 0x25 << 26,
293 afa05235 Aurelien Jarno
    OPC_LWU      = 0x27 << 26,
294 afa05235 Aurelien Jarno
    OPC_SB       = 0x28 << 26,
295 afa05235 Aurelien Jarno
    OPC_SH       = 0x29 << 26,
296 afa05235 Aurelien Jarno
    OPC_SW       = 0x2B << 26,
297 116348de Aurelien Jarno
298 116348de Aurelien Jarno
    OPC_SPECIAL  = 0x00 << 26,
299 afa05235 Aurelien Jarno
    OPC_SLL      = OPC_SPECIAL | 0x00,
300 afa05235 Aurelien Jarno
    OPC_SRL      = OPC_SPECIAL | 0x02,
301 afa05235 Aurelien Jarno
    OPC_SRA      = OPC_SPECIAL | 0x03,
302 afa05235 Aurelien Jarno
    OPC_SLLV     = OPC_SPECIAL | 0x04,
303 afa05235 Aurelien Jarno
    OPC_SRLV     = OPC_SPECIAL | 0x06,
304 afa05235 Aurelien Jarno
    OPC_SRAV     = OPC_SPECIAL | 0x07,
305 afa05235 Aurelien Jarno
    OPC_JR       = OPC_SPECIAL | 0x08,
306 afa05235 Aurelien Jarno
    OPC_JALR     = OPC_SPECIAL | 0x09,
307 afa05235 Aurelien Jarno
    OPC_MFHI     = OPC_SPECIAL | 0x10,
308 afa05235 Aurelien Jarno
    OPC_MFLO     = OPC_SPECIAL | 0x12,
309 afa05235 Aurelien Jarno
    OPC_MULT     = OPC_SPECIAL | 0x18,
310 afa05235 Aurelien Jarno
    OPC_MULTU    = OPC_SPECIAL | 0x19,
311 afa05235 Aurelien Jarno
    OPC_DIV      = OPC_SPECIAL | 0x1A,
312 afa05235 Aurelien Jarno
    OPC_DIVU     = OPC_SPECIAL | 0x1B,
313 afa05235 Aurelien Jarno
    OPC_ADDU     = OPC_SPECIAL | 0x21,
314 afa05235 Aurelien Jarno
    OPC_SUBU     = OPC_SPECIAL | 0x23,
315 afa05235 Aurelien Jarno
    OPC_AND      = OPC_SPECIAL | 0x24,
316 afa05235 Aurelien Jarno
    OPC_OR       = OPC_SPECIAL | 0x25,
317 afa05235 Aurelien Jarno
    OPC_XOR      = OPC_SPECIAL | 0x26,
318 afa05235 Aurelien Jarno
    OPC_NOR      = OPC_SPECIAL | 0x27,
319 afa05235 Aurelien Jarno
    OPC_SLT      = OPC_SPECIAL | 0x2A,
320 afa05235 Aurelien Jarno
    OPC_SLTU     = OPC_SPECIAL | 0x2B,
321 116348de Aurelien Jarno
322 116348de Aurelien Jarno
    OPC_SPECIAL3 = 0x1f << 26,
323 116348de Aurelien Jarno
    OPC_SEB      = OPC_SPECIAL3 | 0x420,
324 116348de Aurelien Jarno
    OPC_SEH      = OPC_SPECIAL3 | 0x620,
325 afa05235 Aurelien Jarno
};
326 afa05235 Aurelien Jarno
327 afa05235 Aurelien Jarno
/*
328 afa05235 Aurelien Jarno
 * Type reg
329 afa05235 Aurelien Jarno
 */
330 afa05235 Aurelien Jarno
static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
331 afa05235 Aurelien Jarno
{
332 afa05235 Aurelien Jarno
    int32_t inst;
333 afa05235 Aurelien Jarno
334 afa05235 Aurelien Jarno
    inst = opc;
335 afa05235 Aurelien Jarno
    inst |= (rs & 0x1F) << 21;
336 afa05235 Aurelien Jarno
    inst |= (rt & 0x1F) << 16;
337 afa05235 Aurelien Jarno
    inst |= (rd & 0x1F) << 11;
338 afa05235 Aurelien Jarno
    tcg_out32(s, inst);
339 afa05235 Aurelien Jarno
}
340 afa05235 Aurelien Jarno
341 afa05235 Aurelien Jarno
/*
342 afa05235 Aurelien Jarno
 * Type immediate
343 afa05235 Aurelien Jarno
 */
344 afa05235 Aurelien Jarno
static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
345 afa05235 Aurelien Jarno
{
346 afa05235 Aurelien Jarno
    int32_t inst;
347 afa05235 Aurelien Jarno
348 afa05235 Aurelien Jarno
    inst = opc;
349 afa05235 Aurelien Jarno
    inst |= (rs & 0x1F) << 21;
350 afa05235 Aurelien Jarno
    inst |= (rt & 0x1F) << 16;
351 afa05235 Aurelien Jarno
    inst |= (imm & 0xffff);
352 afa05235 Aurelien Jarno
    tcg_out32(s, inst);
353 afa05235 Aurelien Jarno
}
354 afa05235 Aurelien Jarno
355 afa05235 Aurelien Jarno
/*
356 6d8ff4d8 Aurelien Jarno
 * Type branch
357 6d8ff4d8 Aurelien Jarno
 */
358 6d8ff4d8 Aurelien Jarno
static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
359 6d8ff4d8 Aurelien Jarno
{
360 56779034 Aurelien Jarno
    /* We pay attention here to not modify the branch target by reading
361 56779034 Aurelien Jarno
       the existing value and using it again. This ensure that caches and
362 56779034 Aurelien Jarno
       memory are kept coherent during retranslation. */
363 d43ffce1 Aurelien Jarno
    uint16_t offset = (uint16_t)(*(uint32_t *) s->code_ptr);
364 6d8ff4d8 Aurelien Jarno
365 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_imm(s, opc, rt, rs, offset);
366 6d8ff4d8 Aurelien Jarno
}
367 6d8ff4d8 Aurelien Jarno
368 6d8ff4d8 Aurelien Jarno
/*
369 afa05235 Aurelien Jarno
 * Type sa
370 afa05235 Aurelien Jarno
 */
371 afa05235 Aurelien Jarno
static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
372 afa05235 Aurelien Jarno
{
373 afa05235 Aurelien Jarno
    int32_t inst;
374 afa05235 Aurelien Jarno
375 afa05235 Aurelien Jarno
    inst = opc;
376 afa05235 Aurelien Jarno
    inst |= (rt & 0x1F) << 16;
377 afa05235 Aurelien Jarno
    inst |= (rd & 0x1F) << 11;
378 afa05235 Aurelien Jarno
    inst |= (sa & 0x1F) <<  6;
379 afa05235 Aurelien Jarno
    tcg_out32(s, inst);
380 afa05235 Aurelien Jarno
381 afa05235 Aurelien Jarno
}
382 afa05235 Aurelien Jarno
383 afa05235 Aurelien Jarno
static inline void tcg_out_nop(TCGContext *s)
384 afa05235 Aurelien Jarno
{
385 afa05235 Aurelien Jarno
    tcg_out32(s, 0);
386 afa05235 Aurelien Jarno
}
387 afa05235 Aurelien Jarno
388 2a534aff Richard Henderson
static inline void tcg_out_mov(TCGContext *s, TCGType type,
389 2a534aff Richard Henderson
                               TCGReg ret, TCGReg arg)
390 afa05235 Aurelien Jarno
{
391 18fec301 Aurelien Jarno
    /* Simple reg-reg move, optimising out the 'do nothing' case */
392 18fec301 Aurelien Jarno
    if (ret != arg) {
393 18fec301 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, ret, arg, TCG_REG_ZERO);
394 18fec301 Aurelien Jarno
    }
395 afa05235 Aurelien Jarno
}
396 afa05235 Aurelien Jarno
397 afa05235 Aurelien Jarno
static inline void tcg_out_movi(TCGContext *s, TCGType type,
398 2a534aff Richard Henderson
                                TCGReg reg, tcg_target_long arg)
399 afa05235 Aurelien Jarno
{
400 afa05235 Aurelien Jarno
    if (arg == (int16_t)arg) {
401 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ADDIU, reg, TCG_REG_ZERO, arg);
402 afa05235 Aurelien Jarno
    } else if (arg == (uint16_t)arg) {
403 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ORI, reg, TCG_REG_ZERO, arg);
404 afa05235 Aurelien Jarno
    } else {
405 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_LUI, reg, 0, arg >> 16);
406 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ORI, reg, reg, arg & 0xffff);
407 afa05235 Aurelien Jarno
    }
408 afa05235 Aurelien Jarno
}
409 afa05235 Aurelien Jarno
410 afa05235 Aurelien Jarno
static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
411 afa05235 Aurelien Jarno
{
412 afa05235 Aurelien Jarno
    /* ret and arg can't be register at */
413 afa05235 Aurelien Jarno
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
414 afa05235 Aurelien Jarno
        tcg_abort();
415 afa05235 Aurelien Jarno
    }
416 afa05235 Aurelien Jarno
417 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
418 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
419 afa05235 Aurelien Jarno
420 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
421 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
422 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
423 afa05235 Aurelien Jarno
}
424 afa05235 Aurelien Jarno
425 afa05235 Aurelien Jarno
static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
426 afa05235 Aurelien Jarno
{
427 afa05235 Aurelien Jarno
    /* ret and arg can't be register at */
428 afa05235 Aurelien Jarno
    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
429 afa05235 Aurelien Jarno
        tcg_abort();
430 afa05235 Aurelien Jarno
    }
431 afa05235 Aurelien Jarno
432 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
433 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
434 afa05235 Aurelien Jarno
435 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
436 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
437 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
438 afa05235 Aurelien Jarno
}
439 afa05235 Aurelien Jarno
440 afa05235 Aurelien Jarno
static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
441 afa05235 Aurelien Jarno
{
442 afa05235 Aurelien Jarno
    /* ret and arg must be different and can't be register at */
443 afa05235 Aurelien Jarno
    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
444 afa05235 Aurelien Jarno
        tcg_abort();
445 afa05235 Aurelien Jarno
    }
446 afa05235 Aurelien Jarno
447 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
448 afa05235 Aurelien Jarno
449 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
450 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
451 afa05235 Aurelien Jarno
452 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
453 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
454 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
455 afa05235 Aurelien Jarno
456 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
457 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
458 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
459 afa05235 Aurelien Jarno
}
460 afa05235 Aurelien Jarno
461 116348de Aurelien Jarno
static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
462 116348de Aurelien Jarno
{
463 116348de Aurelien Jarno
#ifdef _MIPS_ARCH_MIPS32R2
464 116348de Aurelien Jarno
    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
465 116348de Aurelien Jarno
#else
466 116348de Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
467 116348de Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
468 116348de Aurelien Jarno
#endif
469 116348de Aurelien Jarno
}
470 116348de Aurelien Jarno
471 116348de Aurelien Jarno
static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
472 116348de Aurelien Jarno
{
473 116348de Aurelien Jarno
#ifdef _MIPS_ARCH_MIPS32R2
474 116348de Aurelien Jarno
    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
475 116348de Aurelien Jarno
#else
476 116348de Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
477 116348de Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
478 116348de Aurelien Jarno
#endif
479 116348de Aurelien Jarno
}
480 116348de Aurelien Jarno
481 afa05235 Aurelien Jarno
static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
482 afa05235 Aurelien Jarno
                              int arg1, tcg_target_long arg2)
483 afa05235 Aurelien Jarno
{
484 afa05235 Aurelien Jarno
    if (arg2 == (int16_t) arg2) {
485 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, opc, arg, arg1, arg2);
486 afa05235 Aurelien Jarno
    } else {
487 afa05235 Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, arg2);
488 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, TCG_REG_AT, arg1);
489 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, opc, arg, TCG_REG_AT, 0);
490 afa05235 Aurelien Jarno
    }
491 afa05235 Aurelien Jarno
}
492 afa05235 Aurelien Jarno
493 2a534aff Richard Henderson
static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
494 2a534aff Richard Henderson
                              TCGReg arg1, tcg_target_long arg2)
495 afa05235 Aurelien Jarno
{
496 afa05235 Aurelien Jarno
    tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
497 afa05235 Aurelien Jarno
}
498 afa05235 Aurelien Jarno
499 2a534aff Richard Henderson
static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
500 2a534aff Richard Henderson
                              TCGReg arg1, tcg_target_long arg2)
501 afa05235 Aurelien Jarno
{
502 afa05235 Aurelien Jarno
    tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
503 afa05235 Aurelien Jarno
}
504 afa05235 Aurelien Jarno
505 afa05235 Aurelien Jarno
static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
506 afa05235 Aurelien Jarno
{
507 afa05235 Aurelien Jarno
    if (val == (int16_t)val) {
508 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
509 afa05235 Aurelien Jarno
    } else {
510 afa05235 Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, val);
511 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, reg, reg, TCG_REG_AT);
512 afa05235 Aurelien Jarno
    }
513 afa05235 Aurelien Jarno
}
514 afa05235 Aurelien Jarno
515 18fec301 Aurelien Jarno
/* Helper routines for marshalling helper function arguments into
516 18fec301 Aurelien Jarno
 * the correct registers and stack.
517 18fec301 Aurelien Jarno
 * arg_num is where we want to put this argument, and is updated to be ready
518 18fec301 Aurelien Jarno
 * for the next call. arg is the argument itself. Note that arg_num 0..3 is
519 18fec301 Aurelien Jarno
 * real registers, 4+ on stack.
520 18fec301 Aurelien Jarno
 *
521 18fec301 Aurelien Jarno
 * We provide routines for arguments which are: immediate, 32 bit
522 18fec301 Aurelien Jarno
 * value in register, 16 and 8 bit values in register (which must be zero
523 18fec301 Aurelien Jarno
 * extended before use) and 64 bit value in a lo:hi register pair.
524 18fec301 Aurelien Jarno
 */
525 18fec301 Aurelien Jarno
#define DEFINE_TCG_OUT_CALL_IARG(NAME, ARGPARAM)                               \
526 18fec301 Aurelien Jarno
    static inline void NAME(TCGContext *s, int *arg_num, ARGPARAM)             \
527 18fec301 Aurelien Jarno
    {                                                                          \
528 18fec301 Aurelien Jarno
    if (*arg_num < 4) {                                                        \
529 18fec301 Aurelien Jarno
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(tcg_target_call_iarg_regs[*arg_num]); \
530 18fec301 Aurelien Jarno
    } else {                                                                   \
531 18fec301 Aurelien Jarno
        DEFINE_TCG_OUT_CALL_IARG_GET_ARG(TCG_REG_AT);                          \
532 18fec301 Aurelien Jarno
        tcg_out_st(s, TCG_TYPE_I32, TCG_REG_AT, TCG_REG_SP, 4 * (*arg_num));   \
533 18fec301 Aurelien Jarno
    }                                                                          \
534 18fec301 Aurelien Jarno
    (*arg_num)++;                                                              \
535 18fec301 Aurelien Jarno
}
536 18fec301 Aurelien Jarno
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
537 18fec301 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xff);
538 18fec301 Aurelien Jarno
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg8, TCGReg arg)
539 18fec301 Aurelien Jarno
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
540 18fec301 Aurelien Jarno
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
541 18fec301 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, A, arg, 0xffff);
542 18fec301 Aurelien Jarno
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
543 18fec301 Aurelien Jarno
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
544 18fec301 Aurelien Jarno
#define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
545 18fec301 Aurelien Jarno
    tcg_out_movi(s, TCG_TYPE_I32, A, arg);
546 18fec301 Aurelien Jarno
DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg)
547 18fec301 Aurelien Jarno
#undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
548 18fec301 Aurelien Jarno
549 18fec301 Aurelien Jarno
/* We don't use the macro for this one to avoid an unnecessary reg-reg
550 18fec301 Aurelien Jarno
   move when storing to the stack. */
551 18fec301 Aurelien Jarno
static inline void tcg_out_call_iarg_reg32(TCGContext *s, int *arg_num,
552 18fec301 Aurelien Jarno
                                           TCGReg arg)
553 18fec301 Aurelien Jarno
{
554 18fec301 Aurelien Jarno
    if (*arg_num < 4) {
555 18fec301 Aurelien Jarno
        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[*arg_num], arg);
556 18fec301 Aurelien Jarno
    } else {
557 18fec301 Aurelien Jarno
        tcg_out_st(s, TCG_TYPE_I32, arg, TCG_REG_SP, 4 * (*arg_num));
558 18fec301 Aurelien Jarno
    }
559 18fec301 Aurelien Jarno
    (*arg_num)++;
560 18fec301 Aurelien Jarno
}
561 18fec301 Aurelien Jarno
562 18fec301 Aurelien Jarno
static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
563 18fec301 Aurelien Jarno
                                           TCGReg arg_low, TCGReg arg_high)
564 18fec301 Aurelien Jarno
{
565 18fec301 Aurelien Jarno
    (*arg_num) = (*arg_num + 1) & ~1;
566 18fec301 Aurelien Jarno
567 18fec301 Aurelien Jarno
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
568 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
569 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
570 18fec301 Aurelien Jarno
#else
571 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, arg_num, arg_low);
572 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, arg_num, arg_high);
573 18fec301 Aurelien Jarno
#endif
574 18fec301 Aurelien Jarno
}
575 18fec301 Aurelien Jarno
576 8a56e840 Richard Henderson
static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
577 afa05235 Aurelien Jarno
                           int arg2, int label_index)
578 afa05235 Aurelien Jarno
{
579 afa05235 Aurelien Jarno
    TCGLabel *l = &s->labels[label_index];
580 afa05235 Aurelien Jarno
581 afa05235 Aurelien Jarno
    switch (cond) {
582 afa05235 Aurelien Jarno
    case TCG_COND_EQ:
583 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BEQ, arg1, arg2);
584 afa05235 Aurelien Jarno
        break;
585 afa05235 Aurelien Jarno
    case TCG_COND_NE:
586 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
587 afa05235 Aurelien Jarno
        break;
588 afa05235 Aurelien Jarno
    case TCG_COND_LT:
589 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
590 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
591 afa05235 Aurelien Jarno
        break;
592 afa05235 Aurelien Jarno
    case TCG_COND_LTU:
593 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
594 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
595 afa05235 Aurelien Jarno
        break;
596 afa05235 Aurelien Jarno
    case TCG_COND_GE:
597 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
598 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
599 afa05235 Aurelien Jarno
        break;
600 afa05235 Aurelien Jarno
    case TCG_COND_GEU:
601 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
602 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
603 afa05235 Aurelien Jarno
        break;
604 afa05235 Aurelien Jarno
    case TCG_COND_LE:
605 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
606 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
607 afa05235 Aurelien Jarno
        break;
608 afa05235 Aurelien Jarno
    case TCG_COND_LEU:
609 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
610 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
611 afa05235 Aurelien Jarno
        break;
612 afa05235 Aurelien Jarno
    case TCG_COND_GT:
613 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
614 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
615 afa05235 Aurelien Jarno
        break;
616 afa05235 Aurelien Jarno
    case TCG_COND_GTU:
617 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
618 6d8ff4d8 Aurelien Jarno
        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
619 afa05235 Aurelien Jarno
        break;
620 afa05235 Aurelien Jarno
    default:
621 afa05235 Aurelien Jarno
        tcg_abort();
622 afa05235 Aurelien Jarno
        break;
623 afa05235 Aurelien Jarno
    }
624 afa05235 Aurelien Jarno
    if (l->has_value) {
625 afa05235 Aurelien Jarno
        reloc_pc16(s->code_ptr - 4, l->u.value);
626 afa05235 Aurelien Jarno
    } else {
627 afa05235 Aurelien Jarno
        tcg_out_reloc(s, s->code_ptr - 4, R_MIPS_PC16, label_index, 0);
628 afa05235 Aurelien Jarno
    }
629 afa05235 Aurelien Jarno
    tcg_out_nop(s);
630 afa05235 Aurelien Jarno
}
631 afa05235 Aurelien Jarno
632 afa05235 Aurelien Jarno
/* XXX: we implement it at the target level to avoid having to
633 afa05235 Aurelien Jarno
   handle cross basic blocks temporaries */
634 8a56e840 Richard Henderson
static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
635 afa05235 Aurelien Jarno
                            int arg2, int arg3, int arg4, int label_index)
636 afa05235 Aurelien Jarno
{
637 afa05235 Aurelien Jarno
    void *label_ptr;
638 afa05235 Aurelien Jarno
639 afa05235 Aurelien Jarno
    switch(cond) {
640 afa05235 Aurelien Jarno
    case TCG_COND_NE:
641 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_NE, arg2, arg4, label_index);
642 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_NE, arg1, arg3, label_index);
643 afa05235 Aurelien Jarno
        return;
644 afa05235 Aurelien Jarno
    case TCG_COND_EQ:
645 afa05235 Aurelien Jarno
        break;
646 afa05235 Aurelien Jarno
    case TCG_COND_LT:
647 afa05235 Aurelien Jarno
    case TCG_COND_LE:
648 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_LT, arg2, arg4, label_index);
649 afa05235 Aurelien Jarno
        break;
650 afa05235 Aurelien Jarno
    case TCG_COND_GT:
651 afa05235 Aurelien Jarno
    case TCG_COND_GE:
652 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_GT, arg2, arg4, label_index);
653 afa05235 Aurelien Jarno
        break;
654 afa05235 Aurelien Jarno
    case TCG_COND_LTU:
655 afa05235 Aurelien Jarno
    case TCG_COND_LEU:
656 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_LTU, arg2, arg4, label_index);
657 afa05235 Aurelien Jarno
        break;
658 afa05235 Aurelien Jarno
    case TCG_COND_GTU:
659 afa05235 Aurelien Jarno
    case TCG_COND_GEU:
660 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_GTU, arg2, arg4, label_index);
661 afa05235 Aurelien Jarno
        break;
662 afa05235 Aurelien Jarno
    default:
663 afa05235 Aurelien Jarno
        tcg_abort();
664 afa05235 Aurelien Jarno
    }
665 afa05235 Aurelien Jarno
666 afa05235 Aurelien Jarno
    label_ptr = s->code_ptr;
667 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BNE, arg2, arg4);
668 afa05235 Aurelien Jarno
    tcg_out_nop(s);
669 afa05235 Aurelien Jarno
670 afa05235 Aurelien Jarno
    switch(cond) {
671 afa05235 Aurelien Jarno
    case TCG_COND_EQ:
672 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_EQ, arg1, arg3, label_index);
673 afa05235 Aurelien Jarno
        break;
674 afa05235 Aurelien Jarno
    case TCG_COND_LT:
675 afa05235 Aurelien Jarno
    case TCG_COND_LTU:
676 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_LTU, arg1, arg3, label_index);
677 afa05235 Aurelien Jarno
        break;
678 afa05235 Aurelien Jarno
    case TCG_COND_LE:
679 afa05235 Aurelien Jarno
    case TCG_COND_LEU:
680 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_LEU, arg1, arg3, label_index);
681 afa05235 Aurelien Jarno
        break;
682 afa05235 Aurelien Jarno
    case TCG_COND_GT:
683 afa05235 Aurelien Jarno
    case TCG_COND_GTU:
684 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_GTU, arg1, arg3, label_index);
685 afa05235 Aurelien Jarno
        break;
686 afa05235 Aurelien Jarno
    case TCG_COND_GE:
687 afa05235 Aurelien Jarno
    case TCG_COND_GEU:
688 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_GEU, arg1, arg3, label_index);
689 afa05235 Aurelien Jarno
        break;
690 afa05235 Aurelien Jarno
    default:
691 afa05235 Aurelien Jarno
        tcg_abort();
692 afa05235 Aurelien Jarno
    }
693 afa05235 Aurelien Jarno
694 afa05235 Aurelien Jarno
    reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
695 afa05235 Aurelien Jarno
}
696 afa05235 Aurelien Jarno
697 8a56e840 Richard Henderson
static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
698 4cb26382 Aurelien Jarno
                            int arg1, int arg2)
699 4cb26382 Aurelien Jarno
{
700 4cb26382 Aurelien Jarno
    switch (cond) {
701 4cb26382 Aurelien Jarno
    case TCG_COND_EQ:
702 4cb26382 Aurelien Jarno
        if (arg1 == 0) {
703 4cb26382 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg2, 1);
704 4cb26382 Aurelien Jarno
        } else if (arg2 == 0) {
705 4cb26382 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SLTIU, ret, arg1, 1);
706 4cb26382 Aurelien Jarno
        } else {
707 434254aa Aurelien Jarno
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
708 434254aa Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SLTIU, ret, ret, 1);
709 4cb26382 Aurelien Jarno
        }
710 4cb26382 Aurelien Jarno
        break;
711 4cb26382 Aurelien Jarno
    case TCG_COND_NE:
712 4cb26382 Aurelien Jarno
        if (arg1 == 0) {
713 4cb26382 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg2);
714 4cb26382 Aurelien Jarno
        } else if (arg2 == 0) {
715 4cb26382 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, arg1);
716 4cb26382 Aurelien Jarno
        } else {
717 434254aa Aurelien Jarno
            tcg_out_opc_reg(s, OPC_XOR, ret, arg1, arg2);
718 434254aa Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, ret);
719 4cb26382 Aurelien Jarno
        }
720 4cb26382 Aurelien Jarno
        break;
721 4cb26382 Aurelien Jarno
    case TCG_COND_LT:
722 4cb26382 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
723 4cb26382 Aurelien Jarno
        break;
724 4cb26382 Aurelien Jarno
    case TCG_COND_LTU:
725 4cb26382 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
726 4cb26382 Aurelien Jarno
        break;
727 4cb26382 Aurelien Jarno
    case TCG_COND_GE:
728 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, ret, arg1, arg2);
729 434254aa Aurelien Jarno
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
730 4cb26382 Aurelien Jarno
        break;
731 4cb26382 Aurelien Jarno
    case TCG_COND_GEU:
732 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg1, arg2);
733 434254aa Aurelien Jarno
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
734 4cb26382 Aurelien Jarno
        break;
735 4cb26382 Aurelien Jarno
    case TCG_COND_LE:
736 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
737 434254aa Aurelien Jarno
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
738 4cb26382 Aurelien Jarno
        break;
739 4cb26382 Aurelien Jarno
    case TCG_COND_LEU:
740 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
741 434254aa Aurelien Jarno
        tcg_out_opc_imm(s, OPC_XORI, ret, ret, 1);
742 4cb26382 Aurelien Jarno
        break;
743 4cb26382 Aurelien Jarno
    case TCG_COND_GT:
744 4cb26382 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLT, ret, arg2, arg1);
745 4cb26382 Aurelien Jarno
        break;
746 4cb26382 Aurelien Jarno
    case TCG_COND_GTU:
747 4cb26382 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, ret, arg2, arg1);
748 4cb26382 Aurelien Jarno
        break;
749 4cb26382 Aurelien Jarno
    default:
750 4cb26382 Aurelien Jarno
        tcg_abort();
751 4cb26382 Aurelien Jarno
        break;
752 4cb26382 Aurelien Jarno
    }
753 4cb26382 Aurelien Jarno
}
754 4cb26382 Aurelien Jarno
755 434254aa Aurelien Jarno
/* XXX: we implement it at the target level to avoid having to
756 434254aa Aurelien Jarno
   handle cross basic blocks temporaries */
757 8a56e840 Richard Henderson
static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
758 434254aa Aurelien Jarno
                             int arg1, int arg2, int arg3, int arg4)
759 434254aa Aurelien Jarno
{
760 434254aa Aurelien Jarno
    switch (cond) {
761 434254aa Aurelien Jarno
    case TCG_COND_EQ:
762 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_AT, arg2, arg4);
763 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg1, arg3);
764 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_AND, ret, TCG_REG_AT, TCG_REG_T0);
765 434254aa Aurelien Jarno
        return;
766 434254aa Aurelien Jarno
    case TCG_COND_NE:
767 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_AT, arg2, arg4);
768 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_NE, TCG_REG_T0, arg1, arg3);
769 434254aa Aurelien Jarno
        tcg_out_opc_reg(s, OPC_OR, ret, TCG_REG_AT, TCG_REG_T0);
770 434254aa Aurelien Jarno
        return;
771 434254aa Aurelien Jarno
    case TCG_COND_LT:
772 434254aa Aurelien Jarno
    case TCG_COND_LE:
773 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_LT, TCG_REG_AT, arg2, arg4);
774 434254aa Aurelien Jarno
        break;
775 434254aa Aurelien Jarno
    case TCG_COND_GT:
776 434254aa Aurelien Jarno
    case TCG_COND_GE:
777 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_GT, TCG_REG_AT, arg2, arg4);
778 434254aa Aurelien Jarno
        break;
779 434254aa Aurelien Jarno
    case TCG_COND_LTU:
780 434254aa Aurelien Jarno
    case TCG_COND_LEU:
781 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_LTU, TCG_REG_AT, arg2, arg4);
782 434254aa Aurelien Jarno
        break;
783 434254aa Aurelien Jarno
    case TCG_COND_GTU:
784 434254aa Aurelien Jarno
    case TCG_COND_GEU:
785 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_GTU, TCG_REG_AT, arg2, arg4);
786 434254aa Aurelien Jarno
        break;
787 434254aa Aurelien Jarno
    default:
788 434254aa Aurelien Jarno
        tcg_abort();
789 434254aa Aurelien Jarno
        break;
790 434254aa Aurelien Jarno
    }
791 434254aa Aurelien Jarno
792 434254aa Aurelien Jarno
    tcg_out_setcond(s, TCG_COND_EQ, TCG_REG_T0, arg2, arg4);
793 434254aa Aurelien Jarno
794 434254aa Aurelien Jarno
    switch(cond) {
795 434254aa Aurelien Jarno
    case TCG_COND_LT:
796 434254aa Aurelien Jarno
    case TCG_COND_LTU:
797 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_LTU, ret, arg1, arg3);
798 434254aa Aurelien Jarno
        break;
799 434254aa Aurelien Jarno
    case TCG_COND_LE:
800 434254aa Aurelien Jarno
    case TCG_COND_LEU:
801 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_LEU, ret, arg1, arg3);
802 434254aa Aurelien Jarno
        break;
803 434254aa Aurelien Jarno
    case TCG_COND_GT:
804 434254aa Aurelien Jarno
    case TCG_COND_GTU:
805 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_GTU, ret, arg1, arg3);
806 434254aa Aurelien Jarno
        break;
807 434254aa Aurelien Jarno
    case TCG_COND_GE:
808 434254aa Aurelien Jarno
    case TCG_COND_GEU:
809 434254aa Aurelien Jarno
        tcg_out_setcond(s, TCG_COND_GEU, ret, arg1, arg3);
810 434254aa Aurelien Jarno
        break;
811 434254aa Aurelien Jarno
    default:
812 434254aa Aurelien Jarno
        tcg_abort();
813 434254aa Aurelien Jarno
    }
814 434254aa Aurelien Jarno
815 434254aa Aurelien Jarno
    tcg_out_opc_reg(s, OPC_AND, ret, ret, TCG_REG_T0);
816 434254aa Aurelien Jarno
    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
817 434254aa Aurelien Jarno
}
818 434254aa Aurelien Jarno
819 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
820 afa05235 Aurelien Jarno
821 afa05235 Aurelien Jarno
#include "../../softmmu_defs.h"
822 afa05235 Aurelien Jarno
823 e141ab52 Blue Swirl
/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
824 e141ab52 Blue Swirl
   int mmu_idx) */
825 e141ab52 Blue Swirl
static const void * const qemu_ld_helpers[4] = {
826 e141ab52 Blue Swirl
    helper_ldb_mmu,
827 e141ab52 Blue Swirl
    helper_ldw_mmu,
828 e141ab52 Blue Swirl
    helper_ldl_mmu,
829 e141ab52 Blue Swirl
    helper_ldq_mmu,
830 e141ab52 Blue Swirl
};
831 e141ab52 Blue Swirl
832 e141ab52 Blue Swirl
/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
833 e141ab52 Blue Swirl
   uintxx_t val, int mmu_idx) */
834 e141ab52 Blue Swirl
static const void * const qemu_st_helpers[4] = {
835 e141ab52 Blue Swirl
    helper_stb_mmu,
836 e141ab52 Blue Swirl
    helper_stw_mmu,
837 e141ab52 Blue Swirl
    helper_stl_mmu,
838 e141ab52 Blue Swirl
    helper_stq_mmu,
839 e141ab52 Blue Swirl
};
840 e141ab52 Blue Swirl
#endif
841 afa05235 Aurelien Jarno
842 afa05235 Aurelien Jarno
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
843 afa05235 Aurelien Jarno
                            int opc)
844 afa05235 Aurelien Jarno
{
845 0834c9ea Aurelien Jarno
    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
846 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
847 afa05235 Aurelien Jarno
    void *label1_ptr, *label2_ptr;
848 18fec301 Aurelien Jarno
    int arg_num;
849 0834c9ea Aurelien Jarno
    int mem_index, s_bits;
850 0834c9ea Aurelien Jarno
    int addr_meml;
851 0834c9ea Aurelien Jarno
# if TARGET_LONG_BITS == 64
852 afa05235 Aurelien Jarno
    uint8_t *label3_ptr;
853 18fec301 Aurelien Jarno
    int addr_regh, addr_memh;
854 0834c9ea Aurelien Jarno
# endif
855 afa05235 Aurelien Jarno
#endif
856 afa05235 Aurelien Jarno
    data_regl = *args++;
857 afa05235 Aurelien Jarno
    if (opc == 3)
858 afa05235 Aurelien Jarno
        data_regh = *args++;
859 afa05235 Aurelien Jarno
    else
860 afa05235 Aurelien Jarno
        data_regh = 0;
861 afa05235 Aurelien Jarno
    addr_regl = *args++;
862 0834c9ea Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
863 0834c9ea Aurelien Jarno
# if TARGET_LONG_BITS == 64
864 afa05235 Aurelien Jarno
    addr_regh = *args++;
865 0834c9ea Aurelien Jarno
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
866 0834c9ea Aurelien Jarno
    addr_memh = 0;
867 0834c9ea Aurelien Jarno
    addr_meml = 4;
868 0834c9ea Aurelien Jarno
#  else
869 0834c9ea Aurelien Jarno
    addr_memh = 4;
870 0834c9ea Aurelien Jarno
    addr_meml = 0;
871 0834c9ea Aurelien Jarno
#  endif
872 0834c9ea Aurelien Jarno
# else
873 0834c9ea Aurelien Jarno
    addr_meml = 0;
874 0834c9ea Aurelien Jarno
# endif
875 afa05235 Aurelien Jarno
    mem_index = *args;
876 afa05235 Aurelien Jarno
    s_bits = opc & 3;
877 0834c9ea Aurelien Jarno
#endif
878 afa05235 Aurelien Jarno
879 afa05235 Aurelien Jarno
    if (opc == 3) {
880 afa05235 Aurelien Jarno
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
881 afa05235 Aurelien Jarno
        data_reg1 = data_regh;
882 afa05235 Aurelien Jarno
        data_reg2 = data_regl;
883 afa05235 Aurelien Jarno
#else
884 afa05235 Aurelien Jarno
        data_reg1 = data_regl;
885 afa05235 Aurelien Jarno
        data_reg2 = data_regh;
886 afa05235 Aurelien Jarno
#endif
887 afa05235 Aurelien Jarno
    } else {
888 afa05235 Aurelien Jarno
        data_reg1 = data_regl;
889 afa05235 Aurelien Jarno
        data_reg2 = 0;
890 afa05235 Aurelien Jarno
    }
891 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
892 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
893 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
894 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
895 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
896 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_meml);
897 afa05235 Aurelien Jarno
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
898 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
899 afa05235 Aurelien Jarno
900 afa05235 Aurelien Jarno
# if TARGET_LONG_BITS == 64
901 afa05235 Aurelien Jarno
    label3_ptr = s->code_ptr;
902 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
903 afa05235 Aurelien Jarno
    tcg_out_nop(s);
904 afa05235 Aurelien Jarno
905 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
906 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_read) + addr_memh);
907 afa05235 Aurelien Jarno
908 afa05235 Aurelien Jarno
    label1_ptr = s->code_ptr;
909 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
910 afa05235 Aurelien Jarno
    tcg_out_nop(s);
911 afa05235 Aurelien Jarno
912 afa05235 Aurelien Jarno
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
913 afa05235 Aurelien Jarno
# else
914 afa05235 Aurelien Jarno
    label1_ptr = s->code_ptr;
915 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
916 afa05235 Aurelien Jarno
    tcg_out_nop(s);
917 afa05235 Aurelien Jarno
# endif
918 afa05235 Aurelien Jarno
919 afa05235 Aurelien Jarno
    /* slow path */
920 18fec301 Aurelien Jarno
    arg_num = 0;
921 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
922 afa05235 Aurelien Jarno
# if TARGET_LONG_BITS == 64
923 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
924 18fec301 Aurelien Jarno
# else
925 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
926 afa05235 Aurelien Jarno
# endif
927 18fec301 Aurelien Jarno
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
928 afa05235 Aurelien Jarno
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_ld_helpers[s_bits]);
929 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
930 afa05235 Aurelien Jarno
    tcg_out_nop(s);
931 afa05235 Aurelien Jarno
932 afa05235 Aurelien Jarno
    switch(opc) {
933 afa05235 Aurelien Jarno
    case 0:
934 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xff);
935 afa05235 Aurelien Jarno
        break;
936 afa05235 Aurelien Jarno
    case 0 | 4:
937 116348de Aurelien Jarno
        tcg_out_ext8s(s, data_reg1, TCG_REG_V0);
938 afa05235 Aurelien Jarno
        break;
939 afa05235 Aurelien Jarno
    case 1:
940 afa05235 Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ANDI, data_reg1, TCG_REG_V0, 0xffff);
941 afa05235 Aurelien Jarno
        break;
942 afa05235 Aurelien Jarno
    case 1 | 4:
943 116348de Aurelien Jarno
        tcg_out_ext16s(s, data_reg1, TCG_REG_V0);
944 afa05235 Aurelien Jarno
        break;
945 afa05235 Aurelien Jarno
    case 2:
946 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
947 afa05235 Aurelien Jarno
        break;
948 afa05235 Aurelien Jarno
    case 3:
949 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_V1);
950 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, data_reg1, TCG_REG_V0);
951 afa05235 Aurelien Jarno
        break;
952 afa05235 Aurelien Jarno
    default:
953 afa05235 Aurelien Jarno
        tcg_abort();
954 afa05235 Aurelien Jarno
    }
955 afa05235 Aurelien Jarno
956 afa05235 Aurelien Jarno
    label2_ptr = s->code_ptr;
957 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
958 afa05235 Aurelien Jarno
    tcg_out_nop(s);
959 afa05235 Aurelien Jarno
960 afa05235 Aurelien Jarno
    /* label1: fast path */
961 afa05235 Aurelien Jarno
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
962 afa05235 Aurelien Jarno
963 cca1af8c Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
964 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
965 cca1af8c Aurelien Jarno
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
966 cc01cc8e Aurelien Jarno
#else
967 cc01cc8e Aurelien Jarno
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
968 ba0d89bb Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_regl, GUEST_BASE);
969 cc01cc8e Aurelien Jarno
    } else {
970 cc01cc8e Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
971 ba0d89bb Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_regl);
972 cc01cc8e Aurelien Jarno
    }
973 afa05235 Aurelien Jarno
#endif
974 afa05235 Aurelien Jarno
975 afa05235 Aurelien Jarno
    switch(opc) {
976 afa05235 Aurelien Jarno
    case 0:
977 cc01cc8e Aurelien Jarno
        tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
978 afa05235 Aurelien Jarno
        break;
979 afa05235 Aurelien Jarno
    case 0 | 4:
980 cc01cc8e Aurelien Jarno
        tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
981 afa05235 Aurelien Jarno
        break;
982 afa05235 Aurelien Jarno
    case 1:
983 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
984 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
985 afa05235 Aurelien Jarno
            tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
986 afa05235 Aurelien Jarno
        } else {
987 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
988 afa05235 Aurelien Jarno
        }
989 afa05235 Aurelien Jarno
        break;
990 afa05235 Aurelien Jarno
    case 1 | 4:
991 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
992 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
993 afa05235 Aurelien Jarno
            tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
994 afa05235 Aurelien Jarno
        } else {
995 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
996 afa05235 Aurelien Jarno
        }
997 afa05235 Aurelien Jarno
        break;
998 afa05235 Aurelien Jarno
    case 2:
999 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
1000 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1001 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1002 afa05235 Aurelien Jarno
        } else {
1003 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1004 afa05235 Aurelien Jarno
        }
1005 afa05235 Aurelien Jarno
        break;
1006 afa05235 Aurelien Jarno
    case 3:
1007 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
1008 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
1009 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
1010 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
1011 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
1012 afa05235 Aurelien Jarno
        } else {
1013 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
1014 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
1015 afa05235 Aurelien Jarno
        }
1016 afa05235 Aurelien Jarno
        break;
1017 afa05235 Aurelien Jarno
    default:
1018 afa05235 Aurelien Jarno
        tcg_abort();
1019 afa05235 Aurelien Jarno
    }
1020 afa05235 Aurelien Jarno
1021 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
1022 afa05235 Aurelien Jarno
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1023 afa05235 Aurelien Jarno
#endif
1024 afa05235 Aurelien Jarno
}
1025 afa05235 Aurelien Jarno
1026 afa05235 Aurelien Jarno
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
1027 afa05235 Aurelien Jarno
                            int opc)
1028 afa05235 Aurelien Jarno
{
1029 0834c9ea Aurelien Jarno
    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
1030 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
1031 afa05235 Aurelien Jarno
    uint8_t *label1_ptr, *label2_ptr;
1032 18fec301 Aurelien Jarno
    int arg_num;
1033 0834c9ea Aurelien Jarno
    int mem_index, s_bits;
1034 0834c9ea Aurelien Jarno
    int addr_meml;
1035 afa05235 Aurelien Jarno
#endif
1036 afa05235 Aurelien Jarno
#if TARGET_LONG_BITS == 64
1037 afa05235 Aurelien Jarno
# if defined(CONFIG_SOFTMMU)
1038 afa05235 Aurelien Jarno
    uint8_t *label3_ptr;
1039 18fec301 Aurelien Jarno
    int addr_regh, addr_memh;
1040 0834c9ea Aurelien Jarno
# endif
1041 afa05235 Aurelien Jarno
#endif
1042 afa05235 Aurelien Jarno
    data_regl = *args++;
1043 afa05235 Aurelien Jarno
    if (opc == 3) {
1044 afa05235 Aurelien Jarno
        data_regh = *args++;
1045 afa05235 Aurelien Jarno
    } else {
1046 afa05235 Aurelien Jarno
        data_regh = 0;
1047 afa05235 Aurelien Jarno
    }
1048 afa05235 Aurelien Jarno
    addr_regl = *args++;
1049 0834c9ea Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
1050 0834c9ea Aurelien Jarno
# if TARGET_LONG_BITS == 64
1051 afa05235 Aurelien Jarno
    addr_regh = *args++;
1052 0834c9ea Aurelien Jarno
#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
1053 afa05235 Aurelien Jarno
    addr_memh = 0;
1054 afa05235 Aurelien Jarno
    addr_meml = 4;
1055 0834c9ea Aurelien Jarno
#  else
1056 afa05235 Aurelien Jarno
    addr_memh = 4;
1057 afa05235 Aurelien Jarno
    addr_meml = 0;
1058 0834c9ea Aurelien Jarno
#  endif
1059 0834c9ea Aurelien Jarno
# else
1060 afa05235 Aurelien Jarno
    addr_meml = 0;
1061 0834c9ea Aurelien Jarno
# endif
1062 afa05235 Aurelien Jarno
    mem_index = *args;
1063 afa05235 Aurelien Jarno
    s_bits = opc;
1064 0834c9ea Aurelien Jarno
#endif
1065 0834c9ea Aurelien Jarno
1066 0834c9ea Aurelien Jarno
    if (opc == 3) {
1067 0834c9ea Aurelien Jarno
#if defined(TCG_TARGET_WORDS_BIGENDIAN)
1068 0834c9ea Aurelien Jarno
        data_reg1 = data_regh;
1069 0834c9ea Aurelien Jarno
        data_reg2 = data_regl;
1070 0834c9ea Aurelien Jarno
#else
1071 0834c9ea Aurelien Jarno
        data_reg1 = data_regl;
1072 0834c9ea Aurelien Jarno
        data_reg2 = data_regh;
1073 0834c9ea Aurelien Jarno
#endif
1074 0834c9ea Aurelien Jarno
    } else {
1075 0834c9ea Aurelien Jarno
        data_reg1 = data_regl;
1076 0834c9ea Aurelien Jarno
        data_reg2 = 0;
1077 0834c9ea Aurelien Jarno
    }
1078 afa05235 Aurelien Jarno
1079 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
1080 afa05235 Aurelien Jarno
    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
1081 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
1082 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, TCG_AREG0);
1083 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1084 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_meml);
1085 afa05235 Aurelien Jarno
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
1086 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_AND, TCG_REG_T0, TCG_REG_T0, addr_regl);
1087 afa05235 Aurelien Jarno
1088 afa05235 Aurelien Jarno
# if TARGET_LONG_BITS == 64
1089 afa05235 Aurelien Jarno
    label3_ptr = s->code_ptr;
1090 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BNE, TCG_REG_T0, TCG_REG_AT);
1091 afa05235 Aurelien Jarno
    tcg_out_nop(s);
1092 afa05235 Aurelien Jarno
1093 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_AT, TCG_REG_A0,
1094 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addr_write) + addr_memh);
1095 afa05235 Aurelien Jarno
1096 afa05235 Aurelien Jarno
    label1_ptr = s->code_ptr;
1097 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, addr_regh, TCG_REG_AT);
1098 afa05235 Aurelien Jarno
    tcg_out_nop(s);
1099 afa05235 Aurelien Jarno
1100 afa05235 Aurelien Jarno
    reloc_pc16(label3_ptr, (tcg_target_long) s->code_ptr);
1101 afa05235 Aurelien Jarno
# else
1102 afa05235 Aurelien Jarno
    label1_ptr = s->code_ptr;
1103 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_T0, TCG_REG_AT);
1104 afa05235 Aurelien Jarno
    tcg_out_nop(s);
1105 afa05235 Aurelien Jarno
# endif
1106 afa05235 Aurelien Jarno
1107 afa05235 Aurelien Jarno
    /* slow path */
1108 18fec301 Aurelien Jarno
    arg_num = 0;
1109 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
1110 afa05235 Aurelien Jarno
# if TARGET_LONG_BITS == 64
1111 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
1112 18fec301 Aurelien Jarno
# else
1113 18fec301 Aurelien Jarno
    tcg_out_call_iarg_reg32(s, &arg_num, addr_regl);
1114 afa05235 Aurelien Jarno
# endif
1115 afa05235 Aurelien Jarno
    switch(opc) {
1116 afa05235 Aurelien Jarno
    case 0:
1117 18fec301 Aurelien Jarno
        tcg_out_call_iarg_reg8(s, &arg_num, data_regl);
1118 afa05235 Aurelien Jarno
        break;
1119 afa05235 Aurelien Jarno
    case 1:
1120 18fec301 Aurelien Jarno
        tcg_out_call_iarg_reg16(s, &arg_num, data_regl);
1121 afa05235 Aurelien Jarno
        break;
1122 afa05235 Aurelien Jarno
    case 2:
1123 18fec301 Aurelien Jarno
        tcg_out_call_iarg_reg32(s, &arg_num, data_regl);
1124 afa05235 Aurelien Jarno
        break;
1125 afa05235 Aurelien Jarno
    case 3:
1126 18fec301 Aurelien Jarno
        tcg_out_call_iarg_reg64(s, &arg_num, data_regl, data_regh);
1127 afa05235 Aurelien Jarno
        break;
1128 afa05235 Aurelien Jarno
    default:
1129 afa05235 Aurelien Jarno
        tcg_abort();
1130 afa05235 Aurelien Jarno
    }
1131 18fec301 Aurelien Jarno
    tcg_out_call_iarg_imm32(s, &arg_num, mem_index);
1132 afa05235 Aurelien Jarno
    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T9, (tcg_target_long)qemu_st_helpers[s_bits]);
1133 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, TCG_REG_T9, 0);
1134 afa05235 Aurelien Jarno
    tcg_out_nop(s);
1135 afa05235 Aurelien Jarno
1136 afa05235 Aurelien Jarno
    label2_ptr = s->code_ptr;
1137 6d8ff4d8 Aurelien Jarno
    tcg_out_opc_br(s, OPC_BEQ, TCG_REG_ZERO, TCG_REG_ZERO);
1138 afa05235 Aurelien Jarno
    tcg_out_nop(s);
1139 afa05235 Aurelien Jarno
1140 afa05235 Aurelien Jarno
    /* label1: fast path */
1141 afa05235 Aurelien Jarno
    reloc_pc16(label1_ptr, (tcg_target_long) s->code_ptr);
1142 afa05235 Aurelien Jarno
1143 afa05235 Aurelien Jarno
    tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
1144 9349b4f9 Andreas Färber
                    offsetof(CPUArchState, tlb_table[mem_index][0].addend));
1145 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1146 cc01cc8e Aurelien Jarno
#else
1147 cc01cc8e Aurelien Jarno
    if (GUEST_BASE == (int16_t)GUEST_BASE) {
1148 ba0d89bb Aurelien Jarno
        tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_regl, GUEST_BASE);
1149 cc01cc8e Aurelien Jarno
    } else {
1150 cc01cc8e Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
1151 ba0d89bb Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
1152 cc01cc8e Aurelien Jarno
    }
1153 afa05235 Aurelien Jarno
1154 afa05235 Aurelien Jarno
#endif
1155 afa05235 Aurelien Jarno
1156 afa05235 Aurelien Jarno
    switch(opc) {
1157 afa05235 Aurelien Jarno
    case 0:
1158 cc01cc8e Aurelien Jarno
        tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
1159 afa05235 Aurelien Jarno
        break;
1160 afa05235 Aurelien Jarno
    case 1:
1161 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
1162 afa05235 Aurelien Jarno
            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
1163 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
1164 afa05235 Aurelien Jarno
        } else {
1165 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
1166 afa05235 Aurelien Jarno
        }
1167 afa05235 Aurelien Jarno
        break;
1168 afa05235 Aurelien Jarno
    case 2:
1169 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
1170 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1171 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1172 afa05235 Aurelien Jarno
        } else {
1173 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1174 afa05235 Aurelien Jarno
        }
1175 afa05235 Aurelien Jarno
        break;
1176 afa05235 Aurelien Jarno
    case 3:
1177 afa05235 Aurelien Jarno
        if (TCG_NEED_BSWAP) {
1178 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
1179 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
1180 afa05235 Aurelien Jarno
            tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
1181 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
1182 afa05235 Aurelien Jarno
        } else {
1183 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
1184 cc01cc8e Aurelien Jarno
            tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
1185 afa05235 Aurelien Jarno
        }
1186 afa05235 Aurelien Jarno
        break;
1187 afa05235 Aurelien Jarno
    default:
1188 afa05235 Aurelien Jarno
        tcg_abort();
1189 afa05235 Aurelien Jarno
    }
1190 afa05235 Aurelien Jarno
1191 afa05235 Aurelien Jarno
#if defined(CONFIG_SOFTMMU)
1192 afa05235 Aurelien Jarno
    reloc_pc16(label2_ptr, (tcg_target_long) s->code_ptr);
1193 afa05235 Aurelien Jarno
#endif
1194 afa05235 Aurelien Jarno
}
1195 afa05235 Aurelien Jarno
1196 a9751609 Richard Henderson
static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1197 afa05235 Aurelien Jarno
                              const TCGArg *args, const int *const_args)
1198 afa05235 Aurelien Jarno
{
1199 afa05235 Aurelien Jarno
    switch(opc) {
1200 afa05235 Aurelien Jarno
    case INDEX_op_exit_tb:
1201 afa05235 Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_V0, args[0]);
1202 afa05235 Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, (tcg_target_long)tb_ret_addr);
1203 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1204 afa05235 Aurelien Jarno
        tcg_out_nop(s);
1205 afa05235 Aurelien Jarno
        break;
1206 afa05235 Aurelien Jarno
    case INDEX_op_goto_tb:
1207 afa05235 Aurelien Jarno
        if (s->tb_jmp_offset) {
1208 afa05235 Aurelien Jarno
            /* direct jump method */
1209 afa05235 Aurelien Jarno
            tcg_abort();
1210 afa05235 Aurelien Jarno
        } else {
1211 afa05235 Aurelien Jarno
            /* indirect jump method */
1212 afa05235 Aurelien Jarno
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
1213 afa05235 Aurelien Jarno
            tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_AT, TCG_REG_AT, 0);
1214 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_AT, 0);
1215 afa05235 Aurelien Jarno
        }
1216 afa05235 Aurelien Jarno
        tcg_out_nop(s);
1217 afa05235 Aurelien Jarno
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
1218 afa05235 Aurelien Jarno
        break;
1219 afa05235 Aurelien Jarno
    case INDEX_op_call:
1220 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_JALR, TCG_REG_RA, args[0], 0);
1221 afa05235 Aurelien Jarno
        tcg_out_nop(s);
1222 afa05235 Aurelien Jarno
        break;
1223 afa05235 Aurelien Jarno
    case INDEX_op_jmp:
1224 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_JR, 0, args[0], 0);
1225 afa05235 Aurelien Jarno
        tcg_out_nop(s);
1226 afa05235 Aurelien Jarno
        break;
1227 afa05235 Aurelien Jarno
    case INDEX_op_br:
1228 afa05235 Aurelien Jarno
        tcg_out_brcond(s, TCG_COND_EQ, TCG_REG_ZERO, TCG_REG_ZERO, args[0]);
1229 afa05235 Aurelien Jarno
        break;
1230 afa05235 Aurelien Jarno
1231 afa05235 Aurelien Jarno
    case INDEX_op_mov_i32:
1232 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
1233 afa05235 Aurelien Jarno
        break;
1234 afa05235 Aurelien Jarno
    case INDEX_op_movi_i32:
1235 afa05235 Aurelien Jarno
        tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
1236 afa05235 Aurelien Jarno
        break;
1237 afa05235 Aurelien Jarno
1238 afa05235 Aurelien Jarno
    case INDEX_op_ld8u_i32:
1239 116348de Aurelien Jarno
        tcg_out_ldst(s, OPC_LBU, args[0], args[1], args[2]);
1240 afa05235 Aurelien Jarno
        break;
1241 afa05235 Aurelien Jarno
    case INDEX_op_ld8s_i32:
1242 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_LB, args[0], args[1], args[2]);
1243 afa05235 Aurelien Jarno
        break;
1244 afa05235 Aurelien Jarno
    case INDEX_op_ld16u_i32:
1245 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_LHU, args[0], args[1], args[2]);
1246 afa05235 Aurelien Jarno
        break;
1247 afa05235 Aurelien Jarno
    case INDEX_op_ld16s_i32:
1248 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_LH, args[0], args[1], args[2]);
1249 afa05235 Aurelien Jarno
        break;
1250 afa05235 Aurelien Jarno
    case INDEX_op_ld_i32:
1251 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_LW, args[0], args[1], args[2]);
1252 afa05235 Aurelien Jarno
        break;
1253 afa05235 Aurelien Jarno
    case INDEX_op_st8_i32:
1254 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_SB, args[0], args[1], args[2]);
1255 afa05235 Aurelien Jarno
        break;
1256 afa05235 Aurelien Jarno
    case INDEX_op_st16_i32:
1257 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_SH, args[0], args[1], args[2]);
1258 afa05235 Aurelien Jarno
        break;
1259 afa05235 Aurelien Jarno
    case INDEX_op_st_i32:
1260 afa05235 Aurelien Jarno
        tcg_out_ldst(s, OPC_SW, args[0], args[1], args[2]);
1261 afa05235 Aurelien Jarno
        break;
1262 afa05235 Aurelien Jarno
1263 afa05235 Aurelien Jarno
    case INDEX_op_add_i32:
1264 afa05235 Aurelien Jarno
        if (const_args[2]) {
1265 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], args[2]);
1266 afa05235 Aurelien Jarno
        } else {
1267 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_ADDU, args[0], args[1], args[2]);
1268 afa05235 Aurelien Jarno
        }
1269 afa05235 Aurelien Jarno
        break;
1270 afa05235 Aurelien Jarno
    case INDEX_op_add2_i32:
1271 afa05235 Aurelien Jarno
        if (const_args[4]) {
1272 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], args[4]);
1273 afa05235 Aurelien Jarno
        } else {
1274 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_AT, args[2], args[4]);
1275 afa05235 Aurelien Jarno
        }
1276 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, TCG_REG_AT, args[2]);
1277 afa05235 Aurelien Jarno
        if (const_args[5]) {
1278 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], args[5]);
1279 afa05235 Aurelien Jarno
        } else {
1280 afa05235 Aurelien Jarno
             tcg_out_opc_reg(s, OPC_ADDU, args[1], args[3], args[5]);
1281 afa05235 Aurelien Jarno
        }
1282 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_ADDU, args[1], args[1], TCG_REG_T0);
1283 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1284 afa05235 Aurelien Jarno
        break;
1285 afa05235 Aurelien Jarno
    case INDEX_op_sub_i32:
1286 afa05235 Aurelien Jarno
        if (const_args[2]) {
1287 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, args[0], args[1], -args[2]);
1288 afa05235 Aurelien Jarno
        } else {
1289 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SUBU, args[0], args[1], args[2]);
1290 afa05235 Aurelien Jarno
        }
1291 afa05235 Aurelien Jarno
        break;
1292 afa05235 Aurelien Jarno
    case INDEX_op_sub2_i32:
1293 afa05235 Aurelien Jarno
        if (const_args[4]) {
1294 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_AT, args[2], -args[4]);
1295 afa05235 Aurelien Jarno
        } else {
1296 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, args[2], args[4]);
1297 afa05235 Aurelien Jarno
        }
1298 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_T0, args[2], TCG_REG_AT);
1299 afa05235 Aurelien Jarno
        if (const_args[5]) {
1300 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ADDIU, args[1], args[3], -args[5]);
1301 afa05235 Aurelien Jarno
        } else {
1302 afa05235 Aurelien Jarno
             tcg_out_opc_reg(s, OPC_SUBU, args[1], args[3], args[5]);
1303 afa05235 Aurelien Jarno
        }
1304 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_SUBU, args[1], args[1], TCG_REG_T0);
1305 3b6dac34 Richard Henderson
        tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
1306 afa05235 Aurelien Jarno
        break;
1307 afa05235 Aurelien Jarno
    case INDEX_op_mul_i32:
1308 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
1309 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1310 afa05235 Aurelien Jarno
        break;
1311 afa05235 Aurelien Jarno
    case INDEX_op_mulu2_i32:
1312 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MULTU, 0, args[2], args[3]);
1313 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1314 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
1315 afa05235 Aurelien Jarno
        break;
1316 afa05235 Aurelien Jarno
    case INDEX_op_div_i32:
1317 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1318 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1319 afa05235 Aurelien Jarno
        break;
1320 afa05235 Aurelien Jarno
    case INDEX_op_divu_i32:
1321 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1322 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
1323 afa05235 Aurelien Jarno
        break;
1324 afa05235 Aurelien Jarno
    case INDEX_op_rem_i32:
1325 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
1326 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1327 afa05235 Aurelien Jarno
        break;
1328 afa05235 Aurelien Jarno
    case INDEX_op_remu_i32:
1329 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_DIVU, 0, args[1], args[2]);
1330 afa05235 Aurelien Jarno
        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
1331 afa05235 Aurelien Jarno
        break;
1332 afa05235 Aurelien Jarno
1333 afa05235 Aurelien Jarno
    case INDEX_op_and_i32:
1334 afa05235 Aurelien Jarno
        if (const_args[2]) {
1335 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ANDI, args[0], args[1], args[2]);
1336 afa05235 Aurelien Jarno
        } else {
1337 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_AND, args[0], args[1], args[2]);
1338 afa05235 Aurelien Jarno
        }
1339 afa05235 Aurelien Jarno
        break;
1340 afa05235 Aurelien Jarno
    case INDEX_op_or_i32:
1341 afa05235 Aurelien Jarno
        if (const_args[2]) {
1342 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_ORI, args[0], args[1], args[2]);
1343 afa05235 Aurelien Jarno
        } else {
1344 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_OR, args[0], args[1], args[2]);
1345 afa05235 Aurelien Jarno
        }
1346 afa05235 Aurelien Jarno
        break;
1347 2b79487a Aurelien Jarno
    case INDEX_op_nor_i32:
1348 2b79487a Aurelien Jarno
        tcg_out_opc_reg(s, OPC_NOR, args[0], args[1], args[2]);
1349 2b79487a Aurelien Jarno
        break;
1350 afa05235 Aurelien Jarno
    case INDEX_op_not_i32:
1351 489722cf Aurelien Jarno
        tcg_out_opc_reg(s, OPC_NOR, args[0], TCG_REG_ZERO, args[1]);
1352 afa05235 Aurelien Jarno
        break;
1353 afa05235 Aurelien Jarno
    case INDEX_op_xor_i32:
1354 afa05235 Aurelien Jarno
        if (const_args[2]) {
1355 afa05235 Aurelien Jarno
            tcg_out_opc_imm(s, OPC_XORI, args[0], args[1], args[2]);
1356 afa05235 Aurelien Jarno
        } else {
1357 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_XOR, args[0], args[1], args[2]);
1358 afa05235 Aurelien Jarno
        }
1359 afa05235 Aurelien Jarno
        break;
1360 afa05235 Aurelien Jarno
1361 afa05235 Aurelien Jarno
    case INDEX_op_sar_i32:
1362 afa05235 Aurelien Jarno
        if (const_args[2]) {
1363 afa05235 Aurelien Jarno
            tcg_out_opc_sa(s, OPC_SRA, args[0], args[1], args[2]);
1364 afa05235 Aurelien Jarno
        } else {
1365 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SRAV, args[0], args[2], args[1]);
1366 afa05235 Aurelien Jarno
        }
1367 afa05235 Aurelien Jarno
        break;
1368 afa05235 Aurelien Jarno
    case INDEX_op_shl_i32:
1369 afa05235 Aurelien Jarno
        if (const_args[2]) {
1370 afa05235 Aurelien Jarno
            tcg_out_opc_sa(s, OPC_SLL, args[0], args[1], args[2]);
1371 afa05235 Aurelien Jarno
        } else {
1372 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SLLV, args[0], args[2], args[1]);
1373 afa05235 Aurelien Jarno
        }
1374 afa05235 Aurelien Jarno
        break;
1375 afa05235 Aurelien Jarno
    case INDEX_op_shr_i32:
1376 afa05235 Aurelien Jarno
        if (const_args[2]) {
1377 afa05235 Aurelien Jarno
            tcg_out_opc_sa(s, OPC_SRL, args[0], args[1], args[2]);
1378 afa05235 Aurelien Jarno
        } else {
1379 afa05235 Aurelien Jarno
            tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
1380 afa05235 Aurelien Jarno
        }
1381 afa05235 Aurelien Jarno
        break;
1382 afa05235 Aurelien Jarno
1383 116348de Aurelien Jarno
    case INDEX_op_ext8s_i32:
1384 116348de Aurelien Jarno
        tcg_out_ext8s(s, args[0], args[1]);
1385 116348de Aurelien Jarno
        break;
1386 116348de Aurelien Jarno
    case INDEX_op_ext16s_i32:
1387 116348de Aurelien Jarno
        tcg_out_ext16s(s, args[0], args[1]);
1388 116348de Aurelien Jarno
        break;
1389 116348de Aurelien Jarno
1390 afa05235 Aurelien Jarno
    case INDEX_op_brcond_i32:
1391 afa05235 Aurelien Jarno
        tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
1392 afa05235 Aurelien Jarno
        break;
1393 afa05235 Aurelien Jarno
    case INDEX_op_brcond2_i32:
1394 afa05235 Aurelien Jarno
        tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
1395 afa05235 Aurelien Jarno
        break;
1396 afa05235 Aurelien Jarno
1397 4cb26382 Aurelien Jarno
    case INDEX_op_setcond_i32:
1398 4cb26382 Aurelien Jarno
        tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
1399 4cb26382 Aurelien Jarno
        break;
1400 434254aa Aurelien Jarno
    case INDEX_op_setcond2_i32:
1401 434254aa Aurelien Jarno
        tcg_out_setcond2(s, args[5], args[0], args[1], args[2], args[3], args[4]);
1402 434254aa Aurelien Jarno
        break;
1403 4cb26382 Aurelien Jarno
1404 afa05235 Aurelien Jarno
    case INDEX_op_qemu_ld8u:
1405 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 0);
1406 afa05235 Aurelien Jarno
        break;
1407 afa05235 Aurelien Jarno
    case INDEX_op_qemu_ld8s:
1408 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 0 | 4);
1409 afa05235 Aurelien Jarno
        break;
1410 afa05235 Aurelien Jarno
    case INDEX_op_qemu_ld16u:
1411 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 1);
1412 afa05235 Aurelien Jarno
        break;
1413 afa05235 Aurelien Jarno
    case INDEX_op_qemu_ld16s:
1414 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 1 | 4);
1415 afa05235 Aurelien Jarno
        break;
1416 86feb1c8 Richard Henderson
    case INDEX_op_qemu_ld32:
1417 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 2);
1418 afa05235 Aurelien Jarno
        break;
1419 afa05235 Aurelien Jarno
    case INDEX_op_qemu_ld64:
1420 afa05235 Aurelien Jarno
        tcg_out_qemu_ld(s, args, 3);
1421 afa05235 Aurelien Jarno
        break;
1422 afa05235 Aurelien Jarno
    case INDEX_op_qemu_st8:
1423 afa05235 Aurelien Jarno
        tcg_out_qemu_st(s, args, 0);
1424 afa05235 Aurelien Jarno
        break;
1425 afa05235 Aurelien Jarno
    case INDEX_op_qemu_st16:
1426 afa05235 Aurelien Jarno
        tcg_out_qemu_st(s, args, 1);
1427 afa05235 Aurelien Jarno
        break;
1428 afa05235 Aurelien Jarno
    case INDEX_op_qemu_st32:
1429 afa05235 Aurelien Jarno
        tcg_out_qemu_st(s, args, 2);
1430 afa05235 Aurelien Jarno
        break;
1431 afa05235 Aurelien Jarno
    case INDEX_op_qemu_st64:
1432 afa05235 Aurelien Jarno
        tcg_out_qemu_st(s, args, 3);
1433 afa05235 Aurelien Jarno
        break;
1434 afa05235 Aurelien Jarno
1435 afa05235 Aurelien Jarno
    default:
1436 afa05235 Aurelien Jarno
        tcg_abort();
1437 afa05235 Aurelien Jarno
    }
1438 afa05235 Aurelien Jarno
}
1439 afa05235 Aurelien Jarno
1440 afa05235 Aurelien Jarno
static const TCGTargetOpDef mips_op_defs[] = {
1441 afa05235 Aurelien Jarno
    { INDEX_op_exit_tb, { } },
1442 afa05235 Aurelien Jarno
    { INDEX_op_goto_tb, { } },
1443 afa05235 Aurelien Jarno
    { INDEX_op_call, { "C" } },
1444 afa05235 Aurelien Jarno
    { INDEX_op_jmp, { "r" } },
1445 afa05235 Aurelien Jarno
    { INDEX_op_br, { } },
1446 afa05235 Aurelien Jarno
1447 afa05235 Aurelien Jarno
    { INDEX_op_mov_i32, { "r", "r" } },
1448 afa05235 Aurelien Jarno
    { INDEX_op_movi_i32, { "r" } },
1449 afa05235 Aurelien Jarno
    { INDEX_op_ld8u_i32, { "r", "r" } },
1450 afa05235 Aurelien Jarno
    { INDEX_op_ld8s_i32, { "r", "r" } },
1451 afa05235 Aurelien Jarno
    { INDEX_op_ld16u_i32, { "r", "r" } },
1452 afa05235 Aurelien Jarno
    { INDEX_op_ld16s_i32, { "r", "r" } },
1453 afa05235 Aurelien Jarno
    { INDEX_op_ld_i32, { "r", "r" } },
1454 afa05235 Aurelien Jarno
    { INDEX_op_st8_i32, { "rZ", "r" } },
1455 afa05235 Aurelien Jarno
    { INDEX_op_st16_i32, { "rZ", "r" } },
1456 afa05235 Aurelien Jarno
    { INDEX_op_st_i32, { "rZ", "r" } },
1457 afa05235 Aurelien Jarno
1458 2ceb3a9e Aurelien Jarno
    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
1459 afa05235 Aurelien Jarno
    { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
1460 afa05235 Aurelien Jarno
    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
1461 afa05235 Aurelien Jarno
    { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
1462 afa05235 Aurelien Jarno
    { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
1463 afa05235 Aurelien Jarno
    { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
1464 afa05235 Aurelien Jarno
    { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
1465 2ceb3a9e Aurelien Jarno
    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
1466 afa05235 Aurelien Jarno
1467 2ceb3a9e Aurelien Jarno
    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
1468 2b79487a Aurelien Jarno
    { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
1469 afa05235 Aurelien Jarno
    { INDEX_op_not_i32, { "r", "rZ" } },
1470 afa05235 Aurelien Jarno
    { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
1471 afa05235 Aurelien Jarno
    { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
1472 afa05235 Aurelien Jarno
1473 2ceb3a9e Aurelien Jarno
    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
1474 2ceb3a9e Aurelien Jarno
    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
1475 2ceb3a9e Aurelien Jarno
    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
1476 afa05235 Aurelien Jarno
1477 116348de Aurelien Jarno
    { INDEX_op_ext8s_i32, { "r", "rZ" } },
1478 116348de Aurelien Jarno
    { INDEX_op_ext16s_i32, { "r", "rZ" } },
1479 116348de Aurelien Jarno
1480 afa05235 Aurelien Jarno
    { INDEX_op_brcond_i32, { "rZ", "rZ" } },
1481 4cb26382 Aurelien Jarno
    { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
1482 434254aa Aurelien Jarno
    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
1483 afa05235 Aurelien Jarno
1484 2ceb3a9e Aurelien Jarno
    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1485 2ceb3a9e Aurelien Jarno
    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
1486 afa05235 Aurelien Jarno
    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
1487 afa05235 Aurelien Jarno
1488 afa05235 Aurelien Jarno
#if TARGET_LONG_BITS == 32
1489 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld8u, { "L", "lZ" } },
1490 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld8s, { "L", "lZ" } },
1491 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld16u, { "L", "lZ" } },
1492 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld16s, { "L", "lZ" } },
1493 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "L", "lZ" } },
1494 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld64, { "L", "L", "lZ" } },
1495 afa05235 Aurelien Jarno
1496 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st8, { "SZ", "SZ" } },
1497 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st16, { "SZ", "SZ" } },
1498 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st32, { "SZ", "SZ" } },
1499 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ" } },
1500 afa05235 Aurelien Jarno
#else
1501 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld8u, { "L", "lZ", "lZ" } },
1502 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld8s, { "L", "lZ", "lZ" } },
1503 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld16u, { "L", "lZ", "lZ" } },
1504 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld16s, { "L", "lZ", "lZ" } },
1505 86feb1c8 Richard Henderson
    { INDEX_op_qemu_ld32, { "L", "lZ", "lZ" } },
1506 afa05235 Aurelien Jarno
    { INDEX_op_qemu_ld64, { "L", "L", "lZ", "lZ" } },
1507 afa05235 Aurelien Jarno
1508 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st8, { "SZ", "SZ", "SZ" } },
1509 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st16, { "SZ", "SZ", "SZ" } },
1510 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st32, { "SZ", "SZ", "SZ" } },
1511 afa05235 Aurelien Jarno
    { INDEX_op_qemu_st64, { "SZ", "SZ", "SZ", "SZ" } },
1512 afa05235 Aurelien Jarno
#endif
1513 afa05235 Aurelien Jarno
    { -1 },
1514 afa05235 Aurelien Jarno
};
1515 afa05235 Aurelien Jarno
1516 afa05235 Aurelien Jarno
static int tcg_target_callee_save_regs[] = {
1517 cea5f9a2 Blue Swirl
    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
1518 afa05235 Aurelien Jarno
    TCG_REG_S1,
1519 afa05235 Aurelien Jarno
    TCG_REG_S2,
1520 afa05235 Aurelien Jarno
    TCG_REG_S3,
1521 afa05235 Aurelien Jarno
    TCG_REG_S4,
1522 afa05235 Aurelien Jarno
    TCG_REG_S5,
1523 afa05235 Aurelien Jarno
    TCG_REG_S6,
1524 afa05235 Aurelien Jarno
    TCG_REG_S7,
1525 afa05235 Aurelien Jarno
    TCG_REG_GP,
1526 60bf84cf Stefan Weil
    TCG_REG_FP,
1527 afa05235 Aurelien Jarno
    TCG_REG_RA,       /* should be last for ABI compliance */
1528 afa05235 Aurelien Jarno
};
1529 afa05235 Aurelien Jarno
1530 afa05235 Aurelien Jarno
/* Generate global QEMU prologue and epilogue code */
1531 e4d58b41 Richard Henderson
static void tcg_target_qemu_prologue(TCGContext *s)
1532 afa05235 Aurelien Jarno
{
1533 afa05235 Aurelien Jarno
    int i, frame_size;
1534 afa05235 Aurelien Jarno
1535 afa05235 Aurelien Jarno
    /* reserve some stack space */
1536 afa05235 Aurelien Jarno
    frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
1537 afa05235 Aurelien Jarno
                 + TCG_STATIC_CALL_ARGS_SIZE;
1538 afa05235 Aurelien Jarno
    frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
1539 afa05235 Aurelien Jarno
                 ~(TCG_TARGET_STACK_ALIGN - 1);
1540 afa05235 Aurelien Jarno
1541 afa05235 Aurelien Jarno
    /* TB prologue */
1542 afa05235 Aurelien Jarno
    tcg_out_addi(s, TCG_REG_SP, -frame_size);
1543 afa05235 Aurelien Jarno
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1544 afa05235 Aurelien Jarno
        tcg_out_st(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1545 afa05235 Aurelien Jarno
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1546 afa05235 Aurelien Jarno
    }
1547 afa05235 Aurelien Jarno
1548 afa05235 Aurelien Jarno
    /* Call generated code */
1549 ea15fb06 Stefan Weil
    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1], 0);
1550 cea5f9a2 Blue Swirl
    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1551 afa05235 Aurelien Jarno
    tb_ret_addr = s->code_ptr;
1552 afa05235 Aurelien Jarno
1553 afa05235 Aurelien Jarno
    /* TB epilogue */
1554 afa05235 Aurelien Jarno
    for(i = 0 ; i < ARRAY_SIZE(tcg_target_callee_save_regs) ; i++) {
1555 afa05235 Aurelien Jarno
        tcg_out_ld(s, TCG_TYPE_I32, tcg_target_callee_save_regs[i],
1556 afa05235 Aurelien Jarno
                   TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE + i * 4);
1557 afa05235 Aurelien Jarno
    }
1558 afa05235 Aurelien Jarno
1559 afa05235 Aurelien Jarno
    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_RA, 0);
1560 afa05235 Aurelien Jarno
    tcg_out_addi(s, TCG_REG_SP, frame_size);
1561 afa05235 Aurelien Jarno
}
1562 afa05235 Aurelien Jarno
1563 e4d58b41 Richard Henderson
static void tcg_target_init(TCGContext *s)
1564 afa05235 Aurelien Jarno
{
1565 afa05235 Aurelien Jarno
    tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
1566 afa05235 Aurelien Jarno
    tcg_regset_set(tcg_target_call_clobber_regs,
1567 afa05235 Aurelien Jarno
                   (1 << TCG_REG_V0) |
1568 afa05235 Aurelien Jarno
                   (1 << TCG_REG_V1) |
1569 afa05235 Aurelien Jarno
                   (1 << TCG_REG_A0) |
1570 afa05235 Aurelien Jarno
                   (1 << TCG_REG_A1) |
1571 afa05235 Aurelien Jarno
                   (1 << TCG_REG_A2) |
1572 afa05235 Aurelien Jarno
                   (1 << TCG_REG_A3) |
1573 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T1) |
1574 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T2) |
1575 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T3) |
1576 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T4) |
1577 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T5) |
1578 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T6) |
1579 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T7) |
1580 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T8) |
1581 afa05235 Aurelien Jarno
                   (1 << TCG_REG_T9));
1582 afa05235 Aurelien Jarno
1583 afa05235 Aurelien Jarno
    tcg_regset_clear(s->reserved_regs);
1584 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO); /* zero register */
1585 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K0);   /* kernel use only */
1586 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_K1);   /* kernel use only */
1587 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_AT);   /* internal use */
1588 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
1589 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
1590 afa05235 Aurelien Jarno
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
1591 afa05235 Aurelien Jarno
1592 afa05235 Aurelien Jarno
    tcg_add_target_add_op_defs(mips_op_defs);
1593 9349b4f9 Andreas Färber
    tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1594 614f104d Blue Swirl
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
1595 afa05235 Aurelien Jarno
}