@@ -985,6 +985,167 @@ def CmpOp : CIR_Op<"cmp", [Pure, SameTypeOperands]> {
985
985
let hasVerifier = 0;
986
986
}
987
987
988
+ //===----------------------------------------------------------------------===//
989
+ // BitsOp
990
+ //===----------------------------------------------------------------------===//
991
+
992
+ class CIR_BitOp<string mnemonic, TypeConstraint inputTy>
993
+ : CIR_Op<mnemonic, [Pure]> {
994
+ let arguments = (ins inputTy:$input);
995
+ let results = (outs SInt32:$result);
996
+
997
+ let assemblyFormat = [{
998
+ `(` $input `:` type($input) `)` `:` type($result) attr-dict
999
+ }];
1000
+ }
1001
+
1002
+ def BitClrsbOp : CIR_BitOp<"bit.clrsb", SIntOfWidths<[32, 64]>> {
1003
+ let summary = "Get the number of leading redundant sign bits in the input";
1004
+ let description = [{
1005
+ Compute the number of leading redundant sign bits in the input integer.
1006
+
1007
+ The input integer must be a signed integer. The most significant bit of the
1008
+ input integer is the sign bit. The `cir.bit.clrsb` operation returns the
1009
+ number of redundant sign bits in the input, that is, the number of bits
1010
+ following the most significant bit that are identical to it.
1011
+
1012
+ The bit width of the input integer must be either 32 or 64.
1013
+
1014
+ Examples:
1015
+
1016
+ ```mlir
1017
+ !s32i = !cir.int<s, 32>
1018
+
1019
+ // %0 = 0xDEADBEEF, 0b1101_1110_1010_1101_1011_1110_1110_1111
1020
+ %0 = cir.const(#cir.int<3735928559> : !s32i) : !s32i
1021
+ // %1 will be 1 because there is 1 bit following the most significant bit
1022
+ // that is identical to it.
1023
+ %1 = cir.bit.clrsb(%0 : !s32i) : !s32i
1024
+
1025
+ // %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
1026
+ %2 = cir.const(#cir.int<1> : !s32i) : !s32i
1027
+ // %3 will be 30
1028
+ %3 = cir.bit.clrsb(%2 : !s32i) : !s32i
1029
+ ```
1030
+ }];
1031
+ }
1032
+
1033
+ def BitClzOp : CIR_BitOp<"bit.clz", UIntOfWidths<[16, 32, 64]>> {
1034
+ let summary = "Get the number of leading 0-bits in the input";
1035
+ let description = [{
1036
+ Compute the number of leading 0-bits in the input.
1037
+
1038
+ The input integer must be an unsigned integer. The `cir.bit.clz` operation
1039
+ returns the number of consecutive 0-bits at the most significant bit
1040
+ position in the input.
1041
+
1042
+ This operation invokes undefined behavior if the input value is 0.
1043
+
1044
+ Example:
1045
+
1046
+ ```mlir
1047
+ !s32i = !cir.int<s, 32>
1048
+ !u32i = !cir.int<u, 32>
1049
+
1050
+ // %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
1051
+ %0 = cir.const(#cir.int<8> : !u32i) : !u32i
1052
+ // %1 will be 28
1053
+ %1 = cir.bit.clz(%0 : !u32i) : !s32i
1054
+ ```
1055
+ }];
1056
+ }
1057
+
1058
+ def BitCtzOp : CIR_BitOp<"bit.ctz", UIntOfWidths<[16, 32, 64]>> {
1059
+ let summary = "Get the number of trailing 0-bits in the input";
1060
+ let description = [{
1061
+ Compute the number of trailing 0-bits in the input.
1062
+
1063
+ The input integer must be an unsigned integer. The `cir.bit.ctz` operation
1064
+ returns the number of consecutive 0-bits at the least significant bit
1065
+ position in the input.
1066
+
1067
+ This operation invokes undefined behavior if the input value is 0.
1068
+
1069
+ Example:
1070
+
1071
+ ```mlir
1072
+ !s32i = !cir.int<s, 32>
1073
+ !u32i = !cir.int<u, 32>
1074
+
1075
+ // %0 = 0b1000
1076
+ %0 = cir.const(#cir.int<8> : !u32i) : !u32i
1077
+ // %1 will be 3
1078
+ %1 = cir.bit.ctz(%0 : !u32i) : !s32i
1079
+ ```
1080
+ }];
1081
+ }
1082
+
1083
+ def BitFfsOp : CIR_BitOp<"bit.ffs", SIntOfWidths<[32, 64]>> {
1084
+ let summary = "Get the position of the least significant 1-bit of input";
1085
+ let description = [{
1086
+ Compute the position of the least significant 1-bit of the input.
1087
+
1088
+ The input integer must be a signed integer. The `cir.bit.ffs` operation
1089
+ returns one plus the index of the least significant 1-bit of the input
1090
+ signed integer. As a special case, if the input integer is 0, `cir.bit.ffs`
1091
+ returns 0.
1092
+
1093
+ Example:
1094
+
1095
+ ```mlir
1096
+ !s32i = !cir.int<s, 32>
1097
+
1098
+ // %0 = 0x0010_1000
1099
+ %0 = cir.const(#cir.int<40> : !s32i) : !s32i
1100
+ // #1 will be 4 since the 4th least significant bit is 1.
1101
+ %1 = cir.bit.ffs(%0 : !s32i) : !s32i
1102
+ ```
1103
+ }];
1104
+ }
1105
+
1106
+ def BitParityOp : CIR_BitOp<"bit.parity", UIntOfWidths<[32, 64]>> {
1107
+ let summary = "Get the parity of input";
1108
+ let description = [{
1109
+ Compute the parity of the input. The parity of an integer is the number of
1110
+ 1-bits in it modulo 2.
1111
+
1112
+ The input must be an unsigned integer.
1113
+
1114
+ Example:
1115
+
1116
+ ```mlir
1117
+ !s32i = !cir.int<s, 32>
1118
+ !u32i = !cir.int<u, 32>
1119
+
1120
+ // %0 = 0x0110_1000
1121
+ %0 = cir.const(#cir.int<104> : !u32i) : !s32i
1122
+ // %1 will be 1 since there are 3 1-bits in %0
1123
+ %1 = cir.bit.parity(%0 : !u32i) : !s32i
1124
+ ```
1125
+ }];
1126
+ }
1127
+
1128
+ def BitPopcountOp : CIR_BitOp<"bit.popcount", UIntOfWidths<[16, 32, 64]>> {
1129
+ let summary = "Get the number of 1-bits in input";
1130
+ let description = [{
1131
+ Compute the number of 1-bits in the input.
1132
+
1133
+ The input must be an unsigned integer.
1134
+
1135
+ Example:
1136
+
1137
+ ```mlir
1138
+ !s32i = !cir.int<s, 32>
1139
+ !u32i = !cir.int<u, 32>
1140
+
1141
+ // %0 = 0x0110_1000
1142
+ %0 = cir.const(#cir.int<104> : !u32i) : !s32i
1143
+ // %1 will be 3 since there are 3 1-bits in %0
1144
+ %1 = cir.bit.popcount(%0 : !u32i) : !s32i
1145
+ ```
1146
+ }];
1147
+ }
1148
+
988
1149
//===----------------------------------------------------------------------===//
989
1150
// SwitchOp
990
1151
//===----------------------------------------------------------------------===//
0 commit comments