Skip to content

Commit

Permalink
Added some aarch64 atomic access emitter (not finished)
Browse files Browse the repository at this point in the history
Removed public Imports::import_shared_memory and try to auto-initialize shared memory directly

Fixed clippy

Added Atomic Add/Sub/And/Or/Xor operator to Singlepass/AArch64 backend

Added atomic_xchg support for Singlepass/AArch64 backend

Finished all atomic access operator for Singlepass/Aarch64 backend
  • Loading branch information
ptitSeb committed Nov 22, 2022
1 parent 12ce309 commit 8a0bd4b
Show file tree
Hide file tree
Showing 8 changed files with 3,110 additions and 655 deletions.
6 changes: 5 additions & 1 deletion lib/api/src/js/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,11 @@ impl Imports {
/// Resolve and return a vector of imports in the order they are defined in the `module`'s source code.
///
/// This means the returned `Vec<Extern>` might be a subset of the imports contained in `self`.
pub fn imports_for_module(&self, module: &Module) -> Result<Vec<Extern>, LinkError> {
pub fn imports_for_module(
&self,
module: &Module,
_store: &mut impl AsStoreMut,
) -> Result<Vec<Extern>, LinkError> {
let mut ret = vec![];
for import in module.imports() {
if let Some(imp) = self
Expand Down
38 changes: 24 additions & 14 deletions lib/api/src/sys/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ impl Imports {

/// Imports (any) shared memory into the imports.
/// (if the module does not import memory then this function is ignored)
pub fn import_shared_memory(
&mut self,
pub(crate) fn import_shared_memory(
&self,
module: &Module,
store: &mut impl AsStoreMut,
) -> Option<VMSharedMemory> {
) -> Self {
// Determine if shared memory needs to be created and imported
let shared_memory = module
.imports()
Expand All @@ -130,16 +130,21 @@ impl Imports {
VMSharedMemory::new(&ty, &style).unwrap()
});

let mut ret = self.clone();
if let Some(memory) = shared_memory {
self.define(
"env",
"memory",
Memory::new_from_existing(store, memory.clone().into()),
);
Some(memory)
} else {
None
}
// if the memory has already be defined, don't redefine it!
if !self
.map
.contains_key(&("env".to_string(), "memory".to_string()))
{
ret.define(
"env",
"memory",
Memory::new_from_existing(store, memory.into()),
);
}
};
ret
}

/// Returns the contents of a namespace as an `Exports`.
Expand All @@ -162,10 +167,15 @@ impl Imports {
/// Resolve and return a vector of imports in the order they are defined in the `module`'s source code.
///
/// This means the returned `Vec<Extern>` might be a subset of the imports contained in `self`.
pub fn imports_for_module(&self, module: &Module) -> Result<Vec<Extern>, LinkError> {
pub fn imports_for_module(
&self,
module: &Module,
store: &mut impl AsStoreMut,
) -> Result<Vec<Extern>, LinkError> {
let mut ret = vec![];
let imports = self.import_shared_memory(module, store);
for import in module.imports() {
if let Some(imp) = self
if let Some(imp) = imports
.map
.get(&(import.module().to_string(), import.name().to_string()))
{
Expand Down
2 changes: 1 addition & 1 deletion lib/api/src/sys/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl Instance {
imports: &Imports,
) -> Result<Self, InstantiationError> {
let imports = imports
.imports_for_module(module)
.imports_for_module(module, store)
.map_err(InstantiationError::Link)?;
let mut handle = module.instantiate(store, &imports)?;
let exports = module
Expand Down
3 changes: 1 addition & 2 deletions lib/cli/src/commands/run/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ impl Wasi {
is_wasix_module(module),
std::sync::atomic::Ordering::Release,
);
let mut import_object = import_object_for_all_wasi_versions(store, &wasi_env.env);
import_object.import_shared_memory(module, store);
let import_object = import_object_for_all_wasi_versions(store, &wasi_env.env);
let instance = Instance::new(store, module, &import_object)?;
let memory = instance.exports.get_memory("memory")?;
wasi_env.data_mut(store).set_memory(memory.clone());
Expand Down
124 changes: 124 additions & 0 deletions lib/compiler-singlepass/src/emitter_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,31 @@ pub trait EmitterARM64 {
fn emit_strb(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError>;
fn emit_strh(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError>;

fn emit_ldaxr(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError>;
fn emit_ldaxrb(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError>;
fn emit_ldaxrh(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError>;
fn emit_stlxr(
&mut self,
sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError>;
fn emit_stlxrb(
&mut self,
sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError>;
fn emit_stlxrh(
&mut self,
sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError>;

fn emit_mov(&mut self, sz: Size, src: Location, dst: Location) -> Result<(), CompileError>;

fn emit_movn(&mut self, sz: Size, reg: Location, val: u32) -> Result<(), CompileError>;
Expand Down Expand Up @@ -1059,6 +1084,105 @@ impl EmitterARM64 for Assembler {
Ok(())
}

fn emit_ldaxr(&mut self, sz: Size, reg: Location, dst: Location) -> Result<(), CompileError> {
match (sz, reg, dst) {
(Size::S32, Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; ldaxr W(reg), [X(dst)]);
}
(Size::S64, Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; ldaxr X(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit LDAXR {:?}, {:?}", reg, dst),
}
Ok(())
}
fn emit_ldaxrb(&mut self, _sz: Size, reg: Location, dst: Location) -> Result<(), CompileError> {
match (reg, dst) {
(Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; ldaxrb W(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit LDAXRB {:?}, {:?}", reg, dst),
}
Ok(())
}
fn emit_ldaxrh(&mut self, _sz: Size, reg: Location, dst: Location) -> Result<(), CompileError> {
match (reg, dst) {
(Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
dynasm!(self ; ldaxrh W(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit LDAXRH {:?}, {:?}", reg, dst),
}
Ok(())
}
fn emit_stlxr(
&mut self,
sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError> {
match (sz, status, reg, dst) {
(Size::S32, Location::GPR(status), Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
let status = status.into_index() as u32;
dynasm!(self ; stlxr W(status), W(reg), [X(dst)]);
}
(Size::S64, Location::GPR(status), Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
let status = status.into_index() as u32;
dynasm!(self ; stlxr W(status), X(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit STLXR {:?}, {:?}", reg, dst),
}
Ok(())
}
fn emit_stlxrb(
&mut self,
_sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError> {
match (status, reg, dst) {
(Location::GPR(status), Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
let status = status.into_index() as u32;
dynasm!(self ; stlxrb W(status), W(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit STLXRB {:?}, {:?}", reg, dst),
}
Ok(())
}
fn emit_stlxrh(
&mut self,
_sz: Size,
status: Location,
reg: Location,
dst: Location,
) -> Result<(), CompileError> {
match (status, reg, dst) {
(Location::GPR(status), Location::GPR(reg), Location::GPR(dst)) => {
let reg = reg.into_index() as u32;
let dst = dst.into_index() as u32;
let status = status.into_index() as u32;
dynasm!(self ; stlxrh W(status), W(reg), [X(dst)]);
}
_ => codegen_error!("singlepass can't emit STLXRH {:?}, {:?}", reg, dst),
}
Ok(())
}

fn emit_mov(&mut self, sz: Size, src: Location, dst: Location) -> Result<(), CompileError> {
match (sz, src, dst) {
(Size::S64, Location::GPR(src), Location::GPR(dst)) => {
Expand Down
Loading

0 comments on commit 8a0bd4b

Please sign in to comment.