diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff | 516 |
1 files changed, 516 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff new file mode 100644 index 0000000..d6e65da --- /dev/null +++ b/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff @@ -0,0 +1,516 @@ +Pull in r198533 from upstream llvm trunk (by Venkatraman Govindaraju): + + [Sparc] Add initial implementation of MC Code emitter for sparc. + +Introduced here: http://svn.freebsd.org/changeset/base/262261 + +Index: lib/Target/Sparc/SparcInstrInfo.td +=================================================================== +--- lib/Target/Sparc/SparcInstrInfo.td ++++ lib/Target/Sparc/SparcInstrInfo.td +@@ -100,9 +100,14 @@ def MEMri : Operand<iPTR> { + def TLSSym : Operand<iPTR>; + + // Branch targets have OtherVT type. +-def brtarget : Operand<OtherVT>; +-def calltarget : Operand<i32>; ++def brtarget : Operand<OtherVT> { ++ let EncoderMethod = "getBranchTargetOpValue"; ++} + ++def calltarget : Operand<i32> { ++ let EncoderMethod = "getCallTargetOpValue"; ++} ++ + // Operand for printing out a condition code. + let PrintMethod = "printCCOperand" in + def CCOp : Operand<i32>; +Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt ++++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt +@@ -1,6 +1,8 @@ + add_llvm_library(LLVMSparcDesc ++ SparcAsmBackend.cpp ++ SparcMCAsmInfo.cpp ++ SparcMCCodeEmitter.cpp + SparcMCTargetDesc.cpp +- SparcMCAsmInfo.cpp + SparcMCExpr.cpp + SparcTargetStreamer.cpp + ) +Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +@@ -0,0 +1,131 @@ ++//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++// ++// This file implements the SparcMCCodeEmitter class. ++// ++//===----------------------------------------------------------------------===// ++ ++#define DEBUG_TYPE "mccodeemitter" ++#include "SparcMCTargetDesc.h" ++#include "MCTargetDesc/SparcFixupKinds.h" ++#include "llvm/MC/MCCodeEmitter.h" ++#include "llvm/MC/MCContext.h" ++#include "llvm/MC/MCExpr.h" ++#include "llvm/MC/MCInst.h" ++#include "llvm/MC/MCRegisterInfo.h" ++#include "llvm/ADT/Statistic.h" ++#include "llvm/Support/raw_ostream.h" ++ ++using namespace llvm; ++ ++STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); ++ ++namespace { ++class SparcMCCodeEmitter : public MCCodeEmitter { ++ SparcMCCodeEmitter(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; ++ void operator=(const SparcMCCodeEmitter &) LLVM_DELETED_FUNCTION; ++ MCContext &Ctx; ++ ++public: ++ SparcMCCodeEmitter(MCContext &ctx): Ctx(ctx) {} ++ ++ ~SparcMCCodeEmitter() {} ++ ++ void EncodeInstruction(const MCInst &MI, raw_ostream &OS, ++ SmallVectorImpl<MCFixup> &Fixups) const; ++ ++ // getBinaryCodeForInstr - TableGen'erated function for getting the ++ // binary encoding for an instruction. ++ uint64_t getBinaryCodeForInstr(const MCInst &MI, ++ SmallVectorImpl<MCFixup> &Fixups) const; ++ ++ /// getMachineOpValue - Return binary encoding of operand. If the machine ++ /// operand requires relocation, record the relocation and return zero. ++ unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, ++ SmallVectorImpl<MCFixup> &Fixups) const; ++ ++ unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl<MCFixup> &Fixups) const; ++ unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl<MCFixup> &Fixups) const; ++ ++}; ++} // end anonymous namespace ++ ++MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII, ++ const MCRegisterInfo &MRI, ++ const MCSubtargetInfo &STI, ++ MCContext &Ctx) { ++ return new SparcMCCodeEmitter(Ctx); ++} ++ ++void SparcMCCodeEmitter:: ++EncodeInstruction(const MCInst &MI, raw_ostream &OS, ++ SmallVectorImpl<MCFixup> &Fixups) const { ++ unsigned Bits = getBinaryCodeForInstr(MI, Fixups); ++ ++ // Output the constant in big endian byte order. ++ for (unsigned i = 0; i != 4; ++i) { ++ OS << (char)(Bits >> 24); ++ Bits <<= 8; ++ } ++ ++ ++MCNumEmitted; // Keep track of the # of mi's emitted. ++} ++ ++ ++unsigned SparcMCCodeEmitter:: ++getMachineOpValue(const MCInst &MI, const MCOperand &MO, ++ SmallVectorImpl<MCFixup> &Fixups) const { ++ ++ if (MO.isReg()) ++ return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); ++ ++ if (MO.isImm()) ++ return MO.getImm(); ++ ++ assert(MO.isExpr()); ++ const MCExpr *Expr = MO.getExpr(); ++ int64_t Res; ++ if (Expr->EvaluateAsAbsolute(Res)) ++ return Res; ++ ++ assert(0 && "Unhandled expression!"); ++ return 0; ++} ++ ++unsigned SparcMCCodeEmitter:: ++getCallTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl<MCFixup> &Fixups) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isReg() || MO.isImm()) ++ return getMachineOpValue(MI, MO, Fixups); ++ ++ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), ++ (MCFixupKind)Sparc::fixup_sparc_call30)); ++ return 0; ++} ++ ++unsigned SparcMCCodeEmitter:: ++getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, ++ SmallVectorImpl<MCFixup> &Fixups) const { ++ const MCOperand &MO = MI.getOperand(OpNo); ++ if (MO.isReg() || MO.isImm()) ++ return getMachineOpValue(MI, MO, Fixups); ++ ++ Sparc::Fixups fixup = Sparc::fixup_sparc_br22; ++ if (MI.getOpcode() == SP::BPXCC) ++ fixup = Sparc::fixup_sparc_br19; ++ ++ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), ++ (MCFixupKind)fixup)); ++ return 0; ++} ++ ++#include "SparcGenMCCodeEmitter.inc" +Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +@@ -136,6 +136,18 @@ extern "C" void LLVMInitializeSparcTargetMC() { + TargetRegistry::RegisterMCSubtargetInfo(TheSparcV9Target, + createSparcMCSubtargetInfo); + ++ // Register the MC Code Emitter. ++ TargetRegistry::RegisterMCCodeEmitter(TheSparcTarget, ++ createSparcMCCodeEmitter); ++ TargetRegistry::RegisterMCCodeEmitter(TheSparcV9Target, ++ createSparcMCCodeEmitter); ++ ++ //Register the asm backend. ++ TargetRegistry::RegisterMCAsmBackend(TheSparcTarget, ++ createSparcAsmBackend); ++ TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target, ++ createSparcAsmBackend); ++ + TargetRegistry::RegisterAsmStreamer(TheSparcTarget, + createMCAsmStreamer); + TargetRegistry::RegisterAsmStreamer(TheSparcV9Target, +Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp ++++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +@@ -0,0 +1,101 @@ ++//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "llvm/MC/MCAsmBackend.h" ++#include "MCTargetDesc/SparcMCTargetDesc.h" ++#include "MCTargetDesc/SparcFixupKinds.h" ++#include "llvm/MC/MCFixupKindInfo.h" ++#include "llvm/MC/MCObjectWriter.h" ++#include "llvm/Support/TargetRegistry.h" ++ ++using namespace llvm; ++ ++namespace { ++ class SparcAsmBackend : public MCAsmBackend { ++ ++ public: ++ SparcAsmBackend(const Target &T) : MCAsmBackend() {} ++ ++ unsigned getNumFixupKinds() const { ++ return Sparc::NumTargetFixupKinds; ++ } ++ ++ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { ++ const static MCFixupKindInfo Infos[Sparc::NumTargetFixupKinds] = { ++ // name offset bits flags ++ { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, ++ { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, ++ { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel } ++ }; ++ ++ if (Kind < FirstTargetFixupKind) ++ return MCAsmBackend::getFixupKindInfo(Kind); ++ ++ assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && ++ "Invalid kind!"); ++ return Infos[Kind - FirstTargetFixupKind]; ++ } ++ ++ bool mayNeedRelaxation(const MCInst &Inst) const { ++ // FIXME. ++ return false; ++ } ++ ++ /// fixupNeedsRelaxation - Target specific predicate for whether a given ++ /// fixup requires the associated instruction to be relaxed. ++ bool fixupNeedsRelaxation(const MCFixup &Fixup, ++ uint64_t Value, ++ const MCRelaxableFragment *DF, ++ const MCAsmLayout &Layout) const { ++ // FIXME. ++ assert(0 && "fixupNeedsRelaxation() unimplemented"); ++ return false; ++ } ++ void relaxInstruction(const MCInst &Inst, MCInst &Res) const { ++ // FIXME. ++ assert(0 && "relaxInstruction() unimplemented"); ++ } ++ ++ bool writeNopData(uint64_t Count, MCObjectWriter *OW) const { ++ // FIXME: Zero fill for now. ++ for (uint64_t i = 0; i != Count; ++i) ++ OW->Write8(0); ++ return true; ++ } ++ }; ++ ++ class ELFSparcAsmBackend : public SparcAsmBackend { ++ public: ++ ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) : ++ SparcAsmBackend(T) { } ++ ++ void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, ++ uint64_t Value) const { ++ assert(0 && "applyFixup not implemented yet"); ++ } ++ ++ MCObjectWriter *createObjectWriter(raw_ostream &OS) const { ++ assert(0 && "Object Writer not implemented yet"); ++ return 0; ++ } ++ ++ virtual bool doesSectionRequireSymbols(const MCSection &Section) const { ++ return false; ++ } ++ }; ++ ++} // end anonymous namespace ++ ++ ++MCAsmBackend *llvm::createSparcAsmBackend(const Target &T, ++ const MCRegisterInfo &MRI, ++ StringRef TT, ++ StringRef CPU) { ++ return new ELFSparcAsmBackend(T, Triple(TT).getOS()); ++} +Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h ++++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +@@ -0,0 +1,36 @@ ++//===-- SparcFixupKinds.h - Sparc 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_SPARC_FIXUPKINDS_H ++#define LLVM_SPARC_FIXUPKINDS_H ++ ++#include "llvm/MC/MCFixup.h" ++ ++namespace llvm { ++ namespace Sparc { ++ enum Fixups { ++ // fixup_sparc_call30 - 30-bit PC relative relocation for call ++ fixup_sparc_call30 = FirstTargetFixupKind, ++ ++ /// fixup_sparc_br22 - 22-bit PC relative relocation for ++ /// branches ++ fixup_sparc_br22, ++ ++ /// fixup_sparc_br22 - 22-bit PC relative relocation for ++ /// branches on icc/xcc ++ fixup_sparc_br19, ++ ++ // Marker ++ LastTargetFixupKind, ++ NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind ++ }; ++ } ++} ++ ++#endif +Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +=================================================================== +--- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h ++++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +@@ -15,11 +15,27 @@ + #define SPARCMCTARGETDESC_H + + namespace llvm { ++class MCAsmBackend; ++class MCCodeEmitter; ++class MCContext; ++class MCInstrInfo; ++class MCRegisterInfo; ++class MCSubtargetInfo; + class Target; ++class StringRef; + + extern Target TheSparcTarget; + extern Target TheSparcV9Target; + ++MCCodeEmitter *createSparcMCCodeEmitter(const MCInstrInfo &MCII, ++ const MCRegisterInfo &MRI, ++ const MCSubtargetInfo &STI, ++ MCContext &Ctx); ++MCAsmBackend *createSparcAsmBackend(const Target &T, ++ const MCRegisterInfo &MRI, ++ StringRef TT, ++ StringRef CPU); ++ + } // End llvm namespace + + // Defines symbolic names for Sparc registers. This defines a mapping from +Index: lib/Target/Sparc/Makefile +=================================================================== +--- lib/Target/Sparc/Makefile ++++ lib/Target/Sparc/Makefile +@@ -16,7 +16,7 @@ BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenI + SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \ + SparcGenDAGISel.inc \ + SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \ +- SparcGenCodeEmitter.inc ++ SparcGenCodeEmitter.inc SparcGenMCCodeEmitter.inc + + DIRS = InstPrinter AsmParser TargetInfo MCTargetDesc + +Index: lib/Target/Sparc/CMakeLists.txt +=================================================================== +--- lib/Target/Sparc/CMakeLists.txt ++++ lib/Target/Sparc/CMakeLists.txt +@@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS Sparc.td) + tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info) + tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info) + tablegen(LLVM SparcGenCodeEmitter.inc -gen-emitter) ++tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter -mc-emitter) + tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer) + tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher) + tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel) +Index: lib/Target/Sparc/SparcCodeEmitter.cpp +=================================================================== +--- lib/Target/Sparc/SparcCodeEmitter.cpp ++++ lib/Target/Sparc/SparcCodeEmitter.cpp +@@ -72,6 +72,11 @@ class SparcCodeEmitter : public MachineFunctionPas + unsigned getMachineOpValue(const MachineInstr &MI, + const MachineOperand &MO) const; + ++ unsigned getCallTargetOpValue(const MachineInstr &MI, ++ unsigned) const; ++ unsigned getBranchTargetOpValue(const MachineInstr &MI, ++ unsigned) const; ++ + void emitWord(unsigned Word); + + unsigned getRelocation(const MachineInstr &MI, +@@ -181,6 +186,18 @@ unsigned SparcCodeEmitter::getMachineOpValue(const + llvm_unreachable("Unable to encode MachineOperand!"); + return 0; + } ++unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI, ++ unsigned opIdx) const { ++ const MachineOperand MO = MI.getOperand(opIdx); ++ return getMachineOpValue(MI, MO); ++} ++ ++unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, ++ unsigned opIdx) const { ++ const MachineOperand MO = MI.getOperand(opIdx); ++ return getMachineOpValue(MI, MO); ++} ++ + unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, + const MachineOperand &MO) const { + +Index: test/MC/Sparc/sparc-alu-instructions.s +=================================================================== +--- test/MC/Sparc/sparc-alu-instructions.s ++++ test/MC/Sparc/sparc-alu-instructions.s +@@ -0,0 +1,72 @@ ++! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s ++! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s ++ ++ ! CHECK: add %g0, %g0, %g0 ! encoding: [0x80,0x00,0x00,0x00] ++ add %g0, %g0, %g0 ++ ! CHECK: add %g1, %g2, %g3 ! encoding: [0x86,0x00,0x40,0x02] ++ add %g1, %g2, %g3 ++ ! CHECK: add %o0, %o1, %l0 ! encoding: [0xa0,0x02,0x00,0x09] ++ add %r8, %r9, %l0 ++ ! CHECK: add %o0, 10, %l0 ! encoding: [0xa0,0x02,0x20,0x0a] ++ add %o0, 10, %l0 ++ ++ ! CHECK: addcc %g1, %g2, %g3 ! encoding: [0x86,0x80,0x40,0x02] ++ addcc %g1, %g2, %g3 ++ ++ ! CHECK: addxcc %g1, %g2, %g3 ! encoding: [0x86,0xc0,0x40,0x02] ++ addxcc %g1, %g2, %g3 ++ ++ ! CHECK: udiv %g1, %g2, %g3 ! encoding: [0x86,0x70,0x40,0x02] ++ udiv %g1, %g2, %g3 ++ ++ ! CHECK: sdiv %g1, %g2, %g3 ! encoding: [0x86,0x78,0x40,0x02] ++ sdiv %g1, %g2, %g3 ++ ++ ! CHECK: and %g1, %g2, %g3 ! encoding: [0x86,0x08,0x40,0x02] ++ and %g1, %g2, %g3 ++ ! CHECK: andn %g1, %g2, %g3 ! encoding: [0x86,0x28,0x40,0x02] ++ andn %g1, %g2, %g3 ++ ! CHECK: or %g1, %g2, %g3 ! encoding: [0x86,0x10,0x40,0x02] ++ or %g1, %g2, %g3 ++ ! CHECK: orn %g1, %g2, %g3 ! encoding: [0x86,0x30,0x40,0x02] ++ orn %g1, %g2, %g3 ++ ! CHECK: xor %g1, %g2, %g3 ! encoding: [0x86,0x18,0x40,0x02] ++ xor %g1, %g2, %g3 ++ ! CHECK: xnor %g1, %g2, %g3 ! encoding: [0x86,0x38,0x40,0x02] ++ xnor %g1, %g2, %g3 ++ ++ ! CHECK: umul %g1, %g2, %g3 ! encoding: [0x86,0x50,0x40,0x02] ++ umul %g1, %g2, %g3 ++ ++ ! CHECK: smul %g1, %g2, %g3 ! encoding: [0x86,0x58,0x40,0x02] ++ smul %g1, %g2, %g3 ++ ++ ! CHECK: nop ! encoding: [0x01,0x00,0x00,0x00] ++ nop ++ ++ ! CHECK: sethi 10, %l0 ! encoding: [0x21,0x00,0x00,0x0a] ++ sethi 10, %l0 ++ ++ ! CHECK: sll %g1, %g2, %g3 ! encoding: [0x87,0x28,0x40,0x02] ++ sll %g1, %g2, %g3 ++ ! CHECK: sll %g1, 31, %g3 ! encoding: [0x87,0x28,0x60,0x1f] ++ sll %g1, 31, %g3 ++ ++ ! CHECK: srl %g1, %g2, %g3 ! encoding: [0x87,0x30,0x40,0x02] ++ srl %g1, %g2, %g3 ++ ! CHECK: srl %g1, 31, %g3 ! encoding: [0x87,0x30,0x60,0x1f] ++ srl %g1, 31, %g3 ++ ++ ! CHECK: sra %g1, %g2, %g3 ! encoding: [0x87,0x38,0x40,0x02] ++ sra %g1, %g2, %g3 ++ ! CHECK: sra %g1, 31, %g3 ! encoding: [0x87,0x38,0x60,0x1f] ++ sra %g1, 31, %g3 ++ ++ ! CHECK: sub %g1, %g2, %g3 ! encoding: [0x86,0x20,0x40,0x02] ++ sub %g1, %g2, %g3 ++ ! CHECK: subcc %g1, %g2, %g3 ! encoding: [0x86,0xa0,0x40,0x02] ++ subcc %g1, %g2, %g3 ++ ++ ! CHECK: subxcc %g1, %g2, %g3 ! encoding: [0x86,0xe0,0x40,0x02] ++ subxcc %g1, %g2, %g3 ++ |