Message ID | 20230808031143.50925-15-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | tcg: Introduce negsetcond opcodes | expand |
On 8/8/23 00:11, Richard Henderson wrote: > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > tcg/riscv/tcg-target.h | 4 ++-- > tcg/riscv/tcg-target.c.inc | 45 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+), 2 deletions(-) > > diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h > index b2961fec8e..7e8ac48a7d 100644 > --- a/tcg/riscv/tcg-target.h > +++ b/tcg/riscv/tcg-target.h > @@ -120,7 +120,7 @@ extern bool have_zbb; > #define TCG_TARGET_HAS_ctpop_i32 have_zbb > #define TCG_TARGET_HAS_brcond2 1 > #define TCG_TARGET_HAS_setcond2 1 > -#define TCG_TARGET_HAS_negsetcond_i32 0 > +#define TCG_TARGET_HAS_negsetcond_i32 1 > #define TCG_TARGET_HAS_qemu_st8_i32 0 > > #define TCG_TARGET_HAS_movcond_i64 1 > @@ -159,7 +159,7 @@ extern bool have_zbb; > #define TCG_TARGET_HAS_muls2_i64 0 > #define TCG_TARGET_HAS_muluh_i64 1 > #define TCG_TARGET_HAS_mulsh_i64 1 > -#define TCG_TARGET_HAS_negsetcond_i64 0 > +#define TCG_TARGET_HAS_negsetcond_i64 1 > > #define TCG_TARGET_HAS_qemu_ldst_i128 0 > > diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc > index eeaeb6b6e3..232b616af3 100644 > --- a/tcg/riscv/tcg-target.c.inc > +++ b/tcg/riscv/tcg-target.c.inc > @@ -936,6 +936,44 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, > } > } > > +static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret, > + TCGReg arg1, tcg_target_long arg2, bool c2) > +{ > + int tmpflags; > + TCGReg tmp; > + > + /* For LT/GE comparison against 0, replicate the sign bit. */ > + if (c2 && arg2 == 0) { > + switch (cond) { > + case TCG_COND_GE: > + tcg_out_opc_imm(s, OPC_XORI, ret, arg1, -1); > + arg1 = ret; > + /* fall through */ > + case TCG_COND_LT: > + tcg_out_opc_imm(s, OPC_SRAI, ret, arg1, TCG_TARGET_REG_BITS - 1); > + return; > + default: > + break; > + } > + } > + > + tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2); > + tmp = tmpflags & ~SETCOND_FLAGS; > + > + /* If intermediate result is zero/non-zero: test != 0. */ > + if (tmpflags & SETCOND_NEZ) { > + tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp); > + tmp = ret; > + } > + > + /* Produce the 0/-1 result. */ > + if (tmpflags & SETCOND_INV) { > + tcg_out_opc_imm(s, OPC_ADDI, ret, tmp, -1); > + } else { > + tcg_out_opc_reg(s, OPC_SUB, ret, TCG_REG_ZERO, tmp); > + } > +} > + > static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne, > int val1, bool c_val1, > int val2, bool c_val2) > @@ -1782,6 +1820,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, > tcg_out_setcond(s, args[3], a0, a1, a2, c2); > break; > > + case INDEX_op_negsetcond_i32: > + case INDEX_op_negsetcond_i64: > + tcg_out_negsetcond(s, args[3], a0, a1, a2, c2); > + break; > + > case INDEX_op_movcond_i32: > case INDEX_op_movcond_i64: > tcg_out_movcond(s, args[5], a0, a1, a2, c2, > @@ -1910,6 +1953,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) > case INDEX_op_xor_i64: > case INDEX_op_setcond_i32: > case INDEX_op_setcond_i64: > + case INDEX_op_negsetcond_i32: > + case INDEX_op_negsetcond_i64: > return C_O1_I2(r, r, rI); > > case INDEX_op_andc_i32:
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h index b2961fec8e..7e8ac48a7d 100644 --- a/tcg/riscv/tcg-target.h +++ b/tcg/riscv/tcg-target.h @@ -120,7 +120,7 @@ extern bool have_zbb; #define TCG_TARGET_HAS_ctpop_i32 have_zbb #define TCG_TARGET_HAS_brcond2 1 #define TCG_TARGET_HAS_setcond2 1 -#define TCG_TARGET_HAS_negsetcond_i32 0 +#define TCG_TARGET_HAS_negsetcond_i32 1 #define TCG_TARGET_HAS_qemu_st8_i32 0 #define TCG_TARGET_HAS_movcond_i64 1 @@ -159,7 +159,7 @@ extern bool have_zbb; #define TCG_TARGET_HAS_muls2_i64 0 #define TCG_TARGET_HAS_muluh_i64 1 #define TCG_TARGET_HAS_mulsh_i64 1 -#define TCG_TARGET_HAS_negsetcond_i64 0 +#define TCG_TARGET_HAS_negsetcond_i64 1 #define TCG_TARGET_HAS_qemu_ldst_i128 0 diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc index eeaeb6b6e3..232b616af3 100644 --- a/tcg/riscv/tcg-target.c.inc +++ b/tcg/riscv/tcg-target.c.inc @@ -936,6 +936,44 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret, } } +static void tcg_out_negsetcond(TCGContext *s, TCGCond cond, TCGReg ret, + TCGReg arg1, tcg_target_long arg2, bool c2) +{ + int tmpflags; + TCGReg tmp; + + /* For LT/GE comparison against 0, replicate the sign bit. */ + if (c2 && arg2 == 0) { + switch (cond) { + case TCG_COND_GE: + tcg_out_opc_imm(s, OPC_XORI, ret, arg1, -1); + arg1 = ret; + /* fall through */ + case TCG_COND_LT: + tcg_out_opc_imm(s, OPC_SRAI, ret, arg1, TCG_TARGET_REG_BITS - 1); + return; + default: + break; + } + } + + tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2); + tmp = tmpflags & ~SETCOND_FLAGS; + + /* If intermediate result is zero/non-zero: test != 0. */ + if (tmpflags & SETCOND_NEZ) { + tcg_out_opc_reg(s, OPC_SLTU, ret, TCG_REG_ZERO, tmp); + tmp = ret; + } + + /* Produce the 0/-1 result. */ + if (tmpflags & SETCOND_INV) { + tcg_out_opc_imm(s, OPC_ADDI, ret, tmp, -1); + } else { + tcg_out_opc_reg(s, OPC_SUB, ret, TCG_REG_ZERO, tmp); + } +} + static void tcg_out_movcond_zicond(TCGContext *s, TCGReg ret, TCGReg test_ne, int val1, bool c_val1, int val2, bool c_val2) @@ -1782,6 +1820,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_setcond(s, args[3], a0, a1, a2, c2); break; + case INDEX_op_negsetcond_i32: + case INDEX_op_negsetcond_i64: + tcg_out_negsetcond(s, args[3], a0, a1, a2, c2); + break; + case INDEX_op_movcond_i32: case INDEX_op_movcond_i64: tcg_out_movcond(s, args[5], a0, a1, a2, c2, @@ -1910,6 +1953,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op) case INDEX_op_xor_i64: case INDEX_op_setcond_i32: case INDEX_op_setcond_i64: + case INDEX_op_negsetcond_i32: + case INDEX_op_negsetcond_i64: return C_O1_I2(r, r, rI); case INDEX_op_andc_i32:
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/riscv/tcg-target.h | 4 ++-- tcg/riscv/tcg-target.c.inc | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-)