Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,14 +0,0 @@
add_llvm_library(LLVMMipsDesc
MipsABIInfo.cpp
MipsABIFlagsSection.cpp
MipsAsmBackend.cpp
MipsELFObjectWriter.cpp
MipsELFStreamer.cpp
MipsMCAsmInfo.cpp
MipsMCCodeEmitter.cpp
MipsMCExpr.cpp
MipsMCTargetDesc.cpp
MipsNaClELFStreamer.cpp
MipsOptionRecord.cpp
MipsTargetStreamer.cpp
)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/Mips/MCTargetDesc/LLVMBuild.txt -------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MipsDesc
parent = Mips
required_libraries = MC MipsAsmPrinter MipsInfo Support
add_to_library_groups = Mips

View File

@ -1,75 +0,0 @@
//===- MipsABIFlagsSection.cpp - Mips ELF ABI Flags Section ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/MipsABIFlagsSection.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MipsABIFlags.h"
using namespace llvm;
uint8_t MipsABIFlagsSection::getFpABIValue() {
switch (FpABI) {
case FpABIKind::ANY:
return Mips::Val_GNU_MIPS_ABI_FP_ANY;
case FpABIKind::SOFT:
return Mips::Val_GNU_MIPS_ABI_FP_SOFT;
case FpABIKind::XX:
return Mips::Val_GNU_MIPS_ABI_FP_XX;
case FpABIKind::S32:
return Mips::Val_GNU_MIPS_ABI_FP_DOUBLE;
case FpABIKind::S64:
if (Is32BitABI)
return OddSPReg ? Mips::Val_GNU_MIPS_ABI_FP_64
: Mips::Val_GNU_MIPS_ABI_FP_64A;
return Mips::Val_GNU_MIPS_ABI_FP_DOUBLE;
}
llvm_unreachable("unexpected fp abi value");
}
StringRef MipsABIFlagsSection::getFpABIString(FpABIKind Value) {
switch (Value) {
case FpABIKind::XX:
return "xx";
case FpABIKind::S32:
return "32";
case FpABIKind::S64:
return "64";
default:
llvm_unreachable("unsupported fp abi value");
}
}
uint8_t MipsABIFlagsSection::getCPR1SizeValue() {
if (FpABI == FpABIKind::XX)
return (uint8_t)Mips::AFL_REG_32;
return (uint8_t)CPR1Size;
}
namespace llvm {
MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection) {
// Write out a Elf_Internal_ABIFlags_v0 struct
OS.EmitIntValue(ABIFlagsSection.getVersionValue(), 2); // version
OS.EmitIntValue(ABIFlagsSection.getISALevelValue(), 1); // isa_level
OS.EmitIntValue(ABIFlagsSection.getISARevisionValue(), 1); // isa_rev
OS.EmitIntValue(ABIFlagsSection.getGPRSizeValue(), 1); // gpr_size
OS.EmitIntValue(ABIFlagsSection.getCPR1SizeValue(), 1); // cpr1_size
OS.EmitIntValue(ABIFlagsSection.getCPR2SizeValue(), 1); // cpr2_size
OS.EmitIntValue(ABIFlagsSection.getFpABIValue(), 1); // fp_abi
OS.EmitIntValue(ABIFlagsSection.getISAExtensionValue(), 4); // isa_ext
OS.EmitIntValue(ABIFlagsSection.getASESetValue(), 4); // ases
OS.EmitIntValue(ABIFlagsSection.getFlags1Value(), 4); // flags1
OS.EmitIntValue(ABIFlagsSection.getFlags2Value(), 4); // flags2
return OS;
}
} // end namespace llvm

View File

@ -1,201 +0,0 @@
//===- MipsABIFlagsSection.h - Mips ELF ABI Flags Section -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MipsABIFlags.h"
#include <cstdint>
namespace llvm {
class MCStreamer;
struct MipsABIFlagsSection {
// Internal representation of the fp_abi related values used in .module.
enum class FpABIKind { ANY, XX, S32, S64, SOFT };
// Version of flags structure.
uint16_t Version = 0;
// The level of the ISA: 1-5, 32, 64.
uint8_t ISALevel = 0;
// The revision of ISA: 0 for MIPS V and below, 1-n otherwise.
uint8_t ISARevision = 0;
// The size of general purpose registers.
Mips::AFL_REG GPRSize = Mips::AFL_REG_NONE;
// The size of co-processor 1 registers.
Mips::AFL_REG CPR1Size = Mips::AFL_REG_NONE;
// The size of co-processor 2 registers.
Mips::AFL_REG CPR2Size = Mips::AFL_REG_NONE;
// Processor-specific extension.
Mips::AFL_EXT ISAExtension = Mips::AFL_EXT_NONE;
// Mask of ASEs used.
uint32_t ASESet = 0;
bool OddSPReg = false;
bool Is32BitABI = false;
protected:
// The floating-point ABI.
FpABIKind FpABI = FpABIKind::ANY;
public:
MipsABIFlagsSection() = default;
uint16_t getVersionValue() { return (uint16_t)Version; }
uint8_t getISALevelValue() { return (uint8_t)ISALevel; }
uint8_t getISARevisionValue() { return (uint8_t)ISARevision; }
uint8_t getGPRSizeValue() { return (uint8_t)GPRSize; }
uint8_t getCPR1SizeValue();
uint8_t getCPR2SizeValue() { return (uint8_t)CPR2Size; }
uint8_t getFpABIValue();
uint32_t getISAExtensionValue() { return (uint32_t)ISAExtension; }
uint32_t getASESetValue() { return (uint32_t)ASESet; }
uint32_t getFlags1Value() {
uint32_t Value = 0;
if (OddSPReg)
Value |= (uint32_t)Mips::AFL_FLAGS1_ODDSPREG;
return Value;
}
uint32_t getFlags2Value() { return 0; }
FpABIKind getFpABI() { return FpABI; }
void setFpABI(FpABIKind Value, bool IsABI32Bit) {
FpABI = Value;
Is32BitABI = IsABI32Bit;
}
StringRef getFpABIString(FpABIKind Value);
template <class PredicateLibrary>
void setISALevelAndRevisionFromPredicates(const PredicateLibrary &P) {
if (P.hasMips64()) {
ISALevel = 64;
if (P.hasMips64r6())
ISARevision = 6;
else if (P.hasMips64r5())
ISARevision = 5;
else if (P.hasMips64r3())
ISARevision = 3;
else if (P.hasMips64r2())
ISARevision = 2;
else
ISARevision = 1;
} else if (P.hasMips32()) {
ISALevel = 32;
if (P.hasMips32r6())
ISARevision = 6;
else if (P.hasMips32r5())
ISARevision = 5;
else if (P.hasMips32r3())
ISARevision = 3;
else if (P.hasMips32r2())
ISARevision = 2;
else
ISARevision = 1;
} else {
ISARevision = 0;
if (P.hasMips5())
ISALevel = 5;
else if (P.hasMips4())
ISALevel = 4;
else if (P.hasMips3())
ISALevel = 3;
else if (P.hasMips2())
ISALevel = 2;
else if (P.hasMips1())
ISALevel = 1;
else
llvm_unreachable("Unknown ISA level!");
}
}
template <class PredicateLibrary>
void setGPRSizeFromPredicates(const PredicateLibrary &P) {
GPRSize = P.isGP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
}
template <class PredicateLibrary>
void setCPR1SizeFromPredicates(const PredicateLibrary &P) {
if (P.useSoftFloat())
CPR1Size = Mips::AFL_REG_NONE;
else if (P.hasMSA())
CPR1Size = Mips::AFL_REG_128;
else
CPR1Size = P.isFP64bit() ? Mips::AFL_REG_64 : Mips::AFL_REG_32;
}
template <class PredicateLibrary>
void setISAExtensionFromPredicates(const PredicateLibrary &P) {
if (P.hasCnMips())
ISAExtension = Mips::AFL_EXT_OCTEON;
else
ISAExtension = Mips::AFL_EXT_NONE;
}
template <class PredicateLibrary>
void setASESetFromPredicates(const PredicateLibrary &P) {
ASESet = 0;
if (P.hasDSP())
ASESet |= Mips::AFL_ASE_DSP;
if (P.hasDSPR2())
ASESet |= Mips::AFL_ASE_DSPR2;
if (P.hasMSA())
ASESet |= Mips::AFL_ASE_MSA;
if (P.inMicroMipsMode())
ASESet |= Mips::AFL_ASE_MICROMIPS;
if (P.inMips16Mode())
ASESet |= Mips::AFL_ASE_MIPS16;
if (P.hasMT())
ASESet |= Mips::AFL_ASE_MT;
}
template <class PredicateLibrary>
void setFpAbiFromPredicates(const PredicateLibrary &P) {
Is32BitABI = P.isABI_O32();
FpABI = FpABIKind::ANY;
if (P.useSoftFloat())
FpABI = FpABIKind::SOFT;
else if (P.isABI_N32() || P.isABI_N64())
FpABI = FpABIKind::S64;
else if (P.isABI_O32()) {
if (P.isABI_FPXX())
FpABI = FpABIKind::XX;
else if (P.isFP64bit())
FpABI = FpABIKind::S64;
else
FpABI = FpABIKind::S32;
}
}
template <class PredicateLibrary>
void setAllFromPredicates(const PredicateLibrary &P) {
setISALevelAndRevisionFromPredicates(P);
setGPRSizeFromPredicates(P);
setCPR1SizeFromPredicates(P);
setISAExtensionFromPredicates(P);
setASESetFromPredicates(P);
setFpAbiFromPredicates(P);
OddSPReg = P.useOddSPReg();
}
};
MCStreamer &operator<<(MCStreamer &OS, MipsABIFlagsSection &ABIFlagsSection);
} // end namespace llvm
#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIFLAGSSECTION_H

View File

@ -1,119 +0,0 @@
//===---- MipsABIInfo.cpp - Information about MIPS ABI's ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MipsABIInfo.h"
#include "MipsRegisterInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/MC/MCTargetOptions.h"
using namespace llvm;
namespace {
static const MCPhysReg O32IntRegs[4] = {Mips::A0, Mips::A1, Mips::A2, Mips::A3};
static const MCPhysReg Mips64IntRegs[8] = {
Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
}
ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
if (IsO32())
return makeArrayRef(O32IntRegs);
if (IsN32() || IsN64())
return makeArrayRef(Mips64IntRegs);
llvm_unreachable("Unhandled ABI");
}
ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
if (IsO32())
return makeArrayRef(O32IntRegs);
if (IsN32() || IsN64())
return makeArrayRef(Mips64IntRegs);
llvm_unreachable("Unhandled ABI");
}
unsigned MipsABIInfo::GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const {
if (IsO32())
return CC != CallingConv::Fast ? 16 : 0;
if (IsN32() || IsN64())
return 0;
llvm_unreachable("Unhandled ABI");
}
MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU,
const MCTargetOptions &Options) {
if (Options.getABIName().startswith("o32"))
return MipsABIInfo::O32();
if (Options.getABIName().startswith("n32"))
return MipsABIInfo::N32();
if (Options.getABIName().startswith("n64"))
return MipsABIInfo::N64();
assert(Options.getABIName().empty() && "Unknown ABI option for MIPS");
if (TT.getArch() == Triple::mips64 || TT.getArch() == Triple::mips64el)
return MipsABIInfo::N64();
return MipsABIInfo::O32();
}
unsigned MipsABIInfo::GetStackPtr() const {
return ArePtrs64bit() ? Mips::SP_64 : Mips::SP;
}
unsigned MipsABIInfo::GetFramePtr() const {
return ArePtrs64bit() ? Mips::FP_64 : Mips::FP;
}
unsigned MipsABIInfo::GetBasePtr() const {
return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
}
unsigned MipsABIInfo::GetGlobalPtr() const {
return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
}
unsigned MipsABIInfo::GetNullPtr() const {
return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
}
unsigned MipsABIInfo::GetZeroReg() const {
return AreGprs64bit() ? Mips::ZERO_64 : Mips::ZERO;
}
unsigned MipsABIInfo::GetPtrAdduOp() const {
return ArePtrs64bit() ? Mips::DADDu : Mips::ADDu;
}
unsigned MipsABIInfo::GetPtrAddiuOp() const {
return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
}
unsigned MipsABIInfo::GetPtrSubuOp() const {
return ArePtrs64bit() ? Mips::DSUBu : Mips::SUBu;
}
unsigned MipsABIInfo::GetPtrAndOp() const {
return ArePtrs64bit() ? Mips::AND64 : Mips::AND;
}
unsigned MipsABIInfo::GetGPRMoveOp() const {
return ArePtrs64bit() ? Mips::OR64 : Mips::OR;
}
unsigned MipsABIInfo::GetEhDataReg(unsigned I) const {
static const unsigned EhDataReg[] = {
Mips::A0, Mips::A1, Mips::A2, Mips::A3
};
static const unsigned EhDataReg64[] = {
Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64
};
return IsN64() ? EhDataReg64[I] : EhDataReg[I];
}

View File

@ -1,82 +0,0 @@
//===---- MipsABIInfo.h - Information about MIPS ABI's --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIINFO_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSABIINFO_H
#include "llvm/ADT/Triple.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
namespace llvm {
template <typename T> class ArrayRef;
class MCTargetOptions;
class StringRef;
class TargetRegisterClass;
class MipsABIInfo {
public:
enum class ABI { Unknown, O32, N32, N64 };
protected:
ABI ThisABI;
public:
MipsABIInfo(ABI ThisABI) : ThisABI(ThisABI) {}
static MipsABIInfo Unknown() { return MipsABIInfo(ABI::Unknown); }
static MipsABIInfo O32() { return MipsABIInfo(ABI::O32); }
static MipsABIInfo N32() { return MipsABIInfo(ABI::N32); }
static MipsABIInfo N64() { return MipsABIInfo(ABI::N64); }
static MipsABIInfo computeTargetABI(const Triple &TT, StringRef CPU,
const MCTargetOptions &Options);
bool IsKnown() const { return ThisABI != ABI::Unknown; }
bool IsO32() const { return ThisABI == ABI::O32; }
bool IsN32() const { return ThisABI == ABI::N32; }
bool IsN64() const { return ThisABI == ABI::N64; }
ABI GetEnumValue() const { return ThisABI; }
/// The registers to use for byval arguments.
ArrayRef<MCPhysReg> GetByValArgRegs() const;
/// The registers to use for the variable argument list.
ArrayRef<MCPhysReg> GetVarArgRegs() const;
/// Obtain the size of the area allocated by the callee for arguments.
/// CallingConv::FastCall affects the value for O32.
unsigned GetCalleeAllocdArgSizeInBytes(CallingConv::ID CC) const;
/// Ordering of ABI's
/// MipsGenSubtargetInfo.inc will use this to resolve conflicts when given
/// multiple ABI options.
bool operator<(const MipsABIInfo Other) const {
return ThisABI < Other.GetEnumValue();
}
unsigned GetStackPtr() const;
unsigned GetFramePtr() const;
unsigned GetBasePtr() const;
unsigned GetGlobalPtr() const;
unsigned GetNullPtr() const;
unsigned GetZeroReg() const;
unsigned GetPtrAdduOp() const;
unsigned GetPtrAddiuOp() const;
unsigned GetPtrSubuOp() const;
unsigned GetPtrAndOp() const;
unsigned GetGPRMoveOp() const;
inline bool ArePtrs64bit() const { return IsN64(); }
inline bool AreGprs64bit() const { return IsN32() || IsN64(); }
unsigned GetEhDataReg(unsigned I) const;
};
}
#endif

View File

@ -1,484 +0,0 @@
//===-- MipsAsmBackend.cpp - Mips Asm Backend ----------------------------===//
//
// 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 class.
//
//===----------------------------------------------------------------------===//
//
#include "MCTargetDesc/MipsAsmBackend.h"
#include "MCTargetDesc/MipsFixupKinds.h"
#include "MCTargetDesc/MipsMCExpr.h"
#include "MCTargetDesc/MipsMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixupKindInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
// Prepare value for the target space for it
static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
MCContext &Ctx) {
unsigned Kind = Fixup.getKind();
// Add/subtract and shift
switch (Kind) {
default:
return 0;
case FK_Data_2:
case Mips::fixup_Mips_LO16:
case Mips::fixup_Mips_GPREL16:
case Mips::fixup_Mips_GPOFF_HI:
case Mips::fixup_Mips_GPOFF_LO:
case Mips::fixup_Mips_GOT_PAGE:
case Mips::fixup_Mips_GOT_OFST:
case Mips::fixup_Mips_GOT_DISP:
case Mips::fixup_Mips_GOT_LO16:
case Mips::fixup_Mips_CALL_LO16:
case Mips::fixup_MICROMIPS_LO16:
case Mips::fixup_MICROMIPS_GOT_PAGE:
case Mips::fixup_MICROMIPS_GOT_OFST:
case Mips::fixup_MICROMIPS_GOT_DISP:
case Mips::fixup_MIPS_PCLO16:
Value &= 0xffff;
break;
case FK_DTPRel_4:
case FK_DTPRel_8:
case FK_TPRel_4:
case FK_TPRel_8:
case FK_GPRel_4:
case FK_Data_4:
case FK_Data_8:
case Mips::fixup_Mips_SUB:
case Mips::fixup_MICROMIPS_SUB:
break;
case Mips::fixup_Mips_PC16:
// The displacement is then divided by 4 to give us an 18 bit
// address range. Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 4;
// We now check if Value can be encoded as a 16-bit signed immediate.
if (!isInt<16>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
return 0;
}
break;
case Mips::fixup_MIPS_PC19_S2:
case Mips::fixup_MICROMIPS_PC19_S2:
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 4;
// We now check if Value can be encoded as a 19-bit signed immediate.
if (!isInt<19>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup");
return 0;
}
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;
case Mips::fixup_Mips_HI16:
case Mips::fixup_Mips_GOT:
case Mips::fixup_MICROMIPS_GOT16:
case Mips::fixup_Mips_GOT_HI16:
case Mips::fixup_Mips_CALL_HI16:
case Mips::fixup_MICROMIPS_HI16:
case Mips::fixup_MIPS_PCHI16:
// Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
Value = ((Value + 0x8000) >> 16) & 0xffff;
break;
case Mips::fixup_Mips_HIGHER:
// Get the 3rd 16-bits.
Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
break;
case Mips::fixup_Mips_HIGHEST:
// Get the 4th 16-bits.
Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
break;
case Mips::fixup_MICROMIPS_26_S1:
Value >>= 1;
break;
case Mips::fixup_MICROMIPS_PC7_S1:
Value -= 4;
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 2;
// We now check if Value can be encoded as a 7-bit signed immediate.
if (!isInt<7>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup");
return 0;
}
break;
case Mips::fixup_MICROMIPS_PC10_S1:
Value -= 2;
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 2;
// We now check if Value can be encoded as a 10-bit signed immediate.
if (!isInt<10>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup");
return 0;
}
break;
case Mips::fixup_MICROMIPS_PC16_S1:
Value -= 4;
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 2;
// We now check if Value can be encoded as a 16-bit signed immediate.
if (!isInt<16>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
return 0;
}
break;
case Mips::fixup_MIPS_PC18_S3:
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 8;
// We now check if Value can be encoded as a 18-bit signed immediate.
if (!isInt<18>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
return 0;
}
break;
case Mips::fixup_MICROMIPS_PC18_S3:
// Check alignment.
if ((Value & 7)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
}
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 8;
// We now check if Value can be encoded as a 18-bit signed immediate.
if (!isInt<18>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
return 0;
}
break;
case Mips::fixup_MIPS_PC21_S2:
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 4;
// We now check if Value can be encoded as a 21-bit signed immediate.
if (!isInt<21>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
return 0;
}
break;
case Mips::fixup_MIPS_PC26_S2:
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 4;
// We now check if Value can be encoded as a 26-bit signed immediate.
if (!isInt<26>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup");
return 0;
}
break;
case Mips::fixup_MICROMIPS_PC26_S1:
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 2;
// We now check if Value can be encoded as a 26-bit signed immediate.
if (!isInt<26>(Value)) {
Ctx.reportFatalError(Fixup.getLoc(), "out of range PC26 fixup");
return 0;
}
break;
case Mips::fixup_MICROMIPS_PC21_S1:
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 2;
// We now check if Value can be encoded as a 21-bit signed immediate.
if (!isInt<21>(Value)) {
Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
return 0;
}
break;
}
return Value;
}
std::unique_ptr<MCObjectWriter>
MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
return createMipsELFObjectWriter(OS, TheTriple, IsN32);
}
// Little-endian fixup data byte ordering:
// mips32r2: a | b | x | x
// microMIPS: x | x | a | b
static bool needsMMLEByteOrder(unsigned Kind) {
return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
Kind >= Mips::fixup_MICROMIPS_26_S1 &&
Kind < Mips::LastTargetFixupKind;
}
// Calculate index for microMIPS specific little endian byte order
static unsigned calculateMMLEIndex(unsigned i) {
assert(i <= 3 && "Index out of range!");
return (1 - i / 2) * 2 + i % 2;
}
/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
bool IsResolved) const {
MCFixupKind Kind = Fixup.getKind();
MCContext &Ctx = Asm.getContext();
Value = adjustFixupValue(Fixup, Value, Ctx);
if (!Value)
return; // Doesn't change encoding.
// Where do we start in the object
unsigned Offset = Fixup.getOffset();
// Number of bytes we need to fixup
unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
// Used to point to big endian bytes
unsigned FullSize;
switch ((unsigned)Kind) {
case FK_Data_2:
case Mips::fixup_Mips_16:
case Mips::fixup_MICROMIPS_PC10_S1:
FullSize = 2;
break;
case FK_Data_8:
case Mips::fixup_Mips_64:
FullSize = 8;
break;
case FK_Data_4:
default:
FullSize = 4;
break;
}
// Grab current value, if any, from bits.
uint64_t CurVal = 0;
bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
: i)
: (FullSize - 1 - i);
CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
}
uint64_t Mask = ((uint64_t)(-1) >>
(64 - getFixupKindInfo(Kind).TargetSize));
CurVal |= Value & Mask;
// Write out the fixed up bytes back to the code/data bits.
for (unsigned i = 0; i != NumBytes; ++i) {
unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
: i)
: (FullSize - 1 - i);
Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
}
}
Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
return StringSwitch<Optional<MCFixupKind>>(Name)
.Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE)
.Case("R_MIPS_32", FK_Data_4)
.Default(MCAsmBackend::getFixupKind(Name));
}
const MCFixupKindInfo &MipsAsmBackend::
getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = {
// This table *must* be in same the order of fixup_* kinds in
// 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_GOT", 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_TLSLDM", 0, 16, 0 },
{ "fixup_Mips_DTPREL_HI", 0, 16, 0 },
{ "fixup_Mips_DTPREL_LO", 0, 16, 0 },
{ "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_Mips_GPOFF_HI", 0, 16, 0 },
{ "fixup_Mips_GPOFF_LO", 0, 16, 0 },
{ "fixup_Mips_GOT_PAGE", 0, 16, 0 },
{ "fixup_Mips_GOT_OFST", 0, 16, 0 },
{ "fixup_Mips_GOT_DISP", 0, 16, 0 },
{ "fixup_Mips_HIGHER", 0, 16, 0 },
{ "fixup_Mips_HIGHEST", 0, 16, 0 },
{ "fixup_Mips_GOT_HI16", 0, 16, 0 },
{ "fixup_Mips_GOT_LO16", 0, 16, 0 },
{ "fixup_Mips_CALL_HI16", 0, 16, 0 },
{ "fixup_Mips_CALL_LO16", 0, 16, 0 },
{ "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PCHI16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PCLO16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_26_S1", 0, 26, 0 },
{ "fixup_MICROMIPS_HI16", 0, 16, 0 },
{ "fixup_MICROMIPS_LO16", 0, 16, 0 },
{ "fixup_MICROMIPS_GOT16", 0, 16, 0 },
{ "fixup_MICROMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_CALL16", 0, 16, 0 },
{ "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 },
{ "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 },
{ "fixup_MICROMIPS_GOT_OFST", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_GD", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_LDM", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 },
{ "fixup_MICROMIPS_GOTTPREL", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 },
{ "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 },
{ "fixup_Mips_SUB", 0, 64, 0 },
{ "fixup_MICROMIPS_SUB", 0, 64, 0 }
};
const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = {
// This table *must* be in same the order of fixup_* kinds in
// MipsFixupKinds.h.
//
// name offset bits flags
{ "fixup_Mips_NONE", 0, 0, 0 },
{ "fixup_Mips_16", 16, 16, 0 },
{ "fixup_Mips_32", 0, 32, 0 },
{ "fixup_Mips_REL32", 0, 32, 0 },
{ "fixup_Mips_26", 6, 26, 0 },
{ "fixup_Mips_HI16", 16, 16, 0 },
{ "fixup_Mips_LO16", 16, 16, 0 },
{ "fixup_Mips_GPREL16", 16, 16, 0 },
{ "fixup_Mips_LITERAL", 16, 16, 0 },
{ "fixup_Mips_GOT", 16, 16, 0 },
{ "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_Mips_CALL16", 16, 16, 0 },
{ "fixup_Mips_GPREL32", 0, 32, 0 },
{ "fixup_Mips_SHIFT5", 21, 5, 0 },
{ "fixup_Mips_SHIFT6", 21, 5, 0 },
{ "fixup_Mips_64", 0, 64, 0 },
{ "fixup_Mips_TLSGD", 16, 16, 0 },
{ "fixup_Mips_GOTTPREL", 16, 16, 0 },
{ "fixup_Mips_TPREL_HI", 16, 16, 0 },
{ "fixup_Mips_TPREL_LO", 16, 16, 0 },
{ "fixup_Mips_TLSLDM", 16, 16, 0 },
{ "fixup_Mips_DTPREL_HI", 16, 16, 0 },
{ "fixup_Mips_DTPREL_LO", 16, 16, 0 },
{ "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_Mips_GPOFF_HI", 16, 16, 0 },
{ "fixup_Mips_GPOFF_LO", 16, 16, 0 },
{ "fixup_Mips_GOT_PAGE", 16, 16, 0 },
{ "fixup_Mips_GOT_OFST", 16, 16, 0 },
{ "fixup_Mips_GOT_DISP", 16, 16, 0 },
{ "fixup_Mips_HIGHER", 16, 16, 0 },
{ "fixup_Mips_HIGHEST", 16, 16, 0 },
{ "fixup_Mips_GOT_HI16", 16, 16, 0 },
{ "fixup_Mips_GOT_LO16", 16, 16, 0 },
{ "fixup_Mips_CALL_HI16", 16, 16, 0 },
{ "fixup_Mips_CALL_LO16", 16, 16, 0 },
{ "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PCHI16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PCLO16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_26_S1", 6, 26, 0 },
{ "fixup_MICROMIPS_HI16", 16, 16, 0 },
{ "fixup_MICROMIPS_LO16", 16, 16, 0 },
{ "fixup_MICROMIPS_GOT16", 16, 16, 0 },
{ "fixup_MICROMIPS_PC7_S1", 9, 7, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC10_S1", 6, 10, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MICROMIPS_CALL16", 16, 16, 0 },
{ "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 },
{ "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 },
{ "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_GD", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 },
{ "fixup_MICROMIPS_GOTTPREL", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 },
{ "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 },
{ "fixup_Mips_SUB", 0, 64, 0 },
{ "fixup_MICROMIPS_SUB", 0, 64, 0 }
};
if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind);
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
"Invalid kind!");
if (IsLittle)
return LittleEndianInfos[Kind - FirstTargetFixupKind];
return BigEndianInfos[Kind - FirstTargetFixupKind];
}
/// WriteNopData - Write an (optimal) nop sequence of Count bytes
/// to the given output. If the target cannot generate such a sequence,
/// it should return an error.
///
/// \return - True on success.
bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
// Check for a less than instruction size number of bytes
// FIXME: 16 bit instructions are not handled yet here.
// We shouldn't be using a hard coded number for instruction size.
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
OW->WriteZeros(Count);
return true;
}
MCAsmBackend *llvm::createMipsAsmBackend(const Target &T,
const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
const MCTargetOptions &Options) {
return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(),
Options.ABIName == "n32");
}

View File

@ -1,92 +0,0 @@
//===-- MipsAsmBackend.h - Mips Asm Backend ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MipsAsmBackend class.
//
//===----------------------------------------------------------------------===//
//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSASMBACKEND_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSASMBACKEND_H
#include "MCTargetDesc/MipsFixupKinds.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCAsmBackend.h"
namespace llvm {
class MCAssembler;
struct MCFixupKindInfo;
class MCObjectWriter;
class MCRegisterInfo;
class Target;
class MipsAsmBackend : public MCAsmBackend {
Triple TheTriple;
bool IsLittle; // Big or little endian
bool IsN32;
public:
MipsAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT,
StringRef CPU, bool N32)
: TheTriple(TT), IsLittle(TT.isLittleEndian()), IsN32(N32) {}
std::unique_ptr<MCObjectWriter>
createObjectWriter(raw_pwrite_stream &OS) const override;
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsResolved) const override;
Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
unsigned getNumFixupKinds() const override {
return Mips::NumTargetFixupKinds;
}
/// @name Target Relaxation Interfaces
/// @{
/// MayNeedRelaxation - Check whether the given instruction may need
/// relaxation.
///
/// \param Inst - The instruction to test.
bool mayNeedRelaxation(const MCInst &Inst) const override {
return false;
}
/// fixupNeedsRelaxation - Target specific predicate for whether a given
/// fixup requires the associated instruction to be relaxed.
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const override {
// FIXME.
llvm_unreachable("RelaxInstruction() unimplemented");
return false;
}
/// RelaxInstruction - Relax the instruction in the given fragment
/// to the next wider instruction.
///
/// \param Inst - The instruction to relax, which may be the same
/// as the output.
/// \param [out] Res On return, the relaxed instruction.
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
MCInst &Res) const override {}
/// @}
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
}; // class MipsAsmBackend
} // namespace
#endif

View File

@ -1,134 +0,0 @@
//===-- MipsBaseInfo.h - Top level definitions for MIPS MC ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains small standalone helper functions and enum definitions for
// the Mips target useful for the compiler back-end and the MC libraries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSBASEINFO_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSBASEINFO_H
#include "MipsFixupKinds.h"
#include "MipsMCTargetDesc.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
/// MipsII - This namespace holds all of the target specific flags that
/// instruction info tracks.
///
namespace MipsII {
/// Target Operand Flag enum.
enum TOF {
//===------------------------------------------------------------------===//
// Mips Specific MachineOperand flags.
MO_NO_FLAG,
/// MO_GOT - Represents the offset into the global offset table at which
/// the address the relocation entry symbol resides during execution.
MO_GOT,
/// MO_GOT_CALL - Represents the offset into the global offset table at
/// which the address of a call site relocation entry symbol resides
/// during execution. This is different from the above since this flag
/// can only be present in call instructions.
MO_GOT_CALL,
/// MO_GPREL - Represents the offset from the current gp value to be used
/// for the relocatable object file being produced.
MO_GPREL,
/// MO_ABS_HI/LO - Represents the hi or low part of an absolute symbol
/// address.
MO_ABS_HI,
MO_ABS_LO,
/// MO_TLSGD - Represents the offset into the global offset table at which
// the module ID and TSL block offset reside during execution (General
// Dynamic TLS).
MO_TLSGD,
/// MO_TLSLDM - Represents the offset into the global offset table at which
// the module ID and TSL block offset reside during execution (Local
// Dynamic TLS).
MO_TLSLDM,
MO_DTPREL_HI,
MO_DTPREL_LO,
/// 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,
/// MO_HIGHER/HIGHEST - Represents the highest or higher half word of a
/// 64-bit symbol address.
MO_HIGHER,
MO_HIGHEST,
/// MO_GOT_HI16/LO16, MO_CALL_HI16/LO16 - Relocations used for large GOTs.
MO_GOT_HI16,
MO_GOT_LO16,
MO_CALL_HI16,
MO_CALL_LO16
};
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,
/// IsCTI - Instruction is a Control Transfer Instruction.
IsCTI = 1 << 4,
/// HasForbiddenSlot - Instruction has a forbidden slot.
HasForbiddenSlot = 1 << 5,
/// IsPCRelativeLoad - A Load instruction with implicit source register
/// ($pc) with explicit offset and destination register
IsPCRelativeLoad = 1 << 6,
/// HasFCCRegOperand - Instruction uses an $fcc<x> register.
HasFCCRegOperand = 1 << 7
};
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +0,0 @@
//===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MipsELFStreamer.h"
#include "MipsOptionRecord.h"
#include "MipsTargetStreamer.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/Casting.h"
using namespace llvm;
MipsELFStreamer::MipsELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter)
: MCELFStreamer(Context, std::move(MAB), OS, std::move(Emitter)) {
RegInfoRecord = new MipsRegInfoRecord(this, Context);
MipsOptionRecords.push_back(
std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
}
void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI, bool) {
MCELFStreamer::EmitInstruction(Inst, STI);
MCContext &Context = getContext();
const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
const MCOperand &Op = Inst.getOperand(OpIndex);
if (!Op.isReg())
continue;
unsigned Reg = Op.getReg();
RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
}
createPendingLabelRelocs();
}
void MipsELFStreamer::createPendingLabelRelocs() {
MipsTargetELFStreamer *ELFTargetStreamer =
static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
// FIXME: Also mark labels when in MIPS16 mode.
if (ELFTargetStreamer->isMicroMipsEnabled()) {
for (auto *L : Labels) {
auto *Label = cast<MCSymbolELF>(L);
getAssembler().registerSymbol(*Label);
Label->setOther(ELF::STO_MIPS_MICROMIPS);
}
}
Labels.clear();
}
void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCELFStreamer::EmitLabel(Symbol);
Labels.push_back(Symbol);
}
void MipsELFStreamer::SwitchSection(MCSection *Section,
const MCExpr *Subsection) {
MCELFStreamer::SwitchSection(Section, Subsection);
Labels.clear();
}
void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc) {
MCELFStreamer::EmitValueImpl(Value, Size, Loc);
Labels.clear();
}
void MipsELFStreamer::EmitMipsOptionRecords() {
for (const auto &I : MipsOptionRecords)
I->EmitMipsOptionRecord();
}
MCELFStreamer *llvm::createMipsELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS, std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll) {
return new MipsELFStreamer(Context, std::move(MAB), OS, std::move(Emitter));
}

View File

@ -1,75 +0,0 @@
//===- MipsELFStreamer.h - ELF Object Output --------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a custom MCELFStreamer which allows us to insert some hooks before
// emitting data into an actual object file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
#include "MipsOptionRecord.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCELFStreamer.h"
#include <memory>
namespace llvm {
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCSubtargetInfo;
class MipsELFStreamer : public MCELFStreamer {
SmallVector<std::unique_ptr<MipsOptionRecord>, 8> MipsOptionRecords;
MipsRegInfoRecord *RegInfoRecord;
SmallVector<MCSymbol*, 4> Labels;
public:
MipsELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter);
/// Overriding this function allows us to add arbitrary behaviour before the
/// \p Inst is actually emitted. For example, we can inspect the operands and
/// gather sufficient information that allows us to reason about the register
/// usage for the translation unit.
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
bool = false) override;
/// Overriding this function allows us to record all labels that should be
/// marked as microMIPS. Based on this data marking is done in
/// EmitInstruction.
void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
/// Overriding this function allows us to dismiss all labels that are
/// candidates for marking as microMIPS when .section directive is processed.
void SwitchSection(MCSection *Section,
const MCExpr *Subsection = nullptr) override;
/// Overriding this function allows us to dismiss all labels that are
/// candidates for marking as microMIPS when .word directive is emitted.
void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
/// Emits all the option records stored up until the point it's called.
void EmitMipsOptionRecords();
/// Mark labels as microMIPS, if necessary for the subtarget.
void createPendingLabelRelocs();
};
MCELFStreamer *createMipsELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll);
} // end namespace llvm
#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H

View File

@ -1,227 +0,0 @@
//===-- MipsFixupKinds.h - Mips Specific Fixup Entries ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSFIXUPKINDS_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSFIXUPKINDS_H
#include "llvm/MC/MCFixup.h"
namespace llvm {
namespace Mips {
// Although most of the current fixup types reflect a unique relocation
// one can have multiple fixup types for a given relocation and thus need
// to be uniquely named.
//
// This table *must* be in the same order of
// MCFixupKindInfo Infos[Mips::NumTargetFixupKinds]
// in MipsAsmBackend.cpp.
//
enum Fixups {
// Branch fixups resulting in R_MIPS_NONE.
fixup_Mips_NONE = FirstTargetFixupKind,
// Branch fixups resulting in R_MIPS_16.
fixup_Mips_16,
// Pure 32 bit data fixup resulting in - R_MIPS_32.
fixup_Mips_32,
// Full 32 bit data relative data fixup resulting in - R_MIPS_REL32.
fixup_Mips_REL32,
// Jump 26 bit fixup resulting in - R_MIPS_26.
fixup_Mips_26,
// Pure upper 16 bit fixup resulting in - R_MIPS_HI16.
fixup_Mips_HI16,
// Pure lower 16 bit fixup resulting in - R_MIPS_LO16.
fixup_Mips_LO16,
// 16 bit fixup for GP offest resulting in - R_MIPS_GPREL16.
fixup_Mips_GPREL16,
// 16 bit literal fixup resulting in - R_MIPS_LITERAL.
fixup_Mips_LITERAL,
// Symbol fixup resulting in - R_MIPS_GOT16.
fixup_Mips_GOT,
// PC relative branch fixup resulting in - R_MIPS_PC16.
fixup_Mips_PC16,
// resulting in - R_MIPS_CALL16.
fixup_Mips_CALL16,
// resulting in - R_MIPS_GPREL32.
fixup_Mips_GPREL32,
// resulting in - R_MIPS_SHIFT5.
fixup_Mips_SHIFT5,
// resulting in - R_MIPS_SHIFT6.
fixup_Mips_SHIFT6,
// Pure 64 bit data fixup resulting in - R_MIPS_64.
fixup_Mips_64,
// resulting in - R_MIPS_TLS_GD.
fixup_Mips_TLSGD,
// resulting in - R_MIPS_TLS_GOTTPREL.
fixup_Mips_GOTTPREL,
// resulting in - R_MIPS_TLS_TPREL_HI16.
fixup_Mips_TPREL_HI,
// resulting in - R_MIPS_TLS_TPREL_LO16.
fixup_Mips_TPREL_LO,
// resulting in - R_MIPS_TLS_LDM.
fixup_Mips_TLSLDM,
// resulting in - R_MIPS_TLS_DTPREL_HI16.
fixup_Mips_DTPREL_HI,
// resulting in - R_MIPS_TLS_DTPREL_LO16.
fixup_Mips_DTPREL_LO,
// PC relative branch fixup resulting in - R_MIPS_PC16
fixup_Mips_Branch_PCRel,
// resulting in - R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16
fixup_Mips_GPOFF_HI,
// resulting in - R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16
fixup_Mips_GPOFF_LO,
// resulting in - R_MIPS_PAGE
fixup_Mips_GOT_PAGE,
// resulting in - R_MIPS_GOT_OFST
fixup_Mips_GOT_OFST,
// resulting in - R_MIPS_GOT_DISP
fixup_Mips_GOT_DISP,
// resulting in - R_MIPS_GOT_HIGHER
fixup_Mips_HIGHER,
// resulting in - R_MIPS_HIGHEST
fixup_Mips_HIGHEST,
// resulting in - R_MIPS_GOT_HI16
fixup_Mips_GOT_HI16,
// resulting in - R_MIPS_GOT_LO16
fixup_Mips_GOT_LO16,
// resulting in - R_MIPS_CALL_HI16
fixup_Mips_CALL_HI16,
// resulting in - R_MIPS_CALL_LO16
fixup_Mips_CALL_LO16,
// resulting in - R_MIPS_PC18_S3
fixup_MIPS_PC18_S3,
// resulting in - R_MIPS_PC19_S2
fixup_MIPS_PC19_S2,
// resulting in - R_MIPS_PC21_S2
fixup_MIPS_PC21_S2,
// resulting in - R_MIPS_PC26_S2
fixup_MIPS_PC26_S2,
// resulting in - R_MIPS_PCHI16
fixup_MIPS_PCHI16,
// resulting in - R_MIPS_PCLO16
fixup_MIPS_PCLO16,
// resulting in - R_MICROMIPS_26_S1
fixup_MICROMIPS_26_S1,
// resulting in - R_MICROMIPS_HI16
fixup_MICROMIPS_HI16,
// resulting in - R_MICROMIPS_LO16
fixup_MICROMIPS_LO16,
// resulting in - R_MICROMIPS_GOT16
fixup_MICROMIPS_GOT16,
// resulting in - R_MICROMIPS_PC7_S1
fixup_MICROMIPS_PC7_S1,
// resulting in - R_MICROMIPS_PC10_S1
fixup_MICROMIPS_PC10_S1,
// resulting in - R_MICROMIPS_PC16_S1
fixup_MICROMIPS_PC16_S1,
// resulting in - R_MICROMIPS_PC26_S1
fixup_MICROMIPS_PC26_S1,
// resulting in - R_MICROMIPS_PC19_S2
fixup_MICROMIPS_PC19_S2,
// resulting in - R_MICROMIPS_PC18_S3
fixup_MICROMIPS_PC18_S3,
// resulting in - R_MICROMIPS_PC21_S1
fixup_MICROMIPS_PC21_S1,
// resulting in - R_MICROMIPS_CALL16
fixup_MICROMIPS_CALL16,
// resulting in - R_MICROMIPS_GOT_DISP
fixup_MICROMIPS_GOT_DISP,
// resulting in - R_MICROMIPS_GOT_PAGE
fixup_MICROMIPS_GOT_PAGE,
// resulting in - R_MICROMIPS_GOT_OFST
fixup_MICROMIPS_GOT_OFST,
// resulting in - R_MICROMIPS_TLS_GD
fixup_MICROMIPS_TLS_GD,
// resulting in - R_MICROMIPS_TLS_LDM
fixup_MICROMIPS_TLS_LDM,
// resulting in - R_MICROMIPS_TLS_DTPREL_HI16
fixup_MICROMIPS_TLS_DTPREL_HI16,
// resulting in - R_MICROMIPS_TLS_DTPREL_LO16
fixup_MICROMIPS_TLS_DTPREL_LO16,
// resulting in - R_MICROMIPS_TLS_GOTTPREL.
fixup_MICROMIPS_GOTTPREL,
// resulting in - R_MICROMIPS_TLS_TPREL_HI16
fixup_MICROMIPS_TLS_TPREL_HI16,
// resulting in - R_MICROMIPS_TLS_TPREL_LO16
fixup_MICROMIPS_TLS_TPREL_LO16,
// resulting in - R_MIPS_SUB/R_MICROMIPS_SUB
fixup_Mips_SUB,
fixup_MICROMIPS_SUB,
// Marker
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
};
} // namespace Mips
} // namespace llvm
#endif

View File

@ -1,68 +0,0 @@
//===-- MipsMCAsmInfo.cpp - Mips Asm Properties ---------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declarations of the MipsMCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
#include "MipsMCAsmInfo.h"
#include "llvm/ADT/Triple.h"
using namespace llvm;
void MipsMCAsmInfo::anchor() { }
MipsMCAsmInfo::MipsMCAsmInfo(const Triple &TheTriple) {
IsLittleEndian = TheTriple.isLittleEndian();
if ((TheTriple.getArch() == Triple::mips64el) ||
(TheTriple.getArch() == Triple::mips64)) {
CodePointerSize = CalleeSaveStackSlotSize = 8;
}
// FIXME: This condition isn't quite right but it's the best we can do until
// this object can identify the ABI. It will misbehave when using O32
// on a mips64*-* triple.
if ((TheTriple.getArch() == Triple::mipsel) ||
(TheTriple.getArch() == Triple::mips)) {
PrivateGlobalPrefix = "$";
PrivateLabelPrefix = "$";
}
AlignmentIsInBytes = false;
Data16bitsDirective = "\t.2byte\t";
Data32bitsDirective = "\t.4byte\t";
Data64bitsDirective = "\t.8byte\t";
CommentString = "#";
ZeroDirective = "\t.space\t";
GPRel32Directive = "\t.gpword\t";
GPRel64Directive = "\t.gpdword\t";
DTPRel32Directive = "\t.dtprelword\t";
DTPRel64Directive = "\t.dtpreldword\t";
TPRel32Directive = "\t.tprelword\t";
TPRel64Directive = "\t.tpreldword\t";
UseAssignmentForEHBegin = true;
SupportsDebugInformation = true;
ExceptionsType = ExceptionHandling::DwarfCFI;
DwarfRegNumForCFI = true;
HasMipsExpressions = true;
// Enable IAS by default for O32.
if (TheTriple.getArch() == Triple::mips ||
TheTriple.getArch() == Triple::mipsel)
UseIntegratedAssembler = true;
// Enable IAS by default for Debian mips64/mips64el.
if (TheTriple.getEnvironment() == Triple::GNUABI64)
UseIntegratedAssembler = true;
// Enable IAS by default for Android mips64el that uses N64 ABI.
if (TheTriple.getArch() == Triple::mips64el && TheTriple.isAndroid())
UseIntegratedAssembler = true;
}

View File

@ -1,31 +0,0 @@
//===-- MipsMCAsmInfo.h - Mips Asm Info ------------------------*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the MipsMCAsmInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCASMINFO_H
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
class Triple;
class MipsMCAsmInfo : public MCAsmInfoELF {
void anchor() override;
public:
explicit MipsMCAsmInfo(const Triple &TheTriple);
};
} // namespace llvm
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +0,0 @@
//===- MipsMCCodeEmitter.h - Convert Mips Code to Machine Code --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MipsMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCCODEEMITTER_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCCODEEMITTER_H
#include "llvm/MC/MCCodeEmitter.h"
#include <cstdint>
namespace llvm {
class MCContext;
class MCExpr;
class MCFixup;
class MCInst;
class MCInstrInfo;
class MCOperand;
class MCSubtargetInfo;
class raw_ostream;
class MipsMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
MCContext &Ctx;
bool IsLittleEndian;
bool isMicroMips(const MCSubtargetInfo &STI) const;
bool isMips32r6(const MCSubtargetInfo &STI) const;
public:
MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, bool IsLittle)
: MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) {}
MipsMCCodeEmitter(const MipsMCCodeEmitter &) = delete;
MipsMCCodeEmitter &operator=(const MipsMCCodeEmitter &) = delete;
~MipsMCCodeEmitter() override = default;
void EmitByte(unsigned char C, raw_ostream &OS) const;
void EmitInstruction(uint64_t Val, unsigned Size, const MCSubtargetInfo &STI,
raw_ostream &OS) const;
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
// getBinaryCodeForInstr - TableGen'erated function for getting the
// binary encoding for an instruction.
uint64_t getBinaryCodeForInstr(const MCInst &MI,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getJumpTargetOpValue - 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 MCSubtargetInfo &STI) const;
// getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getUImm5Lsl2Encoding - Return binary encoding of the microMIPS jump
// target operand.
unsigned getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getSImm9AddiuspValue - Return binary encoding of the microMIPS addiusp
// instruction immediate operand.
unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) 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 MCSubtargetInfo &STI) const;
// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTarget7OpValue - Return binary encoding of the microMIPS branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
// 10-bit branch target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
// target operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTarget21OpValue - Return binary encoding of the branch
// offset operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTarget21OpValueMM - Return binary encoding of the branch
// offset operand for microMIPS. If the machine operand requires
// relocation,record the relocation and return zero.
unsigned getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTarget26OpValue - Return binary encoding of the branch
// offset operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getBranchTarget26OpValueMM - Return binary encoding of the branch
// offset operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getBranchTarget26OpValueMM(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
// getJumpOffset16OpValue - Return binary encoding of the jump
// offset operand. If the machine operand requires relocation,
// record the relocation and return zero.
unsigned getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) 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 MCSubtargetInfo &STI) const;
unsigned getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
template <unsigned ShiftAmount = 0>
unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Subtract Offset then encode as a N-bit unsigned integer.
template <unsigned Bits, int Offset>
unsigned getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getUImm4AndValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
private:
void LowerCompactBranch(MCInst& Inst) const;
};
} // end namespace llvm
#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCCODEEMITTER_H

View File

@ -1,293 +0,0 @@
//===-- MipsMCExpr.cpp - Mips specific MC expression classes --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MipsMCExpr.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
using namespace llvm;
#define DEBUG_TYPE "mipsmcexpr"
const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind,
const MCExpr *Expr, MCContext &Ctx) {
return new (Ctx) MipsMCExpr(Kind, Expr);
}
const MipsMCExpr *MipsMCExpr::createGpOff(MipsMCExpr::MipsExprKind Kind,
const MCExpr *Expr, MCContext &Ctx) {
return create(Kind, create(MEK_NEG, create(MEK_GPREL, Expr, Ctx), Ctx), Ctx);
}
void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
int64_t AbsVal;
switch (Kind) {
case MEK_None:
case MEK_Special:
llvm_unreachable("MEK_None and MEK_Special are invalid");
break;
case MEK_CALL_HI16:
OS << "%call_hi";
break;
case MEK_CALL_LO16:
OS << "%call_lo";
break;
case MEK_DTPREL_HI:
OS << "%dtprel_hi";
break;
case MEK_DTPREL_LO:
OS << "%dtprel_lo";
break;
case MEK_GOT:
OS << "%got";
break;
case MEK_GOTTPREL:
OS << "%gottprel";
break;
case MEK_GOT_CALL:
OS << "%call16";
break;
case MEK_GOT_DISP:
OS << "%got_disp";
break;
case MEK_GOT_HI16:
OS << "%got_hi";
break;
case MEK_GOT_LO16:
OS << "%got_lo";
break;
case MEK_GOT_PAGE:
OS << "%got_page";
break;
case MEK_GOT_OFST:
OS << "%got_ofst";
break;
case MEK_GPREL:
OS << "%gp_rel";
break;
case MEK_HI:
OS << "%hi";
break;
case MEK_HIGHER:
OS << "%higher";
break;
case MEK_HIGHEST:
OS << "%highest";
break;
case MEK_LO:
OS << "%lo";
break;
case MEK_NEG:
OS << "%neg";
break;
case MEK_PCREL_HI16:
OS << "%pcrel_hi";
break;
case MEK_PCREL_LO16:
OS << "%pcrel_lo";
break;
case MEK_TLSGD:
OS << "%tlsgd";
break;
case MEK_TLSLDM:
OS << "%tlsldm";
break;
case MEK_TPREL_HI:
OS << "%tprel_hi";
break;
case MEK_TPREL_LO:
OS << "%tprel_lo";
break;
}
OS << '(';
if (Expr->evaluateAsAbsolute(AbsVal))
OS << AbsVal;
else
Expr->print(OS, MAI, true);
OS << ')';
}
bool
MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout,
const MCFixup *Fixup) const {
// Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X))) special cases.
if (isGpOff()) {
const MCExpr *SubExpr =
cast<MipsMCExpr>(cast<MipsMCExpr>(getSubExpr())->getSubExpr())
->getSubExpr();
if (!SubExpr->evaluateAsRelocatable(Res, Layout, Fixup))
return false;
Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(),
MEK_Special);
return true;
}
if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
return false;
if (Res.getRefKind() != MCSymbolRefExpr::VK_None)
return false;
// evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the
// %hi/%lo/etc. here. Fixup is a null pointer when either of these is the
// caller.
if (Res.isAbsolute() && Fixup == nullptr) {
int64_t AbsVal = Res.getConstant();
switch (Kind) {
case MEK_None:
case MEK_Special:
llvm_unreachable("MEK_None and MEK_Special are invalid");
case MEK_DTPREL_HI:
case MEK_DTPREL_LO:
case MEK_GOT:
case MEK_GOTTPREL:
case MEK_GOT_CALL:
case MEK_GOT_DISP:
case MEK_GOT_HI16:
case MEK_GOT_LO16:
case MEK_GOT_OFST:
case MEK_GOT_PAGE:
case MEK_GPREL:
case MEK_PCREL_HI16:
case MEK_PCREL_LO16:
case MEK_TLSGD:
case MEK_TLSLDM:
case MEK_TPREL_HI:
case MEK_TPREL_LO:
return false;
case MEK_LO:
case MEK_CALL_LO16:
AbsVal = SignExtend64<16>(AbsVal);
break;
case MEK_CALL_HI16:
case MEK_HI:
AbsVal = SignExtend64<16>((AbsVal + 0x8000) >> 16);
break;
case MEK_HIGHER:
AbsVal = SignExtend64<16>((AbsVal + 0x80008000LL) >> 32);
break;
case MEK_HIGHEST:
AbsVal = SignExtend64<16>((AbsVal + 0x800080008000LL) >> 48);
break;
case MEK_NEG:
AbsVal = -AbsVal;
break;
}
Res = MCValue::get(AbsVal);
return true;
}
// We want to defer it for relocatable expressions since the constant is
// applied to the whole symbol value.
//
// The value of getKind() that is given to MCValue is only intended to aid
// debugging when inspecting MCValue objects. It shouldn't be relied upon
// for decision making.
Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
return true;
}
void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Streamer.visitUsedExpr(*getSubExpr());
}
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
switch (Expr->getKind()) {
case MCExpr::Target:
fixELFSymbolsInTLSFixupsImpl(cast<MipsMCExpr>(Expr)->getSubExpr(), Asm);
break;
case MCExpr::Constant:
break;
case MCExpr::Binary: {
const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
break;
}
case MCExpr::SymbolRef: {
// We're known to be under a TLS fixup, so any symbol should be
// modified. There should be only one.
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
break;
}
case MCExpr::Unary:
fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
break;
}
}
void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
switch (getKind()) {
case MEK_None:
case MEK_Special:
llvm_unreachable("MEK_None and MEK_Special are invalid");
break;
case MEK_CALL_HI16:
case MEK_CALL_LO16:
case MEK_GOT:
case MEK_GOT_CALL:
case MEK_GOT_DISP:
case MEK_GOT_HI16:
case MEK_GOT_LO16:
case MEK_GOT_OFST:
case MEK_GOT_PAGE:
case MEK_GPREL:
case MEK_HI:
case MEK_HIGHER:
case MEK_HIGHEST:
case MEK_LO:
case MEK_NEG:
case MEK_PCREL_HI16:
case MEK_PCREL_LO16:
// If we do have nested target-specific expressions, they will be in
// a consecutive chain.
if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr()))
E->fixELFSymbolsInTLSFixups(Asm);
break;
case MEK_DTPREL_HI:
case MEK_DTPREL_LO:
case MEK_TLSLDM:
case MEK_TLSGD:
case MEK_GOTTPREL:
case MEK_TPREL_HI:
case MEK_TPREL_LO:
fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
break;
}
}
bool MipsMCExpr::isGpOff(MipsExprKind &Kind) const {
if (getKind() == MEK_HI || getKind() == MEK_LO) {
if (const MipsMCExpr *S1 = dyn_cast<const MipsMCExpr>(getSubExpr())) {
if (const MipsMCExpr *S2 = dyn_cast<const MipsMCExpr>(S1->getSubExpr())) {
if (S1->getKind() == MEK_NEG && S2->getKind() == MEK_GPREL) {
Kind = getKind();
return true;
}
}
}
}
return false;
}

View File

@ -1,93 +0,0 @@
//===- MipsMCExpr.h - Mips specific MC expression classes -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCEXPR_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCEXPR_H
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
namespace llvm {
class MipsMCExpr : public MCTargetExpr {
public:
enum MipsExprKind {
MEK_None,
MEK_CALL_HI16,
MEK_CALL_LO16,
MEK_DTPREL_HI,
MEK_DTPREL_LO,
MEK_GOT,
MEK_GOTTPREL,
MEK_GOT_CALL,
MEK_GOT_DISP,
MEK_GOT_HI16,
MEK_GOT_LO16,
MEK_GOT_OFST,
MEK_GOT_PAGE,
MEK_GPREL,
MEK_HI,
MEK_HIGHER,
MEK_HIGHEST,
MEK_LO,
MEK_NEG,
MEK_PCREL_HI16,
MEK_PCREL_LO16,
MEK_TLSGD,
MEK_TLSLDM,
MEK_TPREL_HI,
MEK_TPREL_LO,
MEK_Special,
};
private:
const MipsExprKind Kind;
const MCExpr *Expr;
explicit MipsMCExpr(MipsExprKind Kind, const MCExpr *Expr)
: Kind(Kind), Expr(Expr) {}
public:
static const MipsMCExpr *create(MipsExprKind Kind, const MCExpr *Expr,
MCContext &Ctx);
static const MipsMCExpr *createGpOff(MipsExprKind Kind, const MCExpr *Expr,
MCContext &Ctx);
/// Get the kind of this expression.
MipsExprKind getKind() const { return Kind; }
/// Get the child of this expression.
const MCExpr *getSubExpr() const { return Expr; }
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
MCFragment *findAssociatedFragment() const override {
return getSubExpr()->findAssociatedFragment();
}
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
bool isGpOff(MipsExprKind &Kind) const;
bool isGpOff() const {
MipsExprKind Kind;
return isGpOff(Kind);
}
};
} // end namespace llvm
#endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCEXPR_H

View File

@ -1,32 +0,0 @@
//===-- MipsMCNaCl.h - NaCl-related declarations --------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCNACL_H
#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSMCNACL_H
#include "llvm/MC/MCELFStreamer.h"
namespace llvm {
// Log2 of the NaCl MIPS sandbox's instruction bundle size.
static const unsigned MIPS_NACL_BUNDLE_ALIGN = 4u;
bool isBasePlusOffsetMemoryAccess(unsigned Opcode, unsigned *AddrIdx,
bool *IsStore = nullptr);
bool baseRegNeedsLoadStoreMask(unsigned Reg);
// This function creates an MCELFStreamer for Mips NaCl.
MCELFStreamer *createMipsNaClELFStreamer(MCContext &Context,
std::unique_ptr<MCAsmBackend> TAB,
raw_pwrite_stream &OS,
std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll);
}
#endif

Some files were not shown because too many files have changed in this diff Show More