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