diff options
author | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
---|---|---|
committer | Shih-wei Liao <sliao@google.com> | 2010-02-10 11:10:31 -0800 |
commit | e264f62ca09a8f65c87a46d562a4d0f9ec5d457e (patch) | |
tree | 59e3d57ef656cef79afa708ae0a3daf25cd91fcf /test/TableGen | |
download | external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.zip external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.gz external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.bz2 |
Check in LLVM r95781.
Diffstat (limited to 'test/TableGen')
42 files changed, 1057 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..afd813f --- /dev/null +++ b/test/TableGen/2006-09-18-LargeInt.td @@ -0,0 +1,5 @@ +// RUN: tblgen %s | grep -- 4294901760 + +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..076b3f6 --- /dev/null +++ b/test/TableGen/BitsInitOverflow.td @@ -0,0 +1,5 @@ +// RUN: not tblgen %s 2> /dev/null + +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.td b/test/TableGen/DagDefSubst.td new file mode 100644 index 0000000..e5eebe9 --- /dev/null +++ b/test/TableGen/DagDefSubst.td @@ -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.td b/test/TableGen/DagIntSubst.td new file mode 100644 index 0000000..3c1291c --- /dev/null +++ b/test/TableGen/DagIntSubst.td @@ -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/DefmInherit.td b/test/TableGen/DefmInherit.td new file mode 100644 index 0000000..4f37edf --- /dev/null +++ b/test/TableGen/DefmInherit.td @@ -0,0 +1,32 @@ +// RUN: tblgen %s | grep {zing = 4} | count 4 + +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">; +} + +multiclass s<int a> { + def S3 : C1<a, "moo"> { + int moo = 3; + let bar = 1; + } + def S4 : C1<a, "baz">; +} + +defm FOO : t<42>, s<24>; + +def T4 : C1<6, "foo">; + +let zing = 4 in + defm BAZ : t<3>, s<4>; 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/ListArgs.td b/test/TableGen/ListArgs.td new file mode 100644 index 0000000..daa0de6 --- /dev/null +++ b/test/TableGen/ListArgs.td @@ -0,0 +1,11 @@ +// RUN: tblgen %s + +class B<list<int> v> { + list<int> vals = v; +} + +class BB<list<list<int>> vals> : B<vals[0]>; +class BBB<list<list<int>> vals> : BB<vals>; + +def OneB : BBB<[[1,2,3]]>; +def TwoB : BBB<[[1,2,3],[4,5,6]]>; diff --git a/test/TableGen/ListArgsSimple.td b/test/TableGen/ListArgsSimple.td new file mode 100644 index 0000000..b3b2078 --- /dev/null +++ b/test/TableGen/ListArgsSimple.td @@ -0,0 +1,8 @@ +// RUN: tblgen %s + +class B<int v> { + int val = v; +} + +class BB<list<int> vals> : B<vals[0]>; +class BBB<list<int> vals> : BB<vals>; 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..52ba59c --- /dev/null +++ b/test/TableGen/MultiClass.td @@ -0,0 +1,25 @@ +// RUN: tblgen %s | grep {zing = 4} | count 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/MultiClassDefName.td b/test/TableGen/MultiClassDefName.td new file mode 100644 index 0000000..2e71f7d --- /dev/null +++ b/test/TableGen/MultiClassDefName.td @@ -0,0 +1,12 @@ +// RUN: tblgen %s | grep WorldHelloCC | count 1 + +class C<string n> { + string name = n; +} + +multiclass Names<string n, string m> { + def CC : C<n>; + def World#NAME#CC : C<m>; +} + +defm Hello : Names<"hello", "world">; diff --git a/test/TableGen/MultiClassInherit.td b/test/TableGen/MultiClassInherit.td new file mode 100644 index 0000000..d4c4ce5 --- /dev/null +++ b/test/TableGen/MultiClassInherit.td @@ -0,0 +1,64 @@ +// RUN: tblgen %s | grep {zing = 4} | count 28 + +class C1<int A, string B> { + int bar = A; + string thestr = B; + int zing; +} + +def T : C1<4, "blah">; + +multiclass t1<int a1> { + def S1 : C1<a1, "foo"> { + int foo = 4; + let bar = 1; + } + def S2 : C1<a1, "bar">; +} + +multiclass t2<int a2> { + def S3 : C1<a2, "foo"> { + int foo = 4; + let bar = 1; + } + def S4 : C1<a2, "bar">; +} + +multiclass s1<int as1, int bs1> : t1<as1> { + def S5 : C1<bs1, "moo"> { + int moo = 3; + let bar = 1; + } + def S6 : C1<bs1, "baz">; +} + +multiclass s2<int as2> : t1<as2>, t2<as2>; + +multiclass s3<int as3, int bs3> : t1<as3>, t2<as3> { + def S7 : C1<bs3, "moo"> { + int moo = 3; + let bar = 1; + } + def S8 : C1<bs3, "baz">; +} + +let zing = 4 in +defm FOO1 : s1<42, 24>; + +let zing = 4 in +defm FOO2 : s2<99>; + +let zing = 4 in +defm FOO3 : s3<84, 48>; + +def T4 : C1<6, "foo">; + +let zing = 4 in + defm BAZ1 : s1<3, 4>; + +let zing = 4 in + defm BAZ2 : s2<5>; + +let zing = 4 in + defm BAZ3 : s3<6, 7>; + diff --git a/test/TableGen/Slice.td b/test/TableGen/Slice.td new file mode 100644 index 0000000..cd9c6da --- /dev/null +++ b/test/TableGen/Slice.td @@ -0,0 +1,87 @@ +// RUN: tblgen %s | grep {\\\[(set} | count 2 +// RUN: tblgen %s | grep {\\\[\\\]} | count 2 + +class ValueType<int size, int value> { + int Size = size; + int Value = value; +} + +def f32 : ValueType<32, 1>; // 2 x i64 vector value + +class Intrinsic<string name> { + string Name = name; +} + +class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, + list<dag> pattern> { + bits<8> Opcode = opcode; + dag OutOperands = oopnds; + dag InOperands = iopnds; + string AssemblyString = asmstr; + list<dag> Pattern = pattern; +} + +def ops; +def outs; +def ins; + +def set; + +// Define registers +class Register<string n> { + string Name = n; +} + +class RegisterClass<list<ValueType> regTypes, list<Register> regList> { + list<ValueType> RegTypes = regTypes; + list<Register> MemberList = regList; +} + +def XMM0: Register<"xmm0">; +def XMM1: Register<"xmm1">; +def XMM2: Register<"xmm2">; +def XMM3: Register<"xmm3">; +def XMM4: Register<"xmm4">; +def XMM5: Register<"xmm5">; +def XMM6: Register<"xmm6">; +def XMM7: Register<"xmm7">; +def XMM8: Register<"xmm8">; +def XMM9: Register<"xmm9">; +def XMM10: Register<"xmm10">; +def XMM11: Register<"xmm11">; +def XMM12: Register<"xmm12">; +def XMM13: Register<"xmm13">; +def XMM14: Register<"xmm14">; +def XMM15: Register<"xmm15">; + +def FR32 : RegisterClass<[f32], + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, + XMM12, XMM13, XMM14, XMM15]>; + +class SDNode {} +def not : SDNode; + +multiclass scalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> { + def SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src), + !strconcat(asmstr, "\t$dst, $src"), + !if(!null(patterns),[]<dag>,patterns[0])>; + def SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src), + !strconcat(asmstr, "\t$dst, $src"), + !if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>; +} + +multiclass vscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> { + def V#NAME#SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src), + !strconcat(asmstr, "\t$dst, $src"), + !if(!null(patterns),[]<dag>,patterns[0])>; + def V#NAME#SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src), + !strconcat(asmstr, "\t$dst, $src"), + !if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>; +} + +multiclass myscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> : + scalar<opcode, asmstr, patterns>, + vscalar<opcode, asmstr, patterns>; + +defm NOT : myscalar<0x10, "not", [[], [(set FR32:$dst, (f32 (not FR32:$src)))]]>; diff --git a/test/TableGen/String.td b/test/TableGen/String.td new file mode 100644 index 0000000..d2ae451 --- /dev/null +++ b/test/TableGen/String.td @@ -0,0 +1,5 @@ +// RUN: tblgen %s +class x { + string y = "missing terminating '\"' character"; +} + 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..8299541 --- /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 TargetRegisterInfo::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/TargetInstrSpec.td b/test/TableGen/TargetInstrSpec.td new file mode 100644 index 0000000..7c3dd57 --- /dev/null +++ b/test/TableGen/TargetInstrSpec.td @@ -0,0 +1,97 @@ +// RUN: tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_pd VR128:\$src1, VR128:\$src2))\\\]} | count 1 +// RUN: tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_ps VR128:\$src1, VR128:\$src2))\\\]} | count 1 + +class ValueType<int size, int value> { + int Size = size; + int Value = value; +} + +def v2i64 : ValueType<128, 22>; // 2 x i64 vector value +def v2f64 : ValueType<128, 28>; // 2 x f64 vector value + +class Intrinsic<string name> { + string Name = name; +} + +class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, + list<dag> pattern> { + bits<8> Opcode = opcode; + dag OutOperands = oopnds; + dag InOperands = iopnds; + string AssemblyString = asmstr; + list<dag> Pattern = pattern; +} + +def ops; +def outs; +def ins; + +def set; + +// Define registers +class Register<string n> { + string Name = n; +} + +class RegisterClass<list<ValueType> regTypes, list<Register> regList> { + list<ValueType> RegTypes = regTypes; + list<Register> MemberList = regList; +} + +def XMM0: Register<"xmm0">; +def XMM1: Register<"xmm1">; +def XMM2: Register<"xmm2">; +def XMM3: Register<"xmm3">; +def XMM4: Register<"xmm4">; +def XMM5: Register<"xmm5">; +def XMM6: Register<"xmm6">; +def XMM7: Register<"xmm7">; +def XMM8: Register<"xmm8">; +def XMM9: Register<"xmm9">; +def XMM10: Register<"xmm10">; +def XMM11: Register<"xmm11">; +def XMM12: Register<"xmm12">; +def XMM13: Register<"xmm13">; +def XMM14: Register<"xmm14">; +def XMM15: Register<"xmm15">; + +def VR128 : RegisterClass<[v2i64, v2f64], + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, + XMM12, XMM13, XMM14, XMM15]>; + +// Dummy for subst +def REGCLASS : RegisterClass<[], []>; + +class decls { + // Dummy for foreach + dag pattern; + int operand; +} + +def Decls : decls; + +// Define intrinsics +def int_x86_sse2_add_ps : Intrinsic<"addps">; +def int_x86_sse2_add_pd : Intrinsic<"addpd">; +def INTRINSIC : Intrinsic<"Dummy">; + +multiclass arith<bits<8> opcode, string asmstr, string intr, list<dag> patterns> { + def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + !foreach(Decls.pattern, patterns, + !foreach(Decls.operand, Decls.pattern, + !subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", "_ps", intr)), + !subst(REGCLASS, VR128, Decls.operand))))>; + + def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + !foreach(Decls.pattern, patterns, + !foreach(Decls.operand, Decls.pattern, + !subst(INTRINSIC, !cast<Intrinsic>(!subst("SUFFIX", "_pd", intr)), + !subst(REGCLASS, VR128, Decls.operand))))>; +} + +defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX", + [(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))]>; + 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/UnsetBitInit.td b/test/TableGen/UnsetBitInit.td new file mode 100644 index 0000000..91342ec --- /dev/null +++ b/test/TableGen/UnsetBitInit.td @@ -0,0 +1,10 @@ +// RUN: tblgen %s +class x { + field bits<32> A; +} + +class y<bits<2> B> : x { + let A{21-20} = B; +} + +def z : y<{0,?}>; diff --git a/test/TableGen/UnterminatedComment.td b/test/TableGen/UnterminatedComment.td new file mode 100644 index 0000000..158cede --- /dev/null +++ b/test/TableGen/UnterminatedComment.td @@ -0,0 +1,6 @@ +// RUN: not tblgen < %s >& /dev/null + +def x; + +/* /* /* */ + diff --git a/test/TableGen/cast.td b/test/TableGen/cast.td new file mode 100644 index 0000000..4a771ae --- /dev/null +++ b/test/TableGen/cast.td @@ -0,0 +1,90 @@ +// RUN: tblgen %s | grep {add_ps} | count 3 + +class ValueType<int size, int value> { + int Size = size; + int Value = value; +} + +def v2i64 : ValueType<128, 22>; // 2 x i64 vector value +def v2f64 : ValueType<128, 28>; // 2 x f64 vector value + +class Intrinsic<string name> { + string Name = name; +} + +class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, + list<dag> pattern> { + bits<8> Opcode = opcode; + dag OutOperands = oopnds; + dag InOperands = iopnds; + string AssemblyString = asmstr; + list<dag> Pattern = pattern; +} + +def ops; +def outs; +def ins; + +def set; + +// Define registers +class Register<string n> { + string Name = n; +} + +class RegisterClass<list<ValueType> regTypes, list<Register> regList> { + list<ValueType> RegTypes = regTypes; + list<Register> MemberList = regList; +} + +def XMM0: Register<"xmm0">; +def XMM1: Register<"xmm1">; +def XMM2: Register<"xmm2">; +def XMM3: Register<"xmm3">; +def XMM4: Register<"xmm4">; +def XMM5: Register<"xmm5">; +def XMM6: Register<"xmm6">; +def XMM7: Register<"xmm7">; +def XMM8: Register<"xmm8">; +def XMM9: Register<"xmm9">; +def XMM10: Register<"xmm10">; +def XMM11: Register<"xmm11">; +def XMM12: Register<"xmm12">; +def XMM13: Register<"xmm13">; +def XMM14: Register<"xmm14">; +def XMM15: Register<"xmm15">; + +def VR128 : RegisterClass<[v2i64, v2f64], + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, + XMM12, XMM13, XMM14, XMM15]>; + +// Define intrinsics +def int_x86_sse2_add_ps : Intrinsic<"addps">; +def int_x86_sse2_add_pd : Intrinsic<"addpd">; + +multiclass arith<bits<8> opcode, string asmstr, string Intr> { + def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_ps")) VR128:$src1, VR128:$src2))]>; + + def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_pd")) VR128:$src1, VR128:$src2))]>; +} + +defm ADD : arith<0x58, "add", "int_x86_sse2_add">; + +class IntInst<bits<8> opcode, string asmstr, Intrinsic Intr> : + Inst<opcode,(outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (Intr VR128:$src1, VR128:$src2))]>; + + +multiclass arith_int<bits<8> opcode, string asmstr, string Intr> { + def PS_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_ps"))>; + + def PD_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_pd"))>; +} + +defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">; 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/eq.td b/test/TableGen/eq.td new file mode 100644 index 0000000..8ba6d7e --- /dev/null +++ b/test/TableGen/eq.td @@ -0,0 +1,13 @@ +// RUN: tblgen %s | FileCheck %s +// CHECK: Value = 0 +// CHECK: Value = 1 + +class Base<int V> { + int Value = V; +} + +class Derived<string Truth> : + Base<!if(!eq(Truth, "true"), 1, 0)>; + +def TRUE : Derived<"true">; +def FALSE : Derived<"false">; diff --git a/test/TableGen/foreach.td b/test/TableGen/foreach.td new file mode 100644 index 0000000..acce449 --- /dev/null +++ b/test/TableGen/foreach.td @@ -0,0 +1,31 @@ +// RUN: tblgen %s | grep {Jr} | count 2 +// RUN: tblgen %s | grep {Sr} | count 2 +// RUN: tblgen %s | grep {NAME} | count 1 + +// Variables for foreach +class decls { + string name; +} + +def Decls : decls; + +class A<list<string> names> { + list<string> Names = names; +} + +class B<list<string> names> : A<!foreach(Decls.name, names, !strconcat(Decls.name, ", Sr."))>; + +class C<list<string> names> : A<!foreach(Decls.name, names, !strconcat(Decls.name, ", Jr."))>; + +class D<list<string> names> : A<!foreach(Decls.name, names, !subst("NAME", "John Smith", Decls.name))>; + +class Names { + list<string> values = ["Ken Griffey", "Seymour Cray"]; +} + +def People : Names; + +def Seniors : B<People.values>; +def Juniors : C<People.values>; +def Smiths : D<["NAME", "Jane Smith"]>; +def Unprocessed : D<People.values>; diff --git a/test/TableGen/if.td b/test/TableGen/if.td new file mode 100644 index 0000000..9b24382 --- /dev/null +++ b/test/TableGen/if.td @@ -0,0 +1,20 @@ +// RUN: tblgen %s | grep {\\\[1, 2, 3\\\]} | count 4 +// RUN: tblgen %s | grep {\\\[4, 5, 6\\\]} | count 2 + +class A<list<list<int>> vals> { + list<int> first = vals[0]; + list<int> rest = !if(!null(!cdr(vals)), vals[0], vals[1]); +} + +def One : A<[[1,2,3]]>; +def Two : A<[[1,2,3],[4,5,6]]>; + +class B<list<int> v> { + list<int> vals = v; +} + +class BB<list<list<int>> vals> : B<!if(!null(!cdr(vals)), vals[0], vals[1])>; +class BBB<list<list<int>> vals> : BB<vals>; + +def OneB : BBB<[[1,2,3]]>; +def TwoB : BBB<[[1,2,3],[4,5,6]]>; diff --git a/test/TableGen/lisp.td b/test/TableGen/lisp.td new file mode 100644 index 0000000..3e392fd --- /dev/null +++ b/test/TableGen/lisp.td @@ -0,0 +1,21 @@ +// RUN: tblgen %s | grep {} + +class List<list<string> n> { + list<string> names = n; +} + +class CAR<string e> { + string element = e; +} + +class CDR<list<string> r, int n> { + list<string> rest = r; + int null = n; +} + +class NameList<list<string> Names> : + List<Names>, CAR<!car(Names)>, CDR<!cdr(Names), !null(!cdr(Names))>; + +def Three : NameList<["Tom", "Dick", "Harry"]>; + +def One : NameList<["Jeffrey Sinclair"]>; diff --git a/test/TableGen/nameconcat.td b/test/TableGen/nameconcat.td new file mode 100644 index 0000000..fc865f9 --- /dev/null +++ b/test/TableGen/nameconcat.td @@ -0,0 +1,90 @@ +// RUN: tblgen %s | grep {add_ps} | count 3 + +class ValueType<int size, int value> { + int Size = size; + int Value = value; +} + +def v2i64 : ValueType<128, 22>; // 2 x i64 vector value +def v2f64 : ValueType<128, 28>; // 2 x f64 vector value + +class Intrinsic<string name> { + string Name = name; +} + +class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, + list<dag> pattern> { + bits<8> Opcode = opcode; + dag OutOperands = oopnds; + dag InOperands = iopnds; + string AssemblyString = asmstr; + list<dag> Pattern = pattern; +} + +def ops; +def outs; +def ins; + +def set; + +// Define registers +class Register<string n> { + string Name = n; +} + +class RegisterClass<list<ValueType> regTypes, list<Register> regList> { + list<ValueType> RegTypes = regTypes; + list<Register> MemberList = regList; +} + +def XMM0: Register<"xmm0">; +def XMM1: Register<"xmm1">; +def XMM2: Register<"xmm2">; +def XMM3: Register<"xmm3">; +def XMM4: Register<"xmm4">; +def XMM5: Register<"xmm5">; +def XMM6: Register<"xmm6">; +def XMM7: Register<"xmm7">; +def XMM8: Register<"xmm8">; +def XMM9: Register<"xmm9">; +def XMM10: Register<"xmm10">; +def XMM11: Register<"xmm11">; +def XMM12: Register<"xmm12">; +def XMM13: Register<"xmm13">; +def XMM14: Register<"xmm14">; +def XMM15: Register<"xmm15">; + +def VR128 : RegisterClass<[v2i64, v2f64], + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, + XMM12, XMM13, XMM14, XMM15]>; + +// Define intrinsics +def int_x86_sse2_add_ps : Intrinsic<"addps">; +def int_x86_sse2_add_pd : Intrinsic<"addpd">; + +multiclass arith<bits<8> opcode, string asmstr, string Intr> { + def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (!nameconcat<Intrinsic>(Intr, "_ps") VR128:$src1, VR128:$src2))]>; + + def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (!nameconcat<Intrinsic>(Intr, "_pd") VR128:$src1, VR128:$src2))]>; +} + +defm ADD : arith<0x58, "add", "int_x86_sse2_add">; + +class IntInst<bits<8> opcode, string asmstr, Intrinsic Intr> : + Inst<opcode,(outs VR128:$dst), (ins VR128:$src1, VR128:$src2), + !strconcat(asmstr, "\t$dst, $src1, $src2"), + [(set VR128:$dst, (Intr VR128:$src1, VR128:$src2))]>; + + +multiclass arith_int<bits<8> opcode, string asmstr, string Intr> { + def PS_Int : IntInst<opcode, asmstr, !nameconcat<Intrinsic>(Intr, "_ps")>; + + def PD_Int : IntInst<opcode, asmstr, !nameconcat<Intrinsic>(Intr, "_pd")>; +} + +defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">; 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..fc0d805 --- /dev/null +++ b/test/TableGen/strconcat.td @@ -0,0 +1,10 @@ +// RUN: tblgen %s | grep fufoo + +class Y<string S> { + string T = !strconcat(S, "foo"); + + // String values concatenate lexically, as in C. + string S = "foo" "bar"; +} + +def Z : Y<"fu">; diff --git a/test/TableGen/subst.td b/test/TableGen/subst.td new file mode 100644 index 0000000..ce9f45d --- /dev/null +++ b/test/TableGen/subst.td @@ -0,0 +1,29 @@ +// RUN: tblgen %s | grep {Smith} | count 7 +// RUN: tblgen %s | grep {Johnson} | count 2 +// RUN: tblgen %s | grep {FIRST} | count 1 +// RUN: tblgen %s | grep {LAST} | count 1 +// RUN: tblgen %s | grep {TVAR} | count 2 +// RUN: tblgen %s | grep {Bogus} | count 1 + +class Honorific<string t> { + string honorific = t; +} + +def Mr : Honorific<"Mr.">; +def Ms : Honorific<"Ms.">; +def Mrs : Honorific<"Mrs.">; +def TVAR : Honorific<"Bogus">; + +class Name<string n, Honorific t> { + string name = n; + Honorific honorific = t; +} + +class AName<string name, Honorific honorific> : + Name<!subst("FIRST", "John", !subst("LAST", "Smith", name)), + !subst(TVAR, Mr, honorific)>; + +def JohnSmith : AName<"FIRST LAST", TVAR>; +def JaneSmith : AName<"Jane LAST", Ms>; +def JohnSmithJones : AName<"FIRST LAST-Jones", Mr>; +def JimmyJohnson : AName<"Jimmy Johnson", Mr>; diff --git a/test/TableGen/subst2.td b/test/TableGen/subst2.td new file mode 100644 index 0000000..3366c9d --- /dev/null +++ b/test/TableGen/subst2.td @@ -0,0 +1,15 @@ +// RUN: tblgen %s | FileCheck %s +// CHECK: No subst +// CHECK: No foo +// CHECK: RECURSE foo + +class Recurse<string t> { + string Text = t; +} + +class Text<string text> : + Recurse<!subst("RECURSE", "RECURSE", !subst("NORECURSE", "foo", text))>; + +def Ok1 : Text<"No subst">; +def Ok2 : Text<"No NORECURSE">; +def Trouble : Text<"RECURSE NORECURSE">; |