Path: blob/main/winch/codegen/src/isa/x64/mod.rs
1693 views
use crate::{1abi::{ABI, wasm_sig},2codegen::{BuiltinFunctions, CodeGen, CodeGenContext, FuncEnv, TypeConverter},3};45use crate::frame::{DefinedLocals, Frame};6use crate::isa::x64::masm::MacroAssembler as X64Masm;7use crate::isa::{Builder, TargetIsa};8use crate::masm::MacroAssembler;9use crate::regalloc::RegAlloc;10use crate::stack::Stack;11use anyhow::Result;12use cranelift_codegen::settings::{self, Flags};13use cranelift_codegen::{Final, MachBufferFinalized, isa::x64::settings as x64_settings};14use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};15use target_lexicon::Triple;16use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};17use wasmtime_cranelift::CompiledFunction;18use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};1920use self::regs::{fpr_bit_set, gpr_bit_set};2122mod abi;23mod address;24mod asm;25mod masm;26// Not all the fpr and gpr constructors are used at the moment;27// in that sense, this directive is a temporary measure to avoid28// dead code warnings.29#[expect(dead_code, reason = "not everything used yet, will be in the future")]30mod regs;3132/// Create an ISA builder.33pub(crate) fn isa_builder(triple: Triple) -> Builder {34Builder::new(35triple,36x64_settings::builder(),37|triple, shared_flags, settings| {38// TODO: Once enabling/disabling flags is allowed, and once features like SIMD are supported39// ensure compatibility between shared flags and ISA flags.40let isa_flags = x64_settings::Flags::new(&shared_flags, settings);41let isa = X64::new(triple, shared_flags, isa_flags);42Ok(Box::new(isa))43},44)45}4647/// x64 ISA.48pub(crate) struct X64 {49/// The target triple.50triple: Triple,51/// ISA specific flags.52isa_flags: x64_settings::Flags,53/// Shared flags.54shared_flags: Flags,55}5657impl X64 {58/// Create a x64 ISA.59pub fn new(triple: Triple, shared_flags: Flags, isa_flags: x64_settings::Flags) -> Self {60Self {61isa_flags,62shared_flags,63triple,64}65}66}6768impl TargetIsa for X64 {69fn name(&self) -> &'static str {70"x64"71}7273fn triple(&self) -> &Triple {74&self.triple75}7677fn flags(&self) -> &settings::Flags {78&self.shared_flags79}8081fn isa_flags(&self) -> Vec<settings::Value> {82self.isa_flags.iter().collect()83}8485fn compile_function(86&self,87sig: &WasmFuncType,88body: &FunctionBody,89translation: &ModuleTranslation,90types: &ModuleTypesBuilder,91builtins: &mut BuiltinFunctions,92validator: &mut FuncValidator<ValidatorResources>,93tunables: &Tunables,94) -> Result<CompiledFunction> {95let pointer_bytes = self.pointer_bytes();96let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);9798let mut body = body.get_binary_reader();99let mut masm = X64Masm::new(100pointer_bytes,101self.shared_flags.clone(),102self.isa_flags.clone(),103)?;104let stack = Stack::new();105106let abi_sig = wasm_sig::<abi::X64ABI>(sig)?;107108let env = FuncEnv::new(109&vmoffsets,110translation,111types,112builtins,113self,114abi::X64ABI::ptr_type(),115);116let type_converter = TypeConverter::new(env.translation, env.types);117let defined_locals =118DefinedLocals::new::<abi::X64ABI>(&type_converter, &mut body, validator)?;119let frame = Frame::new::<abi::X64ABI>(&abi_sig, &defined_locals)?;120let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());121let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);122let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);123124let mut body_codegen = codegen.emit_prologue()?;125126body_codegen.emit(body, validator)?;127let base = body_codegen.source_location.base;128129let names = body_codegen.env.take_name_map();130Ok(CompiledFunction::new(131masm.finalize(base)?,132names,133self.function_alignment(),134))135}136137fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {138Box::new(MachTextSectionBuilder::<cranelift_codegen::isa::x64::Inst>::new(num_funcs))139}140141fn function_alignment(&self) -> u32 {142// See `cranelift_codegen`'s value of this for more information.14316144}145146fn emit_unwind_info(147&self,148buffer: &MachBufferFinalized<Final>,149kind: cranelift_codegen::isa::unwind::UnwindInfoKind,150) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {151Ok(cranelift_codegen::isa::x64::emit_unwind_info(buffer, kind)?)152}153154fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {155Some(cranelift_codegen::isa::x64::create_cie())156}157158fn page_size_align_log2(&self) -> u8 {15912160}161}162163164