summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198533-sparc.diff516
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
++
OpenPOWER on IntegriCloud