llvm.org GIT mirror llvm / c7cafcd
Implement !nameconcat to concatenate strings and look up the resulting name in the symbol table, returning an object. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69822 91177308-0d34-0410-b5e6-96231b3b80d8 David Greene 10 years ago
8 changed file(s) with 192 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
397397
!strconcat(a, b)
398398
A string value that is the result of concatenating the 'a' and 'b'
399399 strings.
400
!nameconcat(a, b)
401
A value that is the result of concatenating the 'a' and 'b'
402 strings and looking up the resulting name in the symbol table. The symbol type
403 determines the type of the resulting value. If the symbol is not found,
404 TableGen emits an error and aborts.
400405
401406
402407

Note that all of the values have rules specifying how they convert to values

626631
627632

The name of the resultant definitions has the multidef fragment names

628633 appended to them, so this defines ADD_rr, ADD_ri,
629 SUB_rr, etc. Using a multiclass this way is exactly equivalent to
630 instantiating the classes multiple times yourself, e.g. by writing:

634 SUB_rr, etc. Using a multiclass this way is exactly
635 equivalent to instantiating the classes multiple times yourself,
636 e.g. by writing:

631637
632638
633639

                  
                
0 // RUN: tblgen %s | grep {add_ps} | count 2
1
2 class ValueType {
3 int Size = size;
4 int Value = value;
5 }
6
7 def v2i64 : ValueType<128, 22>; // 2 x i64 vector value
8 def v2f64 : ValueType<128, 28>; // 2 x f64 vector value
9
10 class Intrinsic {
11 string Name = name;
12 }
13
14 class Inst opcode, dag oopnds, dag iopnds, string asmstr,
15 list pattern> {
16 bits<8> Opcode = opcode;
17 dag OutOperands = oopnds;
18 dag InOperands = iopnds;
19 string AssemblyString = asmstr;
20 list Pattern = pattern;
21 }
22
23 def ops;
24 def outs;
25 def ins;
26
27 def set;
28
29 // Define registers
30 class Register {
31 string Name = n;
32 }
33
34 class RegisterClass regTypes, list regList> {
35 list RegTypes = regTypes;
36 list MemberList = regList;
37 }
38
39 def XMM0: Register<"xmm0">;
40 def XMM1: Register<"xmm1">;
41 def XMM2: Register<"xmm2">;
42 def XMM3: Register<"xmm3">;
43 def XMM4: Register<"xmm4">;
44 def XMM5: Register<"xmm5">;
45 def XMM6: Register<"xmm6">;
46 def XMM7: Register<"xmm7">;
47 def XMM8: Register<"xmm8">;
48 def XMM9: Register<"xmm9">;
49 def XMM10: Register<"xmm10">;
50 def XMM11: Register<"xmm11">;
51 def XMM12: Register<"xmm12">;
52 def XMM13: Register<"xmm13">;
53 def XMM14: Register<"xmm14">;
54 def XMM15: Register<"xmm15">;
55
56 def VR128 : RegisterClass<[v2i64, v2f64],
57 [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
58 XMM8, XMM9, XMM10, XMM11,
59 XMM12, XMM13, XMM14, XMM15]>;
60
61 // Define intrinsics
62 def int_x86_sse2_add_ps : Intrinsic<"addps">;
63 def int_x86_sse2_add_pd : Intrinsic<"addpd">;
64
65 multiclass arith opcode, string asmstr, string Intr> {
66 def PS : Inst
67 !strconcat(asmstr, "\t$dst, $src1, $src2"),
68 [(set VR128:$dst, (!nameconcat(Intr, "_ps") VR128:$src1, VR128:$src2))]>;
69
70 def PD : Inst
71 !strconcat(asmstr, "\t$dst, $src1, $src2"),
72 [(set VR128:$dst, (!nameconcat(Intr, "_pd") VR128:$src1, VR128:$src2))]>;
73 }
74
75 defm ADD : arith<0x58, "add", "int_x86_sse2_add">;
126126 OperandList.clear();
127127 return;
128128 }
129 DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold();
129 DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(R, 0);
130130
131131 unsigned MIOperandNo = 0;
132132 std::set OperandNames;
394394 return Result + "]";
395395 }
396396
397 Init *BinOpInit::Fold() {
397 Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
398398 switch (getOpcode()) {
399399 default: assert(0 && "Unknown binop");
400400 case CONCAT: {
436436 return new StringInit(LHSs->getValue() + RHSs->getValue());
437437 break;
438438 }
439 case NAMECONCAT: {
440 StringInit *LHSs = dynamic_cast(LHS);
441 StringInit *RHSs = dynamic_cast(RHS);
442 if (LHSs && RHSs) {
443 std::string Name(LHSs->getValue() + RHSs->getValue());
444
445 // From TGParser::ParseIDValue
446 if (CurRec) {
447 if (const RecordVal *RV = CurRec->getValue(Name))
448 return new VarInit(Name, RV->getType());
449
450 std::string TemplateArgName = CurRec->getName()+":"+Name;
451 if (CurRec->isTemplateArg(TemplateArgName)) {
452 const RecordVal *RV = CurRec->getValue(TemplateArgName);
453 assert(RV && "Template arg doesn't exist??");
454 return new VarInit(TemplateArgName, RV->getType());
455 }
456 }
457
458 if (CurMultiClass) {
459 std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
460 if (CurMultiClass->Rec.isTemplateArg(MCName)) {
461 const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
462 assert(RV && "Template arg doesn't exist??");
463 return new VarInit(MCName, RV->getType());
464 }
465 }
466
467 if (Record *D = Records.getDef(Name))
468 return new DefInit(D);
469
470 cerr << "Variable not defined: '" + Name + "'\n";
471 assert(0 && "Variable not found");
472 return 0;
473 }
474 break;
475 }
439476 case SHL:
440477 case SRA:
441478 case SRL: {
463500 Init *rhs = RHS->resolveReferences(R, RV);
464501
465502 if (LHS != lhs || RHS != rhs)
466 return (new BinOpInit(getOpcode(), lhs, rhs))->Fold();
467 return Fold();
503 return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(&R, 0);
504 return Fold(&R, 0);
468505 }
469506
470507 std::string BinOpInit::getAsString() const {
475512 case SRA: Result = "!sra"; break;
476513 case SRL: Result = "!srl"; break;
477514 case STRCONCAT: Result = "!strconcat"; break;
515 case NAMECONCAT: Result = "!nameconcat"; break;
478516 }
479517 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
480518 }
5252 // Other classes.
5353 class Record;
5454 class RecordVal;
55 class MultiClass;
5556
5657 //===----------------------------------------------------------------------===//
5758 // Type Classes
658659 ///
659660 class BinOpInit : public Init {
660661 public:
661 enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT };
662 enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
662663 private:
663664 BinaryOp Opc;
664665 Init *LHS, *RHS;
672673
673674 // Fold - If possible, fold this to a simpler init. Return this if not
674675 // possible to fold.
675 Init *Fold();
676 Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
676677
677678 virtual Init *convertInitializerTo(RecTy *Ty) {
678679 return Ty->convertValue(this);
11231124
11241125 std::ostream &operator<<(std::ostream &OS, const Record &R);
11251126
1127 struct MultiClass {
1128 Record Rec; // Placeholder for template args and Name.
1129 typedef std::vector RecordVector;
1130 RecordVector DefPrototypes;
1131
1132 MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
1133 };
1134
11261135 class RecordKeeper {
11271136 std::map Classes, Defs;
11281137 public:
428428 // Check to see which operator this is.
429429 unsigned Len = CurPtr-Start;
430430
431 if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat;
432 if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA;
433 if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL;
434 if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
435 if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat;
431 if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat;
432 if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA;
433 if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL;
434 if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
435 if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat;
436 if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
436437
437438 return ReturnError(Start-1, "Unknown operator");
438439 }
4444 MultiClass, String,
4545
4646 // !keywords.
47 XConcat, XSRA, XSRL, XSHL, XStrConcat,
48
47 XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat,
48
4949 // Integer value.
5050 IntVal,
5151
2222 //===----------------------------------------------------------------------===//
2323
2424 namespace llvm {
25 struct MultiClass {
26 Record Rec; // Placeholder for template args and Name.
27 typedef std::vector RecordVector;
28 RecordVector DefPrototypes;
29
30 MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
31 };
32
3325 struct SubClassReference {
3426 TGLoc RefLoc;
3527 Record *Rec;
776768 }
777769 case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
778770 Lex.Lex(); // eat the '('
779 if (Lex.getCode() != tgtok::Id) {
771 if (Lex.getCode() != tgtok::Id
772 && Lex.getCode() != tgtok::XNameConcat) {
780773 TokError("expected identifier in dag init");
781774 return 0;
782775 }
783776
784 Init *Operator = ParseIDValue(CurRec);
785 if (Operator == 0) return 0;
786
777 Init *Operator = 0;
778 if (Lex.getCode() == tgtok::Id) {
779 Operator = ParseIDValue(CurRec);
780 if (Operator == 0) return 0;
781 }
782 else {
783 BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT;
784
785 Lex.Lex(); // eat the operation
786 if (Lex.getCode() != tgtok::l_paren) {
787 TokError("expected '(' after binary operator");
788 return 0;
789 }
790 Lex.Lex(); // eat the '('
791
792 Init *LHS = ParseValue(CurRec);
793 if (LHS == 0) return 0;
794
795 if (Lex.getCode() != tgtok::comma) {
796 TokError("expected ',' in binary operator");
797 return 0;
798 }
799 Lex.Lex(); // eat the ','
800
801 Init *RHS = ParseValue(CurRec);
802 if (RHS == 0) return 0;
803
804 if (Lex.getCode() != tgtok::r_paren) {
805 TokError("expected ')' in binary operator");
806 return 0;
807 }
808 Lex.Lex(); // eat the ')'
809 Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
810 }
811
787812 // If the operator name is present, parse it.
788813 std::string OperatorName;
789814 if (Lex.getCode() == tgtok::colon) {
795820 Lex.Lex(); // eat the VarName.
796821 }
797822
798
799823 std::vector > DagArgs;
800824 if (Lex.getCode() != tgtok::r_paren) {
801825 DagArgs = ParseDagArgList(CurRec);
814838 case tgtok::XSRA:
815839 case tgtok::XSRL:
816840 case tgtok::XSHL:
817 case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')'
841 case tgtok::XStrConcat:
842 case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
818843 BinOpInit::BinaryOp Code;
819844 switch (Lex.getCode()) {
820845 default: assert(0 && "Unhandled code!");
821 case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
822 case tgtok::XSRA: Code = BinOpInit::SRA; break;
823 case tgtok::XSRL: Code = BinOpInit::SRL; break;
824 case tgtok::XSHL: Code = BinOpInit::SHL; break;
825 case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
846 case tgtok::XConcat: Code = BinOpInit::CONCAT; break;
847 case tgtok::XSRA: Code = BinOpInit::SRA; break;
848 case tgtok::XSRL: Code = BinOpInit::SRL; break;
849 case tgtok::XSHL: Code = BinOpInit::SHL; break;
850 case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
851 case tgtok::XNameConcat: Code = BinOpInit::NAMECONCAT; break;
826852 }
827853 Lex.Lex(); // eat the operation
828854 if (Lex.getCode() != tgtok::l_paren) {
830856 return 0;
831857 }
832858 Lex.Lex(); // eat the '('
833
859
834860 Init *LHS = ParseValue(CurRec);
835861 if (LHS == 0) return 0;
836862
848874 return 0;
849875 }
850876 Lex.Lex(); // eat the ')'
851 return (new BinOpInit(Code, LHS, RHS))->Fold();
877 return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
852878 }
853879 }
854880