@@ -694,7 +694,6 @@ class ARMAsmParser : public MCTargetAsmParser {
694
694
Match_RequiresThumb2,
695
695
Match_RequiresV8,
696
696
Match_RequiresFlagSetting,
697
- Match_RequiresDestinationRegisterMatchASourceRegister,
698
697
#define GET_OPERAND_DIAGNOSTIC_TYPES
699
698
#include " ARMGenAsmMatcher.inc"
700
699
@@ -6686,7 +6685,7 @@ bool operandsContainWide(OperandVector &Operands, unsigned MnemonicOpsEndInd) {
6686
6685
return true ;
6687
6686
}
6688
6687
return false ;
6689
- };
6688
+ }
6690
6689
6691
6690
// Some Thumb instructions have two operand forms that are not
6692
6691
// available as three operand, convert to two operand form if possible.
@@ -11071,8 +11070,10 @@ unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
11071
11070
case ARM::tMUL:
11072
11071
// The second source operand must be the same register as the destination
11073
11072
// operand.
11073
+ // FIXME: Ideally this would be handled by ARMGenAsmMatcher and
11074
+ // emitAsmTiedOperandConstraints.
11074
11075
if (Inst.getOperand (0 ).getReg () != Inst.getOperand (3 ).getReg ())
11075
- return Match_RequiresDestinationRegisterMatchASourceRegister ;
11076
+ return Match_InvalidTiedOperand ;
11076
11077
break ;
11077
11078
default :
11078
11079
break ;
@@ -12597,6 +12598,8 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12597
12598
SmallSet<FeatureBitset, 4 > FeatureMissesSeen;
12598
12599
bool ReportedTooFewOperands = false ;
12599
12600
12601
+ unsigned MnemonicOpsEndInd = getMnemonicOpsEndInd (Operands);
12602
+
12600
12603
// Process the near-misses in reverse order, so that we see more general ones
12601
12604
// first, and so can avoid emitting more specific ones.
12602
12605
for (NearMissInfo &I : reverse (NearMissesIn)) {
@@ -12705,9 +12708,16 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
12705
12708
case Match_RequiresFlagSetting:
12706
12709
Message.Message = " no flag-preserving variant of this instruction available" ;
12707
12710
break ;
12708
- case Match_RequiresDestinationRegisterMatchASourceRegister:
12709
- Message.Message = " destination register must match a source register" ;
12711
+ case Match_InvalidTiedOperand: {
12712
+ ARMOperand &Op = static_cast <ARMOperand &>(*Operands[0 ]);
12713
+ if (Op.isToken () && Op.getToken () == " mul" ) {
12714
+ Message.Message = " destination register must match a source register" ;
12715
+ Message.Loc = Operands[MnemonicOpsEndInd]->getStartLoc ();
12716
+ } else {
12717
+ llvm_unreachable (" Match_InvalidTiedOperand only used for tMUL." );
12718
+ }
12710
12719
break ;
12720
+ }
12711
12721
case Match_InvalidOperand:
12712
12722
Message.Message = " invalid operand for instruction" ;
12713
12723
break ;
@@ -12907,6 +12917,10 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
12907
12917
if (hasV8Ops () && Op.isReg () && Op.getReg () == ARM::SP)
12908
12918
return Match_Success;
12909
12919
return Match_rGPR;
12920
+ // Note: This mutates the operand which could cause issues for future
12921
+ // matches if this one fails later.
12922
+ // It would be better to do this in addVecList but as this doesn't have access
12923
+ // to MRI this isn't possible.
12910
12924
// If trying to match a VecListDPair with a Q register, convert Q to list.
12911
12925
case MCK_VecListDPair:
12912
12926
if (Op.isQReg () && !hasMVE ()) {
@@ -12917,6 +12931,7 @@ unsigned ARMAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
12917
12931
return Match_Success;
12918
12932
}
12919
12933
return Match_InvalidOperand;
12934
+ // Note: This mutates the operand (see above).
12920
12935
// If trying to match a VecListDPair with a D register, convert D singleton
12921
12936
// list.
12922
12937
case MCK_VecListOneD:
0 commit comments