ARM implement TargetInstrInfo::getNoopForMachoTarget()
authorJim Grosbach <grosbach@apple.com>
Tue, 28 Feb 2012 23:53:30 +0000 (23:53 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 28 Feb 2012 23:53:30 +0000 (23:53 +0000)
Without this hook, functions w/ a completely empty body (including no
epilogue) will cause an MCEmitter assertion failure.

For example,
define internal fastcc void @empty_function() {
  unreachable
}

rdar://10947471

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151673 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMBaseInstrInfo.h
lib/Target/ARM/ARMInstrInfo.cpp
lib/Target/ARM/ARMInstrInfo.h
lib/Target/ARM/Thumb1InstrInfo.cpp
lib/Target/ARM/Thumb1InstrInfo.h
lib/Target/ARM/Thumb2InstrInfo.cpp
lib/Target/ARM/Thumb2InstrInfo.h
test/MC/MachO/ARM/empty-function-nop.ll [new file with mode: 0644]

index ea4baab95c50a9d3cc2477ba18a150486e7e82fe..8fb04276f1c40d45c279db64219c84ae603c0df1 100644 (file)
@@ -3003,3 +3003,7 @@ ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
   // This will go before any implicit ops.
   AddDefaultPred(MachineInstrBuilder(MI).addOperand(MI->getOperand(1)));
 }
+
+bool ARMBaseInstrInfo::hasNOP() const {
+  return (Subtarget.getFeatureBits() & ARM::HasV6T2Ops) != 0;
+}
index 8899c9a8331ffe687373a86866031e13356bfe6e..314e3177bec29fb960d08a2ccd8d54511b129a6d 100644 (file)
@@ -35,6 +35,9 @@ protected:
   explicit ARMBaseInstrInfo(const ARMSubtarget &STI);
 
 public:
+  // Return whether the target has an explicit NOP encoding.
+  bool hasNOP() const;
+
   // Return the non-pre/post incrementing version of 'Opc'. Return 0
   // if there is not such an opcode.
   virtual unsigned getUnindexedOpcode(unsigned Opc) const =0;
index e4d46d19ef5ac8877394af54913e7168b4015a5b..b8f607eb4c552aececa2bd53d01a73b069358902 100644 (file)
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCInst.h"
 using namespace llvm;
 
 ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
   : ARMBaseInstrInfo(STI), RI(*this, STI) {
 }
 
+/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+void ARMInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
+  if (hasNOP()) {
+    NopInst.setOpcode(ARM::NOP);
+    NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+    NopInst.addOperand(MCOperand::CreateReg(0));
+  } else {
+    NopInst.setOpcode(ARM::MOVr);
+    NopInst.addOperand(MCOperand::CreateReg(ARM::R0));
+    NopInst.addOperand(MCOperand::CreateReg(ARM::R0));
+    NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+    NopInst.addOperand(MCOperand::CreateReg(0));
+    NopInst.addOperand(MCOperand::CreateReg(0));
+  }
+}
+
 unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const {
   switch (Opc) {
   default: break;
index 3a69692326d9111e28a9bc7c5ebe873ac959488a..7bedf30cbe353ea6a9139b2b7541d961af272e27 100644 (file)
@@ -28,6 +28,9 @@ class ARMInstrInfo : public ARMBaseInstrInfo {
 public:
   explicit ARMInstrInfo(const ARMSubtarget &STI);
 
+  /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+  void getNoopForMachoTarget(MCInst &NopInst) const;
+
   // Return the non-pre/post incrementing version of 'Opc'. Return 0
   // if there is not such an opcode.
   unsigned getUnindexedOpcode(unsigned Opc) const;
index ba16db34bd05bd33cb62c6a9cecec1ef80bd98f6..adaccddf8749e25df3479265313e174b3b26c16a 100644 (file)
@@ -19,7 +19,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/ADT/SmallVector.h"
-#include "Thumb1InstrInfo.h"
+#include "llvm/MC/MCInst.h"
 
 using namespace llvm;
 
@@ -27,6 +27,15 @@ Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
   : ARMBaseInstrInfo(STI), RI(*this, STI) {
 }
 
+/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+void Thumb1InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
+  NopInst.setOpcode(ARM::tMOVr);
+  NopInst.addOperand(MCOperand::CreateReg(ARM::R8));
+  NopInst.addOperand(MCOperand::CreateReg(ARM::R8));
+  NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+  NopInst.addOperand(MCOperand::CreateReg(0));
+}
+
 unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
   return 0;
 }
index 4479101f2e6ca4e6e041b32938ffd8b14fda951e..4d97626925d1b63541f36e5bd0e8e969ea05cd8c 100644 (file)
@@ -27,6 +27,9 @@ class Thumb1InstrInfo : public ARMBaseInstrInfo {
 public:
   explicit Thumb1InstrInfo(const ARMSubtarget &STI);
 
+  /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+  void getNoopForMachoTarget(MCInst &NopInst) const;
+
   // Return the non-pre/post incrementing version of 'Opc'. Return 0
   // if there is not such an opcode.
   unsigned getUnindexedOpcode(unsigned Opc) const;
index 8a6276be51476bbfb9bf9229cb8db350940dd84e..6cb182a08491c64491daec8fd0b7fd38955dac79 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineMemOperand.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCInst.h"
 #include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
@@ -34,6 +35,13 @@ Thumb2InstrInfo::Thumb2InstrInfo(const ARMSubtarget &STI)
   : ARMBaseInstrInfo(STI), RI(*this, STI) {
 }
 
+/// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+void Thumb2InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const {
+  NopInst.setOpcode(ARM::tNOP);
+  NopInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
+  NopInst.addOperand(MCOperand::CreateReg(0));
+}
+
 unsigned Thumb2InstrInfo::getUnindexedOpcode(unsigned Opc) const {
   // FIXME
   return 0;
index 447949c7be328d4c3c24ff40a2c56cf8f6131738..a754649b7f6c3f7436bcd644d2929978f8c443fe 100644 (file)
@@ -28,6 +28,9 @@ class Thumb2InstrInfo : public ARMBaseInstrInfo {
 public:
   explicit Thumb2InstrInfo(const ARMSubtarget &STI);
 
+  /// getNoopForMachoTarget - Return the noop instruction to use for a noop.
+  void getNoopForMachoTarget(MCInst &NopInst) const;
+
   // Return the non-pre/post incrementing version of 'Opc'. Return 0
   // if there is not such an opcode.
   unsigned getUnindexedOpcode(unsigned Opc) const;
diff --git a/test/MC/MachO/ARM/empty-function-nop.ll b/test/MC/MachO/ARM/empty-function-nop.ll
new file mode 100644 (file)
index 0000000..3ac4d82
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llc < %s -filetype=obj -mtriple=thumbv6-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=T1
+; RUN: llc < %s -filetype=obj -mtriple=thumbv7-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=T2
+; RUN: llc < %s -filetype=obj -mtriple=armv6-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=ARM
+; RUN: llc < %s -filetype=obj -mtriple=armv7-apple-darwin -o - | macho-dump -dump-section-data | FileCheck -prefix=ARMV7
+
+; Empty functions need a NOP in them for MachO to prevent DWARF FDEs from
+; getting all mucked up. See lib/CodeGen/AsmPrinter/AsmPrinter.cpp for
+; details.
+define internal fastcc void @empty_function() {
+  unreachable
+}
+; CHECK-T1:    ('_section_data', 'c046')
+; CHECK-T2:    ('_section_data', '00bf')
+; CHECK-ARM:   ('_section_data', '0000a0e1')
+; CHECK-ARMV7: ('_section_data', '00f020e3')