Path: blob/main/winch/codegen/src/isa/x64/mod.rs
3067 views
use crate::frame::{DefinedLocals, Frame};1use crate::isa::x64::masm::MacroAssembler as X64Masm;2use crate::isa::{Builder, TargetIsa};3use crate::masm::MacroAssembler;4use crate::regalloc::RegAlloc;5use crate::stack::Stack;6use crate::{7Result,8abi::{ABI, wasm_sig},9codegen::{BuiltinFunctions, CodeGen, CodeGenContext, FuncEnv, TypeConverter},10};11use cranelift_codegen::settings::{self, Flags};12use cranelift_codegen::{Final, MachBufferFinalized, isa::x64::settings as x64_settings};13use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};14use target_lexicon::Triple;15use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};16use wasmtime_cranelift::CompiledFunction;17use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};1819use self::regs::{fpr_bit_set, gpr_bit_set};2021mod abi;22mod address;23mod asm;24mod masm;25// Not all the fpr and gpr constructors are used at the moment;26// in that sense, this directive is a temporary measure to avoid27// dead code warnings.28#[expect(dead_code, reason = "not everything used yet, will be in the future")]29mod regs;3031/// Create an ISA builder.32pub(crate) fn isa_builder(triple: Triple) -> Builder {33Builder::new(34triple,35x64_settings::builder(),36|triple, shared_flags, settings| {37// TODO: Once enabling/disabling flags is allowed, and once features like SIMD are supported38// ensure compatibility between shared flags and ISA flags.39let isa_flags = x64_settings::Flags::new(&shared_flags, settings);40let isa = X64::new(triple, shared_flags, isa_flags);41Ok(Box::new(isa))42},43)44}4546/// x64 ISA.47pub(crate) struct X64 {48/// The target triple.49triple: Triple,50/// ISA specific flags.51isa_flags: x64_settings::Flags,52/// Shared flags.53shared_flags: Flags,54}5556impl X64 {57/// Create a x64 ISA.58pub fn new(triple: Triple, shared_flags: Flags, isa_flags: x64_settings::Flags) -> Self {59Self {60isa_flags,61shared_flags,62triple,63}64}65}6667impl TargetIsa for X64 {68fn name(&self) -> &'static str {69"x64"70}7172fn triple(&self) -> &Triple {73&self.triple74}7576fn flags(&self) -> &settings::Flags {77&self.shared_flags78}7980fn isa_flags(&self) -> Vec<settings::Value> {81self.isa_flags.iter().collect()82}8384fn compile_function(85&self,86sig: &WasmFuncType,87body: &FunctionBody,88translation: &ModuleTranslation,89types: &ModuleTypesBuilder,90builtins: &mut BuiltinFunctions,91validator: &mut FuncValidator<ValidatorResources>,92tunables: &Tunables,93) -> Result<CompiledFunction> {94let pointer_bytes = self.pointer_bytes();95let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);9697let mut body = body.get_binary_reader();98let mut masm = X64Masm::new(99pointer_bytes,100self.shared_flags.clone(),101self.isa_flags.clone(),102)?;103let stack = Stack::new();104105let abi_sig = wasm_sig::<abi::X64ABI>(sig)?;106107let env = FuncEnv::new(108&vmoffsets,109translation,110types,111builtins,112self,113abi::X64ABI::ptr_type(),114);115let type_converter = TypeConverter::new(env.translation, env.types);116let defined_locals =117DefinedLocals::new::<abi::X64ABI>(&type_converter, &mut body, validator)?;118let frame = Frame::new::<abi::X64ABI>(&abi_sig, &defined_locals)?;119let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());120let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);121let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);122123let mut body_codegen = codegen.emit_prologue()?;124125body_codegen.emit(body, validator)?;126let base = body_codegen.source_location.base;127128let names = body_codegen.env.take_name_map();129Ok(CompiledFunction::new(130masm.finalize(base)?,131names,132self.function_alignment(),133))134}135136fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {137Box::new(MachTextSectionBuilder::<cranelift_codegen::isa::x64::Inst>::new(num_funcs))138}139140fn function_alignment(&self) -> u32 {141// See `cranelift_codegen`'s value of this for more information.14216143}144145fn emit_unwind_info(146&self,147buffer: &MachBufferFinalized<Final>,148kind: cranelift_codegen::isa::unwind::UnwindInfoKind,149) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {150Ok(cranelift_codegen::isa::x64::emit_unwind_info(buffer, kind)?)151}152153fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {154Some(cranelift_codegen::isa::x64::create_cie())155}156157fn page_size_align_log2(&self) -> u8 {15812159}160}161162163