mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-10-27 03:11:18 +00:00
Fix issues of fnn.cmp (#1204)
- use native functions to do f.eq and f.ne - only use ZF=0 and CF=0 to do f.lt and f.gt - only use CF=0 to do f.le and f.ge could use comiss and setCC to replace comiss and jmpCC be able to pass f32_cmp and f64_cmp ``` cmp_eq: xor eax, eax ucomisd xmm0, xmm1 mov edx, 0 setnp al cmovne eax, edx ret cmp_ne: xor eax, eax ucomisd xmm0, xmm1 mov edx, 1 setp al cmovne eax, edx ret ```
This commit is contained in:
parent
66cd90d847
commit
b3a27e7257
|
|
@ -363,7 +363,7 @@ cmp_r_and_jmp_label(JitCompContext *cc, x86::Assembler &a,
|
||||||
case GTS:
|
case GTS:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jnbe(imm);
|
a.ja(imm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jg(imm);
|
a.jg(imm);
|
||||||
|
|
@ -373,7 +373,7 @@ cmp_r_and_jmp_label(JitCompContext *cc, x86::Assembler &a,
|
||||||
case LES:
|
case LES:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jbe(imm);
|
a.jnb(imm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jng(imm);
|
a.jng(imm);
|
||||||
|
|
@ -394,7 +394,7 @@ cmp_r_and_jmp_label(JitCompContext *cc, x86::Assembler &a,
|
||||||
case LTS:
|
case LTS:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jb(imm);
|
a.ja(imm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jl(imm);
|
a.jl(imm);
|
||||||
|
|
@ -5071,7 +5071,7 @@ cmp_r_and_jmp_relative(JitCompContext *cc, x86::Assembler &a, int32 reg_no,
|
||||||
case GTS:
|
case GTS:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jnbe(target);
|
a.ja(target);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jg(target);
|
a.jg(target);
|
||||||
|
|
@ -5081,7 +5081,7 @@ cmp_r_and_jmp_relative(JitCompContext *cc, x86::Assembler &a, int32 reg_no,
|
||||||
case LES:
|
case LES:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jbe(target);
|
a.jnb(target);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jng(target);
|
a.jng(target);
|
||||||
|
|
@ -5094,7 +5094,6 @@ cmp_r_and_jmp_relative(JitCompContext *cc, x86::Assembler &a, int32 reg_no,
|
||||||
a.jnb(target);
|
a.jnb(target);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
a.jnl(target);
|
a.jnl(target);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -5102,7 +5101,7 @@ cmp_r_and_jmp_relative(JitCompContext *cc, x86::Assembler &a, int32 reg_no,
|
||||||
case LTS:
|
case LTS:
|
||||||
{
|
{
|
||||||
if (fp_cmp) {
|
if (fp_cmp) {
|
||||||
a.jb(target);
|
a.ja(target);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a.jl(target);
|
a.jl(target);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "jit_emit_compare.h"
|
#include "jit_emit_compare.h"
|
||||||
#include "../jit_frontend.h"
|
#include "../jit_frontend.h"
|
||||||
|
#include "../jit_codegen.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
jit_compile_op_compare_integer(JitCompContext *cc, IntCond cond, bool is64Bit)
|
jit_compile_op_compare_integer(JitCompContext *cc, IntCond cond, bool is64Bit)
|
||||||
|
|
@ -116,45 +117,120 @@ jit_compile_op_i64_compare(JitCompContext *cc, IntCond cond)
|
||||||
return jit_compile_op_compare_integer(cc, cond, true);
|
return jit_compile_op_compare_integer(cc, cond, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
float_cmp_eq(float f1, float f2)
|
||||||
|
{
|
||||||
|
if (isnan(f1) || isnan(f2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return f1 == f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
float_cmp_ne(float f1, float f2)
|
||||||
|
{
|
||||||
|
if (isnan(f1) || isnan(f2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return f1 != f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
double_cmp_eq(double d1, double d2)
|
||||||
|
{
|
||||||
|
if (isnan(d1) || isnan(d2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return d1 == d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
double_cmp_ne(double d1, double d2)
|
||||||
|
{
|
||||||
|
if (isnan(d1) || isnan(d2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return d1 != d2;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
jit_compile_op_compare_float_point(JitCompContext *cc, FloatCond cond,
|
jit_compile_op_compare_float_point(JitCompContext *cc, FloatCond cond,
|
||||||
JitReg lhs, JitReg rhs)
|
JitReg lhs, JitReg rhs)
|
||||||
{
|
{
|
||||||
JitReg res, const_zero, const_one;
|
JitReg res, const_zero, const_one;
|
||||||
|
|
||||||
GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
|
if (cond == FLOAT_EQ) {
|
||||||
|
JitInsn *insn = NULL;
|
||||||
|
JitRegKind kind = jit_reg_kind(lhs);
|
||||||
|
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
res = jit_codegen_get_hreg_by_name("eax");
|
||||||
|
#else
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (kind == JIT_REG_KIND_F32) {
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)float_cmp_eq), 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)double_cmp_eq), 2);
|
||||||
|
}
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = lhs;
|
||||||
|
*(jit_insn_opndv(insn, 3)) = rhs;
|
||||||
|
}
|
||||||
|
else if (cond == FLOAT_NE) {
|
||||||
|
JitInsn *insn = NULL;
|
||||||
|
JitRegKind kind = jit_reg_kind(lhs);
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
res = jit_codegen_get_hreg_by_name("eax");
|
||||||
|
#else
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
#endif
|
||||||
|
if (kind == JIT_REG_KIND_F32) {
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)float_cmp_ne), 2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)double_cmp_ne), 2);
|
||||||
|
}
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = lhs;
|
||||||
|
*(jit_insn_opndv(insn, 3)) = rhs;
|
||||||
|
}
|
||||||
|
else {
|
||||||
res = jit_cc_new_reg_I32(cc);
|
res = jit_cc_new_reg_I32(cc);
|
||||||
const_zero = NEW_CONST(I32, 0);
|
const_zero = NEW_CONST(I32, 0);
|
||||||
const_one = NEW_CONST(I32, 1);
|
const_one = NEW_CONST(I32, 1);
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
case FLOAT_EQ:
|
|
||||||
{
|
|
||||||
GEN_INSN(SELECTEQ, res, cc->cmp_reg, const_one, const_zero);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FLOAT_NE:
|
|
||||||
{
|
|
||||||
GEN_INSN(SELECTNE, res, cc->cmp_reg, const_one, const_zero);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case FLOAT_LT:
|
case FLOAT_LT:
|
||||||
{
|
{
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, rhs, lhs);
|
||||||
GEN_INSN(SELECTLTS, res, cc->cmp_reg, const_one, const_zero);
|
GEN_INSN(SELECTLTS, res, cc->cmp_reg, const_one, const_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FLOAT_GT:
|
case FLOAT_GT:
|
||||||
{
|
{
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
|
||||||
GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
|
GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FLOAT_LE:
|
case FLOAT_LE:
|
||||||
{
|
{
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, rhs, lhs);
|
||||||
GEN_INSN(SELECTLES, res, cc->cmp_reg, const_one, const_zero);
|
GEN_INSN(SELECTLES, res, cc->cmp_reg, const_one, const_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FLOAT_GE:
|
case FLOAT_GE:
|
||||||
{
|
{
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
|
||||||
GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
|
GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -164,6 +240,7 @@ jit_compile_op_compare_float_point(JitCompContext *cc, FloatCond cond,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
PUSH_I32(res);
|
PUSH_I32(res);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user