summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/MC/MCWin64EH.h56
-rw-r--r--llvm/include/llvm/MC/MCWinEH.h29
-rw-r--r--llvm/lib/MC/MCStreamer.cpp32
-rw-r--r--llvm/lib/MC/MCWin64EH.cpp13
4 files changed, 85 insertions, 45 deletions
diff --git a/llvm/include/llvm/MC/MCWin64EH.h b/llvm/include/llvm/MC/MCWin64EH.h
index 907b033f7e7..3df0d0ab8c4 100644
--- a/llvm/include/llvm/MC/MCWin64EH.h
+++ b/llvm/include/llvm/MC/MCWin64EH.h
@@ -15,8 +15,8 @@
#ifndef LLVM_MC_MCWIN64EH_H
#define LLVM_MC_MCWIN64EH_H
+#include "llvm/MC/MCWinEH.h"
#include "llvm/Support/Win64EH.h"
-#include <cassert>
#include <vector>
namespace llvm {
@@ -24,37 +24,35 @@ namespace llvm {
class MCStreamer;
class MCSymbol;
-struct MCWin64EHInstruction {
- typedef Win64EH::UnwindOpcodes OpType;
- const OpType Operation;
- const MCSymbol *Label;
- const unsigned Offset;
- const unsigned Register;
-
- MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg)
- : Operation(Op), Label(L), Offset(0), Register(Reg) {
- assert(Op == Win64EH::UOP_PushNonVol);
+namespace Win64EH {
+struct Instruction {
+ static WinEH::Instruction PushNonVol(MCSymbol *L, unsigned Reg) {
+ return WinEH::Instruction(Win64EH::UOP_PushNonVol, L, Reg, -1);
}
-
- MCWin64EHInstruction(MCSymbol *L, unsigned Size)
- : Operation(Size > 128 ? Win64EH::UOP_AllocLarge
- : Win64EH::UOP_AllocSmall),
- Label(L), Offset(Size), Register(-1) {}
-
- MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off)
- : Operation(Op), Label(L), Offset(Off), Register(Reg) {
- assert(Op == Win64EH::UOP_SetFPReg ||
- Op == Win64EH::UOP_SaveNonVol ||
- Op == Win64EH::UOP_SaveNonVolBig ||
- Op == Win64EH::UOP_SaveXMM128 ||
- Op == Win64EH::UOP_SaveXMM128Big);
+ static WinEH::Instruction Alloc(MCSymbol *L, unsigned Size) {
+ return WinEH::Instruction(Size > 128 ? UOP_AllocLarge : UOP_AllocSmall, L,
+ -1, Size);
}
-
- MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code)
- : Operation(Op), Label(L), Offset(Code ? 1 : 0), Register(-1) {
- assert(Op == Win64EH::UOP_PushMachFrame);
+ static WinEH::Instruction PushMachFrame(MCSymbol *L, bool Code) {
+ return WinEH::Instruction(UOP_PushMachFrame, L, -1, Code ? 1 : 0);
+ }
+ static WinEH::Instruction SaveNonVol(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveNonVolBig
+ : UOP_SaveNonVol,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SaveXMM(MCSymbol *L, unsigned Reg,
+ unsigned Offset) {
+ return WinEH::Instruction(Offset > 512 * 1024 - 8 ? UOP_SaveXMM128Big
+ : UOP_SaveXMM128,
+ L, Reg, Offset);
+ }
+ static WinEH::Instruction SetFPReg(MCSymbol *L, unsigned Reg, unsigned Off) {
+ return WinEH::Instruction(UOP_SetFPReg, L, Reg, Off);
}
};
+}
struct MCWinFrameInfo {
MCWinFrameInfo()
@@ -72,7 +70,7 @@ struct MCWin64EHInstruction {
bool HandlesExceptions;
int LastFrameInst;
MCWinFrameInfo *ChainedParent;
- std::vector<MCWin64EHInstruction> Instructions;
+ std::vector<WinEH::Instruction> Instructions;
};
class MCWin64EHUnwindEmitter {
diff --git a/llvm/include/llvm/MC/MCWinEH.h b/llvm/include/llvm/MC/MCWinEH.h
new file mode 100644
index 00000000000..1cd1b0f1b8c
--- /dev/null
+++ b/llvm/include/llvm/MC/MCWinEH.h
@@ -0,0 +1,29 @@
+//===- MCWinEH.h - Windows Unwinding Support --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCWINEH_H
+#define LLVM_MC_MCWINEH_H
+
+namespace llvm {
+class MCSymbol;
+
+namespace WinEH {
+struct Instruction {
+ const MCSymbol *Label;
+ const unsigned Offset;
+ const unsigned Register;
+ const unsigned Operation;
+
+ Instruction(unsigned Op, MCSymbol *L, unsigned Reg, unsigned Off)
+ : Label(L), Offset(Off), Register(Reg), Operation(Op) {}
+};
+}
+}
+
+#endif
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index c99fe93dcee..f3564027bf3 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
@@ -479,9 +480,11 @@ void MCStreamer::EmitWinEHHandlerData() {
void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
EnsureValidWinFrameInfo();
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register);
EmitLabel(Label);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
@@ -493,9 +496,12 @@ void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
report_fatal_error("Misaligned frame pointer offset!");
if (Offset > 240)
report_fatal_error("Frame offset must be less than or equal to 240!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset);
EmitLabel(Label);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SetFPReg(Label, Register, Offset);
CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
@@ -506,9 +512,11 @@ void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
report_fatal_error("Allocation size must be non-zero!");
if (Size & 7)
report_fatal_error("Misaligned stack allocation!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Label, Size);
EmitLabel(Label);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
@@ -516,11 +524,12 @@ void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
EnsureValidWinFrameInfo();
if (Offset & 7)
report_fatal_error("Misaligned saved register offset!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol,
- Label, Register, Offset);
EmitLabel(Label);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
@@ -528,11 +537,12 @@ void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
EnsureValidWinFrameInfo();
if (Offset & 0x0F)
report_fatal_error("Misaligned saved vector register offset!");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(
- Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128,
- Label, Register, Offset);
EmitLabel(Label);
+
+ WinEH::Instruction Inst =
+ Win64EH::Instruction::SaveXMM(Label, Register, Offset);
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
@@ -540,9 +550,11 @@ void MCStreamer::EmitWinCFIPushFrame(bool Code) {
EnsureValidWinFrameInfo();
if (CurrentWinFrameInfo->Instructions.size() > 0)
report_fatal_error("If present, PushMachFrame must be the first UOP");
+
MCSymbol *Label = getContext().CreateTempSymbol();
- MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code);
EmitLabel(Label);
+
+ WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
CurrentWinFrameInfo->Instructions.push_back(Inst);
}
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 4c0bf8c536d..95e19839372 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -15,15 +15,16 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Win64EH.h"
namespace llvm {
// NOTE: All relocations generated here are 4-byte image-relative.
-static uint8_t CountOfUnwindCodes(std::vector<MCWin64EHInstruction> &Insns) {
+static uint8_t CountOfUnwindCodes(std::vector<WinEH::Instruction> &Insns) {
uint8_t Count = 0;
for (const auto &I : Insns) {
- switch (I.Operation) {
+ switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
case Win64EH::UOP_PushNonVol:
case Win64EH::UOP_AllocSmall:
case Win64EH::UOP_SetFPReg:
@@ -56,11 +57,11 @@ static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
}
static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
- MCWin64EHInstruction &inst) {
+ WinEH::Instruction &inst) {
uint8_t b2;
uint16_t w;
b2 = (inst.Operation & 0x0F);
- switch (inst.Operation) {
+ switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
case Win64EH::UOP_PushNonVol:
EmitAbsDifference(streamer, inst.Label, begin);
b2 |= (inst.Register & 0x0F) << 4;
@@ -177,7 +178,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) {
uint8_t frame = 0;
if (info->LastFrameInst >= 0) {
- MCWin64EHInstruction &frameInst = info->Instructions[info->LastFrameInst];
+ WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst];
assert(frameInst.Operation == Win64EH::UOP_SetFPReg);
frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0);
}
@@ -186,7 +187,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWinFrameInfo *info) {
// Emit unwind instructions (in reverse order).
uint8_t numInst = info->Instructions.size();
for (uint8_t c = 0; c < numInst; ++c) {
- MCWin64EHInstruction inst = info->Instructions.back();
+ WinEH::Instruction inst = info->Instructions.back();
info->Instructions.pop_back();
EmitUnwindCode(streamer, info->Begin, inst);
}
OpenPOWER on IntegriCloud