diff options
Diffstat (limited to 'test/TableGen')
25 files changed, 419 insertions, 0 deletions
diff --git a/test/TableGen/2003-08-03-PassCode.td b/test/TableGen/2003-08-03-PassCode.td new file mode 100644 index 0000000..7142186 --- /dev/null +++ b/test/TableGen/2003-08-03-PassCode.td @@ -0,0 +1,7 @@ +// RUN: tblgen %s + +class test<code C> { + code Code = C; +} + +def foo : test<[{ hello world! }]>; diff --git a/test/TableGen/2006-09-18-LargeInt.td b/test/TableGen/2006-09-18-LargeInt.td new file mode 100644 index 0000000..0e441c5 --- /dev/null +++ b/test/TableGen/2006-09-18-LargeInt.td @@ -0,0 +1,5 @@ +// RUN: tblgen %s | grep -- -65536 + +def X { + int Y = 0xFFFF0000; +} diff --git a/test/TableGen/AnonDefinitionOnDemand.td b/test/TableGen/AnonDefinitionOnDemand.td new file mode 100644 index 0000000..d567fc8 --- /dev/null +++ b/test/TableGen/AnonDefinitionOnDemand.td @@ -0,0 +1,12 @@ +// RUN: tblgen < %s + +class foo<int X> { int THEVAL = X; } +def foo_imp : foo<1>; + +def x { + foo Y = foo_imp; // This works. +} + +def X { + foo Y = foo<1>; // This should work too, synthesizing a new foo<1>. +} diff --git a/test/TableGen/BitsInitOverflow.td b/test/TableGen/BitsInitOverflow.td new file mode 100644 index 0000000..c0b5da9 --- /dev/null +++ b/test/TableGen/BitsInitOverflow.td @@ -0,0 +1,5 @@ +// RUN: not tblgen %s + +def { + bits<2> X = 5; // bitfield is too small, reject +} diff --git a/test/TableGen/CStyleComment.td b/test/TableGen/CStyleComment.td new file mode 100644 index 0000000..703ae68 --- /dev/null +++ b/test/TableGen/CStyleComment.td @@ -0,0 +1,14 @@ +// Test that multiline, nested, comments work correctly. +// +// RUN: tblgen < %s + +/* Foo + bar + /* + blah + */ + + stuff + */ + +def x; diff --git a/test/TableGen/DagDefSubst.ll b/test/TableGen/DagDefSubst.ll new file mode 100644 index 0000000..e5eebe9 --- /dev/null +++ b/test/TableGen/DagDefSubst.ll @@ -0,0 +1,15 @@ +// RUN: tblgen %s | grep {dag d = (X Y)} +// RUN: tblgen %s | grep {dag e = (Y X)} +def X; + +class yclass; +def Y : yclass; + +class C<yclass N> { + dag d = (X N); + dag e = (N X); +} + +def VAL : C<Y>; + + diff --git a/test/TableGen/DagIntSubst.ll b/test/TableGen/DagIntSubst.ll new file mode 100644 index 0000000..3c1291c --- /dev/null +++ b/test/TableGen/DagIntSubst.ll @@ -0,0 +1,10 @@ +// RUN: tblgen %s | grep {dag d = (X 13)} +def X; + +class C<int N> { + dag d = (X N); +} + +def VAL : C<13>; + + diff --git a/test/TableGen/ForwardRef.td b/test/TableGen/ForwardRef.td new file mode 100644 index 0000000..2056b1f --- /dev/null +++ b/test/TableGen/ForwardRef.td @@ -0,0 +1,15 @@ +// RUN: tblgen %s -o - + +class bar { + list<bar> x; +} + +class foo; +class foo; + +class baz { list<foo> y; } + +class foo { + +} + diff --git a/test/TableGen/GeneralList.td b/test/TableGen/GeneralList.td new file mode 100644 index 0000000..7f099f2 --- /dev/null +++ b/test/TableGen/GeneralList.td @@ -0,0 +1,8 @@ +// RUN: tblgen %s +// +// Test to make sure that lists work with any data-type + +class foo { + list<int> Test = [1, 2, 3]; + list<string> Test2 = ["abc", "xyz", "gtq"]; +} diff --git a/test/TableGen/Include.inc b/test/TableGen/Include.inc new file mode 100644 index 0000000..876bf47 --- /dev/null +++ b/test/TableGen/Include.inc @@ -0,0 +1,4 @@ +// This is used by the Include.td test +def InInclude; + + diff --git a/test/TableGen/Include.td b/test/TableGen/Include.td new file mode 100644 index 0000000..29ed515 --- /dev/null +++ b/test/TableGen/Include.td @@ -0,0 +1,7 @@ +// RUN: tblgen -I %p %s +def BeforeInclude; + +include "Include.inc" + +def AfterInclude; + diff --git a/test/TableGen/IntBitInit.td b/test/TableGen/IntBitInit.td new file mode 100644 index 0000000..b949bfe --- /dev/null +++ b/test/TableGen/IntBitInit.td @@ -0,0 +1,5 @@ +// RUN: tblgen %s +def { + bit A = 1; + int B = A; +} diff --git a/test/TableGen/LazyChange.td b/test/TableGen/LazyChange.td new file mode 100644 index 0000000..145fd0b --- /dev/null +++ b/test/TableGen/LazyChange.td @@ -0,0 +1,11 @@ +// RUN: tblgen %s | grep {int Y = 3} + + +class C { + int X = 4; + int Y = X; +} + +let X = 3 in +def D : C; // Y should be 3 too! + diff --git a/test/TableGen/ListConversion.td b/test/TableGen/ListConversion.td new file mode 100644 index 0000000..773ed6e --- /dev/null +++ b/test/TableGen/ListConversion.td @@ -0,0 +1,10 @@ +// RUN: tblgen %s +class A; +class B : A; + +def b : B; + +def { + list<B> X = [b]; + list<A> Y = X; +} diff --git a/test/TableGen/ListSlices.td b/test/TableGen/ListSlices.td new file mode 100644 index 0000000..be794cf --- /dev/null +++ b/test/TableGen/ListSlices.td @@ -0,0 +1,18 @@ +// RUN: tblgen %s + +def A { + list<int> B = [10, 20, 30, 4, 1, 1231, 20]; +} + +def B { + list<int> X = [10, 20, 30, 4, 1, 1231, 20] [2-4,2,2,0-6]; + + list<int> Y = X[4,5]; + int Z = X[4]; + + list<int> C = A.B[1-4]; + + list<list<int>> AA = [X, Y]; + + int BB = AA[0][1]; +} diff --git a/test/TableGen/MultiClass.td b/test/TableGen/MultiClass.td new file mode 100644 index 0000000..41019eb --- /dev/null +++ b/test/TableGen/MultiClass.td @@ -0,0 +1,25 @@ +// RUN: tblgen %s | grep {zing = 4} | wc -l | grep 2 + +class C1<int A, string B> { + int bar = A; + string thestr = B; + int zing; +} + +def T : C1<4, "blah">; + +multiclass t<int a> { + def S1 : C1<a, "foo"> { + int foo = 4; + let bar = 1; + } + def S2 : C1<a, "bar">; +} + +defm FOO : t<42>; + +def T4 : C1<6, "foo">; + +let zing = 4 in + defm BAZ : t<3>; + diff --git a/test/TableGen/SuperSubclassSameName.td b/test/TableGen/SuperSubclassSameName.td new file mode 100644 index 0000000..087df87 --- /dev/null +++ b/test/TableGen/SuperSubclassSameName.td @@ -0,0 +1,20 @@ +// RUN: tblgen < %s +// Test for template arguments that have the same name as superclass template +// arguments. + + +class Arg { int a; } +def TheArg : Arg { let a = 1; } + + +class Super<Arg F> { + int X = F.a; +} +class Sub<Arg F> : Super<F>; +def inst : Sub<TheArg>; + + +class Super2<int F> { + int X = F; +} +class Sub2<int F> : Super2<F>; diff --git a/test/TableGen/TargetInstrInfo.td b/test/TableGen/TargetInstrInfo.td new file mode 100644 index 0000000..bbee743 --- /dev/null +++ b/test/TableGen/TargetInstrInfo.td @@ -0,0 +1,148 @@ +// This test describes how we eventually want to describe instructions in +// the target independent code generators. +// RUN: tblgen %s + +// Target indep stuff. +class Instruction { // Would have other stuff eventually + bit isTwoAddress = 0; + string AssemblyString; +} +class RegisterClass; + +class RTLNode; + +def ops; // Marker for operand list. + +// Various expressions used in RTL descriptions. +def imm8 : RTLNode; +def imm32 : RTLNode; +def addr : RTLNode; + +def set : RTLNode; +def signext : RTLNode; +def zeroext : RTLNode; +def plus : RTLNode; +def and : RTLNode; +def xor : RTLNode; +def shl : RTLNode; +def load : RTLNode; +def store : RTLNode; +def unspec : RTLNode; + +// Start of X86 specific stuff. + +def R8 : RegisterClass; +def R16 : RegisterClass; +def R32 : RegisterClass; + +def CL; // As are currently defined +def AL; +def AX; +def EDX; + +class Format<bits<5> val> { + bits<5> Value = val; +} + +def Pseudo : Format<0>; def RawFrm : Format<1>; +def AddRegFrm : Format<2>; def MRMDestReg : Format<3>; +def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>; +def MRMSrcMem : Format<6>; +def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>; +def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>; +def MRM6r : Format<22>; def MRM7r : Format<23>; +def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>; +def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>; +def MRM6m : Format<30>; def MRM7m : Format<31>; + + +class Inst<dag opnds, string asmstr, bits<8> opcode, + Format f, list<dag> rtl> : Instruction { + dag Operands = opnds; + string AssemblyString = asmstr; + bits<8> Opcode = opcode; + Format Format = f; + list<dag> RTL = rtl; +} + + +// Start of instruction definitions, the real point of this file. +// +// Note that these patterns show a couple of important things: +// 1. The order and contents of the operands of the MachineInstr are +// described here. Eventually we can do away with this when everything +// is generated from the description. +// 2. The asm string is captured here, which makes it possible to get rid of +// a ton of hacks in the various printers and a bunch of flags. +// 3. Target specific properties (e.g. Format) can still be captured as +// needed. +// 4. We capture the behavior of the instruction with a simplified RTL-like +// expression. +// 5. The use/def properties for each operand are automatically inferred from +// the pattern. +// 6. Address expressions should become first-class entities. + +// Simple copy instruction. isMoveInstr could easily be inferred from this, +// as could MRegisterInfo::copyRegToReg. +def MOV8rr : Inst<(ops R8:$dst, R8:$src), + "mov $dst, $src", 0x88, MRMDestReg, + [(set R8:$dst, R8:$src)]>; + +// Simple immediate initialization. +def MOV8ri : Inst<(ops R8:$dst, imm8:$src), + "mov $dst, $src", 0xB0, AddRegFrm, + [(set R8:$dst, imm8:$src)]>; + +// Two address instructions are described as three-addr instructions, with +// the special target-independent isTwoAddress flag set. The asm pattern +// should not refer to the $src1, this would be enforced by the +// TargetInstrInfo tablegen backend. +let isTwoAddress = 1 in +def AND8rr : Inst<(ops R8:$dst, R8:$src1, R8:$src2), + "and $dst, $src2", 0x20, MRMDestReg, + [(set R8:$dst, (and R8:$src1, R8:$src2))]>; + +// Instructions that have explicit uses/defs make them explicit in the RTL. +// Instructions that need extra stuff emitted in the assembly can, trivially. +let isTwoAddress = 1 in +def SHL32rCL : Inst<(ops R32:$dst, R32:$src), + "shl $dst, CL", 0xD2, MRM4r, + [(set R32:$dst, (shl R32:$src, CL))]>; + +// The RTL list is a list, allowing complex instructions to be defined easily. +// Temporary 'internal' registers can be used to break instructions appart. +let isTwoAddress = 1 in +def XOR32mi : Inst<(ops addr:$addr, imm32:$imm), + "xor $dst, $src2", 0x81, MRM6m, + [(set R32:$tmp1, (load addr:$addr)), + (set R32:$tmp2, (xor R32:$tmp1, imm32:$imm)), + (store addr:$addr, R32:$tmp2)]>; + +// Alternatively, if each tmporary register is only used once, the instruction +// can just be described in nested form. This would be the canonical +// representation the target generator would convert the above into. Pick your +// favorite indentation scheme. +let isTwoAddress = 1 in +def AND32mr : Inst<(ops addr:$addr, R32:$src), + "xor $dst, $src2", 0x81, MRM6m, + [(store addr:$addr, + (and + (load addr:$addr), + R32:$src) + ) + ]>; + +// Describing complex instructions is not too hard! Note how implicit uses/defs +// become explicit here. +def CBW : Inst<(ops), + "cbw", 0x98, RawFrm, + [(set AX, (signext AL))]>; + +// Noop, does nothing. +def NOOP : Inst<(ops), "nop", 0x90, RawFrm, []>; + + +// Instructions that don't expect optimization can use unspec. +def IN8rr : Inst<(ops), "in AL, EDX", 0xEC, RawFrm, + [(set AL, (unspec EDX))]>; + diff --git a/test/TableGen/TemplateArgRename.td b/test/TableGen/TemplateArgRename.td new file mode 100644 index 0000000..535c2e4 --- /dev/null +++ b/test/TableGen/TemplateArgRename.td @@ -0,0 +1,17 @@ +// RUN: tblgen %s + +// Make sure there is no collision between XX and XX. +def S; + +class Before<int XX>; +class After : Before<4> { + dag XX = (S); +} + + + +class C1<int X> { + int Y = X; +} +class C2<int Y, dag X> : C1<Y>; + diff --git a/test/TableGen/Tree.td b/test/TableGen/Tree.td new file mode 100644 index 0000000..f9f1f15 --- /dev/null +++ b/test/TableGen/Tree.td @@ -0,0 +1,18 @@ +// This tests to make sure we can parse tree patterns. +// RUN: tblgen %s + +class TreeNode; +class RegisterClass; + +def set : TreeNode; +def plus : TreeNode; +def imm : TreeNode; +def R32 : RegisterClass; + +class Inst<dag T> { + dag Pattern = T; +} + +def ADDrr32 : Inst<(set R32, (plus R32, R32))>; // a = b + c +def ADDri32 : Inst<(set R32, (plus R32, imm))>; // a = b + imm + diff --git a/test/TableGen/TreeNames.td b/test/TableGen/TreeNames.td new file mode 100644 index 0000000..05a3298 --- /dev/null +++ b/test/TableGen/TreeNames.td @@ -0,0 +1,17 @@ +// This tests to make sure we can parse tree patterns with names. +// RUN: tblgen %s + +class TreeNode; +class RegisterClass; + +def set : TreeNode; +def plus : TreeNode; +def imm : TreeNode; +def R32 : RegisterClass; + +class Inst<dag T> { + dag Pattern = T; +} + +def ADDrr32 : Inst<(set R32, (plus R32:$A, R32:$def))>; + diff --git a/test/TableGen/UnterminatedComment.td b/test/TableGen/UnterminatedComment.td new file mode 100644 index 0000000..7f449c4 --- /dev/null +++ b/test/TableGen/UnterminatedComment.td @@ -0,0 +1,6 @@ +// RUN: not tblgen < %s + +def x; + +/* /* /* */ + diff --git a/test/TableGen/dg.exp b/test/TableGen/dg.exp new file mode 100644 index 0000000..f7d275a --- /dev/null +++ b/test/TableGen/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{td}]] diff --git a/test/TableGen/nested-comment.td b/test/TableGen/nested-comment.td new file mode 100644 index 0000000..68e2958 --- /dev/null +++ b/test/TableGen/nested-comment.td @@ -0,0 +1,12 @@ +// RUN: tblgen < %s + +/* foo + +/ foo + + /*NoReg*/, baz + + + */ + +def X; diff --git a/test/TableGen/strconcat.td b/test/TableGen/strconcat.td new file mode 100644 index 0000000..cdf3928 --- /dev/null +++ b/test/TableGen/strconcat.td @@ -0,0 +1,7 @@ +// RUN: tblgen %s | grep fufoo + +class Y<string S> { + string T = !strconcat(S, "foo"); +} + +def Z : Y<"fu">; |