[machinst x64]: implement packed not
This begins to use `Inst` helper functions as discussed in #2252.
This commit is contained in:
@@ -1105,6 +1105,33 @@ 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
|
/// 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],
|
/// 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.
|
/// [ExtKind::ZeroExtend]); loads with no extension necessary will ignore this.
|
||||||
|
|||||||
@@ -892,15 +892,18 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
|
|
||||||
Opcode::Bnot => {
|
Opcode::Bnot => {
|
||||||
let ty = ty.unwrap();
|
let ty = ty.unwrap();
|
||||||
|
let size = ty.bytes() as u8;
|
||||||
|
let src = put_input_in_reg(ctx, inputs[0]);
|
||||||
|
let dst = get_output_reg(ctx, outputs[0]);
|
||||||
|
ctx.emit(Inst::gen_move(dst, src, ty));
|
||||||
|
|
||||||
if ty.is_vector() {
|
if ty.is_vector() {
|
||||||
unimplemented!("vector bnot");
|
let tmp = ctx.alloc_tmp(RegClass::V128, ty);
|
||||||
|
ctx.emit(Inst::equals(ty, RegMem::from(tmp), tmp));
|
||||||
|
ctx.emit(Inst::xor(ty, RegMem::from(tmp), dst));
|
||||||
} else if ty.is_bool() {
|
} else if ty.is_bool() {
|
||||||
unimplemented!("bool bnot")
|
unimplemented!("bool bnot")
|
||||||
} else {
|
} else {
|
||||||
let size = ty.bytes() as u8;
|
|
||||||
let src = put_input_in_reg(ctx, inputs[0]);
|
|
||||||
let dst = get_output_reg(ctx, outputs[0]);
|
|
||||||
ctx.emit(Inst::gen_move(dst, src, ty));
|
|
||||||
ctx.emit(Inst::not(size, dst));
|
ctx.emit(Inst::not(size, dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user