tcg-op.h revision 4af48bf7c72ef1e201c64bd475377b5af9d8e8a1
/*
* Tiny Code Generator for QEMU
*
* Copyright (c) 2008 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "tcg.h"
int gen_new_label(void);
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg1;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg2;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg2;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg1;
*gen_opparam_ptr++ = arg2;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg3;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg3;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = offset;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = offset;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = mem_index;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = mem_index;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg4;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg4;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg3;
*gen_opparam_ptr++ = arg4;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg3;
*gen_opparam_ptr++ = arg4;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg5;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg5;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg5;
*gen_opparam_ptr++ = arg6;
}
{
*gen_opc_ptr++ = opc;
*gen_opparam_ptr++ = arg5;
*gen_opparam_ptr++ = arg6;
}
static inline void gen_set_label(int n)
{
}
static inline void tcg_gen_br(int label)
{
}
{
}
{
}
/* helper calls */
{
}
/* FIXME: Should this be pure? */
{
args[0] = GET_TCGV_I64(a);
}
/* 32 bit ops */
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
{
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
tcg_gen_movi_i32(ret, 0);
} else if (arg2 == 0xffffffff) {
} else {
}
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0xffffffff) {
} else if (arg2 == 0) {
} else {
}
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
{
}
{
if (arg2 == 0) {
} else {
}
}
{
}
{
if (arg2 == 0) {
} else {
}
}
{
}
{
if (arg2 == 0) {
} else {
}
}
int label_index)
{
}
int label_index)
{
}
{
}
{
}
#ifdef TCG_TARGET_HAS_div_i32
{
}
{
}
{
}
{
}
#else
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i32();
tcg_gen_movi_i32(t0, 0);
}
{
t0 = tcg_temp_new_i32();
tcg_gen_movi_i32(t0, 0);
}
#endif
#if TCG_TARGET_REG_BITS == 32
{
}
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
/* since arg2 and ret have different types, they cannot be the
same temporary */
#ifdef TCG_TARGET_WORDS_BIGENDIAN
#else
#endif
}
{
}
{
}
{
}
{
#ifdef TCG_TARGET_WORDS_BIGENDIAN
#else
#endif
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
/* XXX: use generic code when basic block handling is OK or CPU
specific code (x86) */
{
}
{
}
{
}
{
}
{
}
{
}
int label_index)
{
}
{
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i32();
}
{
}
{
}
{
}
{
}
#else
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
if (arg2 == 0) {
} else {
}
}
{
}
{
if (arg2 == 0) {
} else {
}
}
{
}
{
if (arg2 == 0) {
} else {
}
}
int label_index)
{
}
{
}
#ifdef TCG_TARGET_HAS_div_i64
{
}
{
}
{
}
{
}
#else
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i64();
tcg_gen_movi_i64(t0, 0);
}
{
t0 = tcg_temp_new_i64();
tcg_gen_movi_i64(t0, 0);
}
#endif
#endif
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
{
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
int label_index)
{
}
{
}
/***************************************/
/* optional operations */
{
#ifdef TCG_TARGET_HAS_ext8s_i32
#else
#endif
}
{
#ifdef TCG_TARGET_HAS_ext16s_i32
#else
#endif
}
/* These are currently just for convenience.
We assume a target will recognise these automatically . */
{
}
{
}
/* Note: we assume the two high bytes are set to zero */
{
#ifdef TCG_TARGET_HAS_bswap16_i32
#else
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
#endif
}
{
#ifdef TCG_TARGET_HAS_bswap_i32
#else
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
#endif
}
#if TCG_TARGET_REG_BITS == 32
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
}
#else
{
#ifdef TCG_TARGET_HAS_ext8s_i64
#else
#endif
}
{
#ifdef TCG_TARGET_HAS_ext16s_i64
#else
#endif
}
{
#ifdef TCG_TARGET_HAS_ext32s_i64
#else
#endif
}
{
}
{
}
{
}
/* Note: we assume the target supports move between 32 and 64 bit
registers. This will probably break MIPS64 targets. */
{
}
/* Note: we assume the target supports move between 32 and 64 bit
registers */
{
}
/* Note: we assume the target supports move between 32 and 64 bit
registers */
{
}
{
#ifdef TCG_TARGET_HAS_bswap_i64
#else
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
#endif
}
#endif
{
#ifdef TCG_TARGET_HAS_neg_i32
#else
#endif
}
{
#ifdef TCG_TARGET_HAS_neg_i64
#else
#endif
}
{
}
{
}
{
}
#if TCG_TARGET_REG_BITS == 32
{
}
#else
{
}
#endif
{
#if TCG_TARGET_REG_BITS == 32
#else
/* This extension is only needed for type correctness.
We may be able to do better given target specific information. */
#endif
}
{
#if TCG_TARGET_REG_BITS == 32
#else
#endif
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
}
{
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
}
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
}
}
{
t0 = tcg_temp_new_i32();
t1 = tcg_temp_new_i32();
}
{
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
{
/* some cases can be optimized here */
if (arg2 == 0) {
} else {
}
}
/***************************************/
/* QEMU specific operations. Their type depend on the QEMU CPU
type. */
#ifndef TARGET_LONG_BITS
#endif
#if TARGET_LONG_BITS == 32
#define tcg_temp_new() tcg_temp_new_i32()
#define tcg_temp_local_new() tcg_temp_local_new_i32()
#define tcg_temp_free tcg_temp_free_i32
#define tcg_gen_qemu_ldst_op tcg_gen_op3i_i32
#define TCGV_UNUSED(x) TCGV_UNUSED_I32(x)
#else
#define tcg_temp_new() tcg_temp_new_i64()
#define tcg_temp_local_new() tcg_temp_local_new_i64()
#define tcg_temp_free tcg_temp_free_i64
#define tcg_gen_qemu_ldst_op tcg_gen_op3i_i64
#define TCGV_UNUSED(x) TCGV_UNUSED_I64(x)
#endif
/* debug info: write the PC of the corresponding QEMU CPU instruction */
{
/* XXX: must really use a 32 bit size for TCGArg in all cases */
#else
#endif
}
{
}
static inline void tcg_gen_goto_tb(int idx)
{
}
#if TCG_TARGET_REG_BITS == 32
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
{
#if TARGET_LONG_BITS == 32
#else
#endif
}
#define tcg_gen_ld_ptr tcg_gen_ld_i32
#else /* TCG_TARGET_REG_BITS == 32 */
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
#define tcg_gen_ld_ptr tcg_gen_ld_i64
#endif /* TCG_TARGET_REG_BITS != 32 */
#if TARGET_LONG_BITS == 64
#define TCG_TYPE_TL TCG_TYPE_I64
#define tcg_gen_movi_tl tcg_gen_movi_i64
#define tcg_gen_mov_tl tcg_gen_mov_i64
#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
#define tcg_gen_ld_tl tcg_gen_ld_i64
#define tcg_gen_st8_tl tcg_gen_st8_i64
#define tcg_gen_st16_tl tcg_gen_st16_i64
#define tcg_gen_st32_tl tcg_gen_st32_i64
#define tcg_gen_st_tl tcg_gen_st_i64
#define tcg_gen_add_tl tcg_gen_add_i64
#define tcg_gen_addi_tl tcg_gen_addi_i64
#define tcg_gen_sub_tl tcg_gen_sub_i64
#define tcg_gen_neg_tl tcg_gen_neg_i64
#define tcg_gen_subfi_tl tcg_gen_subfi_i64
#define tcg_gen_subi_tl tcg_gen_subi_i64
#define tcg_gen_and_tl tcg_gen_and_i64
#define tcg_gen_andi_tl tcg_gen_andi_i64
#define tcg_gen_or_tl tcg_gen_or_i64
#define tcg_gen_ori_tl tcg_gen_ori_i64
#define tcg_gen_xor_tl tcg_gen_xor_i64
#define tcg_gen_xori_tl tcg_gen_xori_i64
#define tcg_gen_not_tl tcg_gen_not_i64
#define tcg_gen_shl_tl tcg_gen_shl_i64
#define tcg_gen_shli_tl tcg_gen_shli_i64
#define tcg_gen_shr_tl tcg_gen_shr_i64
#define tcg_gen_shri_tl tcg_gen_shri_i64
#define tcg_gen_sar_tl tcg_gen_sar_i64
#define tcg_gen_sari_tl tcg_gen_sari_i64
#define tcg_gen_brcond_tl tcg_gen_brcond_i64
#define tcg_gen_mul_tl tcg_gen_mul_i64
#define tcg_gen_muli_tl tcg_gen_muli_i64
#define tcg_gen_trunc_i64_tl tcg_gen_mov_i64
#define tcg_gen_extu_tl_i64 tcg_gen_mov_i64
#define tcg_gen_ext_tl_i64 tcg_gen_mov_i64
#define tcg_gen_ext8u_tl tcg_gen_ext8u_i64
#define tcg_gen_ext8s_tl tcg_gen_ext8s_i64
#define tcg_gen_ext16u_tl tcg_gen_ext16u_i64
#define tcg_gen_ext16s_tl tcg_gen_ext16s_i64
#define tcg_gen_ext32u_tl tcg_gen_ext32u_i64
#define tcg_gen_ext32s_tl tcg_gen_ext32s_i64
#define tcg_gen_andc_tl tcg_gen_andc_i64
#define tcg_gen_eqv_tl tcg_gen_eqv_i64
#define tcg_gen_nand_tl tcg_gen_nand_i64
#define tcg_gen_nor_tl tcg_gen_nor_i64
#define tcg_gen_orc_tl tcg_gen_orc_i64
#define tcg_gen_rotl_tl tcg_gen_rotl_i64
#define tcg_gen_rotli_tl tcg_gen_rotli_i64
#define tcg_gen_rotr_tl tcg_gen_rotr_i64
#define tcg_gen_rotri_tl tcg_gen_rotri_i64
#define tcg_const_tl tcg_const_i64
#else
#define TCG_TYPE_TL TCG_TYPE_I32
#define tcg_gen_movi_tl tcg_gen_movi_i32
#define tcg_gen_mov_tl tcg_gen_mov_i32
#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
#define tcg_gen_ld32u_tl tcg_gen_ld_i32
#define tcg_gen_ld32s_tl tcg_gen_ld_i32
#define tcg_gen_ld_tl tcg_gen_ld_i32
#define tcg_gen_st8_tl tcg_gen_st8_i32
#define tcg_gen_st16_tl tcg_gen_st16_i32
#define tcg_gen_st32_tl tcg_gen_st_i32
#define tcg_gen_st_tl tcg_gen_st_i32
#define tcg_gen_add_tl tcg_gen_add_i32
#define tcg_gen_addi_tl tcg_gen_addi_i32
#define tcg_gen_sub_tl tcg_gen_sub_i32
#define tcg_gen_neg_tl tcg_gen_neg_i32
#define tcg_gen_subfi_tl tcg_gen_subfi_i32
#define tcg_gen_subi_tl tcg_gen_subi_i32
#define tcg_gen_and_tl tcg_gen_and_i32
#define tcg_gen_andi_tl tcg_gen_andi_i32
#define tcg_gen_or_tl tcg_gen_or_i32
#define tcg_gen_ori_tl tcg_gen_ori_i32
#define tcg_gen_xor_tl tcg_gen_xor_i32
#define tcg_gen_xori_tl tcg_gen_xori_i32
#define tcg_gen_not_tl tcg_gen_not_i32
#define tcg_gen_shl_tl tcg_gen_shl_i32
#define tcg_gen_shli_tl tcg_gen_shli_i32
#define tcg_gen_shr_tl tcg_gen_shr_i32
#define tcg_gen_shri_tl tcg_gen_shri_i32
#define tcg_gen_sar_tl tcg_gen_sar_i32
#define tcg_gen_sari_tl tcg_gen_sari_i32
#define tcg_gen_brcond_tl tcg_gen_brcond_i32
#define tcg_gen_mul_tl tcg_gen_mul_i32
#define tcg_gen_muli_tl tcg_gen_muli_i32
#define tcg_gen_trunc_tl_i32 tcg_gen_mov_i32
#define tcg_gen_extu_i32_tl tcg_gen_mov_i32
#define tcg_gen_ext_i32_tl tcg_gen_mov_i32
#define tcg_gen_ext8u_tl tcg_gen_ext8u_i32
#define tcg_gen_ext8s_tl tcg_gen_ext8s_i32
#define tcg_gen_ext16u_tl tcg_gen_ext16u_i32
#define tcg_gen_ext16s_tl tcg_gen_ext16s_i32
#define tcg_gen_ext32u_tl tcg_gen_mov_i32
#define tcg_gen_ext32s_tl tcg_gen_mov_i32
#define tcg_gen_andc_tl tcg_gen_andc_i32
#define tcg_gen_eqv_tl tcg_gen_eqv_i32
#define tcg_gen_nand_tl tcg_gen_nand_i32
#define tcg_gen_nor_tl tcg_gen_nor_i32
#define tcg_gen_orc_tl tcg_gen_orc_i32
#define tcg_gen_rotl_tl tcg_gen_rotl_i32
#define tcg_gen_rotli_tl tcg_gen_rotli_i32
#define tcg_gen_rotr_tl tcg_gen_rotr_i32
#define tcg_gen_rotri_tl tcg_gen_rotri_i32
#define tcg_const_tl tcg_const_i32
#endif
#if TCG_TARGET_REG_BITS == 32
#define tcg_gen_add_ptr tcg_gen_add_i32
#define tcg_gen_addi_ptr tcg_gen_addi_i32
#define tcg_gen_ext_i32_ptr tcg_gen_mov_i32
#else /* TCG_TARGET_REG_BITS == 32 */
#define tcg_gen_add_ptr tcg_gen_add_i64
#define tcg_gen_addi_ptr tcg_gen_addi_i64
#endif /* TCG_TARGET_REG_BITS != 32 */