diff options
author | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-02-11 20:01:10 -0800 |
commit | ce9904c6ea8fd669978a8eefb854b330eb9828ff (patch) | |
tree | 2418ee2e96ea220977c8fb74959192036ab5b133 /lib/Target/Mips/MCTargetDesc | |
parent | c27b10b198c1d9e9b51f2303994313ec2778edd7 (diff) | |
parent | dbb832b83351cec97b025b61c26536ef50c3181c (diff) | |
download | external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.zip external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.gz external_llvm-ce9904c6ea8fd669978a8eefb854b330eb9828ff.tar.bz2 |
Merge remote-tracking branch 'upstream/release_34' into merge-20140211
Conflicts:
lib/Linker/LinkModules.cpp
lib/Support/Unix/Signals.inc
Change-Id: Ia54f291fa5dc828052d2412736e8495c1282aa64
Diffstat (limited to 'lib/Target/Mips/MCTargetDesc')
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 43 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 39 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp | 93 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h | 43 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 39 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 140 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 39 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h | 16 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 67 |
12 files changed, 346 insertions, 180 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt index 1f08789..9116748 100644 --- a/lib/Target/Mips/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/Mips/MCTargetDesc/CMakeLists.txt @@ -5,7 +5,7 @@ add_llvm_library(LLVMMipsDesc MipsMCTargetDesc.cpp MipsELFObjectWriter.cpp MipsReginfo.cpp - MipsELFStreamer.cpp + MipsTargetStreamer.cpp ) add_dependencies(LLVMMipsDesc MipsCommonTableGen) diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 0b13607..3e70b23 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -45,6 +45,10 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { 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: break; case Mips::fixup_Mips_PC16: // So far we are only using this type for branches. @@ -65,6 +69,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { case Mips::fixup_Mips_GOT_Local: case Mips::fixup_Mips_GOT_HI16: case Mips::fixup_Mips_CALL_HI16: + case Mips::fixup_MICROMIPS_HI16: // Get the 2nd 16-bits. Also add 1 if bit 15 is 1. Value = ((Value + 0x8000) >> 16) & 0xffff; break; @@ -76,6 +81,13 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { // Get the 4th 16-bits. Value = ((Value + 0x800080008000LL) >> 48) & 0xffff; break; + case Mips::fixup_MICROMIPS_26_S1: + Value >>= 1; + break; + case Mips::fixup_MICROMIPS_PC16_S1: + Value -= 4; + Value >>= 1; + break; } return Value; @@ -188,7 +200,20 @@ public: { "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_CALL_LO16", 0, 16, 0 }, + { "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_PC16_S1", 0, 16, 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_DTPREL_HI16", 0, 16, 0 }, + { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 }, + { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 }, + { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 } }; if (Kind < FirstTargetFixupKind) @@ -253,25 +278,33 @@ public: } // namespace // MCAsmBackend -MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, StringRef TT, +MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return new MipsAsmBackend(T, Triple(TT).getOS(), /*IsLittle*/true, /*Is64Bit*/false); } -MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, StringRef TT, +MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return new MipsAsmBackend(T, Triple(TT).getOS(), /*IsLittle*/false, /*Is64Bit*/false); } -MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, StringRef TT, +MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return new MipsAsmBackend(T, Triple(TT).getOS(), /*IsLittle*/true, /*Is64Bit*/true); } -MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT, +MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, + const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU) { return new MipsAsmBackend(T, Triple(TT).getOS(), /*IsLittle*/false, /*Is64Bit*/true); diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 6471b51..83c7d4b 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -183,6 +183,45 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, case Mips::fixup_Mips_CALL_LO16: Type = ELF::R_MIPS_CALL_LO16; break; + case Mips::fixup_MICROMIPS_26_S1: + Type = ELF::R_MICROMIPS_26_S1; + break; + case Mips::fixup_MICROMIPS_HI16: + Type = ELF::R_MICROMIPS_HI16; + break; + case Mips::fixup_MICROMIPS_LO16: + Type = ELF::R_MICROMIPS_LO16; + break; + case Mips::fixup_MICROMIPS_GOT16: + Type = ELF::R_MICROMIPS_GOT16; + break; + case Mips::fixup_MICROMIPS_PC16_S1: + Type = ELF::R_MICROMIPS_PC16_S1; + break; + case Mips::fixup_MICROMIPS_CALL16: + Type = ELF::R_MICROMIPS_CALL16; + break; + case Mips::fixup_MICROMIPS_GOT_DISP: + Type = ELF::R_MICROMIPS_GOT_DISP; + break; + case Mips::fixup_MICROMIPS_GOT_PAGE: + Type = ELF::R_MICROMIPS_GOT_PAGE; + break; + case Mips::fixup_MICROMIPS_GOT_OFST: + Type = ELF::R_MICROMIPS_GOT_OFST; + break; + case Mips::fixup_MICROMIPS_TLS_DTPREL_HI16: + Type = ELF::R_MICROMIPS_TLS_DTPREL_HI16; + break; + case Mips::fixup_MICROMIPS_TLS_DTPREL_LO16: + Type = ELF::R_MICROMIPS_TLS_DTPREL_LO16; + break; + case Mips::fixup_MICROMIPS_TLS_TPREL_HI16: + Type = ELF::R_MICROMIPS_TLS_TPREL_HI16; + break; + case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: + Type = ELF::R_MICROMIPS_TLS_TPREL_LO16; + break; } return Type; } diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp deleted file mode 100644 index cfcb877..0000000 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ /dev/null @@ -1,93 +0,0 @@ -//===-- MipsELFStreamer.cpp - MipsELFStreamer ---------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===-------------------------------------------------------------------===// -#include "MCTargetDesc/MipsELFStreamer.h" -#include "MipsSubtarget.h" -#include "llvm/MC/MCAssembler.h" -#include "llvm/MC/MCELF.h" -#include "llvm/MC/MCELFSymbolFlags.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/ELF.h" -#include "llvm/Support/ErrorHandling.h" - -namespace llvm { - - MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) { - MipsELFStreamer *S = new MipsELFStreamer(Context, TAB, OS, Emitter, - RelaxAll, NoExecStack); - return S; - } - - // For llc. Set a group of ELF header flags - void - MipsELFStreamer::emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget) { - - if (hasRawTextSupport()) - return; - - // Update e_header flags - MCAssembler& MCA = getAssembler(); - unsigned EFlags = MCA.getELFHeaderEFlags(); - - // TODO: Need to add -mabicalls and -mno-abicalls flags. - // Currently we assume that -mabicalls is the default. - EFlags |= ELF::EF_MIPS_CPIC; - - if (Subtarget.inMips16Mode()) - EFlags |= ELF::EF_MIPS_ARCH_ASE_M16; - else - EFlags |= ELF::EF_MIPS_NOREORDER; - - // Architecture - if (Subtarget.hasMips64r2()) - EFlags |= ELF::EF_MIPS_ARCH_64R2; - else if (Subtarget.hasMips64()) - EFlags |= ELF::EF_MIPS_ARCH_64; - else if (Subtarget.hasMips32r2()) - EFlags |= ELF::EF_MIPS_ARCH_32R2; - else - EFlags |= ELF::EF_MIPS_ARCH_32; - - if (Subtarget.inMicroMipsMode()) - EFlags |= ELF::EF_MIPS_MICROMIPS; - - // ABI - if (Subtarget.isABI_O32()) - EFlags |= ELF::EF_MIPS_ABI_O32; - - // Relocation Model - Reloc::Model RM = Subtarget.getRelocationModel(); - if (RM == Reloc::PIC_ || RM == Reloc::Default) - EFlags |= ELF::EF_MIPS_PIC; - else if (RM == Reloc::Static) - ; // Do nothing for Reloc::Static - else - llvm_unreachable("Unsupported relocation model for e_flags"); - - MCA.setELFHeaderEFlags(EFlags); - } - - // For llc. Set a symbol's STO flags - void - MipsELFStreamer::emitMipsSTOCG(const MipsSubtarget &Subtarget, - MCSymbol *Sym, - unsigned Val) { - - if (hasRawTextSupport()) - return; - - MCSymbolData &Data = getOrCreateSymbolData(Sym); - // The "other" values are stored in the last 6 bits of the second byte - // The traditional defines for STO values assume the full byte and thus - // the shift to pack it. - MCELF::setOther(Data, Val >> 2); - } - -} // namespace llvm diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h deleted file mode 100644 index b10ccc7..0000000 --- a/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ /dev/null @@ -1,43 +0,0 @@ -//=== MipsELFStreamer.h - MipsELFStreamer ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENCE.TXT for details. -// -//===-------------------------------------------------------------------===// -#ifndef MIPSELFSTREAMER_H_ -#define MIPSELFSTREAMER_H_ - -#include "llvm/MC/MCELFStreamer.h" - -namespace llvm { -class MipsAsmPrinter; -class MipsSubtarget; -class MCSymbol; - -class MipsELFStreamer : public MCELFStreamer { -public: - MipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack) - : MCELFStreamer(SK_MipsELFStreamer, Context, TAB, OS, Emitter) { - } - - ~MipsELFStreamer() {} - void emitELFHeaderFlagsCG(const MipsSubtarget &Subtarget); - void emitMipsSTOCG(const MipsSubtarget &Subtarget, - MCSymbol *Sym, - unsigned Val); - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_MipsELFStreamer; - } -}; - - MCELFStreamer* createMipsELFStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter, - bool RelaxAll, bool NoExecStack); -} - -#endif /* MIPSELFSTREAMER_H_ */ diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index f963900..6ed44b7 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -128,6 +128,45 @@ namespace Mips { // resulting in - R_MIPS_CALL_LO16 fixup_Mips_CALL_LO16, + // 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_PC16_S1 + fixup_MICROMIPS_PC16_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_DTPREL_HI16 + fixup_MICROMIPS_TLS_DTPREL_HI16, + + // resulting in - R_MICROMIPS_TLS_DTPREL_LO16 + fixup_MICROMIPS_TLS_DTPREL_LO16, + + // resulting in - R_MICROMIPS_TLS_TPREL_HI16 + fixup_MICROMIPS_TLS_TPREL_HI16, + + // resulting in - R_MICROMIPS_TLS_TPREL_LO16 + fixup_MICROMIPS_TLS_TPREL_LO16, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp index 33f6f96..6aa3c76 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp @@ -38,7 +38,6 @@ MipsMCAsmInfo::MipsMCAsmInfo(StringRef TT) { ZeroDirective = "\t.space\t"; GPRel32Directive = "\t.gpword\t"; GPRel64Directive = "\t.gpdword\t"; - WeakRefDirective = "\t.weak\t"; DebugLabelSuffix = "=."; SupportsDebugInformation = true; ExceptionsType = ExceptionHandling::DwarfCFI; diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h index 772234e..1000113 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.h @@ -14,12 +14,12 @@ #ifndef MIPSTARGETASMINFO_H #define MIPSTARGETASMINFO_H -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAsmInfoELF.h" namespace llvm { class StringRef; - class MipsMCAsmInfo : public MCAsmInfo { + class MipsMCAsmInfo : public MCAsmInfoELF { virtual void anchor(); public: explicit MipsMCAsmInfo(StringRef TT); diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 4dc6917..66428bd 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -39,11 +39,14 @@ class MipsMCCodeEmitter : public MCCodeEmitter { MCContext &Ctx; const MCSubtargetInfo &STI; bool IsLittleEndian; + bool IsMicroMips; public: MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, const MCSubtargetInfo &sti, bool IsLittle) : - MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {} + MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) { + IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; + } ~MipsMCCodeEmitter() {} @@ -53,9 +56,17 @@ public: void EmitInstruction(uint64_t Val, unsigned Size, raw_ostream &OS) const { // Output the instruction encoding in little endian byte order. - for (unsigned i = 0; i < Size; ++i) { - unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; - EmitByte((Val >> Shift) & 0xff, OS); + // Little-endian byte ordering: + // mips32r2: 4 | 3 | 2 | 1 + // microMIPS: 2 | 1 | 4 | 3 + if (IsLittleEndian && Size == 4 && IsMicroMips) { + EmitInstruction(Val>>16, 2, OS); + EmitInstruction(Val, 2, OS); + } else { + for (unsigned i = 0; i < Size; ++i) { + unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; + EmitByte((Val >> Shift) & 0xff, OS); + } } } @@ -73,12 +84,24 @@ public: unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) 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; + // 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; + // 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; + // 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, @@ -86,11 +109,17 @@ public: unsigned getMemEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; + unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const; unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const; + // getLSAImmEncoding - Return binary encoding of LSA immediate. + unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const; + unsigned getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const; @@ -142,6 +171,9 @@ static void LowerLargeShift(MCInst& Inst) { case Mips::DSRA: Inst.setOpcode(Mips::DSRA32); return; + case Mips::DROTR: + Inst.setOpcode(Mips::DROTR32); + return; } } @@ -177,7 +209,7 @@ static void LowerDextDins(MCInst& InstIn) { } /// EncodeInstruction - Emit the instruction. -/// Size the instruction (currently only 4 bytes +/// Size the instruction with Desc.getSize(). void MipsMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const @@ -193,6 +225,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, case Mips::DSLL: case Mips::DSRL: case Mips::DSRA: + case Mips::DROTR: LowerLargeShift(TmpInst); break; // Double extract instruction is chosen by pos and size operands @@ -201,6 +234,7 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, LowerDextDins(TmpInst); } + unsigned long N = Fixups.size(); uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups); // Check for unimplemented opcodes. @@ -213,6 +247,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, if (STI.getFeatureBits() & Mips::FeatureMicroMips) { int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); if (NewOpcode != -1) { + if (Fixups.size() > N) + Fixups.pop_back(); Opcode = NewOpcode; TmpInst.setOpcode (NewOpcode); Binary = getBinaryCodeForInstr(TmpInst, Fixups); @@ -250,6 +286,28 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, return 0; } +/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch +/// target operand. If the machine operand requires relocation, +/// record the relocation and return zero. +unsigned MipsMCCodeEmitter:: +getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const { + + const MCOperand &MO = MI.getOperand(OpNo); + + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getBranchTargetOpValueMM expects only expressions or immediates"); + + const MCExpr *Expr = MO.getExpr(); + Fixups.push_back(MCFixup::Create(0, Expr, + MCFixupKind(Mips:: + fixup_MICROMIPS_PC16_S1))); + return 0; +} + /// getJumpTargetOpValue - Return binary encoding of the jump /// target operand. If the machine operand requires relocation, /// record the relocation and return zero. @@ -271,6 +329,23 @@ getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: +getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const { + + const MCOperand &MO = MI.getOperand(OpNo); + // If the destination is an immediate, divide by 2. + if (MO.isImm()) return MO.getImm() >> 1; + + assert(MO.isExpr() && + "getJumpTargetOpValueMM expects only expressions or an immediate"); + + const MCExpr *Expr = MO.getExpr(); + Fixups.push_back(MCFixup::Create(0, Expr, + MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); + return 0; +} + +unsigned MipsMCCodeEmitter:: getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const { int64_t Res; @@ -300,31 +375,39 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const { FixupKind = Mips::fixup_Mips_GPOFF_LO; break; case MCSymbolRefExpr::VK_Mips_GOT_PAGE : - FixupKind = Mips::fixup_Mips_GOT_PAGE; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_PAGE + : Mips::fixup_Mips_GOT_PAGE; break; case MCSymbolRefExpr::VK_Mips_GOT_OFST : - FixupKind = Mips::fixup_Mips_GOT_OFST; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_OFST + : Mips::fixup_Mips_GOT_OFST; break; case MCSymbolRefExpr::VK_Mips_GOT_DISP : - FixupKind = Mips::fixup_Mips_GOT_DISP; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_DISP + : Mips::fixup_Mips_GOT_DISP; break; case MCSymbolRefExpr::VK_Mips_GPREL: FixupKind = Mips::fixup_Mips_GPREL16; break; case MCSymbolRefExpr::VK_Mips_GOT_CALL: - FixupKind = Mips::fixup_Mips_CALL16; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_CALL16 + : Mips::fixup_Mips_CALL16; break; case MCSymbolRefExpr::VK_Mips_GOT16: - FixupKind = Mips::fixup_Mips_GOT_Global; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16 + : Mips::fixup_Mips_GOT_Global; break; case MCSymbolRefExpr::VK_Mips_GOT: - FixupKind = Mips::fixup_Mips_GOT_Local; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16 + : Mips::fixup_Mips_GOT_Local; break; case MCSymbolRefExpr::VK_Mips_ABS_HI: - FixupKind = Mips::fixup_Mips_HI16; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_HI16 + : Mips::fixup_Mips_HI16; break; case MCSymbolRefExpr::VK_Mips_ABS_LO: - FixupKind = Mips::fixup_Mips_LO16; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_LO16 + : Mips::fixup_Mips_LO16; break; case MCSymbolRefExpr::VK_Mips_TLSGD: FixupKind = Mips::fixup_Mips_TLSGD; @@ -333,19 +416,23 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const { FixupKind = Mips::fixup_Mips_TLSLDM; break; case MCSymbolRefExpr::VK_Mips_DTPREL_HI: - FixupKind = Mips::fixup_Mips_DTPREL_HI; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 + : Mips::fixup_Mips_DTPREL_HI; break; case MCSymbolRefExpr::VK_Mips_DTPREL_LO: - FixupKind = Mips::fixup_Mips_DTPREL_LO; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 + : Mips::fixup_Mips_DTPREL_LO; break; case MCSymbolRefExpr::VK_Mips_GOTTPREL: FixupKind = Mips::fixup_Mips_GOTTPREL; break; case MCSymbolRefExpr::VK_Mips_TPREL_HI: - FixupKind = Mips::fixup_Mips_TPREL_HI; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 + : Mips::fixup_Mips_TPREL_HI; break; case MCSymbolRefExpr::VK_Mips_TPREL_LO: - FixupKind = Mips::fixup_Mips_TPREL_LO; + FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 + : Mips::fixup_Mips_TPREL_LO; break; case MCSymbolRefExpr::VK_Mips_HIGHER: FixupKind = Mips::fixup_Mips_HIGHER; @@ -406,6 +493,17 @@ MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, return (OffBits & 0xFFFF) | RegBits; } +unsigned MipsMCCodeEmitter:: +getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const { + // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. + assert(MI.getOperand(OpNo).isReg()); + unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) << 16; + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups); + + return (OffBits & 0x0FFF) | RegBits; +} + unsigned MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups) const { @@ -427,5 +525,13 @@ MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, return Position + Size - 1; } +unsigned +MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups) const { + assert(MI.getOperand(OpNo).isImm()); + // The immediate is encoded as 'immediate - 1'. + return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) - 1; +} + #include "MipsGenMCCodeEmitter.inc" diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 837fabe..5548aaa 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -11,17 +11,21 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/MipsELFStreamer.h" #include "MipsMCTargetDesc.h" #include "InstPrinter/MipsInstPrinter.h" #include "MipsMCAsmInfo.h" +#include "MipsTargetStreamer.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCELF.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MachineLocation.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" #define GET_INSTRINFO_MC_DESC @@ -125,14 +129,23 @@ static MCInstPrinter *createMipsMCInstPrinter(const Target &T, } static MCStreamer *createMCStreamer(const Target &T, StringRef TT, - MCContext &Ctx, MCAsmBackend &MAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack) { - Triple TheTriple(TT); - - return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); + MCContext &Context, MCAsmBackend &MAB, + raw_ostream &OS, MCCodeEmitter *Emitter, + bool RelaxAll, bool NoExecStack) { + MipsTargetELFStreamer *S = new MipsTargetELFStreamer(); + return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack); +} + +static MCStreamer * +createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useLoc, bool useCFI, + bool useDwarfDirectory, MCInstPrinter *InstPrint, + MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst) { + MipsTargetAsmStreamer *S = new MipsTargetAsmStreamer(OS); + + return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, + useDwarfDirectory, InstPrint, CE, TAB, + ShowInst); } extern "C" void LLVMInitializeMipsTargetMC() { @@ -183,6 +196,12 @@ extern "C" void LLVMInitializeMipsTargetMC() { TargetRegistry::RegisterMCObjectStreamer(TheMips64elTarget, createMCStreamer); + // Register the asm streamer. + TargetRegistry::RegisterAsmStreamer(TheMipsTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMipselTarget, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMips64Target, createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheMips64elTarget, createMCAsmStreamer); + // Register the asm backend. TargetRegistry::RegisterMCAsmBackend(TheMipsTarget, createMipsAsmBackendEB32); diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h index 71954a4..eabebfe 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h @@ -42,14 +42,14 @@ MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCSubtargetInfo &STI, MCContext &Ctx); -MCAsmBackend *createMipsAsmBackendEB32(const Target &T, StringRef TT, - StringRef CPU); -MCAsmBackend *createMipsAsmBackendEL32(const Target &T, StringRef TT, - StringRef CPU); -MCAsmBackend *createMipsAsmBackendEB64(const Target &T, StringRef TT, - StringRef CPU); -MCAsmBackend *createMipsAsmBackendEL64(const Target &T, StringRef TT, - StringRef CPU); +MCAsmBackend *createMipsAsmBackendEB32(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); +MCAsmBackend *createMipsAsmBackendEL32(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); +MCAsmBackend *createMipsAsmBackendEB64(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); +MCAsmBackend *createMipsAsmBackendEL64(const Target &T, const MCRegisterInfo &MRI, + StringRef TT, StringRef CPU); MCObjectWriter *createMipsELFObjectWriter(raw_ostream &OS, uint8_t OSABI, diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp new file mode 100644 index 0000000..5e90bbc --- /dev/null +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -0,0 +1,67 @@ +//===-- MipsTargetStreamer.cpp - Mips Target Streamer Methods -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides Mips specific target streamer methods. +// +//===----------------------------------------------------------------------===// + +#include "MipsTargetStreamer.h" +#include "llvm/MC/MCELF.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" + +using namespace llvm; + +static cl::opt<bool> PrintHackDirectives("print-hack-directives", + cl::init(false), cl::Hidden); + +// pin vtable to this file +void MipsTargetStreamer::anchor() {} + +MipsTargetAsmStreamer::MipsTargetAsmStreamer(formatted_raw_ostream &OS) + : OS(OS) {} + +void MipsTargetAsmStreamer::emitMipsHackELFFlags(unsigned Flags) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_elf_flags 0x"; + OS.write_hex(Flags); + OS << '\n'; +} +void MipsTargetAsmStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + if (!PrintHackDirectives) + return; + + OS << "\t.mips_hack_stocg "; + OS << Sym->getName(); + OS << ", "; + OS << Val; + OS << '\n'; +} + +MCELFStreamer &MipsTargetELFStreamer::getStreamer() { + return static_cast<MCELFStreamer &>(*Streamer); +} + +void MipsTargetELFStreamer::emitMipsHackELFFlags(unsigned Flags) { + MCAssembler &MCA = getStreamer().getAssembler(); + MCA.setELFHeaderEFlags(Flags); +} + +// Set a symbol's STO flags +void MipsTargetELFStreamer::emitMipsHackSTOCG(MCSymbol *Sym, unsigned Val) { + MCSymbolData &Data = getStreamer().getOrCreateSymbolData(Sym); + // The "other" values are stored in the last 6 bits of the second byte + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + MCELF::setOther(Data, Val >> 2); +} |