Merge pull request #2626 from bnjbvr/x64-new-iset-requirements

cranelift x64: add instruction set checks for popcnt/tzcnt/lzcnt
This commit is contained in:
Chris Fallin
2021-01-30 10:39:31 -08:00
committed by GitHub
3 changed files with 24 additions and 4 deletions

View File

@@ -410,6 +410,17 @@ pub enum UnaryRmROpcode {
Popcnt,
}
impl UnaryRmROpcode {
pub(crate) fn available_from(&self) -> Option<InstructionSet> {
match self {
UnaryRmROpcode::Bsr | UnaryRmROpcode::Bsf => None,
UnaryRmROpcode::Lzcnt => Some(InstructionSet::Lzcnt),
UnaryRmROpcode::Tzcnt => Some(InstructionSet::BMI1),
UnaryRmROpcode::Popcnt => Some(InstructionSet::Popcnt),
}
}
}
impl fmt::Debug for UnaryRmROpcode {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
@@ -442,6 +453,10 @@ pub(crate) enum InstructionSet {
SSSE3,
SSE41,
SSE42,
Popcnt,
Lzcnt,
BMI1,
BMI2,
}
/// Some SSE operations requiring 2 operands r/m and r.

View File

@@ -529,9 +529,13 @@ pub(crate) fn emit(
match iset_requirement {
// Cranelift assumes SSE2 at least.
InstructionSet::SSE | InstructionSet::SSE2 => {}
InstructionSet::SSSE3 => assert!(info.isa_flags.has_ssse3()),
InstructionSet::SSE41 => assert!(info.isa_flags.has_sse41()),
InstructionSet::SSE42 => assert!(info.isa_flags.has_sse42()),
InstructionSet::SSSE3 => assert!(info.isa_flags.use_ssse3()),
InstructionSet::SSE41 => assert!(info.isa_flags.use_sse41()),
InstructionSet::SSE42 => assert!(info.isa_flags.use_sse42()),
InstructionSet::Popcnt => assert!(info.isa_flags.use_popcnt()),
InstructionSet::Lzcnt => assert!(info.isa_flags.use_lzcnt()),
InstructionSet::BMI1 => assert!(info.isa_flags.use_bmi1()),
InstructionSet::BMI2 => assert!(info.isa_flags.has_bmi2()),
}
}

View File

@@ -539,7 +539,6 @@ impl Inst {
| Inst::SignExtendData { .. }
| Inst::TrapIf { .. }
| Inst::Ud2 { .. }
| Inst::UnaryRmR { .. }
| Inst::VirtualSPOffsetAdj { .. }
| Inst::XmmCmove { .. }
| Inst::XmmCmpRmR { .. }
@@ -550,6 +549,8 @@ impl Inst {
| Inst::MachOTlsGetAddr { .. }
| Inst::ValueLabelMarker { .. } => None,
Inst::UnaryRmR { op, .. } => op.available_from(),
// These use dynamic SSE opcodes.
Inst::GprToXmm { op, .. }
| Inst::XmmMovRM { op, .. }