1 /*
2 * Tiny Code Generator for QEMU
3 *
4 * Copyright (c) 2008 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "tcg/tcg.h"
27 #include "tcg/tcg-temp-internal.h"
28 #include "tcg/tcg-op-common.h"
29 #include "exec/translation-block.h"
30 #include "exec/plugin-gen.h"
31 #include "tcg-internal.h"
32
33
34 /*
35 * Encourage the compiler to tail-call to a function, rather than inlining.
36 * Minimizes code size across 99 bottles of beer on the wall.
37 */
38 #define NI __attribute__((noinline))
39
tcg_gen_op1(TCGOpcode opc,TCGArg a1)40 TCGOp * NI tcg_gen_op1(TCGOpcode opc, TCGArg a1)
41 {
42 TCGOp *op = tcg_emit_op(opc, 1);
43 op->args[0] = a1;
44 return op;
45 }
46
tcg_gen_op2(TCGOpcode opc,TCGArg a1,TCGArg a2)47 TCGOp * NI tcg_gen_op2(TCGOpcode opc, TCGArg a1, TCGArg a2)
48 {
49 TCGOp *op = tcg_emit_op(opc, 2);
50 op->args[0] = a1;
51 op->args[1] = a2;
52 return op;
53 }
54
tcg_gen_op3(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3)55 TCGOp * NI tcg_gen_op3(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3)
56 {
57 TCGOp *op = tcg_emit_op(opc, 3);
58 op->args[0] = a1;
59 op->args[1] = a2;
60 op->args[2] = a3;
61 return op;
62 }
63
tcg_gen_op4(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4)64 TCGOp * NI tcg_gen_op4(TCGOpcode opc, TCGArg a1, TCGArg a2,
65 TCGArg a3, TCGArg a4)
66 {
67 TCGOp *op = tcg_emit_op(opc, 4);
68 op->args[0] = a1;
69 op->args[1] = a2;
70 op->args[2] = a3;
71 op->args[3] = a4;
72 return op;
73 }
74
tcg_gen_op5(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5)75 TCGOp * NI tcg_gen_op5(TCGOpcode opc, TCGArg a1, TCGArg a2,
76 TCGArg a3, TCGArg a4, TCGArg a5)
77 {
78 TCGOp *op = tcg_emit_op(opc, 5);
79 op->args[0] = a1;
80 op->args[1] = a2;
81 op->args[2] = a3;
82 op->args[3] = a4;
83 op->args[4] = a5;
84 return op;
85 }
86
tcg_gen_op6(TCGOpcode opc,TCGArg a1,TCGArg a2,TCGArg a3,TCGArg a4,TCGArg a5,TCGArg a6)87 TCGOp * NI tcg_gen_op6(TCGOpcode opc, TCGArg a1, TCGArg a2, TCGArg a3,
88 TCGArg a4, TCGArg a5, TCGArg a6)
89 {
90 TCGOp *op = tcg_emit_op(opc, 6);
91 op->args[0] = a1;
92 op->args[1] = a2;
93 op->args[2] = a3;
94 op->args[3] = a4;
95 op->args[4] = a5;
96 op->args[5] = a6;
97 return op;
98 }
99
100 /*
101 * With CONFIG_DEBUG_TCG, tcgv_*_tmp via tcgv_*_arg, is an out-of-line
102 * assertion check. Force tail calls to avoid too much code expansion.
103 */
104 #ifdef CONFIG_DEBUG_TCG
105 # define DNI NI
106 #else
107 # define DNI
108 #endif
109
tcg_gen_op1_i32(TCGOpcode opc,TCGv_i32 a1)110 static void DNI tcg_gen_op1_i32(TCGOpcode opc, TCGv_i32 a1)
111 {
112 tcg_gen_op1(opc, tcgv_i32_arg(a1));
113 }
114
tcg_gen_op1_i64(TCGOpcode opc,TCGv_i64 a1)115 static void DNI tcg_gen_op1_i64(TCGOpcode opc, TCGv_i64 a1)
116 {
117 tcg_gen_op1(opc, tcgv_i64_arg(a1));
118 }
119
tcg_gen_op1i(TCGOpcode opc,TCGArg a1)120 static TCGOp * DNI tcg_gen_op1i(TCGOpcode opc, TCGArg a1)
121 {
122 return tcg_gen_op1(opc, a1);
123 }
124
tcg_gen_op2_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2)125 static void DNI tcg_gen_op2_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2)
126 {
127 tcg_gen_op2(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2));
128 }
129
tcg_gen_op2_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2)130 static void DNI tcg_gen_op2_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2)
131 {
132 tcg_gen_op2(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2));
133 }
134
tcg_gen_op3_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3)135 static void DNI tcg_gen_op3_i32(TCGOpcode opc, TCGv_i32 a1,
136 TCGv_i32 a2, TCGv_i32 a3)
137 {
138 tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), tcgv_i32_arg(a3));
139 }
140
tcg_gen_op3_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3)141 static void DNI tcg_gen_op3_i64(TCGOpcode opc, TCGv_i64 a1,
142 TCGv_i64 a2, TCGv_i64 a3)
143 {
144 tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), tcgv_i64_arg(a3));
145 }
146
tcg_gen_op3i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3)147 static void DNI tcg_gen_op3i_i32(TCGOpcode opc, TCGv_i32 a1,
148 TCGv_i32 a2, TCGArg a3)
149 {
150 tcg_gen_op3(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3);
151 }
152
tcg_gen_op3i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3)153 static void DNI tcg_gen_op3i_i64(TCGOpcode opc, TCGv_i64 a1,
154 TCGv_i64 a2, TCGArg a3)
155 {
156 tcg_gen_op3(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3);
157 }
158
tcg_gen_ldst_op_i32(TCGOpcode opc,TCGv_i32 val,TCGv_ptr base,TCGArg offset)159 static void DNI tcg_gen_ldst_op_i32(TCGOpcode opc, TCGv_i32 val,
160 TCGv_ptr base, TCGArg offset)
161 {
162 tcg_gen_op3(opc, tcgv_i32_arg(val), tcgv_ptr_arg(base), offset);
163 }
164
tcg_gen_ldst_op_i64(TCGOpcode opc,TCGv_i64 val,TCGv_ptr base,TCGArg offset)165 static void DNI tcg_gen_ldst_op_i64(TCGOpcode opc, TCGv_i64 val,
166 TCGv_ptr base, TCGArg offset)
167 {
168 tcg_gen_op3(opc, tcgv_i64_arg(val), tcgv_ptr_arg(base), offset);
169 }
170
tcg_gen_op4_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4)171 static void DNI tcg_gen_op4_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
172 TCGv_i32 a3, TCGv_i32 a4)
173 {
174 tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
175 tcgv_i32_arg(a3), tcgv_i32_arg(a4));
176 }
177
tcg_gen_op4_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4)178 static void DNI tcg_gen_op4_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
179 TCGv_i64 a3, TCGv_i64 a4)
180 {
181 tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
182 tcgv_i64_arg(a3), tcgv_i64_arg(a4));
183 }
184
tcg_gen_op4i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4)185 static void DNI tcg_gen_op4i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
186 TCGv_i32 a3, TCGArg a4)
187 {
188 tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
189 tcgv_i32_arg(a3), a4);
190 }
191
tcg_gen_op4i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4)192 static void DNI tcg_gen_op4i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
193 TCGv_i64 a3, TCGArg a4)
194 {
195 tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
196 tcgv_i64_arg(a3), a4);
197 }
198
tcg_gen_op4ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGArg a3,TCGArg a4)199 static TCGOp * DNI tcg_gen_op4ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
200 TCGArg a3, TCGArg a4)
201 {
202 return tcg_gen_op4(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2), a3, a4);
203 }
204
tcg_gen_op4ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGArg a3,TCGArg a4)205 static TCGOp * DNI tcg_gen_op4ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
206 TCGArg a3, TCGArg a4)
207 {
208 return tcg_gen_op4(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2), a3, a4);
209 }
210
tcg_gen_op5_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5)211 static void DNI tcg_gen_op5_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
212 TCGv_i32 a3, TCGv_i32 a4, TCGv_i32 a5)
213 {
214 tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
215 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5));
216 }
217
tcg_gen_op5_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5)218 static void DNI tcg_gen_op5_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
219 TCGv_i64 a3, TCGv_i64 a4, TCGv_i64 a5)
220 {
221 tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
222 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5));
223 }
224
tcg_gen_op5ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGArg a4,TCGArg a5)225 static void DNI tcg_gen_op5ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
226 TCGv_i32 a3, TCGArg a4, TCGArg a5)
227 {
228 tcg_gen_op5(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
229 tcgv_i32_arg(a3), a4, a5);
230 }
231
tcg_gen_op5ii_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGArg a4,TCGArg a5)232 static void DNI tcg_gen_op5ii_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
233 TCGv_i64 a3, TCGArg a4, TCGArg a5)
234 {
235 tcg_gen_op5(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
236 tcgv_i64_arg(a3), a4, a5);
237 }
238
tcg_gen_op6_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5,TCGv_i32 a6)239 static void DNI tcg_gen_op6_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
240 TCGv_i32 a3, TCGv_i32 a4,
241 TCGv_i32 a5, TCGv_i32 a6)
242 {
243 tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
244 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5),
245 tcgv_i32_arg(a6));
246 }
247
tcg_gen_op6_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5,TCGv_i64 a6)248 static void DNI tcg_gen_op6_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
249 TCGv_i64 a3, TCGv_i64 a4,
250 TCGv_i64 a5, TCGv_i64 a6)
251 {
252 tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
253 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5),
254 tcgv_i64_arg(a6));
255 }
256
tcg_gen_op6i_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGv_i32 a5,TCGArg a6)257 static void DNI tcg_gen_op6i_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
258 TCGv_i32 a3, TCGv_i32 a4,
259 TCGv_i32 a5, TCGArg a6)
260 {
261 tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
262 tcgv_i32_arg(a3), tcgv_i32_arg(a4), tcgv_i32_arg(a5), a6);
263 }
264
tcg_gen_op6i_i64(TCGOpcode opc,TCGv_i64 a1,TCGv_i64 a2,TCGv_i64 a3,TCGv_i64 a4,TCGv_i64 a5,TCGArg a6)265 static void DNI tcg_gen_op6i_i64(TCGOpcode opc, TCGv_i64 a1, TCGv_i64 a2,
266 TCGv_i64 a3, TCGv_i64 a4,
267 TCGv_i64 a5, TCGArg a6)
268 {
269 tcg_gen_op6(opc, tcgv_i64_arg(a1), tcgv_i64_arg(a2),
270 tcgv_i64_arg(a3), tcgv_i64_arg(a4), tcgv_i64_arg(a5), a6);
271 }
272
tcg_gen_op6ii_i32(TCGOpcode opc,TCGv_i32 a1,TCGv_i32 a2,TCGv_i32 a3,TCGv_i32 a4,TCGArg a5,TCGArg a6)273 static TCGOp * DNI tcg_gen_op6ii_i32(TCGOpcode opc, TCGv_i32 a1, TCGv_i32 a2,
274 TCGv_i32 a3, TCGv_i32 a4,
275 TCGArg a5, TCGArg a6)
276 {
277 return tcg_gen_op6(opc, tcgv_i32_arg(a1), tcgv_i32_arg(a2),
278 tcgv_i32_arg(a3), tcgv_i32_arg(a4), a5, a6);
279 }
280
281 /* Generic ops. */
282
gen_set_label(TCGLabel * l)283 void gen_set_label(TCGLabel *l)
284 {
285 l->present = 1;
286 tcg_gen_op1(INDEX_op_set_label, label_arg(l));
287 }
288
add_as_label_use(TCGLabel * l,TCGOp * op)289 static void add_as_label_use(TCGLabel *l, TCGOp *op)
290 {
291 TCGLabelUse *u = tcg_malloc(sizeof(TCGLabelUse));
292
293 u->op = op;
294 QSIMPLEQ_INSERT_TAIL(&l->branches, u, next);
295 }
296
tcg_gen_br(TCGLabel * l)297 void tcg_gen_br(TCGLabel *l)
298 {
299 add_as_label_use(l, tcg_gen_op1(INDEX_op_br, label_arg(l)));
300 }
301
tcg_gen_mb(TCGBar mb_type)302 void tcg_gen_mb(TCGBar mb_type)
303 {
304 #ifdef CONFIG_USER_ONLY
305 bool parallel = tcg_ctx->gen_tb->cflags & CF_PARALLEL;
306 #else
307 /*
308 * It is tempting to elide the barrier in a uniprocessor context.
309 * However, even with a single cpu we have i/o threads running in
310 * parallel, and lack of memory order can result in e.g. virtio
311 * queue entries being read incorrectly.
312 */
313 bool parallel = true;
314 #endif
315
316 if (parallel) {
317 tcg_gen_op1(INDEX_op_mb, mb_type);
318 }
319 }
320
tcg_gen_plugin_cb(unsigned from)321 void tcg_gen_plugin_cb(unsigned from)
322 {
323 tcg_gen_op1(INDEX_op_plugin_cb, from);
324 }
325
tcg_gen_plugin_mem_cb(TCGv_i64 addr,unsigned meminfo)326 void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
327 {
328 tcg_gen_op2(INDEX_op_plugin_mem_cb, tcgv_i64_arg(addr), meminfo);
329 }
330
331 /* 32 bit ops */
332
tcg_gen_discard_i32(TCGv_i32 arg)333 void tcg_gen_discard_i32(TCGv_i32 arg)
334 {
335 tcg_gen_op1_i32(INDEX_op_discard, arg);
336 }
337
tcg_gen_mov_i32(TCGv_i32 ret,TCGv_i32 arg)338 void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
339 {
340 if (ret != arg) {
341 tcg_gen_op2_i32(INDEX_op_mov_i32, ret, arg);
342 }
343 }
344
tcg_gen_movi_i32(TCGv_i32 ret,int32_t arg)345 void tcg_gen_movi_i32(TCGv_i32 ret, int32_t arg)
346 {
347 tcg_gen_mov_i32(ret, tcg_constant_i32(arg));
348 }
349
tcg_gen_add_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)350 void tcg_gen_add_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
351 {
352 tcg_gen_op3_i32(INDEX_op_add_i32, ret, arg1, arg2);
353 }
354
tcg_gen_addi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)355 void tcg_gen_addi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
356 {
357 /* some cases can be optimized here */
358 if (arg2 == 0) {
359 tcg_gen_mov_i32(ret, arg1);
360 } else {
361 tcg_gen_add_i32(ret, arg1, tcg_constant_i32(arg2));
362 }
363 }
364
tcg_gen_sub_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)365 void tcg_gen_sub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
366 {
367 tcg_gen_op3_i32(INDEX_op_sub_i32, ret, arg1, arg2);
368 }
369
tcg_gen_subfi_i32(TCGv_i32 ret,int32_t arg1,TCGv_i32 arg2)370 void tcg_gen_subfi_i32(TCGv_i32 ret, int32_t arg1, TCGv_i32 arg2)
371 {
372 if (arg1 == 0) {
373 tcg_gen_neg_i32(ret, arg2);
374 } else {
375 tcg_gen_sub_i32(ret, tcg_constant_i32(arg1), arg2);
376 }
377 }
378
tcg_gen_subi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)379 void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
380 {
381 tcg_gen_addi_i32(ret, arg1, -arg2);
382 }
383
tcg_gen_neg_i32(TCGv_i32 ret,TCGv_i32 arg)384 void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
385 {
386 tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
387 }
388
tcg_gen_and_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)389 void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
390 {
391 tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2);
392 }
393
tcg_gen_andi_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)394 void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
395 {
396 /* Some cases can be optimized here. */
397 switch (arg2) {
398 case 0:
399 tcg_gen_movi_i32(ret, 0);
400 return;
401 case -1:
402 tcg_gen_mov_i32(ret, arg1);
403 return;
404 case 0xff:
405 /* Don't recurse with tcg_gen_ext8u_i32. */
406 if (TCG_TARGET_HAS_ext8u_i32) {
407 tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
408 return;
409 }
410 break;
411 case 0xffff:
412 if (TCG_TARGET_HAS_ext16u_i32) {
413 tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
414 return;
415 }
416 break;
417 }
418
419 tcg_gen_and_i32(ret, arg1, tcg_constant_i32(arg2));
420 }
421
tcg_gen_or_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)422 void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
423 {
424 tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2);
425 }
426
tcg_gen_ori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)427 void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
428 {
429 /* Some cases can be optimized here. */
430 if (arg2 == -1) {
431 tcg_gen_movi_i32(ret, -1);
432 } else if (arg2 == 0) {
433 tcg_gen_mov_i32(ret, arg1);
434 } else {
435 tcg_gen_or_i32(ret, arg1, tcg_constant_i32(arg2));
436 }
437 }
438
tcg_gen_xor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)439 void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
440 {
441 tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2);
442 }
443
tcg_gen_xori_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)444 void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
445 {
446 /* Some cases can be optimized here. */
447 if (arg2 == 0) {
448 tcg_gen_mov_i32(ret, arg1);
449 } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
450 /* Don't recurse with tcg_gen_not_i32. */
451 tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
452 } else {
453 tcg_gen_xor_i32(ret, arg1, tcg_constant_i32(arg2));
454 }
455 }
456
tcg_gen_not_i32(TCGv_i32 ret,TCGv_i32 arg)457 void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
458 {
459 if (TCG_TARGET_HAS_not_i32) {
460 tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
461 } else {
462 tcg_gen_xori_i32(ret, arg, -1);
463 }
464 }
465
tcg_gen_shl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)466 void tcg_gen_shl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
467 {
468 tcg_gen_op3_i32(INDEX_op_shl_i32, ret, arg1, arg2);
469 }
470
tcg_gen_shli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)471 void tcg_gen_shli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
472 {
473 tcg_debug_assert(arg2 >= 0 && arg2 < 32);
474 if (arg2 == 0) {
475 tcg_gen_mov_i32(ret, arg1);
476 } else {
477 tcg_gen_shl_i32(ret, arg1, tcg_constant_i32(arg2));
478 }
479 }
480
tcg_gen_shr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)481 void tcg_gen_shr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
482 {
483 tcg_gen_op3_i32(INDEX_op_shr_i32, ret, arg1, arg2);
484 }
485
tcg_gen_shri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)486 void tcg_gen_shri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
487 {
488 tcg_debug_assert(arg2 >= 0 && arg2 < 32);
489 if (arg2 == 0) {
490 tcg_gen_mov_i32(ret, arg1);
491 } else {
492 tcg_gen_shr_i32(ret, arg1, tcg_constant_i32(arg2));
493 }
494 }
495
tcg_gen_sar_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)496 void tcg_gen_sar_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
497 {
498 tcg_gen_op3_i32(INDEX_op_sar_i32, ret, arg1, arg2);
499 }
500
tcg_gen_sari_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)501 void tcg_gen_sari_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
502 {
503 tcg_debug_assert(arg2 >= 0 && arg2 < 32);
504 if (arg2 == 0) {
505 tcg_gen_mov_i32(ret, arg1);
506 } else {
507 tcg_gen_sar_i32(ret, arg1, tcg_constant_i32(arg2));
508 }
509 }
510
tcg_gen_brcond_i32(TCGCond cond,TCGv_i32 arg1,TCGv_i32 arg2,TCGLabel * l)511 void tcg_gen_brcond_i32(TCGCond cond, TCGv_i32 arg1, TCGv_i32 arg2, TCGLabel *l)
512 {
513 if (cond == TCG_COND_ALWAYS) {
514 tcg_gen_br(l);
515 } else if (cond != TCG_COND_NEVER) {
516 TCGOp *op = tcg_gen_op4ii_i32(INDEX_op_brcond_i32,
517 arg1, arg2, cond, label_arg(l));
518 add_as_label_use(l, op);
519 }
520 }
521
tcg_gen_brcondi_i32(TCGCond cond,TCGv_i32 arg1,int32_t arg2,TCGLabel * l)522 void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, TCGLabel *l)
523 {
524 if (cond == TCG_COND_ALWAYS) {
525 tcg_gen_br(l);
526 } else if (cond != TCG_COND_NEVER) {
527 tcg_gen_brcond_i32(cond, arg1, tcg_constant_i32(arg2), l);
528 }
529 }
530
tcg_gen_setcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)531 void tcg_gen_setcond_i32(TCGCond cond, TCGv_i32 ret,
532 TCGv_i32 arg1, TCGv_i32 arg2)
533 {
534 if (cond == TCG_COND_ALWAYS) {
535 tcg_gen_movi_i32(ret, 1);
536 } else if (cond == TCG_COND_NEVER) {
537 tcg_gen_movi_i32(ret, 0);
538 } else {
539 tcg_gen_op4i_i32(INDEX_op_setcond_i32, ret, arg1, arg2, cond);
540 }
541 }
542
tcg_gen_setcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)543 void tcg_gen_setcondi_i32(TCGCond cond, TCGv_i32 ret,
544 TCGv_i32 arg1, int32_t arg2)
545 {
546 tcg_gen_setcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
547 }
548
tcg_gen_negsetcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)549 void tcg_gen_negsetcond_i32(TCGCond cond, TCGv_i32 ret,
550 TCGv_i32 arg1, TCGv_i32 arg2)
551 {
552 if (cond == TCG_COND_ALWAYS) {
553 tcg_gen_movi_i32(ret, -1);
554 } else if (cond == TCG_COND_NEVER) {
555 tcg_gen_movi_i32(ret, 0);
556 } else if (TCG_TARGET_HAS_negsetcond_i32) {
557 tcg_gen_op4i_i32(INDEX_op_negsetcond_i32, ret, arg1, arg2, cond);
558 } else {
559 tcg_gen_setcond_i32(cond, ret, arg1, arg2);
560 tcg_gen_neg_i32(ret, ret);
561 }
562 }
563
tcg_gen_negsetcondi_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)564 void tcg_gen_negsetcondi_i32(TCGCond cond, TCGv_i32 ret,
565 TCGv_i32 arg1, int32_t arg2)
566 {
567 tcg_gen_negsetcond_i32(cond, ret, arg1, tcg_constant_i32(arg2));
568 }
569
tcg_gen_mul_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)570 void tcg_gen_mul_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
571 {
572 tcg_gen_op3_i32(INDEX_op_mul_i32, ret, arg1, arg2);
573 }
574
tcg_gen_muli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)575 void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
576 {
577 if (arg2 == 0) {
578 tcg_gen_movi_i32(ret, 0);
579 } else if (is_power_of_2(arg2)) {
580 tcg_gen_shli_i32(ret, arg1, ctz32(arg2));
581 } else {
582 tcg_gen_mul_i32(ret, arg1, tcg_constant_i32(arg2));
583 }
584 }
585
tcg_gen_div_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)586 void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
587 {
588 if (TCG_TARGET_HAS_div_i32) {
589 tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
590 } else if (TCG_TARGET_HAS_div2_i32) {
591 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
592 tcg_gen_sari_i32(t0, arg1, 31);
593 tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
594 tcg_temp_free_i32(t0);
595 } else {
596 gen_helper_div_i32(ret, arg1, arg2);
597 }
598 }
599
tcg_gen_rem_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)600 void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
601 {
602 if (TCG_TARGET_HAS_rem_i32) {
603 tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
604 } else if (TCG_TARGET_HAS_div_i32) {
605 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
606 tcg_gen_op3_i32(INDEX_op_div_i32, t0, arg1, arg2);
607 tcg_gen_mul_i32(t0, t0, arg2);
608 tcg_gen_sub_i32(ret, arg1, t0);
609 tcg_temp_free_i32(t0);
610 } else if (TCG_TARGET_HAS_div2_i32) {
611 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
612 tcg_gen_sari_i32(t0, arg1, 31);
613 tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
614 tcg_temp_free_i32(t0);
615 } else {
616 gen_helper_rem_i32(ret, arg1, arg2);
617 }
618 }
619
tcg_gen_divu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)620 void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
621 {
622 if (TCG_TARGET_HAS_div_i32) {
623 tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
624 } else if (TCG_TARGET_HAS_div2_i32) {
625 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
626 TCGv_i32 zero = tcg_constant_i32(0);
627 tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, zero, arg2);
628 tcg_temp_free_i32(t0);
629 } else {
630 gen_helper_divu_i32(ret, arg1, arg2);
631 }
632 }
633
tcg_gen_remu_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)634 void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
635 {
636 if (TCG_TARGET_HAS_rem_i32) {
637 tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
638 } else if (TCG_TARGET_HAS_div_i32) {
639 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
640 tcg_gen_op3_i32(INDEX_op_divu_i32, t0, arg1, arg2);
641 tcg_gen_mul_i32(t0, t0, arg2);
642 tcg_gen_sub_i32(ret, arg1, t0);
643 tcg_temp_free_i32(t0);
644 } else if (TCG_TARGET_HAS_div2_i32) {
645 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
646 TCGv_i32 zero = tcg_constant_i32(0);
647 tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, zero, arg2);
648 tcg_temp_free_i32(t0);
649 } else {
650 gen_helper_remu_i32(ret, arg1, arg2);
651 }
652 }
653
tcg_gen_andc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)654 void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
655 {
656 if (TCG_TARGET_HAS_andc_i32) {
657 tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
658 } else {
659 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
660 tcg_gen_not_i32(t0, arg2);
661 tcg_gen_and_i32(ret, arg1, t0);
662 tcg_temp_free_i32(t0);
663 }
664 }
665
tcg_gen_eqv_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)666 void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
667 {
668 if (TCG_TARGET_HAS_eqv_i32) {
669 tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
670 } else {
671 tcg_gen_xor_i32(ret, arg1, arg2);
672 tcg_gen_not_i32(ret, ret);
673 }
674 }
675
tcg_gen_nand_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)676 void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
677 {
678 if (TCG_TARGET_HAS_nand_i32) {
679 tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
680 } else {
681 tcg_gen_and_i32(ret, arg1, arg2);
682 tcg_gen_not_i32(ret, ret);
683 }
684 }
685
tcg_gen_nor_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)686 void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
687 {
688 if (TCG_TARGET_HAS_nor_i32) {
689 tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
690 } else {
691 tcg_gen_or_i32(ret, arg1, arg2);
692 tcg_gen_not_i32(ret, ret);
693 }
694 }
695
tcg_gen_orc_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)696 void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
697 {
698 if (TCG_TARGET_HAS_orc_i32) {
699 tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
700 } else {
701 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
702 tcg_gen_not_i32(t0, arg2);
703 tcg_gen_or_i32(ret, arg1, t0);
704 tcg_temp_free_i32(t0);
705 }
706 }
707
tcg_gen_clz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)708 void tcg_gen_clz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
709 {
710 if (TCG_TARGET_HAS_clz_i32) {
711 tcg_gen_op3_i32(INDEX_op_clz_i32, ret, arg1, arg2);
712 } else if (TCG_TARGET_HAS_clz_i64) {
713 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
714 TCGv_i64 t2 = tcg_temp_ebb_new_i64();
715 tcg_gen_extu_i32_i64(t1, arg1);
716 tcg_gen_extu_i32_i64(t2, arg2);
717 tcg_gen_addi_i64(t2, t2, 32);
718 tcg_gen_clz_i64(t1, t1, t2);
719 tcg_gen_extrl_i64_i32(ret, t1);
720 tcg_temp_free_i64(t1);
721 tcg_temp_free_i64(t2);
722 tcg_gen_subi_i32(ret, ret, 32);
723 } else {
724 gen_helper_clz_i32(ret, arg1, arg2);
725 }
726 }
727
tcg_gen_clzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)728 void tcg_gen_clzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
729 {
730 tcg_gen_clz_i32(ret, arg1, tcg_constant_i32(arg2));
731 }
732
tcg_gen_ctz_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)733 void tcg_gen_ctz_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
734 {
735 if (TCG_TARGET_HAS_ctz_i32) {
736 tcg_gen_op3_i32(INDEX_op_ctz_i32, ret, arg1, arg2);
737 } else if (TCG_TARGET_HAS_ctz_i64) {
738 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
739 TCGv_i64 t2 = tcg_temp_ebb_new_i64();
740 tcg_gen_extu_i32_i64(t1, arg1);
741 tcg_gen_extu_i32_i64(t2, arg2);
742 tcg_gen_ctz_i64(t1, t1, t2);
743 tcg_gen_extrl_i64_i32(ret, t1);
744 tcg_temp_free_i64(t1);
745 tcg_temp_free_i64(t2);
746 } else if (TCG_TARGET_HAS_ctpop_i32
747 || TCG_TARGET_HAS_ctpop_i64
748 || TCG_TARGET_HAS_clz_i32
749 || TCG_TARGET_HAS_clz_i64) {
750 TCGv_i32 z, t = tcg_temp_ebb_new_i32();
751
752 if (TCG_TARGET_HAS_ctpop_i32 || TCG_TARGET_HAS_ctpop_i64) {
753 tcg_gen_subi_i32(t, arg1, 1);
754 tcg_gen_andc_i32(t, t, arg1);
755 tcg_gen_ctpop_i32(t, t);
756 } else {
757 /* Since all non-x86 hosts have clz(0) == 32, don't fight it. */
758 tcg_gen_neg_i32(t, arg1);
759 tcg_gen_and_i32(t, t, arg1);
760 tcg_gen_clzi_i32(t, t, 32);
761 tcg_gen_xori_i32(t, t, 31);
762 }
763 z = tcg_constant_i32(0);
764 tcg_gen_movcond_i32(TCG_COND_EQ, ret, arg1, z, arg2, t);
765 tcg_temp_free_i32(t);
766 } else {
767 gen_helper_ctz_i32(ret, arg1, arg2);
768 }
769 }
770
tcg_gen_ctzi_i32(TCGv_i32 ret,TCGv_i32 arg1,uint32_t arg2)771 void tcg_gen_ctzi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
772 {
773 if (!TCG_TARGET_HAS_ctz_i32 && TCG_TARGET_HAS_ctpop_i32 && arg2 == 32) {
774 /* This equivalence has the advantage of not requiring a fixup. */
775 TCGv_i32 t = tcg_temp_ebb_new_i32();
776 tcg_gen_subi_i32(t, arg1, 1);
777 tcg_gen_andc_i32(t, t, arg1);
778 tcg_gen_ctpop_i32(ret, t);
779 tcg_temp_free_i32(t);
780 } else {
781 tcg_gen_ctz_i32(ret, arg1, tcg_constant_i32(arg2));
782 }
783 }
784
tcg_gen_clrsb_i32(TCGv_i32 ret,TCGv_i32 arg)785 void tcg_gen_clrsb_i32(TCGv_i32 ret, TCGv_i32 arg)
786 {
787 if (TCG_TARGET_HAS_clz_i32) {
788 TCGv_i32 t = tcg_temp_ebb_new_i32();
789 tcg_gen_sari_i32(t, arg, 31);
790 tcg_gen_xor_i32(t, t, arg);
791 tcg_gen_clzi_i32(t, t, 32);
792 tcg_gen_subi_i32(ret, t, 1);
793 tcg_temp_free_i32(t);
794 } else {
795 gen_helper_clrsb_i32(ret, arg);
796 }
797 }
798
tcg_gen_ctpop_i32(TCGv_i32 ret,TCGv_i32 arg1)799 void tcg_gen_ctpop_i32(TCGv_i32 ret, TCGv_i32 arg1)
800 {
801 if (TCG_TARGET_HAS_ctpop_i32) {
802 tcg_gen_op2_i32(INDEX_op_ctpop_i32, ret, arg1);
803 } else if (TCG_TARGET_HAS_ctpop_i64) {
804 TCGv_i64 t = tcg_temp_ebb_new_i64();
805 tcg_gen_extu_i32_i64(t, arg1);
806 tcg_gen_ctpop_i64(t, t);
807 tcg_gen_extrl_i64_i32(ret, t);
808 tcg_temp_free_i64(t);
809 } else {
810 gen_helper_ctpop_i32(ret, arg1);
811 }
812 }
813
tcg_gen_rotl_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)814 void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
815 {
816 if (TCG_TARGET_HAS_rot_i32) {
817 tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
818 } else {
819 TCGv_i32 t0, t1;
820
821 t0 = tcg_temp_ebb_new_i32();
822 t1 = tcg_temp_ebb_new_i32();
823 tcg_gen_shl_i32(t0, arg1, arg2);
824 tcg_gen_subfi_i32(t1, 32, arg2);
825 tcg_gen_shr_i32(t1, arg1, t1);
826 tcg_gen_or_i32(ret, t0, t1);
827 tcg_temp_free_i32(t0);
828 tcg_temp_free_i32(t1);
829 }
830 }
831
tcg_gen_rotli_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)832 void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
833 {
834 tcg_debug_assert(arg2 >= 0 && arg2 < 32);
835 /* some cases can be optimized here */
836 if (arg2 == 0) {
837 tcg_gen_mov_i32(ret, arg1);
838 } else if (TCG_TARGET_HAS_rot_i32) {
839 tcg_gen_rotl_i32(ret, arg1, tcg_constant_i32(arg2));
840 } else {
841 TCGv_i32 t0, t1;
842 t0 = tcg_temp_ebb_new_i32();
843 t1 = tcg_temp_ebb_new_i32();
844 tcg_gen_shli_i32(t0, arg1, arg2);
845 tcg_gen_shri_i32(t1, arg1, 32 - arg2);
846 tcg_gen_or_i32(ret, t0, t1);
847 tcg_temp_free_i32(t0);
848 tcg_temp_free_i32(t1);
849 }
850 }
851
tcg_gen_rotr_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2)852 void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
853 {
854 if (TCG_TARGET_HAS_rot_i32) {
855 tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
856 } else {
857 TCGv_i32 t0, t1;
858
859 t0 = tcg_temp_ebb_new_i32();
860 t1 = tcg_temp_ebb_new_i32();
861 tcg_gen_shr_i32(t0, arg1, arg2);
862 tcg_gen_subfi_i32(t1, 32, arg2);
863 tcg_gen_shl_i32(t1, arg1, t1);
864 tcg_gen_or_i32(ret, t0, t1);
865 tcg_temp_free_i32(t0);
866 tcg_temp_free_i32(t1);
867 }
868 }
869
tcg_gen_rotri_i32(TCGv_i32 ret,TCGv_i32 arg1,int32_t arg2)870 void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
871 {
872 tcg_debug_assert(arg2 >= 0 && arg2 < 32);
873 /* some cases can be optimized here */
874 if (arg2 == 0) {
875 tcg_gen_mov_i32(ret, arg1);
876 } else {
877 tcg_gen_rotli_i32(ret, arg1, 32 - arg2);
878 }
879 }
880
tcg_gen_deposit_i32(TCGv_i32 ret,TCGv_i32 arg1,TCGv_i32 arg2,unsigned int ofs,unsigned int len)881 void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2,
882 unsigned int ofs, unsigned int len)
883 {
884 uint32_t mask;
885 TCGv_i32 t1;
886
887 tcg_debug_assert(ofs < 32);
888 tcg_debug_assert(len > 0);
889 tcg_debug_assert(len <= 32);
890 tcg_debug_assert(ofs + len <= 32);
891
892 if (len == 32) {
893 tcg_gen_mov_i32(ret, arg2);
894 return;
895 }
896 if (TCG_TARGET_HAS_deposit_i32 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
897 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
898 return;
899 }
900
901 t1 = tcg_temp_ebb_new_i32();
902
903 if (TCG_TARGET_HAS_extract2_i32) {
904 if (ofs + len == 32) {
905 tcg_gen_shli_i32(t1, arg1, len);
906 tcg_gen_extract2_i32(ret, t1, arg2, len);
907 goto done;
908 }
909 if (ofs == 0) {
910 tcg_gen_extract2_i32(ret, arg1, arg2, len);
911 tcg_gen_rotli_i32(ret, ret, len);
912 goto done;
913 }
914 }
915
916 mask = (1u << len) - 1;
917 if (ofs + len < 32) {
918 tcg_gen_andi_i32(t1, arg2, mask);
919 tcg_gen_shli_i32(t1, t1, ofs);
920 } else {
921 tcg_gen_shli_i32(t1, arg2, ofs);
922 }
923 tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
924 tcg_gen_or_i32(ret, ret, t1);
925 done:
926 tcg_temp_free_i32(t1);
927 }
928
tcg_gen_deposit_z_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)929 void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
930 unsigned int ofs, unsigned int len)
931 {
932 tcg_debug_assert(ofs < 32);
933 tcg_debug_assert(len > 0);
934 tcg_debug_assert(len <= 32);
935 tcg_debug_assert(ofs + len <= 32);
936
937 if (ofs + len == 32) {
938 tcg_gen_shli_i32(ret, arg, ofs);
939 } else if (ofs == 0) {
940 tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
941 } else if (TCG_TARGET_HAS_deposit_i32
942 && TCG_TARGET_deposit_i32_valid(ofs, len)) {
943 TCGv_i32 zero = tcg_constant_i32(0);
944 tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
945 } else {
946 /* To help two-operand hosts we prefer to zero-extend first,
947 which allows ARG to stay live. */
948 switch (len) {
949 case 16:
950 if (TCG_TARGET_HAS_ext16u_i32) {
951 tcg_gen_ext16u_i32(ret, arg);
952 tcg_gen_shli_i32(ret, ret, ofs);
953 return;
954 }
955 break;
956 case 8:
957 if (TCG_TARGET_HAS_ext8u_i32) {
958 tcg_gen_ext8u_i32(ret, arg);
959 tcg_gen_shli_i32(ret, ret, ofs);
960 return;
961 }
962 break;
963 }
964 /* Otherwise prefer zero-extension over AND for code size. */
965 switch (ofs + len) {
966 case 16:
967 if (TCG_TARGET_HAS_ext16u_i32) {
968 tcg_gen_shli_i32(ret, arg, ofs);
969 tcg_gen_ext16u_i32(ret, ret);
970 return;
971 }
972 break;
973 case 8:
974 if (TCG_TARGET_HAS_ext8u_i32) {
975 tcg_gen_shli_i32(ret, arg, ofs);
976 tcg_gen_ext8u_i32(ret, ret);
977 return;
978 }
979 break;
980 }
981 tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
982 tcg_gen_shli_i32(ret, ret, ofs);
983 }
984 }
985
tcg_gen_extract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)986 void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
987 unsigned int ofs, unsigned int len)
988 {
989 tcg_debug_assert(ofs < 32);
990 tcg_debug_assert(len > 0);
991 tcg_debug_assert(len <= 32);
992 tcg_debug_assert(ofs + len <= 32);
993
994 /* Canonicalize certain special cases, even if extract is supported. */
995 if (ofs + len == 32) {
996 tcg_gen_shri_i32(ret, arg, 32 - len);
997 return;
998 }
999 if (ofs == 0) {
1000 tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
1001 return;
1002 }
1003
1004 if (TCG_TARGET_HAS_extract_i32
1005 && TCG_TARGET_extract_i32_valid(ofs, len)) {
1006 tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
1007 return;
1008 }
1009
1010 /* Assume that zero-extension, if available, is cheaper than a shift. */
1011 switch (ofs + len) {
1012 case 16:
1013 if (TCG_TARGET_HAS_ext16u_i32) {
1014 tcg_gen_ext16u_i32(ret, arg);
1015 tcg_gen_shri_i32(ret, ret, ofs);
1016 return;
1017 }
1018 break;
1019 case 8:
1020 if (TCG_TARGET_HAS_ext8u_i32) {
1021 tcg_gen_ext8u_i32(ret, arg);
1022 tcg_gen_shri_i32(ret, ret, ofs);
1023 return;
1024 }
1025 break;
1026 }
1027
1028 /* ??? Ideally we'd know what values are available for immediate AND.
1029 Assume that 8 bits are available, plus the special case of 16,
1030 so that we get ext8u, ext16u. */
1031 switch (len) {
1032 case 1 ... 8: case 16:
1033 tcg_gen_shri_i32(ret, arg, ofs);
1034 tcg_gen_andi_i32(ret, ret, (1u << len) - 1);
1035 break;
1036 default:
1037 tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
1038 tcg_gen_shri_i32(ret, ret, 32 - len);
1039 break;
1040 }
1041 }
1042
tcg_gen_sextract_i32(TCGv_i32 ret,TCGv_i32 arg,unsigned int ofs,unsigned int len)1043 void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
1044 unsigned int ofs, unsigned int len)
1045 {
1046 tcg_debug_assert(ofs < 32);
1047 tcg_debug_assert(len > 0);
1048 tcg_debug_assert(len <= 32);
1049 tcg_debug_assert(ofs + len <= 32);
1050
1051 /* Canonicalize certain special cases, even if extract is supported. */
1052 if (ofs + len == 32) {
1053 tcg_gen_sari_i32(ret, arg, 32 - len);
1054 return;
1055 }
1056 if (ofs == 0) {
1057 switch (len) {
1058 case 16:
1059 tcg_gen_ext16s_i32(ret, arg);
1060 return;
1061 case 8:
1062 tcg_gen_ext8s_i32(ret, arg);
1063 return;
1064 }
1065 }
1066
1067 if (TCG_TARGET_HAS_sextract_i32
1068 && TCG_TARGET_extract_i32_valid(ofs, len)) {
1069 tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
1070 return;
1071 }
1072
1073 /* Assume that sign-extension, if available, is cheaper than a shift. */
1074 switch (ofs + len) {
1075 case 16:
1076 if (TCG_TARGET_HAS_ext16s_i32) {
1077 tcg_gen_ext16s_i32(ret, arg);
1078 tcg_gen_sari_i32(ret, ret, ofs);
1079 return;
1080 }
1081 break;
1082 case 8:
1083 if (TCG_TARGET_HAS_ext8s_i32) {
1084 tcg_gen_ext8s_i32(ret, arg);
1085 tcg_gen_sari_i32(ret, ret, ofs);
1086 return;
1087 }
1088 break;
1089 }
1090 switch (len) {
1091 case 16:
1092 if (TCG_TARGET_HAS_ext16s_i32) {
1093 tcg_gen_shri_i32(ret, arg, ofs);
1094 tcg_gen_ext16s_i32(ret, ret);
1095 return;
1096 }
1097 break;
1098 case 8:
1099 if (TCG_TARGET_HAS_ext8s_i32) {
1100 tcg_gen_shri_i32(ret, arg, ofs);
1101 tcg_gen_ext8s_i32(ret, ret);
1102 return;
1103 }
1104 break;
1105 }
1106
1107 tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
1108 tcg_gen_sari_i32(ret, ret, 32 - len);
1109 }
1110
1111 /*
1112 * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
1113 * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
1114 */
tcg_gen_extract2_i32(TCGv_i32 ret,TCGv_i32 al,TCGv_i32 ah,unsigned int ofs)1115 void tcg_gen_extract2_i32(TCGv_i32 ret, TCGv_i32 al, TCGv_i32 ah,
1116 unsigned int ofs)
1117 {
1118 tcg_debug_assert(ofs <= 32);
1119 if (ofs == 0) {
1120 tcg_gen_mov_i32(ret, al);
1121 } else if (ofs == 32) {
1122 tcg_gen_mov_i32(ret, ah);
1123 } else if (al == ah) {
1124 tcg_gen_rotri_i32(ret, al, ofs);
1125 } else if (TCG_TARGET_HAS_extract2_i32) {
1126 tcg_gen_op4i_i32(INDEX_op_extract2_i32, ret, al, ah, ofs);
1127 } else {
1128 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1129 tcg_gen_shri_i32(t0, al, ofs);
1130 tcg_gen_deposit_i32(ret, t0, ah, 32 - ofs, ofs);
1131 tcg_temp_free_i32(t0);
1132 }
1133 }
1134
tcg_gen_movcond_i32(TCGCond cond,TCGv_i32 ret,TCGv_i32 c1,TCGv_i32 c2,TCGv_i32 v1,TCGv_i32 v2)1135 void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret, TCGv_i32 c1,
1136 TCGv_i32 c2, TCGv_i32 v1, TCGv_i32 v2)
1137 {
1138 if (cond == TCG_COND_ALWAYS) {
1139 tcg_gen_mov_i32(ret, v1);
1140 } else if (cond == TCG_COND_NEVER) {
1141 tcg_gen_mov_i32(ret, v2);
1142 } else {
1143 tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
1144 }
1145 }
1146
tcg_gen_add2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1147 void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1148 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1149 {
1150 if (TCG_TARGET_HAS_add2_i32) {
1151 tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
1152 } else {
1153 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1154 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1155 tcg_gen_concat_i32_i64(t0, al, ah);
1156 tcg_gen_concat_i32_i64(t1, bl, bh);
1157 tcg_gen_add_i64(t0, t0, t1);
1158 tcg_gen_extr_i64_i32(rl, rh, t0);
1159 tcg_temp_free_i64(t0);
1160 tcg_temp_free_i64(t1);
1161 }
1162 }
1163
tcg_gen_sub2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 al,TCGv_i32 ah,TCGv_i32 bl,TCGv_i32 bh)1164 void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
1165 TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
1166 {
1167 if (TCG_TARGET_HAS_sub2_i32) {
1168 tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
1169 } else {
1170 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1171 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1172 tcg_gen_concat_i32_i64(t0, al, ah);
1173 tcg_gen_concat_i32_i64(t1, bl, bh);
1174 tcg_gen_sub_i64(t0, t0, t1);
1175 tcg_gen_extr_i64_i32(rl, rh, t0);
1176 tcg_temp_free_i64(t0);
1177 tcg_temp_free_i64(t1);
1178 }
1179 }
1180
tcg_gen_mulu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1181 void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1182 {
1183 if (TCG_TARGET_HAS_mulu2_i32) {
1184 tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
1185 } else if (TCG_TARGET_HAS_muluh_i32) {
1186 TCGv_i32 t = tcg_temp_ebb_new_i32();
1187 tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1188 tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
1189 tcg_gen_mov_i32(rl, t);
1190 tcg_temp_free_i32(t);
1191 } else if (TCG_TARGET_REG_BITS == 64) {
1192 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1193 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1194 tcg_gen_extu_i32_i64(t0, arg1);
1195 tcg_gen_extu_i32_i64(t1, arg2);
1196 tcg_gen_mul_i64(t0, t0, t1);
1197 tcg_gen_extr_i64_i32(rl, rh, t0);
1198 tcg_temp_free_i64(t0);
1199 tcg_temp_free_i64(t1);
1200 } else {
1201 qemu_build_not_reached();
1202 }
1203 }
1204
tcg_gen_muls2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1205 void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1206 {
1207 if (TCG_TARGET_HAS_muls2_i32) {
1208 tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
1209 } else if (TCG_TARGET_HAS_mulsh_i32) {
1210 TCGv_i32 t = tcg_temp_ebb_new_i32();
1211 tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
1212 tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
1213 tcg_gen_mov_i32(rl, t);
1214 tcg_temp_free_i32(t);
1215 } else if (TCG_TARGET_REG_BITS == 32) {
1216 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1217 TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1218 TCGv_i32 t2 = tcg_temp_ebb_new_i32();
1219 TCGv_i32 t3 = tcg_temp_ebb_new_i32();
1220 tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
1221 /* Adjust for negative inputs. */
1222 tcg_gen_sari_i32(t2, arg1, 31);
1223 tcg_gen_sari_i32(t3, arg2, 31);
1224 tcg_gen_and_i32(t2, t2, arg2);
1225 tcg_gen_and_i32(t3, t3, arg1);
1226 tcg_gen_sub_i32(rh, t1, t2);
1227 tcg_gen_sub_i32(rh, rh, t3);
1228 tcg_gen_mov_i32(rl, t0);
1229 tcg_temp_free_i32(t0);
1230 tcg_temp_free_i32(t1);
1231 tcg_temp_free_i32(t2);
1232 tcg_temp_free_i32(t3);
1233 } else {
1234 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1235 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1236 tcg_gen_ext_i32_i64(t0, arg1);
1237 tcg_gen_ext_i32_i64(t1, arg2);
1238 tcg_gen_mul_i64(t0, t0, t1);
1239 tcg_gen_extr_i64_i32(rl, rh, t0);
1240 tcg_temp_free_i64(t0);
1241 tcg_temp_free_i64(t1);
1242 }
1243 }
1244
tcg_gen_mulsu2_i32(TCGv_i32 rl,TCGv_i32 rh,TCGv_i32 arg1,TCGv_i32 arg2)1245 void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
1246 {
1247 if (TCG_TARGET_REG_BITS == 32) {
1248 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1249 TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1250 TCGv_i32 t2 = tcg_temp_ebb_new_i32();
1251 tcg_gen_mulu2_i32(t0, t1, arg1, arg2);
1252 /* Adjust for negative input for the signed arg1. */
1253 tcg_gen_sari_i32(t2, arg1, 31);
1254 tcg_gen_and_i32(t2, t2, arg2);
1255 tcg_gen_sub_i32(rh, t1, t2);
1256 tcg_gen_mov_i32(rl, t0);
1257 tcg_temp_free_i32(t0);
1258 tcg_temp_free_i32(t1);
1259 tcg_temp_free_i32(t2);
1260 } else {
1261 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
1262 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
1263 tcg_gen_ext_i32_i64(t0, arg1);
1264 tcg_gen_extu_i32_i64(t1, arg2);
1265 tcg_gen_mul_i64(t0, t0, t1);
1266 tcg_gen_extr_i64_i32(rl, rh, t0);
1267 tcg_temp_free_i64(t0);
1268 tcg_temp_free_i64(t1);
1269 }
1270 }
1271
tcg_gen_ext8s_i32(TCGv_i32 ret,TCGv_i32 arg)1272 void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
1273 {
1274 if (TCG_TARGET_HAS_ext8s_i32) {
1275 tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
1276 } else {
1277 tcg_gen_shli_i32(ret, arg, 24);
1278 tcg_gen_sari_i32(ret, ret, 24);
1279 }
1280 }
1281
tcg_gen_ext16s_i32(TCGv_i32 ret,TCGv_i32 arg)1282 void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
1283 {
1284 if (TCG_TARGET_HAS_ext16s_i32) {
1285 tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
1286 } else {
1287 tcg_gen_shli_i32(ret, arg, 16);
1288 tcg_gen_sari_i32(ret, ret, 16);
1289 }
1290 }
1291
tcg_gen_ext8u_i32(TCGv_i32 ret,TCGv_i32 arg)1292 void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
1293 {
1294 if (TCG_TARGET_HAS_ext8u_i32) {
1295 tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
1296 } else {
1297 tcg_gen_andi_i32(ret, arg, 0xffu);
1298 }
1299 }
1300
tcg_gen_ext16u_i32(TCGv_i32 ret,TCGv_i32 arg)1301 void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
1302 {
1303 if (TCG_TARGET_HAS_ext16u_i32) {
1304 tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
1305 } else {
1306 tcg_gen_andi_i32(ret, arg, 0xffffu);
1307 }
1308 }
1309
1310 /*
1311 * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value.
1312 *
1313 * Byte pattern: xxab -> yyba
1314 *
1315 * With TCG_BSWAP_IZ, x == zero, else undefined.
1316 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
1317 */
tcg_gen_bswap16_i32(TCGv_i32 ret,TCGv_i32 arg,int flags)1318 void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg, int flags)
1319 {
1320 /* Only one extension flag may be present. */
1321 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
1322
1323 if (TCG_TARGET_HAS_bswap16_i32) {
1324 tcg_gen_op3i_i32(INDEX_op_bswap16_i32, ret, arg, flags);
1325 } else {
1326 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1327 TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1328
1329 /* arg = ..ab (IZ) xxab (!IZ) */
1330 tcg_gen_shri_i32(t0, arg, 8); /* t0 = ...a (IZ) .xxa (!IZ) */
1331 if (!(flags & TCG_BSWAP_IZ)) {
1332 tcg_gen_ext8u_i32(t0, t0); /* t0 = ...a */
1333 }
1334
1335 if (flags & TCG_BSWAP_OS) {
1336 tcg_gen_shli_i32(t1, arg, 24); /* t1 = b... */
1337 tcg_gen_sari_i32(t1, t1, 16); /* t1 = ssb. */
1338 } else if (flags & TCG_BSWAP_OZ) {
1339 tcg_gen_ext8u_i32(t1, arg); /* t1 = ...b */
1340 tcg_gen_shli_i32(t1, t1, 8); /* t1 = ..b. */
1341 } else {
1342 tcg_gen_shli_i32(t1, arg, 8); /* t1 = xab. */
1343 }
1344
1345 tcg_gen_or_i32(ret, t0, t1); /* ret = ..ba (OZ) */
1346 /* = ssba (OS) */
1347 /* = xaba (no flag) */
1348 tcg_temp_free_i32(t0);
1349 tcg_temp_free_i32(t1);
1350 }
1351 }
1352
1353 /*
1354 * bswap32_i32: 32-bit byte swap on a 32-bit value.
1355 *
1356 * Byte pattern: abcd -> dcba
1357 */
tcg_gen_bswap32_i32(TCGv_i32 ret,TCGv_i32 arg)1358 void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
1359 {
1360 if (TCG_TARGET_HAS_bswap32_i32) {
1361 tcg_gen_op3i_i32(INDEX_op_bswap32_i32, ret, arg, 0);
1362 } else {
1363 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1364 TCGv_i32 t1 = tcg_temp_ebb_new_i32();
1365 TCGv_i32 t2 = tcg_constant_i32(0x00ff00ff);
1366
1367 /* arg = abcd */
1368 tcg_gen_shri_i32(t0, arg, 8); /* t0 = .abc */
1369 tcg_gen_and_i32(t1, arg, t2); /* t1 = .b.d */
1370 tcg_gen_and_i32(t0, t0, t2); /* t0 = .a.c */
1371 tcg_gen_shli_i32(t1, t1, 8); /* t1 = b.d. */
1372 tcg_gen_or_i32(ret, t0, t1); /* ret = badc */
1373
1374 tcg_gen_shri_i32(t0, ret, 16); /* t0 = ..ba */
1375 tcg_gen_shli_i32(t1, ret, 16); /* t1 = dc.. */
1376 tcg_gen_or_i32(ret, t0, t1); /* ret = dcba */
1377
1378 tcg_temp_free_i32(t0);
1379 tcg_temp_free_i32(t1);
1380 }
1381 }
1382
1383 /*
1384 * hswap_i32: Swap 16-bit halfwords within a 32-bit value.
1385 *
1386 * Byte pattern: abcd -> cdab
1387 */
tcg_gen_hswap_i32(TCGv_i32 ret,TCGv_i32 arg)1388 void tcg_gen_hswap_i32(TCGv_i32 ret, TCGv_i32 arg)
1389 {
1390 /* Swapping 2 16-bit elements is a rotate. */
1391 tcg_gen_rotli_i32(ret, arg, 16);
1392 }
1393
tcg_gen_smin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1394 void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1395 {
1396 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
1397 }
1398
tcg_gen_umin_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1399 void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1400 {
1401 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
1402 }
1403
tcg_gen_smax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1404 void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1405 {
1406 tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
1407 }
1408
tcg_gen_umax_i32(TCGv_i32 ret,TCGv_i32 a,TCGv_i32 b)1409 void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
1410 {
1411 tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
1412 }
1413
tcg_gen_abs_i32(TCGv_i32 ret,TCGv_i32 a)1414 void tcg_gen_abs_i32(TCGv_i32 ret, TCGv_i32 a)
1415 {
1416 TCGv_i32 t = tcg_temp_ebb_new_i32();
1417
1418 tcg_gen_sari_i32(t, a, 31);
1419 tcg_gen_xor_i32(ret, a, t);
1420 tcg_gen_sub_i32(ret, ret, t);
1421 tcg_temp_free_i32(t);
1422 }
1423
tcg_gen_ld8u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)1424 void tcg_gen_ld8u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
1425 {
1426 tcg_gen_ldst_op_i32(INDEX_op_ld8u_i32, ret, arg2, offset);
1427 }
1428
tcg_gen_ld8s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)1429 void tcg_gen_ld8s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
1430 {
1431 tcg_gen_ldst_op_i32(INDEX_op_ld8s_i32, ret, arg2, offset);
1432 }
1433
tcg_gen_ld16u_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)1434 void tcg_gen_ld16u_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
1435 {
1436 tcg_gen_ldst_op_i32(INDEX_op_ld16u_i32, ret, arg2, offset);
1437 }
1438
tcg_gen_ld16s_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)1439 void tcg_gen_ld16s_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
1440 {
1441 tcg_gen_ldst_op_i32(INDEX_op_ld16s_i32, ret, arg2, offset);
1442 }
1443
tcg_gen_ld_i32(TCGv_i32 ret,TCGv_ptr arg2,tcg_target_long offset)1444 void tcg_gen_ld_i32(TCGv_i32 ret, TCGv_ptr arg2, tcg_target_long offset)
1445 {
1446 tcg_gen_ldst_op_i32(INDEX_op_ld_i32, ret, arg2, offset);
1447 }
1448
tcg_gen_st8_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)1449 void tcg_gen_st8_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
1450 {
1451 tcg_gen_ldst_op_i32(INDEX_op_st8_i32, arg1, arg2, offset);
1452 }
1453
tcg_gen_st16_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)1454 void tcg_gen_st16_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
1455 {
1456 tcg_gen_ldst_op_i32(INDEX_op_st16_i32, arg1, arg2, offset);
1457 }
1458
tcg_gen_st_i32(TCGv_i32 arg1,TCGv_ptr arg2,tcg_target_long offset)1459 void tcg_gen_st_i32(TCGv_i32 arg1, TCGv_ptr arg2, tcg_target_long offset)
1460 {
1461 tcg_gen_ldst_op_i32(INDEX_op_st_i32, arg1, arg2, offset);
1462 }
1463
1464
1465 /* 64-bit ops */
1466
tcg_gen_discard_i64(TCGv_i64 arg)1467 void tcg_gen_discard_i64(TCGv_i64 arg)
1468 {
1469 if (TCG_TARGET_REG_BITS == 64) {
1470 tcg_gen_op1_i64(INDEX_op_discard, arg);
1471 } else {
1472 tcg_gen_discard_i32(TCGV_LOW(arg));
1473 tcg_gen_discard_i32(TCGV_HIGH(arg));
1474 }
1475 }
1476
tcg_gen_mov_i64(TCGv_i64 ret,TCGv_i64 arg)1477 void tcg_gen_mov_i64(TCGv_i64 ret, TCGv_i64 arg)
1478 {
1479 if (ret == arg) {
1480 return;
1481 }
1482 if (TCG_TARGET_REG_BITS == 64) {
1483 tcg_gen_op2_i64(INDEX_op_mov_i64, ret, arg);
1484 } else {
1485 TCGTemp *ts = tcgv_i64_temp(arg);
1486
1487 /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
1488 if (ts->kind == TEMP_CONST) {
1489 tcg_gen_movi_i64(ret, ts->val);
1490 } else {
1491 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
1492 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
1493 }
1494 }
1495 }
1496
tcg_gen_movi_i64(TCGv_i64 ret,int64_t arg)1497 void tcg_gen_movi_i64(TCGv_i64 ret, int64_t arg)
1498 {
1499 if (TCG_TARGET_REG_BITS == 64) {
1500 tcg_gen_mov_i64(ret, tcg_constant_i64(arg));
1501 } else {
1502 tcg_gen_movi_i32(TCGV_LOW(ret), arg);
1503 tcg_gen_movi_i32(TCGV_HIGH(ret), arg >> 32);
1504 }
1505 }
1506
tcg_gen_ld8u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1507 void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1508 {
1509 if (TCG_TARGET_REG_BITS == 64) {
1510 tcg_gen_ldst_op_i64(INDEX_op_ld8u_i64, ret, arg2, offset);
1511 } else {
1512 tcg_gen_ld8u_i32(TCGV_LOW(ret), arg2, offset);
1513 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1514 }
1515 }
1516
tcg_gen_ld8s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1517 void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1518 {
1519 if (TCG_TARGET_REG_BITS == 64) {
1520 tcg_gen_ldst_op_i64(INDEX_op_ld8s_i64, ret, arg2, offset);
1521 } else {
1522 tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset);
1523 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1524 }
1525 }
1526
tcg_gen_ld16u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1527 void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1528 {
1529 if (TCG_TARGET_REG_BITS == 64) {
1530 tcg_gen_ldst_op_i64(INDEX_op_ld16u_i64, ret, arg2, offset);
1531 } else {
1532 tcg_gen_ld16u_i32(TCGV_LOW(ret), arg2, offset);
1533 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1534 }
1535 }
1536
tcg_gen_ld16s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1537 void tcg_gen_ld16s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1538 {
1539 if (TCG_TARGET_REG_BITS == 64) {
1540 tcg_gen_ldst_op_i64(INDEX_op_ld16s_i64, ret, arg2, offset);
1541 } else {
1542 tcg_gen_ld16s_i32(TCGV_LOW(ret), arg2, offset);
1543 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1544 }
1545 }
1546
tcg_gen_ld32u_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1547 void tcg_gen_ld32u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1548 {
1549 if (TCG_TARGET_REG_BITS == 64) {
1550 tcg_gen_ldst_op_i64(INDEX_op_ld32u_i64, ret, arg2, offset);
1551 } else {
1552 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1553 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1554 }
1555 }
1556
tcg_gen_ld32s_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1557 void tcg_gen_ld32s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1558 {
1559 if (TCG_TARGET_REG_BITS == 64) {
1560 tcg_gen_ldst_op_i64(INDEX_op_ld32s_i64, ret, arg2, offset);
1561 } else {
1562 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1563 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
1564 }
1565 }
1566
tcg_gen_ld_i64(TCGv_i64 ret,TCGv_ptr arg2,tcg_target_long offset)1567 void tcg_gen_ld_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset)
1568 {
1569 /*
1570 * For 32-bit host, since arg2 and ret have different types,
1571 * they cannot be the same temporary -- no chance of overlap.
1572 */
1573 if (TCG_TARGET_REG_BITS == 64) {
1574 tcg_gen_ldst_op_i64(INDEX_op_ld_i64, ret, arg2, offset);
1575 } else if (HOST_BIG_ENDIAN) {
1576 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset);
1577 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset + 4);
1578 } else {
1579 tcg_gen_ld_i32(TCGV_LOW(ret), arg2, offset);
1580 tcg_gen_ld_i32(TCGV_HIGH(ret), arg2, offset + 4);
1581 }
1582 }
1583
tcg_gen_st8_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1584 void tcg_gen_st8_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1585 {
1586 if (TCG_TARGET_REG_BITS == 64) {
1587 tcg_gen_ldst_op_i64(INDEX_op_st8_i64, arg1, arg2, offset);
1588 } else {
1589 tcg_gen_st8_i32(TCGV_LOW(arg1), arg2, offset);
1590 }
1591 }
1592
tcg_gen_st16_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1593 void tcg_gen_st16_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1594 {
1595 if (TCG_TARGET_REG_BITS == 64) {
1596 tcg_gen_ldst_op_i64(INDEX_op_st16_i64, arg1, arg2, offset);
1597 } else {
1598 tcg_gen_st16_i32(TCGV_LOW(arg1), arg2, offset);
1599 }
1600 }
1601
tcg_gen_st32_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1602 void tcg_gen_st32_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1603 {
1604 if (TCG_TARGET_REG_BITS == 64) {
1605 tcg_gen_ldst_op_i64(INDEX_op_st32_i64, arg1, arg2, offset);
1606 } else {
1607 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1608 }
1609 }
1610
tcg_gen_st_i64(TCGv_i64 arg1,TCGv_ptr arg2,tcg_target_long offset)1611 void tcg_gen_st_i64(TCGv_i64 arg1, TCGv_ptr arg2, tcg_target_long offset)
1612 {
1613 if (TCG_TARGET_REG_BITS == 64) {
1614 tcg_gen_ldst_op_i64(INDEX_op_st_i64, arg1, arg2, offset);
1615 } else if (HOST_BIG_ENDIAN) {
1616 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset);
1617 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset + 4);
1618 } else {
1619 tcg_gen_st_i32(TCGV_LOW(arg1), arg2, offset);
1620 tcg_gen_st_i32(TCGV_HIGH(arg1), arg2, offset + 4);
1621 }
1622 }
1623
tcg_gen_add_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1624 void tcg_gen_add_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1625 {
1626 if (TCG_TARGET_REG_BITS == 64) {
1627 tcg_gen_op3_i64(INDEX_op_add_i64, ret, arg1, arg2);
1628 } else {
1629 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1630 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1631 }
1632 }
1633
tcg_gen_sub_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1634 void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1635 {
1636 if (TCG_TARGET_REG_BITS == 64) {
1637 tcg_gen_op3_i64(INDEX_op_sub_i64, ret, arg1, arg2);
1638 } else {
1639 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret), TCGV_LOW(arg1),
1640 TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2));
1641 }
1642 }
1643
tcg_gen_and_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1644 void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1645 {
1646 if (TCG_TARGET_REG_BITS == 64) {
1647 tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2);
1648 } else {
1649 tcg_gen_and_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1650 tcg_gen_and_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1651 }
1652 }
1653
tcg_gen_or_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1654 void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1655 {
1656 if (TCG_TARGET_REG_BITS == 64) {
1657 tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2);
1658 } else {
1659 tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1660 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1661 }
1662 }
1663
tcg_gen_xor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1664 void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1665 {
1666 if (TCG_TARGET_REG_BITS == 64) {
1667 tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2);
1668 } else {
1669 tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
1670 tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
1671 }
1672 }
1673
tcg_gen_shl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1674 void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1675 {
1676 if (TCG_TARGET_REG_BITS == 64) {
1677 tcg_gen_op3_i64(INDEX_op_shl_i64, ret, arg1, arg2);
1678 } else {
1679 gen_helper_shl_i64(ret, arg1, arg2);
1680 }
1681 }
1682
tcg_gen_shr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1683 void tcg_gen_shr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1684 {
1685 if (TCG_TARGET_REG_BITS == 64) {
1686 tcg_gen_op3_i64(INDEX_op_shr_i64, ret, arg1, arg2);
1687 } else {
1688 gen_helper_shr_i64(ret, arg1, arg2);
1689 }
1690 }
1691
tcg_gen_sar_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1692 void tcg_gen_sar_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1693 {
1694 if (TCG_TARGET_REG_BITS == 64) {
1695 tcg_gen_op3_i64(INDEX_op_sar_i64, ret, arg1, arg2);
1696 } else {
1697 gen_helper_sar_i64(ret, arg1, arg2);
1698 }
1699 }
1700
tcg_gen_mul_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1701 void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
1702 {
1703 TCGv_i64 t0;
1704 TCGv_i32 t1;
1705
1706 if (TCG_TARGET_REG_BITS == 64) {
1707 tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
1708 return;
1709 }
1710
1711
1712 t0 = tcg_temp_ebb_new_i64();
1713 t1 = tcg_temp_ebb_new_i32();
1714
1715 tcg_gen_mulu2_i32(TCGV_LOW(t0), TCGV_HIGH(t0),
1716 TCGV_LOW(arg1), TCGV_LOW(arg2));
1717
1718 tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
1719 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1720 tcg_gen_mul_i32(t1, TCGV_HIGH(arg1), TCGV_LOW(arg2));
1721 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
1722
1723 tcg_gen_mov_i64(ret, t0);
1724 tcg_temp_free_i64(t0);
1725 tcg_temp_free_i32(t1);
1726 }
1727
tcg_gen_addi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1728 void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1729 {
1730 /* some cases can be optimized here */
1731 if (arg2 == 0) {
1732 tcg_gen_mov_i64(ret, arg1);
1733 } else if (TCG_TARGET_REG_BITS == 64) {
1734 tcg_gen_add_i64(ret, arg1, tcg_constant_i64(arg2));
1735 } else {
1736 tcg_gen_add2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1737 TCGV_LOW(arg1), TCGV_HIGH(arg1),
1738 tcg_constant_i32(arg2), tcg_constant_i32(arg2 >> 32));
1739 }
1740 }
1741
tcg_gen_subfi_i64(TCGv_i64 ret,int64_t arg1,TCGv_i64 arg2)1742 void tcg_gen_subfi_i64(TCGv_i64 ret, int64_t arg1, TCGv_i64 arg2)
1743 {
1744 if (arg1 == 0) {
1745 tcg_gen_neg_i64(ret, arg2);
1746 } else if (TCG_TARGET_REG_BITS == 64) {
1747 tcg_gen_sub_i64(ret, tcg_constant_i64(arg1), arg2);
1748 } else {
1749 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1750 tcg_constant_i32(arg1), tcg_constant_i32(arg1 >> 32),
1751 TCGV_LOW(arg2), TCGV_HIGH(arg2));
1752 }
1753 }
1754
tcg_gen_subi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1755 void tcg_gen_subi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1756 {
1757 tcg_gen_addi_i64(ret, arg1, -arg2);
1758 }
1759
tcg_gen_neg_i64(TCGv_i64 ret,TCGv_i64 arg)1760 void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
1761 {
1762 if (TCG_TARGET_REG_BITS == 64) {
1763 tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
1764 } else {
1765 TCGv_i32 zero = tcg_constant_i32(0);
1766 tcg_gen_sub2_i32(TCGV_LOW(ret), TCGV_HIGH(ret),
1767 zero, zero, TCGV_LOW(arg), TCGV_HIGH(arg));
1768 }
1769 }
1770
tcg_gen_andi_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1771 void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1772 {
1773 if (TCG_TARGET_REG_BITS == 32) {
1774 tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1775 tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1776 return;
1777 }
1778
1779 /* Some cases can be optimized here. */
1780 switch (arg2) {
1781 case 0:
1782 tcg_gen_movi_i64(ret, 0);
1783 return;
1784 case -1:
1785 tcg_gen_mov_i64(ret, arg1);
1786 return;
1787 case 0xff:
1788 /* Don't recurse with tcg_gen_ext8u_i64. */
1789 if (TCG_TARGET_HAS_ext8u_i64) {
1790 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
1791 return;
1792 }
1793 break;
1794 case 0xffff:
1795 if (TCG_TARGET_HAS_ext16u_i64) {
1796 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
1797 return;
1798 }
1799 break;
1800 case 0xffffffffu:
1801 if (TCG_TARGET_HAS_ext32u_i64) {
1802 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
1803 return;
1804 }
1805 break;
1806 }
1807
1808 tcg_gen_and_i64(ret, arg1, tcg_constant_i64(arg2));
1809 }
1810
tcg_gen_ori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1811 void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1812 {
1813 if (TCG_TARGET_REG_BITS == 32) {
1814 tcg_gen_ori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1815 tcg_gen_ori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1816 return;
1817 }
1818 /* Some cases can be optimized here. */
1819 if (arg2 == -1) {
1820 tcg_gen_movi_i64(ret, -1);
1821 } else if (arg2 == 0) {
1822 tcg_gen_mov_i64(ret, arg1);
1823 } else {
1824 tcg_gen_or_i64(ret, arg1, tcg_constant_i64(arg2));
1825 }
1826 }
1827
tcg_gen_xori_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1828 void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1829 {
1830 if (TCG_TARGET_REG_BITS == 32) {
1831 tcg_gen_xori_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2);
1832 tcg_gen_xori_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32);
1833 return;
1834 }
1835 /* Some cases can be optimized here. */
1836 if (arg2 == 0) {
1837 tcg_gen_mov_i64(ret, arg1);
1838 } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
1839 /* Don't recurse with tcg_gen_not_i64. */
1840 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
1841 } else {
1842 tcg_gen_xor_i64(ret, arg1, tcg_constant_i64(arg2));
1843 }
1844 }
1845
tcg_gen_shifti_i64(TCGv_i64 ret,TCGv_i64 arg1,unsigned c,bool right,bool arith)1846 static inline void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
1847 unsigned c, bool right, bool arith)
1848 {
1849 tcg_debug_assert(c < 64);
1850 if (c == 0) {
1851 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
1852 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
1853 } else if (c >= 32) {
1854 c -= 32;
1855 if (right) {
1856 if (arith) {
1857 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1858 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), 31);
1859 } else {
1860 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), c);
1861 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1862 }
1863 } else {
1864 tcg_gen_shli_i32(TCGV_HIGH(ret), TCGV_LOW(arg1), c);
1865 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
1866 }
1867 } else if (right) {
1868 if (TCG_TARGET_HAS_extract2_i32) {
1869 tcg_gen_extract2_i32(TCGV_LOW(ret),
1870 TCGV_LOW(arg1), TCGV_HIGH(arg1), c);
1871 } else {
1872 tcg_gen_shri_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1873 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(ret),
1874 TCGV_HIGH(arg1), 32 - c, c);
1875 }
1876 if (arith) {
1877 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1878 } else {
1879 tcg_gen_shri_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), c);
1880 }
1881 } else {
1882 if (TCG_TARGET_HAS_extract2_i32) {
1883 tcg_gen_extract2_i32(TCGV_HIGH(ret),
1884 TCGV_LOW(arg1), TCGV_HIGH(arg1), 32 - c);
1885 } else {
1886 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
1887 tcg_gen_shri_i32(t0, TCGV_LOW(arg1), 32 - c);
1888 tcg_gen_deposit_i32(TCGV_HIGH(ret), t0,
1889 TCGV_HIGH(arg1), c, 32 - c);
1890 tcg_temp_free_i32(t0);
1891 }
1892 tcg_gen_shli_i32(TCGV_LOW(ret), TCGV_LOW(arg1), c);
1893 }
1894 }
1895
tcg_gen_shli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1896 void tcg_gen_shli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1897 {
1898 tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1899 if (TCG_TARGET_REG_BITS == 32) {
1900 tcg_gen_shifti_i64(ret, arg1, arg2, 0, 0);
1901 } else if (arg2 == 0) {
1902 tcg_gen_mov_i64(ret, arg1);
1903 } else {
1904 tcg_gen_shl_i64(ret, arg1, tcg_constant_i64(arg2));
1905 }
1906 }
1907
tcg_gen_shri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1908 void tcg_gen_shri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1909 {
1910 tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1911 if (TCG_TARGET_REG_BITS == 32) {
1912 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 0);
1913 } else if (arg2 == 0) {
1914 tcg_gen_mov_i64(ret, arg1);
1915 } else {
1916 tcg_gen_shr_i64(ret, arg1, tcg_constant_i64(arg2));
1917 }
1918 }
1919
tcg_gen_sari_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1920 void tcg_gen_sari_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
1921 {
1922 tcg_debug_assert(arg2 >= 0 && arg2 < 64);
1923 if (TCG_TARGET_REG_BITS == 32) {
1924 tcg_gen_shifti_i64(ret, arg1, arg2, 1, 1);
1925 } else if (arg2 == 0) {
1926 tcg_gen_mov_i64(ret, arg1);
1927 } else {
1928 tcg_gen_sar_i64(ret, arg1, tcg_constant_i64(arg2));
1929 }
1930 }
1931
tcg_gen_brcond_i64(TCGCond cond,TCGv_i64 arg1,TCGv_i64 arg2,TCGLabel * l)1932 void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, TCGLabel *l)
1933 {
1934 if (cond == TCG_COND_ALWAYS) {
1935 tcg_gen_br(l);
1936 } else if (cond != TCG_COND_NEVER) {
1937 TCGOp *op;
1938 if (TCG_TARGET_REG_BITS == 32) {
1939 op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1),
1940 TCGV_HIGH(arg1), TCGV_LOW(arg2),
1941 TCGV_HIGH(arg2), cond, label_arg(l));
1942 } else {
1943 op = tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond,
1944 label_arg(l));
1945 }
1946 add_as_label_use(l, op);
1947 }
1948 }
1949
tcg_gen_brcondi_i64(TCGCond cond,TCGv_i64 arg1,int64_t arg2,TCGLabel * l)1950 void tcg_gen_brcondi_i64(TCGCond cond, TCGv_i64 arg1, int64_t arg2, TCGLabel *l)
1951 {
1952 if (TCG_TARGET_REG_BITS == 64) {
1953 tcg_gen_brcond_i64(cond, arg1, tcg_constant_i64(arg2), l);
1954 } else if (cond == TCG_COND_ALWAYS) {
1955 tcg_gen_br(l);
1956 } else if (cond != TCG_COND_NEVER) {
1957 TCGOp *op = tcg_gen_op6ii_i32(INDEX_op_brcond2_i32,
1958 TCGV_LOW(arg1), TCGV_HIGH(arg1),
1959 tcg_constant_i32(arg2),
1960 tcg_constant_i32(arg2 >> 32),
1961 cond, label_arg(l));
1962 add_as_label_use(l, op);
1963 }
1964 }
1965
tcg_gen_setcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)1966 void tcg_gen_setcond_i64(TCGCond cond, TCGv_i64 ret,
1967 TCGv_i64 arg1, TCGv_i64 arg2)
1968 {
1969 if (cond == TCG_COND_ALWAYS) {
1970 tcg_gen_movi_i64(ret, 1);
1971 } else if (cond == TCG_COND_NEVER) {
1972 tcg_gen_movi_i64(ret, 0);
1973 } else {
1974 if (TCG_TARGET_REG_BITS == 32) {
1975 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1976 TCGV_LOW(arg1), TCGV_HIGH(arg1),
1977 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
1978 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
1979 } else {
1980 tcg_gen_op4i_i64(INDEX_op_setcond_i64, ret, arg1, arg2, cond);
1981 }
1982 }
1983 }
1984
tcg_gen_setcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)1985 void tcg_gen_setcondi_i64(TCGCond cond, TCGv_i64 ret,
1986 TCGv_i64 arg1, int64_t arg2)
1987 {
1988 if (TCG_TARGET_REG_BITS == 64) {
1989 tcg_gen_setcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
1990 } else if (cond == TCG_COND_ALWAYS) {
1991 tcg_gen_movi_i64(ret, 1);
1992 } else if (cond == TCG_COND_NEVER) {
1993 tcg_gen_movi_i64(ret, 0);
1994 } else {
1995 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
1996 TCGV_LOW(arg1), TCGV_HIGH(arg1),
1997 tcg_constant_i32(arg2),
1998 tcg_constant_i32(arg2 >> 32), cond);
1999 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2000 }
2001 }
2002
tcg_gen_negsetcondi_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2003 void tcg_gen_negsetcondi_i64(TCGCond cond, TCGv_i64 ret,
2004 TCGv_i64 arg1, int64_t arg2)
2005 {
2006 tcg_gen_negsetcond_i64(cond, ret, arg1, tcg_constant_i64(arg2));
2007 }
2008
tcg_gen_negsetcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2009 void tcg_gen_negsetcond_i64(TCGCond cond, TCGv_i64 ret,
2010 TCGv_i64 arg1, TCGv_i64 arg2)
2011 {
2012 if (cond == TCG_COND_ALWAYS) {
2013 tcg_gen_movi_i64(ret, -1);
2014 } else if (cond == TCG_COND_NEVER) {
2015 tcg_gen_movi_i64(ret, 0);
2016 } else if (TCG_TARGET_HAS_negsetcond_i64) {
2017 tcg_gen_op4i_i64(INDEX_op_negsetcond_i64, ret, arg1, arg2, cond);
2018 } else if (TCG_TARGET_REG_BITS == 32) {
2019 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, TCGV_LOW(ret),
2020 TCGV_LOW(arg1), TCGV_HIGH(arg1),
2021 TCGV_LOW(arg2), TCGV_HIGH(arg2), cond);
2022 tcg_gen_neg_i32(TCGV_LOW(ret), TCGV_LOW(ret));
2023 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_LOW(ret));
2024 } else {
2025 tcg_gen_setcond_i64(cond, ret, arg1, arg2);
2026 tcg_gen_neg_i64(ret, ret);
2027 }
2028 }
2029
tcg_gen_muli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2030 void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2031 {
2032 if (arg2 == 0) {
2033 tcg_gen_movi_i64(ret, 0);
2034 } else if (is_power_of_2(arg2)) {
2035 tcg_gen_shli_i64(ret, arg1, ctz64(arg2));
2036 } else {
2037 tcg_gen_mul_i64(ret, arg1, tcg_constant_i64(arg2));
2038 }
2039 }
2040
tcg_gen_div_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2041 void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2042 {
2043 if (TCG_TARGET_HAS_div_i64) {
2044 tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
2045 } else if (TCG_TARGET_HAS_div2_i64) {
2046 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2047 tcg_gen_sari_i64(t0, arg1, 63);
2048 tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
2049 tcg_temp_free_i64(t0);
2050 } else {
2051 gen_helper_div_i64(ret, arg1, arg2);
2052 }
2053 }
2054
tcg_gen_rem_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2055 void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2056 {
2057 if (TCG_TARGET_HAS_rem_i64) {
2058 tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
2059 } else if (TCG_TARGET_HAS_div_i64) {
2060 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2061 tcg_gen_op3_i64(INDEX_op_div_i64, t0, arg1, arg2);
2062 tcg_gen_mul_i64(t0, t0, arg2);
2063 tcg_gen_sub_i64(ret, arg1, t0);
2064 tcg_temp_free_i64(t0);
2065 } else if (TCG_TARGET_HAS_div2_i64) {
2066 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2067 tcg_gen_sari_i64(t0, arg1, 63);
2068 tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
2069 tcg_temp_free_i64(t0);
2070 } else {
2071 gen_helper_rem_i64(ret, arg1, arg2);
2072 }
2073 }
2074
tcg_gen_divu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2075 void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2076 {
2077 if (TCG_TARGET_HAS_div_i64) {
2078 tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
2079 } else if (TCG_TARGET_HAS_div2_i64) {
2080 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2081 TCGv_i64 zero = tcg_constant_i64(0);
2082 tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, zero, arg2);
2083 tcg_temp_free_i64(t0);
2084 } else {
2085 gen_helper_divu_i64(ret, arg1, arg2);
2086 }
2087 }
2088
tcg_gen_remu_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2089 void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2090 {
2091 if (TCG_TARGET_HAS_rem_i64) {
2092 tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
2093 } else if (TCG_TARGET_HAS_div_i64) {
2094 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2095 tcg_gen_op3_i64(INDEX_op_divu_i64, t0, arg1, arg2);
2096 tcg_gen_mul_i64(t0, t0, arg2);
2097 tcg_gen_sub_i64(ret, arg1, t0);
2098 tcg_temp_free_i64(t0);
2099 } else if (TCG_TARGET_HAS_div2_i64) {
2100 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2101 TCGv_i64 zero = tcg_constant_i64(0);
2102 tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, zero, arg2);
2103 tcg_temp_free_i64(t0);
2104 } else {
2105 gen_helper_remu_i64(ret, arg1, arg2);
2106 }
2107 }
2108
tcg_gen_ext8s_i64(TCGv_i64 ret,TCGv_i64 arg)2109 void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
2110 {
2111 if (TCG_TARGET_REG_BITS == 32) {
2112 tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2113 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2114 } else if (TCG_TARGET_HAS_ext8s_i64) {
2115 tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
2116 } else {
2117 tcg_gen_shli_i64(ret, arg, 56);
2118 tcg_gen_sari_i64(ret, ret, 56);
2119 }
2120 }
2121
tcg_gen_ext16s_i64(TCGv_i64 ret,TCGv_i64 arg)2122 void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
2123 {
2124 if (TCG_TARGET_REG_BITS == 32) {
2125 tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2126 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2127 } else if (TCG_TARGET_HAS_ext16s_i64) {
2128 tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
2129 } else {
2130 tcg_gen_shli_i64(ret, arg, 48);
2131 tcg_gen_sari_i64(ret, ret, 48);
2132 }
2133 }
2134
tcg_gen_ext32s_i64(TCGv_i64 ret,TCGv_i64 arg)2135 void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
2136 {
2137 if (TCG_TARGET_REG_BITS == 32) {
2138 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2139 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2140 } else if (TCG_TARGET_HAS_ext32s_i64) {
2141 tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
2142 } else {
2143 tcg_gen_shli_i64(ret, arg, 32);
2144 tcg_gen_sari_i64(ret, ret, 32);
2145 }
2146 }
2147
tcg_gen_ext8u_i64(TCGv_i64 ret,TCGv_i64 arg)2148 void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
2149 {
2150 if (TCG_TARGET_REG_BITS == 32) {
2151 tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2152 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2153 } else if (TCG_TARGET_HAS_ext8u_i64) {
2154 tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
2155 } else {
2156 tcg_gen_andi_i64(ret, arg, 0xffu);
2157 }
2158 }
2159
tcg_gen_ext16u_i64(TCGv_i64 ret,TCGv_i64 arg)2160 void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
2161 {
2162 if (TCG_TARGET_REG_BITS == 32) {
2163 tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2164 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2165 } else if (TCG_TARGET_HAS_ext16u_i64) {
2166 tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
2167 } else {
2168 tcg_gen_andi_i64(ret, arg, 0xffffu);
2169 }
2170 }
2171
tcg_gen_ext32u_i64(TCGv_i64 ret,TCGv_i64 arg)2172 void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
2173 {
2174 if (TCG_TARGET_REG_BITS == 32) {
2175 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2176 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2177 } else if (TCG_TARGET_HAS_ext32u_i64) {
2178 tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
2179 } else {
2180 tcg_gen_andi_i64(ret, arg, 0xffffffffu);
2181 }
2182 }
2183
2184 /*
2185 * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value.
2186 *
2187 * Byte pattern: xxxxxxxxab -> yyyyyyyyba
2188 *
2189 * With TCG_BSWAP_IZ, x == zero, else undefined.
2190 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
2191 */
tcg_gen_bswap16_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)2192 void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2193 {
2194 /* Only one extension flag may be present. */
2195 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
2196
2197 if (TCG_TARGET_REG_BITS == 32) {
2198 tcg_gen_bswap16_i32(TCGV_LOW(ret), TCGV_LOW(arg), flags);
2199 if (flags & TCG_BSWAP_OS) {
2200 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2201 } else {
2202 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2203 }
2204 } else if (TCG_TARGET_HAS_bswap16_i64) {
2205 tcg_gen_op3i_i64(INDEX_op_bswap16_i64, ret, arg, flags);
2206 } else {
2207 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2208 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2209
2210 /* arg = ......ab or xxxxxxab */
2211 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .......a or .xxxxxxa */
2212 if (!(flags & TCG_BSWAP_IZ)) {
2213 tcg_gen_ext8u_i64(t0, t0); /* t0 = .......a */
2214 }
2215
2216 if (flags & TCG_BSWAP_OS) {
2217 tcg_gen_shli_i64(t1, arg, 56); /* t1 = b....... */
2218 tcg_gen_sari_i64(t1, t1, 48); /* t1 = ssssssb. */
2219 } else if (flags & TCG_BSWAP_OZ) {
2220 tcg_gen_ext8u_i64(t1, arg); /* t1 = .......b */
2221 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ......b. */
2222 } else {
2223 tcg_gen_shli_i64(t1, arg, 8); /* t1 = xxxxxab. */
2224 }
2225
2226 tcg_gen_or_i64(ret, t0, t1); /* ret = ......ba (OZ) */
2227 /* ssssssba (OS) */
2228 /* xxxxxaba (no flag) */
2229 tcg_temp_free_i64(t0);
2230 tcg_temp_free_i64(t1);
2231 }
2232 }
2233
2234 /*
2235 * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value.
2236 *
2237 * Byte pattern: xxxxabcd -> yyyydcba
2238 *
2239 * With TCG_BSWAP_IZ, x == zero, else undefined.
2240 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
2241 */
tcg_gen_bswap32_i64(TCGv_i64 ret,TCGv_i64 arg,int flags)2242 void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg, int flags)
2243 {
2244 /* Only one extension flag may be present. */
2245 tcg_debug_assert(!(flags & TCG_BSWAP_OS) || !(flags & TCG_BSWAP_OZ));
2246
2247 if (TCG_TARGET_REG_BITS == 32) {
2248 tcg_gen_bswap32_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2249 if (flags & TCG_BSWAP_OS) {
2250 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2251 } else {
2252 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2253 }
2254 } else if (TCG_TARGET_HAS_bswap32_i64) {
2255 tcg_gen_op3i_i64(INDEX_op_bswap32_i64, ret, arg, flags);
2256 } else {
2257 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2258 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2259 TCGv_i64 t2 = tcg_constant_i64(0x00ff00ff);
2260
2261 /* arg = xxxxabcd */
2262 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .xxxxabc */
2263 tcg_gen_and_i64(t1, arg, t2); /* t1 = .....b.d */
2264 tcg_gen_and_i64(t0, t0, t2); /* t0 = .....a.c */
2265 tcg_gen_shli_i64(t1, t1, 8); /* t1 = ....b.d. */
2266 tcg_gen_or_i64(ret, t0, t1); /* ret = ....badc */
2267
2268 tcg_gen_shli_i64(t1, ret, 48); /* t1 = dc...... */
2269 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ......ba */
2270 if (flags & TCG_BSWAP_OS) {
2271 tcg_gen_sari_i64(t1, t1, 32); /* t1 = ssssdc.. */
2272 } else {
2273 tcg_gen_shri_i64(t1, t1, 32); /* t1 = ....dc.. */
2274 }
2275 tcg_gen_or_i64(ret, t0, t1); /* ret = ssssdcba (OS) */
2276 /* ....dcba (else) */
2277
2278 tcg_temp_free_i64(t0);
2279 tcg_temp_free_i64(t1);
2280 }
2281 }
2282
2283 /*
2284 * bswap64_i64: 64-bit byte swap on a 64-bit value.
2285 *
2286 * Byte pattern: abcdefgh -> hgfedcba
2287 */
tcg_gen_bswap64_i64(TCGv_i64 ret,TCGv_i64 arg)2288 void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
2289 {
2290 if (TCG_TARGET_REG_BITS == 32) {
2291 TCGv_i32 t0, t1;
2292 t0 = tcg_temp_ebb_new_i32();
2293 t1 = tcg_temp_ebb_new_i32();
2294
2295 tcg_gen_bswap32_i32(t0, TCGV_LOW(arg));
2296 tcg_gen_bswap32_i32(t1, TCGV_HIGH(arg));
2297 tcg_gen_mov_i32(TCGV_LOW(ret), t1);
2298 tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
2299 tcg_temp_free_i32(t0);
2300 tcg_temp_free_i32(t1);
2301 } else if (TCG_TARGET_HAS_bswap64_i64) {
2302 tcg_gen_op3i_i64(INDEX_op_bswap64_i64, ret, arg, 0);
2303 } else {
2304 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2305 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2306 TCGv_i64 t2 = tcg_temp_ebb_new_i64();
2307
2308 /* arg = abcdefgh */
2309 tcg_gen_movi_i64(t2, 0x00ff00ff00ff00ffull);
2310 tcg_gen_shri_i64(t0, arg, 8); /* t0 = .abcdefg */
2311 tcg_gen_and_i64(t1, arg, t2); /* t1 = .b.d.f.h */
2312 tcg_gen_and_i64(t0, t0, t2); /* t0 = .a.c.e.g */
2313 tcg_gen_shli_i64(t1, t1, 8); /* t1 = b.d.f.h. */
2314 tcg_gen_or_i64(ret, t0, t1); /* ret = badcfehg */
2315
2316 tcg_gen_movi_i64(t2, 0x0000ffff0000ffffull);
2317 tcg_gen_shri_i64(t0, ret, 16); /* t0 = ..badcfe */
2318 tcg_gen_and_i64(t1, ret, t2); /* t1 = ..dc..hg */
2319 tcg_gen_and_i64(t0, t0, t2); /* t0 = ..ba..fe */
2320 tcg_gen_shli_i64(t1, t1, 16); /* t1 = dc..hg.. */
2321 tcg_gen_or_i64(ret, t0, t1); /* ret = dcbahgfe */
2322
2323 tcg_gen_shri_i64(t0, ret, 32); /* t0 = ....dcba */
2324 tcg_gen_shli_i64(t1, ret, 32); /* t1 = hgfe.... */
2325 tcg_gen_or_i64(ret, t0, t1); /* ret = hgfedcba */
2326
2327 tcg_temp_free_i64(t0);
2328 tcg_temp_free_i64(t1);
2329 tcg_temp_free_i64(t2);
2330 }
2331 }
2332
2333 /*
2334 * hswap_i64: Swap 16-bit halfwords within a 64-bit value.
2335 * See also include/qemu/bitops.h, hswap64.
2336 *
2337 * Byte pattern: abcdefgh -> ghefcdab
2338 */
tcg_gen_hswap_i64(TCGv_i64 ret,TCGv_i64 arg)2339 void tcg_gen_hswap_i64(TCGv_i64 ret, TCGv_i64 arg)
2340 {
2341 uint64_t m = 0x0000ffff0000ffffull;
2342 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2343 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
2344
2345 /* arg = abcdefgh */
2346 tcg_gen_rotli_i64(t1, arg, 32); /* t1 = efghabcd */
2347 tcg_gen_andi_i64(t0, t1, m); /* t0 = ..gh..cd */
2348 tcg_gen_shli_i64(t0, t0, 16); /* t0 = gh..cd.. */
2349 tcg_gen_shri_i64(t1, t1, 16); /* t1 = ..efghab */
2350 tcg_gen_andi_i64(t1, t1, m); /* t1 = ..ef..ab */
2351 tcg_gen_or_i64(ret, t0, t1); /* ret = ghefcdab */
2352
2353 tcg_temp_free_i64(t0);
2354 tcg_temp_free_i64(t1);
2355 }
2356
2357 /*
2358 * wswap_i64: Swap 32-bit words within a 64-bit value.
2359 *
2360 * Byte pattern: abcdefgh -> efghabcd
2361 */
tcg_gen_wswap_i64(TCGv_i64 ret,TCGv_i64 arg)2362 void tcg_gen_wswap_i64(TCGv_i64 ret, TCGv_i64 arg)
2363 {
2364 /* Swapping 2 32-bit elements is a rotate. */
2365 tcg_gen_rotli_i64(ret, arg, 32);
2366 }
2367
tcg_gen_not_i64(TCGv_i64 ret,TCGv_i64 arg)2368 void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
2369 {
2370 if (TCG_TARGET_REG_BITS == 32) {
2371 tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2372 tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
2373 } else if (TCG_TARGET_HAS_not_i64) {
2374 tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
2375 } else {
2376 tcg_gen_xori_i64(ret, arg, -1);
2377 }
2378 }
2379
tcg_gen_andc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2380 void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2381 {
2382 if (TCG_TARGET_REG_BITS == 32) {
2383 tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
2384 tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
2385 } else if (TCG_TARGET_HAS_andc_i64) {
2386 tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
2387 } else {
2388 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2389 tcg_gen_not_i64(t0, arg2);
2390 tcg_gen_and_i64(ret, arg1, t0);
2391 tcg_temp_free_i64(t0);
2392 }
2393 }
2394
tcg_gen_eqv_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2395 void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2396 {
2397 if (TCG_TARGET_REG_BITS == 32) {
2398 tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
2399 tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
2400 } else if (TCG_TARGET_HAS_eqv_i64) {
2401 tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
2402 } else {
2403 tcg_gen_xor_i64(ret, arg1, arg2);
2404 tcg_gen_not_i64(ret, ret);
2405 }
2406 }
2407
tcg_gen_nand_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2408 void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2409 {
2410 if (TCG_TARGET_REG_BITS == 32) {
2411 tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
2412 tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
2413 } else if (TCG_TARGET_HAS_nand_i64) {
2414 tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
2415 } else {
2416 tcg_gen_and_i64(ret, arg1, arg2);
2417 tcg_gen_not_i64(ret, ret);
2418 }
2419 }
2420
tcg_gen_nor_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2421 void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2422 {
2423 if (TCG_TARGET_REG_BITS == 32) {
2424 tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
2425 tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
2426 } else if (TCG_TARGET_HAS_nor_i64) {
2427 tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
2428 } else {
2429 tcg_gen_or_i64(ret, arg1, arg2);
2430 tcg_gen_not_i64(ret, ret);
2431 }
2432 }
2433
tcg_gen_orc_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2434 void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2435 {
2436 if (TCG_TARGET_REG_BITS == 32) {
2437 tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
2438 tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
2439 } else if (TCG_TARGET_HAS_orc_i64) {
2440 tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
2441 } else {
2442 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2443 tcg_gen_not_i64(t0, arg2);
2444 tcg_gen_or_i64(ret, arg1, t0);
2445 tcg_temp_free_i64(t0);
2446 }
2447 }
2448
tcg_gen_clz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2449 void tcg_gen_clz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2450 {
2451 if (TCG_TARGET_HAS_clz_i64) {
2452 tcg_gen_op3_i64(INDEX_op_clz_i64, ret, arg1, arg2);
2453 } else {
2454 gen_helper_clz_i64(ret, arg1, arg2);
2455 }
2456 }
2457
tcg_gen_clzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)2458 void tcg_gen_clzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
2459 {
2460 if (TCG_TARGET_REG_BITS == 32
2461 && TCG_TARGET_HAS_clz_i32
2462 && arg2 <= 0xffffffffu) {
2463 TCGv_i32 t = tcg_temp_ebb_new_i32();
2464 tcg_gen_clzi_i32(t, TCGV_LOW(arg1), arg2 - 32);
2465 tcg_gen_addi_i32(t, t, 32);
2466 tcg_gen_clz_i32(TCGV_LOW(ret), TCGV_HIGH(arg1), t);
2467 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2468 tcg_temp_free_i32(t);
2469 } else {
2470 tcg_gen_clz_i64(ret, arg1, tcg_constant_i64(arg2));
2471 }
2472 }
2473
tcg_gen_ctz_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2474 void tcg_gen_ctz_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2475 {
2476 if (TCG_TARGET_HAS_ctz_i64) {
2477 tcg_gen_op3_i64(INDEX_op_ctz_i64, ret, arg1, arg2);
2478 } else if (TCG_TARGET_HAS_ctpop_i64 || TCG_TARGET_HAS_clz_i64) {
2479 TCGv_i64 z, t = tcg_temp_ebb_new_i64();
2480
2481 if (TCG_TARGET_HAS_ctpop_i64) {
2482 tcg_gen_subi_i64(t, arg1, 1);
2483 tcg_gen_andc_i64(t, t, arg1);
2484 tcg_gen_ctpop_i64(t, t);
2485 } else {
2486 /* Since all non-x86 hosts have clz(0) == 64, don't fight it. */
2487 tcg_gen_neg_i64(t, arg1);
2488 tcg_gen_and_i64(t, t, arg1);
2489 tcg_gen_clzi_i64(t, t, 64);
2490 tcg_gen_xori_i64(t, t, 63);
2491 }
2492 z = tcg_constant_i64(0);
2493 tcg_gen_movcond_i64(TCG_COND_EQ, ret, arg1, z, arg2, t);
2494 tcg_temp_free_i64(t);
2495 tcg_temp_free_i64(z);
2496 } else {
2497 gen_helper_ctz_i64(ret, arg1, arg2);
2498 }
2499 }
2500
tcg_gen_ctzi_i64(TCGv_i64 ret,TCGv_i64 arg1,uint64_t arg2)2501 void tcg_gen_ctzi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
2502 {
2503 if (TCG_TARGET_REG_BITS == 32
2504 && TCG_TARGET_HAS_ctz_i32
2505 && arg2 <= 0xffffffffu) {
2506 TCGv_i32 t32 = tcg_temp_ebb_new_i32();
2507 tcg_gen_ctzi_i32(t32, TCGV_HIGH(arg1), arg2 - 32);
2508 tcg_gen_addi_i32(t32, t32, 32);
2509 tcg_gen_ctz_i32(TCGV_LOW(ret), TCGV_LOW(arg1), t32);
2510 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2511 tcg_temp_free_i32(t32);
2512 } else if (!TCG_TARGET_HAS_ctz_i64
2513 && TCG_TARGET_HAS_ctpop_i64
2514 && arg2 == 64) {
2515 /* This equivalence has the advantage of not requiring a fixup. */
2516 TCGv_i64 t = tcg_temp_ebb_new_i64();
2517 tcg_gen_subi_i64(t, arg1, 1);
2518 tcg_gen_andc_i64(t, t, arg1);
2519 tcg_gen_ctpop_i64(ret, t);
2520 tcg_temp_free_i64(t);
2521 } else {
2522 tcg_gen_ctz_i64(ret, arg1, tcg_constant_i64(arg2));
2523 }
2524 }
2525
tcg_gen_clrsb_i64(TCGv_i64 ret,TCGv_i64 arg)2526 void tcg_gen_clrsb_i64(TCGv_i64 ret, TCGv_i64 arg)
2527 {
2528 if (TCG_TARGET_HAS_clz_i64 || TCG_TARGET_HAS_clz_i32) {
2529 TCGv_i64 t = tcg_temp_ebb_new_i64();
2530 tcg_gen_sari_i64(t, arg, 63);
2531 tcg_gen_xor_i64(t, t, arg);
2532 tcg_gen_clzi_i64(t, t, 64);
2533 tcg_gen_subi_i64(ret, t, 1);
2534 tcg_temp_free_i64(t);
2535 } else {
2536 gen_helper_clrsb_i64(ret, arg);
2537 }
2538 }
2539
tcg_gen_ctpop_i64(TCGv_i64 ret,TCGv_i64 arg1)2540 void tcg_gen_ctpop_i64(TCGv_i64 ret, TCGv_i64 arg1)
2541 {
2542 if (TCG_TARGET_HAS_ctpop_i64) {
2543 tcg_gen_op2_i64(INDEX_op_ctpop_i64, ret, arg1);
2544 } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_ctpop_i32) {
2545 tcg_gen_ctpop_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2546 tcg_gen_ctpop_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2547 tcg_gen_add_i32(TCGV_LOW(ret), TCGV_LOW(ret), TCGV_HIGH(ret));
2548 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2549 } else {
2550 gen_helper_ctpop_i64(ret, arg1);
2551 }
2552 }
2553
tcg_gen_rotl_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2554 void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2555 {
2556 if (TCG_TARGET_HAS_rot_i64) {
2557 tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
2558 } else {
2559 TCGv_i64 t0, t1;
2560 t0 = tcg_temp_ebb_new_i64();
2561 t1 = tcg_temp_ebb_new_i64();
2562 tcg_gen_shl_i64(t0, arg1, arg2);
2563 tcg_gen_subfi_i64(t1, 64, arg2);
2564 tcg_gen_shr_i64(t1, arg1, t1);
2565 tcg_gen_or_i64(ret, t0, t1);
2566 tcg_temp_free_i64(t0);
2567 tcg_temp_free_i64(t1);
2568 }
2569 }
2570
tcg_gen_rotli_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2571 void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2572 {
2573 tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2574 /* some cases can be optimized here */
2575 if (arg2 == 0) {
2576 tcg_gen_mov_i64(ret, arg1);
2577 } else if (TCG_TARGET_HAS_rot_i64) {
2578 tcg_gen_rotl_i64(ret, arg1, tcg_constant_i64(arg2));
2579 } else {
2580 TCGv_i64 t0, t1;
2581 t0 = tcg_temp_ebb_new_i64();
2582 t1 = tcg_temp_ebb_new_i64();
2583 tcg_gen_shli_i64(t0, arg1, arg2);
2584 tcg_gen_shri_i64(t1, arg1, 64 - arg2);
2585 tcg_gen_or_i64(ret, t0, t1);
2586 tcg_temp_free_i64(t0);
2587 tcg_temp_free_i64(t1);
2588 }
2589 }
2590
tcg_gen_rotr_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2)2591 void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
2592 {
2593 if (TCG_TARGET_HAS_rot_i64) {
2594 tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
2595 } else {
2596 TCGv_i64 t0, t1;
2597 t0 = tcg_temp_ebb_new_i64();
2598 t1 = tcg_temp_ebb_new_i64();
2599 tcg_gen_shr_i64(t0, arg1, arg2);
2600 tcg_gen_subfi_i64(t1, 64, arg2);
2601 tcg_gen_shl_i64(t1, arg1, t1);
2602 tcg_gen_or_i64(ret, t0, t1);
2603 tcg_temp_free_i64(t0);
2604 tcg_temp_free_i64(t1);
2605 }
2606 }
2607
tcg_gen_rotri_i64(TCGv_i64 ret,TCGv_i64 arg1,int64_t arg2)2608 void tcg_gen_rotri_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
2609 {
2610 tcg_debug_assert(arg2 >= 0 && arg2 < 64);
2611 /* some cases can be optimized here */
2612 if (arg2 == 0) {
2613 tcg_gen_mov_i64(ret, arg1);
2614 } else {
2615 tcg_gen_rotli_i64(ret, arg1, 64 - arg2);
2616 }
2617 }
2618
tcg_gen_deposit_i64(TCGv_i64 ret,TCGv_i64 arg1,TCGv_i64 arg2,unsigned int ofs,unsigned int len)2619 void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2,
2620 unsigned int ofs, unsigned int len)
2621 {
2622 uint64_t mask;
2623 TCGv_i64 t1;
2624
2625 tcg_debug_assert(ofs < 64);
2626 tcg_debug_assert(len > 0);
2627 tcg_debug_assert(len <= 64);
2628 tcg_debug_assert(ofs + len <= 64);
2629
2630 if (len == 64) {
2631 tcg_gen_mov_i64(ret, arg2);
2632 return;
2633 }
2634 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2635 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
2636 return;
2637 }
2638
2639 if (TCG_TARGET_REG_BITS == 32) {
2640 if (ofs >= 32) {
2641 tcg_gen_deposit_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1),
2642 TCGV_LOW(arg2), ofs - 32, len);
2643 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg1));
2644 return;
2645 }
2646 if (ofs + len <= 32) {
2647 tcg_gen_deposit_i32(TCGV_LOW(ret), TCGV_LOW(arg1),
2648 TCGV_LOW(arg2), ofs, len);
2649 tcg_gen_mov_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1));
2650 return;
2651 }
2652 }
2653
2654 t1 = tcg_temp_ebb_new_i64();
2655
2656 if (TCG_TARGET_HAS_extract2_i64) {
2657 if (ofs + len == 64) {
2658 tcg_gen_shli_i64(t1, arg1, len);
2659 tcg_gen_extract2_i64(ret, t1, arg2, len);
2660 goto done;
2661 }
2662 if (ofs == 0) {
2663 tcg_gen_extract2_i64(ret, arg1, arg2, len);
2664 tcg_gen_rotli_i64(ret, ret, len);
2665 goto done;
2666 }
2667 }
2668
2669 mask = (1ull << len) - 1;
2670 if (ofs + len < 64) {
2671 tcg_gen_andi_i64(t1, arg2, mask);
2672 tcg_gen_shli_i64(t1, t1, ofs);
2673 } else {
2674 tcg_gen_shli_i64(t1, arg2, ofs);
2675 }
2676 tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
2677 tcg_gen_or_i64(ret, ret, t1);
2678 done:
2679 tcg_temp_free_i64(t1);
2680 }
2681
tcg_gen_deposit_z_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)2682 void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
2683 unsigned int ofs, unsigned int len)
2684 {
2685 tcg_debug_assert(ofs < 64);
2686 tcg_debug_assert(len > 0);
2687 tcg_debug_assert(len <= 64);
2688 tcg_debug_assert(ofs + len <= 64);
2689
2690 if (ofs + len == 64) {
2691 tcg_gen_shli_i64(ret, arg, ofs);
2692 } else if (ofs == 0) {
2693 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2694 } else if (TCG_TARGET_HAS_deposit_i64
2695 && TCG_TARGET_deposit_i64_valid(ofs, len)) {
2696 TCGv_i64 zero = tcg_constant_i64(0);
2697 tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, zero, arg, ofs, len);
2698 } else {
2699 if (TCG_TARGET_REG_BITS == 32) {
2700 if (ofs >= 32) {
2701 tcg_gen_deposit_z_i32(TCGV_HIGH(ret), TCGV_LOW(arg),
2702 ofs - 32, len);
2703 tcg_gen_movi_i32(TCGV_LOW(ret), 0);
2704 return;
2705 }
2706 if (ofs + len <= 32) {
2707 tcg_gen_deposit_z_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2708 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2709 return;
2710 }
2711 }
2712 /* To help two-operand hosts we prefer to zero-extend first,
2713 which allows ARG to stay live. */
2714 switch (len) {
2715 case 32:
2716 if (TCG_TARGET_HAS_ext32u_i64) {
2717 tcg_gen_ext32u_i64(ret, arg);
2718 tcg_gen_shli_i64(ret, ret, ofs);
2719 return;
2720 }
2721 break;
2722 case 16:
2723 if (TCG_TARGET_HAS_ext16u_i64) {
2724 tcg_gen_ext16u_i64(ret, arg);
2725 tcg_gen_shli_i64(ret, ret, ofs);
2726 return;
2727 }
2728 break;
2729 case 8:
2730 if (TCG_TARGET_HAS_ext8u_i64) {
2731 tcg_gen_ext8u_i64(ret, arg);
2732 tcg_gen_shli_i64(ret, ret, ofs);
2733 return;
2734 }
2735 break;
2736 }
2737 /* Otherwise prefer zero-extension over AND for code size. */
2738 switch (ofs + len) {
2739 case 32:
2740 if (TCG_TARGET_HAS_ext32u_i64) {
2741 tcg_gen_shli_i64(ret, arg, ofs);
2742 tcg_gen_ext32u_i64(ret, ret);
2743 return;
2744 }
2745 break;
2746 case 16:
2747 if (TCG_TARGET_HAS_ext16u_i64) {
2748 tcg_gen_shli_i64(ret, arg, ofs);
2749 tcg_gen_ext16u_i64(ret, ret);
2750 return;
2751 }
2752 break;
2753 case 8:
2754 if (TCG_TARGET_HAS_ext8u_i64) {
2755 tcg_gen_shli_i64(ret, arg, ofs);
2756 tcg_gen_ext8u_i64(ret, ret);
2757 return;
2758 }
2759 break;
2760 }
2761 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2762 tcg_gen_shli_i64(ret, ret, ofs);
2763 }
2764 }
2765
tcg_gen_extract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)2766 void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
2767 unsigned int ofs, unsigned int len)
2768 {
2769 tcg_debug_assert(ofs < 64);
2770 tcg_debug_assert(len > 0);
2771 tcg_debug_assert(len <= 64);
2772 tcg_debug_assert(ofs + len <= 64);
2773
2774 /* Canonicalize certain special cases, even if extract is supported. */
2775 if (ofs + len == 64) {
2776 tcg_gen_shri_i64(ret, arg, 64 - len);
2777 return;
2778 }
2779 if (ofs == 0) {
2780 tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
2781 return;
2782 }
2783
2784 if (TCG_TARGET_REG_BITS == 32) {
2785 /* Look for a 32-bit extract within one of the two words. */
2786 if (ofs >= 32) {
2787 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2788 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2789 return;
2790 }
2791 if (ofs + len <= 32) {
2792 tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2793 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
2794 return;
2795 }
2796 /* The field is split across two words. One double-word
2797 shift is better than two double-word shifts. */
2798 goto do_shift_and;
2799 }
2800
2801 if (TCG_TARGET_HAS_extract_i64
2802 && TCG_TARGET_extract_i64_valid(ofs, len)) {
2803 tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
2804 return;
2805 }
2806
2807 /* Assume that zero-extension, if available, is cheaper than a shift. */
2808 switch (ofs + len) {
2809 case 32:
2810 if (TCG_TARGET_HAS_ext32u_i64) {
2811 tcg_gen_ext32u_i64(ret, arg);
2812 tcg_gen_shri_i64(ret, ret, ofs);
2813 return;
2814 }
2815 break;
2816 case 16:
2817 if (TCG_TARGET_HAS_ext16u_i64) {
2818 tcg_gen_ext16u_i64(ret, arg);
2819 tcg_gen_shri_i64(ret, ret, ofs);
2820 return;
2821 }
2822 break;
2823 case 8:
2824 if (TCG_TARGET_HAS_ext8u_i64) {
2825 tcg_gen_ext8u_i64(ret, arg);
2826 tcg_gen_shri_i64(ret, ret, ofs);
2827 return;
2828 }
2829 break;
2830 }
2831
2832 /* ??? Ideally we'd know what values are available for immediate AND.
2833 Assume that 8 bits are available, plus the special cases of 16 and 32,
2834 so that we get ext8u, ext16u, and ext32u. */
2835 switch (len) {
2836 case 1 ... 8: case 16: case 32:
2837 do_shift_and:
2838 tcg_gen_shri_i64(ret, arg, ofs);
2839 tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
2840 break;
2841 default:
2842 tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2843 tcg_gen_shri_i64(ret, ret, 64 - len);
2844 break;
2845 }
2846 }
2847
tcg_gen_sextract_i64(TCGv_i64 ret,TCGv_i64 arg,unsigned int ofs,unsigned int len)2848 void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
2849 unsigned int ofs, unsigned int len)
2850 {
2851 tcg_debug_assert(ofs < 64);
2852 tcg_debug_assert(len > 0);
2853 tcg_debug_assert(len <= 64);
2854 tcg_debug_assert(ofs + len <= 64);
2855
2856 /* Canonicalize certain special cases, even if sextract is supported. */
2857 if (ofs + len == 64) {
2858 tcg_gen_sari_i64(ret, arg, 64 - len);
2859 return;
2860 }
2861 if (ofs == 0) {
2862 switch (len) {
2863 case 32:
2864 tcg_gen_ext32s_i64(ret, arg);
2865 return;
2866 case 16:
2867 tcg_gen_ext16s_i64(ret, arg);
2868 return;
2869 case 8:
2870 tcg_gen_ext8s_i64(ret, arg);
2871 return;
2872 }
2873 }
2874
2875 if (TCG_TARGET_REG_BITS == 32) {
2876 /* Look for a 32-bit extract within one of the two words. */
2877 if (ofs >= 32) {
2878 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_HIGH(arg), ofs - 32, len);
2879 } else if (ofs + len <= 32) {
2880 tcg_gen_sextract_i32(TCGV_LOW(ret), TCGV_LOW(arg), ofs, len);
2881 } else if (ofs == 0) {
2882 tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
2883 tcg_gen_sextract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg), 0, len - 32);
2884 return;
2885 } else if (len > 32) {
2886 TCGv_i32 t = tcg_temp_ebb_new_i32();
2887 /* Extract the bits for the high word normally. */
2888 tcg_gen_sextract_i32(t, TCGV_HIGH(arg), ofs + 32, len - 32);
2889 /* Shift the field down for the low part. */
2890 tcg_gen_shri_i64(ret, arg, ofs);
2891 /* Overwrite the shift into the high part. */
2892 tcg_gen_mov_i32(TCGV_HIGH(ret), t);
2893 tcg_temp_free_i32(t);
2894 return;
2895 } else {
2896 /* Shift the field down for the low part, such that the
2897 field sits at the MSB. */
2898 tcg_gen_shri_i64(ret, arg, ofs + len - 32);
2899 /* Shift the field down from the MSB, sign extending. */
2900 tcg_gen_sari_i32(TCGV_LOW(ret), TCGV_LOW(ret), 32 - len);
2901 }
2902 /* Sign-extend the field from 32 bits. */
2903 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
2904 return;
2905 }
2906
2907 if (TCG_TARGET_HAS_sextract_i64
2908 && TCG_TARGET_extract_i64_valid(ofs, len)) {
2909 tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, ofs, len);
2910 return;
2911 }
2912
2913 /* Assume that sign-extension, if available, is cheaper than a shift. */
2914 switch (ofs + len) {
2915 case 32:
2916 if (TCG_TARGET_HAS_ext32s_i64) {
2917 tcg_gen_ext32s_i64(ret, arg);
2918 tcg_gen_sari_i64(ret, ret, ofs);
2919 return;
2920 }
2921 break;
2922 case 16:
2923 if (TCG_TARGET_HAS_ext16s_i64) {
2924 tcg_gen_ext16s_i64(ret, arg);
2925 tcg_gen_sari_i64(ret, ret, ofs);
2926 return;
2927 }
2928 break;
2929 case 8:
2930 if (TCG_TARGET_HAS_ext8s_i64) {
2931 tcg_gen_ext8s_i64(ret, arg);
2932 tcg_gen_sari_i64(ret, ret, ofs);
2933 return;
2934 }
2935 break;
2936 }
2937 switch (len) {
2938 case 32:
2939 if (TCG_TARGET_HAS_ext32s_i64) {
2940 tcg_gen_shri_i64(ret, arg, ofs);
2941 tcg_gen_ext32s_i64(ret, ret);
2942 return;
2943 }
2944 break;
2945 case 16:
2946 if (TCG_TARGET_HAS_ext16s_i64) {
2947 tcg_gen_shri_i64(ret, arg, ofs);
2948 tcg_gen_ext16s_i64(ret, ret);
2949 return;
2950 }
2951 break;
2952 case 8:
2953 if (TCG_TARGET_HAS_ext8s_i64) {
2954 tcg_gen_shri_i64(ret, arg, ofs);
2955 tcg_gen_ext8s_i64(ret, ret);
2956 return;
2957 }
2958 break;
2959 }
2960 tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
2961 tcg_gen_sari_i64(ret, ret, 64 - len);
2962 }
2963
2964 /*
2965 * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
2966 * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
2967 */
tcg_gen_extract2_i64(TCGv_i64 ret,TCGv_i64 al,TCGv_i64 ah,unsigned int ofs)2968 void tcg_gen_extract2_i64(TCGv_i64 ret, TCGv_i64 al, TCGv_i64 ah,
2969 unsigned int ofs)
2970 {
2971 tcg_debug_assert(ofs <= 64);
2972 if (ofs == 0) {
2973 tcg_gen_mov_i64(ret, al);
2974 } else if (ofs == 64) {
2975 tcg_gen_mov_i64(ret, ah);
2976 } else if (al == ah) {
2977 tcg_gen_rotri_i64(ret, al, ofs);
2978 } else if (TCG_TARGET_HAS_extract2_i64) {
2979 tcg_gen_op4i_i64(INDEX_op_extract2_i64, ret, al, ah, ofs);
2980 } else {
2981 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
2982 tcg_gen_shri_i64(t0, al, ofs);
2983 tcg_gen_deposit_i64(ret, t0, ah, 64 - ofs, ofs);
2984 tcg_temp_free_i64(t0);
2985 }
2986 }
2987
tcg_gen_movcond_i64(TCGCond cond,TCGv_i64 ret,TCGv_i64 c1,TCGv_i64 c2,TCGv_i64 v1,TCGv_i64 v2)2988 void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret, TCGv_i64 c1,
2989 TCGv_i64 c2, TCGv_i64 v1, TCGv_i64 v2)
2990 {
2991 if (cond == TCG_COND_ALWAYS) {
2992 tcg_gen_mov_i64(ret, v1);
2993 } else if (cond == TCG_COND_NEVER) {
2994 tcg_gen_mov_i64(ret, v2);
2995 } else if (TCG_TARGET_REG_BITS == 64) {
2996 tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
2997 } else {
2998 TCGv_i32 t0 = tcg_temp_ebb_new_i32();
2999 TCGv_i32 zero = tcg_constant_i32(0);
3000
3001 tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
3002 TCGV_LOW(c1), TCGV_HIGH(c1),
3003 TCGV_LOW(c2), TCGV_HIGH(c2), cond);
3004
3005 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, zero,
3006 TCGV_LOW(v1), TCGV_LOW(v2));
3007 tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, zero,
3008 TCGV_HIGH(v1), TCGV_HIGH(v2));
3009
3010 tcg_temp_free_i32(t0);
3011 }
3012 }
3013
tcg_gen_add2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3014 void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3015 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3016 {
3017 if (TCG_TARGET_HAS_add2_i64) {
3018 tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
3019 } else {
3020 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3021 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3022 tcg_gen_add_i64(t0, al, bl);
3023 tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
3024 tcg_gen_add_i64(rh, ah, bh);
3025 tcg_gen_add_i64(rh, rh, t1);
3026 tcg_gen_mov_i64(rl, t0);
3027 tcg_temp_free_i64(t0);
3028 tcg_temp_free_i64(t1);
3029 }
3030 }
3031
tcg_gen_sub2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 al,TCGv_i64 ah,TCGv_i64 bl,TCGv_i64 bh)3032 void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
3033 TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
3034 {
3035 if (TCG_TARGET_HAS_sub2_i64) {
3036 tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
3037 } else {
3038 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3039 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3040 tcg_gen_sub_i64(t0, al, bl);
3041 tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
3042 tcg_gen_sub_i64(rh, ah, bh);
3043 tcg_gen_sub_i64(rh, rh, t1);
3044 tcg_gen_mov_i64(rl, t0);
3045 tcg_temp_free_i64(t0);
3046 tcg_temp_free_i64(t1);
3047 }
3048 }
3049
tcg_gen_mulu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3050 void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3051 {
3052 if (TCG_TARGET_HAS_mulu2_i64) {
3053 tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
3054 } else if (TCG_TARGET_HAS_muluh_i64) {
3055 TCGv_i64 t = tcg_temp_ebb_new_i64();
3056 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3057 tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
3058 tcg_gen_mov_i64(rl, t);
3059 tcg_temp_free_i64(t);
3060 } else {
3061 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3062 tcg_gen_mul_i64(t0, arg1, arg2);
3063 gen_helper_muluh_i64(rh, arg1, arg2);
3064 tcg_gen_mov_i64(rl, t0);
3065 tcg_temp_free_i64(t0);
3066 }
3067 }
3068
tcg_gen_muls2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3069 void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3070 {
3071 if (TCG_TARGET_HAS_muls2_i64) {
3072 tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
3073 } else if (TCG_TARGET_HAS_mulsh_i64) {
3074 TCGv_i64 t = tcg_temp_ebb_new_i64();
3075 tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
3076 tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
3077 tcg_gen_mov_i64(rl, t);
3078 tcg_temp_free_i64(t);
3079 } else if (TCG_TARGET_HAS_mulu2_i64 || TCG_TARGET_HAS_muluh_i64) {
3080 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3081 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3082 TCGv_i64 t2 = tcg_temp_ebb_new_i64();
3083 TCGv_i64 t3 = tcg_temp_ebb_new_i64();
3084 tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
3085 /* Adjust for negative inputs. */
3086 tcg_gen_sari_i64(t2, arg1, 63);
3087 tcg_gen_sari_i64(t3, arg2, 63);
3088 tcg_gen_and_i64(t2, t2, arg2);
3089 tcg_gen_and_i64(t3, t3, arg1);
3090 tcg_gen_sub_i64(rh, t1, t2);
3091 tcg_gen_sub_i64(rh, rh, t3);
3092 tcg_gen_mov_i64(rl, t0);
3093 tcg_temp_free_i64(t0);
3094 tcg_temp_free_i64(t1);
3095 tcg_temp_free_i64(t2);
3096 tcg_temp_free_i64(t3);
3097 } else {
3098 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3099 tcg_gen_mul_i64(t0, arg1, arg2);
3100 gen_helper_mulsh_i64(rh, arg1, arg2);
3101 tcg_gen_mov_i64(rl, t0);
3102 tcg_temp_free_i64(t0);
3103 }
3104 }
3105
tcg_gen_mulsu2_i64(TCGv_i64 rl,TCGv_i64 rh,TCGv_i64 arg1,TCGv_i64 arg2)3106 void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
3107 {
3108 TCGv_i64 t0 = tcg_temp_ebb_new_i64();
3109 TCGv_i64 t1 = tcg_temp_ebb_new_i64();
3110 TCGv_i64 t2 = tcg_temp_ebb_new_i64();
3111 tcg_gen_mulu2_i64(t0, t1, arg1, arg2);
3112 /* Adjust for negative input for the signed arg1. */
3113 tcg_gen_sari_i64(t2, arg1, 63);
3114 tcg_gen_and_i64(t2, t2, arg2);
3115 tcg_gen_sub_i64(rh, t1, t2);
3116 tcg_gen_mov_i64(rl, t0);
3117 tcg_temp_free_i64(t0);
3118 tcg_temp_free_i64(t1);
3119 tcg_temp_free_i64(t2);
3120 }
3121
tcg_gen_smin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3122 void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3123 {
3124 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
3125 }
3126
tcg_gen_umin_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3127 void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3128 {
3129 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
3130 }
3131
tcg_gen_smax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3132 void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3133 {
3134 tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
3135 }
3136
tcg_gen_umax_i64(TCGv_i64 ret,TCGv_i64 a,TCGv_i64 b)3137 void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
3138 {
3139 tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
3140 }
3141
tcg_gen_abs_i64(TCGv_i64 ret,TCGv_i64 a)3142 void tcg_gen_abs_i64(TCGv_i64 ret, TCGv_i64 a)
3143 {
3144 TCGv_i64 t = tcg_temp_ebb_new_i64();
3145
3146 tcg_gen_sari_i64(t, a, 63);
3147 tcg_gen_xor_i64(ret, a, t);
3148 tcg_gen_sub_i64(ret, ret, t);
3149 tcg_temp_free_i64(t);
3150 }
3151
3152 /* Size changing operations. */
3153
tcg_gen_extrl_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3154 void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3155 {
3156 if (TCG_TARGET_REG_BITS == 32) {
3157 tcg_gen_mov_i32(ret, TCGV_LOW(arg));
3158 } else if (TCG_TARGET_HAS_extr_i64_i32) {
3159 tcg_gen_op2(INDEX_op_extrl_i64_i32,
3160 tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3161 } else {
3162 tcg_gen_mov_i32(ret, (TCGv_i32)arg);
3163 }
3164 }
3165
tcg_gen_extrh_i64_i32(TCGv_i32 ret,TCGv_i64 arg)3166 void tcg_gen_extrh_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
3167 {
3168 if (TCG_TARGET_REG_BITS == 32) {
3169 tcg_gen_mov_i32(ret, TCGV_HIGH(arg));
3170 } else if (TCG_TARGET_HAS_extr_i64_i32) {
3171 tcg_gen_op2(INDEX_op_extrh_i64_i32,
3172 tcgv_i32_arg(ret), tcgv_i64_arg(arg));
3173 } else {
3174 TCGv_i64 t = tcg_temp_ebb_new_i64();
3175 tcg_gen_shri_i64(t, arg, 32);
3176 tcg_gen_mov_i32(ret, (TCGv_i32)t);
3177 tcg_temp_free_i64(t);
3178 }
3179 }
3180
tcg_gen_extu_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3181 void tcg_gen_extu_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3182 {
3183 if (TCG_TARGET_REG_BITS == 32) {
3184 tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3185 tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
3186 } else {
3187 tcg_gen_op2(INDEX_op_extu_i32_i64,
3188 tcgv_i64_arg(ret), tcgv_i32_arg(arg));
3189 }
3190 }
3191
tcg_gen_ext_i32_i64(TCGv_i64 ret,TCGv_i32 arg)3192 void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
3193 {
3194 if (TCG_TARGET_REG_BITS == 32) {
3195 tcg_gen_mov_i32(TCGV_LOW(ret), arg);
3196 tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
3197 } else {
3198 tcg_gen_op2(INDEX_op_ext_i32_i64,
3199 tcgv_i64_arg(ret), tcgv_i32_arg(arg));
3200 }
3201 }
3202
tcg_gen_concat_i32_i64(TCGv_i64 dest,TCGv_i32 low,TCGv_i32 high)3203 void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
3204 {
3205 TCGv_i64 tmp;
3206
3207 if (TCG_TARGET_REG_BITS == 32) {
3208 tcg_gen_mov_i32(TCGV_LOW(dest), low);
3209 tcg_gen_mov_i32(TCGV_HIGH(dest), high);
3210 return;
3211 }
3212
3213 tmp = tcg_temp_ebb_new_i64();
3214 /* These extensions are only needed for type correctness.
3215 We may be able to do better given target specific information. */
3216 tcg_gen_extu_i32_i64(tmp, high);
3217 tcg_gen_extu_i32_i64(dest, low);
3218 /* If deposit is available, use it. Otherwise use the extra
3219 knowledge that we have of the zero-extensions above. */
3220 if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
3221 tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
3222 } else {
3223 tcg_gen_shli_i64(tmp, tmp, 32);
3224 tcg_gen_or_i64(dest, dest, tmp);
3225 }
3226 tcg_temp_free_i64(tmp);
3227 }
3228
tcg_gen_extr_i64_i32(TCGv_i32 lo,TCGv_i32 hi,TCGv_i64 arg)3229 void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
3230 {
3231 if (TCG_TARGET_REG_BITS == 32) {
3232 tcg_gen_mov_i32(lo, TCGV_LOW(arg));
3233 tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
3234 } else {
3235 tcg_gen_extrl_i64_i32(lo, arg);
3236 tcg_gen_extrh_i64_i32(hi, arg);
3237 }
3238 }
3239
tcg_gen_extr32_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i64 arg)3240 void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
3241 {
3242 tcg_gen_ext32u_i64(lo, arg);
3243 tcg_gen_shri_i64(hi, arg, 32);
3244 }
3245
tcg_gen_concat32_i64(TCGv_i64 ret,TCGv_i64 lo,TCGv_i64 hi)3246 void tcg_gen_concat32_i64(TCGv_i64 ret, TCGv_i64 lo, TCGv_i64 hi)
3247 {
3248 tcg_gen_deposit_i64(ret, lo, hi, 32, 32);
3249 }
3250
tcg_gen_extr_i128_i64(TCGv_i64 lo,TCGv_i64 hi,TCGv_i128 arg)3251 void tcg_gen_extr_i128_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i128 arg)
3252 {
3253 tcg_gen_mov_i64(lo, TCGV128_LOW(arg));
3254 tcg_gen_mov_i64(hi, TCGV128_HIGH(arg));
3255 }
3256
tcg_gen_concat_i64_i128(TCGv_i128 ret,TCGv_i64 lo,TCGv_i64 hi)3257 void tcg_gen_concat_i64_i128(TCGv_i128 ret, TCGv_i64 lo, TCGv_i64 hi)
3258 {
3259 tcg_gen_mov_i64(TCGV128_LOW(ret), lo);
3260 tcg_gen_mov_i64(TCGV128_HIGH(ret), hi);
3261 }
3262
tcg_gen_mov_i128(TCGv_i128 dst,TCGv_i128 src)3263 void tcg_gen_mov_i128(TCGv_i128 dst, TCGv_i128 src)
3264 {
3265 if (dst != src) {
3266 tcg_gen_mov_i64(TCGV128_LOW(dst), TCGV128_LOW(src));
3267 tcg_gen_mov_i64(TCGV128_HIGH(dst), TCGV128_HIGH(src));
3268 }
3269 }
3270
tcg_gen_ld_i128(TCGv_i128 ret,TCGv_ptr base,tcg_target_long offset)3271 void tcg_gen_ld_i128(TCGv_i128 ret, TCGv_ptr base, tcg_target_long offset)
3272 {
3273 if (HOST_BIG_ENDIAN) {
3274 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset);
3275 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset + 8);
3276 } else {
3277 tcg_gen_ld_i64(TCGV128_LOW(ret), base, offset);
3278 tcg_gen_ld_i64(TCGV128_HIGH(ret), base, offset + 8);
3279 }
3280 }
3281
tcg_gen_st_i128(TCGv_i128 val,TCGv_ptr base,tcg_target_long offset)3282 void tcg_gen_st_i128(TCGv_i128 val, TCGv_ptr base, tcg_target_long offset)
3283 {
3284 if (HOST_BIG_ENDIAN) {
3285 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset);
3286 tcg_gen_st_i64(TCGV128_LOW(val), base, offset + 8);
3287 } else {
3288 tcg_gen_st_i64(TCGV128_LOW(val), base, offset);
3289 tcg_gen_st_i64(TCGV128_HIGH(val), base, offset + 8);
3290 }
3291 }
3292
3293 /* QEMU specific operations. */
3294
tcg_gen_exit_tb(const TranslationBlock * tb,unsigned idx)3295 void tcg_gen_exit_tb(const TranslationBlock *tb, unsigned idx)
3296 {
3297 /*
3298 * Let the jit code return the read-only version of the
3299 * TranslationBlock, so that we minimize the pc-relative
3300 * distance of the address of the exit_tb code to TB.
3301 * This will improve utilization of pc-relative address loads.
3302 *
3303 * TODO: Move this to translator_loop, so that all const
3304 * TranslationBlock pointers refer to read-only memory.
3305 * This requires coordination with targets that do not use
3306 * the translator_loop.
3307 */
3308 uintptr_t val = (uintptr_t)tcg_splitwx_to_rx((void *)tb) + idx;
3309
3310 if (tb == NULL) {
3311 tcg_debug_assert(idx == 0);
3312 } else if (idx <= TB_EXIT_IDXMAX) {
3313 #ifdef CONFIG_DEBUG_TCG
3314 /* This is an exit following a goto_tb. Verify that we have
3315 seen this numbered exit before, via tcg_gen_goto_tb. */
3316 tcg_debug_assert(tcg_ctx->goto_tb_issue_mask & (1 << idx));
3317 #endif
3318 } else {
3319 /* This is an exit via the exitreq label. */
3320 tcg_debug_assert(idx == TB_EXIT_REQUESTED);
3321 }
3322
3323 tcg_gen_op1i(INDEX_op_exit_tb, val);
3324 }
3325
tcg_gen_goto_tb(unsigned idx)3326 void tcg_gen_goto_tb(unsigned idx)
3327 {
3328 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
3329 tcg_debug_assert(!(tcg_ctx->gen_tb->cflags & CF_NO_GOTO_TB));
3330 /* We only support two chained exits. */
3331 tcg_debug_assert(idx <= TB_EXIT_IDXMAX);
3332 #ifdef CONFIG_DEBUG_TCG
3333 /* Verify that we haven't seen this numbered exit before. */
3334 tcg_debug_assert((tcg_ctx->goto_tb_issue_mask & (1 << idx)) == 0);
3335 tcg_ctx->goto_tb_issue_mask |= 1 << idx;
3336 #endif
3337 plugin_gen_disable_mem_helpers();
3338 tcg_gen_op1i(INDEX_op_goto_tb, idx);
3339 }
3340
tcg_gen_lookup_and_goto_ptr(void)3341 void tcg_gen_lookup_and_goto_ptr(void)
3342 {
3343 TCGv_ptr ptr;
3344
3345 if (tcg_ctx->gen_tb->cflags & CF_NO_GOTO_PTR) {
3346 tcg_gen_exit_tb(NULL, 0);
3347 return;
3348 }
3349
3350 plugin_gen_disable_mem_helpers();
3351 ptr = tcg_temp_ebb_new_ptr();
3352 gen_helper_lookup_tb_ptr(ptr, tcg_env);
3353 tcg_gen_op1i(INDEX_op_goto_ptr, tcgv_ptr_arg(ptr));
3354 tcg_temp_free_ptr(ptr);
3355 }
3356