Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
("reference_types", _) if cfg!(feature = "old-x86-backend") => return true,
// No simd support yet for s390x.
("simd", _) if platform_is_s390x() => return true,
// No memory64 support yet for s390x.
("memory64", _) if platform_is_s390x() => return true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come memory64 isn't implemented on s390x? Does it lower to unimplemented clif things at the moment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is all fixable, but I'd prefer to do that separately.

_ => {}
},
_ => panic!("unrecognized strategy"),
Expand Down
36 changes: 28 additions & 8 deletions cranelift/codegen/src/isa/s390x/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3607,6 +3607,9 @@ pub enum LabelUse {
/// 32-bit PC relative constant offset (from address of constant itself),
/// signed. Used in jump tables.
PCRel32,
/// 32-bit PC relative constant offset (from address of call instruction),
/// signed. Offset is imm << 1. Used for call relocations.
PCRel32Dbl,
}

impl MachInstLabelUse for LabelUse {
Expand All @@ -3617,21 +3620,29 @@ impl MachInstLabelUse for LabelUse {
fn max_pos_range(self) -> CodeOffset {
match self {
// 16-bit signed immediate, left-shifted by 1.
LabelUse::BranchRI => (1 << 20) - 1,
// This can address any valid CodeOffset.
LabelUse::BranchRIL => 0x7fff_ffff,
LabelUse::BranchRI => ((1 << 15) - 1) << 1,
// 32-bit signed immediate, left-shifted by 1.
LabelUse::BranchRIL => 0xffff_fffe,
// 32-bit signed immediate.
LabelUse::PCRel32 => 0x7fff_ffff,
// 32-bit signed immediate, left-shifted by 1, offset by 2.
LabelUse::PCRel32Dbl => 0xffff_fffc,
}
}

/// Maximum PC-relative range (negative).
fn max_neg_range(self) -> CodeOffset {
match self {
// 16-bit signed immediate, left-shifted by 1.
LabelUse::BranchRI => 1 << 20,
// This can address any valid CodeOffset.
LabelUse::BranchRIL => 0x8000_0000,
LabelUse::BranchRI => (1 << 15) << 1,
// 32-bit signed immediate, left-shifted by 1.
// NOTE: This should be 4GB, but CodeOffset is only u32.
LabelUse::BranchRIL => 0xffff_ffff,
// 32-bit signed immediate.
LabelUse::PCRel32 => 0x8000_0000,
// 32-bit signed immediate, left-shifted by 1, offset by 2.
// NOTE: This should be 4GB + 2, but CodeOffset is only u32.
LabelUse::PCRel32Dbl => 0xffff_ffff,
}
}

Expand All @@ -3641,6 +3652,7 @@ impl MachInstLabelUse for LabelUse {
LabelUse::BranchRI => 4,
LabelUse::BranchRIL => 6,
LabelUse::PCRel32 => 4,
LabelUse::PCRel32Dbl => 4,
}
}

Expand All @@ -3664,6 +3676,11 @@ impl MachInstLabelUse for LabelUse {
let insn_word = insn_word.wrapping_add(pc_rel as u32);
buffer[0..4].clone_from_slice(&u32::to_be_bytes(insn_word));
}
LabelUse::PCRel32Dbl => {
let insn_word = u32::from_be_bytes([buffer[0], buffer[1], buffer[2], buffer[3]]);
let insn_word = insn_word.wrapping_add((pc_rel_shifted + 1) as u32);
buffer[0..4].clone_from_slice(&u32::to_be_bytes(insn_word));
}
}
}

Expand All @@ -3687,7 +3704,10 @@ impl MachInstLabelUse for LabelUse {
unreachable!();
}

fn from_reloc(_reloc: Reloc, _addend: Addend) -> Option<Self> {
None
fn from_reloc(reloc: Reloc, addend: Addend) -> Option<Self> {
match (reloc, addend) {
(Reloc::S390xPCRel32Dbl, 2) => Some(LabelUse::PCRel32Dbl),
_ => None,
}
}
}
26 changes: 18 additions & 8 deletions cranelift/codegen/src/isa/s390x/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,16 @@ fn input_matches_const<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) ->
input.constant
}

/// Lower an instruction input to a 64-bit signed constant, if possible.
fn input_matches_sconst<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) -> Option<i64> {
if let Some(imm) = input_matches_const(ctx, input) {
let ty = ctx.input_ty(input.insn, input.input);
Some(sign_extend_to_u64(imm, ty_bits(ty) as u8) as i64)
} else {
None
}
}

/// Return false if instruction input cannot have the value Imm, true otherwise.
fn input_maybe_imm<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput, imm: u64) -> bool {
if let Some(c) = input_matches_const(ctx, input) {
Expand All @@ -79,8 +89,8 @@ fn input_maybe_imm<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput, imm: u6

/// Lower an instruction input to a 16-bit signed constant, if possible.
fn input_matches_simm16<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) -> Option<i16> {
if let Some(imm_value) = input_matches_const(ctx, input) {
if let Ok(imm) = i16::try_from(imm_value as i64) {
if let Some(imm_value) = input_matches_sconst(ctx, input) {
if let Ok(imm) = i16::try_from(imm_value) {
return Some(imm);
}
}
Expand All @@ -89,8 +99,8 @@ fn input_matches_simm16<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) ->

/// Lower an instruction input to a 32-bit signed constant, if possible.
fn input_matches_simm32<C: LowerCtx<I = Inst>>(ctx: &mut C, input: InsnInput) -> Option<i32> {
if let Some(imm_value) = input_matches_const(ctx, input) {
if let Ok(imm) = i32::try_from(imm_value as i64) {
if let Some(imm_value) = input_matches_sconst(ctx, input) {
if let Ok(imm) = i32::try_from(imm_value) {
return Some(imm);
}
}
Expand All @@ -112,8 +122,8 @@ fn negated_input_matches_simm16<C: LowerCtx<I = Inst>>(
ctx: &mut C,
input: InsnInput,
) -> Option<i16> {
if let Some(imm_value) = input_matches_const(ctx, input) {
if let Ok(imm) = i16::try_from(-(imm_value as i64)) {
if let Some(imm_value) = input_matches_sconst(ctx, input) {
if let Ok(imm) = i16::try_from(-imm_value) {
return Some(imm);
}
}
Expand All @@ -125,8 +135,8 @@ fn negated_input_matches_simm32<C: LowerCtx<I = Inst>>(
ctx: &mut C,
input: InsnInput,
) -> Option<i32> {
if let Some(imm_value) = input_matches_const(ctx, input) {
if let Ok(imm) = i32::try_from(-(imm_value as i64)) {
if let Some(imm_value) = input_matches_sconst(ctx, input) {
if let Ok(imm) = i32::try_from(-imm_value) {
return Some(imm);
}
}
Expand Down
2 changes: 1 addition & 1 deletion cranelift/codegen/src/machinst/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ impl<I: VCodeInst> MachBuffer<I> {
self.island_worst_case_size += kind.veneer_size();
self.island_worst_case_size &= !(I::LabelUse::ALIGN - 1);
}
let deadline = offset + kind.max_pos_range();
let deadline = offset.saturating_add(kind.max_pos_range());
if deadline < self.island_deadline {
self.island_deadline = deadline;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
test interpret
test run
target aarch64
target s390x
target x86_64 machinst

function %iconcat_isplit(i64, i64) -> i64, i64 {
Expand Down
4 changes: 2 additions & 2 deletions crates/fuzzing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ wasmi = "0.7.0"
# We rely on precompiled v8 binaries, but rusty-v8 doesn't have a precompiled
# binary for MinGW which is built on our CI. It does have one for Windows-msvc,
# though, so we could use that if we wanted. For now though just simplify a bit
# and don't depend on this on Windows.
[target.'cfg(not(windows))'.dependencies]
# and don't depend on this on Windows. The same applies on s390x.
[target.'cfg(not(any(windows, target_arch = "s390x")))'.dependencies]
rusty_v8 = "0.27"

[dev-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions crates/fuzzing/src/oracles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use std::time::{Duration, Instant};
use wasmtime::*;
use wasmtime_wast::WastContext;

#[cfg(not(windows))]
#[cfg(not(any(windows, target_arch = "s390x")))]
pub use v8::*;
#[cfg(not(windows))]
#[cfg(not(any(windows, target_arch = "s390x")))]
mod v8;

static CNT: AtomicUsize = AtomicUsize::new(0);
Expand Down