From 4403b930f867f61b48304a23a6843026b0b9a32a Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 16 Jul 2009 13:27:25 +0000 Subject: [PATCH] Let's start another backend :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75909 91177308-0d34-0410-b5e6-96231b3b80d8 --- autoconf/configure.ac | 6 +- configure | 7 +- lib/Target/SystemZ/AsmPrinter/Makefile | 15 + .../SystemZ/AsmPrinter/SystemZAsmPrinter.cpp | 172 ++++++ lib/Target/SystemZ/Makefile | 22 + lib/Target/SystemZ/SystemZ.h | 40 ++ lib/Target/SystemZ/SystemZ.td | 60 ++ lib/Target/SystemZ/SystemZCallingConv.td | 36 ++ lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 129 +++++ lib/Target/SystemZ/SystemZISelLowering.cpp | 72 +++ lib/Target/SystemZ/SystemZISelLowering.h | 49 ++ lib/Target/SystemZ/SystemZInstrFormats.td | 534 ++++++++++++++++++ lib/Target/SystemZ/SystemZInstrInfo.cpp | 81 +++ lib/Target/SystemZ/SystemZInstrInfo.h | 70 +++ lib/Target/SystemZ/SystemZInstrInfo.td | 17 + .../SystemZ/SystemZMachineFunctionInfo.h | 39 ++ lib/Target/SystemZ/SystemZRegisterInfo.cpp | 119 ++++ lib/Target/SystemZ/SystemZRegisterInfo.h | 65 +++ lib/Target/SystemZ/SystemZRegisterInfo.td | 93 +++ lib/Target/SystemZ/SystemZSubtarget.cpp | 27 + lib/Target/SystemZ/SystemZSubtarget.h | 40 ++ lib/Target/SystemZ/SystemZTargetAsmInfo.cpp | 22 + lib/Target/SystemZ/SystemZTargetAsmInfo.h | 31 + lib/Target/SystemZ/SystemZTargetMachine.cpp | 72 +++ lib/Target/SystemZ/SystemZTargetMachine.h | 68 +++ 25 files changed, 1884 insertions(+), 2 deletions(-) create mode 100644 lib/Target/SystemZ/AsmPrinter/Makefile create mode 100644 lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp create mode 100644 lib/Target/SystemZ/Makefile create mode 100644 lib/Target/SystemZ/SystemZ.h create mode 100644 lib/Target/SystemZ/SystemZ.td create mode 100644 lib/Target/SystemZ/SystemZCallingConv.td create mode 100644 lib/Target/SystemZ/SystemZISelDAGToDAG.cpp create mode 100644 lib/Target/SystemZ/SystemZISelLowering.cpp create mode 100644 lib/Target/SystemZ/SystemZISelLowering.h create mode 100644 lib/Target/SystemZ/SystemZInstrFormats.td create mode 100644 lib/Target/SystemZ/SystemZInstrInfo.cpp create mode 100644 lib/Target/SystemZ/SystemZInstrInfo.h create mode 100644 lib/Target/SystemZ/SystemZInstrInfo.td create mode 100644 lib/Target/SystemZ/SystemZMachineFunctionInfo.h create mode 100644 lib/Target/SystemZ/SystemZRegisterInfo.cpp create mode 100644 lib/Target/SystemZ/SystemZRegisterInfo.h create mode 100644 lib/Target/SystemZ/SystemZRegisterInfo.td create mode 100644 lib/Target/SystemZ/SystemZSubtarget.cpp create mode 100644 lib/Target/SystemZ/SystemZSubtarget.h create mode 100644 lib/Target/SystemZ/SystemZTargetAsmInfo.cpp create mode 100644 lib/Target/SystemZ/SystemZTargetAsmInfo.h create mode 100644 lib/Target/SystemZ/SystemZTargetMachine.cpp create mode 100644 lib/Target/SystemZ/SystemZTargetMachine.h diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 3a5a35183ae..189c2d6fabb 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -227,6 +227,7 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch], pic16-*) llvm_cv_target_arch="PIC16" ;; xcore-*) llvm_cv_target_arch="XCore" ;; msp430-*) llvm_cv_target_arch="MSP430" ;; + s390x-*) llvm_cv_target_arch="SystemZ" ;; *) llvm_cv_target_arch="Unknown" ;; esac]) @@ -352,6 +353,7 @@ else PIC16) AC_SUBST(TARGET_HAS_JIT,0) ;; XCore) AC_SUBST(TARGET_HAS_JIT,0) ;; MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;; + SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;; *) AC_SUBST(TARGET_HAS_JIT,0) ;; esac fi @@ -401,7 +403,7 @@ AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets], [Build specific host targets: all,host-only,{target-name} (default=all)]),, enableval=all) case "$enableval" in - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 CBackend MSIL CppBackend" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; @@ -416,6 +418,7 @@ case "$enableval" in PIC16) TARGETS_TO_BUILD="PIC16" ;; XCore) TARGETS_TO_BUILD="XCore" ;; MSP430) TARGETS_TO_BUILD="MSP430" ;; + SystemZ) TARGETS_TO_BUILD="SystemZ" ;; *) AC_MSG_ERROR([Can not set target to build]) ;; esac ;; @@ -433,6 +436,7 @@ case "$enableval" in pic16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;; xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;; msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;; + systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; diff --git a/configure b/configure index d52f03de917..913c6e79fba 100755 --- a/configure +++ b/configure @@ -2405,6 +2405,7 @@ else pic16-*) llvm_cv_target_arch="PIC16" ;; xcore-*) llvm_cv_target_arch="XCore" ;; msp430-*) llvm_cv_target_arch="MSP430" ;; + s390x-*) llvm_cv_target_arch="SystemZ" ;; *) llvm_cv_target_arch="Unknown" ;; esac fi @@ -4852,6 +4853,8 @@ else XCore) TARGET_HAS_JIT=0 ;; MSP430) TARGET_HAS_JIT=0 + ;; + SystemZ) TARGET_HAS_JIT=0 ;; *) TARGET_HAS_JIT=0 ;; @@ -4934,7 +4937,7 @@ else fi case "$enableval" in - all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 CBackend MSIL CppBackend" ;; + all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; @@ -4949,6 +4952,7 @@ case "$enableval" in PIC16) TARGETS_TO_BUILD="PIC16" ;; XCore) TARGETS_TO_BUILD="XCore" ;; MSP430) TARGETS_TO_BUILD="MSP430" ;; + SystemZ) TARGETS_TO_BUILD="SystemZ" ;; *) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5 echo "$as_me: error: Can not set target to build" >&2;} { (exit 1); exit 1; }; } ;; @@ -4968,6 +4972,7 @@ echo "$as_me: error: Can not set target to build" >&2;} pic16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;; xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;; msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;; + systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;; cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;; msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;; cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;; diff --git a/lib/Target/SystemZ/AsmPrinter/Makefile b/lib/Target/SystemZ/AsmPrinter/Makefile new file mode 100644 index 00000000000..06998837c47 --- /dev/null +++ b/lib/Target/SystemZ/AsmPrinter/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/SystemZ/Makefile ------------- -----------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMSystemZAsmPrinter + +# Hack: we need to include 'main' SystemZ target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp new file mode 100644 index 00000000000..1c1e2554b79 --- /dev/null +++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp @@ -0,0 +1,172 @@ +//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly writer ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the SystemZ assembly language. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "SystemZ.h" +#include "SystemZInstrInfo.h" +#include "SystemZTargetMachine.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +STATISTIC(EmittedInsts, "Number of machine instrs printed"); + +namespace { + class VISIBILITY_HIDDEN SystemZAsmPrinter : public AsmPrinter { + public: + SystemZAsmPrinter(raw_ostream &O, SystemZTargetMachine &TM, + const TargetAsmInfo *TAI, + CodeGenOpt::Level OL, bool V) + : AsmPrinter(O, TM, TAI, OL, V) {} + + virtual const char *getPassName() const { + return "SystemZ Assembly Printer"; + } + + void printOperand(const MachineInstr *MI, int OpNum, + const char* Modifier = 0); + bool printInstruction(const MachineInstr *MI); // autogenerated. + void printMachineInstruction(const MachineInstr * MI); + + void emitFunctionHeader(const MachineFunction &MF); + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + + void getAnalysisUsage(AnalysisUsage &AU) const { + AsmPrinter::getAnalysisUsage(AU); + AU.setPreservesAll(); + } + }; +} // end of anonymous namespace + +#include "SystemZGenAsmWriter.inc" + +/// createSystemZCodePrinterPass - Returns a pass that prints the SystemZ +/// assembly code for a MachineFunction to the given output stream, +/// using the given target machine description. This should work +/// regardless of whether the function is in SSA form. +/// +FunctionPass *llvm::createSystemZCodePrinterPass(raw_ostream &o, + SystemZTargetMachine &tm, + CodeGenOpt::Level OptLevel, + bool verbose) { + return new SystemZAsmPrinter(o, tm, tm.getTargetAsmInfo(), OptLevel, verbose); +} + +bool SystemZAsmPrinter::doInitialization(Module &M) { + Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix()); + return false; // success +} + + +bool SystemZAsmPrinter::doFinalization(Module &M) { + return AsmPrinter::doFinalization(M); +} + +void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { + const Function *F = MF.getFunction(); + + SwitchToSection(TAI->SectionForGlobal(F)); + + unsigned FnAlign = 4; + if (F->hasFnAttr(Attribute::OptimizeForSize)) + FnAlign = 1; + + EmitAlignment(FnAlign, F); + + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + case Function::PrivateLinkage: + break; + case Function::ExternalLinkage: + O << "\t.globl\t" << CurrentFnName << '\n'; + break; + case Function::LinkOnceAnyLinkage: + case Function::LinkOnceODRLinkage: + case Function::WeakAnyLinkage: + case Function::WeakODRLinkage: + O << "\t.weak\t" << CurrentFnName << '\n'; + break; + } + + printVisibility(CurrentFnName, F->getVisibility()); + + O << "\t.type\t" << CurrentFnName << ",@function\n" + << CurrentFnName << ":\n"; +} + +bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + SetupMachineFunction(MF); + O << "\n\n"; + + // Print the 'header' of function + emitFunctionHeader(MF); + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) { + // This is an entry block or a block that's only reachable via a + // fallthrough edge. In non-VerboseAsm mode, don't print the label. + } else { + printBasicBlockLabel(I, true, true, VerboseAsm); + O << '\n'; + } + + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) + // Print the assembly for the instruction. + printMachineInstruction(II); + } + + if (TAI->hasDotTypeDotSizeDirective()) + O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; + + O.flush(); + + // We didn't modify anything + return false; +} + +void SystemZAsmPrinter::printMachineInstruction(const MachineInstr *MI) { + ++EmittedInsts; + + // Call the autogenerated instruction printer routines. + if (printInstruction(MI)) + return; + + assert(0 && "Should not happen"); +} + +void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, + const char* Modifier) { + assert(0 && "Not implemented yet!"); +} diff --git a/lib/Target/SystemZ/Makefile b/lib/Target/SystemZ/Makefile new file mode 100644 index 00000000000..c4574dc2484 --- /dev/null +++ b/lib/Target/SystemZ/Makefile @@ -0,0 +1,22 @@ +##===- lib/Target/SystemZ/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../.. +LIBRARYNAME = LLVMSystemZCodeGen +TARGET = SystemZ + +# Make sure that tblgen is run, first thing. +BUILT_SOURCES = SystemZGenRegisterInfo.h.inc SystemZGenRegisterNames.inc \ + SystemZGenRegisterInfo.inc SystemZGenInstrNames.inc \ + SystemZGenInstrInfo.inc SystemZGenAsmWriter.inc \ + SystemZGenDAGISel.inc SystemZGenSubtarget.inc SystemZGenCallingConv.inc + +DIRS = AsmPrinter + +include $(LEVEL)/Makefile.common + diff --git a/lib/Target/SystemZ/SystemZ.h b/lib/Target/SystemZ/SystemZ.h new file mode 100644 index 00000000000..c58daa374c8 --- /dev/null +++ b/lib/Target/SystemZ/SystemZ.h @@ -0,0 +1,40 @@ +//=-- SystemZ.h - Top-level interface for SystemZ representation -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the entry points for global functions defined in +// the LLVM SystemZ backend. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SystemZ_H +#define LLVM_TARGET_SystemZ_H + +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + class SystemZTargetMachine; + class FunctionPass; + class raw_ostream; + + FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM, + CodeGenOpt::Level OptLevel); + FunctionPass *createSystemZCodePrinterPass(raw_ostream &o, + SystemZTargetMachine &tm, + CodeGenOpt::Level OptLevel, + bool verbose); +} // end namespace llvm; + +// Defines symbolic names for SystemZ registers. +// This defines a mapping from register name to register number. +#include "SystemZGenRegisterNames.inc" + +// Defines symbolic names for the SystemZ instructions. +#include "SystemZGenInstrNames.inc" + +#endif diff --git a/lib/Target/SystemZ/SystemZ.td b/lib/Target/SystemZ/SystemZ.td new file mode 100644 index 00000000000..a062dc67f2f --- /dev/null +++ b/lib/Target/SystemZ/SystemZ.td @@ -0,0 +1,60 @@ +//===- SystemZ.td - Describe the SystemZ Target Machine ------*- tblgen -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This is the top level entry point for the SystemZ target. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Target-independent interfaces +//===----------------------------------------------------------------------===// + +include "llvm/Target/Target.td" + +//===----------------------------------------------------------------------===// +// Subtarget Features. +//===----------------------------------------------------------------------===// +def FeatureX + : SubtargetFeature<"dummy", "DummyFeature", "true", + "Some feature">; + +//===----------------------------------------------------------------------===// +// SystemZ supported processors. +//===----------------------------------------------------------------------===// +class Proc Features> + : Processor; + +def : Proc<"generic", []>; + +//===----------------------------------------------------------------------===// +// Register File Description +//===----------------------------------------------------------------------===// + +include "SystemZRegisterInfo.td" + +//===----------------------------------------------------------------------===// +// Calling Convention Description +//===----------------------------------------------------------------------===// + +include "SystemZCallingConv.td" + +//===----------------------------------------------------------------------===// +// Instruction Descriptions +//===----------------------------------------------------------------------===// + +include "SystemZInstrInfo.td" + +def SystemZInstrInfo : InstrInfo {} + +//===----------------------------------------------------------------------===// +// Target Declaration +//===----------------------------------------------------------------------===// + +def SystemZ : Target { + let InstructionSet = SystemZInstrInfo; +} + diff --git a/lib/Target/SystemZ/SystemZCallingConv.td b/lib/Target/SystemZ/SystemZCallingConv.td new file mode 100644 index 00000000000..8216f80a25b --- /dev/null +++ b/lib/Target/SystemZ/SystemZCallingConv.td @@ -0,0 +1,36 @@ +//=- SystemZCallingConv.td - Calling Conventions for SystemZ -*- tablegen -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This describes the calling conventions for SystemZ architecture. +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// SystemZ Return Value Calling Convention +//===----------------------------------------------------------------------===// +def RetCC_SystemZ : CallingConv<[ + // i64 is returned in register R2 + CCIfType<[i64], CCAssignToReg<[R2]>> +]>; + +//===----------------------------------------------------------------------===// +// SystemZ Argument Calling Conventions +//===----------------------------------------------------------------------===// +def CC_SystemZ : CallingConv<[ + // Promote i8/i16/i32 arguments to i64. + CCIfType<[i8, i16, i32], CCPromoteToType>, + + // The first 5 integer arguments of non-varargs functions are passed in + // integer registers. + // FIXME: Check stuff for varagrs + CCIfNotVarArg>>, + + // Integer values get stored in stack slots that are 8 bytes in + // size and 8-byte aligned. + CCIfType<[i64], CCAssignToStack<8, 8>> +]>; diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp new file mode 100644 index 00000000000..9b9eeb2abed --- /dev/null +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -0,0 +1,129 @@ +//==-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines an instruction selector for the SystemZ target. +// +//===----------------------------------------------------------------------===// + +#include "SystemZ.h" +#include "SystemZISelLowering.h" +#include "SystemZTargetMachine.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/Intrinsics.h" +#include "llvm/CallingConv.h" +#include "llvm/Constants.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +using namespace llvm; + +/// SystemZDAGToDAGISel - SystemZ specific code to select SystemZ machine +/// instructions for SelectionDAG operations. +/// +namespace { + class SystemZDAGToDAGISel : public SelectionDAGISel { + SystemZTargetLowering &Lowering; + const SystemZSubtarget &Subtarget; + + public: + SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) + : SelectionDAGISel(TM, OptLevel), + Lowering(*TM.getTargetLowering()), + Subtarget(*TM.getSubtargetImpl()) { } + + virtual void InstructionSelect(); + + virtual const char *getPassName() const { + return "SystemZ DAG->DAG Pattern Instruction Selection"; + } + + // Include the pieces autogenerated from the target description. + #include "SystemZGenDAGISel.inc" + + private: + SDNode *Select(SDValue Op); + + #ifndef NDEBUG + unsigned Indent; + #endif + }; +} // end anonymous namespace + +/// createSystemZISelDag - This pass converts a legalized DAG into a +/// SystemZ-specific DAG, ready for instruction scheduling. +/// +FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, + CodeGenOpt::Level OptLevel) { + return new SystemZDAGToDAGISel(TM, OptLevel); +} + + +/// InstructionSelect - This callback is invoked by +/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. +void SystemZDAGToDAGISel::InstructionSelect() { + DEBUG(BB->dump()); + + // Codegen the basic block. +#ifndef NDEBUG + DOUT << "===== Instruction selection begins:\n"; + Indent = 0; +#endif + SelectRoot(*CurDAG); +#ifndef NDEBUG + DOUT << "===== Instruction selection ends:\n"; +#endif + + CurDAG->RemoveDeadNodes(); +} + +SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { + SDNode *Node = Op.getNode(); + DebugLoc dl = Op.getDebugLoc(); + + // Dump information about the Node being selected + #ifndef NDEBUG + DOUT << std::string(Indent, ' ') << "Selecting: "; + DEBUG(Node->dump(CurDAG)); + DOUT << "\n"; + Indent += 2; + #endif + + // If we have a custom node, we already have selected! + if (Node->isMachineOpcode()) { + #ifndef NDEBUG + DOUT << std::string(Indent-2, ' ') << "== "; + DEBUG(Node->dump(CurDAG)); + DOUT << "\n"; + Indent -= 2; + #endif + return NULL; + } + + // Select the default instruction + SDNode *ResNode = SelectCode(Op); + + #ifndef NDEBUG + DOUT << std::string(Indent-2, ' ') << "=> "; + if (ResNode == NULL || ResNode == Op.getNode()) + DEBUG(Op.getNode()->dump(CurDAG)); + else + DEBUG(ResNode->dump(CurDAG)); + DOUT << "\n"; + Indent -= 2; + #endif + + return ResNode; +} diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp new file mode 100644 index 00000000000..31572af1bd3 --- /dev/null +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -0,0 +1,72 @@ +//===-- SystemZISelLowering.cpp - SystemZ DAG Lowering Implementation -----==// +// +// 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 SystemZTargetLowering class. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "systemz-lower" + +#include "SystemZISelLowering.h" +#include "SystemZ.h" +#include "SystemZTargetMachine.h" +#include "SystemZSubtarget.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/Intrinsics.h" +#include "llvm/CallingConv.h" +#include "llvm/GlobalVariable.h" +#include "llvm/GlobalAlias.h" +#include "llvm/CodeGen/CallingConvLower.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Support/Debug.h" +#include "llvm/ADT/VectorExtras.h" +using namespace llvm; + +SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : + TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { + + // Set up the register classes. + addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass); + + // Compute derived properties from the register classes + computeRegisterProperties(); + + // Provide all sorts of operation actions + + setStackPointerRegisterToSaveRestore(SystemZ::R15); + setSchedulingPreference(SchedulingForLatency); +} + +SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { + switch (Op.getOpcode()) { + default: + assert(0 && "unimplemented operand"); + return SDValue(); + } +} + +//===----------------------------------------------------------------------===// +// Calling Convention Implementation +//===----------------------------------------------------------------------===// + +#include "SystemZGenCallingConv.inc" + +const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { + switch (Opcode) { + default: return NULL; + } +} + diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h new file mode 100644 index 00000000000..ca9918d111a --- /dev/null +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -0,0 +1,49 @@ +//==-- SystemZISelLowering.h - SystemZ DAG Lowering Interface ----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interfaces that SystemZ uses to lower LLVM code into a +// selection DAG. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SystemZ_ISELLOWERING_H +#define LLVM_TARGET_SystemZ_ISELLOWERING_H + +#include "SystemZ.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/Target/TargetLowering.h" + +namespace llvm { + namespace SystemZISD { + enum { + FIRST_NUMBER = ISD::BUILTIN_OP_END + }; + } + + class SystemZSubtarget; + class SystemZTargetMachine; + + class SystemZTargetLowering : public TargetLowering { + public: + explicit SystemZTargetLowering(SystemZTargetMachine &TM); + + /// LowerOperation - Provide custom lowering hooks for some operations. + virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG); + + /// getTargetNodeName - This method returns the name of a target specific + /// DAG node. + virtual const char *getTargetNodeName(unsigned Opcode) const; + + private: + const SystemZSubtarget &Subtarget; + const SystemZTargetMachine &TM; + }; +} // namespace llvm + +#endif // LLVM_TARGET_SystemZ_ISELLOWERING_H diff --git a/lib/Target/SystemZ/SystemZInstrFormats.td b/lib/Target/SystemZ/SystemZInstrFormats.td new file mode 100644 index 00000000000..12753e8d06c --- /dev/null +++ b/lib/Target/SystemZ/SystemZInstrFormats.td @@ -0,0 +1,534 @@ +//===- SystemZInstrFormats.td - SystemZ Instruction Formats ----*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class InstSystemZ pattern> : Instruction { + let Namespace = "SystemZ"; + + dag OutOperandList = outs; + dag InOperandList = ins; + let AsmString = asmstr; + let Pattern = pattern; +} + +//===----------------------------------------------------------------------===// +// E format +//===----------------------------------------------------------------------===// + +class F_E opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<16> Inst; + + let Inst{15-0} = opcode; +} + +//===----------------------------------------------------------------------===// +// I format +//===----------------------------------------------------------------------===// + +class F_I opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-32} = opcode; + //let Inst{31-0} = simm32; +} + +//===----------------------------------------------------------------------===// +// RR format +//===----------------------------------------------------------------------===// + +class F_RR opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<16> Inst; + + let Inst{15-8} = opcode; +} + +//===----------------------------------------------------------------------===// +// RRE format +//===----------------------------------------------------------------------===// + +class F_RRE opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-16} = opcode; + let Inst{15-8} = 0; + //let Inst{7-4} = r1; + //let Inst{3-0} = r2; +} + +//===----------------------------------------------------------------------===// +// RRF format (1) +//===----------------------------------------------------------------------===// + +class F_RRF_1 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-16} = opcode; + //let Inst{15-12} = r1; + let Inst{11-8} = 0; + //let Inst{7-4} = r3; + //let Inst{3-0} = r2; +} + +//===----------------------------------------------------------------------===// +// RRF format (2) +//===----------------------------------------------------------------------===// + +class F_RRF_2 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-16} = opcode; + //let Inst{15-12} = m3; + let Inst{11-8} = 0; + //let Inst{7-4} = r1; + //let Inst{3-0} = r2; +} + +//===----------------------------------------------------------------------===// +// RRF format (3) +//===----------------------------------------------------------------------===// + +class F_RRF_3 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-16} = opcode; + //let Inst{15-12} = r3; + //let Inst{11-8} = m4; + //let Inst{7-4} = r1; + //let Inst{3-0} = r2; +} + +//===----------------------------------------------------------------------===// +// RX format +//===----------------------------------------------------------------------===// + +class F_RX opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + //let Inst{19-16} = x2; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// RXE format +//===----------------------------------------------------------------------===// + +class F_RXE opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = x2; + //let Inst{31-28} = b2; + //let Inst{27-16} = udisp12; + let Inst{15-8} = 0; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RXF format +//===----------------------------------------------------------------------===// + +class F_RXF opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r3; + //let Inst{35-32} = x2; + //let Inst{31-28} = b2; + //let Inst{27-16} = udisp12; + //let Inst{15-11} = r1; + let Inst{11-8} = 0; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RXY format +//===----------------------------------------------------------------------===// + +class F_RXY opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = x2; + //let Inst{31-28} = b2; + //let Inst{27-8} = sdisp20; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RS format (1) +//===----------------------------------------------------------------------===// + +class F_RS_1 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + //let Inst{19-16} = r3; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// RS format (2) +//===----------------------------------------------------------------------===// + +class F_RS_2 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + //let Inst{19-16} = m3; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// RS format (3) +//===----------------------------------------------------------------------===// + +class F_RS_3 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + let Inst{19-16} = 0; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// RSY format (1) +//===----------------------------------------------------------------------===// + +class F_RSY_1 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = r3; + //let Inst{31-28} = b2; + //let Inst{27-8} = sdisp20; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RSY format (2) +//===----------------------------------------------------------------------===// + +class F_RSY_2 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = m3; + //let Inst{31-28} = b2; + //let Inst{27-8} = sdisp20; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RSL format +//===----------------------------------------------------------------------===// + +class F_RSL opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = ll; + let Inst{35-32} = 0; + //let Inst{31-28} = b1; + //let Inst{27-16} = udisp12; + let Inst{15-8} = 0; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RSI format +//===----------------------------------------------------------------------===// + +class F_RSI opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + //let Inst{19-16} = r3; + //let Inst{15-0} = simm16; +} + +//===----------------------------------------------------------------------===// +// RI format +//===----------------------------------------------------------------------===// + +class F_RI opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-20} = r1; + //let Inst{19-16} = op2; + //let Inst{15-0} = simm16; +} + +//===----------------------------------------------------------------------===// +// RIE format +//===----------------------------------------------------------------------===// + +class F_RIE opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = r2; + //let Inst{31-16} = simm16; + let Inst{15-8} = 0; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// RIL format (1) +//===----------------------------------------------------------------------===// + +class F_RIL_1 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = op2; + //let Inst{31-0} = simm32; +} + +//===----------------------------------------------------------------------===// +// RIL format (2) +//===----------------------------------------------------------------------===// + +class F_RIL_2 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = m1; + //let Inst{35-32} = op2; + //let Inst{31-0} = simm32; +} + +//===----------------------------------------------------------------------===// +// SI format +//===----------------------------------------------------------------------===// + +class F_SI opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-24} = opcode; + //let Inst{23-16} = simm8; + //let Inst{15-12} = b1; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// SIY format +//===----------------------------------------------------------------------===// + +class F_SIY opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-32} = simm8; + //let Inst{31-28} = b1; + //let Inst{27-8} = sdisp20; + //let Inst{7-0} = op2; +} + +//===----------------------------------------------------------------------===// +// S format +//===----------------------------------------------------------------------===// + +class F_S opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<32> Inst; + + let Inst{31-16} = opcode; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12; +} + +//===----------------------------------------------------------------------===// +// SS format (1) +//===----------------------------------------------------------------------===// + +class F_SS_1 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-32} = ll; + //let Inst{31-28} = b1; + //let Inst{27-16} = udisp12; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12_2; +} + +//===----------------------------------------------------------------------===// +// SS format (2) +//===----------------------------------------------------------------------===// + +class F_SS_2 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = l1; + //let Inst{35-32} = l2; + //let Inst{31-28} = b1; + //let Inst{27-16} = udisp12; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12_2; +} + +//===----------------------------------------------------------------------===// +// SS format (3) +//===----------------------------------------------------------------------===// + +class F_SS_3 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = r3; + //let Inst{31-28} = b1; + //let Inst{27-16} = udisp12; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12_2; +} + +//===----------------------------------------------------------------------===// +// SS format (4) +//===----------------------------------------------------------------------===// + +class F_SS_4 opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-40} = opcode; + //let Inst{39-36} = r1; + //let Inst{35-32} = r3; + //let Inst{31-28} = b2; + //let Inst{27-16} = udisp12_2; + //let Inst{15-12} = b4; + //let Inst{11-0} = udisp12_4; +} + +//===----------------------------------------------------------------------===// +// SSE format +//===----------------------------------------------------------------------===// + +class F_SSE opcode, + dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ { + + field bits<48> Inst; + + let Inst{47-32} = opcode; + //let Inst{31-28} = b1; + //let Inst{27-16} = udisp12; + //let Inst{15-12} = b2; + //let Inst{11-0} = udisp12_2; +} + +//===----------------------------------------------------------------------===// +// Pseudo instructions +//===----------------------------------------------------------------------===// + +class Pseudo pattern> + : InstSystemZ { +} diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp new file mode 100644 index 00000000000..5747126a4d2 --- /dev/null +++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -0,0 +1,81 @@ +//===- SystemZInstrInfo.cpp - SystemZ Instruction Information --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SystemZ implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "SystemZ.h" +#include "SystemZInstrInfo.h" +#include "SystemZMachineFunctionInfo.h" +#include "SystemZTargetMachine.h" +#include "SystemZGenInstrInfo.inc" +#include "llvm/Function.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" + +using namespace llvm; + +SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm) + : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)), + RI(tm, *this), TM(tm) {} + +void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, bool isKill, int FrameIdx, + const TargetRegisterClass *RC) const { + assert(0 && "Cannot store this register to stack slot!"); +} + +void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const{ + assert(0 && "Cannot store this register to stack slot!"); +} + +bool SystemZInstrInfo::copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const { + return false; +} + +bool +SystemZInstrInfo::isMoveInstr(const MachineInstr& MI, + unsigned &SrcReg, unsigned &DstReg, + unsigned &SrcSubIdx, unsigned &DstSubIdx) const { + return false; +} + +bool +SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const { + return false; +} + +bool +SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const { + return false; +} + +unsigned +SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const SmallVectorImpl &Cond) const { + assert(0 && "Implement branches!"); + + return 0; +} diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h new file mode 100644 index 00000000000..9f461353190 --- /dev/null +++ b/lib/Target/SystemZ/SystemZInstrInfo.h @@ -0,0 +1,70 @@ +//===- SystemZInstrInfo.h - SystemZ Instruction Information -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SystemZ implementation of the TargetInstrInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SYSTEMZINSTRINFO_H +#define LLVM_TARGET_SYSTEMZINSTRINFO_H + +#include "llvm/Target/TargetInstrInfo.h" +#include "SystemZRegisterInfo.h" + +namespace llvm { + +class SystemZTargetMachine; + +class SystemZInstrInfo : public TargetInstrInfoImpl { + const SystemZRegisterInfo RI; + SystemZTargetMachine &TM; +public: + explicit SystemZInstrInfo(SystemZTargetMachine &TM); + + /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As + /// such, whenever a client has an instance of instruction info, it should + /// always be able to get register info as well (through this method). + /// + virtual const TargetRegisterInfo &getRegisterInfo() const { return RI; } + + bool copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *DestRC, + const TargetRegisterClass *SrcRC) const; + + bool isMoveInstr(const MachineInstr& MI, + unsigned &SrcReg, unsigned &DstReg, + unsigned &SrcSubIdx, unsigned &DstSubIdx) const; + + virtual void storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, bool isKill, + int FrameIndex, + const TargetRegisterClass *RC) const; + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC) const; + + virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI) const; + + virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + const SmallVectorImpl &Cond) const; + +}; + +} + +#endif diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td new file mode 100644 index 00000000000..c2f27a15300 --- /dev/null +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -0,0 +1,17 @@ +//===- SystemZInstrInfo.td - SystemZ Instruction defs ---------*- tblgen-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file describes the SystemZ instructions in TableGen format. +// +//===----------------------------------------------------------------------===// + +include "SystemZInstrFormats.td" + +let neverHasSideEffects = 1 in +def NOP : Pseudo<(outs), (ins), "# no-op", []>; diff --git a/lib/Target/SystemZ/SystemZMachineFunctionInfo.h b/lib/Target/SystemZ/SystemZMachineFunctionInfo.h new file mode 100644 index 00000000000..9b45b0364ce --- /dev/null +++ b/lib/Target/SystemZ/SystemZMachineFunctionInfo.h @@ -0,0 +1,39 @@ +//==- SystemZMachineFuctionInfo.h - SystemZ machine function info -*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares SystemZ-specific per-machine-function information. +// +//===----------------------------------------------------------------------===// + +#ifndef SYSTEMZMACHINEFUNCTIONINFO_H +#define SYSTEMZMACHINEFUNCTIONINFO_H + +#include "llvm/CodeGen/MachineFunction.h" + +namespace llvm { + +/// SystemZMachineFunctionInfo - This class is derived from MachineFunction and +/// contains private SystemZ target-specific information for each MachineFunction. +class SystemZMachineFunctionInfo : public MachineFunctionInfo { + /// CalleeSavedFrameSize - Size of the callee-saved register portion of the + /// stack frame in bytes. + unsigned CalleeSavedFrameSize; + +public: + SystemZMachineFunctionInfo() : CalleeSavedFrameSize(0) {} + + SystemZMachineFunctionInfo(MachineFunction &MF) : CalleeSavedFrameSize(0) {} + + unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } + void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } +}; + +} // End llvm namespace + +#endif diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp new file mode 100644 index 00000000000..9a5fe4e60a9 --- /dev/null +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -0,0 +1,119 @@ +//===- SystemZRegisterInfo.cpp - SystemZ Register Information -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SystemZ implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#include "SystemZ.h" +#include "SystemZRegisterInfo.h" +#include "SystemZSubtarget.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/BitVector.h" +using namespace llvm; + +SystemZRegisterInfo::SystemZRegisterInfo(SystemZTargetMachine &tm, + const TargetInstrInfo &tii) + : SystemZGenRegisterInfo(SystemZ::NOP, SystemZ::NOP), + TM(tm), TII(tii) { +} + +const unsigned* +SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + static const unsigned CalleeSavedRegs[] = { + SystemZ::R6, SystemZ::R7, SystemZ::R8, SystemZ::R9, + SystemZ::R10, SystemZ::R11, SystemZ::R12, SystemZ::R13, + SystemZ::F1, SystemZ::F3, SystemZ::F5, SystemZ::F7, + 0 + }; + + return CalleeSavedRegs; +} + +const TargetRegisterClass* const* +SystemZRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { + static const TargetRegisterClass * const CalleeSavedRegClasses[] = { + &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, + &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, + &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, + &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, + &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, + &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0 + }; + return CalleeSavedRegClasses; +} + +BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const { + BitVector Reserved(getNumRegs()); + if (hasFP(MF)) + Reserved.set(SystemZ::R11); + Reserved.set(SystemZ::R14); + Reserved.set(SystemZ::R15); + return Reserved; +} + +// needsFP - Return true if the specified function should have a dedicated frame +// pointer register. This is true if the function has variable sized allocas or +// if frame pointer elimination is disabled. +// +bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + return NoFramePointerElim || MFI->hasVarSizedObjects(); +} + +void SystemZRegisterInfo:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + assert(0 && "Not implemented yet!"); +} + +void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, RegScavenger *RS) const { + assert(0 && "Not implemented yet!"); +} + +void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { + // Nothing here yet +} + +void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + // Nothing here yet +} + +unsigned SystemZRegisterInfo::getRARegister() const { + assert(0 && "What is the return address register"); + return 0; +} + +unsigned SystemZRegisterInfo::getFrameRegister(MachineFunction &MF) const { + assert(0 && "What is the frame register"); + return 0; +} + +unsigned SystemZRegisterInfo::getEHExceptionRegister() const { + assert(0 && "What is the exception register"); + return 0; +} + +unsigned SystemZRegisterInfo::getEHHandlerRegister() const { + assert(0 && "What is the exception handler register"); + return 0; +} + +int SystemZRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { + assert(0 && "What is the dwarf register number"); + return -1; +} + +#include "SystemZGenRegisterInfo.inc" diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.h b/lib/Target/SystemZ/SystemZRegisterInfo.h new file mode 100644 index 00000000000..1af6f931aec --- /dev/null +++ b/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -0,0 +1,65 @@ +//===- SystemZRegisterInfo.h - SystemZ Register Information Impl ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SystemZ implementation of the TargetRegisterInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef SystemZREGISTERINFO_H +#define SystemZREGISTERINFO_H + +#include "llvm/Target/TargetRegisterInfo.h" +#include "SystemZGenRegisterInfo.h.inc" + +namespace llvm { + +class SystemZSubtarget; +class TargetInstrInfo; +class Type; + +struct SystemZRegisterInfo : public SystemZGenRegisterInfo { + SystemZTargetMachine &TM; + const TargetInstrInfo &TII; + + SystemZRegisterInfo(SystemZTargetMachine &tm, const TargetInstrInfo &tii); + + /// Code Generation virtual methods... + const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const; + + const TargetRegisterClass* const* getCalleeSavedRegClasses( + const MachineFunction *MF = 0) const; + + BitVector getReservedRegs(const MachineFunction &MF) const; + + bool hasFP(const MachineFunction &MF) const; + + void eliminateCallFramePseudoInstr(MachineFunction &MF, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const; + + void eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, RegScavenger *RS = NULL) const; + + void emitPrologue(MachineFunction &MF) const; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + + // Debug information queries. + unsigned getRARegister() const; + unsigned getFrameRegister(MachineFunction &MF) const; + + // Exception handling queries. + unsigned getEHExceptionRegister() const; + unsigned getEHHandlerRegister() const; + + int getDwarfRegNum(unsigned RegNum, bool isEH) const; +}; + +} // end namespace llvm + +#endif diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.td b/lib/Target/SystemZ/SystemZRegisterInfo.td new file mode 100644 index 00000000000..f0d00ae8330 --- /dev/null +++ b/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -0,0 +1,93 @@ +//===- SystemZRegisterInfo.td - The PowerPC Register File ------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +class SystemZReg : Register { + let Namespace = "SystemZ"; +} + +// We identify all our registers with a 4-bit ID, for consistency's sake. + +// GPR - One of the 16 64-bit general-purpose registers +class GPR num, string n> : SystemZReg { + field bits<4> Num = num; +} + +// FPR - One of the 16 64-bit floating-point registers +class FPR num, string n> : SystemZReg { + field bits<4> Num = num; +} + +// General-purpose registers +def R0 : GPR< 0, "r0">, DwarfRegNum<[0]>; +def R1 : GPR< 1, "r1">, DwarfRegNum<[1]>; +def R2 : GPR< 2, "r2">, DwarfRegNum<[2]>; +def R3 : GPR< 3, "r3">, DwarfRegNum<[3]>; +def R4 : GPR< 4, "r4">, DwarfRegNum<[4]>; +def R5 : GPR< 5, "r5">, DwarfRegNum<[5]>; +def R6 : GPR< 6, "r6">, DwarfRegNum<[6]>; +def R7 : GPR< 7, "r7">, DwarfRegNum<[7]>; +def R8 : GPR< 8, "r8">, DwarfRegNum<[8]>; +def R9 : GPR< 9, "r9">, DwarfRegNum<[9]>; +def R10 : GPR<10, "r10">, DwarfRegNum<[10]>; +def R11 : GPR<11, "r11">, DwarfRegNum<[11]>; +def R12 : GPR<12, "r12">, DwarfRegNum<[12]>; +def R13 : GPR<13, "r13">, DwarfRegNum<[13]>; +def R14 : GPR<14, "r14">, DwarfRegNum<[14]>; +def R15 : GPR<15, "r15">, DwarfRegNum<[15]>; + +// Floating-point registers +def F0 : FPR< 0, "f0">, DwarfRegNum<[16]>; +def F1 : FPR< 1, "f1">, DwarfRegNum<[17]>; +def F2 : FPR< 2, "f2">, DwarfRegNum<[18]>; +def F3 : FPR< 3, "f3">, DwarfRegNum<[19]>; +def F4 : FPR< 4, "f4">, DwarfRegNum<[20]>; +def F5 : FPR< 5, "f5">, DwarfRegNum<[21]>; +def F6 : FPR< 6, "f6">, DwarfRegNum<[22]>; +def F7 : FPR< 7, "f7">, DwarfRegNum<[23]>; +def F8 : FPR< 8, "f8">, DwarfRegNum<[24]>; +def F9 : FPR< 9, "f9">, DwarfRegNum<[25]>; +def F10 : FPR<10, "f10">, DwarfRegNum<[26]>; +def F11 : FPR<11, "f11">, DwarfRegNum<[27]>; +def F12 : FPR<12, "f12">, DwarfRegNum<[28]>; +def F13 : FPR<13, "f13">, DwarfRegNum<[29]>; +def F14 : FPR<14, "f14">, DwarfRegNum<[30]>; +def F15 : FPR<15, "f15">, DwarfRegNum<[31]>; + +/// Register classes +def GR64 : RegisterClass<"SystemZ", [i64], 16, + // Volatile registers + [R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R12, R13, + // Frame pointer, sometimes allocable + R11, + // Volatile, but not allocable + R14, R15]> +{ + let MethodProtos = [{ + iterator allocation_order_end(const MachineFunction &MF) const; + }]; + let MethodBodies = [{ + GR64Class::iterator + GR64Class::allocation_order_end(const MachineFunction &MF) const { + const TargetMachine &TM = MF.getTarget(); + const TargetRegisterInfo *RI = TM.getRegisterInfo(); + // Depending on whether the function uses frame pointer or not, last 2 or 3 + // registers on the list above are reserved + if (RI->hasFP(MF)) + return end()-3; + else + return end()-2; + } + }]; +} + +def FP64 : RegisterClass<"SystemZ", [f64], 64, + [F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15]>; diff --git a/lib/Target/SystemZ/SystemZSubtarget.cpp b/lib/Target/SystemZ/SystemZSubtarget.cpp new file mode 100644 index 00000000000..e5b2a1ed330 --- /dev/null +++ b/lib/Target/SystemZ/SystemZSubtarget.cpp @@ -0,0 +1,27 @@ +//===- SystemZSubtarget.cpp - SystemZ Subtarget Information -------*- C++ -*-=// +// +// 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 SystemZ specific subclass of TargetSubtarget. +// +//===----------------------------------------------------------------------===// + +#include "SystemZSubtarget.h" +#include "SystemZ.h" +#include "SystemZGenSubtarget.inc" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +SystemZSubtarget::SystemZSubtarget(const TargetMachine &TM, const Module &M, + const std::string &FS) { + std::string CPU = "generic"; + + // Parse features string. + ParseSubtargetFeatures(FS, CPU); +} diff --git a/lib/Target/SystemZ/SystemZSubtarget.h b/lib/Target/SystemZ/SystemZSubtarget.h new file mode 100644 index 00000000000..fbd31a3a1bd --- /dev/null +++ b/lib/Target/SystemZ/SystemZSubtarget.h @@ -0,0 +1,40 @@ +//==-- SystemZSubtarget.h - Define Subtarget for the SystemZ ---*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the SystemZ specific subclass of TargetSubtarget. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SystemZ_SUBTARGET_H +#define LLVM_TARGET_SystemZ_SUBTARGET_H + +#include "llvm/Target/TargetSubtarget.h" + +#include + +namespace llvm { +class Module; +class TargetMachine; + +class SystemZSubtarget : public TargetSubtarget { + bool DummyFeature; +public: + /// This constructor initializes the data members to match that + /// of the specified module. + /// + SystemZSubtarget(const TargetMachine &TM, const Module &M, + const std::string &FS); + + /// ParseSubtargetFeatures - Parses features string setting specified + /// subtarget options. Definition of function is auto generated by tblgen. + void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU); +}; +} // End llvm namespace + +#endif // LLVM_TARGET_SystemZ_SUBTARGET_H diff --git a/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp new file mode 100644 index 00000000000..c841a0e4930 --- /dev/null +++ b/lib/Target/SystemZ/SystemZTargetAsmInfo.cpp @@ -0,0 +1,22 @@ +//===-- SystemZTargetAsmInfo.cpp - SystemZ asm properties -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the SystemZTargetAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "SystemZTargetAsmInfo.h" +#include "SystemZTargetMachine.h" + +using namespace llvm; + +SystemZTargetAsmInfo::SystemZTargetAsmInfo(const SystemZTargetMachine &TM) + : ELFTargetAsmInfo(TM) { + AlignmentIsInBytes = false; +} diff --git a/lib/Target/SystemZ/SystemZTargetAsmInfo.h b/lib/Target/SystemZ/SystemZTargetAsmInfo.h new file mode 100644 index 00000000000..b0a7639eee9 --- /dev/null +++ b/lib/Target/SystemZ/SystemZTargetAsmInfo.h @@ -0,0 +1,31 @@ +//====-- SystemZTargetAsmInfo.h - SystemZ asm properties -------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the SystemZTargetAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef SystemZTARGETASMINFO_H +#define SystemZTARGETASMINFO_H + +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/ELFTargetAsmInfo.h" + +namespace llvm { + + // Forward declaration. + class SystemZTargetMachine; + + struct SystemZTargetAsmInfo : public ELFTargetAsmInfo { + explicit SystemZTargetAsmInfo(const SystemZTargetMachine &TM); + }; + +} // namespace llvm + +#endif diff --git a/lib/Target/SystemZ/SystemZTargetMachine.cpp b/lib/Target/SystemZ/SystemZTargetMachine.cpp new file mode 100644 index 00000000000..a8b2b7688cd --- /dev/null +++ b/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -0,0 +1,72 @@ +//===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +#include "SystemZTargetAsmInfo.h" +#include "SystemZTargetMachine.h" +#include "SystemZ.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Target/TargetMachineRegistry.h" +using namespace llvm; + +/// SystemZTargetMachineModule - Note that this is used on hosts that +/// cannot link in a library unless there are references into the +/// library. In particular, it seems that it is not possible to get +/// things to work on Win32 without this. Though it is unused, do not +/// remove it. +extern "C" int SystemZTargetMachineModule; +int SystemZTargetMachineModule = 0; + +// Register the target. +static RegisterTarget +X("systemz", "SystemZ [experimental]"); + +const TargetAsmInfo *SystemZTargetMachine::createTargetAsmInfo() const { + // FIXME: Handle Solaris subtarget someday :) + return new SystemZTargetAsmInfo(*this); +} + +/// SystemZTargetMachine ctor - Create an ILP64 architecture model +/// +SystemZTargetMachine::SystemZTargetMachine(const Module &M, const std::string &FS) + : Subtarget(*this, M, FS), + DataLayout("E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128"), + InstrInfo(*this), TLInfo(*this), + FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { +} + +bool SystemZTargetMachine::addInstSelector(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { + // Install an instruction selector. + PM.add(createSystemZISelDag(*this, OptLevel)); + return false; +} + +bool SystemZTargetMachine::addAssemblyEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool Verbose, + raw_ostream &Out) { + // Output assembly language. + PM.add(createSystemZCodePrinterPass(Out, *this, OptLevel, Verbose)); + return false; +} + +unsigned SystemZTargetMachine::getModuleMatchQuality(const Module &M) { + std::string TT = M.getTargetTriple(); + + // We strongly match s390x + if (TT.size() >= 5 && TT[0] == 's' && TT[1] == '3' && TT[2] == '9' && + TT[3] == '0' && TT[4] == 'x') + return 20; + + return 0; +} diff --git a/lib/Target/SystemZ/SystemZTargetMachine.h b/lib/Target/SystemZ/SystemZTargetMachine.h new file mode 100644 index 00000000000..194d5fe016c --- /dev/null +++ b/lib/Target/SystemZ/SystemZTargetMachine.h @@ -0,0 +1,68 @@ +//==- SystemZTargetMachine.h - Define TargetMachine for SystemZ ---*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the SystemZ specific subclass of TargetMachine. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_TARGET_SYSTEMZ_TARGETMACHINE_H +#define LLVM_TARGET_SYSTEMZ_TARGETMACHINE_H + +#include "SystemZInstrInfo.h" +#include "SystemZISelLowering.h" +#include "SystemZRegisterInfo.h" +#include "SystemZSubtarget.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + +/// SystemZTargetMachine +/// +class SystemZTargetMachine : public LLVMTargetMachine { + SystemZSubtarget Subtarget; + const TargetData DataLayout; // Calculates type size & alignment + SystemZInstrInfo InstrInfo; + SystemZTargetLowering TLInfo; + + // SystemZ does not have any call stack frame, therefore not having + // any SystemZ specific FrameInfo class. + TargetFrameInfo FrameInfo; + +protected: + virtual const TargetAsmInfo *createTargetAsmInfo() const; + +public: + SystemZTargetMachine(const Module &M, const std::string &FS); + + virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const SystemZInstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const TargetData *getTargetData() const { return &DataLayout;} + virtual const SystemZSubtarget *getSubtargetImpl() const { return &Subtarget; } + + virtual const TargetRegisterInfo *getRegisterInfo() const { + return &InstrInfo.getRegisterInfo(); + } + + virtual SystemZTargetLowering *getTargetLowering() const { + return const_cast(&TLInfo); + } + + virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); + virtual bool addAssemblyEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, bool Verbose, + raw_ostream &Out); + static unsigned getModuleMatchQuality(const Module &M); +}; // SystemZTargetMachine. + +} // end namespace llvm + +#endif // LLVM_TARGET_SystemZ_TARGETMACHINE_H -- 2.34.1