@@ -6865,8 +6865,9 @@ static void applyMnemonicAliases(StringRef &Mnemonic,
6865
6865
const FeatureBitset &Features,
6866
6866
unsigned VariantID);
6867
6867
6868
- // The GNU assembler has aliases of ldrd and strd with the second register
6869
- // omitted. We don't have a way to do that in tablegen, so fix it up here.
6868
+ // The GNU assembler has aliases of ldrd, strd, ldrexd, strexd, ldaexd, and
6869
+ // stlexd with the second register omitted. We don't have a way to do that in
6870
+ // tablegen, so fix it up here.
6870
6871
//
6871
6872
// We have to be careful to not emit an invalid Rt2 here, because the rest of
6872
6873
// the assembly parser could then generate confusing diagnostics refering to
@@ -6876,13 +6877,19 @@ static void applyMnemonicAliases(StringRef &Mnemonic,
6876
6877
void ARMAsmParser::fixupGNULDRDAlias (StringRef Mnemonic,
6877
6878
OperandVector &Operands,
6878
6879
unsigned MnemonicOpsEndInd) {
6879
- if (Mnemonic != " ldrd" && Mnemonic != " strd" )
6880
+ if (Mnemonic != " ldrd" && Mnemonic != " strd" && Mnemonic != " ldrexd" &&
6881
+ Mnemonic != " strexd" && Mnemonic != " ldaexd" && Mnemonic != " stlexd" )
6880
6882
return ;
6881
- if (Operands.size () < MnemonicOpsEndInd + 2 )
6883
+
6884
+ unsigned IdX = Mnemonic == " strexd" || Mnemonic == " stlexd"
6885
+ ? MnemonicOpsEndInd + 1
6886
+ : MnemonicOpsEndInd;
6887
+
6888
+ if (Operands.size () < IdX + 2 )
6882
6889
return ;
6883
6890
6884
- ARMOperand &Op2 = static_cast <ARMOperand &>(*Operands[MnemonicOpsEndInd ]);
6885
- ARMOperand &Op3 = static_cast <ARMOperand &>(*Operands[MnemonicOpsEndInd + 1 ]);
6891
+ ARMOperand &Op2 = static_cast <ARMOperand &>(*Operands[IdX ]);
6892
+ ARMOperand &Op3 = static_cast <ARMOperand &>(*Operands[IdX + 1 ]);
6886
6893
6887
6894
if (!Op2.isReg ())
6888
6895
return ;
@@ -6907,7 +6914,7 @@ void ARMAsmParser::fixupGNULDRDAlias(StringRef Mnemonic,
6907
6914
return ;
6908
6915
6909
6916
Operands.insert (
6910
- Operands.begin () + MnemonicOpsEndInd + 1 ,
6917
+ Operands.begin () + IdX + 1 ,
6911
6918
ARMOperand::CreateReg (PairedReg, Op2.getStartLoc (), Op2.getEndLoc ()));
6912
6919
}
6913
6920
@@ -7336,6 +7343,9 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
7336
7343
static_cast <ARMOperand &>(*Operands[MnemonicOpsEndInd]).isImm ())
7337
7344
removeCondCode (Operands, MnemonicOpsEndInd);
7338
7345
7346
+ // GNU Assembler extension (compatibility).
7347
+ fixupGNULDRDAlias (Mnemonic, Operands, MnemonicOpsEndInd);
7348
+
7339
7349
// Adjust operands of ldrexd/strexd to MCK_GPRPair.
7340
7350
// ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
7341
7351
// a single GPRPair reg operand is used in the .td file to replace the two
@@ -7352,23 +7362,18 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
7352
7362
ARMOperand &Op2 = static_cast <ARMOperand &>(*Operands[Idx + 1 ]);
7353
7363
7354
7364
const MCRegisterClass &MRC = MRI->getRegClass (ARM::GPRRegClassID);
7355
- bool IsGNUAlias = !(Op2.isReg () && MRC.contains (Op2.getReg ()));
7356
7365
// Adjust only if Op1 is a GPR.
7357
7366
if (Op1.isReg () && MRC.contains (Op1.getReg ())) {
7358
7367
unsigned Reg1 = Op1.getReg ();
7359
7368
unsigned Rt = MRI->getEncodingValue (Reg1);
7369
+ unsigned Reg2 = Op2.getReg ();
7370
+ unsigned Rt2 = MRI->getEncodingValue (Reg2);
7371
+ // Rt2 must be Rt + 1.
7372
+ if (Rt + 1 != Rt2)
7373
+ return Error (Op2.getStartLoc (),
7374
+ IsLoad ? " destination operands must be sequential"
7375
+ : " source operands must be sequential" );
7360
7376
7361
- // Check we are not in the GNU alias case with only one of the register
7362
- // pair specified
7363
- if (!IsGNUAlias) {
7364
- unsigned Reg2 = Op2.getReg ();
7365
- unsigned Rt2 = MRI->getEncodingValue (Reg2);
7366
- // Rt2 must be Rt + 1.
7367
- if (Rt + 1 != Rt2)
7368
- return Error (Op2.getStartLoc (),
7369
- IsLoad ? " destination operands must be sequential"
7370
- : " source operands must be sequential" );
7371
- }
7372
7377
// Rt must be even
7373
7378
if (Rt & 1 )
7374
7379
return Error (
@@ -7378,17 +7383,13 @@ bool ARMAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
7378
7383
7379
7384
unsigned NewReg = MRI->getMatchingSuperReg (
7380
7385
Reg1, ARM::gsub_0, &(MRI->getRegClass (ARM::GPRPairRegClassID)));
7386
+
7381
7387
Operands[Idx] =
7382
7388
ARMOperand::CreateReg (NewReg, Op1.getStartLoc (), Op2.getEndLoc ());
7383
- // redundant operand only exists if not in GNU alias case
7384
- if (!IsGNUAlias)
7385
- Operands.erase (Operands.begin () + Idx + 1 );
7389
+ Operands.erase (Operands.begin () + Idx + 1 );
7386
7390
}
7387
7391
}
7388
7392
7389
- // GNU Assembler extension (compatibility).
7390
- fixupGNULDRDAlias (Mnemonic, Operands, MnemonicOpsEndInd);
7391
-
7392
7393
// FIXME: As said above, this is all a pretty gross hack. This instruction
7393
7394
// does not fit with other "subs" and tblgen.
7394
7395
// Adjust operands of B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction
0 commit comments