tci: Support deposit operations

The operations for INDEX_op_deposit_i32 and INDEX_op_deposit_i64
are now supported and enabled by default.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
master
Stefan Weil 2012-09-18 22:52:14 +02:00 committed by Blue Swirl
parent 1358681344
commit e24dc9feb0
3 changed files with 48 additions and 2 deletions

View File

@ -122,6 +122,9 @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
{ INDEX_op_rotl_i32, { R, RI, RI } },
{ INDEX_op_rotr_i32, { R, RI, RI } },
#endif
#if TCG_TARGET_HAS_deposit_i32
{ INDEX_op_deposit_i32, { R, "0", R } },
#endif
{ INDEX_op_brcond_i32, { R, RI } },
@ -199,6 +202,9 @@ static const TCGTargetOpDef tcg_target_op_defs[] = {
#if TCG_TARGET_HAS_rot_i64
{ INDEX_op_rotl_i64, { R, RI, RI } },
{ INDEX_op_rotr_i64, { R, RI, RI } },
#endif
#if TCG_TARGET_HAS_deposit_i64
{ INDEX_op_deposit_i64, { R, "0", R } },
#endif
{ INDEX_op_brcond_i64, { R, RI } },
@ -653,6 +659,15 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out_ri32(s, const_args[1], args[1]);
tcg_out_ri32(s, const_args[2], args[2]);
break;
case INDEX_op_deposit_i32: /* Optional (TCG_TARGET_HAS_deposit_i32). */
tcg_out_r(s, args[0]);
tcg_out_r(s, args[1]);
tcg_out_r(s, args[2]);
assert(args[3] <= UINT8_MAX);
tcg_out8(s, args[3]);
assert(args[4] <= UINT8_MAX);
tcg_out8(s, args[4]);
break;
#if TCG_TARGET_REG_BITS == 64
case INDEX_op_mov_i64:
@ -680,6 +695,15 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
tcg_out_ri64(s, const_args[1], args[1]);
tcg_out_ri64(s, const_args[2], args[2]);
break;
case INDEX_op_deposit_i64: /* Optional (TCG_TARGET_HAS_deposit_i64). */
tcg_out_r(s, args[0]);
tcg_out_r(s, args[1]);
tcg_out_r(s, args[2]);
assert(args[3] <= UINT8_MAX);
tcg_out8(s, args[3]);
assert(args[4] <= UINT8_MAX);
tcg_out8(s, args[4]);
break;
case INDEX_op_div_i64: /* Optional (TCG_TARGET_HAS_div_i64). */
case INDEX_op_divu_i64: /* Optional (TCG_TARGET_HAS_div_i64). */
case INDEX_op_rem_i64: /* Optional (TCG_TARGET_HAS_div_i64). */

View File

@ -67,7 +67,7 @@
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_andc_i32 0
#define TCG_TARGET_HAS_deposit_i32 0
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_eqv_i32 0
#define TCG_TARGET_HAS_nand_i32 0
#define TCG_TARGET_HAS_nor_i32 0
@ -81,7 +81,7 @@
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_deposit_i64 0
#define TCG_TARGET_HAS_deposit_i64 1
/* Not more than one of the next two defines must be 1. */
#define TCG_TARGET_HAS_div_i64 0
#define TCG_TARGET_HAS_div2_i64 0

22
tci.c
View File

@ -688,6 +688,17 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
t2 = tci_read_ri32(&tb_ptr);
tci_write_reg32(t0, (t1 >> t2) | (t1 << (32 - t2)));
break;
#endif
#if TCG_TARGET_HAS_deposit_i32
case INDEX_op_deposit_i32:
t0 = *tb_ptr++;
t1 = tci_read_r32(&tb_ptr);
t2 = tci_read_r32(&tb_ptr);
tmp16 = *tb_ptr++;
tmp8 = *tb_ptr++;
tmp32 = (((1 << tmp8) - 1) << tmp16);
tci_write_reg32(t0, (t1 & ~tmp32) | ((t2 << tmp16) & tmp32));
break;
#endif
case INDEX_op_brcond_i32:
t0 = tci_read_r32(&tb_ptr);
@ -935,6 +946,17 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
case INDEX_op_rotr_i64:
TODO();
break;
#endif
#if TCG_TARGET_HAS_deposit_i64
case INDEX_op_deposit_i64:
t0 = *tb_ptr++;
t1 = tci_read_r64(&tb_ptr);
t2 = tci_read_r64(&tb_ptr);
tmp16 = *tb_ptr++;
tmp8 = *tb_ptr++;
tmp64 = (((1ULL << tmp8) - 1) << tmp16);
tci_write_reg64(t0, (t1 & ~tmp64) | ((t2 << tmp16) & tmp64));
break;
#endif
case INDEX_op_brcond_i64:
t0 = tci_read_r64(&tb_ptr);