Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/winch/codegen/src/isa/aarch64/mod.rs
1692 views
1
use self::regs::{fpr_bit_set, gpr_bit_set};
2
use crate::{
3
BuiltinFunctions,
4
abi::{ABI, wasm_sig},
5
codegen::{CodeGen, CodeGenContext, FuncEnv, TypeConverter},
6
frame::{DefinedLocals, Frame},
7
isa::{Builder, TargetIsa},
8
masm::MacroAssembler,
9
regalloc::RegAlloc,
10
stack::Stack,
11
};
12
use anyhow::Result;
13
use cranelift_codegen::settings::{self, Flags};
14
use cranelift_codegen::{Final, MachBufferFinalized, isa::aarch64::settings as aarch64_settings};
15
use cranelift_codegen::{MachTextSectionBuilder, TextSectionBuilder};
16
use masm::MacroAssembler as Aarch64Masm;
17
use target_lexicon::Triple;
18
use wasmparser::{FuncValidator, FunctionBody, ValidatorResources};
19
use wasmtime_cranelift::CompiledFunction;
20
use wasmtime_environ::{ModuleTranslation, ModuleTypesBuilder, Tunables, VMOffsets, WasmFuncType};
21
22
mod abi;
23
mod address;
24
mod asm;
25
mod masm;
26
mod regs;
27
28
/// Create an ISA from the given triple.
29
pub(crate) fn isa_builder(triple: Triple) -> Builder {
30
Builder::new(
31
triple,
32
aarch64_settings::builder(),
33
|triple, shared_flags, settings| {
34
let isa_flags = aarch64_settings::Flags::new(&shared_flags, settings);
35
let isa = Aarch64::new(triple, shared_flags, isa_flags);
36
Ok(Box::new(isa))
37
},
38
)
39
}
40
41
/// Aarch64 ISA.
42
pub(crate) struct Aarch64 {
43
/// The target triple.
44
triple: Triple,
45
/// ISA specific flags.
46
isa_flags: aarch64_settings::Flags,
47
/// Shared flags.
48
shared_flags: Flags,
49
}
50
51
impl Aarch64 {
52
/// Create an Aarch64 ISA.
53
pub fn new(triple: Triple, shared_flags: Flags, isa_flags: aarch64_settings::Flags) -> Self {
54
Self {
55
isa_flags,
56
shared_flags,
57
triple,
58
}
59
}
60
}
61
62
impl TargetIsa for Aarch64 {
63
fn name(&self) -> &'static str {
64
"aarch64"
65
}
66
67
fn triple(&self) -> &Triple {
68
&self.triple
69
}
70
71
fn flags(&self) -> &settings::Flags {
72
&self.shared_flags
73
}
74
75
fn isa_flags(&self) -> Vec<settings::Value> {
76
self.isa_flags.iter().collect()
77
}
78
79
fn is_branch_protection_enabled(&self) -> bool {
80
self.isa_flags.use_bti()
81
}
82
83
fn compile_function(
84
&self,
85
sig: &WasmFuncType,
86
body: &FunctionBody,
87
translation: &ModuleTranslation,
88
types: &ModuleTypesBuilder,
89
builtins: &mut BuiltinFunctions,
90
validator: &mut FuncValidator<ValidatorResources>,
91
tunables: &Tunables,
92
) -> Result<CompiledFunction> {
93
let pointer_bytes = self.pointer_bytes();
94
let vmoffsets = VMOffsets::new(pointer_bytes, &translation.module);
95
let mut body = body.get_binary_reader();
96
let mut masm = Aarch64Masm::new(pointer_bytes, self.shared_flags.clone())?;
97
let stack = Stack::new();
98
let abi_sig = wasm_sig::<abi::Aarch64ABI>(sig)?;
99
100
let env = FuncEnv::new(
101
&vmoffsets,
102
translation,
103
types,
104
builtins,
105
self,
106
abi::Aarch64ABI::ptr_type(),
107
);
108
let type_converter = TypeConverter::new(env.translation, env.types);
109
let defined_locals =
110
DefinedLocals::new::<abi::Aarch64ABI>(&type_converter, &mut body, validator)?;
111
let frame = Frame::new::<abi::Aarch64ABI>(&abi_sig, &defined_locals)?;
112
let regalloc = RegAlloc::from(gpr_bit_set(), fpr_bit_set());
113
let codegen_context = CodeGenContext::new(regalloc, stack, frame, &vmoffsets);
114
let codegen = CodeGen::new(tunables, &mut masm, codegen_context, env, abi_sig);
115
116
let mut body_codegen = codegen.emit_prologue()?;
117
body_codegen.emit(body, validator)?;
118
let names = body_codegen.env.take_name_map();
119
let base = body_codegen.source_location.base;
120
Ok(CompiledFunction::new(
121
masm.finalize(base)?,
122
names,
123
self.function_alignment(),
124
))
125
}
126
127
fn text_section_builder(&self, num_funcs: usize) -> Box<dyn TextSectionBuilder> {
128
Box::new(MachTextSectionBuilder::<
129
cranelift_codegen::isa::aarch64::inst::Inst,
130
>::new(num_funcs))
131
}
132
133
fn function_alignment(&self) -> u32 {
134
// See `cranelift_codegen::isa::TargetIsa::function_alignment`.
135
32
136
}
137
138
fn emit_unwind_info(
139
&self,
140
_result: &MachBufferFinalized<Final>,
141
_kind: cranelift_codegen::isa::unwind::UnwindInfoKind,
142
) -> Result<Option<cranelift_codegen::isa::unwind::UnwindInfo>> {
143
// TODO: should fill this in with an actual implementation
144
Ok(None)
145
}
146
147
fn page_size_align_log2(&self) -> u8 {
148
use target_lexicon::*;
149
match self.triple().operating_system {
150
OperatingSystem::MacOSX { .. }
151
| OperatingSystem::Darwin(_)
152
| OperatingSystem::IOS(_)
153
| OperatingSystem::TvOS(_) => {
154
debug_assert_eq!(1 << 14, 0x4000);
155
14
156
}
157
_ => {
158
debug_assert_eq!(1 << 16, 0x10000);
159
16
160
}
161
}
162
}
163
}
164
165