Path: blob/main/winch/codegen/src/isa/aarch64/mod.rs
3064 views
use self::regs::{fpr_bit_set, gpr_bit_set};1use crate::{2BuiltinFunctions, Result,3abi::{ABI, wasm_sig},4codegen::{CodeGen, CodeGenContext, FuncEnv, TypeConverter},5frame::{DefinedLocals, Frame},6isa::{Builder, TargetIsa},7masm::MacroAssembler,8regalloc::RegAlloc,9stack::Stack,10};11use cranelift_codegen::settings::{self, Flags};12use cranelift_codegen::{Final, MachBufferFinalized, isa::aarch64::settings as aarch64_settings};13use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};14use masm::MacroAssembler as Aarch64Masm;15use target_lexicon::Triple;16use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};17use wasmtime_cranelift::CompiledFunction;18use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};1920mod abi;21mod address;22mod asm;23mod masm;24mod regs;2526/// Create an ISA from the given triple.27pub(crate) fn isa_builder(triple: Triple) -> Builder {28Builder::new(29triple,30aarch64_settings::builder(),31|triple, shared_flags, settings| {32let isa_flags = aarch64_settings::Flags::new(&shared_flags, settings);33let isa = Aarch64::new(triple, shared_flags, isa_flags);34Ok(Box::new(isa))35},36)37}3839/// Aarch64 ISA.40pub(crate) struct Aarch64 {41/// The target triple.42triple: Triple,43/// ISA specific flags.44isa_flags: aarch64_settings::Flags,45/// Shared flags.46shared_flags: Flags,47}4849impl Aarch64 {50/// Create an Aarch64 ISA.51pub fn new(triple: Triple, shared_flags: Flags, isa_flags: aarch64_settings::Flags) -> Self {52Self {53isa_flags,54shared_flags,55triple,56}57}58}5960impl TargetIsa for Aarch64 {61fn name(&self) -> &'static str {62"aarch64"63}6465fn triple(&self) -> &Triple {66&self.triple67}6869fn flags(&self) -> &settings::Flags {70&self.shared_flags71}7273fn isa_flags(&self) -> Vec<settings::Value> {74self.isa_flags.iter().collect()75}7677fn is_branch_protection_enabled(&self) -> bool {78self.isa_flags.use_bti()79}8081fn compile_function(82&self,83sig: &WasmFuncType,84body: &FunctionBody,85translation: &ModuleTranslation,86types: &ModuleTypesBuilder,87builtins: &mut BuiltinFunctions,88validator: &mut FuncValidator<ValidatorResources>,89tunables: &Tunables,90) -> Result<CompiledFunction> {91let pointer_bytes = self.pointer_bytes();92let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);93let mut body = body.get_binary_reader();94let mut masm = Aarch64Masm::new(pointer_bytes, self.shared_flags.clone())?;95let stack = Stack::new();96let abi_sig = wasm_sig::<abi::Aarch64ABI>(sig)?;9798let env = FuncEnv::new(99&vmoffsets,100translation,101types,102builtins,103self,104abi::Aarch64ABI::ptr_type(),105);106let type_converter = TypeConverter::new(env.translation, env.types);107let defined_locals =108DefinedLocals::new::<abi::Aarch64ABI>(&type_converter, &mut body, validator)?;109let frame = Frame::new::<abi::Aarch64ABI>(&abi_sig, &defined_locals)?;110let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());111let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);112let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);113114let mut body_codegen = codegen.emit_prologue()?;115body_codegen.emit(body, validator)?;116let names = body_codegen.env.take_name_map();117let base = body_codegen.source_location.base;118Ok(CompiledFunction::new(119masm.finalize(base)?,120names,121self.function_alignment(),122))123}124125fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {126Box::new(MachTextSectionBuilder::<127cranelift_codegen::isa::aarch64::inst::Inst,128>::new(num_funcs))129}130131fn function_alignment(&self) -> u32 {132// See `cranelift_codegen::isa::TargetIsa::function_alignment`.13332134}135136fn emit_unwind_info(137&self,138_result: &MachBufferFinalized<Final>,139_kind: cranelift_codegen::isa::unwind::UnwindInfoKind,140) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {141// TODO: should fill this in with an actual implementation142Ok(None)143}144145fn page_size_align_log2(&self) -> u8 {146use target_lexicon::*;147match self.triple().operating_system {148OperatingSystem::MacOSX { .. }149| OperatingSystem::Darwin(_)150| OperatingSystem::IOS(_)151| OperatingSystem::TvOS(_) => {152debug_assert_eq!(1 << 14, 0x4000);15314154}155_ => {156debug_assert_eq!(1 << 16, 0x10000);15716158}159}160}161}162163164