mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-26 15:11:37 +00:00
Merge master.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ pub enum Condition {
|
||||
Signed,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum Size {
|
||||
S8,
|
||||
S16,
|
||||
@ -37,7 +37,7 @@ pub enum Size {
|
||||
S64,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[allow(dead_code)]
|
||||
pub enum XMMOrMemory {
|
||||
XMM(XMM),
|
||||
@ -80,6 +80,7 @@ pub trait Emitter {
|
||||
fn emit_cmp(&mut self, sz: Size, left: Location, right: Location);
|
||||
fn emit_add(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_neg(&mut self, sz: Size, value: Location);
|
||||
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_imul_imm32_gpr64(&mut self, src: u32, dst: GPR);
|
||||
fn emit_div(&mut self, sz: Size, divisor: Location);
|
||||
@ -91,11 +92,14 @@ pub trait Emitter {
|
||||
fn emit_ror(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_and(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_or(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_lzcnt(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_tzcnt(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_bsr(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_bsf(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_popcnt(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_movzx(&mut self, sz_src: Size, src: Location, sz_dst: Size, dst: Location);
|
||||
fn emit_movsx(&mut self, sz_src: Size, src: Location, sz_dst: Size, dst: Location);
|
||||
fn emit_xchg(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_lock_xadd(&mut self, sz: Size, src: Location, dst: Location);
|
||||
fn emit_lock_cmpxchg(&mut self, sz: Size, src: Location, dst: Location);
|
||||
|
||||
fn emit_btc_gpr_imm8_32(&mut self, src: u8, dst: GPR);
|
||||
fn emit_btc_gpr_imm8_64(&mut self, src: u8, dst: GPR);
|
||||
@ -103,6 +107,11 @@ pub trait Emitter {
|
||||
fn emit_cmovae_gpr_32(&mut self, src: GPR, dst: GPR);
|
||||
fn emit_cmovae_gpr_64(&mut self, src: GPR, dst: GPR);
|
||||
|
||||
fn emit_vmovaps(&mut self, src: XMMOrMemory, dst: XMMOrMemory);
|
||||
fn emit_vmovapd(&mut self, src: XMMOrMemory, dst: XMMOrMemory);
|
||||
fn emit_vxorps(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
fn emit_vxorpd(&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);
|
||||
fn emit_vsubss(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
@ -134,6 +143,12 @@ pub trait Emitter {
|
||||
fn emit_vcmpgess(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
fn emit_vcmpgesd(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
|
||||
fn emit_vcmpunordss(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
fn emit_vcmpunordsd(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
|
||||
fn emit_vcmpordss(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
fn emit_vcmpordsd(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
|
||||
fn emit_vsqrtss(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
fn emit_vsqrtsd(&mut self, src1: XMM, src2: XMMOrMemory, dst: XMM);
|
||||
|
||||
@ -162,6 +177,9 @@ pub trait Emitter {
|
||||
fn emit_vcvtsi2sd_32(&mut self, src1: XMM, src2: GPROrMemory, dst: XMM);
|
||||
fn emit_vcvtsi2sd_64(&mut self, src1: XMM, src2: GPROrMemory, dst: XMM);
|
||||
|
||||
fn emit_vblendvps(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM);
|
||||
fn emit_vblendvpd(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM);
|
||||
|
||||
fn emit_test_gpr_64(&mut self, reg: GPR);
|
||||
|
||||
fn emit_ud2(&mut self);
|
||||
@ -401,6 +419,14 @@ macro_rules! avx_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, Rx((x as u8))),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, Rx((x as u8))),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, Rx((x as u8))),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, Rx((x as u8))),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, Rx((x as u8))),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, Rx((x as u8))),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, Rx((x as u8))),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, Rx((x as u8))),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, Rx((x as u8))),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, Rx((x as u8))),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, Rx((x as u8))),
|
||||
},
|
||||
XMMOrMemory::Memory(base, disp) => match src1 {
|
||||
XMM::XMM0 => dynasm!(self ; $ins Rx((dst as u8)), xmm0, [Rq((base as u8)) + disp]),
|
||||
@ -411,6 +437,14 @@ macro_rules! avx_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, [Rq((base as u8)) + disp]),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, [Rq((base as u8)) + disp]),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -430,6 +464,14 @@ macro_rules! avx_i2f_64_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, Rq((x as u8))),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, Rq((x as u8))),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, Rq((x as u8))),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, Rq((x as u8))),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, Rq((x as u8))),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, Rq((x as u8))),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, Rq((x as u8))),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, Rq((x as u8))),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, Rq((x as u8))),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, Rq((x as u8))),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, Rq((x as u8))),
|
||||
},
|
||||
GPROrMemory::Memory(base, disp) => match src1 {
|
||||
XMM::XMM0 => dynasm!(self ; $ins Rx((dst as u8)), xmm0, QWORD [Rq((base as u8)) + disp]),
|
||||
@ -440,6 +482,14 @@ macro_rules! avx_i2f_64_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, QWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, QWORD [Rq((base as u8)) + disp]),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -459,6 +509,14 @@ macro_rules! avx_i2f_32_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, Rd((x as u8))),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, Rd((x as u8))),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, Rd((x as u8))),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, Rd((x as u8))),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, Rd((x as u8))),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, Rd((x as u8))),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, Rd((x as u8))),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, Rd((x as u8))),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, Rd((x as u8))),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, Rd((x as u8))),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, Rd((x as u8))),
|
||||
},
|
||||
GPROrMemory::Memory(base, disp) => match src1 {
|
||||
XMM::XMM0 => dynasm!(self ; $ins Rx((dst as u8)), xmm0, DWORD [Rq((base as u8)) + disp]),
|
||||
@ -469,6 +527,14 @@ macro_rules! avx_i2f_32_fn {
|
||||
XMM::XMM5 => dynasm!(self ; $ins Rx((dst as u8)), xmm5, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM6 => dynasm!(self ; $ins Rx((dst as u8)), xmm6, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM7 => dynasm!(self ; $ins Rx((dst as u8)), xmm7, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM8 => dynasm!(self ; $ins Rx((dst as u8)), xmm8, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM9 => dynasm!(self ; $ins Rx((dst as u8)), xmm9, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM10 => dynasm!(self ; $ins Rx((dst as u8)), xmm10, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM11 => dynasm!(self ; $ins Rx((dst as u8)), xmm11, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM12 => dynasm!(self ; $ins Rx((dst as u8)), xmm12, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM13 => dynasm!(self ; $ins Rx((dst as u8)), xmm13, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM14 => dynasm!(self ; $ins Rx((dst as u8)), xmm14, DWORD [Rq((base as u8)) + disp]),
|
||||
XMM::XMM15 => dynasm!(self ; $ins Rx((dst as u8)), xmm15, DWORD [Rq((base as u8)) + disp]),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -589,7 +655,7 @@ impl Emitter for Assembler {
|
||||
dynasm!(self ; movq Rx(dst as u8), Rx(src as u8));
|
||||
}
|
||||
|
||||
_ => panic!("MOV {:?} {:?} {:?}", sz, src, dst),
|
||||
_ => panic!("singlepass can't emit MOV {:?} {:?} {:?}", sz, src, dst),
|
||||
}
|
||||
})
|
||||
});
|
||||
@ -602,7 +668,7 @@ impl Emitter for Assembler {
|
||||
(Size::S64, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; lea Rq(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => panic!("singlepass can't emit LEA {:?} {:?} {:?}", sz, src, dst),
|
||||
}
|
||||
}
|
||||
fn emit_lea_label(&mut self, label: Self::Label, dst: Location) {
|
||||
@ -610,7 +676,7 @@ impl Emitter for Assembler {
|
||||
Location::GPR(x) => {
|
||||
dynasm!(self ; lea Rq(x as u8), [=>label]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => panic!("singlepass can't emit LEA label={:?} {:?}", label, dst),
|
||||
}
|
||||
}
|
||||
fn emit_cdq(&mut self) {
|
||||
@ -620,7 +686,9 @@ impl Emitter for Assembler {
|
||||
dynasm!(self ; cqo);
|
||||
}
|
||||
fn emit_xor(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(xor, self, sz, src, dst, { unreachable!() });
|
||||
binop_all_nofp!(xor, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit XOR {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_jmp(&mut self, condition: Condition, label: Self::Label) {
|
||||
match condition {
|
||||
@ -642,7 +710,7 @@ impl Emitter for Assembler {
|
||||
match loc {
|
||||
Location::GPR(x) => dynasm!(self ; jmp Rq(x as u8)),
|
||||
Location::Memory(base, disp) => dynasm!(self ; jmp QWORD [Rq(base as u8) + disp]),
|
||||
_ => unreachable!(),
|
||||
_ => panic!("singlepass can't emit JMP {:?}", loc),
|
||||
}
|
||||
}
|
||||
fn emit_conditional_trap(&mut self, condition: Condition) {
|
||||
@ -674,87 +742,126 @@ impl Emitter for Assembler {
|
||||
Condition::Equal => dynasm!(self ; sete Rb(dst as u8)),
|
||||
Condition::NotEqual => dynasm!(self ; setne Rb(dst as u8)),
|
||||
Condition::Signed => dynasm!(self ; sets Rb(dst as u8)),
|
||||
_ => unreachable!(),
|
||||
_ => panic!("singlepass can't emit SET {:?} {:?}", condition, dst),
|
||||
}
|
||||
}
|
||||
fn emit_push(&mut self, sz: Size, src: Location) {
|
||||
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])
|
||||
}
|
||||
_ => panic!("push {:?} {:?}", sz, src),
|
||||
(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])
|
||||
}
|
||||
_ => panic!("pop {:?} {:?}", sz, dst),
|
||||
(Size::S64, Location::Memory(dst, disp)) => dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]),
|
||||
_ => panic!("singlepass can't emit POP {:?} {:?}", sz, dst),
|
||||
}
|
||||
}
|
||||
fn emit_cmp(&mut self, sz: Size, left: Location, right: Location) {
|
||||
binop_all_nofp!(cmp, self, sz, left, right, {
|
||||
panic!("{:?} {:?} {:?}", sz, left, right);
|
||||
panic!("singlepass can't emit CMP {:?} {:?} {:?}", sz, left, right);
|
||||
});
|
||||
}
|
||||
fn emit_add(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(add, self, sz, src, dst, { unreachable!() });
|
||||
binop_all_nofp!(add, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit ADD {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_sub(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(sub, self, sz, src, dst, { unreachable!() });
|
||||
binop_all_nofp!(sub, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit SUB {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
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::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::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::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]),
|
||||
_ => panic!("singlepass can't emit NEG {:?} {:?}", sz, value),
|
||||
}
|
||||
}
|
||||
fn emit_imul(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(imul, self, sz, src, dst, {
|
||||
binop_mem_gpr!(imul, self, sz, src, dst, { unreachable!() })
|
||||
binop_mem_gpr!(imul, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit IMUL {:?} {:?} {:?}", sz, src, dst)
|
||||
})
|
||||
});
|
||||
}
|
||||
fn emit_imul_imm32_gpr64(&mut self, src: u32, dst: GPR) {
|
||||
dynasm!(self ; imul Rq(dst as u8), Rq(dst as u8), src as i32);
|
||||
}
|
||||
fn emit_div(&mut self, sz: Size, divisor: Location) {
|
||||
unop_gpr_or_mem!(div, self, sz, divisor, { unreachable!() });
|
||||
}
|
||||
fn emit_idiv(&mut self, sz: Size, divisor: Location) {
|
||||
unop_gpr_or_mem!(idiv, self, sz, divisor, { unreachable!() });
|
||||
}
|
||||
fn emit_shl(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(shl, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_shr(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(shr, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_sar(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(sar, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_rol(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(rol, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_ror(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(ror, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_and(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(and, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_or(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(or, self, sz, src, dst, { unreachable!() });
|
||||
}
|
||||
fn emit_lzcnt(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(lzcnt, self, sz, src, dst, {
|
||||
binop_mem_gpr!(lzcnt, self, sz, src, dst, { unreachable!() })
|
||||
unop_gpr_or_mem!(div, self, sz, divisor, {
|
||||
panic!("singlepass can't emit DIV {:?} {:?}", sz, divisor)
|
||||
});
|
||||
}
|
||||
fn emit_tzcnt(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(tzcnt, self, sz, src, dst, {
|
||||
binop_mem_gpr!(tzcnt, self, sz, src, dst, { unreachable!() })
|
||||
fn emit_idiv(&mut self, sz: Size, divisor: Location) {
|
||||
unop_gpr_or_mem!(idiv, self, sz, divisor, {
|
||||
panic!("singlepass can't emit IDIV {:?} {:?}", sz, divisor)
|
||||
});
|
||||
}
|
||||
fn emit_shl(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(shl, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit SHL {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_shr(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(shr, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit SHR {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_sar(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(sar, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit SAR {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_rol(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(rol, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit ROL {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_ror(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_shift!(ror, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit ROR {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_and(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(and, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit AND {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_or(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_all_nofp!(or, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit OR {:?} {:?} {:?}", sz, src, dst)
|
||||
});
|
||||
}
|
||||
fn emit_bsr(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(bsr, self, sz, src, dst, {
|
||||
binop_mem_gpr!(bsr, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit BSR {:?} {:?} {:?}", sz, src, dst)
|
||||
})
|
||||
});
|
||||
}
|
||||
fn emit_bsf(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(bsf, self, sz, src, dst, {
|
||||
binop_mem_gpr!(bsf, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit BSF {:?} {:?} {:?}", sz, src, dst)
|
||||
})
|
||||
});
|
||||
}
|
||||
fn emit_popcnt(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
binop_gpr_gpr!(popcnt, self, sz, src, dst, {
|
||||
binop_mem_gpr!(popcnt, self, sz, src, dst, { unreachable!() })
|
||||
binop_mem_gpr!(popcnt, self, sz, src, dst, {
|
||||
panic!("singlepass can't emit POPCNT {:?} {:?} {:?}", sz, src, dst)
|
||||
})
|
||||
});
|
||||
}
|
||||
fn emit_movzx(&mut self, sz_src: Size, src: Location, sz_dst: Size, dst: Location) {
|
||||
@ -783,7 +890,10 @@ impl Emitter for Assembler {
|
||||
(Size::S16, Location::Memory(src, disp), Size::S64, Location::GPR(dst)) => {
|
||||
dynasm!(self ; movzx Rq(dst as u8), WORD [Rq(src as u8) + disp]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => panic!(
|
||||
"singlepass can't emit MOVZX {:?} {:?} {:?} {:?}",
|
||||
sz_src, src, sz_dst, dst
|
||||
),
|
||||
}
|
||||
}
|
||||
fn emit_movsx(&mut self, sz_src: Size, src: Location, sz_dst: Size, dst: Location) {
|
||||
@ -818,7 +928,94 @@ impl Emitter for Assembler {
|
||||
(Size::S32, Location::Memory(src, disp), Size::S64, Location::GPR(dst)) => {
|
||||
dynasm!(self ; movsx Rq(dst as u8), DWORD [Rq(src as u8) + disp]);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
_ => panic!(
|
||||
"singlepass can't emit MOVSX {:?} {:?} {:?} {:?}",
|
||||
sz_src, src, sz_dst, dst
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_xchg(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
match (sz, src, dst) {
|
||||
(Size::S8, Location::GPR(src), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rb(dst as u8), Rb(src as u8));
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rw(dst as u8), Rw(src as u8));
|
||||
}
|
||||
(Size::S32, Location::GPR(src), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rd(dst as u8), Rd(src as u8));
|
||||
}
|
||||
(Size::S64, Location::GPR(src), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rq(dst as u8), Rq(src as u8));
|
||||
}
|
||||
(Size::S8, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rb(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S8, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; xchg [Rq(dst as u8) + disp], Rb(src as u8));
|
||||
}
|
||||
(Size::S16, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rw(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; xchg [Rq(dst as u8) + disp], Rw(src as u8));
|
||||
}
|
||||
(Size::S32, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rd(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S32, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; xchg [Rq(dst as u8) + disp], Rd(src as u8));
|
||||
}
|
||||
(Size::S64, Location::Memory(src, disp), Location::GPR(dst)) => {
|
||||
dynasm!(self ; xchg Rq(dst as u8), [Rq(src as u8) + disp]);
|
||||
}
|
||||
(Size::S64, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; xchg [Rq(dst as u8) + disp], Rq(src as u8));
|
||||
}
|
||||
_ => panic!("singlepass can't emit XCHG {:?} {:?} {:?}", sz, src, dst),
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_lock_xadd(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
match (sz, src, dst) {
|
||||
(Size::S8, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock xadd [Rq(dst as u8) + disp], Rb(src as u8));
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock xadd [Rq(dst as u8) + disp], Rw(src as u8));
|
||||
}
|
||||
(Size::S32, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock xadd [Rq(dst as u8) + disp], Rd(src as u8));
|
||||
}
|
||||
(Size::S64, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock xadd [Rq(dst as u8) + disp], Rq(src as u8));
|
||||
}
|
||||
_ => panic!(
|
||||
"singlepass can't emit LOCK XADD {:?} {:?} {:?}",
|
||||
sz, src, dst
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_lock_cmpxchg(&mut self, sz: Size, src: Location, dst: Location) {
|
||||
match (sz, src, dst) {
|
||||
(Size::S8, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock cmpxchg [Rq(dst as u8) + disp], Rb(src as u8));
|
||||
}
|
||||
(Size::S16, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock cmpxchg [Rq(dst as u8) + disp], Rw(src as u8));
|
||||
}
|
||||
(Size::S32, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock cmpxchg [Rq(dst as u8) + disp], Rd(src as u8));
|
||||
}
|
||||
(Size::S64, Location::GPR(src), Location::Memory(dst, disp)) => {
|
||||
dynasm!(self ; lock cmpxchg [Rq(dst as u8) + disp], Rq(src as u8));
|
||||
}
|
||||
_ => panic!(
|
||||
"singlepass can't emit LOCK CMPXCHG {:?} {:?} {:?}",
|
||||
sz, src, dst
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,6 +1035,27 @@ impl Emitter for Assembler {
|
||||
dynasm!(self ; cmovae Rq(dst as u8), Rq(src as u8));
|
||||
}
|
||||
|
||||
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)),
|
||||
_ => 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)),
|
||||
_ => panic!("singlepass can't emit VMOVAPD {:?} {:?}", src, dst),
|
||||
};
|
||||
}
|
||||
|
||||
avx_fn!(vxorps, emit_vxorps);
|
||||
avx_fn!(vxorpd, emit_vxorpd);
|
||||
|
||||
avx_fn!(vaddss, emit_vaddss);
|
||||
avx_fn!(vaddsd, emit_vaddsd);
|
||||
|
||||
@ -874,6 +1092,12 @@ impl Emitter for Assembler {
|
||||
avx_fn!(vcmpgess, emit_vcmpgess);
|
||||
avx_fn!(vcmpgesd, emit_vcmpgesd);
|
||||
|
||||
avx_fn!(vcmpunordss, emit_vcmpunordss);
|
||||
avx_fn!(vcmpunordsd, emit_vcmpunordsd);
|
||||
|
||||
avx_fn!(vcmpordss, emit_vcmpordss);
|
||||
avx_fn!(vcmpordsd, emit_vcmpordsd);
|
||||
|
||||
avx_fn!(vsqrtss, emit_vsqrtss);
|
||||
avx_fn!(vsqrtsd, emit_vsqrtsd);
|
||||
|
||||
@ -894,57 +1118,59 @@ impl Emitter for Assembler {
|
||||
avx_i2f_64_fn!(vcvtsi2ss, emit_vcvtsi2ss_64);
|
||||
avx_i2f_64_fn!(vcvtsi2sd, emit_vcvtsi2sd_64);
|
||||
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
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)),
|
||||
}
|
||||
}
|
||||
|
||||
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]),
|
||||
}
|
||||
}
|
||||
|
||||
@ -966,7 +1192,7 @@ impl Emitter for Assembler {
|
||||
match loc {
|
||||
Location::GPR(x) => dynasm!(self ; call Rq(x as u8)),
|
||||
Location::Memory(base, disp) => dynasm!(self ; call QWORD [Rq(base as u8) + disp]),
|
||||
_ => unreachable!(),
|
||||
_ => panic!("singlepass can't emit CALL {:?}", loc),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::emitter_x64::*;
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::HashSet;
|
||||
use wasmer_runtime_core::state::x64::X64Register;
|
||||
use wasmer_runtime_core::state::*;
|
||||
use wasmparser::Type as WpType;
|
||||
use wasmer_runtime_core::{
|
||||
state::{x64::X64Register, *},
|
||||
wasmparser::Type as WpType,
|
||||
};
|
||||
|
||||
struct MachineStackOffset(usize);
|
||||
|
||||
@ -83,7 +84,14 @@ impl Machine {
|
||||
|
||||
/// Releases a temporary GPR.
|
||||
pub fn release_temp_gpr(&mut self, gpr: GPR) {
|
||||
assert_eq!(self.used_gprs.remove(&gpr), true);
|
||||
assert!(self.used_gprs.remove(&gpr));
|
||||
}
|
||||
|
||||
/// Specify that a given register is in use.
|
||||
pub fn reserve_unused_temp_gpr(&mut self, gpr: GPR) -> GPR {
|
||||
assert!(!self.used_gprs.contains(&gpr));
|
||||
self.used_gprs.insert(gpr);
|
||||
gpr
|
||||
}
|
||||
|
||||
/// Picks an unused XMM register.
|
||||
|
Reference in New Issue
Block a user