diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSABitwiseOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSABitwiseOps.td index 8a4b91c3df3e..0b726b372ba9 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSABitwiseOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSABitwiseOps.td @@ -34,6 +34,27 @@ def DXSA_And : DXSA_BinaryOp<"and"> { }]; } +//===----------------------------------------------------------------------===// +// dxsa.bfi +//===----------------------------------------------------------------------===// + +def DXSA_BFI : DXSA_PlainOp<"bfi", 1, 4> { + let summary = "bit field insert"; + let description = [{ + The `dxsa.bfi` operation takes a bit range from the LSB of a number + and places that number of bits in another number at any offset. + + `$src0` specifies the bitfield width to take from `$src2`. `$src1` + specifies the offset at which to insert the bitfield in `$src3`. + + Example: + + ```mlir + dxsa.bfi r<0, >, l(0x1E), l(0x2), v<0, >, l(0x1) + ``` + }]; +} + //===----------------------------------------------------------------------===// // dxsa.bfrev //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td index 6f67ca4c3329..492ad424b0fa 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOpBase.td @@ -25,40 +25,35 @@ class DXSA_Op traits = []> : Op; //===----------------------------------------------------------------------===// -// DXSA shared bases for ops with inline operands +// DXSA shared base for ops with inline operands //===----------------------------------------------------------------------===// -class DXSA_UnaryOp : DXSA_Op { - let arguments = (ins - DXSA_DstOperandAttr:$dst, - DXSA_SrcOperandAttr:$src, - OptionalAttr:$precise); +class DXSA_PlainOp : DXSA_Op { + defvar dstnames = !cond(!eq(dsts, 1): ["dst"], + true: !foreach(n, !range(dsts), !strconcat("dst", !cast(n)))); + defvar srcnames = !cond(!eq(srcs, 1): ["src"], + !eq(srcs, 2): ["lhs", "rhs"], + true: !foreach(n, !range(srcs), !strconcat("src", !cast(n)))); + defvar precisename = ["precise"]; + defvar argnames = !listconcat(dstnames, srcnames, precisename); + + defvar args = !foldl(!dag(ins, ?, argnames), + !range(!add(dsts, srcs, 1)), + acc, n, !setdagarg(acc, n, !cond( + !lt(n, dsts): DXSA_DstOperandAttr, + !lt(n, !add(dsts, srcs)): DXSA_SrcOperandAttr, + true: OptionalAttr))); + let arguments = args; let results = (outs); - let assemblyFormat = - "(`precise` $precise^)? $dst `,` $src attr-dict"; + let assemblyFormat = !interleave(!listconcat( + ["(`precise` $precise^)?"], + !tail(!cond(!eq(!add(dsts, srcs), 0): [""], true: !listflatten(!foreach(n, !listconcat(dstnames, srcnames), ["`,`", !strconcat("$", n)])))), + ["attr-dict"]), " "); } -class DXSA_BinaryOp : DXSA_Op { - let arguments = (ins - DXSA_DstOperandAttr:$dst, - DXSA_SrcOperandAttr:$lhs, - DXSA_SrcOperandAttr:$rhs, - OptionalAttr:$precise); - let results = (outs); - let assemblyFormat = - "(`precise` $precise^)? $dst `,` $lhs `,` $rhs attr-dict"; -} - -class DXSA_TernaryOp : DXSA_Op { - let arguments = (ins - DXSA_DstOperandAttr:$dst, - DXSA_SrcOperandAttr:$src0, - DXSA_SrcOperandAttr:$src1, - DXSA_SrcOperandAttr:$src2, - OptionalAttr:$precise); - let results = (outs); - let assemblyFormat = - "(`precise` $precise^)? $dst `,` $src0 `,` $src1 `,` $src2 attr-dict"; -} +class DXSA_NullaryOp : DXSA_PlainOp; +class DXSA_UnaryOp : DXSA_PlainOp; +class DXSA_BinaryOp : DXSA_PlainOp; +class DXSA_TernaryOp : DXSA_PlainOp; #endif // MLIR_DIALECT_DXSA_IR_DXSAOPBASE diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index b783e6be85f8..ff42301984e9 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -2383,6 +2383,8 @@ class Parser { // Bitwise instructions case D3D10_SB_OPCODE_AND: return PLAIN_OP(And, 1, 2, HasPreciseAttr::Yes); + case D3D11_SB_OPCODE_BFI: + return PLAIN_OP(BFI, 1, 4, HasPreciseAttr::Yes); case D3D11_SB_OPCODE_BFREV: return PLAIN_OP(BFRev, 1, 1, HasPreciseAttr::Yes); case D3D11_SB_OPCODE_COUNTBITS: diff --git a/mlir/test/Target/DXSA/bfi.test b/mlir/test/Target/DXSA/bfi.test new file mode 100644 index 000000000000..1f66e0ebe668 --- /dev/null +++ b/mlir/test/Target/DXSA/bfi.test @@ -0,0 +1,8 @@ +// RUN: mlir-translate --import-dxsa-hex %s | FileCheck %s +// RUN: mlir-translate --import-dxsa-hex %s | mlir-opt --verify-roundtrip + +// CHECK: dxsa.module { + +// CHECK-NEXT: dxsa.bfi r<0, >, l(0x1E), l(0x2), v<0, >, l(0x1) +0x0B00008C, 0x00100022, 0x00000000, 0x00004001, 0x0000001E, 0x00004001, 0x00000002, 0x0010100A, 0x00000000, 0x00004001, 0x00000001 +// CHECK-NEXT: }