Skip to content

Commit 845ef23

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 68fae22 commit 845ef23

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
@@ -146,4 +146,14 @@ def DXSA_DclTemps : DXSA_Op<"dcl_temps"> {
146146
let assemblyFormat = [{ $count attr-dict }];
147147
}
148148

149+
def DXSA_DclIndexableTemp : DXSA_Op<"dcl_indexable_temp"> {
150+
let summary = "declare a temporary register";
151+
let arguments = (ins I32Attr:$register_index,
152+
ConfinedAttr<I32Attr, [IntPositive, IntMaxValue<4096>]>:$register_count,
153+
ConfinedAttr<I32Attr, [IntMinValue<1>, IntMaxValue<4>]>:$num_components);
154+
let assemblyFormat = [{
155+
custom<IndexableTempRegister>($register_index) `[` $register_count `]` `,` $num_components attr-dict
156+
}];
157+
}
158+
149159
#endif // DXSA_OPS

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,54 @@ void DXSADialect::initialize() {
3434
>();
3535
}
3636

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

mlir/lib/Target/DXSA/BinaryParser.cpp

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

518+
Instruction buildDclIndexableTemp(uint32_t registerIndex,
519+
uint32_t registerCount,
520+
uint32_t numComponents, Location loc) {
521+
return dxsa::DclIndexableTemp::create(
522+
builder, loc, builder.getI32IntegerAttr(registerIndex),
523+
builder.getI32IntegerAttr(registerCount),
524+
builder.getI32IntegerAttr(numComponents));
525+
}
526+
518527
private:
519528
MLIRContext *context;
520529
ModuleOp module;
@@ -853,6 +862,40 @@ class Parser {
853862
return builder.buildDclTemps(count, loc);
854863
}
855864

865+
FailureOr<Instruction> parseDclIndexableTemp(Location loc) {
866+
auto registerIndexToken = parseToken();
867+
if (failed(registerIndexToken))
868+
return failure();
869+
auto registerCountToken = parseToken();
870+
if (failed(registerCountToken))
871+
return failure();
872+
auto numComponentsToken = parseToken();
873+
if (failed(numComponentsToken))
874+
return failure();
875+
876+
auto registerCount = *registerCountToken;
877+
if (registerCount == 0) {
878+
emitError(getLocation(), "indexable temp array size cannot be zero");
879+
return failure();
880+
}
881+
if (registerCount > 4096) {
882+
emitError(getLocation(), "invalid indexable temp array size: ")
883+
<< registerCount << " (max 4096)";
884+
return failure();
885+
}
886+
887+
auto numComponents = *numComponentsToken;
888+
if (numComponents < 1 || numComponents > 4) {
889+
emitError(getLocation(), "indexable temp num components must be in 1..4, "
890+
"got ")
891+
<< numComponents;
892+
return failure();
893+
}
894+
895+
return builder.buildDclIndexableTemp(*registerIndexToken, registerCount,
896+
numComponents, loc);
897+
}
898+
856899
OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc,
857900
Instruction &out) {
858901
FailureOr<Instruction> result;
@@ -863,6 +906,9 @@ class Parser {
863906
case D3D10_SB_OPCODE_DCL_TEMPS:
864907
result = parseDclTemps(loc);
865908
break;
909+
case D3D10_SB_OPCODE_DCL_INDEXABLE_TEMP:
910+
result = parseDclIndexableTemp(loc);
911+
break;
866912
default:
867913
return std::nullopt;
868914
}
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)