mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
tcg/loongarch64: Support negsetcond
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
d776198cd3
commit
84f57d50ac
3 changed files with 29 additions and 11 deletions
|
@ -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
|
||||
|
|
|
@ -646,14 +646,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);
|
||||
|
@ -1800,7 +1815,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:
|
||||
|
@ -2434,9 +2453,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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue