Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/winch/codegen/src/isa/x64/mod.rs
3067 views
1
use crate::frame::{DefinedLocals, Frame};
2
use crate::isa::x64::masm::MacroAssembler as X64Masm;
3
use crate::isa::{Builder, TargetIsa};
4
use crate::masm::MacroAssembler;
5
use crate::regalloc::RegAlloc;
6
use crate::stack::Stack;
7
use crate::{
8
Result,
9
abi::{ABI, wasm_sig},
10
codegen::{BuiltinFunctions, CodeGen, CodeGenContext, FuncEnv, TypeConverter},
11
};
12
use cranelift_codegen::settings::{self, Flags};
13
use cranelift_codegen::{Final, MachBufferFinalized, isa::x64::settings as x64_settings};
14
use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};
15
use target_lexicon::Triple;
16
use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};
17
use wasmtime_cranelift::CompiledFunction;
18
use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};
19
20
use self::regs::{fpr_bit_set, gpr_bit_set};
21
22
mod abi;
23
mod address;
24
mod asm;
25
mod 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 avoid
28
// dead code warnings.
29
#[expect(dead_code, reason = "not everything used yet, will be in the future")]
30
mod regs;
31
32
/// Create an ISA builder.
33
pub(crate) fn isa_builder(triple: Triple) -> Builder {
34
Builder::new(
35
triple,
36
x64_settings::builder(),
37
|triple, shared_flags, settings| {
38
// TODO: Once enabling/disabling flags is allowed, and once features like SIMD are supported
39
// ensure compatibility between shared flags and ISA flags.
40
let isa_flags = x64_settings::Flags::new(&shared_flags, settings);
41
let isa = X64::new(triple, shared_flags, isa_flags);
42
Ok(Box::new(isa))
43
},
44
)
45
}
46
47
/// x64 ISA.
48
pub(crate) struct X64 {
49
/// The target triple.
50
triple: Triple,
51
/// ISA specific flags.
52
isa_flags: x64_settings::Flags,
53
/// Shared flags.
54
shared_flags: Flags,
55
}
56
57
impl X64 {
58
/// Create a x64 ISA.
59
pub fn new(triple: Triple, shared_flags: Flags, isa_flags: x64_settings::Flags) -> Self {
60
Self {
61
isa_flags,
62
shared_flags,
63
triple,
64
}
65
}
66
}
67
68
impl TargetIsa for X64 {
69
fn name(&self) -> &'static str {
70
"x64"
71
}
72
73
fn triple(&self) -> &Triple {
74
&self.triple
75
}
76
77
fn flags(&self) -> &settings::Flags {
78
&self.shared_flags
79
}
80
81
fn isa_flags(&self) -> Vec<settings::Value> {
82
self.isa_flags.iter().collect()
83
}
84
85
fn compile_function(
86
&self,
87
sig: &WasmFuncType,
88
body: &FunctionBody,
89
translation: &ModuleTranslation,
90
types: &ModuleTypesBuilder,
91
builtins: &mut BuiltinFunctions,
92
validator: &mut FuncValidator<ValidatorResources>,
93
tunables: &Tunables,
94
) -> Result<CompiledFunction> {
95
let pointer_bytes = self.pointer_bytes();
96
let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);
97
98
let mut body = body.get_binary_reader();
99
let mut masm = X64Masm::new(
100
pointer_bytes,
101
self.shared_flags.clone(),
102
self.isa_flags.clone(),
103
)?;
104
let stack = Stack::new();
105
106
let abi_sig = wasm_sig::<abi::X64ABI>(sig)?;
107
108
let env = FuncEnv::new(
109
&vmoffsets,
110
translation,
111
types,
112
builtins,
113
self,
114
abi::X64ABI::ptr_type(),
115
);
116
let type_converter = TypeConverter::new(env.translation, env.types);
117
let defined_locals =
118
DefinedLocals::new::<abi::X64ABI>(&type_converter, &mut body, validator)?;
119
let frame = Frame::new::<abi::X64ABI>(&abi_sig, &defined_locals)?;
120
let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());
121
let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);
122
let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);
123
124
let mut body_codegen = codegen.emit_prologue()?;
125
126
body_codegen.emit(body, validator)?;
127
let base = body_codegen.source_location.base;
128
129
let names = body_codegen.env.take_name_map();
130
Ok(CompiledFunction::new(
131
masm.finalize(base)?,
132
names,
133
self.function_alignment(),
134
))
135
}
136
137
fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {
138
Box::new(MachTextSectionBuilder::<cranelift_codegen::isa::x64::Inst>::new(num_funcs))
139
}
140
141
fn function_alignment(&self) -> u32 {
142
// See `cranelift_codegen`'s value of this for more information.
143
16
144
}
145
146
fn emit_unwind_info(
147
&self,
148
buffer: &MachBufferFinalized<Final>,
149
kind: cranelift_codegen::isa::unwind::UnwindInfoKind,
150
) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {
151
Ok(cranelift_codegen::isa::x64::emit_unwind_info(buffer, kind)?)
152
}
153
154
fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
155
Some(cranelift_codegen::isa::x64::create_cie())
156
}
157
158
fn page_size_align_log2(&self) -> u8 {
159
12
160
}
161
}
162
163