Mips MC object code emission improvements:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 11 Nov 2011 22:58:42 +0000 (22:58 +0000)
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>
Fri, 11 Nov 2011 22:58:42 +0000 (22:58 +0000)
"With this patch we can now generate runnable Mips code through LLVM
direct object emission. We have run numerous simple programs, both C
and C++ and with -O0 and -O3 from the output. The code is not production
ready, but quite useful for experimentation." Patch and message by
Jack Carter

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

13 files changed:
lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
lib/Target/Mips/Makefile
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsCodeEmitter.cpp
lib/Target/Mips/MipsFrameLowering.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsInstrInfo.h
lib/Target/Mips/MipsInstrInfo.td
lib/Target/Mips/MipsMCInstLower.cpp

index f190ec42c776c6cc267e42ec107d4a743a05b713..4f017d0b20365ce9e02869a27a56f19541818d22 100644 (file)
@@ -1,5 +1,21 @@
+//===-- MipsASMBackend.cpp -  ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MipsAsmBackend and MipsELFObjectWriter classes.
+//
+//===----------------------------------------------------------------------===//
+//
+
+#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"
@@ -8,7 +24,6 @@
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionMachO.h"
-#include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/Object/MachOFormat.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace llvm;
 
+static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
+
+  // Add/subtract and shift
+  switch (Kind) {
+  default:
+    break;
+  case Mips::fixup_Mips_PC16:
+    // So far we are only using this type for branches.
+    // For branches we start 1 instruction after the branch
+    // so the displacement will be one instruction size less.
+    Value -= 4;
+    // The displacement is then divided by 4 to give us an 18 bit
+    // address range.
+    Value >>= 2;
+    break;
+  case Mips::fixup_Mips_26:
+    // So far we are only using this type for jumps.
+    // The displacement is then divided by 4 to give us an 28 bit
+    // address range.
+    Value >>= 2;
+    break;
+  }
+
+  // Mask off value for placement as an operand
+  switch (Kind) {
+  default:
+    break;
+  case FK_Data_4:
+    Value &= 0xffffffff;
+    break;
+  case Mips::fixup_Mips_26:
+    Value &= 0x03ffffff;
+    break;
+  case Mips::fixup_Mips_LO16:
+  case Mips::fixup_Mips_PC16:
+    Value &= 0x0000ffff;
+    break;
+  }
+
+  return Value;
+}
+
 namespace {
+
 class MipsELFObjectWriter : public MCELFObjectTargetWriter {
 public:
   MipsELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine,
@@ -27,18 +85,75 @@ public:
 
 class MipsAsmBackend : public MCAsmBackend {
 public:
-  MipsAsmBackend(const Target &T)
-    : MCAsmBackend() {}
-
-  unsigned getNumFixupKinds() const {
-    return 1;   //tbd
-  }
+  MipsAsmBackend(const Target &T) : MCAsmBackend() {}
 
   /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
   /// data fragment, at the offset specified by the fixup and following the
   /// fixup kind as appropriate.
   void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
                   uint64_t Value) const {
+    unsigned Kind = (unsigned)Fixup.getKind();
+    Value = adjustFixupValue(Kind, Value);
+
+    if (!Value)
+      return;           // Doesn't change encoding.
+
+    unsigned Offset = Fixup.getOffset();
+    switch (Kind) {
+    default:
+      llvm_unreachable("Unknown fixup kind!");
+    case Mips::fixup_Mips_GOT16: // This will be fixed up at link time
+     break;
+    case FK_Data_4:
+    case Mips::fixup_Mips_26:
+    case Mips::fixup_Mips_LO16:
+    case Mips::fixup_Mips_PC16:
+      // For each byte of the fragment that the fixup touches, mask i
+      // the fixup value. The Value has been "split up" into the appr
+      // bitfields above.
+      for (unsigned i = 0; i != 4; ++i) // FIXME - Need to support 2 and 8 bytes
+        Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
+      break;
+    }
+  }
+
+  unsigned getNumFixupKinds() const { return Mips::NumTargetFixupKinds; }
+
+  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+    const static MCFixupKindInfo Infos[Mips::NumTargetFixupKinds] = {
+      // This table *must* be in the order that the fixup_* kinds a
+      // MipsFixupKinds.h.
+      //
+      // name                    offset  bits  flags
+      { "fixup_Mips_NONE",         0,      0,   0 },
+      { "fixup_Mips_16",           0,     16,   0 },
+      { "fixup_Mips_32",           0,     32,   0 },
+      { "fixup_Mips_REL32",        0,     32,   0 },
+      { "fixup_Mips_26",           0,     26,   0 },
+      { "fixup_Mips_HI16",         0,     16,   0 },
+      { "fixup_Mips_LO16",         0,     16,   0 },
+      { "fixup_Mips_GPREL16",      0,     16,   0 },
+      { "fixup_Mips_LITERAL",      0,     16,   0 },
+      { "fixup_Mips_GOT16",        0,     16,   0 },
+      { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
+      { "fixup_Mips_CALL16",       0,     16,   0 },
+      { "fixup_Mips_GPREL32",      0,     32,   0 },
+      { "fixup_Mips_SHIFT5",       6,      5,   0 },
+      { "fixup_Mips_SHIFT6",       6,      5,   0 },
+      { "fixup_Mips_64",           0,     64,   0 },
+      { "fixup_Mips_TLSGD",        0,     16,   0 },
+      { "fixup_Mips_GOTTPREL",     0,     16,   0 },
+      { "fixup_Mips_TPREL_HI",     0,     16,   0 },
+      { "fixup_Mips_TPREL_LO",     0,     16,   0 },
+      { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel }
+    };
+
+    if (Kind < FirstTargetFixupKind)
+      return MCAsmBackend::getFixupKindInfo(Kind);
+
+    assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
+           "Invalid kind!");
+    return Infos[Kind - FirstTargetFixupKind];
   }
 
   /// @name Target Relaxation Interfaces
@@ -52,24 +167,24 @@ public:
     return false;
   }
 
-  /// RelaxInstruction - Relax the instruction in the given fragment to the next
-  /// wider instruction.
+  /// RelaxInstruction - Relax the instruction in the given fragment
+  /// to the next wider instruction.
   ///
-  /// \param Inst - The instruction to relax, which may be the same as the
-  /// output.
+  /// \param Inst - The instruction to relax, which may be the same
+  /// as the output.
   /// \parm Res [output] - On return, the relaxed instruction.
   void RelaxInstruction(const MCInst &Inst, MCInst &Res) const {
   }
   
   /// @}
 
-  /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
-  /// output. If the target cannot generate such a sequence, it should return an
-  /// error.
+  /// WriteNopData - Write an (optimal) nop sequence of Count bytes
+  /// to the given output. If the target cannot generate such a sequence,
+  /// it should return an error.
   ///
   /// \return - True on success.
   bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
-    return false;
+    return true;
   }
 };
 
@@ -106,7 +221,7 @@ public:
     return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false);
   }
 };
-}
+} // namespace
 
 MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, StringRef TT) {
   Triple TheTriple(TT);
index f7a6fa949091486aa947f7fa7ce359a4acc71f78..cebfde087817b2b480fc5fb90975d932ff7d9805 100644 (file)
 #include "llvm/Support/ErrorHandling.h"
 
 namespace llvm {
+
+/// MipsII - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace MipsII {
+  /// Target Operand Flag enum.
+  enum TOF {
+    //===------------------------------------------------------------------===//
+    // Mips Specific MachineOperand flags.
+
+    MO_NO_FLAG,
+
+    /// MO_GOT - Represents the offset into the global offset table at which
+    /// the address the relocation entry symbol resides during execution.
+    MO_GOT,
+
+    /// MO_GOT_CALL - Represents the offset into the global offset table at
+    /// which the address of a call site relocation entry symbol resides
+    /// during execution. This is different from the above since this flag
+    /// can only be present in call instructions.
+    MO_GOT_CALL,
+
+    /// MO_GPREL - Represents the offset from the current gp value to be used
+    /// for the relocatable object file being produced.
+    MO_GPREL,
+
+    /// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol
+    /// address.
+    MO_ABS_HI,
+    MO_ABS_LO,
+
+    /// MO_TLSGD - Represents the offset into the global offset table at which
+    // the module ID and TSL block offset reside during execution (General
+    // Dynamic TLS).
+    MO_TLSGD,
+
+    /// MO_GOTTPREL - Represents the offset from the thread pointer (Initial
+    // Exec TLS).
+    MO_GOTTPREL,
+
+    /// MO_TPREL_HI/LO - Represents the hi and low part of the offset from
+    // the thread pointer (Local Exec TLS).
+    MO_TPREL_HI,
+    MO_TPREL_LO,
+
+    // N32/64 Flags.
+    MO_GPOFF_HI,
+    MO_GPOFF_LO,
+    MO_GOT_DISP,
+    MO_GOT_PAGE,
+    MO_GOT_OFST
+  };
+
+  enum {
+    //===------------------------------------------------------------------===//
+    // Instruction encodings.  These are the standard/most common forms for
+    // Mips instructions.
+    //
+
+    // Pseudo - This represents an instruction that is a pseudo instruction
+    // or one that has not been implemented yet.  It is illegal to code generate
+    // it, but tolerated for intermediate implementation stages.
+    Pseudo   = 0,
+
+    /// FrmR - This form is for instructions of the format R.
+    FrmR  = 1,
+    /// FrmI - This form is for instructions of the format I.
+    FrmI  = 2,
+    /// FrmJ - This form is for instructions of the format J.
+    FrmJ  = 3,
+    /// FrmFR - This form is for instructions of the format FR.
+    FrmFR = 4,
+    /// FrmFI - This form is for instructions of the format FI.
+    FrmFI = 5,
+    /// FrmOther - This form is for instructions that have no specific format.
+    FrmOther = 6,
+
+    FormMask = 15
+  };
+}
+
+
 /// getMipsRegisterNumbering - Given the enum value for some register,
 /// return the number that it corresponds to.
 inline static unsigned getMipsRegisterNumbering(unsigned RegEnum)
index d66de23ba115c407bef0634ddde2f9cfccd25e2e..1115fec8aab563311005a53a31a232365c0887d5 100644 (file)
 //===----------------------------------------------------------------------===//
 //
 #define DEBUG_TYPE "mccodeemitter"
+#include "MCTargetDesc/MipsBaseInfo.h"
+#include "MCTargetDesc/MipsFixupKinds.h"
+#include "MCTargetDesc/MipsMCTargetDesc.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/MC/MCInstrInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/Statistic.h"
 #include "llvm/Support/raw_ostream.h"
-#include "MCTargetDesc/MipsMCTargetDesc.h"
 
 using namespace llvm;
 
@@ -31,22 +33,217 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
   void operator=(const MipsMCCodeEmitter &); // DO NOT IMPLEMENT
   const MCInstrInfo &MCII;
   const MCSubtargetInfo &STI;
+  MCContext &Ctx;
 
 public:
   MipsMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
-                    MCContext &ctx)
-    : MCII(mcii), STI(sti) {}
+                    MCContext &ctx) : MCII(mcii), STI(sti) , Ctx(ctx) {}
 
   ~MipsMCCodeEmitter() {}
 
-  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
-                         SmallVectorImpl<MCFixup> &Fixups) const {
+  void EmitByte(unsigned char C, raw_ostream &OS) const {
+    OS << (char)C;
+  }
+
+  void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const {
+    // Output the instruction encoding in little endian byte order.
+    for (unsigned i = 0; i != Size; ++i) {
+      EmitByte(Val & 255, OS);
+      Val >>= 8;
+    }
   }
+
+  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+                         SmallVectorImpl<MCFixup> &Fixups) const;
+
+  // getBinaryCodeForInstr - TableGen'erated function for getting the
+  // binary encoding for an instruction.
+  unsigned getBinaryCodeForInstr(const MCInst &MI,
+                                 SmallVectorImpl<MCFixup> &Fixups) const;
+
+  // getBranchJumpOpValue - Return binary encoding of the jump
+  // target operand. If the machine operand requires relocation,
+  // record the relocation and return zero.
+   unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
+                                 SmallVectorImpl<MCFixup> &Fixups) const;
+
+   // getBranchTargetOpValue - Return binary encoding of the branch
+   // target operand. If the machine operand requires relocation,
+   // record the relocation and return zero.
+  unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
+                                  SmallVectorImpl<MCFixup> &Fixups) const;
+
+   // getMachineOpValue - Return binary encoding of operand. If the machin
+   // operand requires relocation, record the relocation and return zero.
+  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
+                             SmallVectorImpl<MCFixup> &Fixups) const;
+
+  unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
+                          SmallVectorImpl<MCFixup> &Fixups) const;
+  unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
+                              SmallVectorImpl<MCFixup> &Fixups) const;
+  unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
+                              SmallVectorImpl<MCFixup> &Fixups) const;
+
 }; // class MipsMCCodeEmitter
 }  // namespace
 
 MCCodeEmitter *llvm::createMipsMCCodeEmitter(const MCInstrInfo &MCII,
                                              const MCSubtargetInfo &STI,
-                                             MCContext &Ctx) {
+                                             MCContext &Ctx)
+{
   return new MipsMCCodeEmitter(MCII, STI, Ctx);
 }
+
+/// EncodeInstruction - Emit the instruction.
+/// Size the instruction (currently only 4 bytes
+void MipsMCCodeEmitter::
+EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+                  SmallVectorImpl<MCFixup> &Fixups) const
+{
+  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);
+
+  // Check for unimplemented opcodes.
+  // Unfortunately in MIPS both NOT and SLL will come in with Binary == 0
+  // so we have to special check for them.
+  unsigned Opcode = MI.getOpcode();
+  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
+    llvm_unreachable("unimplemented opcode in EncodeInstruction()");
+
+  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
+  uint64_t TSFlags = Desc.TSFlags;
+
+  // Pseudo instructions don't get encoded and shouldn't be here
+  // in the first place!
+  if ((TSFlags & MipsII::FormMask) == MipsII::Pseudo)
+    llvm_unreachable("Pseudo opcode found in EncodeInstruction()");
+
+  // For now all instructions are 4 bytes
+  int Size = 4; // FIXME: Have Desc.getSize() return the correct value!
+
+  EmitInstruction(Binary, Size, OS);
+}
+
+/// getBranchTargetOpValue - Return binary encoding of the branch
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
+                       SmallVectorImpl<MCFixup> &Fixups) const {
+
+  const MCOperand &MO = MI.getOperand(OpNo);
+  assert(MO.isExpr() && "getBranchTargetOpValue expects only expressions");
+
+  const MCExpr *Expr = MO.getExpr();
+  Fixups.push_back(MCFixup::Create(0, Expr,
+                                   MCFixupKind(Mips::fixup_Mips_PC16)));
+  return 0;
+}
+
+/// getJumpTargetOpValue - Return binary encoding of the jump
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
+                     SmallVectorImpl<MCFixup> &Fixups) const {
+
+  const MCOperand &MO = MI.getOperand(OpNo);
+  assert(MO.isExpr() && "getJumpTargetOpValue expects only expressions");
+
+  const MCExpr *Expr = MO.getExpr();
+  Fixups.push_back(MCFixup::Create(0, Expr,
+                                   MCFixupKind(Mips::fixup_Mips_26)));
+  return 0;
+}
+
+/// getMachineOpValue - Return binary encoding of operand. If the machine
+/// operand requires relocation, record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+                  SmallVectorImpl<MCFixup> &Fixups) const {
+  if (MO.isReg()) {
+    unsigned Reg = MO.getReg();
+    unsigned RegNo = getMipsRegisterNumbering(Reg);
+    return RegNo;
+  } else if (MO.isImm()) {
+    return static_cast<unsigned>(MO.getImm());
+  } else if (MO.isFPImm()) {
+    return static_cast<unsigned>(APFloat(MO.getFPImm())
+        .bitcastToAPInt().getHiBits(32).getLimitedValue());
+  } else if (MO.isExpr()) {
+    const MCExpr *Expr = MO.getExpr();
+    MCExpr::ExprKind Kind = Expr->getKind();
+    if (Kind == MCExpr::SymbolRef) {
+      Mips::Fixups FixupKind = Mips::fixup_Mips_NONE;
+      MCSymbolRefExpr::VariantKind SymRefKind =
+          cast<MCSymbolRefExpr>(Expr)->getKind();
+      switch(SymRefKind) {
+      case MCSymbolRefExpr::VK_Mips_GPREL:
+        FixupKind = Mips::fixup_Mips_GPREL16;
+        break;
+      case MCSymbolRefExpr::VK_Mips_GOT_CALL:
+        FixupKind = Mips::fixup_Mips_CALL16;
+        break;
+      case MCSymbolRefExpr::VK_Mips_GOT:
+        FixupKind = Mips::fixup_Mips_GOT16;
+        break;
+      case MCSymbolRefExpr::VK_Mips_ABS_HI:
+        FixupKind = Mips::fixup_Mips_HI16;
+        break;
+      case MCSymbolRefExpr::VK_Mips_ABS_LO:
+        FixupKind = Mips::fixup_Mips_LO16;
+        break;
+      case MCSymbolRefExpr::VK_Mips_TLSGD:
+        FixupKind = Mips::fixup_Mips_TLSGD;
+        break;
+      case MCSymbolRefExpr::VK_Mips_GOTTPREL:
+        FixupKind = Mips::fixup_Mips_GOTTPREL;
+        break;
+      case MCSymbolRefExpr::VK_Mips_TPREL_HI:
+        FixupKind = Mips::fixup_Mips_TPREL_HI;
+        break;
+      case MCSymbolRefExpr::VK_Mips_TPREL_LO:
+        FixupKind = Mips::fixup_Mips_TPREL_LO;
+        break;
+      default:
+        return 0;
+      } // switch
+      Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
+    } // if SymbolRef
+    // All of the information is in the fixup.
+    return 0;
+  }
+  llvm_unreachable("Unable to encode MCOperand!");
+  // Not reached
+  return 0;
+}
+
+/// getMemEncoding - Return binary encoding of memory related operand.
+/// If the offset operand requires relocation, record the relocation.
+unsigned
+MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
+                                  SmallVectorImpl<MCFixup> &Fixups) const {
+  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
+  assert(MI.getOperand(OpNo).isReg());
+  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
+  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
+
+  return (OffBits & 0xFFFF) | RegBits;
+}
+
+unsigned
+MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
+                                      SmallVectorImpl<MCFixup> &Fixups) const {
+  // FIXME: implement
+  return 0;
+}
+
+unsigned
+MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
+                                      SmallVectorImpl<MCFixup> &Fixups) const {
+  // FIXME: implement
+  return 0;
+}
+
+#include "MipsGenMCCodeEmitter.inc"
+
index 1f9e3ddf13c86ef5cfaafb97b99e8c0121febce9..e6040e45fbd1804cae8eb4d295db1ce45ca09b00 100644 (file)
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "MipsMCTargetDesc.h"
 #include "MipsMCAsmInfo.h"
+#include "MipsMCTargetDesc.h"
 #include "InstPrinter/MipsInstPrinter.h"
 #include "llvm/MC/MachineLocation.h"
 #include "llvm/MC/MCCodeGenInfo.h"
@@ -140,6 +140,9 @@ extern "C" void LLVMInitializeMipsTargetMC() {
   TargetRegistry::RegisterMCAsmBackend(TheMips64Target, createMipsAsmBackend);
   TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget, createMipsAsmBackend);
 
+  TargetRegistry::RegisterMCCodeEmitter(TheMipsTarget, createMipsMCCodeEmitter);
+  TargetRegistry::RegisterMCCodeEmitter(TheMipselTarget, createMipsMCCodeEmitter);
+
   // Register the MC subtarget info.
   TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget,
                                           createMipsMCSubtargetInfo);
index 7a0042ad889ead787046b104fea20f4320e10504..fc43d2d6fc481d47783994ef5d18ae7a7010a91c 100644 (file)
 
 namespace llvm {
 class MCAsmBackend;
-class MCInstrInfo;
 class MCCodeEmitter;
 class MCContext;
+class MCInstrInfo;
+class MCObjectWriter;
 class MCSubtargetInfo;
 class StringRef;
 class Target;
+class raw_ostream;
 
 extern Target TheMipsTarget;
 extern Target TheMipselTarget;
@@ -33,6 +35,7 @@ MCCodeEmitter *createMipsMCCodeEmitter(const MCInstrInfo &MCII,
                                        MCContext &Ctx);
 
 MCAsmBackend *createMipsAsmBackend(const Target &T, StringRef TT);
+
 } // End llvm namespace
 
 // Defines symbolic names for Mips registers.  This defines a mapping from
index d72693c0940d95f3bb9ae33a98d6a657dd65bc2c..94f7c18eec4e0cef36a3093f3ed1fce99c2487e2 100644 (file)
@@ -15,7 +15,7 @@ TARGET = Mips
 BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
                 MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
                 MipsGenDAGISel.inc MipsGenCallingConv.inc \
-                MipsGenSubtargetInfo.inc
+                MipsGenSubtargetInfo.inc MipsGenMCCodeEmitter.inc
 
 DIRS = InstPrinter TargetInfo MCTargetDesc
 
index d7b7f06c72df05b06c442b892598901d85df8ace..186a5e3949cbc43b521f62de8523309b529d2420 100644 (file)
@@ -20,6 +20,7 @@
 #include "MipsMCInstLower.h"
 #include "MipsMCSymbolRefExpr.h"
 #include "InstPrinter/MipsInstPrinter.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
index dc4ecd690053e9e5476b08c51f93e8305a002ee5..a8f29ae7a615596ef6d95e3164c9d9138d15b513 100644 (file)
 #include "MipsRelocations.h"
 #include "MipsSubtarget.h"
 #include "MipsTargetMachine.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/PassManager.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/JITCodeEmitter.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/Passes.h"
-#include "llvm/ADT/Statistic.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/PassManager.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
@@ -37,8 +39,6 @@
 #include <iomanip>
 #endif
 
-#include "llvm/CodeGen/MachineOperand.h"
-
 using namespace llvm;
 
 STATISTIC(NumEmitted, "Number of machine instructions emitted");
@@ -66,9 +66,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
   public:
     MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
       MachineFunctionPass(ID), JTI(0),
-        II((const MipsInstrInfo *) tm.getInstrInfo()),
-        TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
-        IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
+      II((const MipsInstrInfo *) tm.getInstrInfo()),
+      TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
+      IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
     }
 
     bool runOnMachineFunction(MachineFunction &MF);
@@ -91,7 +91,7 @@ class MipsCodeEmitter : public MachineFunctionPass {
     /// Routines that handle operands which add machine relocations which are
     /// fixed up by the relocation stage.
     void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
-                                bool MayNeedFarStub) const;
+                           bool MayNeedFarStub) const;
     void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
     void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
     void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
@@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
     unsigned getRelocation(const MachineInstr &MI,
                            const MachineOperand &MO) const;
 
+    unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
+
+    unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
     unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
@@ -165,23 +168,34 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
   return Mips::reloc_mips_lo;
 }
 
+unsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI,
+                                               unsigned OpNo) const {
+  // FIXME: implement
+  return 0;
+}
+
+unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
+                                                 unsigned OpNo) const {
+  // FIXME: implement
+  return 0;
+}
+
 unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
-                                          unsigned OpNo) const {
+                                         unsigned OpNo) const {
   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
   assert(MI.getOperand(OpNo).isReg());
   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
-  return
-    (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
+  return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
 }
 
 unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
-                                          unsigned OpNo) const {
+                                             unsigned OpNo) const {
   // size is encoded as size-1.
   return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
 }
 
 unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
-                                          unsigned OpNo) const {
+                                             unsigned OpNo) const {
   // size is encoded as pos+size-1.
   return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
          getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
@@ -190,7 +204,7 @@ unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
 /// getMachineOpValue - Return binary encoding of operand. If the machine
 /// operand requires relocation, record the relocation and return zero.
 unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
-                                           const MachineOperand &MO) const {
+                                            const MachineOperand &MO) const {
   if (MO.isReg())
     return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
   else if (MO.isImm())
@@ -217,9 +231,10 @@ unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
 }
 
 void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
-                                                bool MayNeedFarStub) const {
+                                        bool MayNeedFarStub) const {
   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
-                             const_cast<GlobalValue *>(GV), 0, MayNeedFarStub));
+                                             const_cast<GlobalValue *>(GV), 0,
+                                             MayNeedFarStub));
 }
 
 void MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV,
@@ -248,7 +263,7 @@ emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
 }
 
 void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
-                                           unsigned Reloc) const {
+                                            unsigned Reloc) const {
   MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
                                              Reloc, BB));
 }
@@ -395,7 +410,7 @@ void MipsCodeEmitter::emitWordLE(unsigned Word) {
 /// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
 /// code to the specified MCE object.
 FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
-    JITCodeEmitter &JCE) {
+                                                 JITCodeEmitter &JCE) {
   return new MipsCodeEmitter(TM, JCE);
 }
 
index 68adfe6b8a52da43181beec419a07419baa50e19..07de251193671828e29dfee2b5af09dcc2b71d89 100644 (file)
@@ -14,6 +14,7 @@
 #include "MipsFrameLowering.h"
 #include "MipsInstrInfo.h"
 #include "MipsMachineFunction.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "llvm/Function.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
index 2b0e90b894ea4da0b6dc57334dc15e21a95272fa..96ec588d88bb209dfb082af4b8c61bd62687ae9d 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/CallingConv.h"
 #include "InstPrinter/MipsInstPrinter.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
index 271d2487ecfaac0fb08b4cbe46d37dea53e05df0..8fa30529b8d6a822e086ff36a2a240a435752a1a 100644 (file)
@@ -30,86 +30,6 @@ namespace Mips {
   unsigned GetOppositeBranchOpc(unsigned Opc);
 }
 
-/// MipsII - This namespace holds all of the target specific flags that
-/// instruction info tracks.
-///
-namespace MipsII {
-  /// Target Operand Flag enum.
-  enum TOF {
-    //===------------------------------------------------------------------===//
-    // Mips Specific MachineOperand flags.
-
-    MO_NO_FLAG,
-
-    /// MO_GOT - Represents the offset into the global offset table at which
-    /// the address the relocation entry symbol resides during execution.
-    MO_GOT,
-
-    /// MO_GOT_CALL - Represents the offset into the global offset table at
-    /// which the address of a call site relocation entry symbol resides
-    /// during execution. This is different from the above since this flag
-    /// can only be present in call instructions.
-    MO_GOT_CALL,
-
-    /// MO_GPREL - Represents the offset from the current gp value to be used
-    /// for the relocatable object file being produced.
-    MO_GPREL,
-
-    /// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol
-    /// address.
-    MO_ABS_HI,
-    MO_ABS_LO,
-
-    /// MO_TLSGD - Represents the offset into the global offset table at which
-    // the module ID and TSL block offset reside during execution (General
-    // Dynamic TLS).
-    MO_TLSGD,
-
-    /// MO_GOTTPREL - Represents the offset from the thread pointer (Initial
-    // Exec TLS).
-    MO_GOTTPREL,
-
-    /// MO_TPREL_HI/LO - Represents the hi and low part of the offset from
-    // the thread pointer (Local Exec TLS).
-    MO_TPREL_HI,
-    MO_TPREL_LO,
-
-    // N32/64 Flags.
-    MO_GPOFF_HI,
-    MO_GPOFF_LO,
-    MO_GOT_DISP,
-    MO_GOT_PAGE,
-    MO_GOT_OFST
-  };
-
-  enum {
-    //===------------------------------------------------------------------===//
-    // Instruction encodings.  These are the standard/most common forms for
-    // Mips instructions.
-    //
-
-    // Pseudo - This represents an instruction that is a pseudo instruction
-    // or one that has not been implemented yet.  It is illegal to code generate
-    // it, but tolerated for intermediate implementation stages.
-    Pseudo   = 0,
-
-    /// FrmR - This form is for instructions of the format R.
-    FrmR  = 1,
-    /// FrmI - This form is for instructions of the format I.
-    FrmI  = 2,
-    /// FrmJ - This form is for instructions of the format J.
-    FrmJ  = 3,
-    /// FrmFR - This form is for instructions of the format FR.
-    FrmFR = 4,
-    /// FrmFI - This form is for instructions of the format FI.
-    FrmFI = 5,
-    /// FrmOther - This form is for instructions that have no specific format.
-    FrmOther = 6,
-
-    FormMask = 15
-  };
-}
-
 class MipsInstrInfo : public MipsGenInstrInfo {
   MipsTargetMachine &TM;
   bool IsN64;
index a58ce9904c083e4d19632c6087ae924c8b580eed..5dca9b67104ee28125c942d3b859deb6de7d2299 100644 (file)
@@ -138,7 +138,13 @@ def NotN64      : Predicate<"!Subtarget.isABI_N64()">;
 //===----------------------------------------------------------------------===//
 
 // Instruction operand types
-def brtarget    : Operand<OtherVT>;
+def jmptarget   : Operand<OtherVT> {
+  let EncoderMethod = "getJumpTargetOpValue";
+}
+def brtarget    : Operand<OtherVT> {
+  let EncoderMethod = "getBranchTargetOpValue";
+  let OperandType = "OPERAND_PCREL";
+}
 def calltarget  : Operand<i32>;
 def calltarget64: Operand<i64>;
 def simm16      : Operand<i32>;
@@ -449,7 +455,7 @@ class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od,
 // Unconditional branch
 let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in
 class JumpFJ<bits<6> op, string instr_asm>:
-  FJ<op, (outs), (ins brtarget:$target),
+  FJ<op, (outs), (ins jmptarget:$target),
      !strconcat(instr_asm, "\t$target"), [(br bb:$target)], IIBranch>;
 
 let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in
index 6c0e4f6d09e650e26ded1aa1d633138b30d46d7e..1fab52c8402ab51efc42a693ebe7ac0faa5d76f5 100644 (file)
@@ -15,6 +15,7 @@
 #include "MipsAsmPrinter.h"
 #include "MipsInstrInfo.h"
 #include "MipsMCInstLower.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineOperand.h"