|
|
@ -1105,33 +1105,6 @@ impl Inst { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for comparing two values for equality.
|
|
|
|
pub(crate) fn equals(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::I8X16 => Inst::xmm_rm_r(SseOpcode::Pcmpeqb, from, to), |
|
|
|
types::I16X8 => Inst::xmm_rm_r(SseOpcode::Pcmpeqw, from, to), |
|
|
|
types::I32X4 => Inst::xmm_rm_r(SseOpcode::Pcmpeqd, from, to), |
|
|
|
types::I64X2 => Inst::xmm_rm_r(SseOpcode::Pcmpeqq, from, to), |
|
|
|
types::F32X4 => { |
|
|
|
Inst::xmm_rm_r_imm(SseOpcode::Cmpps, from, to, FcmpImm::Equal.encode(), false) |
|
|
|
} |
|
|
|
types::F64X2 => { |
|
|
|
Inst::xmm_rm_r_imm(SseOpcode::Cmppd, from, to, FcmpImm::Equal.encode(), false) |
|
|
|
} |
|
|
|
_ => unimplemented!("unimplemented type for Inst::equals: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for computing a bitwise XOR on two values.
|
|
|
|
pub(crate) fn xor(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::F32X4 => Inst::xmm_rm_r(SseOpcode::Xorps, from, to), |
|
|
|
types::F64X2 => Inst::xmm_rm_r(SseOpcode::Xorpd, from, to), |
|
|
|
_ if ty.is_vector() => Inst::xmm_rm_r(SseOpcode::Pxor, from, to), |
|
|
|
_ => unimplemented!("unimplemented type for Inst::xor: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for loading a register value from memory. For loads smaller
|
|
|
|
/// than 64 bits, this method expects a way to extend the value (i.e. [ExtKind::SignExtend],
|
|
|
|
/// [ExtKind::ZeroExtend]); loads with no extension necessary will ignore this.
|
|
|
@ -1256,6 +1229,63 @@ impl Inst { |
|
|
|
_ => false, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for comparing two values for equality.
|
|
|
|
pub(crate) fn equals(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::I8X16 | types::B8X16 => Inst::xmm_rm_r(SseOpcode::Pcmpeqb, from, to), |
|
|
|
types::I16X8 | types::B16X8 => Inst::xmm_rm_r(SseOpcode::Pcmpeqw, from, to), |
|
|
|
types::I32X4 | types::B32X4 => Inst::xmm_rm_r(SseOpcode::Pcmpeqd, from, to), |
|
|
|
types::I64X2 | types::B64X2 => Inst::xmm_rm_r(SseOpcode::Pcmpeqq, from, to), |
|
|
|
types::F32X4 => { |
|
|
|
Inst::xmm_rm_r_imm(SseOpcode::Cmpps, from, to, FcmpImm::Equal.encode(), false) |
|
|
|
} |
|
|
|
types::F64X2 => { |
|
|
|
Inst::xmm_rm_r_imm(SseOpcode::Cmppd, from, to, FcmpImm::Equal.encode(), false) |
|
|
|
} |
|
|
|
_ => unimplemented!("unimplemented type for Inst::equals: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for computing a bitwise AND on two values.
|
|
|
|
pub(crate) fn and(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::F32X4 => Inst::xmm_rm_r(SseOpcode::Andps, from, to), |
|
|
|
types::F64X2 => Inst::xmm_rm_r(SseOpcode::Andpd, from, to), |
|
|
|
_ if ty.is_vector() && ty.bits() == 128 => Inst::xmm_rm_r(SseOpcode::Pand, from, to), |
|
|
|
_ => unimplemented!("unimplemented type for Inst::and: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for computing a bitwise AND NOT on two values.
|
|
|
|
pub(crate) fn and_not(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::F32X4 => Inst::xmm_rm_r(SseOpcode::Andnps, from, to), |
|
|
|
types::F64X2 => Inst::xmm_rm_r(SseOpcode::Andnpd, from, to), |
|
|
|
_ if ty.is_vector() && ty.bits() == 128 => Inst::xmm_rm_r(SseOpcode::Pandn, from, to), |
|
|
|
_ => unimplemented!("unimplemented type for Inst::and_not: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for computing a bitwise OR on two values.
|
|
|
|
pub(crate) fn or(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::F32X4 => Inst::xmm_rm_r(SseOpcode::Orps, from, to), |
|
|
|
types::F64X2 => Inst::xmm_rm_r(SseOpcode::Orpd, from, to), |
|
|
|
_ if ty.is_vector() && ty.bits() == 128 => Inst::xmm_rm_r(SseOpcode::Por, from, to), |
|
|
|
_ => unimplemented!("unimplemented type for Inst::or: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Choose which instruction to use for computing a bitwise XOR on two values.
|
|
|
|
pub(crate) fn xor(ty: Type, from: RegMem, to: Writable<Reg>) -> Inst { |
|
|
|
match ty { |
|
|
|
types::F32X4 => Inst::xmm_rm_r(SseOpcode::Xorps, from, to), |
|
|
|
types::F64X2 => Inst::xmm_rm_r(SseOpcode::Xorpd, from, to), |
|
|
|
_ if ty.is_vector() && ty.bits() == 128 => Inst::xmm_rm_r(SseOpcode::Pxor, from, to), |
|
|
|
_ => unimplemented!("unimplemented type for Inst::xor: {}", ty), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|