Implemented compare operation for boolean and int types

This commit is contained in:
Amuthan Mannar authored and Jeong YunWon committed 2023-10-07 21:05:27 +09:00
1 parent f8365ca6c3
commit b9ee0b6b7a
2 files changed
+97 -19

No files matched your search

+21 -19
View File
@@ -315,18 +315,36 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
let a_type:Option<JitType> = a.to_jit_type();
let b_type:Option<JitType> = b.to_jit_type();
match (a, b) {
(JitValue::Int(a), JitValue::Int(b)) => {
(JitValue::Int(a), JitValue::Int(b)) |
(JitValue::Bool(a), JitValue::Bool(b)) |
(JitValue::Bool(a), JitValue::Int(b)) |
(JitValue::Int(a), JitValue::Bool(b))
=> {
let operand_one = match a_type.unwrap() {
JitType::Bool => self.builder.ins().uextend(types::I64, a),
_=> a
};
let operand_two = match b_type.unwrap() {
JitType::Bool => self.builder.ins().uextend(types::I64, b),
_=> b
};
let cond = match op {
ComparisonOperator::Equal => IntCC::Equal,
ComparisonOperator::NotEqual => IntCC::NotEqual,
ComparisonOperator::Less => IntCC::SignedLessThan,
ComparisonOperator::LessOrEqual => IntCC::SignedLessThanOrEqual,
ComparisonOperator::Greater => IntCC::SignedGreaterThan,
ComparisonOperator::GreaterOrEqual => IntCC::SignedLessThanOrEqual,
ComparisonOperator::GreaterOrEqual => IntCC::SignedGreaterThanOrEqual,
};
let val = self.builder.ins().icmp(cond, a, b);
let val = self.builder.ins().icmp(cond, operand_one, operand_two);
// TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
self.stack
.push(JitValue::Bool(self.builder.ins().bint(types::I8, val)));
@@ -348,22 +366,6 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
.push(JitValue::Bool(self.builder.ins().bint(types::I8, val)));
Ok(())
}
(JitValue::Bool(a), JitValue::Bool(b)) => {
let cond = match op {
ComparisonOperator::Equal => IntCC::Equal,
ComparisonOperator::NotEqual => IntCC::NotEqual,
ComparisonOperator::Less => IntCC::UnsignedLessThan,
ComparisonOperator::LessOrEqual => IntCC::UnsignedLessThanOrEqual,
ComparisonOperator::Greater => IntCC::UnsignedGreaterThan,
ComparisonOperator::GreaterOrEqual => IntCC::UnsignedGreaterThanOrEqual,
};
let val = self.builder.ins().icmp(cond, a, b);
// TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
self.stack
.push(JitValue::Bool(self.builder.ins().bint(types::I8, val)));
Ok(())
}
_ => Err(JitCompileError::NotSupported),
}
}
+76
View File
@@ -66,6 +66,21 @@ fn test_eq() {
assert_eq!(eq(true, false), Ok(0));
}
#[test]
fn test_eq_with_integers() {
let eq = jit_function! { eq(a:bool, b:i64) -> i64 => r##"
def eq(a: bool, b: int):
if a == b:
return 1
return 0
"## };
assert_eq!(eq(false, 0), Ok(1));
assert_eq!(eq(true, 1), Ok(1));
assert_eq!(eq(false, 1), Ok(0));
assert_eq!(eq(true, 0), Ok(0));
}
#[test]
fn test_gt() {
let gt = jit_function! { gt(a:bool, b:bool) -> i64 => r##"
@@ -81,6 +96,21 @@ fn test_gt() {
assert_eq!(gt(true, false), Ok(1));
}
#[test]
fn test_gt_with_integers() {
let gt = jit_function! { gt(a:i64, b:bool) -> i64 => r##"
def gt(a: int, b: bool):
if a > b:
return 1
return 0
"## };
assert_eq!(gt(0, false), Ok(0));
assert_eq!(gt(1, true), Ok(0));
assert_eq!(gt(0, true), Ok(0));
assert_eq!(gt(1, false), Ok(1));
}
#[test]
fn test_lt() {
let lt = jit_function! { lt(a:bool, b:bool) -> i64 => r##"
@@ -96,6 +126,21 @@ fn test_lt() {
assert_eq!(lt(true, false), Ok(0));
}
#[test]
fn test_lt_with_integers() {
let lt = jit_function! { lt(a:i64, b:bool) -> i64 => r##"
def lt(a: int, b: bool):
if a < b:
return 1
return 0
"## };
assert_eq!(lt(0, false), Ok(0));
assert_eq!(lt(1, true), Ok(0));
assert_eq!(lt(0, true), Ok(1));
assert_eq!(lt(1, false), Ok(0));
}
#[test]
fn test_gte() {
let gte = jit_function! { gte(a:bool, b:bool) -> i64 => r##"
@@ -111,6 +156,22 @@ fn test_gte() {
assert_eq!(gte(true, false), Ok(1));
}
#[test]
fn test_gte_with_integers() {
let gte = jit_function! { gte(a:bool, b:i64) -> i64 => r##"
def gte(a: bool, b: int):
if a >= b:
return 1
return 0
"## };
assert_eq!(gte(false, 0), Ok(1));
assert_eq!(gte(true, 1), Ok(1));
assert_eq!(gte(false, 1), Ok(0));
assert_eq!(gte(true, 0), Ok(1));
}
#[test]
fn test_lte() {
let lte = jit_function! { lte(a:bool, b:bool) -> i64 => r##"
@@ -125,3 +186,18 @@ fn test_lte() {
assert_eq!(lte(false, true), Ok(1));
assert_eq!(lte(true, false), Ok(0));
}
#[test]
fn test_lte_with_integers() {
let lte = jit_function! { lte(a:bool, b:i64) -> i64 => r##"
def lte(a: bool, b: int):
if a <= b:
return 1
return 0
"## };
assert_eq!(lte(false, 0), Ok(1));
assert_eq!(lte(true, 1), Ok(1));
assert_eq!(lte(false, 1), Ok(1));
assert_eq!(lte(true, 0), Ok(0));
}