summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/MCTargetDesc
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2013-12-19 05:17:58 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2013-12-19 05:17:58 +0000
commit304512cf4042163cad99c895d11e5132546d02ea (patch)
tree0894cb273368feb77917d48a83a429f98af0de6a /lib/Target/ARM/MCTargetDesc
parent2ad4cf54ee097fe6bfdb2e6593bf3db1895951cd (diff)
downloadllvm-304512cf4042163cad99c895d11e5132546d02ea.tar.gz
llvm-304512cf4042163cad99c895d11e5132546d02ea.tar.bz2
llvm-304512cf4042163cad99c895d11e5132546d02ea.tar.xz
ARM IAS: support .inst directive
This adds support for the .inst directive. This is an ARM specific directive to indicate an instruction encoded as a constant expression. The major difference between .word, .short, or .byte and .inst is that the latter will be disassembled as an instruction since it does not get flagged as data. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/MCTargetDesc')
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index deab955640..2d2497895c 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -20,8 +20,10 @@
#include "ARMUnwindOp.h"
#include "ARMUnwindOpAsm.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
@@ -121,6 +123,7 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
virtual void emitArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
+ virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
public:
@@ -190,6 +193,13 @@ void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
void ARMTargetAsmStreamer::finishAttributeSection() {
}
+void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
+ OS << "\t.inst";
+ if (Suffix)
+ OS << "." << Suffix;
+ OS << "\t0x" << utohexstr(Inst) << "\n";
+}
+
class ARMTargetELFStreamer : public ARMTargetStreamer {
private:
// This structure holds all attributes, accounting for
@@ -295,6 +305,7 @@ private:
virtual void emitTextAttribute(unsigned Attribute, StringRef String);
virtual void emitArch(unsigned Arch);
virtual void emitFPU(unsigned FPU);
+ virtual void emitInst(uint32_t Inst, char Suffix = '\0');
virtual void finishAttributeSection();
size_t calculateContentSize() const;
@@ -367,6 +378,44 @@ public:
MCELFStreamer::EmitInstruction(Inst);
}
+ virtual void emitInst(uint32_t Inst, char Suffix) {
+ unsigned Size;
+ char Buffer[4];
+ const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
+
+ switch (Suffix) {
+ case '\0':
+ Size = 4;
+
+ assert(!IsThumb);
+ EmitARMMappingSymbol();
+ for (unsigned II = 0, IE = Size; II != IE; II++) {
+ const unsigned I = LittleEndian ? (Size - II - 1) : II;
+ Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
+ }
+
+ break;
+ case 'n':
+ case 'w':
+ Size = (Suffix == 'n' ? 2 : 4);
+
+ assert(IsThumb);
+ EmitThumbMappingSymbol();
+ for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
+ const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
+ const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
+ Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
+ Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
+ }
+
+ break;
+ default:
+ llvm_unreachable("Invalid Suffix");
+ }
+
+ MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
+ }
+
/// This is one of the functions used to emit data into an ELF section, so the
/// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
/// necessary.
@@ -791,6 +840,9 @@ void ARMTargetELFStreamer::finishAttributeSection() {
Contents.clear();
FPU = ARM::INVALID_FPU;
}
+void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
+ getStreamer().emitInst(Inst, Suffix);
+}
void ARMELFStreamer::FinishImpl() {
MCTargetStreamer &TS = getTargetStreamer();