Skip to content
Merged
  •  
  •  
  •  
6 changes: 0 additions & 6 deletions cranelift/codegen/src/isa/aarch64/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ impl ABIMachineSpec for AArch64MachineDeps {
add_ret_area_ptr: bool,
mut args: ArgsAccumulator,
) -> CodegenResult<(u32, Option<usize>)> {
assert_ne!(
call_conv,
isa::CallConv::Winch,
"aarch64 does not support the 'winch' calling convention yet"
);

if matches!(call_conv, isa::CallConv::Tail) {
return compute_arg_locs_tail(params, add_ret_area_ptr, args);
}
Expand Down
1 change: 1 addition & 0 deletions cranelift/codegen/src/isa/aarch64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ impl TargetIsa for AArch64Backend {
let mut cs = Capstone::new()
.arm64()
.mode(arch::arm64::ArchMode::Arm)
.detail(true)
.build()?;
// AArch64 uses inline constants rather than a separate constant pool right now.
// Without this option, Capstone will stop disassembling as soon as it sees
Expand Down
1 change: 1 addition & 0 deletions cranelift/codegen/src/isa/x64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ impl TargetIsa for X64Backend {
.x86()
.mode(arch::x86::ArchMode::Mode64)
.syntax(arch::x86::ArchSyntax::Att)
.detail(true)
.build()
}

Expand Down
4 changes: 2 additions & 2 deletions crates/cranelift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ fn wasm_call_signature(
// The winch calling convention is only implemented for x64 and aarch64
arch if tunables.winch_callable => {
assert!(
matches!(arch, Architecture::X86_64),
"The Winch calling convention is only implemented for x86_64"
matches!(arch, Architecture::X86_64 | Architecture::Aarch64(_)),
"The Winch calling convention is only implemented for x86_64 and aarch64"
);
CallConv::Winch
}
Expand Down
7 changes: 4 additions & 3 deletions crates/cranelift/src/obj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,10 @@ impl<'a> UnwindInfoBuilder<'a> {
section_id: SectionId,
text_section_size: u64,
) {
let mut cie = compiler
.create_systemv_cie()
.expect("must be able to create a CIE for system-v unwind info");
let mut cie = match compiler.create_systemv_cie() {
Some(cie) => cie,
None => return,
};
let mut table = FrameTable::default();
cie.fde_address_encoding = gimli::constants::DW_EH_PE_pcrel;
let cie_id = table.add_cie(cie);
Expand Down
54 changes: 50 additions & 4 deletions tests/disas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use std::fmt::Write;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tempfile::TempDir;
use wasmtime::{Engine, OptLevel};
use wasmtime::{Engine, OptLevel, Strategy};
use wasmtime_cli_flags::CommonOptions;

fn main() -> Result<()> {
Expand Down Expand Up @@ -139,6 +139,8 @@ enum TestKind {
Compile,
/// Test the CLIF output, optimized.
Optimize,
/// Alias for "compile" plus `-C compiler=winch`
Winch,
}

impl Test {
Expand Down Expand Up @@ -194,6 +196,9 @@ impl Test {
config.emit_clif(tempdir.path());
}
TestKind::Compile => {}
TestKind::Winch => {
config.strategy(Strategy::Winch);
}
}
let engine = Engine::new(&config).context("failed to create engine")?;
let module = wat::parse_file(&self.path)?;
Expand Down Expand Up @@ -236,7 +241,7 @@ impl Test {
});
Ok(CompileOutput::Clif(functions))
}
TestKind::Compile => Ok(CompileOutput::Elf(elf)),
TestKind::Compile | TestKind::Winch => Ok(CompileOutput::Elf(elf)),
}
}

Expand Down Expand Up @@ -291,7 +296,7 @@ fn assert_output(
CompileOutput::Clif(funcs) => {
for mut func in funcs {
match kind {
TestKind::Compile => unreachable!(),
TestKind::Compile | TestKind::Winch => unreachable!(),
TestKind::Optimize => {
let mut ctx = cranelift_codegen::Context::for_function(func.clone());
ctx.optimize(isa, &mut Default::default())
Expand All @@ -316,7 +321,9 @@ fn assert_output(
}

fn disas_elf(disas: &capstone::Capstone, result: &mut String, elf: &[u8]) -> Result<()> {
use capstone::InsnGroupType::{CS_GRP_JUMP, CS_GRP_RET};
use object::{Endianness, Object, ObjectSection, ObjectSymbol};

let elf = object::read::elf::ElfFile64::<Endianness>::parse(elf)?;
let text = elf.section_by_name(".text").unwrap();
let text = text.data()?;
Expand All @@ -338,8 +345,32 @@ fn disas_elf(disas: &capstone::Capstone, result: &mut String, elf: &[u8]) -> Res
result.push_str("\n");
}
writeln!(result, "{name}:")?;

// By default don't write all the offsets of all the instructions. That
// means that small changes in the instruction sequence cause large
// diffs which aren't always the most readable. As a rough balance,
// print offset of instructions-after-jumps and anything-after-ret as
// that's a decent-enough heuristic for jump targets.
let mut prev_jump = false;
let mut write_offsets = false;

for inst in disas.disasm_all(bytes, sym.address())?.iter() {
write!(result, "{:>4x}: ", inst.address())?;
let detail = disas.insn_detail(&inst).ok();
let detail = detail.as_ref();
let is_jump = detail
.map(|d| {
d.groups()
.iter()
.find(|g| g.0 as u32 == CS_GRP_JUMP)
.is_some()
})
.unwrap_or(false);

if write_offsets || (prev_jump && !is_jump) {
write!(result, "{:>4x}: ", inst.address())?;
} else {
write!(result, " ")?;
}

match (inst.mnemonic(), inst.op_str()) {
(Some(i), Some(o)) => {
Expand All @@ -352,6 +383,21 @@ fn disas_elf(disas: &capstone::Capstone, result: &mut String, elf: &[u8]) -> Res
(Some(i), None) => writeln!(result, "{i}")?,
_ => unreachable!(),
}

prev_jump = is_jump;

// Flip write_offsets to true once we've seen a `ret`, as
// instructions that follow the return are often related to trap
// tables.
write_offsets = write_offsets
|| detail
.map(|d| {
d.groups()
.iter()
.find(|g| g.0 as u32 == CS_GRP_RET)
.is_some()
})
.unwrap_or(false);
}
}
Ok(())
Expand Down
76 changes: 38 additions & 38 deletions tests/disas/aarch64-relaxed-simd.wat
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,51 @@
)

;; wasm[0]::function[0]:
;; 0: stp x29, x30, [sp, #-0x10]!
;; 4: mov x29, sp
;; 8: fcvtzs v0.4s, v0.4s
;; c: ldp x29, x30, [sp], #0x10
;; 10: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; fcvtzs v0.4s, v0.4s
;; ldp x29, x30, [sp], #0x10
;; ret
;;
;; wasm[0]::function[1]:
;; 20: stp x29, x30, [sp, #-0x10]!
;; 24: mov x29, sp
;; 28: fcvtzu v0.4s, v0.4s
;; 2c: ldp x29, x30, [sp], #0x10
;; 30: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; fcvtzu v0.4s, v0.4s
;; ldp x29, x30, [sp], #0x10
;; ret
;;
;; wasm[0]::function[2]:
;; 40: stp x29, x30, [sp, #-0x10]!
;; 44: mov x29, sp
;; 48: fcvtzs v6.2d, v0.2d
;; 4c: sqxtn v0.2s, v6.2d
;; 50: ldp x29, x30, [sp], #0x10
;; 54: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; fcvtzs v6.2d, v0.2d
;; sqxtn v0.2s, v6.2d
;; ldp x29, x30, [sp], #0x10
;; ret
;;
;; wasm[0]::function[3]:
;; 60: stp x29, x30, [sp, #-0x10]!
;; 64: mov x29, sp
;; 68: fcvtzu v6.2d, v0.2d
;; 6c: uqxtn v0.2s, v6.2d
;; 70: ldp x29, x30, [sp], #0x10
;; 74: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; fcvtzu v6.2d, v0.2d
;; uqxtn v0.2s, v6.2d
;; ldp x29, x30, [sp], #0x10
;; ret
;;
;; wasm[0]::function[4]:
;; 80: stp x29, x30, [sp, #-0x10]!
;; 84: mov x29, sp
;; 88: smull v16.8h, v0.8b, v1.8b
;; 8c: smull2 v17.8h, v0.16b, v1.16b
;; 90: addp v0.8h, v16.8h, v17.8h
;; 94: ldp x29, x30, [sp], #0x10
;; 98: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; smull v16.8h, v0.8b, v1.8b
;; smull2 v17.8h, v0.16b, v1.16b
;; addp v0.8h, v16.8h, v17.8h
;; ldp x29, x30, [sp], #0x10
;; ret
;;
;; wasm[0]::function[5]:
;; a0: stp x29, x30, [sp, #-0x10]!
;; a4: mov x29, sp
;; a8: smull v19.8h, v0.8b, v1.8b
;; ac: smull2 v20.8h, v0.16b, v1.16b
;; b0: addp v19.8h, v19.8h, v20.8h
;; b4: saddlp v19.4s, v19.8h
;; b8: add v0.4s, v19.4s, v2.4s
;; bc: ldp x29, x30, [sp], #0x10
;; c0: ret
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; smull v19.8h, v0.8b, v1.8b
;; smull2 v20.8h, v0.16b, v1.16b
;; addp v19.8h, v19.8h, v20.8h
;; saddlp v19.4s, v19.8h
;; add v0.4s, v19.4s, v2.4s
;; ldp x29, x30, [sp], #0x10
;; ret
26 changes: 13 additions & 13 deletions tests/disas/i32-not-x64.wat
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@
)

;; wasm[0]::function[0]:
;; 0: pushq %rbp
;; 1: movq %rsp, %rbp
;; 4: movq %rdx, %rax
;; 7: notl %eax
;; 9: movq %rbp, %rsp
;; c: popq %rbp
;; d: retq
;; pushq %rbp
;; movq %rsp, %rbp
;; movq %rdx, %rax
;; notl %eax
;; movq %rbp, %rsp
;; popq %rbp
;; retq
;;
;; wasm[0]::function[1]:
;; 10: pushq %rbp
;; 11: movq %rsp, %rbp
;; 14: andnl %edx, %ecx, %eax
;; 19: movq %rbp, %rsp
;; 1c: popq %rbp
;; 1d: retq
;; pushq %rbp
;; movq %rsp, %rbp
;; andnl %edx, %ecx, %eax
;; movq %rbp, %rsp
;; popq %rbp
;; retq
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,29 @@
i32.load offset=0))

;; wasm[0]::function[0]:
;; 0: stp x29, x30, [sp, #-0x10]!
;; 4: mov x29, sp
;; 8: ldr x8, [x0, #0x58]
;; c: mov w9, w2
;; 10: sub x8, x8, #4
;; 14: cmp x9, x8
;; 18: b.hi #0x2c
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; ldr x8, [x0, #0x58]
;; mov w9, w2
;; sub x8, x8, #4
;; cmp x9, x8
;; b.hi #0x2c
;; 1c: ldr x10, [x0, #0x50]
;; 20: str w3, [x10, w2, uxtw]
;; 24: ldp x29, x30, [sp], #0x10
;; 28: ret
;; str w3, [x10, w2, uxtw]
;; ldp x29, x30, [sp], #0x10
;; ret
;; 2c: .byte 0x1f, 0xc1, 0x00, 0x00
;;
;; wasm[0]::function[1]:
;; 40: stp x29, x30, [sp, #-0x10]!
;; 44: mov x29, sp
;; 48: ldr x8, [x0, #0x58]
;; 4c: mov w9, w2
;; 50: sub x8, x8, #4
;; 54: cmp x9, x8
;; 58: b.hi #0x6c
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; ldr x8, [x0, #0x58]
;; mov w9, w2
;; sub x8, x8, #4
;; cmp x9, x8
;; b.hi #0x6c
;; 5c: ldr x10, [x0, #0x50]
;; 60: ldr w0, [x10, w2, uxtw]
;; 64: ldp x29, x30, [sp], #0x10
;; 68: ret
;; ldr w0, [x10, w2, uxtw]
;; ldp x29, x30, [sp], #0x10
;; ret
;; 6c: .byte 0x1f, 0xc1, 0x00, 0x00
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,33 @@
i32.load offset=0x1000))

;; wasm[0]::function[0]:
;; 0: stp x29, x30, [sp, #-0x10]!
;; 4: mov x29, sp
;; 8: ldr x10, [x0, #0x58]
;; c: mov w11, w2
;; 10: mov x12, #0x1004
;; 14: sub x10, x10, x12
;; 18: cmp x11, x10
;; 1c: b.hi #0x34
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; ldr x10, [x0, #0x58]
;; mov w11, w2
;; mov x12, #0x1004
;; sub x10, x10, x12
;; cmp x11, x10
;; b.hi #0x34
;; 20: ldr x12, [x0, #0x50]
;; 24: add x12, x12, #1, lsl #12
;; 28: str w3, [x12, w2, uxtw]
;; 2c: ldp x29, x30, [sp], #0x10
;; 30: ret
;; add x12, x12, #1, lsl #12
;; str w3, [x12, w2, uxtw]
;; ldp x29, x30, [sp], #0x10
;; ret
;; 34: .byte 0x1f, 0xc1, 0x00, 0x00
;;
;; wasm[0]::function[1]:
;; 40: stp x29, x30, [sp, #-0x10]!
;; 44: mov x29, sp
;; 48: ldr x10, [x0, #0x58]
;; 4c: mov w11, w2
;; 50: mov x12, #0x1004
;; 54: sub x10, x10, x12
;; 58: cmp x11, x10
;; 5c: b.hi #0x74
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; ldr x10, [x0, #0x58]
;; mov w11, w2
;; mov x12, #0x1004
;; sub x10, x10, x12
;; cmp x11, x10
;; b.hi #0x74
;; 60: ldr x12, [x0, #0x50]
;; 64: add x11, x12, #1, lsl #12
;; 68: ldr w0, [x11, w2, uxtw]
;; 6c: ldp x29, x30, [sp], #0x10
;; 70: ret
;; add x11, x12, #1, lsl #12
;; ldr w0, [x11, w2, uxtw]
;; ldp x29, x30, [sp], #0x10
;; ret
;; 74: .byte 0x1f, 0xc1, 0x00, 0x00
Loading