mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Mips MC object code emission improvements:
"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
This commit is contained in:
		| @@ -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 "MCTargetDesc/MipsMCTargetDesc.h" | ||||||
| #include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | ||||||
|  | #include "llvm/MC/MCAsmBackend.h" | ||||||
| #include "llvm/MC/MCAssembler.h" | #include "llvm/MC/MCAssembler.h" | ||||||
| #include "llvm/MC/MCDirectives.h" | #include "llvm/MC/MCDirectives.h" | ||||||
| #include "llvm/MC/MCELFObjectWriter.h" | #include "llvm/MC/MCELFObjectWriter.h" | ||||||
| @@ -8,7 +24,6 @@ | |||||||
| #include "llvm/MC/MCObjectWriter.h" | #include "llvm/MC/MCObjectWriter.h" | ||||||
| #include "llvm/MC/MCSectionELF.h" | #include "llvm/MC/MCSectionELF.h" | ||||||
| #include "llvm/MC/MCSectionMachO.h" | #include "llvm/MC/MCSectionMachO.h" | ||||||
| #include "llvm/MC/MCAsmBackend.h" |  | ||||||
| #include "llvm/MC/MCSubtargetInfo.h" | #include "llvm/MC/MCSubtargetInfo.h" | ||||||
| #include "llvm/Object/MachOFormat.h" | #include "llvm/Object/MachOFormat.h" | ||||||
| #include "llvm/Support/ELF.h" | #include "llvm/Support/ELF.h" | ||||||
| @@ -16,7 +31,50 @@ | |||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
| using namespace llvm; | 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 { | namespace { | ||||||
|  |  | ||||||
| class MipsELFObjectWriter : public MCELFObjectTargetWriter { | class MipsELFObjectWriter : public MCELFObjectTargetWriter { | ||||||
| public: | public: | ||||||
|   MipsELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine, |   MipsELFObjectWriter(bool is64Bit, Triple::OSType OSType, uint16_t EMachine, | ||||||
| @@ -27,18 +85,75 @@ public: | |||||||
|  |  | ||||||
| class MipsAsmBackend : public MCAsmBackend { | class MipsAsmBackend : public MCAsmBackend { | ||||||
| public: | public: | ||||||
|   MipsAsmBackend(const Target &T) |   MipsAsmBackend(const Target &T) : MCAsmBackend() {} | ||||||
|     : MCAsmBackend() {} |  | ||||||
|  |  | ||||||
|   unsigned getNumFixupKinds() const { |  | ||||||
|     return 1;   //tbd |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided |   /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided | ||||||
|   /// data fragment, at the offset specified by the fixup and following the |   /// data fragment, at the offset specified by the fixup and following the | ||||||
|   /// fixup kind as appropriate. |   /// fixup kind as appropriate. | ||||||
|   void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, |   void ApplyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, | ||||||
|                   uint64_t Value) const { |                   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 |   /// @name Target Relaxation Interfaces | ||||||
| @@ -52,24 +167,24 @@ public: | |||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /// RelaxInstruction - Relax the instruction in the given fragment to the next |   /// RelaxInstruction - Relax the instruction in the given fragment | ||||||
|   /// wider instruction. |   /// to the next wider instruction. | ||||||
|   /// |   /// | ||||||
|   /// \param Inst - The instruction to relax, which may be the same as the |   /// \param Inst - The instruction to relax, which may be the same | ||||||
|   /// output. |   /// as the output. | ||||||
|   /// \parm Res [output] - On return, the relaxed instruction. |   /// \parm Res [output] - On return, the relaxed instruction. | ||||||
|   void RelaxInstruction(const MCInst &Inst, MCInst &Res) const { |   void RelaxInstruction(const MCInst &Inst, MCInst &Res) const { | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   /// @} |   /// @} | ||||||
|  |  | ||||||
|   /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given |   /// WriteNopData - Write an (optimal) nop sequence of Count bytes | ||||||
|   /// output. If the target cannot generate such a sequence, it should return an |   /// to the given output. If the target cannot generate such a sequence, | ||||||
|   /// error. |   /// it should return an error. | ||||||
|   /// |   /// | ||||||
|   /// \return - True on success. |   /// \return - True on success. | ||||||
|   bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const { |   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); |     return new MipsELFObjectWriter(false, OSType, ELF::EM_MIPS, false); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| } | } // namespace | ||||||
|  |  | ||||||
| MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, StringRef TT) { | MCAsmBackend *llvm::createMipsAsmBackend(const Target &T, StringRef TT) { | ||||||
|   Triple TheTriple(TT); |   Triple TheTriple(TT); | ||||||
|   | |||||||
| @@ -19,6 +19,88 @@ | |||||||
| #include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | ||||||
|  |  | ||||||
| namespace llvm { | 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, | /// getMipsRegisterNumbering - Given the enum value for some register, | ||||||
| /// return the number that it corresponds to. | /// return the number that it corresponds to. | ||||||
| inline static unsigned getMipsRegisterNumbering(unsigned RegEnum) | inline static unsigned getMipsRegisterNumbering(unsigned RegEnum) | ||||||
|   | |||||||
| @@ -12,16 +12,18 @@ | |||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| // | // | ||||||
| #define DEBUG_TYPE "mccodeemitter" | #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/MCCodeEmitter.h" | ||||||
| #include "llvm/MC/MCExpr.h" | #include "llvm/MC/MCExpr.h" | ||||||
| #include "llvm/MC/MCInst.h" | #include "llvm/MC/MCInst.h" | ||||||
| #include "llvm/MC/MCInstrInfo.h" | #include "llvm/MC/MCInstrInfo.h" | ||||||
| #include "llvm/MC/MCRegisterInfo.h" | #include "llvm/MC/MCRegisterInfo.h" | ||||||
| #include "llvm/MC/MCSubtargetInfo.h" | #include "llvm/MC/MCSubtargetInfo.h" | ||||||
| #include "llvm/ADT/APFloat.h" |  | ||||||
| #include "llvm/ADT/Statistic.h" |  | ||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
| #include "MCTargetDesc/MipsMCTargetDesc.h" |  | ||||||
|  |  | ||||||
| using namespace llvm; | using namespace llvm; | ||||||
|  |  | ||||||
| @@ -31,22 +33,217 @@ class MipsMCCodeEmitter : public MCCodeEmitter { | |||||||
|   void operator=(const MipsMCCodeEmitter &); // DO NOT IMPLEMENT |   void operator=(const MipsMCCodeEmitter &); // DO NOT IMPLEMENT | ||||||
|   const MCInstrInfo &MCII; |   const MCInstrInfo &MCII; | ||||||
|   const MCSubtargetInfo &STI; |   const MCSubtargetInfo &STI; | ||||||
|  |   MCContext &Ctx; | ||||||
|  |  | ||||||
| public: | public: | ||||||
|   MipsMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, |   MipsMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, | ||||||
|                     MCContext &ctx) |                     MCContext &ctx) : MCII(mcii), STI(sti) , Ctx(ctx) {} | ||||||
|     : MCII(mcii), STI(sti) {} |  | ||||||
|  |  | ||||||
|   ~MipsMCCodeEmitter() {} |   ~MipsMCCodeEmitter() {} | ||||||
|  |  | ||||||
|   void EncodeInstruction(const MCInst &MI, raw_ostream &OS, |   void EmitByte(unsigned char C, raw_ostream &OS) const { | ||||||
|                          SmallVectorImpl<MCFixup> &Fixups) 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 | }; // class MipsMCCodeEmitter | ||||||
| }  // namespace | }  // namespace | ||||||
|  |  | ||||||
| MCCodeEmitter *llvm::createMipsMCCodeEmitter(const MCInstrInfo &MCII, | MCCodeEmitter *llvm::createMipsMCCodeEmitter(const MCInstrInfo &MCII, | ||||||
|                                              const MCSubtargetInfo &STI, |                                              const MCSubtargetInfo &STI, | ||||||
|                                              MCContext &Ctx) { |                                              MCContext &Ctx) | ||||||
|  | { | ||||||
|   return new MipsMCCodeEmitter(MCII, STI, 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" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,8 +11,8 @@ | |||||||
| // | // | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
| #include "MipsMCTargetDesc.h" |  | ||||||
| #include "MipsMCAsmInfo.h" | #include "MipsMCAsmInfo.h" | ||||||
|  | #include "MipsMCTargetDesc.h" | ||||||
| #include "InstPrinter/MipsInstPrinter.h" | #include "InstPrinter/MipsInstPrinter.h" | ||||||
| #include "llvm/MC/MachineLocation.h" | #include "llvm/MC/MachineLocation.h" | ||||||
| #include "llvm/MC/MCCodeGenInfo.h" | #include "llvm/MC/MCCodeGenInfo.h" | ||||||
| @@ -140,6 +140,9 @@ extern "C" void LLVMInitializeMipsTargetMC() { | |||||||
|   TargetRegistry::RegisterMCAsmBackend(TheMips64Target, createMipsAsmBackend); |   TargetRegistry::RegisterMCAsmBackend(TheMips64Target, createMipsAsmBackend); | ||||||
|   TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget, createMipsAsmBackend); |   TargetRegistry::RegisterMCAsmBackend(TheMips64elTarget, createMipsAsmBackend); | ||||||
|  |  | ||||||
|  |   TargetRegistry::RegisterMCCodeEmitter(TheMipsTarget, createMipsMCCodeEmitter); | ||||||
|  |   TargetRegistry::RegisterMCCodeEmitter(TheMipselTarget, createMipsMCCodeEmitter); | ||||||
|  |  | ||||||
|   // Register the MC subtarget info. |   // Register the MC subtarget info. | ||||||
|   TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget, |   TargetRegistry::RegisterMCSubtargetInfo(TheMipsTarget, | ||||||
|                                           createMipsMCSubtargetInfo); |                                           createMipsMCSubtargetInfo); | ||||||
|   | |||||||
| @@ -16,12 +16,14 @@ | |||||||
|  |  | ||||||
| namespace llvm { | namespace llvm { | ||||||
| class MCAsmBackend; | class MCAsmBackend; | ||||||
| class MCInstrInfo; |  | ||||||
| class MCCodeEmitter; | class MCCodeEmitter; | ||||||
| class MCContext; | class MCContext; | ||||||
|  | class MCInstrInfo; | ||||||
|  | class MCObjectWriter; | ||||||
| class MCSubtargetInfo; | class MCSubtargetInfo; | ||||||
| class StringRef; | class StringRef; | ||||||
| class Target; | class Target; | ||||||
|  | class raw_ostream; | ||||||
|  |  | ||||||
| extern Target TheMipsTarget; | extern Target TheMipsTarget; | ||||||
| extern Target TheMipselTarget; | extern Target TheMipselTarget; | ||||||
| @@ -33,6 +35,7 @@ MCCodeEmitter *createMipsMCCodeEmitter(const MCInstrInfo &MCII, | |||||||
|                                        MCContext &Ctx); |                                        MCContext &Ctx); | ||||||
|  |  | ||||||
| MCAsmBackend *createMipsAsmBackend(const Target &T, StringRef TT); | MCAsmBackend *createMipsAsmBackend(const Target &T, StringRef TT); | ||||||
|  |  | ||||||
| } // End llvm namespace | } // End llvm namespace | ||||||
|  |  | ||||||
| // Defines symbolic names for Mips registers.  This defines a mapping from | // Defines symbolic names for Mips registers.  This defines a mapping from | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ TARGET = Mips | |||||||
| BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \ | BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \ | ||||||
|                 MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \ |                 MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \ | ||||||
|                 MipsGenDAGISel.inc MipsGenCallingConv.inc \ |                 MipsGenDAGISel.inc MipsGenCallingConv.inc \ | ||||||
|                 MipsGenSubtargetInfo.inc |                 MipsGenSubtargetInfo.inc MipsGenMCCodeEmitter.inc | ||||||
|  |  | ||||||
| DIRS = InstPrinter TargetInfo MCTargetDesc | DIRS = InstPrinter TargetInfo MCTargetDesc | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ | |||||||
| #include "MipsMCInstLower.h" | #include "MipsMCInstLower.h" | ||||||
| #include "MipsMCSymbolRefExpr.h" | #include "MipsMCSymbolRefExpr.h" | ||||||
| #include "InstPrinter/MipsInstPrinter.h" | #include "InstPrinter/MipsInstPrinter.h" | ||||||
|  | #include "MCTargetDesc/MipsBaseInfo.h" | ||||||
| #include "llvm/ADT/SmallString.h" | #include "llvm/ADT/SmallString.h" | ||||||
| #include "llvm/ADT/StringExtras.h" | #include "llvm/ADT/StringExtras.h" | ||||||
| #include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | ||||||
|   | |||||||
| @@ -18,18 +18,20 @@ | |||||||
| #include "MipsRelocations.h" | #include "MipsRelocations.h" | ||||||
| #include "MipsSubtarget.h" | #include "MipsSubtarget.h" | ||||||
| #include "MipsTargetMachine.h" | #include "MipsTargetMachine.h" | ||||||
| #include "llvm/Constants.h" | #include "MCTargetDesc/MipsBaseInfo.h" | ||||||
| #include "llvm/DerivedTypes.h" | #include "llvm/ADT/Statistic.h" | ||||||
| #include "llvm/Function.h" |  | ||||||
| #include "llvm/PassManager.h" |  | ||||||
| #include "llvm/CodeGen/JITCodeEmitter.h" | #include "llvm/CodeGen/JITCodeEmitter.h" | ||||||
| #include "llvm/CodeGen/MachineConstantPool.h" | #include "llvm/CodeGen/MachineConstantPool.h" | ||||||
| #include "llvm/CodeGen/MachineFunctionPass.h" | #include "llvm/CodeGen/MachineFunctionPass.h" | ||||||
| #include "llvm/CodeGen/MachineInstr.h" | #include "llvm/CodeGen/MachineInstr.h" | ||||||
| #include "llvm/CodeGen/MachineJumpTableInfo.h" | #include "llvm/CodeGen/MachineJumpTableInfo.h" | ||||||
| #include "llvm/CodeGen/MachineModuleInfo.h" | #include "llvm/CodeGen/MachineModuleInfo.h" | ||||||
|  | #include "llvm/CodeGen/MachineOperand.h" | ||||||
| #include "llvm/CodeGen/Passes.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/Debug.h" | ||||||
| #include "llvm/Support/ErrorHandling.h" | #include "llvm/Support/ErrorHandling.h" | ||||||
| #include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||||
| @@ -37,8 +39,6 @@ | |||||||
| #include <iomanip> | #include <iomanip> | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include "llvm/CodeGen/MachineOperand.h" |  | ||||||
|  |  | ||||||
| using namespace llvm; | using namespace llvm; | ||||||
|  |  | ||||||
| STATISTIC(NumEmitted, "Number of machine instructions emitted"); | STATISTIC(NumEmitted, "Number of machine instructions emitted"); | ||||||
| @@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass { | |||||||
|     unsigned getRelocation(const MachineInstr &MI, |     unsigned getRelocation(const MachineInstr &MI, | ||||||
|                            const MachineOperand &MO) const; |                            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 getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; | ||||||
|     unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; |     unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; | ||||||
|     unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; |     unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; | ||||||
| @@ -165,13 +168,24 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI, | |||||||
|   return Mips::reloc_mips_lo; |   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 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. |   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. | ||||||
|   assert(MI.getOperand(OpNo).isReg()); |   assert(MI.getOperand(OpNo).isReg()); | ||||||
|   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16; |   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16; | ||||||
|   return |   return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits; | ||||||
|     (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI, | unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI, | ||||||
| @@ -219,7 +233,8 @@ unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, | |||||||
| void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, | void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, | ||||||
|                                         bool MayNeedFarStub) const { |                                         bool MayNeedFarStub) const { | ||||||
|   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, |   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, | void MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV, | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
| #include "MipsFrameLowering.h" | #include "MipsFrameLowering.h" | ||||||
| #include "MipsInstrInfo.h" | #include "MipsInstrInfo.h" | ||||||
| #include "MipsMachineFunction.h" | #include "MipsMachineFunction.h" | ||||||
|  | #include "MCTargetDesc/MipsBaseInfo.h" | ||||||
| #include "llvm/Function.h" | #include "llvm/Function.h" | ||||||
| #include "llvm/CodeGen/MachineFrameInfo.h" | #include "llvm/CodeGen/MachineFrameInfo.h" | ||||||
| #include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ | |||||||
| #include "llvm/Intrinsics.h" | #include "llvm/Intrinsics.h" | ||||||
| #include "llvm/CallingConv.h" | #include "llvm/CallingConv.h" | ||||||
| #include "InstPrinter/MipsInstPrinter.h" | #include "InstPrinter/MipsInstPrinter.h" | ||||||
|  | #include "MCTargetDesc/MipsBaseInfo.h" | ||||||
| #include "llvm/CodeGen/CallingConvLower.h" | #include "llvm/CodeGen/CallingConvLower.h" | ||||||
| #include "llvm/CodeGen/MachineFrameInfo.h" | #include "llvm/CodeGen/MachineFrameInfo.h" | ||||||
| #include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | ||||||
|   | |||||||
| @@ -30,86 +30,6 @@ namespace Mips { | |||||||
|   unsigned GetOppositeBranchOpc(unsigned Opc); |   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 { | class MipsInstrInfo : public MipsGenInstrInfo { | ||||||
|   MipsTargetMachine &TM; |   MipsTargetMachine &TM; | ||||||
|   bool IsN64; |   bool IsN64; | ||||||
|   | |||||||
| @@ -138,7 +138,13 @@ def NotN64      : Predicate<"!Subtarget.isABI_N64()">; | |||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
| // Instruction operand types | // 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 calltarget  : Operand<i32>; | ||||||
| def calltarget64: Operand<i64>; | def calltarget64: Operand<i64>; | ||||||
| def simm16      : Operand<i32>; | def simm16      : Operand<i32>; | ||||||
| @@ -449,7 +455,7 @@ class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od, | |||||||
| // Unconditional branch | // Unconditional branch | ||||||
| let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in | let isBranch=1, isTerminator=1, isBarrier=1, hasDelaySlot = 1 in | ||||||
| class JumpFJ<bits<6> op, string instr_asm>: | 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>; |      !strconcat(instr_asm, "\t$target"), [(br bb:$target)], IIBranch>; | ||||||
|  |  | ||||||
| let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in | let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1 in | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ | |||||||
| #include "MipsAsmPrinter.h" | #include "MipsAsmPrinter.h" | ||||||
| #include "MipsInstrInfo.h" | #include "MipsInstrInfo.h" | ||||||
| #include "MipsMCInstLower.h" | #include "MipsMCInstLower.h" | ||||||
|  | #include "MCTargetDesc/MipsBaseInfo.h" | ||||||
| #include "llvm/CodeGen/MachineFunction.h" | #include "llvm/CodeGen/MachineFunction.h" | ||||||
| #include "llvm/CodeGen/MachineInstr.h" | #include "llvm/CodeGen/MachineInstr.h" | ||||||
| #include "llvm/CodeGen/MachineOperand.h" | #include "llvm/CodeGen/MachineOperand.h" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user