Add fneg.

This commit is contained in:
losfair
2019-11-07 01:30:27 +08:00
parent 6135a004a4
commit 001213716e
3 changed files with 67 additions and 10 deletions

View File

@@ -2969,11 +2969,34 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
false,
)[0];
self.value_stack.push(ret);
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S32, loc, Location::GPR(tmp));
a.emit_btc_gpr_imm8_32(31, tmp);
a.emit_mov(Size::S32, Location::GPR(tmp), ret);
self.machine.release_temp_gpr(tmp);
if a.arch_has_fneg() {
let tmp = self.machine.acquire_temp_xmm().unwrap();
Self::emit_relaxed_binop(
a,
&mut self.machine,
Assembler::emit_mov,
Size::S32,
loc,
Location::XMM(tmp),
);
a.arch_emit_f32_neg(tmp, tmp);
Self::emit_relaxed_binop(
a,
&mut self.machine,
Assembler::emit_mov,
Size::S32,
Location::XMM(tmp),
ret,
);
self.machine.release_temp_xmm(tmp);
} else {
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S32, loc, Location::GPR(tmp));
a.emit_btc_gpr_imm8_32(31, tmp);
a.emit_mov(Size::S32, Location::GPR(tmp), ret);
self.machine.release_temp_gpr(tmp);
}
}
Operator::F64Const { value } => {
@@ -3162,11 +3185,33 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
false,
)[0];
self.value_stack.push(ret);
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S64, loc, Location::GPR(tmp));
a.emit_btc_gpr_imm8_64(63, tmp);
a.emit_mov(Size::S64, Location::GPR(tmp), ret);
self.machine.release_temp_gpr(tmp);
if a.arch_has_fneg() {
let tmp = self.machine.acquire_temp_xmm().unwrap();
Self::emit_relaxed_binop(
a,
&mut self.machine,
Assembler::emit_mov,
Size::S64,
loc,
Location::XMM(tmp),
);
a.arch_emit_f64_neg(tmp, tmp);
Self::emit_relaxed_binop(
a,
&mut self.machine,
Assembler::emit_mov,
Size::S64,
Location::XMM(tmp),
ret,
);
self.machine.release_temp_xmm(tmp);
} else {
let tmp = self.machine.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S64, loc, Location::GPR(tmp));
a.emit_btc_gpr_imm8_64(63, tmp);
a.emit_mov(Size::S64, Location::GPR(tmp), ret);
self.machine.release_temp_gpr(tmp);
}
}
Operator::F64PromoteF32 => Self::emit_fp_unop_avx(

View File

@@ -193,6 +193,10 @@ pub trait Emitter {
fn arch_emit_f64_convert_si64(&mut self, _src: GPR, _dst: XMM) { unimplemented!() }
fn arch_emit_f64_convert_ui32(&mut self, _src: GPR, _dst: XMM) { unimplemented!() }
fn arch_emit_f64_convert_ui64(&mut self, _src: GPR, _dst: XMM) { unimplemented!() }
fn arch_has_fneg(&self) -> bool { false }
fn arch_emit_f32_neg(&mut self, _src: XMM, _dst: XMM) { unimplemented!() }
fn arch_emit_f64_neg(&mut self, _src: XMM, _dst: XMM) { unimplemented!() }
}
fn _dummy(a: &mut Assembler) {

View File

@@ -1453,6 +1453,14 @@ impl Emitter for Assembler {
dynasm!(self ; ucvtf D(map_xmm(dst).v()), X(map_gpr(src).x()));
}
fn arch_has_fneg(&self) -> bool { true }
fn arch_emit_f32_neg(&mut self, src: XMM, dst: XMM) {
dynasm!(self ; fneg S(map_xmm(dst).v()), S(map_xmm(src).v()));
}
fn arch_emit_f64_neg(&mut self, src: XMM, dst: XMM) {
dynasm!(self ; fneg D(map_xmm(dst).v()), D(map_xmm(src).v()));
}
// These instructions are only used in itruncf-type/fconverti-type opcodes.
fn emit_btc_gpr_imm8_32(&mut self, src: u8, dst: GPR) {
unimplemented!();