summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/MCTargetDesc
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2014-01-21 02:33:10 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2014-01-21 02:33:10 +0000
commitd9f086036a50a6b073b6a6c345531d8cc0299330 (patch)
treea4f28cbec15ccfb815a6d645ce764afb2c3e696e /llvm/lib/Target/ARM/MCTargetDesc
parent662f5c1a5a4c7895efc66a6584dc4ea9653dce9e (diff)
downloadbcm5719-llvm-d9f086036a50a6b073b6a6c345531d8cc0299330.tar.gz
bcm5719-llvm-d9f086036a50a6b073b6a6c345531d8cc0299330.zip
ARM IAS: add support for .unwind_raw directive
This implements the unwind_raw directive for the ARM IAS. The unwind_raw directive takes the form of a stack offset value followed by one or more bytes representing the opcodes to be emitted. The opcode emitted will interpreted as if it were assembled by the opcode assembler via the standard unwinding directives. Thanks to Logan Chien for an extra test! llvm-svn: 199707
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc')
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp26
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h6
2 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
index 82543a45f24..79d5619b764 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
@@ -123,6 +123,8 @@ class ARMTargetAsmStreamer : public ARMTargetStreamer {
virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
+ virtual void emitUnwindRaw(int64_t Offset,
+ const SmallVectorImpl<uint8_t> &Opcodes);
virtual void switchVendor(StringRef Vendor);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
@@ -242,6 +244,16 @@ void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
OS << "\t0x" << utohexstr(Inst) << "\n";
}
+void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
+ const SmallVectorImpl<uint8_t> &Opcodes) {
+ OS << "\t.unwind_raw " << Offset;
+ for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
+ OCE = Opcodes.end();
+ OCI != OCE; ++OCI)
+ OS << ", 0x" << utohexstr(*OCI);
+ OS << '\n';
+}
+
class ARMTargetELFStreamer : public ARMTargetStreamer {
private:
// This structure holds all attributes, accounting for
@@ -367,6 +379,8 @@ private:
virtual void emitPad(int64_t Offset);
virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
+ virtual void emitUnwindRaw(int64_t Offset,
+ const SmallVectorImpl<uint8_t> &Opcodes);
virtual void switchVendor(StringRef Vendor);
virtual void emitAttribute(unsigned Attribute, unsigned Value);
@@ -425,6 +439,7 @@ public:
void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
void emitPad(int64_t Offset);
void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
+ void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
virtual void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) {
@@ -637,6 +652,10 @@ void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector) {
getStreamer().emitRegSave(RegList, isVector);
}
+void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
+ const SmallVectorImpl<uint8_t> &Opcodes) {
+ getStreamer().emitUnwindRaw(Offset, Opcodes);
+}
void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
assert(!Vendor.empty() && "Vendor cannot be empty.");
@@ -1202,6 +1221,13 @@ void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
UnwindOpAsm.EmitRegSave(Mask);
}
+void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
+ const SmallVectorImpl<uint8_t> &Opcodes) {
+ FlushPendingOffset();
+ SPOffset = SPOffset - Offset;
+ UnwindOpAsm.EmitRaw(Opcodes);
+}
+
namespace llvm {
MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
index b7937535761..e2c44008144 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
@@ -61,6 +61,12 @@ public:
/// Emit unwind opcodes to add $sp with an offset.
void EmitSPOffset(int64_t Offset);
+ /// Emit unwind raw opcodes
+ void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
+ Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end());
+ OpBegins.push_back(OpBegins.back() + Opcodes.size());
+ }
+
/// Finalize the unwind opcode sequence for EmitBytes()
void Finalize(unsigned &PersonalityIndex,
SmallVectorImpl<uint8_t> &Result);
OpenPOWER on IntegriCloud