Path: blob/main/winch/codegen/src/isa/aarch64/mod.rs
1692 views
use self::regs::{fpr_bit_set, gpr_bit_set};1use crate::{2BuiltinFunctions,3abi::{ABI, wasm_sig},4codegen::{CodeGen, CodeGenContext, FuncEnv, TypeConverter},5frame::{DefinedLocals, Frame},6isa::{Builder, TargetIsa},7masm::MacroAssembler,8regalloc::RegAlloc,9stack::Stack,10};11use anyhow::Result;12use cranelift_codegen::settings::{self, Flags};13use cranelift_codegen::{Final, MachBufferFinalized, isa::aarch64::settings as aarch64_settings};14use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};15use masm::MacroAssembler as Aarch64Masm;16use target_lexicon::Triple;17use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};18use wasmtime_cranelift::CompiledFunction;19use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};2021mod abi;22mod address;23mod asm;24mod masm;25mod regs;2627/// Create an ISA from the given triple.28pub(crate) fn isa_builder(triple: Triple) -> Builder {29Builder::new(30triple,31aarch64_settings::builder(),32|triple, shared_flags, settings| {33let isa_flags = aarch64_settings::Flags::new(&shared_flags, settings);34let isa = Aarch64::new(triple, shared_flags, isa_flags);35Ok(Box::new(isa))36},37)38}3940/// Aarch64 ISA.41pub(crate) struct Aarch64 {42/// The target triple.43triple: Triple,44/// ISA specific flags.45isa_flags: aarch64_settings::Flags,46/// Shared flags.47shared_flags: Flags,48}4950impl Aarch64 {51/// Create an Aarch64 ISA.52pub fn new(triple: Triple, shared_flags: Flags, isa_flags: aarch64_settings::Flags) -> Self {53Self {54isa_flags,55shared_flags,56triple,57}58}59}6061impl TargetIsa for Aarch64 {62fn name(&self) -> &'static str {63"aarch64"64}6566fn triple(&self) -> &Triple {67&self.triple68}6970fn flags(&self) -> &settings::Flags {71&self.shared_flags72}7374fn isa_flags(&self) -> Vec<settings::Value> {75self.isa_flags.iter().collect()76}7778fn is_branch_protection_enabled(&self) -> bool {79self.isa_flags.use_bti()80}8182fn compile_function(83&self,84sig: &WasmFuncType,85body: &FunctionBody,86translation: &ModuleTranslation,87types: &ModuleTypesBuilder,88builtins: &mut BuiltinFunctions,89validator: &mut FuncValidator<ValidatorResources>,90tunables: &Tunables,91) -> Result<CompiledFunction> {92let pointer_bytes = self.pointer_bytes();93let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);94let mut body = body.get_binary_reader();95let mut masm = Aarch64Masm::new(pointer_bytes, self.shared_flags.clone())?;96let stack = Stack::new();97let abi_sig = wasm_sig::<abi::Aarch64ABI>(sig)?;9899let env = FuncEnv::new(100&vmoffsets,101translation,102types,103builtins,104self,105abi::Aarch64ABI::ptr_type(),106);107let type_converter = TypeConverter::new(env.translation, env.types);108let defined_locals =109DefinedLocals::new::<abi::Aarch64ABI>(&type_converter, &mut body, validator)?;110let frame = Frame::new::<abi::Aarch64ABI>(&abi_sig, &defined_locals)?;111let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());112let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);113let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);114115let mut body_codegen = codegen.emit_prologue()?;116body_codegen.emit(body, validator)?;117let names = body_codegen.env.take_name_map();118let base = body_codegen.source_location.base;119Ok(CompiledFunction::new(120masm.finalize(base)?,121names,122self.function_alignment(),123))124}125126fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {127Box::new(MachTextSectionBuilder::<128cranelift_codegen::isa::aarch64::inst::Inst,129>::new(num_funcs))130}131132fn function_alignment(&self) -> u32 {133// See `cranelift_codegen::isa::TargetIsa::function_alignment`.13432135}136137fn emit_unwind_info(138&self,139_result: &MachBufferFinalized<Final>,140_kind: cranelift_codegen::isa::unwind::UnwindInfoKind,141) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {142// TODO: should fill this in with an actual implementation143Ok(None)144}145146fn page_size_align_log2(&self) -> u8 {147use target_lexicon::*;148match self.triple().operating_system {149OperatingSystem::MacOSX { .. }150| OperatingSystem::Darwin(_)151| OperatingSystem::IOS(_)152| OperatingSystem::TvOS(_) => {153debug_assert_eq!(1 << 14, 0x4000);15414155}156_ => {157debug_assert_eq!(1 << 16, 0x10000);15816159}160}161}162}163164165