Merge remote-tracking branch 'origin/master' into feature/singlepass-aarch64

This commit is contained in:
losfair
2019-11-20 01:54:34 +08:00
33 changed files with 457 additions and 371 deletions

View File

@ -857,32 +857,34 @@ impl X64FunctionCode {
sz_dst: Size,
dst: Location,
) {
let tmp_src = m.acquire_temp_gpr().unwrap();
let tmp_dst = m.acquire_temp_gpr().unwrap();
match src {
Location::Imm32(_) | Location::Imm64(_) => {
a.emit_mov(Size::S64, src, Location::GPR(tmp_src));
src = Location::GPR(tmp_src);
}
Location::Memory(_, _) | Location::GPR(_) => {}
_ => unreachable!(),
}
match dst {
let inner = |m: &mut Machine, a: &mut Assembler, src: Location| match dst {
Location::Imm32(_) | Location::Imm64(_) => unreachable!(),
Location::Memory(_, _) => {
let tmp_dst = m.acquire_temp_gpr().unwrap();
op(a, sz_src, src, sz_dst, Location::GPR(tmp_dst));
a.emit_mov(Size::S64, Location::GPR(tmp_dst), dst);
m.release_temp_gpr(tmp_dst);
}
Location::GPR(_) => {
op(a, sz_src, src, sz_dst, dst);
}
_ => unreachable!(),
}
};
m.release_temp_gpr(tmp_dst);
m.release_temp_gpr(tmp_src);
match src {
Location::Imm32(_) | Location::Imm64(_) => {
let tmp_src = m.acquire_temp_gpr().unwrap();
a.emit_mov(Size::S64, src, Location::GPR(tmp_src));
src = Location::GPR(tmp_src);
inner(m, a, src);
m.release_temp_gpr(tmp_src);
}
Location::GPR(_) | Location::Memory(_, _) => inner(m, a, src),
_ => unreachable!(),
}
}
/// Moves `src` and `dst` to valid locations for generic instructions.
@ -3173,6 +3175,106 @@ impl FunctionCodeGenerator<CodegenError> for X64FunctionCode {
ret,
);
}
Operator::I32Extend8S => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
Self::emit_relaxed_zx_sx(
a,
&mut self.machine,
Assembler::emit_movsx,
Size::S8,
loc,
Size::S32,
ret,
);
}
Operator::I32Extend16S => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&[(WpType::I32, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
Self::emit_relaxed_zx_sx(
a,
&mut self.machine,
Assembler::emit_movsx,
Size::S16,
loc,
Size::S32,
ret,
);
}
Operator::I64Extend8S => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
Self::emit_relaxed_zx_sx(
a,
&mut self.machine,
Assembler::emit_movsx,
Size::S8,
loc,
Size::S64,
ret,
);
}
Operator::I64Extend16S => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
Self::emit_relaxed_zx_sx(
a,
&mut self.machine,
Assembler::emit_movsx,
Size::S16,
loc,
Size::S64,
ret,
);
}
Operator::I64Extend32S => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());
let ret = self.machine.acquire_locations(
a,
&[(WpType::I64, MachineValue::WasmStack(self.value_stack.len()))],
false,
)[0];
self.value_stack.push(ret);
Self::emit_relaxed_zx_sx(
a,
&mut self.machine,
Assembler::emit_movsx,
Size::S32,
loc,
Size::S64,
ret,
);
}
Operator::I32WrapI64 => {
let loc =
get_location_released(a, &mut self.machine, self.value_stack.pop().unwrap());

View File

@ -809,18 +809,14 @@ impl Emitter for Assembler {
match (sz, src) {
(Size::S64, Location::Imm32(src)) => dynasm!(self ; push src as i32),
(Size::S64, Location::GPR(src)) => dynasm!(self ; push Rq(src as u8)),
(Size::S64, Location::Memory(src, disp)) => {
dynasm!(self ; push QWORD [Rq(src as u8) + disp])
}
(Size::S64, Location::Memory(src, disp)) => dynasm!(self ; push QWORD [Rq(src as u8) + disp]),
_ => panic!("singlepass can't emit PUSH {:?} {:?}", sz, src),
}
}
fn emit_pop(&mut self, sz: Size, dst: Location) {
match (sz, dst) {
(Size::S64, Location::GPR(dst)) => dynasm!(self ; pop Rq(dst as u8)),
(Size::S64, Location::Memory(dst, disp)) => {
dynasm!(self ; pop QWORD [Rq(dst as u8) + disp])
}
(Size::S64, Location::Memory(dst, disp)) => dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]),
_ => panic!("singlepass can't emit POP {:?} {:?}", sz, dst),
}
}
@ -842,21 +838,13 @@ impl Emitter for Assembler {
fn emit_neg(&mut self, sz: Size, value: Location) {
match (sz, value) {
(Size::S8, Location::GPR(value)) => dynasm!(self ; neg Rb(value as u8)),
(Size::S8, Location::Memory(value, disp)) => {
dynasm!(self ; neg [Rq(value as u8) + disp])
}
(Size::S8, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]),
(Size::S16, Location::GPR(value)) => dynasm!(self ; neg Rw(value as u8)),
(Size::S16, Location::Memory(value, disp)) => {
dynasm!(self ; neg [Rq(value as u8) + disp])
}
(Size::S16, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]),
(Size::S32, Location::GPR(value)) => dynasm!(self ; neg Rd(value as u8)),
(Size::S32, Location::Memory(value, disp)) => {
dynasm!(self ; neg [Rq(value as u8) + disp])
}
(Size::S32, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]),
(Size::S64, Location::GPR(value)) => dynasm!(self ; neg Rq(value as u8)),
(Size::S64, Location::Memory(value, disp)) => {
dynasm!(self ; neg [Rq(value as u8) + disp])
}
(Size::S64, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]),
_ => panic!("singlepass can't emit NEG {:?} {:?}", sz, value),
}
}
@ -1109,30 +1097,18 @@ impl Emitter for Assembler {
fn emit_vmovaps(&mut self, src: XMMOrMemory, dst: XMMOrMemory) {
match (src, dst) {
(XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => {
dynasm!(self ; movaps Rx(dst as u8), Rx(src as u8))
}
(XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => {
dynasm!(self ; movaps Rx(dst as u8), [Rq(base as u8) + disp])
}
(XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => {
dynasm!(self ; movaps [Rq(base as u8) + disp], Rx(src as u8))
}
(XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => dynasm!(self ; movaps Rx(dst as u8), Rx(src as u8)),
(XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => dynasm!(self ; movaps Rx(dst as u8), [Rq(base as u8) + disp]),
(XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => dynasm!(self ; movaps [Rq(base as u8) + disp], Rx(src as u8)),
_ => panic!("singlepass can't emit VMOVAPS {:?} {:?}", src, dst),
};
}
fn emit_vmovapd(&mut self, src: XMMOrMemory, dst: XMMOrMemory) {
match (src, dst) {
(XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => {
dynasm!(self ; movapd Rx(dst as u8), Rx(src as u8))
}
(XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => {
dynasm!(self ; movapd Rx(dst as u8), [Rq(base as u8) + disp])
}
(XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => {
dynasm!(self ; movapd [Rq(base as u8) + disp], Rx(src as u8))
}
(XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => dynasm!(self ; movapd Rx(dst as u8), Rx(src as u8)),
(XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => dynasm!(self ; movapd Rx(dst as u8), [Rq(base as u8) + disp]),
(XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => dynasm!(self ; movapd [Rq(base as u8) + disp], Rx(src as u8)),
_ => panic!("singlepass can't emit VMOVAPD {:?} {:?}", src, dst),
};
}
@ -1204,77 +1180,57 @@ impl Emitter for Assembler {
fn emit_vblendvps(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM) {
match src2 {
XMMOrMemory::XMM(src2) => {
dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8))
}
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8))
}
XMMOrMemory::XMM(src2) => dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)),
XMMOrMemory::Memory(base, disp) => dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)),
}
}
fn emit_vblendvpd(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM) {
match src2 {
XMMOrMemory::XMM(src2) => {
dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8))
}
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8))
}
XMMOrMemory::XMM(src2) => dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)),
XMMOrMemory::Memory(base, disp) => dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)),
}
}
fn emit_ucomiss(&mut self, src: XMMOrMemory, dst: XMM) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; ucomiss Rx(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp]),
}
}
fn emit_ucomisd(&mut self, src: XMMOrMemory, dst: XMM) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; ucomisd Rx(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp]),
}
}
fn emit_cvttss2si_32(&mut self, src: XMMOrMemory, dst: GPR) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rd(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp]),
}
}
fn emit_cvttss2si_64(&mut self, src: XMMOrMemory, dst: GPR) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rq(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp]),
}
}
fn emit_cvttsd2si_32(&mut self, src: XMMOrMemory, dst: GPR) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rd(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp]),
}
}
fn emit_cvttsd2si_64(&mut self, src: XMMOrMemory, dst: GPR) {
match src {
XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rq(dst as u8), Rx(x as u8)),
XMMOrMemory::Memory(base, disp) => {
dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp])
}
XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp]),
}
}