diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index e886609de829..5039217ee07b 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -151,4 +151,11 @@ def DXSA_DclGlobalFlags : DXSA_Op<"dcl_global_flags"> { let hasVerifier = 1; } +def DXSA_DclTemps : DXSA_Op<"dcl_temps"> { + let summary = "declares the number of temporary registers"; + let arguments = (ins ConfinedAttr]>:$count); + let assemblyFormat = [{ $count attr-dict }]; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 2dddb82a366a..2ac6629e6d75 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -505,13 +505,17 @@ class DXBuilder { return module; } - Instruction buildDclGlobalFlags(uint32_t flags, FileLineColLoc loc) { + Instruction buildDclGlobalFlags(uint32_t flags, Location loc) { auto flagsAttr = dxsa::GlobalFlagsAttr::get( - builder.getContext(), - static_cast(flags)); + builder.getContext(), static_cast(flags)); return dxsa::DclGlobalFlags::create(builder, loc, flagsAttr); } + Instruction buildDclTemps(uint32_t count, Location loc) { + return dxsa::DclTemps::create(builder, loc, + builder.getI32IntegerAttr(count)); + } + private: MLIRContext *context; ModuleOp module; @@ -804,6 +808,48 @@ class Parser { getLocation()); } + FailureOr parseDclGlobalFlags(uint32_t opcodeToken, + Location loc) { + return builder.buildDclGlobalFlags( + DECODE_D3D10_SB_GLOBAL_FLAGS(opcodeToken), loc); + } + + FailureOr parseDclTemps(Location loc) { + auto countToken = parseToken(); + if (failed(countToken)) + return failure(); + auto count = *countToken; + if (count == 0) { + emitError(getLocation(), "temp register count cannot be zero"); + return failure(); + } + if (count > 4096) { + emitError(getLocation(), "invalid temp register count: ") + << count << " (max 4096)"; + return failure(); + } + return builder.buildDclTemps(count, loc); + } + + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, + Instruction &out) { + FailureOr result; + switch (DECODE_D3D10_SB_OPCODE_TYPE(opcodeToken)) { + case D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS: + result = parseDclGlobalFlags(opcodeToken, loc); + break; + case D3D10_SB_OPCODE_DCL_TEMPS: + result = parseDclTemps(loc); + break; + default: + return std::nullopt; + } + if (failed(result)) + return failure(); + out = *result; + return success(); + } + FailureOr parseInstruction() { size_t beginOffset = currentTokenOffset; Token token = parseToken(); @@ -829,12 +875,16 @@ class Parser { return failure(); } - uint32_t opcodeToken = *token; + auto opcodeToken = *token; - if (opcode == D3D10_SB_OPCODE_DCL_GLOBAL_FLAGS) { + Instruction dclInstruction; + auto parseResult = parseDclInstruction(opcodeToken, loc, dclInstruction); + if (parseResult.has_value()) { + if (failed(*parseResult)) + return failure(); if (failed(verifyInstructionLength(beginOffset, length))) return failure(); - return builder.buildDclGlobalFlags(DECODE_D3D10_SB_GLOBAL_FLAGS(opcodeToken), loc); + return dclInstruction; } unsigned numOperands = instrInfo[opcode].numOperands; diff --git a/mlir/test/Target/DXSA/dcl_temps.mlir b/mlir/test/Target/DXSA/dcl_temps.mlir new file mode 100644 index 000000000000..686700499217 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_temps.mlir @@ -0,0 +1,7 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_temps.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_temps 1 +// CHECK-NEXT: dxsa.dcl_temps 16 +// CHECK-NEXT: dxsa.dcl_temps 4096 +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/dcl_temps_invalid.mlir b/mlir/test/Target/DXSA/dcl_temps_invalid.mlir new file mode 100644 index 000000000000..f2a8852ae366 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_temps_invalid.mlir @@ -0,0 +1,9 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 4096}} +dxsa.dcl_temps 0 + +// ----- + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 4096}} +dxsa.dcl_temps 4097 diff --git a/mlir/test/Target/DXSA/inputs/dcl_temps.bin b/mlir/test/Target/DXSA/inputs/dcl_temps.bin new file mode 100644 index 000000000000..dbad1a6a78bb Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_temps.bin differ