mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
tcg: Remove INDEX_op_ext{8,16,32}*
Use the fully general extract opcodes instead. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
2225fa242c
commit
48e8de684a
27 changed files with 135 additions and 823 deletions
|
@ -396,20 +396,6 @@ Misc
|
|||
- | *t0* = *t1*
|
||||
| Move *t1* to *t0* (both operands must have the same type).
|
||||
|
||||
* - ext8s_i32/i64 *t0*, *t1*
|
||||
|
||||
ext8u_i32/i64 *t0*, *t1*
|
||||
|
||||
ext16s_i32/i64 *t0*, *t1*
|
||||
|
||||
ext16u_i32/i64 *t0*, *t1*
|
||||
|
||||
ext32s_i64 *t0*, *t1*
|
||||
|
||||
ext32u_i64 *t0*, *t1*
|
||||
|
||||
- | 8, 16 or 32 bit sign/zero extension (both operands must have the same type)
|
||||
|
||||
* - bswap16_i32/i64 *t0*, *t1*, *flags*
|
||||
|
||||
- | 16 bit byte swap on the low bits of a 32/64 bit input.
|
||||
|
|
|
@ -85,10 +85,6 @@ DEF(mulsh_i32, 1, 2, 0, 0)
|
|||
DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
|
||||
DEF(setcond2_i32, 1, 4, 1, 0)
|
||||
|
||||
DEF(ext8s_i32, 1, 1, 0, 0)
|
||||
DEF(ext16s_i32, 1, 1, 0, 0)
|
||||
DEF(ext8u_i32, 1, 1, 0, 0)
|
||||
DEF(ext16u_i32, 1, 1, 0, 0)
|
||||
DEF(bswap16_i32, 1, 1, 1, 0)
|
||||
DEF(bswap32_i32, 1, 1, 1, 0)
|
||||
DEF(not_i32, 1, 1, 0, 0)
|
||||
|
@ -149,12 +145,6 @@ DEF(extrl_i64_i32, 1, 1, 0, 0)
|
|||
DEF(extrh_i64_i32, 1, 1, 0, 0)
|
||||
|
||||
DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
|
||||
DEF(ext8s_i64, 1, 1, 0, 0)
|
||||
DEF(ext16s_i64, 1, 1, 0, 0)
|
||||
DEF(ext32s_i64, 1, 1, 0, 0)
|
||||
DEF(ext8u_i64, 1, 1, 0, 0)
|
||||
DEF(ext16u_i64, 1, 1, 0, 0)
|
||||
DEF(ext32u_i64, 1, 1, 0, 0)
|
||||
DEF(bswap16_i64, 1, 1, 1, 0)
|
||||
DEF(bswap32_i64, 1, 1, 1, 0)
|
||||
DEF(bswap64_i64, 1, 1, 1, 0)
|
||||
|
|
|
@ -15,10 +15,6 @@
|
|||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_div_i32 1
|
||||
#define TCG_TARGET_HAS_rem_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -44,12 +40,6 @@
|
|||
|
||||
#define TCG_TARGET_HAS_div_i64 1
|
||||
#define TCG_TARGET_HAS_rem_i64 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
|
|
|
@ -2493,17 +2493,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType ext,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -2979,16 +2969,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_bswap16_i64:
|
||||
case INDEX_op_bswap32_i64:
|
||||
case INDEX_op_bswap64_i64:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extract_i32:
|
||||
|
|
|
@ -24,10 +24,6 @@ extern bool use_neon_instructions;
|
|||
#endif
|
||||
|
||||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 0 /* and r0, r1, #0xff */
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
|
|
@ -2113,10 +2113,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16u_i32:
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
@ -2138,9 +2134,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_not_i32:
|
||||
case INDEX_op_bswap16_i32:
|
||||
case INDEX_op_bswap32_i32:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_extract_i32:
|
||||
case INDEX_op_sextract_i32:
|
||||
return C_O1_I1(r, r);
|
||||
|
|
|
@ -28,10 +28,6 @@
|
|||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_div2_i32 1
|
||||
#define TCG_TARGET_HAS_rot_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -57,12 +53,6 @@
|
|||
#define TCG_TARGET_HAS_extr_i64_i32 1
|
||||
#define TCG_TARGET_HAS_div2_i64 1
|
||||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
|
|
|
@ -3016,17 +3016,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -3663,18 +3653,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_extrh_i64_i32:
|
||||
return C_O1_I1(r, 0);
|
||||
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
return C_O1_I1(r, q);
|
||||
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
#define TCG_TARGET_HAS_muls2_i32 0
|
||||
#define TCG_TARGET_HAS_muluh_i32 1
|
||||
#define TCG_TARGET_HAS_mulsh_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -47,12 +43,6 @@
|
|||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
#define TCG_TARGET_HAS_extract2_i64 0
|
||||
#define TCG_TARGET_HAS_extr_i64_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
|
|
|
@ -1707,17 +1707,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -2243,16 +2233,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_brcond_i64:
|
||||
return C_O0_I2(rz, rz);
|
||||
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
|
|
|
@ -80,8 +80,6 @@ extern bool use_mips32r2_instructions;
|
|||
|
||||
/* optional instructions detected at runtime */
|
||||
#define TCG_TARGET_HAS_extract2_i32 0
|
||||
#define TCG_TARGET_HAS_ext8s_i32 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_clz_i32 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_ctz_i32 0
|
||||
|
@ -93,23 +91,12 @@ extern bool use_mips32r2_instructions;
|
|||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
#define TCG_TARGET_HAS_extract2_i64 0
|
||||
#define TCG_TARGET_HAS_ext8s_i64 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_ext16s_i64 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_rot_i64 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_clz_i64 use_mips32r2_instructions
|
||||
#define TCG_TARGET_HAS_ctz_i64 0
|
||||
#define TCG_TARGET_HAS_ctpop_i64 0
|
||||
#endif
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
|
||||
#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */
|
||||
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
#define TCG_TARGET_HAS_ext8u_i64 0 /* andi rt, rs, 0xff */
|
||||
#define TCG_TARGET_HAS_ext16u_i64 0 /* andi rt, rs, 0xffff */
|
||||
#endif
|
||||
|
||||
#define TCG_TARGET_HAS_qemu_ldst_i128 0
|
||||
#define TCG_TARGET_HAS_tst 0
|
||||
|
||||
|
|
|
@ -647,7 +647,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
|
|||
|
||||
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32);
|
||||
tcg_debug_assert(use_mips32r2_instructions);
|
||||
tcg_out_opc_reg(s, OPC_SEB, rd, TCG_REG_ZERO, rs);
|
||||
}
|
||||
|
||||
|
@ -658,7 +658,7 @@ static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
|
|||
|
||||
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32);
|
||||
tcg_debug_assert(use_mips32r2_instructions);
|
||||
tcg_out_opc_reg(s, OPC_SEH, rd, TCG_REG_ZERO, rs);
|
||||
}
|
||||
|
||||
|
@ -2106,15 +2106,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -2138,8 +2130,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_not_i32:
|
||||
case INDEX_op_bswap16_i32:
|
||||
case INDEX_op_bswap32_i32:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_extract_i32:
|
||||
case INDEX_op_sextract_i32:
|
||||
case INDEX_op_ld8u_i64:
|
||||
|
@ -2154,10 +2144,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_bswap16_i64:
|
||||
case INDEX_op_bswap32_i64:
|
||||
case INDEX_op_bswap64_i64:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
|
|
|
@ -513,18 +513,6 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y)
|
|||
case INDEX_op_ctpop_i64:
|
||||
return ctpop64(x);
|
||||
|
||||
CASE_OP_32_64(ext8s):
|
||||
return (int8_t)x;
|
||||
|
||||
CASE_OP_32_64(ext16s):
|
||||
return (int16_t)x;
|
||||
|
||||
CASE_OP_32_64(ext8u):
|
||||
return (uint8_t)x;
|
||||
|
||||
CASE_OP_32_64(ext16u):
|
||||
return (uint16_t)x;
|
||||
|
||||
CASE_OP_32_64(bswap16):
|
||||
x = bswap16(x);
|
||||
return y & TCG_BSWAP_OS ? (int16_t)x : x;
|
||||
|
@ -537,12 +525,10 @@ static uint64_t do_constant_folding_2(TCGOpcode op, uint64_t x, uint64_t y)
|
|||
return bswap64(x);
|
||||
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
return (int32_t)x;
|
||||
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_ext32u_i64:
|
||||
return (uint32_t)x;
|
||||
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
|
@ -1869,8 +1855,7 @@ static bool fold_extract2(OptContext *ctx, TCGOp *op)
|
|||
|
||||
static bool fold_exts(OptContext *ctx, TCGOp *op)
|
||||
{
|
||||
uint64_t s_mask_old, s_mask, z_mask;
|
||||
bool type_change = false;
|
||||
uint64_t s_mask, z_mask;
|
||||
TempOptInfo *t1;
|
||||
|
||||
if (fold_const1(ctx, op)) {
|
||||
|
@ -1880,72 +1865,38 @@ static bool fold_exts(OptContext *ctx, TCGOp *op)
|
|||
t1 = arg_info(op->args[1]);
|
||||
z_mask = t1->z_mask;
|
||||
s_mask = t1->s_mask;
|
||||
s_mask_old = s_mask;
|
||||
|
||||
switch (op->opc) {
|
||||
CASE_OP_32_64(ext8s):
|
||||
s_mask |= INT8_MIN;
|
||||
z_mask = (int8_t)z_mask;
|
||||
break;
|
||||
CASE_OP_32_64(ext16s):
|
||||
s_mask |= INT16_MIN;
|
||||
z_mask = (int16_t)z_mask;
|
||||
break;
|
||||
case INDEX_op_ext_i32_i64:
|
||||
type_change = true;
|
||||
QEMU_FALLTHROUGH;
|
||||
case INDEX_op_ext32s_i64:
|
||||
s_mask |= INT32_MIN;
|
||||
z_mask = (int32_t)z_mask;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (!type_change && fold_affected_mask(ctx, op, s_mask & ~s_mask_old)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return fold_masks_zs(ctx, op, z_mask, s_mask);
|
||||
}
|
||||
|
||||
static bool fold_extu(OptContext *ctx, TCGOp *op)
|
||||
{
|
||||
uint64_t z_mask_old, z_mask;
|
||||
bool type_change = false;
|
||||
uint64_t z_mask;
|
||||
|
||||
if (fold_const1(ctx, op)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
z_mask_old = z_mask = arg_info(op->args[1])->z_mask;
|
||||
|
||||
z_mask = arg_info(op->args[1])->z_mask;
|
||||
switch (op->opc) {
|
||||
CASE_OP_32_64(ext8u):
|
||||
z_mask = (uint8_t)z_mask;
|
||||
break;
|
||||
CASE_OP_32_64(ext16u):
|
||||
z_mask = (uint16_t)z_mask;
|
||||
break;
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
type_change = true;
|
||||
QEMU_FALLTHROUGH;
|
||||
case INDEX_op_ext32u_i64:
|
||||
z_mask = (uint32_t)z_mask;
|
||||
break;
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
type_change = true;
|
||||
z_mask >>= 32;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if (!type_change && fold_affected_mask(ctx, op, z_mask_old ^ z_mask)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return fold_masks_z(ctx, op, z_mask);
|
||||
}
|
||||
|
||||
|
@ -2948,15 +2899,9 @@ void tcg_optimize(TCGContext *s)
|
|||
CASE_OP_32_64(extract2):
|
||||
done = fold_extract2(&ctx, op);
|
||||
break;
|
||||
CASE_OP_32_64(ext8s):
|
||||
CASE_OP_32_64(ext16s):
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
done = fold_exts(&ctx, op);
|
||||
break;
|
||||
CASE_OP_32_64(ext8u):
|
||||
CASE_OP_32_64(ext16u):
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
|
|
|
@ -16,16 +16,10 @@
|
|||
#define have_altivec (cpuinfo & CPUINFO_ALTIVEC)
|
||||
#define have_vsx (cpuinfo & CPUINFO_VSX)
|
||||
|
||||
/* optional instructions automatically implemented */
|
||||
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi */
|
||||
#define TCG_TARGET_HAS_ext16u_i32 0
|
||||
|
||||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_div_i32 1
|
||||
#define TCG_TARGET_HAS_rem_i32 have_isa_3_00
|
||||
#define TCG_TARGET_HAS_rot_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -52,12 +46,6 @@
|
|||
#define TCG_TARGET_HAS_div_i64 1
|
||||
#define TCG_TARGET_HAS_rem_i64 have_isa_3_00
|
||||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 0
|
||||
#define TCG_TARGET_HAS_ext16u_i64 0
|
||||
#define TCG_TARGET_HAS_ext32u_i64 0
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
|
|
|
@ -3473,17 +3473,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -4109,8 +4099,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_ctpop_i32:
|
||||
case INDEX_op_neg_i32:
|
||||
case INDEX_op_not_i32:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_bswap16_i32:
|
||||
case INDEX_op_bswap32_i32:
|
||||
case INDEX_op_extract_i32:
|
||||
|
@ -4125,9 +4113,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_ctpop_i64:
|
||||
case INDEX_op_neg_i64:
|
||||
case INDEX_op_not_i64:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_bswap16_i64:
|
||||
|
|
|
@ -22,10 +22,6 @@
|
|||
#define TCG_TARGET_HAS_muls2_i32 0
|
||||
#define TCG_TARGET_HAS_muluh_i32 0
|
||||
#define TCG_TARGET_HAS_mulsh_i32 0
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 (cpuinfo & CPUINFO_ZBB)
|
||||
#define TCG_TARGET_HAS_bswap32_i32 (cpuinfo & CPUINFO_ZBB)
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -46,12 +42,6 @@
|
|||
#define TCG_TARGET_HAS_rot_i64 (cpuinfo & CPUINFO_ZBB)
|
||||
#define TCG_TARGET_HAS_extract2_i64 0
|
||||
#define TCG_TARGET_HAS_extr_i64_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 (cpuinfo & CPUINFO_ZBB)
|
||||
#define TCG_TARGET_HAS_bswap32_i64 (cpuinfo & CPUINFO_ZBB)
|
||||
#define TCG_TARGET_HAS_bswap64_i64 (cpuinfo & CPUINFO_ZBB)
|
||||
|
|
|
@ -2385,17 +2385,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -2643,17 +2633,7 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_ld_i64:
|
||||
case INDEX_op_not_i64:
|
||||
case INDEX_op_neg_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
|
|
|
@ -31,10 +31,6 @@ extern uint64_t s390_facilities[3];
|
|||
/* optional instructions */
|
||||
#define TCG_TARGET_HAS_div2_i32 1
|
||||
#define TCG_TARGET_HAS_rot_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_bswap16_i32 1
|
||||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_not_i32 HAVE_FACILITY(MISC_INSN_EXT3)
|
||||
|
@ -59,12 +55,6 @@ extern uint64_t s390_facilities[3];
|
|||
|
||||
#define TCG_TARGET_HAS_div2_i64 1
|
||||
#define TCG_TARGET_HAS_rot_i64 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 1
|
||||
#define TCG_TARGET_HAS_bswap32_i64 1
|
||||
#define TCG_TARGET_HAS_bswap64_i64 1
|
||||
|
|
|
@ -2781,17 +2781,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
@ -3340,16 +3330,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_neg_i64:
|
||||
case INDEX_op_not_i32:
|
||||
case INDEX_op_not_i64:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extract_i32:
|
||||
|
|
|
@ -17,10 +17,6 @@ extern bool use_vis3_instructions;
|
|||
#define TCG_TARGET_HAS_div_i32 1
|
||||
#define TCG_TARGET_HAS_rem_i32 0
|
||||
#define TCG_TARGET_HAS_rot_i32 0
|
||||
#define TCG_TARGET_HAS_ext8s_i32 0
|
||||
#define TCG_TARGET_HAS_ext16s_i32 0
|
||||
#define TCG_TARGET_HAS_ext8u_i32 0
|
||||
#define TCG_TARGET_HAS_ext16u_i32 0
|
||||
#define TCG_TARGET_HAS_bswap16_i32 0
|
||||
#define TCG_TARGET_HAS_bswap32_i32 0
|
||||
#define TCG_TARGET_HAS_not_i32 1
|
||||
|
@ -46,12 +42,6 @@ extern bool use_vis3_instructions;
|
|||
#define TCG_TARGET_HAS_div_i64 1
|
||||
#define TCG_TARGET_HAS_rem_i64 0
|
||||
#define TCG_TARGET_HAS_rot_i64 0
|
||||
#define TCG_TARGET_HAS_ext8s_i64 0
|
||||
#define TCG_TARGET_HAS_ext16s_i64 0
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 0
|
||||
#define TCG_TARGET_HAS_ext16u_i64 0
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_bswap16_i64 0
|
||||
#define TCG_TARGET_HAS_bswap32_i64 0
|
||||
#define TCG_TARGET_HAS_bswap64_i64 0
|
||||
|
|
|
@ -1517,17 +1517,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
|
@ -1557,8 +1547,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_neg_i64:
|
||||
case INDEX_op_not_i32:
|
||||
case INDEX_op_not_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extract_i64:
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
#define TCG_TARGET_HAS_rem_i64 0
|
||||
#define TCG_TARGET_HAS_div2_i64 0
|
||||
#define TCG_TARGET_HAS_rot_i64 0
|
||||
#define TCG_TARGET_HAS_ext8s_i64 0
|
||||
#define TCG_TARGET_HAS_ext16s_i64 0
|
||||
#define TCG_TARGET_HAS_ext32s_i64 0
|
||||
#define TCG_TARGET_HAS_ext8u_i64 0
|
||||
#define TCG_TARGET_HAS_ext16u_i64 0
|
||||
#define TCG_TARGET_HAS_ext32u_i64 0
|
||||
#define TCG_TARGET_HAS_bswap16_i64 0
|
||||
#define TCG_TARGET_HAS_bswap32_i64 0
|
||||
#define TCG_TARGET_HAS_bswap64_i64 0
|
||||
|
|
366
tcg/tcg-op.c
366
tcg/tcg-op.c
|
@ -414,17 +414,19 @@ void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
|
|||
case -1:
|
||||
tcg_gen_mov_i32(ret, arg1);
|
||||
return;
|
||||
case 0xff:
|
||||
/* Don't recurse with tcg_gen_ext8u_i32. */
|
||||
if (TCG_TARGET_HAS_ext8u_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
|
||||
default:
|
||||
/*
|
||||
* Canonicalize on extract, if valid. This aids x86 with its
|
||||
* 2 operand MOVZBL and 2 operand AND, selecting the TCGOpcode
|
||||
* which does not require matching operands. Other backends can
|
||||
* trivially expand the extract to AND during code generation.
|
||||
*/
|
||||
if (!(arg2 & (arg2 + 1))) {
|
||||
unsigned len = ctz32(~arg2);
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, len)) {
|
||||
tcg_gen_extract_i32(ret, arg1, 0, len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xffff:
|
||||
if (TCG_TARGET_HAS_ext16u_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -955,41 +957,21 @@ void tcg_gen_deposit_z_i32(TCGv_i32 ret, TCGv_i32 arg,
|
|||
TCGv_i32 zero = tcg_constant_i32(0);
|
||||
tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, zero, arg, ofs, len);
|
||||
} else {
|
||||
/* To help two-operand hosts we prefer to zero-extend first,
|
||||
which allows ARG to stay live. */
|
||||
switch (len) {
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i32) {
|
||||
tcg_gen_ext16u_i32(ret, arg);
|
||||
/*
|
||||
* To help two-operand hosts we prefer to zero-extend first,
|
||||
* which allows ARG to stay live.
|
||||
*/
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, len)) {
|
||||
tcg_gen_extract_i32(ret, arg, 0, len);
|
||||
tcg_gen_shli_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i32) {
|
||||
tcg_gen_ext8u_i32(ret, arg);
|
||||
tcg_gen_shli_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Otherwise prefer zero-extension over AND for code size. */
|
||||
switch (ofs + len) {
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i32) {
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, ofs + len)) {
|
||||
tcg_gen_shli_i32(ret, arg, ofs);
|
||||
tcg_gen_ext16u_i32(ret, ret);
|
||||
tcg_gen_extract_i32(ret, ret, 0, ofs + len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i32) {
|
||||
tcg_gen_shli_i32(ret, arg, ofs);
|
||||
tcg_gen_ext8u_i32(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
|
||||
tcg_gen_shli_i32(ret, ret, ofs);
|
||||
}
|
||||
|
@ -1008,33 +990,22 @@ void tcg_gen_extract_i32(TCGv_i32 ret, TCGv_i32 arg,
|
|||
tcg_gen_shri_i32(ret, arg, 32 - len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, ofs, len)) {
|
||||
tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, ofs, len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
tcg_gen_andi_i32(ret, arg, (1u << len) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Assume that zero-extension, if available, is cheaper than a shift. */
|
||||
switch (ofs + len) {
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i32) {
|
||||
tcg_gen_ext16u_i32(ret, arg);
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I32, 0, ofs + len)) {
|
||||
tcg_gen_op4ii_i32(INDEX_op_extract_i32, ret, arg, 0, ofs + len);
|
||||
tcg_gen_shri_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i32) {
|
||||
tcg_gen_ext8u_i32(ret, arg);
|
||||
tcg_gen_shri_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ??? Ideally we'd know what values are available for immediate AND.
|
||||
Assume that 8 bits are available, plus the special case of 16,
|
||||
|
@ -1064,16 +1035,6 @@ void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
|
|||
tcg_gen_sari_i32(ret, arg, 32 - len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
switch (len) {
|
||||
case 16:
|
||||
tcg_gen_ext16s_i32(ret, arg);
|
||||
return;
|
||||
case 8:
|
||||
tcg_gen_ext8s_i32(ret, arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, ofs, len)) {
|
||||
tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, ofs, len);
|
||||
|
@ -1081,38 +1042,16 @@ void tcg_gen_sextract_i32(TCGv_i32 ret, TCGv_i32 arg,
|
|||
}
|
||||
|
||||
/* Assume that sign-extension, if available, is cheaper than a shift. */
|
||||
switch (ofs + len) {
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16s_i32) {
|
||||
tcg_gen_ext16s_i32(ret, arg);
|
||||
if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, 0, ofs + len)) {
|
||||
tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, arg, 0, ofs + len);
|
||||
tcg_gen_sari_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8s_i32) {
|
||||
tcg_gen_ext8s_i32(ret, arg);
|
||||
tcg_gen_sari_i32(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (len) {
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16s_i32) {
|
||||
if (TCG_TARGET_sextract_valid(TCG_TYPE_I32, 0, len)) {
|
||||
tcg_gen_shri_i32(ret, arg, ofs);
|
||||
tcg_gen_ext16s_i32(ret, ret);
|
||||
tcg_gen_op4ii_i32(INDEX_op_sextract_i32, ret, ret, 0, len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8s_i32) {
|
||||
tcg_gen_shri_i32(ret, arg, ofs);
|
||||
tcg_gen_ext8s_i32(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tcg_gen_shli_i32(ret, arg, 32 - len - ofs);
|
||||
tcg_gen_sari_i32(ret, ret, 32 - len);
|
||||
|
@ -1281,40 +1220,22 @@ void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2)
|
|||
|
||||
void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
|
||||
{
|
||||
if (TCG_TARGET_HAS_ext8s_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
|
||||
} else {
|
||||
tcg_gen_shli_i32(ret, arg, 24);
|
||||
tcg_gen_sari_i32(ret, ret, 24);
|
||||
}
|
||||
tcg_gen_sextract_i32(ret, arg, 0, 8);
|
||||
}
|
||||
|
||||
void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
|
||||
{
|
||||
if (TCG_TARGET_HAS_ext16s_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
|
||||
} else {
|
||||
tcg_gen_shli_i32(ret, arg, 16);
|
||||
tcg_gen_sari_i32(ret, ret, 16);
|
||||
}
|
||||
tcg_gen_sextract_i32(ret, arg, 0, 16);
|
||||
}
|
||||
|
||||
void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
|
||||
{
|
||||
if (TCG_TARGET_HAS_ext8u_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
|
||||
} else {
|
||||
tcg_gen_andi_i32(ret, arg, 0xffu);
|
||||
}
|
||||
tcg_gen_extract_i32(ret, arg, 0, 8);
|
||||
}
|
||||
|
||||
void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
|
||||
{
|
||||
if (TCG_TARGET_HAS_ext16u_i32) {
|
||||
tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
|
||||
} else {
|
||||
tcg_gen_andi_i32(ret, arg, 0xffffu);
|
||||
}
|
||||
tcg_gen_extract_i32(ret, arg, 0, 16);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1794,23 +1715,19 @@ void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
|
|||
case -1:
|
||||
tcg_gen_mov_i64(ret, arg1);
|
||||
return;
|
||||
case 0xff:
|
||||
/* Don't recurse with tcg_gen_ext8u_i64. */
|
||||
if (TCG_TARGET_HAS_ext8u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
|
||||
default:
|
||||
/*
|
||||
* Canonicalize on extract, if valid. This aids x86 with its
|
||||
* 2 operand MOVZBL and 2 operand AND, selecting the TCGOpcode
|
||||
* which does not require matching operands. Other backends can
|
||||
* trivially expand the extract to AND during code generation.
|
||||
*/
|
||||
if (!(arg2 & (arg2 + 1))) {
|
||||
unsigned len = ctz64(~arg2);
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len)) {
|
||||
tcg_gen_extract_i64(ret, arg1, 0, len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xffff:
|
||||
if (TCG_TARGET_HAS_ext16u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0xffffffffu:
|
||||
if (TCG_TARGET_HAS_ext32u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2118,77 +2035,32 @@ void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
|
|||
|
||||
void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_ext8s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
|
||||
} else if (TCG_TARGET_HAS_ext8s_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_shli_i64(ret, arg, 56);
|
||||
tcg_gen_sari_i64(ret, ret, 56);
|
||||
}
|
||||
tcg_gen_sextract_i64(ret, arg, 0, 8);
|
||||
}
|
||||
|
||||
void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_ext16s_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
|
||||
} else if (TCG_TARGET_HAS_ext16s_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_shli_i64(ret, arg, 48);
|
||||
tcg_gen_sari_i64(ret, ret, 48);
|
||||
}
|
||||
tcg_gen_sextract_i64(ret, arg, 0, 16);
|
||||
}
|
||||
|
||||
void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31);
|
||||
} else if (TCG_TARGET_HAS_ext32s_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_shli_i64(ret, arg, 32);
|
||||
tcg_gen_sari_i64(ret, ret, 32);
|
||||
}
|
||||
tcg_gen_sextract_i64(ret, arg, 0, 32);
|
||||
}
|
||||
|
||||
void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_ext8u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
|
||||
} else if (TCG_TARGET_HAS_ext8u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_andi_i64(ret, arg, 0xffu);
|
||||
}
|
||||
tcg_gen_extract_i64(ret, arg, 0, 8);
|
||||
}
|
||||
|
||||
void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_ext16u_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
|
||||
} else if (TCG_TARGET_HAS_ext16u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_andi_i64(ret, arg, 0xffffu);
|
||||
}
|
||||
tcg_gen_extract_i64(ret, arg, 0, 16);
|
||||
}
|
||||
|
||||
void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
tcg_gen_mov_i32(TCGV_LOW(ret), TCGV_LOW(arg));
|
||||
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
|
||||
} else if (TCG_TARGET_HAS_ext32u_i64) {
|
||||
tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
|
||||
} else {
|
||||
tcg_gen_andi_i64(ret, arg, 0xffffffffu);
|
||||
}
|
||||
tcg_gen_extract_i64(ret, arg, 0, 32);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2720,55 +2592,21 @@ void tcg_gen_deposit_z_i64(TCGv_i64 ret, TCGv_i64 arg,
|
|||
return;
|
||||
}
|
||||
}
|
||||
/* To help two-operand hosts we prefer to zero-extend first,
|
||||
which allows ARG to stay live. */
|
||||
switch (len) {
|
||||
case 32:
|
||||
if (TCG_TARGET_HAS_ext32u_i64) {
|
||||
tcg_gen_ext32u_i64(ret, arg);
|
||||
/*
|
||||
* To help two-operand hosts we prefer to zero-extend first,
|
||||
* which allows ARG to stay live.
|
||||
*/
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, len)) {
|
||||
tcg_gen_extract_i64(ret, arg, 0, len);
|
||||
tcg_gen_shli_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i64) {
|
||||
tcg_gen_ext16u_i64(ret, arg);
|
||||
tcg_gen_shli_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i64) {
|
||||
tcg_gen_ext8u_i64(ret, arg);
|
||||
tcg_gen_shli_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Otherwise prefer zero-extension over AND for code size. */
|
||||
switch (ofs + len) {
|
||||
case 32:
|
||||
if (TCG_TARGET_HAS_ext32u_i64) {
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, ofs + len)) {
|
||||
tcg_gen_shli_i64(ret, arg, ofs);
|
||||
tcg_gen_ext32u_i64(ret, ret);
|
||||
tcg_gen_extract_i64(ret, ret, 0, ofs + len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i64) {
|
||||
tcg_gen_shli_i64(ret, arg, ofs);
|
||||
tcg_gen_ext16u_i64(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i64) {
|
||||
tcg_gen_shli_i64(ret, arg, ofs);
|
||||
tcg_gen_ext8u_i64(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
|
||||
tcg_gen_shli_i64(ret, ret, ofs);
|
||||
}
|
||||
|
@ -2787,10 +2625,6 @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
|
|||
tcg_gen_shri_i64(ret, arg, 64 - len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
/* Look for a 32-bit extract within one of the two words. */
|
||||
|
@ -2822,31 +2656,17 @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
|
|||
tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, ofs, len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
tcg_gen_andi_i64(ret, arg, (1ull << len) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Assume that zero-extension, if available, is cheaper than a shift. */
|
||||
switch (ofs + len) {
|
||||
case 32:
|
||||
if (TCG_TARGET_HAS_ext32u_i64) {
|
||||
tcg_gen_ext32u_i64(ret, arg);
|
||||
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, 0, ofs + len)) {
|
||||
tcg_gen_op4ii_i64(INDEX_op_extract_i64, ret, arg, 0, ofs + len);
|
||||
tcg_gen_shri_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16u_i64) {
|
||||
tcg_gen_ext16u_i64(ret, arg);
|
||||
tcg_gen_shri_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8u_i64) {
|
||||
tcg_gen_ext8u_i64(ret, arg);
|
||||
tcg_gen_shri_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* ??? Ideally we'd know what values are available for immediate AND.
|
||||
Assume that 8 bits are available, plus the special cases of 16 and 32,
|
||||
|
@ -2876,19 +2696,6 @@ void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
|
|||
tcg_gen_sari_i64(ret, arg, 64 - len);
|
||||
return;
|
||||
}
|
||||
if (ofs == 0) {
|
||||
switch (len) {
|
||||
case 32:
|
||||
tcg_gen_ext32s_i64(ret, arg);
|
||||
return;
|
||||
case 16:
|
||||
tcg_gen_ext16s_i64(ret, arg);
|
||||
return;
|
||||
case 8:
|
||||
tcg_gen_ext8s_i64(ret, arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (TCG_TARGET_REG_BITS == 32) {
|
||||
/* Look for a 32-bit extract within one of the two words. */
|
||||
|
@ -2928,52 +2735,17 @@ void tcg_gen_sextract_i64(TCGv_i64 ret, TCGv_i64 arg,
|
|||
}
|
||||
|
||||
/* Assume that sign-extension, if available, is cheaper than a shift. */
|
||||
switch (ofs + len) {
|
||||
case 32:
|
||||
if (TCG_TARGET_HAS_ext32s_i64) {
|
||||
tcg_gen_ext32s_i64(ret, arg);
|
||||
if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, 0, ofs + len)) {
|
||||
tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, arg, 0, ofs + len);
|
||||
tcg_gen_sari_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16s_i64) {
|
||||
tcg_gen_ext16s_i64(ret, arg);
|
||||
tcg_gen_sari_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8s_i64) {
|
||||
tcg_gen_ext8s_i64(ret, arg);
|
||||
tcg_gen_sari_i64(ret, ret, ofs);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (len) {
|
||||
case 32:
|
||||
if (TCG_TARGET_HAS_ext32s_i64) {
|
||||
if (TCG_TARGET_sextract_valid(TCG_TYPE_I64, 0, len)) {
|
||||
tcg_gen_shri_i64(ret, arg, ofs);
|
||||
tcg_gen_ext32s_i64(ret, ret);
|
||||
tcg_gen_op4ii_i64(INDEX_op_sextract_i64, ret, ret, 0, len);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
if (TCG_TARGET_HAS_ext16s_i64) {
|
||||
tcg_gen_shri_i64(ret, arg, ofs);
|
||||
tcg_gen_ext16s_i64(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (TCG_TARGET_HAS_ext8s_i64) {
|
||||
tcg_gen_shri_i64(ret, arg, ofs);
|
||||
tcg_gen_ext8s_i64(ret, ret);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
tcg_gen_shli_i64(ret, arg, 64 - len - ofs);
|
||||
tcg_gen_sari_i64(ret, ret, 64 - len);
|
||||
}
|
||||
|
|
46
tcg/tcg.c
46
tcg/tcg.c
|
@ -2242,14 +2242,6 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
|
|||
return TCG_TARGET_HAS_muluh_i32;
|
||||
case INDEX_op_mulsh_i32:
|
||||
return TCG_TARGET_HAS_mulsh_i32;
|
||||
case INDEX_op_ext8s_i32:
|
||||
return TCG_TARGET_HAS_ext8s_i32;
|
||||
case INDEX_op_ext16s_i32:
|
||||
return TCG_TARGET_HAS_ext16s_i32;
|
||||
case INDEX_op_ext8u_i32:
|
||||
return TCG_TARGET_HAS_ext8u_i32;
|
||||
case INDEX_op_ext16u_i32:
|
||||
return TCG_TARGET_HAS_ext16u_i32;
|
||||
case INDEX_op_bswap16_i32:
|
||||
return TCG_TARGET_HAS_bswap16_i32;
|
||||
case INDEX_op_bswap32_i32:
|
||||
|
@ -2328,18 +2320,6 @@ bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_extrl_i64_i32:
|
||||
case INDEX_op_extrh_i64_i32:
|
||||
return TCG_TARGET_HAS_extr_i64_i32;
|
||||
case INDEX_op_ext8s_i64:
|
||||
return TCG_TARGET_HAS_ext8s_i64;
|
||||
case INDEX_op_ext16s_i64:
|
||||
return TCG_TARGET_HAS_ext16s_i64;
|
||||
case INDEX_op_ext32s_i64:
|
||||
return TCG_TARGET_HAS_ext32s_i64;
|
||||
case INDEX_op_ext8u_i64:
|
||||
return TCG_TARGET_HAS_ext8u_i64;
|
||||
case INDEX_op_ext16u_i64:
|
||||
return TCG_TARGET_HAS_ext16u_i64;
|
||||
case INDEX_op_ext32u_i64:
|
||||
return TCG_TARGET_HAS_ext32u_i64;
|
||||
case INDEX_op_bswap16_i64:
|
||||
return TCG_TARGET_HAS_bswap16_i64;
|
||||
case INDEX_op_bswap32_i64:
|
||||
|
@ -5430,32 +5410,6 @@ static void tcg_reg_alloc_op(TCGContext *s, const TCGOp *op)
|
|||
|
||||
/* emit instruction */
|
||||
switch (op->opc) {
|
||||
case INDEX_op_ext8s_i32:
|
||||
tcg_out_ext8s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext8s_i64:
|
||||
tcg_out_ext8s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
tcg_out_ext8u(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext16s_i32:
|
||||
tcg_out_ext16s(s, TCG_TYPE_I32, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext16s_i64:
|
||||
tcg_out_ext16s(s, TCG_TYPE_I64, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
tcg_out_ext16u(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext32s_i64:
|
||||
tcg_out_ext32s(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext32u_i64:
|
||||
tcg_out_ext32u(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
case INDEX_op_ext_i32_i64:
|
||||
tcg_out_exts_i32_i64(s, new_args[0], new_args[1]);
|
||||
break;
|
||||
|
|
36
tcg/tci.c
36
tcg/tci.c
|
@ -689,31 +689,6 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||
tci_write_reg64(regs, r1, r0, tmp64);
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_ext8s_i32 || TCG_TARGET_HAS_ext8s_i64
|
||||
CASE_32_64(ext8s)
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (int8_t)regs[r1];
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_ext16s_i32 || TCG_TARGET_HAS_ext16s_i64 || \
|
||||
TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
|
||||
CASE_32_64(ext16s)
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (int16_t)regs[r1];
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_ext8u_i32 || TCG_TARGET_HAS_ext8u_i64
|
||||
CASE_32_64(ext8u)
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (uint8_t)regs[r1];
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_ext16u_i32 || TCG_TARGET_HAS_ext16u_i64
|
||||
CASE_32_64(ext16u)
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (uint16_t)regs[r1];
|
||||
break;
|
||||
#endif
|
||||
#if TCG_TARGET_HAS_bswap16_i32 || TCG_TARGET_HAS_bswap16_i64
|
||||
CASE_32_64(bswap16)
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
|
@ -864,12 +839,10 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
|
|||
tb_ptr = ptr;
|
||||
}
|
||||
break;
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (int32_t)regs[r1];
|
||||
break;
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
tci_args_rr(insn, &r0, &r1);
|
||||
regs[r0] = (uint32_t)regs[r1];
|
||||
|
@ -1092,15 +1065,6 @@ int print_insn_tci(bfd_vma addr, disassemble_info *info)
|
|||
|
||||
case INDEX_op_mov_i32:
|
||||
case INDEX_op_mov_i64:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_bswap16_i32:
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
#define TCG_TARGET_HAS_bswap32_i32 1
|
||||
#define TCG_TARGET_HAS_div_i32 1
|
||||
#define TCG_TARGET_HAS_rem_i32 1
|
||||
#define TCG_TARGET_HAS_ext8s_i32 1
|
||||
#define TCG_TARGET_HAS_ext16s_i32 1
|
||||
#define TCG_TARGET_HAS_ext8u_i32 1
|
||||
#define TCG_TARGET_HAS_ext16u_i32 1
|
||||
#define TCG_TARGET_HAS_andc_i32 1
|
||||
#define TCG_TARGET_HAS_extract2_i32 0
|
||||
#define TCG_TARGET_HAS_eqv_i32 1
|
||||
|
@ -40,12 +36,6 @@
|
|||
#define TCG_TARGET_HAS_extract2_i64 0
|
||||
#define TCG_TARGET_HAS_div_i64 1
|
||||
#define TCG_TARGET_HAS_rem_i64 1
|
||||
#define TCG_TARGET_HAS_ext8s_i64 1
|
||||
#define TCG_TARGET_HAS_ext16s_i64 1
|
||||
#define TCG_TARGET_HAS_ext32s_i64 1
|
||||
#define TCG_TARGET_HAS_ext8u_i64 1
|
||||
#define TCG_TARGET_HAS_ext16u_i64 1
|
||||
#define TCG_TARGET_HAS_ext32u_i64 1
|
||||
#define TCG_TARGET_HAS_andc_i64 1
|
||||
#define TCG_TARGET_HAS_eqv_i64 1
|
||||
#define TCG_TARGET_HAS_nand_i64 1
|
||||
|
|
|
@ -59,16 +59,6 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
|
|||
case INDEX_op_not_i64:
|
||||
case INDEX_op_neg_i32:
|
||||
case INDEX_op_neg_i64:
|
||||
case INDEX_op_ext8s_i32:
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_bswap16_i32:
|
||||
|
@ -535,76 +525,54 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
|
|||
}
|
||||
}
|
||||
|
||||
static void tcg_out_extract(TCGContext *s, TCGType type, TCGReg rd,
|
||||
TCGReg rs, unsigned pos, unsigned len)
|
||||
{
|
||||
TCGOpcode opc = type == TCG_TYPE_I32 ?
|
||||
INDEX_op_extract_i32 :
|
||||
INDEX_op_extract_i64;
|
||||
tcg_out_op_rrbb(s, opc, rd, rs, pos, len);
|
||||
}
|
||||
|
||||
static void tcg_out_sextract(TCGContext *s, TCGType type, TCGReg rd,
|
||||
TCGReg rs, unsigned pos, unsigned len)
|
||||
{
|
||||
TCGOpcode opc = type == TCG_TYPE_I32 ?
|
||||
INDEX_op_sextract_i32 :
|
||||
INDEX_op_sextract_i64;
|
||||
tcg_out_op_rrbb(s, opc, rd, rs, pos, len);
|
||||
}
|
||||
|
||||
static void tcg_out_ext8s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
switch (type) {
|
||||
case TCG_TYPE_I32:
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext8s_i32);
|
||||
tcg_out_op_rr(s, INDEX_op_ext8s_i32, rd, rs);
|
||||
break;
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
case TCG_TYPE_I64:
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext8s_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext8s_i64, rd, rs);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
tcg_out_sextract(s, type, rd, rs, 0, 8);
|
||||
}
|
||||
|
||||
static void tcg_out_ext8u(TCGContext *s, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 64) {
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext8u_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext8u_i64, rd, rs);
|
||||
} else {
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext8u_i32);
|
||||
tcg_out_op_rr(s, INDEX_op_ext8u_i32, rd, rs);
|
||||
}
|
||||
tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 8);
|
||||
}
|
||||
|
||||
static void tcg_out_ext16s(TCGContext *s, TCGType type, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
switch (type) {
|
||||
case TCG_TYPE_I32:
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext16s_i32);
|
||||
tcg_out_op_rr(s, INDEX_op_ext16s_i32, rd, rs);
|
||||
break;
|
||||
#if TCG_TARGET_REG_BITS == 64
|
||||
case TCG_TYPE_I64:
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext16s_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext16s_i64, rd, rs);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
tcg_out_sextract(s, type, rd, rs, 0, 16);
|
||||
}
|
||||
|
||||
static void tcg_out_ext16u(TCGContext *s, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
if (TCG_TARGET_REG_BITS == 64) {
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext16u_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext16u_i64, rd, rs);
|
||||
} else {
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext16u_i32);
|
||||
tcg_out_op_rr(s, INDEX_op_ext16u_i32, rd, rs);
|
||||
}
|
||||
tcg_out_extract(s, TCG_TYPE_REG, rd, rs, 0, 16);
|
||||
}
|
||||
|
||||
static void tcg_out_ext32s(TCGContext *s, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext32s_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext32s_i64, rd, rs);
|
||||
tcg_out_sextract(s, TCG_TYPE_I64, rd, rs, 0, 32);
|
||||
}
|
||||
|
||||
static void tcg_out_ext32u(TCGContext *s, TCGReg rd, TCGReg rs)
|
||||
{
|
||||
tcg_debug_assert(TCG_TARGET_REG_BITS == 64);
|
||||
tcg_debug_assert(TCG_TARGET_HAS_ext32u_i64);
|
||||
tcg_out_op_rr(s, INDEX_op_ext32u_i64, rd, rs);
|
||||
tcg_out_extract(s, TCG_TYPE_I64, rd, rs, 0, 32);
|
||||
}
|
||||
|
||||
static void tcg_out_exts_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
|
||||
|
@ -690,7 +658,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
const TCGArg args[TCG_MAX_OP_ARGS],
|
||||
const int const_args[TCG_MAX_OP_ARGS])
|
||||
{
|
||||
TCGOpcode exts;
|
||||
int width;
|
||||
|
||||
switch (opc) {
|
||||
case INDEX_op_goto_ptr:
|
||||
|
@ -777,18 +745,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
break;
|
||||
|
||||
case INDEX_op_bswap16_i32: /* Optional (TCG_TARGET_HAS_bswap16_i32). */
|
||||
exts = INDEX_op_ext16s_i32;
|
||||
goto do_bswap;
|
||||
case INDEX_op_bswap16_i64: /* Optional (TCG_TARGET_HAS_bswap16_i64). */
|
||||
exts = INDEX_op_ext16s_i64;
|
||||
width = 16;
|
||||
goto do_bswap;
|
||||
case INDEX_op_bswap32_i64: /* Optional (TCG_TARGET_HAS_bswap32_i64). */
|
||||
exts = INDEX_op_ext32s_i64;
|
||||
width = 32;
|
||||
do_bswap:
|
||||
/* The base tci bswaps zero-extend, and ignore high bits. */
|
||||
tcg_out_op_rr(s, opc, args[0], args[1]);
|
||||
if (args[2] & TCG_BSWAP_OS) {
|
||||
tcg_out_op_rr(s, exts, args[0], args[0]);
|
||||
tcg_out_sextract(s, TCG_TYPE_REG, args[0], args[0], 0, width);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -838,17 +804,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
|
|||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
case INDEX_op_exit_tb: /* Always emitted via tcg_out_exit_tb. */
|
||||
case INDEX_op_goto_tb: /* Always emitted via tcg_out_goto_tb. */
|
||||
case INDEX_op_ext8s_i32: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_ext8s_i64:
|
||||
case INDEX_op_ext8u_i32:
|
||||
case INDEX_op_ext8u_i64:
|
||||
case INDEX_op_ext16s_i32:
|
||||
case INDEX_op_ext16s_i64:
|
||||
case INDEX_op_ext16u_i32:
|
||||
case INDEX_op_ext16u_i64:
|
||||
case INDEX_op_ext32s_i64:
|
||||
case INDEX_op_ext32u_i64:
|
||||
case INDEX_op_ext_i32_i64:
|
||||
case INDEX_op_ext_i32_i64: /* Always emitted via tcg_reg_alloc_op. */
|
||||
case INDEX_op_extu_i32_i64:
|
||||
case INDEX_op_extrl_i64_i32:
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue