forked from OSchip/llvm-project
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 llvm-svn: 144414
This commit is contained in:
parent
1094ded6f3
commit
c85e3ff334
|
@ -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");
|
||||||
|
@ -66,9 +66,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||||
public:
|
public:
|
||||||
MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
|
MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
|
||||||
MachineFunctionPass(ID), JTI(0),
|
MachineFunctionPass(ID), JTI(0),
|
||||||
II((const MipsInstrInfo *) tm.getInstrInfo()),
|
II((const MipsInstrInfo *) tm.getInstrInfo()),
|
||||||
TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
|
TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
|
||||||
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
|
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runOnMachineFunction(MachineFunction &MF);
|
bool runOnMachineFunction(MachineFunction &MF);
|
||||||
|
@ -91,7 +91,7 @@ class MipsCodeEmitter : public MachineFunctionPass {
|
||||||
/// Routines that handle operands which add machine relocations which are
|
/// Routines that handle operands which add machine relocations which are
|
||||||
/// fixed up by the relocation stage.
|
/// fixed up by the relocation stage.
|
||||||
void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
|
void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
|
||||||
bool MayNeedFarStub) const;
|
bool MayNeedFarStub) const;
|
||||||
void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
|
void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
|
||||||
void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
|
void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
|
||||||
void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
|
void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
|
||||||
|
@ -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,23 +168,34 @@ 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,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
// size is encoded as size-1.
|
// size is encoded as size-1.
|
||||||
return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
// size is encoded as pos+size-1.
|
// size is encoded as pos+size-1.
|
||||||
return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
|
return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
|
||||||
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
|
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||||
/// operand requires relocation, record the relocation and return zero.
|
/// operand requires relocation, record the relocation and return zero.
|
||||||
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
|
||||||
const MachineOperand &MO) const {
|
const MachineOperand &MO) const {
|
||||||
if (MO.isReg())
|
if (MO.isReg())
|
||||||
return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
|
return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
|
||||||
else if (MO.isImm())
|
else if (MO.isImm())
|
||||||
|
@ -217,9 +231,10 @@ 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,
|
||||||
|
@ -248,7 +263,7 @@ emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
|
void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
|
||||||
unsigned Reloc) const {
|
unsigned Reloc) const {
|
||||||
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
|
||||||
Reloc, BB));
|
Reloc, BB));
|
||||||
}
|
}
|
||||||
|
@ -395,7 +410,7 @@ void MipsCodeEmitter::emitWordLE(unsigned Word) {
|
||||||
/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
|
/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
|
||||||
/// code to the specified MCE object.
|
/// code to the specified MCE object.
|
||||||
FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
|
||||||
JITCodeEmitter &JCE) {
|
JITCodeEmitter &JCE) {
|
||||||
return new MipsCodeEmitter(TM, JCE);
|
return new MipsCodeEmitter(TM, JCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue