diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp b/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp index 489cec742bc..f8228714a24 100644 --- a/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -9,9 +9,11 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "MCTargetDesc/AMDGPUFixupKinds.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/TargetRegistry.h" @@ -58,6 +60,8 @@ public: bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override { return true; } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; }; } //End anonymous namespace @@ -78,6 +82,19 @@ void AMDGPUAsmBackend::applyFixup(const MCFixup &Fixup, char *Data, *Dst = (Value - 4) / 4; } +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 } + }; + + if (Kind < FirstTargetFixupKind) + return MCAsmBackend::getFixupKindInfo(Kind); + + return Infos[Kind - FirstTargetFixupKind]; +} + //===----------------------------------------------------------------------===// // ELFAMDGPUAsmBackend class //===----------------------------------------------------------------------===// diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h b/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h new file mode 100644 index 00000000000..ef64b40b3a6 --- /dev/null +++ b/lib/Target/R600/MCTargetDesc/AMDGPUFixupKinds.h @@ -0,0 +1,28 @@ +//===-- AMDGPUFixupKinds.h - AMDGPU 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_AMDGPUFIXUPKINDS_H +#define LLVM_AMDGPUFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace AMDGPU { +enum Fixups { + /// 16-bit PC relative fixup for SOPP branch instructions. + fixup_si_sopp_br = FirstTargetFixupKind, + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind +}; +} +} + +#endif // LLVM_AMDGPUFIXUPKINDS_H diff --git a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h index 6a5cd67bc0d..d5e432de564 100644 --- a/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h +++ b/lib/Target/R600/MCTargetDesc/AMDGPUMCCodeEmitter.h @@ -37,6 +37,12 @@ public: const MCSubtargetInfo &STI) const { return 0; } + + virtual unsigned getSOPPBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + return 0; + } }; } // End namespace llvm diff --git a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp index ee021115ded..5e674d6394d 100644 --- a/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/lib/Target/R600/MCTargetDesc/SIMCCodeEmitter.cpp @@ -15,6 +15,7 @@ #include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "MCTargetDesc/AMDGPUMCCodeEmitter.h" +#include "MCTargetDesc/AMDGPUFixupKinds.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCFixup.h" @@ -62,6 +63,12 @@ public: uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const override; + + /// \brief Use a fixup to encode the simm16 field for SOPP branch + /// instructions. + unsigned getSOPPBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const override; }; } // End anonymous namespace @@ -169,6 +176,21 @@ void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, } } +unsigned SIMCCodeEmitter::getSOPPBrEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + + if (MO.isExpr()) { + const MCExpr *Expr = MO.getExpr(); + MCFixupKind Kind = (MCFixupKind)AMDGPU::fixup_si_sopp_br; + Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); + return 0; + } + + return getMachineOpValue(MI, MO, Fixups, STI); +} + uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups, @@ -176,13 +198,6 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, if (MO.isReg()) return MRI.getEncodingValue(MO.getReg()); - if (MO.isExpr()) { - const MCExpr *Expr = MO.getExpr(); - MCFixupKind Kind = MCFixupKind(FK_PCRel_4); - Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); - return 0; - } - // Figure out the operand number, needed for isSrcOperand check unsigned OpNo = 0; for (unsigned e = MI.getNumOperands(); OpNo < e; ++OpNo) { diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index 774c9d13b17..7093db6d41c 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -142,10 +142,19 @@ class SGPRImm : PatLeaf; +//===----------------------------------------------------------------------===// +// Custom Operands +//===----------------------------------------------------------------------===// + def FRAMEri32 : Operand { let MIOperandInfo = (ops i32:$ptr, i32imm:$index); } +def sopp_brtarget : Operand { + let EncoderMethod = "getSOPPBrEncoding"; + let OperandType = "OPERAND_PCREL"; +} + //===----------------------------------------------------------------------===// // Complex patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index 42942430949..7663b2e0a20 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -378,42 +378,42 @@ def S_ENDPGM : SOPP <0x00000001, (ins), "S_ENDPGM", let isBranch = 1 in { def S_BRANCH : SOPP < - 0x00000002, (ins brtarget:$simm16), "S_BRANCH $simm16", + 0x00000002, (ins sopp_brtarget:$simm16), "S_BRANCH $simm16", [(br bb:$simm16)]> { let isBarrier = 1; } let DisableEncoding = "$scc" in { def S_CBRANCH_SCC0 : SOPP < - 0x00000004, (ins brtarget:$simm16, SCCReg:$scc), + 0x00000004, (ins sopp_brtarget:$simm16, SCCReg:$scc), "S_CBRANCH_SCC0 $simm16", [] >; def S_CBRANCH_SCC1 : SOPP < - 0x00000005, (ins brtarget:$simm16, SCCReg:$scc), + 0x00000005, (ins sopp_brtarget:$simm16, SCCReg:$scc), "S_CBRANCH_SCC1 $simm16", [] >; } // End DisableEncoding = "$scc" def S_CBRANCH_VCCZ : SOPP < - 0x00000006, (ins brtarget:$simm16, VCCReg:$vcc), + 0x00000006, (ins sopp_brtarget:$simm16, VCCReg:$vcc), "S_CBRANCH_VCCZ $simm16", [] >; def S_CBRANCH_VCCNZ : SOPP < - 0x00000007, (ins brtarget:$simm16, VCCReg:$vcc), + 0x00000007, (ins sopp_brtarget:$simm16, VCCReg:$vcc), "S_CBRANCH_VCCNZ $simm16", [] >; let DisableEncoding = "$exec" in { def S_CBRANCH_EXECZ : SOPP < - 0x00000008, (ins brtarget:$simm16, EXECReg:$exec), + 0x00000008, (ins sopp_brtarget:$simm16, EXECReg:$exec), "S_CBRANCH_EXECZ $simm16", [] >; def S_CBRANCH_EXECNZ : SOPP < - 0x00000009, (ins brtarget:$simm16, EXECReg:$exec), + 0x00000009, (ins sopp_brtarget:$simm16, EXECReg:$exec), "S_CBRANCH_EXECNZ $simm16", [] >;