<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>