From 925eab3fd73322f04c27560a8817b10ced91ddac Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Thu, 19 May 2011 19:35:55 +0000 Subject: [PATCH] Implement the Win64 EH prolog instruction methods on the base MCStreamer. I had to change the API slightly to avoid overloading issues. llvm-svn: 131666 --- include/llvm/MC/MCStreamer.h | 10 ++++---- include/llvm/MC/MCWin64EH.h | 22 +++++++--------- lib/MC/MCAsmStreamer.cpp | 20 +++++++-------- lib/MC/MCStreamer.cpp | 50 ++++++++++++++++++++++++------------ 4 files changed, 57 insertions(+), 45 deletions(-) diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index b5e99305e02..c19e9b8c97f 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -470,11 +470,11 @@ namespace llvm { virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, bool Except); virtual void EmitWin64EHHandlerData(); - virtual void EmitWin64EHPushReg(int64_t Register); - virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); - virtual void EmitWin64EHAllocStack(int64_t Size); - virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); - virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset); + virtual void EmitWin64EHPushReg(unsigned Register); + virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); + virtual void EmitWin64EHAllocStack(unsigned Size); + virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); + virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); virtual void EmitWin64EHPushFrame(bool Code); virtual void EmitWin64EHEndProlog(); diff --git a/include/llvm/MC/MCWin64EH.h b/include/llvm/MC/MCWin64EH.h index 4c6d91972ed..cc3bc6e1a62 100644 --- a/include/llvm/MC/MCWin64EH.h +++ b/include/llvm/MC/MCWin64EH.h @@ -15,7 +15,6 @@ #ifndef LLVM_MC_MCWIN64EH_H #define LLVM_MC_MCWIN64EH_H -#include "llvm/CodeGen/MachineLocation.h" // FIXME #include "llvm/Support/Win64EH.h" #include @@ -29,22 +28,20 @@ namespace llvm { private: OpType Operation; unsigned Offset; - MachineLocation Destination; - MachineLocation Source; + unsigned Register; public: - MCWin64EHInstruction(OpType Op, unsigned Register) - : Operation(Op), Offset(0), Destination(0), Source(Register) { + MCWin64EHInstruction(OpType Op, unsigned Reg) + : Operation(Op), Offset(0), Register(Reg) { assert(Op == Win64EH::UOP_PushNonVol); } MCWin64EHInstruction(unsigned Size) : Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall), Offset(Size) { } - MCWin64EHInstruction(unsigned Register, unsigned Off) - : Operation(Win64EH::UOP_SetFPReg), Offset(Off), Destination(Register) { } - MCWin64EHInstruction(OpType Op, const MachineLocation &D, - unsigned S) - : Operation(Op), Destination(D), Source(S) { - assert(Op == Win64EH::UOP_SaveNonVol || + MCWin64EHInstruction(OpType Op, unsigned Reg, + unsigned Off) + : Operation(Op), 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); @@ -56,9 +53,8 @@ namespace llvm { OpType getOperation() const { return Operation; } unsigned getOffset() const { return Offset; } unsigned getSize() const { return Offset; } + unsigned getRegister() const { return Register; } bool isPushCodeFrame() const { return Offset == 1; } - const MachineLocation &getDestination() const { return Destination; } - const MachineLocation &getSource() const { return Source; } }; struct MCWin64EHUnwindInfo { diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 6be02988777..e24a3c44ffd 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -215,11 +215,11 @@ public: virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, bool Except); virtual void EmitWin64EHHandlerData(); - virtual void EmitWin64EHPushReg(int64_t Register); - virtual void EmitWin64EHSetFrame(int64_t Register, int64_t Offset); - virtual void EmitWin64EHAllocStack(int64_t Size); - virtual void EmitWin64EHSaveReg(int64_t Register, int64_t Offset); - virtual void EmitWin64EHSaveXMM(int64_t Register, int64_t Offset); + virtual void EmitWin64EHPushReg(unsigned Register); + virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset); + virtual void EmitWin64EHAllocStack(unsigned Size); + virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset); + virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset); virtual void EmitWin64EHPushFrame(bool Code); virtual void EmitWin64EHEndProlog(); @@ -965,27 +965,27 @@ void MCAsmStreamer::EmitWin64EHHandlerData() { EmitEOL(); } -void MCAsmStreamer::EmitWin64EHPushReg(int64_t Register) { +void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) { OS << "\t.seh_pushreg " << Register; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) { +void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { OS << "\t.seh_setframe " << Register << ", " << Offset; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHAllocStack(int64_t Size) { +void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) { OS << "\t.seh_stackalloc " << Size; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) { +void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { OS << "\t.seh_savereg " << Register << ", " << Offset; EmitEOL(); } -void MCAsmStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) { +void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { OS << "\t.seh_savexmm " << Register << ", " << Offset; EmitEOL(); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index fc09369ae2b..fcc338991f1 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -378,34 +378,50 @@ void MCStreamer::EmitWin64EHHandlerData() { abort(); } -void MCStreamer::EmitWin64EHPushReg(int64_t Register) { - errs() << "Not implemented yet\n"; - abort(); +void MCStreamer::EmitWin64EHPushReg(unsigned Register) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Register); + CurFrame->Instructions.push_back(Inst); } -void MCStreamer::EmitWin64EHSetFrame(int64_t Register, int64_t Offset) { - errs() << "Not implemented yet\n"; - abort(); +void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Register, Offset); + CurFrame->Instructions.push_back(Inst); } -void MCStreamer::EmitWin64EHAllocStack(int64_t Size) { - errs() << "Not implemented yet\n"; - abort(); +void MCStreamer::EmitWin64EHAllocStack(unsigned Size) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst(Size); + CurFrame->Instructions.push_back(Inst); } -void MCStreamer::EmitWin64EHSaveReg(int64_t Register, int64_t Offset) { - errs() << "Not implemented yet\n"; - abort(); +void MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst( + Offset > 0xFFFF ? Win64EH::UOP_SaveNonVol : Win64EH::UOP_SaveNonVolBig, + Register, Offset); + CurFrame->Instructions.push_back(Inst); } -void MCStreamer::EmitWin64EHSaveXMM(int64_t Register, int64_t Offset) { - errs() << "Not implemented yet\n"; - abort(); +void MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst( + Offset > 0xFFFF ? Win64EH::UOP_SaveXMM128 : Win64EH::UOP_SaveXMM128Big, + Register, Offset); + CurFrame->Instructions.push_back(Inst); } void MCStreamer::EmitWin64EHPushFrame(bool Code) { - errs() << "Not implemented yet\n"; - abort(); + EnsureValidW64UnwindInfo(); + MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; + MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Code); + CurFrame->Instructions.push_back(Inst); } void MCStreamer::EmitWin64EHEndProlog() {