mirror of https://github.com/llvm/circt.git
[Moore] Add `moore.string_cmp` op (#8447)
Add a new op to handle operations involving `!moore.string` operands per the rules mentioned in IEEE 1800-2012 table 6-9 "String operators".
This commit is contained in:
parent
aa49f0adb8
commit
25b09ba72b
|
@ -623,6 +623,19 @@ def UArrayCmpPredicateAttr : I64EnumAttr<
|
|||
let cppNamespace = "circt::moore";
|
||||
}
|
||||
|
||||
def StringCmpPredicateAttr : I64EnumAttr<
|
||||
"StringCmpPredicate", "",
|
||||
[
|
||||
I64EnumAttrCase<"eq", 0>,
|
||||
I64EnumAttrCase<"ne", 1>,
|
||||
I64EnumAttrCase<"lt", 2>,
|
||||
I64EnumAttrCase<"le", 3>,
|
||||
I64EnumAttrCase<"gt", 4>,
|
||||
I64EnumAttrCase<"ge", 5>
|
||||
]> {
|
||||
let cppNamespace = "circt::moore";
|
||||
}
|
||||
|
||||
def NegOp : MooreOp<"neg", [Pure, SameOperandsAndResultType]> {
|
||||
let summary = "Arithmetic negation";
|
||||
let description = [{
|
||||
|
@ -926,6 +939,35 @@ def UArrayCmpOp : MooreOp<"uarray_cmp", [
|
|||
}];
|
||||
}
|
||||
|
||||
def StringCmpOp : MooreOp<"string_cmp", [
|
||||
Pure,
|
||||
SameTypeOperands
|
||||
]> {
|
||||
let description = [{
|
||||
Compares two string operands using the specified
|
||||
predicate and returns a single bit result. Supported predicates:
|
||||
- eq : equal
|
||||
- ne : not equal
|
||||
- lt : less than
|
||||
- le : less or equal
|
||||
- gt : greater than
|
||||
- ge : greater or equal
|
||||
|
||||
The equality operator yields 1 if its operands are equal and 0 otherwise.
|
||||
Relational operators compare two strings lexicographically,
|
||||
returning 1 when the specified condition holds and 0 when it does not.
|
||||
}];
|
||||
let arguments = (ins
|
||||
StringCmpPredicateAttr:$predicate,
|
||||
StringType:$lhs,
|
||||
StringType:$rhs
|
||||
);
|
||||
let results = (outs BitType:$result);
|
||||
let assemblyFormat = [{
|
||||
$predicate $lhs `,` $rhs attr-dict `:` type($lhs) `->` type($result)
|
||||
}];
|
||||
}
|
||||
|
||||
class LogicalEqOpBase<string mnemonic> : MooreOp<mnemonic, [
|
||||
Pure,
|
||||
Commutative,
|
||||
|
|
|
@ -293,12 +293,18 @@ struct RvalueExprVisitor {
|
|||
if (isa<moore::UnpackedArrayType>(lhs.getType()))
|
||||
return builder.create<moore::UArrayCmpOp>(
|
||||
loc, moore::UArrayCmpPredicate::eq, lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::eq, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::EqOp>(lhs, rhs);
|
||||
case BinaryOperator::Inequality:
|
||||
if (isa<moore::UnpackedArrayType>(lhs.getType()))
|
||||
return builder.create<moore::UArrayCmpOp>(
|
||||
loc, moore::UArrayCmpPredicate::ne, lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::ne, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::NeOp>(lhs, rhs);
|
||||
case BinaryOperator::CaseEquality:
|
||||
|
@ -313,21 +319,33 @@ struct RvalueExprVisitor {
|
|||
case BinaryOperator::GreaterThanEqual:
|
||||
if (expr.left().type->isSigned())
|
||||
return createBinary<moore::SgeOp>(lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::ge, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::UgeOp>(lhs, rhs);
|
||||
case BinaryOperator::GreaterThan:
|
||||
if (expr.left().type->isSigned())
|
||||
return createBinary<moore::SgtOp>(lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::gt, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::UgtOp>(lhs, rhs);
|
||||
case BinaryOperator::LessThanEqual:
|
||||
if (expr.left().type->isSigned())
|
||||
return createBinary<moore::SleOp>(lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::le, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::UleOp>(lhs, rhs);
|
||||
case BinaryOperator::LessThan:
|
||||
if (expr.left().type->isSigned())
|
||||
return createBinary<moore::SltOp>(lhs, rhs);
|
||||
else if (isa<moore::StringType>(lhs.getType()))
|
||||
return builder.create<moore::StringCmpOp>(
|
||||
loc, moore::StringCmpPredicate::lt, lhs, rhs);
|
||||
else
|
||||
return createBinary<moore::UltOp>(lhs, rhs);
|
||||
|
||||
|
|
|
@ -735,6 +735,14 @@ module Expressions;
|
|||
bit [31:0] arr2 [2];
|
||||
// CHECK: %m = moore.variable : <l4>
|
||||
logic [3:0] m;
|
||||
// CHECK: [[STR_HELLO:%.+]] = moore.string_constant "Hello" : i40
|
||||
// CHECK: [[CONV_HELLO:%.+]] = moore.conversion [[STR_HELLO]] : !moore.i40 -> !moore.string
|
||||
// CHECK: [[VAR_S:%.+]] = moore.variable [[CONV_HELLO]] : <string>
|
||||
string s = "Hello";
|
||||
// CHECK: [[STR_WORLD:%.+]] = moore.string_constant "World" : i40
|
||||
// CHECK: [[CONV_WORLD:%.+]] = moore.conversion [[STR_WORLD]] : !moore.i40 -> !moore.string
|
||||
// CHECK: [[VAR_S1:%.+]] = moore.variable [[CONV_WORLD]] : <string>
|
||||
string s1 = "World";
|
||||
|
||||
initial begin
|
||||
// CHECK: moore.constant 0 : i32
|
||||
|
@ -1169,6 +1177,31 @@ module Expressions;
|
|||
// CHECK: moore.uarray_cmp ne [[TMP3]], [[TMP4]] : <2 x i32> -> i1
|
||||
x = arr1 != arr2;
|
||||
|
||||
// CHECK: [[TMP5:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP6:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp eq [[TMP5]], [[TMP6]] : string -> i1
|
||||
x = s == s1;
|
||||
// CHECK: [[TMP7:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP8:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp ne [[TMP7]], [[TMP8]] : string -> i1
|
||||
x = s != s1;
|
||||
// CHECK: [[TMP9:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP10:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp gt [[TMP9]], [[TMP10]] : string -> i1
|
||||
x = s > s1;
|
||||
// CHECK: [[TMP11:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP12:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp ge [[TMP11]], [[TMP12]] : string -> i1
|
||||
x = s >= s1;
|
||||
// CHECK: [[TMP13:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP14:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp lt [[TMP13]], [[TMP14]] : string -> i1
|
||||
x = s < s1;
|
||||
// CHECK: [[TMP15:%.+]] = moore.read %s
|
||||
// CHECK: [[TMP16:%.+]] = moore.read %s1
|
||||
// CHECK: moore.string_cmp le [[TMP15]], [[TMP16]] : string -> i1
|
||||
x = s <= s1;
|
||||
|
||||
// CHECK: [[TMP1:%.+]] = moore.read %a
|
||||
// CHECK: [[TMP2:%.+]] = moore.read %b
|
||||
// CHECK: moore.ne [[TMP1]], [[TMP2]] : i32 -> i1
|
||||
|
|
|
@ -122,6 +122,11 @@ moore.module @Expressions(
|
|||
// CHECK-SAME: in [[ARRAY2:%[^:]+]] : !moore.uarray<2 x uarray<4 x i8>>
|
||||
in %array2: !moore.uarray<2 x uarray<4 x i8>>,
|
||||
|
||||
// CHECK-SAME: in %s1 : !moore.string
|
||||
in %s1 : !moore.string,
|
||||
// CHECK-SAME: in %s2 : !moore.string
|
||||
in %s2 : !moore.string,
|
||||
|
||||
// CHECK-SAME: in [[REF_A:%[^:]+]] : !moore.ref<i32>
|
||||
in %refA: !moore.ref<i32>,
|
||||
// CHECK-SAME: in [[REF_B:%[^:]+]] : !moore.ref<i32>
|
||||
|
@ -310,6 +315,18 @@ moore.module @Expressions(
|
|||
moore.string_constant "Test" : i128
|
||||
// CHECK: moore.string_constant "" : i128
|
||||
moore.string_constant "" : i128
|
||||
// CHECK: moore.string_cmp eq %s1, %s2 : string -> i1
|
||||
moore.string_cmp eq %s1, %s2 : string -> i1
|
||||
// CHECK: moore.string_cmp ne %s1, %s2 : string -> i1
|
||||
moore.string_cmp ne %s1, %s2 : string -> i1
|
||||
// CHECK: moore.string_cmp lt %s1, %s2 : string -> i1
|
||||
moore.string_cmp lt %s1, %s2 : string -> i1
|
||||
// CHECK: moore.string_cmp le %s1, %s2 : string -> i1
|
||||
moore.string_cmp le %s1, %s2 : string -> i1
|
||||
// CHECK: moore.string_cmp gt %s1, %s2 : string -> i1
|
||||
moore.string_cmp gt %s1, %s2 : string -> i1
|
||||
// CHECK: moore.string_cmp ge %s1, %s2 : string -> i1
|
||||
moore.string_cmp ge %s1, %s2 : string -> i1
|
||||
|
||||
moore.output
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue