mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
285 lines
6.6 KiB
Rust
285 lines
6.6 KiB
Rust
#![cfg(test)]
|
|
|
|
use roc_wasm_interp::test_utils::test_op_example;
|
|
use roc_wasm_module::{opcodes::OpCode, opcodes::OpCode::*, Value};
|
|
|
|
fn test_i32_binop(op: OpCode, arg1: i32, arg2: i32, expected: i32) {
|
|
test_op_example(
|
|
op,
|
|
[Value::from(arg1), Value::from(arg2)],
|
|
Value::from(expected),
|
|
)
|
|
}
|
|
|
|
fn test_u32_binop(op: OpCode, arg1: u32, arg2: u32, expected: u32) {
|
|
test_op_example(
|
|
op,
|
|
[Value::from(arg1), Value::from(arg2)],
|
|
Value::from(expected),
|
|
)
|
|
}
|
|
|
|
fn test_i32_unop(op: OpCode, arg: i32, expected: i32) {
|
|
test_op_example(op, [Value::from(arg)], Value::from(expected))
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32eqz() {
|
|
let op = I32EQZ;
|
|
test_i32_unop(op, 0, 1);
|
|
test_i32_unop(op, i32::MIN, 0);
|
|
test_i32_unop(op, i32::MAX, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32eq() {
|
|
let op = I32EQ;
|
|
test_i32_binop(op, 0, 0, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32ne() {
|
|
let op = I32NE;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32lts() {
|
|
let op = I32LTS;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32ltu() {
|
|
let op = I32LTU;
|
|
test_u32_binop(op, 0, 0, 0);
|
|
test_u32_binop(op, u32::MIN, u32::MIN, 0);
|
|
test_u32_binop(op, u32::MAX, u32::MAX, 0);
|
|
test_u32_binop(op, u32::MIN, u32::MAX, 1);
|
|
test_u32_binop(op, u32::MAX, u32::MIN, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32gts() {
|
|
let op = I32GTS;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32gtu() {
|
|
let op = I32GTU;
|
|
test_u32_binop(op, 0, 0, 0);
|
|
test_u32_binop(op, u32::MIN, u32::MIN, 0);
|
|
test_u32_binop(op, u32::MAX, u32::MAX, 0);
|
|
test_u32_binop(op, u32::MIN, u32::MAX, 0);
|
|
test_u32_binop(op, u32::MAX, u32::MIN, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32les() {
|
|
let op = I32LES;
|
|
test_i32_binop(op, 0, 0, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32leu() {
|
|
let op = I32LEU;
|
|
test_u32_binop(op, 0, 0, 1);
|
|
test_u32_binop(op, u32::MIN, u32::MIN, 1);
|
|
test_u32_binop(op, u32::MAX, u32::MAX, 1);
|
|
test_u32_binop(op, u32::MIN, u32::MAX, 1);
|
|
test_u32_binop(op, u32::MAX, u32::MIN, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32ges() {
|
|
let op = I32GES;
|
|
test_i32_binop(op, 0, 0, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MIN, 1);
|
|
test_i32_binop(op, i32::MAX, i32::MAX, 1);
|
|
test_i32_binop(op, i32::MIN, i32::MAX, 0);
|
|
test_i32_binop(op, i32::MAX, i32::MIN, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32geu() {
|
|
let op = I32GEU;
|
|
test_u32_binop(op, 0, 0, 1);
|
|
test_u32_binop(op, u32::MIN, u32::MIN, 1);
|
|
test_u32_binop(op, u32::MAX, u32::MAX, 1);
|
|
test_u32_binop(op, u32::MIN, u32::MAX, 0);
|
|
test_u32_binop(op, u32::MAX, u32::MIN, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32clz() {
|
|
let op = I32CLZ;
|
|
test_i32_unop(op, 0, 32);
|
|
test_i32_unop(op, -1, 0);
|
|
test_i32_unop(op, 1, 31);
|
|
test_i32_unop(op, 1024, 21);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32ctz() {
|
|
let op = I32CTZ;
|
|
test_i32_unop(op, 0, 32);
|
|
test_i32_unop(op, -1, 0);
|
|
test_i32_unop(op, 2, 1);
|
|
test_i32_unop(op, 1024, 10);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32popcnt() {
|
|
let op = I32POPCNT;
|
|
test_i32_unop(op, 0, 0);
|
|
test_i32_unop(op, -1, 32);
|
|
test_i32_unop(op, 2, 1);
|
|
test_i32_unop(op, 96, 2);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32add() {
|
|
let op = I32ADD;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, -1, -1, -2);
|
|
test_i32_binop(op, 1, 1, 2);
|
|
test_i32_binop(op, i32::MAX, 1, i32::MIN);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32sub() {
|
|
let op = I32SUB;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, -1, 1, -2);
|
|
test_i32_binop(op, 1, 1, 0);
|
|
test_i32_binop(op, i32::MIN, 1, i32::MAX);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32mul() {
|
|
let op = I32MUL;
|
|
test_i32_binop(op, 0, 0, 0);
|
|
test_i32_binop(op, -1, -1, 1);
|
|
test_i32_binop(op, 2, 3, 6);
|
|
test_i32_binop(op, i32::MAX, 2, -2);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32divs() {
|
|
let op = I32DIVS;
|
|
test_i32_binop(op, -1, -1, 1);
|
|
test_i32_binop(op, 6, 3, 2);
|
|
test_i32_binop(op, i32::MIN, -1, i32::MIN);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "divide by zero")]
|
|
fn test_i32divs_zero() {
|
|
test_i32_binop(I32DIVS, 1, 0, -1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32divu() {
|
|
let op = I32DIVU;
|
|
test_u32_binop(op, 1, 1, 1);
|
|
test_u32_binop(op, 6, 3, 2);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "divide by zero")]
|
|
fn test_i32divu_zero() {
|
|
test_i32_binop(I32DIVU, 1, 0, -1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32rems() {
|
|
let op = I32REMS;
|
|
test_i32_binop(op, 5, 2, 1);
|
|
// test_i32_binop(op, 5, -2, 1); // TODO: we don't match Wasmer, we get 0
|
|
test_i32_binop(op, -5, 2, -1);
|
|
// test_i32_binop(op, -5, -2, -1); // TODO: we don't match Wasmer, we get 0
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "divisor of zero")]
|
|
fn test_i32rems_zero() {
|
|
test_i32_binop(I32REMS, 1, 0, -1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32remu() {
|
|
let op = I32REMU;
|
|
test_i32_binop(op, 5, 2, 1);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic(expected = "divisor of zero")]
|
|
fn test_i32remu_zero() {
|
|
test_i32_binop(I32REMU, 1, 0, -1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32and() {
|
|
test_u32_binop(I32AND, 0x0000_ffff, 0x00ff_00ff, 0x0000_00ff);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32or() {
|
|
test_u32_binop(I32OR, 0x0000_ffff, 0x00ff_00ff, 0x00ff_ffff);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32xor() {
|
|
test_u32_binop(I32XOR, 0x0000_ffff, 0x00ff_00ff, 0x00ff_ff00);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32shl() {
|
|
test_u32_binop(I32SHL, 0xffff_ffff, 8, 0xffff_ff00);
|
|
test_u32_binop(I32SHL, 0xffff_ffff, 40, 0xffff_ff00);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32shrs() {
|
|
test_u32_binop(I32SHRS, 0xffff_0000, 8, 0xffff_ff00);
|
|
test_u32_binop(I32SHRS, 0xffff_0000, 40, 0xffff_ff00);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32shru() {
|
|
test_u32_binop(I32SHRU, 0xffff_0000, 8, 0x00ff_ff00);
|
|
test_u32_binop(I32SHRU, 0xffff_0000, 40, 0x00ff_ff00);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32rotl() {
|
|
test_u32_binop(I32ROTL, 0xff00_0000, 4, 0xf000_000f);
|
|
test_u32_binop(I32ROTL, 0xff00_0000, 36, 0xf000_000f);
|
|
}
|
|
|
|
#[test]
|
|
fn test_i32rotr() {
|
|
test_u32_binop(I32ROTR, 0x0000_00ff, 4, 0xf000_000f);
|
|
test_u32_binop(I32ROTR, 0x0000_00ff, 36, 0xf000_000f);
|
|
}
|