diff --git a/include/p4mlir/Dialect/P4HIR/P4HIR_Ops.td b/include/p4mlir/Dialect/P4HIR/P4HIR_Ops.td index 62503ee..561a1b6 100644 --- a/include/p4mlir/Dialect/P4HIR/P4HIR_Ops.td +++ b/include/p4mlir/Dialect/P4HIR/P4HIR_Ops.td @@ -217,8 +217,8 @@ def UnaryOp : P4HIR_Op<"unary", [Pure, SameOperandsAndResultType]> { should be the same. ```mlir - %7 = p4hir.unary(minus, %1) : i32 - %8 = p4hir.unary(not, %2) : i32 + %7 = p4hir.unary(minus, %1) : !p4hir.bit<32> + %8 = p4hir.unary(not, %2) : !p4hir.bit<32> ``` }]; @@ -234,4 +234,55 @@ def UnaryOp : P4HIR_Op<"unary", [Pure, SameOperandsAndResultType]> { let hasVerifier = 1; } +def BinOpKind_Mul : I32EnumAttrCase<"Mul", 1, "mul">; +def BinOpKind_Div : I32EnumAttrCase<"Div", 2, "div">; +def BinOpKind_Mod : I32EnumAttrCase<"Mod", 3, "mod">; +def BinOpKind_Add : I32EnumAttrCase<"Add", 4, "add">; +def BinOpKind_Sub : I32EnumAttrCase<"Sub", 5, "sub">; +def BinOpKind_AddSat : I32EnumAttrCase<"AddSat",6, "sadd">; +def BinOpKind_SubSat : I32EnumAttrCase<"SubSat",7, "ssub">; +def BinOpKind_BOr : I32EnumAttrCase<"Or", 8, "or">; +def BinOpKind_BXor : I32EnumAttrCase<"Xor", 9, "xor">; +def BinOpKind_BAnd : I32EnumAttrCase<"And", 10,"and">; + +def BinOpKind : I32EnumAttr<"BinOpKind", + "binary operation (arith and logic) kind", + [BinOpKind_Mul, BinOpKind_Div, BinOpKind_Mod, + BinOpKind_Add, BinOpKind_Sub, + BinOpKind_AddSat, BinOpKind_SubSat, + BinOpKind_BOr, BinOpKind_BXor, BinOpKind_BAnd]> { + let cppNamespace = "::P4::P4MLIR::P4HIR"; +} + +def BinOp : P4HIR_Op<"binop", [Pure, + SameTypeOperands, SameOperandsAndResultType]> { + + let summary = "Binary operations (arith and logic)"; + let description = [{ + p4hir.binop performs the binary operation according to + the specified opcode kind: [mul, div, mod, add, sub, + sadd, ssub, and, xor, or]. + + It requires two input operands and has one result, all types + should be the same. + + ```mlir + %7 = p4hir.binop(add, %1, %2) : !p4hir.bit<32> + %7 = p4hir.binop(mul, %1, %2) : !p4hir.bit<32> + ``` + }]; + + // TODO: get more accurate than AnyP4Type + let results = (outs AnyP4Type:$result); + let arguments = (ins Arg:$kind, + AnyP4Type:$lhs, AnyP4Type:$rhs); + + let assemblyFormat = [{ + `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) attr-dict + }]; + + // TODO: Implement verification + let hasVerifier = 0; +} + #endif // P4MLIR_DIALECT_P4HIR_P4HIR_OPS_TD diff --git a/test/Dialect/P4HIR/binop.mlir b/test/Dialect/P4HIR/binop.mlir new file mode 100644 index 0000000..a080433 --- /dev/null +++ b/test/Dialect/P4HIR/binop.mlir @@ -0,0 +1,19 @@ +// RUN: p4mlir-opt %s | FileCheck %s + +// No need to check stuff. If it parses, it's fine. +// CHECK: module +module { + %0 = p4hir.const #p4hir.int<42> : !p4hir.bit<8> + %1 = p4hir.const #p4hir.int<42> : !p4hir.bit<8> + + %2 = p4hir.binop(mul, %0, %1) : !p4hir.bit<8> + %3 = p4hir.binop(div, %0, %2) : !p4hir.bit<8> + %4 = p4hir.binop(mod, %0, %3) : !p4hir.bit<8> + %5 = p4hir.binop(add, %0, %4) : !p4hir.bit<8> + %6 = p4hir.binop(sub, %0, %5) : !p4hir.bit<8> + %7 = p4hir.binop(sadd, %0, %6) : !p4hir.bit<8> + %8 = p4hir.binop(ssub, %0, %7) : !p4hir.bit<8> + %9 = p4hir.binop(and, %0, %8) : !p4hir.bit<8> + %10 = p4hir.binop(or, %0, %9) : !p4hir.bit<8> + %11 = p4hir.binop(xor, %0, %10) : !p4hir.bit<8> +} diff --git a/test/Translate/Ops/binop.p4 b/test/Translate/Ops/binop.p4 new file mode 100644 index 0000000..88c335d --- /dev/null +++ b/test/Translate/Ops/binop.p4 @@ -0,0 +1,205 @@ +// RUN: p4mlir-translate --typeinference-only %s | FileCheck %s + +// NOTE: Assertions have been autogenerated by utils/generate-test-checks.py + +action bit_binops() { + bit<10> res; + + bit<10> lhs = 1; + bit<10> rhs = 2; + + bit<10> r1 = lhs + rhs; + bit<10> r2 = lhs - rhs; + bit<10> r3 = lhs * rhs; + + bit<10> r4 = lhs * 3; + bit<10> r5 = 2 * rhs; + + bit<10> r6 = rhs * rhs; + + bit<10> r7 = lhs + rhs * 3 + (2 - rhs); + + bit<10> r8 = lhs / rhs; + bit<10> r9 = lhs % lhs; + + bit<10> r10 = lhs |+| rhs; + bit<10> r11 = lhs |-| rhs; + + bit<10> r12 = lhs | rhs; + bit<10> r13 = lhs & rhs; + bit<10> r14 = lhs ^ rhs; +} + +action int_binops() { + int<10> res; + + int<10> lhs = 1; + int<10> rhs = 2; + + int<10> r1 = lhs + rhs; + int<10> r2 = lhs - rhs; + int<10> r3 = lhs * rhs; + + int<10> r4 = lhs * 3; + int<10> r5 = 2 * rhs; + + int<10> r6 = rhs * rhs; + + int<10> r7 = lhs |+| rhs; + int<10> r8 = lhs |-| rhs; + + int<10> r11 = lhs | rhs; + int<10> r12 = lhs & rhs; + int<10> r13 = lhs ^ rhs; +} + +// CHECK-LABEL: module +// CHECK-NEXT: %[[VAL_0:.*]] = p4hir.alloca !p4hir.bit<10> ["res"] : !p4hir.ref> +// CHECK: %[[VAL_1:.*]] = p4hir.const #p4hir.int<1> : !p4hir.bit<10> +// CHECK: %[[VAL_2:.*]] = p4hir.cast(%[[VAL_1]] : !p4hir.bit<10>) : !p4hir.bit<10> +// CHECK: %[[VAL_3:.*]] = p4hir.alloca !p4hir.bit<10> ["lhs", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_2]], %[[VAL_3]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_4:.*]] = p4hir.const #p4hir.int<2> : !p4hir.bit<10> +// CHECK: %[[VAL_5:.*]] = p4hir.cast(%[[VAL_4]] : !p4hir.bit<10>) : !p4hir.bit<10> +// CHECK: %[[VAL_6:.*]] = p4hir.alloca !p4hir.bit<10> ["rhs", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_5]], %[[VAL_6]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_7:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_8:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_9:.*]] = p4hir.binop(add, %[[VAL_7]], %[[VAL_8]]) : !p4hir.bit<10> +// CHECK: %[[VAL_10:.*]] = p4hir.alloca !p4hir.bit<10> ["r1", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_9]], %[[VAL_10]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_11:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_12:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_13:.*]] = p4hir.binop(sub, %[[VAL_11]], %[[VAL_12]]) : !p4hir.bit<10> +// CHECK: %[[VAL_14:.*]] = p4hir.alloca !p4hir.bit<10> ["r2", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_13]], %[[VAL_14]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_15:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_16:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_17:.*]] = p4hir.binop(mul, %[[VAL_15]], %[[VAL_16]]) : !p4hir.bit<10> +// CHECK: %[[VAL_18:.*]] = p4hir.alloca !p4hir.bit<10> ["r3", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_17]], %[[VAL_18]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_19:.*]] = p4hir.const #p4hir.int<3> : !p4hir.bit<10> +// CHECK: %[[VAL_20:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_21:.*]] = p4hir.binop(mul, %[[VAL_20]], %[[VAL_19]]) : !p4hir.bit<10> +// CHECK: %[[VAL_22:.*]] = p4hir.alloca !p4hir.bit<10> ["r4", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_21]], %[[VAL_22]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_23:.*]] = p4hir.const #p4hir.int<2> : !p4hir.bit<10> +// CHECK: %[[VAL_24:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_25:.*]] = p4hir.binop(mul, %[[VAL_23]], %[[VAL_24]]) : !p4hir.bit<10> +// CHECK: %[[VAL_26:.*]] = p4hir.alloca !p4hir.bit<10> ["r5", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_25]], %[[VAL_26]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_27:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_28:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_29:.*]] = p4hir.binop(mul, %[[VAL_27]], %[[VAL_28]]) : !p4hir.bit<10> +// CHECK: %[[VAL_30:.*]] = p4hir.alloca !p4hir.bit<10> ["r6", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_29]], %[[VAL_30]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_31:.*]] = p4hir.const #p4hir.int<3> : !p4hir.bit<10> +// CHECK: %[[VAL_32:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_33:.*]] = p4hir.binop(mul, %[[VAL_32]], %[[VAL_31]]) : !p4hir.bit<10> +// CHECK: %[[VAL_34:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_35:.*]] = p4hir.binop(add, %[[VAL_34]], %[[VAL_33]]) : !p4hir.bit<10> +// CHECK: %[[VAL_36:.*]] = p4hir.const #p4hir.int<2> : !p4hir.bit<10> +// CHECK: %[[VAL_37:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_38:.*]] = p4hir.binop(sub, %[[VAL_36]], %[[VAL_37]]) : !p4hir.bit<10> +// CHECK: %[[VAL_39:.*]] = p4hir.binop(add, %[[VAL_35]], %[[VAL_38]]) : !p4hir.bit<10> +// CHECK: %[[VAL_40:.*]] = p4hir.alloca !p4hir.bit<10> ["r7", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_39]], %[[VAL_40]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_41:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_42:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_43:.*]] = p4hir.binop(div, %[[VAL_41]], %[[VAL_42]]) : !p4hir.bit<10> +// CHECK: %[[VAL_44:.*]] = p4hir.alloca !p4hir.bit<10> ["r8", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_43]], %[[VAL_44]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_45:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_46:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_47:.*]] = p4hir.binop(mod, %[[VAL_45]], %[[VAL_46]]) : !p4hir.bit<10> +// CHECK: %[[VAL_48:.*]] = p4hir.alloca !p4hir.bit<10> ["r9", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_47]], %[[VAL_48]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_49:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_50:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_51:.*]] = p4hir.binop(sadd, %[[VAL_49]], %[[VAL_50]]) : !p4hir.bit<10> +// CHECK: %[[VAL_52:.*]] = p4hir.alloca !p4hir.bit<10> ["r10", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_51]], %[[VAL_52]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_53:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_54:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_55:.*]] = p4hir.binop(ssub, %[[VAL_53]], %[[VAL_54]]) : !p4hir.bit<10> +// CHECK: %[[VAL_56:.*]] = p4hir.alloca !p4hir.bit<10> ["r11", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_55]], %[[VAL_56]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_57:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_58:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_59:.*]] = p4hir.binop(or, %[[VAL_57]], %[[VAL_58]]) : !p4hir.bit<10> +// CHECK: %[[VAL_60:.*]] = p4hir.alloca !p4hir.bit<10> ["r12", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_59]], %[[VAL_60]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_61:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_62:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_63:.*]] = p4hir.binop(and, %[[VAL_61]], %[[VAL_62]]) : !p4hir.bit<10> +// CHECK: %[[VAL_64:.*]] = p4hir.alloca !p4hir.bit<10> ["r13", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_63]], %[[VAL_64]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_65:.*]] = p4hir.load %[[VAL_3]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_66:.*]] = p4hir.load %[[VAL_6]] : !p4hir.ref>, !p4hir.bit<10> +// CHECK: %[[VAL_67:.*]] = p4hir.binop(xor, %[[VAL_65]], %[[VAL_66]]) : !p4hir.bit<10> +// CHECK: %[[VAL_68:.*]] = p4hir.alloca !p4hir.bit<10> ["r14", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_67]], %[[VAL_68]] : !p4hir.bit<10>, !p4hir.ref> +// CHECK: %[[VAL_69:.*]] = p4hir.alloca !p4hir.int<10> ["res"] : !p4hir.ref> +// CHECK: %[[VAL_70:.*]] = p4hir.const #p4hir.int<1> : !p4hir.int<10> +// CHECK: %[[VAL_71:.*]] = p4hir.cast(%[[VAL_70]] : !p4hir.int<10>) : !p4hir.int<10> +// CHECK: %[[VAL_72:.*]] = p4hir.alloca !p4hir.int<10> ["lhs", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_71]], %[[VAL_72]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_73:.*]] = p4hir.const #p4hir.int<2> : !p4hir.int<10> +// CHECK: %[[VAL_74:.*]] = p4hir.cast(%[[VAL_73]] : !p4hir.int<10>) : !p4hir.int<10> +// CHECK: %[[VAL_75:.*]] = p4hir.alloca !p4hir.int<10> ["rhs", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_74]], %[[VAL_75]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_76:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_77:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_78:.*]] = p4hir.binop(add, %[[VAL_76]], %[[VAL_77]]) : !p4hir.int<10> +// CHECK: %[[VAL_79:.*]] = p4hir.alloca !p4hir.int<10> ["r1", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_78]], %[[VAL_79]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_80:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_81:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_82:.*]] = p4hir.binop(sub, %[[VAL_80]], %[[VAL_81]]) : !p4hir.int<10> +// CHECK: %[[VAL_83:.*]] = p4hir.alloca !p4hir.int<10> ["r2", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_82]], %[[VAL_83]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_84:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_85:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_86:.*]] = p4hir.binop(mul, %[[VAL_84]], %[[VAL_85]]) : !p4hir.int<10> +// CHECK: %[[VAL_87:.*]] = p4hir.alloca !p4hir.int<10> ["r3", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_86]], %[[VAL_87]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_88:.*]] = p4hir.const #p4hir.int<3> : !p4hir.int<10> +// CHECK: %[[VAL_89:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_90:.*]] = p4hir.binop(mul, %[[VAL_89]], %[[VAL_88]]) : !p4hir.int<10> +// CHECK: %[[VAL_91:.*]] = p4hir.alloca !p4hir.int<10> ["r4", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_90]], %[[VAL_91]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_92:.*]] = p4hir.const #p4hir.int<2> : !p4hir.int<10> +// CHECK: %[[VAL_93:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_94:.*]] = p4hir.binop(mul, %[[VAL_92]], %[[VAL_93]]) : !p4hir.int<10> +// CHECK: %[[VAL_95:.*]] = p4hir.alloca !p4hir.int<10> ["r5", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_94]], %[[VAL_95]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_96:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_97:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_98:.*]] = p4hir.binop(mul, %[[VAL_96]], %[[VAL_97]]) : !p4hir.int<10> +// CHECK: %[[VAL_99:.*]] = p4hir.alloca !p4hir.int<10> ["r6", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_98]], %[[VAL_99]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_100:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_101:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_102:.*]] = p4hir.binop(sadd, %[[VAL_100]], %[[VAL_101]]) : !p4hir.int<10> +// CHECK: %[[VAL_103:.*]] = p4hir.alloca !p4hir.int<10> ["r7", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_102]], %[[VAL_103]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_104:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_105:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_106:.*]] = p4hir.binop(ssub, %[[VAL_104]], %[[VAL_105]]) : !p4hir.int<10> +// CHECK: %[[VAL_107:.*]] = p4hir.alloca !p4hir.int<10> ["r8", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_106]], %[[VAL_107]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_108:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_109:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_110:.*]] = p4hir.binop(or, %[[VAL_108]], %[[VAL_109]]) : !p4hir.int<10> +// CHECK: %[[VAL_111:.*]] = p4hir.alloca !p4hir.int<10> ["r11", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_110]], %[[VAL_111]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_112:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_113:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_114:.*]] = p4hir.binop(and, %[[VAL_112]], %[[VAL_113]]) : !p4hir.int<10> +// CHECK: %[[VAL_115:.*]] = p4hir.alloca !p4hir.int<10> ["r12", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_114]], %[[VAL_115]] : !p4hir.int<10>, !p4hir.ref> +// CHECK: %[[VAL_116:.*]] = p4hir.load %[[VAL_72]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_117:.*]] = p4hir.load %[[VAL_75]] : !p4hir.ref>, !p4hir.int<10> +// CHECK: %[[VAL_118:.*]] = p4hir.binop(xor, %[[VAL_116]], %[[VAL_117]]) : !p4hir.int<10> +// CHECK: %[[VAL_119:.*]] = p4hir.alloca !p4hir.int<10> ["r13", init] : !p4hir.ref> +// CHECK: p4hir.store %[[VAL_118]], %[[VAL_119]] : !p4hir.int<10>, !p4hir.ref> diff --git a/tools/p4mlir-translate/translate.cpp b/tools/p4mlir-translate/translate.cpp index d2c23cc..1e12cef 100644 --- a/tools/p4mlir-translate/translate.cpp +++ b/tools/p4mlir-translate/translate.cpp @@ -269,17 +269,32 @@ class P4HIRConverter : public P4::Inspector, public P4::ResolutionContext { bool preorder(const P4::IR::NodeTy *) override { return true; } \ void postorder(const P4::IR::NodeTy *) override; - HANDLE_IN_POSTORDER(Cast) + // Unary ops HANDLE_IN_POSTORDER(Neg) HANDLE_IN_POSTORDER(LNot) HANDLE_IN_POSTORDER(UPlus) HANDLE_IN_POSTORDER(Cmpl) + + // Binary ops + HANDLE_IN_POSTORDER(Mul) + HANDLE_IN_POSTORDER(Div) + HANDLE_IN_POSTORDER(Mod) + HANDLE_IN_POSTORDER(Add) + HANDLE_IN_POSTORDER(Sub) + HANDLE_IN_POSTORDER(AddSat) + HANDLE_IN_POSTORDER(SubSat) + HANDLE_IN_POSTORDER(BOr) + HANDLE_IN_POSTORDER(BAnd) + HANDLE_IN_POSTORDER(BXor) + + HANDLE_IN_POSTORDER(Cast) HANDLE_IN_POSTORDER(Declaration_Variable) #undef HANDLE_IN_POSTORDER + bool preorder(const P4::IR::Declaration_Constant *decl) override; mlir::Value emitUnOp(const P4::IR::Operation_Unary *unop, P4HIR::UnaryOpKind kind); - bool preorder(const P4::IR::Declaration_Constant *decl) override; + mlir::Value emitBinOp(const P4::IR::Operation_Binary *binop, P4HIR::BinOpKind kind); }; bool P4TypeConverter::preorder(const P4::IR::Type_Bits *type) { @@ -433,25 +448,43 @@ mlir::Value P4HIRConverter::emitUnOp(const P4::IR::Operation_Unary *unop, P4HIR: return builder.create(getLoc(builder, unop), kind, getValue(unop->expr)); } -void P4HIRConverter::postorder(const P4::IR::Neg *neg) { - ConversionTracer trace("Converting ", neg); - setValue(neg, emitUnOp(neg, P4HIR::UnaryOpKind::Neg)); +mlir::Value P4HIRConverter::emitBinOp(const P4::IR::Operation_Binary *binop, + P4HIR::BinOpKind kind) { + return builder.create(getLoc(builder, binop), kind, getValue(binop->left), + getValue(binop->right)); } -void P4HIRConverter::postorder(const P4::IR::LNot *lnot) { - ConversionTracer trace("Converting ", lnot); - setValue(lnot, emitUnOp(lnot, P4HIR::UnaryOpKind::LNot)); -} +#define CONVERT_UNOP(Node, Kind) \ + void P4HIRConverter::postorder(const P4::IR::Node *node) { \ + ConversionTracer trace("Converting ", node); \ + setValue(node, emitUnOp(node, P4HIR::UnaryOpKind::Kind)); \ + } -void P4HIRConverter::postorder(const P4::IR::UPlus *plus) { - ConversionTracer trace("Converting ", plus); - setValue(plus, emitUnOp(plus, P4HIR::UnaryOpKind::UPlus)); -} +CONVERT_UNOP(Neg, Neg); +CONVERT_UNOP(UPlus, UPlus); +CONVERT_UNOP(Cmpl, Cmpl); +CONVERT_UNOP(LNot, LNot); -void P4HIRConverter::postorder(const P4::IR::Cmpl *cmpl) { - ConversionTracer trace("Converting ", cmpl); - setValue(cmpl, emitUnOp(cmpl, P4HIR::UnaryOpKind::Cmpl)); -} +#undef CONVERT_UNOP + +#define CONVERT_BINOP(Node, Kind) \ + void P4HIRConverter::postorder(const P4::IR::Node *node) { \ + ConversionTracer trace("Converting ", node); \ + setValue(node, emitBinOp(node, P4HIR::BinOpKind::Kind)); \ + } + +CONVERT_BINOP(Mul, Mul); +CONVERT_BINOP(Div, Div); +CONVERT_BINOP(Mod, Mod); +CONVERT_BINOP(Add, Add); +CONVERT_BINOP(Sub, Sub); +CONVERT_BINOP(AddSat, AddSat); +CONVERT_BINOP(SubSat, SubSat); +CONVERT_BINOP(BOr, Or); +CONVERT_BINOP(BAnd, And); +CONVERT_BINOP(BXor, Xor); + +#undef CONVERT_BINOP } // namespace