Prune some includes and forward declarations.
[oota-llvm.git] / lib / Target / Mips / MCTargetDesc / MipsAsmBackend.cpp
index ca60225f10738e1ab868fde61ff596a35033121d..a92604d26c8c519112be399e12aba9af928874c6 100644 (file)
 
 #include "MipsFixupKinds.h"
 #include "MCTargetDesc/MipsMCTargetDesc.h"
-#include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCELFObjectWriter.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCMachObjectWriter.h"
+#include "llvm/MC/MCFixupKindInfo.h"
 #include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/MCSectionELF.h"
-#include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Object/MachOFormat.h"
-#include "llvm/Support/ELF.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -70,10 +64,16 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
 
 namespace {
 class MipsAsmBackend : public MCAsmBackend {
+  Triple::OSType OSType;
+  bool IsLittle; // Big or little endian
+
 public:
-  uint8_t OSABI;
-  MipsAsmBackend(const Target &T, uint8_t OSABI_) :
-    MCAsmBackend(), OSABI(OSABI_) {}
+  MipsAsmBackend(const Target &T,  Triple::OSType _OSType, bool _isLittle) :
+    MCAsmBackend(), OSType(_OSType), IsLittle(_isLittle) {}
+
+  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
+    return createMipsELFObjectWriter(OS, OSType, IsLittle);
+  }
 
   /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
   /// data fragment, at the offset specified by the fixup and following the
@@ -86,25 +86,42 @@ public:
     if (!Value)
       return; // Doesn't change encoding.
 
+    // Where do we start in the object
     unsigned Offset = Fixup.getOffset();
-    // FIXME: The below code will not work across endian models
-    // How many bytes/bits are we fixing up?
-    unsigned NumBytes = ((getFixupKindInfo(Kind).TargetSize-1)/8)+1;
-    uint64_t Mask = ((uint64_t)1 << getFixupKindInfo(Kind).TargetSize) - 1;
+    // Number of bytes we need to fixup
+    unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
+    // Used to point to big endian bytes
+    unsigned FullSize;
+
+    switch ((unsigned)Kind) {
+    case Mips::fixup_Mips_16:
+      FullSize = 2;
+      break;
+    case Mips::fixup_Mips_64:
+      FullSize = 8;
+      break;
+    default:
+      FullSize = 4;
+      break;
+    }
 
     // Grab current value, if any, from bits.
     uint64_t CurVal = 0;
-    for (unsigned i = 0; i != NumBytes; ++i)
-      CurVal |= ((uint8_t)Data[Offset + i]) << (i * 8);
 
+    for (unsigned i = 0; i != NumBytes; ++i) {
+      unsigned Idx = IsLittle ? i : (FullSize - 1 - i);
+      CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
+    }
+
+    uint64_t Mask = ((uint64_t)(-1) >> (64 - getFixupKindInfo(Kind).TargetSize));
     CurVal = (CurVal & ~Mask) | ((CurVal + Value) & Mask);
 
-    // Write out the bytes back to the code/data bits.
-    // First the unaffected bits and then the fixup.
+    // Write out the fixed up bytes back to the code/data bits.
     for (unsigned i = 0; i != NumBytes; ++i) {
-      Data[Offset + i] = uint8_t((CurVal >> (i * 8)) & 0xff);
+      unsigned Idx = IsLittle ? i : (FullSize - 1 - i);
+      Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
     }
-}
+  }
 
   unsigned getNumFixupKinds() const { return Mips::NumTargetFixupKinds; }
 
@@ -191,33 +208,15 @@ public:
   }
 };
 
-class MipsEB_AsmBackend : public MipsAsmBackend {
-public:
-  MipsEB_AsmBackend(const Target &T, uint8_t _OSABI)
-    : MipsAsmBackend(T, _OSABI) {}
-
-  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
-    return createMipsELFObjectWriter(OS, /*IsLittleEndian*/ false, OSABI);
-  }
-};
-
-class MipsEL_AsmBackend : public MipsAsmBackend {
-public:
-  MipsEL_AsmBackend(const Target &T, uint8_t _OSABI)
-    : MipsAsmBackend(T, _OSABI) {}
-
-  MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
-    return createMipsELFObjectWriter(OS, /*IsLittleEndian*/ true, OSABI);
-  }
-};
 } // namespace
 
-MCAsmBackend *llvm::createMipsBEAsmBackend(const Target &T, StringRef TT) {
-  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
-  return new MipsEB_AsmBackend(T, OSABI);
+// MCAsmBackend
+MCAsmBackend *llvm::createMipsAsmBackendEL(const Target &T, StringRef TT) {
+  return new MipsAsmBackend(T, Triple(TT).getOS(),
+                            /*IsLittle*/true);
 }
 
-MCAsmBackend *llvm::createMipsLEAsmBackend(const Target &T, StringRef TT) {
-  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
-  return new MipsEL_AsmBackend(T, OSABI);
+MCAsmBackend *llvm::createMipsAsmBackendEB(const Target &T, StringRef TT) {
+  return new MipsAsmBackend(T, Triple(TT).getOS(),
+                            /*IsLittle*/false);
 }