summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Mips/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MCTargetDesc')
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp13
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h7
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp62
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h1
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp17
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp2
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h3
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h5
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h13
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp73
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h25
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h4
-rw-r--r--contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp82
13 files changed, 247 insertions, 60 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
index 8e6c9e6..cdcc392 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
@@ -23,7 +23,7 @@ static const MCPhysReg Mips64IntRegs[8] = {
Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64};
}
-const ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
+ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
if (IsO32())
return makeArrayRef(O32IntRegs);
if (IsN32() || IsN64())
@@ -31,7 +31,7 @@ const ArrayRef<MCPhysReg> MipsABIInfo::GetByValArgRegs() const {
llvm_unreachable("Unhandled ABI");
}
-const ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
+ArrayRef<MCPhysReg> MipsABIInfo::GetVarArgRegs() const {
if (IsO32())
return makeArrayRef(O32IntRegs);
if (IsN32() || IsN64())
@@ -78,7 +78,6 @@ MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU,
.Case("mips32r3", MipsABIInfo::O32())
.Case("mips32r5", MipsABIInfo::O32())
.Case("mips32r6", MipsABIInfo::O32())
- .Case("mips16", MipsABIInfo::O32())
.Case("mips3", MipsABIInfo::N64())
.Case("mips4", MipsABIInfo::N64())
.Case("mips5", MipsABIInfo::N64())
@@ -107,6 +106,10 @@ 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;
}
@@ -115,6 +118,10 @@ unsigned MipsABIInfo::GetPtrAddiuOp() const {
return ArePtrs64bit() ? Mips::DADDiu : Mips::ADDiu;
}
+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
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
index 40c5681..ffa2c76 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
@@ -47,10 +47,10 @@ public:
ABI GetEnumValue() const { return ThisABI; }
/// The registers to use for byval arguments.
- const ArrayRef<MCPhysReg> GetByValArgRegs() const;
+ ArrayRef<MCPhysReg> GetByValArgRegs() const;
/// The registers to use for the variable argument list.
- const ArrayRef<MCPhysReg> GetVarArgRegs() const;
+ ArrayRef<MCPhysReg> GetVarArgRegs() const;
/// Obtain the size of the area allocated by the callee for arguments.
/// CallingConv::FastCall affects the value for O32.
@@ -67,9 +67,12 @@ public:
unsigned GetFramePtr() const;
unsigned GetBasePtr() const;
unsigned GetNullPtr() const;
+ unsigned GetZeroReg() const;
unsigned GetPtrAdduOp() const;
unsigned GetPtrAddiuOp() const;
+ unsigned GetGPRMoveOp() const;
inline bool ArePtrs64bit() const { return IsN64(); }
+ inline bool AreGprs64bit() const { return IsN32() || IsN64(); }
unsigned GetEhDataReg(unsigned I) const;
};
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 328e717..e4865e2 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -63,15 +63,19 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
// 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 (!isIntN(16, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC16 fixup");
+ if (!isInt<16>(Value) && Ctx) {
+ Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup");
+ return 0;
+ }
break;
case Mips::fixup_MIPS_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 (!isIntN(19, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC19 fixup");
+ if (!isInt<19>(Value) && Ctx) {
+ 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.
@@ -104,45 +108,57 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
// 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 (!isIntN(7, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC7 fixup");
+ if (!isInt<7>(Value) && Ctx) {
+ 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 (!isIntN(10, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC10 fixup");
+ if (!isInt<10>(Value) && Ctx) {
+ 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 (!isIntN(16, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC16 fixup");
+ if (!isInt<16>(Value) && Ctx) {
+ 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 (!isIntN(18, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC18 fixup");
+ if (!isInt<18>(Value) && Ctx) {
+ 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 (!isIntN(21, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC21 fixup");
+ if (!isInt<21>(Value) && Ctx) {
+ 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 (!isIntN(26, Value) && Ctx)
- Ctx->reportFatalError(Fixup.getLoc(), "out of range PC26 fixup");
+ if (!isInt<26>(Value) && Ctx) {
+ Ctx->reportError(Fixup.getLoc(), "out of range PC26 fixup");
+ return 0;
+ }
break;
}
@@ -232,6 +248,18 @@ void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
}
}
+bool MipsAsmBackend::getFixupKind(StringRef Name, MCFixupKind &MappedKind) const {
+ if (Name == "R_MIPS_NONE") {
+ MappedKind = (MCFixupKind)Mips::fixup_Mips_NONE;
+ return true;
+ }
+ if (Name == "R_MIPS_32") {
+ MappedKind = FK_Data_4;
+ return true;
+ }
+ return MCAsmBackend::getFixupKind(Name, MappedKind);
+}
+
const MCFixupKindInfo &MipsAsmBackend::
getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = {
@@ -239,6 +267,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
// 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 },
@@ -304,6 +333,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
// 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 },
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
index b3d5a49..1c9af92 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h
@@ -41,6 +41,7 @@ public:
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value, bool IsPCRel) const override;
+ bool getFixupKind(StringRef Name, MCFixupKind &MappedKind) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
unsigned getNumFixupKinds() const override {
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index 9b29527..5b9f02b 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -68,6 +68,8 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
unsigned Kind = (unsigned)Fixup.getKind();
switch (Kind) {
+ case Mips::fixup_Mips_NONE:
+ return ELF::R_MIPS_NONE;
case Mips::fixup_Mips_16:
case FK_Data_2:
return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;
@@ -325,13 +327,24 @@ static void setMatch(MipsRelocationEntry &Hi, MipsRelocationEntry &Lo) {
// matching LO;
// - prefer LOs without a pair;
// - prefer LOs with higher offset;
+
+static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
+ const ELFRelocationEntry &A = *AP;
+ const ELFRelocationEntry &B = *BP;
+ if (A.Offset != B.Offset)
+ return B.Offset - A.Offset;
+ if (B.Type != A.Type)
+ return A.Type - B.Type;
+ return 0;
+}
+
void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) {
if (Relocs.size() < 2)
return;
- // The default function sorts entries by Offset in descending order.
- MCELFObjectTargetWriter::sortRelocs(Asm, Relocs);
+ // Sorts entries by Offset in descending order.
+ array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
// Init MipsRelocs from Relocs.
std::vector<MipsRelocationEntry> MipsRelocs;
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
index b45d9cf..e7d687e 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
@@ -63,7 +63,7 @@ void MipsELFStreamer::SwitchSection(MCSection *Section,
}
void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
- const SMLoc &Loc) {
+ SMLoc Loc) {
MCELFStreamer::EmitValueImpl(Value, Size, Loc);
Labels.clear();
}
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index af9311f..a241cde 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
@@ -60,8 +60,7 @@ public:
/// 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,
- const SMLoc &Loc) override;
+ 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();
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
index e601963..3652f4b 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
@@ -23,8 +23,11 @@ namespace Mips {
// 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 = FirstTargetFixupKind,
+ fixup_Mips_16,
// Pure 32 bit data fixup resulting in - R_MIPS_32.
fixup_Mips_32,
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
index 5d23fcb..d4ccf03 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h
@@ -17,13 +17,14 @@
#include "llvm/MC/MCAsmInfoELF.h"
namespace llvm {
- class Triple;
+class Triple;
- class MipsMCAsmInfo : public MCAsmInfoELF {
- void anchor() override;
- public:
- explicit MipsMCAsmInfo(const Triple &TheTriple);
- };
+class MipsMCAsmInfo : public MCAsmInfoELF {
+ void anchor() override;
+
+public:
+ explicit MipsMCAsmInfo(const Triple &TheTriple);
+};
} // namespace llvm
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index e36263d..4b030eb 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -190,6 +190,10 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
else
NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
+ // Check whether it is Dsp instruction.
+ if (NewOpcode == -1)
+ NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
+
if (NewOpcode != -1) {
if (Fixups.size() > N)
Fixups.pop_back();
@@ -346,6 +350,23 @@ getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
return 0;
}
+/// getBranchTarget26OpValueMM - Return binary encoding of the branch
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
+ const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ // If the destination is an immediate, divide by 2.
+ if (MO.isImm())
+ return MO.getImm() >> 1;
+
+ // TODO: Push 26 PC fixup.
+ return 0;
+}
+
/// getJumpOffset16OpValue - Return binary encoding of the jump
/// target operand. If the machine operand requires relocation,
/// record the relocation and return zero.
@@ -745,7 +766,8 @@ getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
const MCSubtargetInfo &STI) const {
// Register is encoded in bits 9-5, offset is encoded in bits 4-0.
assert(MI.getOperand(OpNo).isReg() &&
- MI.getOperand(OpNo).getReg() == Mips::SP &&
+ (MI.getOperand(OpNo).getReg() == Mips::SP ||
+ MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
"Unexpected base register!");
unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
Fixups, STI) >> 2;
@@ -769,6 +791,19 @@ getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
}
unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
+ assert(MI.getOperand(OpNo).isReg());
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
+ STI) << 16;
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
+
+ return (OffBits & 0x1FF) | RegBits;
+}
+
+unsigned MipsMCCodeEmitter::
getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@@ -792,6 +827,19 @@ getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
}
unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) 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,
+ STI) << 16;
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
+
+ return (OffBits & 0xFFFF) | RegBits;
+}
+
+unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@@ -801,7 +849,9 @@ getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
default:
break;
case Mips::SWM16_MM:
+ case Mips::SWM16_MMR6:
case Mips::LWM16_MM:
+ case Mips::LWM16_MMR6:
OpNo = MI.getNumOperands() - 2;
break;
}
@@ -815,15 +865,6 @@ getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
return ((OffBits >> 2) & 0x0F);
}
-unsigned
-MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
- assert(MI.getOperand(OpNo).isImm());
- unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
- return SizeEncoding - 1;
-}
-
// FIXME: should be called getMSBEncoding
//
unsigned
@@ -838,13 +879,15 @@ MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
return Position + Size - 1;
}
+template <unsigned Bits, int Offset>
unsigned
-MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
- SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const {
+MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
assert(MI.getOperand(OpNo).isImm());
- // The immediate is encoded as 'immediate - 1'.
- return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
+ unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
+ Value -= Offset;
+ return Value;
}
unsigned
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index 911cc2f..fdacd17 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -137,6 +137,13 @@ public:
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.
@@ -172,23 +179,27 @@ public:
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 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 getSizeExtEncoding(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;
- // getLSAImmEncoding - Return binary encoding of LSA immediate.
- unsigned getLSAImmEncoding(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,
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
index fd2ed17..e889972 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
@@ -51,8 +51,8 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override {
- return getSubExpr()->findAssociatedSection();
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
}
// There are no TLS MipsMCExprs at the moment.
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
index e4da2df..e5fa755 100644
--- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
+++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
@@ -89,9 +89,15 @@ void MipsTargetStreamer::emitDirectiveSetHardFloat() {
void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
+void MipsTargetStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ forbidModuleDirective();
+}
void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) {
}
+void MipsTargetStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
+ bool SaveLocationIsRegister) {}
void MipsTargetStreamer::emitDirectiveModuleFP() {}
@@ -358,6 +364,12 @@ void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
forbidModuleDirective();
}
+void MipsTargetAsmStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ MipsTargetStreamer::emitDirectiveCpRestore(StoreInsts, Offset);
+ OS << "\t.cprestore\t" << Offset << "\n";
+}
+
void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
int RegOrOffset,
const MCSymbol &Sym,
@@ -373,7 +385,13 @@ void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo,
OS << ", ";
- OS << Sym.getName() << "\n";
+ OS << Sym.getName();
+ forbidModuleDirective();
+}
+
+void MipsTargetAsmStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
+ bool SaveLocationIsRegister) {
+ OS << "\t.cpreturn";
forbidModuleDirective();
}
@@ -595,8 +613,9 @@ void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
MCSectionELF *Sec = Context.getELFSection(".pdr", ELF::SHT_PROGBITS,
ELF::SHF_ALLOC | ELF::SHT_REL);
+ MCSymbol *Sym = Context.getOrCreateSymbol(Name);
const MCSymbolRefExpr *ExprRef =
- MCSymbolRefExpr::create(Name, MCSymbolRefExpr::VK_None, Context);
+ MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Context);
MCA.registerSection(*Sec);
Sec->setAlignment(4);
@@ -622,10 +641,25 @@ void MipsTargetELFStreamer::emitDirectiveEnd(StringRef Name) {
GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
OS.PopSection();
+
+ // .end also implicitly sets the size.
+ MCSymbol *CurPCSym = Context.createTempSymbol();
+ OS.EmitLabel(CurPCSym);
+ const MCExpr *Size = MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(CurPCSym, MCSymbolRefExpr::VK_None, Context),
+ ExprRef, Context);
+ int64_t AbsSize;
+ if (!Size->evaluateAsAbsolute(AbsSize, MCA))
+ llvm_unreachable("Function size must be evaluatable as absolute");
+ Size = MCConstantExpr::create(AbsSize, Context);
+ static_cast<MCSymbolELF *>(Sym)->setSize(Size);
}
void MipsTargetELFStreamer::emitDirectiveEnt(const MCSymbol &Symbol) {
GPRInfoSet = FPRInfoSet = FrameInfoSet = false;
+
+ // .ent also acts like an implicit '.type symbol, STT_FUNC'
+ static_cast<const MCSymbolELF &>(Symbol).setType(ELF::STT_FUNC);
}
void MipsTargetELFStreamer::emitDirectiveAbiCalls() {
@@ -752,6 +786,24 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
forbidModuleDirective();
}
+void MipsTargetELFStreamer::emitDirectiveCpRestore(
+ SmallVector<MCInst, 3> &StoreInsts, int Offset) {
+ MipsTargetStreamer::emitDirectiveCpRestore(StoreInsts, Offset);
+ // .cprestore offset
+ // When PIC mode is enabled and the O32 ABI is used, this directive expands
+ // to:
+ // sw $gp, offset($sp)
+ // and adds a corresponding LW after every JAL.
+
+ // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
+ // is used in non-PIC mode.
+ if (!Pic || (getABI().IsN32() || getABI().IsN64()))
+ return;
+
+ for (const MCInst &Inst : StoreInsts)
+ getStreamer().EmitInstruction(Inst, STI);
+}
+
void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
int RegOrOffset,
const MCSymbol &Sym,
@@ -766,7 +818,7 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
// Either store the old $gp in a register or on the stack
if (IsReg) {
// move $save, $gpreg
- Inst.setOpcode(Mips::DADDu);
+ Inst.setOpcode(Mips::OR64);
Inst.addOperand(MCOperand::createReg(RegOrOffset));
Inst.addOperand(MCOperand::createReg(Mips::GP));
Inst.addOperand(MCOperand::createReg(Mips::ZERO));
@@ -810,6 +862,30 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
forbidModuleDirective();
}
+void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
+ bool SaveLocationIsRegister) {
+ // Only N32 and N64 emit anything for .cpreturn iff PIC is set.
+ if (!Pic || !(getABI().IsN32() || getABI().IsN64()))
+ return;
+
+ MCInst Inst;
+ // Either restore the old $gp from a register or on the stack
+ if (SaveLocationIsRegister) {
+ Inst.setOpcode(Mips::OR);
+ Inst.addOperand(MCOperand::createReg(Mips::GP));
+ Inst.addOperand(MCOperand::createReg(SaveLocation));
+ Inst.addOperand(MCOperand::createReg(Mips::ZERO));
+ } else {
+ Inst.setOpcode(Mips::LD);
+ Inst.addOperand(MCOperand::createReg(Mips::GP));
+ Inst.addOperand(MCOperand::createReg(Mips::SP));
+ Inst.addOperand(MCOperand::createImm(SaveLocation));
+ }
+ getStreamer().EmitInstruction(Inst, STI);
+
+ forbidModuleDirective();
+}
+
void MipsTargetELFStreamer::emitMipsAbiFlags() {
MCAssembler &MCA = getStreamer().getAssembler();
MCContext &Context = MCA.getContext();
OpenPOWER on IntegriCloud