Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Singlepass aarch64 #2750

Merged
merged 37 commits into from Jan 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
1e1032e
improvement(compiler) Added basic arm64 declaration for singlepass
ptitSeb Dec 10, 2021
d317e1e
Fixed linting
ptitSeb Dec 10, 2021
69478cd
improvement(compiler) Added squeleton for arm64 singlepass
ptitSeb Dec 13, 2021
26d334f
improv(compiler) Enabled aarch64 tests
ptitSeb Dec 13, 2021
9002208
improv(compiler) Added some machine_arm64 methods
ptitSeb Dec 13, 2021
19a9fa7
improv(compiler) Added some more machine_arm64 and emitter_arm64 meth…
ptitSeb Dec 14, 2021
72eead3
improv(compiler) Calls are now working properly (and 43 tests passes)
ptitSeb Dec 16, 2021
a57c422
improv(compiler) Some ork on register affectation (60 tests passes now)
ptitSeb Dec 16, 2021
ae1925e
improv(compiler) Cleaned up warnings
ptitSeb Dec 17, 2021
67e5f9c
improv(compiler) Added emit_relaxed_ldr64 utility (65 tests passes now)
ptitSeb Dec 17, 2021
4a65664
improv(compiler) Fixed emit_mov_imm for 64bits values (67 tests passe…
ptitSeb Dec 17, 2021
2f6264a
improv(compiler) Added emit_jmp_to_jumptable (68 tests passes now)
ptitSeb Dec 17, 2021
962511d
improv(compiler) Fixed stack alignment on native function call (69 te…
ptitSeb Dec 17, 2021
e9b80d4
improv(compiler) Added logic and shift operations (70 tests passes now)
ptitSeb Dec 17, 2021
7c2eac1
improv(compiler) Added/Fixed Store/Load of i32/i64 (74 tests passes now)
ptitSeb Dec 17, 2021
6b593ed
improv(compiler) More logic oprations (91 tests passes now)
ptitSeb Dec 20, 2021
f23a137
improv(compiler) More memory oprations (95 tests passes now)
ptitSeb Dec 20, 2021
ddc1737
improv(compiler) Added CLZ, CTZ and a few float operations (99 tests …
ptitSeb Dec 20, 2021
005351b
improv(compiler) Added SDIV, UDIV and UREM operations (105 tests pass…
ptitSeb Dec 20, 2021
7ce5475
improv(compiler) More work on SDIV, UDIV, UREM and SREM operations (1…
ptitSeb Dec 20, 2021
7cbf2fe
improv(compiler) More logic and float operations, but no canonicaliza…
ptitSeb Dec 21, 2021
8d066a1
improv(compiler) More float and native call work (133 tests passes now)
ptitSeb Dec 21, 2021
0bbc81a
improv(compiler) Oops, that was a mystake
ptitSeb Dec 22, 2021
4f93864
improv(compiler) More native call work and fixes (166 tests passes now)
ptitSeb Jan 3, 2022
8f5a30a
improv(compiler) More fixes (176 tests passes now)
ptitSeb Jan 4, 2022
9d188cb
improv(compiler) Added canonicalization and rounding (182 tests passe…
ptitSeb Jan 5, 2022
77e65cd
improv(compiler) Added float to int conversion, with trap (187 tests …
ptitSeb Jan 6, 2022
da1d96b
improv(compiler) Fixed some mystakes (207 tests passes now, 0 failed)
ptitSeb Jan 7, 2022
0e2d809
imp(compiler) Add support for AppleAarch64 ABI to SinglePass
ptitSeb Jan 13, 2022
c8ae8c8
imp(feature) Fixed x64 backend of Singlepass
ptitSeb Jan 13, 2022
ab3e978
feat(compiler) Added entry in ChangeLog
ptitSeb Jan 13, 2022
7f4fd02
feat(compiler) Adapted/Fixed/Removed some comments in SinglePass codegen
ptitSeb Jan 13, 2022
80f9c8f
feat(compiler) Small adaption after comments
ptitSeb Jan 17, 2022
61609c9
improv(compiler) Added a few more arm64 emitter, just in case
ptitSeb Jan 19, 2022
b676d18
Merge branch 'master' into singlepass_aarch64
ptitSeb Jan 19, 2022
74779f5
Merge branch 'master' into singlepass_aarch64
ptitSeb Jan 21, 2022
bff3c09
Merge branch 'master' into singlepass_aarch64
ptitSeb Jan 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/CHANGELOG.md).

## **[Unreleased]**
- [#2750](https://github.com/wasmerio/wasmer/pull/2750) Added Aarch64 support to Singlepass (both Linux and macOS).

## 2.1.1 - 2021/12/20

Expand Down
8 changes: 8 additions & 0 deletions Makefile
Expand Up @@ -179,6 +179,11 @@ ifneq ($(ENABLE_SINGLEPASS), 0)
ifeq ($(IS_AMD64), 1)
compilers += singlepass
endif
ifeq ($(IS_AARCH64), 1)
ifneq ($(IS_WINDOWS), 1)
compilers += singlepass
endif
endif
endif
endif

Expand Down Expand Up @@ -249,6 +254,9 @@ ifeq ($(ENABLE_SINGLEPASS), 1)
ifeq ($(IS_AMD64), 1)
compilers_engines += singlepass-universal
endif
ifeq ($(IS_AARCH64), 1)
compilers_engines += singlepass-universal
endif
endif
endif

Expand Down
4 changes: 2 additions & 2 deletions lib/compiler-singlepass/Cargo.toml
Expand Up @@ -18,8 +18,8 @@ wasmer-types = { path = "../types", version = "=2.1.1", default-features = false
rayon = { version = "1.5", optional = true }
hashbrown = { version = "0.11", optional = true }
more-asserts = "0.2"
dynasm = "1.2"
dynasmrt = "1.2"
dynasm = "1.2.1"
dynasmrt = "1.2.1"
lazy_static = "1.4"
byteorder = "1.3"
smallvec = "1.6"
Expand Down
302 changes: 302 additions & 0 deletions lib/compiler-singlepass/src/arm64_decl.rs
@@ -0,0 +1,302 @@
//! ARM64 structures.

use crate::common_decl::{MachineState, MachineValue, RegisterIndex};
use crate::location::CombinedRegister;
use crate::location::Reg as AbstractReg;
use std::collections::BTreeMap;
use wasmer_compiler::CallingConvention;
use wasmer_types::Type;

/// General-purpose registers.
#[repr(u8)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum GPR {
X0 = 0,
X1 = 1,
X2 = 2,
X3 = 3,
X4 = 4,
X5 = 5,
X6 = 6,
X7 = 7,
X8 = 8,
X9 = 9,
X10 = 10,
X11 = 11,
X12 = 12,
X13 = 13,
X14 = 14,
X15 = 15,
X16 = 16,
X17 = 17,
X18 = 18,
X19 = 19,
X20 = 20,
X21 = 21,
X22 = 22,
X23 = 23,
X24 = 24,
X25 = 25,
X26 = 26,
X27 = 27,
X28 = 28,
X29 = 29,
X30 = 30,
XzrSp = 31,
}

/// NEON registers.
#[repr(u8)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[allow(dead_code)]
pub enum NEON {
V0 = 0,
V1 = 1,
V2 = 2,
V3 = 3,
V4 = 4,
V5 = 5,
V6 = 6,
V7 = 7,
V8 = 8,
V9 = 9,
V10 = 10,
V11 = 11,
V12 = 12,
V13 = 13,
V14 = 14,
V15 = 15,
V16 = 16,
V17 = 17,
V18 = 18,
V19 = 19,
V20 = 20,
V21 = 21,
V22 = 22,
V23 = 23,
V24 = 24,
V25 = 25,
V26 = 26,
V27 = 27,
V28 = 28,
V29 = 29,
V30 = 30,
V31 = 31,
}

impl AbstractReg for GPR {
fn is_callee_save(self) -> bool {
self as usize > 18
}
fn is_reserved(self) -> bool {
match self.into_index() {
0..=16 | 19..=27 => false,
_ => true,
}
}
fn into_index(self) -> usize {
self as usize
}
fn from_index(n: usize) -> Result<GPR, ()> {
const REGS: [GPR; 32] = [
GPR::X0,
GPR::X1,
GPR::X2,
GPR::X3,
GPR::X4,
GPR::X5,
GPR::X6,
GPR::X7,
GPR::X8,
GPR::X9,
GPR::X10,
GPR::X11,
GPR::X12,
GPR::X13,
GPR::X14,
GPR::X15,
GPR::X16,
GPR::X17,
GPR::X18,
GPR::X19,
GPR::X20,
GPR::X21,
GPR::X22,
GPR::X23,
GPR::X24,
GPR::X25,
GPR::X26,
GPR::X27,
GPR::X28,
GPR::X29,
GPR::X30,
GPR::XzrSp,
];
REGS.get(n).cloned().ok_or(())
}
}

impl AbstractReg for NEON {
fn is_callee_save(self) -> bool {
self as usize > 16
}
fn is_reserved(self) -> bool {
false
}
fn into_index(self) -> usize {
self as usize
}
fn from_index(n: usize) -> Result<NEON, ()> {
const REGS: [NEON; 32] = [
NEON::V0,
NEON::V1,
NEON::V2,
NEON::V3,
NEON::V4,
NEON::V5,
NEON::V6,
NEON::V7,
NEON::V8,
NEON::V9,
NEON::V10,
NEON::V11,
NEON::V12,
NEON::V13,
NEON::V14,
NEON::V15,
NEON::V16,
NEON::V17,
NEON::V18,
NEON::V19,
NEON::V20,
NEON::V21,
NEON::V22,
NEON::V23,
NEON::V24,
NEON::V25,
NEON::V26,
NEON::V27,
NEON::V28,
NEON::V29,
NEON::V30,
NEON::V31,
];
match n {
0..=31 => Ok(REGS[n]),
_ => Err(()),
}
}
}

/// A machine register under the x86-64 architecture.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ARM64Register {
/// General-purpose registers.
GPR(GPR),
/// NEON (floating point/SIMD) registers.
NEON(NEON),
}

impl CombinedRegister for ARM64Register {
/// Returns the index of the register.
fn to_index(&self) -> RegisterIndex {
match *self {
ARM64Register::GPR(x) => RegisterIndex(x as usize),
ARM64Register::NEON(x) => RegisterIndex(x as usize + 64),
}
}
/// Convert from a GPR register
fn from_gpr(x: u16) -> Self {
ARM64Register::GPR(GPR::from_index(x as usize).unwrap())
}
/// Convert from an SIMD register
fn from_simd(x: u16) -> Self {
ARM64Register::NEON(NEON::from_index(x as usize).unwrap())
}

/// Converts a DWARF regnum to ARM64Register.
fn _from_dwarf_regnum(x: u16) -> Option<ARM64Register> {
Some(match x {
0..=31 => ARM64Register::GPR(GPR::from_index(x as usize).unwrap()),
64..=95 => ARM64Register::NEON(NEON::from_index(x as usize - 64).unwrap()),
_ => return None,
})
}
}

/// An allocator that allocates registers for function arguments according to the System V ABI.
#[derive(Default)]
pub struct ArgumentRegisterAllocator {
n_gprs: usize,
n_neons: usize,
}

impl ArgumentRegisterAllocator {
/// Allocates a register for argument type `ty`. Returns `None` if no register is available for this type.
pub fn next(
&mut self,
ty: Type,
calling_convention: CallingConvention,
) -> Option<ARM64Register> {
match calling_convention {
CallingConvention::SystemV | CallingConvention::AppleAarch64 => {
static GPR_SEQ: &'static [GPR] = &[
GPR::X0,
GPR::X1,
GPR::X2,
GPR::X3,
GPR::X4,
GPR::X5,
GPR::X6,
GPR::X7,
];
static NEON_SEQ: &'static [NEON] = &[
NEON::V0,
NEON::V1,
NEON::V2,
NEON::V3,
NEON::V4,
NEON::V5,
NEON::V6,
NEON::V7,
];
match ty {
Type::I32 | Type::I64 => {
if self.n_gprs < GPR_SEQ.len() {
let gpr = GPR_SEQ[self.n_gprs];
self.n_gprs += 1;
Some(ARM64Register::GPR(gpr))
} else {
None
}
}
Type::F32 | Type::F64 => {
if self.n_neons < NEON_SEQ.len() {
let neon = NEON_SEQ[self.n_neons];
self.n_neons += 1;
Some(ARM64Register::NEON(neon))
} else {
None
}
}
_ => todo!(
"ArgumentRegisterAllocator::next: Unsupported type: {:?}",
ty
),
}
}
_ => unimplemented!(),
}
}
}

/// Create a new `MachineState` with default values.
pub fn new_machine_state() -> MachineState {
MachineState {
stack_values: vec![],
register_values: vec![MachineValue::Undefined; 32 + 32],
prev_frame: BTreeMap::new(),
wasm_stack: vec![],
wasm_inst_offset: std::usize::MAX,
}
}