Statistics
| Branch: | Revision:

root / tcg / tci / tcg-target.c @ 3cf246f0

History | View | Annotate | Download (26.3 kB)

1 7316329a Stefan Weil
/*
2 7316329a Stefan Weil
 * Tiny Code Generator for QEMU
3 7316329a Stefan Weil
 *
4 7316329a Stefan Weil
 * Copyright (c) 2009, 2011 Stefan Weil
5 7316329a Stefan Weil
 *
6 7316329a Stefan Weil
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 7316329a Stefan Weil
 * of this software and associated documentation files (the "Software"), to deal
8 7316329a Stefan Weil
 * in the Software without restriction, including without limitation the rights
9 7316329a Stefan Weil
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 7316329a Stefan Weil
 * copies of the Software, and to permit persons to whom the Software is
11 7316329a Stefan Weil
 * furnished to do so, subject to the following conditions:
12 7316329a Stefan Weil
 *
13 7316329a Stefan Weil
 * The above copyright notice and this permission notice shall be included in
14 7316329a Stefan Weil
 * all copies or substantial portions of the Software.
15 7316329a Stefan Weil
 *
16 7316329a Stefan Weil
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 7316329a Stefan Weil
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 7316329a Stefan Weil
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 7316329a Stefan Weil
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 7316329a Stefan Weil
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 7316329a Stefan Weil
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 7316329a Stefan Weil
 * THE SOFTWARE.
23 7316329a Stefan Weil
 */
24 7316329a Stefan Weil
25 3cf246f0 Richard Henderson
#include "tcg-be-null.h"
26 3cf246f0 Richard Henderson
27 7316329a Stefan Weil
/* TODO list:
28 7316329a Stefan Weil
 * - See TODO comments in code.
29 7316329a Stefan Weil
 */
30 7316329a Stefan Weil
31 7316329a Stefan Weil
/* Marker for missing code. */
32 7316329a Stefan Weil
#define TODO() \
33 7316329a Stefan Weil
    do { \
34 7316329a Stefan Weil
        fprintf(stderr, "TODO %s:%u: %s()\n", \
35 7316329a Stefan Weil
                __FILE__, __LINE__, __func__); \
36 7316329a Stefan Weil
        tcg_abort(); \
37 7316329a Stefan Weil
    } while (0)
38 7316329a Stefan Weil
39 7316329a Stefan Weil
/* Bitfield n...m (in 32 bit value). */
40 7316329a Stefan Weil
#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
41 7316329a Stefan Weil
42 7316329a Stefan Weil
/* Macros used in tcg_target_op_defs. */
43 7316329a Stefan Weil
#define R       "r"
44 7316329a Stefan Weil
#define RI      "ri"
45 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
46 7316329a Stefan Weil
# define R64    "r", "r"
47 7316329a Stefan Weil
#else
48 7316329a Stefan Weil
# define R64    "r"
49 7316329a Stefan Weil
#endif
50 7316329a Stefan Weil
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
51 7316329a Stefan Weil
# define L      "L", "L"
52 7316329a Stefan Weil
# define S      "S", "S"
53 7316329a Stefan Weil
#else
54 7316329a Stefan Weil
# define L      "L"
55 7316329a Stefan Weil
# define S      "S"
56 7316329a Stefan Weil
#endif
57 7316329a Stefan Weil
58 7316329a Stefan Weil
/* TODO: documentation. */
59 7316329a Stefan Weil
static const TCGTargetOpDef tcg_target_op_defs[] = {
60 7316329a Stefan Weil
    { INDEX_op_exit_tb, { NULL } },
61 7316329a Stefan Weil
    { INDEX_op_goto_tb, { NULL } },
62 7316329a Stefan Weil
    { INDEX_op_call, { RI } },
63 7316329a Stefan Weil
    { INDEX_op_br, { NULL } },
64 7316329a Stefan Weil
65 7316329a Stefan Weil
    { INDEX_op_mov_i32, { R, R } },
66 7316329a Stefan Weil
    { INDEX_op_movi_i32, { R } },
67 7316329a Stefan Weil
68 7316329a Stefan Weil
    { INDEX_op_ld8u_i32, { R, R } },
69 7316329a Stefan Weil
    { INDEX_op_ld8s_i32, { R, R } },
70 7316329a Stefan Weil
    { INDEX_op_ld16u_i32, { R, R } },
71 7316329a Stefan Weil
    { INDEX_op_ld16s_i32, { R, R } },
72 7316329a Stefan Weil
    { INDEX_op_ld_i32, { R, R } },
73 7316329a Stefan Weil
    { INDEX_op_st8_i32, { R, R } },
74 7316329a Stefan Weil
    { INDEX_op_st16_i32, { R, R } },
75 7316329a Stefan Weil
    { INDEX_op_st_i32, { R, R } },
76 7316329a Stefan Weil
77 7316329a Stefan Weil
    { INDEX_op_add_i32, { R, RI, RI } },
78 7316329a Stefan Weil
    { INDEX_op_sub_i32, { R, RI, RI } },
79 7316329a Stefan Weil
    { INDEX_op_mul_i32, { R, RI, RI } },
80 7316329a Stefan Weil
#if TCG_TARGET_HAS_div_i32
81 7316329a Stefan Weil
    { INDEX_op_div_i32, { R, R, R } },
82 7316329a Stefan Weil
    { INDEX_op_divu_i32, { R, R, R } },
83 7316329a Stefan Weil
    { INDEX_op_rem_i32, { R, R, R } },
84 7316329a Stefan Weil
    { INDEX_op_remu_i32, { R, R, R } },
85 7316329a Stefan Weil
#elif TCG_TARGET_HAS_div2_i32
86 7316329a Stefan Weil
    { INDEX_op_div2_i32, { R, R, "0", "1", R } },
87 7316329a Stefan Weil
    { INDEX_op_divu2_i32, { R, R, "0", "1", R } },
88 7316329a Stefan Weil
#endif
89 7316329a Stefan Weil
    /* TODO: Does R, RI, RI result in faster code than R, R, RI?
90 7316329a Stefan Weil
       If both operands are constants, we can optimize. */
91 7316329a Stefan Weil
    { INDEX_op_and_i32, { R, RI, RI } },
92 7316329a Stefan Weil
#if TCG_TARGET_HAS_andc_i32
93 7316329a Stefan Weil
    { INDEX_op_andc_i32, { R, RI, RI } },
94 7316329a Stefan Weil
#endif
95 7316329a Stefan Weil
#if TCG_TARGET_HAS_eqv_i32
96 7316329a Stefan Weil
    { INDEX_op_eqv_i32, { R, RI, RI } },
97 7316329a Stefan Weil
#endif
98 7316329a Stefan Weil
#if TCG_TARGET_HAS_nand_i32
99 7316329a Stefan Weil
    { INDEX_op_nand_i32, { R, RI, RI } },
100 7316329a Stefan Weil
#endif
101 7316329a Stefan Weil
#if TCG_TARGET_HAS_nor_i32
102 7316329a Stefan Weil
    { INDEX_op_nor_i32, { R, RI, RI } },
103 7316329a Stefan Weil
#endif
104 7316329a Stefan Weil
    { INDEX_op_or_i32, { R, RI, RI } },
105 7316329a Stefan Weil
#if TCG_TARGET_HAS_orc_i32
106 7316329a Stefan Weil
    { INDEX_op_orc_i32, { R, RI, RI } },
107 7316329a Stefan Weil
#endif
108 7316329a Stefan Weil
    { INDEX_op_xor_i32, { R, RI, RI } },
109 7316329a Stefan Weil
    { INDEX_op_shl_i32, { R, RI, RI } },
110 7316329a Stefan Weil
    { INDEX_op_shr_i32, { R, RI, RI } },
111 7316329a Stefan Weil
    { INDEX_op_sar_i32, { R, RI, RI } },
112 7316329a Stefan Weil
#if TCG_TARGET_HAS_rot_i32
113 7316329a Stefan Weil
    { INDEX_op_rotl_i32, { R, RI, RI } },
114 7316329a Stefan Weil
    { INDEX_op_rotr_i32, { R, RI, RI } },
115 7316329a Stefan Weil
#endif
116 e24dc9fe Stefan Weil
#if TCG_TARGET_HAS_deposit_i32
117 e24dc9fe Stefan Weil
    { INDEX_op_deposit_i32, { R, "0", R } },
118 e24dc9fe Stefan Weil
#endif
119 7316329a Stefan Weil
120 7316329a Stefan Weil
    { INDEX_op_brcond_i32, { R, RI } },
121 7316329a Stefan Weil
122 7316329a Stefan Weil
    { INDEX_op_setcond_i32, { R, R, RI } },
123 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
124 7316329a Stefan Weil
    { INDEX_op_setcond_i64, { R, R, RI } },
125 7316329a Stefan Weil
#endif /* TCG_TARGET_REG_BITS == 64 */
126 7316329a Stefan Weil
127 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
128 7316329a Stefan Weil
    /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
129 7316329a Stefan Weil
    { INDEX_op_add2_i32, { R, R, R, R, R, R } },
130 7316329a Stefan Weil
    { INDEX_op_sub2_i32, { R, R, R, R, R, R } },
131 7316329a Stefan Weil
    { INDEX_op_brcond2_i32, { R, R, RI, RI } },
132 7316329a Stefan Weil
    { INDEX_op_mulu2_i32, { R, R, R, R } },
133 7316329a Stefan Weil
    { INDEX_op_setcond2_i32, { R, R, R, RI, RI } },
134 7316329a Stefan Weil
#endif
135 7316329a Stefan Weil
136 7316329a Stefan Weil
#if TCG_TARGET_HAS_not_i32
137 7316329a Stefan Weil
    { INDEX_op_not_i32, { R, R } },
138 7316329a Stefan Weil
#endif
139 7316329a Stefan Weil
#if TCG_TARGET_HAS_neg_i32
140 7316329a Stefan Weil
    { INDEX_op_neg_i32, { R, R } },
141 7316329a Stefan Weil
#endif
142 7316329a Stefan Weil
143 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
144 7316329a Stefan Weil
    { INDEX_op_mov_i64, { R, R } },
145 7316329a Stefan Weil
    { INDEX_op_movi_i64, { R } },
146 7316329a Stefan Weil
147 7316329a Stefan Weil
    { INDEX_op_ld8u_i64, { R, R } },
148 7316329a Stefan Weil
    { INDEX_op_ld8s_i64, { R, R } },
149 7316329a Stefan Weil
    { INDEX_op_ld16u_i64, { R, R } },
150 7316329a Stefan Weil
    { INDEX_op_ld16s_i64, { R, R } },
151 7316329a Stefan Weil
    { INDEX_op_ld32u_i64, { R, R } },
152 7316329a Stefan Weil
    { INDEX_op_ld32s_i64, { R, R } },
153 7316329a Stefan Weil
    { INDEX_op_ld_i64, { R, R } },
154 7316329a Stefan Weil
155 7316329a Stefan Weil
    { INDEX_op_st8_i64, { R, R } },
156 7316329a Stefan Weil
    { INDEX_op_st16_i64, { R, R } },
157 7316329a Stefan Weil
    { INDEX_op_st32_i64, { R, R } },
158 7316329a Stefan Weil
    { INDEX_op_st_i64, { R, R } },
159 7316329a Stefan Weil
160 7316329a Stefan Weil
    { INDEX_op_add_i64, { R, RI, RI } },
161 7316329a Stefan Weil
    { INDEX_op_sub_i64, { R, RI, RI } },
162 7316329a Stefan Weil
    { INDEX_op_mul_i64, { R, RI, RI } },
163 7316329a Stefan Weil
#if TCG_TARGET_HAS_div_i64
164 7316329a Stefan Weil
    { INDEX_op_div_i64, { R, R, R } },
165 7316329a Stefan Weil
    { INDEX_op_divu_i64, { R, R, R } },
166 7316329a Stefan Weil
    { INDEX_op_rem_i64, { R, R, R } },
167 7316329a Stefan Weil
    { INDEX_op_remu_i64, { R, R, R } },
168 7316329a Stefan Weil
#elif TCG_TARGET_HAS_div2_i64
169 7316329a Stefan Weil
    { INDEX_op_div2_i64, { R, R, "0", "1", R } },
170 7316329a Stefan Weil
    { INDEX_op_divu2_i64, { R, R, "0", "1", R } },
171 7316329a Stefan Weil
#endif
172 7316329a Stefan Weil
    { INDEX_op_and_i64, { R, RI, RI } },
173 7316329a Stefan Weil
#if TCG_TARGET_HAS_andc_i64
174 7316329a Stefan Weil
    { INDEX_op_andc_i64, { R, RI, RI } },
175 7316329a Stefan Weil
#endif
176 7316329a Stefan Weil
#if TCG_TARGET_HAS_eqv_i64
177 7316329a Stefan Weil
    { INDEX_op_eqv_i64, { R, RI, RI } },
178 7316329a Stefan Weil
#endif
179 7316329a Stefan Weil
#if TCG_TARGET_HAS_nand_i64
180 7316329a Stefan Weil
    { INDEX_op_nand_i64, { R, RI, RI } },
181 7316329a Stefan Weil
#endif
182 7316329a Stefan Weil
#if TCG_TARGET_HAS_nor_i64
183 7316329a Stefan Weil
    { INDEX_op_nor_i64, { R, RI, RI } },
184 7316329a Stefan Weil
#endif
185 7316329a Stefan Weil
    { INDEX_op_or_i64, { R, RI, RI } },
186 7316329a Stefan Weil
#if TCG_TARGET_HAS_orc_i64
187 7316329a Stefan Weil
    { INDEX_op_orc_i64, { R, RI, RI } },
188 7316329a Stefan Weil
#endif
189 7316329a Stefan Weil
    { INDEX_op_xor_i64, { R, RI, RI } },
190 7316329a Stefan Weil
    { INDEX_op_shl_i64, { R, RI, RI } },
191 7316329a Stefan Weil
    { INDEX_op_shr_i64, { R, RI, RI } },
192 7316329a Stefan Weil
    { INDEX_op_sar_i64, { R, RI, RI } },
193 7316329a Stefan Weil
#if TCG_TARGET_HAS_rot_i64
194 7316329a Stefan Weil
    { INDEX_op_rotl_i64, { R, RI, RI } },
195 7316329a Stefan Weil
    { INDEX_op_rotr_i64, { R, RI, RI } },
196 7316329a Stefan Weil
#endif
197 e24dc9fe Stefan Weil
#if TCG_TARGET_HAS_deposit_i64
198 e24dc9fe Stefan Weil
    { INDEX_op_deposit_i64, { R, "0", R } },
199 e24dc9fe Stefan Weil
#endif
200 7316329a Stefan Weil
    { INDEX_op_brcond_i64, { R, RI } },
201 7316329a Stefan Weil
202 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext8s_i64
203 7316329a Stefan Weil
    { INDEX_op_ext8s_i64, { R, R } },
204 7316329a Stefan Weil
#endif
205 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext16s_i64
206 7316329a Stefan Weil
    { INDEX_op_ext16s_i64, { R, R } },
207 7316329a Stefan Weil
#endif
208 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext32s_i64
209 7316329a Stefan Weil
    { INDEX_op_ext32s_i64, { R, R } },
210 7316329a Stefan Weil
#endif
211 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext8u_i64
212 7316329a Stefan Weil
    { INDEX_op_ext8u_i64, { R, R } },
213 7316329a Stefan Weil
#endif
214 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext16u_i64
215 7316329a Stefan Weil
    { INDEX_op_ext16u_i64, { R, R } },
216 7316329a Stefan Weil
#endif
217 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext32u_i64
218 7316329a Stefan Weil
    { INDEX_op_ext32u_i64, { R, R } },
219 7316329a Stefan Weil
#endif
220 7316329a Stefan Weil
#if TCG_TARGET_HAS_bswap16_i64
221 7316329a Stefan Weil
    { INDEX_op_bswap16_i64, { R, R } },
222 7316329a Stefan Weil
#endif
223 7316329a Stefan Weil
#if TCG_TARGET_HAS_bswap32_i64
224 7316329a Stefan Weil
    { INDEX_op_bswap32_i64, { R, R } },
225 7316329a Stefan Weil
#endif
226 7316329a Stefan Weil
#if TCG_TARGET_HAS_bswap64_i64
227 7316329a Stefan Weil
    { INDEX_op_bswap64_i64, { R, R } },
228 7316329a Stefan Weil
#endif
229 7316329a Stefan Weil
#if TCG_TARGET_HAS_not_i64
230 7316329a Stefan Weil
    { INDEX_op_not_i64, { R, R } },
231 7316329a Stefan Weil
#endif
232 7316329a Stefan Weil
#if TCG_TARGET_HAS_neg_i64
233 7316329a Stefan Weil
    { INDEX_op_neg_i64, { R, R } },
234 7316329a Stefan Weil
#endif
235 7316329a Stefan Weil
#endif /* TCG_TARGET_REG_BITS == 64 */
236 7316329a Stefan Weil
237 7316329a Stefan Weil
    { INDEX_op_qemu_ld8u, { R, L } },
238 7316329a Stefan Weil
    { INDEX_op_qemu_ld8s, { R, L } },
239 7316329a Stefan Weil
    { INDEX_op_qemu_ld16u, { R, L } },
240 7316329a Stefan Weil
    { INDEX_op_qemu_ld16s, { R, L } },
241 7316329a Stefan Weil
    { INDEX_op_qemu_ld32, { R, L } },
242 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
243 7316329a Stefan Weil
    { INDEX_op_qemu_ld32u, { R, L } },
244 7316329a Stefan Weil
    { INDEX_op_qemu_ld32s, { R, L } },
245 7316329a Stefan Weil
#endif
246 7316329a Stefan Weil
    { INDEX_op_qemu_ld64, { R64, L } },
247 7316329a Stefan Weil
248 7316329a Stefan Weil
    { INDEX_op_qemu_st8, { R, S } },
249 7316329a Stefan Weil
    { INDEX_op_qemu_st16, { R, S } },
250 7316329a Stefan Weil
    { INDEX_op_qemu_st32, { R, S } },
251 7316329a Stefan Weil
    { INDEX_op_qemu_st64, { R64, S } },
252 7316329a Stefan Weil
253 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext8s_i32
254 7316329a Stefan Weil
    { INDEX_op_ext8s_i32, { R, R } },
255 7316329a Stefan Weil
#endif
256 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext16s_i32
257 7316329a Stefan Weil
    { INDEX_op_ext16s_i32, { R, R } },
258 7316329a Stefan Weil
#endif
259 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext8u_i32
260 7316329a Stefan Weil
    { INDEX_op_ext8u_i32, { R, R } },
261 7316329a Stefan Weil
#endif
262 7316329a Stefan Weil
#if TCG_TARGET_HAS_ext16u_i32
263 7316329a Stefan Weil
    { INDEX_op_ext16u_i32, { R, R } },
264 7316329a Stefan Weil
#endif
265 7316329a Stefan Weil
266 7316329a Stefan Weil
#if TCG_TARGET_HAS_bswap16_i32
267 7316329a Stefan Weil
    { INDEX_op_bswap16_i32, { R, R } },
268 7316329a Stefan Weil
#endif
269 7316329a Stefan Weil
#if TCG_TARGET_HAS_bswap32_i32
270 7316329a Stefan Weil
    { INDEX_op_bswap32_i32, { R, R } },
271 7316329a Stefan Weil
#endif
272 7316329a Stefan Weil
273 7316329a Stefan Weil
    { -1 },
274 7316329a Stefan Weil
};
275 7316329a Stefan Weil
276 7316329a Stefan Weil
static const int tcg_target_reg_alloc_order[] = {
277 7316329a Stefan Weil
    TCG_REG_R0,
278 7316329a Stefan Weil
    TCG_REG_R1,
279 7316329a Stefan Weil
    TCG_REG_R2,
280 7316329a Stefan Weil
    TCG_REG_R3,
281 7316329a Stefan Weil
#if 0 /* used for TCG_REG_CALL_STACK */
282 7316329a Stefan Weil
    TCG_REG_R4,
283 7316329a Stefan Weil
#endif
284 7316329a Stefan Weil
    TCG_REG_R5,
285 7316329a Stefan Weil
    TCG_REG_R6,
286 7316329a Stefan Weil
    TCG_REG_R7,
287 7316329a Stefan Weil
#if TCG_TARGET_NB_REGS >= 16
288 7316329a Stefan Weil
    TCG_REG_R8,
289 7316329a Stefan Weil
    TCG_REG_R9,
290 7316329a Stefan Weil
    TCG_REG_R10,
291 7316329a Stefan Weil
    TCG_REG_R11,
292 7316329a Stefan Weil
    TCG_REG_R12,
293 7316329a Stefan Weil
    TCG_REG_R13,
294 7316329a Stefan Weil
    TCG_REG_R14,
295 7316329a Stefan Weil
    TCG_REG_R15,
296 7316329a Stefan Weil
#endif
297 7316329a Stefan Weil
};
298 7316329a Stefan Weil
299 6673f47d Stefan Weil
#if MAX_OPC_PARAM_IARGS != 5
300 7316329a Stefan Weil
# error Fix needed, number of supported input arguments changed!
301 7316329a Stefan Weil
#endif
302 7316329a Stefan Weil
303 7316329a Stefan Weil
static const int tcg_target_call_iarg_regs[] = {
304 7316329a Stefan Weil
    TCG_REG_R0,
305 7316329a Stefan Weil
    TCG_REG_R1,
306 7316329a Stefan Weil
    TCG_REG_R2,
307 7316329a Stefan Weil
    TCG_REG_R3,
308 7316329a Stefan Weil
#if 0 /* used for TCG_REG_CALL_STACK */
309 7316329a Stefan Weil
    TCG_REG_R4,
310 7316329a Stefan Weil
#endif
311 7316329a Stefan Weil
    TCG_REG_R5,
312 6673f47d Stefan Weil
#if TCG_TARGET_REG_BITS == 32
313 6673f47d Stefan Weil
    /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
314 7316329a Stefan Weil
    TCG_REG_R6,
315 7316329a Stefan Weil
    TCG_REG_R7,
316 7316329a Stefan Weil
#if TCG_TARGET_NB_REGS >= 16
317 7316329a Stefan Weil
    TCG_REG_R8,
318 6673f47d Stefan Weil
    TCG_REG_R9,
319 6673f47d Stefan Weil
    TCG_REG_R10,
320 7316329a Stefan Weil
#else
321 7316329a Stefan Weil
# error Too few input registers available
322 7316329a Stefan Weil
#endif
323 7316329a Stefan Weil
#endif
324 7316329a Stefan Weil
};
325 7316329a Stefan Weil
326 7316329a Stefan Weil
static const int tcg_target_call_oarg_regs[] = {
327 7316329a Stefan Weil
    TCG_REG_R0,
328 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
329 7316329a Stefan Weil
    TCG_REG_R1
330 7316329a Stefan Weil
#endif
331 7316329a Stefan Weil
};
332 7316329a Stefan Weil
333 7316329a Stefan Weil
#ifndef NDEBUG
334 7316329a Stefan Weil
static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
335 7316329a Stefan Weil
    "r00",
336 7316329a Stefan Weil
    "r01",
337 7316329a Stefan Weil
    "r02",
338 7316329a Stefan Weil
    "r03",
339 7316329a Stefan Weil
    "r04",
340 7316329a Stefan Weil
    "r05",
341 7316329a Stefan Weil
    "r06",
342 7316329a Stefan Weil
    "r07",
343 7316329a Stefan Weil
#if TCG_TARGET_NB_REGS >= 16
344 7316329a Stefan Weil
    "r08",
345 7316329a Stefan Weil
    "r09",
346 7316329a Stefan Weil
    "r10",
347 7316329a Stefan Weil
    "r11",
348 7316329a Stefan Weil
    "r12",
349 7316329a Stefan Weil
    "r13",
350 7316329a Stefan Weil
    "r14",
351 7316329a Stefan Weil
    "r15",
352 7316329a Stefan Weil
#if TCG_TARGET_NB_REGS >= 32
353 7316329a Stefan Weil
    "r16",
354 7316329a Stefan Weil
    "r17",
355 7316329a Stefan Weil
    "r18",
356 7316329a Stefan Weil
    "r19",
357 7316329a Stefan Weil
    "r20",
358 7316329a Stefan Weil
    "r21",
359 7316329a Stefan Weil
    "r22",
360 7316329a Stefan Weil
    "r23",
361 7316329a Stefan Weil
    "r24",
362 7316329a Stefan Weil
    "r25",
363 7316329a Stefan Weil
    "r26",
364 7316329a Stefan Weil
    "r27",
365 7316329a Stefan Weil
    "r28",
366 7316329a Stefan Weil
    "r29",
367 7316329a Stefan Weil
    "r30",
368 7316329a Stefan Weil
    "r31"
369 7316329a Stefan Weil
#endif
370 7316329a Stefan Weil
#endif
371 7316329a Stefan Weil
};
372 7316329a Stefan Weil
#endif
373 7316329a Stefan Weil
374 7316329a Stefan Weil
static void patch_reloc(uint8_t *code_ptr, int type,
375 2ba7fae2 Richard Henderson
                        intptr_t value, intptr_t addend)
376 7316329a Stefan Weil
{
377 7316329a Stefan Weil
    /* tcg_out_reloc always uses the same type, addend. */
378 7316329a Stefan Weil
    assert(type == sizeof(tcg_target_long));
379 7316329a Stefan Weil
    assert(addend == 0);
380 7316329a Stefan Weil
    assert(value != 0);
381 7316329a Stefan Weil
    *(tcg_target_long *)code_ptr = value;
382 7316329a Stefan Weil
}
383 7316329a Stefan Weil
384 7316329a Stefan Weil
/* Parse target specific constraints. */
385 7316329a Stefan Weil
static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
386 7316329a Stefan Weil
{
387 7316329a Stefan Weil
    const char *ct_str = *pct_str;
388 7316329a Stefan Weil
    switch (ct_str[0]) {
389 7316329a Stefan Weil
    case 'r':
390 7316329a Stefan Weil
    case 'L':                   /* qemu_ld constraint */
391 7316329a Stefan Weil
    case 'S':                   /* qemu_st constraint */
392 7316329a Stefan Weil
        ct->ct |= TCG_CT_REG;
393 7316329a Stefan Weil
        tcg_regset_set32(ct->u.regs, 0, BIT(TCG_TARGET_NB_REGS) - 1);
394 7316329a Stefan Weil
        break;
395 7316329a Stefan Weil
    default:
396 7316329a Stefan Weil
        return -1;
397 7316329a Stefan Weil
    }
398 7316329a Stefan Weil
    ct_str++;
399 7316329a Stefan Weil
    *pct_str = ct_str;
400 7316329a Stefan Weil
    return 0;
401 7316329a Stefan Weil
}
402 7316329a Stefan Weil
403 7316329a Stefan Weil
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
404 7316329a Stefan Weil
/* Show current bytecode. Used by tcg interpreter. */
405 7316329a Stefan Weil
void tci_disas(uint8_t opc)
406 7316329a Stefan Weil
{
407 7316329a Stefan Weil
    const TCGOpDef *def = &tcg_op_defs[opc];
408 7316329a Stefan Weil
    fprintf(stderr, "TCG %s %u, %u, %u\n",
409 7316329a Stefan Weil
            def->name, def->nb_oargs, def->nb_iargs, def->nb_cargs);
410 7316329a Stefan Weil
}
411 7316329a Stefan Weil
#endif
412 7316329a Stefan Weil
413 7316329a Stefan Weil
/* Write value (native size). */
414 7316329a Stefan Weil
static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
415 7316329a Stefan Weil
{
416 7316329a Stefan Weil
    *(tcg_target_ulong *)s->code_ptr = v;
417 7316329a Stefan Weil
    s->code_ptr += sizeof(tcg_target_ulong);
418 7316329a Stefan Weil
}
419 7316329a Stefan Weil
420 7316329a Stefan Weil
/* Write opcode. */
421 7316329a Stefan Weil
static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
422 7316329a Stefan Weil
{
423 7316329a Stefan Weil
    tcg_out8(s, op);
424 7316329a Stefan Weil
    tcg_out8(s, 0);
425 7316329a Stefan Weil
}
426 7316329a Stefan Weil
427 7316329a Stefan Weil
/* Write register. */
428 7316329a Stefan Weil
static void tcg_out_r(TCGContext *s, TCGArg t0)
429 7316329a Stefan Weil
{
430 7316329a Stefan Weil
    assert(t0 < TCG_TARGET_NB_REGS);
431 7316329a Stefan Weil
    tcg_out8(s, t0);
432 7316329a Stefan Weil
}
433 7316329a Stefan Weil
434 7316329a Stefan Weil
/* Write register or constant (native size). */
435 7316329a Stefan Weil
static void tcg_out_ri(TCGContext *s, int const_arg, TCGArg arg)
436 7316329a Stefan Weil
{
437 7316329a Stefan Weil
    if (const_arg) {
438 7316329a Stefan Weil
        assert(const_arg == 1);
439 7316329a Stefan Weil
        tcg_out8(s, TCG_CONST);
440 7316329a Stefan Weil
        tcg_out_i(s, arg);
441 7316329a Stefan Weil
    } else {
442 7316329a Stefan Weil
        tcg_out_r(s, arg);
443 7316329a Stefan Weil
    }
444 7316329a Stefan Weil
}
445 7316329a Stefan Weil
446 7316329a Stefan Weil
/* Write register or constant (32 bit). */
447 7316329a Stefan Weil
static void tcg_out_ri32(TCGContext *s, int const_arg, TCGArg arg)
448 7316329a Stefan Weil
{
449 7316329a Stefan Weil
    if (const_arg) {
450 7316329a Stefan Weil
        assert(const_arg == 1);
451 7316329a Stefan Weil
        tcg_out8(s, TCG_CONST);
452 7316329a Stefan Weil
        tcg_out32(s, arg);
453 7316329a Stefan Weil
    } else {
454 7316329a Stefan Weil
        tcg_out_r(s, arg);
455 7316329a Stefan Weil
    }
456 7316329a Stefan Weil
}
457 7316329a Stefan Weil
458 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
459 7316329a Stefan Weil
/* Write register or constant (64 bit). */
460 7316329a Stefan Weil
static void tcg_out_ri64(TCGContext *s, int const_arg, TCGArg arg)
461 7316329a Stefan Weil
{
462 7316329a Stefan Weil
    if (const_arg) {
463 7316329a Stefan Weil
        assert(const_arg == 1);
464 7316329a Stefan Weil
        tcg_out8(s, TCG_CONST);
465 7316329a Stefan Weil
        tcg_out64(s, arg);
466 7316329a Stefan Weil
    } else {
467 7316329a Stefan Weil
        tcg_out_r(s, arg);
468 7316329a Stefan Weil
    }
469 7316329a Stefan Weil
}
470 7316329a Stefan Weil
#endif
471 7316329a Stefan Weil
472 7316329a Stefan Weil
/* Write label. */
473 7316329a Stefan Weil
static void tci_out_label(TCGContext *s, TCGArg arg)
474 7316329a Stefan Weil
{
475 7316329a Stefan Weil
    TCGLabel *label = &s->labels[arg];
476 7316329a Stefan Weil
    if (label->has_value) {
477 7316329a Stefan Weil
        tcg_out_i(s, label->u.value);
478 7316329a Stefan Weil
        assert(label->u.value);
479 7316329a Stefan Weil
    } else {
480 7316329a Stefan Weil
        tcg_out_reloc(s, s->code_ptr, sizeof(tcg_target_ulong), arg, 0);
481 3c01ae0e Scott Wood
        s->code_ptr += sizeof(tcg_target_ulong);
482 7316329a Stefan Weil
    }
483 7316329a Stefan Weil
}
484 7316329a Stefan Weil
485 2a534aff Richard Henderson
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
486 a05b5b9b Richard Henderson
                       intptr_t arg2)
487 7316329a Stefan Weil
{
488 7316329a Stefan Weil
    uint8_t *old_code_ptr = s->code_ptr;
489 7316329a Stefan Weil
    if (type == TCG_TYPE_I32) {
490 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_ld_i32);
491 7316329a Stefan Weil
        tcg_out_r(s, ret);
492 7316329a Stefan Weil
        tcg_out_r(s, arg1);
493 7316329a Stefan Weil
        tcg_out32(s, arg2);
494 7316329a Stefan Weil
    } else {
495 7316329a Stefan Weil
        assert(type == TCG_TYPE_I64);
496 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
497 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_ld_i64);
498 7316329a Stefan Weil
        tcg_out_r(s, ret);
499 7316329a Stefan Weil
        tcg_out_r(s, arg1);
500 03fc0548 Richard Henderson
        assert(arg2 == (int32_t)arg2);
501 7316329a Stefan Weil
        tcg_out32(s, arg2);
502 7316329a Stefan Weil
#else
503 7316329a Stefan Weil
        TODO();
504 7316329a Stefan Weil
#endif
505 7316329a Stefan Weil
    }
506 7316329a Stefan Weil
    old_code_ptr[1] = s->code_ptr - old_code_ptr;
507 7316329a Stefan Weil
}
508 7316329a Stefan Weil
509 2a534aff Richard Henderson
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
510 7316329a Stefan Weil
{
511 7316329a Stefan Weil
    uint8_t *old_code_ptr = s->code_ptr;
512 7316329a Stefan Weil
    assert(ret != arg);
513 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
514 7316329a Stefan Weil
    tcg_out_op_t(s, INDEX_op_mov_i32);
515 7316329a Stefan Weil
#else
516 7316329a Stefan Weil
    tcg_out_op_t(s, INDEX_op_mov_i64);
517 7316329a Stefan Weil
#endif
518 7316329a Stefan Weil
    tcg_out_r(s, ret);
519 7316329a Stefan Weil
    tcg_out_r(s, arg);
520 7316329a Stefan Weil
    old_code_ptr[1] = s->code_ptr - old_code_ptr;
521 7316329a Stefan Weil
}
522 7316329a Stefan Weil
523 7316329a Stefan Weil
static void tcg_out_movi(TCGContext *s, TCGType type,
524 2a534aff Richard Henderson
                         TCGReg t0, tcg_target_long arg)
525 7316329a Stefan Weil
{
526 7316329a Stefan Weil
    uint8_t *old_code_ptr = s->code_ptr;
527 7316329a Stefan Weil
    uint32_t arg32 = arg;
528 7316329a Stefan Weil
    if (type == TCG_TYPE_I32 || arg == arg32) {
529 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_movi_i32);
530 7316329a Stefan Weil
        tcg_out_r(s, t0);
531 7316329a Stefan Weil
        tcg_out32(s, arg32);
532 7316329a Stefan Weil
    } else {
533 7316329a Stefan Weil
        assert(type == TCG_TYPE_I64);
534 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
535 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_movi_i64);
536 7316329a Stefan Weil
        tcg_out_r(s, t0);
537 7316329a Stefan Weil
        tcg_out64(s, arg);
538 7316329a Stefan Weil
#else
539 7316329a Stefan Weil
        TODO();
540 7316329a Stefan Weil
#endif
541 7316329a Stefan Weil
    }
542 7316329a Stefan Weil
    old_code_ptr[1] = s->code_ptr - old_code_ptr;
543 7316329a Stefan Weil
}
544 7316329a Stefan Weil
545 7316329a Stefan Weil
static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
546 7316329a Stefan Weil
                       const int *const_args)
547 7316329a Stefan Weil
{
548 7316329a Stefan Weil
    uint8_t *old_code_ptr = s->code_ptr;
549 7316329a Stefan Weil
550 7316329a Stefan Weil
    tcg_out_op_t(s, opc);
551 7316329a Stefan Weil
552 7316329a Stefan Weil
    switch (opc) {
553 7316329a Stefan Weil
    case INDEX_op_exit_tb:
554 7316329a Stefan Weil
        tcg_out64(s, args[0]);
555 7316329a Stefan Weil
        break;
556 7316329a Stefan Weil
    case INDEX_op_goto_tb:
557 7316329a Stefan Weil
        if (s->tb_jmp_offset) {
558 7316329a Stefan Weil
            /* Direct jump method. */
559 7316329a Stefan Weil
            assert(args[0] < ARRAY_SIZE(s->tb_jmp_offset));
560 7316329a Stefan Weil
            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
561 7316329a Stefan Weil
            tcg_out32(s, 0);
562 7316329a Stefan Weil
        } else {
563 7316329a Stefan Weil
            /* Indirect jump method. */
564 7316329a Stefan Weil
            TODO();
565 7316329a Stefan Weil
        }
566 7316329a Stefan Weil
        assert(args[0] < ARRAY_SIZE(s->tb_next_offset));
567 7316329a Stefan Weil
        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
568 7316329a Stefan Weil
        break;
569 7316329a Stefan Weil
    case INDEX_op_br:
570 7316329a Stefan Weil
        tci_out_label(s, args[0]);
571 7316329a Stefan Weil
        break;
572 7316329a Stefan Weil
    case INDEX_op_call:
573 7316329a Stefan Weil
        tcg_out_ri(s, const_args[0], args[0]);
574 7316329a Stefan Weil
        break;
575 7316329a Stefan Weil
    case INDEX_op_setcond_i32:
576 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
577 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
578 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[2], args[2]);
579 7316329a Stefan Weil
        tcg_out8(s, args[3]);   /* condition */
580 7316329a Stefan Weil
        break;
581 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
582 7316329a Stefan Weil
    case INDEX_op_setcond2_i32:
583 7316329a Stefan Weil
        /* setcond2_i32 cond, t0, t1_low, t1_high, t2_low, t2_high */
584 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
585 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
586 7316329a Stefan Weil
        tcg_out_r(s, args[2]);
587 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[3], args[3]);
588 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[4], args[4]);
589 7316329a Stefan Weil
        tcg_out8(s, args[5]);   /* condition */
590 7316329a Stefan Weil
        break;
591 7316329a Stefan Weil
#elif TCG_TARGET_REG_BITS == 64
592 7316329a Stefan Weil
    case INDEX_op_setcond_i64:
593 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
594 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
595 7316329a Stefan Weil
        tcg_out_ri64(s, const_args[2], args[2]);
596 7316329a Stefan Weil
        tcg_out8(s, args[3]);   /* condition */
597 7316329a Stefan Weil
        break;
598 7316329a Stefan Weil
#endif
599 7316329a Stefan Weil
    case INDEX_op_movi_i32:
600 7316329a Stefan Weil
        TODO(); /* Handled by tcg_out_movi? */
601 7316329a Stefan Weil
        break;
602 7316329a Stefan Weil
    case INDEX_op_ld8u_i32:
603 7316329a Stefan Weil
    case INDEX_op_ld8s_i32:
604 7316329a Stefan Weil
    case INDEX_op_ld16u_i32:
605 7316329a Stefan Weil
    case INDEX_op_ld16s_i32:
606 7316329a Stefan Weil
    case INDEX_op_ld_i32:
607 7316329a Stefan Weil
    case INDEX_op_st8_i32:
608 7316329a Stefan Weil
    case INDEX_op_st16_i32:
609 7316329a Stefan Weil
    case INDEX_op_st_i32:
610 7316329a Stefan Weil
    case INDEX_op_ld8u_i64:
611 7316329a Stefan Weil
    case INDEX_op_ld8s_i64:
612 7316329a Stefan Weil
    case INDEX_op_ld16u_i64:
613 7316329a Stefan Weil
    case INDEX_op_ld16s_i64:
614 7316329a Stefan Weil
    case INDEX_op_ld32u_i64:
615 7316329a Stefan Weil
    case INDEX_op_ld32s_i64:
616 7316329a Stefan Weil
    case INDEX_op_ld_i64:
617 7316329a Stefan Weil
    case INDEX_op_st8_i64:
618 7316329a Stefan Weil
    case INDEX_op_st16_i64:
619 7316329a Stefan Weil
    case INDEX_op_st32_i64:
620 7316329a Stefan Weil
    case INDEX_op_st_i64:
621 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
622 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
623 03fc0548 Richard Henderson
        assert(args[2] == (int32_t)args[2]);
624 7316329a Stefan Weil
        tcg_out32(s, args[2]);
625 7316329a Stefan Weil
        break;
626 7316329a Stefan Weil
    case INDEX_op_add_i32:
627 7316329a Stefan Weil
    case INDEX_op_sub_i32:
628 7316329a Stefan Weil
    case INDEX_op_mul_i32:
629 7316329a Stefan Weil
    case INDEX_op_and_i32:
630 7316329a Stefan Weil
    case INDEX_op_andc_i32:     /* Optional (TCG_TARGET_HAS_andc_i32). */
631 7316329a Stefan Weil
    case INDEX_op_eqv_i32:      /* Optional (TCG_TARGET_HAS_eqv_i32). */
632 7316329a Stefan Weil
    case INDEX_op_nand_i32:     /* Optional (TCG_TARGET_HAS_nand_i32). */
633 7316329a Stefan Weil
    case INDEX_op_nor_i32:      /* Optional (TCG_TARGET_HAS_nor_i32). */
634 7316329a Stefan Weil
    case INDEX_op_or_i32:
635 7316329a Stefan Weil
    case INDEX_op_orc_i32:      /* Optional (TCG_TARGET_HAS_orc_i32). */
636 7316329a Stefan Weil
    case INDEX_op_xor_i32:
637 7316329a Stefan Weil
    case INDEX_op_shl_i32:
638 7316329a Stefan Weil
    case INDEX_op_shr_i32:
639 7316329a Stefan Weil
    case INDEX_op_sar_i32:
640 7316329a Stefan Weil
    case INDEX_op_rotl_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
641 7316329a Stefan Weil
    case INDEX_op_rotr_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
642 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
643 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[1], args[1]);
644 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[2], args[2]);
645 7316329a Stefan Weil
        break;
646 e24dc9fe Stefan Weil
    case INDEX_op_deposit_i32:  /* Optional (TCG_TARGET_HAS_deposit_i32). */
647 e24dc9fe Stefan Weil
        tcg_out_r(s, args[0]);
648 e24dc9fe Stefan Weil
        tcg_out_r(s, args[1]);
649 e24dc9fe Stefan Weil
        tcg_out_r(s, args[2]);
650 e24dc9fe Stefan Weil
        assert(args[3] <= UINT8_MAX);
651 e24dc9fe Stefan Weil
        tcg_out8(s, args[3]);
652 e24dc9fe Stefan Weil
        assert(args[4] <= UINT8_MAX);
653 e24dc9fe Stefan Weil
        tcg_out8(s, args[4]);
654 e24dc9fe Stefan Weil
        break;
655 7316329a Stefan Weil
656 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
657 7316329a Stefan Weil
    case INDEX_op_mov_i64:
658 7316329a Stefan Weil
    case INDEX_op_movi_i64:
659 7316329a Stefan Weil
        TODO();
660 7316329a Stefan Weil
        break;
661 7316329a Stefan Weil
    case INDEX_op_add_i64:
662 7316329a Stefan Weil
    case INDEX_op_sub_i64:
663 7316329a Stefan Weil
    case INDEX_op_mul_i64:
664 7316329a Stefan Weil
    case INDEX_op_and_i64:
665 7316329a Stefan Weil
    case INDEX_op_andc_i64:     /* Optional (TCG_TARGET_HAS_andc_i64). */
666 7316329a Stefan Weil
    case INDEX_op_eqv_i64:      /* Optional (TCG_TARGET_HAS_eqv_i64). */
667 7316329a Stefan Weil
    case INDEX_op_nand_i64:     /* Optional (TCG_TARGET_HAS_nand_i64). */
668 7316329a Stefan Weil
    case INDEX_op_nor_i64:      /* Optional (TCG_TARGET_HAS_nor_i64). */
669 7316329a Stefan Weil
    case INDEX_op_or_i64:
670 7316329a Stefan Weil
    case INDEX_op_orc_i64:      /* Optional (TCG_TARGET_HAS_orc_i64). */
671 7316329a Stefan Weil
    case INDEX_op_xor_i64:
672 7316329a Stefan Weil
    case INDEX_op_shl_i64:
673 7316329a Stefan Weil
    case INDEX_op_shr_i64:
674 7316329a Stefan Weil
    case INDEX_op_sar_i64:
675 7316329a Stefan Weil
    case INDEX_op_rotl_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
676 7316329a Stefan Weil
    case INDEX_op_rotr_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
677 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
678 7316329a Stefan Weil
        tcg_out_ri64(s, const_args[1], args[1]);
679 7316329a Stefan Weil
        tcg_out_ri64(s, const_args[2], args[2]);
680 7316329a Stefan Weil
        break;
681 e24dc9fe Stefan Weil
    case INDEX_op_deposit_i64:  /* Optional (TCG_TARGET_HAS_deposit_i64). */
682 e24dc9fe Stefan Weil
        tcg_out_r(s, args[0]);
683 e24dc9fe Stefan Weil
        tcg_out_r(s, args[1]);
684 e24dc9fe Stefan Weil
        tcg_out_r(s, args[2]);
685 e24dc9fe Stefan Weil
        assert(args[3] <= UINT8_MAX);
686 e24dc9fe Stefan Weil
        tcg_out8(s, args[3]);
687 e24dc9fe Stefan Weil
        assert(args[4] <= UINT8_MAX);
688 e24dc9fe Stefan Weil
        tcg_out8(s, args[4]);
689 e24dc9fe Stefan Weil
        break;
690 7316329a Stefan Weil
    case INDEX_op_div_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
691 7316329a Stefan Weil
    case INDEX_op_divu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
692 7316329a Stefan Weil
    case INDEX_op_rem_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
693 7316329a Stefan Weil
    case INDEX_op_remu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
694 7316329a Stefan Weil
        TODO();
695 7316329a Stefan Weil
        break;
696 7316329a Stefan Weil
    case INDEX_op_div2_i64:     /* Optional (TCG_TARGET_HAS_div2_i64). */
697 7316329a Stefan Weil
    case INDEX_op_divu2_i64:    /* Optional (TCG_TARGET_HAS_div2_i64). */
698 7316329a Stefan Weil
        TODO();
699 7316329a Stefan Weil
        break;
700 7316329a Stefan Weil
    case INDEX_op_brcond_i64:
701 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
702 7316329a Stefan Weil
        tcg_out_ri64(s, const_args[1], args[1]);
703 7316329a Stefan Weil
        tcg_out8(s, args[2]);           /* condition */
704 7316329a Stefan Weil
        tci_out_label(s, args[3]);
705 7316329a Stefan Weil
        break;
706 7316329a Stefan Weil
    case INDEX_op_bswap16_i64:  /* Optional (TCG_TARGET_HAS_bswap16_i64). */
707 7316329a Stefan Weil
    case INDEX_op_bswap32_i64:  /* Optional (TCG_TARGET_HAS_bswap32_i64). */
708 7316329a Stefan Weil
    case INDEX_op_bswap64_i64:  /* Optional (TCG_TARGET_HAS_bswap64_i64). */
709 7316329a Stefan Weil
    case INDEX_op_not_i64:      /* Optional (TCG_TARGET_HAS_not_i64). */
710 7316329a Stefan Weil
    case INDEX_op_neg_i64:      /* Optional (TCG_TARGET_HAS_neg_i64). */
711 7316329a Stefan Weil
    case INDEX_op_ext8s_i64:    /* Optional (TCG_TARGET_HAS_ext8s_i64). */
712 7316329a Stefan Weil
    case INDEX_op_ext8u_i64:    /* Optional (TCG_TARGET_HAS_ext8u_i64). */
713 7316329a Stefan Weil
    case INDEX_op_ext16s_i64:   /* Optional (TCG_TARGET_HAS_ext16s_i64). */
714 7316329a Stefan Weil
    case INDEX_op_ext16u_i64:   /* Optional (TCG_TARGET_HAS_ext16u_i64). */
715 7316329a Stefan Weil
    case INDEX_op_ext32s_i64:   /* Optional (TCG_TARGET_HAS_ext32s_i64). */
716 7316329a Stefan Weil
    case INDEX_op_ext32u_i64:   /* Optional (TCG_TARGET_HAS_ext32u_i64). */
717 7316329a Stefan Weil
#endif /* TCG_TARGET_REG_BITS == 64 */
718 7316329a Stefan Weil
    case INDEX_op_neg_i32:      /* Optional (TCG_TARGET_HAS_neg_i32). */
719 7316329a Stefan Weil
    case INDEX_op_not_i32:      /* Optional (TCG_TARGET_HAS_not_i32). */
720 7316329a Stefan Weil
    case INDEX_op_ext8s_i32:    /* Optional (TCG_TARGET_HAS_ext8s_i32). */
721 7316329a Stefan Weil
    case INDEX_op_ext16s_i32:   /* Optional (TCG_TARGET_HAS_ext16s_i32). */
722 7316329a Stefan Weil
    case INDEX_op_ext8u_i32:    /* Optional (TCG_TARGET_HAS_ext8u_i32). */
723 7316329a Stefan Weil
    case INDEX_op_ext16u_i32:   /* Optional (TCG_TARGET_HAS_ext16u_i32). */
724 7316329a Stefan Weil
    case INDEX_op_bswap16_i32:  /* Optional (TCG_TARGET_HAS_bswap16_i32). */
725 7316329a Stefan Weil
    case INDEX_op_bswap32_i32:  /* Optional (TCG_TARGET_HAS_bswap32_i32). */
726 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
727 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
728 7316329a Stefan Weil
        break;
729 7316329a Stefan Weil
    case INDEX_op_div_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
730 7316329a Stefan Weil
    case INDEX_op_divu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
731 7316329a Stefan Weil
    case INDEX_op_rem_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
732 7316329a Stefan Weil
    case INDEX_op_remu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
733 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
734 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[1], args[1]);
735 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[2], args[2]);
736 7316329a Stefan Weil
        break;
737 7316329a Stefan Weil
    case INDEX_op_div2_i32:     /* Optional (TCG_TARGET_HAS_div2_i32). */
738 7316329a Stefan Weil
    case INDEX_op_divu2_i32:    /* Optional (TCG_TARGET_HAS_div2_i32). */
739 7316329a Stefan Weil
        TODO();
740 7316329a Stefan Weil
        break;
741 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
742 7316329a Stefan Weil
    case INDEX_op_add2_i32:
743 7316329a Stefan Weil
    case INDEX_op_sub2_i32:
744 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
745 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
746 7316329a Stefan Weil
        tcg_out_r(s, args[2]);
747 7316329a Stefan Weil
        tcg_out_r(s, args[3]);
748 7316329a Stefan Weil
        tcg_out_r(s, args[4]);
749 7316329a Stefan Weil
        tcg_out_r(s, args[5]);
750 7316329a Stefan Weil
        break;
751 7316329a Stefan Weil
    case INDEX_op_brcond2_i32:
752 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
753 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
754 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[2], args[2]);
755 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[3], args[3]);
756 7316329a Stefan Weil
        tcg_out8(s, args[4]);           /* condition */
757 7316329a Stefan Weil
        tci_out_label(s, args[5]);
758 7316329a Stefan Weil
        break;
759 7316329a Stefan Weil
    case INDEX_op_mulu2_i32:
760 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
761 7316329a Stefan Weil
        tcg_out_r(s, args[1]);
762 7316329a Stefan Weil
        tcg_out_r(s, args[2]);
763 7316329a Stefan Weil
        tcg_out_r(s, args[3]);
764 7316329a Stefan Weil
        break;
765 7316329a Stefan Weil
#endif
766 7316329a Stefan Weil
    case INDEX_op_brcond_i32:
767 7316329a Stefan Weil
        tcg_out_r(s, args[0]);
768 7316329a Stefan Weil
        tcg_out_ri32(s, const_args[1], args[1]);
769 7316329a Stefan Weil
        tcg_out8(s, args[2]);           /* condition */
770 7316329a Stefan Weil
        tci_out_label(s, args[3]);
771 7316329a Stefan Weil
        break;
772 7316329a Stefan Weil
    case INDEX_op_qemu_ld8u:
773 7316329a Stefan Weil
    case INDEX_op_qemu_ld8s:
774 7316329a Stefan Weil
    case INDEX_op_qemu_ld16u:
775 7316329a Stefan Weil
    case INDEX_op_qemu_ld16s:
776 7316329a Stefan Weil
    case INDEX_op_qemu_ld32:
777 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
778 7316329a Stefan Weil
    case INDEX_op_qemu_ld32s:
779 7316329a Stefan Weil
    case INDEX_op_qemu_ld32u:
780 7316329a Stefan Weil
#endif
781 7316329a Stefan Weil
        tcg_out_r(s, *args++);
782 7316329a Stefan Weil
        tcg_out_r(s, *args++);
783 7316329a Stefan Weil
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
784 7316329a Stefan Weil
        tcg_out_r(s, *args++);
785 7316329a Stefan Weil
#endif
786 7316329a Stefan Weil
#ifdef CONFIG_SOFTMMU
787 7316329a Stefan Weil
        tcg_out_i(s, *args);
788 7316329a Stefan Weil
#endif
789 7316329a Stefan Weil
        break;
790 7316329a Stefan Weil
    case INDEX_op_qemu_ld64:
791 7316329a Stefan Weil
        tcg_out_r(s, *args++);
792 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
793 7316329a Stefan Weil
        tcg_out_r(s, *args++);
794 7316329a Stefan Weil
#endif
795 7316329a Stefan Weil
        tcg_out_r(s, *args++);
796 7316329a Stefan Weil
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
797 7316329a Stefan Weil
        tcg_out_r(s, *args++);
798 7316329a Stefan Weil
#endif
799 7316329a Stefan Weil
#ifdef CONFIG_SOFTMMU
800 7316329a Stefan Weil
        tcg_out_i(s, *args);
801 7316329a Stefan Weil
#endif
802 7316329a Stefan Weil
        break;
803 7316329a Stefan Weil
    case INDEX_op_qemu_st8:
804 7316329a Stefan Weil
    case INDEX_op_qemu_st16:
805 7316329a Stefan Weil
    case INDEX_op_qemu_st32:
806 7316329a Stefan Weil
        tcg_out_r(s, *args++);
807 7316329a Stefan Weil
        tcg_out_r(s, *args++);
808 7316329a Stefan Weil
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
809 7316329a Stefan Weil
        tcg_out_r(s, *args++);
810 7316329a Stefan Weil
#endif
811 7316329a Stefan Weil
#ifdef CONFIG_SOFTMMU
812 7316329a Stefan Weil
        tcg_out_i(s, *args);
813 7316329a Stefan Weil
#endif
814 7316329a Stefan Weil
        break;
815 7316329a Stefan Weil
    case INDEX_op_qemu_st64:
816 7316329a Stefan Weil
        tcg_out_r(s, *args++);
817 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 32
818 7316329a Stefan Weil
        tcg_out_r(s, *args++);
819 7316329a Stefan Weil
#endif
820 7316329a Stefan Weil
        tcg_out_r(s, *args++);
821 7316329a Stefan Weil
#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
822 7316329a Stefan Weil
        tcg_out_r(s, *args++);
823 7316329a Stefan Weil
#endif
824 7316329a Stefan Weil
#ifdef CONFIG_SOFTMMU
825 7316329a Stefan Weil
        tcg_out_i(s, *args);
826 7316329a Stefan Weil
#endif
827 7316329a Stefan Weil
        break;
828 7316329a Stefan Weil
    case INDEX_op_end:
829 7316329a Stefan Weil
        TODO();
830 7316329a Stefan Weil
        break;
831 7316329a Stefan Weil
    default:
832 7316329a Stefan Weil
        fprintf(stderr, "Missing: %s\n", tcg_op_defs[opc].name);
833 7316329a Stefan Weil
        tcg_abort();
834 7316329a Stefan Weil
    }
835 7316329a Stefan Weil
    old_code_ptr[1] = s->code_ptr - old_code_ptr;
836 7316329a Stefan Weil
}
837 7316329a Stefan Weil
838 2a534aff Richard Henderson
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
839 a05b5b9b Richard Henderson
                       intptr_t arg2)
840 7316329a Stefan Weil
{
841 7316329a Stefan Weil
    uint8_t *old_code_ptr = s->code_ptr;
842 7316329a Stefan Weil
    if (type == TCG_TYPE_I32) {
843 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_st_i32);
844 7316329a Stefan Weil
        tcg_out_r(s, arg);
845 7316329a Stefan Weil
        tcg_out_r(s, arg1);
846 7316329a Stefan Weil
        tcg_out32(s, arg2);
847 7316329a Stefan Weil
    } else {
848 7316329a Stefan Weil
        assert(type == TCG_TYPE_I64);
849 7316329a Stefan Weil
#if TCG_TARGET_REG_BITS == 64
850 7316329a Stefan Weil
        tcg_out_op_t(s, INDEX_op_st_i64);
851 7316329a Stefan Weil
        tcg_out_r(s, arg);
852 7316329a Stefan Weil
        tcg_out_r(s, arg1);
853 7316329a Stefan Weil
        tcg_out32(s, arg2);
854 7316329a Stefan Weil
#else
855 7316329a Stefan Weil
        TODO();
856 7316329a Stefan Weil
#endif
857 7316329a Stefan Weil
    }
858 7316329a Stefan Weil
    old_code_ptr[1] = s->code_ptr - old_code_ptr;
859 7316329a Stefan Weil
}
860 7316329a Stefan Weil
861 7316329a Stefan Weil
/* Test if a constant matches the constraint. */
862 7316329a Stefan Weil
static int tcg_target_const_match(tcg_target_long val,
863 7316329a Stefan Weil
                                  const TCGArgConstraint *arg_ct)
864 7316329a Stefan Weil
{
865 7316329a Stefan Weil
    /* No need to return 0 or 1, 0 or != 0 is good enough. */
866 7316329a Stefan Weil
    return arg_ct->ct & TCG_CT_CONST;
867 7316329a Stefan Weil
}
868 7316329a Stefan Weil
869 7316329a Stefan Weil
static void tcg_target_init(TCGContext *s)
870 7316329a Stefan Weil
{
871 7316329a Stefan Weil
#if defined(CONFIG_DEBUG_TCG_INTERPRETER)
872 7316329a Stefan Weil
    const char *envval = getenv("DEBUG_TCG");
873 7316329a Stefan Weil
    if (envval) {
874 24537a01 Peter Maydell
        qemu_set_log(strtol(envval, NULL, 0));
875 7316329a Stefan Weil
    }
876 7316329a Stefan Weil
#endif
877 7316329a Stefan Weil
878 7316329a Stefan Weil
    /* The current code uses uint8_t for tcg operations. */
879 7316329a Stefan Weil
    assert(ARRAY_SIZE(tcg_op_defs) <= UINT8_MAX);
880 7316329a Stefan Weil
881 7316329a Stefan Weil
    /* Registers available for 32 bit operations. */
882 7316329a Stefan Weil
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
883 7316329a Stefan Weil
                     BIT(TCG_TARGET_NB_REGS) - 1);
884 7316329a Stefan Weil
    /* Registers available for 64 bit operations. */
885 7316329a Stefan Weil
    tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0,
886 7316329a Stefan Weil
                     BIT(TCG_TARGET_NB_REGS) - 1);
887 7316329a Stefan Weil
    /* TODO: Which registers should be set here? */
888 7316329a Stefan Weil
    tcg_regset_set32(tcg_target_call_clobber_regs, 0,
889 7316329a Stefan Weil
                     BIT(TCG_TARGET_NB_REGS) - 1);
890 ee79c356 Richard Henderson
891 7316329a Stefan Weil
    tcg_regset_clear(s->reserved_regs);
892 7316329a Stefan Weil
    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
893 7316329a Stefan Weil
    tcg_add_target_add_op_defs(tcg_target_op_defs);
894 ee79c356 Richard Henderson
895 ee79c356 Richard Henderson
    /* We use negative offsets from "sp" so that we can distinguish
896 ee79c356 Richard Henderson
       stores that might pretend to be call arguments.  */
897 ee79c356 Richard Henderson
    tcg_set_frame(s, TCG_REG_CALL_STACK,
898 ee79c356 Richard Henderson
                  -CPU_TEMP_BUF_NLONGS * sizeof(long),
899 7316329a Stefan Weil
                  CPU_TEMP_BUF_NLONGS * sizeof(long));
900 7316329a Stefan Weil
}
901 7316329a Stefan Weil
902 7316329a Stefan Weil
/* Generate global QEMU prologue and epilogue code. */
903 4699ca6d Richard Henderson
static inline void tcg_target_qemu_prologue(TCGContext *s)
904 7316329a Stefan Weil
{
905 7316329a Stefan Weil
}