aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/ARM/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp78
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h2
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h2
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h12
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h11
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h48
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp22
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp90
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp50
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h5
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp40
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp2
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp2
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp6
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp6
15 files changed, 213 insertions, 163 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index eb55a2b5e70b..6e2886a19292 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -25,15 +25,13 @@
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSectionELF.h"
-#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -445,6 +443,16 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool IsResolved, MCContext &Ctx,
const MCSubtargetInfo* STI) const {
unsigned Kind = Fixup.getKind();
+ int64_t Addend = Target.getConstant();
+
+ // For MOVW/MOVT Instructions, the fixup value must already be within a
+ // signed 16bit range.
+ if ((Kind == ARM::fixup_arm_movw_lo16 || Kind == ARM::fixup_arm_movt_hi16 ||
+ Kind == ARM::fixup_t2_movw_lo16 || Kind == ARM::fixup_t2_movt_hi16) &&
+ (Addend < minIntN(16) || Addend > maxIntN(16))) {
+ Ctx.reportError(Fixup.getLoc(), "Relocation Not In Range");
+ return 0;
+ }
// MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
// and .word relocations they put the Thumb bit into the addend if possible.
@@ -579,14 +587,36 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
case ARM::fixup_arm_uncondbl:
case ARM::fixup_arm_condbl:
case ARM::fixup_arm_blx:
+ // Check that the relocation value is legal.
+ Value -= 8;
+ if (!isInt<26>(Value)) {
+ Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
+ return 0;
+ }
+ // Alignment differs for blx. Because we are switching to thumb ISA, we use
+ // 16-bit alignment. Otherwise, use 32-bit.
+ if ((Kind == ARM::fixup_arm_blx && Value % 2 != 0) ||
+ (Kind != ARM::fixup_arm_blx && Value % 4 != 0)) {
+ Ctx.reportError(Fixup.getLoc(), "Relocation not aligned");
+ return 0;
+ }
+
// These values don't encode the low two bits since they're always zero.
// Offset by 8 just as above.
if (const MCSymbolRefExpr *SRE =
dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
if (SRE->getKind() == MCSymbolRefExpr::VK_TLSCALL)
return 0;
- return 0xffffff & ((Value - 8) >> 2);
+ return 0xffffff & (Value >> 2);
case ARM::fixup_t2_uncondbranch: {
+ if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
+ Value != 4) {
+ // MSVC link.exe and lld do not support this relocation type
+ // with a non-zero offset. ("Value" is offset by 4 at this point.)
+ Ctx.reportError(Fixup.getLoc(),
+ "cannot perform a PC-relative fixup with a non-zero "
+ "symbol offset");
+ }
Value = Value - 4;
if (!isInt<25>(Value)) {
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
@@ -637,6 +667,14 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
Ctx.reportError(Fixup.getLoc(), "Relocation out of range");
return 0;
}
+ if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
+ Value != 4) {
+ // MSVC link.exe and lld do not support this relocation type
+ // with a non-zero offset. ("Value" is offset by 4 at this point.)
+ Ctx.reportError(Fixup.getLoc(),
+ "cannot perform a PC-relative fixup with a non-zero "
+ "symbol offset");
+ }
// The value doesn't encode the low bit (always zero) and is offset by
// four. The 32-bit immediate value is encoded as
@@ -666,6 +704,14 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
Endian == llvm::endianness::little);
}
case ARM::fixup_arm_thumb_blx: {
+ if (STI->getTargetTriple().isOSBinFormatCOFF() && !IsResolved &&
+ Value != 4) {
+ // MSVC link.exe and lld do not support this relocation type
+ // with a non-zero offset. ("Value" is offset by 4 at this point.)
+ Ctx.reportError(Fixup.getLoc(),
+ "cannot perform a PC-relative fixup with a non-zero "
+ "symbol offset");
+ }
// The value doesn't encode the low two bits (always zero) and is offset by
// four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
// imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
@@ -909,7 +955,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
@@ -1146,7 +1192,7 @@ enum CompactUnwindEncodings {
/// instructions. If the CFI instructions describe a frame that cannot be
/// encoded in compact unwind, the method returns UNWIND_ARM_MODE_DWARF which
/// tells the runtime to fallback and unwind using dwarf.
-uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
+uint64_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
const MCDwarfFrameInfo *FI, const MCContext *Ctxt) const {
DEBUG_WITH_TYPE("compact-unwind", llvm::dbgs() << "generateCU()\n");
// Only armv7k uses CFI based unwinding.
@@ -1161,14 +1207,14 @@ uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
return CU::UNWIND_ARM_MODE_DWARF;
// Start off assuming CFA is at SP+0.
- unsigned CFARegister = ARM::SP;
+ MCRegister CFARegister = ARM::SP;
int CFARegisterOffset = 0;
// Mark savable registers as initially unsaved
- DenseMap<unsigned, int> RegOffsets;
+ DenseMap<MCRegister, int> RegOffsets;
int FloatRegCount = 0;
// Process each .cfi directive and build up compact unwind info.
for (const MCCFIInstruction &Inst : Instrs) {
- unsigned Reg;
+ MCRegister Reg;
switch (Inst.getOperation()) {
case MCCFIInstruction::OpDefCfa: // DW_CFA_def_cfa
CFARegisterOffset = Inst.getOffset();
@@ -1222,12 +1268,12 @@ uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
}
int StackAdjust = CFARegisterOffset - 8;
if (RegOffsets.lookup(ARM::LR) != (-4 - StackAdjust)) {
- DEBUG_WITH_TYPE("compact-unwind",
- llvm::dbgs()
- << "LR not saved as standard frame, StackAdjust="
- << StackAdjust
- << ", CFARegisterOffset=" << CFARegisterOffset
- << ", lr save at offset=" << RegOffsets[14] << "\n");
+ DEBUG_WITH_TYPE(
+ "compact-unwind",
+ llvm::dbgs() << "LR not saved as standard frame, StackAdjust="
+ << StackAdjust
+ << ", CFARegisterOffset=" << CFARegisterOffset
+ << ", lr save at offset=" << RegOffsets[ARM::LR] << "\n");
return CU::UNWIND_ARM_MODE_DWARF;
}
if (RegOffsets.lookup(ARM::R7) != (-8 - StackAdjust)) {
@@ -1308,7 +1354,7 @@ uint32_t ARMAsmBackendDarwin::generateCompactUnwindEncoding(
// Floating point registers must either be saved sequentially, or we defer to
// DWARF. No gaps allowed here so check that each saved d-register is
// precisely where it should be.
- static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
+ static MCPhysReg FPRCSRegs[] = {ARM::D8, ARM::D10, ARM::D12, ARM::D14};
for (int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
auto Offset = RegOffsets.find(FPRCSRegs[Idx]);
if (Offset == RegOffsets.end()) {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index f33cd8b7c242..2932e68cd98e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -36,7 +36,7 @@ public:
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
index ac0c9b101cae..9c958003ca75 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendDarwin.h
@@ -34,7 +34,7 @@ public:
/*Is64Bit=*/false, cantFail(MachO::getCPUType(TT)), Subtype);
}
- uint32_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
+ uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
const MCContext *Ctxt) const override;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h
index abbe73e336f5..17ae262c0826 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendELF.h
@@ -6,16 +6,14 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H
-#define LLVM_LIB_TARGET_ARM_ELFARMASMBACKEND_H
+#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ELFARMASMBACKEND_H
+#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ELFARMASMBACKEND_H
#include "ARMAsmBackend.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/MC/MCObjectWriter.h"
-using namespace llvm;
-
-namespace {
+namespace llvm {
class ARMAsmBackendELF : public ARMAsmBackend {
public:
uint8_t OSABI;
@@ -30,6 +28,6 @@ public:
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
};
-}
+} // namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ELFARMASMBACKEND_H
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h
index 86ce6efe662a..9b50fb7f0758 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackendWinCOFF.h
@@ -6,14 +6,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H
-#define LLVM_LIB_TARGET_ARM_ARMASMBACKENDWINCOFF_H
+#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMASMBACKENDWINCOFF_H
+#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMASMBACKENDWINCOFF_H
#include "ARMAsmBackend.h"
#include "llvm/MC/MCObjectWriter.h"
-using namespace llvm;
-namespace {
+namespace llvm {
class ARMAsmBackendWinCOFF : public ARMAsmBackend {
public:
ARMAsmBackendWinCOFF(const Target &T, bool isThumb)
@@ -23,6 +22,6 @@ public:
return createARMWinCOFFObjectWriter();
}
};
-}
+} // namespace llvm
-#endif
+#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMASMBACKENDWINCOFF_H
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
index 1e87085d7bf0..e56cb028c4e2 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
@@ -157,9 +157,9 @@ namespace ARM_ISB {
/// isARMLowRegister - Returns true if the register is a low register (r0-r7).
///
-static inline bool isARMLowRegister(unsigned Reg) {
+static inline bool isARMLowRegister(MCRegister Reg) {
using namespace ARM;
- switch (Reg) {
+ switch (Reg.id()) {
case R0: case R1: case R2: case R3:
case R4: case R5: case R6: case R7:
return true;
@@ -211,30 +211,30 @@ namespace ARMII {
inline static const char *AddrModeToString(AddrMode addrmode) {
switch (addrmode) {
- case AddrModeNone: return "AddrModeNone";
- case AddrMode1: return "AddrMode1";
- case AddrMode2: return "AddrMode2";
- case AddrMode3: return "AddrMode3";
- case AddrMode4: return "AddrMode4";
- case AddrMode5: return "AddrMode5";
- case AddrMode5FP16: return "AddrMode5FP16";
- case AddrMode6: return "AddrMode6";
- case AddrModeT1_1: return "AddrModeT1_1";
- case AddrModeT1_2: return "AddrModeT1_2";
- case AddrModeT1_4: return "AddrModeT1_4";
- case AddrModeT1_s: return "AddrModeT1_s";
- case AddrModeT2_i12: return "AddrModeT2_i12";
- case AddrModeT2_i8: return "AddrModeT2_i8";
+ case AddrModeNone: return "AddrModeNone";
+ case AddrMode1: return "AddrMode1";
+ case AddrMode2: return "AddrMode2";
+ case AddrMode3: return "AddrMode3";
+ case AddrMode4: return "AddrMode4";
+ case AddrMode5: return "AddrMode5";
+ case AddrMode5FP16: return "AddrMode5FP16";
+ case AddrMode6: return "AddrMode6";
+ case AddrModeT1_1: return "AddrModeT1_1";
+ case AddrModeT1_2: return "AddrModeT1_2";
+ case AddrModeT1_4: return "AddrModeT1_4";
+ case AddrModeT1_s: return "AddrModeT1_s";
+ case AddrModeT2_i12: return "AddrModeT2_i12";
+ case AddrModeT2_i8: return "AddrModeT2_i8";
case AddrModeT2_i8pos: return "AddrModeT2_i8pos";
case AddrModeT2_i8neg: return "AddrModeT2_i8neg";
- case AddrModeT2_so: return "AddrModeT2_so";
- case AddrModeT2_pc: return "AddrModeT2_pc";
- case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
- case AddrMode_i12: return "AddrMode_i12";
- case AddrModeT2_ldrex:return "AddrModeT2_ldrex";
- case AddrModeT2_i7s4: return "AddrModeT2_i7s4";
- case AddrModeT2_i7s2: return "AddrModeT2_i7s2";
- case AddrModeT2_i7: return "AddrModeT2_i7";
+ case AddrModeT2_so: return "AddrModeT2_so";
+ case AddrModeT2_pc: return "AddrModeT2_pc";
+ case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
+ case AddrMode_i12: return "AddrMode_i12";
+ case AddrModeT2_ldrex: return "AddrModeT2_ldrex";
+ case AddrModeT2_i7s4: return "AddrModeT2_i7s4";
+ case AddrModeT2_i7s2: return "AddrModeT2_i7s2";
+ case AddrModeT2_i7: return "AddrModeT2_i7";
}
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 50a59ce76763..ad7e27979dd9 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -18,7 +18,6 @@
#include "llvm/MC/MCValue.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
#include <cstdint>
using namespace llvm;
@@ -41,8 +40,6 @@ namespace {
bool needsRelocateWithSymbol(const MCValue &Val, const MCSymbol &Sym,
unsigned Type) const override;
-
- void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override;
};
} // end anonymous namespace
@@ -319,25 +316,6 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
}
}
-void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx,
- MCSectionELF &Sec) {
- // The mix of execute-only and non-execute-only at link time is
- // non-execute-only. To avoid the empty implicitly created .text
- // section from making the whole .text section non-execute-only, we
- // mark it execute-only if it is empty and there is at least one
- // execute-only section in the object.
- MCSectionELF *TextSection =
- static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
- bool IsExecOnly = Sec.getFlags() & ELF::SHF_ARM_PURECODE;
- if (IsExecOnly && !TextSection->hasInstructions()) {
- for (auto &F : *TextSection)
- if (auto *DF = dyn_cast<MCDataFragment>(&F))
- if (!DF->getContents().empty())
- return;
- TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE);
- }
-}
-
std::unique_ptr<MCObjectTargetWriter>
llvm::createARMELFObjectWriter(uint8_t OSABI) {
return std::make_unique<ARMELFObjectWriter>(OSABI);
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index 3182fecffecf..c528526382a2 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -27,12 +27,14 @@
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
@@ -48,10 +50,8 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
#include <cassert>
#include <climits>
-#include <cstddef>
#include <cstdint>
#include <string>
@@ -78,10 +78,11 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
void emitPersonality(const MCSymbol *Personality) override;
void emitPersonalityIndex(unsigned Index) override;
void emitHandlerData() override;
- void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
- void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
+ void emitSetFP(MCRegister FpReg, MCRegister SpReg,
+ int64_t Offset = 0) override;
+ void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
void emitPad(int64_t Offset) override;
- void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
bool isVector) override;
void emitUnwindRaw(int64_t Offset,
const SmallVectorImpl<uint8_t> &Opcodes) override;
@@ -137,7 +138,7 @@ void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
-void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
+void ARMTargetAsmStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
int64_t Offset) {
OS << "\t.setfp\t";
InstPrinter.printRegName(OS, FpReg);
@@ -148,7 +149,7 @@ void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
OS << '\n';
}
-void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
+void ARMTargetAsmStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
assert((Reg != ARM::SP && Reg != ARM::PC) &&
"the operand of .movsp cannot be either sp or pc");
@@ -163,8 +164,8 @@ void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
OS << "\t.pad\t#" << Offset << '\n';
}
-void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
- bool isVector) {
+void ARMTargetAsmStreamer::emitRegSave(
+ const SmallVectorImpl<MCRegister> &RegList, bool isVector) {
assert(RegList.size() && "RegList should not be empty");
if (isVector)
OS << "\t.vsave\t{";
@@ -399,10 +400,11 @@ private:
void emitPersonality(const MCSymbol *Personality) override;
void emitPersonalityIndex(unsigned Index) override;
void emitHandlerData() override;
- void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
- void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
+ void emitSetFP(MCRegister FpReg, MCRegister SpReg,
+ int64_t Offset = 0) override;
+ void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
void emitPad(int64_t Offset) override;
- void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+ void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
bool isVector) override;
void emitUnwindRaw(int64_t Offset,
const SmallVectorImpl<uint8_t> &Opcodes) override;
@@ -467,10 +469,10 @@ public:
void emitPersonality(const MCSymbol *Per);
void emitPersonalityIndex(unsigned index);
void emitHandlerData();
- void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
- void emitMovSP(unsigned Reg, int64_t Offset = 0);
+ void emitSetFP(MCRegister NewFpReg, MCRegister NewSpReg, int64_t Offset = 0);
+ void emitMovSP(MCRegister Reg, int64_t Offset = 0);
void emitPad(int64_t Offset);
- void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
+ void emitRegSave(const SmallVectorImpl<MCRegister> &RegList, bool isVector);
void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
SMLoc Loc) override {
@@ -670,8 +672,7 @@ private:
}
void EmitMappingSymbol(StringRef Name) {
- auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
- Name + "." + Twine(MappingSymbolCounter++)));
+ auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
emitLabel(Symbol);
Symbol->setType(ELF::STT_NOTYPE);
@@ -679,8 +680,7 @@ private:
}
void emitMappingSymbol(StringRef Name, MCDataFragment &F, uint64_t Offset) {
- auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
- Name + "." + Twine(MappingSymbolCounter++)));
+ auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
emitLabelAtPos(Symbol, SMLoc(), F, Offset);
Symbol->setType(ELF::STT_NOTYPE);
Symbol->setBinding(ELF::STB_LOCAL);
@@ -710,7 +710,6 @@ private:
bool IsThumb;
bool IsAndroid;
- int64_t MappingSymbolCounter = 0;
DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
LastMappingSymbols;
@@ -722,7 +721,7 @@ private:
MCSymbol *FnStart;
const MCSymbol *Personality;
unsigned PersonalityIndex;
- unsigned FPReg; // Frame pointer register
+ MCRegister FPReg; // Frame pointer register
int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
@@ -754,12 +753,12 @@ void ARMTargetELFStreamer::emitHandlerData() {
getStreamer().emitHandlerData();
}
-void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
+void ARMTargetELFStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
int64_t Offset) {
getStreamer().emitSetFP(FpReg, SpReg, Offset);
}
-void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
+void ARMTargetELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
getStreamer().emitMovSP(Reg, Offset);
}
@@ -767,8 +766,8 @@ void ARMTargetELFStreamer::emitPad(int64_t Offset) {
getStreamer().emitPad(Offset);
}
-void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
- bool isVector) {
+void ARMTargetELFStreamer::emitRegSave(
+ const SmallVectorImpl<MCRegister> &RegList, bool isVector) {
getStreamer().emitRegSave(RegList, isVector);
}
@@ -893,6 +892,7 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() {
case ARM::ArchKind::ARMV9_3A:
case ARM::ArchKind::ARMV9_4A:
case ARM::ArchKind::ARMV9_5A:
+ case ARM::ArchKind::ARMV9_6A:
S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
S.setAttributeItem(ARM_ISA_use, Allowed, false);
S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
@@ -993,6 +993,10 @@ void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
// uses the FP_ARMV8_D16 build attribute.
case ARM::FK_FPV5_SP_D16:
case ARM::FK_FPV5_D16:
+ // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
+ // FPU, but there are two different names for it depending on the CPU.
+ case ARM::FK_FP_ARMV8_FULLFP16_SP_D16:
+ case ARM::FK_FP_ARMV8_FULLFP16_D16:
S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8B,
/* OverwriteExisting= */ false);
break;
@@ -1115,13 +1119,31 @@ void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
void ARMTargetELFStreamer::finish() {
ARMTargetStreamer::finish();
finishAttributeSection();
+
+ // The mix of execute-only and non-execute-only at link time is
+ // non-execute-only. To avoid the empty implicitly created .text
+ // section from making the whole .text section non-execute-only, we
+ // mark it execute-only if it is empty and there is at least one
+ // execute-only section in the object.
+ MCContext &Ctx = getStreamer().getContext();
+ auto &Asm = getStreamer().getAssembler();
+ if (any_of(Asm, [](const MCSection &Sec) {
+ return cast<MCSectionELF>(Sec).getFlags() & ELF::SHF_ARM_PURECODE;
+ })) {
+ auto *Text =
+ static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
+ for (auto &F : *Text)
+ if (auto *DF = dyn_cast<MCDataFragment>(&F))
+ if (!DF->getContents().empty())
+ return;
+ Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);
+ }
}
void ARMELFStreamer::reset() {
MCTargetStreamer &TS = *getTargetStreamer();
ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
ATS.reset();
- MappingSymbolCounter = 0;
MCELFStreamer::reset();
LastMappingSymbols.clear();
LastEMSInfo.reset();
@@ -1352,7 +1374,7 @@ void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
PersonalityIndex = Index;
}
-void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
+void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,
int64_t Offset) {
assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
"the operand of .setfp directive should be either $sp or $fp");
@@ -1366,7 +1388,7 @@ void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
FPOffset += Offset;
}
-void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
+void ARMELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
assert((Reg != ARM::SP && Reg != ARM::PC) &&
"the operand of .movsp cannot be either sp or pc");
assert(FPReg == ARM::SP && "current FP must be SP");
@@ -1391,17 +1413,17 @@ void ARMELFStreamer::emitPad(int64_t Offset) {
static std::pair<unsigned, unsigned>
collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx,
- const SmallVectorImpl<unsigned> &RegList, bool IsVector,
+ const SmallVectorImpl<MCRegister> &RegList, bool IsVector,
uint32_t &Mask_) {
uint32_t Mask = 0;
unsigned Count = 0;
while (Idx > 0) {
- unsigned Reg = RegList[Idx - 1];
+ MCRegister Reg = RegList[Idx - 1];
if (Reg == ARM::RA_AUTH_CODE)
break;
- Reg = MRI.getEncodingValue(Reg);
- assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
- unsigned Bit = (1u << Reg);
+ unsigned RegEnc = MRI.getEncodingValue(Reg);
+ assert(RegEnc < (IsVector ? 32U : 16U) && "Register out of range");
+ unsigned Bit = (1u << RegEnc);
if ((Mask & Bit) == 0) {
Mask |= Bit;
++Count;
@@ -1413,7 +1435,7 @@ collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx,
return {Idx, Count};
}
-void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+void ARMELFStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
bool IsVector) {
uint32_t Mask;
unsigned Idx, Count;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
index 24e627cd9a4e..ac90095a20be 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.cpp
@@ -11,9 +11,9 @@
//===----------------------------------------------------------------------===//
#include "ARMInstPrinter.h"
-#include "Utils/ARMBaseInfo.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
+#include "Utils/ARMBaseInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
@@ -23,10 +23,8 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/SubtargetFeature.h"
-#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -50,7 +48,7 @@ static unsigned translateShiftImm(unsigned imm) {
}
static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
- unsigned ShImm, const ARMInstPrinter &printer) {
+ unsigned ShImm, ARMInstPrinter &printer) {
if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
return;
O << ", ";
@@ -81,7 +79,7 @@ bool ARMInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {
return false;
}
-void ARMInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
+void ARMInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
markup(OS, Markup::Register) << getRegisterName(Reg, DefaultAltIdx);
}
@@ -260,7 +258,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case ARM::tLDMIA: {
bool Writeback = true;
- unsigned BaseReg = MI->getOperand(0).getReg();
+ MCRegister BaseReg = MI->getOperand(0).getReg();
for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
if (MI->getOperand(i).getReg() == BaseReg)
Writeback = false;
@@ -291,7 +289,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case ARM::STLEXD: {
const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
- unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
+ MCRegister Reg = MI->getOperand(isStore ? 1 : 0).getReg();
if (MRC.contains(Reg)) {
MCInst NewMI;
MCOperand NewReg;
@@ -342,7 +340,7 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
- unsigned Reg = Op.getReg();
+ MCRegister Reg = Op.getReg();
printRegName(O, Reg);
} else if (Op.isImm()) {
markup(O, Markup::Immediate) << '#' << formatImm(Op.getImm());
@@ -767,7 +765,7 @@ void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNum);
- if (MO.getReg() == 0)
+ if (!MO.getReg())
O << "!";
else {
O << ", ";
@@ -851,7 +849,7 @@ void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- if (MI->getOpcode() != ARM::t2CLRM) {
+ if (MI->getOpcode() != ARM::t2CLRM && MI->getOpcode() != ARM::VSCCLRMS) {
assert(is_sorted(drop_begin(*MI, OpNum),
[&](const MCOperand &LHS, const MCOperand &RHS) {
return MRI.getEncodingValue(LHS.getReg()) <
@@ -871,7 +869,7 @@ void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
O << ", ";
printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
@@ -1141,7 +1139,7 @@ void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
WithMarkup ScopedMarkup = markup(O, Markup::Memory);
O << "[";
printRegName(O, MO1.getReg());
- if (unsigned RegNum = MO2.getReg()) {
+ if (MCRegister RegNum = MO2.getReg()) {
O << ", ";
printRegName(O, RegNum);
}
@@ -1208,7 +1206,7 @@ void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
const MCOperand &MO1 = MI->getOperand(OpNum);
const MCOperand &MO2 = MI->getOperand(OpNum + 1);
- unsigned Reg = MO1.getReg();
+ MCRegister Reg = MO1.getReg();
printRegName(O, Reg);
// Print the shift opc.
@@ -1490,9 +1488,9 @@ void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
- unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
- unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
+ MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
O << "{";
printRegName(O, Reg0);
O << ", ";
@@ -1503,9 +1501,9 @@ void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
- unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
- unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
+ MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
O << "{";
printRegName(O, Reg0);
O << ", ";
@@ -1558,9 +1556,9 @@ void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
- unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
- unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
+ MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
O << "{";
printRegName(O, Reg0);
O << "[], ";
@@ -1605,9 +1603,9 @@ void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
- unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
- unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
+ MCRegister Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
O << "{";
printRegName(O, Reg0);
O << "[], ";
@@ -1684,7 +1682,7 @@ template<unsigned NumRegs>
void ARMInstPrinter::printMVEVectorList(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
- unsigned Reg = MI->getOperand(OpNum).getReg();
+ MCRegister Reg = MI->getOperand(OpNum).getReg();
const char *Prefix = "{";
for (unsigned i = 0; i < NumRegs; i++) {
O << Prefix;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
index 494a644cf545..7b95b9580740 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
@@ -27,10 +27,11 @@ public:
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &O) override;
- void printRegName(raw_ostream &OS, MCRegister Reg) const override;
+ void printRegName(raw_ostream &OS, MCRegister Reg) override;
// Autogenerated by tblgen.
- std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
+ std::pair<const char *, uint64_t>
+ getMnemonic(const MCInst &MI) const override;
void printInstruction(const MCInst *MI, uint64_t Address,
const MCSubtargetInfo &STI, raw_ostream &O);
virtual bool printAliasInstr(const MCInst *MI, uint64_t Address,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 3f37acff292b..41d5d95a6424 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -32,9 +32,7 @@
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
-#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstdlib>
@@ -543,7 +541,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
if (MO.isReg()) {
- unsigned Reg = MO.getReg();
+ MCRegister Reg = MO.getReg();
unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
// In NEON, Q registers are encoded as 2x their register number,
@@ -555,7 +553,7 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
if (STI.hasFeature(ARM::HasMVEIntegerOps))
return RegNo;
- switch (Reg) {
+ switch (Reg.id()) {
default:
return RegNo;
case ARM::Q0: case ARM::Q1: case ARM::Q2: case ARM::Q3:
@@ -711,7 +709,7 @@ static bool HasConditionalBranch(const MCInst &MI) {
const MCOperand &MCOp1 = MI.getOperand(i);
const MCOperand &MCOp2 = MI.getOperand(i + 1);
if (MCOp1.isImm() && MCOp2.isReg() &&
- (MCOp2.getReg() == 0 || MCOp2.getReg() == ARM::CPSR)) {
+ (!MCOp2.getReg() || MCOp2.getReg() == ARM::CPSR)) {
if (ARMCC::CondCodes(MCOp1.getImm()) != ARMCC::AL)
return true;
}
@@ -1311,7 +1309,7 @@ getAddrMode2OffsetOpValue(const MCInst &MI, unsigned OpIdx,
const MCOperand &MO1 = MI.getOperand(OpIdx+1);
unsigned Imm = MO1.getImm();
bool isAdd = ARM_AM::getAM2Op(Imm) == ARM_AM::add;
- bool isReg = MO.getReg() != 0;
+ bool isReg = MO.getReg().isValid();
uint32_t Binary = ARM_AM::getAM2Offset(Imm);
// if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm12
if (isReg) {
@@ -1347,7 +1345,7 @@ getAddrMode3OffsetOpValue(const MCInst &MI, unsigned OpIdx,
const MCOperand &MO1 = MI.getOperand(OpIdx+1);
unsigned Imm = MO1.getImm();
bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
- bool isImm = MO.getReg() == 0;
+ bool isImm = !MO.getReg().isValid();
uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
// if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
if (!isImm)
@@ -1383,7 +1381,7 @@ getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
unsigned Rn = CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
unsigned Imm = MO2.getImm();
bool isAdd = ARM_AM::getAM3Op(Imm) == ARM_AM::add;
- bool isImm = MO1.getReg() == 0;
+ bool isImm = !MO1.getReg().isValid();
uint32_t Imm8 = ARM_AM::getAM3Offset(Imm);
// if reg +/- reg, Rm will be non-zero. Otherwise, we have reg +/- imm8
if (!isImm)
@@ -1537,7 +1535,7 @@ getSORegRegOpValue(const MCInst &MI, unsigned OpIdx,
// Encode the shift opcode.
unsigned SBits = 0;
- unsigned Rs = MO1.getReg();
+ MCRegister Rs = MO1.getReg();
if (Rs) {
// Set shift operand (bit[7:4]).
// LSL - 0001
@@ -1737,21 +1735,34 @@ getRegisterListOpValue(const MCInst &MI, unsigned Op,
//
// LDM/STM:
// {15-0} = Bitfield of GPRs.
- unsigned Reg = MI.getOperand(Op).getReg();
+ MCRegister Reg = MI.getOperand(Op).getReg();
bool SPRRegs = ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg);
bool DPRRegs = ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg);
unsigned Binary = 0;
- if (SPRRegs || DPRRegs) {
+ if (SPRRegs || DPRRegs || Reg == ARM::VPR) {
// VLDM/VSTM/VSCCLRM
unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg);
unsigned NumRegs = (MI.getNumOperands() - Op) & 0xff;
Binary |= (RegNo & 0x1f) << 8;
- // Ignore VPR
- if (MI.getOpcode() == ARM::VSCCLRMD || MI.getOpcode() == ARM::VSCCLRMS)
+ if (MI.getOpcode() == ARM::VSCCLRMD)
+ // Ignore VPR
--NumRegs;
+ else if (MI.getOpcode() == ARM::VSCCLRMS) {
+ // The register list can contain both S registers and D registers, with D
+ // registers counting as two registers. VPR doesn't count towards the
+ // number of registers.
+ NumRegs = 0;
+ for (unsigned I = Op, E = MI.getNumOperands(); I < E; ++I) {
+ Reg = MI.getOperand(I).getReg();
+ if (ARMMCRegisterClasses[ARM::SPRRegClassID].contains(Reg))
+ NumRegs += 1;
+ else if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg))
+ NumRegs += 2;
+ }
+ }
if (SPRRegs)
Binary |= NumRegs;
else
@@ -1851,7 +1862,8 @@ getAddrMode6OffsetOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(Op);
- if (MO.getReg() == 0) return 0x0D;
+ if (!MO.getReg())
+ return 0x0D;
return CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index cf4fc37f8455..01a271327049 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -111,7 +111,7 @@ static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
bool ListContainsPC = false, ListContainsLR = false;
for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
assert(MI.getOperand(OI).isReg() && "expected register");
- switch (MI.getOperand(OI).getReg()) {
+ switch (MI.getOperand(OI).getReg().id()) {
default:
break;
case ARM::LR:
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
index e4a2cce18a23..357654615e00 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
@@ -6,7 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMFixupKinds.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
#include "llvm/ADT/StringExtras.h"
@@ -16,7 +15,6 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCMachObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCValue.h"
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
index 1237e50c22fd..84a0fb44c9ac 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp
@@ -92,11 +92,11 @@ void ARMTargetStreamer::emitCantUnwind() {}
void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {}
void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) {}
void ARMTargetStreamer::emitHandlerData() {}
-void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
+void ARMTargetStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
int64_t Offset) {}
-void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {}
+void ARMTargetStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {}
void ARMTargetStreamer::emitPad(int64_t Offset) {}
-void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
+void ARMTargetStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
bool isVector) {}
void ARMTargetStreamer::emitUnwindRaw(int64_t StackOffset,
const SmallVectorImpl<uint8_t> &Opcodes) {
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
index c4427948d3b8..34d9e5a91063 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp
@@ -13,12 +13,10 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/MCWinCOFFObjectWriter.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -61,8 +59,8 @@ unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Ctx,
switch (FixupKind) {
default: {
- const MCFixupKindInfo &Info = MAB.getFixupKindInfo(Fixup.getKind());
- report_fatal_error(Twine("unsupported relocation type: ") + Info.Name);
+ Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
+ return COFF::IMAGE_REL_ARM_ABSOLUTE;
}
case FK_Data_4:
switch (Modifier) {