@@ -29,8 +29,6 @@ C_O1_I2(r, r, rJ)
C_O1_I2(r, r, rU)
C_O1_I2(r, r, rW)
C_O1_I2(r, 0, rz)
-C_O1_I2(r, rz, ri)
-C_O1_I2(r, rz, rJ)
C_O1_I2(w, w, w)
C_O1_I2(w, w, wM)
C_O1_I2(w, w, wA)
@@ -10,7 +10,7 @@
#include "host/cpuinfo.h"
/* optional instructions */
-#define TCG_TARGET_HAS_negsetcond_i32 0
+#define TCG_TARGET_HAS_negsetcond_i32 1
#define TCG_TARGET_HAS_extract2_i32 0
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
@@ -19,7 +19,7 @@
#define TCG_TARGET_HAS_qemu_st8_i32 0
/* 64-bit operations */
-#define TCG_TARGET_HAS_negsetcond_i64 0
+#define TCG_TARGET_HAS_negsetcond_i64 1
#define TCG_TARGET_HAS_extract2_i64 0
#define TCG_TARGET_HAS_extr_i64_i32 1
#define TCG_TARGET_HAS_bswap16_i64 1
@@ -634,14 +634,29 @@ static int tcg_out_setcond_int(TCGContext *s, TCGCond cond, TCGReg ret,
}
static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
- TCGReg arg1, tcg_target_long arg2, bool c2)
+ TCGReg arg1, tcg_target_long arg2,
+ bool c2, bool neg)
{
int tmpflags = tcg_out_setcond_int(s, cond, ret, arg1, arg2, c2);
+ TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
- if (tmpflags != ret) {
- TCGReg tmp = tmpflags & ~SETCOND_FLAGS;
-
+ if (neg) {
+ /* If intermediate result is zero/non-zero: test != 0. */
+ if (tmpflags & SETCOND_NEZ) {
+ tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
+ tmp = ret;
+ }
+ /* Produce the 0/-1 result. */
+ if (tmpflags & SETCOND_INV) {
+ tcg_out_opc_addi_d(s, ret, tmp, -1);
+ } else {
+ tcg_out_opc_sub_d(s, ret, TCG_REG_ZERO, tmp);
+ }
+ } else {
switch (tmpflags & SETCOND_FLAGS) {
+ case 0:
+ tcg_debug_assert(tmp == ret);
+ break;
case SETCOND_INV:
/* Intermediate result is boolean: simply invert. */
tcg_out_opc_xori(s, ret, tmp, 1);
@@ -1788,7 +1803,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, TCGType type,
case INDEX_op_setcond_i32:
case INDEX_op_setcond_i64:
- tcg_out_setcond(s, args[3], a0, a1, a2, c2);
+ tcg_out_setcond(s, args[3], a0, a1, a2, c2, false);
+ break;
+ case INDEX_op_negsetcond_i32:
+ case INDEX_op_negsetcond_i64:
+ tcg_out_setcond(s, args[3], a0, a1, a2, c2, true);
break;
case INDEX_op_movcond_i32:
@@ -2428,9 +2447,10 @@ tcg_target_op_def(TCGOpcode op, TCGType type, unsigned flags)
return C_O1_I2(r, 0, rz);
case INDEX_op_setcond_i32:
- return C_O1_I2(r, rz, ri);
case INDEX_op_setcond_i64:
- return C_O1_I2(r, rz, rJ);
+ case INDEX_op_negsetcond_i32:
+ case INDEX_op_negsetcond_i64:
+ return C_O1_I2(r, r, rJ);
case INDEX_op_movcond_i32:
case INDEX_op_movcond_i64:
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- tcg/loongarch64/tcg-target-con-set.h | 2 -- tcg/loongarch64/tcg-target-has.h | 4 ++-- tcg/loongarch64/tcg-target.c.inc | 34 ++++++++++++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-)