From 721cfc16b301db01d73982da94002173c53943ff Mon Sep 17 00:00:00 2001 From: dheaton-arm Date: Mon, 16 Aug 2021 11:43:16 +0100 Subject: [PATCH 1/2] Implement `IsubBin`, `IsubBout`, and `IsubBorrow` Implemented the following Opcodes for the Cranelift interpreter: - `IsubBin` to subtract two scalar integers with an input borrow flag. - `IsubBout` to subtract two scalar integers with an output borrow flag. - `IsubBorrow` to subtract two scalar integers with an input and output borrow flag. Copyright (c) 2021, Arm Limited --- .../filetests/interpreter/isubbin.clif | 49 +++++++++++ .../filetests/interpreter/isubborrow.clif | 73 ++++++++++++++++ .../filetests/interpreter/isubbout.clif | 87 +++++++++++++++++++ cranelift/interpreter/src/step.rs | 23 ++++- 4 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 cranelift/filetests/filetests/interpreter/isubbin.clif create mode 100644 cranelift/filetests/filetests/interpreter/isubborrow.clif create mode 100644 cranelift/filetests/filetests/interpreter/isubbout.clif diff --git a/cranelift/filetests/filetests/interpreter/isubbin.clif b/cranelift/filetests/filetests/interpreter/isubbin.clif new file mode 100644 index 0000000000..304d118d6a --- /dev/null +++ b/cranelift/filetests/filetests/interpreter/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/interpreter/isubborrow.clif b/cranelift/filetests/filetests/interpreter/isubborrow.clif new file mode 100644 index 0000000000..743a1bc797 --- /dev/null +++ b/cranelift/filetests/filetests/interpreter/isubborrow.clif @@ -0,0 +1,73 @@ +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 \ No newline at end of file diff --git a/cranelift/filetests/filetests/interpreter/isubbout.clif b/cranelift/filetests/filetests/interpreter/isubbout.clif new file mode 100644 index 0000000000..db07b1a6f3 --- /dev/null +++ b/cranelift/filetests/filetests/interpreter/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 c9c0372980..3ff67970be 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -460,11 +460,28 @@ where Opcode::IaddIfcout => unimplemented!("IaddIfcout"), Opcode::IaddCarry => unimplemented!("IaddCarry"), 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)?)?, From d1fe72affa4fb12ed0d72ca9ed86c399586bac7b Mon Sep 17 00:00:00 2001 From: dheaton-arm Date: Wed, 25 Aug 2021 14:56:06 +0100 Subject: [PATCH 2/2] Add `i64` tests to `IsubBorrow` and move tests. Copyright (c) 2021, Arm Limited --- .../{interpreter => runtests}/isubbin.clif | 0 .../{interpreter => runtests}/isubborrow.clif | 27 ++++++++++++++++++- .../{interpreter => runtests}/isubbout.clif | 0 3 files changed, 26 insertions(+), 1 deletion(-) rename cranelift/filetests/filetests/{interpreter => runtests}/isubbin.clif (100%) rename cranelift/filetests/filetests/{interpreter => runtests}/isubborrow.clif (71%) rename cranelift/filetests/filetests/{interpreter => runtests}/isubbout.clif (100%) diff --git a/cranelift/filetests/filetests/interpreter/isubbin.clif b/cranelift/filetests/filetests/runtests/isubbin.clif similarity index 100% rename from cranelift/filetests/filetests/interpreter/isubbin.clif rename to cranelift/filetests/filetests/runtests/isubbin.clif diff --git a/cranelift/filetests/filetests/interpreter/isubborrow.clif b/cranelift/filetests/filetests/runtests/isubborrow.clif similarity index 71% rename from cranelift/filetests/filetests/interpreter/isubborrow.clif rename to cranelift/filetests/filetests/runtests/isubborrow.clif index 743a1bc797..cf1f2fd5a3 100644 --- a/cranelift/filetests/filetests/interpreter/isubborrow.clif +++ b/cranelift/filetests/filetests/runtests/isubborrow.clif @@ -70,4 +70,29 @@ block0(v0: i32, v1: i32, v2: b1): ; 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 \ No newline at end of file +; 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/interpreter/isubbout.clif b/cranelift/filetests/filetests/runtests/isubbout.clif similarity index 100% rename from cranelift/filetests/filetests/interpreter/isubbout.clif rename to cranelift/filetests/filetests/runtests/isubbout.clif