2 * Tiny Code Generator for QEMU
4 * Copyright (c) 2008 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 #include "qemu/osdep.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"
34 void tcg_gen_op1(TCGOpcode opc
, TCGArg a1
)
36 TCGOp
*op
= tcg_emit_op(opc
, 1);
40 void tcg_gen_op2(TCGOpcode opc
, TCGArg a1
, TCGArg a2
)
42 TCGOp
*op
= tcg_emit_op(opc
, 2);
47 void tcg_gen_op3(TCGOpcode opc
, TCGArg a1
, TCGArg a2
, TCGArg a3
)
49 TCGOp
*op
= tcg_emit_op(opc
, 3);
55 void tcg_gen_op4(TCGOpcode opc
, TCGArg a1
, TCGArg a2
, TCGArg a3
, TCGArg a4
)
57 TCGOp
*op
= tcg_emit_op(opc
, 4);
64 void tcg_gen_op5(TCGOpcode opc
, TCGArg a1
, TCGArg a2
, TCGArg a3
,
67 TCGOp
*op
= tcg_emit_op(opc
, 5);
75 void tcg_gen_op6(TCGOpcode opc
, TCGArg a1
, TCGArg a2
, TCGArg a3
,
76 TCGArg a4
, TCGArg a5
, TCGArg a6
)
78 TCGOp
*op
= tcg_emit_op(opc
, 6);
89 static void add_last_as_label_use(TCGLabel
*l
)
91 TCGLabelUse
*u
= tcg_malloc(sizeof(TCGLabelUse
));
93 u
->op
= tcg_last_op();
94 QSIMPLEQ_INSERT_TAIL(&l
->branches
, u
, next
);
97 void tcg_gen_br(TCGLabel
*l
)
99 tcg_gen_op1(INDEX_op_br
, label_arg(l
));
100 add_last_as_label_use(l
);
103 void tcg_gen_mb(TCGBar mb_type
)
105 #ifdef CONFIG_USER_ONLY
106 bool parallel
= tcg_ctx
->gen_tb
->cflags
& CF_PARALLEL
;
109 * It is tempting to elide the barrier in a uniprocessor context.
110 * However, even with a single cpu we have i/o threads running in
111 * parallel, and lack of memory order can result in e.g. virtio
112 * queue entries being read incorrectly.
114 bool parallel
= true;
118 tcg_gen_op1(INDEX_op_mb
, mb_type
);
124 void tcg_gen_movi_i32(TCGv_i32 ret
, int32_t arg
)
126 tcg_gen_mov_i32(ret
, tcg_constant_i32(arg
));
129 void tcg_gen_addi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
131 /* some cases can be optimized here */
133 tcg_gen_mov_i32(ret
, arg1
);
135 tcg_gen_add_i32(ret
, arg1
, tcg_constant_i32(arg2
));
139 void tcg_gen_subfi_i32(TCGv_i32 ret
, int32_t arg1
, TCGv_i32 arg2
)
141 if (arg1
== 0 && TCG_TARGET_HAS_neg_i32
) {
142 /* Don't recurse with tcg_gen_neg_i32. */
143 tcg_gen_op2_i32(INDEX_op_neg_i32
, ret
, arg2
);
145 tcg_gen_sub_i32(ret
, tcg_constant_i32(arg1
), arg2
);
149 void tcg_gen_subi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
151 /* some cases can be optimized here */
153 tcg_gen_mov_i32(ret
, arg1
);
155 tcg_gen_sub_i32(ret
, arg1
, tcg_constant_i32(arg2
));
159 void tcg_gen_andi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
161 /* Some cases can be optimized here. */
164 tcg_gen_movi_i32(ret
, 0);
167 tcg_gen_mov_i32(ret
, arg1
);
170 /* Don't recurse with tcg_gen_ext8u_i32. */
171 if (TCG_TARGET_HAS_ext8u_i32
) {
172 tcg_gen_op2_i32(INDEX_op_ext8u_i32
, ret
, arg1
);
177 if (TCG_TARGET_HAS_ext16u_i32
) {
178 tcg_gen_op2_i32(INDEX_op_ext16u_i32
, ret
, arg1
);
184 tcg_gen_and_i32(ret
, arg1
, tcg_constant_i32(arg2
));
187 void tcg_gen_ori_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
189 /* Some cases can be optimized here. */
191 tcg_gen_movi_i32(ret
, -1);
192 } else if (arg2
== 0) {
193 tcg_gen_mov_i32(ret
, arg1
);
195 tcg_gen_or_i32(ret
, arg1
, tcg_constant_i32(arg2
));
199 void tcg_gen_xori_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
201 /* Some cases can be optimized here. */
203 tcg_gen_mov_i32(ret
, arg1
);
204 } else if (arg2
== -1 && TCG_TARGET_HAS_not_i32
) {
205 /* Don't recurse with tcg_gen_not_i32. */
206 tcg_gen_op2_i32(INDEX_op_not_i32
, ret
, arg1
);
208 tcg_gen_xor_i32(ret
, arg1
, tcg_constant_i32(arg2
));
212 void tcg_gen_shli_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
214 tcg_debug_assert(arg2
>= 0 && arg2
< 32);
216 tcg_gen_mov_i32(ret
, arg1
);
218 tcg_gen_shl_i32(ret
, arg1
, tcg_constant_i32(arg2
));
222 void tcg_gen_shri_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
224 tcg_debug_assert(arg2
>= 0 && arg2
< 32);
226 tcg_gen_mov_i32(ret
, arg1
);
228 tcg_gen_shr_i32(ret
, arg1
, tcg_constant_i32(arg2
));
232 void tcg_gen_sari_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
234 tcg_debug_assert(arg2
>= 0 && arg2
< 32);
236 tcg_gen_mov_i32(ret
, arg1
);
238 tcg_gen_sar_i32(ret
, arg1
, tcg_constant_i32(arg2
));
242 void tcg_gen_brcond_i32(TCGCond cond
, TCGv_i32 arg1
, TCGv_i32 arg2
, TCGLabel
*l
)
244 if (cond
== TCG_COND_ALWAYS
) {
246 } else if (cond
!= TCG_COND_NEVER
) {
247 tcg_gen_op4ii_i32(INDEX_op_brcond_i32
, arg1
, arg2
, cond
, label_arg(l
));
248 add_last_as_label_use(l
);
252 void tcg_gen_brcondi_i32(TCGCond cond
, TCGv_i32 arg1
, int32_t arg2
, TCGLabel
*l
)
254 if (cond
== TCG_COND_ALWAYS
) {
256 } else if (cond
!= TCG_COND_NEVER
) {
257 tcg_gen_brcond_i32(cond
, arg1
, tcg_constant_i32(arg2
), l
);
261 void tcg_gen_setcond_i32(TCGCond cond
, TCGv_i32 ret
,
262 TCGv_i32 arg1
, TCGv_i32 arg2
)
264 if (cond
== TCG_COND_ALWAYS
) {
265 tcg_gen_movi_i32(ret
, 1);
266 } else if (cond
== TCG_COND_NEVER
) {
267 tcg_gen_movi_i32(ret
, 0);
269 tcg_gen_op4i_i32(INDEX_op_setcond_i32
, ret
, arg1
, arg2
, cond
);
273 void tcg_gen_setcondi_i32(TCGCond cond
, TCGv_i32 ret
,
274 TCGv_i32 arg1
, int32_t arg2
)
276 tcg_gen_setcond_i32(cond
, ret
, arg1
, tcg_constant_i32(arg2
));
279 void tcg_gen_negsetcond_i32(TCGCond cond
, TCGv_i32 ret
,
280 TCGv_i32 arg1
, TCGv_i32 arg2
)
282 if (cond
== TCG_COND_ALWAYS
) {
283 tcg_gen_movi_i32(ret
, -1);
284 } else if (cond
== TCG_COND_NEVER
) {
285 tcg_gen_movi_i32(ret
, 0);
286 } else if (TCG_TARGET_HAS_negsetcond_i32
) {
287 tcg_gen_op4i_i32(INDEX_op_negsetcond_i32
, ret
, arg1
, arg2
, cond
);
289 tcg_gen_setcond_i32(cond
, ret
, arg1
, arg2
);
290 tcg_gen_neg_i32(ret
, ret
);
294 void tcg_gen_negsetcondi_i32(TCGCond cond
, TCGv_i32 ret
,
295 TCGv_i32 arg1
, int32_t arg2
)
297 tcg_gen_negsetcond_i32(cond
, ret
, arg1
, tcg_constant_i32(arg2
));
300 void tcg_gen_muli_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
303 tcg_gen_movi_i32(ret
, 0);
304 } else if (is_power_of_2(arg2
)) {
305 tcg_gen_shli_i32(ret
, arg1
, ctz32(arg2
));
307 tcg_gen_mul_i32(ret
, arg1
, tcg_constant_i32(arg2
));
311 void tcg_gen_div_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
313 if (TCG_TARGET_HAS_div_i32
) {
314 tcg_gen_op3_i32(INDEX_op_div_i32
, ret
, arg1
, arg2
);
315 } else if (TCG_TARGET_HAS_div2_i32
) {
316 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
317 tcg_gen_sari_i32(t0
, arg1
, 31);
318 tcg_gen_op5_i32(INDEX_op_div2_i32
, ret
, t0
, arg1
, t0
, arg2
);
319 tcg_temp_free_i32(t0
);
321 gen_helper_div_i32(ret
, arg1
, arg2
);
325 void tcg_gen_rem_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
327 if (TCG_TARGET_HAS_rem_i32
) {
328 tcg_gen_op3_i32(INDEX_op_rem_i32
, ret
, arg1
, arg2
);
329 } else if (TCG_TARGET_HAS_div_i32
) {
330 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
331 tcg_gen_op3_i32(INDEX_op_div_i32
, t0
, arg1
, arg2
);
332 tcg_gen_mul_i32(t0
, t0
, arg2
);
333 tcg_gen_sub_i32(ret
, arg1
, t0
);
334 tcg_temp_free_i32(t0
);
335 } else if (TCG_TARGET_HAS_div2_i32
) {
336 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
337 tcg_gen_sari_i32(t0
, arg1
, 31);
338 tcg_gen_op5_i32(INDEX_op_div2_i32
, t0
, ret
, arg1
, t0
, arg2
);
339 tcg_temp_free_i32(t0
);
341 gen_helper_rem_i32(ret
, arg1
, arg2
);
345 void tcg_gen_divu_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
347 if (TCG_TARGET_HAS_div_i32
) {
348 tcg_gen_op3_i32(INDEX_op_divu_i32
, ret
, arg1
, arg2
);
349 } else if (TCG_TARGET_HAS_div2_i32
) {
350 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
351 TCGv_i32 zero
= tcg_constant_i32(0);
352 tcg_gen_op5_i32(INDEX_op_divu2_i32
, ret
, t0
, arg1
, zero
, arg2
);
353 tcg_temp_free_i32(t0
);
355 gen_helper_divu_i32(ret
, arg1
, arg2
);
359 void tcg_gen_remu_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
361 if (TCG_TARGET_HAS_rem_i32
) {
362 tcg_gen_op3_i32(INDEX_op_remu_i32
, ret
, arg1
, arg2
);
363 } else if (TCG_TARGET_HAS_div_i32
) {
364 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
365 tcg_gen_op3_i32(INDEX_op_divu_i32
, t0
, arg1
, arg2
);
366 tcg_gen_mul_i32(t0
, t0
, arg2
);
367 tcg_gen_sub_i32(ret
, arg1
, t0
);
368 tcg_temp_free_i32(t0
);
369 } else if (TCG_TARGET_HAS_div2_i32
) {
370 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
371 TCGv_i32 zero
= tcg_constant_i32(0);
372 tcg_gen_op5_i32(INDEX_op_divu2_i32
, t0
, ret
, arg1
, zero
, arg2
);
373 tcg_temp_free_i32(t0
);
375 gen_helper_remu_i32(ret
, arg1
, arg2
);
379 void tcg_gen_andc_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
381 if (TCG_TARGET_HAS_andc_i32
) {
382 tcg_gen_op3_i32(INDEX_op_andc_i32
, ret
, arg1
, arg2
);
384 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
385 tcg_gen_not_i32(t0
, arg2
);
386 tcg_gen_and_i32(ret
, arg1
, t0
);
387 tcg_temp_free_i32(t0
);
391 void tcg_gen_eqv_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
393 if (TCG_TARGET_HAS_eqv_i32
) {
394 tcg_gen_op3_i32(INDEX_op_eqv_i32
, ret
, arg1
, arg2
);
396 tcg_gen_xor_i32(ret
, arg1
, arg2
);
397 tcg_gen_not_i32(ret
, ret
);
401 void tcg_gen_nand_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
403 if (TCG_TARGET_HAS_nand_i32
) {
404 tcg_gen_op3_i32(INDEX_op_nand_i32
, ret
, arg1
, arg2
);
406 tcg_gen_and_i32(ret
, arg1
, arg2
);
407 tcg_gen_not_i32(ret
, ret
);
411 void tcg_gen_nor_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
413 if (TCG_TARGET_HAS_nor_i32
) {
414 tcg_gen_op3_i32(INDEX_op_nor_i32
, ret
, arg1
, arg2
);
416 tcg_gen_or_i32(ret
, arg1
, arg2
);
417 tcg_gen_not_i32(ret
, ret
);
421 void tcg_gen_orc_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
423 if (TCG_TARGET_HAS_orc_i32
) {
424 tcg_gen_op3_i32(INDEX_op_orc_i32
, ret
, arg1
, arg2
);
426 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
427 tcg_gen_not_i32(t0
, arg2
);
428 tcg_gen_or_i32(ret
, arg1
, t0
);
429 tcg_temp_free_i32(t0
);
433 void tcg_gen_clz_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
435 if (TCG_TARGET_HAS_clz_i32
) {
436 tcg_gen_op3_i32(INDEX_op_clz_i32
, ret
, arg1
, arg2
);
437 } else if (TCG_TARGET_HAS_clz_i64
) {
438 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
439 TCGv_i64 t2
= tcg_temp_ebb_new_i64();
440 tcg_gen_extu_i32_i64(t1
, arg1
);
441 tcg_gen_extu_i32_i64(t2
, arg2
);
442 tcg_gen_addi_i64(t2
, t2
, 32);
443 tcg_gen_clz_i64(t1
, t1
, t2
);
444 tcg_gen_extrl_i64_i32(ret
, t1
);
445 tcg_temp_free_i64(t1
);
446 tcg_temp_free_i64(t2
);
447 tcg_gen_subi_i32(ret
, ret
, 32);
449 gen_helper_clz_i32(ret
, arg1
, arg2
);
453 void tcg_gen_clzi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, uint32_t arg2
)
455 tcg_gen_clz_i32(ret
, arg1
, tcg_constant_i32(arg2
));
458 void tcg_gen_ctz_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
460 if (TCG_TARGET_HAS_ctz_i32
) {
461 tcg_gen_op3_i32(INDEX_op_ctz_i32
, ret
, arg1
, arg2
);
462 } else if (TCG_TARGET_HAS_ctz_i64
) {
463 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
464 TCGv_i64 t2
= tcg_temp_ebb_new_i64();
465 tcg_gen_extu_i32_i64(t1
, arg1
);
466 tcg_gen_extu_i32_i64(t2
, arg2
);
467 tcg_gen_ctz_i64(t1
, t1
, t2
);
468 tcg_gen_extrl_i64_i32(ret
, t1
);
469 tcg_temp_free_i64(t1
);
470 tcg_temp_free_i64(t2
);
471 } else if (TCG_TARGET_HAS_ctpop_i32
472 || TCG_TARGET_HAS_ctpop_i64
473 || TCG_TARGET_HAS_clz_i32
474 || TCG_TARGET_HAS_clz_i64
) {
475 TCGv_i32 z
, t
= tcg_temp_ebb_new_i32();
477 if (TCG_TARGET_HAS_ctpop_i32
|| TCG_TARGET_HAS_ctpop_i64
) {
478 tcg_gen_subi_i32(t
, arg1
, 1);
479 tcg_gen_andc_i32(t
, t
, arg1
);
480 tcg_gen_ctpop_i32(t
, t
);
482 /* Since all non-x86 hosts have clz(0) == 32, don't fight it. */
483 tcg_gen_neg_i32(t
, arg1
);
484 tcg_gen_and_i32(t
, t
, arg1
);
485 tcg_gen_clzi_i32(t
, t
, 32);
486 tcg_gen_xori_i32(t
, t
, 31);
488 z
= tcg_constant_i32(0);
489 tcg_gen_movcond_i32(TCG_COND_EQ
, ret
, arg1
, z
, arg2
, t
);
490 tcg_temp_free_i32(t
);
492 gen_helper_ctz_i32(ret
, arg1
, arg2
);
496 void tcg_gen_ctzi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, uint32_t arg2
)
498 if (!TCG_TARGET_HAS_ctz_i32
&& TCG_TARGET_HAS_ctpop_i32
&& arg2
== 32) {
499 /* This equivalence has the advantage of not requiring a fixup. */
500 TCGv_i32 t
= tcg_temp_ebb_new_i32();
501 tcg_gen_subi_i32(t
, arg1
, 1);
502 tcg_gen_andc_i32(t
, t
, arg1
);
503 tcg_gen_ctpop_i32(ret
, t
);
504 tcg_temp_free_i32(t
);
506 tcg_gen_ctz_i32(ret
, arg1
, tcg_constant_i32(arg2
));
510 void tcg_gen_clrsb_i32(TCGv_i32 ret
, TCGv_i32 arg
)
512 if (TCG_TARGET_HAS_clz_i32
) {
513 TCGv_i32 t
= tcg_temp_ebb_new_i32();
514 tcg_gen_sari_i32(t
, arg
, 31);
515 tcg_gen_xor_i32(t
, t
, arg
);
516 tcg_gen_clzi_i32(t
, t
, 32);
517 tcg_gen_subi_i32(ret
, t
, 1);
518 tcg_temp_free_i32(t
);
520 gen_helper_clrsb_i32(ret
, arg
);
524 void tcg_gen_ctpop_i32(TCGv_i32 ret
, TCGv_i32 arg1
)
526 if (TCG_TARGET_HAS_ctpop_i32
) {
527 tcg_gen_op2_i32(INDEX_op_ctpop_i32
, ret
, arg1
);
528 } else if (TCG_TARGET_HAS_ctpop_i64
) {
529 TCGv_i64 t
= tcg_temp_ebb_new_i64();
530 tcg_gen_extu_i32_i64(t
, arg1
);
531 tcg_gen_ctpop_i64(t
, t
);
532 tcg_gen_extrl_i64_i32(ret
, t
);
533 tcg_temp_free_i64(t
);
535 gen_helper_ctpop_i32(ret
, arg1
);
539 void tcg_gen_rotl_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
541 if (TCG_TARGET_HAS_rot_i32
) {
542 tcg_gen_op3_i32(INDEX_op_rotl_i32
, ret
, arg1
, arg2
);
546 t0
= tcg_temp_ebb_new_i32();
547 t1
= tcg_temp_ebb_new_i32();
548 tcg_gen_shl_i32(t0
, arg1
, arg2
);
549 tcg_gen_subfi_i32(t1
, 32, arg2
);
550 tcg_gen_shr_i32(t1
, arg1
, t1
);
551 tcg_gen_or_i32(ret
, t0
, t1
);
552 tcg_temp_free_i32(t0
);
553 tcg_temp_free_i32(t1
);
557 void tcg_gen_rotli_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
559 tcg_debug_assert(arg2
>= 0 && arg2
< 32);
560 /* some cases can be optimized here */
562 tcg_gen_mov_i32(ret
, arg1
);
563 } else if (TCG_TARGET_HAS_rot_i32
) {
564 tcg_gen_rotl_i32(ret
, arg1
, tcg_constant_i32(arg2
));
567 t0
= tcg_temp_ebb_new_i32();
568 t1
= tcg_temp_ebb_new_i32();
569 tcg_gen_shli_i32(t0
, arg1
, arg2
);
570 tcg_gen_shri_i32(t1
, arg1
, 32 - arg2
);
571 tcg_gen_or_i32(ret
, t0
, t1
);
572 tcg_temp_free_i32(t0
);
573 tcg_temp_free_i32(t1
);
577 void tcg_gen_rotr_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
579 if (TCG_TARGET_HAS_rot_i32
) {
580 tcg_gen_op3_i32(INDEX_op_rotr_i32
, ret
, arg1
, arg2
);
584 t0
= tcg_temp_ebb_new_i32();
585 t1
= tcg_temp_ebb_new_i32();
586 tcg_gen_shr_i32(t0
, arg1
, arg2
);
587 tcg_gen_subfi_i32(t1
, 32, arg2
);
588 tcg_gen_shl_i32(t1
, arg1
, t1
);
589 tcg_gen_or_i32(ret
, t0
, t1
);
590 tcg_temp_free_i32(t0
);
591 tcg_temp_free_i32(t1
);
595 void tcg_gen_rotri_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
597 tcg_debug_assert(arg2
>= 0 && arg2
< 32);
598 /* some cases can be optimized here */
600 tcg_gen_mov_i32(ret
, arg1
);
602 tcg_gen_rotli_i32(ret
, arg1
, 32 - arg2
);
606 void tcg_gen_deposit_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
,
607 unsigned int ofs
, unsigned int len
)
612 tcg_debug_assert(ofs
< 32);
613 tcg_debug_assert(len
> 0);
614 tcg_debug_assert(len
<= 32);
615 tcg_debug_assert(ofs
+ len
<= 32);
618 tcg_gen_mov_i32(ret
, arg2
);
621 if (TCG_TARGET_HAS_deposit_i32
&& TCG_TARGET_deposit_i32_valid(ofs
, len
)) {
622 tcg_gen_op5ii_i32(INDEX_op_deposit_i32
, ret
, arg1
, arg2
, ofs
, len
);
626 t1
= tcg_temp_ebb_new_i32();
628 if (TCG_TARGET_HAS_extract2_i32
) {
629 if (ofs
+ len
== 32) {
630 tcg_gen_shli_i32(t1
, arg1
, len
);
631 tcg_gen_extract2_i32(ret
, t1
, arg2
, len
);
635 tcg_gen_extract2_i32(ret
, arg1
, arg2
, len
);
636 tcg_gen_rotli_i32(ret
, ret
, len
);
641 mask
= (1u << len
) - 1;
642 if (ofs
+ len
< 32) {
643 tcg_gen_andi_i32(t1
, arg2
, mask
);
644 tcg_gen_shli_i32(t1
, t1
, ofs
);
646 tcg_gen_shli_i32(t1
, arg2
, ofs
);
648 tcg_gen_andi_i32(ret
, arg1
, ~(mask
<< ofs
));
649 tcg_gen_or_i32(ret
, ret
, t1
);
651 tcg_temp_free_i32(t1
);
654 void tcg_gen_deposit_z_i32(TCGv_i32 ret
, TCGv_i32 arg
,
655 unsigned int ofs
, unsigned int len
)
657 tcg_debug_assert(ofs
< 32);
658 tcg_debug_assert(len
> 0);
659 tcg_debug_assert(len
<= 32);
660 tcg_debug_assert(ofs
+ len
<= 32);
662 if (ofs
+ len
== 32) {
663 tcg_gen_shli_i32(ret
, arg
, ofs
);
664 } else if (ofs
== 0) {
665 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
666 } else if (TCG_TARGET_HAS_deposit_i32
667 && TCG_TARGET_deposit_i32_valid(ofs
, len
)) {
668 TCGv_i32 zero
= tcg_constant_i32(0);
669 tcg_gen_op5ii_i32(INDEX_op_deposit_i32
, ret
, zero
, arg
, ofs
, len
);
671 /* To help two-operand hosts we prefer to zero-extend first,
672 which allows ARG to stay live. */
675 if (TCG_TARGET_HAS_ext16u_i32
) {
676 tcg_gen_ext16u_i32(ret
, arg
);
677 tcg_gen_shli_i32(ret
, ret
, ofs
);
682 if (TCG_TARGET_HAS_ext8u_i32
) {
683 tcg_gen_ext8u_i32(ret
, arg
);
684 tcg_gen_shli_i32(ret
, ret
, ofs
);
689 /* Otherwise prefer zero-extension over AND for code size. */
692 if (TCG_TARGET_HAS_ext16u_i32
) {
693 tcg_gen_shli_i32(ret
, arg
, ofs
);
694 tcg_gen_ext16u_i32(ret
, ret
);
699 if (TCG_TARGET_HAS_ext8u_i32
) {
700 tcg_gen_shli_i32(ret
, arg
, ofs
);
701 tcg_gen_ext8u_i32(ret
, ret
);
706 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
707 tcg_gen_shli_i32(ret
, ret
, ofs
);
711 void tcg_gen_extract_i32(TCGv_i32 ret
, TCGv_i32 arg
,
712 unsigned int ofs
, unsigned int len
)
714 tcg_debug_assert(ofs
< 32);
715 tcg_debug_assert(len
> 0);
716 tcg_debug_assert(len
<= 32);
717 tcg_debug_assert(ofs
+ len
<= 32);
719 /* Canonicalize certain special cases, even if extract is supported. */
720 if (ofs
+ len
== 32) {
721 tcg_gen_shri_i32(ret
, arg
, 32 - len
);
725 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
729 if (TCG_TARGET_HAS_extract_i32
730 && TCG_TARGET_extract_i32_valid(ofs
, len
)) {
731 tcg_gen_op4ii_i32(INDEX_op_extract_i32
, ret
, arg
, ofs
, len
);
735 /* Assume that zero-extension, if available, is cheaper than a shift. */
738 if (TCG_TARGET_HAS_ext16u_i32
) {
739 tcg_gen_ext16u_i32(ret
, arg
);
740 tcg_gen_shri_i32(ret
, ret
, ofs
);
745 if (TCG_TARGET_HAS_ext8u_i32
) {
746 tcg_gen_ext8u_i32(ret
, arg
);
747 tcg_gen_shri_i32(ret
, ret
, ofs
);
753 /* ??? Ideally we'd know what values are available for immediate AND.
754 Assume that 8 bits are available, plus the special case of 16,
755 so that we get ext8u, ext16u. */
757 case 1 ... 8: case 16:
758 tcg_gen_shri_i32(ret
, arg
, ofs
);
759 tcg_gen_andi_i32(ret
, ret
, (1u << len
) - 1);
762 tcg_gen_shli_i32(ret
, arg
, 32 - len
- ofs
);
763 tcg_gen_shri_i32(ret
, ret
, 32 - len
);
768 void tcg_gen_sextract_i32(TCGv_i32 ret
, TCGv_i32 arg
,
769 unsigned int ofs
, unsigned int len
)
771 tcg_debug_assert(ofs
< 32);
772 tcg_debug_assert(len
> 0);
773 tcg_debug_assert(len
<= 32);
774 tcg_debug_assert(ofs
+ len
<= 32);
776 /* Canonicalize certain special cases, even if extract is supported. */
777 if (ofs
+ len
== 32) {
778 tcg_gen_sari_i32(ret
, arg
, 32 - len
);
784 tcg_gen_ext16s_i32(ret
, arg
);
787 tcg_gen_ext8s_i32(ret
, arg
);
792 if (TCG_TARGET_HAS_sextract_i32
793 && TCG_TARGET_extract_i32_valid(ofs
, len
)) {
794 tcg_gen_op4ii_i32(INDEX_op_sextract_i32
, ret
, arg
, ofs
, len
);
798 /* Assume that sign-extension, if available, is cheaper than a shift. */
801 if (TCG_TARGET_HAS_ext16s_i32
) {
802 tcg_gen_ext16s_i32(ret
, arg
);
803 tcg_gen_sari_i32(ret
, ret
, ofs
);
808 if (TCG_TARGET_HAS_ext8s_i32
) {
809 tcg_gen_ext8s_i32(ret
, arg
);
810 tcg_gen_sari_i32(ret
, ret
, ofs
);
817 if (TCG_TARGET_HAS_ext16s_i32
) {
818 tcg_gen_shri_i32(ret
, arg
, ofs
);
819 tcg_gen_ext16s_i32(ret
, ret
);
824 if (TCG_TARGET_HAS_ext8s_i32
) {
825 tcg_gen_shri_i32(ret
, arg
, ofs
);
826 tcg_gen_ext8s_i32(ret
, ret
);
832 tcg_gen_shli_i32(ret
, arg
, 32 - len
- ofs
);
833 tcg_gen_sari_i32(ret
, ret
, 32 - len
);
837 * Extract 32-bits from a 64-bit input, ah:al, starting from ofs.
838 * Unlike tcg_gen_extract_i32 above, len is fixed at 32.
840 void tcg_gen_extract2_i32(TCGv_i32 ret
, TCGv_i32 al
, TCGv_i32 ah
,
843 tcg_debug_assert(ofs
<= 32);
845 tcg_gen_mov_i32(ret
, al
);
846 } else if (ofs
== 32) {
847 tcg_gen_mov_i32(ret
, ah
);
848 } else if (al
== ah
) {
849 tcg_gen_rotri_i32(ret
, al
, ofs
);
850 } else if (TCG_TARGET_HAS_extract2_i32
) {
851 tcg_gen_op4i_i32(INDEX_op_extract2_i32
, ret
, al
, ah
, ofs
);
853 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
854 tcg_gen_shri_i32(t0
, al
, ofs
);
855 tcg_gen_deposit_i32(ret
, t0
, ah
, 32 - ofs
, ofs
);
856 tcg_temp_free_i32(t0
);
860 void tcg_gen_movcond_i32(TCGCond cond
, TCGv_i32 ret
, TCGv_i32 c1
,
861 TCGv_i32 c2
, TCGv_i32 v1
, TCGv_i32 v2
)
863 if (cond
== TCG_COND_ALWAYS
) {
864 tcg_gen_mov_i32(ret
, v1
);
865 } else if (cond
== TCG_COND_NEVER
) {
866 tcg_gen_mov_i32(ret
, v2
);
867 } else if (TCG_TARGET_HAS_movcond_i32
) {
868 tcg_gen_op6i_i32(INDEX_op_movcond_i32
, ret
, c1
, c2
, v1
, v2
, cond
);
870 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
871 TCGv_i32 t1
= tcg_temp_ebb_new_i32();
872 tcg_gen_negsetcond_i32(cond
, t0
, c1
, c2
);
873 tcg_gen_and_i32(t1
, v1
, t0
);
874 tcg_gen_andc_i32(ret
, v2
, t0
);
875 tcg_gen_or_i32(ret
, ret
, t1
);
876 tcg_temp_free_i32(t0
);
877 tcg_temp_free_i32(t1
);
881 void tcg_gen_add2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 al
,
882 TCGv_i32 ah
, TCGv_i32 bl
, TCGv_i32 bh
)
884 if (TCG_TARGET_HAS_add2_i32
) {
885 tcg_gen_op6_i32(INDEX_op_add2_i32
, rl
, rh
, al
, ah
, bl
, bh
);
887 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
888 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
889 tcg_gen_concat_i32_i64(t0
, al
, ah
);
890 tcg_gen_concat_i32_i64(t1
, bl
, bh
);
891 tcg_gen_add_i64(t0
, t0
, t1
);
892 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
893 tcg_temp_free_i64(t0
);
894 tcg_temp_free_i64(t1
);
898 void tcg_gen_sub2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 al
,
899 TCGv_i32 ah
, TCGv_i32 bl
, TCGv_i32 bh
)
901 if (TCG_TARGET_HAS_sub2_i32
) {
902 tcg_gen_op6_i32(INDEX_op_sub2_i32
, rl
, rh
, al
, ah
, bl
, bh
);
904 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
905 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
906 tcg_gen_concat_i32_i64(t0
, al
, ah
);
907 tcg_gen_concat_i32_i64(t1
, bl
, bh
);
908 tcg_gen_sub_i64(t0
, t0
, t1
);
909 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
910 tcg_temp_free_i64(t0
);
911 tcg_temp_free_i64(t1
);
915 void tcg_gen_mulu2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
917 if (TCG_TARGET_HAS_mulu2_i32
) {
918 tcg_gen_op4_i32(INDEX_op_mulu2_i32
, rl
, rh
, arg1
, arg2
);
919 } else if (TCG_TARGET_HAS_muluh_i32
) {
920 TCGv_i32 t
= tcg_temp_ebb_new_i32();
921 tcg_gen_op3_i32(INDEX_op_mul_i32
, t
, arg1
, arg2
);
922 tcg_gen_op3_i32(INDEX_op_muluh_i32
, rh
, arg1
, arg2
);
923 tcg_gen_mov_i32(rl
, t
);
924 tcg_temp_free_i32(t
);
925 } else if (TCG_TARGET_REG_BITS
== 64) {
926 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
927 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
928 tcg_gen_extu_i32_i64(t0
, arg1
);
929 tcg_gen_extu_i32_i64(t1
, arg2
);
930 tcg_gen_mul_i64(t0
, t0
, t1
);
931 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
932 tcg_temp_free_i64(t0
);
933 tcg_temp_free_i64(t1
);
935 qemu_build_not_reached();
939 void tcg_gen_muls2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
941 if (TCG_TARGET_HAS_muls2_i32
) {
942 tcg_gen_op4_i32(INDEX_op_muls2_i32
, rl
, rh
, arg1
, arg2
);
943 } else if (TCG_TARGET_HAS_mulsh_i32
) {
944 TCGv_i32 t
= tcg_temp_ebb_new_i32();
945 tcg_gen_op3_i32(INDEX_op_mul_i32
, t
, arg1
, arg2
);
946 tcg_gen_op3_i32(INDEX_op_mulsh_i32
, rh
, arg1
, arg2
);
947 tcg_gen_mov_i32(rl
, t
);
948 tcg_temp_free_i32(t
);
949 } else 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 TCGv_i32 t3
= tcg_temp_ebb_new_i32();
954 tcg_gen_mulu2_i32(t0
, t1
, arg1
, arg2
);
955 /* Adjust for negative inputs. */
956 tcg_gen_sari_i32(t2
, arg1
, 31);
957 tcg_gen_sari_i32(t3
, arg2
, 31);
958 tcg_gen_and_i32(t2
, t2
, arg2
);
959 tcg_gen_and_i32(t3
, t3
, arg1
);
960 tcg_gen_sub_i32(rh
, t1
, t2
);
961 tcg_gen_sub_i32(rh
, rh
, t3
);
962 tcg_gen_mov_i32(rl
, t0
);
963 tcg_temp_free_i32(t0
);
964 tcg_temp_free_i32(t1
);
965 tcg_temp_free_i32(t2
);
966 tcg_temp_free_i32(t3
);
968 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
969 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
970 tcg_gen_ext_i32_i64(t0
, arg1
);
971 tcg_gen_ext_i32_i64(t1
, arg2
);
972 tcg_gen_mul_i64(t0
, t0
, t1
);
973 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
974 tcg_temp_free_i64(t0
);
975 tcg_temp_free_i64(t1
);
979 void tcg_gen_mulsu2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
981 if (TCG_TARGET_REG_BITS
== 32) {
982 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
983 TCGv_i32 t1
= tcg_temp_ebb_new_i32();
984 TCGv_i32 t2
= tcg_temp_ebb_new_i32();
985 tcg_gen_mulu2_i32(t0
, t1
, arg1
, arg2
);
986 /* Adjust for negative input for the signed arg1. */
987 tcg_gen_sari_i32(t2
, arg1
, 31);
988 tcg_gen_and_i32(t2
, t2
, arg2
);
989 tcg_gen_sub_i32(rh
, t1
, t2
);
990 tcg_gen_mov_i32(rl
, t0
);
991 tcg_temp_free_i32(t0
);
992 tcg_temp_free_i32(t1
);
993 tcg_temp_free_i32(t2
);
995 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
996 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
997 tcg_gen_ext_i32_i64(t0
, arg1
);
998 tcg_gen_extu_i32_i64(t1
, arg2
);
999 tcg_gen_mul_i64(t0
, t0
, t1
);
1000 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
1001 tcg_temp_free_i64(t0
);
1002 tcg_temp_free_i64(t1
);
1006 void tcg_gen_ext8s_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1008 if (TCG_TARGET_HAS_ext8s_i32
) {
1009 tcg_gen_op2_i32(INDEX_op_ext8s_i32
, ret
, arg
);
1011 tcg_gen_shli_i32(ret
, arg
, 24);
1012 tcg_gen_sari_i32(ret
, ret
, 24);
1016 void tcg_gen_ext16s_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1018 if (TCG_TARGET_HAS_ext16s_i32
) {
1019 tcg_gen_op2_i32(INDEX_op_ext16s_i32
, ret
, arg
);
1021 tcg_gen_shli_i32(ret
, arg
, 16);
1022 tcg_gen_sari_i32(ret
, ret
, 16);
1026 void tcg_gen_ext8u_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1028 if (TCG_TARGET_HAS_ext8u_i32
) {
1029 tcg_gen_op2_i32(INDEX_op_ext8u_i32
, ret
, arg
);
1031 tcg_gen_andi_i32(ret
, arg
, 0xffu
);
1035 void tcg_gen_ext16u_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1037 if (TCG_TARGET_HAS_ext16u_i32
) {
1038 tcg_gen_op2_i32(INDEX_op_ext16u_i32
, ret
, arg
);
1040 tcg_gen_andi_i32(ret
, arg
, 0xffffu
);
1045 * bswap16_i32: 16-bit byte swap on the low bits of a 32-bit value.
1047 * Byte pattern: xxab -> yyba
1049 * With TCG_BSWAP_IZ, x == zero, else undefined.
1050 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
1052 void tcg_gen_bswap16_i32(TCGv_i32 ret
, TCGv_i32 arg
, int flags
)
1054 /* Only one extension flag may be present. */
1055 tcg_debug_assert(!(flags
& TCG_BSWAP_OS
) || !(flags
& TCG_BSWAP_OZ
));
1057 if (TCG_TARGET_HAS_bswap16_i32
) {
1058 tcg_gen_op3i_i32(INDEX_op_bswap16_i32
, ret
, arg
, flags
);
1060 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
1061 TCGv_i32 t1
= tcg_temp_ebb_new_i32();
1063 /* arg = ..ab (IZ) xxab (!IZ) */
1064 tcg_gen_shri_i32(t0
, arg
, 8); /* t0 = ...a (IZ) .xxa (!IZ) */
1065 if (!(flags
& TCG_BSWAP_IZ
)) {
1066 tcg_gen_ext8u_i32(t0
, t0
); /* t0 = ...a */
1069 if (flags
& TCG_BSWAP_OS
) {
1070 tcg_gen_shli_i32(t1
, arg
, 24); /* t1 = b... */
1071 tcg_gen_sari_i32(t1
, t1
, 16); /* t1 = ssb. */
1072 } else if (flags
& TCG_BSWAP_OZ
) {
1073 tcg_gen_ext8u_i32(t1
, arg
); /* t1 = ...b */
1074 tcg_gen_shli_i32(t1
, t1
, 8); /* t1 = ..b. */
1076 tcg_gen_shli_i32(t1
, arg
, 8); /* t1 = xab. */
1079 tcg_gen_or_i32(ret
, t0
, t1
); /* ret = ..ba (OZ) */
1081 /* = xaba (no flag) */
1082 tcg_temp_free_i32(t0
);
1083 tcg_temp_free_i32(t1
);
1088 * bswap32_i32: 32-bit byte swap on a 32-bit value.
1090 * Byte pattern: abcd -> dcba
1092 void tcg_gen_bswap32_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1094 if (TCG_TARGET_HAS_bswap32_i32
) {
1095 tcg_gen_op3i_i32(INDEX_op_bswap32_i32
, ret
, arg
, 0);
1097 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
1098 TCGv_i32 t1
= tcg_temp_ebb_new_i32();
1099 TCGv_i32 t2
= tcg_constant_i32(0x00ff00ff);
1102 tcg_gen_shri_i32(t0
, arg
, 8); /* t0 = .abc */
1103 tcg_gen_and_i32(t1
, arg
, t2
); /* t1 = .b.d */
1104 tcg_gen_and_i32(t0
, t0
, t2
); /* t0 = .a.c */
1105 tcg_gen_shli_i32(t1
, t1
, 8); /* t1 = b.d. */
1106 tcg_gen_or_i32(ret
, t0
, t1
); /* ret = badc */
1108 tcg_gen_shri_i32(t0
, ret
, 16); /* t0 = ..ba */
1109 tcg_gen_shli_i32(t1
, ret
, 16); /* t1 = dc.. */
1110 tcg_gen_or_i32(ret
, t0
, t1
); /* ret = dcba */
1112 tcg_temp_free_i32(t0
);
1113 tcg_temp_free_i32(t1
);
1118 * hswap_i32: Swap 16-bit halfwords within a 32-bit value.
1120 * Byte pattern: abcd -> cdab
1122 void tcg_gen_hswap_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1124 /* Swapping 2 16-bit elements is a rotate. */
1125 tcg_gen_rotli_i32(ret
, arg
, 16);
1128 void tcg_gen_smin_i32(TCGv_i32 ret
, TCGv_i32 a
, TCGv_i32 b
)
1130 tcg_gen_movcond_i32(TCG_COND_LT
, ret
, a
, b
, a
, b
);
1133 void tcg_gen_umin_i32(TCGv_i32 ret
, TCGv_i32 a
, TCGv_i32 b
)
1135 tcg_gen_movcond_i32(TCG_COND_LTU
, ret
, a
, b
, a
, b
);
1138 void tcg_gen_smax_i32(TCGv_i32 ret
, TCGv_i32 a
, TCGv_i32 b
)
1140 tcg_gen_movcond_i32(TCG_COND_LT
, ret
, a
, b
, b
, a
);
1143 void tcg_gen_umax_i32(TCGv_i32 ret
, TCGv_i32 a
, TCGv_i32 b
)
1145 tcg_gen_movcond_i32(TCG_COND_LTU
, ret
, a
, b
, b
, a
);
1148 void tcg_gen_abs_i32(TCGv_i32 ret
, TCGv_i32 a
)
1150 TCGv_i32 t
= tcg_temp_ebb_new_i32();
1152 tcg_gen_sari_i32(t
, a
, 31);
1153 tcg_gen_xor_i32(ret
, a
, t
);
1154 tcg_gen_sub_i32(ret
, ret
, t
);
1155 tcg_temp_free_i32(t
);
1160 #if TCG_TARGET_REG_BITS == 32
1161 /* These are all inline for TCG_TARGET_REG_BITS == 64. */
1163 void tcg_gen_discard_i64(TCGv_i64 arg
)
1165 tcg_gen_discard_i32(TCGV_LOW(arg
));
1166 tcg_gen_discard_i32(TCGV_HIGH(arg
));
1169 void tcg_gen_mov_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1171 TCGTemp
*ts
= tcgv_i64_temp(arg
);
1173 /* Canonicalize TCGv_i64 TEMP_CONST into TCGv_i32 TEMP_CONST. */
1174 if (ts
->kind
== TEMP_CONST
) {
1175 tcg_gen_movi_i64(ret
, ts
->val
);
1177 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1178 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
));
1182 void tcg_gen_movi_i64(TCGv_i64 ret
, int64_t arg
)
1184 tcg_gen_movi_i32(TCGV_LOW(ret
), arg
);
1185 tcg_gen_movi_i32(TCGV_HIGH(ret
), arg
>> 32);
1188 void tcg_gen_ld8u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1190 tcg_gen_ld8u_i32(TCGV_LOW(ret
), arg2
, offset
);
1191 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1194 void tcg_gen_ld8s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1196 tcg_gen_ld8s_i32(TCGV_LOW(ret
), arg2
, offset
);
1197 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1200 void tcg_gen_ld16u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1202 tcg_gen_ld16u_i32(TCGV_LOW(ret
), arg2
, offset
);
1203 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1206 void tcg_gen_ld16s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1208 tcg_gen_ld16s_i32(TCGV_LOW(ret
), arg2
, offset
);
1209 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1212 void tcg_gen_ld32u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1214 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1215 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1218 void tcg_gen_ld32s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1220 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1221 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1224 void tcg_gen_ld_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1226 /* Since arg2 and ret have different types,
1227 they cannot be the same temporary */
1229 tcg_gen_ld_i32(TCGV_HIGH(ret
), arg2
, offset
);
1230 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
+ 4);
1232 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1233 tcg_gen_ld_i32(TCGV_HIGH(ret
), arg2
, offset
+ 4);
1237 void tcg_gen_st8_i64(TCGv_i64 arg1
, TCGv_ptr arg2
, tcg_target_long offset
)
1239 tcg_gen_st8_i32(TCGV_LOW(arg1
), arg2
, offset
);
1242 void tcg_gen_st16_i64(TCGv_i64 arg1
, TCGv_ptr arg2
, tcg_target_long offset
)
1244 tcg_gen_st16_i32(TCGV_LOW(arg1
), arg2
, offset
);
1247 void tcg_gen_st32_i64(TCGv_i64 arg1
, TCGv_ptr arg2
, tcg_target_long offset
)
1249 tcg_gen_st_i32(TCGV_LOW(arg1
), arg2
, offset
);
1252 void tcg_gen_st_i64(TCGv_i64 arg1
, TCGv_ptr arg2
, tcg_target_long offset
)
1255 tcg_gen_st_i32(TCGV_HIGH(arg1
), arg2
, offset
);
1256 tcg_gen_st_i32(TCGV_LOW(arg1
), arg2
, offset
+ 4);
1258 tcg_gen_st_i32(TCGV_LOW(arg1
), arg2
, offset
);
1259 tcg_gen_st_i32(TCGV_HIGH(arg1
), arg2
, offset
+ 4);
1263 void tcg_gen_add_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1265 tcg_gen_add2_i32(TCGV_LOW(ret
), TCGV_HIGH(ret
), TCGV_LOW(arg1
),
1266 TCGV_HIGH(arg1
), TCGV_LOW(arg2
), TCGV_HIGH(arg2
));
1269 void tcg_gen_sub_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1271 tcg_gen_sub2_i32(TCGV_LOW(ret
), TCGV_HIGH(ret
), TCGV_LOW(arg1
),
1272 TCGV_HIGH(arg1
), TCGV_LOW(arg2
), TCGV_HIGH(arg2
));
1275 void tcg_gen_and_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1277 tcg_gen_and_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1278 tcg_gen_and_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1281 void tcg_gen_or_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1283 tcg_gen_or_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1284 tcg_gen_or_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1287 void tcg_gen_xor_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1289 tcg_gen_xor_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1290 tcg_gen_xor_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1293 void tcg_gen_shl_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1295 gen_helper_shl_i64(ret
, arg1
, arg2
);
1298 void tcg_gen_shr_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1300 gen_helper_shr_i64(ret
, arg1
, arg2
);
1303 void tcg_gen_sar_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1305 gen_helper_sar_i64(ret
, arg1
, arg2
);
1308 void tcg_gen_mul_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1313 t0
= tcg_temp_ebb_new_i64();
1314 t1
= tcg_temp_ebb_new_i32();
1316 tcg_gen_mulu2_i32(TCGV_LOW(t0
), TCGV_HIGH(t0
),
1317 TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1319 tcg_gen_mul_i32(t1
, TCGV_LOW(arg1
), TCGV_HIGH(arg2
));
1320 tcg_gen_add_i32(TCGV_HIGH(t0
), TCGV_HIGH(t0
), t1
);
1321 tcg_gen_mul_i32(t1
, TCGV_HIGH(arg1
), TCGV_LOW(arg2
));
1322 tcg_gen_add_i32(TCGV_HIGH(t0
), TCGV_HIGH(t0
), t1
);
1324 tcg_gen_mov_i64(ret
, t0
);
1325 tcg_temp_free_i64(t0
);
1326 tcg_temp_free_i32(t1
);
1331 void tcg_gen_movi_i64(TCGv_i64 ret
, int64_t arg
)
1333 tcg_gen_mov_i64(ret
, tcg_constant_i64(arg
));
1336 #endif /* TCG_TARGET_REG_SIZE == 32 */
1338 void tcg_gen_addi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1340 /* some cases can be optimized here */
1342 tcg_gen_mov_i64(ret
, arg1
);
1343 } else if (TCG_TARGET_REG_BITS
== 64) {
1344 tcg_gen_add_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1346 tcg_gen_add2_i32(TCGV_LOW(ret
), TCGV_HIGH(ret
),
1347 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1348 tcg_constant_i32(arg2
), tcg_constant_i32(arg2
>> 32));
1352 void tcg_gen_subfi_i64(TCGv_i64 ret
, int64_t arg1
, TCGv_i64 arg2
)
1354 if (arg1
== 0 && TCG_TARGET_HAS_neg_i64
) {
1355 /* Don't recurse with tcg_gen_neg_i64. */
1356 tcg_gen_op2_i64(INDEX_op_neg_i64
, ret
, arg2
);
1357 } else if (TCG_TARGET_REG_BITS
== 64) {
1358 tcg_gen_sub_i64(ret
, tcg_constant_i64(arg1
), arg2
);
1360 tcg_gen_sub2_i32(TCGV_LOW(ret
), TCGV_HIGH(ret
),
1361 tcg_constant_i32(arg1
), tcg_constant_i32(arg1
>> 32),
1362 TCGV_LOW(arg2
), TCGV_HIGH(arg2
));
1366 void tcg_gen_subi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1368 /* some cases can be optimized here */
1370 tcg_gen_mov_i64(ret
, arg1
);
1371 } else if (TCG_TARGET_REG_BITS
== 64) {
1372 tcg_gen_sub_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1374 tcg_gen_sub2_i32(TCGV_LOW(ret
), TCGV_HIGH(ret
),
1375 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1376 tcg_constant_i32(arg2
), tcg_constant_i32(arg2
>> 32));
1380 void tcg_gen_andi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1382 if (TCG_TARGET_REG_BITS
== 32) {
1383 tcg_gen_andi_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1384 tcg_gen_andi_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1388 /* Some cases can be optimized here. */
1391 tcg_gen_movi_i64(ret
, 0);
1394 tcg_gen_mov_i64(ret
, arg1
);
1397 /* Don't recurse with tcg_gen_ext8u_i64. */
1398 if (TCG_TARGET_HAS_ext8u_i64
) {
1399 tcg_gen_op2_i64(INDEX_op_ext8u_i64
, ret
, arg1
);
1404 if (TCG_TARGET_HAS_ext16u_i64
) {
1405 tcg_gen_op2_i64(INDEX_op_ext16u_i64
, ret
, arg1
);
1410 if (TCG_TARGET_HAS_ext32u_i64
) {
1411 tcg_gen_op2_i64(INDEX_op_ext32u_i64
, ret
, arg1
);
1417 tcg_gen_and_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1420 void tcg_gen_ori_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1422 if (TCG_TARGET_REG_BITS
== 32) {
1423 tcg_gen_ori_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1424 tcg_gen_ori_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1427 /* Some cases can be optimized here. */
1429 tcg_gen_movi_i64(ret
, -1);
1430 } else if (arg2
== 0) {
1431 tcg_gen_mov_i64(ret
, arg1
);
1433 tcg_gen_or_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1437 void tcg_gen_xori_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1439 if (TCG_TARGET_REG_BITS
== 32) {
1440 tcg_gen_xori_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1441 tcg_gen_xori_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1444 /* Some cases can be optimized here. */
1446 tcg_gen_mov_i64(ret
, arg1
);
1447 } else if (arg2
== -1 && TCG_TARGET_HAS_not_i64
) {
1448 /* Don't recurse with tcg_gen_not_i64. */
1449 tcg_gen_op2_i64(INDEX_op_not_i64
, ret
, arg1
);
1451 tcg_gen_xor_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1455 static inline void tcg_gen_shifti_i64(TCGv_i64 ret
, TCGv_i64 arg1
,
1456 unsigned c
, bool right
, bool arith
)
1458 tcg_debug_assert(c
< 64);
1460 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
));
1461 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
));
1462 } else if (c
>= 32) {
1466 tcg_gen_sari_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), c
);
1467 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), 31);
1469 tcg_gen_shri_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), c
);
1470 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1473 tcg_gen_shli_i32(TCGV_HIGH(ret
), TCGV_LOW(arg1
), c
);
1474 tcg_gen_movi_i32(TCGV_LOW(ret
), 0);
1477 if (TCG_TARGET_HAS_extract2_i32
) {
1478 tcg_gen_extract2_i32(TCGV_LOW(ret
),
1479 TCGV_LOW(arg1
), TCGV_HIGH(arg1
), c
);
1481 tcg_gen_shri_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), c
);
1482 tcg_gen_deposit_i32(TCGV_LOW(ret
), TCGV_LOW(ret
),
1483 TCGV_HIGH(arg1
), 32 - c
, c
);
1486 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), c
);
1488 tcg_gen_shri_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), c
);
1491 if (TCG_TARGET_HAS_extract2_i32
) {
1492 tcg_gen_extract2_i32(TCGV_HIGH(ret
),
1493 TCGV_LOW(arg1
), TCGV_HIGH(arg1
), 32 - c
);
1495 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
1496 tcg_gen_shri_i32(t0
, TCGV_LOW(arg1
), 32 - c
);
1497 tcg_gen_deposit_i32(TCGV_HIGH(ret
), t0
,
1498 TCGV_HIGH(arg1
), c
, 32 - c
);
1499 tcg_temp_free_i32(t0
);
1501 tcg_gen_shli_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), c
);
1505 void tcg_gen_shli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1507 tcg_debug_assert(arg2
>= 0 && arg2
< 64);
1508 if (TCG_TARGET_REG_BITS
== 32) {
1509 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 0, 0);
1510 } else if (arg2
== 0) {
1511 tcg_gen_mov_i64(ret
, arg1
);
1513 tcg_gen_shl_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1517 void tcg_gen_shri_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1519 tcg_debug_assert(arg2
>= 0 && arg2
< 64);
1520 if (TCG_TARGET_REG_BITS
== 32) {
1521 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 0);
1522 } else if (arg2
== 0) {
1523 tcg_gen_mov_i64(ret
, arg1
);
1525 tcg_gen_shr_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1529 void tcg_gen_sari_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1531 tcg_debug_assert(arg2
>= 0 && arg2
< 64);
1532 if (TCG_TARGET_REG_BITS
== 32) {
1533 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 1);
1534 } else if (arg2
== 0) {
1535 tcg_gen_mov_i64(ret
, arg1
);
1537 tcg_gen_sar_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1541 void tcg_gen_brcond_i64(TCGCond cond
, TCGv_i64 arg1
, TCGv_i64 arg2
, TCGLabel
*l
)
1543 if (cond
== TCG_COND_ALWAYS
) {
1545 } else if (cond
!= TCG_COND_NEVER
) {
1546 if (TCG_TARGET_REG_BITS
== 32) {
1547 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32
, TCGV_LOW(arg1
),
1548 TCGV_HIGH(arg1
), TCGV_LOW(arg2
),
1549 TCGV_HIGH(arg2
), cond
, label_arg(l
));
1551 tcg_gen_op4ii_i64(INDEX_op_brcond_i64
, arg1
, arg2
, cond
,
1554 add_last_as_label_use(l
);
1558 void tcg_gen_brcondi_i64(TCGCond cond
, TCGv_i64 arg1
, int64_t arg2
, TCGLabel
*l
)
1560 if (TCG_TARGET_REG_BITS
== 64) {
1561 tcg_gen_brcond_i64(cond
, arg1
, tcg_constant_i64(arg2
), l
);
1562 } else if (cond
== TCG_COND_ALWAYS
) {
1564 } else if (cond
!= TCG_COND_NEVER
) {
1565 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32
,
1566 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1567 tcg_constant_i32(arg2
),
1568 tcg_constant_i32(arg2
>> 32),
1569 cond
, label_arg(l
));
1570 add_last_as_label_use(l
);
1574 void tcg_gen_setcond_i64(TCGCond cond
, TCGv_i64 ret
,
1575 TCGv_i64 arg1
, TCGv_i64 arg2
)
1577 if (cond
== TCG_COND_ALWAYS
) {
1578 tcg_gen_movi_i64(ret
, 1);
1579 } else if (cond
== TCG_COND_NEVER
) {
1580 tcg_gen_movi_i64(ret
, 0);
1582 if (TCG_TARGET_REG_BITS
== 32) {
1583 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, TCGV_LOW(ret
),
1584 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1585 TCGV_LOW(arg2
), TCGV_HIGH(arg2
), cond
);
1586 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1588 tcg_gen_op4i_i64(INDEX_op_setcond_i64
, ret
, arg1
, arg2
, cond
);
1593 void tcg_gen_setcondi_i64(TCGCond cond
, TCGv_i64 ret
,
1594 TCGv_i64 arg1
, int64_t arg2
)
1596 if (TCG_TARGET_REG_BITS
== 64) {
1597 tcg_gen_setcond_i64(cond
, ret
, arg1
, tcg_constant_i64(arg2
));
1598 } else if (cond
== TCG_COND_ALWAYS
) {
1599 tcg_gen_movi_i64(ret
, 1);
1600 } else if (cond
== TCG_COND_NEVER
) {
1601 tcg_gen_movi_i64(ret
, 0);
1603 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, TCGV_LOW(ret
),
1604 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1605 tcg_constant_i32(arg2
),
1606 tcg_constant_i32(arg2
>> 32), cond
);
1607 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1611 void tcg_gen_negsetcondi_i64(TCGCond cond
, TCGv_i64 ret
,
1612 TCGv_i64 arg1
, int64_t arg2
)
1614 tcg_gen_negsetcond_i64(cond
, ret
, arg1
, tcg_constant_i64(arg2
));
1617 void tcg_gen_negsetcond_i64(TCGCond cond
, TCGv_i64 ret
,
1618 TCGv_i64 arg1
, TCGv_i64 arg2
)
1620 if (cond
== TCG_COND_ALWAYS
) {
1621 tcg_gen_movi_i64(ret
, -1);
1622 } else if (cond
== TCG_COND_NEVER
) {
1623 tcg_gen_movi_i64(ret
, 0);
1624 } else if (TCG_TARGET_HAS_negsetcond_i64
) {
1625 tcg_gen_op4i_i64(INDEX_op_negsetcond_i64
, ret
, arg1
, arg2
, cond
);
1626 } else if (TCG_TARGET_REG_BITS
== 32) {
1627 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, TCGV_LOW(ret
),
1628 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1629 TCGV_LOW(arg2
), TCGV_HIGH(arg2
), cond
);
1630 tcg_gen_neg_i32(TCGV_LOW(ret
), TCGV_LOW(ret
));
1631 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
));
1633 tcg_gen_setcond_i64(cond
, ret
, arg1
, arg2
);
1634 tcg_gen_neg_i64(ret
, ret
);
1638 void tcg_gen_muli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1641 tcg_gen_movi_i64(ret
, 0);
1642 } else if (is_power_of_2(arg2
)) {
1643 tcg_gen_shli_i64(ret
, arg1
, ctz64(arg2
));
1645 tcg_gen_mul_i64(ret
, arg1
, tcg_constant_i64(arg2
));
1649 void tcg_gen_div_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1651 if (TCG_TARGET_HAS_div_i64
) {
1652 tcg_gen_op3_i64(INDEX_op_div_i64
, ret
, arg1
, arg2
);
1653 } else if (TCG_TARGET_HAS_div2_i64
) {
1654 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1655 tcg_gen_sari_i64(t0
, arg1
, 63);
1656 tcg_gen_op5_i64(INDEX_op_div2_i64
, ret
, t0
, arg1
, t0
, arg2
);
1657 tcg_temp_free_i64(t0
);
1659 gen_helper_div_i64(ret
, arg1
, arg2
);
1663 void tcg_gen_rem_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1665 if (TCG_TARGET_HAS_rem_i64
) {
1666 tcg_gen_op3_i64(INDEX_op_rem_i64
, ret
, arg1
, arg2
);
1667 } else if (TCG_TARGET_HAS_div_i64
) {
1668 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1669 tcg_gen_op3_i64(INDEX_op_div_i64
, t0
, arg1
, arg2
);
1670 tcg_gen_mul_i64(t0
, t0
, arg2
);
1671 tcg_gen_sub_i64(ret
, arg1
, t0
);
1672 tcg_temp_free_i64(t0
);
1673 } else if (TCG_TARGET_HAS_div2_i64
) {
1674 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1675 tcg_gen_sari_i64(t0
, arg1
, 63);
1676 tcg_gen_op5_i64(INDEX_op_div2_i64
, t0
, ret
, arg1
, t0
, arg2
);
1677 tcg_temp_free_i64(t0
);
1679 gen_helper_rem_i64(ret
, arg1
, arg2
);
1683 void tcg_gen_divu_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1685 if (TCG_TARGET_HAS_div_i64
) {
1686 tcg_gen_op3_i64(INDEX_op_divu_i64
, ret
, arg1
, arg2
);
1687 } else if (TCG_TARGET_HAS_div2_i64
) {
1688 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1689 TCGv_i64 zero
= tcg_constant_i64(0);
1690 tcg_gen_op5_i64(INDEX_op_divu2_i64
, ret
, t0
, arg1
, zero
, arg2
);
1691 tcg_temp_free_i64(t0
);
1693 gen_helper_divu_i64(ret
, arg1
, arg2
);
1697 void tcg_gen_remu_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1699 if (TCG_TARGET_HAS_rem_i64
) {
1700 tcg_gen_op3_i64(INDEX_op_remu_i64
, ret
, arg1
, arg2
);
1701 } else if (TCG_TARGET_HAS_div_i64
) {
1702 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1703 tcg_gen_op3_i64(INDEX_op_divu_i64
, t0
, arg1
, arg2
);
1704 tcg_gen_mul_i64(t0
, t0
, arg2
);
1705 tcg_gen_sub_i64(ret
, arg1
, t0
);
1706 tcg_temp_free_i64(t0
);
1707 } else if (TCG_TARGET_HAS_div2_i64
) {
1708 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1709 TCGv_i64 zero
= tcg_constant_i64(0);
1710 tcg_gen_op5_i64(INDEX_op_divu2_i64
, t0
, ret
, arg1
, zero
, arg2
);
1711 tcg_temp_free_i64(t0
);
1713 gen_helper_remu_i64(ret
, arg1
, arg2
);
1717 void tcg_gen_ext8s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1719 if (TCG_TARGET_REG_BITS
== 32) {
1720 tcg_gen_ext8s_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1721 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1722 } else if (TCG_TARGET_HAS_ext8s_i64
) {
1723 tcg_gen_op2_i64(INDEX_op_ext8s_i64
, ret
, arg
);
1725 tcg_gen_shli_i64(ret
, arg
, 56);
1726 tcg_gen_sari_i64(ret
, ret
, 56);
1730 void tcg_gen_ext16s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1732 if (TCG_TARGET_REG_BITS
== 32) {
1733 tcg_gen_ext16s_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1734 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1735 } else if (TCG_TARGET_HAS_ext16s_i64
) {
1736 tcg_gen_op2_i64(INDEX_op_ext16s_i64
, ret
, arg
);
1738 tcg_gen_shli_i64(ret
, arg
, 48);
1739 tcg_gen_sari_i64(ret
, ret
, 48);
1743 void tcg_gen_ext32s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1745 if (TCG_TARGET_REG_BITS
== 32) {
1746 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1747 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1748 } else if (TCG_TARGET_HAS_ext32s_i64
) {
1749 tcg_gen_op2_i64(INDEX_op_ext32s_i64
, ret
, arg
);
1751 tcg_gen_shli_i64(ret
, arg
, 32);
1752 tcg_gen_sari_i64(ret
, ret
, 32);
1756 void tcg_gen_ext8u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1758 if (TCG_TARGET_REG_BITS
== 32) {
1759 tcg_gen_ext8u_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1760 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1761 } else if (TCG_TARGET_HAS_ext8u_i64
) {
1762 tcg_gen_op2_i64(INDEX_op_ext8u_i64
, ret
, arg
);
1764 tcg_gen_andi_i64(ret
, arg
, 0xffu
);
1768 void tcg_gen_ext16u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1770 if (TCG_TARGET_REG_BITS
== 32) {
1771 tcg_gen_ext16u_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1772 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1773 } else if (TCG_TARGET_HAS_ext16u_i64
) {
1774 tcg_gen_op2_i64(INDEX_op_ext16u_i64
, ret
, arg
);
1776 tcg_gen_andi_i64(ret
, arg
, 0xffffu
);
1780 void tcg_gen_ext32u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1782 if (TCG_TARGET_REG_BITS
== 32) {
1783 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1784 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1785 } else if (TCG_TARGET_HAS_ext32u_i64
) {
1786 tcg_gen_op2_i64(INDEX_op_ext32u_i64
, ret
, arg
);
1788 tcg_gen_andi_i64(ret
, arg
, 0xffffffffu
);
1793 * bswap16_i64: 16-bit byte swap on the low bits of a 64-bit value.
1795 * Byte pattern: xxxxxxxxab -> yyyyyyyyba
1797 * With TCG_BSWAP_IZ, x == zero, else undefined.
1798 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
1800 void tcg_gen_bswap16_i64(TCGv_i64 ret
, TCGv_i64 arg
, int flags
)
1802 /* Only one extension flag may be present. */
1803 tcg_debug_assert(!(flags
& TCG_BSWAP_OS
) || !(flags
& TCG_BSWAP_OZ
));
1805 if (TCG_TARGET_REG_BITS
== 32) {
1806 tcg_gen_bswap16_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), flags
);
1807 if (flags
& TCG_BSWAP_OS
) {
1808 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1810 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1812 } else if (TCG_TARGET_HAS_bswap16_i64
) {
1813 tcg_gen_op3i_i64(INDEX_op_bswap16_i64
, ret
, arg
, flags
);
1815 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1816 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
1818 /* arg = ......ab or xxxxxxab */
1819 tcg_gen_shri_i64(t0
, arg
, 8); /* t0 = .......a or .xxxxxxa */
1820 if (!(flags
& TCG_BSWAP_IZ
)) {
1821 tcg_gen_ext8u_i64(t0
, t0
); /* t0 = .......a */
1824 if (flags
& TCG_BSWAP_OS
) {
1825 tcg_gen_shli_i64(t1
, arg
, 56); /* t1 = b....... */
1826 tcg_gen_sari_i64(t1
, t1
, 48); /* t1 = ssssssb. */
1827 } else if (flags
& TCG_BSWAP_OZ
) {
1828 tcg_gen_ext8u_i64(t1
, arg
); /* t1 = .......b */
1829 tcg_gen_shli_i64(t1
, t1
, 8); /* t1 = ......b. */
1831 tcg_gen_shli_i64(t1
, arg
, 8); /* t1 = xxxxxab. */
1834 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = ......ba (OZ) */
1836 /* xxxxxaba (no flag) */
1837 tcg_temp_free_i64(t0
);
1838 tcg_temp_free_i64(t1
);
1843 * bswap32_i64: 32-bit byte swap on the low bits of a 64-bit value.
1845 * Byte pattern: xxxxabcd -> yyyydcba
1847 * With TCG_BSWAP_IZ, x == zero, else undefined.
1848 * With TCG_BSWAP_OZ, y == zero, with TCG_BSWAP_OS y == sign, else undefined.
1850 void tcg_gen_bswap32_i64(TCGv_i64 ret
, TCGv_i64 arg
, int flags
)
1852 /* Only one extension flag may be present. */
1853 tcg_debug_assert(!(flags
& TCG_BSWAP_OS
) || !(flags
& TCG_BSWAP_OZ
));
1855 if (TCG_TARGET_REG_BITS
== 32) {
1856 tcg_gen_bswap32_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1857 if (flags
& TCG_BSWAP_OS
) {
1858 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1860 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1862 } else if (TCG_TARGET_HAS_bswap32_i64
) {
1863 tcg_gen_op3i_i64(INDEX_op_bswap32_i64
, ret
, arg
, flags
);
1865 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1866 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
1867 TCGv_i64 t2
= tcg_constant_i64(0x00ff00ff);
1869 /* arg = xxxxabcd */
1870 tcg_gen_shri_i64(t0
, arg
, 8); /* t0 = .xxxxabc */
1871 tcg_gen_and_i64(t1
, arg
, t2
); /* t1 = .....b.d */
1872 tcg_gen_and_i64(t0
, t0
, t2
); /* t0 = .....a.c */
1873 tcg_gen_shli_i64(t1
, t1
, 8); /* t1 = ....b.d. */
1874 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = ....badc */
1876 tcg_gen_shli_i64(t1
, ret
, 48); /* t1 = dc...... */
1877 tcg_gen_shri_i64(t0
, ret
, 16); /* t0 = ......ba */
1878 if (flags
& TCG_BSWAP_OS
) {
1879 tcg_gen_sari_i64(t1
, t1
, 32); /* t1 = ssssdc.. */
1881 tcg_gen_shri_i64(t1
, t1
, 32); /* t1 = ....dc.. */
1883 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = ssssdcba (OS) */
1884 /* ....dcba (else) */
1886 tcg_temp_free_i64(t0
);
1887 tcg_temp_free_i64(t1
);
1892 * bswap64_i64: 64-bit byte swap on a 64-bit value.
1894 * Byte pattern: abcdefgh -> hgfedcba
1896 void tcg_gen_bswap64_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1898 if (TCG_TARGET_REG_BITS
== 32) {
1900 t0
= tcg_temp_ebb_new_i32();
1901 t1
= tcg_temp_ebb_new_i32();
1903 tcg_gen_bswap32_i32(t0
, TCGV_LOW(arg
));
1904 tcg_gen_bswap32_i32(t1
, TCGV_HIGH(arg
));
1905 tcg_gen_mov_i32(TCGV_LOW(ret
), t1
);
1906 tcg_gen_mov_i32(TCGV_HIGH(ret
), t0
);
1907 tcg_temp_free_i32(t0
);
1908 tcg_temp_free_i32(t1
);
1909 } else if (TCG_TARGET_HAS_bswap64_i64
) {
1910 tcg_gen_op3i_i64(INDEX_op_bswap64_i64
, ret
, arg
, 0);
1912 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1913 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
1914 TCGv_i64 t2
= tcg_temp_ebb_new_i64();
1916 /* arg = abcdefgh */
1917 tcg_gen_movi_i64(t2
, 0x00ff00ff00ff00ffull
);
1918 tcg_gen_shri_i64(t0
, arg
, 8); /* t0 = .abcdefg */
1919 tcg_gen_and_i64(t1
, arg
, t2
); /* t1 = .b.d.f.h */
1920 tcg_gen_and_i64(t0
, t0
, t2
); /* t0 = .a.c.e.g */
1921 tcg_gen_shli_i64(t1
, t1
, 8); /* t1 = b.d.f.h. */
1922 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = badcfehg */
1924 tcg_gen_movi_i64(t2
, 0x0000ffff0000ffffull
);
1925 tcg_gen_shri_i64(t0
, ret
, 16); /* t0 = ..badcfe */
1926 tcg_gen_and_i64(t1
, ret
, t2
); /* t1 = ..dc..hg */
1927 tcg_gen_and_i64(t0
, t0
, t2
); /* t0 = ..ba..fe */
1928 tcg_gen_shli_i64(t1
, t1
, 16); /* t1 = dc..hg.. */
1929 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = dcbahgfe */
1931 tcg_gen_shri_i64(t0
, ret
, 32); /* t0 = ....dcba */
1932 tcg_gen_shli_i64(t1
, ret
, 32); /* t1 = hgfe.... */
1933 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = hgfedcba */
1935 tcg_temp_free_i64(t0
);
1936 tcg_temp_free_i64(t1
);
1937 tcg_temp_free_i64(t2
);
1942 * hswap_i64: Swap 16-bit halfwords within a 64-bit value.
1943 * See also include/qemu/bitops.h, hswap64.
1945 * Byte pattern: abcdefgh -> ghefcdab
1947 void tcg_gen_hswap_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1949 uint64_t m
= 0x0000ffff0000ffffull
;
1950 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1951 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
1953 /* arg = abcdefgh */
1954 tcg_gen_rotli_i64(t1
, arg
, 32); /* t1 = efghabcd */
1955 tcg_gen_andi_i64(t0
, t1
, m
); /* t0 = ..gh..cd */
1956 tcg_gen_shli_i64(t0
, t0
, 16); /* t0 = gh..cd.. */
1957 tcg_gen_shri_i64(t1
, t1
, 16); /* t1 = ..efghab */
1958 tcg_gen_andi_i64(t1
, t1
, m
); /* t1 = ..ef..ab */
1959 tcg_gen_or_i64(ret
, t0
, t1
); /* ret = ghefcdab */
1961 tcg_temp_free_i64(t0
);
1962 tcg_temp_free_i64(t1
);
1966 * wswap_i64: Swap 32-bit words within a 64-bit value.
1968 * Byte pattern: abcdefgh -> efghabcd
1970 void tcg_gen_wswap_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1972 /* Swapping 2 32-bit elements is a rotate. */
1973 tcg_gen_rotli_i64(ret
, arg
, 32);
1976 void tcg_gen_not_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1978 if (TCG_TARGET_REG_BITS
== 32) {
1979 tcg_gen_not_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1980 tcg_gen_not_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
));
1981 } else if (TCG_TARGET_HAS_not_i64
) {
1982 tcg_gen_op2_i64(INDEX_op_not_i64
, ret
, arg
);
1984 tcg_gen_xori_i64(ret
, arg
, -1);
1988 void tcg_gen_andc_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1990 if (TCG_TARGET_REG_BITS
== 32) {
1991 tcg_gen_andc_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1992 tcg_gen_andc_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1993 } else if (TCG_TARGET_HAS_andc_i64
) {
1994 tcg_gen_op3_i64(INDEX_op_andc_i64
, ret
, arg1
, arg2
);
1996 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
1997 tcg_gen_not_i64(t0
, arg2
);
1998 tcg_gen_and_i64(ret
, arg1
, t0
);
1999 tcg_temp_free_i64(t0
);
2003 void tcg_gen_eqv_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2005 if (TCG_TARGET_REG_BITS
== 32) {
2006 tcg_gen_eqv_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
2007 tcg_gen_eqv_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
2008 } else if (TCG_TARGET_HAS_eqv_i64
) {
2009 tcg_gen_op3_i64(INDEX_op_eqv_i64
, ret
, arg1
, arg2
);
2011 tcg_gen_xor_i64(ret
, arg1
, arg2
);
2012 tcg_gen_not_i64(ret
, ret
);
2016 void tcg_gen_nand_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2018 if (TCG_TARGET_REG_BITS
== 32) {
2019 tcg_gen_nand_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
2020 tcg_gen_nand_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
2021 } else if (TCG_TARGET_HAS_nand_i64
) {
2022 tcg_gen_op3_i64(INDEX_op_nand_i64
, ret
, arg1
, arg2
);
2024 tcg_gen_and_i64(ret
, arg1
, arg2
);
2025 tcg_gen_not_i64(ret
, ret
);
2029 void tcg_gen_nor_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2031 if (TCG_TARGET_REG_BITS
== 32) {
2032 tcg_gen_nor_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
2033 tcg_gen_nor_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
2034 } else if (TCG_TARGET_HAS_nor_i64
) {
2035 tcg_gen_op3_i64(INDEX_op_nor_i64
, ret
, arg1
, arg2
);
2037 tcg_gen_or_i64(ret
, arg1
, arg2
);
2038 tcg_gen_not_i64(ret
, ret
);
2042 void tcg_gen_orc_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2044 if (TCG_TARGET_REG_BITS
== 32) {
2045 tcg_gen_orc_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
2046 tcg_gen_orc_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
2047 } else if (TCG_TARGET_HAS_orc_i64
) {
2048 tcg_gen_op3_i64(INDEX_op_orc_i64
, ret
, arg1
, arg2
);
2050 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2051 tcg_gen_not_i64(t0
, arg2
);
2052 tcg_gen_or_i64(ret
, arg1
, t0
);
2053 tcg_temp_free_i64(t0
);
2057 void tcg_gen_clz_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2059 if (TCG_TARGET_HAS_clz_i64
) {
2060 tcg_gen_op3_i64(INDEX_op_clz_i64
, ret
, arg1
, arg2
);
2062 gen_helper_clz_i64(ret
, arg1
, arg2
);
2066 void tcg_gen_clzi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, uint64_t arg2
)
2068 if (TCG_TARGET_REG_BITS
== 32
2069 && TCG_TARGET_HAS_clz_i32
2070 && arg2
<= 0xffffffffu
) {
2071 TCGv_i32 t
= tcg_temp_ebb_new_i32();
2072 tcg_gen_clzi_i32(t
, TCGV_LOW(arg1
), arg2
- 32);
2073 tcg_gen_addi_i32(t
, t
, 32);
2074 tcg_gen_clz_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), t
);
2075 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2076 tcg_temp_free_i32(t
);
2078 tcg_gen_clz_i64(ret
, arg1
, tcg_constant_i64(arg2
));
2082 void tcg_gen_ctz_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2084 if (TCG_TARGET_HAS_ctz_i64
) {
2085 tcg_gen_op3_i64(INDEX_op_ctz_i64
, ret
, arg1
, arg2
);
2086 } else if (TCG_TARGET_HAS_ctpop_i64
|| TCG_TARGET_HAS_clz_i64
) {
2087 TCGv_i64 z
, t
= tcg_temp_ebb_new_i64();
2089 if (TCG_TARGET_HAS_ctpop_i64
) {
2090 tcg_gen_subi_i64(t
, arg1
, 1);
2091 tcg_gen_andc_i64(t
, t
, arg1
);
2092 tcg_gen_ctpop_i64(t
, t
);
2094 /* Since all non-x86 hosts have clz(0) == 64, don't fight it. */
2095 tcg_gen_neg_i64(t
, arg1
);
2096 tcg_gen_and_i64(t
, t
, arg1
);
2097 tcg_gen_clzi_i64(t
, t
, 64);
2098 tcg_gen_xori_i64(t
, t
, 63);
2100 z
= tcg_constant_i64(0);
2101 tcg_gen_movcond_i64(TCG_COND_EQ
, ret
, arg1
, z
, arg2
, t
);
2102 tcg_temp_free_i64(t
);
2103 tcg_temp_free_i64(z
);
2105 gen_helper_ctz_i64(ret
, arg1
, arg2
);
2109 void tcg_gen_ctzi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, uint64_t arg2
)
2111 if (TCG_TARGET_REG_BITS
== 32
2112 && TCG_TARGET_HAS_ctz_i32
2113 && arg2
<= 0xffffffffu
) {
2114 TCGv_i32 t32
= tcg_temp_ebb_new_i32();
2115 tcg_gen_ctzi_i32(t32
, TCGV_HIGH(arg1
), arg2
- 32);
2116 tcg_gen_addi_i32(t32
, t32
, 32);
2117 tcg_gen_ctz_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), t32
);
2118 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2119 tcg_temp_free_i32(t32
);
2120 } else if (!TCG_TARGET_HAS_ctz_i64
2121 && TCG_TARGET_HAS_ctpop_i64
2123 /* This equivalence has the advantage of not requiring a fixup. */
2124 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2125 tcg_gen_subi_i64(t
, arg1
, 1);
2126 tcg_gen_andc_i64(t
, t
, arg1
);
2127 tcg_gen_ctpop_i64(ret
, t
);
2128 tcg_temp_free_i64(t
);
2130 tcg_gen_ctz_i64(ret
, arg1
, tcg_constant_i64(arg2
));
2134 void tcg_gen_clrsb_i64(TCGv_i64 ret
, TCGv_i64 arg
)
2136 if (TCG_TARGET_HAS_clz_i64
|| TCG_TARGET_HAS_clz_i32
) {
2137 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2138 tcg_gen_sari_i64(t
, arg
, 63);
2139 tcg_gen_xor_i64(t
, t
, arg
);
2140 tcg_gen_clzi_i64(t
, t
, 64);
2141 tcg_gen_subi_i64(ret
, t
, 1);
2142 tcg_temp_free_i64(t
);
2144 gen_helper_clrsb_i64(ret
, arg
);
2148 void tcg_gen_ctpop_i64(TCGv_i64 ret
, TCGv_i64 arg1
)
2150 if (TCG_TARGET_HAS_ctpop_i64
) {
2151 tcg_gen_op2_i64(INDEX_op_ctpop_i64
, ret
, arg1
);
2152 } else if (TCG_TARGET_REG_BITS
== 32 && TCG_TARGET_HAS_ctpop_i32
) {
2153 tcg_gen_ctpop_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
));
2154 tcg_gen_ctpop_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
));
2155 tcg_gen_add_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), TCGV_HIGH(ret
));
2156 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2158 gen_helper_ctpop_i64(ret
, arg1
);
2162 void tcg_gen_rotl_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2164 if (TCG_TARGET_HAS_rot_i64
) {
2165 tcg_gen_op3_i64(INDEX_op_rotl_i64
, ret
, arg1
, arg2
);
2168 t0
= tcg_temp_ebb_new_i64();
2169 t1
= tcg_temp_ebb_new_i64();
2170 tcg_gen_shl_i64(t0
, arg1
, arg2
);
2171 tcg_gen_subfi_i64(t1
, 64, arg2
);
2172 tcg_gen_shr_i64(t1
, arg1
, t1
);
2173 tcg_gen_or_i64(ret
, t0
, t1
);
2174 tcg_temp_free_i64(t0
);
2175 tcg_temp_free_i64(t1
);
2179 void tcg_gen_rotli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
2181 tcg_debug_assert(arg2
>= 0 && arg2
< 64);
2182 /* some cases can be optimized here */
2184 tcg_gen_mov_i64(ret
, arg1
);
2185 } else if (TCG_TARGET_HAS_rot_i64
) {
2186 tcg_gen_rotl_i64(ret
, arg1
, tcg_constant_i64(arg2
));
2189 t0
= tcg_temp_ebb_new_i64();
2190 t1
= tcg_temp_ebb_new_i64();
2191 tcg_gen_shli_i64(t0
, arg1
, arg2
);
2192 tcg_gen_shri_i64(t1
, arg1
, 64 - arg2
);
2193 tcg_gen_or_i64(ret
, t0
, t1
);
2194 tcg_temp_free_i64(t0
);
2195 tcg_temp_free_i64(t1
);
2199 void tcg_gen_rotr_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2201 if (TCG_TARGET_HAS_rot_i64
) {
2202 tcg_gen_op3_i64(INDEX_op_rotr_i64
, ret
, arg1
, arg2
);
2205 t0
= tcg_temp_ebb_new_i64();
2206 t1
= tcg_temp_ebb_new_i64();
2207 tcg_gen_shr_i64(t0
, arg1
, arg2
);
2208 tcg_gen_subfi_i64(t1
, 64, arg2
);
2209 tcg_gen_shl_i64(t1
, arg1
, t1
);
2210 tcg_gen_or_i64(ret
, t0
, t1
);
2211 tcg_temp_free_i64(t0
);
2212 tcg_temp_free_i64(t1
);
2216 void tcg_gen_rotri_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
2218 tcg_debug_assert(arg2
>= 0 && arg2
< 64);
2219 /* some cases can be optimized here */
2221 tcg_gen_mov_i64(ret
, arg1
);
2223 tcg_gen_rotli_i64(ret
, arg1
, 64 - arg2
);
2227 void tcg_gen_deposit_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
,
2228 unsigned int ofs
, unsigned int len
)
2233 tcg_debug_assert(ofs
< 64);
2234 tcg_debug_assert(len
> 0);
2235 tcg_debug_assert(len
<= 64);
2236 tcg_debug_assert(ofs
+ len
<= 64);
2239 tcg_gen_mov_i64(ret
, arg2
);
2242 if (TCG_TARGET_HAS_deposit_i64
&& TCG_TARGET_deposit_i64_valid(ofs
, len
)) {
2243 tcg_gen_op5ii_i64(INDEX_op_deposit_i64
, ret
, arg1
, arg2
, ofs
, len
);
2247 if (TCG_TARGET_REG_BITS
== 32) {
2249 tcg_gen_deposit_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
),
2250 TCGV_LOW(arg2
), ofs
- 32, len
);
2251 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
));
2254 if (ofs
+ len
<= 32) {
2255 tcg_gen_deposit_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
),
2256 TCGV_LOW(arg2
), ofs
, len
);
2257 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
));
2262 t1
= tcg_temp_ebb_new_i64();
2264 if (TCG_TARGET_HAS_extract2_i64
) {
2265 if (ofs
+ len
== 64) {
2266 tcg_gen_shli_i64(t1
, arg1
, len
);
2267 tcg_gen_extract2_i64(ret
, t1
, arg2
, len
);
2271 tcg_gen_extract2_i64(ret
, arg1
, arg2
, len
);
2272 tcg_gen_rotli_i64(ret
, ret
, len
);
2277 mask
= (1ull << len
) - 1;
2278 if (ofs
+ len
< 64) {
2279 tcg_gen_andi_i64(t1
, arg2
, mask
);
2280 tcg_gen_shli_i64(t1
, t1
, ofs
);
2282 tcg_gen_shli_i64(t1
, arg2
, ofs
);
2284 tcg_gen_andi_i64(ret
, arg1
, ~(mask
<< ofs
));
2285 tcg_gen_or_i64(ret
, ret
, t1
);
2287 tcg_temp_free_i64(t1
);
2290 void tcg_gen_deposit_z_i64(TCGv_i64 ret
, TCGv_i64 arg
,
2291 unsigned int ofs
, unsigned int len
)
2293 tcg_debug_assert(ofs
< 64);
2294 tcg_debug_assert(len
> 0);
2295 tcg_debug_assert(len
<= 64);
2296 tcg_debug_assert(ofs
+ len
<= 64);
2298 if (ofs
+ len
== 64) {
2299 tcg_gen_shli_i64(ret
, arg
, ofs
);
2300 } else if (ofs
== 0) {
2301 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
2302 } else if (TCG_TARGET_HAS_deposit_i64
2303 && TCG_TARGET_deposit_i64_valid(ofs
, len
)) {
2304 TCGv_i64 zero
= tcg_constant_i64(0);
2305 tcg_gen_op5ii_i64(INDEX_op_deposit_i64
, ret
, zero
, arg
, ofs
, len
);
2307 if (TCG_TARGET_REG_BITS
== 32) {
2309 tcg_gen_deposit_z_i32(TCGV_HIGH(ret
), TCGV_LOW(arg
),
2311 tcg_gen_movi_i32(TCGV_LOW(ret
), 0);
2314 if (ofs
+ len
<= 32) {
2315 tcg_gen_deposit_z_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
2316 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2320 /* To help two-operand hosts we prefer to zero-extend first,
2321 which allows ARG to stay live. */
2324 if (TCG_TARGET_HAS_ext32u_i64
) {
2325 tcg_gen_ext32u_i64(ret
, arg
);
2326 tcg_gen_shli_i64(ret
, ret
, ofs
);
2331 if (TCG_TARGET_HAS_ext16u_i64
) {
2332 tcg_gen_ext16u_i64(ret
, arg
);
2333 tcg_gen_shli_i64(ret
, ret
, ofs
);
2338 if (TCG_TARGET_HAS_ext8u_i64
) {
2339 tcg_gen_ext8u_i64(ret
, arg
);
2340 tcg_gen_shli_i64(ret
, ret
, ofs
);
2345 /* Otherwise prefer zero-extension over AND for code size. */
2346 switch (ofs
+ len
) {
2348 if (TCG_TARGET_HAS_ext32u_i64
) {
2349 tcg_gen_shli_i64(ret
, arg
, ofs
);
2350 tcg_gen_ext32u_i64(ret
, ret
);
2355 if (TCG_TARGET_HAS_ext16u_i64
) {
2356 tcg_gen_shli_i64(ret
, arg
, ofs
);
2357 tcg_gen_ext16u_i64(ret
, ret
);
2362 if (TCG_TARGET_HAS_ext8u_i64
) {
2363 tcg_gen_shli_i64(ret
, arg
, ofs
);
2364 tcg_gen_ext8u_i64(ret
, ret
);
2369 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
2370 tcg_gen_shli_i64(ret
, ret
, ofs
);
2374 void tcg_gen_extract_i64(TCGv_i64 ret
, TCGv_i64 arg
,
2375 unsigned int ofs
, unsigned int len
)
2377 tcg_debug_assert(ofs
< 64);
2378 tcg_debug_assert(len
> 0);
2379 tcg_debug_assert(len
<= 64);
2380 tcg_debug_assert(ofs
+ len
<= 64);
2382 /* Canonicalize certain special cases, even if extract is supported. */
2383 if (ofs
+ len
== 64) {
2384 tcg_gen_shri_i64(ret
, arg
, 64 - len
);
2388 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
2392 if (TCG_TARGET_REG_BITS
== 32) {
2393 /* Look for a 32-bit extract within one of the two words. */
2395 tcg_gen_extract_i32(TCGV_LOW(ret
), TCGV_HIGH(arg
), ofs
- 32, len
);
2396 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2399 if (ofs
+ len
<= 32) {
2400 tcg_gen_extract_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
2401 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2404 /* The field is split across two words. One double-word
2405 shift is better than two double-word shifts. */
2409 if (TCG_TARGET_HAS_extract_i64
2410 && TCG_TARGET_extract_i64_valid(ofs
, len
)) {
2411 tcg_gen_op4ii_i64(INDEX_op_extract_i64
, ret
, arg
, ofs
, len
);
2415 /* Assume that zero-extension, if available, is cheaper than a shift. */
2416 switch (ofs
+ len
) {
2418 if (TCG_TARGET_HAS_ext32u_i64
) {
2419 tcg_gen_ext32u_i64(ret
, arg
);
2420 tcg_gen_shri_i64(ret
, ret
, ofs
);
2425 if (TCG_TARGET_HAS_ext16u_i64
) {
2426 tcg_gen_ext16u_i64(ret
, arg
);
2427 tcg_gen_shri_i64(ret
, ret
, ofs
);
2432 if (TCG_TARGET_HAS_ext8u_i64
) {
2433 tcg_gen_ext8u_i64(ret
, arg
);
2434 tcg_gen_shri_i64(ret
, ret
, ofs
);
2440 /* ??? Ideally we'd know what values are available for immediate AND.
2441 Assume that 8 bits are available, plus the special cases of 16 and 32,
2442 so that we get ext8u, ext16u, and ext32u. */
2444 case 1 ... 8: case 16: case 32:
2446 tcg_gen_shri_i64(ret
, arg
, ofs
);
2447 tcg_gen_andi_i64(ret
, ret
, (1ull << len
) - 1);
2450 tcg_gen_shli_i64(ret
, arg
, 64 - len
- ofs
);
2451 tcg_gen_shri_i64(ret
, ret
, 64 - len
);
2456 void tcg_gen_sextract_i64(TCGv_i64 ret
, TCGv_i64 arg
,
2457 unsigned int ofs
, unsigned int len
)
2459 tcg_debug_assert(ofs
< 64);
2460 tcg_debug_assert(len
> 0);
2461 tcg_debug_assert(len
<= 64);
2462 tcg_debug_assert(ofs
+ len
<= 64);
2464 /* Canonicalize certain special cases, even if sextract is supported. */
2465 if (ofs
+ len
== 64) {
2466 tcg_gen_sari_i64(ret
, arg
, 64 - len
);
2472 tcg_gen_ext32s_i64(ret
, arg
);
2475 tcg_gen_ext16s_i64(ret
, arg
);
2478 tcg_gen_ext8s_i64(ret
, arg
);
2483 if (TCG_TARGET_REG_BITS
== 32) {
2484 /* Look for a 32-bit extract within one of the two words. */
2486 tcg_gen_sextract_i32(TCGV_LOW(ret
), TCGV_HIGH(arg
), ofs
- 32, len
);
2487 } else if (ofs
+ len
<= 32) {
2488 tcg_gen_sextract_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
2489 } else if (ofs
== 0) {
2490 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
2491 tcg_gen_sextract_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
), 0, len
- 32);
2493 } else if (len
> 32) {
2494 TCGv_i32 t
= tcg_temp_ebb_new_i32();
2495 /* Extract the bits for the high word normally. */
2496 tcg_gen_sextract_i32(t
, TCGV_HIGH(arg
), ofs
+ 32, len
- 32);
2497 /* Shift the field down for the low part. */
2498 tcg_gen_shri_i64(ret
, arg
, ofs
);
2499 /* Overwrite the shift into the high part. */
2500 tcg_gen_mov_i32(TCGV_HIGH(ret
), t
);
2501 tcg_temp_free_i32(t
);
2504 /* Shift the field down for the low part, such that the
2505 field sits at the MSB. */
2506 tcg_gen_shri_i64(ret
, arg
, ofs
+ len
- 32);
2507 /* Shift the field down from the MSB, sign extending. */
2508 tcg_gen_sari_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), 32 - len
);
2510 /* Sign-extend the field from 32 bits. */
2511 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
2515 if (TCG_TARGET_HAS_sextract_i64
2516 && TCG_TARGET_extract_i64_valid(ofs
, len
)) {
2517 tcg_gen_op4ii_i64(INDEX_op_sextract_i64
, ret
, arg
, ofs
, len
);
2521 /* Assume that sign-extension, if available, is cheaper than a shift. */
2522 switch (ofs
+ len
) {
2524 if (TCG_TARGET_HAS_ext32s_i64
) {
2525 tcg_gen_ext32s_i64(ret
, arg
);
2526 tcg_gen_sari_i64(ret
, ret
, ofs
);
2531 if (TCG_TARGET_HAS_ext16s_i64
) {
2532 tcg_gen_ext16s_i64(ret
, arg
);
2533 tcg_gen_sari_i64(ret
, ret
, ofs
);
2538 if (TCG_TARGET_HAS_ext8s_i64
) {
2539 tcg_gen_ext8s_i64(ret
, arg
);
2540 tcg_gen_sari_i64(ret
, ret
, ofs
);
2547 if (TCG_TARGET_HAS_ext32s_i64
) {
2548 tcg_gen_shri_i64(ret
, arg
, ofs
);
2549 tcg_gen_ext32s_i64(ret
, ret
);
2554 if (TCG_TARGET_HAS_ext16s_i64
) {
2555 tcg_gen_shri_i64(ret
, arg
, ofs
);
2556 tcg_gen_ext16s_i64(ret
, ret
);
2561 if (TCG_TARGET_HAS_ext8s_i64
) {
2562 tcg_gen_shri_i64(ret
, arg
, ofs
);
2563 tcg_gen_ext8s_i64(ret
, ret
);
2568 tcg_gen_shli_i64(ret
, arg
, 64 - len
- ofs
);
2569 tcg_gen_sari_i64(ret
, ret
, 64 - len
);
2573 * Extract 64 bits from a 128-bit input, ah:al, starting from ofs.
2574 * Unlike tcg_gen_extract_i64 above, len is fixed at 64.
2576 void tcg_gen_extract2_i64(TCGv_i64 ret
, TCGv_i64 al
, TCGv_i64 ah
,
2579 tcg_debug_assert(ofs
<= 64);
2581 tcg_gen_mov_i64(ret
, al
);
2582 } else if (ofs
== 64) {
2583 tcg_gen_mov_i64(ret
, ah
);
2584 } else if (al
== ah
) {
2585 tcg_gen_rotri_i64(ret
, al
, ofs
);
2586 } else if (TCG_TARGET_HAS_extract2_i64
) {
2587 tcg_gen_op4i_i64(INDEX_op_extract2_i64
, ret
, al
, ah
, ofs
);
2589 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2590 tcg_gen_shri_i64(t0
, al
, ofs
);
2591 tcg_gen_deposit_i64(ret
, t0
, ah
, 64 - ofs
, ofs
);
2592 tcg_temp_free_i64(t0
);
2596 void tcg_gen_movcond_i64(TCGCond cond
, TCGv_i64 ret
, TCGv_i64 c1
,
2597 TCGv_i64 c2
, TCGv_i64 v1
, TCGv_i64 v2
)
2599 if (cond
== TCG_COND_ALWAYS
) {
2600 tcg_gen_mov_i64(ret
, v1
);
2601 } else if (cond
== TCG_COND_NEVER
) {
2602 tcg_gen_mov_i64(ret
, v2
);
2603 } else if (TCG_TARGET_REG_BITS
== 32) {
2604 TCGv_i32 t0
= tcg_temp_ebb_new_i32();
2605 TCGv_i32 t1
= tcg_temp_ebb_new_i32();
2606 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, t0
,
2607 TCGV_LOW(c1
), TCGV_HIGH(c1
),
2608 TCGV_LOW(c2
), TCGV_HIGH(c2
), cond
);
2610 if (TCG_TARGET_HAS_movcond_i32
) {
2611 tcg_gen_movi_i32(t1
, 0);
2612 tcg_gen_movcond_i32(TCG_COND_NE
, TCGV_LOW(ret
), t0
, t1
,
2613 TCGV_LOW(v1
), TCGV_LOW(v2
));
2614 tcg_gen_movcond_i32(TCG_COND_NE
, TCGV_HIGH(ret
), t0
, t1
,
2615 TCGV_HIGH(v1
), TCGV_HIGH(v2
));
2617 tcg_gen_neg_i32(t0
, t0
);
2619 tcg_gen_and_i32(t1
, TCGV_LOW(v1
), t0
);
2620 tcg_gen_andc_i32(TCGV_LOW(ret
), TCGV_LOW(v2
), t0
);
2621 tcg_gen_or_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), t1
);
2623 tcg_gen_and_i32(t1
, TCGV_HIGH(v1
), t0
);
2624 tcg_gen_andc_i32(TCGV_HIGH(ret
), TCGV_HIGH(v2
), t0
);
2625 tcg_gen_or_i32(TCGV_HIGH(ret
), TCGV_HIGH(ret
), t1
);
2627 tcg_temp_free_i32(t0
);
2628 tcg_temp_free_i32(t1
);
2629 } else if (TCG_TARGET_HAS_movcond_i64
) {
2630 tcg_gen_op6i_i64(INDEX_op_movcond_i64
, ret
, c1
, c2
, v1
, v2
, cond
);
2632 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2633 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
2634 tcg_gen_negsetcond_i64(cond
, t0
, c1
, c2
);
2635 tcg_gen_and_i64(t1
, v1
, t0
);
2636 tcg_gen_andc_i64(ret
, v2
, t0
);
2637 tcg_gen_or_i64(ret
, ret
, t1
);
2638 tcg_temp_free_i64(t0
);
2639 tcg_temp_free_i64(t1
);
2643 void tcg_gen_add2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 al
,
2644 TCGv_i64 ah
, TCGv_i64 bl
, TCGv_i64 bh
)
2646 if (TCG_TARGET_HAS_add2_i64
) {
2647 tcg_gen_op6_i64(INDEX_op_add2_i64
, rl
, rh
, al
, ah
, bl
, bh
);
2649 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2650 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
2651 tcg_gen_add_i64(t0
, al
, bl
);
2652 tcg_gen_setcond_i64(TCG_COND_LTU
, t1
, t0
, al
);
2653 tcg_gen_add_i64(rh
, ah
, bh
);
2654 tcg_gen_add_i64(rh
, rh
, t1
);
2655 tcg_gen_mov_i64(rl
, t0
);
2656 tcg_temp_free_i64(t0
);
2657 tcg_temp_free_i64(t1
);
2661 void tcg_gen_sub2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 al
,
2662 TCGv_i64 ah
, TCGv_i64 bl
, TCGv_i64 bh
)
2664 if (TCG_TARGET_HAS_sub2_i64
) {
2665 tcg_gen_op6_i64(INDEX_op_sub2_i64
, rl
, rh
, al
, ah
, bl
, bh
);
2667 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2668 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
2669 tcg_gen_sub_i64(t0
, al
, bl
);
2670 tcg_gen_setcond_i64(TCG_COND_LTU
, t1
, al
, bl
);
2671 tcg_gen_sub_i64(rh
, ah
, bh
);
2672 tcg_gen_sub_i64(rh
, rh
, t1
);
2673 tcg_gen_mov_i64(rl
, t0
);
2674 tcg_temp_free_i64(t0
);
2675 tcg_temp_free_i64(t1
);
2679 void tcg_gen_mulu2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2681 if (TCG_TARGET_HAS_mulu2_i64
) {
2682 tcg_gen_op4_i64(INDEX_op_mulu2_i64
, rl
, rh
, arg1
, arg2
);
2683 } else if (TCG_TARGET_HAS_muluh_i64
) {
2684 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2685 tcg_gen_op3_i64(INDEX_op_mul_i64
, t
, arg1
, arg2
);
2686 tcg_gen_op3_i64(INDEX_op_muluh_i64
, rh
, arg1
, arg2
);
2687 tcg_gen_mov_i64(rl
, t
);
2688 tcg_temp_free_i64(t
);
2690 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2691 tcg_gen_mul_i64(t0
, arg1
, arg2
);
2692 gen_helper_muluh_i64(rh
, arg1
, arg2
);
2693 tcg_gen_mov_i64(rl
, t0
);
2694 tcg_temp_free_i64(t0
);
2698 void tcg_gen_muls2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2700 if (TCG_TARGET_HAS_muls2_i64
) {
2701 tcg_gen_op4_i64(INDEX_op_muls2_i64
, rl
, rh
, arg1
, arg2
);
2702 } else if (TCG_TARGET_HAS_mulsh_i64
) {
2703 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2704 tcg_gen_op3_i64(INDEX_op_mul_i64
, t
, arg1
, arg2
);
2705 tcg_gen_op3_i64(INDEX_op_mulsh_i64
, rh
, arg1
, arg2
);
2706 tcg_gen_mov_i64(rl
, t
);
2707 tcg_temp_free_i64(t
);
2708 } else if (TCG_TARGET_HAS_mulu2_i64
|| TCG_TARGET_HAS_muluh_i64
) {
2709 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2710 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
2711 TCGv_i64 t2
= tcg_temp_ebb_new_i64();
2712 TCGv_i64 t3
= tcg_temp_ebb_new_i64();
2713 tcg_gen_mulu2_i64(t0
, t1
, arg1
, arg2
);
2714 /* Adjust for negative inputs. */
2715 tcg_gen_sari_i64(t2
, arg1
, 63);
2716 tcg_gen_sari_i64(t3
, arg2
, 63);
2717 tcg_gen_and_i64(t2
, t2
, arg2
);
2718 tcg_gen_and_i64(t3
, t3
, arg1
);
2719 tcg_gen_sub_i64(rh
, t1
, t2
);
2720 tcg_gen_sub_i64(rh
, rh
, t3
);
2721 tcg_gen_mov_i64(rl
, t0
);
2722 tcg_temp_free_i64(t0
);
2723 tcg_temp_free_i64(t1
);
2724 tcg_temp_free_i64(t2
);
2725 tcg_temp_free_i64(t3
);
2727 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2728 tcg_gen_mul_i64(t0
, arg1
, arg2
);
2729 gen_helper_mulsh_i64(rh
, arg1
, arg2
);
2730 tcg_gen_mov_i64(rl
, t0
);
2731 tcg_temp_free_i64(t0
);
2735 void tcg_gen_mulsu2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2737 TCGv_i64 t0
= tcg_temp_ebb_new_i64();
2738 TCGv_i64 t1
= tcg_temp_ebb_new_i64();
2739 TCGv_i64 t2
= tcg_temp_ebb_new_i64();
2740 tcg_gen_mulu2_i64(t0
, t1
, arg1
, arg2
);
2741 /* Adjust for negative input for the signed arg1. */
2742 tcg_gen_sari_i64(t2
, arg1
, 63);
2743 tcg_gen_and_i64(t2
, t2
, arg2
);
2744 tcg_gen_sub_i64(rh
, t1
, t2
);
2745 tcg_gen_mov_i64(rl
, t0
);
2746 tcg_temp_free_i64(t0
);
2747 tcg_temp_free_i64(t1
);
2748 tcg_temp_free_i64(t2
);
2751 void tcg_gen_smin_i64(TCGv_i64 ret
, TCGv_i64 a
, TCGv_i64 b
)
2753 tcg_gen_movcond_i64(TCG_COND_LT
, ret
, a
, b
, a
, b
);
2756 void tcg_gen_umin_i64(TCGv_i64 ret
, TCGv_i64 a
, TCGv_i64 b
)
2758 tcg_gen_movcond_i64(TCG_COND_LTU
, ret
, a
, b
, a
, b
);
2761 void tcg_gen_smax_i64(TCGv_i64 ret
, TCGv_i64 a
, TCGv_i64 b
)
2763 tcg_gen_movcond_i64(TCG_COND_LT
, ret
, a
, b
, b
, a
);
2766 void tcg_gen_umax_i64(TCGv_i64 ret
, TCGv_i64 a
, TCGv_i64 b
)
2768 tcg_gen_movcond_i64(TCG_COND_LTU
, ret
, a
, b
, b
, a
);
2771 void tcg_gen_abs_i64(TCGv_i64 ret
, TCGv_i64 a
)
2773 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2775 tcg_gen_sari_i64(t
, a
, 63);
2776 tcg_gen_xor_i64(ret
, a
, t
);
2777 tcg_gen_sub_i64(ret
, ret
, t
);
2778 tcg_temp_free_i64(t
);
2781 /* Size changing operations. */
2783 void tcg_gen_extrl_i64_i32(TCGv_i32 ret
, TCGv_i64 arg
)
2785 if (TCG_TARGET_REG_BITS
== 32) {
2786 tcg_gen_mov_i32(ret
, TCGV_LOW(arg
));
2787 } else if (TCG_TARGET_HAS_extr_i64_i32
) {
2788 tcg_gen_op2(INDEX_op_extrl_i64_i32
,
2789 tcgv_i32_arg(ret
), tcgv_i64_arg(arg
));
2791 tcg_gen_mov_i32(ret
, (TCGv_i32
)arg
);
2795 void tcg_gen_extrh_i64_i32(TCGv_i32 ret
, TCGv_i64 arg
)
2797 if (TCG_TARGET_REG_BITS
== 32) {
2798 tcg_gen_mov_i32(ret
, TCGV_HIGH(arg
));
2799 } else if (TCG_TARGET_HAS_extr_i64_i32
) {
2800 tcg_gen_op2(INDEX_op_extrh_i64_i32
,
2801 tcgv_i32_arg(ret
), tcgv_i64_arg(arg
));
2803 TCGv_i64 t
= tcg_temp_ebb_new_i64();
2804 tcg_gen_shri_i64(t
, arg
, 32);
2805 tcg_gen_mov_i32(ret
, (TCGv_i32
)t
);
2806 tcg_temp_free_i64(t
);
2810 void tcg_gen_extu_i32_i64(TCGv_i64 ret
, TCGv_i32 arg
)
2812 if (TCG_TARGET_REG_BITS
== 32) {
2813 tcg_gen_mov_i32(TCGV_LOW(ret
), arg
);
2814 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2816 tcg_gen_op2(INDEX_op_extu_i32_i64
,
2817 tcgv_i64_arg(ret
), tcgv_i32_arg(arg
));
2821 void tcg_gen_ext_i32_i64(TCGv_i64 ret
, TCGv_i32 arg
)
2823 if (TCG_TARGET_REG_BITS
== 32) {
2824 tcg_gen_mov_i32(TCGV_LOW(ret
), arg
);
2825 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
2827 tcg_gen_op2(INDEX_op_ext_i32_i64
,
2828 tcgv_i64_arg(ret
), tcgv_i32_arg(arg
));
2832 void tcg_gen_concat_i32_i64(TCGv_i64 dest
, TCGv_i32 low
, TCGv_i32 high
)
2836 if (TCG_TARGET_REG_BITS
== 32) {
2837 tcg_gen_mov_i32(TCGV_LOW(dest
), low
);
2838 tcg_gen_mov_i32(TCGV_HIGH(dest
), high
);
2842 tmp
= tcg_temp_ebb_new_i64();
2843 /* These extensions are only needed for type correctness.
2844 We may be able to do better given target specific information. */
2845 tcg_gen_extu_i32_i64(tmp
, high
);
2846 tcg_gen_extu_i32_i64(dest
, low
);
2847 /* If deposit is available, use it. Otherwise use the extra
2848 knowledge that we have of the zero-extensions above. */
2849 if (TCG_TARGET_HAS_deposit_i64
&& TCG_TARGET_deposit_i64_valid(32, 32)) {
2850 tcg_gen_deposit_i64(dest
, dest
, tmp
, 32, 32);
2852 tcg_gen_shli_i64(tmp
, tmp
, 32);
2853 tcg_gen_or_i64(dest
, dest
, tmp
);
2855 tcg_temp_free_i64(tmp
);
2858 void tcg_gen_extr_i64_i32(TCGv_i32 lo
, TCGv_i32 hi
, TCGv_i64 arg
)
2860 if (TCG_TARGET_REG_BITS
== 32) {
2861 tcg_gen_mov_i32(lo
, TCGV_LOW(arg
));
2862 tcg_gen_mov_i32(hi
, TCGV_HIGH(arg
));
2864 tcg_gen_extrl_i64_i32(lo
, arg
);
2865 tcg_gen_extrh_i64_i32(hi
, arg
);
2869 void tcg_gen_extr32_i64(TCGv_i64 lo
, TCGv_i64 hi
, TCGv_i64 arg
)
2871 tcg_gen_ext32u_i64(lo
, arg
);
2872 tcg_gen_shri_i64(hi
, arg
, 32);
2875 void tcg_gen_extr_i128_i64(TCGv_i64 lo
, TCGv_i64 hi
, TCGv_i128 arg
)
2877 tcg_gen_mov_i64(lo
, TCGV128_LOW(arg
));
2878 tcg_gen_mov_i64(hi
, TCGV128_HIGH(arg
));
2881 void tcg_gen_concat_i64_i128(TCGv_i128 ret
, TCGv_i64 lo
, TCGv_i64 hi
)
2883 tcg_gen_mov_i64(TCGV128_LOW(ret
), lo
);
2884 tcg_gen_mov_i64(TCGV128_HIGH(ret
), hi
);
2887 void tcg_gen_mov_i128(TCGv_i128 dst
, TCGv_i128 src
)
2890 tcg_gen_mov_i64(TCGV128_LOW(dst
), TCGV128_LOW(src
));
2891 tcg_gen_mov_i64(TCGV128_HIGH(dst
), TCGV128_HIGH(src
));
2895 void tcg_gen_ld_i128(TCGv_i128 ret
, TCGv_ptr base
, tcg_target_long offset
)
2897 if (HOST_BIG_ENDIAN
) {
2898 tcg_gen_ld_i64(TCGV128_HIGH(ret
), base
, offset
);
2899 tcg_gen_ld_i64(TCGV128_LOW(ret
), base
, offset
+ 8);
2901 tcg_gen_ld_i64(TCGV128_LOW(ret
), base
, offset
);
2902 tcg_gen_ld_i64(TCGV128_HIGH(ret
), base
, offset
+ 8);
2906 void tcg_gen_st_i128(TCGv_i128 val
, TCGv_ptr base
, tcg_target_long offset
)
2908 if (HOST_BIG_ENDIAN
) {
2909 tcg_gen_st_i64(TCGV128_HIGH(val
), base
, offset
);
2910 tcg_gen_st_i64(TCGV128_LOW(val
), base
, offset
+ 8);
2912 tcg_gen_st_i64(TCGV128_LOW(val
), base
, offset
);
2913 tcg_gen_st_i64(TCGV128_HIGH(val
), base
, offset
+ 8);
2917 /* QEMU specific operations. */
2919 void tcg_gen_exit_tb(const TranslationBlock
*tb
, unsigned idx
)
2922 * Let the jit code return the read-only version of the
2923 * TranslationBlock, so that we minimize the pc-relative
2924 * distance of the address of the exit_tb code to TB.
2925 * This will improve utilization of pc-relative address loads.
2927 * TODO: Move this to translator_loop, so that all const
2928 * TranslationBlock pointers refer to read-only memory.
2929 * This requires coordination with targets that do not use
2930 * the translator_loop.
2932 uintptr_t val
= (uintptr_t)tcg_splitwx_to_rx((void *)tb
) + idx
;
2935 tcg_debug_assert(idx
== 0);
2936 } else if (idx
<= TB_EXIT_IDXMAX
) {
2937 #ifdef CONFIG_DEBUG_TCG
2938 /* This is an exit following a goto_tb. Verify that we have
2939 seen this numbered exit before, via tcg_gen_goto_tb. */
2940 tcg_debug_assert(tcg_ctx
->goto_tb_issue_mask
& (1 << idx
));
2943 /* This is an exit via the exitreq label. */
2944 tcg_debug_assert(idx
== TB_EXIT_REQUESTED
);
2947 tcg_gen_op1i(INDEX_op_exit_tb
, val
);
2950 void tcg_gen_goto_tb(unsigned idx
)
2952 /* We tested CF_NO_GOTO_TB in translator_use_goto_tb. */
2953 tcg_debug_assert(!(tcg_ctx
->gen_tb
->cflags
& CF_NO_GOTO_TB
));
2954 /* We only support two chained exits. */
2955 tcg_debug_assert(idx
<= TB_EXIT_IDXMAX
);
2956 #ifdef CONFIG_DEBUG_TCG
2957 /* Verify that we haven't seen this numbered exit before. */
2958 tcg_debug_assert((tcg_ctx
->goto_tb_issue_mask
& (1 << idx
)) == 0);
2959 tcg_ctx
->goto_tb_issue_mask
|= 1 << idx
;
2961 plugin_gen_disable_mem_helpers();
2962 tcg_gen_op1i(INDEX_op_goto_tb
, idx
);
2965 void tcg_gen_lookup_and_goto_ptr(void)
2969 if (tcg_ctx
->gen_tb
->cflags
& CF_NO_GOTO_PTR
) {
2970 tcg_gen_exit_tb(NULL
, 0);
2974 plugin_gen_disable_mem_helpers();
2975 ptr
= tcg_temp_ebb_new_ptr();
2976 gen_helper_lookup_tb_ptr(ptr
, tcg_env
);
2977 tcg_gen_op1i(INDEX_op_goto_ptr
, tcgv_ptr_arg(ptr
));
2978 tcg_temp_free_ptr(ptr
);