ADT/Triple: Move a variety of clients to using isOSDarwin() and isOSWindows()
[oota-llvm.git] / lib / Target / MBlaze / MBlazeAsmBackend.cpp
index 7e11f7371e581869583d91b9e5dd37a94a3dfff8..08f14c3659571306b9f203e78760539f7e37f4dd 100644 (file)
@@ -9,16 +9,18 @@
 
 #include "llvm/Target/TargetAsmBackend.h"
 #include "MBlaze.h"
-#include "MBlazeFixupKinds.h"
+#include "MBlazeELFWriterInfo.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/MC/ELFObjectWriter.h"
 #include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCELFSymbolFlags.h"
 #include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCObjectFormat.h"
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MachObjectWriter.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/ELF.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetRegistry.h"
@@ -29,9 +31,9 @@ static unsigned getFixupKindSize(unsigned Kind) {
   switch (Kind) {
   default: assert(0 && "invalid fixup kind!");
   case FK_Data_1: return 1;
-  case MBlaze::reloc_pcrel_2byte:
+  case FK_PCRel_2:
   case FK_Data_2: return 2;
-  case MBlaze::reloc_pcrel_4byte:
+  case FK_PCRel_4:
   case FK_Data_4: return 4;
   case FK_Data_8: return 8;
   }
@@ -39,10 +41,21 @@ static unsigned getFixupKindSize(unsigned Kind) {
 
 
 namespace {
+class MBlazeELFObjectWriter : public MCELFObjectTargetWriter {
+public:
+  MBlazeELFObjectWriter(Triple::OSType OSType)
+    : MCELFObjectTargetWriter(/*is64Bit*/ false, OSType, ELF::EM_MBLAZE,
+                              /*HasRelocationAddend*/ true) {}
+};
+
 class MBlazeAsmBackend : public TargetAsmBackend {
 public:
   MBlazeAsmBackend(const Target &T)
-    : TargetAsmBackend(T) {
+    : TargetAsmBackend() {
+  }
+
+  unsigned getNumFixupKinds() const {
+    return 2;
   }
 
   bool MayNeedRelaxation(const MCInst &Inst) const;
@@ -56,74 +69,72 @@ public:
   }
 };
 
+static unsigned getRelaxedOpcode(unsigned Op) {
+    switch (Op) {
+    default:            return Op;
+    case MBlaze::ADDIK: return MBlaze::ADDIK32;
+    case MBlaze::ORI:   return MBlaze::ORI32;
+    case MBlaze::BRLID: return MBlaze::BRLID32;
+    }
+}
+
 bool MBlazeAsmBackend::MayNeedRelaxation(const MCInst &Inst) const {
-  return false;
+  if (getRelaxedOpcode(Inst.getOpcode()) == Inst.getOpcode())
+    return false;
+
+  bool hasExprOrImm = false;
+  for (unsigned i = 0; i < Inst.getNumOperands(); ++i)
+    hasExprOrImm |= Inst.getOperand(i).isExpr();
+
+  return hasExprOrImm;
 }
 
 void MBlazeAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
-  assert(0 && "MBlazeAsmBackend::RelaxInstruction() unimplemented");
-  return;
+  Res = Inst;
+  Res.setOpcode(getRelaxedOpcode(Inst.getOpcode()));
 }
 
 bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
   if ((Count % 4) != 0)
     return false;
 
-  for (uint64_t i = 0; i < Count; i += 4 )
-      OW->Write32( 0x00000000 );
+  for (uint64_t i = 0; i < Count; i += 4)
+      OW->Write32(0x00000000);
 
   return true;
 }
 } // end anonymous namespace
 
 namespace {
-// FIXME: This should be in a separate file.
-// ELF is an ELF of course...
 class ELFMBlazeAsmBackend : public MBlazeAsmBackend {
-  MCELFObjectFormat Format;
-
 public:
   Triple::OSType OSType;
   ELFMBlazeAsmBackend(const Target &T, Triple::OSType _OSType)
-    : MBlazeAsmBackend(T), OSType(_OSType) {
-    HasScatteredSymbols = true;
-  }
-
-  virtual const MCObjectFormat &getObjectFormat() const {
-    return Format;
-  }
+    : MBlazeAsmBackend(T), OSType(_OSType) { }
 
-
-  void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
+  void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
                   uint64_t Value) const;
 
-  bool isVirtualSection(const MCSection &Section) const {
-    const MCSectionELF &SE = static_cast<const MCSectionELF&>(Section);
-    return SE.getType() == MCSectionELF::SHT_NOBITS;
-  }
-
   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
-    return new ELFObjectWriter(OS, /*Is64Bit=*/false,
-                               OSType,
-                               /*IsLittleEndian=*/false,
-                               /*HasRelocationAddend=*/true);
+    return createELFObjectWriter(new MBlazeELFObjectWriter(OSType), OS,
+                                 /*IsLittleEndian*/ false);
   }
 };
 
-void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
-                                     uint64_t Value) const {
+void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, char *Data,
+                                     unsigned DataSize, uint64_t Value) const {
   unsigned Size = getFixupKindSize(Fixup.getKind());
-            
-  assert(Fixup.getOffset() + Size <= DF.getContents().size() &&
+
+  assert(Fixup.getOffset() + Size <= DataSize &&
          "Invalid fixup offset!");
 
-  char *data = DF.getContents().data() + Fixup.getOffset();
+  char *data = Data + Fixup.getOffset();
   switch (Size) {
-  default: llvm_unreachable( "Cannot fixup unknown value." );
-  case 1:  llvm_unreachable( "Cannot fixup 1 byte value." );
-  case 8:  llvm_unreachable( "Cannot fixup 8 byte value." );
+  default: llvm_unreachable("Cannot fixup unknown value.");
+  case 1:  llvm_unreachable("Cannot fixup 1 byte value.");
+  case 8:  llvm_unreachable("Cannot fixup 8 byte value.");
 
-  case 4: 
+  case 4:
     *(data+7) = uint8_t(Value);
     *(data+6) = uint8_t(Value >> 8);
     *(data+3) = uint8_t(Value >> 16);
@@ -139,14 +150,13 @@ void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF,
 
 TargetAsmBackend *llvm::createMBlazeAsmBackend(const Target &T,
                                             const std::string &TT) {
-  switch (Triple(TT).getOS()) {
-  case Triple::Darwin:
+  Triple TheTriple(TT);
+
+  if (TheTriple.isOSDarwin())
     assert(0 && "Mac not supported on MBlaze");
-  case Triple::MinGW32:
-  case Triple::Cygwin:
-  case Triple::Win32:
+
+  if (TheTriple.isOSWindows())
     assert(0 && "Windows not supported on MBlaze");
-  default:
-    return new ELFMBlazeAsmBackend(T, Triple(TT).getOS());
-  }
+
+  return new ELFMBlazeAsmBackend(T, TheTriple.getOS());
 }