llvm.org GIT mirror llvm / c9cc57b
TableGen: Check the dynamic type of !cast<Rec>(string) Summary: The docs already claim that this happens, but so far it hasn't. As a consequence, existing TableGen files get this wrong a lot, but luckily the fixes are all reasonably straightforward. To make this work with all the existing forms of self-references (since the true type of a record is only built up over time), the lookup of self-references in !cast is delayed until the final resolving step. Change-Id: If5923a72a252ba2fbc81a889d59775df0ef31164 Reviewers: arsenm, craig.topper, tra, MartinO Subscribers: wdng, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D44475 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327849 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolai Haehnle 1 year, 7 months ago
8 changed file(s) with 159 addition(s) and 91 deletion(s). Raw diff Collapse all Expand all
787787
788788 // Fold - If possible, fold this to a simpler init. Return this if not
789789 // possible to fold.
790 Init *Fold(Record *CurRec) const;
790 Init *Fold(Record *CurRec, bool IsFinal = false) const;
791791
792792 Init *resolveReferences(Resolver &R) const override;
793793
14961496
14971497 /// If there are any field references that refer to fields
14981498 /// that have been filled in, we can propagate the values now.
1499 ///
1500 /// This is a final resolve: any error messages, e.g. due to undefined
1501 /// !cast references, are generated now.
14991502 void resolveReferences();
15001503
15011504 /// Apply the resolver to the name of the record as well as to the
17851788 /// Init::resolveReferences.
17861789 class Resolver {
17871790 Record *CurRec;
1791 bool IsFinal = false;
17881792
17891793 public:
17901794 explicit Resolver(Record *CurRec) : CurRec(CurRec) {}
18001804 // result in a ? (UnsetInit). This behavior is used to represent instruction
18011805 // encodings by keeping references to unset variables within a record.
18021806 virtual bool keepUnsetBits() const { return false; }
1807
1808 // Whether this is the final resolve step before adding a record to the
1809 // RecordKeeper. Error reporting during resolve and related constant folding
1810 // should only happen when this is true.
1811 bool isFinal() const { return IsFinal; }
1812
1813 void setFinal(bool Final) { IsFinal = Final; }
18031814 };
18041815
18051816 /// Resolve arbitrary mappings.
18601871 DenseSet Shadowed;
18611872
18621873 public:
1863 explicit ShadowResolver(Resolver &R) : Resolver(R.getCurrentRecord()), R(R) {}
1874 explicit ShadowResolver(Resolver &R)
1875 : Resolver(R.getCurrentRecord()), R(R) {
1876 setFinal(R.isFinal());
1877 }
18641878
18651879 void addShadow(Init *Key) { Shadowed.insert(Key); }
18661880
11311131
11321132 multiclass binary_atomic_op_ord {
11331133 def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
1134 (!castNode>(#NAME) node:$ptr, node:$val)> {
1134 (!castPatternOperator>(#NAME) node:$ptr, node:$val)> {
11351135 let IsAtomic = 1;
11361136 let IsAtomicOrderingMonotonic = 1;
11371137 }
11381138 def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
1139 (!castNode>(#NAME) node:$ptr, node:$val)> {
1139 (!castPatternOperator>(#NAME) node:$ptr, node:$val)> {
11401140 let IsAtomic = 1;
11411141 let IsAtomicOrderingAcquire = 1;
11421142 }
11431143 def #NAME#_release : PatFrag<(ops node:$ptr, node:$val),
1144 (!castNode>(#NAME) node:$ptr, node:$val)> {
1144 (!castPatternOperator>(#NAME) node:$ptr, node:$val)> {
11451145 let IsAtomic = 1;
11461146 let IsAtomicOrderingRelease = 1;
11471147 }
11481148 def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
1149 (!castNode>(#NAME) node:$ptr, node:$val)> {
1149 (!castPatternOperator>(#NAME) node:$ptr, node:$val)> {
11501150 let IsAtomic = 1;
11511151 let IsAtomicOrderingAcquireRelease = 1;
11521152 }
11531153 def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
1154 (!castNode>(#NAME) node:$ptr, node:$val)> {
1154 (!castPatternOperator>(#NAME) node:$ptr, node:$val)> {
11551155 let IsAtomic = 1;
11561156 let IsAtomicOrderingSequentiallyConsistent = 1;
11571157 }
11591159
11601160 multiclass ternary_atomic_op_ord {
11611161 def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1162 (!castNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
1162 (!castPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
11631163 let IsAtomic = 1;
11641164 let IsAtomicOrderingMonotonic = 1;
11651165 }
11661166 def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1167 (!castNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
1167 (!castPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
11681168 let IsAtomic = 1;
11691169 let IsAtomicOrderingAcquire = 1;
11701170 }
11711171 def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1172 (!castNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
1172 (!castPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
11731173 let IsAtomic = 1;
11741174 let IsAtomicOrderingRelease = 1;
11751175 }
11761176 def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1177 (!castNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
1177 (!castPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
11781178 let IsAtomic = 1;
11791179 let IsAtomicOrderingAcquireRelease = 1;
11801180 }
11811181 def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1182 (!castNode>(#NAME) node:$ptr, node:$cmp, node:$val)> {
1182 (!castPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
11831183 let IsAtomic = 1;
11841184 let IsAtomicOrderingSequentiallyConsistent = 1;
11851185 }
193193
194194 std::string RecordRecTy::getAsString() const {
195195 if (NumClasses == 1)
196 return getClasses()[0]->getName();
196 return getClasses()[0]->getNameInitAsString();
197197
198198 std::string Str = "{";
199199 bool First = true;
201201 if (!First)
202202 Str += ", ";
203203 First = false;
204 Str += R->getName();
204 Str += R->getNameInitAsString();
205205 }
206206 Str += "}";
207207 return Str;
699699 ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
700700 }
701701
702 Init *UnOpInit::Fold(Record *CurRec) const {
702 Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
703703 switch (getOpcode()) {
704704 case CAST:
705705 if (isa(getType())) {
714714 } else if (isa(getType())) {
715715 if (StringInit *Name = dyn_cast(LHS)) {
716716 assert(CurRec && "NULL pointer");
717 if (Record *D = (CurRec->getRecords()).getDef(Name->getValue()))
718 return DefInit::get(D);
719
720 PrintFatalError(CurRec->getLoc(),
721 Twine("Undefined reference to record: '") +
722 Name->getValue() + "'\n");
717 Record *D;
718
719 // Self-references are allowed, but their resolution is delayed until
720 // the final resolve to ensure that we get the correct type for them.
721 if (Name == CurRec->getNameInit()) {
722 if (!IsFinal)
723 break;
724 D = CurRec;
725 } else {
726 D = CurRec->getRecords().getDef(Name->getValue());
727 if (!D) {
728 if (IsFinal)
729 PrintFatalError(CurRec->getLoc(),
730 Twine("Undefined reference to record: '") +
731 Name->getValue() + "'\n");
732 break;
733 }
734 }
735
736 DefInit *DI = DefInit::get(D);
737 if (!DI->getType()->typeIsA(getType())) {
738 PrintFatalError(CurRec->getLoc(),
739 Twine("Expected type '") +
740 getType()->getAsString() + "', got '" +
741 DI->getType()->getAsString() + "' in: " +
742 getAsString() + "\n");
743 }
744 return DI;
723745 }
724746 }
725747
761783 Init *UnOpInit::resolveReferences(Resolver &R) const {
762784 Init *lhs = LHS->resolveReferences(R);
763785
764 if (LHS != lhs)
786 if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
765787 return (UnOpInit::get(getOpcode(), lhs, getType()))
766 ->Fold(R.getCurrentRecord());
788 ->Fold(R.getCurrentRecord(), R.isFinal());
767789 return const_cast(this);
768790 }
769791
19031925
19041926 void Record::resolveReferences() {
19051927 RecordResolver R(*this);
1928 R.setFinal(true);
19061929 resolveReferences(R);
19071930 }
19081931
59305930 multiclass SIMDThreeScalarHSTied opc, string asm,
59315931 SDPatternOperator OpNode = null_frag> {
59325932 def v1i32: BaseSIMDThreeScalarTied
5933 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5933 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
59345934 asm, []>;
59355935 def v1i16: BaseSIMDThreeScalarTied
5936 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5936 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
59375937 asm, []>;
59385938 }
59395939
87888788
87898789 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
87908790 class BaseSIMDLdR opcode, bit S, bits<2> size, string asm,
8791 Operand listtype>
8791 DAGOperand listtype>
87928792 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
87938793 (outs listtype:$Vt), (ins GPR64sp:$Rn),
87948794 []> {
88008800 }
88018801 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
88028802 class BaseSIMDLdRPost opcode, bit S, bits<2> size,
8803 string asm, Operand listtype, Operand GPR64pi>
8803 string asm, DAGOperand listtype, DAGOperand GPR64pi>
88048804 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
88058805 "$Rn = $wback",
88068806 (outs GPR64sp:$wback, listtype:$Vt),
88588858 multiclass SIMDLdR opcode, bit S, string asm, string Count,
88598859 int Offset1, int Offset2, int Offset4, int Offset8> {
88608860 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8861 !cast<Operand>("VecList" # Count # "8b")>;
8861 !cast<DAGOperand>("VecList" # Count # "8b")>;
88628862 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8863 !cast<Operand>("VecList" # Count #"16b")>;
8863 !cast<DAGOperand>("VecList" # Count #"16b")>;
88648864 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8865 !cast<Operand>("VecList" # Count #"4h")>;
8865 !cast<DAGOperand>("VecList" # Count #"4h")>;
88668866 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8867 !cast<Operand>("VecList" # Count #"8h")>;
8867 !cast<DAGOperand>("VecList" # Count #"8h")>;
88688868 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8869 !cast<Operand>("VecList" # Count #"2s")>;
8869 !cast<DAGOperand>("VecList" # Count #"2s")>;
88708870 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8871 !cast<Operand>("VecList" # Count #"4s")>;
8871 !cast<DAGOperand>("VecList" # Count #"4s")>;
88728872 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8873 !cast<Operand>("VecList" # Count #"1d")>;
8873 !cast<DAGOperand>("VecList" # Count #"1d")>;
88748874 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8875 !cast<Operand>("VecList" # Count #"2d")>;
8875 !cast<DAGOperand>("VecList" # Count #"2d")>;
88768876
88778877 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8878 !cast("VecList" # Count # "8b"),
8879 !cast<Operand>("GPR64pi" # Offset1)>;
8878 !cast<DAGOperand>("VecList" # Count # "8b"),
8879 !cast("GPR64pi" # Offset1)>;
88808880 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8881 !cast("VecList" # Count # "16b"),
8882 !cast<Operand>("GPR64pi" # Offset1)>;
8881 !cast<DAGOperand>("VecList" # Count # "16b"),
8882 !cast("GPR64pi" # Offset1)>;
88838883 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8884 !cast("VecList" # Count # "4h"),
8885 !cast<Operand>("GPR64pi" # Offset2)>;
8884 !cast<DAGOperand>("VecList" # Count # "4h"),
8885 !cast("GPR64pi" # Offset2)>;
88868886 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8887 !cast("VecList" # Count # "8h"),
8888 !cast<Operand>("GPR64pi" # Offset2)>;
8887 !cast<DAGOperand>("VecList" # Count # "8h"),
8888 !cast("GPR64pi" # Offset2)>;
88898889 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8890 !cast("VecList" # Count # "2s"),
8891 !cast<Operand>("GPR64pi" # Offset4)>;
8890 !cast<DAGOperand>("VecList" # Count # "2s"),
8891 !cast("GPR64pi" # Offset4)>;
88928892 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8893 !cast("VecList" # Count # "4s"),
8894 !cast<Operand>("GPR64pi" # Offset4)>;
8893 !cast<DAGOperand>("VecList" # Count # "4s"),
8894 !cast("GPR64pi" # Offset4)>;
88958895 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8896 !cast("VecList" # Count # "1d"),
8897 !cast<Operand>("GPR64pi" # Offset8)>;
8896 !cast<DAGOperand>("VecList" # Count # "1d"),
8897 !cast("GPR64pi" # Offset8)>;
88988898 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8899 !cast("VecList" # Count # "2d"),
8900 !cast<Operand>("GPR64pi" # Offset8)>;
8899 !cast<DAGOperand>("VecList" # Count # "2d"),
8900 !cast("GPR64pi" # Offset8)>;
89018901
89028902 defm : SIMDLdrAliases;
89038903 defm : SIMDLdrAliases;
92999299 let Predicates = [HasNEON, HasRDM] in {
93009300
93019301 class BaseSIMDThreeSameVectorTiedR0 size, bits<5> opcode,
9302 RegisterOperand regtype, string asm,
9302 RegisterOperand regtype, string asm,
93039303 string kind, list pattern>
9304 : BaseSIMDThreeSameVectorTied
9304 : BaseSIMDThreeSameVectorTied
93059305 pattern> {
93069306 }
93079307 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS opc, string asm,
93109310 [(set (v4i16 V64:$dst),
93119311 (Accum (v4i16 V64:$Rd),
93129312 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9313 (v4i16 V64:$Rm)))))]>;
9313 (v4i16 V64:$Rm)))))]>;
93149314 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
93159315 [(set (v8i16 V128:$dst),
93169316 (Accum (v8i16 V128:$Rd),
93749374 let Inst{21} = idx{0};
93759375 }
93769376
9377 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9377 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
93789378 // an intermediate EXTRACT_SUBREG would be untyped.
9379 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9379 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
93809380 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
93819381 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9382 (i32 (vector_extract
9382 (i32 (vector_extract
93839383 (v4i32 (insert_subvector
9384 (undef),
9385 (v2i32 (int_aarch64_neon_sqrdmulh
9384 (undef),
9385 (v2i32 (int_aarch64_neon_sqrdmulh
93869386 (v2i32 V64:$Rn),
9387 (v2i32 (AArch64duplane32
9387 (v2i32 (AArch64duplane32
93889388 (v4i32 V128:$Rm),
93899389 VectorIndexS:$idx)))),
93909390 (i32 0))),
93919391 (i64 0))))),
93929392 (EXTRACT_SUBREG
93939393 (v2i32 (!cast(NAME # v2i32_indexed)
9394 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9395 FPR32Op:$Rd,
9396 ssub)),
9394 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9395 FPR32Op:$Rd,
9396 ssub)),
93979397 V64:$Rn,
9398 V128:$Rm,
9398 V128:$Rm,
93999399 VectorIndexS:$idx)),
94009400 ssub)>;
94019401
94169416 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
94179417 // an intermediate EXTRACT_SUBREG would be untyped.
94189418 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9419 (i32 (vector_extract
9420 (v4i32 (int_aarch64_neon_sqrdmulh
9419 (i32 (vector_extract
9420 (v4i32 (int_aarch64_neon_sqrdmulh
94219421 (v4i32 V128:$Rn),
9422 (v4i32 (AArch64duplane32
9422 (v4i32 (AArch64duplane32
94239423 (v4i32 V128:$Rm),
94249424 VectorIndexS:$idx)))),
94259425 (i64 0))))),
94269426 (EXTRACT_SUBREG
94279427 (v4i32 (!cast(NAME # v4i32_indexed)
9428 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9429 FPR32Op:$Rd,
9430 ssub)),
9428 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9429 FPR32Op:$Rd,
9430 ssub)),
94319431 V128:$Rn,
9432 V128:$Rm,
9432 V128:$Rm,
94339433 VectorIndexS:$idx)),
94349434 ssub)>;
94359435
94369436 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
94379437 FPR16Op, FPR16Op, V128_lo,
9438 VectorIndexH, asm, ".h", "", "", ".h",
9438 VectorIndexH, asm, ".h", "", "", ".h",
94399439 []> {
94409440 bits<3> idx;
94419441 let Inst{11} = idx{2};
99299929 let Predicates = [HasLSE];
99309930 }
99319931
9932 multiclass LDOPregister opc, string op, bits<1> Acq, bits<1> Rel,
9932 multiclass LDOPregister opc, string op, bits<1> Acq, bits<1> Rel,
99339933 string order> {
99349934 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
99359935 def B : BaseLDOPregister;
99469946 let Predicates = [HasLSE] in
99479947 multiclass LDOPregister_patterns_ord_dag
99489948 string size, dag SrcRHS, dag DstRHS> {
9949 def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
9949 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
99509950 (!cast(inst # suffix) DstRHS, GPR64sp:$Rn)>;
9951 def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
9951 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
99529952 (!cast(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
9953 def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
9953 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
99549954 (!cast(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
9955 def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
9955 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
99569956 (!cast(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
9957 def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
9957 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
99589958 (!cast(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
99599959 }
99609960
99939993 let Predicates = [HasLSE] in
99949994 multiclass CASregister_patterns_ord_dag
99959995 string size, dag OLD, dag NEW> {
9996 def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
9996 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
99979997 (!cast(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
9998 def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
9998 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
99999999 (!cast(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10000 def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
10000 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
1000110001 (!cast(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10002 def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
10002 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
1000310003 (!cast(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10004 def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
10004 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
1000510005 (!cast(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
1000610006 }
1000710007
499499
500500 class SMRD_Pattern_ci : GCNPat <
501501 (smrd_load (SMRDImm32 i64:$sbase, i32:$offset)),
502 (vt (!cast<SM_Pseudo>(Instr#"_IMM_ci") $sbase, $offset, 0))> {
502 (vt (!cast<InstSI>(Instr#"_IMM_ci") $sbase, $offset, 0))> {
503503 let OtherPredicates = [isCIOnly];
504504 }
505505
114114 class BDMode
115115 : AddressingMode
116116 (ops !cast("ADDR"##bitsize),
117 !cast<Immediate>("disp"##dispsize##"imm"##bitsize))>;
117 !cast<Operand>("disp"##dispsize##"imm"##bitsize))>;
118118
119119 // An addressing mode with a base, displacement and index.
120120 class BDXMode
121121 : AddressingMode
122122 (ops !cast("ADDR"##bitsize),
123 !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
123 !cast<Operand>("disp"##dispsize##"imm"##bitsize),
124124 !cast("ADDR"##bitsize))>;
125125
126126 // A BDMode paired with an immediate length operand of LENSIZE bits.
129129 : AddressingMode
130130 "BDLAddr",
131131 (ops !cast("ADDR"##bitsize),
132 !cast("disp"##dispsize##"imm"##bitsize),
133 !cast<Immediate>("imm"##bitsize))>;
132 !cast<Operand>("disp"##dispsize##"imm"##bitsize),
133 !cast("imm"##bitsize))>;
134134
135135 // A BDMode paired with a register length operand.
136136 class BDRMode
137137 : AddressingMode
138138 (ops !cast("ADDR"##bitsize),
139 !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
139 !cast<Operand>("disp"##dispsize##"imm"##bitsize),
140140 !cast("GR"##bitsize))>;
141141
142142 // An addressing mode with a base, displacement and a vector index.
143143 class BDVMode
144144 : AddressOperand
145145 (ops !cast("ADDR"##bitsize),
146 !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
146 !cast<Operand>("disp"##dispsize##"imm"##bitsize),
147147 !cast("VR128"))>;
148148
149149 //===----------------------------------------------------------------------===//
99 B b = !cast(name);
1010 }
1111
12 // CHECK: error: Invalid value of type 'A' is found when setting 'b' of type 'B'
12 // CHECK: error: Expected type 'B', got 'A' in: !cast("A0")
1313 def Test : C<"A0">;
1313
1414 // CHECK: def C0 {
1515 // CHECK: dag q = (ops C0);
16 // CHECK: }
17
18 // CHECK: def D0 {
19 // CHECK: D d = D0;
20 // CHECK: }
21
22 // CHECK: def E0 {
23 // CHECK: E e = E0;
1624 // CHECK: }
1725
1826 def ops;
4149 }
4250
4351 def C0 : C<"C0">;
52
53 // Explore some unused corner cases.
54 //
55 // A self-reference within a class may seem icky, but it unavoidably falls out
56 // orthogonally of having forward class declarations and late resolve of self
57 // references.
58 class D {
59 D d = !cast(self);
60 }
61
62 def D0 : D<"D0">;
63
64 class E {
65 E e = x;
66 }
67
68 // Putting the !cast directly in the def should work as well: we shouldn't
69 // depend on implementation details of when exactly the record is looked up.
70 //
71 // Note the difference between !cast("E0") and plain E0: the latter wouldn't
72 // work here because E0 does not yet have E as a superclass while the template
73 // arguments are being parsed.
74 def E0 : E("E0")>;