@@ -3559,16 +3559,15 @@ class ARMOperand : public MCParsedAsmOperand {
3559
3559
Kind = k_SPRRegisterList;
3560
3560
}
3561
3561
3562
- // Sort based on the register encoding values.
3563
- array_pod_sort(Regs.begin(), Regs.end());
3564
-
3565
3562
if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
3566
3563
Kind = k_RegisterListWithAPSR;
3567
3564
3565
+ assert(std::is_sorted(Regs.begin(), Regs.end()) &&
3566
+ "Register list must be sorted by encoding");
3567
+
3568
3568
auto Op = make_unique<ARMOperand>(Kind);
3569
- for (SmallVectorImpl<std::pair<unsigned, unsigned>>::const_iterator
3570
- I = Regs.begin(), E = Regs.end(); I != E; ++I)
3571
- Op->Registers.push_back(I->second);
3569
+ for (const auto &P : Regs)
3570
+ Op->Registers.push_back(P.second);
3572
3571
3573
3572
Op->StartLoc = StartLoc;
3574
3573
Op->EndLoc = EndLoc;
@@ -4269,6 +4268,24 @@ static unsigned getNextRegister(unsigned Reg) {
4269
4268
}
4270
4269
}
4271
4270
4271
+ // Insert an <Encoding, Register> pair in an ordered vector. Return true on
4272
+ // success, or false, if duplicate encoding found.
4273
+ static bool
4274
+ insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
4275
+ unsigned Enc, unsigned Reg) {
4276
+ Regs.emplace_back(Enc, Reg);
4277
+ for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4278
+ if (J->first == Enc) {
4279
+ Regs.erase(J.base());
4280
+ return false;
4281
+ }
4282
+ if (J->first < Enc)
4283
+ break;
4284
+ std::swap(*I, *J);
4285
+ }
4286
+ return true;
4287
+ }
4288
+
4272
4289
/// Parse a register list.
4273
4290
bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4274
4291
bool EnforceOrder) {
@@ -4294,7 +4311,7 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4294
4311
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
4295
4312
Reg = getDRegFromQReg(Reg);
4296
4313
EReg = MRI->getEncodingValue(Reg);
4297
- Registers.push_back(std::pair<unsigned, unsigned>( EReg, Reg) );
4314
+ Registers.emplace_back( EReg, Reg);
4298
4315
++Reg;
4299
4316
}
4300
4317
const MCRegisterClass *RC;
@@ -4311,7 +4328,7 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4311
4328
4312
4329
// Store the register.
4313
4330
EReg = MRI->getEncodingValue(Reg);
4314
- Registers.push_back(std::pair<unsigned, unsigned>( EReg, Reg) );
4331
+ Registers.emplace_back( EReg, Reg);
4315
4332
4316
4333
// This starts immediately after the first register token in the list,
4317
4334
// so we can see either a comma or a minus (range separator) as a legal
@@ -4342,7 +4359,11 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4342
4359
while (Reg != EndReg) {
4343
4360
Reg = getNextRegister(Reg);
4344
4361
EReg = MRI->getEncodingValue(Reg);
4345
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
4362
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
4363
+ Warning(AfterMinusLoc, StringRef("duplicated register (") +
4364
+ ARMInstPrinter::getRegisterName(Reg) +
4365
+ ") in register list");
4366
+ }
4346
4367
}
4347
4368
continue;
4348
4369
}
@@ -4366,11 +4387,16 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4366
4387
// subset of GPRRegClassId except it contains APSR as well.
4367
4388
RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4368
4389
}
4369
- if (Reg == ARM::VPR && (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4370
- RC == &ARMMCRegisterClasses[ARM::DPRRegClassID])) {
4390
+ if (Reg == ARM::VPR &&
4391
+ (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4392
+ RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4393
+ RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
4371
4394
RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4372
4395
EReg = MRI->getEncodingValue(Reg);
4373
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
4396
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
4397
+ Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4398
+ ") in register list");
4399
+ }
4374
4400
continue;
4375
4401
}
4376
4402
// The register must be in the same register class as the first.
@@ -4387,21 +4413,19 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
4387
4413
else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
4388
4414
return Error(RegLoc, "register list not in ascending order");
4389
4415
}
4390
- if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
4391
- Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4392
- ") in register list");
4393
- continue;
4394
- }
4395
4416
// VFP register lists must also be contiguous.
4396
4417
if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
4397
4418
RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4398
4419
Reg != OldReg + 1)
4399
4420
return Error(RegLoc, "non-contiguous register range");
4400
4421
EReg = MRI->getEncodingValue(Reg);
4401
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
4422
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
4423
+ Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4424
+ ") in register list");
4425
+ }
4402
4426
if (isQReg) {
4403
4427
EReg = MRI->getEncodingValue(++Reg);
4404
- Registers.push_back(std::pair<unsigned, unsigned>( EReg, Reg) );
4428
+ Registers.emplace_back( EReg, Reg);
4405
4429
}
4406
4430
}
4407
4431
0 commit comments