Skip to content

Commit

Permalink
Merge with upstream (bytecodealliance#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhil authored Mar 18, 2024
2 parents 8f8dded + 4a52b7f commit b376b91
Show file tree
Hide file tree
Showing 127 changed files with 4,489 additions and 2,517 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ wit-component = { workspace = true }
cranelift-filetests = { workspace = true }
cranelift-codegen = { workspace = true }
cranelift-reader = { workspace = true }
toml = { workspace = true }
similar = { workspace = true }

[target.'cfg(windows)'.dev-dependencies]
windows-sys = { workspace = true, features = ["Win32_System_Memory"] }
Expand Down
5 changes: 2 additions & 3 deletions cranelift/codegen/src/isa/x64/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,8 @@ fn emit_vm_call(
assert_eq!(inputs.len(), abi.num_args(ctx.sigs()));

for (i, input) in inputs.iter().enumerate() {
for inst in abi.gen_arg(ctx, i, ValueRegs::one(*input)) {
ctx.emit(inst);
}
let moves = abi.gen_arg(ctx, i, ValueRegs::one(*input));
abi.emit_arg_moves(ctx, moves);
}

let mut retval_insts: SmallInstVec<_> = smallvec![];
Expand Down
95 changes: 55 additions & 40 deletions cranelift/codegen/src/machinst/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ impl StackAMode {
StackAMode::SPOffset(off, ty) => StackAMode::SPOffset(off + addend, ty),
}
}

pub fn get_type(&self) -> ir::Type {
match self {
&StackAMode::FPOffset(_, ty) => ty,
&StackAMode::NominalSPOffset(_, ty) => ty,
&StackAMode::SPOffset(_, ty) => ty,
}
}
}

/// Trait implemented by machine-specific backend to represent ISA flags.
Expand Down Expand Up @@ -2041,6 +2049,13 @@ impl<M: ABIMachineSpec> Callee<M> {
}
}

/// The register or stack slot location of an argument.
#[derive(Clone, Debug)]
pub enum ArgLoc {
Reg(PReg),
Stack(StackAMode),
}

/// An input argument to a call instruction: the vreg that is used,
/// and the preg it is constrained to (per the ABI).
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -2289,6 +2304,20 @@ impl<M: ABIMachineSpec> CallSite<M> {
}
}

/// Emit moves or uses for the moves list generated by [`Self::gen_arg`].
pub fn emit_arg_moves(&mut self, ctx: &mut Lower<M::I>, moves: SmallVec<[(VReg, ArgLoc); 2]>) {
for (vreg, loc) in moves {
let vreg = vreg.into();
match loc {
ArgLoc::Reg(preg) => self.uses.push(CallArgPair {
vreg,
preg: preg.into(),
}),
ArgLoc::Stack(amode) => ctx.emit(M::gen_store_stack(amode, vreg, amode.get_type())),
}
}
}

/// Add a constraint for an argument value from a source register.
/// For large arguments with associated stack buffer, this may
/// load the address of the buffer into the argument register, if
Expand All @@ -2298,8 +2327,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
ctx: &mut Lower<M::I>,
idx: usize,
from_regs: ValueRegs<Reg>,
) -> SmallInstVec<M::I> {
let mut insts = smallvec![];
) -> SmallVec<[(VReg, ArgLoc); 2]> {
let mut insts = SmallInstVec::new();
let mut locs = smallvec![];
let word_rc = M::word_reg_class();
let word_bits = M::word_bits() as usize;

Expand Down Expand Up @@ -2357,10 +2387,7 @@ impl<M: ABIMachineSpec> CallSite<M> {
ty_bits(ty) as u8,
word_bits as u8,
));
self.uses.push(CallArgPair {
vreg: extend_result.to_reg(),
preg: reg.into(),
});
locs.push((extend_result.to_reg().into(), ArgLoc::Reg(reg.into())));
} else if ty.is_ref() {
// Reference-typed args need to be
// passed as a copy; the original vreg
Expand All @@ -2369,15 +2396,10 @@ impl<M: ABIMachineSpec> CallSite<M> {
let ref_copy =
temps.pop().expect("Must have allocated enough temps");
insts.push(M::gen_move(ref_copy, *from_reg, M::word_type()));
self.uses.push(CallArgPair {
vreg: ref_copy.to_reg(),
preg: reg.into(),
});

locs.push((ref_copy.to_reg().into(), ArgLoc::Reg(reg.into())));
} else {
self.uses.push(CallArgPair {
vreg: *from_reg,
preg: reg.into(),
});
locs.push((from_reg.into(), ArgLoc::Reg(reg.into())));
}
}
&ABIArgSlot::Stack {
Expand Down Expand Up @@ -2409,10 +2431,9 @@ impl<M: ABIMachineSpec> CallSite<M> {
} else {
(*from_reg, ty)
};
insts.push(M::gen_store_stack(
StackAMode::SPOffset(offset, ty),
data,
ty,
locs.push((
data.into(),
ArgLoc::Stack(StackAMode::SPOffset(offset, ty)),
));
}
}
Expand All @@ -2434,25 +2455,22 @@ impl<M: ABIMachineSpec> CallSite<M> {
insts.push(M::gen_get_stack_addr(amode, tmp, ty));
let tmp = tmp.to_reg();
insts.push(M::gen_store_base_offset(tmp, 0, vreg, ty));
match pointer {
ABIArgSlot::Reg { reg, .. } => {
self.uses.push(CallArgPair {
vreg: tmp,
preg: reg.into(),
});
}
let loc = match pointer {
ABIArgSlot::Reg { reg, .. } => ArgLoc::Reg(reg.into()),
ABIArgSlot::Stack { offset, .. } => {
let ty = M::word_type();
insts.push(M::gen_store_stack(
StackAMode::SPOffset(offset, ty),
tmp,
ty,
));
ArgLoc::Stack(StackAMode::SPOffset(offset, ty))
}
};
locs.push((tmp.into(), loc));
}
}
insts

for inst in insts {
ctx.emit(inst);
}

locs
}

/// Call `gen_arg` for each non-hidden argument and emit all instructions
Expand All @@ -2470,9 +2488,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
self.emit_copy_regs_to_buffer(ctx, i, *arg_regs);
}
for (i, value_regs) in arg_value_regs.iter().enumerate() {
for inst in self.gen_arg(ctx, i, *value_regs) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i, *value_regs);
self.emit_arg_moves(ctx, moves);
}
}

Expand All @@ -2484,9 +2501,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
"if the tail callee has a return pointer, then the tail caller \
must as well",
);
for inst in self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr.to_reg())) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i.into(), ValueRegs::one(ret_area_ptr.to_reg()));
self.emit_arg_moves(ctx, moves);
}
}

Expand Down Expand Up @@ -2592,9 +2608,8 @@ impl<M: ABIMachineSpec> CallSite<M> {
rd,
I8,
));
for inst in self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg())) {
ctx.emit(inst);
}
let moves = self.gen_arg(ctx, i.into(), ValueRegs::one(rd.to_reg()));
self.emit_arg_moves(ctx, moves);
}

let (uses, defs) = (
Expand Down
5 changes: 2 additions & 3 deletions cranelift/codegen/src/machinst/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -825,9 +825,8 @@ macro_rules! isle_prelude_method_helpers {
call_site.emit_copy_regs_to_buffer(self.lower_ctx, i, *arg_regs);
}
for (i, arg_regs) in arg_regs.iter().enumerate() {
for inst in call_site.gen_arg(self.lower_ctx, i, *arg_regs) {
self.lower_ctx.emit(inst);
}
let moves = call_site.gen_arg(self.lower_ctx, i, *arg_regs);
call_site.emit_arg_moves(self.lower_ctx, moves);
}
}

Expand Down
18 changes: 18 additions & 0 deletions cranelift/codegen/src/nan_canonicalization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,24 @@ fn is_fp_arith(pos: &mut FuncCursor, inst: Inst) -> bool {
|| opcode == Opcode::Fsub
}
InstructionData::Ternary { opcode, .. } => opcode == Opcode::Fma,

// bitcasts coming from arbitrary integers need canonicalization as the
// integer isn't known to necessarily be a canonical NaN
InstructionData::LoadNoOffset {
opcode: Opcode::Bitcast,
arg,
flags: _,
} => {
let ret = pos.func.dfg.first_result(inst);
let ret_type = pos.func.dfg.value_type(ret);
let arg_type = pos.func.dfg.value_type(arg);
match (arg_type, ret_type) {
(types::I32, types::F32) => true,
(types::I64, types::F64) => true,
_ => false,
}
}

_ => false,
}
}
Expand Down
2 changes: 0 additions & 2 deletions cranelift/filetests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,5 @@ wat.workspace = true
toml = { workspace = true }
serde = { workspace = true }
serde_derive = { workspace = true }
cranelift-wasm.workspace = true
wasmparser.workspace = true
cranelift.workspace = true
smallvec = { workspace = true }
14 changes: 14 additions & 0 deletions cranelift/filetests/src/function_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ impl TestFileCompiler {
}
}));
}

// On Unix platforms force `libm` to get linked into this executable
// because tests that use libcalls rely on this library being present.
// Without this it's been seen that when cross-compiled to riscv64 the
// final binary doesn't link in `libm`.
#[cfg(unix)]
{
extern "C" {
fn ceilf(f: f32) -> f32;
}
let f = 1.2_f32;
assert_eq!(f.ceil(), unsafe { ceilf(f) });
}

let module = JITModule::new(builder);
let ctx = module.make_context();

Expand Down
1 change: 0 additions & 1 deletion cranelift/filetests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ mod test_run;
mod test_safepoint;
mod test_unwind;
mod test_verifier;
pub mod test_wasm;

/// Main entry point for `clif-util test`.
///
Expand Down
5 changes: 0 additions & 5 deletions cranelift/filetests/src/runone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ pub fn run(
let buffer =
fs::read_to_string(path).with_context(|| format!("failed to read {}", path.display()))?;

if path.extension().map_or(false, |ext| ext == "wat") {
crate::test_wasm::run(path, &buffer)?;
return Ok(started.elapsed());
}

let options = ParseOptions {
target,
passes,
Expand Down
Loading

0 comments on commit b376b91

Please # to comment.