mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-19 03:41:22 +00:00
Initial commit, reimplementation of F32Min. Fixes F32Min(negative_zero, zero) issue.
Also removes some previously-fixed i32 and i64 exclusions from the tests.
This commit is contained in:
@ -2822,7 +2822,69 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
|
|||||||
a,
|
a,
|
||||||
&mut self.machine,
|
&mut self.machine,
|
||||||
&mut self.value_stack,
|
&mut self.value_stack,
|
||||||
Assembler::emit_vminss,
|
|a, src1, src2, dst| {
|
||||||
|
let loc1 = Location::XMM(src1);
|
||||||
|
let loc2 = match src2 {
|
||||||
|
XMMOrMemory::XMM(x) => Location::XMM(x),
|
||||||
|
XMMOrMemory::Memory(base, disp) => Location::Memory(base, disp),
|
||||||
|
};
|
||||||
|
// TODO: use temp_gpr (or at least check that src2 isn't
|
||||||
|
// XMMOrMemory that uses AX or DX.
|
||||||
|
a.emit_mov(Size::S32, loc1, Location::GPR(GPR::RAX));
|
||||||
|
a.emit_mov(Size::S32, loc2, Location::GPR(GPR::RDX));
|
||||||
|
// TODO: we can skip this when dst is an XMM reg.
|
||||||
|
let tmp_xmm = if src1 == XMM::XMM0 {
|
||||||
|
if src2 == XMMOrMemory::XMM(XMM::XMM1) {
|
||||||
|
XMM::XMM2
|
||||||
|
} else {
|
||||||
|
XMM::XMM1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
XMM::XMM0
|
||||||
|
};
|
||||||
|
match src2 {
|
||||||
|
XMMOrMemory::XMM(x) => {
|
||||||
|
a.emit_mov(Size::S64, Location::XMM(x), Location::XMM(tmp_xmm))
|
||||||
|
}
|
||||||
|
XMMOrMemory::Memory(base, disp) => a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Memory(base, disp),
|
||||||
|
Location::XMM(tmp_xmm),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
a.emit_ucomiss(XMMOrMemory::XMM(src1), tmp_xmm);
|
||||||
|
let do_vminss = a.get_label();
|
||||||
|
a.emit_jmp(Condition::NotEqual, do_vminss);
|
||||||
|
a.emit_jmp(Condition::ParityEven, do_vminss);
|
||||||
|
a.emit_cmp(Size::S32, Location::GPR(GPR::RAX), Location::GPR(GPR::RDX));
|
||||||
|
a.emit_jmp(Condition::Equal, do_vminss);
|
||||||
|
static NEG_ZERO: u128 = 0x80000000;
|
||||||
|
match src2 {
|
||||||
|
XMMOrMemory::XMM(x) => {
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm64((&NEG_ZERO as *const u128) as u64),
|
||||||
|
Location::GPR(GPR::RDX),
|
||||||
|
);
|
||||||
|
a.emit_mov(Size::S64, Location::Memory(GPR::RDX, 0), Location::XMM(x));
|
||||||
|
}
|
||||||
|
XMMOrMemory::Memory(base, disp) => {
|
||||||
|
// TODO: What if base == RDX?
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Imm64((&NEG_ZERO as *const u128) as u64),
|
||||||
|
Location::GPR(GPR::RDX),
|
||||||
|
);
|
||||||
|
a.emit_mov(
|
||||||
|
Size::S64,
|
||||||
|
Location::Memory(GPR::RDX, 0),
|
||||||
|
Location::Memory(base, disp),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a.emit_label(do_vminss);
|
||||||
|
a.emit_vminss(src1, src2, dst);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Operator::F32Eq => Self::emit_fp_cmpop_avx(
|
Operator::F32Eq => Self::emit_fp_cmpop_avx(
|
||||||
a,
|
a,
|
||||||
|
@ -26,6 +26,8 @@ pub enum Condition {
|
|||||||
Equal,
|
Equal,
|
||||||
NotEqual,
|
NotEqual,
|
||||||
Signed,
|
Signed,
|
||||||
|
ParityEven,
|
||||||
|
ParityOdd,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
@ -36,7 +38,7 @@ pub enum Size {
|
|||||||
S64,
|
S64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum XMMOrMemory {
|
pub enum XMMOrMemory {
|
||||||
XMM(XMM),
|
XMM(XMM),
|
||||||
@ -602,6 +604,8 @@ impl Emitter for Assembler {
|
|||||||
Condition::Equal => jmp_op!(je, self, label),
|
Condition::Equal => jmp_op!(je, self, label),
|
||||||
Condition::NotEqual => jmp_op!(jne, self, label),
|
Condition::NotEqual => jmp_op!(jne, self, label),
|
||||||
Condition::Signed => jmp_op!(js, self, label),
|
Condition::Signed => jmp_op!(js, self, label),
|
||||||
|
Condition::ParityEven => jmp_op!(jp, self, label),
|
||||||
|
Condition::ParityOdd => jmp_op!(jnp, self, label),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn emit_jmp_location(&mut self, loc: Location) {
|
fn emit_jmp_location(&mut self, loc: Location) {
|
||||||
@ -625,6 +629,8 @@ impl Emitter for Assembler {
|
|||||||
Condition::Equal => trap_op!(je, self),
|
Condition::Equal => trap_op!(je, self),
|
||||||
Condition::NotEqual => trap_op!(jne, self),
|
Condition::NotEqual => trap_op!(jne, self),
|
||||||
Condition::Signed => trap_op!(js, self),
|
Condition::Signed => trap_op!(js, self),
|
||||||
|
Condition::ParityEven => trap_op!(jp, self),
|
||||||
|
Condition::ParityOdd => trap_op!(jnp, self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn emit_set(&mut self, condition: Condition, dst: GPR) {
|
fn emit_set(&mut self, condition: Condition, dst: GPR) {
|
||||||
|
@ -465,7 +465,6 @@ singlepass:fail:conversions.wast:240 # AssertTrap - expected trap, got Runtime:E
|
|||||||
singlepass:fail:conversions.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:conversions.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:conversions.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:conversions.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:elem.wast:353 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:elem.wast:353 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:f32.wast:1620 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000")
|
|
||||||
singlepass:fail:f32.wast:1652 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
singlepass:fail:f32.wast:1652 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
||||||
singlepass:fail:f32.wast:1654 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
singlepass:fail:f32.wast:1654 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
||||||
singlepass:fail:f32.wast:1656 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
singlepass:fail:f32.wast:1656 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
|
||||||
@ -902,15 +901,6 @@ singlepass:fail:i32.wast:99 # AssertTrap - expected trap, got Runtime:Error unkn
|
|||||||
singlepass:fail:i32.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i32.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i32.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i32.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i32.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i32.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i32.wast:242 # AssertReturn - result I32(31) ("0x1f") does not match expected I32(0) ("0x0")
|
|
||||||
singlepass:fail:i32.wast:243 # AssertReturn - result I32(0) ("0x0") does not match expected I32(32) ("0x20")
|
|
||||||
singlepass:fail:i32.wast:244 # AssertReturn - result I32(15) ("0xf") does not match expected I32(16) ("0x10")
|
|
||||||
singlepass:fail:i32.wast:245 # AssertReturn - result I32(7) ("0x7") does not match expected I32(24) ("0x18")
|
|
||||||
singlepass:fail:i32.wast:246 # AssertReturn - result I32(31) ("0x1f") does not match expected I32(0) ("0x0")
|
|
||||||
singlepass:fail:i32.wast:247 # AssertReturn - result I32(0) ("0x0") does not match expected I32(31) ("0x1f")
|
|
||||||
singlepass:fail:i32.wast:248 # AssertReturn - result I32(1) ("0x1") does not match expected I32(30) ("0x1e")
|
|
||||||
singlepass:fail:i32.wast:249 # AssertReturn - result I32(30) ("0x1e") does not match expected I32(1) ("0x1")
|
|
||||||
singlepass:fail:i32.wast:252 # AssertReturn - result I32(0) ("0x0") does not match expected I32(32) ("0x20")
|
|
||||||
singlepass:fail:i64.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i64.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i64.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
@ -920,15 +910,6 @@ singlepass:fail:i64.wast:99 # AssertTrap - expected trap, got Runtime:Error unkn
|
|||||||
singlepass:fail:i64.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i64.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i64.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:i64.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:i64.wast:242 # AssertReturn - result I64(63) ("0x3f") does not match expected I64(0) ("0x0")
|
|
||||||
singlepass:fail:i64.wast:243 # AssertReturn - result I64(0) ("0x0") does not match expected I64(64) ("0x40")
|
|
||||||
singlepass:fail:i64.wast:244 # AssertReturn - result I64(15) ("0xf") does not match expected I64(48) ("0x30")
|
|
||||||
singlepass:fail:i64.wast:245 # AssertReturn - result I64(7) ("0x7") does not match expected I64(56) ("0x38")
|
|
||||||
singlepass:fail:i64.wast:246 # AssertReturn - result I64(63) ("0x3f") does not match expected I64(0) ("0x0")
|
|
||||||
singlepass:fail:i64.wast:247 # AssertReturn - result I64(0) ("0x0") does not match expected I64(63) ("0x3f")
|
|
||||||
singlepass:fail:i64.wast:248 # AssertReturn - result I64(1) ("0x1") does not match expected I64(62) ("0x3e")
|
|
||||||
singlepass:fail:i64.wast:249 # AssertReturn - result I64(62) ("0x3e") does not match expected I64(1) ("0x1")
|
|
||||||
singlepass:fail:i64.wast:252 # AssertReturn - result I64(0) ("0x0") does not match expected I64(64) ("0x40")
|
|
||||||
singlepass:fail:if.wast:440 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:if.wast:440 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:imports.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:imports.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
singlepass:fail:imports.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
|
singlepass:fail:imports.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
|
||||||
|
Reference in New Issue
Block a user