Allow both x86 backends to be included, selected with a "variant" flag. (#2514)
This PR adds a new `isa::lookup_variant()` that takes a `BackendVariant` (`Legacy`, `MachInst` or `Any`), and exposes both x86 backends as separate variants if both are compiled into the build. This will allow some new use-cases that require both backends in the same process: for example, differential fuzzing between old and new backends, or perhaps allowing for dynamic feature-flag selection between the backends.
This commit is contained in:
@@ -75,10 +75,13 @@ use thiserror::Error;
|
||||
#[cfg(feature = "riscv")]
|
||||
mod riscv;
|
||||
|
||||
// Exclude the old x86 backend when the new one is enabled; it is unreachable
|
||||
// anyway (requesting the x86-64 ISA will return the new backend), and a number
|
||||
// of old-backend-specific tests fail.
|
||||
#[cfg(all(feature = "x86", not(feature = "x64")))]
|
||||
// N.B.: the old x86-64 backend (`x86`) and the new one (`x64`) can both be
|
||||
// included; if the new backend is included, then it is the default backend
|
||||
// returned for an x86-64 triple, but a specific option can request the old
|
||||
// backend. It is important to have the ability to instantiate *both* backends
|
||||
// in the same build so that we can do things like differential fuzzing between
|
||||
// backends, or perhaps offer a runtime configuration flag in the future.
|
||||
#[cfg(feature = "x86")]
|
||||
mod x86;
|
||||
|
||||
#[cfg(feature = "x64")]
|
||||
@@ -117,24 +120,56 @@ macro_rules! isa_builder {
|
||||
}};
|
||||
}
|
||||
|
||||
/// The "variant" for a given target. On one platform (x86-64), we have two
|
||||
/// backends, the "old" and "new" one; the new one is the default if included
|
||||
/// in the build configuration and not otherwise specified.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum BackendVariant {
|
||||
/// Any backend available.
|
||||
Any,
|
||||
/// A "legacy" backend: one that operates using legalizations and encodings.
|
||||
Legacy,
|
||||
/// A backend built on `MachInst`s and the `VCode` framework.
|
||||
MachInst,
|
||||
}
|
||||
|
||||
impl Default for BackendVariant {
|
||||
fn default() -> Self {
|
||||
BackendVariant::Any
|
||||
}
|
||||
}
|
||||
|
||||
/// Look for an ISA for the given `triple`, selecting the backend variant given
|
||||
/// by `variant` if available.
|
||||
pub fn lookup_variant(triple: Triple, variant: BackendVariant) -> Result<Builder, LookupError> {
|
||||
match (triple.architecture, variant) {
|
||||
(Architecture::Riscv32 { .. }, _) | (Architecture::Riscv64 { .. }, _) => {
|
||||
isa_builder!(riscv, (feature = "riscv"), triple)
|
||||
}
|
||||
(Architecture::X86_64, BackendVariant::Legacy) => {
|
||||
isa_builder!(x86, (feature = "x86"), triple)
|
||||
}
|
||||
(Architecture::X86_64, BackendVariant::MachInst) => {
|
||||
isa_builder!(x64, (feature = "x64"), triple)
|
||||
}
|
||||
#[cfg(feature = "x64")]
|
||||
(Architecture::X86_64, BackendVariant::Any) => {
|
||||
isa_builder!(x64, (feature = "x64"), triple)
|
||||
}
|
||||
#[cfg(not(feature = "x64"))]
|
||||
(Architecture::X86_64, BackendVariant::Any) => {
|
||||
isa_builder!(x86, (feature = "x86"), triple)
|
||||
}
|
||||
(Architecture::Arm { .. }, _) => isa_builder!(arm32, (feature = "arm32"), triple),
|
||||
(Architecture::Aarch64 { .. }, _) => isa_builder!(aarch64, (feature = "arm64"), triple),
|
||||
_ => Err(LookupError::Unsupported),
|
||||
}
|
||||
}
|
||||
|
||||
/// Look for an ISA for the given `triple`.
|
||||
/// Return a builder that can create a corresponding `TargetIsa`.
|
||||
pub fn lookup(triple: Triple) -> Result<Builder, LookupError> {
|
||||
match triple.architecture {
|
||||
Architecture::Riscv32 { .. } | Architecture::Riscv64 { .. } => {
|
||||
isa_builder!(riscv, (feature = "riscv"), triple)
|
||||
}
|
||||
Architecture::X86_32 { .. } | Architecture::X86_64 => {
|
||||
if cfg!(feature = "x64") {
|
||||
isa_builder!(x64, (feature = "x64"), triple)
|
||||
} else {
|
||||
isa_builder!(x86, (all(feature = "x86", not(feature = "x64"))), triple)
|
||||
}
|
||||
}
|
||||
Architecture::Arm { .. } => isa_builder!(arm32, (feature = "arm32"), triple),
|
||||
Architecture::Aarch64 { .. } => isa_builder!(aarch64, (feature = "arm64"), triple),
|
||||
_ => Err(LookupError::Unsupported),
|
||||
}
|
||||
lookup_variant(triple, BackendVariant::Any)
|
||||
}
|
||||
|
||||
/// Look for a supported ISA with the given `name`.
|
||||
|
||||
Reference in New Issue
Block a user