From 7c5c7e4b6d5d12fa2fd9da8cb092e45ec4a815f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Cabrera?= Date: Wed, 8 Feb 2023 20:01:44 -0500 Subject: [PATCH] winch: Add full support for integer `sub` and `add` instructions (#5737) This patch adds complete support for the `sub` and `add` WebAssembly instructions for x64, and complete support for the `add` WebAssembly instruction for aarch64. This patch also refactors how the binary operations get constructed within the `VisitOperator` trait implementation. The refactor adds methods in the `CodeGenContext` to abstract all the common steps to emit binary operations, making this process less repetitive and less brittle (e.g. omitting to push the resulting value to the stack, or omitting to free registers after used). This patch also improves test coverage and refactors the filetests directory to make it easier to add tests for other instructions. --- winch/codegen/src/codegen.rs | 62 +++++++++++++- winch/codegen/src/isa/aarch64/asm.rs | 4 +- winch/codegen/src/isa/aarch64/masm.rs | 4 + winch/codegen/src/isa/x64/asm.rs | 47 ++++++++++- winch/codegen/src/isa/x64/masm.rs | 13 +++ winch/codegen/src/masm.rs | 9 +- winch/codegen/src/regalloc.rs | 3 +- winch/codegen/src/stack.rs | 39 ++++++++- winch/codegen/src/visitor.rs | 84 ++++++++----------- .../{basic_add.wat => i32_add/const.wat} | 7 +- .../locals.wat} | 9 +- .../filetests/aarch64/i32_add/max.wat | 16 ++++ .../filetests/aarch64/i32_add/max_one.wat | 18 ++++ .../filetests/aarch64/i32_add/mixed.wat | 17 ++++ .../params.wat} | 11 ++- .../filetests/aarch64/i32_add/signed.wat | 18 ++++ .../aarch64/i32_add/unsigned_with_zero.wat | 17 ++++ .../filetests/aarch64/i64_add/const.wat | 17 ++++ .../filetests/aarch64/i64_add/locals.wat | 40 +++++++++ .../filetests/aarch64/i64_add/max.wat | 17 ++++ .../filetests/aarch64/i64_add/max_one.wat | 18 ++++ .../filetests/aarch64/i64_add/mixed.wat | 17 ++++ .../filetests/aarch64/i64_add/params.wat | 24 ++++++ .../filetests/aarch64/i64_add/signed.wat | 18 ++++ .../aarch64/i64_add/unsigned_with_zero.wat | 17 ++++ winch/filetests/filetests/aarch64/simple.wat | 15 ---- .../x64/{basic_add.wat => i32_add/const.wat} | 7 +- .../locals.wat} | 9 +- winch/filetests/filetests/x64/i32_add/max.wat | 14 ++++ .../filetests/x64/i32_add/max_one.wat | 15 ++++ .../filetests/filetests/x64/i32_add/mixed.wat | 15 ++++ .../params.wat} | 11 ++- .../filetests/x64/i32_add/signed.wat | 15 ++++ .../x64/i32_add/unsigned_with_zero.wat | 15 ++++ .../filetests/filetests/x64/i32_sub/const.wat | 15 ++++ .../filetests/x64/i32_sub/locals.wat | 33 ++++++++ winch/filetests/filetests/x64/i32_sub/max.wat | 14 ++++ .../filetests/x64/i32_sub/max_one.wat | 15 ++++ .../filetests/filetests/x64/i32_sub/mixed.wat | 15 ++++ .../filetests/x64/i32_sub/params.wat | 21 +++++ .../filetests/x64/i32_sub/signed.wat | 15 ++++ .../x64/i32_sub/unsigned_with_zero.wat | 15 ++++ .../filetests/filetests/x64/i64_add/const.wat | 15 ++++ .../filetests/x64/i64_add/locals.wat | 35 ++++++++ winch/filetests/filetests/x64/i64_add/max.wat | 16 ++++ .../filetests/x64/i64_add/max_one.wat | 16 ++++ .../filetests/filetests/x64/i64_add/mixed.wat | 15 ++++ .../filetests/x64/i64_add/params.wat | 21 +++++ .../filetests/x64/i64_add/signed.wat | 15 ++++ .../x64/i64_add/unsigned_with_zero.wat | 15 ++++ .../filetests/filetests/x64/i64_sub/const.wat | 15 ++++ .../filetests/x64/i64_sub/locals.wat | 35 ++++++++ winch/filetests/filetests/x64/i64_sub/max.wat | 15 ++++ .../filetests/x64/i64_sub/max_one.wat | 16 ++++ .../filetests/filetests/x64/i64_sub/mixed.wat | 15 ++++ .../filetests/x64/i64_sub/params.wat | 21 +++++ .../filetests/x64/i64_sub/signed.wat | 15 ++++ .../x64/i64_sub/unsigned_with_zero.wat | 15 ++++ winch/filetests/filetests/x64/simple.wat | 12 --- 59 files changed, 992 insertions(+), 120 deletions(-) rename winch/filetests/filetests/aarch64/{basic_add.wat => i32_add/const.wat} (86%) rename winch/filetests/filetests/aarch64/{basic_add_with_locals.wat => i32_add/locals.wat} (94%) create mode 100644 winch/filetests/filetests/aarch64/i32_add/max.wat create mode 100644 winch/filetests/filetests/aarch64/i32_add/max_one.wat create mode 100644 winch/filetests/filetests/aarch64/i32_add/mixed.wat rename winch/filetests/filetests/aarch64/{basic_add_with_params.wat => i32_add/params.wat} (83%) create mode 100644 winch/filetests/filetests/aarch64/i32_add/signed.wat create mode 100644 winch/filetests/filetests/aarch64/i32_add/unsigned_with_zero.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/const.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/locals.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/max.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/max_one.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/mixed.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/params.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/signed.wat create mode 100644 winch/filetests/filetests/aarch64/i64_add/unsigned_with_zero.wat delete mode 100644 winch/filetests/filetests/aarch64/simple.wat rename winch/filetests/filetests/x64/{basic_add.wat => i32_add/const.wat} (81%) rename winch/filetests/filetests/x64/{basic_add_with_locals.wat => i32_add/locals.wat} (92%) create mode 100644 winch/filetests/filetests/x64/i32_add/max.wat create mode 100644 winch/filetests/filetests/x64/i32_add/max_one.wat create mode 100644 winch/filetests/filetests/x64/i32_add/mixed.wat rename winch/filetests/filetests/x64/{basic_add_with_params.wat => i32_add/params.wat} (80%) create mode 100644 winch/filetests/filetests/x64/i32_add/signed.wat create mode 100644 winch/filetests/filetests/x64/i32_add/unsigned_with_zero.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/const.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/locals.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/max.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/max_one.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/mixed.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/params.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/signed.wat create mode 100644 winch/filetests/filetests/x64/i32_sub/unsigned_with_zero.wat create mode 100644 winch/filetests/filetests/x64/i64_add/const.wat create mode 100644 winch/filetests/filetests/x64/i64_add/locals.wat create mode 100644 winch/filetests/filetests/x64/i64_add/max.wat create mode 100644 winch/filetests/filetests/x64/i64_add/max_one.wat create mode 100644 winch/filetests/filetests/x64/i64_add/mixed.wat create mode 100644 winch/filetests/filetests/x64/i64_add/params.wat create mode 100644 winch/filetests/filetests/x64/i64_add/signed.wat create mode 100644 winch/filetests/filetests/x64/i64_add/unsigned_with_zero.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/const.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/locals.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/max.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/max_one.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/mixed.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/params.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/signed.wat create mode 100644 winch/filetests/filetests/x64/i64_sub/unsigned_with_zero.wat delete mode 100644 winch/filetests/filetests/x64/simple.wat diff --git a/winch/codegen/src/codegen.rs b/winch/codegen/src/codegen.rs index 460e0089d2..7114db7708 100644 --- a/winch/codegen/src/codegen.rs +++ b/winch/codegen/src/codegen.rs @@ -1,9 +1,9 @@ use crate::{ abi::{ABISig, ABI}, frame::Frame, - masm::{MacroAssembler, OperandSize}, + masm::{MacroAssembler, OperandSize, RegImm}, regalloc::RegAlloc, - stack::Stack, + stack::{Stack, Val}, }; use anyhow::Result; use wasmparser::{BinaryReader, FuncValidator, ValType, ValidatorResources, VisitOperator}; @@ -22,9 +22,67 @@ impl<'a, M> CodeGenContext<'a, M> where M: MacroAssembler, { + /// Create a new code generation context. pub fn new(masm: &'a mut M, stack: Stack, frame: &'a Frame) -> Self { Self { masm, stack, frame } } + + /// Prepares arguments for emitting an i32 binary operation. + pub fn i32_binop(&mut self, regalloc: &mut RegAlloc, emit: &mut F) + where + F: FnMut(&mut M, RegImm, RegImm, OperandSize), + { + let top = self.stack.peek().expect("value at stack top"); + + if top.is_i32_const() { + let val = self + .stack + .pop_i32_const() + .expect("i32 const value at stack top"); + let reg = regalloc.pop_to_reg(self, OperandSize::S32); + emit( + &mut self.masm, + RegImm::reg(reg), + RegImm::imm(val as i64), + OperandSize::S32, + ); + self.stack.push(Val::reg(reg)); + } else { + let src = regalloc.pop_to_reg(self, OperandSize::S32); + let dst = regalloc.pop_to_reg(self, OperandSize::S32); + emit(&mut self.masm, dst.into(), src.into(), OperandSize::S32); + regalloc.free_gpr(src); + self.stack.push(Val::reg(dst)); + } + } + + /// Prepares arguments for emitting an i64 binary operation. + pub fn i64_binop(&mut self, regalloc: &mut RegAlloc, emit: &mut F) + where + F: FnMut(&mut M, RegImm, RegImm, OperandSize), + { + let top = self.stack.peek().expect("value at stack top"); + if top.is_i64_const() { + let val = self + .stack + .pop_i64_const() + .expect("i64 const value at stack top"); + let reg = regalloc.pop_to_reg(self, OperandSize::S64); + emit( + &mut self.masm, + RegImm::reg(reg), + RegImm::imm(val), + OperandSize::S64, + ); + self.stack.push(Val::reg(reg)); + } else { + let src = regalloc.pop_to_reg(self, OperandSize::S64); + let dst = regalloc.pop_to_reg(self, OperandSize::S64); + emit(&mut self.masm, dst.into(), src.into(), OperandSize::S64); + regalloc.free_gpr(src); + self.stack.push(Val::reg(dst)); + } + } } /// The code generation abstraction. diff --git a/winch/codegen/src/isa/aarch64/asm.rs b/winch/codegen/src/isa/aarch64/asm.rs index a8eb741db8..34a19cfb09 100644 --- a/winch/codegen/src/isa/aarch64/asm.rs +++ b/winch/codegen/src/isa/aarch64/asm.rs @@ -19,8 +19,8 @@ pub(crate) enum Operand { Reg(Reg), /// Memory address. Mem(Address), - /// Immediate. - Imm(i32), + /// 64-bit signed immediate. + Imm(i64), } // Conversions between winch-codegen aarch64 types and cranelift-codegen diff --git a/winch/codegen/src/isa/aarch64/masm.rs b/winch/codegen/src/isa/aarch64/masm.rs index 40f2313fe0..65c5790e95 100644 --- a/winch/codegen/src/isa/aarch64/masm.rs +++ b/winch/codegen/src/isa/aarch64/masm.rs @@ -143,6 +143,10 @@ impl Masm for MacroAssembler { self.asm.add(rhs.into(), lhs.into(), dst.into(), size); } + fn sub(&mut self, _dst: RegImm, _lhs: RegImm, _rhs: RegImm, _size: OperandSize) { + todo!() + } + fn zero(&mut self, reg: Reg) { self.asm.load_constant(0, reg); } diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs index 7628851604..765f41dbe2 100644 --- a/winch/codegen/src/isa/x64/asm.rs +++ b/winch/codegen/src/isa/x64/asm.rs @@ -12,7 +12,7 @@ use cranelift_codegen::{ settings, Final, MachBuffer, MachBufferFinalized, MachInstEmit, Writable, }; -use super::address::Address; +use super::{address::Address, regs}; /// A x64 instruction operand. #[derive(Debug, Copy, Clone)] @@ -21,8 +21,8 @@ pub(crate) enum Operand { Reg(Reg), /// Memory address. Mem(Address), - /// Immediate. - Imm(i32), + /// Signed 64-bit immediate. + Imm(i64), } // Conversions between winch-codegen x64 types and cranelift-codegen x64 types. @@ -198,6 +198,37 @@ impl Assembler { } } + /// Subtract instruction variants. + pub fn sub(&mut self, src: Operand, dst: Operand, size: OperandSize) { + match &(src, dst) { + (Operand::Imm(imm), Operand::Reg(dst)) => { + if let Ok(val) = i32::try_from(*imm) { + self.sub_ir(val, *dst, size) + } else { + let scratch = regs::scratch(); + self.mov_ir(*imm as u64, scratch, size); + self.sub_rr(scratch, *dst, size); + } + } + (Operand::Reg(src), Operand::Reg(dst)) => self.sub_rr(*src, *dst, size), + _ => panic!( + "Invalid operand combination for sub; src = {:?} dst = {:?}", + src, dst + ), + } + } + + /// Subtract register and register + pub fn sub_rr(&mut self, src: Reg, dst: Reg, size: OperandSize) { + self.emit(Inst::AluRmiR { + size: size.into(), + op: AluRmiROpcode::Sub, + src1: dst.into(), + src2: src.into(), + dst: dst.into(), + }); + } + /// Subtact immediate register. pub fn sub_ir(&mut self, imm: i32, dst: Reg, size: OperandSize) { let imm = RegMemImm::imm(imm as u32); @@ -214,7 +245,15 @@ impl Assembler { /// Add instruction variants. pub fn add(&mut self, src: Operand, dst: Operand, size: OperandSize) { match &(src, dst) { - (Operand::Imm(imm), Operand::Reg(dst)) => self.add_ir(*imm, *dst, size), + (Operand::Imm(imm), Operand::Reg(dst)) => { + if let Ok(val) = i32::try_from(*imm) { + self.add_ir(val, *dst, size) + } else { + let scratch = regs::scratch(); + self.mov_ir(*imm as u64, scratch, size); + self.add_rr(scratch, *dst, size); + } + } (Operand::Reg(src), Operand::Reg(dst)) => self.add_rr(*src, *dst, size), _ => panic!( "Invalid operand combination for add; src = {:?} dst = {:?}", diff --git a/winch/codegen/src/isa/x64/masm.rs b/winch/codegen/src/isa/x64/masm.rs index b5cd3e54d6..5e5fbedd36 100644 --- a/winch/codegen/src/isa/x64/masm.rs +++ b/winch/codegen/src/isa/x64/masm.rs @@ -126,6 +126,19 @@ impl Masm for MacroAssembler { self.asm.add(src, dst, size); } + fn sub(&mut self, dst: RegImm, lhs: RegImm, rhs: RegImm, size: OperandSize) { + let (src, dst): (Operand, Operand) = if dst == lhs { + (rhs.into(), dst.into()) + } else { + panic!( + "the destination and first source argument must be the same, dst={:?}, lhs={:?}", + dst, lhs + ); + }; + + self.asm.sub(src, dst, size); + } + fn epilogue(&mut self, locals_size: u32) { assert!(self.sp_offset == locals_size); diff --git a/winch/codegen/src/masm.rs b/winch/codegen/src/masm.rs index 030c56cc66..508efe4bac 100644 --- a/winch/codegen/src/masm.rs +++ b/winch/codegen/src/masm.rs @@ -18,8 +18,8 @@ pub(crate) enum OperandSize { pub(crate) enum RegImm { /// A register. Reg(Reg), - /// An immediate. - Imm(i32), + /// 64-bit signed immediate. + Imm(i64), } impl RegImm { @@ -29,7 +29,7 @@ impl RegImm { } /// Immediate constructor. - pub fn imm(imm: i32) -> Self { + pub fn imm(imm: i64) -> Self { RegImm::Imm(imm) } } @@ -88,6 +88,9 @@ pub(crate) trait MacroAssembler { /// Perform add operation. fn add(&mut self, dst: RegImm, lhs: RegImm, rhs: RegImm, size: OperandSize); + /// Perform subtraction operation. + fn sub(&mut self, dst: RegImm, lhs: RegImm, rhs: RegImm, size: OperandSize); + /// Push the register to the stack, returning the offset. fn push(&mut self, src: Reg) -> u32; diff --git a/winch/codegen/src/regalloc.rs b/winch/codegen/src/regalloc.rs index 0d67808ee1..bdfd384862 100644 --- a/winch/codegen/src/regalloc.rs +++ b/winch/codegen/src/regalloc.rs @@ -76,7 +76,8 @@ impl RegAlloc { ) { match src { Val::Reg(src) => masm.mov(RegImm::reg(src), RegImm::reg(dst), size), - Val::I32(imm) => masm.mov(RegImm::imm(imm), RegImm::reg(dst), size), + Val::I32(imm) => masm.mov(RegImm::imm(imm.into()), RegImm::reg(dst), size), + Val::I64(imm) => masm.mov(RegImm::imm(imm), RegImm::reg(dst), size), Val::Local(index) => { let slot = frame .get_local(index) diff --git a/winch/codegen/src/stack.rs b/winch/codegen/src/stack.rs index c81511f682..72308006fc 100644 --- a/winch/codegen/src/stack.rs +++ b/winch/codegen/src/stack.rs @@ -6,6 +6,8 @@ use std::collections::VecDeque; pub(crate) enum Val { /// I32 Constant. I32(i32), + /// I64 Constant. + I64(i64), /// A register. Reg(Reg), /// A local slot. @@ -20,6 +22,11 @@ impl Val { Self::I32(v) } + /// Create a new I64 constant value. + pub fn i64(v: i64) -> Self { + Self::I64(v) + } + /// Create a new Reg value. pub fn reg(r: Reg) -> Self { Self::Reg(r) @@ -60,6 +67,17 @@ impl Val { } } + /// Get the integer representation of the value. + /// + /// # Panics + /// This method will panic if the value is not an i64. + pub fn get_i64(&self) -> i64 { + match self { + Self::I64(v) => *v, + v => panic!("expected value {:?} to be i64", v), + } + } + /// Check whether the value is an i32 constant. pub fn is_i32_const(&self) -> bool { match *self { @@ -67,6 +85,14 @@ impl Val { _ => false, } } + + /// Check whether the value is an i64 constant. + pub fn is_i64_const(&self) -> bool { + match *self { + Self::I64(_) => true, + _ => false, + } + } } /// The shadow stack used for compilation. @@ -89,7 +115,7 @@ impl Stack { } /// Peek into the top in the stack. - pub fn peek(&mut self) -> Option<&Val> { + pub fn peek(&self) -> Option<&Val> { self.inner.back() } @@ -98,7 +124,7 @@ impl Stack { self.inner.pop_back() } - /// Pops the element at the top of the stack if it is a const; + /// Pops the element at the top of the stack if it is an i32 const; /// returns `None` otherwise. pub fn pop_i32_const(&mut self) -> Option { match self.peek() { @@ -107,6 +133,15 @@ impl Stack { } } + /// Pops the element at the top of the stack if it is an i64 const; + /// returns `None` otherwise. + pub fn pop_i64_const(&mut self) -> Option { + match self.peek() { + Some(v) => v.is_i64_const().then(|| self.pop().unwrap().get_i64()), + _ => None, + } + } + /// Pops the element at the top of the stack if it is a register; /// returns `None` otherwise. pub fn pop_reg(&mut self) -> Option { diff --git a/winch/codegen/src/visitor.rs b/winch/codegen/src/visitor.rs index 10d0663265..b6c4b093c8 100644 --- a/winch/codegen/src/visitor.rs +++ b/winch/codegen/src/visitor.rs @@ -10,45 +10,6 @@ use crate::stack::Val; use wasmparser::ValType; use wasmparser::VisitOperator; -impl<'a, M> CodeGen<'a, M> -where - M: MacroAssembler, -{ - fn add_imm_i32(&mut self) { - let val = self - .context - .stack - .pop_i32_const() - .expect("i32 constant at stack top"); - let reg = self - .regalloc - .pop_to_reg(&mut self.context, OperandSize::S32); - - let dst = RegImm::reg(reg); - self.context - .masm - .add(dst, dst, RegImm::imm(val), OperandSize::S32); - self.context.stack.push(Val::reg(reg)); - } - - fn add_i32(&mut self) { - let src = self - .regalloc - .pop_to_reg(&mut self.context, OperandSize::S32); - let dst = self - .regalloc - .pop_to_reg(&mut self.context, OperandSize::S32); - - let lhs = RegImm::reg(dst); - self.context - .masm - .add(lhs, lhs, RegImm::reg(src), OperandSize::S32); - - self.regalloc.free_gpr(src); - self.context.stack.push(Val::reg(dst)); - } -} - /// A macro to define unsupported WebAssembly operators. /// /// This macro calls itself recursively; @@ -71,7 +32,11 @@ macro_rules! def_unsupported { }; (emit I32Const $($rest:tt)*) => {}; + (emit I64Const $($rest:tt)*) => {}; (emit I32Add $($rest:tt)*) => {}; + (emit I64Add $($rest:tt)*) => {}; + (emit I32Sub $($rest:tt)*) => {}; + (emit I64Sub $($rest:tt)*) => {}; (emit LocalGet $($rest:tt)*) => {}; (emit LocalSet $($rest:tt)*) => {}; (emit End $($rest:tt)*) => {}; @@ -89,19 +54,36 @@ where self.context.stack.push(Val::i32(val)); } - fn visit_i32_add(&mut self) { - let is_const = self - .context - .stack - .peek() - .expect("value at stack top") - .is_i32_const(); + fn visit_i64_const(&mut self, val: i64) { + self.context.stack.push(Val::i64(val)); + } - if is_const { - self.add_imm_i32(); - } else { - self.add_i32(); - } + fn visit_i32_add(&mut self) { + self.context + .i32_binop(&mut self.regalloc, &mut |masm: &mut M, dst, src, size| { + masm.add(dst, dst, src, size); + }); + } + + fn visit_i64_add(&mut self) { + self.context + .i64_binop(&mut self.regalloc, &mut |masm: &mut M, dst, src, size| { + masm.add(dst, dst, src, size); + }); + } + + fn visit_i32_sub(&mut self) { + self.context + .i32_binop(&mut self.regalloc, &mut |masm: &mut M, dst, src, size| { + masm.sub(dst, dst, src, size); + }); + } + + fn visit_i64_sub(&mut self) { + self.context + .i64_binop(&mut self.regalloc, &mut |masm: &mut M, dst, src, size| { + masm.sub(dst, dst, src, size); + }); } fn visit_end(&mut self) {} diff --git a/winch/filetests/filetests/aarch64/basic_add.wat b/winch/filetests/filetests/aarch64/i32_add/const.wat similarity index 86% rename from winch/filetests/filetests/aarch64/basic_add.wat rename to winch/filetests/filetests/aarch64/i32_add/const.wat index 8c8e9f84d6..0165dc7021 100644 --- a/winch/filetests/filetests/aarch64/basic_add.wat +++ b/winch/filetests/filetests/aarch64/i32_add/const.wat @@ -1,12 +1,11 @@ ;;! target = "aarch64" (module - (export "main" (func $main)) - - (func $main (result i32) + (func (result i32) (i32.const 10) (i32.const 20) - i32.add) + (i32.add) + ) ) ;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! ;; 4: fd030091 mov x29, sp diff --git a/winch/filetests/filetests/aarch64/basic_add_with_locals.wat b/winch/filetests/filetests/aarch64/i32_add/locals.wat similarity index 94% rename from winch/filetests/filetests/aarch64/basic_add_with_locals.wat rename to winch/filetests/filetests/aarch64/i32_add/locals.wat index 4d9f5577ee..655e98e990 100644 --- a/winch/filetests/filetests/aarch64/basic_add_with_locals.wat +++ b/winch/filetests/filetests/aarch64/i32_add/locals.wat @@ -1,19 +1,20 @@ ;;! target = "aarch64" (module - (export "main" (func $main)) - - (func $main (result i32) + (func (result i32) (local $foo i32) (local $bar i32) + (i32.const 10) (local.set $foo) + (i32.const 20) (local.set $bar) (local.get $foo) (local.get $bar) - i32.add) + i32.add + ) ) ;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! ;; 4: fd030091 mov x29, sp diff --git a/winch/filetests/filetests/aarch64/i32_add/max.wat b/winch/filetests/filetests/aarch64/i32_add/max.wat new file mode 100644 index 0000000000..e90af642b3 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i32_add/max.wat @@ -0,0 +1,16 @@ +;;! target = "aarch64" +(module + (func (result i32) + (i32.const 0x7fffffff) + (i32.const 1) + (i32.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: f07b40b2 orr x16, xzr, #0x7fffffff +;; 10: e003102a mov w0, w16 +;; 14: 00040011 add w0, w0, #1 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i32_add/max_one.wat b/winch/filetests/filetests/aarch64/i32_add/max_one.wat new file mode 100644 index 0000000000..a369d07a00 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i32_add/max_one.wat @@ -0,0 +1,18 @@ +;;! target = "aarch64" + +(module + (func (result i32) + (i32.const 0x80000000) + (i32.const -1) + (i32.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: f08361b2 orr x16, xzr, #0xffffffff80000000 +;; 10: e003102a mov w0, w16 +;; 14: 10008092 mov x16, #-1 +;; 18: 0060300b add w0, w0, w16, uxtx +;; 1c: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 20: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i32_add/mixed.wat b/winch/filetests/filetests/aarch64/i32_add/mixed.wat new file mode 100644 index 0000000000..06ac4f9b69 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i32_add/mixed.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" + +(module + (func (result i32) + (i32.const -1) + (i32.const 1) + (i32.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 10008092 mov x16, #-1 +;; 10: e003102a mov w0, w16 +;; 14: 00040011 add w0, w0, #1 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/basic_add_with_params.wat b/winch/filetests/filetests/aarch64/i32_add/params.wat similarity index 83% rename from winch/filetests/filetests/aarch64/basic_add_with_params.wat rename to winch/filetests/filetests/aarch64/i32_add/params.wat index 3f8fff92ad..3c9871c745 100644 --- a/winch/filetests/filetests/aarch64/basic_add_with_params.wat +++ b/winch/filetests/filetests/aarch64/i32_add/params.wat @@ -1,12 +1,11 @@ ;;! target = "aarch64" (module - (export "main" (func $main)) - - (func $main (param i32) (param i32) (result i32) - (local.get 0) - (local.get 1) - i32.add) + (func (param i32) (param i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) ) ;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! ;; 4: fd030091 mov x29, sp diff --git a/winch/filetests/filetests/aarch64/i32_add/signed.wat b/winch/filetests/filetests/aarch64/i32_add/signed.wat new file mode 100644 index 0000000000..fc6a0b8199 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i32_add/signed.wat @@ -0,0 +1,18 @@ +;;! target = "aarch64" + +(module + (func (result i32) + (i32.const -1) + (i32.const -1) + (i32.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 10008092 mov x16, #-1 +;; 10: e003102a mov w0, w16 +;; 14: 10008092 mov x16, #-1 +;; 18: 0060300b add w0, w0, w16, uxtx +;; 1c: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 20: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i32_add/unsigned_with_zero.wat b/winch/filetests/filetests/aarch64/i32_add/unsigned_with_zero.wat new file mode 100644 index 0000000000..8820919a12 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i32_add/unsigned_with_zero.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" + +(module + (func (result i32) + (i32.const 1) + (i32.const 0) + (i32.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 300080d2 mov x16, #1 +;; 10: e003102a mov w0, w16 +;; 14: 00000011 add w0, w0, #0 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/const.wat b/winch/filetests/filetests/aarch64/i64_add/const.wat new file mode 100644 index 0000000000..b2cb3e75dd --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/const.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (i64.const 10) + (i64.const 20) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 500180d2 mov x16, #0xa +;; 10: e00310aa mov x0, x16 +;; 14: 00500091 add x0, x0, #0x14 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/locals.wat b/winch/filetests/filetests/aarch64/i64_add/locals.wat new file mode 100644 index 0000000000..b4eb21ca54 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/locals.wat @@ -0,0 +1,40 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (local $foo i64) + (local $bar i64) + + (i64.const 10) + (local.set $foo) + + (i64.const 20) + (local.set $bar) + + (local.get $foo) + (local.get $bar) + i64.add + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: ff4300d1 sub sp, sp, #0x10 +;; 10: fc030091 mov x28, sp +;; 14: 100080d2 mov x16, #0 +;; 18: 908300f8 stur x16, [x28, #8] +;; 1c: 900300f8 stur x16, [x28] +;; 20: 500180d2 mov x16, #0xa +;; 24: e00310aa mov x0, x16 +;; 28: 808300f8 stur x0, [x28, #8] +;; 2c: 900280d2 mov x16, #0x14 +;; 30: e00310aa mov x0, x16 +;; 34: 800300f8 stur x0, [x28] +;; 38: 800340f8 ldur x0, [x28] +;; 3c: 818340f8 ldur x1, [x28, #8] +;; 40: 2160208b add x1, x1, x0, uxtx +;; 44: e00301aa mov x0, x1 +;; 48: ff430091 add sp, sp, #0x10 +;; 4c: fc030091 mov x28, sp +;; 50: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 54: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/max.wat b/winch/filetests/filetests/aarch64/i64_add/max.wat new file mode 100644 index 0000000000..cf4f283565 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/max.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" +(module + (func (result i64) + (i64.const 1) + (i64.const 0x7fffffffffffffff) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 300080d2 mov x16, #1 +;; 10: e00310aa mov x0, x16 +;; 14: 1000f092 mov x16, #0x7fffffffffffffff +;; 18: 0060308b add x0, x0, x16, uxtx +;; 1c: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 20: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/max_one.wat b/winch/filetests/filetests/aarch64/i64_add/max_one.wat new file mode 100644 index 0000000000..61b4a51047 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/max_one.wat @@ -0,0 +1,18 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (i64.const 0x8000000000000000) + (i64.const -1) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 1000f0d2 mov x16, #-0x8000000000000000 +;; 10: e00310aa mov x0, x16 +;; 14: 10008092 mov x16, #-1 +;; 18: 0060308b add x0, x0, x16, uxtx +;; 1c: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 20: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/mixed.wat b/winch/filetests/filetests/aarch64/i64_add/mixed.wat new file mode 100644 index 0000000000..4ac6868418 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/mixed.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (i64.const -1) + (i64.const 1) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 10008092 mov x16, #-1 +;; 10: e00310aa mov x0, x16 +;; 14: 00040091 add x0, x0, #1 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/params.wat b/winch/filetests/filetests/aarch64/i64_add/params.wat new file mode 100644 index 0000000000..2bf460def9 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/params.wat @@ -0,0 +1,24 @@ +;;! target = "aarch64" + +(module + (func (param i64) (param i64) (result i64) + (local.get 0) + (local.get 1) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: ff4300d1 sub sp, sp, #0x10 +;; 10: fc030091 mov x28, sp +;; 14: 808300f8 stur x0, [x28, #8] +;; 18: 810300f8 stur x1, [x28] +;; 1c: 800340f8 ldur x0, [x28] +;; 20: 818340f8 ldur x1, [x28, #8] +;; 24: 2160208b add x1, x1, x0, uxtx +;; 28: e00301aa mov x0, x1 +;; 2c: ff430091 add sp, sp, #0x10 +;; 30: fc030091 mov x28, sp +;; 34: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 38: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/signed.wat b/winch/filetests/filetests/aarch64/i64_add/signed.wat new file mode 100644 index 0000000000..d5c92a5d82 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/signed.wat @@ -0,0 +1,18 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (i64.const -1) + (i64.const -1) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 10008092 mov x16, #-1 +;; 10: e00310aa mov x0, x16 +;; 14: 10008092 mov x16, #-1 +;; 18: 0060308b add x0, x0, x16, uxtx +;; 1c: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 20: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/i64_add/unsigned_with_zero.wat b/winch/filetests/filetests/aarch64/i64_add/unsigned_with_zero.wat new file mode 100644 index 0000000000..89230d72d4 --- /dev/null +++ b/winch/filetests/filetests/aarch64/i64_add/unsigned_with_zero.wat @@ -0,0 +1,17 @@ +;;! target = "aarch64" + +(module + (func (result i64) + (i64.const 1) + (i64.const 0) + (i64.add) + ) +) +;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! +;; 4: fd030091 mov x29, sp +;; 8: fc030091 mov x28, sp +;; c: 300080d2 mov x16, #1 +;; 10: e00310aa mov x0, x16 +;; 14: 00000091 add x0, x0, #0 +;; 18: fd7bc1a8 ldp x29, x30, [sp], #0x10 +;; 1c: c0035fd6 ret diff --git a/winch/filetests/filetests/aarch64/simple.wat b/winch/filetests/filetests/aarch64/simple.wat deleted file mode 100644 index a55aae1e96..0000000000 --- a/winch/filetests/filetests/aarch64/simple.wat +++ /dev/null @@ -1,15 +0,0 @@ -;;! target = "aarch64" - -(module - (func (result i32) - (i32.const 42) - ) -) - -;; 0: fd7bbfa9 stp x29, x30, [sp, #-0x10]! -;; 4: fd030091 mov x29, sp -;; 8: fc030091 mov x28, sp -;; c: 500580d2 mov x16, #0x2a -;; 10: e00310aa mov x0, x16 -;; 14: fd7bc1a8 ldp x29, x30, [sp], #0x10 -;; 18: c0035fd6 ret diff --git a/winch/filetests/filetests/x64/basic_add.wat b/winch/filetests/filetests/x64/i32_add/const.wat similarity index 81% rename from winch/filetests/filetests/x64/basic_add.wat rename to winch/filetests/filetests/x64/i32_add/const.wat index 3a2f2cb7bb..b60b97d11f 100644 --- a/winch/filetests/filetests/x64/basic_add.wat +++ b/winch/filetests/filetests/x64/i32_add/const.wat @@ -1,12 +1,11 @@ ;;! target = "x86_64" (module - (export "main" (func $main)) - - (func $main (result i32) + (func (result i32) (i32.const 10) (i32.const 20) - i32.add) + (i32.add) + ) ) ;; 0: 55 push rbp ;; 1: 4889e5 mov rbp, rsp diff --git a/winch/filetests/filetests/x64/basic_add_with_locals.wat b/winch/filetests/filetests/x64/i32_add/locals.wat similarity index 92% rename from winch/filetests/filetests/x64/basic_add_with_locals.wat rename to winch/filetests/filetests/x64/i32_add/locals.wat index 4bd237d998..eaea5d955b 100644 --- a/winch/filetests/filetests/x64/basic_add_with_locals.wat +++ b/winch/filetests/filetests/x64/i32_add/locals.wat @@ -1,19 +1,20 @@ ;;! target = "x86_64" (module - (export "main" (func $main)) - - (func $main (result i32) + (func (result i32) (local $foo i32) (local $bar i32) + (i32.const 10) (local.set $foo) + (i32.const 20) (local.set $bar) (local.get $foo) (local.get $bar) - i32.add) + i32.add + ) ) ;; 0: 55 push rbp ;; 1: 4889e5 mov rbp, rsp diff --git a/winch/filetests/filetests/x64/i32_add/max.wat b/winch/filetests/filetests/x64/i32_add/max.wat new file mode 100644 index 0000000000..3361a43b1d --- /dev/null +++ b/winch/filetests/filetests/x64/i32_add/max.wat @@ -0,0 +1,14 @@ +;;! target = "x86_64" +(module + (func (result i32) + (i32.const 0x7fffffff) + (i32.const 1) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffff7f mov eax, 0x7fffffff +;; 9: 83c001 add eax, 1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_add/max_one.wat b/winch/filetests/filetests/x64/i32_add/max_one.wat new file mode 100644 index 0000000000..147125508a --- /dev/null +++ b/winch/filetests/filetests/x64/i32_add/max_one.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 0x80000000) + (i32.const -1) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b800000080 mov eax, 0x80000000 +;; 9: 83c0ff add eax, -1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_add/mixed.wat b/winch/filetests/filetests/x64/i32_add/mixed.wat new file mode 100644 index 0000000000..ce40539bda --- /dev/null +++ b/winch/filetests/filetests/x64/i32_add/mixed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const -1) + (i32.const 1) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffffff mov eax, 0xffffffff +;; 9: 83c001 add eax, 1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/basic_add_with_params.wat b/winch/filetests/filetests/x64/i32_add/params.wat similarity index 80% rename from winch/filetests/filetests/x64/basic_add_with_params.wat rename to winch/filetests/filetests/x64/i32_add/params.wat index d3809ac3a1..33b381d5aa 100644 --- a/winch/filetests/filetests/x64/basic_add_with_params.wat +++ b/winch/filetests/filetests/x64/i32_add/params.wat @@ -1,12 +1,11 @@ ;;! target = "x86_64" (module - (export "main" (func $main)) - - (func $main (param i32) (param i32) (result i32) - (local.get 0) - (local.get 1) - i32.add) + (func (param i32) (param i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) ) ;; 0: 55 push rbp ;; 1: 4889e5 mov rbp, rsp diff --git a/winch/filetests/filetests/x64/i32_add/signed.wat b/winch/filetests/filetests/x64/i32_add/signed.wat new file mode 100644 index 0000000000..7cd06f7633 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_add/signed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const -1) + (i32.const -1) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffffff mov eax, 0xffffffff +;; 9: 83c0ff add eax, -1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_add/unsigned_with_zero.wat b/winch/filetests/filetests/x64/i32_add/unsigned_with_zero.wat new file mode 100644 index 0000000000..5d8b174687 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_add/unsigned_with_zero.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 1) + (i32.const 0) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b801000000 mov eax, 1 +;; 9: 83c000 add eax, 0 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/const.wat b/winch/filetests/filetests/x64/i32_sub/const.wat new file mode 100644 index 0000000000..21808460f1 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/const.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 10) + (i32.const 20) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b80a000000 mov eax, 0xa +;; 9: 83e814 sub eax, 0x14 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/locals.wat b/winch/filetests/filetests/x64/i32_sub/locals.wat new file mode 100644 index 0000000000..5de1b20a2d --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/locals.wat @@ -0,0 +1,33 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (local $foo i32) + (local $bar i32) + + (i32.const 10) + (local.set $foo) + + (i32.const 20) + (local.set $bar) + + (local.get $foo) + (local.get $bar) + i32.sub + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec08 sub rsp, 8 +;; 8: 48c7042400000000 mov qword ptr [rsp], 0 +;; 10: b80a000000 mov eax, 0xa +;; 15: 89442404 mov dword ptr [rsp + 4], eax +;; 19: b814000000 mov eax, 0x14 +;; 1e: 890424 mov dword ptr [rsp], eax +;; 21: 8b0424 mov eax, dword ptr [rsp] +;; 24: 8b4c2404 mov ecx, dword ptr [rsp + 4] +;; 28: 29c1 sub ecx, eax +;; 2a: 4889c8 mov rax, rcx +;; 2d: 4883c408 add rsp, 8 +;; 31: 5d pop rbp +;; 32: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/max.wat b/winch/filetests/filetests/x64/i32_sub/max.wat new file mode 100644 index 0000000000..28f27a9a34 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/max.wat @@ -0,0 +1,14 @@ +;;! target = "x86_64" +(module + (func (result i32) + (i32.const 0x7fffffff) + (i32.const -1) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffff7f mov eax, 0x7fffffff +;; 9: 83e8ff sub eax, -1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/max_one.wat b/winch/filetests/filetests/x64/i32_sub/max_one.wat new file mode 100644 index 0000000000..7f9c962cf3 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/max_one.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 0x80000000) + (i32.const 1) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b800000080 mov eax, 0x80000000 +;; 9: 83e801 sub eax, 1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/mixed.wat b/winch/filetests/filetests/x64/i32_sub/mixed.wat new file mode 100644 index 0000000000..f46b818e9a --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/mixed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const -1) + (i32.const 1) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffffff mov eax, 0xffffffff +;; 9: 83e801 sub eax, 1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/params.wat b/winch/filetests/filetests/x64/i32_sub/params.wat new file mode 100644 index 0000000000..10f430b526 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/params.wat @@ -0,0 +1,21 @@ +;;! target = "x86_64" + +(module + (func (param i32) (param i32) (result i32) + (local.get 0) + (local.get 1) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec08 sub rsp, 8 +;; 8: 897c2404 mov dword ptr [rsp + 4], edi +;; c: 893424 mov dword ptr [rsp], esi +;; f: 8b0424 mov eax, dword ptr [rsp] +;; 12: 8b4c2404 mov ecx, dword ptr [rsp + 4] +;; 16: 29c1 sub ecx, eax +;; 18: 4889c8 mov rax, rcx +;; 1b: 4883c408 add rsp, 8 +;; 1f: 5d pop rbp +;; 20: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/signed.wat b/winch/filetests/filetests/x64/i32_sub/signed.wat new file mode 100644 index 0000000000..fe48975634 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/signed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const -1) + (i32.const -1) + (i32.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b8ffffffff mov eax, 0xffffffff +;; 9: 83e8ff sub eax, -1 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_sub/unsigned_with_zero.wat b/winch/filetests/filetests/x64/i32_sub/unsigned_with_zero.wat new file mode 100644 index 0000000000..5d8b174687 --- /dev/null +++ b/winch/filetests/filetests/x64/i32_sub/unsigned_with_zero.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i32) + (i32.const 1) + (i32.const 0) + (i32.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: b801000000 mov eax, 1 +;; 9: 83c000 add eax, 0 +;; c: 5d pop rbp +;; d: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/const.wat b/winch/filetests/filetests/x64/i64_add/const.wat new file mode 100644 index 0000000000..8e51cb223d --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/const.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 10) + (i64.const 20) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c00a000000 mov rax, 0xa +;; b: 4883c014 add rax, 0x14 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/locals.wat b/winch/filetests/filetests/x64/i64_add/locals.wat new file mode 100644 index 0000000000..7f60a2dda8 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/locals.wat @@ -0,0 +1,35 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (local $foo i64) + (local $bar i64) + + (i64.const 10) + (local.set $foo) + + (i64.const 20) + (local.set $bar) + + (local.get $foo) + (local.get $bar) + i64.add + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 4531db xor r11d, r11d +;; b: 4c895c2408 mov qword ptr [rsp + 8], r11 +;; 10: 4c891c24 mov qword ptr [rsp], r11 +;; 14: 48c7c00a000000 mov rax, 0xa +;; 1b: 4889442408 mov qword ptr [rsp + 8], rax +;; 20: 48c7c014000000 mov rax, 0x14 +;; 27: 48890424 mov qword ptr [rsp], rax +;; 2b: 488b0424 mov rax, qword ptr [rsp] +;; 2f: 488b4c2408 mov rcx, qword ptr [rsp + 8] +;; 34: 4801c1 add rcx, rax +;; 37: 4889c8 mov rax, rcx +;; 3a: 4883c410 add rsp, 0x10 +;; 3e: 5d pop rbp +;; 3f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/max.wat b/winch/filetests/filetests/x64/i64_add/max.wat new file mode 100644 index 0000000000..6b0e79b843 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/max.wat @@ -0,0 +1,16 @@ +;;! target = "x86_64" +(module + (func (result i64) + (i64.const 1) + (i64.const 0x7fffffffffffffff) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c001000000 mov rax, 1 +;; b: 49bbffffffffffffff7f +;; movabs r11, 0x7fffffffffffffff +;; 15: 4c01d8 add rax, r11 +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/max_one.wat b/winch/filetests/filetests/x64/i64_add/max_one.wat new file mode 100644 index 0000000000..6453e8519b --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/max_one.wat @@ -0,0 +1,16 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 0x8000000000000000) + (i64.const -1) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48b80000000000000080 +;; movabs rax, 0x8000000000000000 +;; e: 4883c0ff add rax, -1 +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/mixed.wat b/winch/filetests/filetests/x64/i64_add/mixed.wat new file mode 100644 index 0000000000..7d2b8da72c --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/mixed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const -1) + (i64.const 1) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff +;; b: 4883c001 add rax, 1 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/params.wat b/winch/filetests/filetests/x64/i64_add/params.wat new file mode 100644 index 0000000000..c27831fe07 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/params.wat @@ -0,0 +1,21 @@ +;;! target = "x86_64" + +(module + (func (param i64) (param i64) (result i64) + (local.get 0) + (local.get 1) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 48897c2408 mov qword ptr [rsp + 8], rdi +;; d: 48893424 mov qword ptr [rsp], rsi +;; 11: 488b0424 mov rax, qword ptr [rsp] +;; 15: 488b4c2408 mov rcx, qword ptr [rsp + 8] +;; 1a: 4801c1 add rcx, rax +;; 1d: 4889c8 mov rax, rcx +;; 20: 4883c410 add rsp, 0x10 +;; 24: 5d pop rbp +;; 25: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/signed.wat b/winch/filetests/filetests/x64/i64_add/signed.wat new file mode 100644 index 0000000000..a1d5e88f97 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/signed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const -1) + (i64.const -1) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff +;; b: 4883c0ff add rax, -1 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_add/unsigned_with_zero.wat b/winch/filetests/filetests/x64/i64_add/unsigned_with_zero.wat new file mode 100644 index 0000000000..74319b36fb --- /dev/null +++ b/winch/filetests/filetests/x64/i64_add/unsigned_with_zero.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 1) + (i64.const 0) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c001000000 mov rax, 1 +;; b: 4883c000 add rax, 0 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/const.wat b/winch/filetests/filetests/x64/i64_sub/const.wat new file mode 100644 index 0000000000..3d63997507 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/const.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 10) + (i64.const 20) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c00a000000 mov rax, 0xa +;; b: 4883e814 sub rax, 0x14 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/locals.wat b/winch/filetests/filetests/x64/i64_sub/locals.wat new file mode 100644 index 0000000000..d09c4094da --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/locals.wat @@ -0,0 +1,35 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (local $foo i64) + (local $bar i64) + + (i64.const 10) + (local.set $foo) + + (i64.const 20) + (local.set $bar) + + (local.get $foo) + (local.get $bar) + i64.sub + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 4531db xor r11d, r11d +;; b: 4c895c2408 mov qword ptr [rsp + 8], r11 +;; 10: 4c891c24 mov qword ptr [rsp], r11 +;; 14: 48c7c00a000000 mov rax, 0xa +;; 1b: 4889442408 mov qword ptr [rsp + 8], rax +;; 20: 48c7c014000000 mov rax, 0x14 +;; 27: 48890424 mov qword ptr [rsp], rax +;; 2b: 488b0424 mov rax, qword ptr [rsp] +;; 2f: 488b4c2408 mov rcx, qword ptr [rsp + 8] +;; 34: 4829c1 sub rcx, rax +;; 37: 4889c8 mov rax, rcx +;; 3a: 4883c410 add rsp, 0x10 +;; 3e: 5d pop rbp +;; 3f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/max.wat b/winch/filetests/filetests/x64/i64_sub/max.wat new file mode 100644 index 0000000000..01a8995b27 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/max.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" +(module + (func (result i64) + (i64.const 0x7fffffffffffffff) + (i64.const -1) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48b8ffffffffffffff7f +;; movabs rax, 0x7fffffffffffffff +;; e: 4883e8ff sub rax, -1 +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/max_one.wat b/winch/filetests/filetests/x64/i64_sub/max_one.wat new file mode 100644 index 0000000000..7c973c128a --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/max_one.wat @@ -0,0 +1,16 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 0x8000000000000000) + (i64.const 1) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48b80000000000000080 +;; movabs rax, 0x8000000000000000 +;; e: 4883e801 sub rax, 1 +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/mixed.wat b/winch/filetests/filetests/x64/i64_sub/mixed.wat new file mode 100644 index 0000000000..c57e1dcd36 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/mixed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const -1) + (i64.const 1) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff +;; b: 4883e801 sub rax, 1 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/params.wat b/winch/filetests/filetests/x64/i64_sub/params.wat new file mode 100644 index 0000000000..c41acc69f3 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/params.wat @@ -0,0 +1,21 @@ +;;! target = "x86_64" + +(module + (func (param i64) (param i64) (result i64) + (local.get 0) + (local.get 1) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 4883ec10 sub rsp, 0x10 +;; 8: 48897c2408 mov qword ptr [rsp + 8], rdi +;; d: 48893424 mov qword ptr [rsp], rsi +;; 11: 488b0424 mov rax, qword ptr [rsp] +;; 15: 488b4c2408 mov rcx, qword ptr [rsp + 8] +;; 1a: 4829c1 sub rcx, rax +;; 1d: 4889c8 mov rax, rcx +;; 20: 4883c410 add rsp, 0x10 +;; 24: 5d pop rbp +;; 25: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/signed.wat b/winch/filetests/filetests/x64/i64_sub/signed.wat new file mode 100644 index 0000000000..4cf427b595 --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/signed.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const -1) + (i64.const -1) + (i64.sub) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c0ffffffff mov rax, 0xffffffffffffffff +;; b: 4883e8ff sub rax, -1 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/i64_sub/unsigned_with_zero.wat b/winch/filetests/filetests/x64/i64_sub/unsigned_with_zero.wat new file mode 100644 index 0000000000..74319b36fb --- /dev/null +++ b/winch/filetests/filetests/x64/i64_sub/unsigned_with_zero.wat @@ -0,0 +1,15 @@ +;;! target = "x86_64" + +(module + (func (result i64) + (i64.const 1) + (i64.const 0) + (i64.add) + ) +) +;; 0: 55 push rbp +;; 1: 4889e5 mov rbp, rsp +;; 4: 48c7c001000000 mov rax, 1 +;; b: 4883c000 add rax, 0 +;; f: 5d pop rbp +;; 10: c3 ret diff --git a/winch/filetests/filetests/x64/simple.wat b/winch/filetests/filetests/x64/simple.wat deleted file mode 100644 index c839e1f31a..0000000000 --- a/winch/filetests/filetests/x64/simple.wat +++ /dev/null @@ -1,12 +0,0 @@ -;;! target = "x86_64" - -(module - (func (result i32) - (i32.const 42) - ) -) -;; 0: 55 push rbp -;; 1: 4889e5 mov rbp, rsp -;; 4: 48c7c02a000000 mov rax, 0x2a -;; b: 5d pop rbp -;; c: c3 ret