summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.cpp76
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/WinException.h3
2 files changed, 51 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 5661a378c30..56a8b844ca5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -418,7 +418,7 @@ invoke_ranges(WinEHFuncInfo &EHInfo, const MachineBasicBlock &MBB) {
/// imagerel32 LabelStart;
/// imagerel32 LabelEnd;
/// imagerel32 FilterOrFinally; // One means catch-all.
-/// imagerel32 LabelLPad; // Zero means __finally.
+/// imagerel32 ExceptOrNull; // Zero means __finally.
/// } Entries[NumEntries];
/// };
void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
@@ -469,39 +469,20 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
// If this invoke ends a previous one, emit all the actions for this
// state.
- if (LastEHState != -1) {
- assert(LastBeginLabel && LastEndLabel);
- for (int State = LastEHState; State != -1;) {
- SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
- const MCExpr *FilterOrFinally;
- const MCExpr *ExceptOrNull;
- auto *Handler = UME.Handler.get<MachineBasicBlock *>();
- if (UME.IsFinally) {
- FilterOrFinally =
- create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler));
- ExceptOrNull = MCConstantExpr::create(0, Ctx);
- } else {
- // For an except, the filter can be 1 (catch-all) or a function
- // label.
- FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
- : MCConstantExpr::create(1, Ctx);
- ExceptOrNull = create32bitRef(Handler->getSymbol());
- }
-
- OS.EmitValue(getLabelPlusOne(LastBeginLabel), 4);
- OS.EmitValue(getLabelPlusOne(LastEndLabel), 4);
- OS.EmitValue(FilterOrFinally, 4);
- OS.EmitValue(ExceptOrNull, 4);
-
- State = UME.ToState;
- }
- }
+ if (LastEHState != -1)
+ emitSEHActionsForRange(FuncInfo, LastBeginLabel, LastEndLabel,
+ LastEHState);
LastBeginLabel = I.BeginLabel;
LastEndLabel = I.EndLabel;
LastEHState = I.State;
}
}
+
+ if (LastEndLabel)
+ emitSEHActionsForRange(FuncInfo, LastBeginLabel, LastEndLabel,
+ LastEHState);
+
OS.EmitLabel(TableEnd);
return;
}
@@ -589,6 +570,45 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
}
}
+void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
+ MCSymbol *BeginLabel,
+ MCSymbol *EndLabel, int State) {
+ auto &OS = *Asm->OutStreamer;
+ MCContext &Ctx = Asm->OutContext;
+
+ assert(BeginLabel && EndLabel);
+ while (State != -1) {
+ // struct Entry {
+ // imagerel32 LabelStart;
+ // imagerel32 LabelEnd;
+ // imagerel32 FilterOrFinally; // One means catch-all.
+ // imagerel32 ExceptOrNull; // Zero means __finally.
+ // };
+ SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
+ const MCExpr *FilterOrFinally;
+ const MCExpr *ExceptOrNull;
+ auto *Handler = UME.Handler.get<MachineBasicBlock *>();
+ if (UME.IsFinally) {
+ FilterOrFinally = create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler));
+ ExceptOrNull = MCConstantExpr::create(0, Ctx);
+ } else {
+ // For an except, the filter can be 1 (catch-all) or a function
+ // label.
+ FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
+ : MCConstantExpr::create(1, Ctx);
+ ExceptOrNull = create32bitRef(Handler->getSymbol());
+ }
+
+ OS.EmitValue(getLabelPlusOne(BeginLabel), 4);
+ OS.EmitValue(getLabelPlusOne(EndLabel), 4);
+ OS.EmitValue(FilterOrFinally, 4);
+ OS.EmitValue(ExceptOrNull, 4);
+
+ assert(UME.ToState < State && "states should decrease");
+ State = UME.ToState;
+ }
+}
+
void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
const Function *F = MF->getFunction();
auto &OS = *Asm->OutStreamer;
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h
index 5c853349d2e..ded00d5cf39 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h
@@ -41,6 +41,9 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
void emitCSpecificHandlerTable(const MachineFunction *MF);
+ void emitSEHActionsForRange(WinEHFuncInfo &FuncInfo, MCSymbol *BeginLabel,
+ MCSymbol *EndLabel, int State);
+
/// Emit the EH table data for 32-bit and 64-bit functions using
/// the __CxxFrameHandler3 personality.
void emitCXXFrameHandler3Table(const MachineFunction *MF);
OpenPOWER on IntegriCloud