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