<div dir="ltr"><div>Hi Jim,<br><br></div><div> Currently, I can't use llvm-mc to run the test because ARMAsmParser can't parse unwind directives yet.<br>I am working on this issue. I will add more .s test after the ARMAsmParser is ready. Thanks.<br>
<br></div><div>FYI. <a href="https://github.com/loganchien/llvm/compare/master...add-arm-unwind-directives">https://github.com/loganchien/llvm/compare/master...add-arm-unwind-directives</a><br><br>Sincerely,<br></div><div>
Logan<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Apr 17, 2013 at 1:34 PM, Jim Grosbach <span dir="ltr"><<a href="mailto:grosbach@apple.com" target="_blank">grosbach@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi Logan,<div><br></div><div>Why is this test case a .ll file? Normally, anything at the MC level should have test cases as .s files.</div>
<span class="HOEnZb"><font color="#888888"><div><br></div><div>-Jim</div></font></span><div><div class="h5"><div><br></div><div><br><div><div>On Apr 16, 2013, at 5:02 AM, Logan Chien <<a href="mailto:tzuhsiang.chien@gmail.com" target="_blank">tzuhsiang.chien@gmail.com</a>> wrote:</div>
<br><blockquote type="cite"><div style="letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Author: logan<br>Date: Tue Apr 16 07:02:21 2013<br>New Revision: 179591<br>
<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project?rev=179591&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=179591&view=rev</a><br>Log:<br>Implement ARM unwind opcode assembler.<br>
<br>Added:<br> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp<br> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h<br> llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll<br> llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll<br>
Modified:<br> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp<br> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h<br> llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt<br> llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll<br>
llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll<br> llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll<br><br>Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp (original)<br>+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp Tue Apr 16 07:02:21 2013<br>
@@ -13,7 +13,9 @@<br>//<br>//===----------------------------------------------------------------------===//<br><br>+#include "ARMRegisterInfo.h"<br>#include "ARMUnwindOp.h"<br>+#include "ARMUnwindOpAsm.h"<br>
#include "llvm/ADT/SmallPtrSet.h"<br>#include "llvm/ADT/Twine.h"<br>#include "llvm/MC/MCAsmBackend.h"<br>@@ -26,6 +28,7 @@<br>#include "llvm/MC/MCExpr.h"<br>#include "llvm/MC/MCInst.h"<br>
#include "llvm/MC/MCObjectStreamer.h"<br>+#include "llvm/MC/MCRegisterInfo.h"<br>#include "llvm/MC/MCSection.h"<br>#include "llvm/MC/MCSectionELF.h"<br>#include "llvm/MC/MCStreamer.h"<br>
@@ -33,11 +36,15 @@<br>#include "llvm/MC/MCValue.h"<br>#include "llvm/Support/Debug.h"<br>#include "llvm/Support/ELF.h"<br>-#include "llvm/Support/ErrorHandling.h"<br>#include "llvm/Support/raw_ostream.h"<br>
<br>using namespace llvm;<br><br>+static std::string GetAEABIUnwindPersonalityName(unsigned Index) {<br>+ assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index");<br>+ return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();<br>
+}<br>+<br>namespace {<br><br>/// Extend the generic ELFStreamer class so that it can emit mapping symbols at<br>@@ -57,8 +64,9 @@ public:<br> ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,<br>
MCCodeEmitter *Emitter, bool IsThumb)<br> : MCELFStreamer(SK_ARMELFStreamer, Context, TAB, OS, Emitter),<br>- IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None), ExTab(0),<br>- FnStart(0), Personality(0), CantUnwind(false) {}<br>
+ IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {<br>+ Reset();<br>+ }<br><br> ~ARMELFStreamer() {}<br><br>@@ -194,6 +202,7 @@ private:<br> void Reset();<br><br> void EmitPersonalityFixup(StringRef Name);<br>
+ void CollectUnwindOpcodes();<br><br> void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,<br> SectionKind Kind, const MCSymbol &Fn);<br>@@ -210,9 +219,16 @@ private:<br>
MCSymbol *ExTab;<br> MCSymbol *FnStart;<br> const MCSymbol *Personality;<br>+ uint32_t VFPRegSave; // Register mask for {d31-d0}<br>+ uint32_t RegSave; // Register mask for {r15-r0}<br>+ int64_t SPOffset;<br>+ uint16_t FPReg;<br>
+ int64_t FPOffset;<br>+ bool UsedFP;<br> bool CantUnwind;<br>+ UnwindOpcodeAssembler UnwindOpAsm;<br>};<br>-}<br>+} // end anonymous namespace<br><br>inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,<br>
unsigned Type,<br>@@ -238,7 +254,7 @@ inline void ARMELFStreamer::SwitchToEHSe<br> } else {<br> EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);<br> }<br>
- assert(EHSection);<br>+ assert(EHSection && "Failed to get the required EH section");<br><br> // Switch to .ARM.extab or .ARM.exidx section<br> SwitchSection(EHSection);<br>@@ -262,10 +278,20 @@ inline void ARMELFStreamer::SwitchToExId<br>
}<br><br>void ARMELFStreamer::Reset() {<br>+ const MCRegisterInfo &MRI = getContext().getRegisterInfo();<br>+<br> ExTab = NULL;<br> FnStart = NULL;<br> Personality = NULL;<br>+ VFPRegSave = 0;<br>+ RegSave = 0;<br>
+ FPReg = MRI.getEncodingValue(ARM::SP);<br>+ FPOffset = 0;<br>+ SPOffset = 0;<br>+ UsedFP = false;<br> CantUnwind = false;<br>+<br>+ UnwindOpAsm.Reset();<br>}<br><br>// Add the R_ARM_NONE fixup at the same position<br>
@@ -284,6 +310,18 @@ void ARMELFStreamer::EmitPersonalityFixu<br> MCFixup::getKindForSize(4, false)));<br>}<br><br>+void ARMELFStreamer::CollectUnwindOpcodes() {<br>+ if (UsedFP) {<br>+ UnwindOpAsm.EmitSetFP(FPReg);<br>
+ UnwindOpAsm.EmitSPOffset(-FPOffset);<br>+ } else {<br>+ UnwindOpAsm.EmitSPOffset(SPOffset);<br>+ }<br>+ UnwindOpAsm.EmitVFPRegSave(VFPRegSave);<br>+ UnwindOpAsm.EmitRegSave(RegSave);<br>+ UnwindOpAsm.Finalize();<br>
+}<br>+<br>void ARMELFStreamer::EmitFnStart() {<br> assert(FnStart == 0);<br> FnStart = getContext().CreateTempSymbol();<br>@@ -294,35 +332,29 @@ void ARMELFStreamer::EmitFnEnd() {<br> assert(FnStart && ".fnstart must preceeds .fnend");<br>
<br> // Emit unwind opcodes if there is no .handlerdata directive<br>- int PersonalityIndex = -1;<br> if (!ExTab && !CantUnwind) {<br>- // For __aeabi_unwind_cpp_pr1, we have to emit opcodes in .ARM.extab.<br>
- SwitchToExTabSection(*FnStart);<br>-<br>- // Create .ARM.extab label for offset in .ARM.exidx<br>- ExTab = getContext().CreateTempSymbol();<br>- EmitLabel(ExTab);<br>-<br>- PersonalityIndex = 1;<br>-<br>- uint32_t Entry = 0;<br>
- uint32_t NumExtraEntryWords = 0;<br>- Entry |= NumExtraEntryWords << 24;<br>- Entry |= (EHT_COMPACT | PersonalityIndex) << 16;<br>-<br>- // TODO: This should be generated according to .save, .vsave, .setfp<br>
- // directives. Currently, we are simply generating FINISH opcode.<br>- Entry |= UNWIND_OPCODE_FINISH << 8;<br>- Entry |= UNWIND_OPCODE_FINISH;<br>+ CollectUnwindOpcodes();<br><br>- EmitIntValue(Entry, 4, 0);<br>
+ unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex();<br>+ if (PersonalityIndex == AEABI_UNWIND_CPP_PR1 ||<br>+ PersonalityIndex == AEABI_UNWIND_CPP_PR2) {<br>+ // For the __aeabi_unwind_cpp_pr1 and __aeabi_unwind_cpp_pr2, we have to<br>
+ // emit the unwind opcodes in the corresponding ".ARM.extab" section, and<br>+ // then emit a reference to these unwind opcodes in the second word of<br>+ // the exception index table entry.<br>
+ SwitchToExTabSection(*FnStart);<br>+ ExTab = getContext().CreateTempSymbol();<br>+ EmitLabel(ExTab);<br>+ EmitBytes(UnwindOpAsm.data(), 0);<br>+ }<br> }<br><br> // Emit the exception index table entry<br>
SwitchToExIdxSection(*FnStart);<br><br>- if (PersonalityIndex == 1)<br>- EmitPersonalityFixup("__aeabi_unwind_cpp_pr1");<br>+ unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex();<br>+ if (PersonalityIndex < NUM_PERSONALITY_INDEX)<br>
+ EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));<br><br> const MCSymbolRefExpr *FnStartRef =<br> MCSymbolRefExpr::Create(FnStart,<br>@@ -333,12 +365,22 @@ void ARMELFStreamer::EmitFnEnd() {<br>
<br> if (CantUnwind) {<br> EmitIntValue(EXIDX_CANTUNWIND, 4, 0);<br>- } else {<br>+ } else if (ExTab) {<br>+ // Emit a reference to the unwind opcodes in the ".ARM.extab" section.<br> const MCSymbolRefExpr *ExTabEntryRef =<br>
MCSymbolRefExpr::Create(ExTab,<br> MCSymbolRefExpr::VK_ARM_PREL31,<br> getContext());<br> EmitValue(ExTabEntryRef, 4, 0);<br>+ } else {<br>+ // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in<br>
+ // the second word of exception index table entry. The size of the unwind<br>+ // opcodes should always be 4 bytes.<br>+ assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&<br>+ "Compact model must use __aeabi_cpp_unwind_pr0 as personality");<br>
+ assert(UnwindOpAsm.size() == 4u &&<br>+ "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");<br>+ EmitBytes(UnwindOpAsm.data(), 0);<br> }<br><br> // Clean exception handling frame information<br>
@@ -368,36 +410,50 @@ void ARMELFStreamer::EmitHandlerData() {<br> EmitValue(PersonalityRef, 4, 0);<br><br> // Emit unwind opcodes<br>- uint32_t Entry = 0;<br>- uint32_t NumExtraEntryWords = 0;<br>-<br>- // TODO: This should be generated according to .save, .vsave, .setfp<br>
- // directives. Currently, we are simply generating FINISH opcode.<br>- Entry |= NumExtraEntryWords << 24;<br>- Entry |= UNWIND_OPCODE_FINISH << 16;<br>- Entry |= UNWIND_OPCODE_FINISH << 8;<br>- Entry |= UNWIND_OPCODE_FINISH;<br>
-<br>- EmitIntValue(Entry, 4, 0);<br>+ CollectUnwindOpcodes();<br>+ EmitBytes(UnwindOpAsm.data(), 0);<br>}<br><br>void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) {<br> Personality = Per;<br>+ UnwindOpAsm.setPersonality(Per);<br>
}<br><br>-void ARMELFStreamer::EmitSetFP(unsigned NewFpReg,<br>- unsigned NewSpReg,<br>+void ARMELFStreamer::EmitSetFP(unsigned NewFPReg,<br>+ unsigned NewSPReg,<br>
int64_t Offset) {<br>- // TODO: Not implemented<br>+ assert(SPOffset == 0 &&<br>+ "Current implementation assumes .setfp precedes .pad");<br>+<br>+ const MCRegisterInfo &MRI = getContext().getRegisterInfo();<br>
+<br>+ uint16_t NewFPRegEncVal = MRI.getEncodingValue(NewFPReg);<br>+ uint16_t NewSPRegEncVal = MRI.getEncodingValue(NewSPReg);<br>+<br>+ assert((NewSPReg == ARM::SP || NewSPRegEncVal == FPReg) &&<br>+ "the operand of .setfp directive should be either $sp or $fp");<br>
+<br>+ UsedFP = true;<br>+ FPReg = NewFPRegEncVal;<br>+ FPOffset = Offset;<br>}<br><br>void ARMELFStreamer::EmitPad(int64_t Offset) {<br>- // TODO: Not implemented<br>+ SPOffset += Offset;<br>}<br><br>void ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,<br>
bool IsVector) {<br>- // TODO: Not implemented<br>+ const MCRegisterInfo &MRI = getContext().getRegisterInfo();<br>+<br>+ unsigned Max = IsVector ? 32 : 16;<br>+ uint32_t &RegMask = IsVector ? VFPRegSave : RegSave;<br>
+<br>+ for (size_t i = 0; i < RegList.size(); ++i) {<br>+ unsigned Reg = MRI.getEncodingValue(RegList[i]);<br>+ assert(Reg < Max && "Register encoded value out of range");<br>+ RegMask |= 1u << Reg;<br>
+ }<br>}<br><br>namespace llvm {<br><br>Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h (original)<br>+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOp.h Tue Apr 16 07:02:21 2013<br>
@@ -107,6 +107,19 @@ namespace llvm {<br> UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D8 = 0xd0<br> };<br><br>+ /// ARM-defined Personality Routine Index<br>+ enum ARMPersonalityRoutineIndex {<br>+ // To make the exception handling table become more compact, ARM defined<br>
+ // several personality routines in EHABI. There are 3 different<br>+ // personality routines in ARM EHABI currently. It is possible to have 16<br>+ // pre-defined personality routines at most.<br>+ AEABI_UNWIND_CPP_PR0 = 0,<br>
+ AEABI_UNWIND_CPP_PR1 = 1,<br>+ AEABI_UNWIND_CPP_PR2 = 2,<br>+<br>+ NUM_PERSONALITY_INDEX<br>+ };<br>+<br>}<br><br>#endif // ARM_UNWIND_OP_H<br><br>Added: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp<br>
URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp?rev=179591&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp?rev=179591&view=auto</a><br>
==============================================================================<br>--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp (added)<br>+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp Tue Apr 16 07:02:21 2013<br>
@@ -0,0 +1,198 @@<br>+//===-- ARMUnwindOpAsm.cpp - ARM Unwind Opcodes Assembler -------*- C++ -*-===//<br>+//<br>+// The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// This file implements the unwind opcode assmebler for ARM exception handling<br>
+// table.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "ARMUnwindOpAsm.h"<br>+<br>+#include "ARMUnwindOp.h"<br>+#include "llvm/Support/ErrorHandling.h"<br>
+#include "llvm/Support/LEB128.h"<br>+<br>+using namespace llvm;<br>+<br>+void UnwindOpcodeAssembler::EmitRegSave(uint32_t RegSave) {<br>+ if (RegSave == 0u)<br>+ return;<br>+<br>+ // One byte opcode to save register r14 and r11-r4<br>
+ if (RegSave & (1u << 4)) {<br>+ // The one byte opcode will always save r4, thus we can't use the one byte<br>+ // opcode when r4 is not in .save directive.<br>+<br>+ // Compute the consecutive registers from r4 to r11.<br>
+ uint32_t Range = 0;<br>+ uint32_t Mask = (1u << 4);<br>+ for (uint32_t Bit = (1u << 5); Bit < (1u << 12); Bit <<= 1) {<br>+ if ((RegSave & Bit) == 0u)<br>+ break;<br>+ ++Range;<br>
+ Mask |= Bit;<br>+ }<br>+<br>+ // Emit this opcode when the mask covers every registers.<br>+ uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);<br>+ if (UnmaskedReg == 0u) {<br>+ // Pop r[4 : (4 + n)]<br>
+ Ops.push_back(UNWIND_OPCODE_POP_REG_RANGE_R4 | Range);<br>+ RegSave &= 0x000fu;<br>+ } else if (UnmaskedReg == (1u << 14)) {<br>+ // Pop r[14] + r[4 : (4 + n)]<br>+ Ops.push_back(UNWIND_OPCODE_POP_REG_RANGE_R4_R14 | Range);<br>
+ RegSave &= 0x000fu;<br>+ }<br>+ }<br>+<br>+ // Two bytes opcode to save register r15-r4<br>+ if ((RegSave & 0xfff0u) != 0) {<br>+ uint32_t Op = UNWIND_OPCODE_POP_REG_MASK_R4 | (RegSave >> 4);<br>
+ Ops.push_back(static_cast<uint8_t>(Op >> 8));<br>+ Ops.push_back(static_cast<uint8_t>(Op & 0xff));<br>+ }<br>+<br>+ // Opcode to save register r3-r0<br>+ if ((RegSave & 0x000fu) != 0) {<br>
+ uint32_t Op = UNWIND_OPCODE_POP_REG_MASK | (RegSave & 0x000fu);<br>+ Ops.push_back(static_cast<uint8_t>(Op >> 8));<br>+ Ops.push_back(static_cast<uint8_t>(Op & 0xff));<br>+ }<br>+}<br>
+<br>+/// Emit unwind opcodes for .vsave directives<br>+void UnwindOpcodeAssembler::EmitVFPRegSave(uint32_t VFPRegSave) {<br>+ size_t i = 32;<br>+<br>+ while (i > 16) {<br>+ uint32_t Bit = 1u << (i - 1);<br>
+ if ((VFPRegSave & Bit) == 0u) {<br>+ --i;<br>+ continue;<br>+ }<br>+<br>+ uint32_t Range = 0;<br>+<br>+ --i;<br>+ Bit >>= 1;<br>+<br>+ while (i > 16 && (VFPRegSave & Bit)) {<br>
+ --i;<br>+ ++Range;<br>+ Bit >>= 1;<br>+ }<br>+<br>+ uint32_t Op =<br>+ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 | ((i - 16) << 4) | Range;<br>+ Ops.push_back(static_cast<uint8_t>(Op >> 8));<br>
+ Ops.push_back(static_cast<uint8_t>(Op & 0xff));<br>+ }<br>+<br>+ while (i > 0) {<br>+ uint32_t Bit = 1u << (i - 1);<br>+ if ((VFPRegSave & Bit) == 0u) {<br>+ --i;<br>+ continue;<br>
+ }<br>+<br>+ uint32_t Range = 0;<br>+<br>+ --i;<br>+ Bit >>= 1;<br>+<br>+ while (i > 0 && (VFPRegSave & Bit)) {<br>+ --i;<br>+ ++Range;<br>+ Bit >>= 1;<br>+ }<br>
+<br>+ uint32_t Op = UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD | (i << 4) | Range;<br>+ Ops.push_back(static_cast<uint8_t>(Op >> 8));<br>+ Ops.push_back(static_cast<uint8_t>(Op & 0xff));<br>
+ }<br>+}<br>+<br>+/// Emit unwind opcodes for .setfp directives<br>+void UnwindOpcodeAssembler::EmitSetFP(uint16_t FPReg) {<br>+ Ops.push_back(UNWIND_OPCODE_SET_VSP | FPReg);<br>+}<br>+<br>+/// Emit unwind opcodes to update stack pointer<br>
+void UnwindOpcodeAssembler::EmitSPOffset(int64_t Offset) {<br>+ if (Offset > 0x200) {<br>+ uint8_t Buff[10];<br>+ size_t Size = encodeULEB128((Offset - 0x204) >> 2, Buff);<br>+ Ops.push_back(UNWIND_OPCODE_INC_VSP_ULEB128);<br>
+ Ops.append(Buff, Buff + Size);<br>+ } else if (Offset > 0) {<br>+ if (Offset > 0x100) {<br>+ Ops.push_back(UNWIND_OPCODE_INC_VSP | 0x3fu);<br>+ Offset -= 0x100;<br>+ }<br>+ Ops.push_back(UNWIND_OPCODE_INC_VSP |<br>
+ static_cast<uint8_t>((Offset - 4) >> 2));<br>+ } else if (Offset < 0) {<br>+ while (Offset < -0x100) {<br>+ Ops.push_back(UNWIND_OPCODE_DEC_VSP | 0x3fu);<br>+ Offset += 0x100;<br>
+ }<br>+ Ops.push_back(UNWIND_OPCODE_DEC_VSP |<br>+ static_cast<uint8_t>(((-Offset) - 4) >> 2));<br>+ }<br>+}<br>+<br>+void UnwindOpcodeAssembler::AddOpcodeSizePrefix(size_t Pos) {<br>+ size_t SizeInWords = (size() + 3) / 4;<br>
+ assert(SizeInWords <= 0x100u &&<br>+ "Only 256 additional words are allowed for unwind opcodes");<br>+ Ops[Pos] = static_cast<uint8_t>(SizeInWords - 1);<br>+}<br>+<br>+void UnwindOpcodeAssembler::AddPersonalityIndexPrefix(size_t Pos, unsigned PI) {<br>
+ assert(PI < NUM_PERSONALITY_INDEX && "Invalid personality prefix");<br>+ Ops[Pos] = EHT_COMPACT | PI;<br>+}<br>+<br>+void UnwindOpcodeAssembler::EmitFinishOpcodes() {<br>+ for (size_t i = (0x4u - (size() & 0x3u)) & 0x3u; i > 0; --i)<br>
+ Ops.push_back(UNWIND_OPCODE_FINISH);<br>+}<br>+<br>+void UnwindOpcodeAssembler::Finalize() {<br>+ if (HasPersonality) {<br>+ // Personality specified by .personality directive<br>+ Offset = 1;<br>+ AddOpcodeSizePrefix(1);<br>
+ } else {<br>+ if (getOpcodeSize() <= 3) {<br>+ // __aeabi_unwind_cpp_pr0: [ 0x80 , OP1 , OP2 , OP3 ]<br>+ Offset = 1;<br>+ PersonalityIndex = AEABI_UNWIND_CPP_PR0;<br>+ AddPersonalityIndexPrefix(Offset, PersonalityIndex);<br>
+ } else {<br>+ // __aeabi_unwind_cpp_pr1: [ 0x81 , SIZE , OP1 , OP2 , ... ]<br>+ Offset = 0;<br>+ PersonalityIndex = AEABI_UNWIND_CPP_PR1;<br>+ AddPersonalityIndexPrefix(Offset, PersonalityIndex);<br>
+ AddOpcodeSizePrefix(1);<br>+ }<br>+ }<br>+<br>+ // Emit the padding finish opcodes if the size() is not multiple of 4.<br>+ EmitFinishOpcodes();<br>+<br>+ // Swap the byte order<br>+ uint8_t *Ptr = Ops.begin() + Offset;<br>
+ assert(size() % 4 == 0 && "Final unwind opcodes should align to 4");<br>+ for (size_t i = 0, n = size(); i < n; i += 4) {<br>+ std::swap(Ptr[i], Ptr[i + 3]);<br>+ std::swap(Ptr[i + 1], Ptr[i + 2]);<br>
+ }<br>+}<br><br>Added: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h?rev=179591&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h?rev=179591&view=auto</a><br>
==============================================================================<br>--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h (added)<br>+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h Tue Apr 16 07:02:21 2013<br>
@@ -0,0 +1,114 @@<br>+//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===//<br>+//<br>+// The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+//<br>+// This file declares the unwind opcode assmebler for ARM exception handling<br>
+// table.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#ifndef ARM_UNWIND_OP_ASM_H<br>+#define ARM_UNWIND_OP_ASM_H<br>+<br>+#include "ARMUnwindOp.h"<br>+<br>
+#include "llvm/ADT/SmallVector.h"<br>+#include "llvm/ADT/StringRef.h"<br>+#include "llvm/Support/DataTypes.h"<br>+<br>+namespace llvm {<br>+<br>+class MCSymbol;<br>+<br>+class UnwindOpcodeAssembler {<br>
+private:<br>+ llvm::SmallVector<uint8_t, 8> Ops;<br>+<br>+ unsigned Offset;<br>+ unsigned PersonalityIndex;<br>+ bool HasPersonality;<br>+<br>+ enum {<br>+ // The number of bytes to be preserved for the size and personality index<br>
+ // prefix of unwind opcodes.<br>+ NUM_PRESERVED_PREFIX_BUF = 2<br>+ };<br>+<br>+public:<br>+ UnwindOpcodeAssembler()<br>+ : Ops(NUM_PRESERVED_PREFIX_BUF), Offset(NUM_PRESERVED_PREFIX_BUF),<br>+ PersonalityIndex(NUM_PERSONALITY_INDEX), HasPersonality(0) {<br>
+ }<br>+<br>+ /// Reset the unwind opcode assembler.<br>+ void Reset() {<br>+ Ops.resize(NUM_PRESERVED_PREFIX_BUF);<br>+ Offset = NUM_PRESERVED_PREFIX_BUF;<br>+ PersonalityIndex = NUM_PERSONALITY_INDEX;<br>+ HasPersonality = 0;<br>
+ }<br>+<br>+ /// Get the size of the payload (including the size byte)<br>+ size_t size() const {<br>+ return Ops.size() - Offset;<br>+ }<br>+<br>+ /// Get the beginning of the payload<br>+ const uint8_t *begin() const {<br>
+ return Ops.begin() + Offset;<br>+ }<br>+<br>+ /// Get the payload<br>+ StringRef data() const {<br>+ return StringRef(reinterpret_cast<const char *>(begin()), size());<br>+ }<br>+<br>+ /// Set the personality index<br>
+ void setPersonality(const MCSymbol *Per) {<br>+ HasPersonality = 1;<br>+ }<br>+<br>+ /// Get the personality index<br>+ unsigned getPersonalityIndex() const {<br>+ return PersonalityIndex;<br>+ }<br>+<br>+ /// Emit unwind opcodes for .save directives<br>
+ void EmitRegSave(uint32_t RegSave);<br>+<br>+ /// Emit unwind opcodes for .vsave directives<br>+ void EmitVFPRegSave(uint32_t VFPRegSave);<br>+<br>+ /// Emit unwind opcodes for .setfp directives<br>+ void EmitSetFP(uint16_t FPReg);<br>
+<br>+ /// Emit unwind opcodes to update stack pointer<br>+ void EmitSPOffset(int64_t Offset);<br>+<br>+ /// Finalize the unwind opcode sequence for EmitBytes()<br>+ void Finalize();<br>+<br>+private:<br>+ /// Get the size of the opcodes in bytes.<br>
+ size_t getOpcodeSize() const {<br>+ return Ops.size() - NUM_PRESERVED_PREFIX_BUF;<br>+ }<br>+<br>+ /// Add the length prefix to the payload<br>+ void AddOpcodeSizePrefix(size_t Pos);<br>+<br>+ /// Add personality index prefix in some compact format<br>
+ void AddPersonalityIndexPrefix(size_t Pos, unsigned PersonalityIndex);<br>+<br>+ /// Fill the words with finish opcode if it is not aligned<br>+ void EmitFinishOpcodes();<br>+};<br>+<br>+} // namespace llvm<br>+<br>+#endif // ARM_UNWIND_OP_ASM_H<br>
<br>Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt (original)<br>+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/CMakeLists.txt Tue Apr 16 07:02:21 2013<br>
@@ -8,6 +8,7 @@ add_llvm_library(LLVMARMDesc<br> ARMMCTargetDesc.cpp<br> ARMMachObjectWriter.cpp<br> ARMELFObjectWriter.cpp<br>+ ARMUnwindOpAsm.cpp<br> )<br>add_dependencies(LLVMARMDesc ARMCommonTableGen)<br><br><br>
Added: llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll?rev=179591&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll?rev=179591&view=auto</a><br>
==============================================================================<br>--- llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll (added)<br>+++ llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr0.ll Tue Apr 16 07:02:21 2013<br>
@@ -0,0 +1,49 @@<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>+; RUN: | llvm-objdump -s - \<br>
+; RUN: | FileCheck %s --check-prefix=CHECK<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -filetype=obj -o - %s \<br>+; RUN: | llvm-objdump -s - \<br>
+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -r - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK-RELOC<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -r - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK-RELOC<br>+<br>+define void @_Z4testv() {<br>+entry:<br>+ tail call void @_Z15throw_exceptionv()<br>+ ret void<br>+}<br>+<br>+declare void @_Z15throw_exceptionv()<br>
+<br>+; CHECK-NOT: section .ARM.extab<br>+; CHECK: section .text<br>+; CHECK-NOT: section .ARM.extab<br>+; CHECK: section .ARM.exidx<br>+; CHECK-NEXT: 0000 00000000 80849b80<br>+; CHECK-NOT: section .ARM.extab<br>+<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>
+; CHECK-FP-ELIM: section .text<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>+; CHECK-FP-ELIM: section .ARM.exidx<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 b0808480<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>+<br>+; CHECK-RELOC: RELOCATION RECORDS FOR [.ARM.exidx]<br>
+; CHECK-RELOC-NEXT: 0 R_ARM_PREL31 .text<br>+; CHECK-RELOC-NEXT: 0 R_ARM_NONE __aeabi_unwind_cpp_pr0<br><br>Added: llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll?rev=179591&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll?rev=179591&view=auto</a><br>
==============================================================================<br>--- llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll (added)<br>+++ llvm/trunk/test/CodeGen/ARM/ehabi-mc-compact-pr1.ll Tue Apr 16 07:02:21 2013<br>
@@ -0,0 +1,62 @@<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>+; RUN: | llvm-objdump -s - \<br>
+; RUN: | FileCheck %s --check-prefix=CHECK<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -filetype=obj -o - %s \<br>+; RUN: | llvm-objdump -s - \<br>
+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -r - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK-RELOC<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -r - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM-RELOC<br>+<br>+define i32 @_Z3addiiiiiiii(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) {<br>+entry:<br>+ %add = add nsw i32 %b, %a<br>
+ %add1 = add nsw i32 %add, %c<br>+ %add2 = add nsw i32 %add1, %d<br>+ tail call void @_Z15throw_exceptioni(i32 %add2)<br>+ %add3 = add nsw i32 %f, %e<br>+ %add4 = add nsw i32 %add3, %g<br>+ %add5 = add nsw i32 %add4, %h<br>
+ tail call void @_Z15throw_exceptioni(i32 %add5)<br>+ %add6 = add nsw i32 %add5, %add2<br>+ ret i32 %add6<br>+}<br>+<br>+declare void @_Z15throw_exceptioni(i32)<br>+<br>+; CHECK-NOT: section .ARM.extab<br>+; CHECK: section .text<br>
+; CHECK: section .ARM.extab<br>+; CHECK-NEXT: 0000 419b0181 b0b08384<br>+; CHECK: section .ARM.exidx<br>+; CHECK-NEXT: 0000 00000000 00000000<br>+; CHECK-NOT: section .ARM.extab<br>+<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>
+; CHECK-FP-ELIM: section .text<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>+; CHECK-FP-ELIM: section .ARM.exidx<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 b0838480<br>+; CHECK-FP-ELIM-NOT: section .ARM.extab<br>+<br>+; CHECK-RELOC: RELOCATION RECORDS FOR [.ARM.exidx]<br>
+; CHECK-RELOC-NEXT: 0 R_ARM_PREL31 .text<br>+; CHECK-RELOC-NEXT: 0 R_ARM_NONE __aeabi_unwind_cpp_pr1<br>+<br>+; CHECK-FP-ELIM-RELOC: RELOCATION RECORDS FOR [.ARM.exidx]<br>+; CHECK-FP-ELIM-RELOC-NEXT: 0 R_ARM_PREL31 .text<br>
+; CHECK-FP-ELIM-RELOC-NEXT: 0 R_ARM_NONE __aeabi_unwind_cpp_pr0<br><br>Modified: llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll (original)<br>+++ llvm/trunk/test/CodeGen/ARM/ehabi-mc-section-group.ll Tue Apr 16 07:02:21 2013<br>
@@ -72,17 +72,17 @@ declare void @_ZSt9terminatev()<br>; CHECK: Index: 1<br>; CHECK-NEXT: Name: .group (47)<br>; CHECK: SectionData (<br>-; CHECK-NEXT: 0000: 01000000 0A000000 0C000000 0E000000<br>
+; CHECK-NEXT: 0000: 01000000 09000000 0B000000 0D000000<br>; CHECK-NEXT: )<br><br>; CHECK: Section {<br>-; CHECK: Index: 10<br>-; CHECK-NEXT: Name: .text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (225)<br>
+; CHECK: Index: 9<br>+; CHECK-NEXT: Name: .text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (214)<br><br>; CHECK: Section {<br>-; CHECK: Index: 12<br>-; CHECK-NEXT: Name: .ARM.extab.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (215)<br>
+; CHECK: Index: 11<br>+; CHECK-NEXT: Name: .ARM.extab.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (204)<br><br>; CHECK: Section {<br>-; CHECK: Index: 14<br>-; CHECK-NEXT: Name: .ARM.exidx.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (101)<br>
+; CHECK: Index: 13<br>+; CHECK-NEXT: Name: .ARM.exidx.text._Z4testIidEvT_S0_S0_S0_S0_T0_S1_S1_S1_S1_ (90)<br><br>Modified: llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll (original)<br>+++ llvm/trunk/test/CodeGen/ARM/ehabi-mc-section.ll Tue Apr 16 07:02:21 2013<br>
@@ -1,8 +1,14 @@<br>-; RUN: llc -mtriple arm-unknown-linux-gnueabi \<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -s - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>; RUN: -filetype=obj -o - %s \<br>
; RUN: | llvm-objdump -s - \<br>-; RUN: | FileCheck %s<br>+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM<br><br>define void @_Z4testiiiiiddddd(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5, double %v1, double %v2, double %v3, double %v4, double %v5) section ".test_section" {<br>
entry:<br>@@ -54,6 +60,12 @@ declare void @_ZSt9terminatev()<br><br>; CHECK: section .test_section<br>; CHECK: section .ARM.extab.test_section<br>-; CHECK-NEXT: 0000 00000000 b0b0b000<br>+; CHECK-NEXT: 0000 00000000 c9409b01 b0818484<br>
; CHECK: section .ARM.exidx.test_section<br>; CHECK-NEXT: 0000 00000000 00000000<br>+<br>+; CHECK-FP-ELIM: section .test_section<br>+; CHECK-FP-ELIM: section .ARM.extab.test_section<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 84c90501 b0b0b0a8<br>
+; CHECK-FP-ELIM: section .ARM.exidx.test_section<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 00000000<br><br>Modified: llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll<br>URL:<span> </span><a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll?rev=179591&r1=179590&r2=179591&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll?rev=179591&r1=179590&r2=179591&view=diff</a><br>
==============================================================================<br>--- llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll (original)<br>+++ llvm/trunk/test/CodeGen/ARM/ehabi-mc.ll Tue Apr 16 07:02:21 2013<br>@@ -1,8 +1,14 @@<br>
-; RUN: llc -mtriple arm-unknown-linux-gnueabi \<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>+; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>+; RUN: -disable-fp-elim -filetype=obj -o - %s \<br>
+; RUN: | llvm-objdump -s - \<br>+; RUN: | FileCheck %s --check-prefix=CHECK<br>+<br>+; RUN: llc -mtriple armv7-unknown-linux-gnueabi \<br>; RUN: -arm-enable-ehabi -arm-enable-ehabi-descriptors \<br>; RUN: -filetype=obj -o - %s \<br>
; RUN: | llvm-objdump -s - \<br>-; RUN: | FileCheck %s<br>+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM<br><br>define void @_Z4testiiiiiddddd(i32 %u1, i32 %u2, i32 %u3, i32 %u4, i32 %u5, double %v1, double %v2, double %v3, double %v4, double %v5) {<br>
entry:<br>@@ -54,6 +60,12 @@ declare void @_ZSt9terminatev()<br><br>; CHECK: section .text<br>; CHECK: section .ARM.extab<br>-; CHECK-NEXT: 0000 00000000 b0b0b000<br>+; CHECK-NEXT: 0000 00000000 c9409b01 b0818484<br>; CHECK: section .ARM.exidx<br>
; CHECK-NEXT: 0000 00000000 00000000<br>+<br>+; CHECK-FP-ELIM: section .text<br>+; CHECK-FP-ELIM: section .ARM.extab<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 84c90501 b0b0b0a8<br>+; CHECK-FP-ELIM: section .ARM.exidx<br>+; CHECK-FP-ELIM-NEXT: 0000 00000000 00000000<br>
<br><br>_______________________________________________<br>llvm-commits mailing list<br><a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a></div>
</blockquote></div><br></div></div></div></div></blockquote></div><br></div>