pub mod arm64;
pub mod arm64_enc;
pub mod c;
pub mod glsl;
pub mod hlsl;
pub mod llvm;
pub mod spirv;
pub mod wasm;
pub mod x86_64;
pub mod x86_64_enc;
use std::fmt;
use thiserror::Error;
use super::ir::MirModule;
use super::GeneratedCode;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Target {
C,
X86_64,
Arm64,
Wasm,
SpirV,
LlvmIr,
Hlsl,
Glsl,
}
impl Target {
pub fn extension(&self) -> &'static str {
match self {
Target::C => "c",
Target::X86_64 | Target::Arm64 => "o",
Target::Wasm => "wasm",
Target::SpirV => "spv",
Target::LlvmIr => "ll",
Target::Hlsl => "hlsl",
Target::Glsl => "glsl",
}
}
pub fn pointer_size(&self) -> u32 {
match self {
Target::C => 64, Target::X86_64 => 64,
Target::Arm64 => 64,
Target::Wasm => 32, Target::SpirV => 64,
Target::LlvmIr => 64, Target::Hlsl | Target::Glsl => 32, }
}
pub fn is_native(&self) -> bool {
matches!(self, Target::X86_64 | Target::Arm64)
}
pub fn is_ir(&self) -> bool {
matches!(self, Target::LlvmIr)
}
}
impl fmt::Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Target::C => write!(f, "c"),
Target::X86_64 => write!(f, "x86_64"),
Target::Arm64 => write!(f, "arm64"),
Target::Wasm => write!(f, "wasm"),
Target::SpirV => write!(f, "spirv"),
Target::LlvmIr => write!(f, "llvm-ir"),
Target::Hlsl => write!(f, "hlsl"),
Target::Glsl => write!(f, "glsl"),
}
}
}
#[derive(Debug, Clone, Error)]
pub enum CodegenError {
#[error("internal error: {0}")]
Internal(String),
#[error("unsupported feature: {0}")]
Unsupported(String),
#[error("invalid MIR: {0}")]
InvalidMir(String),
#[error("type error: {0}")]
TypeError(String),
#[error("missing function: {0}")]
MissingFunction(String),
#[error("missing type: {0}")]
MissingType(String),
}
pub type CodegenResult<T> = Result<T, CodegenError>;
pub trait Backend {
fn generate(&mut self, mir: &MirModule) -> CodegenResult<GeneratedCode>;
fn target(&self) -> Target;
}