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"
26 #include "qemu-common.h"
28 #include "exec/exec-all.h"
31 #include "trace-tcg.h"
32 #include "trace/mem.h"
34 /* Reduce the number of ifdefs below. This assumes that all uses of
35 TCGV_HIGH and TCGV_LOW are properly protected by a conditional that
36 the compiler can eliminate. */
37 #if TCG_TARGET_REG_BITS == 64
38 extern TCGv_i32
TCGV_LOW_link_error(TCGv_i64
);
39 extern TCGv_i32
TCGV_HIGH_link_error(TCGv_i64
);
40 #define TCGV_LOW TCGV_LOW_link_error
41 #define TCGV_HIGH TCGV_HIGH_link_error
44 /* Note that this is optimized for sequential allocation during translate.
45 Up to and including filling in the forward link immediately. We'll do
46 proper termination of the end of the list after we finish translation. */
48 static void tcg_emit_op(TCGContext
*ctx
, TCGOpcode opc
, int args
)
50 int oi
= ctx
->gen_next_op_idx
;
54 tcg_debug_assert(oi
< OPC_BUF_SIZE
);
55 ctx
->gen_op_buf
[0].prev
= oi
;
56 ctx
->gen_next_op_idx
= ni
;
58 ctx
->gen_op_buf
[oi
] = (TCGOp
){
66 void tcg_gen_op1(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
)
68 int pi
= ctx
->gen_next_parm_idx
;
70 tcg_debug_assert(pi
+ 1 <= OPPARAM_BUF_SIZE
);
71 ctx
->gen_next_parm_idx
= pi
+ 1;
72 ctx
->gen_opparam_buf
[pi
] = a1
;
74 tcg_emit_op(ctx
, opc
, pi
);
77 void tcg_gen_op2(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
, TCGArg a2
)
79 int pi
= ctx
->gen_next_parm_idx
;
81 tcg_debug_assert(pi
+ 2 <= OPPARAM_BUF_SIZE
);
82 ctx
->gen_next_parm_idx
= pi
+ 2;
83 ctx
->gen_opparam_buf
[pi
+ 0] = a1
;
84 ctx
->gen_opparam_buf
[pi
+ 1] = a2
;
86 tcg_emit_op(ctx
, opc
, pi
);
89 void tcg_gen_op3(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
,
92 int pi
= ctx
->gen_next_parm_idx
;
94 tcg_debug_assert(pi
+ 3 <= OPPARAM_BUF_SIZE
);
95 ctx
->gen_next_parm_idx
= pi
+ 3;
96 ctx
->gen_opparam_buf
[pi
+ 0] = a1
;
97 ctx
->gen_opparam_buf
[pi
+ 1] = a2
;
98 ctx
->gen_opparam_buf
[pi
+ 2] = a3
;
100 tcg_emit_op(ctx
, opc
, pi
);
103 void tcg_gen_op4(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
,
104 TCGArg a2
, TCGArg a3
, TCGArg a4
)
106 int pi
= ctx
->gen_next_parm_idx
;
108 tcg_debug_assert(pi
+ 4 <= OPPARAM_BUF_SIZE
);
109 ctx
->gen_next_parm_idx
= pi
+ 4;
110 ctx
->gen_opparam_buf
[pi
+ 0] = a1
;
111 ctx
->gen_opparam_buf
[pi
+ 1] = a2
;
112 ctx
->gen_opparam_buf
[pi
+ 2] = a3
;
113 ctx
->gen_opparam_buf
[pi
+ 3] = a4
;
115 tcg_emit_op(ctx
, opc
, pi
);
118 void tcg_gen_op5(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
,
119 TCGArg a2
, TCGArg a3
, TCGArg a4
, TCGArg a5
)
121 int pi
= ctx
->gen_next_parm_idx
;
123 tcg_debug_assert(pi
+ 5 <= OPPARAM_BUF_SIZE
);
124 ctx
->gen_next_parm_idx
= pi
+ 5;
125 ctx
->gen_opparam_buf
[pi
+ 0] = a1
;
126 ctx
->gen_opparam_buf
[pi
+ 1] = a2
;
127 ctx
->gen_opparam_buf
[pi
+ 2] = a3
;
128 ctx
->gen_opparam_buf
[pi
+ 3] = a4
;
129 ctx
->gen_opparam_buf
[pi
+ 4] = a5
;
131 tcg_emit_op(ctx
, opc
, pi
);
134 void tcg_gen_op6(TCGContext
*ctx
, TCGOpcode opc
, TCGArg a1
, TCGArg a2
,
135 TCGArg a3
, TCGArg a4
, TCGArg a5
, TCGArg a6
)
137 int pi
= ctx
->gen_next_parm_idx
;
139 tcg_debug_assert(pi
+ 6 <= OPPARAM_BUF_SIZE
);
140 ctx
->gen_next_parm_idx
= pi
+ 6;
141 ctx
->gen_opparam_buf
[pi
+ 0] = a1
;
142 ctx
->gen_opparam_buf
[pi
+ 1] = a2
;
143 ctx
->gen_opparam_buf
[pi
+ 2] = a3
;
144 ctx
->gen_opparam_buf
[pi
+ 3] = a4
;
145 ctx
->gen_opparam_buf
[pi
+ 4] = a5
;
146 ctx
->gen_opparam_buf
[pi
+ 5] = a6
;
148 tcg_emit_op(ctx
, opc
, pi
);
151 void tcg_gen_mb(TCGBar mb_type
)
154 tcg_gen_op1(&tcg_ctx
, INDEX_op_mb
, mb_type
);
160 void tcg_gen_addi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
162 /* some cases can be optimized here */
164 tcg_gen_mov_i32(ret
, arg1
);
166 TCGv_i32 t0
= tcg_const_i32(arg2
);
167 tcg_gen_add_i32(ret
, arg1
, t0
);
168 tcg_temp_free_i32(t0
);
172 void tcg_gen_subfi_i32(TCGv_i32 ret
, int32_t arg1
, TCGv_i32 arg2
)
174 if (arg1
== 0 && TCG_TARGET_HAS_neg_i32
) {
175 /* Don't recurse with tcg_gen_neg_i32. */
176 tcg_gen_op2_i32(INDEX_op_neg_i32
, ret
, arg2
);
178 TCGv_i32 t0
= tcg_const_i32(arg1
);
179 tcg_gen_sub_i32(ret
, t0
, arg2
);
180 tcg_temp_free_i32(t0
);
184 void tcg_gen_subi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
186 /* some cases can be optimized here */
188 tcg_gen_mov_i32(ret
, arg1
);
190 TCGv_i32 t0
= tcg_const_i32(arg2
);
191 tcg_gen_sub_i32(ret
, arg1
, t0
);
192 tcg_temp_free_i32(t0
);
196 void tcg_gen_andi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, uint32_t arg2
)
199 /* Some cases can be optimized here. */
202 tcg_gen_movi_i32(ret
, 0);
205 tcg_gen_mov_i32(ret
, arg1
);
208 /* Don't recurse with tcg_gen_ext8u_i32. */
209 if (TCG_TARGET_HAS_ext8u_i32
) {
210 tcg_gen_op2_i32(INDEX_op_ext8u_i32
, ret
, arg1
);
215 if (TCG_TARGET_HAS_ext16u_i32
) {
216 tcg_gen_op2_i32(INDEX_op_ext16u_i32
, ret
, arg1
);
221 t0
= tcg_const_i32(arg2
);
222 tcg_gen_and_i32(ret
, arg1
, t0
);
223 tcg_temp_free_i32(t0
);
226 void tcg_gen_ori_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
228 /* Some cases can be optimized here. */
230 tcg_gen_movi_i32(ret
, -1);
231 } else if (arg2
== 0) {
232 tcg_gen_mov_i32(ret
, arg1
);
234 TCGv_i32 t0
= tcg_const_i32(arg2
);
235 tcg_gen_or_i32(ret
, arg1
, t0
);
236 tcg_temp_free_i32(t0
);
240 void tcg_gen_xori_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
242 /* Some cases can be optimized here. */
244 tcg_gen_mov_i32(ret
, arg1
);
245 } else if (arg2
== -1 && TCG_TARGET_HAS_not_i32
) {
246 /* Don't recurse with tcg_gen_not_i32. */
247 tcg_gen_op2_i32(INDEX_op_not_i32
, ret
, arg1
);
249 TCGv_i32 t0
= tcg_const_i32(arg2
);
250 tcg_gen_xor_i32(ret
, arg1
, t0
);
251 tcg_temp_free_i32(t0
);
255 void tcg_gen_shli_i32(TCGv_i32 ret
, TCGv_i32 arg1
, unsigned arg2
)
257 tcg_debug_assert(arg2
< 32);
259 tcg_gen_mov_i32(ret
, arg1
);
261 TCGv_i32 t0
= tcg_const_i32(arg2
);
262 tcg_gen_shl_i32(ret
, arg1
, t0
);
263 tcg_temp_free_i32(t0
);
267 void tcg_gen_shri_i32(TCGv_i32 ret
, TCGv_i32 arg1
, unsigned arg2
)
269 tcg_debug_assert(arg2
< 32);
271 tcg_gen_mov_i32(ret
, arg1
);
273 TCGv_i32 t0
= tcg_const_i32(arg2
);
274 tcg_gen_shr_i32(ret
, arg1
, t0
);
275 tcg_temp_free_i32(t0
);
279 void tcg_gen_sari_i32(TCGv_i32 ret
, TCGv_i32 arg1
, unsigned arg2
)
281 tcg_debug_assert(arg2
< 32);
283 tcg_gen_mov_i32(ret
, arg1
);
285 TCGv_i32 t0
= tcg_const_i32(arg2
);
286 tcg_gen_sar_i32(ret
, arg1
, t0
);
287 tcg_temp_free_i32(t0
);
291 void tcg_gen_brcond_i32(TCGCond cond
, TCGv_i32 arg1
, TCGv_i32 arg2
, TCGLabel
*l
)
293 if (cond
== TCG_COND_ALWAYS
) {
295 } else if (cond
!= TCG_COND_NEVER
) {
296 tcg_gen_op4ii_i32(INDEX_op_brcond_i32
, arg1
, arg2
, cond
, label_arg(l
));
300 void tcg_gen_brcondi_i32(TCGCond cond
, TCGv_i32 arg1
, int32_t arg2
, TCGLabel
*l
)
302 if (cond
== TCG_COND_ALWAYS
) {
304 } else if (cond
!= TCG_COND_NEVER
) {
305 TCGv_i32 t0
= tcg_const_i32(arg2
);
306 tcg_gen_brcond_i32(cond
, arg1
, t0
, l
);
307 tcg_temp_free_i32(t0
);
311 void tcg_gen_setcond_i32(TCGCond cond
, TCGv_i32 ret
,
312 TCGv_i32 arg1
, TCGv_i32 arg2
)
314 if (cond
== TCG_COND_ALWAYS
) {
315 tcg_gen_movi_i32(ret
, 1);
316 } else if (cond
== TCG_COND_NEVER
) {
317 tcg_gen_movi_i32(ret
, 0);
319 tcg_gen_op4i_i32(INDEX_op_setcond_i32
, ret
, arg1
, arg2
, cond
);
323 void tcg_gen_setcondi_i32(TCGCond cond
, TCGv_i32 ret
,
324 TCGv_i32 arg1
, int32_t arg2
)
326 TCGv_i32 t0
= tcg_const_i32(arg2
);
327 tcg_gen_setcond_i32(cond
, ret
, arg1
, t0
);
328 tcg_temp_free_i32(t0
);
331 void tcg_gen_muli_i32(TCGv_i32 ret
, TCGv_i32 arg1
, int32_t arg2
)
333 TCGv_i32 t0
= tcg_const_i32(arg2
);
334 tcg_gen_mul_i32(ret
, arg1
, t0
);
335 tcg_temp_free_i32(t0
);
338 void tcg_gen_div_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
340 if (TCG_TARGET_HAS_div_i32
) {
341 tcg_gen_op3_i32(INDEX_op_div_i32
, ret
, arg1
, arg2
);
342 } else if (TCG_TARGET_HAS_div2_i32
) {
343 TCGv_i32 t0
= tcg_temp_new_i32();
344 tcg_gen_sari_i32(t0
, arg1
, 31);
345 tcg_gen_op5_i32(INDEX_op_div2_i32
, ret
, t0
, arg1
, t0
, arg2
);
346 tcg_temp_free_i32(t0
);
348 gen_helper_div_i32(ret
, arg1
, arg2
);
352 void tcg_gen_rem_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
354 if (TCG_TARGET_HAS_rem_i32
) {
355 tcg_gen_op3_i32(INDEX_op_rem_i32
, ret
, arg1
, arg2
);
356 } else if (TCG_TARGET_HAS_div_i32
) {
357 TCGv_i32 t0
= tcg_temp_new_i32();
358 tcg_gen_op3_i32(INDEX_op_div_i32
, t0
, arg1
, arg2
);
359 tcg_gen_mul_i32(t0
, t0
, arg2
);
360 tcg_gen_sub_i32(ret
, arg1
, t0
);
361 tcg_temp_free_i32(t0
);
362 } else if (TCG_TARGET_HAS_div2_i32
) {
363 TCGv_i32 t0
= tcg_temp_new_i32();
364 tcg_gen_sari_i32(t0
, arg1
, 31);
365 tcg_gen_op5_i32(INDEX_op_div2_i32
, t0
, ret
, arg1
, t0
, arg2
);
366 tcg_temp_free_i32(t0
);
368 gen_helper_rem_i32(ret
, arg1
, arg2
);
372 void tcg_gen_divu_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
374 if (TCG_TARGET_HAS_div_i32
) {
375 tcg_gen_op3_i32(INDEX_op_divu_i32
, ret
, arg1
, arg2
);
376 } else if (TCG_TARGET_HAS_div2_i32
) {
377 TCGv_i32 t0
= tcg_temp_new_i32();
378 tcg_gen_movi_i32(t0
, 0);
379 tcg_gen_op5_i32(INDEX_op_divu2_i32
, ret
, t0
, arg1
, t0
, arg2
);
380 tcg_temp_free_i32(t0
);
382 gen_helper_divu_i32(ret
, arg1
, arg2
);
386 void tcg_gen_remu_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
388 if (TCG_TARGET_HAS_rem_i32
) {
389 tcg_gen_op3_i32(INDEX_op_remu_i32
, ret
, arg1
, arg2
);
390 } else if (TCG_TARGET_HAS_div_i32
) {
391 TCGv_i32 t0
= tcg_temp_new_i32();
392 tcg_gen_op3_i32(INDEX_op_divu_i32
, t0
, arg1
, arg2
);
393 tcg_gen_mul_i32(t0
, t0
, arg2
);
394 tcg_gen_sub_i32(ret
, arg1
, t0
);
395 tcg_temp_free_i32(t0
);
396 } else if (TCG_TARGET_HAS_div2_i32
) {
397 TCGv_i32 t0
= tcg_temp_new_i32();
398 tcg_gen_movi_i32(t0
, 0);
399 tcg_gen_op5_i32(INDEX_op_divu2_i32
, t0
, ret
, arg1
, t0
, arg2
);
400 tcg_temp_free_i32(t0
);
402 gen_helper_remu_i32(ret
, arg1
, arg2
);
406 void tcg_gen_andc_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
408 if (TCG_TARGET_HAS_andc_i32
) {
409 tcg_gen_op3_i32(INDEX_op_andc_i32
, ret
, arg1
, arg2
);
411 TCGv_i32 t0
= tcg_temp_new_i32();
412 tcg_gen_not_i32(t0
, arg2
);
413 tcg_gen_and_i32(ret
, arg1
, t0
);
414 tcg_temp_free_i32(t0
);
418 void tcg_gen_eqv_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
420 if (TCG_TARGET_HAS_eqv_i32
) {
421 tcg_gen_op3_i32(INDEX_op_eqv_i32
, ret
, arg1
, arg2
);
423 tcg_gen_xor_i32(ret
, arg1
, arg2
);
424 tcg_gen_not_i32(ret
, ret
);
428 void tcg_gen_nand_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
430 if (TCG_TARGET_HAS_nand_i32
) {
431 tcg_gen_op3_i32(INDEX_op_nand_i32
, ret
, arg1
, arg2
);
433 tcg_gen_and_i32(ret
, arg1
, arg2
);
434 tcg_gen_not_i32(ret
, ret
);
438 void tcg_gen_nor_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
440 if (TCG_TARGET_HAS_nor_i32
) {
441 tcg_gen_op3_i32(INDEX_op_nor_i32
, ret
, arg1
, arg2
);
443 tcg_gen_or_i32(ret
, arg1
, arg2
);
444 tcg_gen_not_i32(ret
, ret
);
448 void tcg_gen_orc_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
450 if (TCG_TARGET_HAS_orc_i32
) {
451 tcg_gen_op3_i32(INDEX_op_orc_i32
, ret
, arg1
, arg2
);
453 TCGv_i32 t0
= tcg_temp_new_i32();
454 tcg_gen_not_i32(t0
, arg2
);
455 tcg_gen_or_i32(ret
, arg1
, t0
);
456 tcg_temp_free_i32(t0
);
460 void tcg_gen_clz_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
462 if (TCG_TARGET_HAS_clz_i32
) {
463 tcg_gen_op3_i32(INDEX_op_clz_i32
, ret
, arg1
, arg2
);
464 } else if (TCG_TARGET_HAS_clz_i64
) {
465 TCGv_i64 t1
= tcg_temp_new_i64();
466 TCGv_i64 t2
= tcg_temp_new_i64();
467 tcg_gen_extu_i32_i64(t1
, arg1
);
468 tcg_gen_extu_i32_i64(t2
, arg2
);
469 tcg_gen_addi_i64(t2
, t2
, 32);
470 tcg_gen_clz_i64(t1
, t1
, t2
);
471 tcg_gen_extrl_i64_i32(ret
, t1
);
472 tcg_temp_free_i64(t1
);
473 tcg_temp_free_i64(t2
);
474 tcg_gen_subi_i32(ret
, ret
, 32);
476 gen_helper_clz_i32(ret
, arg1
, arg2
);
480 void tcg_gen_clzi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, uint32_t arg2
)
482 TCGv_i32 t
= tcg_const_i32(arg2
);
483 tcg_gen_clz_i32(ret
, arg1
, t
);
484 tcg_temp_free_i32(t
);
487 void tcg_gen_ctz_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
489 if (TCG_TARGET_HAS_ctz_i32
) {
490 tcg_gen_op3_i32(INDEX_op_ctz_i32
, ret
, arg1
, arg2
);
491 } else if (TCG_TARGET_HAS_ctz_i64
) {
492 TCGv_i64 t1
= tcg_temp_new_i64();
493 TCGv_i64 t2
= tcg_temp_new_i64();
494 tcg_gen_extu_i32_i64(t1
, arg1
);
495 tcg_gen_extu_i32_i64(t2
, arg2
);
496 tcg_gen_ctz_i64(t1
, t1
, t2
);
497 tcg_gen_extrl_i64_i32(ret
, t1
);
498 tcg_temp_free_i64(t1
);
499 tcg_temp_free_i64(t2
);
500 } else if (TCG_TARGET_HAS_clz_i32
) {
501 TCGv_i32 t1
= tcg_temp_new_i32();
502 TCGv_i32 t2
= tcg_temp_new_i32();
503 tcg_gen_neg_i32(t1
, arg1
);
504 tcg_gen_xori_i32(t2
, arg2
, 31);
505 tcg_gen_and_i32(t1
, t1
, arg1
);
506 tcg_gen_clz_i32(ret
, t1
, t2
);
507 tcg_temp_free_i32(t1
);
508 tcg_temp_free_i32(t2
);
509 tcg_gen_xori_i32(ret
, ret
, 31);
510 } else if (TCG_TARGET_HAS_clz_i64
) {
511 TCGv_i32 t1
= tcg_temp_new_i32();
512 TCGv_i32 t2
= tcg_temp_new_i32();
513 TCGv_i64 x1
= tcg_temp_new_i64();
514 TCGv_i64 x2
= tcg_temp_new_i64();
515 tcg_gen_neg_i32(t1
, arg1
);
516 tcg_gen_xori_i32(t2
, arg2
, 63);
517 tcg_gen_and_i32(t1
, t1
, arg1
);
518 tcg_gen_extu_i32_i64(x1
, t1
);
519 tcg_gen_extu_i32_i64(x2
, t2
);
520 tcg_temp_free_i32(t1
);
521 tcg_temp_free_i32(t2
);
522 tcg_gen_clz_i64(x1
, x1
, x2
);
523 tcg_gen_extrl_i64_i32(ret
, x1
);
524 tcg_temp_free_i64(x1
);
525 tcg_temp_free_i64(x2
);
526 tcg_gen_xori_i32(ret
, ret
, 63);
528 gen_helper_ctz_i32(ret
, arg1
, arg2
);
532 void tcg_gen_ctzi_i32(TCGv_i32 ret
, TCGv_i32 arg1
, uint32_t arg2
)
534 TCGv_i32 t
= tcg_const_i32(arg2
);
535 tcg_gen_ctz_i32(ret
, arg1
, t
);
536 tcg_temp_free_i32(t
);
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_new_i32();
547 t1
= tcg_temp_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
, unsigned arg2
)
559 tcg_debug_assert(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 TCGv_i32 t0
= tcg_const_i32(arg2
);
565 tcg_gen_rotl_i32(ret
, arg1
, t0
);
566 tcg_temp_free_i32(t0
);
569 t0
= tcg_temp_new_i32();
570 t1
= tcg_temp_new_i32();
571 tcg_gen_shli_i32(t0
, arg1
, arg2
);
572 tcg_gen_shri_i32(t1
, arg1
, 32 - arg2
);
573 tcg_gen_or_i32(ret
, t0
, t1
);
574 tcg_temp_free_i32(t0
);
575 tcg_temp_free_i32(t1
);
579 void tcg_gen_rotr_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
)
581 if (TCG_TARGET_HAS_rot_i32
) {
582 tcg_gen_op3_i32(INDEX_op_rotr_i32
, ret
, arg1
, arg2
);
586 t0
= tcg_temp_new_i32();
587 t1
= tcg_temp_new_i32();
588 tcg_gen_shr_i32(t0
, arg1
, arg2
);
589 tcg_gen_subfi_i32(t1
, 32, arg2
);
590 tcg_gen_shl_i32(t1
, arg1
, t1
);
591 tcg_gen_or_i32(ret
, t0
, t1
);
592 tcg_temp_free_i32(t0
);
593 tcg_temp_free_i32(t1
);
597 void tcg_gen_rotri_i32(TCGv_i32 ret
, TCGv_i32 arg1
, unsigned arg2
)
599 tcg_debug_assert(arg2
< 32);
600 /* some cases can be optimized here */
602 tcg_gen_mov_i32(ret
, arg1
);
604 tcg_gen_rotli_i32(ret
, arg1
, 32 - arg2
);
608 void tcg_gen_deposit_i32(TCGv_i32 ret
, TCGv_i32 arg1
, TCGv_i32 arg2
,
609 unsigned int ofs
, unsigned int len
)
614 tcg_debug_assert(ofs
< 32);
615 tcg_debug_assert(len
> 0);
616 tcg_debug_assert(len
<= 32);
617 tcg_debug_assert(ofs
+ len
<= 32);
620 tcg_gen_mov_i32(ret
, arg2
);
623 if (TCG_TARGET_HAS_deposit_i32
&& TCG_TARGET_deposit_i32_valid(ofs
, len
)) {
624 tcg_gen_op5ii_i32(INDEX_op_deposit_i32
, ret
, arg1
, arg2
, ofs
, len
);
628 mask
= (1u << len
) - 1;
629 t1
= tcg_temp_new_i32();
631 if (ofs
+ len
< 32) {
632 tcg_gen_andi_i32(t1
, arg2
, mask
);
633 tcg_gen_shli_i32(t1
, t1
, ofs
);
635 tcg_gen_shli_i32(t1
, arg2
, ofs
);
637 tcg_gen_andi_i32(ret
, arg1
, ~(mask
<< ofs
));
638 tcg_gen_or_i32(ret
, ret
, t1
);
640 tcg_temp_free_i32(t1
);
643 void tcg_gen_deposit_z_i32(TCGv_i32 ret
, TCGv_i32 arg
,
644 unsigned int ofs
, unsigned int len
)
646 tcg_debug_assert(ofs
< 32);
647 tcg_debug_assert(len
> 0);
648 tcg_debug_assert(len
<= 32);
649 tcg_debug_assert(ofs
+ len
<= 32);
651 if (ofs
+ len
== 32) {
652 tcg_gen_shli_i32(ret
, arg
, ofs
);
653 } else if (ofs
== 0) {
654 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
655 } else if (TCG_TARGET_HAS_deposit_i32
656 && TCG_TARGET_deposit_i32_valid(ofs
, len
)) {
657 TCGv_i32 zero
= tcg_const_i32(0);
658 tcg_gen_op5ii_i32(INDEX_op_deposit_i32
, ret
, zero
, arg
, ofs
, len
);
659 tcg_temp_free_i32(zero
);
661 /* To help two-operand hosts we prefer to zero-extend first,
662 which allows ARG to stay live. */
665 if (TCG_TARGET_HAS_ext16u_i32
) {
666 tcg_gen_ext16u_i32(ret
, arg
);
667 tcg_gen_shli_i32(ret
, ret
, ofs
);
672 if (TCG_TARGET_HAS_ext8u_i32
) {
673 tcg_gen_ext8u_i32(ret
, arg
);
674 tcg_gen_shli_i32(ret
, ret
, ofs
);
679 /* Otherwise prefer zero-extension over AND for code size. */
682 if (TCG_TARGET_HAS_ext16u_i32
) {
683 tcg_gen_shli_i32(ret
, arg
, ofs
);
684 tcg_gen_ext16u_i32(ret
, ret
);
689 if (TCG_TARGET_HAS_ext8u_i32
) {
690 tcg_gen_shli_i32(ret
, arg
, ofs
);
691 tcg_gen_ext8u_i32(ret
, ret
);
696 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
697 tcg_gen_shli_i32(ret
, ret
, ofs
);
701 void tcg_gen_extract_i32(TCGv_i32 ret
, TCGv_i32 arg
,
702 unsigned int ofs
, unsigned int len
)
704 tcg_debug_assert(ofs
< 32);
705 tcg_debug_assert(len
> 0);
706 tcg_debug_assert(len
<= 32);
707 tcg_debug_assert(ofs
+ len
<= 32);
709 /* Canonicalize certain special cases, even if extract is supported. */
710 if (ofs
+ len
== 32) {
711 tcg_gen_shri_i32(ret
, arg
, 32 - len
);
715 tcg_gen_andi_i32(ret
, arg
, (1u << len
) - 1);
719 if (TCG_TARGET_HAS_extract_i32
720 && TCG_TARGET_extract_i32_valid(ofs
, len
)) {
721 tcg_gen_op4ii_i32(INDEX_op_extract_i32
, ret
, arg
, ofs
, len
);
725 /* Assume that zero-extension, if available, is cheaper than a shift. */
728 if (TCG_TARGET_HAS_ext16u_i32
) {
729 tcg_gen_ext16u_i32(ret
, arg
);
730 tcg_gen_shri_i32(ret
, ret
, ofs
);
735 if (TCG_TARGET_HAS_ext8u_i32
) {
736 tcg_gen_ext8u_i32(ret
, arg
);
737 tcg_gen_shri_i32(ret
, ret
, ofs
);
743 /* ??? Ideally we'd know what values are available for immediate AND.
744 Assume that 8 bits are available, plus the special case of 16,
745 so that we get ext8u, ext16u. */
747 case 1 ... 8: case 16:
748 tcg_gen_shri_i32(ret
, arg
, ofs
);
749 tcg_gen_andi_i32(ret
, ret
, (1u << len
) - 1);
752 tcg_gen_shli_i32(ret
, arg
, 32 - len
- ofs
);
753 tcg_gen_shri_i32(ret
, ret
, 32 - len
);
758 void tcg_gen_sextract_i32(TCGv_i32 ret
, TCGv_i32 arg
,
759 unsigned int ofs
, unsigned int len
)
761 tcg_debug_assert(ofs
< 32);
762 tcg_debug_assert(len
> 0);
763 tcg_debug_assert(len
<= 32);
764 tcg_debug_assert(ofs
+ len
<= 32);
766 /* Canonicalize certain special cases, even if extract is supported. */
767 if (ofs
+ len
== 32) {
768 tcg_gen_sari_i32(ret
, arg
, 32 - len
);
774 tcg_gen_ext16s_i32(ret
, arg
);
777 tcg_gen_ext8s_i32(ret
, arg
);
782 if (TCG_TARGET_HAS_sextract_i32
783 && TCG_TARGET_extract_i32_valid(ofs
, len
)) {
784 tcg_gen_op4ii_i32(INDEX_op_sextract_i32
, ret
, arg
, ofs
, len
);
788 /* Assume that sign-extension, if available, is cheaper than a shift. */
791 if (TCG_TARGET_HAS_ext16s_i32
) {
792 tcg_gen_ext16s_i32(ret
, arg
);
793 tcg_gen_sari_i32(ret
, ret
, ofs
);
798 if (TCG_TARGET_HAS_ext8s_i32
) {
799 tcg_gen_ext8s_i32(ret
, arg
);
800 tcg_gen_sari_i32(ret
, ret
, ofs
);
807 if (TCG_TARGET_HAS_ext16s_i32
) {
808 tcg_gen_shri_i32(ret
, arg
, ofs
);
809 tcg_gen_ext16s_i32(ret
, ret
);
814 if (TCG_TARGET_HAS_ext8s_i32
) {
815 tcg_gen_shri_i32(ret
, arg
, ofs
);
816 tcg_gen_ext8s_i32(ret
, ret
);
822 tcg_gen_shli_i32(ret
, arg
, 32 - len
- ofs
);
823 tcg_gen_sari_i32(ret
, ret
, 32 - len
);
826 void tcg_gen_movcond_i32(TCGCond cond
, TCGv_i32 ret
, TCGv_i32 c1
,
827 TCGv_i32 c2
, TCGv_i32 v1
, TCGv_i32 v2
)
829 if (cond
== TCG_COND_ALWAYS
) {
830 tcg_gen_mov_i32(ret
, v1
);
831 } else if (cond
== TCG_COND_NEVER
) {
832 tcg_gen_mov_i32(ret
, v2
);
833 } else if (TCG_TARGET_HAS_movcond_i32
) {
834 tcg_gen_op6i_i32(INDEX_op_movcond_i32
, ret
, c1
, c2
, v1
, v2
, cond
);
836 TCGv_i32 t0
= tcg_temp_new_i32();
837 TCGv_i32 t1
= tcg_temp_new_i32();
838 tcg_gen_setcond_i32(cond
, t0
, c1
, c2
);
839 tcg_gen_neg_i32(t0
, t0
);
840 tcg_gen_and_i32(t1
, v1
, t0
);
841 tcg_gen_andc_i32(ret
, v2
, t0
);
842 tcg_gen_or_i32(ret
, ret
, t1
);
843 tcg_temp_free_i32(t0
);
844 tcg_temp_free_i32(t1
);
848 void tcg_gen_add2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 al
,
849 TCGv_i32 ah
, TCGv_i32 bl
, TCGv_i32 bh
)
851 if (TCG_TARGET_HAS_add2_i32
) {
852 tcg_gen_op6_i32(INDEX_op_add2_i32
, rl
, rh
, al
, ah
, bl
, bh
);
854 TCGv_i64 t0
= tcg_temp_new_i64();
855 TCGv_i64 t1
= tcg_temp_new_i64();
856 tcg_gen_concat_i32_i64(t0
, al
, ah
);
857 tcg_gen_concat_i32_i64(t1
, bl
, bh
);
858 tcg_gen_add_i64(t0
, t0
, t1
);
859 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
860 tcg_temp_free_i64(t0
);
861 tcg_temp_free_i64(t1
);
865 void tcg_gen_sub2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 al
,
866 TCGv_i32 ah
, TCGv_i32 bl
, TCGv_i32 bh
)
868 if (TCG_TARGET_HAS_sub2_i32
) {
869 tcg_gen_op6_i32(INDEX_op_sub2_i32
, rl
, rh
, al
, ah
, bl
, bh
);
871 TCGv_i64 t0
= tcg_temp_new_i64();
872 TCGv_i64 t1
= tcg_temp_new_i64();
873 tcg_gen_concat_i32_i64(t0
, al
, ah
);
874 tcg_gen_concat_i32_i64(t1
, bl
, bh
);
875 tcg_gen_sub_i64(t0
, t0
, t1
);
876 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
877 tcg_temp_free_i64(t0
);
878 tcg_temp_free_i64(t1
);
882 void tcg_gen_mulu2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
884 if (TCG_TARGET_HAS_mulu2_i32
) {
885 tcg_gen_op4_i32(INDEX_op_mulu2_i32
, rl
, rh
, arg1
, arg2
);
886 } else if (TCG_TARGET_HAS_muluh_i32
) {
887 TCGv_i32 t
= tcg_temp_new_i32();
888 tcg_gen_op3_i32(INDEX_op_mul_i32
, t
, arg1
, arg2
);
889 tcg_gen_op3_i32(INDEX_op_muluh_i32
, rh
, arg1
, arg2
);
890 tcg_gen_mov_i32(rl
, t
);
891 tcg_temp_free_i32(t
);
893 TCGv_i64 t0
= tcg_temp_new_i64();
894 TCGv_i64 t1
= tcg_temp_new_i64();
895 tcg_gen_extu_i32_i64(t0
, arg1
);
896 tcg_gen_extu_i32_i64(t1
, arg2
);
897 tcg_gen_mul_i64(t0
, t0
, t1
);
898 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
899 tcg_temp_free_i64(t0
);
900 tcg_temp_free_i64(t1
);
904 void tcg_gen_muls2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
906 if (TCG_TARGET_HAS_muls2_i32
) {
907 tcg_gen_op4_i32(INDEX_op_muls2_i32
, rl
, rh
, arg1
, arg2
);
908 } else if (TCG_TARGET_HAS_mulsh_i32
) {
909 TCGv_i32 t
= tcg_temp_new_i32();
910 tcg_gen_op3_i32(INDEX_op_mul_i32
, t
, arg1
, arg2
);
911 tcg_gen_op3_i32(INDEX_op_mulsh_i32
, rh
, arg1
, arg2
);
912 tcg_gen_mov_i32(rl
, t
);
913 tcg_temp_free_i32(t
);
914 } else if (TCG_TARGET_REG_BITS
== 32) {
915 TCGv_i32 t0
= tcg_temp_new_i32();
916 TCGv_i32 t1
= tcg_temp_new_i32();
917 TCGv_i32 t2
= tcg_temp_new_i32();
918 TCGv_i32 t3
= tcg_temp_new_i32();
919 tcg_gen_mulu2_i32(t0
, t1
, arg1
, arg2
);
920 /* Adjust for negative inputs. */
921 tcg_gen_sari_i32(t2
, arg1
, 31);
922 tcg_gen_sari_i32(t3
, arg2
, 31);
923 tcg_gen_and_i32(t2
, t2
, arg2
);
924 tcg_gen_and_i32(t3
, t3
, arg1
);
925 tcg_gen_sub_i32(rh
, t1
, t2
);
926 tcg_gen_sub_i32(rh
, rh
, t3
);
927 tcg_gen_mov_i32(rl
, t0
);
928 tcg_temp_free_i32(t0
);
929 tcg_temp_free_i32(t1
);
930 tcg_temp_free_i32(t2
);
931 tcg_temp_free_i32(t3
);
933 TCGv_i64 t0
= tcg_temp_new_i64();
934 TCGv_i64 t1
= tcg_temp_new_i64();
935 tcg_gen_ext_i32_i64(t0
, arg1
);
936 tcg_gen_ext_i32_i64(t1
, arg2
);
937 tcg_gen_mul_i64(t0
, t0
, t1
);
938 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
939 tcg_temp_free_i64(t0
);
940 tcg_temp_free_i64(t1
);
944 void tcg_gen_mulsu2_i32(TCGv_i32 rl
, TCGv_i32 rh
, TCGv_i32 arg1
, TCGv_i32 arg2
)
946 if (TCG_TARGET_REG_BITS
== 32) {
947 TCGv_i32 t0
= tcg_temp_new_i32();
948 TCGv_i32 t1
= tcg_temp_new_i32();
949 TCGv_i32 t2
= tcg_temp_new_i32();
950 tcg_gen_mulu2_i32(t0
, t1
, arg1
, arg2
);
951 /* Adjust for negative input for the signed arg1. */
952 tcg_gen_sari_i32(t2
, arg1
, 31);
953 tcg_gen_and_i32(t2
, t2
, arg2
);
954 tcg_gen_sub_i32(rh
, t1
, t2
);
955 tcg_gen_mov_i32(rl
, t0
);
956 tcg_temp_free_i32(t0
);
957 tcg_temp_free_i32(t1
);
958 tcg_temp_free_i32(t2
);
960 TCGv_i64 t0
= tcg_temp_new_i64();
961 TCGv_i64 t1
= tcg_temp_new_i64();
962 tcg_gen_ext_i32_i64(t0
, arg1
);
963 tcg_gen_extu_i32_i64(t1
, arg2
);
964 tcg_gen_mul_i64(t0
, t0
, t1
);
965 tcg_gen_extr_i64_i32(rl
, rh
, t0
);
966 tcg_temp_free_i64(t0
);
967 tcg_temp_free_i64(t1
);
971 void tcg_gen_ext8s_i32(TCGv_i32 ret
, TCGv_i32 arg
)
973 if (TCG_TARGET_HAS_ext8s_i32
) {
974 tcg_gen_op2_i32(INDEX_op_ext8s_i32
, ret
, arg
);
976 tcg_gen_shli_i32(ret
, arg
, 24);
977 tcg_gen_sari_i32(ret
, ret
, 24);
981 void tcg_gen_ext16s_i32(TCGv_i32 ret
, TCGv_i32 arg
)
983 if (TCG_TARGET_HAS_ext16s_i32
) {
984 tcg_gen_op2_i32(INDEX_op_ext16s_i32
, ret
, arg
);
986 tcg_gen_shli_i32(ret
, arg
, 16);
987 tcg_gen_sari_i32(ret
, ret
, 16);
991 void tcg_gen_ext8u_i32(TCGv_i32 ret
, TCGv_i32 arg
)
993 if (TCG_TARGET_HAS_ext8u_i32
) {
994 tcg_gen_op2_i32(INDEX_op_ext8u_i32
, ret
, arg
);
996 tcg_gen_andi_i32(ret
, arg
, 0xffu
);
1000 void tcg_gen_ext16u_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1002 if (TCG_TARGET_HAS_ext16u_i32
) {
1003 tcg_gen_op2_i32(INDEX_op_ext16u_i32
, ret
, arg
);
1005 tcg_gen_andi_i32(ret
, arg
, 0xffffu
);
1009 /* Note: we assume the two high bytes are set to zero */
1010 void tcg_gen_bswap16_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1012 if (TCG_TARGET_HAS_bswap16_i32
) {
1013 tcg_gen_op2_i32(INDEX_op_bswap16_i32
, ret
, arg
);
1015 TCGv_i32 t0
= tcg_temp_new_i32();
1017 tcg_gen_ext8u_i32(t0
, arg
);
1018 tcg_gen_shli_i32(t0
, t0
, 8);
1019 tcg_gen_shri_i32(ret
, arg
, 8);
1020 tcg_gen_or_i32(ret
, ret
, t0
);
1021 tcg_temp_free_i32(t0
);
1025 void tcg_gen_bswap32_i32(TCGv_i32 ret
, TCGv_i32 arg
)
1027 if (TCG_TARGET_HAS_bswap32_i32
) {
1028 tcg_gen_op2_i32(INDEX_op_bswap32_i32
, ret
, arg
);
1031 t0
= tcg_temp_new_i32();
1032 t1
= tcg_temp_new_i32();
1034 tcg_gen_shli_i32(t0
, arg
, 24);
1036 tcg_gen_andi_i32(t1
, arg
, 0x0000ff00);
1037 tcg_gen_shli_i32(t1
, t1
, 8);
1038 tcg_gen_or_i32(t0
, t0
, t1
);
1040 tcg_gen_shri_i32(t1
, arg
, 8);
1041 tcg_gen_andi_i32(t1
, t1
, 0x0000ff00);
1042 tcg_gen_or_i32(t0
, t0
, t1
);
1044 tcg_gen_shri_i32(t1
, arg
, 24);
1045 tcg_gen_or_i32(ret
, t0
, t1
);
1046 tcg_temp_free_i32(t0
);
1047 tcg_temp_free_i32(t1
);
1053 #if TCG_TARGET_REG_BITS == 32
1054 /* These are all inline for TCG_TARGET_REG_BITS == 64. */
1056 void tcg_gen_discard_i64(TCGv_i64 arg
)
1058 tcg_gen_discard_i32(TCGV_LOW(arg
));
1059 tcg_gen_discard_i32(TCGV_HIGH(arg
));
1062 void tcg_gen_mov_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1064 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1065 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
));
1068 void tcg_gen_movi_i64(TCGv_i64 ret
, int64_t arg
)
1070 tcg_gen_movi_i32(TCGV_LOW(ret
), arg
);
1071 tcg_gen_movi_i32(TCGV_HIGH(ret
), arg
>> 32);
1074 void tcg_gen_ld8u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1076 tcg_gen_ld8u_i32(TCGV_LOW(ret
), arg2
, offset
);
1077 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1080 void tcg_gen_ld8s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1082 tcg_gen_ld8s_i32(TCGV_LOW(ret
), arg2
, offset
);
1083 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1086 void tcg_gen_ld16u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1088 tcg_gen_ld16u_i32(TCGV_LOW(ret
), arg2
, offset
);
1089 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1092 void tcg_gen_ld16s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1094 tcg_gen_ld16s_i32(TCGV_LOW(ret
), arg2
, offset
);
1095 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1098 void tcg_gen_ld32u_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1100 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1101 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1104 void tcg_gen_ld32s_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1106 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1107 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1110 void tcg_gen_ld_i64(TCGv_i64 ret
, TCGv_ptr arg2
, tcg_target_long offset
)
1112 /* Since arg2 and ret have different types,
1113 they cannot be the same temporary */
1114 #ifdef HOST_WORDS_BIGENDIAN
1115 tcg_gen_ld_i32(TCGV_HIGH(ret
), arg2
, offset
);
1116 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
+ 4);
1118 tcg_gen_ld_i32(TCGV_LOW(ret
), arg2
, offset
);
1119 tcg_gen_ld_i32(TCGV_HIGH(ret
), arg2
, offset
+ 4);
1123 void tcg_gen_st_i64(TCGv_i64 arg1
, TCGv_ptr arg2
, tcg_target_long offset
)
1125 #ifdef HOST_WORDS_BIGENDIAN
1126 tcg_gen_st_i32(TCGV_HIGH(arg1
), arg2
, offset
);
1127 tcg_gen_st_i32(TCGV_LOW(arg1
), arg2
, offset
+ 4);
1129 tcg_gen_st_i32(TCGV_LOW(arg1
), arg2
, offset
);
1130 tcg_gen_st_i32(TCGV_HIGH(arg1
), arg2
, offset
+ 4);
1134 void tcg_gen_and_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1136 tcg_gen_and_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1137 tcg_gen_and_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1140 void tcg_gen_or_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1142 tcg_gen_or_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1143 tcg_gen_or_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1146 void tcg_gen_xor_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1148 tcg_gen_xor_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1149 tcg_gen_xor_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1152 void tcg_gen_shl_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1154 gen_helper_shl_i64(ret
, arg1
, arg2
);
1157 void tcg_gen_shr_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1159 gen_helper_shr_i64(ret
, arg1
, arg2
);
1162 void tcg_gen_sar_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1164 gen_helper_sar_i64(ret
, arg1
, arg2
);
1167 void tcg_gen_mul_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1172 t0
= tcg_temp_new_i64();
1173 t1
= tcg_temp_new_i32();
1175 tcg_gen_mulu2_i32(TCGV_LOW(t0
), TCGV_HIGH(t0
),
1176 TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1178 tcg_gen_mul_i32(t1
, TCGV_LOW(arg1
), TCGV_HIGH(arg2
));
1179 tcg_gen_add_i32(TCGV_HIGH(t0
), TCGV_HIGH(t0
), t1
);
1180 tcg_gen_mul_i32(t1
, TCGV_HIGH(arg1
), TCGV_LOW(arg2
));
1181 tcg_gen_add_i32(TCGV_HIGH(t0
), TCGV_HIGH(t0
), t1
);
1183 tcg_gen_mov_i64(ret
, t0
);
1184 tcg_temp_free_i64(t0
);
1185 tcg_temp_free_i32(t1
);
1187 #endif /* TCG_TARGET_REG_SIZE == 32 */
1189 void tcg_gen_addi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1191 /* some cases can be optimized here */
1193 tcg_gen_mov_i64(ret
, arg1
);
1195 TCGv_i64 t0
= tcg_const_i64(arg2
);
1196 tcg_gen_add_i64(ret
, arg1
, t0
);
1197 tcg_temp_free_i64(t0
);
1201 void tcg_gen_subfi_i64(TCGv_i64 ret
, int64_t arg1
, TCGv_i64 arg2
)
1203 if (arg1
== 0 && TCG_TARGET_HAS_neg_i64
) {
1204 /* Don't recurse with tcg_gen_neg_i64. */
1205 tcg_gen_op2_i64(INDEX_op_neg_i64
, ret
, arg2
);
1207 TCGv_i64 t0
= tcg_const_i64(arg1
);
1208 tcg_gen_sub_i64(ret
, t0
, arg2
);
1209 tcg_temp_free_i64(t0
);
1213 void tcg_gen_subi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1215 /* some cases can be optimized here */
1217 tcg_gen_mov_i64(ret
, arg1
);
1219 TCGv_i64 t0
= tcg_const_i64(arg2
);
1220 tcg_gen_sub_i64(ret
, arg1
, t0
);
1221 tcg_temp_free_i64(t0
);
1225 void tcg_gen_andi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, uint64_t arg2
)
1229 if (TCG_TARGET_REG_BITS
== 32) {
1230 tcg_gen_andi_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1231 tcg_gen_andi_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1235 /* Some cases can be optimized here. */
1238 tcg_gen_movi_i64(ret
, 0);
1240 case 0xffffffffffffffffull
:
1241 tcg_gen_mov_i64(ret
, arg1
);
1244 /* Don't recurse with tcg_gen_ext8u_i64. */
1245 if (TCG_TARGET_HAS_ext8u_i64
) {
1246 tcg_gen_op2_i64(INDEX_op_ext8u_i64
, ret
, arg1
);
1251 if (TCG_TARGET_HAS_ext16u_i64
) {
1252 tcg_gen_op2_i64(INDEX_op_ext16u_i64
, ret
, arg1
);
1257 if (TCG_TARGET_HAS_ext32u_i64
) {
1258 tcg_gen_op2_i64(INDEX_op_ext32u_i64
, ret
, arg1
);
1263 t0
= tcg_const_i64(arg2
);
1264 tcg_gen_and_i64(ret
, arg1
, t0
);
1265 tcg_temp_free_i64(t0
);
1268 void tcg_gen_ori_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1270 if (TCG_TARGET_REG_BITS
== 32) {
1271 tcg_gen_ori_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1272 tcg_gen_ori_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1275 /* Some cases can be optimized here. */
1277 tcg_gen_movi_i64(ret
, -1);
1278 } else if (arg2
== 0) {
1279 tcg_gen_mov_i64(ret
, arg1
);
1281 TCGv_i64 t0
= tcg_const_i64(arg2
);
1282 tcg_gen_or_i64(ret
, arg1
, t0
);
1283 tcg_temp_free_i64(t0
);
1287 void tcg_gen_xori_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1289 if (TCG_TARGET_REG_BITS
== 32) {
1290 tcg_gen_xori_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), arg2
);
1291 tcg_gen_xori_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), arg2
>> 32);
1294 /* Some cases can be optimized here. */
1296 tcg_gen_mov_i64(ret
, arg1
);
1297 } else if (arg2
== -1 && TCG_TARGET_HAS_not_i64
) {
1298 /* Don't recurse with tcg_gen_not_i64. */
1299 tcg_gen_op2_i64(INDEX_op_not_i64
, ret
, arg1
);
1301 TCGv_i64 t0
= tcg_const_i64(arg2
);
1302 tcg_gen_xor_i64(ret
, arg1
, t0
);
1303 tcg_temp_free_i64(t0
);
1307 static inline void tcg_gen_shifti_i64(TCGv_i64 ret
, TCGv_i64 arg1
,
1308 unsigned c
, bool right
, bool arith
)
1310 tcg_debug_assert(c
< 64);
1312 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
));
1313 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
));
1314 } else if (c
>= 32) {
1318 tcg_gen_sari_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), c
);
1319 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), 31);
1321 tcg_gen_shri_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), c
);
1322 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1325 tcg_gen_shli_i32(TCGV_HIGH(ret
), TCGV_LOW(arg1
), c
);
1326 tcg_gen_movi_i32(TCGV_LOW(ret
), 0);
1331 t0
= tcg_temp_new_i32();
1332 t1
= tcg_temp_new_i32();
1334 tcg_gen_shli_i32(t0
, TCGV_HIGH(arg1
), 32 - c
);
1336 tcg_gen_sari_i32(t1
, TCGV_HIGH(arg1
), c
);
1338 tcg_gen_shri_i32(t1
, TCGV_HIGH(arg1
), c
);
1340 tcg_gen_shri_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), c
);
1341 tcg_gen_or_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), t0
);
1342 tcg_gen_mov_i32(TCGV_HIGH(ret
), t1
);
1344 tcg_gen_shri_i32(t0
, TCGV_LOW(arg1
), 32 - c
);
1345 /* Note: ret can be the same as arg1, so we use t1 */
1346 tcg_gen_shli_i32(t1
, TCGV_LOW(arg1
), c
);
1347 tcg_gen_shli_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), c
);
1348 tcg_gen_or_i32(TCGV_HIGH(ret
), TCGV_HIGH(ret
), t0
);
1349 tcg_gen_mov_i32(TCGV_LOW(ret
), t1
);
1351 tcg_temp_free_i32(t0
);
1352 tcg_temp_free_i32(t1
);
1356 void tcg_gen_shli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, unsigned arg2
)
1358 tcg_debug_assert(arg2
< 64);
1359 if (TCG_TARGET_REG_BITS
== 32) {
1360 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 0, 0);
1361 } else if (arg2
== 0) {
1362 tcg_gen_mov_i64(ret
, arg1
);
1364 TCGv_i64 t0
= tcg_const_i64(arg2
);
1365 tcg_gen_shl_i64(ret
, arg1
, t0
);
1366 tcg_temp_free_i64(t0
);
1370 void tcg_gen_shri_i64(TCGv_i64 ret
, TCGv_i64 arg1
, unsigned arg2
)
1372 tcg_debug_assert(arg2
< 64);
1373 if (TCG_TARGET_REG_BITS
== 32) {
1374 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 0);
1375 } else if (arg2
== 0) {
1376 tcg_gen_mov_i64(ret
, arg1
);
1378 TCGv_i64 t0
= tcg_const_i64(arg2
);
1379 tcg_gen_shr_i64(ret
, arg1
, t0
);
1380 tcg_temp_free_i64(t0
);
1384 void tcg_gen_sari_i64(TCGv_i64 ret
, TCGv_i64 arg1
, unsigned arg2
)
1386 tcg_debug_assert(arg2
< 64);
1387 if (TCG_TARGET_REG_BITS
== 32) {
1388 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 1);
1389 } else if (arg2
== 0) {
1390 tcg_gen_mov_i64(ret
, arg1
);
1392 TCGv_i64 t0
= tcg_const_i64(arg2
);
1393 tcg_gen_sar_i64(ret
, arg1
, t0
);
1394 tcg_temp_free_i64(t0
);
1398 void tcg_gen_brcond_i64(TCGCond cond
, TCGv_i64 arg1
, TCGv_i64 arg2
, TCGLabel
*l
)
1400 if (cond
== TCG_COND_ALWAYS
) {
1402 } else if (cond
!= TCG_COND_NEVER
) {
1403 if (TCG_TARGET_REG_BITS
== 32) {
1404 tcg_gen_op6ii_i32(INDEX_op_brcond2_i32
, TCGV_LOW(arg1
),
1405 TCGV_HIGH(arg1
), TCGV_LOW(arg2
),
1406 TCGV_HIGH(arg2
), cond
, label_arg(l
));
1408 tcg_gen_op4ii_i64(INDEX_op_brcond_i64
, arg1
, arg2
, cond
,
1414 void tcg_gen_brcondi_i64(TCGCond cond
, TCGv_i64 arg1
, int64_t arg2
, TCGLabel
*l
)
1416 if (cond
== TCG_COND_ALWAYS
) {
1418 } else if (cond
!= TCG_COND_NEVER
) {
1419 TCGv_i64 t0
= tcg_const_i64(arg2
);
1420 tcg_gen_brcond_i64(cond
, arg1
, t0
, l
);
1421 tcg_temp_free_i64(t0
);
1425 void tcg_gen_setcond_i64(TCGCond cond
, TCGv_i64 ret
,
1426 TCGv_i64 arg1
, TCGv_i64 arg2
)
1428 if (cond
== TCG_COND_ALWAYS
) {
1429 tcg_gen_movi_i64(ret
, 1);
1430 } else if (cond
== TCG_COND_NEVER
) {
1431 tcg_gen_movi_i64(ret
, 0);
1433 if (TCG_TARGET_REG_BITS
== 32) {
1434 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, TCGV_LOW(ret
),
1435 TCGV_LOW(arg1
), TCGV_HIGH(arg1
),
1436 TCGV_LOW(arg2
), TCGV_HIGH(arg2
), cond
);
1437 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1439 tcg_gen_op4i_i64(INDEX_op_setcond_i64
, ret
, arg1
, arg2
, cond
);
1444 void tcg_gen_setcondi_i64(TCGCond cond
, TCGv_i64 ret
,
1445 TCGv_i64 arg1
, int64_t arg2
)
1447 TCGv_i64 t0
= tcg_const_i64(arg2
);
1448 tcg_gen_setcond_i64(cond
, ret
, arg1
, t0
);
1449 tcg_temp_free_i64(t0
);
1452 void tcg_gen_muli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, int64_t arg2
)
1454 TCGv_i64 t0
= tcg_const_i64(arg2
);
1455 tcg_gen_mul_i64(ret
, arg1
, t0
);
1456 tcg_temp_free_i64(t0
);
1459 void tcg_gen_div_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1461 if (TCG_TARGET_HAS_div_i64
) {
1462 tcg_gen_op3_i64(INDEX_op_div_i64
, ret
, arg1
, arg2
);
1463 } else if (TCG_TARGET_HAS_div2_i64
) {
1464 TCGv_i64 t0
= tcg_temp_new_i64();
1465 tcg_gen_sari_i64(t0
, arg1
, 63);
1466 tcg_gen_op5_i64(INDEX_op_div2_i64
, ret
, t0
, arg1
, t0
, arg2
);
1467 tcg_temp_free_i64(t0
);
1469 gen_helper_div_i64(ret
, arg1
, arg2
);
1473 void tcg_gen_rem_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1475 if (TCG_TARGET_HAS_rem_i64
) {
1476 tcg_gen_op3_i64(INDEX_op_rem_i64
, ret
, arg1
, arg2
);
1477 } else if (TCG_TARGET_HAS_div_i64
) {
1478 TCGv_i64 t0
= tcg_temp_new_i64();
1479 tcg_gen_op3_i64(INDEX_op_div_i64
, t0
, arg1
, arg2
);
1480 tcg_gen_mul_i64(t0
, t0
, arg2
);
1481 tcg_gen_sub_i64(ret
, arg1
, t0
);
1482 tcg_temp_free_i64(t0
);
1483 } else if (TCG_TARGET_HAS_div2_i64
) {
1484 TCGv_i64 t0
= tcg_temp_new_i64();
1485 tcg_gen_sari_i64(t0
, arg1
, 63);
1486 tcg_gen_op5_i64(INDEX_op_div2_i64
, t0
, ret
, arg1
, t0
, arg2
);
1487 tcg_temp_free_i64(t0
);
1489 gen_helper_rem_i64(ret
, arg1
, arg2
);
1493 void tcg_gen_divu_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1495 if (TCG_TARGET_HAS_div_i64
) {
1496 tcg_gen_op3_i64(INDEX_op_divu_i64
, ret
, arg1
, arg2
);
1497 } else if (TCG_TARGET_HAS_div2_i64
) {
1498 TCGv_i64 t0
= tcg_temp_new_i64();
1499 tcg_gen_movi_i64(t0
, 0);
1500 tcg_gen_op5_i64(INDEX_op_divu2_i64
, ret
, t0
, arg1
, t0
, arg2
);
1501 tcg_temp_free_i64(t0
);
1503 gen_helper_divu_i64(ret
, arg1
, arg2
);
1507 void tcg_gen_remu_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1509 if (TCG_TARGET_HAS_rem_i64
) {
1510 tcg_gen_op3_i64(INDEX_op_remu_i64
, ret
, arg1
, arg2
);
1511 } else if (TCG_TARGET_HAS_div_i64
) {
1512 TCGv_i64 t0
= tcg_temp_new_i64();
1513 tcg_gen_op3_i64(INDEX_op_divu_i64
, t0
, arg1
, arg2
);
1514 tcg_gen_mul_i64(t0
, t0
, arg2
);
1515 tcg_gen_sub_i64(ret
, arg1
, t0
);
1516 tcg_temp_free_i64(t0
);
1517 } else if (TCG_TARGET_HAS_div2_i64
) {
1518 TCGv_i64 t0
= tcg_temp_new_i64();
1519 tcg_gen_movi_i64(t0
, 0);
1520 tcg_gen_op5_i64(INDEX_op_divu2_i64
, t0
, ret
, arg1
, t0
, arg2
);
1521 tcg_temp_free_i64(t0
);
1523 gen_helper_remu_i64(ret
, arg1
, arg2
);
1527 void tcg_gen_ext8s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1529 if (TCG_TARGET_REG_BITS
== 32) {
1530 tcg_gen_ext8s_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1531 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1532 } else if (TCG_TARGET_HAS_ext8s_i64
) {
1533 tcg_gen_op2_i64(INDEX_op_ext8s_i64
, ret
, arg
);
1535 tcg_gen_shli_i64(ret
, arg
, 56);
1536 tcg_gen_sari_i64(ret
, ret
, 56);
1540 void tcg_gen_ext16s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1542 if (TCG_TARGET_REG_BITS
== 32) {
1543 tcg_gen_ext16s_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1544 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1545 } else if (TCG_TARGET_HAS_ext16s_i64
) {
1546 tcg_gen_op2_i64(INDEX_op_ext16s_i64
, ret
, arg
);
1548 tcg_gen_shli_i64(ret
, arg
, 48);
1549 tcg_gen_sari_i64(ret
, ret
, 48);
1553 void tcg_gen_ext32s_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1555 if (TCG_TARGET_REG_BITS
== 32) {
1556 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1557 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
1558 } else if (TCG_TARGET_HAS_ext32s_i64
) {
1559 tcg_gen_op2_i64(INDEX_op_ext32s_i64
, ret
, arg
);
1561 tcg_gen_shli_i64(ret
, arg
, 32);
1562 tcg_gen_sari_i64(ret
, ret
, 32);
1566 void tcg_gen_ext8u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1568 if (TCG_TARGET_REG_BITS
== 32) {
1569 tcg_gen_ext8u_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1570 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1571 } else if (TCG_TARGET_HAS_ext8u_i64
) {
1572 tcg_gen_op2_i64(INDEX_op_ext8u_i64
, ret
, arg
);
1574 tcg_gen_andi_i64(ret
, arg
, 0xffu
);
1578 void tcg_gen_ext16u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1580 if (TCG_TARGET_REG_BITS
== 32) {
1581 tcg_gen_ext16u_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1582 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1583 } else if (TCG_TARGET_HAS_ext16u_i64
) {
1584 tcg_gen_op2_i64(INDEX_op_ext16u_i64
, ret
, arg
);
1586 tcg_gen_andi_i64(ret
, arg
, 0xffffu
);
1590 void tcg_gen_ext32u_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1592 if (TCG_TARGET_REG_BITS
== 32) {
1593 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1594 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1595 } else if (TCG_TARGET_HAS_ext32u_i64
) {
1596 tcg_gen_op2_i64(INDEX_op_ext32u_i64
, ret
, arg
);
1598 tcg_gen_andi_i64(ret
, arg
, 0xffffffffu
);
1602 /* Note: we assume the six high bytes are set to zero */
1603 void tcg_gen_bswap16_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1605 if (TCG_TARGET_REG_BITS
== 32) {
1606 tcg_gen_bswap16_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1607 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1608 } else if (TCG_TARGET_HAS_bswap16_i64
) {
1609 tcg_gen_op2_i64(INDEX_op_bswap16_i64
, ret
, arg
);
1611 TCGv_i64 t0
= tcg_temp_new_i64();
1613 tcg_gen_ext8u_i64(t0
, arg
);
1614 tcg_gen_shli_i64(t0
, t0
, 8);
1615 tcg_gen_shri_i64(ret
, arg
, 8);
1616 tcg_gen_or_i64(ret
, ret
, t0
);
1617 tcg_temp_free_i64(t0
);
1621 /* Note: we assume the four high bytes are set to zero */
1622 void tcg_gen_bswap32_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1624 if (TCG_TARGET_REG_BITS
== 32) {
1625 tcg_gen_bswap32_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1626 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1627 } else if (TCG_TARGET_HAS_bswap32_i64
) {
1628 tcg_gen_op2_i64(INDEX_op_bswap32_i64
, ret
, arg
);
1631 t0
= tcg_temp_new_i64();
1632 t1
= tcg_temp_new_i64();
1634 tcg_gen_shli_i64(t0
, arg
, 24);
1635 tcg_gen_ext32u_i64(t0
, t0
);
1637 tcg_gen_andi_i64(t1
, arg
, 0x0000ff00);
1638 tcg_gen_shli_i64(t1
, t1
, 8);
1639 tcg_gen_or_i64(t0
, t0
, t1
);
1641 tcg_gen_shri_i64(t1
, arg
, 8);
1642 tcg_gen_andi_i64(t1
, t1
, 0x0000ff00);
1643 tcg_gen_or_i64(t0
, t0
, t1
);
1645 tcg_gen_shri_i64(t1
, arg
, 24);
1646 tcg_gen_or_i64(ret
, t0
, t1
);
1647 tcg_temp_free_i64(t0
);
1648 tcg_temp_free_i64(t1
);
1652 void tcg_gen_bswap64_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1654 if (TCG_TARGET_REG_BITS
== 32) {
1656 t0
= tcg_temp_new_i32();
1657 t1
= tcg_temp_new_i32();
1659 tcg_gen_bswap32_i32(t0
, TCGV_LOW(arg
));
1660 tcg_gen_bswap32_i32(t1
, TCGV_HIGH(arg
));
1661 tcg_gen_mov_i32(TCGV_LOW(ret
), t1
);
1662 tcg_gen_mov_i32(TCGV_HIGH(ret
), t0
);
1663 tcg_temp_free_i32(t0
);
1664 tcg_temp_free_i32(t1
);
1665 } else if (TCG_TARGET_HAS_bswap64_i64
) {
1666 tcg_gen_op2_i64(INDEX_op_bswap64_i64
, ret
, arg
);
1668 TCGv_i64 t0
= tcg_temp_new_i64();
1669 TCGv_i64 t1
= tcg_temp_new_i64();
1671 tcg_gen_shli_i64(t0
, arg
, 56);
1673 tcg_gen_andi_i64(t1
, arg
, 0x0000ff00);
1674 tcg_gen_shli_i64(t1
, t1
, 40);
1675 tcg_gen_or_i64(t0
, t0
, t1
);
1677 tcg_gen_andi_i64(t1
, arg
, 0x00ff0000);
1678 tcg_gen_shli_i64(t1
, t1
, 24);
1679 tcg_gen_or_i64(t0
, t0
, t1
);
1681 tcg_gen_andi_i64(t1
, arg
, 0xff000000);
1682 tcg_gen_shli_i64(t1
, t1
, 8);
1683 tcg_gen_or_i64(t0
, t0
, t1
);
1685 tcg_gen_shri_i64(t1
, arg
, 8);
1686 tcg_gen_andi_i64(t1
, t1
, 0xff000000);
1687 tcg_gen_or_i64(t0
, t0
, t1
);
1689 tcg_gen_shri_i64(t1
, arg
, 24);
1690 tcg_gen_andi_i64(t1
, t1
, 0x00ff0000);
1691 tcg_gen_or_i64(t0
, t0
, t1
);
1693 tcg_gen_shri_i64(t1
, arg
, 40);
1694 tcg_gen_andi_i64(t1
, t1
, 0x0000ff00);
1695 tcg_gen_or_i64(t0
, t0
, t1
);
1697 tcg_gen_shri_i64(t1
, arg
, 56);
1698 tcg_gen_or_i64(ret
, t0
, t1
);
1699 tcg_temp_free_i64(t0
);
1700 tcg_temp_free_i64(t1
);
1704 void tcg_gen_not_i64(TCGv_i64 ret
, TCGv_i64 arg
)
1706 if (TCG_TARGET_REG_BITS
== 32) {
1707 tcg_gen_not_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
1708 tcg_gen_not_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
));
1709 } else if (TCG_TARGET_HAS_not_i64
) {
1710 tcg_gen_op2_i64(INDEX_op_not_i64
, ret
, arg
);
1712 tcg_gen_xori_i64(ret
, arg
, -1);
1716 void tcg_gen_andc_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1718 if (TCG_TARGET_REG_BITS
== 32) {
1719 tcg_gen_andc_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1720 tcg_gen_andc_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1721 } else if (TCG_TARGET_HAS_andc_i64
) {
1722 tcg_gen_op3_i64(INDEX_op_andc_i64
, ret
, arg1
, arg2
);
1724 TCGv_i64 t0
= tcg_temp_new_i64();
1725 tcg_gen_not_i64(t0
, arg2
);
1726 tcg_gen_and_i64(ret
, arg1
, t0
);
1727 tcg_temp_free_i64(t0
);
1731 void tcg_gen_eqv_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1733 if (TCG_TARGET_REG_BITS
== 32) {
1734 tcg_gen_eqv_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1735 tcg_gen_eqv_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1736 } else if (TCG_TARGET_HAS_eqv_i64
) {
1737 tcg_gen_op3_i64(INDEX_op_eqv_i64
, ret
, arg1
, arg2
);
1739 tcg_gen_xor_i64(ret
, arg1
, arg2
);
1740 tcg_gen_not_i64(ret
, ret
);
1744 void tcg_gen_nand_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1746 if (TCG_TARGET_REG_BITS
== 32) {
1747 tcg_gen_nand_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1748 tcg_gen_nand_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1749 } else if (TCG_TARGET_HAS_nand_i64
) {
1750 tcg_gen_op3_i64(INDEX_op_nand_i64
, ret
, arg1
, arg2
);
1752 tcg_gen_and_i64(ret
, arg1
, arg2
);
1753 tcg_gen_not_i64(ret
, ret
);
1757 void tcg_gen_nor_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1759 if (TCG_TARGET_REG_BITS
== 32) {
1760 tcg_gen_nor_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1761 tcg_gen_nor_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1762 } else if (TCG_TARGET_HAS_nor_i64
) {
1763 tcg_gen_op3_i64(INDEX_op_nor_i64
, ret
, arg1
, arg2
);
1765 tcg_gen_or_i64(ret
, arg1
, arg2
);
1766 tcg_gen_not_i64(ret
, ret
);
1770 void tcg_gen_orc_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1772 if (TCG_TARGET_REG_BITS
== 32) {
1773 tcg_gen_orc_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), TCGV_LOW(arg2
));
1774 tcg_gen_orc_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
), TCGV_HIGH(arg2
));
1775 } else if (TCG_TARGET_HAS_orc_i64
) {
1776 tcg_gen_op3_i64(INDEX_op_orc_i64
, ret
, arg1
, arg2
);
1778 TCGv_i64 t0
= tcg_temp_new_i64();
1779 tcg_gen_not_i64(t0
, arg2
);
1780 tcg_gen_or_i64(ret
, arg1
, t0
);
1781 tcg_temp_free_i64(t0
);
1785 void tcg_gen_clz_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1787 if (TCG_TARGET_HAS_clz_i64
) {
1788 tcg_gen_op3_i64(INDEX_op_clz_i64
, ret
, arg1
, arg2
);
1790 gen_helper_clz_i64(ret
, arg1
, arg2
);
1794 void tcg_gen_clzi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, uint64_t arg2
)
1796 if (TCG_TARGET_REG_BITS
== 32
1797 && TCG_TARGET_HAS_clz_i32
1798 && arg2
<= 0xffffffffu
) {
1799 TCGv_i32 t
= tcg_const_i32((uint32_t)arg2
- 32);
1800 tcg_gen_clz_i32(t
, TCGV_LOW(arg1
), t
);
1801 tcg_gen_addi_i32(t
, t
, 32);
1802 tcg_gen_clz_i32(TCGV_LOW(ret
), TCGV_HIGH(arg1
), t
);
1803 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1804 tcg_temp_free_i32(t
);
1806 TCGv_i64 t
= tcg_const_i64(arg2
);
1807 tcg_gen_clz_i64(ret
, arg1
, t
);
1808 tcg_temp_free_i64(t
);
1812 void tcg_gen_ctz_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1814 if (TCG_TARGET_HAS_ctz_i64
) {
1815 tcg_gen_op3_i64(INDEX_op_ctz_i64
, ret
, arg1
, arg2
);
1816 } else if (TCG_TARGET_HAS_clz_i64
) {
1817 TCGv_i64 t1
= tcg_temp_new_i64();
1818 TCGv_i64 t2
= tcg_temp_new_i64();
1819 tcg_gen_neg_i64(t1
, arg1
);
1820 tcg_gen_xori_i64(t2
, arg2
, 63);
1821 tcg_gen_and_i64(t1
, t1
, arg1
);
1822 tcg_gen_clz_i64(ret
, t1
, t2
);
1823 tcg_temp_free_i64(t1
);
1824 tcg_temp_free_i64(t2
);
1825 tcg_gen_xori_i64(ret
, ret
, 63);
1827 gen_helper_ctz_i64(ret
, arg1
, arg2
);
1831 void tcg_gen_ctzi_i64(TCGv_i64 ret
, TCGv_i64 arg1
, uint64_t arg2
)
1833 if (TCG_TARGET_REG_BITS
== 32
1834 && TCG_TARGET_HAS_ctz_i32
1835 && arg2
<= 0xffffffffu
) {
1836 TCGv_i32 t32
= tcg_const_i32((uint32_t)arg2
- 32);
1837 tcg_gen_ctz_i32(t32
, TCGV_HIGH(arg1
), t32
);
1838 tcg_gen_addi_i32(t32
, t32
, 32);
1839 tcg_gen_ctz_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
), t32
);
1840 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1841 tcg_temp_free_i32(t32
);
1843 TCGv_i64 t64
= tcg_const_i64(arg2
);
1844 tcg_gen_ctz_i64(ret
, arg1
, t64
);
1845 tcg_temp_free_i64(t64
);
1849 void tcg_gen_rotl_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1851 if (TCG_TARGET_HAS_rot_i64
) {
1852 tcg_gen_op3_i64(INDEX_op_rotl_i64
, ret
, arg1
, arg2
);
1855 t0
= tcg_temp_new_i64();
1856 t1
= tcg_temp_new_i64();
1857 tcg_gen_shl_i64(t0
, arg1
, arg2
);
1858 tcg_gen_subfi_i64(t1
, 64, arg2
);
1859 tcg_gen_shr_i64(t1
, arg1
, t1
);
1860 tcg_gen_or_i64(ret
, t0
, t1
);
1861 tcg_temp_free_i64(t0
);
1862 tcg_temp_free_i64(t1
);
1866 void tcg_gen_rotli_i64(TCGv_i64 ret
, TCGv_i64 arg1
, unsigned arg2
)
1868 tcg_debug_assert(arg2
< 64);
1869 /* some cases can be optimized here */
1871 tcg_gen_mov_i64(ret
, arg1
);
1872 } else if (TCG_TARGET_HAS_rot_i64
) {
1873 TCGv_i64 t0
= tcg_const_i64(arg2
);
1874 tcg_gen_rotl_i64(ret
, arg1
, t0
);
1875 tcg_temp_free_i64(t0
);
1878 t0
= tcg_temp_new_i64();
1879 t1
= tcg_temp_new_i64();
1880 tcg_gen_shli_i64(t0
, arg1
, arg2
);
1881 tcg_gen_shri_i64(t1
, arg1
, 64 - arg2
);
1882 tcg_gen_or_i64(ret
, t0
, t1
);
1883 tcg_temp_free_i64(t0
);
1884 tcg_temp_free_i64(t1
);
1888 void tcg_gen_rotr_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
)
1890 if (TCG_TARGET_HAS_rot_i64
) {
1891 tcg_gen_op3_i64(INDEX_op_rotr_i64
, ret
, arg1
, arg2
);
1894 t0
= tcg_temp_new_i64();
1895 t1
= tcg_temp_new_i64();
1896 tcg_gen_shr_i64(t0
, arg1
, arg2
);
1897 tcg_gen_subfi_i64(t1
, 64, arg2
);
1898 tcg_gen_shl_i64(t1
, arg1
, t1
);
1899 tcg_gen_or_i64(ret
, t0
, t1
);
1900 tcg_temp_free_i64(t0
);
1901 tcg_temp_free_i64(t1
);
1905 void tcg_gen_rotri_i64(TCGv_i64 ret
, TCGv_i64 arg1
, unsigned arg2
)
1907 tcg_debug_assert(arg2
< 64);
1908 /* some cases can be optimized here */
1910 tcg_gen_mov_i64(ret
, arg1
);
1912 tcg_gen_rotli_i64(ret
, arg1
, 64 - arg2
);
1916 void tcg_gen_deposit_i64(TCGv_i64 ret
, TCGv_i64 arg1
, TCGv_i64 arg2
,
1917 unsigned int ofs
, unsigned int len
)
1922 tcg_debug_assert(ofs
< 64);
1923 tcg_debug_assert(len
> 0);
1924 tcg_debug_assert(len
<= 64);
1925 tcg_debug_assert(ofs
+ len
<= 64);
1928 tcg_gen_mov_i64(ret
, arg2
);
1931 if (TCG_TARGET_HAS_deposit_i64
&& TCG_TARGET_deposit_i64_valid(ofs
, len
)) {
1932 tcg_gen_op5ii_i64(INDEX_op_deposit_i64
, ret
, arg1
, arg2
, ofs
, len
);
1936 if (TCG_TARGET_REG_BITS
== 32) {
1938 tcg_gen_deposit_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
),
1939 TCGV_LOW(arg2
), ofs
- 32, len
);
1940 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
));
1943 if (ofs
+ len
<= 32) {
1944 tcg_gen_deposit_i32(TCGV_LOW(ret
), TCGV_LOW(arg1
),
1945 TCGV_LOW(arg2
), ofs
, len
);
1946 tcg_gen_mov_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg1
));
1951 mask
= (1ull << len
) - 1;
1952 t1
= tcg_temp_new_i64();
1954 if (ofs
+ len
< 64) {
1955 tcg_gen_andi_i64(t1
, arg2
, mask
);
1956 tcg_gen_shli_i64(t1
, t1
, ofs
);
1958 tcg_gen_shli_i64(t1
, arg2
, ofs
);
1960 tcg_gen_andi_i64(ret
, arg1
, ~(mask
<< ofs
));
1961 tcg_gen_or_i64(ret
, ret
, t1
);
1963 tcg_temp_free_i64(t1
);
1966 void tcg_gen_deposit_z_i64(TCGv_i64 ret
, TCGv_i64 arg
,
1967 unsigned int ofs
, unsigned int len
)
1969 tcg_debug_assert(ofs
< 64);
1970 tcg_debug_assert(len
> 0);
1971 tcg_debug_assert(len
<= 64);
1972 tcg_debug_assert(ofs
+ len
<= 64);
1974 if (ofs
+ len
== 64) {
1975 tcg_gen_shli_i64(ret
, arg
, ofs
);
1976 } else if (ofs
== 0) {
1977 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
1978 } else if (TCG_TARGET_HAS_deposit_i64
1979 && TCG_TARGET_deposit_i64_valid(ofs
, len
)) {
1980 TCGv_i64 zero
= tcg_const_i64(0);
1981 tcg_gen_op5ii_i64(INDEX_op_deposit_i64
, ret
, zero
, arg
, ofs
, len
);
1982 tcg_temp_free_i64(zero
);
1984 if (TCG_TARGET_REG_BITS
== 32) {
1986 tcg_gen_deposit_z_i32(TCGV_HIGH(ret
), TCGV_LOW(arg
),
1988 tcg_gen_movi_i32(TCGV_LOW(ret
), 0);
1991 if (ofs
+ len
<= 32) {
1992 tcg_gen_deposit_z_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
1993 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
1997 /* To help two-operand hosts we prefer to zero-extend first,
1998 which allows ARG to stay live. */
2001 if (TCG_TARGET_HAS_ext32u_i64
) {
2002 tcg_gen_ext32u_i64(ret
, arg
);
2003 tcg_gen_shli_i64(ret
, ret
, ofs
);
2008 if (TCG_TARGET_HAS_ext16u_i64
) {
2009 tcg_gen_ext16u_i64(ret
, arg
);
2010 tcg_gen_shli_i64(ret
, ret
, ofs
);
2015 if (TCG_TARGET_HAS_ext8u_i64
) {
2016 tcg_gen_ext8u_i64(ret
, arg
);
2017 tcg_gen_shli_i64(ret
, ret
, ofs
);
2022 /* Otherwise prefer zero-extension over AND for code size. */
2023 switch (ofs
+ len
) {
2025 if (TCG_TARGET_HAS_ext32u_i64
) {
2026 tcg_gen_shli_i64(ret
, arg
, ofs
);
2027 tcg_gen_ext32u_i64(ret
, ret
);
2032 if (TCG_TARGET_HAS_ext16u_i64
) {
2033 tcg_gen_shli_i64(ret
, arg
, ofs
);
2034 tcg_gen_ext16u_i64(ret
, ret
);
2039 if (TCG_TARGET_HAS_ext8u_i64
) {
2040 tcg_gen_shli_i64(ret
, arg
, ofs
);
2041 tcg_gen_ext8u_i64(ret
, ret
);
2046 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
2047 tcg_gen_shli_i64(ret
, ret
, ofs
);
2051 void tcg_gen_extract_i64(TCGv_i64 ret
, TCGv_i64 arg
,
2052 unsigned int ofs
, unsigned int len
)
2054 tcg_debug_assert(ofs
< 64);
2055 tcg_debug_assert(len
> 0);
2056 tcg_debug_assert(len
<= 64);
2057 tcg_debug_assert(ofs
+ len
<= 64);
2059 /* Canonicalize certain special cases, even if extract is supported. */
2060 if (ofs
+ len
== 64) {
2061 tcg_gen_shri_i64(ret
, arg
, 64 - len
);
2065 tcg_gen_andi_i64(ret
, arg
, (1ull << len
) - 1);
2069 if (TCG_TARGET_REG_BITS
== 32) {
2070 /* Look for a 32-bit extract within one of the two words. */
2072 tcg_gen_extract_i32(TCGV_LOW(ret
), TCGV_HIGH(arg
), ofs
- 32, len
);
2073 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2076 if (ofs
+ len
<= 32) {
2077 tcg_gen_extract_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
2078 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2081 /* The field is split across two words. One double-word
2082 shift is better than two double-word shifts. */
2086 if (TCG_TARGET_HAS_extract_i64
2087 && TCG_TARGET_extract_i64_valid(ofs
, len
)) {
2088 tcg_gen_op4ii_i64(INDEX_op_extract_i64
, ret
, arg
, ofs
, len
);
2092 /* Assume that zero-extension, if available, is cheaper than a shift. */
2093 switch (ofs
+ len
) {
2095 if (TCG_TARGET_HAS_ext32u_i64
) {
2096 tcg_gen_ext32u_i64(ret
, arg
);
2097 tcg_gen_shri_i64(ret
, ret
, ofs
);
2102 if (TCG_TARGET_HAS_ext16u_i64
) {
2103 tcg_gen_ext16u_i64(ret
, arg
);
2104 tcg_gen_shri_i64(ret
, ret
, ofs
);
2109 if (TCG_TARGET_HAS_ext8u_i64
) {
2110 tcg_gen_ext8u_i64(ret
, arg
);
2111 tcg_gen_shri_i64(ret
, ret
, ofs
);
2117 /* ??? Ideally we'd know what values are available for immediate AND.
2118 Assume that 8 bits are available, plus the special cases of 16 and 32,
2119 so that we get ext8u, ext16u, and ext32u. */
2121 case 1 ... 8: case 16: case 32:
2123 tcg_gen_shri_i64(ret
, arg
, ofs
);
2124 tcg_gen_andi_i64(ret
, ret
, (1ull << len
) - 1);
2127 tcg_gen_shli_i64(ret
, arg
, 64 - len
- ofs
);
2128 tcg_gen_shri_i64(ret
, ret
, 64 - len
);
2133 void tcg_gen_sextract_i64(TCGv_i64 ret
, TCGv_i64 arg
,
2134 unsigned int ofs
, unsigned int len
)
2136 tcg_debug_assert(ofs
< 64);
2137 tcg_debug_assert(len
> 0);
2138 tcg_debug_assert(len
<= 64);
2139 tcg_debug_assert(ofs
+ len
<= 64);
2141 /* Canonicalize certain special cases, even if sextract is supported. */
2142 if (ofs
+ len
== 64) {
2143 tcg_gen_sari_i64(ret
, arg
, 64 - len
);
2149 tcg_gen_ext32s_i64(ret
, arg
);
2152 tcg_gen_ext16s_i64(ret
, arg
);
2155 tcg_gen_ext8s_i64(ret
, arg
);
2160 if (TCG_TARGET_REG_BITS
== 32) {
2161 /* Look for a 32-bit extract within one of the two words. */
2163 tcg_gen_sextract_i32(TCGV_LOW(ret
), TCGV_HIGH(arg
), ofs
- 32, len
);
2164 } else if (ofs
+ len
<= 32) {
2165 tcg_gen_sextract_i32(TCGV_LOW(ret
), TCGV_LOW(arg
), ofs
, len
);
2166 } else if (ofs
== 0) {
2167 tcg_gen_mov_i32(TCGV_LOW(ret
), TCGV_LOW(arg
));
2168 tcg_gen_sextract_i32(TCGV_HIGH(ret
), TCGV_HIGH(arg
), 0, len
- 32);
2170 } else if (len
> 32) {
2171 TCGv_i32 t
= tcg_temp_new_i32();
2172 /* Extract the bits for the high word normally. */
2173 tcg_gen_sextract_i32(t
, TCGV_HIGH(arg
), ofs
+ 32, len
- 32);
2174 /* Shift the field down for the low part. */
2175 tcg_gen_shri_i64(ret
, arg
, ofs
);
2176 /* Overwrite the shift into the high part. */
2177 tcg_gen_mov_i32(TCGV_HIGH(ret
), t
);
2178 tcg_temp_free_i32(t
);
2181 /* Shift the field down for the low part, such that the
2182 field sits at the MSB. */
2183 tcg_gen_shri_i64(ret
, arg
, ofs
+ len
- 32);
2184 /* Shift the field down from the MSB, sign extending. */
2185 tcg_gen_sari_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), 32 - len
);
2187 /* Sign-extend the field from 32 bits. */
2188 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
2192 if (TCG_TARGET_HAS_sextract_i64
2193 && TCG_TARGET_extract_i64_valid(ofs
, len
)) {
2194 tcg_gen_op4ii_i64(INDEX_op_sextract_i64
, ret
, arg
, ofs
, len
);
2198 /* Assume that sign-extension, if available, is cheaper than a shift. */
2199 switch (ofs
+ len
) {
2201 if (TCG_TARGET_HAS_ext32s_i64
) {
2202 tcg_gen_ext32s_i64(ret
, arg
);
2203 tcg_gen_sari_i64(ret
, ret
, ofs
);
2208 if (TCG_TARGET_HAS_ext16s_i64
) {
2209 tcg_gen_ext16s_i64(ret
, arg
);
2210 tcg_gen_sari_i64(ret
, ret
, ofs
);
2215 if (TCG_TARGET_HAS_ext8s_i64
) {
2216 tcg_gen_ext8s_i64(ret
, arg
);
2217 tcg_gen_sari_i64(ret
, ret
, ofs
);
2224 if (TCG_TARGET_HAS_ext32s_i64
) {
2225 tcg_gen_shri_i64(ret
, arg
, ofs
);
2226 tcg_gen_ext32s_i64(ret
, ret
);
2231 if (TCG_TARGET_HAS_ext16s_i64
) {
2232 tcg_gen_shri_i64(ret
, arg
, ofs
);
2233 tcg_gen_ext16s_i64(ret
, ret
);
2238 if (TCG_TARGET_HAS_ext8s_i64
) {
2239 tcg_gen_shri_i64(ret
, arg
, ofs
);
2240 tcg_gen_ext8s_i64(ret
, ret
);
2245 tcg_gen_shli_i64(ret
, arg
, 64 - len
- ofs
);
2246 tcg_gen_sari_i64(ret
, ret
, 64 - len
);
2249 void tcg_gen_movcond_i64(TCGCond cond
, TCGv_i64 ret
, TCGv_i64 c1
,
2250 TCGv_i64 c2
, TCGv_i64 v1
, TCGv_i64 v2
)
2252 if (cond
== TCG_COND_ALWAYS
) {
2253 tcg_gen_mov_i64(ret
, v1
);
2254 } else if (cond
== TCG_COND_NEVER
) {
2255 tcg_gen_mov_i64(ret
, v2
);
2256 } else if (TCG_TARGET_REG_BITS
== 32) {
2257 TCGv_i32 t0
= tcg_temp_new_i32();
2258 TCGv_i32 t1
= tcg_temp_new_i32();
2259 tcg_gen_op6i_i32(INDEX_op_setcond2_i32
, t0
,
2260 TCGV_LOW(c1
), TCGV_HIGH(c1
),
2261 TCGV_LOW(c2
), TCGV_HIGH(c2
), cond
);
2263 if (TCG_TARGET_HAS_movcond_i32
) {
2264 tcg_gen_movi_i32(t1
, 0);
2265 tcg_gen_movcond_i32(TCG_COND_NE
, TCGV_LOW(ret
), t0
, t1
,
2266 TCGV_LOW(v1
), TCGV_LOW(v2
));
2267 tcg_gen_movcond_i32(TCG_COND_NE
, TCGV_HIGH(ret
), t0
, t1
,
2268 TCGV_HIGH(v1
), TCGV_HIGH(v2
));
2270 tcg_gen_neg_i32(t0
, t0
);
2272 tcg_gen_and_i32(t1
, TCGV_LOW(v1
), t0
);
2273 tcg_gen_andc_i32(TCGV_LOW(ret
), TCGV_LOW(v2
), t0
);
2274 tcg_gen_or_i32(TCGV_LOW(ret
), TCGV_LOW(ret
), t1
);
2276 tcg_gen_and_i32(t1
, TCGV_HIGH(v1
), t0
);
2277 tcg_gen_andc_i32(TCGV_HIGH(ret
), TCGV_HIGH(v2
), t0
);
2278 tcg_gen_or_i32(TCGV_HIGH(ret
), TCGV_HIGH(ret
), t1
);
2280 tcg_temp_free_i32(t0
);
2281 tcg_temp_free_i32(t1
);
2282 } else if (TCG_TARGET_HAS_movcond_i64
) {
2283 tcg_gen_op6i_i64(INDEX_op_movcond_i64
, ret
, c1
, c2
, v1
, v2
, cond
);
2285 TCGv_i64 t0
= tcg_temp_new_i64();
2286 TCGv_i64 t1
= tcg_temp_new_i64();
2287 tcg_gen_setcond_i64(cond
, t0
, c1
, c2
);
2288 tcg_gen_neg_i64(t0
, t0
);
2289 tcg_gen_and_i64(t1
, v1
, t0
);
2290 tcg_gen_andc_i64(ret
, v2
, t0
);
2291 tcg_gen_or_i64(ret
, ret
, t1
);
2292 tcg_temp_free_i64(t0
);
2293 tcg_temp_free_i64(t1
);
2297 void tcg_gen_add2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 al
,
2298 TCGv_i64 ah
, TCGv_i64 bl
, TCGv_i64 bh
)
2300 if (TCG_TARGET_HAS_add2_i64
) {
2301 tcg_gen_op6_i64(INDEX_op_add2_i64
, rl
, rh
, al
, ah
, bl
, bh
);
2303 TCGv_i64 t0
= tcg_temp_new_i64();
2304 TCGv_i64 t1
= tcg_temp_new_i64();
2305 tcg_gen_add_i64(t0
, al
, bl
);
2306 tcg_gen_setcond_i64(TCG_COND_LTU
, t1
, t0
, al
);
2307 tcg_gen_add_i64(rh
, ah
, bh
);
2308 tcg_gen_add_i64(rh
, rh
, t1
);
2309 tcg_gen_mov_i64(rl
, t0
);
2310 tcg_temp_free_i64(t0
);
2311 tcg_temp_free_i64(t1
);
2315 void tcg_gen_sub2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 al
,
2316 TCGv_i64 ah
, TCGv_i64 bl
, TCGv_i64 bh
)
2318 if (TCG_TARGET_HAS_sub2_i64
) {
2319 tcg_gen_op6_i64(INDEX_op_sub2_i64
, rl
, rh
, al
, ah
, bl
, bh
);
2321 TCGv_i64 t0
= tcg_temp_new_i64();
2322 TCGv_i64 t1
= tcg_temp_new_i64();
2323 tcg_gen_sub_i64(t0
, al
, bl
);
2324 tcg_gen_setcond_i64(TCG_COND_LTU
, t1
, al
, bl
);
2325 tcg_gen_sub_i64(rh
, ah
, bh
);
2326 tcg_gen_sub_i64(rh
, rh
, t1
);
2327 tcg_gen_mov_i64(rl
, t0
);
2328 tcg_temp_free_i64(t0
);
2329 tcg_temp_free_i64(t1
);
2333 void tcg_gen_mulu2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2335 if (TCG_TARGET_HAS_mulu2_i64
) {
2336 tcg_gen_op4_i64(INDEX_op_mulu2_i64
, rl
, rh
, arg1
, arg2
);
2337 } else if (TCG_TARGET_HAS_muluh_i64
) {
2338 TCGv_i64 t
= tcg_temp_new_i64();
2339 tcg_gen_op3_i64(INDEX_op_mul_i64
, t
, arg1
, arg2
);
2340 tcg_gen_op3_i64(INDEX_op_muluh_i64
, rh
, arg1
, arg2
);
2341 tcg_gen_mov_i64(rl
, t
);
2342 tcg_temp_free_i64(t
);
2344 TCGv_i64 t0
= tcg_temp_new_i64();
2345 tcg_gen_mul_i64(t0
, arg1
, arg2
);
2346 gen_helper_muluh_i64(rh
, arg1
, arg2
);
2347 tcg_gen_mov_i64(rl
, t0
);
2348 tcg_temp_free_i64(t0
);
2352 void tcg_gen_muls2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2354 if (TCG_TARGET_HAS_muls2_i64
) {
2355 tcg_gen_op4_i64(INDEX_op_muls2_i64
, rl
, rh
, arg1
, arg2
);
2356 } else if (TCG_TARGET_HAS_mulsh_i64
) {
2357 TCGv_i64 t
= tcg_temp_new_i64();
2358 tcg_gen_op3_i64(INDEX_op_mul_i64
, t
, arg1
, arg2
);
2359 tcg_gen_op3_i64(INDEX_op_mulsh_i64
, rh
, arg1
, arg2
);
2360 tcg_gen_mov_i64(rl
, t
);
2361 tcg_temp_free_i64(t
);
2362 } else if (TCG_TARGET_HAS_mulu2_i64
|| TCG_TARGET_HAS_muluh_i64
) {
2363 TCGv_i64 t0
= tcg_temp_new_i64();
2364 TCGv_i64 t1
= tcg_temp_new_i64();
2365 TCGv_i64 t2
= tcg_temp_new_i64();
2366 TCGv_i64 t3
= tcg_temp_new_i64();
2367 tcg_gen_mulu2_i64(t0
, t1
, arg1
, arg2
);
2368 /* Adjust for negative inputs. */
2369 tcg_gen_sari_i64(t2
, arg1
, 63);
2370 tcg_gen_sari_i64(t3
, arg2
, 63);
2371 tcg_gen_and_i64(t2
, t2
, arg2
);
2372 tcg_gen_and_i64(t3
, t3
, arg1
);
2373 tcg_gen_sub_i64(rh
, t1
, t2
);
2374 tcg_gen_sub_i64(rh
, rh
, t3
);
2375 tcg_gen_mov_i64(rl
, t0
);
2376 tcg_temp_free_i64(t0
);
2377 tcg_temp_free_i64(t1
);
2378 tcg_temp_free_i64(t2
);
2379 tcg_temp_free_i64(t3
);
2381 TCGv_i64 t0
= tcg_temp_new_i64();
2382 tcg_gen_mul_i64(t0
, arg1
, arg2
);
2383 gen_helper_mulsh_i64(rh
, arg1
, arg2
);
2384 tcg_gen_mov_i64(rl
, t0
);
2385 tcg_temp_free_i64(t0
);
2389 void tcg_gen_mulsu2_i64(TCGv_i64 rl
, TCGv_i64 rh
, TCGv_i64 arg1
, TCGv_i64 arg2
)
2391 TCGv_i64 t0
= tcg_temp_new_i64();
2392 TCGv_i64 t1
= tcg_temp_new_i64();
2393 TCGv_i64 t2
= tcg_temp_new_i64();
2394 tcg_gen_mulu2_i64(t0
, t1
, arg1
, arg2
);
2395 /* Adjust for negative input for the signed arg1. */
2396 tcg_gen_sari_i64(t2
, arg1
, 63);
2397 tcg_gen_and_i64(t2
, t2
, arg2
);
2398 tcg_gen_sub_i64(rh
, t1
, t2
);
2399 tcg_gen_mov_i64(rl
, t0
);
2400 tcg_temp_free_i64(t0
);
2401 tcg_temp_free_i64(t1
);
2402 tcg_temp_free_i64(t2
);
2405 /* Size changing operations. */
2407 void tcg_gen_extrl_i64_i32(TCGv_i32 ret
, TCGv_i64 arg
)
2409 if (TCG_TARGET_REG_BITS
== 32) {
2410 tcg_gen_mov_i32(ret
, TCGV_LOW(arg
));
2411 } else if (TCG_TARGET_HAS_extrl_i64_i32
) {
2412 tcg_gen_op2(&tcg_ctx
, INDEX_op_extrl_i64_i32
,
2413 GET_TCGV_I32(ret
), GET_TCGV_I64(arg
));
2415 tcg_gen_mov_i32(ret
, MAKE_TCGV_I32(GET_TCGV_I64(arg
)));
2419 void tcg_gen_extrh_i64_i32(TCGv_i32 ret
, TCGv_i64 arg
)
2421 if (TCG_TARGET_REG_BITS
== 32) {
2422 tcg_gen_mov_i32(ret
, TCGV_HIGH(arg
));
2423 } else if (TCG_TARGET_HAS_extrh_i64_i32
) {
2424 tcg_gen_op2(&tcg_ctx
, INDEX_op_extrh_i64_i32
,
2425 GET_TCGV_I32(ret
), GET_TCGV_I64(arg
));
2427 TCGv_i64 t
= tcg_temp_new_i64();
2428 tcg_gen_shri_i64(t
, arg
, 32);
2429 tcg_gen_mov_i32(ret
, MAKE_TCGV_I32(GET_TCGV_I64(t
)));
2430 tcg_temp_free_i64(t
);
2434 void tcg_gen_extu_i32_i64(TCGv_i64 ret
, TCGv_i32 arg
)
2436 if (TCG_TARGET_REG_BITS
== 32) {
2437 tcg_gen_mov_i32(TCGV_LOW(ret
), arg
);
2438 tcg_gen_movi_i32(TCGV_HIGH(ret
), 0);
2440 tcg_gen_op2(&tcg_ctx
, INDEX_op_extu_i32_i64
,
2441 GET_TCGV_I64(ret
), GET_TCGV_I32(arg
));
2445 void tcg_gen_ext_i32_i64(TCGv_i64 ret
, TCGv_i32 arg
)
2447 if (TCG_TARGET_REG_BITS
== 32) {
2448 tcg_gen_mov_i32(TCGV_LOW(ret
), arg
);
2449 tcg_gen_sari_i32(TCGV_HIGH(ret
), TCGV_LOW(ret
), 31);
2451 tcg_gen_op2(&tcg_ctx
, INDEX_op_ext_i32_i64
,
2452 GET_TCGV_I64(ret
), GET_TCGV_I32(arg
));
2456 void tcg_gen_concat_i32_i64(TCGv_i64 dest
, TCGv_i32 low
, TCGv_i32 high
)
2460 if (TCG_TARGET_REG_BITS
== 32) {
2461 tcg_gen_mov_i32(TCGV_LOW(dest
), low
);
2462 tcg_gen_mov_i32(TCGV_HIGH(dest
), high
);
2466 tmp
= tcg_temp_new_i64();
2467 /* These extensions are only needed for type correctness.
2468 We may be able to do better given target specific information. */
2469 tcg_gen_extu_i32_i64(tmp
, high
);
2470 tcg_gen_extu_i32_i64(dest
, low
);
2471 /* If deposit is available, use it. Otherwise use the extra
2472 knowledge that we have of the zero-extensions above. */
2473 if (TCG_TARGET_HAS_deposit_i64
&& TCG_TARGET_deposit_i64_valid(32, 32)) {
2474 tcg_gen_deposit_i64(dest
, dest
, tmp
, 32, 32);
2476 tcg_gen_shli_i64(tmp
, tmp
, 32);
2477 tcg_gen_or_i64(dest
, dest
, tmp
);
2479 tcg_temp_free_i64(tmp
);
2482 void tcg_gen_extr_i64_i32(TCGv_i32 lo
, TCGv_i32 hi
, TCGv_i64 arg
)
2484 if (TCG_TARGET_REG_BITS
== 32) {
2485 tcg_gen_mov_i32(lo
, TCGV_LOW(arg
));
2486 tcg_gen_mov_i32(hi
, TCGV_HIGH(arg
));
2488 tcg_gen_extrl_i64_i32(lo
, arg
);
2489 tcg_gen_extrh_i64_i32(hi
, arg
);
2493 void tcg_gen_extr32_i64(TCGv_i64 lo
, TCGv_i64 hi
, TCGv_i64 arg
)
2495 tcg_gen_ext32u_i64(lo
, arg
);
2496 tcg_gen_shri_i64(hi
, arg
, 32);
2499 /* QEMU specific operations. */
2501 void tcg_gen_goto_tb(unsigned idx
)
2503 /* We only support two chained exits. */
2504 tcg_debug_assert(idx
<= 1);
2505 #ifdef CONFIG_DEBUG_TCG
2506 /* Verify that we havn't seen this numbered exit before. */
2507 tcg_debug_assert((tcg_ctx
.goto_tb_issue_mask
& (1 << idx
)) == 0);
2508 tcg_ctx
.goto_tb_issue_mask
|= 1 << idx
;
2510 tcg_gen_op1i(INDEX_op_goto_tb
, idx
);
2513 static inline TCGMemOp
tcg_canonicalize_memop(TCGMemOp op
, bool is64
, bool st
)
2515 /* Trigger the asserts within as early as possible. */
2516 (void)get_alignment_bits(op
);
2518 switch (op
& MO_SIZE
) {
2541 static void gen_ldst_i32(TCGOpcode opc
, TCGv_i32 val
, TCGv addr
,
2542 TCGMemOp memop
, TCGArg idx
)
2544 TCGMemOpIdx oi
= make_memop_idx(memop
, idx
);
2545 #if TARGET_LONG_BITS == 32
2546 tcg_gen_op3i_i32(opc
, val
, addr
, oi
);
2548 if (TCG_TARGET_REG_BITS
== 32) {
2549 tcg_gen_op4i_i32(opc
, val
, TCGV_LOW(addr
), TCGV_HIGH(addr
), oi
);
2551 tcg_gen_op3(&tcg_ctx
, opc
, GET_TCGV_I32(val
), GET_TCGV_I64(addr
), oi
);
2556 static void gen_ldst_i64(TCGOpcode opc
, TCGv_i64 val
, TCGv addr
,
2557 TCGMemOp memop
, TCGArg idx
)
2559 TCGMemOpIdx oi
= make_memop_idx(memop
, idx
);
2560 #if TARGET_LONG_BITS == 32
2561 if (TCG_TARGET_REG_BITS
== 32) {
2562 tcg_gen_op4i_i32(opc
, TCGV_LOW(val
), TCGV_HIGH(val
), addr
, oi
);
2564 tcg_gen_op3(&tcg_ctx
, opc
, GET_TCGV_I64(val
), GET_TCGV_I32(addr
), oi
);
2567 if (TCG_TARGET_REG_BITS
== 32) {
2568 tcg_gen_op5i_i32(opc
, TCGV_LOW(val
), TCGV_HIGH(val
),
2569 TCGV_LOW(addr
), TCGV_HIGH(addr
), oi
);
2571 tcg_gen_op3i_i64(opc
, val
, addr
, oi
);
2576 void tcg_gen_qemu_ld_i32(TCGv_i32 val
, TCGv addr
, TCGArg idx
, TCGMemOp memop
)
2578 memop
= tcg_canonicalize_memop(memop
, 0, 0);
2579 trace_guest_mem_before_tcg(tcg_ctx
.cpu
, tcg_ctx
.tcg_env
,
2580 addr
, trace_mem_get_info(memop
, 0));
2581 gen_ldst_i32(INDEX_op_qemu_ld_i32
, val
, addr
, memop
, idx
);
2584 void tcg_gen_qemu_st_i32(TCGv_i32 val
, TCGv addr
, TCGArg idx
, TCGMemOp memop
)
2586 memop
= tcg_canonicalize_memop(memop
, 0, 1);
2587 trace_guest_mem_before_tcg(tcg_ctx
.cpu
, tcg_ctx
.tcg_env
,
2588 addr
, trace_mem_get_info(memop
, 1));
2589 gen_ldst_i32(INDEX_op_qemu_st_i32
, val
, addr
, memop
, idx
);
2592 void tcg_gen_qemu_ld_i64(TCGv_i64 val
, TCGv addr
, TCGArg idx
, TCGMemOp memop
)
2594 if (TCG_TARGET_REG_BITS
== 32 && (memop
& MO_SIZE
) < MO_64
) {
2595 tcg_gen_qemu_ld_i32(TCGV_LOW(val
), addr
, idx
, memop
);
2596 if (memop
& MO_SIGN
) {
2597 tcg_gen_sari_i32(TCGV_HIGH(val
), TCGV_LOW(val
), 31);
2599 tcg_gen_movi_i32(TCGV_HIGH(val
), 0);
2604 memop
= tcg_canonicalize_memop(memop
, 1, 0);
2605 trace_guest_mem_before_tcg(tcg_ctx
.cpu
, tcg_ctx
.tcg_env
,
2606 addr
, trace_mem_get_info(memop
, 0));
2607 gen_ldst_i64(INDEX_op_qemu_ld_i64
, val
, addr
, memop
, idx
);
2610 void tcg_gen_qemu_st_i64(TCGv_i64 val
, TCGv addr
, TCGArg idx
, TCGMemOp memop
)
2612 if (TCG_TARGET_REG_BITS
== 32 && (memop
& MO_SIZE
) < MO_64
) {
2613 tcg_gen_qemu_st_i32(TCGV_LOW(val
), addr
, idx
, memop
);
2617 memop
= tcg_canonicalize_memop(memop
, 1, 1);
2618 trace_guest_mem_before_tcg(tcg_ctx
.cpu
, tcg_ctx
.tcg_env
,
2619 addr
, trace_mem_get_info(memop
, 1));
2620 gen_ldst_i64(INDEX_op_qemu_st_i64
, val
, addr
, memop
, idx
);
2623 static void tcg_gen_ext_i32(TCGv_i32 ret
, TCGv_i32 val
, TCGMemOp opc
)
2625 switch (opc
& MO_SSIZE
) {
2627 tcg_gen_ext8s_i32(ret
, val
);
2630 tcg_gen_ext8u_i32(ret
, val
);
2633 tcg_gen_ext16s_i32(ret
, val
);
2636 tcg_gen_ext16u_i32(ret
, val
);
2639 tcg_gen_mov_i32(ret
, val
);
2644 static void tcg_gen_ext_i64(TCGv_i64 ret
, TCGv_i64 val
, TCGMemOp opc
)
2646 switch (opc
& MO_SSIZE
) {
2648 tcg_gen_ext8s_i64(ret
, val
);
2651 tcg_gen_ext8u_i64(ret
, val
);
2654 tcg_gen_ext16s_i64(ret
, val
);
2657 tcg_gen_ext16u_i64(ret
, val
);
2660 tcg_gen_ext32s_i64(ret
, val
);
2663 tcg_gen_ext32u_i64(ret
, val
);
2666 tcg_gen_mov_i64(ret
, val
);
2671 #ifdef CONFIG_SOFTMMU
2672 typedef void (*gen_atomic_cx_i32
)(TCGv_i32
, TCGv_env
, TCGv
,
2673 TCGv_i32
, TCGv_i32
, TCGv_i32
);
2674 typedef void (*gen_atomic_cx_i64
)(TCGv_i64
, TCGv_env
, TCGv
,
2675 TCGv_i64
, TCGv_i64
, TCGv_i32
);
2676 typedef void (*gen_atomic_op_i32
)(TCGv_i32
, TCGv_env
, TCGv
,
2677 TCGv_i32
, TCGv_i32
);
2678 typedef void (*gen_atomic_op_i64
)(TCGv_i64
, TCGv_env
, TCGv
,
2679 TCGv_i64
, TCGv_i32
);
2681 typedef void (*gen_atomic_cx_i32
)(TCGv_i32
, TCGv_env
, TCGv
, TCGv_i32
, TCGv_i32
);
2682 typedef void (*gen_atomic_cx_i64
)(TCGv_i64
, TCGv_env
, TCGv
, TCGv_i64
, TCGv_i64
);
2683 typedef void (*gen_atomic_op_i32
)(TCGv_i32
, TCGv_env
, TCGv
, TCGv_i32
);
2684 typedef void (*gen_atomic_op_i64
)(TCGv_i64
, TCGv_env
, TCGv
, TCGv_i64
);
2687 #ifdef CONFIG_ATOMIC64
2688 # define WITH_ATOMIC64(X) X,
2690 # define WITH_ATOMIC64(X)
2693 static void * const table_cmpxchg
[16] = {
2694 [MO_8
] = gen_helper_atomic_cmpxchgb
,
2695 [MO_16
| MO_LE
] = gen_helper_atomic_cmpxchgw_le
,
2696 [MO_16
| MO_BE
] = gen_helper_atomic_cmpxchgw_be
,
2697 [MO_32
| MO_LE
] = gen_helper_atomic_cmpxchgl_le
,
2698 [MO_32
| MO_BE
] = gen_helper_atomic_cmpxchgl_be
,
2699 WITH_ATOMIC64([MO_64
| MO_LE
] = gen_helper_atomic_cmpxchgq_le
)
2700 WITH_ATOMIC64([MO_64
| MO_BE
] = gen_helper_atomic_cmpxchgq_be
)
2703 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv
, TCGv addr
, TCGv_i32 cmpv
,
2704 TCGv_i32 newv
, TCGArg idx
, TCGMemOp memop
)
2706 memop
= tcg_canonicalize_memop(memop
, 0, 0);
2708 if (!parallel_cpus
) {
2709 TCGv_i32 t1
= tcg_temp_new_i32();
2710 TCGv_i32 t2
= tcg_temp_new_i32();
2712 tcg_gen_ext_i32(t2
, cmpv
, memop
& MO_SIZE
);
2714 tcg_gen_qemu_ld_i32(t1
, addr
, idx
, memop
& ~MO_SIGN
);
2715 tcg_gen_movcond_i32(TCG_COND_EQ
, t2
, t1
, t2
, newv
, t1
);
2716 tcg_gen_qemu_st_i32(t2
, addr
, idx
, memop
);
2717 tcg_temp_free_i32(t2
);
2719 if (memop
& MO_SIGN
) {
2720 tcg_gen_ext_i32(retv
, t1
, memop
);
2722 tcg_gen_mov_i32(retv
, t1
);
2724 tcg_temp_free_i32(t1
);
2726 gen_atomic_cx_i32 gen
;
2728 gen
= table_cmpxchg
[memop
& (MO_SIZE
| MO_BSWAP
)];
2729 tcg_debug_assert(gen
!= NULL
);
2731 #ifdef CONFIG_SOFTMMU
2733 TCGv_i32 oi
= tcg_const_i32(make_memop_idx(memop
& ~MO_SIGN
, idx
));
2734 gen(retv
, tcg_ctx
.tcg_env
, addr
, cmpv
, newv
, oi
);
2735 tcg_temp_free_i32(oi
);
2738 gen(retv
, tcg_ctx
.tcg_env
, addr
, cmpv
, newv
);
2741 if (memop
& MO_SIGN
) {
2742 tcg_gen_ext_i32(retv
, retv
, memop
);
2747 void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv
, TCGv addr
, TCGv_i64 cmpv
,
2748 TCGv_i64 newv
, TCGArg idx
, TCGMemOp memop
)
2750 memop
= tcg_canonicalize_memop(memop
, 1, 0);
2752 if (!parallel_cpus
) {
2753 TCGv_i64 t1
= tcg_temp_new_i64();
2754 TCGv_i64 t2
= tcg_temp_new_i64();
2756 tcg_gen_ext_i64(t2
, cmpv
, memop
& MO_SIZE
);
2758 tcg_gen_qemu_ld_i64(t1
, addr
, idx
, memop
& ~MO_SIGN
);
2759 tcg_gen_movcond_i64(TCG_COND_EQ
, t2
, t1
, t2
, newv
, t1
);
2760 tcg_gen_qemu_st_i64(t2
, addr
, idx
, memop
);
2761 tcg_temp_free_i64(t2
);
2763 if (memop
& MO_SIGN
) {
2764 tcg_gen_ext_i64(retv
, t1
, memop
);
2766 tcg_gen_mov_i64(retv
, t1
);
2768 tcg_temp_free_i64(t1
);
2769 } else if ((memop
& MO_SIZE
) == MO_64
) {
2770 #ifdef CONFIG_ATOMIC64
2771 gen_atomic_cx_i64 gen
;
2773 gen
= table_cmpxchg
[memop
& (MO_SIZE
| MO_BSWAP
)];
2774 tcg_debug_assert(gen
!= NULL
);
2776 #ifdef CONFIG_SOFTMMU
2778 TCGv_i32 oi
= tcg_const_i32(make_memop_idx(memop
, idx
));
2779 gen(retv
, tcg_ctx
.tcg_env
, addr
, cmpv
, newv
, oi
);
2780 tcg_temp_free_i32(oi
);
2783 gen(retv
, tcg_ctx
.tcg_env
, addr
, cmpv
, newv
);
2786 gen_helper_exit_atomic(tcg_ctx
.tcg_env
);
2787 #endif /* CONFIG_ATOMIC64 */
2789 TCGv_i32 c32
= tcg_temp_new_i32();
2790 TCGv_i32 n32
= tcg_temp_new_i32();
2791 TCGv_i32 r32
= tcg_temp_new_i32();
2793 tcg_gen_extrl_i64_i32(c32
, cmpv
);
2794 tcg_gen_extrl_i64_i32(n32
, newv
);
2795 tcg_gen_atomic_cmpxchg_i32(r32
, addr
, c32
, n32
, idx
, memop
& ~MO_SIGN
);
2796 tcg_temp_free_i32(c32
);
2797 tcg_temp_free_i32(n32
);
2799 tcg_gen_extu_i32_i64(retv
, r32
);
2800 tcg_temp_free_i32(r32
);
2802 if (memop
& MO_SIGN
) {
2803 tcg_gen_ext_i64(retv
, retv
, memop
);
2808 static void do_nonatomic_op_i32(TCGv_i32 ret
, TCGv addr
, TCGv_i32 val
,
2809 TCGArg idx
, TCGMemOp memop
, bool new_val
,
2810 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
2812 TCGv_i32 t1
= tcg_temp_new_i32();
2813 TCGv_i32 t2
= tcg_temp_new_i32();
2815 memop
= tcg_canonicalize_memop(memop
, 0, 0);
2817 tcg_gen_qemu_ld_i32(t1
, addr
, idx
, memop
& ~MO_SIGN
);
2819 tcg_gen_qemu_st_i32(t2
, addr
, idx
, memop
);
2821 tcg_gen_ext_i32(ret
, (new_val
? t2
: t1
), memop
);
2822 tcg_temp_free_i32(t1
);
2823 tcg_temp_free_i32(t2
);
2826 static void do_atomic_op_i32(TCGv_i32 ret
, TCGv addr
, TCGv_i32 val
,
2827 TCGArg idx
, TCGMemOp memop
, void * const table
[])
2829 gen_atomic_op_i32 gen
;
2831 memop
= tcg_canonicalize_memop(memop
, 0, 0);
2833 gen
= table
[memop
& (MO_SIZE
| MO_BSWAP
)];
2834 tcg_debug_assert(gen
!= NULL
);
2836 #ifdef CONFIG_SOFTMMU
2838 TCGv_i32 oi
= tcg_const_i32(make_memop_idx(memop
& ~MO_SIGN
, idx
));
2839 gen(ret
, tcg_ctx
.tcg_env
, addr
, val
, oi
);
2840 tcg_temp_free_i32(oi
);
2843 gen(ret
, tcg_ctx
.tcg_env
, addr
, val
);
2846 if (memop
& MO_SIGN
) {
2847 tcg_gen_ext_i32(ret
, ret
, memop
);
2851 static void do_nonatomic_op_i64(TCGv_i64 ret
, TCGv addr
, TCGv_i64 val
,
2852 TCGArg idx
, TCGMemOp memop
, bool new_val
,
2853 void (*gen
)(TCGv_i64
, TCGv_i64
, TCGv_i64
))
2855 TCGv_i64 t1
= tcg_temp_new_i64();
2856 TCGv_i64 t2
= tcg_temp_new_i64();
2858 memop
= tcg_canonicalize_memop(memop
, 1, 0);
2860 tcg_gen_qemu_ld_i64(t1
, addr
, idx
, memop
& ~MO_SIGN
);
2862 tcg_gen_qemu_st_i64(t2
, addr
, idx
, memop
);
2864 tcg_gen_ext_i64(ret
, (new_val
? t2
: t1
), memop
);
2865 tcg_temp_free_i64(t1
);
2866 tcg_temp_free_i64(t2
);
2869 static void do_atomic_op_i64(TCGv_i64 ret
, TCGv addr
, TCGv_i64 val
,
2870 TCGArg idx
, TCGMemOp memop
, void * const table
[])
2872 memop
= tcg_canonicalize_memop(memop
, 1, 0);
2874 if ((memop
& MO_SIZE
) == MO_64
) {
2875 #ifdef CONFIG_ATOMIC64
2876 gen_atomic_op_i64 gen
;
2878 gen
= table
[memop
& (MO_SIZE
| MO_BSWAP
)];
2879 tcg_debug_assert(gen
!= NULL
);
2881 #ifdef CONFIG_SOFTMMU
2883 TCGv_i32 oi
= tcg_const_i32(make_memop_idx(memop
& ~MO_SIGN
, idx
));
2884 gen(ret
, tcg_ctx
.tcg_env
, addr
, val
, oi
);
2885 tcg_temp_free_i32(oi
);
2888 gen(ret
, tcg_ctx
.tcg_env
, addr
, val
);
2891 gen_helper_exit_atomic(tcg_ctx
.tcg_env
);
2892 #endif /* CONFIG_ATOMIC64 */
2894 TCGv_i32 v32
= tcg_temp_new_i32();
2895 TCGv_i32 r32
= tcg_temp_new_i32();
2897 tcg_gen_extrl_i64_i32(v32
, val
);
2898 do_atomic_op_i32(r32
, addr
, v32
, idx
, memop
& ~MO_SIGN
, table
);
2899 tcg_temp_free_i32(v32
);
2901 tcg_gen_extu_i32_i64(ret
, r32
);
2902 tcg_temp_free_i32(r32
);
2904 if (memop
& MO_SIGN
) {
2905 tcg_gen_ext_i64(ret
, ret
, memop
);
2910 #define GEN_ATOMIC_HELPER(NAME, OP, NEW) \
2911 static void * const table_##NAME[16] = { \
2912 [MO_8] = gen_helper_atomic_##NAME##b, \
2913 [MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le, \
2914 [MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be, \
2915 [MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le, \
2916 [MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be, \
2917 WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le) \
2918 WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be) \
2920 void tcg_gen_atomic_##NAME##_i32 \
2921 (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, TCGMemOp memop) \
2923 if (parallel_cpus) { \
2924 do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \
2926 do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW, \
2927 tcg_gen_##OP##_i32); \
2930 void tcg_gen_atomic_##NAME##_i64 \
2931 (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, TCGMemOp memop) \
2933 if (parallel_cpus) { \
2934 do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \
2936 do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW, \
2937 tcg_gen_##OP##_i64); \
2941 GEN_ATOMIC_HELPER(fetch_add
, add
, 0)
2942 GEN_ATOMIC_HELPER(fetch_and
, and, 0)
2943 GEN_ATOMIC_HELPER(fetch_or
, or, 0)
2944 GEN_ATOMIC_HELPER(fetch_xor
, xor, 0)
2946 GEN_ATOMIC_HELPER(add_fetch
, add
, 1)
2947 GEN_ATOMIC_HELPER(and_fetch
, and, 1)
2948 GEN_ATOMIC_HELPER(or_fetch
, or, 1)
2949 GEN_ATOMIC_HELPER(xor_fetch
, xor, 1)
2951 static void tcg_gen_mov2_i32(TCGv_i32 r
, TCGv_i32 a
, TCGv_i32 b
)
2953 tcg_gen_mov_i32(r
, b
);
2956 static void tcg_gen_mov2_i64(TCGv_i64 r
, TCGv_i64 a
, TCGv_i64 b
)
2958 tcg_gen_mov_i64(r
, b
);
2961 GEN_ATOMIC_HELPER(xchg
, mov2
, 0)
2963 #undef GEN_ATOMIC_HELPER