diff options
Diffstat (limited to 'llvm/lib/Target/R600/MCTargetDesc')
4 files changed, 61 insertions, 8 deletions
diff --git a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp index f8228714a24..d55f27b0455 100644 --- a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -45,7 +45,7 @@ public: AMDGPUAsmBackend(const Target &T) : MCAsmBackend() {} - unsigned getNumFixupKinds() const override { return 0; }; + unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; }; void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value, bool IsPCRel) const override; bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, @@ -77,16 +77,37 @@ void AMDGPUAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value, bool IsPCRel) const { - uint16_t *Dst = (uint16_t*)(Data + Fixup.getOffset()); - assert(Fixup.getKind() == FK_PCRel_4); - *Dst = (Value - 4) / 4; + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("Unknown fixup kind"); + case AMDGPU::fixup_si_sopp_br: { + uint16_t *Dst = (uint16_t*)(Data + Fixup.getOffset()); + *Dst = (Value - 4) / 4; + break; + } + + case AMDGPU::fixup_si_rodata: { + uint32_t *Dst = (uint32_t*)(Data + Fixup.getOffset()); + *Dst = Value; + break; + } + + case AMDGPU::fixup_si_end_of_text: { + uint32_t *Dst = (uint32_t*)(Data + Fixup.getOffset()); + // The value points to the last instruction in the text section, so we + // need to add 4 bytes to get to the start of the constants. + *Dst = Value + 4; + break; + } + } } const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo( MCFixupKind Kind) const { const static MCFixupKindInfo Infos[AMDGPU::NumTargetFixupKinds] = { // name offset bits flags - { "fixup_si_sopp_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel } + { "fixup_si_sopp_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_si_rodata", 0, 32, 0 }, + { "fixup_si_end_of_text", 0, 32, MCFixupKindInfo::FKF_IsPCRel } }; if (Kind < FirstTargetFixupKind) diff --git a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUELFObjectWriter.cpp b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUELFObjectWriter.cpp index 53b0e85751d..5fb94d5914d 100644 --- a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUELFObjectWriter.cpp +++ b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUELFObjectWriter.cpp @@ -10,6 +10,7 @@ #include "AMDGPUMCTargetDesc.h" #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixup.h" using namespace llvm; @@ -21,7 +22,7 @@ public: protected: unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const override { - llvm_unreachable("Not implemented"); + return Fixup.getKind(); } }; diff --git a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h index ef64b40b3a6..4b12e548a56 100644 --- a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h +++ b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h @@ -18,6 +18,12 @@ enum Fixups { /// 16-bit PC relative fixup for SOPP branch instructions. fixup_si_sopp_br = FirstTargetFixupKind, + /// fixup for global addresses with constant initializers + fixup_si_rodata, + + /// fixup for offset from instruction to end of text section + fixup_si_end_of_text, + // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/llvm/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/llvm/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp index 5e674d6394d..78776c11d75 100644 --- a/llvm/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/llvm/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp @@ -13,6 +13,7 @@ // //===----------------------------------------------------------------------===// +#include "AMDGPU.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "MCTargetDesc/AMDGPUMCCodeEmitter.h" #include "MCTargetDesc/AMDGPUFixupKinds.h" @@ -40,6 +41,7 @@ class SIMCCodeEmitter : public AMDGPUMCCodeEmitter { void operator=(const SIMCCodeEmitter &) LLVM_DELETED_FUNCTION; const MCInstrInfo &MCII; const MCRegisterInfo &MRI; + MCContext &Ctx; /// \brief Can this operand also contain immediate values? bool isSrcOperand(const MCInstrDesc &Desc, unsigned OpNo) const; @@ -50,7 +52,7 @@ class SIMCCodeEmitter : public AMDGPUMCCodeEmitter { public: SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, MCContext &ctx) - : MCII(mcii), MRI(mri) { } + : MCII(mcii), MRI(mri), Ctx(ctx) { } ~SIMCCodeEmitter() { } @@ -97,6 +99,8 @@ uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const { Imm.I = MO.getImm(); else if (MO.isFPImm()) Imm.F = MO.getFPImm(); + else if (MO.isExpr()) + return 255; else return ~0; @@ -164,8 +168,13 @@ void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, IntFloatUnion Imm; if (Op.isImm()) Imm.I = Op.getImm(); - else + else if (Op.isFPImm()) Imm.F = Op.getFPImm(); + else { + assert(Op.isExpr()); + // This will be replaced with a fixup value. + Imm.I = 0; + } for (unsigned j = 0; j < 4; j++) { OS.write((uint8_t) ((Imm.I >> (8 * j)) & 0xff)); @@ -198,6 +207,22 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, if (MO.isReg()) return MRI.getEncodingValue(MO.getReg()); + if (MO.isExpr()) { + const MCSymbolRefExpr *Expr = cast<MCSymbolRefExpr>(MO.getExpr()); + MCFixupKind Kind; + const MCSymbol *Sym = + Ctx.GetOrCreateSymbol(StringRef(END_OF_TEXT_LABEL_NAME)); + + if (&Expr->getSymbol() == Sym) { + // Add the offset to the beginning of the constant values. + Kind = (MCFixupKind)AMDGPU::fixup_si_end_of_text; + } else { + // This is used for constant data stored in .rodata. + Kind = (MCFixupKind)AMDGPU::fixup_si_rodata; + } + Fixups.push_back(MCFixup::Create(4, Expr, Kind, MI.getLoc())); + } + // Figure out the operand number, needed for isSrcOperand check unsigned OpNo = 0; for (unsigned e = MI.getNumOperands(); OpNo < e; ++OpNo) { |

