Skip to content

Commit 0ecbd6a

Browse files
committed
[mlir][dxsa] Add dcl_indexable_temp instruction
Example: dxsa.dcl_indexable_temp x0[23], 2 dxsa.dcl_indexable_temp x7[4096], 4 Signed-off-by: Vladimir Shiryaev <tagolog@users.noreply.github.com>
1 parent 856b5d3 commit 0ecbd6a

6 files changed

Lines changed: 141 additions & 0 deletions

File tree

mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,14 @@ def DXSA_DclTemps : DXSA_Op<"dcl_temps"> {
158158
let assemblyFormat = [{ $count attr-dict }];
159159
}
160160

161+
def DXSA_DclIndexableTemp : DXSA_Op<"dcl_indexable_temp"> {
162+
let summary = "declare a temporary register";
163+
let arguments = (ins I32Attr:$register_index,
164+
ConfinedAttr<I32Attr, [IntPositive, IntMaxValue<4096>]>:$register_count,
165+
ConfinedAttr<I32Attr, [IntMinValue<1>, IntMaxValue<4>]>:$num_components);
166+
let assemblyFormat = [{
167+
custom<IndexableTempRegister>($register_index) `[` $register_count `]` `,` $num_components attr-dict
168+
}];
169+
}
170+
161171
#endif // DXSA_OPS

mlir/lib/Dialect/DXSA/IR/DXSA.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,54 @@ LogicalResult DclGlobalFlags::verify() {
4444
return success();
4545
}
4646

47+
//===----------------------------------------------------------------------===//
48+
// Custom assembly format helpers
49+
//===----------------------------------------------------------------------===//
50+
51+
namespace {
52+
53+
/// Parse a register identifier of the form `<prefix><N>` (e.g. `x0`, `r3`).
54+
/// The whole identifier must be a single token (no whitespace between
55+
/// prefix and number).
56+
ParseResult parseRegisterName(OpAsmParser &parser, StringRef registerPrefix,
57+
IntegerAttr &registerIndex) {
58+
StringRef name;
59+
auto loc = parser.getCurrentLocation();
60+
if (parser.parseKeyword(&name))
61+
return failure();
62+
if (!name.consume_front(registerPrefix))
63+
return parser.emitError(loc)
64+
<< "expected register prefix '" << registerPrefix << "'";
65+
unsigned value;
66+
if (name.getAsInteger(10, value))
67+
return parser.emitError(loc) << "expected integer after register prefix '"
68+
<< registerPrefix << "'";
69+
registerIndex = parser.getBuilder().getI32IntegerAttr(value);
70+
return success();
71+
}
72+
73+
/// Print a register identifier of the form `<prefix><N>`.
74+
void printRegisterName(OpAsmPrinter &printer, StringRef registerPrefix,
75+
IntegerAttr registerIndex) {
76+
printer << registerPrefix << registerIndex.getInt();
77+
}
78+
79+
//===----------------------------------------------------------------------===//
80+
// Custom parser/printer for indexable temp registers (dcl_indexable_temp op)
81+
//===----------------------------------------------------------------------===//
82+
83+
ParseResult parseIndexableTempRegister(OpAsmParser &parser,
84+
IntegerAttr &registerIndex) {
85+
return parseRegisterName(parser, "x", registerIndex);
86+
}
87+
88+
void printIndexableTempRegister(OpAsmPrinter &printer, Operation *op,
89+
IntegerAttr registerIndex) {
90+
printRegisterName(printer, "x", registerIndex);
91+
}
92+
93+
} // namespace
94+
4795
//===----------------------------------------------------------------------===//
4896
// TableGen'd op method definitions
4997
//===----------------------------------------------------------------------===//

mlir/lib/Target/DXSA/BinaryParser.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,15 @@ class DXBuilder {
516516
builder.getI32IntegerAttr(count));
517517
}
518518

519+
Instruction buildDclIndexableTemp(uint32_t registerIndex,
520+
uint32_t registerCount,
521+
uint32_t numComponents, Location loc) {
522+
return dxsa::DclIndexableTemp::create(
523+
builder, loc, builder.getI32IntegerAttr(registerIndex),
524+
builder.getI32IntegerAttr(registerCount),
525+
builder.getI32IntegerAttr(numComponents));
526+
}
527+
519528
private:
520529
MLIRContext *context;
521530
ModuleOp module;
@@ -831,6 +840,40 @@ class Parser {
831840
return builder.buildDclTemps(count, loc);
832841
}
833842

843+
FailureOr<Instruction> parseDclIndexableTemp(Location loc) {
844+
auto registerIndexToken = parseToken();
845+
if (failed(registerIndexToken))
846+
return failure();
847+
auto registerCountToken = parseToken();
848+
if (failed(registerCountToken))
849+
return failure();
850+
auto numComponentsToken = parseToken();
851+
if (failed(numComponentsToken))
852+
return failure();
853+
854+
auto registerCount = *registerCountToken;
855+
if (registerCount == 0) {
856+
emitError(getLocation(), "indexable temp array size cannot be zero");
857+
return failure();
858+
}
859+
if (registerCount > 4096) {
860+
emitError(getLocation(), "invalid indexable temp array size: ")
861+
<< registerCount << " (max 4096)";
862+
return failure();
863+
}
864+
865+
auto numComponents = *numComponentsToken;
866+
if (numComponents < 1 || numComponents > 4) {
867+
emitError(getLocation(), "indexable temp num components must be in 1..4, "
868+
"got ")
869+
<< numComponents;
870+
return failure();
871+
}
872+
873+
return builder.buildDclIndexableTemp(*registerIndexToken, registerCount,
874+
numComponents, loc);
875+
}
876+
834877
OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc,
835878
Instruction &out) {
836879
FailureOr<Instruction> result;
@@ -841,6 +884,9 @@ class Parser {
841884
case D3D10_SB_OPCODE_DCL_TEMPS:
842885
result = parseDclTemps(loc);
843886
break;
887+
case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
888+
result = parseDclIndexableTemp(loc);
889+
break;
844890
default:
845891
return std::nullopt;
846892
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_indexable_temp.bin | FileCheck %s
2+
3+
// CHECK: module {
4+
// CHECK-NEXT: dxsa.dcl_indexable_temp x0[1], 1
5+
// CHECK-NEXT: dxsa.dcl_indexable_temp x1[23], 2
6+
// CHECK-NEXT: dxsa.dcl_indexable_temp x2[16], 4
7+
// CHECK-NEXT: dxsa.dcl_indexable_temp x7[4096], 4
8+
// CHECK-NEXT: }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: mlir-opt %s -split-input-file -verify-diagnostics
2+
3+
// expected-error@+1 {{attribute 'register_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 4096}}
4+
dxsa.dcl_indexable_temp x0[0], 2
5+
6+
// -----
7+
8+
// expected-error@+1 {{attribute 'register_count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 4096}}
9+
dxsa.dcl_indexable_temp x0[4097], 2
10+
11+
// -----
12+
13+
// expected-error@+1 {{attribute 'num_components' failed to satisfy constraint: 32-bit signless integer attribute whose minimum value is 1 whose maximum value is 4}}
14+
dxsa.dcl_indexable_temp x0[16], 0
15+
16+
// -----
17+
18+
// expected-error@+1 {{attribute 'num_components' failed to satisfy constraint: 32-bit signless integer attribute whose minimum value is 1 whose maximum value is 4}}
19+
dxsa.dcl_indexable_temp x0[16], 5
20+
21+
// -----
22+
23+
// expected-error@+1 {{expected register prefix 'x'}}
24+
dxsa.dcl_indexable_temp r0[16], 4
25+
26+
// -----
27+
28+
// expected-error@+1 {{expected integer after register prefix 'x'}}
29+
dxsa.dcl_indexable_temp xfoo[16], 4
64 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)