mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-22 19:49:49 +00:00
Reformatting. Adding "doc_code" divisions for code examples. Updated some
of the examples to reflect the current .TD files. llvm-svn: 46995
This commit is contained in:
parent
30fbb8a24a
commit
08dd4fca8d
@ -68,8 +68,8 @@ href="#backends">TableGen backend</a>" for processing. The current major user
|
||||
of TableGen is the <a href="CodeGenerator.html">LLVM code generator</a>.</p>
|
||||
|
||||
<p>Note that if you work on TableGen much, and use emacs or vim, that you can
|
||||
find an emacs "TableGen mode" and a vim language file in
|
||||
<tt>llvm/utils/emacs</tt> and <tt>llvm/utils/vim</tt> directory of your LLVM
|
||||
find an emacs "TableGen mode" and a vim language file in the
|
||||
<tt>llvm/utils/emacs</tt> and <tt>llvm/utils/vim</tt> directories of your LLVM
|
||||
distribution, respectively.</p>
|
||||
|
||||
</div>
|
||||
@ -83,11 +83,11 @@ distribution, respectively.</p>
|
||||
of which are considered 'records'.</p>
|
||||
|
||||
<p><b>TableGen records</b> have a unique name, a list of values, and a list of
|
||||
superclasses. The list of values is main data that TableGen builds for each
|
||||
record, it is this that holds the domain specific information for the
|
||||
superclasses. The list of values is the main data that TableGen builds for each
|
||||
record; it is this that holds the domain specific information for the
|
||||
application. The interpretation of this data is left to a specific <a
|
||||
href="#backends">TableGen backend</a>, but the structure and format rules are
|
||||
taken care of and fixed by TableGen.</p>
|
||||
taken care of and are fixed by TableGen.</p>
|
||||
|
||||
<p><b>TableGen definitions</b> are the concrete form of 'records'. These
|
||||
generally do not have any undefined values, and are marked with the
|
||||
@ -95,7 +95,7 @@ generally do not have any undefined values, and are marked with the
|
||||
|
||||
<p><b>TableGen classes</b> are abstract records that are used to build and
|
||||
describe other records. These 'classes' allow the end-user to build
|
||||
abstractions for either the domain they are targetting (such as "Register",
|
||||
abstractions for either the domain they are targeting (such as "Register",
|
||||
"RegisterClass", and "Instruction" in the LLVM code generator) or for the
|
||||
implementor to help factor out common properties of records (such as "FPInst",
|
||||
which is used to represent floating point instructions in the X86 backend).
|
||||
@ -119,42 +119,71 @@ all of the classes, then all of the definitions. This is a good way to see what
|
||||
the various definitions expand to fully. Running this on the <tt>X86.td</tt>
|
||||
file prints this (at the time of this writing):</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
...
|
||||
<b>def</b> ADDrr8 { <i>// Instruction X86Inst I2A8 Pattern</i>
|
||||
<b>string</b> Name = "add";
|
||||
<b>def</b> ADD32rr { <i>// Instruction X86Inst I</i>
|
||||
<b>string</b> Namespace = "X86";
|
||||
<b>dag</b> OutOperandList = (outs GR32:$dst);
|
||||
<b>dag</b> InOperandList = (ins GR32:$src1, GR32:$src2);
|
||||
<b>string</b> AsmString = "add{l}\t{$src2, $dst|$dst, $src2}";
|
||||
<b>list</b><dag> Pattern = [(set GR32:$dst, (add GR32:$src1, GR32:$src2))];
|
||||
<b>list</b><Register> Uses = [];
|
||||
<b>list</b><Register> Defs = [];
|
||||
<b>list</b><Register> Defs = [EFLAGS];
|
||||
<b>list</b><Predicate> Predicates = [];
|
||||
<b>int</b> CodeSize = 3;
|
||||
<b>int</b> AddedComplexity = 0;
|
||||
<b>bit</b> isReturn = 0;
|
||||
<b>bit</b> isBranch = 0;
|
||||
<b>bit</b> isIndirectBranch = 0;
|
||||
<b>bit</b> isBarrier = 0;
|
||||
<b>bit</b> isCall = 0;
|
||||
<b>bit</b> isSimpleLoad = 0;
|
||||
<b>bit</b> mayLoad = 0;
|
||||
<b>bit</b> mayStore = 0;
|
||||
<b>bit</b> isImplicitDef = 0;
|
||||
<b>bit</b> isTwoAddress = 1;
|
||||
<b>bit</b> isConvertibleToThreeAddress = 1;
|
||||
<b>bit</b> isCommutable = 1;
|
||||
<b>bit</b> isTerminator = 0;
|
||||
<b>dag</b> Pattern = (set R8, (plus R8, R8));
|
||||
<b>bits</b><8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
<b>bit</b> isReMaterializable = 0;
|
||||
<b>bit</b> isPredicable = 0;
|
||||
<b>bit</b> hasDelaySlot = 0;
|
||||
<b>bit</b> usesCustomDAGSchedInserter = 0;
|
||||
<b>bit</b> hasCtrlDep = 0;
|
||||
<b>bit</b> isNotDuplicable = 0;
|
||||
<b>bit</b> hasSideEffects = 0;
|
||||
<b>bit</b> mayHaveSideEffects = 0;
|
||||
<b>bit</b> neverHasSideEffects = 0;
|
||||
InstrItinClass Itinerary = NoItinerary;
|
||||
<b>string</b> Constraints = "";
|
||||
<b>string</b> DisableEncoding = "";
|
||||
<b>bits</b><8> Opcode = { 0, 0, 0, 0, 0, 0, 0, 1 };
|
||||
Format Form = MRMDestReg;
|
||||
<b>bits</b><5> FormBits = { 0, 0, 0, 1, 1 };
|
||||
ArgType Type = Arg8;
|
||||
<b>bits</b><3> TypeBits = { 0, 0, 1 };
|
||||
<b>bits</b><6> FormBits = { 0, 0, 0, 0, 1, 1 };
|
||||
ImmType ImmT = NoImm;
|
||||
<b>bits</b><3> ImmTypeBits = { 0, 0, 0 };
|
||||
<b>bit</b> hasOpSizePrefix = 0;
|
||||
<b>bit</b> printImplicitUses = 0;
|
||||
<b>bit</b> hasAdSizePrefix = 0;
|
||||
<b>bits</b><4> Prefix = { 0, 0, 0, 0 };
|
||||
<b>bit</b> hasREX_WPrefix = 0;
|
||||
FPFormat FPForm = ?;
|
||||
<b>bits</b><3> FPFormBits = { 0, 0, 0 };
|
||||
}
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This definition corresponds to an 8-bit register-register add instruction in
|
||||
<p>This definition corresponds to a 32-bit register-register add instruction in
|
||||
the X86. The string after the '<tt>def</tt>' string indicates the name of the
|
||||
record ("<tt>ADDrr8</tt>" in this case), and the comment at the end of the line
|
||||
indicates the superclasses of the definition. The body of the record contains
|
||||
all of the data that TableGen assembled for the record, indicating that the
|
||||
instruction is part of the "X86" namespace, should be printed as "<tt>add</tt>"
|
||||
in the assembly file, it is a two-address instruction, has a particular
|
||||
encoding, etc. The contents and semantics of the information in the record is
|
||||
specific to the needs of the X86 backend, and is only shown as an example.</p>
|
||||
record—"<tt>ADD32rr</tt>" in this case—and the comment at the end of
|
||||
the line indicates the superclasses of the definition. The body of the record
|
||||
contains all of the data that TableGen assembled for the record, indicating that
|
||||
the instruction is part of the "X86" namespace, the pattern indicating how the
|
||||
the instruction should be emitted into the assembly file, that it is a
|
||||
two-address instruction, has a particular encoding, etc. The contents and
|
||||
semantics of the information in the record is specific to the needs of the X86
|
||||
backend, and is only shown as an example.</p>
|
||||
|
||||
<p>As you can see, a lot of information is needed for every instruction
|
||||
supported by the code generator, and specifying it all manually would be
|
||||
@ -162,16 +191,23 @@ unmaintainble, prone to bugs, and tiring to do in the first place. Because we
|
||||
are using TableGen, all of the information was derived from the following
|
||||
definition:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>def</b> ADDrr8 : I2A8<"add", 0x00, MRMDestReg>,
|
||||
Pattern<(set R8, (plus R8, R8))>;
|
||||
let Defs = [EFLAGS],
|
||||
isCommutable = 1, <i>// X = ADD Y,Z --> X = ADD Z,Y</i>
|
||||
isConvertibleToThreeAddress = 1 <b>in</b> <i>// Can transform into LEA.</i>
|
||||
def ADD32rr : I<0x01, MRMDestReg, (outs GR32:$dst),
|
||||
(ins GR32:$src1, GR32:$src2),
|
||||
"add{l}\t{$src2, $dst|$dst, $src2}",
|
||||
[(set GR32:$dst, (add GR32:$src1, GR32:$src2))]>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This definition makes use of the custom I2A8 (two address instruction with
|
||||
8-bit operand) class, which is defined in the X86-specific TableGen file to
|
||||
factor out the common features that instructions of its class share. A key
|
||||
feature of TableGen is that it allows the end-user to define the abstractions
|
||||
they prefer to use when describing their information.</p>
|
||||
<p>This definition makes use of the custom class <tt>I</tt> (extended from the
|
||||
custom class <tt>X86Inst</tt>), which is defined in the X86-specific TableGen
|
||||
file, to factor out the common features that instructions of its class share. A
|
||||
key feature of TableGen is that it allows the end-user to define the
|
||||
abstractions they prefer to use when describing their information.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -186,28 +222,37 @@ reads from standard input.</p>
|
||||
|
||||
<p>To be useful, one of the <a href="#backends">TableGen backends</a> must be
|
||||
used. These backends are selectable on the command line (type '<tt>tblgen
|
||||
--help</tt>' for a list). For example, to get a list of all of the definitions
|
||||
-help</tt>' for a list). For example, to get a list of all of the definitions
|
||||
that subclass a particular type (which can be useful for building up an enum
|
||||
list of these records), use the <tt>--print-enums</tt> option:</p>
|
||||
list of these records), use the <tt>-print-enums</tt> option:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
$ tblgen X86.td -print-enums -class=Register
|
||||
AH, AL, AX, BH, BL, BP, BX, CH, CL, CX, DH, DI, DL, DX,
|
||||
EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP, FP0, FP1, FP2, FP3, FP4, FP5, FP6,
|
||||
SI, SP, ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
|
||||
AH, AL, AX, BH, BL, BP, BPL, BX, CH, CL, CX, DH, DI, DIL, DL, DX, EAX, EBP, EBX,
|
||||
ECX, EDI, EDX, EFLAGS, EIP, ESI, ESP, FP0, FP1, FP2, FP3, FP4, FP5, FP6, IP,
|
||||
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, R10, R10B, R10D, R10W, R11, R11B, R11D,
|
||||
R11W, R12, R12B, R12D, R12W, R13, R13B, R13D, R13W, R14, R14B, R14D, R14W, R15,
|
||||
R15B, R15D, R15W, R8, R8B, R8D, R8W, R9, R9B, R9D, R9W, RAX, RBP, RBX, RCX, RDI,
|
||||
RDX, RIP, RSI, RSP, SI, SIL, SP, SPL, ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7,
|
||||
XMM0, XMM1, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5,
|
||||
XMM6, XMM7, XMM8, XMM9,
|
||||
|
||||
$ tblgen X86.td -print-enums -class=Instruction
|
||||
ADCrr32, ADDri16, ADDri16b, ADDri32, ADDri32b, ADDri8, ADDrr16, ADDrr32,
|
||||
ADDrr8, ADJCALLSTACKDOWN, ADJCALLSTACKUP, ANDri16, ANDri16b, ANDri32, ANDri32b,
|
||||
ANDri8, ANDrr16, ANDrr32, ANDrr8, BSWAPr32, CALLm32, CALLpcrel32, ...
|
||||
ABS_F, ABS_Fp32, ABS_Fp64, ABS_Fp80, ADC32mi, ADC32mi8, ADC32mr, ADC32ri,
|
||||
ADC32ri8, ADC32rm, ADC32rr, ADC64mi32, ADC64mi8, ADC64mr, ADC64ri32, ADC64ri8,
|
||||
ADC64rm, ADC64rr, ADD16mi, ADD16mi8, ADD16mr, ADD16ri, ADD16ri8, ADD16rm,
|
||||
ADD16rr, ADD32mi, ADD32mi8, ADD32mr, ADD32ri, ADD32ri8, ADD32rm, ADD32rr,
|
||||
ADD64mi32, ADD64mi8, ADD64mr, ADD64ri32, ...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The default backend prints out all of the records, as described <a
|
||||
href="#example">above</a>.</p>
|
||||
|
||||
<p>If you plan to use TableGen for some purpose, you will most likely have to
|
||||
<a href="#backends">write a backend</a> that extracts the information specific
|
||||
to what you need and formats it in the appropriate way.</p>
|
||||
<p>If you plan to use TableGen, you will most likely have to <a
|
||||
href="#backends">write a backend</a> that extracts the information specific to
|
||||
what you need and formats it in the appropriate way.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -217,10 +262,12 @@ to what you need and formats it in the appropriate way.</p>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>TableGen doesn't care about the meaning of data (that is up to the backend
|
||||
to define), but it does care about syntax, and it enforces a simple type system.
|
||||
|
||||
<p>TableGen doesn't care about the meaning of data (that is up to the backend to
|
||||
define), but it does care about syntax, and it enforces a simple type system.
|
||||
This section describes the syntax and the constructs allowed in a TableGen file.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
@ -230,8 +277,10 @@ This section describes the syntax and the constructs allowed in a TableGen file.
|
||||
<div class="doc_subsubsection"><a name="comments">TableGen comments</a></div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>TableGen supports BCPL style "<tt>//</tt>" comments, which run to the end of
|
||||
the line, and it also supports <b>nestable</b> "<tt>/* */</tt>" comments.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- -------------------------------------------------------------------------->
|
||||
@ -240,6 +289,7 @@ the line, and it also supports <b>nestable</b> "<tt>/* */</tt>" comments.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>TableGen files are strongly typed, in a simple (but complete) type-system.
|
||||
These types are used to perform automatic conversions, check for errors, and to
|
||||
help interface designers constrain the input that they allow. Every <a
|
||||
@ -252,34 +302,41 @@ allows it to describe a wide range of information conveniently and compactly.
|
||||
The TableGen types are:</p>
|
||||
|
||||
<ul>
|
||||
<li>"<tt><b>bit</b></tt>" - A 'bit' is a boolean value that can hold either 0 or
|
||||
1.</li>
|
||||
<dl>
|
||||
|
||||
<li>"<tt><b>int</b></tt>" - The 'int' type represents a simple 32-bit integer
|
||||
value, such as 5.</li>
|
||||
<di><tt><b>bit</b></tt></di>
|
||||
<dd>A 'bit' is a boolean value that can hold either 0 or 1.</dd>
|
||||
|
||||
<li>"<tt><b>string</b></tt>" - The 'string' type represents an ordered sequence
|
||||
of characters of arbitrary length.</li>
|
||||
<di><tt><b>int</b></tt></di>
|
||||
<dd>The 'int' type represents a simple 32-bit integer value, such as 5.</dd>
|
||||
|
||||
<li>"<tt><b>bits</b><n></tt>" - A 'bits' type is an arbitrary, but fixed,
|
||||
size integer that is broken up into individual bits. This type is useful
|
||||
because it can handle some bits being defined while others are undefined.</li>
|
||||
<di><tt><b>string</b></tt></di>
|
||||
<dd>The 'string' type represents an ordered sequence of characters of
|
||||
arbitrary length.</dd>
|
||||
|
||||
<li>"<tt><b>list</b><ty></tt>" - This type represents a list whose
|
||||
elements are some other type. The contained type is arbitrary: it can even be
|
||||
another list type.</li>
|
||||
<di><tt><b>bits</b><n></tt></di>
|
||||
<dd>A 'bits' type is an arbitrary, but fixed, size integer that is broken up
|
||||
into individual bits. This type is useful because it can handle some bits
|
||||
being defined while others are undefined.</dd>
|
||||
|
||||
<li>Class type - Specifying a class name in a type context means that the
|
||||
defined value must be a subclass of the specified class. This is useful in
|
||||
conjunction with the "list" type, for example, to constrain the elements of the
|
||||
list to a common base class (e.g., a <tt><b>list</b><Register></tt> can
|
||||
only contain definitions derived from the "<tt>Register</tt>" class).</li>
|
||||
<di><tt><b>list</b><ty></tt></di>
|
||||
<dd>This type represents a list whose elements are some other type. The
|
||||
contained type is arbitrary: it can even be another list type.</dd>
|
||||
|
||||
<li>"<tt><b>code</b></tt>" - This represents a big hunk of text. NOTE: I don't
|
||||
remember why this is distinct from string!</li>
|
||||
<di>Class type</di>
|
||||
<dd>Specifying a class name in a type context means that the defined value
|
||||
must be a subclass of the specified class. This is useful in conjunction with
|
||||
the <b><tt>list</tt></b> type, for example, to constrain the elements of the
|
||||
list to a common base class (e.g., a <tt><b>list</b><Register></tt> can
|
||||
only contain definitions derived from the "<tt>Register</tt>" class).</dd>
|
||||
|
||||
<li>"<tt><b>dag</b></tt>" - This type represents a nestable directed graph of
|
||||
elements.</li>
|
||||
<di><tt><b>dag</b></tt></di>
|
||||
<dd>This type represents a nestable directed graph of elements.</dd>
|
||||
|
||||
<di><tt><b>code</b></tt></di>
|
||||
<dd>This represents a big hunk of text. NOTE: I don't remember why this is
|
||||
distinct from string!</dd>
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<p>To date, these types have been sufficient for describing things that
|
||||
@ -301,34 +358,54 @@ natural syntax and flavor for the application. The current expression forms
|
||||
supported include:</p>
|
||||
|
||||
<ul>
|
||||
<li><tt>?</tt> - uninitialized field</li>
|
||||
<li><tt>0b1001011</tt> - binary integer value</li>
|
||||
<li><tt>07654321</tt> - octal integer value (indicated by a leading 0)</li>
|
||||
<li><tt>7</tt> - decimal integer value</li>
|
||||
<li><tt>0x7F</tt> - hexadecimal integer value</li>
|
||||
<li><tt>"foo"</tt> - string value</li>
|
||||
<li><tt>[{ ... }]</tt> - code fragment</li>
|
||||
<li><tt>[ X, Y, Z ]</tt> - list value.</li>
|
||||
<li><tt>{ a, b, c }</tt> - initializer for a "bits<3>" value</li>
|
||||
<li><tt>value</tt> - value reference</li>
|
||||
<li><tt>value{17}</tt> - access to one bit of a value</li>
|
||||
<li><tt>value{15-17}</tt> - access to multiple bits of a value</li>
|
||||
<li><tt>DEF</tt> - reference to a record definition</li>
|
||||
<li><tt>CLASS<val list></tt> - reference to a new anonymous definition of
|
||||
CLASS with the specified template arguments.</li>
|
||||
<li><tt>X.Y</tt> - reference to the subfield of a value</li>
|
||||
<li><tt>list[4-7,17,2-3]</tt> - A slice of the 'list' list, including elements
|
||||
4,5,6,7,17,2, and 3 from it. Elements may be included multiple times.</li>
|
||||
<li><tt>(DEF a, b)</tt> - a dag value. The first element is required to be a
|
||||
record definition, the remaining elements in the list may be arbitrary other
|
||||
values, including nested `<tt>dag</tt>' values.</li>
|
||||
<li><tt>!strconcat(a, b)</tt> - A string value that is the result of
|
||||
concatenating the 'a' and 'b' strings.</li>
|
||||
<dl>
|
||||
<di><tt>?</tt></di>
|
||||
<dd>uninitialized field</dd>
|
||||
<di><tt>0b1001011</tt></di>
|
||||
<dd>binary integer value</dd>
|
||||
<di><tt>07654321</tt></di>
|
||||
<dd>octal integer value (indicated by a leading 0)</dd>
|
||||
<di><tt>7</tt></di>
|
||||
<dd>decimal integer value</dd>
|
||||
<di><tt>0x7F</tt></di>
|
||||
<dd>hexadecimal integer value</dd>
|
||||
<di><tt>"foo"</tt></di>
|
||||
<dd>string value</dd>
|
||||
<di><tt>[{ ... }]</tt></di>
|
||||
<dd>code fragment</dd>
|
||||
<di><tt>[ X, Y, Z ]</tt></di>
|
||||
<dd>list value.</dd>
|
||||
<di><tt>{ a, b, c }</tt></di>
|
||||
<dd>initializer for a "bits<3>" value</dd>
|
||||
<di><tt>value</tt></di>
|
||||
<dd>value reference</dd>
|
||||
<di><tt>value{17}</tt></di>
|
||||
<dd>access to one bit of a value</dd>
|
||||
<di><tt>value{15-17}</tt></di>
|
||||
<dd>access to multiple bits of a value</dd>
|
||||
<di><tt>DEF</tt></di>
|
||||
<dd>reference to a record definition</dd>
|
||||
<di><tt>CLASS<val list></tt></di>
|
||||
<dd>reference to a new anonymous definition of CLASS with the specified
|
||||
template arguments.</dd>
|
||||
<di><tt>X.Y</tt></di>
|
||||
<dd>reference to the subfield of a value</dd>
|
||||
<di><tt>list[4-7,17,2-3]</tt></di>
|
||||
<dd>A slice of the 'list' list, including elements 4,5,6,7,17,2, and 3 from
|
||||
it. Elements may be included multiple times.</dd>
|
||||
<di><tt>(DEF a, b)</tt></di>
|
||||
<dd>a dag value. The first element is required to be a record definition, the
|
||||
remaining elements in the list may be arbitrary other values, including nested
|
||||
`<tt>dag</tt>' values.</dd>
|
||||
<di><tt>!strconcat(a, b)</tt></di>
|
||||
<dd>A string value that is the result of concatenating the 'a' and 'b'
|
||||
strings.</dd>
|
||||
</dl>
|
||||
</ul>
|
||||
|
||||
<p>Note that all of the values have rules specifying how they convert to values
|
||||
for different types. These rules allow you to assign a value like "7" to a
|
||||
"bits<4>" value, for example.</p>
|
||||
for different types. These rules allow you to assign a value like "<tt>7</tt>"
|
||||
to a "<tt>bits<4></tt>" value, for example.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -345,11 +422,14 @@ information that TableGen collects. Records are defined with a <tt>def</tt> or
|
||||
<tt>class</tt> keyword, the record name, and an optional list of "<a
|
||||
href="#templateargs">template arguments</a>". If the record has superclasses,
|
||||
they are specified as a comma separated list that starts with a colon character
|
||||
(":"). If <a href="#valuedef">value definitions</a> or <a href="#recordlet">let
|
||||
expressions</a> are needed for the class, they are enclosed in curly braces
|
||||
("{}"); otherwise, the record ends with a semicolon. Here is a simple TableGen
|
||||
file:</p>
|
||||
("<tt>:</tt>"). If <a href="#valuedef">value definitions</a> or <a
|
||||
href="#recordlet">let expressions</a> are needed for the class, they are
|
||||
enclosed in curly braces ("<tt>{}</tt>"); otherwise, the record ends with a
|
||||
semicolon.</p>
|
||||
|
||||
<p>Here is a simple TableGen file:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>class</b> C { <b>bit</b> V = 1; }
|
||||
<b>def</b> X : C;
|
||||
@ -357,6 +437,7 @@ file:</p>
|
||||
<b>string</b> Greeting = "hello";
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This example defines two definitions, <tt>X</tt> and <tt>Y</tt>, both of
|
||||
which derive from the <tt>C</tt> class. Because of this, they both get the
|
||||
@ -376,12 +457,14 @@ subclasses to override them as they wish.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Value definitions define named entries in records. A value must be defined
|
||||
before it can be referred to as the operand for another value definition or
|
||||
before the value is reset with a <a href="#recordlet">let expression</a>. A
|
||||
value is defined by specifying a <a href="#types">TableGen type</a> and a name.
|
||||
If an initial value is available, it may be specified after the type with an
|
||||
equal sign. Value definitions require terminating semicolons.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- -------------------------------------------------------------------------->
|
||||
@ -390,17 +473,20 @@ equal sign. Value definitions require terminating semicolons.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>A record-level let expression is used to change the value of a value
|
||||
definition in a record. This is primarily useful when a superclass defines a
|
||||
value that a derived class or definition wants to override. Let expressions
|
||||
consist of the '<tt>let</tt>' keyword followed by a value name, an equal sign
|
||||
("="), and a new value. For example, a new class could be added to the example
|
||||
above, redefining the <tt>V</tt> field for all of its subclasses:</p>
|
||||
("<tt>=</tt>"), and a new value. For example, a new class could be added to the
|
||||
example above, redefining the <tt>V</tt> field for all of its subclasses:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>class</b> D : C { let V = 0; }
|
||||
<b>def</b> Z : D;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>In this case, the <tt>Z</tt> definition will have a zero value for its "V"
|
||||
value, despite the fact that it derives (indirectly) from the <tt>C</tt> class,
|
||||
@ -414,11 +500,13 @@ because the <tt>D</tt> class overrode its value.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>TableGen permits the definition of parameterized classes as well as normal
|
||||
concrete classes. Parameterized TableGen classes specify a list of variable
|
||||
bindings (which may optionally have defaults) that are bound when used. Here is
|
||||
a simple example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>class</b> FPFormat<<b>bits</b><3> val> {
|
||||
<b>bits</b><3> Value = val;
|
||||
@ -428,16 +516,20 @@ a simple example:</p>
|
||||
<b>def</b> OneArgFP : FPFormat<2>;
|
||||
<b>def</b> OneArgFPRW : FPFormat<3>;
|
||||
<b>def</b> TwoArgFP : FPFormat<4>;
|
||||
<b>def</b> SpecialFP : FPFormat<5>;
|
||||
<b>def</b> CompareFP : FPFormat<5>;
|
||||
<b>def</b> CondMovFP : FPFormat<6>;
|
||||
<b>def</b> SpecialFP : FPFormat<7>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>In this case, template arguments are used as a space efficient way to specify
|
||||
a list of "enumeration values", each with a "Value" field set to the specified
|
||||
integer.</p>
|
||||
a list of "enumeration values", each with a "<tt>Value</tt>" field set to the
|
||||
specified integer.</p>
|
||||
|
||||
<p>The more esoteric forms of <a href="#values">TableGen expressions</a> are
|
||||
useful in conjunction with template arguments. As an example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>class</b> ModRefVal<<b>bits</b><2> val> {
|
||||
<b>bits</b><2> Value = val;
|
||||
@ -449,7 +541,7 @@ useful in conjunction with template arguments. As an example:</p>
|
||||
<b>def</b> ModRef : ModRefVal<3>;
|
||||
|
||||
<b>class</b> Value<ModRefVal MR> {
|
||||
<i>// decode some information into a more convenient format, while providing
|
||||
<i>// Decode some information into a more convenient format, while providing
|
||||
// a nice interface to the user of the "Value" class.</i>
|
||||
<b>bit</b> isMod = MR.Value{0};
|
||||
<b>bit</b> isRef = MR.Value{1};
|
||||
@ -462,12 +554,14 @@ useful in conjunction with template arguments. As an example:</p>
|
||||
<b>def</b> zork : Value<Ref>;
|
||||
<b>def</b> hork : Value<ModRef>;
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>This is obviously a contrived example, but it shows how template arguments
|
||||
can be used to decouple the interface provided to the user of the class from the
|
||||
actual internal data representation expected by the class. In this case,
|
||||
running <tt>tblgen</tt> on the example prints the following definitions:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>def</b> bork { <i>// Value</i>
|
||||
<b>bit</b> isMod = 1;
|
||||
@ -482,6 +576,7 @@ running <tt>tblgen</tt> on the example prints the following definitions:</p>
|
||||
<b>bit</b> isRef = 1;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p> This shows that TableGen was able to dig into the argument and extract a
|
||||
piece of information that was requested by the designer of the "Value" class.
|
||||
@ -502,15 +597,16 @@ While classes with template arguments are a good way to factor commonality
|
||||
between two instances of a definition, multiclasses allow a convenient notation
|
||||
for defining multiple definitions at once (instances of implicitly constructed
|
||||
classes). For example, consider an 3-address instruction set whose instructions
|
||||
come in two forms: "reg = reg op reg" and "reg = reg op imm" (e.g. SPARC). In
|
||||
this case, you'd like to specify in one place that this commonality exists, then
|
||||
in a separate place indicate what all the ops are.
|
||||
come in two forms: "<tt>reg = reg op reg</tt>" and "<tt>reg = reg op imm</tt>"
|
||||
(e.g. SPARC). In this case, you'd like to specify in one place that this
|
||||
commonality exists, then in a separate place indicate what all the ops are.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here is an example TableGen fragment that shows this idea:
|
||||
</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>def</b> ops;
|
||||
<b>def</b> GPR;
|
||||
@ -524,18 +620,20 @@ Here is an example TableGen fragment that shows this idea:
|
||||
(ops GPR:$dst, GPR:$src1, Imm:$src2)>;
|
||||
}
|
||||
|
||||
// Instantiations of the ri_inst multiclass.
|
||||
<i>// Instantiations of the ri_inst multiclass.</i>
|
||||
<b>defm</b> ADD : ri_inst<0b111, "add">;
|
||||
<b>defm</b> SUB : ri_inst<0b101, "sub">;
|
||||
<b>defm</b> MUL : ri_inst<0b100, "mul">;
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>The name of the resultant definitions has the multidef fragment names
|
||||
appended to them, so this defines ADD_rr, ADD_ri, SUB_rr, etc. Using a
|
||||
multiclass this way is exactly equivalent to instantiating the
|
||||
classes multiple times yourself, e.g. by writing:</p>
|
||||
|
||||
appended to them, so this defines <tt>ADD_rr</tt>, <tt>ADD_ri</tt>,
|
||||
<tt>SUB_rr</tt>, etc. Using a multiclass this way is exactly equivalent to
|
||||
instantiating the classes multiple times yourself, e.g. by writing:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>def</b> ops;
|
||||
<b>def</b> GPR;
|
||||
@ -550,7 +648,7 @@ Here is an example TableGen fragment that shows this idea:
|
||||
: inst<opc, !strconcat(asmstr, " $dst, $src1, $src2"),
|
||||
(ops GPR:$dst, GPR:$src1, Imm:$src2)>;
|
||||
|
||||
// Instantiations of the ri_inst multiclass.
|
||||
<i>// Instantiations of the ri_inst multiclass.</i>
|
||||
<b>def</b> ADD_rr : rrinst<0b111, "add">;
|
||||
<b>def</b> ADD_ri : riinst<0b111, "add">;
|
||||
<b>def</b> SUB_rr : rrinst<0b101, "sub">;
|
||||
@ -559,6 +657,7 @@ Here is an example TableGen fragment that shows this idea:
|
||||
<b>def</b> MUL_ri : riinst<0b100, "mul">;
|
||||
...
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -578,9 +677,11 @@ the specified file in place of the include directive. The filename should be
|
||||
specified as a double quoted string immediately after the '<tt>include</tt>'
|
||||
keyword. Example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>include</b> "foo.td"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -590,7 +691,8 @@ keyword. Example:</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p> "let" expressions at file scope are similar to <a href="#recordlet">"let"
|
||||
|
||||
<p>"Let" expressions at file scope are similar to <a href="#recordlet">"let"
|
||||
expressions within a record</a>, except they can specify a value binding for
|
||||
multiple records at a time, and may be useful in certain other cases.
|
||||
File-scope let expressions are really just another way that TableGen allows the
|
||||
@ -600,22 +702,30 @@ end-user to factor out commonality from the records.</p>
|
||||
apply, and one of more records to bind the values in. Here are some
|
||||
examples:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
<b>let</b> isTerminator = 1, isReturn = 1 <b>in</b>
|
||||
<b>def</b> RET : X86Inst<"ret", 0xC3, RawFrm, NoArg>;
|
||||
<b>let</b> isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 <b>in</b>
|
||||
<b>def</b> RET : I<0xC3, RawFrm, (outs), (ins), "ret", [(X86retflag 0)]>;
|
||||
|
||||
<b>let</b> isCall = 1 <b>in</b>
|
||||
<i>// All calls clobber the non-callee saved registers...</i>
|
||||
<b>let</b> Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6] in {
|
||||
<b>def</b> CALLpcrel32 : X86Inst<"call", 0xE8, RawFrm, NoArg>;
|
||||
<b>def</b> CALLr32 : X86Inst<"call", 0xFF, MRMS2r, Arg32>;
|
||||
<b>def</b> CALLm32 : X86Inst<"call", 0xFF, MRMS2m, Arg32>;
|
||||
<b>let</b> Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
|
||||
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
|
||||
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, EFLAGS] <b>in</b> {
|
||||
<b>def</b> CALLpcrel32 : Ii32<0xE8, RawFrm, (outs), (ins i32imm:$dst,variable_ops),
|
||||
"call\t${dst:call}", []>;
|
||||
<b>def</b> CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
|
||||
"call\t{*}$dst", [(X86call GR32:$dst)]>;
|
||||
<b>def</b> CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops),
|
||||
"call\t{*}$dst", []>;
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>File-scope "let" expressions are often useful when a couple of definitions
|
||||
need to be added to several records, and the records do not otherwise need to be
|
||||
opened, as in the case with the CALL* instructions above.</p>
|
||||
opened, as in the case with the <tt>CALL*</tt> instructions above.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
@ -623,9 +733,11 @@ opened, as in the case with the CALL* instructions above.</p>
|
||||
<!-- *********************************************************************** -->
|
||||
|
||||
<div class="doc_text">
|
||||
<p>How they work, how to write one. This section should not contain details
|
||||
about any particular backend, except maybe -print-enums as an example. This
|
||||
should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
|
||||
|
||||
<p>TODO: How they work, how to write one. This section should not contain
|
||||
details about any particular backend, except maybe -print-enums as an example.
|
||||
This should highlight the APIs in <tt>TableGen/Record.h</tt>.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
|
Loading…
Reference in New Issue
Block a user