Skip to content

Commit

Permalink
Winch aarch64 dynamic heap (bytecodealliance#9252)
Browse files Browse the repository at this point in the history
* winch aarch64 traps

* winch aarch64 cmov & checked add

* winch aarch64 dynamic heap tests

* winch aarch64 cmov: use csel

* winch aarch64 checked_uadd: use unsigned overflow condition

* Update filetests and rebase

---------

Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>
  • Loading branch information
vulc41n and saulecabrera authored Oct 4, 2024
1 parent a772164 commit 8096068
Show file tree
Hide file tree
Showing 4 changed files with 239 additions and 14 deletions.
105 changes: 105 additions & 0 deletions tests/disas/winch/aarch64/load/dynamic_heap.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
;;! target = "aarch64"
;;! test = "winch"
;;! flags = "-O static-memory-maximum-size=100 -O dynamic-memory-guard-size=0xffff"

(module
(memory (export "memory") 17)
(func (export "run") (param i32) (result i32 i32 i32)
;; Within the guard region.
local.get 0
i32.load offset=0
;; Also within the guard region, bounds check should GVN with previous.
local.get 0
i32.load offset=4

;; Outside the guard region, needs additional bounds checks.
local.get 0
i32.load offset=0x000fffff
)
(data (i32.const 0) "\45\00\00\00\a4\01\00\00")
(data (i32.const 0x000fffff) "\39\05\00\00")
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x1
;; sub sp, sp, #0x20
;; mov x28, sp
;; stur x1, [x28, #0x18]
;; stur x2, [x28, #0x10]
;; stur w3, [x28, #0xc]
;; stur x0, [x28]
;; ldur w0, [x28, #0xc]
;; ldur x1, [x9, #0x68]
;; mov w2, w0
;; add x2, x2, #4
;; b.hs #0x134
;; 3c: cmp x2, x1, uxtx
;; b.hi #0x138
;; 44: ldur x3, [x9, #0x60]
;; add x3, x3, x0, uxtx
;; mov x16, #0
;; mov x4, x16
;; cmp x2, x1, uxtx
;; csel x3, x4, x4, hi
;; ldur w0, [x3]
;; ldur w1, [x28, #0xc]
;; ldur x2, [x9, #0x68]
;; mov w3, w1
;; add x3, x3, #8
;; b.hs #0x13c
;; 74: cmp x3, x2, uxtx
;; b.hi #0x140
;; 7c: ldur x4, [x9, #0x60]
;; add x4, x4, x1, uxtx
;; add x4, x4, #4
;; mov x16, #0
;; mov x5, x16
;; cmp x3, x2, uxtx
;; csel x4, x5, x5, hi
;; ldur w1, [x4]
;; ldur w2, [x28, #0xc]
;; ldur x3, [x9, #0x68]
;; mov w4, w2
;; mov w16, #3
;; movk w16, #0x10, lsl #16
;; add x4, x4, x16, uxtx
;; b.hs #0x144
;; b8: cmp x4, x3, uxtx
;; b.hi #0x148
;; c0: ldur x5, [x9, #0x60]
;; add x5, x5, x2, uxtx
;; orr x16, xzr, #0xfffff
;; add x5, x5, x16, uxtx
;; mov x16, #0
;; mov x6, x16
;; cmp x4, x3, uxtx
;; csel x5, x6, x6, hi
;; ldur w2, [x5]
;; sub sp, sp, #4
;; mov x28, sp
;; stur w0, [x28]
;; sub sp, sp, #4
;; mov x28, sp
;; stur w1, [x28]
;; mov w0, w2
;; ldur x1, [x28, #8]
;; ldur w16, [x28]
;; add sp, sp, #4
;; mov x28, sp
;; stur w16, [x1]
;; ldur w16, [x28]
;; add sp, sp, #4
;; mov x28, sp
;; stur w16, [x1, #4]
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret
;; 134: .byte 0x1f, 0xc1, 0x00, 0x00
;; 138: .byte 0x1f, 0xc1, 0x00, 0x00
;; 13c: .byte 0x1f, 0xc1, 0x00, 0x00
;; 140: .byte 0x1f, 0xc1, 0x00, 0x00
;; 144: .byte 0x1f, 0xc1, 0x00, 0x00
;; 148: .byte 0x1f, 0xc1, 0x00, 0x00
94 changes: 94 additions & 0 deletions tests/disas/winch/aarch64/store/dynamic_heap.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
;;! target = "aarch64"
;;! test = "winch"
;;! flags = "-O static-memory-maximum-size=0 -O dynamic-memory-guard-size=0xffff"

(module
(memory (export "memory") 1)
(func (export "run") (param i32 i32 i32 i32)
;; Within the guard region.
local.get 0
local.get 1
i32.store offset=0
;; Also within the guard region, bounds check should GVN with previous.
local.get 0
local.get 2
i32.store offset=4
;; Outside the guard region, needs additional bounds checks.
local.get 0
local.get 3
i32.store offset=0x000fffff
)
)
;; wasm[0]::function[0]:
;; stp x29, x30, [sp, #-0x10]!
;; mov x29, sp
;; mov x28, sp
;; mov x9, x0
;; sub sp, sp, #0x20
;; mov x28, sp
;; stur x0, [x28, #0x18]
;; stur x1, [x28, #0x10]
;; stur w2, [x28, #0xc]
;; stur w3, [x28, #8]
;; stur w4, [x28, #4]
;; stur w5, [x28]
;; ldur w0, [x28, #8]
;; ldur w1, [x28, #0xc]
;; ldur x2, [x9, #0x68]
;; mov w3, w1
;; add x3, x3, #4
;; b.hs #0x108
;; 48: cmp x3, x2, uxtx
;; b.hi #0x10c
;; 50: ldur x4, [x9, #0x60]
;; add x4, x4, x1, uxtx
;; mov x16, #0
;; mov x5, x16
;; cmp x3, x2, uxtx
;; csel x4, x5, x5, hi
;; stur w0, [x4]
;; ldur w0, [x28, #4]
;; ldur w1, [x28, #0xc]
;; ldur x2, [x9, #0x68]
;; mov w3, w1
;; add x3, x3, #8
;; b.hs #0x110
;; 84: cmp x3, x2, uxtx
;; b.hi #0x114
;; 8c: ldur x4, [x9, #0x60]
;; add x4, x4, x1, uxtx
;; add x4, x4, #4
;; mov x16, #0
;; mov x5, x16
;; cmp x3, x2, uxtx
;; csel x4, x5, x5, hi
;; stur w0, [x4]
;; ldur w0, [x28]
;; ldur w1, [x28, #0xc]
;; ldur x2, [x9, #0x68]
;; mov w3, w1
;; mov w16, #3
;; movk w16, #0x10, lsl #16
;; add x3, x3, x16, uxtx
;; b.hs #0x118
;; cc: cmp x3, x2, uxtx
;; b.hi #0x11c
;; d4: ldur x4, [x9, #0x60]
;; add x4, x4, x1, uxtx
;; orr x16, xzr, #0xfffff
;; add x4, x4, x16, uxtx
;; mov x16, #0
;; mov x5, x16
;; cmp x3, x2, uxtx
;; csel x4, x5, x5, hi
;; stur w0, [x4]
;; add sp, sp, #0x20
;; mov x28, sp
;; ldp x29, x30, [sp], #0x10
;; ret
;; 108: .byte 0x1f, 0xc1, 0x00, 0x00
;; 10c: .byte 0x1f, 0xc1, 0x00, 0x00
;; 110: .byte 0x1f, 0xc1, 0x00, 0x00
;; 114: .byte 0x1f, 0xc1, 0x00, 0x00
;; 118: .byte 0x1f, 0xc1, 0x00, 0x00
;; 11c: .byte 0x1f, 0xc1, 0x00, 0x00
25 changes: 25 additions & 0 deletions winch/codegen/src/isa/aarch64/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
masm::OperandSize,
reg::{writable, Reg, WritableReg},
};
use cranelift_codegen::ir::TrapCode;
use cranelift_codegen::isa::aarch64::inst::{
BitOp, BranchTarget, Cond, CondBrKind, FPULeftShiftImm, FPUOp1, FPUOp2,
FPUOpRI::{self, UShr32, UShr64},
Expand Down Expand Up @@ -674,6 +675,17 @@ impl Assembler {
});
}

// If the condition is true, Conditional Select writes rm to rd. If the condition is false,
// it writes rn to rd
pub fn csel(&mut self, rm: Reg, rn: Reg, rd: WritableReg, cond: Cond) {
self.emit(Inst::CSel {
rd: rd.map(Into::into),
rm: rm.into(),
rn: rn.into(),
cond,
});
}

// Population Count per byte.
pub fn cnt(&mut self, rd: Reg) {
self.emit(Inst::VecMisc {
Expand All @@ -699,6 +711,19 @@ impl Assembler {
self.emit_alu_rrr(ALUOp::AndS, rm, rn, writable!(regs::zero()), size);
}

/// Permanently Undefined.
pub fn udf(&mut self, code: TrapCode) {
self.emit(Inst::Udf { trap_code: code });
}

/// Conditional trap.
pub fn trapif(&mut self, cc: Cond, code: TrapCode) {
self.emit(Inst::TrapIf {
kind: CondBrKind::Cond(cc),
trap_code: code,
});
}

// Helpers for ALU operations.

fn emit_alu_rri(&mut self, op: ALUOp, imm: Imm12, rn: Reg, rd: WritableReg, size: OperandSize) {
Expand Down
29 changes: 15 additions & 14 deletions winch/codegen/src/isa/aarch64/masm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
use cranelift_codegen::{
binemit::CodeOffset,
ir::{RelSourceLoc, SourceLoc},
isa::aarch64::inst::VectorSize,
isa::aarch64::inst::{Cond, VectorSize},
settings, Final, MachBufferFinalized, MachLabel,
};
use regalloc2::RegClass;
Expand Down Expand Up @@ -238,8 +238,8 @@ impl Masm for MacroAssembler {
}
}

fn cmov(&mut self, _dst: WritableReg, _src: Reg, _cc: IntCmpKind, _size: OperandSize) {
todo!()
fn cmov(&mut self, dst: WritableReg, src: Reg, cc: IntCmpKind, _size: OperandSize) {
self.asm.csel(src, src, dst, Cond::from(cc));
}

fn add(&mut self, dst: WritableReg, lhs: Reg, rhs: RegImm, size: OperandSize) {
Expand All @@ -262,13 +262,14 @@ impl Masm for MacroAssembler {

fn checked_uadd(
&mut self,
_dst: WritableReg,
_lhs: Reg,
_rhs: RegImm,
_size: OperandSize,
_trap: TrapCode,
dst: WritableReg,
lhs: Reg,
rhs: RegImm,
size: OperandSize,
trap: TrapCode,
) {
todo!()
self.add(dst, lhs, rhs, size);
self.asm.trapif(Cond::Hs, trap);
}

fn sub(&mut self, dst: WritableReg, lhs: Reg, rhs: RegImm, size: OperandSize) {
Expand Down Expand Up @@ -632,7 +633,7 @@ impl Masm for MacroAssembler {
}

fn unreachable(&mut self) {
todo!()
self.asm.udf(wasmtime_cranelift::TRAP_UNREACHABLE);
}

fn jmp_table(&mut self, targets: &[MachLabel], index: Reg, tmp: Reg) {
Expand All @@ -647,16 +648,16 @@ impl Masm for MacroAssembler {
self.asm.jmp_table(rest, default, index, tmp1, tmp);
}

fn trap(&mut self, _code: TrapCode) {
todo!()
fn trap(&mut self, code: TrapCode) {
self.asm.udf(code);
}

fn trapz(&mut self, _src: Reg, _code: TrapCode) {
todo!()
}

fn trapif(&mut self, _cc: IntCmpKind, _code: TrapCode) {
todo!()
fn trapif(&mut self, cc: IntCmpKind, code: TrapCode) {
self.asm.trapif(cc.into(), code);
}

fn start_source_loc(&mut self, loc: RelSourceLoc) -> (CodeOffset, RelSourceLoc) {
Expand Down

0 comments on commit 8096068

Please sign in to comment.