This patch fills in the missing pieces needed to support wasm atomics on newBE/x64.
It does this by providing an implementation of the CLIF instructions `AtomicRmw`, `AtomicCas`, `AtomicLoad`, `AtomicStore` and `Fence`. The translation is straightforward. `AtomicCas` is translated into x64 `cmpxchg`, `AtomicLoad` becomes a normal load because x64-TSO provides adequate sequencing, `AtomicStore` becomes a normal store followed by `mfence`, and `Fence` becomes `mfence`. `AtomicRmw` is the only complex case: it becomes a normal load, followed by a loop which computes an updated value, tries to `cmpxchg` it back to memory, and repeats if necessary. This is a minimum-effort initial implementation. `AtomicRmw` could be implemented more efficiently using LOCK-prefixed integer read-modify-write instructions in the case where the old value in memory is not required. Subsequent work could add that, if required. The x64 emitter has been updated to emit the new instructions, obviously. The `LegacyPrefix` mechanism has been revised to handle multiple prefix bytes, not just one, since it is now sometimes necessary to emit both 0x66 (Operand Size Override) and F0 (Lock). In the aarch64 implementation of atomics, there has been some minor renaming for the sake of clarity, and for consistency with this x64 implementation.
This commit is contained in:
committed by
julian-seward1
parent
ec87aee147
commit
620e4b4e82
36
cranelift/codegen/src/machinst/inst_common.rs
Normal file
36
cranelift/codegen/src/machinst/inst_common.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
//! A place to park MachInst::Inst fragments which are common across multiple architectures.
|
||||
|
||||
use crate::ir;
|
||||
|
||||
/// Atomic memory update operations. As of 21 Aug 2020 these are used for the aarch64 and x64
|
||||
/// targets.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum AtomicRmwOp {
|
||||
/// Add
|
||||
Add,
|
||||
/// Sub
|
||||
Sub,
|
||||
/// And
|
||||
And,
|
||||
/// Or
|
||||
Or,
|
||||
/// Exclusive Or
|
||||
Xor,
|
||||
/// Exchange (swap operands)
|
||||
Xchg,
|
||||
}
|
||||
|
||||
impl AtomicRmwOp {
|
||||
/// Converts an `ir::AtomicRmwOp` to the corresponding `inst_common::AtomicRmwOp`.
|
||||
pub fn from(ir_op: ir::AtomicRmwOp) -> Self {
|
||||
match ir_op {
|
||||
ir::AtomicRmwOp::Add => AtomicRmwOp::Add,
|
||||
ir::AtomicRmwOp::Sub => AtomicRmwOp::Sub,
|
||||
ir::AtomicRmwOp::And => AtomicRmwOp::And,
|
||||
ir::AtomicRmwOp::Or => AtomicRmwOp::Or,
|
||||
ir::AtomicRmwOp::Xor => AtomicRmwOp::Xor,
|
||||
ir::AtomicRmwOp::Xchg => AtomicRmwOp::Xchg,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,6 +133,8 @@ pub mod adapter;
|
||||
pub use adapter::*;
|
||||
pub mod helpers;
|
||||
pub use helpers::*;
|
||||
pub mod inst_common;
|
||||
pub use inst_common::*;
|
||||
|
||||
/// A machine instruction.
|
||||
pub trait MachInst: Clone + Debug {
|
||||
|
||||
Reference in New Issue
Block a user