diff --git a/cranelift/filetests/filetests/runtests/isubbin.clif b/cranelift/filetests/filetests/runtests/isubbin.clif new file mode 100644 index 0000000000..304d118d6a --- /dev/null +++ b/cranelift/filetests/filetests/runtests/isubbin.clif @@ -0,0 +1,49 @@ +test interpret + +function %isubbin_i8(i8, i8, b1) -> i8 { +block0(v0: i8, v1: i8, v2: b1): + v3 = isub_bin v0, v1, v2 + return v3 +} +; run: %isubbin_i8(0, 1, true) == -2 +; run: %isubbin_i8(0, 1, false) == -1 +; run: %isubbin_i8(100, 20, true) == 79 +; run: %isubbin_i8(100, 20, false) == 80 +; run: %isubbin_i8(-128, 1, true) == 126 +; run: %isubbin_i8(-128, 1, false) == 127 + +function %isubbin_i16(i16, i16, b1) -> i16 { +block0(v0: i16, v1: i16, v2: b1): + v3 = isub_bin v0, v1, v2 + return v3 +} +; run: %isubbin_i16(0, 1, true) == -2 +; run: %isubbin_i16(0, 1, false) == -1 +; run: %isubbin_i16(100, 20, true) == 79 +; run: %isubbin_i16(100, 20, false) == 80 +; run: %isubbin_i16(-32768, 1, true) == 32766 +; run: %isubbin_i16(-32768, 1, false) == 32767 + +function %isubbin_i32(i32, i32, b1) -> i32 { +block0(v0: i32, v1: i32, v2: b1): + v3 = isub_bin v0, v1, v2 + return v3 +} +; run: %isubbin_i32(0, 1, true) == -2 +; run: %isubbin_i32(0, 1, false) == -1 +; run: %isubbin_i32(100, 20, true) == 79 +; run: %isubbin_i32(100, 20, false) == 80 +; run: %isubbin_i32(-2147483648, 1, true) == 2147483646 +; run: %isubbin_i32(-2147483648, 1, false) == 2147483647 + +function %isubbin_i64(i64, i64, b1) -> i64 { +block0(v0: i64, v1: i64, v2: b1): + v3 = isub_bin v0, v1, v2 + return v3 +} +; run: %isubbin_i64(0, 1, true) == -2 +; run: %isubbin_i64(0, 1, false) == -1 +; run: %isubbin_i64(100, 20, true) == 79 +; run: %isubbin_i64(100, 20, false) == 80 +; run: %isubbin_i64(-2147483648, 1, true) == -2147483650 +; run: %isubbin_i64(-2147483648, 1, false) == -2147483649 \ No newline at end of file diff --git a/cranelift/filetests/filetests/runtests/isubborrow.clif b/cranelift/filetests/filetests/runtests/isubborrow.clif new file mode 100644 index 0000000000..cf1f2fd5a3 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/isubborrow.clif @@ -0,0 +1,98 @@ +test interpret + +function %isubborrow_i8_v(i8, i8, b1) -> i8 { +block0(v0: i8, v1: i8, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v3 +} +; run: %isubborrow_i8_v(0, 1, true) == -2 +; run: %isubborrow_i8_v(0, 1, false) == -1 +; run: %isubborrow_i8_v(100, 20, true) == 79 +; run: %isubborrow_i8_v(100, 20, false) == 80 +; run: %isubborrow_i8_v(127, 127, true) == -1 +; run: %isubborrow_i8_v(127, 127, false) == 0 + +function %isubborrow_i8_c(i8, i8, b1) -> b1 { +block0(v0: i8, v1: i8, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v4 +} +; run: %isubborrow_i8_c(0, 1, true) == true +; run: %isubborrow_i8_c(0, 1, false) == true +; run: %isubborrow_i8_c(100, 20, true) == false +; run: %isubborrow_i8_c(100, 20, false) == false +; run: %isubborrow_i8_c(127, 127, true) == false +; run: %isubborrow_i8_c(127, 127, false) == false + +function %isubborrow_i16_v(i16, i16, b1) -> i16 { +block0(v0: i16, v1: i16, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v3 +} +; run: %isubborrow_i16_v(0, 1, true) == -2 +; run: %isubborrow_i16_v(0, 1, false) == -1 +; run: %isubborrow_i16_v(100, 20, true) == 79 +; run: %isubborrow_i16_v(100, 20, false) == 80 +; run: %isubborrow_i16_v(-32000, 768, true) == 32767 +; run: %isubborrow_i16_v(-32000, 768, false) == -32768 + +function %isubborrow_i16_c(i16, i16, b1) -> b1 { +block0(v0: i16, v1: i16, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v4 +} +; run: %isubborrow_i16_c(0, 1, true) == true +; run: %isubborrow_i16_c(0, 1, false) == true +; run: %isubborrow_i16_c(100, 20, true) == false +; run: %isubborrow_i16_c(100, 20, false) == false +; run: %isubborrow_i16_c(-32000, 768, true) == true +; run: %isubborrow_i16_c(-32000, 768, false) == true + +function %isubborrow_i32_v(i32, i32, b1) -> i32 { +block0(v0: i32, v1: i32, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v3 +} +; run: %isubborrow_i32_v(0, 1, true) == -2 +; run: %isubborrow_i32_v(0, 1, false) == -1 +; run: %isubborrow_i32_v(100, 20, true) == 79 +; run: %isubborrow_i32_v(100, 20, false) == 80 +; run: %isubborrow_i32_v(-2147483640, 8, true) == 2147483647 +; run: %isubborrow_i32_v(-2147483640, 8, false) == -2147483648 + +function %isubborrow_i32_c(i32, i32, b1) -> b1 { +block0(v0: i32, v1: i32, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v4 +} +; run: %isubborrow_i32_c(0, 1, true) == true +; run: %isubborrow_i32_c(0, 1, false) == true +; run: %isubborrow_i32_c(100, 20, true) == false +; run: %isubborrow_i32_c(100, 20, false) == false +; run: %isubborrow_i32_c(-2147483640, 8, true) == true +; run: %isubborrow_i32_c(-2147483640, 8, false) == true + + +function %isubborrow_i64_v(i64, i64, b1) -> i64 { +block0(v0: i64, v1: i64, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v3 +} +; run: %isubborrow_i64_v(0, 1, true) == -2 +; run: %isubborrow_i64_v(0, 1, false) == -1 +; run: %isubborrow_i64_v(100, 20, true) == 79 +; run: %isubborrow_i64_v(100, 20, false) == 80 +; run: %isubborrow_i64_v(-9223372036854775800, 8, true) == 9223372036854775807 +; run: %isubborrow_i64_v(-9223372036854775800, 8, false) == -9223372036854775808 + +function %isubborrow_i64_c(i64, i64, b1) -> b1 { +block0(v0: i64, v1: i64, v2: b1): + v3, v4 = isub_borrow v0, v1, v2 + return v4 +} +; run: %isubborrow_i64_c(0, 1, true) == true +; run: %isubborrow_i64_c(0, 1, false) == true +; run: %isubborrow_i64_c(100, 20, true) == false +; run: %isubborrow_i64_c(100, 20, false) == false +; run: %isubborrow_i64_c(-9223372036854775800, 8, true) == true +; run: %isubborrow_i64_c(-9223372036854775800, 8, false) == true diff --git a/cranelift/filetests/filetests/runtests/isubbout.clif b/cranelift/filetests/filetests/runtests/isubbout.clif new file mode 100644 index 0000000000..db07b1a6f3 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/isubbout.clif @@ -0,0 +1,87 @@ +test interpret + +function %isubbout_i8_v(i8, i8) -> i8 { +block0(v0: i8, v1: i8): + v2, v3 = isub_bout v0, v1 + return v2 +} +; run: %isubbout_i8_v(0, 1) == -1 +; run: %isubbout_i8_v(100, 20) == 80 +; run: %isubbout_i8_v(100, -20) == 120 +; run: %isubbout_i8_v(-128, 1) == 127 + +function %isubbout_i8_c(i8, i8) -> b1 { +block0(v0: i8, v1: i8): + v2, v3 = isub_bout v0, v1 + return v3 +} +; run: %isubbout_i8_c(0, 1) == true +; run: %isubbout_i8_c(100, 20) == false +; run: %isubbout_i8_c(100, -20) == false +; run: %isubbout_i8_c(-128, 1) == true + +function %isubbout_i16_v(i16, i16) -> i16 { +block0(v0: i16, v1: i16): + v2, v3 = isub_bout v0, v1 + return v2 +} +; run: %isubbout_i16_v(0, 1) == -1 +; run: %isubbout_i16_v(100, 20) == 80 +; run: %isubbout_i16_v(100, -28) == 128 +; run: %isubbout_i16_v(-32000, 768) == -32768 +; run: %isubbout_i16_v(-32000, 769) == 32767 + +function %isubbout_i16_c(i16, i16) -> b1 { +block0(v0: i16, v1: i16): + v2, v3 = isub_bout v0, v1 + return v3 +} +; run: %isubbout_i16_c(0, 1) == true +; run: %isubbout_i16_c(100, 20) == false +; run: %isubbout_i16_c(100, -28) == false +; run: %isubbout_i16_c(-32000, 768) == true +; run: %isubbout_i16_c(-32000, 769) == true + +function %isubbout_i32_v(i32, i32) -> i32 { +block0(v0: i32, v1: i32): + v2, v3 = isub_bout v0, v1 + return v2 +} +; run: %isubbout_i32_v(0, 1) == -1 +; run: %isubbout_i32_v(100, 20) == 80 +; run: %isubbout_i32_v(100, -28) == 128 +; run: %isubbout_i32_v(-2147483640, 8) == -2147483648 +; run: %isubbout_i32_v(-2147483640, 9) == 2147483647 + +function %isubbout_i32_c(i32, i32) -> b1 { +block0(v0: i32, v1: i32): + v2, v3 = isub_bout v0, v1 + return v3 +} +; run: %isubbout_i32_c(0, 1) == true +; run: %isubbout_i32_c(100, 20) == false +; run: %isubbout_i32_c(100, -28) == false +; run: %isubbout_i32_c(-2147483640, 8) == true +; run: %isubbout_i32_c(-2147483640, 9) == true + +function %isubbout_i64_v(i64, i64) -> i64 { +block0(v0: i64, v1: i64): + v2, v3 = isub_bout v0, v1 + return v2 +} +; run: %isubbout_i64_v(0, 1) == -1 +; run: %isubbout_i64_v(100, 20) == 80 +; run: %isubbout_i64_v(100, -28) == 128 +; run: %isubbout_i64_v(-2147483640, 8) == -2147483648 +; run: %isubbout_i64_v(-2147483640, 9) == -2147483649 + +function %isubbout_i64_c(i64, i64) -> b1 { +block0(v0: i64, v1: i64): + v2, v3 = isub_bout v0, v1 + return v3 +} +; run: %isubbout_i64_c(0, 1) == true +; run: %isubbout_i64_c(100, 20) == false +; run: %isubbout_i64_c(100, -28) == false +; run: %isubbout_i64_c(-2147483640, 8) == true +; run: %isubbout_i64_c(-2147483640, 9) == true \ No newline at end of file diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index f9dd882357..277ad1db0b 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -550,11 +550,28 @@ where assign_multiple(&[sum, Value::bool(carry, types::B1)?]) } Opcode::IaddIfcarry => unimplemented!("IaddIfcarry"), - Opcode::IsubBin => unimplemented!("IsubBin"), + Opcode::IsubBin => choose( + Value::into_bool(arg(2)?)?, + Value::sub(arg(0)?, Value::add(arg(1)?, Value::int(1, ctrl_ty)?)?)?, + Value::sub(arg(0)?, arg(1)?)?, + ), Opcode::IsubIfbin => unimplemented!("IsubIfbin"), - Opcode::IsubBout => unimplemented!("IsubBout"), + Opcode::IsubBout => { + let sum = Value::sub(arg(0)?, arg(1)?)?; + let borrow = Value::lt(&arg(0)?, &arg(1)?)?; + assign_multiple(&[sum, Value::bool(borrow, types::B1)?]) + } Opcode::IsubIfbout => unimplemented!("IsubIfbout"), - Opcode::IsubBorrow => unimplemented!("IsubBorrow"), + Opcode::IsubBorrow => { + let rhs = if Value::into_bool(arg(2)?)? { + Value::add(arg(1)?, Value::int(1, ctrl_ty)?)? + } else { + arg(1)? + }; + let borrow = Value::lt(&arg(0)?, &rhs)?; + let sum = Value::sub(arg(0)?, rhs)?; + assign_multiple(&[sum, Value::bool(borrow, types::B1)?]) + } Opcode::IsubIfborrow => unimplemented!("IsubIfborrow"), Opcode::Band => binary(Value::and, arg(0)?, arg(1)?)?, Opcode::Bor => binary(Value::or, arg(0)?, arg(1)?)?,