]>
git.proxmox.com Git - mirror_qemu.git/blob - tcg/tcg-op.h
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
26 /* legacy dyngen operations */
29 int gen_new_label(void);
31 static inline void tcg_gen_op1(int opc
, TCGArg arg1
)
34 *gen_opparam_ptr
++ = arg1
;
37 static inline void tcg_gen_op2(int opc
, TCGArg arg1
, TCGArg arg2
)
40 *gen_opparam_ptr
++ = arg1
;
41 *gen_opparam_ptr
++ = arg2
;
44 static inline void tcg_gen_op3(int opc
, TCGArg arg1
, TCGArg arg2
, TCGArg arg3
)
47 *gen_opparam_ptr
++ = arg1
;
48 *gen_opparam_ptr
++ = arg2
;
49 *gen_opparam_ptr
++ = arg3
;
52 static inline void tcg_gen_op4(int opc
, TCGArg arg1
, TCGArg arg2
, TCGArg arg3
,
56 *gen_opparam_ptr
++ = arg1
;
57 *gen_opparam_ptr
++ = arg2
;
58 *gen_opparam_ptr
++ = arg3
;
59 *gen_opparam_ptr
++ = arg4
;
62 static inline void tcg_gen_op5(int opc
, TCGArg arg1
, TCGArg arg2
,
63 TCGArg arg3
, TCGArg arg4
,
67 *gen_opparam_ptr
++ = arg1
;
68 *gen_opparam_ptr
++ = arg2
;
69 *gen_opparam_ptr
++ = arg3
;
70 *gen_opparam_ptr
++ = arg4
;
71 *gen_opparam_ptr
++ = arg5
;
74 static inline void tcg_gen_op6(int opc
, TCGArg arg1
, TCGArg arg2
,
75 TCGArg arg3
, TCGArg arg4
,
76 TCGArg arg5
, TCGArg arg6
)
79 *gen_opparam_ptr
++ = arg1
;
80 *gen_opparam_ptr
++ = arg2
;
81 *gen_opparam_ptr
++ = arg3
;
82 *gen_opparam_ptr
++ = arg4
;
83 *gen_opparam_ptr
++ = arg5
;
84 *gen_opparam_ptr
++ = arg6
;
87 static inline void gen_set_label(int n
)
89 tcg_gen_op1(INDEX_op_set_label
, n
);
92 static inline void tcg_gen_mov_i32(int ret
, int arg
)
94 tcg_gen_op2(INDEX_op_mov_i32
, ret
, arg
);
97 static inline void tcg_gen_movi_i32(int ret
, int32_t arg
)
99 tcg_gen_op2(INDEX_op_movi_i32
, ret
, arg
);
103 #define TCG_HELPER_CALL_FLAGS 0
105 static inline void tcg_gen_helper_0_0(void *func
)
107 tcg_gen_call(&tcg_ctx
,
108 tcg_const_ptr((tcg_target_long
)func
), TCG_HELPER_CALL_FLAGS
,
112 static inline void tcg_gen_helper_0_1(void *func
, TCGArg arg
)
114 tcg_gen_call(&tcg_ctx
,
115 tcg_const_ptr((tcg_target_long
)func
), TCG_HELPER_CALL_FLAGS
,
119 static inline void tcg_gen_helper_0_2(void *func
, TCGArg arg1
, TCGArg arg2
)
124 tcg_gen_call(&tcg_ctx
,
125 tcg_const_ptr((tcg_target_long
)func
), TCG_HELPER_CALL_FLAGS
,
129 static inline void tcg_gen_helper_1_2(void *func
, TCGArg ret
,
130 TCGArg arg1
, TCGArg arg2
)
135 tcg_gen_call(&tcg_ctx
,
136 tcg_const_ptr((tcg_target_long
)func
), TCG_HELPER_CALL_FLAGS
,
142 static inline void tcg_gen_ld8u_i32(int ret
, int arg2
, tcg_target_long offset
)
144 tcg_gen_op3(INDEX_op_ld8u_i32
, ret
, arg2
, offset
);
147 static inline void tcg_gen_ld8s_i32(int ret
, int arg2
, tcg_target_long offset
)
149 tcg_gen_op3(INDEX_op_ld8s_i32
, ret
, arg2
, offset
);
152 static inline void tcg_gen_ld16u_i32(int ret
, int arg2
, tcg_target_long offset
)
154 tcg_gen_op3(INDEX_op_ld16u_i32
, ret
, arg2
, offset
);
157 static inline void tcg_gen_ld16s_i32(int ret
, int arg2
, tcg_target_long offset
)
159 tcg_gen_op3(INDEX_op_ld16s_i32
, ret
, arg2
, offset
);
162 static inline void tcg_gen_ld_i32(int ret
, int arg2
, tcg_target_long offset
)
164 tcg_gen_op3(INDEX_op_ld_i32
, ret
, arg2
, offset
);
167 static inline void tcg_gen_st8_i32(int arg1
, int arg2
, tcg_target_long offset
)
169 tcg_gen_op3(INDEX_op_st8_i32
, arg1
, arg2
, offset
);
172 static inline void tcg_gen_st16_i32(int arg1
, int arg2
, tcg_target_long offset
)
174 tcg_gen_op3(INDEX_op_st16_i32
, arg1
, arg2
, offset
);
177 static inline void tcg_gen_st_i32(int arg1
, int arg2
, tcg_target_long offset
)
179 tcg_gen_op3(INDEX_op_st_i32
, arg1
, arg2
, offset
);
182 static inline void tcg_gen_add_i32(int ret
, int arg1
, int arg2
)
184 tcg_gen_op3(INDEX_op_add_i32
, ret
, arg1
, arg2
);
187 static inline void tcg_gen_addi_i32(int ret
, int arg1
, int32_t arg2
)
189 tcg_gen_add_i32(ret
, arg1
, tcg_const_i32(arg2
));
192 static inline void tcg_gen_sub_i32(int ret
, int arg1
, int arg2
)
194 tcg_gen_op3(INDEX_op_sub_i32
, ret
, arg1
, arg2
);
197 static inline void tcg_gen_subi_i32(int ret
, int arg1
, int32_t arg2
)
199 tcg_gen_sub_i32(ret
, arg1
, tcg_const_i32(arg2
));
202 static inline void tcg_gen_and_i32(int ret
, int arg1
, int arg2
)
204 tcg_gen_op3(INDEX_op_and_i32
, ret
, arg1
, arg2
);
207 static inline void tcg_gen_andi_i32(int ret
, int arg1
, int32_t arg2
)
209 /* some cases can be optimized here */
211 tcg_gen_movi_i32(ret
, 0);
212 } else if (arg2
== 0xffffffff) {
213 tcg_gen_mov_i32(ret
, arg1
);
215 tcg_gen_and_i32(ret
, arg1
, tcg_const_i32(arg2
));
219 static inline void tcg_gen_or_i32(int ret
, int arg1
, int arg2
)
221 tcg_gen_op3(INDEX_op_or_i32
, ret
, arg1
, arg2
);
224 static inline void tcg_gen_ori_i32(int ret
, int arg1
, int32_t arg2
)
226 /* some cases can be optimized here */
227 if (arg2
== 0xffffffff) {
228 tcg_gen_movi_i32(ret
, 0);
229 } else if (arg2
== 0) {
230 tcg_gen_mov_i32(ret
, arg1
);
232 tcg_gen_or_i32(ret
, arg1
, tcg_const_i32(arg2
));
236 static inline void tcg_gen_xor_i32(int ret
, int arg1
, int arg2
)
238 tcg_gen_op3(INDEX_op_xor_i32
, ret
, arg1
, arg2
);
241 static inline void tcg_gen_xori_i32(int ret
, int arg1
, int32_t arg2
)
243 /* some cases can be optimized here */
245 tcg_gen_mov_i32(ret
, arg1
);
247 tcg_gen_xor_i32(ret
, arg1
, tcg_const_i32(arg2
));
251 static inline void tcg_gen_shl_i32(int ret
, int arg1
, int arg2
)
253 tcg_gen_op3(INDEX_op_shl_i32
, ret
, arg1
, arg2
);
256 static inline void tcg_gen_shli_i32(int ret
, int arg1
, int32_t arg2
)
258 tcg_gen_shl_i32(ret
, arg1
, tcg_const_i32(arg2
));
261 static inline void tcg_gen_shr_i32(int ret
, int arg1
, int arg2
)
263 tcg_gen_op3(INDEX_op_shr_i32
, ret
, arg1
, arg2
);
266 static inline void tcg_gen_shri_i32(int ret
, int arg1
, int32_t arg2
)
268 tcg_gen_shr_i32(ret
, arg1
, tcg_const_i32(arg2
));
271 static inline void tcg_gen_sar_i32(int ret
, int arg1
, int arg2
)
273 tcg_gen_op3(INDEX_op_sar_i32
, ret
, arg1
, arg2
);
276 static inline void tcg_gen_sari_i32(int ret
, int arg1
, int32_t arg2
)
278 tcg_gen_sar_i32(ret
, arg1
, tcg_const_i32(arg2
));
281 static inline void tcg_gen_brcond_i32(int cond
, TCGArg arg1
, TCGArg arg2
,
284 tcg_gen_op4(INDEX_op_brcond_i32
, arg1
, arg2
, cond
, label_index
);
287 static inline void tcg_gen_mul_i32(int ret
, int arg1
, int arg2
)
289 tcg_gen_op3(INDEX_op_mul_i32
, ret
, arg1
, arg2
);
292 #ifdef TCG_TARGET_HAS_div_i32
293 static inline void tcg_gen_div_i32(int ret
, int arg1
, int arg2
)
295 tcg_gen_op3(INDEX_op_div_i32
, ret
, arg1
, arg2
);
298 static inline void tcg_gen_rem_i32(int ret
, int arg1
, int arg2
)
300 tcg_gen_op3(INDEX_op_rem_i32
, ret
, arg1
, arg2
);
303 static inline void tcg_gen_divu_i32(int ret
, int arg1
, int arg2
)
305 tcg_gen_op3(INDEX_op_divu_i32
, ret
, arg1
, arg2
);
308 static inline void tcg_gen_remu_i32(int ret
, int arg1
, int arg2
)
310 tcg_gen_op3(INDEX_op_remu_i32
, ret
, arg1
, arg2
);
313 static inline void tcg_gen_div_i32(int ret
, int arg1
, int arg2
)
316 t0
= tcg_temp_new(TCG_TYPE_I32
);
317 tcg_gen_sari_i32(t0
, arg1
, 31);
318 tcg_gen_op5(INDEX_op_div2_i32
, ret
, t0
, arg1
, t0
, arg2
);
321 static inline void tcg_gen_rem_i32(int ret
, int arg1
, int arg2
)
324 t0
= tcg_temp_new(TCG_TYPE_I32
);
325 tcg_gen_sari_i32(t0
, arg1
, 31);
326 tcg_gen_op5(INDEX_op_div2_i32
, t0
, ret
, arg1
, t0
, arg2
);
329 static inline void tcg_gen_divu_i32(int ret
, int arg1
, int arg2
)
332 t0
= tcg_temp_new(TCG_TYPE_I32
);
333 tcg_gen_movi_i32(t0
, 0);
334 tcg_gen_op5(INDEX_op_divu2_i32
, ret
, t0
, arg1
, t0
, arg2
);
337 static inline void tcg_gen_remu_i32(int ret
, int arg1
, int arg2
)
340 t0
= tcg_temp_new(TCG_TYPE_I32
);
341 tcg_gen_movi_i32(t0
, 0);
342 tcg_gen_op5(INDEX_op_divu2_i32
, t0
, ret
, arg1
, t0
, arg2
);
346 #if TCG_TARGET_REG_BITS == 32
348 static inline void tcg_gen_mov_i64(int ret
, int arg
)
350 tcg_gen_mov_i32(ret
, arg
);
351 tcg_gen_mov_i32(ret
+ 1, arg
+ 1);
354 static inline void tcg_gen_movi_i64(int ret
, int64_t arg
)
356 tcg_gen_movi_i32(ret
, arg
);
357 tcg_gen_movi_i32(ret
+ 1, arg
>> 32);
360 static inline void tcg_gen_ld8u_i64(int ret
, int arg2
, tcg_target_long offset
)
362 tcg_gen_ld8u_i32(ret
, arg2
, offset
);
363 tcg_gen_movi_i32(ret
+ 1, 0);
366 static inline void tcg_gen_ld8s_i64(int ret
, int arg2
, tcg_target_long offset
)
368 tcg_gen_ld8s_i32(ret
, arg2
, offset
);
369 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
372 static inline void tcg_gen_ld16u_i64(int ret
, int arg2
, tcg_target_long offset
)
374 tcg_gen_ld16u_i32(ret
, arg2
, offset
);
375 tcg_gen_movi_i32(ret
+ 1, 0);
378 static inline void tcg_gen_ld16s_i64(int ret
, int arg2
, tcg_target_long offset
)
380 tcg_gen_ld16s_i32(ret
, arg2
, offset
);
381 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
384 static inline void tcg_gen_ld32u_i64(int ret
, int arg2
, tcg_target_long offset
)
386 tcg_gen_ld_i32(ret
, arg2
, offset
);
387 tcg_gen_movi_i32(ret
+ 1, 0);
390 static inline void tcg_gen_ld32s_i64(int ret
, int arg2
, tcg_target_long offset
)
392 tcg_gen_ld_i32(ret
, arg2
, offset
);
393 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
396 static inline void tcg_gen_ld_i64(int ret
, int arg2
, tcg_target_long offset
)
398 /* since arg2 and ret have different types, they cannot be the
400 #ifdef TCG_TARGET_WORDS_BIGENDIAN
401 tcg_gen_ld_i32(ret
+ 1, arg2
, offset
);
402 tcg_gen_ld_i32(ret
, arg2
, offset
+ 4);
404 tcg_gen_ld_i32(ret
, arg2
, offset
);
405 tcg_gen_ld_i32(ret
+ 1, arg2
, offset
+ 4);
409 static inline void tcg_gen_st8_i64(int arg1
, int arg2
, tcg_target_long offset
)
411 tcg_gen_st8_i32(arg1
, arg2
, offset
);
414 static inline void tcg_gen_st16_i64(int arg1
, int arg2
, tcg_target_long offset
)
416 tcg_gen_st16_i32(arg1
, arg2
, offset
);
419 static inline void tcg_gen_st32_i64(int arg1
, int arg2
, tcg_target_long offset
)
421 tcg_gen_st_i32(arg1
, arg2
, offset
);
424 static inline void tcg_gen_st_i64(int arg1
, int arg2
, tcg_target_long offset
)
426 #ifdef TCG_TARGET_WORDS_BIGENDIAN
427 tcg_gen_st_i32(arg1
+ 1, arg2
, offset
);
428 tcg_gen_st_i32(arg1
, arg2
, offset
+ 4);
430 tcg_gen_st_i32(arg1
, arg2
, offset
);
431 tcg_gen_st_i32(arg1
+ 1, arg2
, offset
+ 4);
435 static inline void tcg_gen_add_i64(int ret
, int arg1
, int arg2
)
437 tcg_gen_op6(INDEX_op_add2_i32
, ret
, ret
+ 1,
438 arg1
, arg1
+ 1, arg2
, arg2
+ 1);
441 static inline void tcg_gen_addi_i64(int ret
, int arg1
, int64_t arg2
)
443 tcg_gen_add_i64(ret
, arg1
, tcg_const_i64(arg2
));
446 static inline void tcg_gen_sub_i64(int ret
, int arg1
, int arg2
)
448 tcg_gen_op6(INDEX_op_sub2_i32
, ret
, ret
+ 1,
449 arg1
, arg1
+ 1, arg2
, arg2
+ 1);
452 static inline void tcg_gen_subi_i64(int ret
, int arg1
, int64_t arg2
)
454 tcg_gen_sub_i64(ret
, arg1
, tcg_const_i64(arg2
));
457 static inline void tcg_gen_and_i64(int ret
, int arg1
, int arg2
)
459 tcg_gen_and_i32(ret
, arg1
, arg2
);
460 tcg_gen_and_i32(ret
+ 1, arg1
+ 1, arg2
+ 1);
463 static inline void tcg_gen_andi_i64(int ret
, int arg1
, int64_t arg2
)
465 tcg_gen_andi_i32(ret
, arg1
, arg2
);
466 tcg_gen_andi_i32(ret
+ 1, arg1
+ 1, arg2
>> 32);
469 static inline void tcg_gen_or_i64(int ret
, int arg1
, int arg2
)
471 tcg_gen_or_i32(ret
, arg1
, arg2
);
472 tcg_gen_or_i32(ret
+ 1, arg1
+ 1, arg2
+ 1);
475 static inline void tcg_gen_ori_i64(int ret
, int arg1
, int64_t arg2
)
477 tcg_gen_ori_i32(ret
, arg1
, arg2
);
478 tcg_gen_ori_i32(ret
+ 1, arg1
+ 1, arg2
>> 32);
481 static inline void tcg_gen_xor_i64(int ret
, int arg1
, int arg2
)
483 tcg_gen_xor_i32(ret
, arg1
, arg2
);
484 tcg_gen_xor_i32(ret
+ 1, arg1
+ 1, arg2
+ 1);
487 static inline void tcg_gen_xori_i64(int ret
, int arg1
, int64_t arg2
)
489 tcg_gen_xori_i32(ret
, arg1
, arg2
);
490 tcg_gen_xori_i32(ret
+ 1, arg1
+ 1, arg2
>> 32);
493 /* XXX: use generic code when basic block handling is OK or CPU
494 specific code (x86) */
495 static inline void tcg_gen_shl_i64(int ret
, int arg1
, int64_t arg2
)
497 tcg_gen_helper_1_2(tcg_helper_shl_i64
, ret
, arg1
, arg2
);
500 static inline void tcg_gen_shli_i64(int ret
, int arg1
, int64_t arg2
)
502 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 0, 0);
505 static inline void tcg_gen_shr_i64(int ret
, int arg1
, int64_t arg2
)
507 tcg_gen_helper_1_2(tcg_helper_shr_i64
, ret
, arg1
, arg2
);
510 static inline void tcg_gen_shri_i64(int ret
, int arg1
, int64_t arg2
)
512 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 0);
515 static inline void tcg_gen_sar_i64(int ret
, int arg1
, int64_t arg2
)
517 tcg_gen_helper_1_2(tcg_helper_sar_i64
, ret
, arg1
, arg2
);
520 static inline void tcg_gen_sari_i64(int ret
, int arg1
, int64_t arg2
)
522 tcg_gen_shifti_i64(ret
, arg1
, arg2
, 1, 1);
525 static inline void tcg_gen_brcond_i64(int cond
, TCGArg arg1
, TCGArg arg2
,
528 tcg_gen_op6(INDEX_op_brcond2_i32
,
529 arg1
, arg1
+ 1, arg2
, arg2
+ 1, cond
, label_index
);
532 static inline void tcg_gen_mul_i64(int ret
, int arg1
, int arg2
)
536 t0
= tcg_temp_new(TCG_TYPE_I64
);
537 t1
= tcg_temp_new(TCG_TYPE_I32
);
539 tcg_gen_op4(INDEX_op_mulu2_i32
, t0
, t0
+ 1, arg1
, arg2
);
541 tcg_gen_mul_i32(t1
, arg1
, arg2
+ 1);
542 tcg_gen_add_i32(t0
+ 1, t0
+ 1, t1
);
543 tcg_gen_mul_i32(t1
, arg1
+ 1, arg2
);
544 tcg_gen_add_i32(t0
+ 1, t0
+ 1, t1
);
546 tcg_gen_mov_i64(ret
, t0
);
549 static inline void tcg_gen_div_i64(int ret
, int arg1
, int64_t arg2
)
551 tcg_gen_helper_1_2(tcg_helper_div_i64
, ret
, arg1
, arg2
);
554 static inline void tcg_gen_rem_i64(int ret
, int arg1
, int64_t arg2
)
556 tcg_gen_helper_1_2(tcg_helper_rem_i64
, ret
, arg1
, arg2
);
559 static inline void tcg_gen_divu_i64(int ret
, int arg1
, int64_t arg2
)
561 tcg_gen_helper_1_2(tcg_helper_divu_i64
, ret
, arg1
, arg2
);
564 static inline void tcg_gen_remu_i64(int ret
, int arg1
, int64_t arg2
)
566 tcg_gen_helper_1_2(tcg_helper_remu_i64
, ret
, arg1
, arg2
);
571 static inline void tcg_gen_mov_i64(int ret
, int arg
)
573 tcg_gen_op2(INDEX_op_mov_i64
, ret
, arg
);
576 static inline void tcg_gen_movi_i64(int ret
, int64_t arg
)
578 tcg_gen_op2(INDEX_op_movi_i64
, ret
, arg
);
581 static inline void tcg_gen_ld8u_i64(int ret
, int arg2
, tcg_target_long offset
)
583 tcg_gen_op3(INDEX_op_ld8u_i64
, ret
, arg2
, offset
);
586 static inline void tcg_gen_ld8s_i64(int ret
, int arg2
, tcg_target_long offset
)
588 tcg_gen_op3(INDEX_op_ld8s_i64
, ret
, arg2
, offset
);
591 static inline void tcg_gen_ld16u_i64(int ret
, int arg2
, tcg_target_long offset
)
593 tcg_gen_op3(INDEX_op_ld16u_i64
, ret
, arg2
, offset
);
596 static inline void tcg_gen_ld16s_i64(int ret
, int arg2
, tcg_target_long offset
)
598 tcg_gen_op3(INDEX_op_ld16s_i64
, ret
, arg2
, offset
);
601 static inline void tcg_gen_ld32u_i64(int ret
, int arg2
, tcg_target_long offset
)
603 tcg_gen_op3(INDEX_op_ld32u_i64
, ret
, arg2
, offset
);
606 static inline void tcg_gen_ld32s_i64(int ret
, int arg2
, tcg_target_long offset
)
608 tcg_gen_op3(INDEX_op_ld32s_i64
, ret
, arg2
, offset
);
611 static inline void tcg_gen_ld_i64(int ret
, int arg2
, tcg_target_long offset
)
613 tcg_gen_op3(INDEX_op_ld_i64
, ret
, arg2
, offset
);
616 static inline void tcg_gen_st8_i64(int arg1
, int arg2
, tcg_target_long offset
)
618 tcg_gen_op3(INDEX_op_st8_i64
, arg1
, arg2
, offset
);
621 static inline void tcg_gen_st16_i64(int arg1
, int arg2
, tcg_target_long offset
)
623 tcg_gen_op3(INDEX_op_st16_i64
, arg1
, arg2
, offset
);
626 static inline void tcg_gen_st32_i64(int arg1
, int arg2
, tcg_target_long offset
)
628 tcg_gen_op3(INDEX_op_st32_i64
, arg1
, arg2
, offset
);
631 static inline void tcg_gen_st_i64(int arg1
, int arg2
, tcg_target_long offset
)
633 tcg_gen_op3(INDEX_op_st_i64
, arg1
, arg2
, offset
);
636 static inline void tcg_gen_add_i64(int ret
, int arg1
, int arg2
)
638 tcg_gen_op3(INDEX_op_add_i64
, ret
, arg1
, arg2
);
641 static inline void tcg_gen_addi_i64(int ret
, int arg1
, int64_t arg2
)
643 tcg_gen_add_i64(ret
, arg1
, tcg_const_i64(arg2
));
646 static inline void tcg_gen_sub_i64(int ret
, int arg1
, int arg2
)
648 tcg_gen_op3(INDEX_op_sub_i64
, ret
, arg1
, arg2
);
651 static inline void tcg_gen_subi_i64(int ret
, int arg1
, int64_t arg2
)
653 tcg_gen_sub_i64(ret
, arg1
, tcg_const_i64(arg2
));
656 static inline void tcg_gen_and_i64(int ret
, int arg1
, int arg2
)
658 tcg_gen_op3(INDEX_op_and_i64
, ret
, arg1
, arg2
);
661 static inline void tcg_gen_andi_i64(int ret
, int arg1
, int64_t arg2
)
663 tcg_gen_and_i64(ret
, arg1
, tcg_const_i64(arg2
));
666 static inline void tcg_gen_or_i64(int ret
, int arg1
, int arg2
)
668 tcg_gen_op3(INDEX_op_or_i64
, ret
, arg1
, arg2
);
671 static inline void tcg_gen_ori_i64(int ret
, int arg1
, int64_t arg2
)
673 tcg_gen_or_i64(ret
, arg1
, tcg_const_i64(arg2
));
676 static inline void tcg_gen_xor_i64(int ret
, int arg1
, int arg2
)
678 tcg_gen_op3(INDEX_op_xor_i64
, ret
, arg1
, arg2
);
681 static inline void tcg_gen_xori_i64(int ret
, int arg1
, int64_t arg2
)
683 tcg_gen_xor_i64(ret
, arg1
, tcg_const_i64(arg2
));
686 static inline void tcg_gen_shl_i64(int ret
, int arg1
, int arg2
)
688 tcg_gen_op3(INDEX_op_shl_i64
, ret
, arg1
, arg2
);
691 static inline void tcg_gen_shli_i64(int ret
, int arg1
, int64_t arg2
)
693 tcg_gen_shl_i64(ret
, arg1
, tcg_const_i64(arg2
));
696 static inline void tcg_gen_shr_i64(int ret
, int arg1
, int arg2
)
698 tcg_gen_op3(INDEX_op_shr_i64
, ret
, arg1
, arg2
);
701 static inline void tcg_gen_shri_i64(int ret
, int arg1
, int64_t arg2
)
703 tcg_gen_shr_i64(ret
, arg1
, tcg_const_i64(arg2
));
706 static inline void tcg_gen_sar_i64(int ret
, int arg1
, int arg2
)
708 tcg_gen_op3(INDEX_op_sar_i64
, ret
, arg1
, arg2
);
711 static inline void tcg_gen_sari_i64(int ret
, int arg1
, int64_t arg2
)
713 tcg_gen_sar_i64(ret
, arg1
, tcg_const_i64(arg2
));
716 static inline void tcg_gen_brcond_i64(int cond
, TCGArg arg1
, TCGArg arg2
,
719 tcg_gen_op4(INDEX_op_brcond_i64
, arg1
, arg2
, cond
, label_index
);
722 static inline void tcg_gen_mul_i64(int ret
, int arg1
, int arg2
)
724 tcg_gen_op3(INDEX_op_mul_i64
, ret
, arg1
, arg2
);
727 #ifdef TCG_TARGET_HAS_div_i64
728 static inline void tcg_gen_div_i64(int ret
, int arg1
, int arg2
)
730 tcg_gen_op3(INDEX_op_div_i64
, ret
, arg1
, arg2
);
733 static inline void tcg_gen_rem_i64(int ret
, int arg1
, int arg2
)
735 tcg_gen_op3(INDEX_op_rem_i64
, ret
, arg1
, arg2
);
738 static inline void tcg_gen_divu_i64(int ret
, int arg1
, int arg2
)
740 tcg_gen_op3(INDEX_op_divu_i64
, ret
, arg1
, arg2
);
743 static inline void tcg_gen_remu_i64(int ret
, int arg1
, int arg2
)
745 tcg_gen_op3(INDEX_op_remu_i64
, ret
, arg1
, arg2
);
748 static inline void tcg_gen_div_i64(int ret
, int arg1
, int arg2
)
751 t0
= tcg_temp_new(TCG_TYPE_I64
);
752 tcg_gen_sari_i64(t0
, arg1
, 63);
753 tcg_gen_op5(INDEX_op_div2_i64
, ret
, t0
, arg1
, t0
, arg2
);
756 static inline void tcg_gen_rem_i64(int ret
, int arg1
, int arg2
)
759 t0
= tcg_temp_new(TCG_TYPE_I64
);
760 tcg_gen_sari_i64(t0
, arg1
, 63);
761 tcg_gen_op5(INDEX_op_div2_i64
, t0
, ret
, arg1
, t0
, arg2
);
764 static inline void tcg_gen_divu_i64(int ret
, int arg1
, int arg2
)
767 t0
= tcg_temp_new(TCG_TYPE_I64
);
768 tcg_gen_movi_i64(t0
, 0);
769 tcg_gen_op5(INDEX_op_divu2_i64
, ret
, t0
, arg1
, t0
, arg2
);
772 static inline void tcg_gen_remu_i64(int ret
, int arg1
, int arg2
)
775 t0
= tcg_temp_new(TCG_TYPE_I64
);
776 tcg_gen_movi_i64(t0
, 0);
777 tcg_gen_op5(INDEX_op_divu2_i64
, t0
, ret
, arg1
, t0
, arg2
);
783 /***************************************/
784 /* optional operations */
786 static inline void tcg_gen_ext8s_i32(int ret
, int arg
)
788 #ifdef TCG_TARGET_HAS_ext8s_i32
789 tcg_gen_op2(INDEX_op_ext8s_i32
, ret
, arg
);
791 tcg_gen_shli_i32(ret
, arg
, 24);
792 tcg_gen_sari_i32(ret
, arg
, 24);
796 static inline void tcg_gen_ext16s_i32(int ret
, int arg
)
798 #ifdef TCG_TARGET_HAS_ext16s_i32
799 tcg_gen_op2(INDEX_op_ext16s_i32
, ret
, arg
);
801 tcg_gen_shli_i32(ret
, arg
, 16);
802 tcg_gen_sari_i32(ret
, arg
, 16);
806 /* Note: we assume the two high bytes are set to zero */
807 static inline void tcg_gen_bswap16_i32(TCGArg ret
, TCGArg arg
)
809 #ifdef TCG_TARGET_HAS_bswap16_i32
810 tcg_gen_op2(INDEX_op_bswap16_i32
, ret
, arg
);
813 t0
= tcg_temp_new(TCG_TYPE_I32
);
814 t1
= tcg_temp_new(TCG_TYPE_I32
);
816 tcg_gen_shri_i32(t0
, arg
, 8);
817 tcg_gen_andi_i32(t1
, arg
, 0x000000ff);
818 tcg_gen_shli_i32(t1
, t1
, 8);
819 tcg_gen_or_i32(ret
, t0
, t1
);
823 static inline void tcg_gen_bswap_i32(TCGArg ret
, TCGArg arg
)
825 #ifdef TCG_TARGET_HAS_bswap_i32
826 tcg_gen_op2(INDEX_op_bswap_i32
, ret
, arg
);
829 t0
= tcg_temp_new(TCG_TYPE_I32
);
830 t1
= tcg_temp_new(TCG_TYPE_I32
);
832 tcg_gen_shli_i32(t0
, arg
, 24);
834 tcg_gen_andi_i32(t1
, arg
, 0x0000ff00);
835 tcg_gen_shli_i32(t1
, t1
, 8);
836 tcg_gen_or_i32(t0
, t0
, t1
);
838 tcg_gen_shri_i32(t1
, arg
, 8);
839 tcg_gen_andi_i32(t1
, t1
, 0x0000ff00);
840 tcg_gen_or_i32(t0
, t0
, t1
);
842 tcg_gen_shri_i32(t1
, arg
, 24);
843 tcg_gen_or_i32(ret
, t0
, t1
);
847 #if TCG_TARGET_REG_BITS == 32
848 static inline void tcg_gen_ext8s_i64(int ret
, int arg
)
850 tcg_gen_ext8s_i32(ret
, arg
);
851 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
854 static inline void tcg_gen_ext16s_i64(int ret
, int arg
)
856 tcg_gen_ext16s_i32(ret
, arg
);
857 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
860 static inline void tcg_gen_ext32s_i64(int ret
, int arg
)
862 tcg_gen_mov_i32(ret
, arg
);
863 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
866 static inline void tcg_gen_trunc_i64_i32(int ret
, int arg
)
868 tcg_gen_mov_i32(ret
, arg
);
871 static inline void tcg_gen_extu_i32_i64(int ret
, int arg
)
873 tcg_gen_mov_i32(ret
, arg
);
874 tcg_gen_movi_i32(ret
+ 1, 0);
877 static inline void tcg_gen_ext_i32_i64(int ret
, int arg
)
879 tcg_gen_mov_i32(ret
, arg
);
880 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
883 static inline void tcg_gen_bswap_i64(int ret
, int arg
)
886 t0
= tcg_temp_new(TCG_TYPE_I32
);
887 t1
= tcg_temp_new(TCG_TYPE_I32
);
889 tcg_gen_bswap_i32(t0
, arg
);
890 tcg_gen_bswap_i32(t1
, arg
+ 1);
891 tcg_gen_mov_i32(ret
, t1
);
892 tcg_gen_mov_i32(ret
+ 1, t0
);
896 static inline void tcg_gen_ext8s_i64(int ret
, int arg
)
898 #ifdef TCG_TARGET_HAS_ext8s_i64
899 tcg_gen_op2(INDEX_op_ext8s_i64
, ret
, arg
);
901 tcg_gen_shli_i64(ret
, arg
, 56);
902 tcg_gen_sari_i64(ret
, arg
, 56);
906 static inline void tcg_gen_ext16s_i64(int ret
, int arg
)
908 #ifdef TCG_TARGET_HAS_ext16s_i64
909 tcg_gen_op2(INDEX_op_ext16s_i64
, ret
, arg
);
911 tcg_gen_shli_i64(ret
, arg
, 48);
912 tcg_gen_sari_i64(ret
, arg
, 48);
916 static inline void tcg_gen_ext32s_i64(int ret
, int arg
)
918 #ifdef TCG_TARGET_HAS_ext32s_i64
919 tcg_gen_op2(INDEX_op_ext32s_i64
, ret
, arg
);
921 tcg_gen_shli_i64(ret
, arg
, 32);
922 tcg_gen_sari_i64(ret
, arg
, 32);
926 /* Note: we assume the target supports move between 32 and 64 bit
928 static inline void tcg_gen_trunc_i64_i32(int ret
, int arg
)
930 tcg_gen_mov_i32(ret
, arg
);
933 /* Note: we assume the target supports move between 32 and 64 bit
935 static inline void tcg_gen_extu_i32_i64(int ret
, int arg
)
937 tcg_gen_andi_i64(ret
, arg
, 0xffffffff);
940 /* Note: we assume the target supports move between 32 and 64 bit
942 static inline void tcg_gen_ext_i32_i64(int ret
, int arg
)
944 tcg_gen_ext32s_i64(ret
, arg
);
947 static inline void tcg_gen_bswap_i64(TCGArg ret
, TCGArg arg
)
949 #ifdef TCG_TARGET_HAS_bswap_i64
950 tcg_gen_op2(INDEX_op_bswap_i64
, ret
, arg
);
953 t0
= tcg_temp_new(TCG_TYPE_I32
);
954 t1
= tcg_temp_new(TCG_TYPE_I32
);
956 tcg_gen_shli_i64(t0
, arg
, 56);
958 tcg_gen_andi_i64(t1
, arg
, 0x0000ff00);
959 tcg_gen_shli_i64(t1
, t1
, 40);
960 tcg_gen_or_i64(t0
, t0
, t1
);
962 tcg_gen_andi_i64(t1
, arg
, 0x00ff0000);
963 tcg_gen_shli_i64(t1
, t1
, 24);
964 tcg_gen_or_i64(t0
, t0
, t1
);
966 tcg_gen_andi_i64(t1
, arg
, 0xff000000);
967 tcg_gen_shli_i64(t1
, t1
, 8);
968 tcg_gen_or_i64(t0
, t0
, t1
);
970 tcg_gen_shri_i64(t1
, arg
, 8);
971 tcg_gen_andi_i64(t1
, t1
, 0xff000000);
972 tcg_gen_or_i64(t0
, t0
, t1
);
974 tcg_gen_shri_i64(t1
, arg
, 24);
975 tcg_gen_andi_i64(t1
, t1
, 0x00ff0000);
976 tcg_gen_or_i64(t0
, t0
, t1
);
978 tcg_gen_shri_i64(t1
, arg
, 40);
979 tcg_gen_andi_i64(t1
, t1
, 0x0000ff00);
980 tcg_gen_or_i64(t0
, t0
, t1
);
982 tcg_gen_shri_i64(t1
, arg
, 56);
983 tcg_gen_or_i64(ret
, t0
, t1
);
989 /***************************************/
990 static inline void tcg_gen_macro_2(int ret0
, int ret1
, int macro_id
)
992 tcg_gen_op3(INDEX_op_macro_2
, ret0
, ret1
, macro_id
);
995 /***************************************/
996 /* QEMU specific operations. Their type depend on the QEMU CPU
998 #ifndef TARGET_LONG_BITS
999 #error must include QEMU headers
1002 static inline void tcg_gen_exit_tb(tcg_target_long val
)
1004 tcg_gen_op1(INDEX_op_exit_tb
, val
);
1007 static inline void tcg_gen_goto_tb(int idx
)
1009 tcg_gen_op1(INDEX_op_goto_tb
, idx
);
1012 #if TCG_TARGET_REG_BITS == 32
1013 static inline void tcg_gen_qemu_ld8u(int ret
, int addr
, int mem_index
)
1015 #if TARGET_LONG_BITS == 32
1016 tcg_gen_op3(INDEX_op_qemu_ld8u
, ret
, addr
, mem_index
);
1018 tcg_gen_op4(INDEX_op_qemu_ld8u
, ret
, addr
, addr
+ 1, mem_index
);
1019 tcg_gen_movi_i32(ret
+ 1, 0);
1023 static inline void tcg_gen_qemu_ld8s(int ret
, int addr
, int mem_index
)
1025 #if TARGET_LONG_BITS == 32
1026 tcg_gen_op3(INDEX_op_qemu_ld8s
, ret
, addr
, mem_index
);
1028 tcg_gen_op4(INDEX_op_qemu_ld8s
, ret
, addr
, addr
+ 1, mem_index
);
1029 tcg_gen_ext8s_i32(ret
+ 1, ret
);
1033 static inline void tcg_gen_qemu_ld16u(int ret
, int addr
, int mem_index
)
1035 #if TARGET_LONG_BITS == 32
1036 tcg_gen_op3(INDEX_op_qemu_ld16u
, ret
, addr
, mem_index
);
1038 tcg_gen_op4(INDEX_op_qemu_ld16u
, ret
, addr
, addr
+ 1, mem_index
);
1039 tcg_gen_movi_i32(ret
+ 1, 0);
1043 static inline void tcg_gen_qemu_ld16s(int ret
, int addr
, int mem_index
)
1045 #if TARGET_LONG_BITS == 32
1046 tcg_gen_op3(INDEX_op_qemu_ld16s
, ret
, addr
, mem_index
);
1048 tcg_gen_op4(INDEX_op_qemu_ld16s
, ret
, addr
, addr
+ 1, mem_index
);
1049 tcg_gen_ext16s_i32(ret
+ 1, ret
);
1053 static inline void tcg_gen_qemu_ld32u(int ret
, int addr
, int mem_index
)
1055 #if TARGET_LONG_BITS == 32
1056 tcg_gen_op3(INDEX_op_qemu_ld32u
, ret
, addr
, mem_index
);
1058 tcg_gen_op4(INDEX_op_qemu_ld32u
, ret
, addr
, addr
+ 1, mem_index
);
1059 tcg_gen_movi_i32(ret
+ 1, 0);
1063 static inline void tcg_gen_qemu_ld32s(int ret
, int addr
, int mem_index
)
1065 #if TARGET_LONG_BITS == 32
1066 tcg_gen_op3(INDEX_op_qemu_ld32u
, ret
, addr
, mem_index
);
1068 tcg_gen_op4(INDEX_op_qemu_ld32u
, ret
, addr
, addr
+ 1, mem_index
);
1069 tcg_gen_sari_i32(ret
+ 1, ret
, 31);
1073 static inline void tcg_gen_qemu_ld64(int ret
, int addr
, int mem_index
)
1075 #if TARGET_LONG_BITS == 32
1076 tcg_gen_op4(INDEX_op_qemu_ld64
, ret
, ret
+ 1, addr
, mem_index
);
1078 tcg_gen_op5(INDEX_op_qemu_ld64
, ret
, ret
+ 1, addr
, addr
+ 1, mem_index
);
1082 static inline void tcg_gen_qemu_st8(int arg
, int addr
, int mem_index
)
1084 #if TARGET_LONG_BITS == 32
1085 tcg_gen_op3(INDEX_op_qemu_st8
, arg
, addr
, mem_index
);
1087 tcg_gen_op4(INDEX_op_qemu_st8
, arg
, addr
, addr
+ 1, mem_index
);
1091 static inline void tcg_gen_qemu_st16(int arg
, int addr
, int mem_index
)
1093 #if TARGET_LONG_BITS == 32
1094 tcg_gen_op3(INDEX_op_qemu_st16
, arg
, addr
, mem_index
);
1096 tcg_gen_op4(INDEX_op_qemu_st16
, arg
, addr
, addr
+ 1, mem_index
);
1100 static inline void tcg_gen_qemu_st32(int arg
, int addr
, int mem_index
)
1102 #if TARGET_LONG_BITS == 32
1103 tcg_gen_op3(INDEX_op_qemu_st32
, arg
, addr
, mem_index
);
1105 tcg_gen_op4(INDEX_op_qemu_st32
, arg
, addr
, addr
+ 1, mem_index
);
1109 static inline void tcg_gen_qemu_st64(int arg
, int addr
, int mem_index
)
1111 #if TARGET_LONG_BITS == 32
1112 tcg_gen_op4(INDEX_op_qemu_st64
, arg
, arg
+ 1, addr
, mem_index
);
1114 tcg_gen_op5(INDEX_op_qemu_st64
, arg
, arg
+ 1, addr
, addr
+ 1, mem_index
);
1118 #else /* TCG_TARGET_REG_BITS == 32 */
1120 static inline void tcg_gen_qemu_ld8u(int ret
, int addr
, int mem_index
)
1122 tcg_gen_op3(INDEX_op_qemu_ld8u
, ret
, addr
, mem_index
);
1125 static inline void tcg_gen_qemu_ld8s(int ret
, int addr
, int mem_index
)
1127 tcg_gen_op3(INDEX_op_qemu_ld8s
, ret
, addr
, mem_index
);
1130 static inline void tcg_gen_qemu_ld16u(int ret
, int addr
, int mem_index
)
1132 tcg_gen_op3(INDEX_op_qemu_ld16u
, ret
, addr
, mem_index
);
1135 static inline void tcg_gen_qemu_ld16s(int ret
, int addr
, int mem_index
)
1137 tcg_gen_op3(INDEX_op_qemu_ld16s
, ret
, addr
, mem_index
);
1140 static inline void tcg_gen_qemu_ld32u(int ret
, int addr
, int mem_index
)
1142 tcg_gen_op3(INDEX_op_qemu_ld32u
, ret
, addr
, mem_index
);
1145 static inline void tcg_gen_qemu_ld32s(int ret
, int addr
, int mem_index
)
1147 tcg_gen_op3(INDEX_op_qemu_ld32s
, ret
, addr
, mem_index
);
1150 static inline void tcg_gen_qemu_ld64(int ret
, int addr
, int mem_index
)
1152 tcg_gen_op3(INDEX_op_qemu_ld64
, ret
, addr
, mem_index
);
1155 static inline void tcg_gen_qemu_st8(int arg
, int addr
, int mem_index
)
1157 tcg_gen_op3(INDEX_op_qemu_st8
, arg
, addr
, mem_index
);
1160 static inline void tcg_gen_qemu_st16(int arg
, int addr
, int mem_index
)
1162 tcg_gen_op3(INDEX_op_qemu_st16
, arg
, addr
, mem_index
);
1165 static inline void tcg_gen_qemu_st32(int arg
, int addr
, int mem_index
)
1167 tcg_gen_op3(INDEX_op_qemu_st32
, arg
, addr
, mem_index
);
1170 static inline void tcg_gen_qemu_st64(int arg
, int addr
, int mem_index
)
1172 tcg_gen_op3(INDEX_op_qemu_st64
, arg
, addr
, mem_index
);
1175 #endif /* TCG_TARGET_REG_BITS != 32 */