Reimplement F32Max.

This commit is contained in:
Nick Lewycky
2019-10-14 14:07:30 -07:00
parent b886a41a85
commit 06ffb00deb
3 changed files with 100 additions and 111 deletions

View File

@ -2812,12 +2812,103 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
&mut self.value_stack,
Assembler::emit_vdivss,
),
Operator::F32Max => Self::emit_fp_binop_avx(
Operator::F32Max => {
let src2 =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let src1 =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&mut self.machine,
&mut self.value_stack,
Assembler::emit_vmaxss,
),
&[(WpType::F64, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
let tmp1 = self.machine.acquire_temp_xmm().unwrap();
let tmp2 = self.machine.acquire_temp_xmm().unwrap();
let tmpg1 = self.machine.acquire_temp_gpr().unwrap();
let tmpg2 = self.machine.acquire_temp_gpr().unwrap();
let src1 = match src1 {
Location::XMM(x) => x,
Location::GPR(_) | Location::Memory(_, _) => {
a.emit_mov(Size::S64, src1, Location::XMM(tmp1));
tmp1
}
Location::Imm32(_) => {
a.emit_mov(Size::S32, src1, Location::GPR(tmpg1));
a.emit_mov(Size::S32, Location::GPR(tmpg1), Location::XMM(tmp1));
tmp1
}
Location::Imm64(_) => {
a.emit_mov(Size::S64, src1, Location::GPR(tmpg1));
a.emit_mov(Size::S64, Location::GPR(tmpg1), Location::XMM(tmp1));
tmp1
}
_ => unreachable!(),
};
let src2 = match src2 {
Location::XMM(x) => x,
Location::GPR(_) | Location::Memory(_, _) => {
a.emit_mov(Size::S64, src2, Location::XMM(tmp2));
tmp2
}
Location::Imm32(_) => {
a.emit_mov(Size::S32, src2, Location::GPR(tmpg1));
a.emit_mov(Size::S32, Location::GPR(tmpg1), Location::XMM(tmp2));
tmp2
}
Location::Imm64(_) => {
a.emit_mov(Size::S64, src2, Location::GPR(tmpg1));
a.emit_mov(Size::S64, Location::GPR(tmpg1), Location::XMM(tmp2));
tmp2
}
_ => unreachable!(),
};
let tmp_xmm1 = XMM::XMM8;
let tmp_xmm2 = XMM::XMM9;
let tmp_xmm3 = XMM::XMM10;
static CANONICAL_NAN: u128 = 0x7FC0_0000;
a.emit_mov(Size::S32, Location::XMM(src1), Location::GPR(tmpg1));
a.emit_mov(Size::S32, Location::XMM(src2), Location::GPR(tmpg2));
a.emit_cmp(Size::S32, Location::GPR(tmpg2), Location::GPR(tmpg1));
a.emit_vmaxss(src1, XMMOrMemory::XMM(src2), tmp_xmm1);
let label1 = a.get_label();
let label2 = a.get_label();
a.emit_jmp(Condition::NotEqual, label1);
a.emit_vmovaps(XMMOrMemory::XMM(tmp_xmm1), XMMOrMemory::XMM(tmp_xmm2));
a.emit_jmp(Condition::None, label2);
a.emit_label(label1);
a.emit_vxorps(tmp_xmm2, XMMOrMemory::XMM(tmp_xmm2), tmp_xmm2);
a.emit_label(label2);
a.emit_vcmpeqss(src1, XMMOrMemory::XMM(src2), tmp_xmm3);
a.emit_vblendvps(tmp_xmm3, XMMOrMemory::XMM(tmp_xmm2), tmp_xmm1, tmp_xmm1);
a.emit_vcmpunordss(src1, XMMOrMemory::XMM(src2), src1);
// load float canonical nan
a.emit_mov(
Size::S64,
Location::Imm64((&CANONICAL_NAN as *const u128) as u64),
Location::GPR(tmpg1),
);
a.emit_mov(Size::S64, Location::Memory(tmpg1, 0), Location::XMM(src2));
a.emit_vblendvps(src1, XMMOrMemory::XMM(src2), tmp_xmm1, src1);
match ret {
Location::XMM(x) => {
a.emit_vmovaps(XMMOrMemory::XMM(src1), XMMOrMemory::XMM(x));
}
Location::Memory(_, _) | Location::GPR(_) => {
a.emit_mov(Size::S64, Location::XMM(src1), ret);
}
_ => unreachable!(),
}
self.machine.release_temp_gpr(tmpg2);
self.machine.release_temp_gpr(tmpg1);
self.machine.release_temp_xmm(tmp2);
self.machine.release_temp_xmm(tmp1);
}
Operator::F32Min => {
let src2 =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());

View File

@ -106,6 +106,7 @@ pub trait Emitter {
fn emit_cmovae_gpr_64(&mut self, src: GPR, dst: GPR);
fn emit_vmovaps(&mut self, src: XMMOrMemory, dst: XMMOrMemory);
fn emit_vxorps(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
fn emit_vaddss(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
fn emit_vaddsd(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
@ -1018,6 +1019,8 @@ impl Emitter for Assembler {
};
}
avx_fn!(vxorps, emit_vxorps);
avx_fn!(vaddss, emit_vaddss);
avx_fn!(vaddsd, emit_vaddsd);

View File

@ -465,111 +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:242 # 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:2021 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0")
singlepass:fail:f32.wast:2052 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2054 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2056 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2058 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2092 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2094 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2096 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2098 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2132 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2134 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2136 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2138 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2172 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2174 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2176 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2178 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2212 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2214 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2216 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2218 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2252 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2254 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2256 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2258 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2292 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2294 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2296 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2298 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2332 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2334 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2336 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2338 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2339 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.0)
singlepass:fail:f32.wast:2340 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.0)
singlepass:fail:f32.wast:2341 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.0)
singlepass:fail:f32.wast:2342 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.0)
singlepass:fail:f32.wast:2343 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.0)
singlepass:fail:f32.wast:2344 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.0)
singlepass:fail:f32.wast:2345 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.0)
singlepass:fail:f32.wast:2346 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.0)
singlepass:fail:f32.wast:2347 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2348 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2349 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2350 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2351 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2352 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2353 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2354 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.000000000000000000000000000000000000000000001)
singlepass:fail:f32.wast:2355 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2356 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2357 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2358 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2359 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2360 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2361 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2362 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.000000000000000000000000000000000000011754944)
singlepass:fail:f32.wast:2363 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.5)
singlepass:fail:f32.wast:2364 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.5)
singlepass:fail:f32.wast:2365 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.5)
singlepass:fail:f32.wast:2366 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.5)
singlepass:fail:f32.wast:2367 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-0.5)
singlepass:fail:f32.wast:2368 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-0.5)
singlepass:fail:f32.wast:2369 # "AssertReturnCanonicalNan" - value is not canonical nan F32(0.5)
singlepass:fail:f32.wast:2370 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(0.5)
singlepass:fail:f32.wast:2371 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-1.0)
singlepass:fail:f32.wast:2372 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-1.0)
singlepass:fail:f32.wast:2373 # "AssertReturnCanonicalNan" - value is not canonical nan F32(1.0)
singlepass:fail:f32.wast:2374 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(1.0)
singlepass:fail:f32.wast:2375 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-1.0)
singlepass:fail:f32.wast:2376 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-1.0)
singlepass:fail:f32.wast:2377 # "AssertReturnCanonicalNan" - value is not canonical nan F32(1.0)
singlepass:fail:f32.wast:2378 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(1.0)
singlepass:fail:f32.wast:2379 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-6.2831855)
singlepass:fail:f32.wast:2380 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-6.2831855)
singlepass:fail:f32.wast:2381 # "AssertReturnCanonicalNan" - value is not canonical nan F32(6.2831855)
singlepass:fail:f32.wast:2382 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(6.2831855)
singlepass:fail:f32.wast:2383 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-6.2831855)
singlepass:fail:f32.wast:2384 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-6.2831855)
singlepass:fail:f32.wast:2385 # "AssertReturnCanonicalNan" - value is not canonical nan F32(6.2831855)
singlepass:fail:f32.wast:2386 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(6.2831855)
singlepass:fail:f32.wast:2387 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2388 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2389 # "AssertReturnCanonicalNan" - value is not canonical nan F32(340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2390 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2391 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2392 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2393 # "AssertReturnCanonicalNan" - value is not canonical nan F32(340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2394 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(340282350000000000000000000000000000000.0)
singlepass:fail:f32.wast:2395 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-inf)
singlepass:fail:f32.wast:2396 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-inf)
singlepass:fail:f32.wast:2397 # "AssertReturnCanonicalNan" - value is not canonical nan F32(inf)
singlepass:fail:f32.wast:2398 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(inf)
singlepass:fail:f32.wast:2399 # "AssertReturnCanonicalNan" - value is not canonical nan F32(-inf)
singlepass:fail:f32.wast:2400 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(-inf)
singlepass:fail:f32.wast:2401 # "AssertReturnCanonicalNan" - value is not canonical nan F32(inf)
singlepass:fail:f32.wast:2402 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(inf)
singlepass:fail:f32.wast:2405 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2406 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2409 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2410 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2413 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2414 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2417 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:2418 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f64.wast:1620 # AssertReturn - result F64(0) ("0x0") does not match expected F64(9223372036854775808) ("0x8000000000000000")
singlepass:fail:f64.wast:1652 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)
singlepass:fail:f64.wast:1654 # "AssertReturnArithmeticNan" - value is not arithmetic nan F64(NaN)