use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CodegenCapability {
IntegerArithmetic,
FloatingPointArithmetic,
ControlFlow,
FunctionCalls,
Recursion,
Print,
HeapAllocation,
StackAllocation,
MemoryOperations,
SimdOperations,
AtomicOperations,
SystemCalls,
InlineAssembly,
ExceptionHandling,
Threading,
GarbageCollection,
ForeignFunctionInterface,
DebugInfo,
TailCallOptimization,
}
impl CodegenCapability {
pub fn description(&self) -> &'static str {
match self {
Self::IntegerArithmetic => "Integer arithmetic operations",
Self::FloatingPointArithmetic => "Floating-point arithmetic operations",
Self::ControlFlow => "Control flow (branches, jumps, loops)",
Self::FunctionCalls => "Function calls",
Self::Recursion => "Recursive function calls",
Self::Print => "Print/log output",
Self::HeapAllocation => "Heap memory allocation",
Self::StackAllocation => "Stack allocation",
Self::MemoryOperations => "Memory load/store operations",
Self::SimdOperations => "SIMD/Vector operations",
Self::AtomicOperations => "Atomic operations",
Self::SystemCalls => "System calls",
Self::InlineAssembly => "Inline assembly",
Self::ExceptionHandling => "Exception handling",
Self::Threading => "Threads/parallelism",
Self::GarbageCollection => "Garbage collection integration",
Self::ForeignFunctionInterface => "Foreign function interface (FFI)",
Self::DebugInfo => "Debug information generation",
Self::TailCallOptimization => "Tail call optimization",
}
}
pub fn is_core(&self) -> bool {
matches!(
self,
Self::IntegerArithmetic | Self::ControlFlow | Self::FunctionCalls
)
}
}
impl fmt::Display for CodegenCapability {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description())
}
}
#[derive(Debug, Clone, Default)]
pub struct CapabilitySet {
capabilities: std::collections::HashSet<CodegenCapability>,
}
impl CapabilitySet {
pub fn new() -> Self {
Self::default()
}
pub fn core() -> Self {
let mut set = Self::new();
set.add(CodegenCapability::IntegerArithmetic);
set.add(CodegenCapability::ControlFlow);
set.add(CodegenCapability::FunctionCalls);
set
}
pub fn add(&mut self, cap: CodegenCapability) {
self.capabilities.insert(cap);
}
pub fn remove(&mut self, cap: &CodegenCapability) {
self.capabilities.remove(cap);
}
pub fn supports(&self, cap: &CodegenCapability) -> bool {
self.capabilities.contains(cap)
}
pub fn all(&self) -> impl Iterator<Item = &CodegenCapability> {
self.capabilities.iter()
}
pub fn unsupported<'a>(&self, required: &'a [CodegenCapability]) -> Vec<&'a CodegenCapability> {
required.iter().filter(|cap| !self.supports(cap)).collect()
}
}
impl FromIterator<CodegenCapability> for CapabilitySet {
fn from_iter<T: IntoIterator<Item = CodegenCapability>>(iter: T) -> Self {
Self {
capabilities: iter.into_iter().collect(),
}
}
}
impl CapabilitySet {
pub fn standard_native() -> Self {
[
CodegenCapability::IntegerArithmetic,
CodegenCapability::FloatingPointArithmetic,
CodegenCapability::ControlFlow,
CodegenCapability::FunctionCalls,
CodegenCapability::Recursion,
CodegenCapability::Print,
CodegenCapability::StackAllocation,
CodegenCapability::MemoryOperations,
CodegenCapability::SystemCalls,
CodegenCapability::InlineAssembly,
CodegenCapability::ForeignFunctionInterface,
CodegenCapability::DebugInfo,
]
.into_iter()
.collect()
}
pub fn for_architecture(arch: lamina_platform::TargetArchitecture) -> Self {
use lamina_platform::TargetArchitecture;
match arch {
TargetArchitecture::X86_64
| TargetArchitecture::Aarch64
| TargetArchitecture::Arx64
| TargetArchitecture::Riscv32
| TargetArchitecture::Riscv64 => Self::standard_native(),
#[cfg(feature = "nightly")]
TargetArchitecture::Riscv128 => Self::standard_native(),
TargetArchitecture::PowerPC64 => Self::standard_native(),
TargetArchitecture::Wasm32 | TargetArchitecture::Wasm64 => Self::wasm(),
_ => Self::core(),
}
}
pub fn extended_native() -> Self {
let mut set = Self::standard_native();
set.capabilities.insert(CodegenCapability::SimdOperations);
set
}
pub fn wasm() -> Self {
[
CodegenCapability::IntegerArithmetic,
CodegenCapability::FloatingPointArithmetic,
CodegenCapability::ControlFlow,
CodegenCapability::FunctionCalls,
CodegenCapability::Recursion,
CodegenCapability::Print,
CodegenCapability::MemoryOperations,
]
.into_iter()
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_capability_set() {
let mut caps = CapabilitySet::new();
caps.add(CodegenCapability::IntegerArithmetic);
caps.add(CodegenCapability::Print);
assert!(caps.supports(&CodegenCapability::IntegerArithmetic));
assert!(caps.supports(&CodegenCapability::Print));
assert!(!caps.supports(&CodegenCapability::HeapAllocation));
}
#[test]
fn test_core_capabilities() {
let caps = CapabilitySet::core();
assert!(caps.supports(&CodegenCapability::IntegerArithmetic));
assert!(caps.supports(&CodegenCapability::ControlFlow));
assert!(caps.supports(&CodegenCapability::FunctionCalls));
}
}