}
bool validatetLDMRegList(MCInst Inst, const OperandVector &Operands,
- unsigned ListNo, bool IsPop = false);
+ unsigned ListNo, bool IsARPop = false);
bool validatetSTMRegList(MCInst Inst, const OperandVector &Operands,
unsigned ListNo);
if (!CE) return false;
int64_t Value = CE->getValue();
return (ARM_AM::getSOImmVal(Value) != -1 ||
- ARM_AM::getSOImmVal(~Value) != -1);;
+ ARM_AM::getSOImmVal(-Value) != -1);;
}
bool isT2SOImm() const {
if (!isImm()) return false;
return true;
}
+ enum {
+ COFF = (1 << MCObjectFileInfo::IsCOFF),
+ ELF = (1 << MCObjectFileInfo::IsELF),
+ MACHO = (1 << MCObjectFileInfo::IsMachO)
+ };
+ static const struct PrefixEntry {
+ const char *Spelling;
+ ARMMCExpr::VariantKind VariantKind;
+ uint8_t SupportedFormats;
+ } PrefixEntries[] = {
+ { "lower16", ARMMCExpr::VK_ARM_LO16, COFF | ELF | MACHO },
+ { "upper16", ARMMCExpr::VK_ARM_HI16, COFF | ELF | MACHO },
+ };
+
StringRef IDVal = Parser.getTok().getIdentifier();
- if (IDVal == "lower16") {
- RefKind = ARMMCExpr::VK_ARM_LO16;
- } else if (IDVal == "upper16") {
- RefKind = ARMMCExpr::VK_ARM_HI16;
- } else {
+
+ const auto &Prefix =
+ std::find_if(std::begin(PrefixEntries), std::end(PrefixEntries),
+ [&IDVal](const PrefixEntry &PE) {
+ return PE.Spelling == IDVal;
+ });
+ if (Prefix == std::end(PrefixEntries)) {
Error(Parser.getTok().getLoc(), "unexpected prefix in operand");
return true;
}
+
+ uint8_t CurrentFormat;
+ switch (getContext().getObjectFileInfo()->getObjectFileType()) {
+ case MCObjectFileInfo::IsMachO:
+ CurrentFormat = MACHO;
+ break;
+ case MCObjectFileInfo::IsELF:
+ CurrentFormat = ELF;
+ break;
+ case MCObjectFileInfo::IsCOFF:
+ CurrentFormat = COFF;
+ break;
+ }
+
+ if (~Prefix->SupportedFormats & CurrentFormat) {
+ Error(Parser.getTok().getLoc(),
+ "cannot represent relocation in the current file format");
+ return true;
+ }
+
+ RefKind = Prefix->VariantKind;
Parser.Lex();
if (getLexer().isNot(AsmToken::Colon)) {
return true;
}
Parser.Lex(); // Eat the last ':'
+
return false;
}
bool ARMAsmParser::validatetLDMRegList(MCInst Inst,
const OperandVector &Operands,
- unsigned ListNo, bool IsPop) {
+ unsigned ListNo, bool IsARPop) {
const ARMOperand &Op = static_cast<const ARMOperand &>(*Operands[ListNo]);
bool HasWritebackToken = Op.isToken() && Op.getToken() == "!";
bool ListContainsLR = listContainsReg(Inst, ListNo, ARM::LR);
bool ListContainsPC = listContainsReg(Inst, ListNo, ARM::PC);
- if (!IsPop && ListContainsSP)
+ if (!IsARPop && ListContainsSP)
return Error(Operands[ListNo + HasWritebackToken]->getStartLoc(),
"SP may not be in the register list");
else if (ListContainsPC && ListContainsLR)
!isThumbTwo())
return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or pc");
- if (validatetLDMRegList(Inst, Operands, 2, /*IsPop=*/true))
+ if (validatetLDMRegList(Inst, Operands, 2, !isMClass()))
return true;
break;
}
// FIXME: This is duplicated in getARMFPUFeatures() in
// tools/clang/lib/Driver/Tools.cpp
static const struct {
- const unsigned Fpu;
+ const unsigned ID;
const uint64_t Enabled;
const uint64_t Disabled;
-} Fpus[] = {
- {ARM::VFP, ARM::FeatureVFP2, ARM::FeatureNEON},
- {ARM::VFPV2, ARM::FeatureVFP2, ARM::FeatureNEON},
- {ARM::VFPV3, ARM::FeatureVFP3, ARM::FeatureNEON},
- {ARM::VFPV3_D16, ARM::FeatureVFP3 | ARM::FeatureD16, ARM::FeatureNEON},
- {ARM::VFPV4, ARM::FeatureVFP4, ARM::FeatureNEON},
- {ARM::VFPV4_D16, ARM::FeatureVFP4 | ARM::FeatureD16, ARM::FeatureNEON},
- {ARM::FPV5_D16, ARM::FeatureFPARMv8 | ARM::FeatureD16,
- ARM::FeatureNEON | ARM::FeatureCrypto},
- {ARM::FP_ARMV8, ARM::FeatureFPARMv8,
- ARM::FeatureNEON | ARM::FeatureCrypto},
- {ARM::NEON, ARM::FeatureNEON, 0},
- {ARM::NEON_VFPV4, ARM::FeatureVFP4 | ARM::FeatureNEON, 0},
- {ARM::NEON_FP_ARMV8, ARM::FeatureFPARMv8 | ARM::FeatureNEON,
- ARM::FeatureCrypto},
- {ARM::CRYPTO_NEON_FP_ARMV8,
- ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto, 0},
- {ARM::SOFTVFP, 0, 0},
+} FPUs[] = {
+ {ARM::VFP, ARM::FeatureVFP2, ARM::FeatureNEON},
+ {ARM::VFPV2, ARM::FeatureVFP2, ARM::FeatureNEON},
+ {ARM::VFPV3, ARM::FeatureVFP2 | ARM::FeatureVFP3, ARM::FeatureNEON},
+ {ARM::VFPV3_D16, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureD16,
+ ARM::FeatureNEON},
+ {ARM::VFPV4, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4,
+ ARM::FeatureNEON},
+ {ARM::VFPV4_D16,
+ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | ARM::FeatureD16,
+ ARM::FeatureNEON},
+ {ARM::FPV5_D16, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
+ ARM::FeatureFPARMv8 | ARM::FeatureD16,
+ ARM::FeatureNEON | ARM::FeatureCrypto},
+ {ARM::FP_ARMV8, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
+ ARM::FeatureFPARMv8,
+ ARM::FeatureNEON | ARM::FeatureCrypto},
+ {ARM::NEON, ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureNEON, 0},
+ {ARM::NEON_VFPV4,
+ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 | ARM::FeatureNEON,
+ 0},
+ {ARM::NEON_FP_ARMV8,
+ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
+ ARM::FeatureFPARMv8 | ARM::FeatureNEON,
+ ARM::FeatureCrypto},
+ {ARM::CRYPTO_NEON_FP_ARMV8,
+ ARM::FeatureVFP2 | ARM::FeatureVFP3 | ARM::FeatureVFP4 |
+ ARM::FeatureFPARMv8 | ARM::FeatureNEON | ARM::FeatureCrypto,
+ 0},
+ {ARM::SOFTVFP, 0, 0},
};
/// parseDirectiveFPU
return false;
}
- for (const auto &Fpu : Fpus) {
- if (Fpu.Fpu != ID)
+ for (const auto &Entry : FPUs) {
+ if (Entry.ID != ID)
continue;
// Need to toggle features that should be on but are off and that
// should off but are on.
- uint64_t Toggle = (Fpu.Enabled & ~STI.getFeatureBits()) |
- (Fpu.Disabled & STI.getFeatureBits());
+ uint64_t Toggle = (Entry.Enabled & ~STI.getFeatureBits()) |
+ (Entry.Disabled & STI.getFeatureBits());
setAvailableFeatures(ComputeAvailableFeatures(STI.ToggleFeature(Toggle)));
break;
}