diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MCTargetDesc')
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(); |