1include "llvm/TableGen/Automaton.td"
2include "llvm/TableGen/SearchableTable.td"
3
4// Define a set of input token symbols.
5class SymKindTy;
6def SK_a : SymKindTy;
7def SK_b : SymKindTy;
8def SK_c : SymKindTy;
9def SK_d : SymKindTy;
10
11// Emit those as a C++ enum using SearchableTables.
12def SymKind : GenericEnum {
13  let FilterClass = "SymKindTy";
14}
15
16// Define a transition implementation.
17class SimpleTransition<bits<2> State, SymKindTy A> : Transition {
18  let NewState{1...0} = State;
19  SymKindTy ActionSym = A;
20}
21
22// Token SK_a sets bit 0b01.
23def : SimpleTransition<0b01, SK_a>;
24// Token SK_b sets bits 0b10.
25def : SimpleTransition<0b10, SK_b>;
26// Token SK_c sets both bits 0b11.
27def : SimpleTransition<0b11, SK_c>;
28
29def SimpleAutomaton : GenericAutomaton {
30  let TransitionClass = "SimpleTransition";
31  let SymbolFields = ["ActionSym"];
32  // Override the type of ActionSym from SymKindTy to the C++ type SymKind.
33  string TypeOf_ActionSym = "SymKind";
34}
35
36//===----------------------------------------------------------------------===//
37// TupleActionAutomaton test implementation
38
39// Define a transition implementation.
40class TupleTransition<bits<2> State, SymKindTy s1, SymKindTy s2, string s3> : Transition {
41  let NewState{1...0} = State;
42  SymKindTy S1 = s1;
43  SymKindTy S2 = s2;
44  string S3 = s3;
45}
46
47def : TupleTransition<0b01, SK_a, SK_b, "yeet">;
48def : TupleTransition<0b10, SK_b, SK_b, "foo">;
49def : TupleTransition<0b10, SK_c, SK_a, "foo">;
50
51def TupleAutomaton : GenericAutomaton {
52  let TransitionClass = "TupleTransition";
53  let SymbolFields = ["S1", "S2", "S3"];
54  string TypeOf_S1 = "SymKind";
55  string TypeOf_S2 = "SymKind";
56}
57
58//===----------------------------------------------------------------------===//
59// NfaAutomaton test implementation
60
61class NfaTransition<bits<2> State, SymKindTy S> : Transition {
62  let NewState{1...0} = State;
63  SymKindTy A = S;
64}
65
66// Symbols a and b can transition to 0b01 or 0b11 (sets bit 0).
67def : NfaTransition<0b01, SK_a>;
68def : NfaTransition<0b01, SK_b>;
69// Symbols a and b can also transition to 0b10 or 0b11 (sets bit 1).
70def : NfaTransition<0b10, SK_a>;
71def : NfaTransition<0b10, SK_b>;
72
73def NfaAutomaton : GenericAutomaton {
74  let TransitionClass = "NfaTransition";
75  let SymbolFields = ["A"];
76  string TypeOf_A = "SymKind";
77}
78
79//===----------------------------------------------------------------------===//
80// BinPacker test implementation
81//===----------------------------------------------------------------------===//
82// This test generates an automaton that can pack values into bins subject to
83// constraints. There are 6 possible bins, and the input tokens are constraint
84// types. Some input types span two bins.
85
86// The symbol type for a bin constraint. We use lists of ints as a tblgen hack
87// to conditionally generate defs within multiclasses based on record
88// information. A bin is nonempty (has a dummy one-element value) if enabled.
89class BinRequirementKind {
90  list<int> Bin0 = [];
91  list<int> Bin1 = [];
92  list<int> Bin2 = [];
93  list<int> Bin3 = [];
94  list<int> Bin4 = [];
95  list<int> Bin5 = [];
96}
97// Can use bins {0-3}
98def BRK_0_to_4    : BinRequirementKind { let Bin0 = [1]; let Bin1 = [1]; let Bin2 = [1]; let Bin3 = [1]; }
99// Can use bins {0-3} but only evens (0 and 2).
100def BRK_0_to_4_lo : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; }
101// Can use bins {0-3} but only odds (1 and 3).
102def BRK_0_to_4_hi : BinRequirementKind { let Bin1 = [1]; let Bin3 = [1]; }
103// Can use bins {0-3} but only even-odd pairs (0+1 or 1+2).
104def BRK_0_to_4_dbl : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; }
105def BRK_0_to_6 :    BinRequirementKind { let Bin0 = [1]; let Bin1 = [1]; let Bin2 = [1];
106                                         let Bin3 = [1]; let Bin4 = [1]; let Bin5 = [1]; }
107def BRK_0_to_6_lo : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; let Bin4 = [1]; }
108def BRK_0_to_6_hi : BinRequirementKind { let Bin1 = [1]; let Bin3 = [1]; let Bin5 = [1]; }
109def BRK_0_to_6_dbl : BinRequirementKind { let Bin0 = [1]; let Bin2 = [1]; let Bin4 = [1]; }
110def BRK_2_to_6 :    BinRequirementKind { let Bin2 = [1];
111                                         let Bin3 = [1]; let Bin4 = [1]; let Bin5 = [1]; }
112def BRK_2_to_6_lo : BinRequirementKind { let Bin2 = [1]; let Bin4 = [1]; }
113def BRK_2_to_6_hi : BinRequirementKind { let Bin3 = [1]; let Bin5 = [1];}
114def BRK_2_to_6_dbl : BinRequirementKind { let Bin2 = [1]; let Bin4 = [1]; }
115def BRK_2_to_4 :    BinRequirementKind { let Bin2 = [1]; let Bin3 = [1]; }
116def BRK_2_to_4_lo : BinRequirementKind { let Bin2 = [1]; }
117def BRK_2_to_4_hi : BinRequirementKind { let Bin3 = [1]; }
118def BRK_2_to_4_dbl : BinRequirementKind { let Bin2 = [1]; }
119
120def BinRequirementKindEnum : GenericEnum {
121  let FilterClass = "BinRequirementKind";
122}
123
124// The transition class is trivial; it just contains the constraint symbol.
125class BinTransition : Transition {
126  BinRequirementKind Sym;
127}
128
129// Mixin that occupies a single bin.
130class Bin0 : BinTransition { let NewState{0} = 1; }
131class Bin1 : BinTransition { let NewState{1} = 1; }
132class Bin2 : BinTransition { let NewState{2} = 1;}
133class Bin3 : BinTransition { let NewState{3} = 1; }
134class Bin4 : BinTransition { let NewState{4} = 1;}
135class Bin5 : BinTransition { let NewState{5} = 1; }
136// Mixin that occupies a pair of bins (even-odd pairs).
137class Bin01 : BinTransition { let NewState{0,1} = 0b11; }
138class Bin23 : BinTransition { let NewState{2,3} = 0b11; }
139class Bin45 : BinTransition { let NewState{4,5} = 0b11; }
140
141// Instantiate all possible bin assignments for E.
142multiclass BinAssignments<BinRequirementKind E> {
143  let Sym = E in {
144    // Note the tablegen hack to conditionally instantiate a def based on E.
145    foreach x = E.Bin0 in { def : Bin0; }
146    foreach x = E.Bin1 in { def : Bin1; }
147    foreach x = E.Bin2 in { def : Bin2; }
148    foreach x = E.Bin3 in { def : Bin3; }
149    foreach x = E.Bin4 in { def : Bin4; }
150    foreach x = E.Bin5 in { def : Bin5; }
151  }
152}
153
154// Instantiate all possible bin assignments for E, which spans even-odd pairs.
155multiclass DblBinAssignments<BinRequirementKind E> {
156  let Sym = E in {
157    foreach x = E.Bin0 in { def : Bin01; }
158    foreach x = E.Bin2 in { def : Bin23; }
159    foreach x = E.Bin4 in { def : Bin45; }
160  }
161}
162
163defm : BinAssignments<BRK_0_to_4>;
164defm : DblBinAssignments<BRK_0_to_4_dbl>;
165defm : BinAssignments<BRK_0_to_4_lo>;
166defm : BinAssignments<BRK_0_to_4_hi>;
167defm : BinAssignments<BRK_0_to_6>;
168defm : DblBinAssignments<BRK_0_to_6_dbl>;
169defm : BinAssignments<BRK_0_to_6_lo>;
170defm : BinAssignments<BRK_0_to_6_hi>;
171defm : BinAssignments<BRK_2_to_6>;
172defm : DblBinAssignments<BRK_2_to_6_dbl>;
173defm : BinAssignments<BRK_2_to_6_lo>;
174defm : BinAssignments<BRK_2_to_6_hi>;
175defm : BinAssignments<BRK_2_to_4>;
176defm : DblBinAssignments<BRK_2_to_4_dbl>;
177defm : BinAssignments<BRK_2_to_4_lo>;
178defm : BinAssignments<BRK_2_to_4_hi>;
179
180def BinPackerAutomaton : GenericAutomaton {
181  let TransitionClass = "BinTransition";
182  let SymbolFields = ["Sym"];
183  string TypeOf_Sym = "BinRequirementKindEnum";
184}
185
186
187