mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
Remove the SystemZ backend.
llvm-svn: 142878
This commit is contained in:
parent
e8a2edd71c
commit
b54d296fd4
@ -76,7 +76,6 @@ set(LLVM_ALL_TARGETS
|
||||
PowerPC
|
||||
PTX
|
||||
Sparc
|
||||
SystemZ
|
||||
X86
|
||||
XCore
|
||||
)
|
||||
|
@ -357,7 +357,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
@ -494,7 +493,6 @@ else
|
||||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
@ -608,13 +606,13 @@ TARGETS_TO_BUILD=""
|
||||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, systemz, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
enableval=all)
|
||||
if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -627,7 +625,6 @@ case "$enableval" in
|
||||
spu) TARGETS_TO_BUILD="CellSPU $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" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
@ -645,7 +642,6 @@ case "$enableval" in
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) AC_MSG_ERROR([Can not set target to build]) ;;
|
||||
|
9
configure
vendored
9
configure
vendored
@ -1416,7 +1416,7 @@ Optional Features:
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, systemz, blackfin, ptx, cbe, and cpp
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp
|
||||
(default=all)
|
||||
--enable-cbe-printf-a Enable C Backend output with hex floating point via
|
||||
%a (default is YES)
|
||||
@ -3880,7 +3880,6 @@ else
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
@ -5084,8 +5083,6 @@ else
|
||||
XCore) TARGET_HAS_JIT=0
|
||||
;;
|
||||
MSP430) TARGET_HAS_JIT=0
|
||||
;;
|
||||
SystemZ) TARGET_HAS_JIT=0
|
||||
;;
|
||||
Blackfin) TARGET_HAS_JIT=0
|
||||
;;
|
||||
@ -5277,7 +5274,7 @@ if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -5290,7 +5287,6 @@ case "$enableval" in
|
||||
spu) TARGETS_TO_BUILD="CellSPU $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" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
@ -5308,7 +5304,6 @@ case "$enableval" in
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5
|
||||
|
@ -2217,7 +2217,6 @@ is the key:</p>
|
||||
<th>PTX</th>
|
||||
<th>PowerPC</th>
|
||||
<th>Sparc</th>
|
||||
<th>SystemZ</th>
|
||||
<th>X86</th>
|
||||
<th>XCore</th>
|
||||
</tr>
|
||||
@ -2234,7 +2233,6 @@ is the key:</p>
|
||||
<td class="no"></td> <!-- PTX -->
|
||||
<td class="yes"></td> <!-- PowerPC -->
|
||||
<td class="yes"></td> <!-- Sparc -->
|
||||
<td class="unknown"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="unknown"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2251,7 +2249,6 @@ is the key:</p>
|
||||
<td class="no"></td> <!-- PTX -->
|
||||
<td class="no"></td> <!-- PowerPC -->
|
||||
<td class="no"></td> <!-- Sparc -->
|
||||
<td class="no"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="no"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2268,7 +2265,6 @@ is the key:</p>
|
||||
<td class="no"></td> <!-- PTX -->
|
||||
<td class="no"></td> <!-- PowerPC -->
|
||||
<td class="no"></td> <!-- Sparc -->
|
||||
<td class="no"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="no"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2285,7 +2281,6 @@ is the key:</p>
|
||||
<td class="unknown"></td> <!-- PTX -->
|
||||
<td class="yes"></td> <!-- PowerPC -->
|
||||
<td class="unknown"></td> <!-- Sparc -->
|
||||
<td class="unknown"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="unknown"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2302,7 +2297,6 @@ is the key:</p>
|
||||
<td class="unknown"></td> <!-- PTX -->
|
||||
<td class="yes"></td> <!-- PowerPC -->
|
||||
<td class="unknown"></td> <!-- Sparc -->
|
||||
<td class="unknown"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="unknown"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2319,7 +2313,6 @@ is the key:</p>
|
||||
<td class="no"></td> <!-- PTX -->
|
||||
<td class="no"></td> <!-- PowerPC -->
|
||||
<td class="no"></td> <!-- Sparc -->
|
||||
<td class="no"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="no"></td> <!-- XCore -->
|
||||
</tr>
|
||||
@ -2336,7 +2329,6 @@ is the key:</p>
|
||||
<td class="unknown"></td> <!-- PTX -->
|
||||
<td class="yes"></td> <!-- PowerPC -->
|
||||
<td class="unknown"></td> <!-- Sparc -->
|
||||
<td class="unknown"></td> <!-- SystemZ -->
|
||||
<td class="yes"></td> <!-- X86 -->
|
||||
<td class="unknown"></td> <!-- XCore -->
|
||||
</tr>
|
||||
|
@ -759,7 +759,7 @@ components, please contact us on the <a
|
||||
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
|
||||
|
||||
<ul>
|
||||
<li>The Alpha, Blackfin, CellSPU, MicroBlaze, MSP430, MIPS, PTX, SystemZ
|
||||
<li>The Alpha, Blackfin, CellSPU, MicroBlaze, MSP430, MIPS, PTX,
|
||||
and XCore backends are experimental.</li>
|
||||
<li><tt>llc</tt> "<tt>-filetype=obj</tt>" is experimental on all targets
|
||||
other than darwin and ELF X86 systems.</li>
|
||||
|
@ -56,7 +56,6 @@ public:
|
||||
ppc64, // PPC64: powerpc64, ppu
|
||||
sparc, // Sparc: sparc
|
||||
sparcv9, // Sparcv9: Sparcv9
|
||||
systemz, // SystemZ: s390x
|
||||
tce, // TCE (http://tce.cs.tut.fi/): tce
|
||||
thumb, // Thumb: thumb, thumbv.*
|
||||
x86, // X86: i[3-9]86
|
||||
|
@ -92,7 +92,7 @@ public:
|
||||
|
||||
/// IsLegalToFold - Returns true if the specific operand node N of
|
||||
/// U can be folded during instruction selection that starts at Root.
|
||||
/// FIXME: This is a static member function because the MSP430/SystemZ/X86
|
||||
/// FIXME: This is a static member function because the MSP430/X86
|
||||
/// targets, which uses it during isel. This could become a proper member.
|
||||
static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
|
@ -31,7 +31,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
||||
case ppc: return "powerpc";
|
||||
case sparc: return "sparc";
|
||||
case sparcv9: return "sparcv9";
|
||||
case systemz: return "s390x";
|
||||
case tce: return "tce";
|
||||
case thumb: return "thumb";
|
||||
case x86: return "i386";
|
||||
@ -165,8 +164,6 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
||||
return sparc;
|
||||
if (Name == "sparcv9")
|
||||
return sparcv9;
|
||||
if (Name == "systemz")
|
||||
return systemz;
|
||||
if (Name == "tce")
|
||||
return tce;
|
||||
if (Name == "thumb")
|
||||
@ -316,8 +313,6 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
|
||||
return sparc;
|
||||
else if (ArchName == "sparcv9")
|
||||
return sparcv9;
|
||||
else if (ArchName == "s390x")
|
||||
return systemz;
|
||||
else if (ArchName == "tce")
|
||||
return tce;
|
||||
else if (ArchName == "xcore")
|
||||
|
@ -1,36 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS SystemZ.td)
|
||||
|
||||
llvm_tablegen(SystemZGenRegisterInfo.inc -gen-register-info)
|
||||
llvm_tablegen(SystemZGenInstrInfo.inc -gen-instr-info)
|
||||
llvm_tablegen(SystemZGenAsmWriter.inc -gen-asm-writer)
|
||||
llvm_tablegen(SystemZGenDAGISel.inc -gen-dag-isel)
|
||||
llvm_tablegen(SystemZGenCallingConv.inc -gen-callingconv)
|
||||
llvm_tablegen(SystemZGenSubtargetInfo.inc -gen-subtarget)
|
||||
add_public_tablegen_target(SystemZCommonTableGen)
|
||||
|
||||
add_llvm_target(SystemZCodeGen
|
||||
SystemZAsmPrinter.cpp
|
||||
SystemZISelDAGToDAG.cpp
|
||||
SystemZISelLowering.cpp
|
||||
SystemZInstrInfo.cpp
|
||||
SystemZFrameLowering.cpp
|
||||
SystemZRegisterInfo.cpp
|
||||
SystemZSubtarget.cpp
|
||||
SystemZTargetMachine.cpp
|
||||
SystemZSelectionDAGInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMSystemZCodeGen
|
||||
LLVMAsmPrinter
|
||||
LLVMCodeGen
|
||||
LLVMCore
|
||||
LLVMMC
|
||||
LLVMSelectionDAG
|
||||
LLVMSupport
|
||||
LLVMSystemZDesc
|
||||
LLVMSystemZInfo
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
@ -1,14 +0,0 @@
|
||||
add_llvm_library(LLVMSystemZDesc
|
||||
SystemZMCTargetDesc.cpp
|
||||
SystemZMCAsmInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMSystemZDesc
|
||||
LLVMMC
|
||||
LLVMSystemZInfo
|
||||
)
|
||||
|
||||
add_dependencies(LLVMSystemZDesc SystemZCommonTableGen)
|
||||
|
||||
# Hack: we need to include 'main' target directory to grab private headers
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/..)
|
@ -1,16 +0,0 @@
|
||||
##===- lib/Target/SystemZ/TargetDesc/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 = LLVMSystemZDesc
|
||||
|
||||
# Hack: we need to include 'main' target directory to grab private headers
|
||||
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
@ -1,32 +0,0 @@
|
||||
//===-- SystemZMCAsmInfo.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 SystemZMCAsmInfo properties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZMCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
using namespace llvm;
|
||||
|
||||
SystemZMCAsmInfo::SystemZMCAsmInfo(const Target &T, StringRef TT) {
|
||||
IsLittleEndian = false;
|
||||
PointerSize = 8;
|
||||
PrivateGlobalPrefix = ".L";
|
||||
WeakRefDirective = "\t.weak\t";
|
||||
PCSymbol = ".";
|
||||
}
|
||||
|
||||
const MCSection *SystemZMCAsmInfo::
|
||||
getNonexecutableStackSection(MCContext &Ctx) const{
|
||||
return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS,
|
||||
0, SectionKind::getMetadata());
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
//====-- SystemZMCAsmInfo.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 SystemZMCAsmInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SystemZTARGETASMINFO_H
|
||||
#define SystemZTARGETASMINFO_H
|
||||
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class Target;
|
||||
class StringRef;
|
||||
|
||||
struct SystemZMCAsmInfo : public MCAsmInfo {
|
||||
explicit SystemZMCAsmInfo(const Target &T, StringRef TT);
|
||||
virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -1,81 +0,0 @@
|
||||
//===-- SystemZMCTargetDesc.cpp - SystemZ Target Descriptions ---*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides SystemZ specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZMCTargetDesc.h"
|
||||
#include "SystemZMCAsmInfo.h"
|
||||
#include "llvm/MC/MCCodeGenInfo.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#define GET_INSTRINFO_MC_DESC
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_MC_DESC
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static MCInstrInfo *createSystemZMCInstrInfo() {
|
||||
MCInstrInfo *X = new MCInstrInfo();
|
||||
InitSystemZMCInstrInfo(X);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCRegisterInfo *createSystemZMCRegisterInfo(StringRef TT) {
|
||||
MCRegisterInfo *X = new MCRegisterInfo();
|
||||
InitSystemZMCRegisterInfo(X, 0);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCSubtargetInfo *createSystemZMCSubtargetInfo(StringRef TT,
|
||||
StringRef CPU,
|
||||
StringRef FS) {
|
||||
MCSubtargetInfo *X = new MCSubtargetInfo();
|
||||
InitSystemZMCSubtargetInfo(X, TT, CPU, FS);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCCodeGenInfo *createSystemZMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
CodeModel::Model CM) {
|
||||
MCCodeGenInfo *X = new MCCodeGenInfo();
|
||||
if (RM == Reloc::Default)
|
||||
RM = Reloc::Static;
|
||||
X->InitMCCodeGenInfo(RM, CM);
|
||||
return X;
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializeSystemZTargetMC() {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfo<SystemZMCAsmInfo> X(TheSystemZTarget);
|
||||
|
||||
// Register the MC codegen info.
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheSystemZTarget,
|
||||
createSystemZMCCodeGenInfo);
|
||||
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(TheSystemZTarget,
|
||||
createSystemZMCInstrInfo);
|
||||
|
||||
// Register the MC register info.
|
||||
TargetRegistry::RegisterMCRegInfo(TheSystemZTarget,
|
||||
createSystemZMCRegisterInfo);
|
||||
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(TheSystemZTarget,
|
||||
createSystemZMCSubtargetInfo);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//===-- SystemZMCTargetDesc.h - SystemZ Target Descriptions -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides SystemZ specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SYSTEMZMCTARGETDESC_H
|
||||
#define SYSTEMZMCTARGETDESC_H
|
||||
|
||||
namespace llvm {
|
||||
class MCSubtargetInfo;
|
||||
class Target;
|
||||
class StringRef;
|
||||
|
||||
extern Target TheSystemZTarget;
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
// Defines symbolic names for SystemZ registers.
|
||||
// This defines a mapping from register name to register number.
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
// Defines symbolic names for the SystemZ instructions.
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
##===- 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.inc SystemZGenInstrInfo.inc \
|
||||
SystemZGenAsmWriter.inc SystemZGenDAGISel.inc \
|
||||
SystemZGenSubtargetInfo.inc SystemZGenCallingConv.inc
|
||||
|
||||
DIRS = TargetInfo MCTargetDesc
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -1,52 +0,0 @@
|
||||
//=-- 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 "MCTargetDesc/SystemZMCTargetDesc.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
namespace llvm {
|
||||
class SystemZTargetMachine;
|
||||
class FunctionPass;
|
||||
class formatted_raw_ostream;
|
||||
|
||||
namespace SystemZCC {
|
||||
// SystemZ specific condition code. These correspond to SYSTEMZ_*_COND in
|
||||
// SystemZInstrInfo.td. They must be kept in synch.
|
||||
enum CondCodes {
|
||||
O = 0,
|
||||
H = 1,
|
||||
NLE = 2,
|
||||
L = 3,
|
||||
NHE = 4,
|
||||
LH = 5,
|
||||
NE = 6,
|
||||
E = 7,
|
||||
NLH = 8,
|
||||
HE = 9,
|
||||
NL = 10,
|
||||
LE = 11,
|
||||
NH = 12,
|
||||
NO = 13,
|
||||
INVALID = -1
|
||||
};
|
||||
}
|
||||
|
||||
FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
||||
} // end namespace llvm;
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
//===- 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 FeatureZ10 : SubtargetFeature<"z10", "HasZ10Insts", "true",
|
||||
"Support Z10 instructions">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SystemZ supported processors.
|
||||
//===----------------------------------------------------------------------===//
|
||||
class Proc<string Name, list<SubtargetFeature> Features>
|
||||
: Processor<Name, NoItineraries, Features>;
|
||||
|
||||
def : Proc<"z9", []>;
|
||||
def : Proc<"z10", [FeatureZ10]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "SystemZRegisterInfo.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "SystemZCallingConv.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Descriptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "SystemZInstrInfo.td"
|
||||
include "SystemZInstrFP.td"
|
||||
|
||||
def SystemZInstrInfo : InstrInfo {}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Target Declaration
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def SystemZ : Target {
|
||||
let InstructionSet = SystemZInstrInfo;
|
||||
}
|
||||
|
@ -1,221 +0,0 @@
|
||||
//===-- 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/Assembly/Writer.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class SystemZAsmPrinter : public AsmPrinter {
|
||||
public:
|
||||
SystemZAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
||||
: AsmPrinter(TM, Streamer) {}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Assembly Printer";
|
||||
}
|
||||
|
||||
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
|
||||
const char* Modifier = 0);
|
||||
void printPCRelImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
|
||||
void printRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
|
||||
const char* Modifier = 0);
|
||||
void printRRIAddrOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
|
||||
const char* Modifier = 0);
|
||||
void printS16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
|
||||
O << (int16_t)MI->getOperand(OpNum).getImm();
|
||||
}
|
||||
void printU16ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
|
||||
O << (uint16_t)MI->getOperand(OpNum).getImm();
|
||||
}
|
||||
void printS32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
|
||||
O << (int32_t)MI->getOperand(OpNum).getImm();
|
||||
}
|
||||
void printU32ImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) {
|
||||
O << (uint32_t)MI->getOperand(OpNum).getImm();
|
||||
}
|
||||
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &O);
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
void EmitInstruction(const MachineInstr *MI);
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
#include "SystemZGenAsmWriter.inc"
|
||||
|
||||
void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
|
||||
void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum,
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Immediate:
|
||||
O << MO.getImm();
|
||||
return;
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
O << *MO.getMBB()->getSymbol();
|
||||
return;
|
||||
case MachineOperand::MO_GlobalAddress: {
|
||||
const GlobalValue *GV = MO.getGlobal();
|
||||
O << *Mang->getSymbol(GV);
|
||||
|
||||
// Assemble calls via PLT for externally visible symbols if PIC.
|
||||
if (TM.getRelocationModel() == Reloc::PIC_ &&
|
||||
!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
|
||||
!GV->hasLocalLinkage())
|
||||
O << "@PLT";
|
||||
|
||||
printOffset(MO.getOffset(), O);
|
||||
return;
|
||||
}
|
||||
case MachineOperand::MO_ExternalSymbol: {
|
||||
std::string Name(MAI->getGlobalPrefix());
|
||||
Name += MO.getSymbolName();
|
||||
O << Name;
|
||||
|
||||
if (TM.getRelocationModel() == Reloc::PIC_)
|
||||
O << "@PLT";
|
||||
|
||||
return;
|
||||
}
|
||||
default:
|
||||
assert(0 && "Not implemented yet!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
||||
raw_ostream &O, const char *Modifier) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNum);
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Register: {
|
||||
assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
||||
"Virtual registers should be already mapped!");
|
||||
unsigned Reg = MO.getReg();
|
||||
if (Modifier && strncmp(Modifier, "subreg", 6) == 0) {
|
||||
if (strncmp(Modifier + 7, "even", 4) == 0)
|
||||
Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_32bit);
|
||||
else if (strncmp(Modifier + 7, "odd", 3) == 0)
|
||||
Reg = TM.getRegisterInfo()->getSubReg(Reg, SystemZ::subreg_odd32);
|
||||
else
|
||||
assert(0 && "Invalid subreg modifier");
|
||||
}
|
||||
|
||||
O << '%' << getRegisterName(Reg);
|
||||
return;
|
||||
}
|
||||
case MachineOperand::MO_Immediate:
|
||||
O << MO.getImm();
|
||||
return;
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
O << *MO.getMBB()->getSymbol();
|
||||
return;
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
|
||||
<< MO.getIndex();
|
||||
|
||||
return;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
|
||||
<< MO.getIndex();
|
||||
|
||||
printOffset(MO.getOffset(), O);
|
||||
break;
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
O << *Mang->getSymbol(MO.getGlobal());
|
||||
break;
|
||||
case MachineOperand::MO_ExternalSymbol: {
|
||||
O << *GetExternalSymbolSymbol(MO.getSymbolName());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0 && "Not implemented yet!");
|
||||
}
|
||||
|
||||
switch (MO.getTargetFlags()) {
|
||||
default: assert(0 && "Unknown target flag on GV operand");
|
||||
case SystemZII::MO_NO_FLAG:
|
||||
break;
|
||||
case SystemZII::MO_GOTENT: O << "@GOTENT"; break;
|
||||
case SystemZII::MO_PLT: O << "@PLT"; break;
|
||||
}
|
||||
|
||||
printOffset(MO.getOffset(), O);
|
||||
}
|
||||
|
||||
void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,
|
||||
raw_ostream &O,
|
||||
const char *Modifier) {
|
||||
const MachineOperand &Base = MI->getOperand(OpNum);
|
||||
|
||||
// Print displacement operand.
|
||||
printOperand(MI, OpNum+1, O);
|
||||
|
||||
// Print base operand (if any)
|
||||
if (Base.getReg()) {
|
||||
O << '(';
|
||||
printOperand(MI, OpNum, O);
|
||||
O << ')';
|
||||
}
|
||||
}
|
||||
|
||||
void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
|
||||
raw_ostream &O,
|
||||
const char *Modifier) {
|
||||
const MachineOperand &Base = MI->getOperand(OpNum);
|
||||
const MachineOperand &Index = MI->getOperand(OpNum+2);
|
||||
|
||||
// Print displacement operand.
|
||||
printOperand(MI, OpNum+1, O);
|
||||
|
||||
// Print base operand (if any)
|
||||
if (Base.getReg()) {
|
||||
O << '(';
|
||||
printOperand(MI, OpNum, O);
|
||||
if (Index.getReg()) {
|
||||
O << ',';
|
||||
printOperand(MI, OpNum+2, O);
|
||||
}
|
||||
O << ')';
|
||||
} else
|
||||
assert(!Index.getReg() && "Should allocate base register first!");
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeSystemZAsmPrinter() {
|
||||
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
//=- 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<[
|
||||
// Promote i8/i16/i32 arguments to i64.
|
||||
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
|
||||
|
||||
// i64 is returned in register R2
|
||||
CCIfType<[i64], CCAssignToReg<[R2D, R3D, R4D, R5D]>>,
|
||||
|
||||
// f32 / f64 are returned in F0
|
||||
CCIfType<[f32], CCAssignToReg<[F0S, F2S, F4S, F6S]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[F0L, F2L, F4L, F6L]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SystemZ Argument Calling Conventions
|
||||
//===----------------------------------------------------------------------===//
|
||||
def CC_SystemZ : CallingConv<[
|
||||
// Promote i8/i16/i32 arguments to i64.
|
||||
CCIfType<[i8, i16, i32], CCPromoteToType<i64>>,
|
||||
|
||||
// The first 5 integer arguments of non-varargs functions are passed in
|
||||
// integer registers.
|
||||
CCIfType<[i64], CCAssignToReg<[R2D, R3D, R4D, R5D, R6D]>>,
|
||||
|
||||
// The first 4 floating point arguments of non-varargs functions are passed
|
||||
// in FP registers.
|
||||
CCIfType<[f32], CCAssignToReg<[F0S, F2S, F4S, F6S]>>,
|
||||
CCIfType<[f64], CCAssignToReg<[F0L, F2L, F4L, F6L]>>,
|
||||
|
||||
// Integer values get stored in stack slots that are 8 bytes in
|
||||
// size and 8-byte aligned.
|
||||
CCIfType<[i64, f32, f64], CCAssignToStack<8, 8>>
|
||||
]>;
|
@ -1,386 +0,0 @@
|
||||
//=====- SystemZFrameLowering.cpp - SystemZ Frame 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 TargetFrameLowering class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZFrameLowering.h"
|
||||
#include "SystemZInstrBuilder.h"
|
||||
#include "SystemZInstrInfo.h"
|
||||
#include "SystemZMachineFunctionInfo.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
SystemZFrameLowering::SystemZFrameLowering(const SystemZSubtarget &sti)
|
||||
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 8, -160), STI(sti) {
|
||||
// Fill the spill offsets map
|
||||
static const unsigned SpillOffsTab[][2] = {
|
||||
{ SystemZ::R2D, 0x10 },
|
||||
{ SystemZ::R3D, 0x18 },
|
||||
{ SystemZ::R4D, 0x20 },
|
||||
{ SystemZ::R5D, 0x28 },
|
||||
{ SystemZ::R6D, 0x30 },
|
||||
{ SystemZ::R7D, 0x38 },
|
||||
{ SystemZ::R8D, 0x40 },
|
||||
{ SystemZ::R9D, 0x48 },
|
||||
{ SystemZ::R10D, 0x50 },
|
||||
{ SystemZ::R11D, 0x58 },
|
||||
{ SystemZ::R12D, 0x60 },
|
||||
{ SystemZ::R13D, 0x68 },
|
||||
{ SystemZ::R14D, 0x70 },
|
||||
{ SystemZ::R15D, 0x78 }
|
||||
};
|
||||
|
||||
RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);
|
||||
|
||||
for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i)
|
||||
RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1];
|
||||
}
|
||||
|
||||
/// 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 SystemZFrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
|
||||
}
|
||||
|
||||
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
|
||||
/// stack pointer by a constant value.
|
||||
static
|
||||
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
|
||||
int64_t NumBytes, const TargetInstrInfo &TII) {
|
||||
unsigned Opc; uint64_t Chunk;
|
||||
bool isSub = NumBytes < 0;
|
||||
uint64_t Offset = isSub ? -NumBytes : NumBytes;
|
||||
|
||||
if (Offset >= (1LL << 15) - 1) {
|
||||
Opc = SystemZ::ADD64ri32;
|
||||
Chunk = (1LL << 31) - 1;
|
||||
} else {
|
||||
Opc = SystemZ::ADD64ri16;
|
||||
Chunk = (1LL << 15) - 1;
|
||||
}
|
||||
|
||||
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||
|
||||
while (Offset) {
|
||||
uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
|
||||
MachineInstr *MI =
|
||||
BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
|
||||
.addReg(SystemZ::R15D).addImm(isSub ? -ThisVal : ThisVal);
|
||||
// The PSW implicit def is dead.
|
||||
MI->getOperand(3).setIsDead();
|
||||
Offset -= ThisVal;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemZFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const SystemZInstrInfo &TII =
|
||||
*static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
|
||||
SystemZMachineFunctionInfo *SystemZMFI =
|
||||
MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo.
|
||||
// Note that area for callee-saved stuff is already allocated, thus we need to
|
||||
// 'undo' the stack movement.
|
||||
uint64_t StackSize = MFI->getStackSize();
|
||||
StackSize -= SystemZMFI->getCalleeSavedFrameSize();
|
||||
|
||||
uint64_t NumBytes = StackSize - getOffsetOfLocalArea();
|
||||
|
||||
// Skip the callee-saved push instructions.
|
||||
while (MBBI != MBB.end() &&
|
||||
(MBBI->getOpcode() == SystemZ::MOV64mr ||
|
||||
MBBI->getOpcode() == SystemZ::MOV64mrm))
|
||||
++MBBI;
|
||||
|
||||
if (MBBI != MBB.end())
|
||||
DL = MBBI->getDebugLoc();
|
||||
|
||||
// adjust stack pointer: R15 -= numbytes
|
||||
if (StackSize || MFI->hasCalls()) {
|
||||
assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
|
||||
"Invalid stack frame calculation!");
|
||||
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
|
||||
}
|
||||
|
||||
if (hasFP(MF)) {
|
||||
// Update R11 with the new base value...
|
||||
BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
|
||||
.addReg(SystemZ::R15D);
|
||||
|
||||
// Mark the FramePtr as live-in in every block except the entry.
|
||||
for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
|
||||
I != E; ++I)
|
||||
I->addLiveIn(SystemZ::R11D);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SystemZFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
||||
const SystemZInstrInfo &TII =
|
||||
*static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
|
||||
SystemZMachineFunctionInfo *SystemZMFI =
|
||||
MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
unsigned RetOpcode = MBBI->getOpcode();
|
||||
|
||||
switch (RetOpcode) {
|
||||
case SystemZ::RET: break; // These are ok
|
||||
default:
|
||||
assert(0 && "Can only insert epilog into returning blocks");
|
||||
}
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo
|
||||
// Note that area for callee-saved stuff is already allocated, thus we need to
|
||||
// 'undo' the stack movement.
|
||||
uint64_t StackSize =
|
||||
MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
|
||||
uint64_t NumBytes = StackSize - getOffsetOfLocalArea();
|
||||
|
||||
// Skip the final terminator instruction.
|
||||
while (MBBI != MBB.begin()) {
|
||||
MachineBasicBlock::iterator PI = prior(MBBI);
|
||||
--MBBI;
|
||||
if (!PI->getDesc().isTerminator())
|
||||
break;
|
||||
}
|
||||
|
||||
// During callee-saved restores emission stack frame was not yet finialized
|
||||
// (and thus - the stack size was unknown). Tune the offset having full stack
|
||||
// size in hands.
|
||||
if (StackSize || MFI->hasCalls()) {
|
||||
assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
|
||||
MBBI->getOpcode() == SystemZ::MOV64rm) &&
|
||||
"Expected to see callee-save register restore code");
|
||||
assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
|
||||
"Invalid stack frame calculation!");
|
||||
|
||||
unsigned i = 0;
|
||||
MachineInstr &MI = *MBBI;
|
||||
while (!MI.getOperand(i).isImm()) {
|
||||
++i;
|
||||
assert(i < MI.getNumOperands() && "Unexpected restore code!");
|
||||
}
|
||||
|
||||
uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
|
||||
// If Offset does not fit into 20-bit signed displacement field we need to
|
||||
// emit some additional code...
|
||||
if (Offset > 524287) {
|
||||
// Fold the displacement into load instruction as much as possible.
|
||||
NumBytes = Offset - 524287;
|
||||
Offset = 524287;
|
||||
emitSPUpdate(MBB, MBBI, NumBytes, TII);
|
||||
}
|
||||
|
||||
MI.getOperand(i).ChangeToImmediate(Offset);
|
||||
}
|
||||
}
|
||||
|
||||
int SystemZFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
|
||||
int FI) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const SystemZMachineFunctionInfo *SystemZMFI =
|
||||
MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment();
|
||||
uint64_t StackSize = MFI->getStackSize();
|
||||
|
||||
// Fixed objects are really located in the "previous" frame.
|
||||
if (FI < 0)
|
||||
StackSize -= SystemZMFI->getCalleeSavedFrameSize();
|
||||
|
||||
Offset += StackSize - getOffsetOfLocalArea();
|
||||
|
||||
// Skip the register save area if we generated the stack frame.
|
||||
if (StackSize || MFI->hasCalls())
|
||||
Offset -= getOffsetOfLocalArea();
|
||||
|
||||
return Offset;
|
||||
}
|
||||
|
||||
bool
|
||||
SystemZFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
const std::vector<CalleeSavedInfo> &CSI,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
if (CSI.empty())
|
||||
return false;
|
||||
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
unsigned CalleeFrameSize = 0;
|
||||
|
||||
// Scan the callee-saved and find the bounds of register spill area.
|
||||
unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
if (!SystemZ::FP64RegClass.contains(Reg)) {
|
||||
unsigned Offset = RegSpillOffsets[Reg];
|
||||
CalleeFrameSize += 8;
|
||||
if (StartOffset > Offset) {
|
||||
LowReg = Reg; StartOffset = Offset;
|
||||
}
|
||||
if (EndOffset < Offset) {
|
||||
HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save information for epilogue inserter.
|
||||
MFI->setCalleeSavedFrameSize(CalleeFrameSize);
|
||||
MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);
|
||||
|
||||
// Save GPRs
|
||||
if (StartOffset) {
|
||||
// Build a store instruction. Use STORE MULTIPLE instruction if there are many
|
||||
// registers to store, otherwise - just STORE.
|
||||
MachineInstrBuilder MIB =
|
||||
BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ?
|
||||
SystemZ::MOV64mr : SystemZ::MOV64mrm)));
|
||||
|
||||
// Add store operands.
|
||||
MIB.addReg(SystemZ::R15D).addImm(StartOffset);
|
||||
if (LowReg == HighReg)
|
||||
MIB.addReg(0);
|
||||
MIB.addReg(LowReg, RegState::Kill);
|
||||
if (LowReg != HighReg)
|
||||
MIB.addReg(HighReg, RegState::Kill);
|
||||
|
||||
// Do a second scan adding regs as being killed by instruction
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
// Add the callee-saved register as live-in. It's killed at the spill.
|
||||
MBB.addLiveIn(Reg);
|
||||
if (Reg != LowReg && Reg != HighReg)
|
||||
MIB.addReg(Reg, RegState::ImplicitKill);
|
||||
}
|
||||
}
|
||||
|
||||
// Save FPRs
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
if (SystemZ::FP64RegClass.contains(Reg)) {
|
||||
MBB.addLiveIn(Reg);
|
||||
TII.storeRegToStackSlot(MBB, MI, Reg, true, CSI[i].getFrameIdx(),
|
||||
&SystemZ::FP64RegClass, TRI);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SystemZFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
const std::vector<CalleeSavedInfo> &CSI,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
if (CSI.empty())
|
||||
return false;
|
||||
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
|
||||
// Restore FP registers
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
if (SystemZ::FP64RegClass.contains(Reg))
|
||||
TII.loadRegFromStackSlot(MBB, MI, Reg, CSI[i].getFrameIdx(),
|
||||
&SystemZ::FP64RegClass, TRI);
|
||||
}
|
||||
|
||||
// Restore GP registers
|
||||
unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
|
||||
unsigned StartOffset = RegSpillOffsets[LowReg];
|
||||
|
||||
if (StartOffset) {
|
||||
// Build a load instruction. Use LOAD MULTIPLE instruction if there are many
|
||||
// registers to load, otherwise - just LOAD.
|
||||
MachineInstrBuilder MIB =
|
||||
BuildMI(MBB, MI, DL, TII.get((LowReg == HighReg ?
|
||||
SystemZ::MOV64rm : SystemZ::MOV64rmm)));
|
||||
// Add store operands.
|
||||
MIB.addReg(LowReg, RegState::Define);
|
||||
if (LowReg != HighReg)
|
||||
MIB.addReg(HighReg, RegState::Define);
|
||||
|
||||
MIB.addReg(hasFP(MF) ? SystemZ::R11D : SystemZ::R15D);
|
||||
MIB.addImm(StartOffset);
|
||||
if (LowReg == HighReg)
|
||||
MIB.addReg(0);
|
||||
|
||||
// Do a second scan adding regs as being defined by instruction
|
||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||
unsigned Reg = CSI[i].getReg();
|
||||
if (Reg != LowReg && Reg != HighReg)
|
||||
MIB.addReg(Reg, RegState::ImplicitDefine);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SystemZFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const {
|
||||
// Determine whether R15/R14 will ever be clobbered inside the function. And
|
||||
// if yes - mark it as 'callee' saved.
|
||||
MachineFrameInfo *FFI = MF.getFrameInfo();
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
|
||||
// Check whether high FPRs are ever used, if yes - we need to save R15 as
|
||||
// well.
|
||||
static const unsigned HighFPRs[] = {
|
||||
SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L,
|
||||
SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
|
||||
SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S,
|
||||
SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S,
|
||||
};
|
||||
|
||||
bool HighFPRsUsed = false;
|
||||
for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i)
|
||||
HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]);
|
||||
|
||||
if (FFI->hasCalls())
|
||||
/* FIXME: function is varargs */
|
||||
/* FIXME: function grabs RA */
|
||||
/* FIXME: function calls eh_return */
|
||||
MRI.setPhysRegUsed(SystemZ::R14D);
|
||||
|
||||
if (HighFPRsUsed ||
|
||||
FFI->hasCalls() ||
|
||||
FFI->getObjectIndexEnd() != 0 || // Contains automatic variables
|
||||
FFI->hasVarSizedObjects() // Function calls dynamic alloca's
|
||||
/* FIXME: function is varargs */)
|
||||
MRI.setPhysRegUsed(SystemZ::R15D);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
//=- SystemZFrameLowering.h - Define frame lowering for z/System -*- C++ -*--=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SYSTEMZ_FRAMEINFO_H
|
||||
#define SYSTEMZ_FRAMEINFO_H
|
||||
|
||||
#include "SystemZ.h"
|
||||
#include "SystemZSubtarget.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/ADT/IndexedMap.h"
|
||||
|
||||
namespace llvm {
|
||||
class SystemZSubtarget;
|
||||
|
||||
class SystemZFrameLowering : public TargetFrameLowering {
|
||||
IndexedMap<unsigned> RegSpillOffsets;
|
||||
protected:
|
||||
const SystemZSubtarget &STI;
|
||||
|
||||
public:
|
||||
explicit SystemZFrameLowering(const SystemZSubtarget &sti);
|
||||
|
||||
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
|
||||
/// the function.
|
||||
void emitPrologue(MachineFunction &MF) const;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
|
||||
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
const std::vector<CalleeSavedInfo> &CSI,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
const std::vector<CalleeSavedInfo> &CSI,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const;
|
||||
|
||||
bool hasReservedCallFrame(const MachineFunction &MF) const { return true; }
|
||||
bool hasFP(const MachineFunction &MF) const;
|
||||
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,779 +0,0 @@
|
||||
//==-- 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 "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"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
/// SystemZRRIAddressMode - This corresponds to rriaddr, but uses SDValue's
|
||||
/// instead of register numbers for the leaves of the matched tree.
|
||||
struct SystemZRRIAddressMode {
|
||||
enum {
|
||||
RegBase,
|
||||
FrameIndexBase
|
||||
} BaseType;
|
||||
|
||||
struct { // This is really a union, discriminated by BaseType!
|
||||
SDValue Reg;
|
||||
int FrameIndex;
|
||||
} Base;
|
||||
|
||||
SDValue IndexReg;
|
||||
int64_t Disp;
|
||||
bool isRI;
|
||||
|
||||
SystemZRRIAddressMode(bool RI = false)
|
||||
: BaseType(RegBase), IndexReg(), Disp(0), isRI(RI) {
|
||||
}
|
||||
|
||||
void dump() {
|
||||
errs() << "SystemZRRIAddressMode " << this << '\n';
|
||||
if (BaseType == RegBase) {
|
||||
errs() << "Base.Reg ";
|
||||
if (Base.Reg.getNode() != 0)
|
||||
Base.Reg.getNode()->dump();
|
||||
else
|
||||
errs() << "nul";
|
||||
errs() << '\n';
|
||||
} else {
|
||||
errs() << " Base.FrameIndex " << Base.FrameIndex << '\n';
|
||||
}
|
||||
if (!isRI) {
|
||||
errs() << "IndexReg ";
|
||||
if (IndexReg.getNode() != 0) IndexReg.getNode()->dump();
|
||||
else errs() << "nul";
|
||||
}
|
||||
errs() << " Disp " << Disp << '\n';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// SystemZDAGToDAGISel - SystemZ specific code to select SystemZ machine
|
||||
/// instructions for SelectionDAG operations.
|
||||
///
|
||||
namespace {
|
||||
class SystemZDAGToDAGISel : public SelectionDAGISel {
|
||||
const SystemZTargetLowering &Lowering;
|
||||
const SystemZSubtarget &Subtarget;
|
||||
|
||||
void getAddressOperandsRI(const SystemZRRIAddressMode &AM,
|
||||
SDValue &Base, SDValue &Disp);
|
||||
void getAddressOperands(const SystemZRRIAddressMode &AM,
|
||||
SDValue &Base, SDValue &Disp,
|
||||
SDValue &Index);
|
||||
|
||||
public:
|
||||
SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel)
|
||||
: SelectionDAGISel(TM, OptLevel),
|
||||
Lowering(*TM.getTargetLowering()),
|
||||
Subtarget(*TM.getSubtargetImpl()) { }
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
|
||||
/// getI8Imm - Return a target constant with the specified value, of type
|
||||
/// i8.
|
||||
inline SDValue getI8Imm(uint64_t Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, MVT::i8);
|
||||
}
|
||||
|
||||
/// getI16Imm - Return a target constant with the specified value, of type
|
||||
/// i16.
|
||||
inline SDValue getI16Imm(uint64_t Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, MVT::i16);
|
||||
}
|
||||
|
||||
/// getI32Imm - Return a target constant with the specified value, of type
|
||||
/// i32.
|
||||
inline SDValue getI32Imm(uint64_t Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, MVT::i32);
|
||||
}
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "SystemZGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
bool SelectAddrRI12Only(SDValue& Addr,
|
||||
SDValue &Base, SDValue &Disp);
|
||||
bool SelectAddrRI12(SDValue& Addr,
|
||||
SDValue &Base, SDValue &Disp,
|
||||
bool is12BitOnly = false);
|
||||
bool SelectAddrRI(SDValue& Addr, SDValue &Base, SDValue &Disp);
|
||||
bool SelectAddrRRI12(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index);
|
||||
bool SelectAddrRRI20(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index);
|
||||
bool SelectLAAddr(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index);
|
||||
|
||||
SDNode *Select(SDNode *Node);
|
||||
|
||||
bool TryFoldLoad(SDNode *P, SDValue N,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index);
|
||||
|
||||
bool MatchAddress(SDValue N, SystemZRRIAddressMode &AM,
|
||||
bool is12Bit, unsigned Depth = 0);
|
||||
bool MatchAddressBase(SDValue N, SystemZRRIAddressMode &AM);
|
||||
};
|
||||
} // 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);
|
||||
}
|
||||
|
||||
/// isImmSExt20 - This method tests to see if the node is either a 32-bit
|
||||
/// or 64-bit immediate, and if the value can be accurately represented as a
|
||||
/// sign extension from a 20-bit value. If so, this returns true and the
|
||||
/// immediate.
|
||||
static bool isImmSExt20(int64_t Val, int64_t &Imm) {
|
||||
if (Val >= -524288 && Val <= 524287) {
|
||||
Imm = Val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// isImmZExt12 - This method tests to see if the node is either a 32-bit
|
||||
/// or 64-bit immediate, and if the value can be accurately represented as a
|
||||
/// zero extension from a 12-bit value. If so, this returns true and the
|
||||
/// immediate.
|
||||
static bool isImmZExt12(int64_t Val, int64_t &Imm) {
|
||||
if (Val >= 0 && Val <= 0xFFF) {
|
||||
Imm = Val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// MatchAddress - Add the specified node to the specified addressing mode,
|
||||
/// returning true if it cannot be done. This just pattern matches for the
|
||||
/// addressing mode.
|
||||
bool SystemZDAGToDAGISel::MatchAddress(SDValue N, SystemZRRIAddressMode &AM,
|
||||
bool is12Bit, unsigned Depth) {
|
||||
DebugLoc dl = N.getDebugLoc();
|
||||
DEBUG(errs() << "MatchAddress: "; AM.dump());
|
||||
// Limit recursion.
|
||||
if (Depth > 5)
|
||||
return MatchAddressBase(N, AM);
|
||||
|
||||
// FIXME: We can perform better here. If we have something like
|
||||
// (shift (add A, imm), N), we can try to reassociate stuff and fold shift of
|
||||
// imm into addressing mode.
|
||||
switch (N.getOpcode()) {
|
||||
default: break;
|
||||
case ISD::Constant: {
|
||||
int64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
|
||||
int64_t Imm = 0;
|
||||
bool Match = (is12Bit ?
|
||||
isImmZExt12(AM.Disp + Val, Imm) :
|
||||
isImmSExt20(AM.Disp + Val, Imm));
|
||||
if (Match) {
|
||||
AM.Disp = Imm;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::FrameIndex:
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase &&
|
||||
AM.Base.Reg.getNode() == 0) {
|
||||
AM.BaseType = SystemZRRIAddressMode::FrameIndexBase;
|
||||
AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::SUB: {
|
||||
// Given A-B, if A can be completely folded into the address and
|
||||
// the index field with the index field unused, use -B as the index.
|
||||
// This is a win if a has multiple parts that can be folded into
|
||||
// the address. Also, this saves a mov if the base register has
|
||||
// other uses, since it avoids a two-address sub instruction, however
|
||||
// it costs an additional mov if the index register has other uses.
|
||||
|
||||
// Test if the LHS of the sub can be folded.
|
||||
SystemZRRIAddressMode Backup = AM;
|
||||
if (MatchAddress(N.getNode()->getOperand(0), AM, is12Bit, Depth+1)) {
|
||||
AM = Backup;
|
||||
break;
|
||||
}
|
||||
// Test if the index field is free for use.
|
||||
if (AM.IndexReg.getNode() || AM.isRI) {
|
||||
AM = Backup;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the base is a register with multiple uses, this transformation may
|
||||
// save a mov. Otherwise it's probably better not to do it.
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase &&
|
||||
(!AM.Base.Reg.getNode() || AM.Base.Reg.getNode()->hasOneUse())) {
|
||||
AM = Backup;
|
||||
break;
|
||||
}
|
||||
|
||||
// Ok, the transformation is legal and appears profitable. Go for it.
|
||||
SDValue RHS = N.getNode()->getOperand(1);
|
||||
SDValue Zero = CurDAG->getConstant(0, N.getValueType());
|
||||
SDValue Neg = CurDAG->getNode(ISD::SUB, dl, N.getValueType(), Zero, RHS);
|
||||
AM.IndexReg = Neg;
|
||||
|
||||
// Insert the new nodes into the topological ordering.
|
||||
if (Zero.getNode()->getNodeId() == -1 ||
|
||||
Zero.getNode()->getNodeId() > N.getNode()->getNodeId()) {
|
||||
CurDAG->RepositionNode(N.getNode(), Zero.getNode());
|
||||
Zero.getNode()->setNodeId(N.getNode()->getNodeId());
|
||||
}
|
||||
if (Neg.getNode()->getNodeId() == -1 ||
|
||||
Neg.getNode()->getNodeId() > N.getNode()->getNodeId()) {
|
||||
CurDAG->RepositionNode(N.getNode(), Neg.getNode());
|
||||
Neg.getNode()->setNodeId(N.getNode()->getNodeId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case ISD::ADD: {
|
||||
SystemZRRIAddressMode Backup = AM;
|
||||
if (!MatchAddress(N.getNode()->getOperand(0), AM, is12Bit, Depth+1) &&
|
||||
!MatchAddress(N.getNode()->getOperand(1), AM, is12Bit, Depth+1))
|
||||
return false;
|
||||
AM = Backup;
|
||||
if (!MatchAddress(N.getNode()->getOperand(1), AM, is12Bit, Depth+1) &&
|
||||
!MatchAddress(N.getNode()->getOperand(0), AM, is12Bit, Depth+1))
|
||||
return false;
|
||||
AM = Backup;
|
||||
|
||||
// If we couldn't fold both operands into the address at the same time,
|
||||
// see if we can just put each operand into a register and fold at least
|
||||
// the add.
|
||||
if (!AM.isRI &&
|
||||
AM.BaseType == SystemZRRIAddressMode::RegBase &&
|
||||
!AM.Base.Reg.getNode() && !AM.IndexReg.getNode()) {
|
||||
AM.Base.Reg = N.getNode()->getOperand(0);
|
||||
AM.IndexReg = N.getNode()->getOperand(1);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::OR:
|
||||
// Handle "X | C" as "X + C" iff X is known to have C bits clear.
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
|
||||
SystemZRRIAddressMode Backup = AM;
|
||||
int64_t Offset = CN->getSExtValue();
|
||||
int64_t Imm = 0;
|
||||
bool MatchOffset = (is12Bit ?
|
||||
isImmZExt12(AM.Disp + Offset, Imm) :
|
||||
isImmSExt20(AM.Disp + Offset, Imm));
|
||||
// The resultant disp must fit in 12 or 20-bits.
|
||||
if (MatchOffset &&
|
||||
// LHS should be an addr mode.
|
||||
!MatchAddress(N.getOperand(0), AM, is12Bit, Depth+1) &&
|
||||
// Check to see if the LHS & C is zero.
|
||||
CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
|
||||
AM.Disp = Imm;
|
||||
return false;
|
||||
}
|
||||
AM = Backup;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return MatchAddressBase(N, AM);
|
||||
}
|
||||
|
||||
/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
|
||||
/// specified addressing mode without any further recursion.
|
||||
bool SystemZDAGToDAGISel::MatchAddressBase(SDValue N,
|
||||
SystemZRRIAddressMode &AM) {
|
||||
// Is the base register already occupied?
|
||||
if (AM.BaseType != SystemZRRIAddressMode::RegBase || AM.Base.Reg.getNode()) {
|
||||
// If so, check to see if the index register is set.
|
||||
if (AM.IndexReg.getNode() == 0 && !AM.isRI) {
|
||||
AM.IndexReg = N;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we cannot select it.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default, generate it as a register.
|
||||
AM.BaseType = SystemZRRIAddressMode::RegBase;
|
||||
AM.Base.Reg = N;
|
||||
return false;
|
||||
}
|
||||
|
||||
void SystemZDAGToDAGISel::getAddressOperandsRI(const SystemZRRIAddressMode &AM,
|
||||
SDValue &Base, SDValue &Disp) {
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
|
||||
Base = AM.Base.Reg;
|
||||
else
|
||||
Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy());
|
||||
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i64);
|
||||
}
|
||||
|
||||
void SystemZDAGToDAGISel::getAddressOperands(const SystemZRRIAddressMode &AM,
|
||||
SDValue &Base, SDValue &Disp,
|
||||
SDValue &Index) {
|
||||
getAddressOperandsRI(AM, Base, Disp);
|
||||
Index = AM.IndexReg;
|
||||
}
|
||||
|
||||
/// Returns true if the address can be represented by a base register plus
|
||||
/// an unsigned 12-bit displacement [r+imm].
|
||||
bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDValue &Addr,
|
||||
SDValue &Base, SDValue &Disp) {
|
||||
return SelectAddrRI12(Addr, Base, Disp, /*is12BitOnly*/true);
|
||||
}
|
||||
|
||||
bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue &Addr,
|
||||
SDValue &Base, SDValue &Disp,
|
||||
bool is12BitOnly) {
|
||||
SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true);
|
||||
bool Done = false;
|
||||
|
||||
if (!Addr.hasOneUse()) {
|
||||
unsigned Opcode = Addr.getOpcode();
|
||||
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
|
||||
// If we are able to fold N into addressing mode, then we'll allow it even
|
||||
// if N has multiple uses. In general, addressing computation is used as
|
||||
// addresses by all of its uses. But watch out for CopyToReg uses, that
|
||||
// means the address computation is liveout. It will be computed by a LA
|
||||
// so we want to avoid computing the address twice.
|
||||
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
|
||||
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
|
||||
if (UI->getOpcode() == ISD::CopyToReg) {
|
||||
MatchAddressBase(Addr, AM12);
|
||||
Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Done && MatchAddress(Addr, AM12, /* is12Bit */ true))
|
||||
return false;
|
||||
|
||||
// Check, whether we can match stuff using 20-bit displacements
|
||||
if (!Done && !is12BitOnly &&
|
||||
!MatchAddress(Addr, AM20, /* is12Bit */ false))
|
||||
if (AM12.Disp == 0 && AM20.Disp != 0)
|
||||
return false;
|
||||
|
||||
DEBUG(errs() << "MatchAddress (final): "; AM12.dump());
|
||||
|
||||
EVT VT = Addr.getValueType();
|
||||
if (AM12.BaseType == SystemZRRIAddressMode::RegBase) {
|
||||
if (!AM12.Base.Reg.getNode())
|
||||
AM12.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
}
|
||||
|
||||
assert(AM12.IndexReg.getNode() == 0 && "Invalid reg-imm address mode!");
|
||||
|
||||
getAddressOperandsRI(AM12, Base, Disp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns true if the address can be represented by a base register plus
|
||||
/// a signed 20-bit displacement [r+imm].
|
||||
bool SystemZDAGToDAGISel::SelectAddrRI(SDValue& Addr,
|
||||
SDValue &Base, SDValue &Disp) {
|
||||
SystemZRRIAddressMode AM(/*isRI*/true);
|
||||
bool Done = false;
|
||||
|
||||
if (!Addr.hasOneUse()) {
|
||||
unsigned Opcode = Addr.getOpcode();
|
||||
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
|
||||
// If we are able to fold N into addressing mode, then we'll allow it even
|
||||
// if N has multiple uses. In general, addressing computation is used as
|
||||
// addresses by all of its uses. But watch out for CopyToReg uses, that
|
||||
// means the address computation is liveout. It will be computed by a LA
|
||||
// so we want to avoid computing the address twice.
|
||||
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
|
||||
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
|
||||
if (UI->getOpcode() == ISD::CopyToReg) {
|
||||
MatchAddressBase(Addr, AM);
|
||||
Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Done && MatchAddress(Addr, AM, /* is12Bit */ false))
|
||||
return false;
|
||||
|
||||
DEBUG(errs() << "MatchAddress (final): "; AM.dump());
|
||||
|
||||
EVT VT = Addr.getValueType();
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase) {
|
||||
if (!AM.Base.Reg.getNode())
|
||||
AM.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
}
|
||||
|
||||
assert(AM.IndexReg.getNode() == 0 && "Invalid reg-imm address mode!");
|
||||
|
||||
getAddressOperandsRI(AM, Base, Disp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns true if the address can be represented by a base register plus
|
||||
/// index register plus an unsigned 12-bit displacement [base + idx + imm].
|
||||
bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index) {
|
||||
SystemZRRIAddressMode AM20, AM12;
|
||||
bool Done = false;
|
||||
|
||||
if (!Addr.hasOneUse()) {
|
||||
unsigned Opcode = Addr.getOpcode();
|
||||
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
|
||||
// If we are able to fold N into addressing mode, then we'll allow it even
|
||||
// if N has multiple uses. In general, addressing computation is used as
|
||||
// addresses by all of its uses. But watch out for CopyToReg uses, that
|
||||
// means the address computation is liveout. It will be computed by a LA
|
||||
// so we want to avoid computing the address twice.
|
||||
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
|
||||
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
|
||||
if (UI->getOpcode() == ISD::CopyToReg) {
|
||||
MatchAddressBase(Addr, AM12);
|
||||
Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Done && MatchAddress(Addr, AM12, /* is12Bit */ true))
|
||||
return false;
|
||||
|
||||
// Check, whether we can match stuff using 20-bit displacements
|
||||
if (!Done && !MatchAddress(Addr, AM20, /* is12Bit */ false))
|
||||
if (AM12.Disp == 0 && AM20.Disp != 0)
|
||||
return false;
|
||||
|
||||
DEBUG(errs() << "MatchAddress (final): "; AM12.dump());
|
||||
|
||||
EVT VT = Addr.getValueType();
|
||||
if (AM12.BaseType == SystemZRRIAddressMode::RegBase) {
|
||||
if (!AM12.Base.Reg.getNode())
|
||||
AM12.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
}
|
||||
|
||||
if (!AM12.IndexReg.getNode())
|
||||
AM12.IndexReg = CurDAG->getRegister(0, VT);
|
||||
|
||||
getAddressOperands(AM12, Base, Disp, Index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Returns true if the address can be represented by a base register plus
|
||||
/// index register plus a signed 20-bit displacement [base + idx + imm].
|
||||
bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index) {
|
||||
SystemZRRIAddressMode AM;
|
||||
bool Done = false;
|
||||
|
||||
if (!Addr.hasOneUse()) {
|
||||
unsigned Opcode = Addr.getOpcode();
|
||||
if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
|
||||
// If we are able to fold N into addressing mode, then we'll allow it even
|
||||
// if N has multiple uses. In general, addressing computation is used as
|
||||
// addresses by all of its uses. But watch out for CopyToReg uses, that
|
||||
// means the address computation is liveout. It will be computed by a LA
|
||||
// so we want to avoid computing the address twice.
|
||||
for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
|
||||
UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
|
||||
if (UI->getOpcode() == ISD::CopyToReg) {
|
||||
MatchAddressBase(Addr, AM);
|
||||
Done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Done && MatchAddress(Addr, AM, /* is12Bit */ false))
|
||||
return false;
|
||||
|
||||
DEBUG(errs() << "MatchAddress (final): "; AM.dump());
|
||||
|
||||
EVT VT = Addr.getValueType();
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase) {
|
||||
if (!AM.Base.Reg.getNode())
|
||||
AM.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
}
|
||||
|
||||
if (!AM.IndexReg.getNode())
|
||||
AM.IndexReg = CurDAG->getRegister(0, VT);
|
||||
|
||||
getAddressOperands(AM, Base, Disp, Index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
|
||||
/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
|
||||
bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Addr,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index) {
|
||||
SystemZRRIAddressMode AM;
|
||||
|
||||
if (MatchAddress(Addr, AM, false))
|
||||
return false;
|
||||
|
||||
EVT VT = Addr.getValueType();
|
||||
unsigned Complexity = 0;
|
||||
if (AM.BaseType == SystemZRRIAddressMode::RegBase)
|
||||
if (AM.Base.Reg.getNode())
|
||||
Complexity = 1;
|
||||
else
|
||||
AM.Base.Reg = CurDAG->getRegister(0, VT);
|
||||
else if (AM.BaseType == SystemZRRIAddressMode::FrameIndexBase)
|
||||
Complexity = 4;
|
||||
|
||||
if (AM.IndexReg.getNode())
|
||||
Complexity += 1;
|
||||
else
|
||||
AM.IndexReg = CurDAG->getRegister(0, VT);
|
||||
|
||||
if (AM.Disp && (AM.Base.Reg.getNode() || AM.IndexReg.getNode()))
|
||||
Complexity += 1;
|
||||
|
||||
if (Complexity > 2) {
|
||||
getAddressOperands(AM, Base, Disp, Index);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
|
||||
SDValue &Base, SDValue &Disp, SDValue &Index) {
|
||||
if (ISD::isNON_EXTLoad(N.getNode()) &&
|
||||
IsLegalToFold(N, P, P, OptLevel))
|
||||
return SelectAddrRRI20(N.getOperand(1), Base, Disp, Index);
|
||||
return false;
|
||||
}
|
||||
|
||||
SDNode *SystemZDAGToDAGISel::Select(SDNode *Node) {
|
||||
EVT NVT = Node->getValueType(0);
|
||||
DebugLoc dl = Node->getDebugLoc();
|
||||
unsigned Opcode = Node->getOpcode();
|
||||
|
||||
// Dump information about the Node being selected
|
||||
DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
|
||||
|
||||
// If we have a custom node, we already have selected!
|
||||
if (Node->isMachineOpcode()) {
|
||||
DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
|
||||
return NULL; // Already selected.
|
||||
}
|
||||
|
||||
switch (Opcode) {
|
||||
default: break;
|
||||
case ISD::SDIVREM: {
|
||||
unsigned Opc, MOpc;
|
||||
SDValue N0 = Node->getOperand(0);
|
||||
SDValue N1 = Node->getOperand(1);
|
||||
|
||||
EVT ResVT;
|
||||
bool is32Bit = false;
|
||||
switch (NVT.getSimpleVT().SimpleTy) {
|
||||
default: assert(0 && "Unsupported VT!");
|
||||
case MVT::i32:
|
||||
Opc = SystemZ::SDIVREM32r; MOpc = SystemZ::SDIVREM32m;
|
||||
ResVT = MVT::v2i64;
|
||||
is32Bit = true;
|
||||
break;
|
||||
case MVT::i64:
|
||||
Opc = SystemZ::SDIVREM64r; MOpc = SystemZ::SDIVREM64m;
|
||||
ResVT = MVT::v2i64;
|
||||
break;
|
||||
}
|
||||
|
||||
SDValue Tmp0, Tmp1, Tmp2;
|
||||
bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2);
|
||||
|
||||
// Prepare the dividend
|
||||
SDNode *Dividend;
|
||||
if (is32Bit)
|
||||
Dividend = CurDAG->getMachineNode(SystemZ::MOVSX64rr32, dl, MVT::i64, N0);
|
||||
else
|
||||
Dividend = N0.getNode();
|
||||
|
||||
// Insert prepared dividend into suitable 'subreg'
|
||||
SDNode *Tmp = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
|
||||
dl, ResVT);
|
||||
Dividend =
|
||||
CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT,
|
||||
SDValue(Tmp, 0), SDValue(Dividend, 0),
|
||||
CurDAG->getTargetConstant(SystemZ::subreg_odd, MVT::i32));
|
||||
|
||||
SDNode *Result;
|
||||
SDValue DivVal = SDValue(Dividend, 0);
|
||||
if (foldedLoad) {
|
||||
SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) };
|
||||
Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other,
|
||||
Ops, array_lengthof(Ops));
|
||||
// Update the chain.
|
||||
ReplaceUses(N1.getValue(1), SDValue(Result, 1));
|
||||
} else {
|
||||
Result = CurDAG->getMachineNode(Opc, dl, ResVT, SDValue(Dividend, 0), N1);
|
||||
}
|
||||
|
||||
// Copy the division (odd subreg) result, if it is needed.
|
||||
if (!SDValue(Node, 0).use_empty()) {
|
||||
unsigned SubRegIdx = (is32Bit ?
|
||||
SystemZ::subreg_odd32 : SystemZ::subreg_odd);
|
||||
SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
|
||||
dl, NVT,
|
||||
SDValue(Result, 0),
|
||||
CurDAG->getTargetConstant(SubRegIdx,
|
||||
MVT::i32));
|
||||
|
||||
ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
|
||||
DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
|
||||
}
|
||||
|
||||
// Copy the remainder (even subreg) result, if it is needed.
|
||||
if (!SDValue(Node, 1).use_empty()) {
|
||||
unsigned SubRegIdx = (is32Bit ?
|
||||
SystemZ::subreg_32bit : SystemZ::subreg_even);
|
||||
SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
|
||||
dl, NVT,
|
||||
SDValue(Result, 0),
|
||||
CurDAG->getTargetConstant(SubRegIdx,
|
||||
MVT::i32));
|
||||
|
||||
ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
|
||||
DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
case ISD::UDIVREM: {
|
||||
unsigned Opc, MOpc, ClrOpc;
|
||||
SDValue N0 = Node->getOperand(0);
|
||||
SDValue N1 = Node->getOperand(1);
|
||||
EVT ResVT;
|
||||
|
||||
bool is32Bit = false;
|
||||
switch (NVT.getSimpleVT().SimpleTy) {
|
||||
default: assert(0 && "Unsupported VT!");
|
||||
case MVT::i32:
|
||||
Opc = SystemZ::UDIVREM32r; MOpc = SystemZ::UDIVREM32m;
|
||||
ClrOpc = SystemZ::MOV64Pr0_even;
|
||||
ResVT = MVT::v2i32;
|
||||
is32Bit = true;
|
||||
break;
|
||||
case MVT::i64:
|
||||
Opc = SystemZ::UDIVREM64r; MOpc = SystemZ::UDIVREM64m;
|
||||
ClrOpc = SystemZ::MOV128r0_even;
|
||||
ResVT = MVT::v2i64;
|
||||
break;
|
||||
}
|
||||
|
||||
SDValue Tmp0, Tmp1, Tmp2;
|
||||
bool foldedLoad = TryFoldLoad(Node, N1, Tmp0, Tmp1, Tmp2);
|
||||
|
||||
// Prepare the dividend
|
||||
SDNode *Dividend = N0.getNode();
|
||||
|
||||
// Insert prepared dividend into suitable 'subreg'
|
||||
SDNode *Tmp = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
|
||||
dl, ResVT);
|
||||
{
|
||||
unsigned SubRegIdx = (is32Bit ?
|
||||
SystemZ::subreg_odd32 : SystemZ::subreg_odd);
|
||||
Dividend =
|
||||
CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG, dl, ResVT,
|
||||
SDValue(Tmp, 0), SDValue(Dividend, 0),
|
||||
CurDAG->getTargetConstant(SubRegIdx, MVT::i32));
|
||||
}
|
||||
|
||||
// Zero out even subreg
|
||||
Dividend = CurDAG->getMachineNode(ClrOpc, dl, ResVT, SDValue(Dividend, 0));
|
||||
|
||||
SDValue DivVal = SDValue(Dividend, 0);
|
||||
SDNode *Result;
|
||||
if (foldedLoad) {
|
||||
SDValue Ops[] = { DivVal, Tmp0, Tmp1, Tmp2, N1.getOperand(0) };
|
||||
Result = CurDAG->getMachineNode(MOpc, dl, ResVT, MVT::Other,
|
||||
Ops, array_lengthof(Ops));
|
||||
// Update the chain.
|
||||
ReplaceUses(N1.getValue(1), SDValue(Result, 1));
|
||||
} else {
|
||||
Result = CurDAG->getMachineNode(Opc, dl, ResVT, DivVal, N1);
|
||||
}
|
||||
|
||||
// Copy the division (odd subreg) result, if it is needed.
|
||||
if (!SDValue(Node, 0).use_empty()) {
|
||||
unsigned SubRegIdx = (is32Bit ?
|
||||
SystemZ::subreg_odd32 : SystemZ::subreg_odd);
|
||||
SDNode *Div = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
|
||||
dl, NVT,
|
||||
SDValue(Result, 0),
|
||||
CurDAG->getTargetConstant(SubRegIdx,
|
||||
MVT::i32));
|
||||
ReplaceUses(SDValue(Node, 0), SDValue(Div, 0));
|
||||
DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
|
||||
}
|
||||
|
||||
// Copy the remainder (even subreg) result, if it is needed.
|
||||
if (!SDValue(Node, 1).use_empty()) {
|
||||
unsigned SubRegIdx = (is32Bit ?
|
||||
SystemZ::subreg_32bit : SystemZ::subreg_even);
|
||||
SDNode *Rem = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
|
||||
dl, NVT,
|
||||
SDValue(Result, 0),
|
||||
CurDAG->getTargetConstant(SubRegIdx,
|
||||
MVT::i32));
|
||||
ReplaceUses(SDValue(Node, 1), SDValue(Rem, 0));
|
||||
DEBUG(errs() << "=> "; Result->dump(CurDAG); errs() << "\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Select the default instruction
|
||||
SDNode *ResNode = SelectCode(Node);
|
||||
|
||||
DEBUG(errs() << "=> ";
|
||||
if (ResNode == NULL || ResNode == Node)
|
||||
Node->dump(CurDAG);
|
||||
else
|
||||
ResNode->dump(CurDAG);
|
||||
errs() << "\n";
|
||||
);
|
||||
return ResNode;
|
||||
}
|
@ -1,868 +0,0 @@
|
||||
//===-- 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/TargetLoweringObjectFileImpl.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/VectorExtras.h"
|
||||
using namespace llvm;
|
||||
|
||||
SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) :
|
||||
TargetLowering(tm, new TargetLoweringObjectFileELF()),
|
||||
Subtarget(*tm.getSubtargetImpl()), TM(tm) {
|
||||
|
||||
RegInfo = TM.getRegisterInfo();
|
||||
|
||||
// Set up the register classes.
|
||||
addRegisterClass(MVT::i32, SystemZ::GR32RegisterClass);
|
||||
addRegisterClass(MVT::i64, SystemZ::GR64RegisterClass);
|
||||
addRegisterClass(MVT::v2i32,SystemZ::GR64PRegisterClass);
|
||||
addRegisterClass(MVT::v2i64,SystemZ::GR128RegisterClass);
|
||||
|
||||
if (!UseSoftFloat) {
|
||||
addRegisterClass(MVT::f32, SystemZ::FP32RegisterClass);
|
||||
addRegisterClass(MVT::f64, SystemZ::FP64RegisterClass);
|
||||
}
|
||||
|
||||
// Compute derived properties from the register classes
|
||||
computeRegisterProperties();
|
||||
|
||||
// Provide all sorts of operation actions
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
|
||||
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::f32, Expand);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::f32, Expand);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
|
||||
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::f64, Expand);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::f64, Expand);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand);
|
||||
|
||||
setStackPointerRegisterToSaveRestore(SystemZ::R15D);
|
||||
|
||||
// TODO: It may be better to default to latency-oriented scheduling, however
|
||||
// LLVM's current latency-oriented scheduler can't handle physreg definitions
|
||||
// such as SystemZ has with PSW, so set this to the register-pressure
|
||||
// scheduler, because it can.
|
||||
setSchedulingPreference(Sched::RegPressure);
|
||||
|
||||
setBooleanContents(ZeroOrOneBooleanContent);
|
||||
setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
|
||||
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BRCOND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::BR_CC, MVT::i64, Custom);
|
||||
setOperationAction(ISD::BR_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::BR_CC, MVT::f64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SDIV, MVT::i64, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SREM, MVT::i64, Expand);
|
||||
setOperationAction(ISD::UREM, MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
|
||||
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
|
||||
setOperationAction(ISD::CTPOP, MVT::i64, Expand);
|
||||
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
|
||||
setOperationAction(ISD::CTTZ, MVT::i64, Expand);
|
||||
setOperationAction(ISD::CTLZ, MVT::i32, Promote);
|
||||
setOperationAction(ISD::CTLZ, MVT::i64, Legal);
|
||||
|
||||
// FIXME: Can we lower these 2 efficiently?
|
||||
setOperationAction(ISD::SETCC, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SETCC, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SETCC, MVT::f32, Expand);
|
||||
setOperationAction(ISD::SETCC, MVT::f64, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::f32, Expand);
|
||||
setOperationAction(ISD::SELECT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
|
||||
|
||||
setOperationAction(ISD::MULHS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
|
||||
|
||||
// FIXME: Can we support these natively?
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
|
||||
|
||||
// Lower some FP stuff
|
||||
setOperationAction(ISD::FSIN, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FSIN, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCOS, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FCOS, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FREM, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FREM, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FMA, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FMA, MVT::f64, Expand);
|
||||
|
||||
// We have only 64-bit bitconverts
|
||||
setOperationAction(ISD::BITCAST, MVT::f32, Expand);
|
||||
setOperationAction(ISD::BITCAST, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
|
||||
|
||||
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
|
||||
|
||||
setMinFunctionAlignment(1);
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
switch (Op.getOpcode()) {
|
||||
case ISD::BR_CC: return LowerBR_CC(Op, DAG);
|
||||
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
default:
|
||||
llvm_unreachable("Should not custom lower this!");
|
||||
return SDValue();
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemZTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
|
||||
if (UseSoftFloat || (VT != MVT::f32 && VT != MVT::f64))
|
||||
return false;
|
||||
|
||||
// +0.0 lzer
|
||||
// +0.0f lzdr
|
||||
// -0.0 lzer + lner
|
||||
// -0.0f lzdr + lndr
|
||||
return Imm.isZero() || Imm.isNegZero();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SystemZ Inline Assembly Support
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// getConstraintType - Given a constraint letter, return the type of
|
||||
/// constraint it is for this target.
|
||||
TargetLowering::ConstraintType
|
||||
SystemZTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
if (Constraint.size() == 1) {
|
||||
switch (Constraint[0]) {
|
||||
case 'r':
|
||||
return C_RegisterClass;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TargetLowering::getConstraintType(Constraint);
|
||||
}
|
||||
|
||||
std::pair<unsigned, const TargetRegisterClass*>
|
||||
SystemZTargetLowering::
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint,
|
||||
EVT VT) const {
|
||||
if (Constraint.size() == 1) {
|
||||
// GCC Constraint Letters
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'r': // GENERAL_REGS
|
||||
if (VT == MVT::i32)
|
||||
return std::make_pair(0U, SystemZ::GR32RegisterClass);
|
||||
else if (VT == MVT::i128)
|
||||
return std::make_pair(0U, SystemZ::GR128RegisterClass);
|
||||
|
||||
return std::make_pair(0U, SystemZ::GR64RegisterClass);
|
||||
}
|
||||
}
|
||||
|
||||
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZGenCallingConv.inc"
|
||||
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg>
|
||||
&Ins,
|
||||
DebugLoc dl,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals)
|
||||
const {
|
||||
|
||||
switch (CallConv) {
|
||||
default:
|
||||
llvm_unreachable("Unsupported calling convention");
|
||||
case CallingConv::C:
|
||||
case CallingConv::Fast:
|
||||
return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
|
||||
}
|
||||
}
|
||||
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
bool &isTailCall,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
// SystemZ target does not yet support tail call optimization.
|
||||
isTailCall = false;
|
||||
|
||||
switch (CallConv) {
|
||||
default:
|
||||
llvm_unreachable("Unsupported calling convention");
|
||||
case CallingConv::Fast:
|
||||
case CallingConv::C:
|
||||
return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
|
||||
Outs, OutVals, Ins, dl, DAG, InVals);
|
||||
}
|
||||
}
|
||||
|
||||
/// LowerCCCArguments - transform physical registers into virtual registers and
|
||||
/// generate load operations for arguments places on the stack.
|
||||
// FIXME: struct return stuff
|
||||
// FIXME: varargs
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerCCCArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg>
|
||||
&Ins,
|
||||
DebugLoc dl,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals)
|
||||
const {
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
||||
|
||||
// Assign locations to all of the incoming arguments.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), ArgLocs, *DAG.getContext());
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_SystemZ);
|
||||
|
||||
if (isVarArg)
|
||||
report_fatal_error("Varargs not supported yet");
|
||||
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
SDValue ArgValue;
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
EVT LocVT = VA.getLocVT();
|
||||
if (VA.isRegLoc()) {
|
||||
// Arguments passed in registers
|
||||
TargetRegisterClass *RC;
|
||||
switch (LocVT.getSimpleVT().SimpleTy) {
|
||||
default:
|
||||
#ifndef NDEBUG
|
||||
errs() << "LowerFormalArguments Unhandled argument type: "
|
||||
<< LocVT.getSimpleVT().SimpleTy
|
||||
<< "\n";
|
||||
#endif
|
||||
llvm_unreachable(0);
|
||||
case MVT::i64:
|
||||
RC = SystemZ::GR64RegisterClass;
|
||||
break;
|
||||
case MVT::f32:
|
||||
RC = SystemZ::FP32RegisterClass;
|
||||
break;
|
||||
case MVT::f64:
|
||||
RC = SystemZ::FP64RegisterClass;
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned VReg = RegInfo.createVirtualRegister(RC);
|
||||
RegInfo.addLiveIn(VA.getLocReg(), VReg);
|
||||
ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, LocVT);
|
||||
} else {
|
||||
// Sanity check
|
||||
assert(VA.isMemLoc());
|
||||
|
||||
// Create the nodes corresponding to a load from this parameter slot.
|
||||
// Create the frame index object for this incoming parameter...
|
||||
int FI = MFI->CreateFixedObject(LocVT.getSizeInBits()/8,
|
||||
VA.getLocMemOffset(), true);
|
||||
|
||||
// Create the SelectionDAG nodes corresponding to a load
|
||||
// from this parameter
|
||||
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
|
||||
ArgValue = DAG.getLoad(LocVT, dl, Chain, FIN,
|
||||
MachinePointerInfo::getFixedStack(FI),
|
||||
false, false, 0);
|
||||
}
|
||||
|
||||
// If this is an 8/16/32-bit value, it is really passed promoted to 64
|
||||
// bits. Insert an assert[sz]ext to capture this, then truncate to the
|
||||
// right size.
|
||||
if (VA.getLocInfo() == CCValAssign::SExt)
|
||||
ArgValue = DAG.getNode(ISD::AssertSext, dl, LocVT, ArgValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
else if (VA.getLocInfo() == CCValAssign::ZExt)
|
||||
ArgValue = DAG.getNode(ISD::AssertZext, dl, LocVT, ArgValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
|
||||
if (VA.getLocInfo() != CCValAssign::Full)
|
||||
ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
|
||||
|
||||
InVals.push_back(ArgValue);
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
/// LowerCCCCallTo - functions arguments are copied from virtual regs to
|
||||
/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
|
||||
/// TODO: sret.
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
bool isTailCall,
|
||||
const SmallVectorImpl<ISD::OutputArg>
|
||||
&Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
const TargetFrameLowering *TFI = TM.getFrameLowering();
|
||||
|
||||
// Offset to first argument stack slot.
|
||||
const unsigned FirstArgOffset = 160;
|
||||
|
||||
// Analyze operands of the call, assigning locations to each operand.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), ArgLocs, *DAG.getContext());
|
||||
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_SystemZ);
|
||||
|
||||
// Get a count of how many bytes are to be pushed on the stack.
|
||||
unsigned NumBytes = CCInfo.getNextStackOffset();
|
||||
|
||||
Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
|
||||
getPointerTy(), true));
|
||||
|
||||
SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
|
||||
SmallVector<SDValue, 12> MemOpChains;
|
||||
SDValue StackPtr;
|
||||
|
||||
// Walk the register/memloc assignments, inserting copies/loads.
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
SDValue Arg = OutVals[i];
|
||||
|
||||
// Promote the value if needed.
|
||||
switch (VA.getLocInfo()) {
|
||||
default: assert(0 && "Unknown loc info!");
|
||||
case CCValAssign::Full: break;
|
||||
case CCValAssign::SExt:
|
||||
Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
|
||||
break;
|
||||
case CCValAssign::ZExt:
|
||||
Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
|
||||
break;
|
||||
case CCValAssign::AExt:
|
||||
Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
|
||||
break;
|
||||
}
|
||||
|
||||
// Arguments that can be passed on register must be kept at RegsToPass
|
||||
// vector
|
||||
if (VA.isRegLoc()) {
|
||||
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
|
||||
} else {
|
||||
assert(VA.isMemLoc());
|
||||
|
||||
if (StackPtr.getNode() == 0)
|
||||
StackPtr =
|
||||
DAG.getCopyFromReg(Chain, dl,
|
||||
(TFI->hasFP(MF) ?
|
||||
SystemZ::R11D : SystemZ::R15D),
|
||||
getPointerTy());
|
||||
|
||||
unsigned Offset = FirstArgOffset + VA.getLocMemOffset();
|
||||
SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
|
||||
StackPtr,
|
||||
DAG.getIntPtrConstant(Offset));
|
||||
|
||||
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
|
||||
MachinePointerInfo(),
|
||||
false, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Transform all store nodes into one single node because all store nodes are
|
||||
// independent of each other.
|
||||
if (!MemOpChains.empty())
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
||||
&MemOpChains[0], MemOpChains.size());
|
||||
|
||||
// Build a sequence of copy-to-reg nodes chained together with token chain and
|
||||
// flag operands which copy the outgoing args into registers. The InFlag in
|
||||
// necessary since all emitted instructions must be stuck together.
|
||||
SDValue InFlag;
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// If the callee is a GlobalAddress node (quite common, every direct call is)
|
||||
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
|
||||
// Likewise ExternalSymbol -> TargetExternalSymbol.
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy());
|
||||
else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
|
||||
|
||||
// Returns a chain & a flag for retval copy to use.
|
||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
|
||||
SmallVector<SDValue, 8> Ops;
|
||||
Ops.push_back(Chain);
|
||||
Ops.push_back(Callee);
|
||||
|
||||
// Add argument registers to the end of the list so that they are
|
||||
// known live into the call.
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
|
||||
Ops.push_back(DAG.getRegister(RegsToPass[i].first,
|
||||
RegsToPass[i].second.getValueType()));
|
||||
|
||||
if (InFlag.getNode())
|
||||
Ops.push_back(InFlag);
|
||||
|
||||
Chain = DAG.getNode(SystemZISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// Create the CALLSEQ_END node.
|
||||
Chain = DAG.getCALLSEQ_END(Chain,
|
||||
DAG.getConstant(NumBytes, getPointerTy(), true),
|
||||
DAG.getConstant(0, getPointerTy(), true),
|
||||
InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// Handle result values, copying them out of physregs into vregs that we
|
||||
// return.
|
||||
return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
|
||||
DAG, InVals);
|
||||
}
|
||||
|
||||
/// LowerCallResult - Lower the result values of a call into the
|
||||
/// appropriate copies out of appropriate physical registers.
|
||||
///
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg>
|
||||
&Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const {
|
||||
|
||||
// Assign locations to each value returned by this call.
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), RVLocs, *DAG.getContext());
|
||||
|
||||
CCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ);
|
||||
|
||||
// Copy all of the result registers out of their specified physreg.
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
CCValAssign &VA = RVLocs[i];
|
||||
|
||||
Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(),
|
||||
VA.getLocVT(), InFlag).getValue(1);
|
||||
SDValue RetValue = Chain.getValue(0);
|
||||
InFlag = Chain.getValue(2);
|
||||
|
||||
// If this is an 8/16/32-bit value, it is really passed promoted to 64
|
||||
// bits. Insert an assert[sz]ext to capture this, then truncate to the
|
||||
// right size.
|
||||
if (VA.getLocInfo() == CCValAssign::SExt)
|
||||
RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
else if (VA.getLocInfo() == CCValAssign::ZExt)
|
||||
RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
|
||||
if (VA.getLocInfo() != CCValAssign::Full)
|
||||
RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue);
|
||||
|
||||
InVals.push_back(RetValue);
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
|
||||
SDValue
|
||||
SystemZTargetLowering::LowerReturn(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
DebugLoc dl, SelectionDAG &DAG) const {
|
||||
|
||||
// CCValAssign - represent the assignment of the return value to a location
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
|
||||
// CCState - Info about the registers and stack slot.
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), RVLocs, *DAG.getContext());
|
||||
|
||||
// Analize return values.
|
||||
CCInfo.AnalyzeReturn(Outs, RetCC_SystemZ);
|
||||
|
||||
// If this is the first return lowered for this function, add the regs to the
|
||||
// liveout set for the function.
|
||||
if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i)
|
||||
if (RVLocs[i].isRegLoc())
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
|
||||
}
|
||||
|
||||
SDValue Flag;
|
||||
|
||||
// Copy the result values into the output registers.
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
CCValAssign &VA = RVLocs[i];
|
||||
SDValue ResValue = OutVals[i];
|
||||
assert(VA.isRegLoc() && "Can only return in registers!");
|
||||
|
||||
// If this is an 8/16/32-bit value, it is really should be passed promoted
|
||||
// to 64 bits.
|
||||
if (VA.getLocInfo() == CCValAssign::SExt)
|
||||
ResValue = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), ResValue);
|
||||
else if (VA.getLocInfo() == CCValAssign::ZExt)
|
||||
ResValue = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), ResValue);
|
||||
else if (VA.getLocInfo() == CCValAssign::AExt)
|
||||
ResValue = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), ResValue);
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ResValue, Flag);
|
||||
|
||||
// Guarantee that all emitted copies are stuck together,
|
||||
// avoiding something bad.
|
||||
Flag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
if (Flag.getNode())
|
||||
return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
|
||||
|
||||
// Return Void
|
||||
return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain);
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::EmitCmp(SDValue LHS, SDValue RHS,
|
||||
ISD::CondCode CC, SDValue &SystemZCC,
|
||||
SelectionDAG &DAG) const {
|
||||
// FIXME: Emit a test if RHS is zero
|
||||
|
||||
bool isUnsigned = false;
|
||||
SystemZCC::CondCodes TCC;
|
||||
switch (CC) {
|
||||
default:
|
||||
llvm_unreachable("Invalid integer condition!");
|
||||
case ISD::SETEQ:
|
||||
case ISD::SETOEQ:
|
||||
TCC = SystemZCC::E;
|
||||
break;
|
||||
case ISD::SETUEQ:
|
||||
TCC = SystemZCC::NLH;
|
||||
break;
|
||||
case ISD::SETNE:
|
||||
case ISD::SETONE:
|
||||
TCC = SystemZCC::NE;
|
||||
break;
|
||||
case ISD::SETUNE:
|
||||
TCC = SystemZCC::LH;
|
||||
break;
|
||||
case ISD::SETO:
|
||||
TCC = SystemZCC::O;
|
||||
break;
|
||||
case ISD::SETUO:
|
||||
TCC = SystemZCC::NO;
|
||||
break;
|
||||
case ISD::SETULE:
|
||||
if (LHS.getValueType().isFloatingPoint()) {
|
||||
TCC = SystemZCC::NH;
|
||||
break;
|
||||
}
|
||||
isUnsigned = true; // FALLTHROUGH
|
||||
case ISD::SETLE:
|
||||
case ISD::SETOLE:
|
||||
TCC = SystemZCC::LE;
|
||||
break;
|
||||
case ISD::SETUGE:
|
||||
if (LHS.getValueType().isFloatingPoint()) {
|
||||
TCC = SystemZCC::NL;
|
||||
break;
|
||||
}
|
||||
isUnsigned = true; // FALLTHROUGH
|
||||
case ISD::SETGE:
|
||||
case ISD::SETOGE:
|
||||
TCC = SystemZCC::HE;
|
||||
break;
|
||||
case ISD::SETUGT:
|
||||
if (LHS.getValueType().isFloatingPoint()) {
|
||||
TCC = SystemZCC::NLE;
|
||||
break;
|
||||
}
|
||||
isUnsigned = true; // FALLTHROUGH
|
||||
case ISD::SETGT:
|
||||
case ISD::SETOGT:
|
||||
TCC = SystemZCC::H;
|
||||
break;
|
||||
case ISD::SETULT:
|
||||
if (LHS.getValueType().isFloatingPoint()) {
|
||||
TCC = SystemZCC::NHE;
|
||||
break;
|
||||
}
|
||||
isUnsigned = true; // FALLTHROUGH
|
||||
case ISD::SETLT:
|
||||
case ISD::SETOLT:
|
||||
TCC = SystemZCC::L;
|
||||
break;
|
||||
}
|
||||
|
||||
SystemZCC = DAG.getConstant(TCC, MVT::i32);
|
||||
|
||||
DebugLoc dl = LHS.getDebugLoc();
|
||||
return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP),
|
||||
dl, MVT::i64, LHS, RHS);
|
||||
}
|
||||
|
||||
|
||||
SDValue SystemZTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
|
||||
SDValue LHS = Op.getOperand(2);
|
||||
SDValue RHS = Op.getOperand(3);
|
||||
SDValue Dest = Op.getOperand(4);
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
SDValue SystemZCC;
|
||||
SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG);
|
||||
return DAG.getNode(SystemZISD::BRCOND, dl, Op.getValueType(),
|
||||
Chain, Dest, SystemZCC, Flag);
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::LowerSELECT_CC(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
SDValue TrueV = Op.getOperand(2);
|
||||
SDValue FalseV = Op.getOperand(3);
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
SDValue SystemZCC;
|
||||
SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG);
|
||||
|
||||
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
|
||||
SmallVector<SDValue, 4> Ops;
|
||||
Ops.push_back(TrueV);
|
||||
Ops.push_back(FalseV);
|
||||
Ops.push_back(SystemZCC);
|
||||
Ops.push_back(Flag);
|
||||
|
||||
return DAG.getNode(SystemZISD::SELECT, dl, VTs, &Ops[0], Ops.size());
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
|
||||
|
||||
bool IsPic = getTargetMachine().getRelocationModel() == Reloc::PIC_;
|
||||
bool ExtraLoadRequired =
|
||||
Subtarget.GVRequiresExtraLoad(GV, getTargetMachine(), false);
|
||||
|
||||
SDValue Result;
|
||||
if (!IsPic && !ExtraLoadRequired) {
|
||||
Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), Offset);
|
||||
Offset = 0;
|
||||
} else {
|
||||
unsigned char OpFlags = 0;
|
||||
if (ExtraLoadRequired)
|
||||
OpFlags = SystemZII::MO_GOTENT;
|
||||
|
||||
Result = DAG.getTargetGlobalAddress(GV, dl, getPointerTy(), 0, OpFlags);
|
||||
}
|
||||
|
||||
Result = DAG.getNode(SystemZISD::PCRelativeWrapper, dl,
|
||||
getPointerTy(), Result);
|
||||
|
||||
if (ExtraLoadRequired)
|
||||
Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
|
||||
MachinePointerInfo::getGOT(), false, false, 0);
|
||||
|
||||
// If there was a non-zero offset that we didn't fold, create an explicit
|
||||
// addition for it.
|
||||
if (Offset != 0)
|
||||
Result = DAG.getNode(ISD::ADD, dl, getPointerTy(), Result,
|
||||
DAG.getConstant(Offset, getPointerTy()));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// FIXME: PIC here
|
||||
SDValue SystemZTargetLowering::LowerJumpTable(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
|
||||
|
||||
return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), Result);
|
||||
}
|
||||
|
||||
|
||||
// FIXME: PIC here
|
||||
// FIXME: This is just dirty hack. We need to lower cpool properly
|
||||
SDValue SystemZTargetLowering::LowerConstantPool(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
|
||||
|
||||
SDValue Result = DAG.getTargetConstantPool(CP->getConstVal(), getPointerTy(),
|
||||
CP->getAlignment(),
|
||||
CP->getOffset());
|
||||
|
||||
return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), Result);
|
||||
}
|
||||
|
||||
const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG";
|
||||
case SystemZISD::CALL: return "SystemZISD::CALL";
|
||||
case SystemZISD::BRCOND: return "SystemZISD::BRCOND";
|
||||
case SystemZISD::CMP: return "SystemZISD::CMP";
|
||||
case SystemZISD::UCMP: return "SystemZISD::UCMP";
|
||||
case SystemZISD::SELECT: return "SystemZISD::SELECT";
|
||||
case SystemZISD::PCRelativeWrapper: return "SystemZISD::PCRelativeWrapper";
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Other Lowering Code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MachineBasicBlock*
|
||||
SystemZTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const {
|
||||
const SystemZInstrInfo &TII = *TM.getInstrInfo();
|
||||
DebugLoc dl = MI->getDebugLoc();
|
||||
assert((MI->getOpcode() == SystemZ::Select32 ||
|
||||
MI->getOpcode() == SystemZ::SelectF32 ||
|
||||
MI->getOpcode() == SystemZ::Select64 ||
|
||||
MI->getOpcode() == SystemZ::SelectF64) &&
|
||||
"Unexpected instr type to insert");
|
||||
|
||||
// To "insert" a SELECT instruction, we actually have to insert the diamond
|
||||
// control-flow pattern. The incoming instruction knows the destination vreg
|
||||
// to set, the condition code register to branch on, the true/false values to
|
||||
// select between, and a branch opcode to use.
|
||||
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||
MachineFunction::iterator I = BB;
|
||||
++I;
|
||||
|
||||
// thisMBB:
|
||||
// ...
|
||||
// TrueVal = ...
|
||||
// cmpTY ccX, r1, r2
|
||||
// jCC copy1MBB
|
||||
// fallthrough --> copy0MBB
|
||||
MachineBasicBlock *thisMBB = BB;
|
||||
MachineFunction *F = BB->getParent();
|
||||
MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
|
||||
MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
|
||||
SystemZCC::CondCodes CC = (SystemZCC::CondCodes)MI->getOperand(3).getImm();
|
||||
F->insert(I, copy0MBB);
|
||||
F->insert(I, copy1MBB);
|
||||
// Update machine-CFG edges by transferring all successors of the current
|
||||
// block to the new block which will contain the Phi node for the select.
|
||||
copy1MBB->splice(copy1MBB->begin(), BB,
|
||||
llvm::next(MachineBasicBlock::iterator(MI)),
|
||||
BB->end());
|
||||
copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
|
||||
// Next, add the true and fallthrough blocks as its successors.
|
||||
BB->addSuccessor(copy0MBB);
|
||||
BB->addSuccessor(copy1MBB);
|
||||
|
||||
BuildMI(BB, dl, TII.getBrCond(CC)).addMBB(copy1MBB);
|
||||
|
||||
// copy0MBB:
|
||||
// %FalseValue = ...
|
||||
// # fallthrough to copy1MBB
|
||||
BB = copy0MBB;
|
||||
|
||||
// Update machine-CFG edges
|
||||
BB->addSuccessor(copy1MBB);
|
||||
|
||||
// copy1MBB:
|
||||
// %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
|
||||
// ...
|
||||
BB = copy1MBB;
|
||||
BuildMI(*BB, BB->begin(), dl, TII.get(SystemZ::PHI),
|
||||
MI->getOperand(0).getReg())
|
||||
.addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
|
||||
.addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
|
||||
|
||||
MI->eraseFromParent(); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
//==-- 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 "SystemZRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace SystemZISD {
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
|
||||
/// Return with a flag operand. Operand 0 is the chain operand.
|
||||
RET_FLAG,
|
||||
|
||||
/// CALL - These operations represent an abstract call
|
||||
/// instruction, which includes a bunch of information.
|
||||
CALL,
|
||||
|
||||
/// PCRelativeWrapper - PC relative address
|
||||
PCRelativeWrapper,
|
||||
|
||||
/// CMP, UCMP - Compare instruction
|
||||
CMP,
|
||||
UCMP,
|
||||
|
||||
/// BRCOND - Conditional branch. Operand 0 is chain operand, operand 1 is
|
||||
/// the block to branch if condition is true, operand 2 is condition code
|
||||
/// and operand 3 is the flag operand produced by a CMP instruction.
|
||||
BRCOND,
|
||||
|
||||
/// SELECT - Operands 0 and 1 are selection variables, operand 2 is
|
||||
/// condition code and operand 3 is the flag operand.
|
||||
SELECT
|
||||
};
|
||||
}
|
||||
|
||||
class SystemZSubtarget;
|
||||
class SystemZTargetMachine;
|
||||
|
||||
class SystemZTargetLowering : public TargetLowering {
|
||||
public:
|
||||
explicit SystemZTargetLowering(SystemZTargetMachine &TM);
|
||||
|
||||
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i64; }
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
/// getTargetNodeName - This method returns the name of a target specific
|
||||
/// DAG node.
|
||||
virtual const char *getTargetNodeName(unsigned Opcode) const;
|
||||
|
||||
std::pair<unsigned, const TargetRegisterClass*>
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const;
|
||||
TargetLowering::ConstraintType
|
||||
getConstraintType(const std::string &Constraint) const;
|
||||
|
||||
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
SDValue EmitCmp(SDValue LHS, SDValue RHS,
|
||||
ISD::CondCode CC, SDValue &SystemZCC,
|
||||
SelectionDAG &DAG) const;
|
||||
|
||||
|
||||
MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
|
||||
/// isFPImmLegal - Returns true if the target can instruction select the
|
||||
/// specified FP immediate natively. If false, the legalizer will
|
||||
/// materialize the FP immediate as a load from a constant pool.
|
||||
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
|
||||
|
||||
private:
|
||||
SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
bool isTailCall,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
|
||||
SDValue LowerCCCArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl,
|
||||
SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
|
||||
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
|
||||
virtual SDValue
|
||||
LowerFormalArguments(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
virtual SDValue
|
||||
LowerCall(SDValue Chain, SDValue Callee,
|
||||
CallingConv::ID CallConv, bool isVarArg, bool &isTailCall,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SmallVectorImpl<ISD::InputArg> &Ins,
|
||||
DebugLoc dl, SelectionDAG &DAG,
|
||||
SmallVectorImpl<SDValue> &InVals) const;
|
||||
|
||||
virtual SDValue
|
||||
LowerReturn(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
DebugLoc dl, SelectionDAG &DAG) const;
|
||||
|
||||
const SystemZSubtarget &Subtarget;
|
||||
const SystemZTargetMachine &TM;
|
||||
const SystemZRegisterInfo *RegInfo;
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_TARGET_SystemZ_ISELLOWERING_H
|
@ -1,128 +0,0 @@
|
||||
//===- SystemZInstrBuilder.h - Functions to aid building insts -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file exposes functions that may be used with BuildMI from the
|
||||
// MachineInstrBuilder.h file to handle SystemZ'isms in a clean way.
|
||||
//
|
||||
// The BuildMem function may be used with the BuildMI function to add entire
|
||||
// memory references in a single, typed, function call.
|
||||
//
|
||||
// For reference, the order of operands for memory references is:
|
||||
// (Operand), Base, Displacement, Index.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SYSTEMZINSTRBUILDER_H
|
||||
#define SYSTEMZINSTRBUILDER_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// SystemZAddressMode - This struct holds a generalized full x86 address mode.
|
||||
/// The base register can be a frame index, which will eventually be replaced
|
||||
/// with R15 or R11 and Disp being offsetted accordingly.
|
||||
struct SystemZAddressMode {
|
||||
enum {
|
||||
RegBase,
|
||||
FrameIndexBase
|
||||
} BaseType;
|
||||
|
||||
union {
|
||||
unsigned Reg;
|
||||
int FrameIndex;
|
||||
} Base;
|
||||
|
||||
unsigned IndexReg;
|
||||
int32_t Disp;
|
||||
const GlobalValue *GV;
|
||||
|
||||
SystemZAddressMode() : BaseType(RegBase), IndexReg(0), Disp(0) {
|
||||
Base.Reg = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// addDirectMem - This function is used to add a direct memory reference to the
|
||||
/// current instruction -- that is, a dereference of an address in a register,
|
||||
/// with no index or displacement.
|
||||
///
|
||||
static inline const MachineInstrBuilder &
|
||||
addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg) {
|
||||
// Because memory references are always represented with 3
|
||||
// values, this adds: Reg, [0, NoReg] to the instruction.
|
||||
return MIB.addReg(Reg).addImm(0).addReg(0);
|
||||
}
|
||||
|
||||
static inline const MachineInstrBuilder &
|
||||
addOffset(const MachineInstrBuilder &MIB, int Offset) {
|
||||
return MIB.addImm(Offset).addReg(0);
|
||||
}
|
||||
|
||||
/// addRegOffset - This function is used to add a memory reference of the form
|
||||
/// [Reg + Offset], i.e., one with no or index, but with a
|
||||
/// displacement. An example is: 10(%r15).
|
||||
///
|
||||
static inline const MachineInstrBuilder &
|
||||
addRegOffset(const MachineInstrBuilder &MIB,
|
||||
unsigned Reg, bool isKill, int Offset) {
|
||||
return addOffset(MIB.addReg(Reg, getKillRegState(isKill)), Offset);
|
||||
}
|
||||
|
||||
/// addRegReg - This function is used to add a memory reference of the form:
|
||||
/// [Reg + Reg].
|
||||
static inline const MachineInstrBuilder &
|
||||
addRegReg(const MachineInstrBuilder &MIB,
|
||||
unsigned Reg1, bool isKill1, unsigned Reg2, bool isKill2) {
|
||||
return MIB.addReg(Reg1, getKillRegState(isKill1)).addImm(0)
|
||||
.addReg(Reg2, getKillRegState(isKill2));
|
||||
}
|
||||
|
||||
static inline const MachineInstrBuilder &
|
||||
addFullAddress(const MachineInstrBuilder &MIB, const SystemZAddressMode &AM) {
|
||||
if (AM.BaseType == SystemZAddressMode::RegBase)
|
||||
MIB.addReg(AM.Base.Reg);
|
||||
else if (AM.BaseType == SystemZAddressMode::FrameIndexBase)
|
||||
MIB.addFrameIndex(AM.Base.FrameIndex);
|
||||
else
|
||||
assert(0);
|
||||
|
||||
return MIB.addImm(AM.Disp).addReg(AM.IndexReg);
|
||||
}
|
||||
|
||||
/// addFrameReference - This function is used to add a reference to the base of
|
||||
/// an abstract object on the stack frame of the current function. This
|
||||
/// reference has base register as the FrameIndex offset until it is resolved.
|
||||
/// This allows a constant offset to be specified as well...
|
||||
///
|
||||
static inline const MachineInstrBuilder &
|
||||
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0) {
|
||||
MachineInstr *MI = MIB;
|
||||
MachineFunction &MF = *MI->getParent()->getParent();
|
||||
MachineFrameInfo &MFI = *MF.getFrameInfo();
|
||||
const MCInstrDesc &MCID = MI->getDesc();
|
||||
unsigned Flags = 0;
|
||||
if (MCID.mayLoad())
|
||||
Flags |= MachineMemOperand::MOLoad;
|
||||
if (MCID.mayStore())
|
||||
Flags |= MachineMemOperand::MOStore;
|
||||
MachineMemOperand *MMO =
|
||||
MF.getMachineMemOperand(MachinePointerInfo(
|
||||
PseudoSourceValue::getFixedStack(FI), Offset),
|
||||
Flags, MFI.getObjectSize(FI),
|
||||
MFI.getObjectAlignment(FI));
|
||||
return addOffset(MIB.addFrameIndex(FI), Offset)
|
||||
.addMemOperand(MMO);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,340 +0,0 @@
|
||||
//===- SystemZInstrFP.td - SystemZ FP 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 (binary) floating point instructions in
|
||||
// TableGen format.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// FIXME: multiclassify!
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FP Pattern fragments
|
||||
|
||||
def fpimm0 : PatLeaf<(fpimm), [{
|
||||
return N->isExactlyValue(+0.0);
|
||||
}]>;
|
||||
|
||||
def fpimmneg0 : PatLeaf<(fpimm), [{
|
||||
return N->isExactlyValue(-0.0);
|
||||
}]>;
|
||||
|
||||
let Uses = [PSW], usesCustomInserter = 1 in {
|
||||
def SelectF32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, i8imm:$cc),
|
||||
"# SelectF32 PSEUDO",
|
||||
[(set FP32:$dst,
|
||||
(SystemZselect FP32:$src1, FP32:$src2, imm:$cc, PSW))]>;
|
||||
def SelectF64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, i8imm:$cc),
|
||||
"# SelectF64 PSEUDO",
|
||||
[(set FP64:$dst,
|
||||
(SystemZselect FP64:$src1, FP64:$src2, imm:$cc, PSW))]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Move Instructions
|
||||
|
||||
// Floating point constant loads.
|
||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
||||
def LD_Fp032 : Pseudo<(outs FP32:$dst), (ins),
|
||||
"lzer\t{$dst}",
|
||||
[(set FP32:$dst, fpimm0)]>;
|
||||
def LD_Fp064 : Pseudo<(outs FP64:$dst), (ins),
|
||||
"lzdr\t{$dst}",
|
||||
[(set FP64:$dst, fpimm0)]>;
|
||||
}
|
||||
|
||||
let neverHasSideEffects = 1 in {
|
||||
def FMOV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
|
||||
"ler\t{$dst, $src}",
|
||||
[]>;
|
||||
def FMOV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
|
||||
"ldr\t{$dst, $src}",
|
||||
[]>;
|
||||
}
|
||||
|
||||
let canFoldAsLoad = 1, isReMaterializable = 1 in {
|
||||
def FMOV32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
|
||||
"le\t{$dst, $src}",
|
||||
[(set FP32:$dst, (load rriaddr12:$src))]>;
|
||||
def FMOV32rmy : Pseudo<(outs FP32:$dst), (ins rriaddr:$src),
|
||||
"ley\t{$dst, $src}",
|
||||
[(set FP32:$dst, (load rriaddr:$src))]>;
|
||||
def FMOV64rm : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
|
||||
"ld\t{$dst, $src}",
|
||||
[(set FP64:$dst, (load rriaddr12:$src))]>;
|
||||
def FMOV64rmy : Pseudo<(outs FP64:$dst), (ins rriaddr:$src),
|
||||
"ldy\t{$dst, $src}",
|
||||
[(set FP64:$dst, (load rriaddr:$src))]>;
|
||||
}
|
||||
|
||||
def FMOV32mr : Pseudo<(outs), (ins rriaddr12:$dst, FP32:$src),
|
||||
"ste\t{$src, $dst}",
|
||||
[(store FP32:$src, rriaddr12:$dst)]>;
|
||||
def FMOV32mry : Pseudo<(outs), (ins rriaddr:$dst, FP32:$src),
|
||||
"stey\t{$src, $dst}",
|
||||
[(store FP32:$src, rriaddr:$dst)]>;
|
||||
def FMOV64mr : Pseudo<(outs), (ins rriaddr12:$dst, FP64:$src),
|
||||
"std\t{$src, $dst}",
|
||||
[(store FP64:$src, rriaddr12:$dst)]>;
|
||||
def FMOV64mry : Pseudo<(outs), (ins rriaddr:$dst, FP64:$src),
|
||||
"stdy\t{$src, $dst}",
|
||||
[(store FP64:$src, rriaddr:$dst)]>;
|
||||
|
||||
def FCOPYSIGN32 : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
|
||||
"cpsdr\t{$dst, $src2, $src1}",
|
||||
[(set FP32:$dst, (fcopysign FP32:$src1, FP32:$src2))]>;
|
||||
def FCOPYSIGN64 : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
|
||||
"cpsdr\t{$dst, $src2, $src1}",
|
||||
[(set FP64:$dst, (fcopysign FP64:$src1, FP64:$src2))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Arithmetic Instructions
|
||||
|
||||
|
||||
let Defs = [PSW] in {
|
||||
def FNEG32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
|
||||
"lcebr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fneg FP32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FNEG64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
|
||||
"lcdbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fneg FP64:$src)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
|
||||
"lpebr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fabs FP32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
|
||||
"lpdbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fabs FP64:$src)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FNABS32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
|
||||
"lnebr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fneg(fabs FP32:$src))),
|
||||
(implicit PSW)]>;
|
||||
def FNABS64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
|
||||
"lndbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fneg(fabs FP64:$src))),
|
||||
(implicit PSW)]>;
|
||||
}
|
||||
|
||||
let Constraints = "$src1 = $dst" in {
|
||||
let Defs = [PSW] in {
|
||||
let isCommutable = 1 in { // X = ADD Y, Z == X = ADD Z, Y
|
||||
def FADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
|
||||
"aebr\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fadd FP32:$src1, FP32:$src2)),
|
||||
(implicit PSW)]>;
|
||||
def FADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
|
||||
"adbr\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fadd FP64:$src1, FP64:$src2)),
|
||||
(implicit PSW)]>;
|
||||
}
|
||||
|
||||
def FADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
|
||||
"aeb\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fadd FP32:$src1, (load rriaddr12:$src2))),
|
||||
(implicit PSW)]>;
|
||||
def FADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
|
||||
"adb\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fadd FP64:$src1, (load rriaddr12:$src2))),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
|
||||
"sebr\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fsub FP32:$src1, FP32:$src2)),
|
||||
(implicit PSW)]>;
|
||||
def FSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
|
||||
"sdbr\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fsub FP64:$src1, FP64:$src2)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
|
||||
"seb\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fsub FP32:$src1, (load rriaddr12:$src2))),
|
||||
(implicit PSW)]>;
|
||||
def FSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
|
||||
"sdb\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fsub FP64:$src1, (load rriaddr12:$src2))),
|
||||
(implicit PSW)]>;
|
||||
} // Defs = [PSW]
|
||||
|
||||
let isCommutable = 1 in { // X = MUL Y, Z == X = MUL Z, Y
|
||||
def FMUL32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
|
||||
"meebr\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fmul FP32:$src1, FP32:$src2))]>;
|
||||
def FMUL64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
|
||||
"mdbr\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fmul FP64:$src1, FP64:$src2))]>;
|
||||
}
|
||||
|
||||
def FMUL32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
|
||||
"meeb\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fmul FP32:$src1, (load rriaddr12:$src2)))]>;
|
||||
def FMUL64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
|
||||
"mdb\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fmul FP64:$src1, (load rriaddr12:$src2)))]>;
|
||||
|
||||
def FMADD32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3),
|
||||
"maebr\t{$dst, $src3, $src2}",
|
||||
[(set FP32:$dst, (fadd (fmul FP32:$src2, FP32:$src3),
|
||||
FP32:$src1))]>;
|
||||
def FMADD32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
|
||||
"maeb\t{$dst, $src3, $src2}",
|
||||
[(set FP32:$dst, (fadd (fmul (load rriaddr12:$src2),
|
||||
FP32:$src3),
|
||||
FP32:$src1))]>;
|
||||
|
||||
def FMADD64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3),
|
||||
"madbr\t{$dst, $src3, $src2}",
|
||||
[(set FP64:$dst, (fadd (fmul FP64:$src2, FP64:$src3),
|
||||
FP64:$src1))]>;
|
||||
def FMADD64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
|
||||
"madb\t{$dst, $src3, $src2}",
|
||||
[(set FP64:$dst, (fadd (fmul (load rriaddr12:$src2),
|
||||
FP64:$src3),
|
||||
FP64:$src1))]>;
|
||||
|
||||
def FMSUB32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2, FP32:$src3),
|
||||
"msebr\t{$dst, $src3, $src2}",
|
||||
[(set FP32:$dst, (fsub (fmul FP32:$src2, FP32:$src3),
|
||||
FP32:$src1))]>;
|
||||
def FMSUB32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2, FP32:$src3),
|
||||
"mseb\t{$dst, $src3, $src2}",
|
||||
[(set FP32:$dst, (fsub (fmul (load rriaddr12:$src2),
|
||||
FP32:$src3),
|
||||
FP32:$src1))]>;
|
||||
|
||||
def FMSUB64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2, FP64:$src3),
|
||||
"msdbr\t{$dst, $src3, $src2}",
|
||||
[(set FP64:$dst, (fsub (fmul FP64:$src2, FP64:$src3),
|
||||
FP64:$src1))]>;
|
||||
def FMSUB64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2, FP64:$src3),
|
||||
"msdb\t{$dst, $src3, $src2}",
|
||||
[(set FP64:$dst, (fsub (fmul (load rriaddr12:$src2),
|
||||
FP64:$src3),
|
||||
FP64:$src1))]>;
|
||||
|
||||
def FDIV32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src1, FP32:$src2),
|
||||
"debr\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fdiv FP32:$src1, FP32:$src2))]>;
|
||||
def FDIV64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src1, FP64:$src2),
|
||||
"ddbr\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fdiv FP64:$src1, FP64:$src2))]>;
|
||||
|
||||
def FDIV32rm : Pseudo<(outs FP32:$dst), (ins FP32:$src1, rriaddr12:$src2),
|
||||
"deb\t{$dst, $src2}",
|
||||
[(set FP32:$dst, (fdiv FP32:$src1, (load rriaddr12:$src2)))]>;
|
||||
def FDIV64rm : Pseudo<(outs FP64:$dst), (ins FP64:$src1, rriaddr12:$src2),
|
||||
"ddb\t{$dst, $src2}",
|
||||
[(set FP64:$dst, (fdiv FP64:$src1, (load rriaddr12:$src2)))]>;
|
||||
|
||||
} // Constraints = "$src1 = $dst"
|
||||
|
||||
def FSQRT32rr : Pseudo<(outs FP32:$dst), (ins FP32:$src),
|
||||
"sqebr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fsqrt FP32:$src))]>;
|
||||
def FSQRT64rr : Pseudo<(outs FP64:$dst), (ins FP64:$src),
|
||||
"sqdbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fsqrt FP64:$src))]>;
|
||||
|
||||
def FSQRT32rm : Pseudo<(outs FP32:$dst), (ins rriaddr12:$src),
|
||||
"sqeb\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fsqrt (load rriaddr12:$src)))]>;
|
||||
def FSQRT64rm : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
|
||||
"sqdb\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fsqrt (load rriaddr12:$src)))]>;
|
||||
|
||||
def FROUND64r32 : Pseudo<(outs FP32:$dst), (ins FP64:$src),
|
||||
"ledbr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (fround FP64:$src))]>;
|
||||
|
||||
def FEXT32r64 : Pseudo<(outs FP64:$dst), (ins FP32:$src),
|
||||
"ldebr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fextend FP32:$src))]>;
|
||||
def FEXT32m64 : Pseudo<(outs FP64:$dst), (ins rriaddr12:$src),
|
||||
"ldeb\t{$dst, $src}",
|
||||
[(set FP64:$dst, (fextend (load rriaddr12:$src)))]>;
|
||||
|
||||
let Defs = [PSW] in {
|
||||
def FCONVFP32 : Pseudo<(outs FP32:$dst), (ins GR32:$src),
|
||||
"cefbr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (sint_to_fp GR32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FCONVFP32r64: Pseudo<(outs FP32:$dst), (ins GR64:$src),
|
||||
"cegbr\t{$dst, $src}",
|
||||
[(set FP32:$dst, (sint_to_fp GR64:$src)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FCONVFP64r32: Pseudo<(outs FP64:$dst), (ins GR32:$src),
|
||||
"cdfbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (sint_to_fp GR32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FCONVFP64 : Pseudo<(outs FP64:$dst), (ins GR64:$src),
|
||||
"cdgbr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (sint_to_fp GR64:$src)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FCONVGR32 : Pseudo<(outs GR32:$dst), (ins FP32:$src),
|
||||
"cfebr\t{$dst, 5, $src}",
|
||||
[(set GR32:$dst, (fp_to_sint FP32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FCONVGR32r64: Pseudo<(outs GR32:$dst), (ins FP64:$src),
|
||||
"cfdbr\t{$dst, 5, $src}",
|
||||
[(set GR32:$dst, (fp_to_sint FP64:$src)),
|
||||
(implicit PSW)]>;
|
||||
|
||||
def FCONVGR64r32: Pseudo<(outs GR64:$dst), (ins FP32:$src),
|
||||
"cgebr\t{$dst, 5, $src}",
|
||||
[(set GR64:$dst, (fp_to_sint FP32:$src)),
|
||||
(implicit PSW)]>;
|
||||
def FCONVGR64 : Pseudo<(outs GR64:$dst), (ins FP64:$src),
|
||||
"cgdbr\t{$dst, 5, $src}",
|
||||
[(set GR64:$dst, (fp_to_sint FP64:$src)),
|
||||
(implicit PSW)]>;
|
||||
} // Defs = [PSW]
|
||||
|
||||
def FBCONVG64 : Pseudo<(outs GR64:$dst), (ins FP64:$src),
|
||||
"lgdr\t{$dst, $src}",
|
||||
[(set GR64:$dst, (bitconvert FP64:$src))]>;
|
||||
def FBCONVF64 : Pseudo<(outs FP64:$dst), (ins GR64:$src),
|
||||
"ldgr\t{$dst, $src}",
|
||||
[(set FP64:$dst, (bitconvert GR64:$src))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Test instructions (like AND but do not produce any result)
|
||||
|
||||
// Integer comparisons
|
||||
let Defs = [PSW] in {
|
||||
def FCMP32rr : Pseudo<(outs), (ins FP32:$src1, FP32:$src2),
|
||||
"cebr\t$src1, $src2",
|
||||
[(set PSW, (SystemZcmp FP32:$src1, FP32:$src2))]>;
|
||||
def FCMP64rr : Pseudo<(outs), (ins FP64:$src1, FP64:$src2),
|
||||
"cdbr\t$src1, $src2",
|
||||
[(set PSW, (SystemZcmp FP64:$src1, FP64:$src2))]>;
|
||||
|
||||
def FCMP32rm : Pseudo<(outs), (ins FP32:$src1, rriaddr12:$src2),
|
||||
"ceb\t$src1, $src2",
|
||||
[(set PSW, (SystemZcmp FP32:$src1,
|
||||
(load rriaddr12:$src2)))]>;
|
||||
def FCMP64rm : Pseudo<(outs), (ins FP64:$src1, rriaddr12:$src2),
|
||||
"cdb\t$src1, $src2",
|
||||
[(set PSW, (SystemZcmp FP64:$src1,
|
||||
(load rriaddr12:$src2)))]>;
|
||||
} // Defs = [PSW]
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Non-Instruction Patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Floating point constant -0.0
|
||||
def : Pat<(f32 fpimmneg0), (FNEG32rr (LD_Fp032))>;
|
||||
def : Pat<(f64 fpimmneg0), (FNEG64rr (LD_Fp064))>;
|
@ -1,133 +0,0 @@
|
||||
//===- 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Format specifies the encoding used by the instruction. This is part of the
|
||||
// ad-hoc solution used to emit machine instruction encodings by our machine
|
||||
// code emitter.
|
||||
class Format<bits<5> val> {
|
||||
bits<5> Value = val;
|
||||
}
|
||||
|
||||
def Pseudo : Format<0>;
|
||||
def EForm : Format<1>;
|
||||
def IForm : Format<2>;
|
||||
def RIForm : Format<3>;
|
||||
def RIEForm : Format<4>;
|
||||
def RILForm : Format<5>;
|
||||
def RISForm : Format<6>;
|
||||
def RRForm : Format<7>;
|
||||
def RREForm : Format<8>;
|
||||
def RRFForm : Format<9>;
|
||||
def RRRForm : Format<10>;
|
||||
def RRSForm : Format<11>;
|
||||
def RSForm : Format<12>;
|
||||
def RSIForm : Format<13>;
|
||||
def RSILForm : Format<14>;
|
||||
def RSYForm : Format<15>;
|
||||
def RXForm : Format<16>;
|
||||
def RXEForm : Format<17>;
|
||||
def RXFForm : Format<18>;
|
||||
def RXYForm : Format<19>;
|
||||
def SForm : Format<20>;
|
||||
def SIForm : Format<21>;
|
||||
def SILForm : Format<22>;
|
||||
def SIYForm : Format<23>;
|
||||
def SSForm : Format<24>;
|
||||
def SSEForm : Format<25>;
|
||||
def SSFForm : Format<26>;
|
||||
|
||||
class InstSystemZ<bits<16> op, Format f, dag outs, dag ins> : Instruction {
|
||||
let Namespace = "SystemZ";
|
||||
|
||||
bits<16> Opcode = op;
|
||||
|
||||
Format Form = f;
|
||||
bits<5> FormBits = Form.Value;
|
||||
|
||||
dag OutOperandList = outs;
|
||||
dag InOperandList = ins;
|
||||
}
|
||||
|
||||
class I8<bits<8> op, Format f, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern>
|
||||
: InstSystemZ<0, f, outs, ins> {
|
||||
let Opcode{0-7} = op;
|
||||
let Opcode{8-15} = 0;
|
||||
|
||||
let Pattern = pattern;
|
||||
let AsmString = asmstr;
|
||||
}
|
||||
|
||||
class I12<bits<12> op, Format f, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern>
|
||||
: InstSystemZ<0, f, outs, ins> {
|
||||
let Opcode{0-11} = op;
|
||||
let Opcode{12-15} = 0;
|
||||
|
||||
let Pattern = pattern;
|
||||
let AsmString = asmstr;
|
||||
}
|
||||
|
||||
class I16<bits<16> op, Format f, dag outs, dag ins, string asmstr,
|
||||
list<dag> pattern>
|
||||
: InstSystemZ<op, f, outs, ins> {
|
||||
let Pattern = pattern;
|
||||
let AsmString = asmstr;
|
||||
}
|
||||
|
||||
class RRI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I8<op, RRForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class RII<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I12<op, RIForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class RILI<bits<12> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I12<op, RILForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class RREI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I16<op, RREForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class RXI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I8<op, RXForm, outs, ins, asmstr, pattern> {
|
||||
let AddedComplexity = 1;
|
||||
}
|
||||
|
||||
class RXYI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I16<op, RXYForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class RSI<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I8<op, RSForm, outs, ins, asmstr, pattern> {
|
||||
let AddedComplexity = 1;
|
||||
}
|
||||
|
||||
class RSYI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I16<op, RSYForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class SII<bits<8> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I8<op, SIForm, outs, ins, asmstr, pattern> {
|
||||
let AddedComplexity = 1;
|
||||
}
|
||||
|
||||
class SIYI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I16<op, SIYForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
class SILI<bits<16> op, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: I16<op, SILForm, outs, ins, asmstr, pattern>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pseudo instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstSystemZ<0, Pseudo, outs, ins> {
|
||||
|
||||
let Pattern = pattern;
|
||||
let AsmString = asmstr;
|
||||
}
|
@ -1,439 +0,0 @@
|
||||
//===- 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 "SystemZInstrBuilder.h"
|
||||
#include "SystemZInstrInfo.h"
|
||||
#include "SystemZMachineFunctionInfo.h"
|
||||
#include "SystemZTargetMachine.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#define GET_INSTRINFO_CTOR
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
|
||||
: SystemZGenInstrInfo(SystemZ::ADJCALLSTACKUP, SystemZ::ADJCALLSTACKDOWN),
|
||||
RI(tm, *this), TM(tm) {
|
||||
}
|
||||
|
||||
/// isGVStub - Return true if the GV requires an extra load to get the
|
||||
/// real address.
|
||||
static inline bool isGVStub(GlobalValue *GV, SystemZTargetMachine &TM) {
|
||||
return TM.getSubtarget<SystemZSubtarget>().GVRequiresExtraLoad(GV, TM, false);
|
||||
}
|
||||
|
||||
void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned SrcReg, bool isKill, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
unsigned Opc = 0;
|
||||
if (RC == &SystemZ::GR32RegClass ||
|
||||
RC == &SystemZ::ADDR32RegClass)
|
||||
Opc = SystemZ::MOV32mr;
|
||||
else if (RC == &SystemZ::GR64RegClass ||
|
||||
RC == &SystemZ::ADDR64RegClass) {
|
||||
Opc = SystemZ::MOV64mr;
|
||||
} else if (RC == &SystemZ::FP32RegClass) {
|
||||
Opc = SystemZ::FMOV32mr;
|
||||
} else if (RC == &SystemZ::FP64RegClass) {
|
||||
Opc = SystemZ::FMOV64mr;
|
||||
} else if (RC == &SystemZ::GR64PRegClass) {
|
||||
Opc = SystemZ::MOV64Pmr;
|
||||
} else if (RC == &SystemZ::GR128RegClass) {
|
||||
Opc = SystemZ::MOV128mr;
|
||||
} else
|
||||
llvm_unreachable("Unsupported regclass to store");
|
||||
|
||||
addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx)
|
||||
.addReg(SrcReg, getKillRegState(isKill));
|
||||
}
|
||||
|
||||
void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const{
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
unsigned Opc = 0;
|
||||
if (RC == &SystemZ::GR32RegClass ||
|
||||
RC == &SystemZ::ADDR32RegClass)
|
||||
Opc = SystemZ::MOV32rm;
|
||||
else if (RC == &SystemZ::GR64RegClass ||
|
||||
RC == &SystemZ::ADDR64RegClass) {
|
||||
Opc = SystemZ::MOV64rm;
|
||||
} else if (RC == &SystemZ::FP32RegClass) {
|
||||
Opc = SystemZ::FMOV32rm;
|
||||
} else if (RC == &SystemZ::FP64RegClass) {
|
||||
Opc = SystemZ::FMOV64rm;
|
||||
} else if (RC == &SystemZ::GR64PRegClass) {
|
||||
Opc = SystemZ::MOV64Prm;
|
||||
} else if (RC == &SystemZ::GR128RegClass) {
|
||||
Opc = SystemZ::MOV128rm;
|
||||
} else
|
||||
llvm_unreachable("Unsupported regclass to load");
|
||||
|
||||
addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx);
|
||||
}
|
||||
|
||||
void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const {
|
||||
unsigned Opc;
|
||||
if (SystemZ::GR64RegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::MOV64rr;
|
||||
else if (SystemZ::GR32RegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::MOV32rr;
|
||||
else if (SystemZ::GR64PRegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::MOV64rrP;
|
||||
else if (SystemZ::GR128RegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::MOV128rr;
|
||||
else if (SystemZ::FP32RegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::FMOV32rr;
|
||||
else if (SystemZ::FP64RegClass.contains(DestReg, SrcReg))
|
||||
Opc = SystemZ::FMOV64rr;
|
||||
else
|
||||
llvm_unreachable("Impossible reg-to-reg copy");
|
||||
|
||||
BuildMI(MBB, I, DL, get(Opc), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
}
|
||||
|
||||
unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case SystemZ::MOV32rm:
|
||||
case SystemZ::MOV32rmy:
|
||||
case SystemZ::MOV64rm:
|
||||
case SystemZ::MOVSX32rm8:
|
||||
case SystemZ::MOVSX32rm16y:
|
||||
case SystemZ::MOVSX64rm8:
|
||||
case SystemZ::MOVSX64rm16:
|
||||
case SystemZ::MOVSX64rm32:
|
||||
case SystemZ::MOVZX32rm8:
|
||||
case SystemZ::MOVZX32rm16:
|
||||
case SystemZ::MOVZX64rm8:
|
||||
case SystemZ::MOVZX64rm16:
|
||||
case SystemZ::MOVZX64rm32:
|
||||
case SystemZ::FMOV32rm:
|
||||
case SystemZ::FMOV32rmy:
|
||||
case SystemZ::FMOV64rm:
|
||||
case SystemZ::FMOV64rmy:
|
||||
case SystemZ::MOV64Prm:
|
||||
case SystemZ::MOV64Prmy:
|
||||
case SystemZ::MOV128rm:
|
||||
if (MI->getOperand(1).isFI() &&
|
||||
MI->getOperand(2).isImm() && MI->getOperand(3).isReg() &&
|
||||
MI->getOperand(2).getImm() == 0 && MI->getOperand(3).getReg() == 0) {
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case SystemZ::MOV32mr:
|
||||
case SystemZ::MOV32mry:
|
||||
case SystemZ::MOV64mr:
|
||||
case SystemZ::MOV32m8r:
|
||||
case SystemZ::MOV32m8ry:
|
||||
case SystemZ::MOV32m16r:
|
||||
case SystemZ::MOV32m16ry:
|
||||
case SystemZ::MOV64m8r:
|
||||
case SystemZ::MOV64m8ry:
|
||||
case SystemZ::MOV64m16r:
|
||||
case SystemZ::MOV64m16ry:
|
||||
case SystemZ::MOV64m32r:
|
||||
case SystemZ::MOV64m32ry:
|
||||
case SystemZ::FMOV32mr:
|
||||
case SystemZ::FMOV32mry:
|
||||
case SystemZ::FMOV64mr:
|
||||
case SystemZ::FMOV64mry:
|
||||
case SystemZ::MOV64Pmr:
|
||||
case SystemZ::MOV64Pmry:
|
||||
case SystemZ::MOV128mr:
|
||||
if (MI->getOperand(0).isFI() &&
|
||||
MI->getOperand(1).isImm() && MI->getOperand(2).isReg() &&
|
||||
MI->getOperand(1).getImm() == 0 && MI->getOperand(2).getReg() == 0) {
|
||||
FrameIndex = MI->getOperand(0).getIndex();
|
||||
return MI->getOperand(3).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SystemZInstrInfo::
|
||||
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
assert(Cond.size() == 1 && "Invalid Xbranch condition!");
|
||||
|
||||
SystemZCC::CondCodes CC = static_cast<SystemZCC::CondCodes>(Cond[0].getImm());
|
||||
Cond[0].setImm(getOppositeCondition(CC));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
|
||||
const MCInstrDesc &MCID = MI->getDesc();
|
||||
if (!MCID.isTerminator()) return false;
|
||||
|
||||
// Conditional branch is a special case.
|
||||
if (MCID.isBranch() && !MCID.isBarrier())
|
||||
return true;
|
||||
if (!MCID.isPredicable())
|
||||
return true;
|
||||
return !isPredicated(MI);
|
||||
}
|
||||
|
||||
bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const {
|
||||
// Start from the bottom of the block and work up, examining the
|
||||
// terminator instructions.
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
while (I != MBB.begin()) {
|
||||
--I;
|
||||
if (I->isDebugValue())
|
||||
continue;
|
||||
// Working from the bottom, when we see a non-terminator
|
||||
// instruction, we're done.
|
||||
if (!isUnpredicatedTerminator(I))
|
||||
break;
|
||||
|
||||
// A terminator that isn't a branch can't easily be handled
|
||||
// by this analysis.
|
||||
if (!I->getDesc().isBranch())
|
||||
return true;
|
||||
|
||||
// Handle unconditional branches.
|
||||
if (I->getOpcode() == SystemZ::JMP) {
|
||||
if (!AllowModify) {
|
||||
TBB = I->getOperand(0).getMBB();
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the block has any instructions after a JMP, delete them.
|
||||
while (llvm::next(I) != MBB.end())
|
||||
llvm::next(I)->eraseFromParent();
|
||||
Cond.clear();
|
||||
FBB = 0;
|
||||
|
||||
// Delete the JMP if it's equivalent to a fall-through.
|
||||
if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
|
||||
TBB = 0;
|
||||
I->eraseFromParent();
|
||||
I = MBB.end();
|
||||
continue;
|
||||
}
|
||||
|
||||
// TBB is used to indicate the unconditinal destination.
|
||||
TBB = I->getOperand(0).getMBB();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle conditional branches.
|
||||
SystemZCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
|
||||
if (BranchCode == SystemZCC::INVALID)
|
||||
return true; // Can't handle indirect branch.
|
||||
|
||||
// Working from the bottom, handle the first conditional branch.
|
||||
if (Cond.empty()) {
|
||||
FBB = TBB;
|
||||
TBB = I->getOperand(0).getMBB();
|
||||
Cond.push_back(MachineOperand::CreateImm(BranchCode));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle subsequent conditional branches. Only handle the case where all
|
||||
// conditional branches branch to the same destination.
|
||||
assert(Cond.size() == 1);
|
||||
assert(TBB);
|
||||
|
||||
// Only handle the case where all conditional branches branch to
|
||||
// the same destination.
|
||||
if (TBB != I->getOperand(0).getMBB())
|
||||
return true;
|
||||
|
||||
SystemZCC::CondCodes OldBranchCode = (SystemZCC::CondCodes)Cond[0].getImm();
|
||||
// If the conditions are the same, we can leave them alone.
|
||||
if (OldBranchCode == BranchCode)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
unsigned Count = 0;
|
||||
|
||||
while (I != MBB.begin()) {
|
||||
--I;
|
||||
if (I->isDebugValue())
|
||||
continue;
|
||||
if (I->getOpcode() != SystemZ::JMP &&
|
||||
getCondFromBranchOpc(I->getOpcode()) == SystemZCC::INVALID)
|
||||
break;
|
||||
// Remove the branch.
|
||||
I->eraseFromParent();
|
||||
I = MBB.end();
|
||||
++Count;
|
||||
}
|
||||
|
||||
return Count;
|
||||
}
|
||||
|
||||
unsigned
|
||||
SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const {
|
||||
// Shouldn't be a fall through.
|
||||
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
|
||||
assert((Cond.size() == 1 || Cond.size() == 0) &&
|
||||
"SystemZ branch conditions have one component!");
|
||||
|
||||
if (Cond.empty()) {
|
||||
// Unconditional branch?
|
||||
assert(!FBB && "Unconditional branch with multiple successors!");
|
||||
BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(TBB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Conditional branch.
|
||||
unsigned Count = 0;
|
||||
SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
|
||||
BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
|
||||
++Count;
|
||||
|
||||
if (FBB) {
|
||||
// Two-way Conditional branch. Insert the second branch.
|
||||
BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(FBB);
|
||||
++Count;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
const MCInstrDesc&
|
||||
SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const {
|
||||
switch (CC) {
|
||||
default:
|
||||
llvm_unreachable("Unknown condition code!");
|
||||
case SystemZCC::O: return get(SystemZ::JO);
|
||||
case SystemZCC::H: return get(SystemZ::JH);
|
||||
case SystemZCC::NLE: return get(SystemZ::JNLE);
|
||||
case SystemZCC::L: return get(SystemZ::JL);
|
||||
case SystemZCC::NHE: return get(SystemZ::JNHE);
|
||||
case SystemZCC::LH: return get(SystemZ::JLH);
|
||||
case SystemZCC::NE: return get(SystemZ::JNE);
|
||||
case SystemZCC::E: return get(SystemZ::JE);
|
||||
case SystemZCC::NLH: return get(SystemZ::JNLH);
|
||||
case SystemZCC::HE: return get(SystemZ::JHE);
|
||||
case SystemZCC::NL: return get(SystemZ::JNL);
|
||||
case SystemZCC::LE: return get(SystemZ::JLE);
|
||||
case SystemZCC::NH: return get(SystemZ::JNH);
|
||||
case SystemZCC::NO: return get(SystemZ::JNO);
|
||||
}
|
||||
}
|
||||
|
||||
SystemZCC::CondCodes
|
||||
SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
|
||||
switch (Opc) {
|
||||
default: return SystemZCC::INVALID;
|
||||
case SystemZ::JO: return SystemZCC::O;
|
||||
case SystemZ::JH: return SystemZCC::H;
|
||||
case SystemZ::JNLE: return SystemZCC::NLE;
|
||||
case SystemZ::JL: return SystemZCC::L;
|
||||
case SystemZ::JNHE: return SystemZCC::NHE;
|
||||
case SystemZ::JLH: return SystemZCC::LH;
|
||||
case SystemZ::JNE: return SystemZCC::NE;
|
||||
case SystemZ::JE: return SystemZCC::E;
|
||||
case SystemZ::JNLH: return SystemZCC::NLH;
|
||||
case SystemZ::JHE: return SystemZCC::HE;
|
||||
case SystemZ::JNL: return SystemZCC::NL;
|
||||
case SystemZ::JLE: return SystemZCC::LE;
|
||||
case SystemZ::JNH: return SystemZCC::NH;
|
||||
case SystemZ::JNO: return SystemZCC::NO;
|
||||
}
|
||||
}
|
||||
|
||||
SystemZCC::CondCodes
|
||||
SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC) const {
|
||||
switch (CC) {
|
||||
default:
|
||||
llvm_unreachable("Invalid condition!");
|
||||
case SystemZCC::O: return SystemZCC::NO;
|
||||
case SystemZCC::H: return SystemZCC::NH;
|
||||
case SystemZCC::NLE: return SystemZCC::LE;
|
||||
case SystemZCC::L: return SystemZCC::NL;
|
||||
case SystemZCC::NHE: return SystemZCC::HE;
|
||||
case SystemZCC::LH: return SystemZCC::NLH;
|
||||
case SystemZCC::NE: return SystemZCC::E;
|
||||
case SystemZCC::E: return SystemZCC::NE;
|
||||
case SystemZCC::NLH: return SystemZCC::LH;
|
||||
case SystemZCC::HE: return SystemZCC::NHE;
|
||||
case SystemZCC::NL: return SystemZCC::L;
|
||||
case SystemZCC::LE: return SystemZCC::NLE;
|
||||
case SystemZCC::NH: return SystemZCC::H;
|
||||
case SystemZCC::NO: return SystemZCC::O;
|
||||
}
|
||||
}
|
||||
|
||||
const MCInstrDesc&
|
||||
SystemZInstrInfo::getLongDispOpc(unsigned Opc) const {
|
||||
switch (Opc) {
|
||||
default:
|
||||
llvm_unreachable("Don't have long disp version of this instruction");
|
||||
case SystemZ::MOV32mr: return get(SystemZ::MOV32mry);
|
||||
case SystemZ::MOV32rm: return get(SystemZ::MOV32rmy);
|
||||
case SystemZ::MOVSX32rm16: return get(SystemZ::MOVSX32rm16y);
|
||||
case SystemZ::MOV32m8r: return get(SystemZ::MOV32m8ry);
|
||||
case SystemZ::MOV32m16r: return get(SystemZ::MOV32m16ry);
|
||||
case SystemZ::MOV64m8r: return get(SystemZ::MOV64m8ry);
|
||||
case SystemZ::MOV64m16r: return get(SystemZ::MOV64m16ry);
|
||||
case SystemZ::MOV64m32r: return get(SystemZ::MOV64m32ry);
|
||||
case SystemZ::MOV8mi: return get(SystemZ::MOV8miy);
|
||||
case SystemZ::MUL32rm: return get(SystemZ::MUL32rmy);
|
||||
case SystemZ::CMP32rm: return get(SystemZ::CMP32rmy);
|
||||
case SystemZ::UCMP32rm: return get(SystemZ::UCMP32rmy);
|
||||
case SystemZ::FMOV32mr: return get(SystemZ::FMOV32mry);
|
||||
case SystemZ::FMOV64mr: return get(SystemZ::FMOV64mry);
|
||||
case SystemZ::FMOV32rm: return get(SystemZ::FMOV32rmy);
|
||||
case SystemZ::FMOV64rm: return get(SystemZ::FMOV64rmy);
|
||||
case SystemZ::MOV64Pmr: return get(SystemZ::MOV64Pmry);
|
||||
case SystemZ::MOV64Prm: return get(SystemZ::MOV64Prmy);
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
//===- 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 "SystemZ.h"
|
||||
#include "SystemZRegisterInfo.h"
|
||||
#include "llvm/ADT/IndexedMap.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
|
||||
#define GET_INSTRINFO_HEADER
|
||||
#include "SystemZGenInstrInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SystemZTargetMachine;
|
||||
|
||||
/// SystemZII - This namespace holds all of the target specific flags that
|
||||
/// instruction info tracks.
|
||||
///
|
||||
namespace SystemZII {
|
||||
enum {
|
||||
//===------------------------------------------------------------------===//
|
||||
// SystemZ Specific MachineOperand flags.
|
||||
|
||||
MO_NO_FLAG = 0,
|
||||
|
||||
/// MO_GOTENT - On a symbol operand this indicates that the immediate is
|
||||
/// the offset to the location of the symbol name from the base of the GOT.
|
||||
///
|
||||
/// SYMBOL_LABEL @GOTENT
|
||||
MO_GOTENT = 1,
|
||||
|
||||
/// MO_PLT - On a symbol operand this indicates that the immediate is
|
||||
/// offset to the PLT entry of symbol name from the current code location.
|
||||
///
|
||||
/// SYMBOL_LABEL @PLT
|
||||
MO_PLT = 2
|
||||
};
|
||||
}
|
||||
|
||||
class SystemZInstrInfo : public SystemZGenInstrInfo {
|
||||
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 SystemZRegisterInfo &getRegisterInfo() const { return RI; }
|
||||
|
||||
virtual void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const;
|
||||
|
||||
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
|
||||
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const;
|
||||
|
||||
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned SrcReg, bool isKill,
|
||||
int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
|
||||
virtual bool AnalyzeBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const;
|
||||
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const;
|
||||
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
|
||||
|
||||
SystemZCC::CondCodes getOppositeCondition(SystemZCC::CondCodes CC) const;
|
||||
SystemZCC::CondCodes getCondFromBranchOpc(unsigned Opc) const;
|
||||
const MCInstrDesc& getBrCond(SystemZCC::CondCodes CC) const;
|
||||
const MCInstrDesc& getLongDispOpc(unsigned Opc) const;
|
||||
|
||||
const MCInstrDesc& getMemoryInstr(unsigned Opc, int64_t Offset = 0) const {
|
||||
if (Offset < 0 || Offset >= 4096)
|
||||
return getLongDispOpc(Opc);
|
||||
else
|
||||
return get(Opc);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
//==- 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;
|
||||
|
||||
/// LowReg - Low register of range of callee-saved registers to store.
|
||||
unsigned LowReg;
|
||||
|
||||
/// HighReg - High register of range of callee-saved registers to store.
|
||||
unsigned HighReg;
|
||||
public:
|
||||
SystemZMachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
||||
|
||||
explicit SystemZMachineFunctionInfo(MachineFunction &MF)
|
||||
: CalleeSavedFrameSize(0) {}
|
||||
|
||||
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
|
||||
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
|
||||
|
||||
unsigned getLowReg() const { return LowReg; }
|
||||
void setLowReg(unsigned Reg) { LowReg = Reg; }
|
||||
|
||||
unsigned getHighReg() const { return HighReg; }
|
||||
void setHighReg(unsigned Reg) { HighReg = Reg; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,325 +0,0 @@
|
||||
//=====- SystemZOperands.td - SystemZ Operands 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 various SystemZ instruction operands.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Pattern Stuff.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// SystemZ specific condition code. These correspond to CondCode in
|
||||
// SystemZ.h. They must be kept in synch.
|
||||
def SYSTEMZ_COND_O : PatLeaf<(i8 0)>;
|
||||
def SYSTEMZ_COND_H : PatLeaf<(i8 1)>;
|
||||
def SYSTEMZ_COND_NLE : PatLeaf<(i8 2)>;
|
||||
def SYSTEMZ_COND_L : PatLeaf<(i8 3)>;
|
||||
def SYSTEMZ_COND_NHE : PatLeaf<(i8 4)>;
|
||||
def SYSTEMZ_COND_LH : PatLeaf<(i8 5)>;
|
||||
def SYSTEMZ_COND_NE : PatLeaf<(i8 6)>;
|
||||
def SYSTEMZ_COND_E : PatLeaf<(i8 7)>;
|
||||
def SYSTEMZ_COND_NLH : PatLeaf<(i8 8)>;
|
||||
def SYSTEMZ_COND_HE : PatLeaf<(i8 9)>;
|
||||
def SYSTEMZ_COND_NL : PatLeaf<(i8 10)>;
|
||||
def SYSTEMZ_COND_LE : PatLeaf<(i8 11)>;
|
||||
def SYSTEMZ_COND_NH : PatLeaf<(i8 12)>;
|
||||
def SYSTEMZ_COND_NO : PatLeaf<(i8 13)>;
|
||||
|
||||
def LO8 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return low 8 bits.
|
||||
return getI8Imm(N->getZExtValue() & 0x00000000000000FFULL);
|
||||
}]>;
|
||||
|
||||
def LL16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return low 16 bits.
|
||||
return getI16Imm(N->getZExtValue() & 0x000000000000FFFFULL);
|
||||
}]>;
|
||||
|
||||
def LH16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return bits 16-31.
|
||||
return getI16Imm((N->getZExtValue() & 0x00000000FFFF0000ULL) >> 16);
|
||||
}]>;
|
||||
|
||||
def HL16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return bits 32-47.
|
||||
return getI16Imm((N->getZExtValue() & 0x0000FFFF00000000ULL) >> 32);
|
||||
}]>;
|
||||
|
||||
def HH16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return bits 48-63.
|
||||
return getI16Imm((N->getZExtValue() & 0xFFFF000000000000ULL) >> 48);
|
||||
}]>;
|
||||
|
||||
def LO32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return low 32 bits.
|
||||
return getI32Imm(N->getZExtValue() & 0x00000000FFFFFFFFULL);
|
||||
}]>;
|
||||
|
||||
def HI32 : SDNodeXForm<imm, [{
|
||||
// Transformation function: return bits 32-63.
|
||||
return getI32Imm(N->getZExtValue() >> 32);
|
||||
}]>;
|
||||
|
||||
def GetI64FromI32 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i64);
|
||||
}]>;
|
||||
|
||||
def i32ll16 : PatLeaf<(i32 imm), [{
|
||||
// i32ll16 predicate - true if the 32-bit immediate has only rightmost 16
|
||||
// bits set.
|
||||
return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
|
||||
}], LL16>;
|
||||
|
||||
def i32lh16 : PatLeaf<(i32 imm), [{
|
||||
// i32lh16 predicate - true if the 32-bit immediate has only bits 16-31 set.
|
||||
return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
|
||||
}], LH16>;
|
||||
|
||||
def i32ll16c : PatLeaf<(i32 imm), [{
|
||||
// i32ll16c predicate - true if the 32-bit immediate has all bits 16-31 set.
|
||||
return ((N->getZExtValue() | 0x00000000FFFF0000ULL) == N->getZExtValue());
|
||||
}], LL16>;
|
||||
|
||||
def i32lh16c : PatLeaf<(i32 imm), [{
|
||||
// i32lh16c predicate - true if the 32-bit immediate has all rightmost 16
|
||||
// bits set.
|
||||
return ((N->getZExtValue() | 0x000000000000FFFFULL) == N->getZExtValue());
|
||||
}], LH16>;
|
||||
|
||||
def i64ll16 : PatLeaf<(i64 imm), [{
|
||||
// i64ll16 predicate - true if the 64-bit immediate has only rightmost 16
|
||||
// bits set.
|
||||
return ((N->getZExtValue() & 0x000000000000FFFFULL) == N->getZExtValue());
|
||||
}], LL16>;
|
||||
|
||||
def i64lh16 : PatLeaf<(i64 imm), [{
|
||||
// i64lh16 predicate - true if the 64-bit immediate has only bits 16-31 set.
|
||||
return ((N->getZExtValue() & 0x00000000FFFF0000ULL) == N->getZExtValue());
|
||||
}], LH16>;
|
||||
|
||||
def i64hl16 : PatLeaf<(i64 imm), [{
|
||||
// i64hl16 predicate - true if the 64-bit immediate has only bits 32-47 set.
|
||||
return ((N->getZExtValue() & 0x0000FFFF00000000ULL) == N->getZExtValue());
|
||||
}], HL16>;
|
||||
|
||||
def i64hh16 : PatLeaf<(i64 imm), [{
|
||||
// i64hh16 predicate - true if the 64-bit immediate has only bits 48-63 set.
|
||||
return ((N->getZExtValue() & 0xFFFF000000000000ULL) == N->getZExtValue());
|
||||
}], HH16>;
|
||||
|
||||
def i64ll16c : PatLeaf<(i64 imm), [{
|
||||
// i64ll16c predicate - true if the 64-bit immediate has only rightmost 16
|
||||
// bits set.
|
||||
return ((N->getZExtValue() | 0xFFFFFFFFFFFF0000ULL) == N->getZExtValue());
|
||||
}], LL16>;
|
||||
|
||||
def i64lh16c : PatLeaf<(i64 imm), [{
|
||||
// i64lh16c predicate - true if the 64-bit immediate has only bits 16-31 set.
|
||||
return ((N->getZExtValue() | 0xFFFFFFFF0000FFFFULL) == N->getZExtValue());
|
||||
}], LH16>;
|
||||
|
||||
def i64hl16c : PatLeaf<(i64 imm), [{
|
||||
// i64hl16c predicate - true if the 64-bit immediate has only bits 32-47 set.
|
||||
return ((N->getZExtValue() | 0xFFFF0000FFFFFFFFULL) == N->getZExtValue());
|
||||
}], HL16>;
|
||||
|
||||
def i64hh16c : PatLeaf<(i64 imm), [{
|
||||
// i64hh16c predicate - true if the 64-bit immediate has only bits 48-63 set.
|
||||
return ((N->getZExtValue() | 0x0000FFFFFFFFFFFFULL) == N->getZExtValue());
|
||||
}], HH16>;
|
||||
|
||||
def immSExt16 : PatLeaf<(imm), [{
|
||||
// immSExt16 predicate - true if the immediate fits in a 16-bit sign extended
|
||||
// field.
|
||||
if (N->getValueType(0) == MVT::i64) {
|
||||
uint64_t val = N->getZExtValue();
|
||||
return ((int64_t)val == (int16_t)val);
|
||||
} else if (N->getValueType(0) == MVT::i32) {
|
||||
uint32_t val = N->getZExtValue();
|
||||
return ((int32_t)val == (int16_t)val);
|
||||
}
|
||||
|
||||
return false;
|
||||
}], LL16>;
|
||||
|
||||
def immSExt32 : PatLeaf<(i64 imm), [{
|
||||
// immSExt32 predicate - true if the immediate fits in a 32-bit sign extended
|
||||
// field.
|
||||
uint64_t val = N->getZExtValue();
|
||||
return ((int64_t)val == (int32_t)val);
|
||||
}], LO32>;
|
||||
|
||||
def i64lo32 : PatLeaf<(i64 imm), [{
|
||||
// i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
|
||||
// bits set.
|
||||
return ((N->getZExtValue() & 0x00000000FFFFFFFFULL) == N->getZExtValue());
|
||||
}], LO32>;
|
||||
|
||||
def i64hi32 : PatLeaf<(i64 imm), [{
|
||||
// i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
|
||||
return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue());
|
||||
}], HI32>;
|
||||
|
||||
def i64lo32c : PatLeaf<(i64 imm), [{
|
||||
// i64lo32 predicate - true if the 64-bit immediate has only rightmost 32
|
||||
// bits set.
|
||||
return ((N->getZExtValue() | 0xFFFFFFFF00000000ULL) == N->getZExtValue());
|
||||
}], LO32>;
|
||||
|
||||
def i64hi32c : PatLeaf<(i64 imm), [{
|
||||
// i64hi32 predicate - true if the 64-bit immediate has only bits 32-63 set.
|
||||
return ((N->getZExtValue() | 0x00000000FFFFFFFFULL) == N->getZExtValue());
|
||||
}], HI32>;
|
||||
|
||||
def i32immSExt8 : PatLeaf<(i32 imm), [{
|
||||
// i32immSExt8 predicate - True if the 32-bit immediate fits in a 8-bit
|
||||
// sign extended field.
|
||||
return (int32_t)N->getZExtValue() == (int8_t)N->getZExtValue();
|
||||
}], LO8>;
|
||||
|
||||
def i32immSExt16 : PatLeaf<(i32 imm), [{
|
||||
// i32immSExt16 predicate - True if the 32-bit immediate fits in a 16-bit
|
||||
// sign extended field.
|
||||
return (int32_t)N->getZExtValue() == (int16_t)N->getZExtValue();
|
||||
}], LL16>;
|
||||
|
||||
def i64immSExt32 : PatLeaf<(i64 imm), [{
|
||||
// i64immSExt32 predicate - True if the 64-bit immediate fits in a 32-bit
|
||||
// sign extended field.
|
||||
return (int64_t)N->getZExtValue() == (int32_t)N->getZExtValue();
|
||||
}], LO32>;
|
||||
|
||||
def i64immZExt32 : PatLeaf<(i64 imm), [{
|
||||
// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit
|
||||
// zero extended field.
|
||||
return (uint64_t)N->getZExtValue() == (uint32_t)N->getZExtValue();
|
||||
}], LO32>;
|
||||
|
||||
// extloads
|
||||
def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;
|
||||
def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
|
||||
def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
|
||||
def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
|
||||
def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
|
||||
|
||||
def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;
|
||||
def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;
|
||||
def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
|
||||
def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
|
||||
def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
|
||||
|
||||
def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;
|
||||
def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;
|
||||
def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
|
||||
def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
|
||||
def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
|
||||
|
||||
// A couple of more descriptive operand definitions.
|
||||
// 32-bits but only 8 bits are significant.
|
||||
def i32i8imm : Operand<i32>;
|
||||
// 32-bits but only 16 bits are significant.
|
||||
def i32i16imm : Operand<i32>;
|
||||
// 64-bits but only 32 bits are significant.
|
||||
def i64i32imm : Operand<i64>;
|
||||
// Branch targets have OtherVT type.
|
||||
def brtarget : Operand<OtherVT>;
|
||||
|
||||
// Unsigned i12
|
||||
def u12imm : Operand<i32> {
|
||||
let PrintMethod = "printU12ImmOperand";
|
||||
}
|
||||
def u12imm64 : Operand<i64> {
|
||||
let PrintMethod = "printU12ImmOperand";
|
||||
}
|
||||
|
||||
// Signed i16
|
||||
def s16imm : Operand<i32> {
|
||||
let PrintMethod = "printS16ImmOperand";
|
||||
}
|
||||
def s16imm64 : Operand<i64> {
|
||||
let PrintMethod = "printS16ImmOperand";
|
||||
}
|
||||
// Unsigned i16
|
||||
def u16imm : Operand<i32> {
|
||||
let PrintMethod = "printU16ImmOperand";
|
||||
}
|
||||
def u16imm64 : Operand<i64> {
|
||||
let PrintMethod = "printU16ImmOperand";
|
||||
}
|
||||
|
||||
// Signed i20
|
||||
def s20imm : Operand<i32> {
|
||||
let PrintMethod = "printS20ImmOperand";
|
||||
}
|
||||
def s20imm64 : Operand<i64> {
|
||||
let PrintMethod = "printS20ImmOperand";
|
||||
}
|
||||
// Signed i32
|
||||
def s32imm : Operand<i32> {
|
||||
let PrintMethod = "printS32ImmOperand";
|
||||
}
|
||||
def s32imm64 : Operand<i64> {
|
||||
let PrintMethod = "printS32ImmOperand";
|
||||
}
|
||||
// Unsigned i32
|
||||
def u32imm : Operand<i32> {
|
||||
let PrintMethod = "printU32ImmOperand";
|
||||
}
|
||||
def u32imm64 : Operand<i64> {
|
||||
let PrintMethod = "printU32ImmOperand";
|
||||
}
|
||||
|
||||
def imm_pcrel : Operand<i64> {
|
||||
let PrintMethod = "printPCRelImmOperand";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SystemZ Operand Definitions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Address operands
|
||||
|
||||
// riaddr := reg + imm
|
||||
def riaddr32 : Operand<i64>,
|
||||
ComplexPattern<i64, 2, "SelectAddrRI12Only", []> {
|
||||
let PrintMethod = "printRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, u12imm:$disp);
|
||||
}
|
||||
|
||||
def riaddr12 : Operand<i64>,
|
||||
ComplexPattern<i64, 2, "SelectAddrRI12", []> {
|
||||
let PrintMethod = "printRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, u12imm64:$disp);
|
||||
}
|
||||
|
||||
def riaddr : Operand<i64>,
|
||||
ComplexPattern<i64, 2, "SelectAddrRI", []> {
|
||||
let PrintMethod = "printRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// rriaddr := reg + reg + imm
|
||||
def rriaddr12 : Operand<i64>,
|
||||
ComplexPattern<i64, 3, "SelectAddrRRI12", [], []> {
|
||||
let PrintMethod = "printRRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, u12imm64:$disp, ADDR64:$index);
|
||||
}
|
||||
def rriaddr : Operand<i64>,
|
||||
ComplexPattern<i64, 3, "SelectAddrRRI20", [], []> {
|
||||
let PrintMethod = "printRRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
|
||||
}
|
||||
def laaddr : Operand<i64>,
|
||||
ComplexPattern<i64, 3, "SelectLAAddr", [add, sub, or, frameindex], []> {
|
||||
let PrintMethod = "printRRIAddrOperand";
|
||||
let MIOperandInfo = (ops ADDR64:$base, s20imm64:$disp, ADDR64:$index);
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
//===- 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 "SystemZInstrInfo.h"
|
||||
#include "SystemZMachineFunctionInfo.h"
|
||||
#include "SystemZRegisterInfo.h"
|
||||
#include "SystemZSubtarget.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
|
||||
#define GET_REGINFO_TARGET_DESC
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
SystemZRegisterInfo::SystemZRegisterInfo(SystemZTargetMachine &tm,
|
||||
const SystemZInstrInfo &tii)
|
||||
: SystemZGenRegisterInfo(0), TM(tm), TII(tii) {
|
||||
}
|
||||
|
||||
const unsigned*
|
||||
SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
static const unsigned CalleeSavedRegs[] = {
|
||||
SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D,
|
||||
SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D,
|
||||
SystemZ::R14D, SystemZ::R15D,
|
||||
SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L,
|
||||
SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L,
|
||||
0
|
||||
};
|
||||
|
||||
return CalleeSavedRegs;
|
||||
}
|
||||
|
||||
BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
BitVector Reserved(getNumRegs());
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
if (TFI->hasFP(MF)) {
|
||||
// R11D is the frame pointer. Reserve all aliases.
|
||||
Reserved.set(SystemZ::R11D);
|
||||
Reserved.set(SystemZ::R11W);
|
||||
Reserved.set(SystemZ::R10P);
|
||||
Reserved.set(SystemZ::R10Q);
|
||||
}
|
||||
|
||||
Reserved.set(SystemZ::R14D);
|
||||
Reserved.set(SystemZ::R15D);
|
||||
Reserved.set(SystemZ::R14W);
|
||||
Reserved.set(SystemZ::R15W);
|
||||
Reserved.set(SystemZ::R14P);
|
||||
Reserved.set(SystemZ::R14Q);
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
const TargetRegisterClass*
|
||||
SystemZRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
|
||||
const TargetRegisterClass *B,
|
||||
unsigned Idx) const {
|
||||
switch(Idx) {
|
||||
// Exact sub-classes don't exist for the other sub-register indexes.
|
||||
default: return 0;
|
||||
case SystemZ::subreg_32bit:
|
||||
if (B == SystemZ::ADDR32RegisterClass)
|
||||
return A->getSize() == 8 ? SystemZ::ADDR64RegisterClass : 0;
|
||||
return A;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemZRegisterInfo::
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const {
|
||||
MBB.erase(I);
|
||||
}
|
||||
|
||||
void
|
||||
SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS) const {
|
||||
assert(SPAdj == 0 && "Unxpected");
|
||||
|
||||
unsigned i = 0;
|
||||
MachineInstr &MI = *II;
|
||||
MachineFunction &MF = *MI.getParent()->getParent();
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
while (!MI.getOperand(i).isFI()) {
|
||||
++i;
|
||||
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
|
||||
}
|
||||
|
||||
int FrameIndex = MI.getOperand(i).getIndex();
|
||||
|
||||
unsigned BasePtr = (TFI->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D);
|
||||
|
||||
// This must be part of a rri or ri operand memory reference. Replace the
|
||||
// FrameIndex with base register with BasePtr. Add an offset to the
|
||||
// displacement field.
|
||||
MI.getOperand(i).ChangeToRegister(BasePtr, false);
|
||||
|
||||
// Offset is a either 12-bit unsigned or 20-bit signed integer.
|
||||
// FIXME: handle "too long" displacements.
|
||||
int Offset =
|
||||
TFI->getFrameIndexOffset(MF, FrameIndex) + MI.getOperand(i+1).getImm();
|
||||
|
||||
// Check whether displacement is too long to fit into 12 bit zext field.
|
||||
MI.setDesc(TII.getMemoryInstr(MI.getOpcode(), Offset));
|
||||
|
||||
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
||||
}
|
||||
|
||||
unsigned
|
||||
SystemZRegisterInfo::getFrameRegister(const 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;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
//===-- SystemZRegisterInfo.h - 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SystemZREGISTERINFO_H
|
||||
#define SystemZREGISTERINFO_H
|
||||
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#define GET_REGINFO_HEADER
|
||||
#include "SystemZGenRegisterInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SystemZSubtarget;
|
||||
class SystemZInstrInfo;
|
||||
class Type;
|
||||
|
||||
struct SystemZRegisterInfo : public SystemZGenRegisterInfo {
|
||||
SystemZTargetMachine &TM;
|
||||
const SystemZInstrInfo &TII;
|
||||
|
||||
SystemZRegisterInfo(SystemZTargetMachine &tm, const SystemZInstrInfo &tii);
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const;
|
||||
|
||||
const TargetRegisterClass*
|
||||
getMatchingSuperRegClass(const TargetRegisterClass *A,
|
||||
const TargetRegisterClass *B, unsigned Idx) const;
|
||||
|
||||
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const;
|
||||
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS = NULL) const;
|
||||
|
||||
// Debug information queries.
|
||||
unsigned getFrameRegister(const MachineFunction &MF) const;
|
||||
|
||||
// Exception handling queries.
|
||||
unsigned getEHExceptionRegister() const;
|
||||
unsigned getEHHandlerRegister() const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,205 +0,0 @@
|
||||
//===- 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<string n> : Register<n> {
|
||||
let Namespace = "SystemZ";
|
||||
}
|
||||
|
||||
class SystemZRegWithSubregs<string n, list<Register> subregs>
|
||||
: RegisterWithSubRegs<n, subregs> {
|
||||
let Namespace = "SystemZ";
|
||||
}
|
||||
|
||||
// We identify all our registers with a 4-bit ID, for consistency's sake.
|
||||
|
||||
// GPR32 - Lower 32 bits of one of the 16 64-bit general-purpose registers
|
||||
class GPR32<bits<4> num, string n> : SystemZReg<n> {
|
||||
field bits<4> Num = num;
|
||||
}
|
||||
|
||||
// GPR64 - One of the 16 64-bit general-purpose registers
|
||||
class GPR64<bits<4> num, string n, list<Register> subregs,
|
||||
list<Register> aliases = []>
|
||||
: SystemZRegWithSubregs<n, subregs> {
|
||||
field bits<4> Num = num;
|
||||
let Aliases = aliases;
|
||||
}
|
||||
|
||||
// GPR128 - 8 even-odd register pairs
|
||||
class GPR128<bits<4> num, string n, list<Register> subregs,
|
||||
list<Register> aliases = []>
|
||||
: SystemZRegWithSubregs<n, subregs> {
|
||||
field bits<4> Num = num;
|
||||
let Aliases = aliases;
|
||||
}
|
||||
|
||||
// FPRS - Lower 32 bits of one of the 16 64-bit floating-point registers
|
||||
class FPRS<bits<4> num, string n> : SystemZReg<n> {
|
||||
field bits<4> Num = num;
|
||||
}
|
||||
|
||||
// FPRL - One of the 16 64-bit floating-point registers
|
||||
class FPRL<bits<4> num, string n, list<Register> subregs>
|
||||
: SystemZRegWithSubregs<n, subregs> {
|
||||
field bits<4> Num = num;
|
||||
}
|
||||
|
||||
let Namespace = "SystemZ" in {
|
||||
def subreg_32bit : SubRegIndex;
|
||||
def subreg_odd32 : SubRegIndex;
|
||||
def subreg_even : SubRegIndex;
|
||||
def subreg_odd : SubRegIndex;
|
||||
}
|
||||
|
||||
// General-purpose registers
|
||||
def R0W : GPR32< 0, "r0">;
|
||||
def R1W : GPR32< 1, "r1">;
|
||||
def R2W : GPR32< 2, "r2">;
|
||||
def R3W : GPR32< 3, "r3">;
|
||||
def R4W : GPR32< 4, "r4">;
|
||||
def R5W : GPR32< 5, "r5">;
|
||||
def R6W : GPR32< 6, "r6">;
|
||||
def R7W : GPR32< 7, "r7">;
|
||||
def R8W : GPR32< 8, "r8">;
|
||||
def R9W : GPR32< 9, "r9">;
|
||||
def R10W : GPR32<10, "r10">;
|
||||
def R11W : GPR32<11, "r11">;
|
||||
def R12W : GPR32<12, "r12">;
|
||||
def R13W : GPR32<13, "r13">;
|
||||
def R14W : GPR32<14, "r14">;
|
||||
def R15W : GPR32<15, "r15">;
|
||||
|
||||
let SubRegIndices = [subreg_32bit] in {
|
||||
def R0D : GPR64< 0, "r0", [R0W]>, DwarfRegNum<[0]>;
|
||||
def R1D : GPR64< 1, "r1", [R1W]>, DwarfRegNum<[1]>;
|
||||
def R2D : GPR64< 2, "r2", [R2W]>, DwarfRegNum<[2]>;
|
||||
def R3D : GPR64< 3, "r3", [R3W]>, DwarfRegNum<[3]>;
|
||||
def R4D : GPR64< 4, "r4", [R4W]>, DwarfRegNum<[4]>;
|
||||
def R5D : GPR64< 5, "r5", [R5W]>, DwarfRegNum<[5]>;
|
||||
def R6D : GPR64< 6, "r6", [R6W]>, DwarfRegNum<[6]>;
|
||||
def R7D : GPR64< 7, "r7", [R7W]>, DwarfRegNum<[7]>;
|
||||
def R8D : GPR64< 8, "r8", [R8W]>, DwarfRegNum<[8]>;
|
||||
def R9D : GPR64< 9, "r9", [R9W]>, DwarfRegNum<[9]>;
|
||||
def R10D : GPR64<10, "r10", [R10W]>, DwarfRegNum<[10]>;
|
||||
def R11D : GPR64<11, "r11", [R11W]>, DwarfRegNum<[11]>;
|
||||
def R12D : GPR64<12, "r12", [R12W]>, DwarfRegNum<[12]>;
|
||||
def R13D : GPR64<13, "r13", [R13W]>, DwarfRegNum<[13]>;
|
||||
def R14D : GPR64<14, "r14", [R14W]>, DwarfRegNum<[14]>;
|
||||
def R15D : GPR64<15, "r15", [R15W]>, DwarfRegNum<[15]>;
|
||||
}
|
||||
|
||||
// Register pairs
|
||||
let SubRegIndices = [subreg_32bit, subreg_odd32] in {
|
||||
def R0P : GPR64< 0, "r0", [R0W, R1W], [R0D, R1D]>;
|
||||
def R2P : GPR64< 2, "r2", [R2W, R3W], [R2D, R3D]>;
|
||||
def R4P : GPR64< 4, "r4", [R4W, R5W], [R4D, R5D]>;
|
||||
def R6P : GPR64< 6, "r6", [R6W, R7W], [R6D, R7D]>;
|
||||
def R8P : GPR64< 8, "r8", [R8W, R9W], [R8D, R9D]>;
|
||||
def R10P : GPR64<10, "r10", [R10W, R11W], [R10D, R11D]>;
|
||||
def R12P : GPR64<12, "r12", [R12W, R13W], [R12D, R13D]>;
|
||||
def R14P : GPR64<14, "r14", [R14W, R15W], [R14D, R15D]>;
|
||||
}
|
||||
|
||||
let SubRegIndices = [subreg_even, subreg_odd],
|
||||
CompositeIndices = [(subreg_odd32 subreg_odd, subreg_32bit)] in {
|
||||
def R0Q : GPR128< 0, "r0", [R0D, R1D], [R0P]>;
|
||||
def R2Q : GPR128< 2, "r2", [R2D, R3D], [R2P]>;
|
||||
def R4Q : GPR128< 4, "r4", [R4D, R5D], [R4P]>;
|
||||
def R6Q : GPR128< 6, "r6", [R6D, R7D], [R6P]>;
|
||||
def R8Q : GPR128< 8, "r8", [R8D, R9D], [R8P]>;
|
||||
def R10Q : GPR128<10, "r10", [R10D, R11D], [R10P]>;
|
||||
def R12Q : GPR128<12, "r12", [R12D, R13D], [R12P]>;
|
||||
def R14Q : GPR128<14, "r14", [R14D, R15D], [R14P]>;
|
||||
}
|
||||
|
||||
// Floating-point registers
|
||||
def F0S : FPRS< 0, "f0">, DwarfRegNum<[16]>;
|
||||
def F1S : FPRS< 1, "f1">, DwarfRegNum<[17]>;
|
||||
def F2S : FPRS< 2, "f2">, DwarfRegNum<[18]>;
|
||||
def F3S : FPRS< 3, "f3">, DwarfRegNum<[19]>;
|
||||
def F4S : FPRS< 4, "f4">, DwarfRegNum<[20]>;
|
||||
def F5S : FPRS< 5, "f5">, DwarfRegNum<[21]>;
|
||||
def F6S : FPRS< 6, "f6">, DwarfRegNum<[22]>;
|
||||
def F7S : FPRS< 7, "f7">, DwarfRegNum<[23]>;
|
||||
def F8S : FPRS< 8, "f8">, DwarfRegNum<[24]>;
|
||||
def F9S : FPRS< 9, "f9">, DwarfRegNum<[25]>;
|
||||
def F10S : FPRS<10, "f10">, DwarfRegNum<[26]>;
|
||||
def F11S : FPRS<11, "f11">, DwarfRegNum<[27]>;
|
||||
def F12S : FPRS<12, "f12">, DwarfRegNum<[28]>;
|
||||
def F13S : FPRS<13, "f13">, DwarfRegNum<[29]>;
|
||||
def F14S : FPRS<14, "f14">, DwarfRegNum<[30]>;
|
||||
def F15S : FPRS<15, "f15">, DwarfRegNum<[31]>;
|
||||
|
||||
let SubRegIndices = [subreg_32bit] in {
|
||||
def F0L : FPRL< 0, "f0", [F0S]>;
|
||||
def F1L : FPRL< 1, "f1", [F1S]>;
|
||||
def F2L : FPRL< 2, "f2", [F2S]>;
|
||||
def F3L : FPRL< 3, "f3", [F3S]>;
|
||||
def F4L : FPRL< 4, "f4", [F4S]>;
|
||||
def F5L : FPRL< 5, "f5", [F5S]>;
|
||||
def F6L : FPRL< 6, "f6", [F6S]>;
|
||||
def F7L : FPRL< 7, "f7", [F7S]>;
|
||||
def F8L : FPRL< 8, "f8", [F8S]>;
|
||||
def F9L : FPRL< 9, "f9", [F9S]>;
|
||||
def F10L : FPRL<10, "f10", [F10S]>;
|
||||
def F11L : FPRL<11, "f11", [F11S]>;
|
||||
def F12L : FPRL<12, "f12", [F12S]>;
|
||||
def F13L : FPRL<13, "f13", [F13S]>;
|
||||
def F14L : FPRL<14, "f14", [F14S]>;
|
||||
def F15L : FPRL<15, "f15", [F15S]>;
|
||||
}
|
||||
|
||||
// Status register
|
||||
def PSW : SystemZReg<"psw">;
|
||||
|
||||
/// Register classes.
|
||||
/// Allocate the callee-saved R6-R12 backwards. That way they can be saved
|
||||
/// together with R14 and R15 in one prolog instruction.
|
||||
def GR32 : RegisterClass<"SystemZ", [i32], 32, (add (sequence "R%uW", 0, 5),
|
||||
(sequence "R%uW", 15, 6))>;
|
||||
|
||||
/// Registers used to generate address. Everything except R0.
|
||||
def ADDR32 : RegisterClass<"SystemZ", [i32], 32, (sub GR32, R0W)>;
|
||||
|
||||
def GR64 : RegisterClass<"SystemZ", [i64], 64, (add (sequence "R%uD", 0, 5),
|
||||
(sequence "R%uD", 15, 6))> {
|
||||
let SubRegClasses = [(GR32 subreg_32bit)];
|
||||
}
|
||||
|
||||
def ADDR64 : RegisterClass<"SystemZ", [i64], 64, (sub GR64, R0D)> {
|
||||
let SubRegClasses = [(ADDR32 subreg_32bit)];
|
||||
}
|
||||
|
||||
// Even-odd register pairs
|
||||
def GR64P : RegisterClass<"SystemZ", [v2i32], 64, (add R0P, R2P, R4P,
|
||||
R12P, R10P, R8P, R6P,
|
||||
R14P)> {
|
||||
let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32)];
|
||||
}
|
||||
|
||||
def GR128 : RegisterClass<"SystemZ", [v2i64], 128, (add R0Q, R2Q, R4Q,
|
||||
R12Q, R10Q, R8Q, R6Q,
|
||||
R14Q)> {
|
||||
let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32),
|
||||
(GR64 subreg_even, subreg_odd)];
|
||||
}
|
||||
|
||||
def FP32 : RegisterClass<"SystemZ", [f32], 32, (sequence "F%uS", 0, 15)>;
|
||||
|
||||
def FP64 : RegisterClass<"SystemZ", [f64], 64, (sequence "F%uL", 0, 15)> {
|
||||
let SubRegClasses = [(FP32 subreg_32bit)];
|
||||
}
|
||||
|
||||
// Status flags registers.
|
||||
def CCR : RegisterClass<"SystemZ", [i64], 64, (add PSW)> {
|
||||
let CopyCost = -1; // Don't allow copying of status registers.
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
//===-- SystemZSelectionDAGInfo.cpp - SystemZ SelectionDAG Info -----------===//
|
||||
//
|
||||
// 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 SystemZSelectionDAGInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "systemz-selectiondag-info"
|
||||
#include "SystemZTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
SystemZSelectionDAGInfo::SystemZSelectionDAGInfo(const SystemZTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
SystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() {
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//===-- SystemZSelectionDAGInfo.h - SystemZ SelectionDAG 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 defines the SystemZ subclass for TargetSelectionDAGInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SYSTEMZSELECTIONDAGINFO_H
|
||||
#define SYSTEMZSELECTIONDAGINFO_H
|
||||
|
||||
#include "llvm/Target/TargetSelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SystemZTargetMachine;
|
||||
|
||||
class SystemZSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
explicit SystemZSelectionDAGInfo(const SystemZTargetMachine &TM);
|
||||
~SystemZSelectionDAGInfo();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,54 +0,0 @@
|
||||
//===- 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 TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZSubtarget.h"
|
||||
#include "SystemZ.h"
|
||||
#include "llvm/GlobalValue.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#define GET_SUBTARGETINFO_TARGET_DESC
|
||||
#define GET_SUBTARGETINFO_CTOR
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
SystemZSubtarget::SystemZSubtarget(const std::string &TT,
|
||||
const std::string &CPU,
|
||||
const std::string &FS):
|
||||
SystemZGenSubtargetInfo(TT, CPU, FS), HasZ10Insts(false) {
|
||||
std::string CPUName = CPU;
|
||||
if (CPUName.empty())
|
||||
CPUName = "z9";
|
||||
|
||||
// Parse features string.
|
||||
ParseSubtargetFeatures(CPUName, FS);
|
||||
}
|
||||
|
||||
/// True if accessing the GV requires an extra load.
|
||||
bool SystemZSubtarget::GVRequiresExtraLoad(const GlobalValue* GV,
|
||||
const TargetMachine& TM,
|
||||
bool isDirectCall) const {
|
||||
if (TM.getRelocationModel() == Reloc::PIC_) {
|
||||
// Extra load is needed for all externally visible.
|
||||
if (isDirectCall)
|
||||
return false;
|
||||
|
||||
if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
//==-- 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 TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_SystemZ_SUBTARGET_H
|
||||
#define LLVM_TARGET_SystemZ_SUBTARGET_H
|
||||
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <string>
|
||||
|
||||
#define GET_SUBTARGETINFO_HEADER
|
||||
#include "SystemZGenSubtargetInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
class GlobalValue;
|
||||
class StringRef;
|
||||
class TargetMachine;
|
||||
|
||||
class SystemZSubtarget : public SystemZGenSubtargetInfo {
|
||||
bool HasZ10Insts;
|
||||
public:
|
||||
/// This constructor initializes the data members to match that
|
||||
/// of the specified triple.
|
||||
///
|
||||
SystemZSubtarget(const std::string &TT, const std::string &CPU,
|
||||
const std::string &FS);
|
||||
|
||||
/// ParseSubtargetFeatures - Parses features string setting specified
|
||||
/// subtarget options. Definition of function is auto generated by tblgen.
|
||||
void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
|
||||
|
||||
bool isZ10() const { return HasZ10Insts; }
|
||||
|
||||
bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine& TM,
|
||||
bool isDirectCall) const;
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif // LLVM_TARGET_SystemZ_SUBTARGET_H
|
@ -1,40 +0,0 @@
|
||||
//===-- 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 "SystemZTargetMachine.h"
|
||||
#include "SystemZ.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
extern "C" void LLVMInitializeSystemZTarget() {
|
||||
// Register the target.
|
||||
RegisterTargetMachine<SystemZTargetMachine> X(TheSystemZTarget);
|
||||
}
|
||||
|
||||
/// SystemZTargetMachine ctor - Create an ILP64 architecture model
|
||||
///
|
||||
SystemZTargetMachine::SystemZTargetMachine(const Target &T,
|
||||
StringRef TT, StringRef CPU,
|
||||
StringRef FS, Reloc::Model RM,
|
||||
CodeModel::Model CM)
|
||||
: LLVMTargetMachine(T, TT, CPU, FS, RM, CM),
|
||||
Subtarget(TT, CPU, FS),
|
||||
DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
|
||||
"-f64:64:64-f128:128:128-a0:16:16-n32:64"),
|
||||
InstrInfo(*this), TLInfo(*this), TSInfo(*this),
|
||||
FrameLowering(Subtarget) {
|
||||
}
|
||||
|
||||
bool SystemZTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
// Install an instruction selector.
|
||||
PM.add(createSystemZISelDag(*this, OptLevel));
|
||||
return false;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
//==- 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 "SystemZFrameLowering.h"
|
||||
#include "SystemZSelectionDAGInfo.h"
|
||||
#include "SystemZRegisterInfo.h"
|
||||
#include "SystemZSubtarget.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameLowering.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;
|
||||
SystemZSelectionDAGInfo TSInfo;
|
||||
SystemZFrameLowering FrameLowering;
|
||||
public:
|
||||
SystemZTargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
Reloc::Model RM, CodeModel::Model CM);
|
||||
|
||||
virtual const TargetFrameLowering *getFrameLowering() const {
|
||||
return &FrameLowering;
|
||||
}
|
||||
virtual const SystemZInstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout;}
|
||||
virtual const SystemZSubtarget *getSubtargetImpl() const { return &Subtarget; }
|
||||
|
||||
virtual const SystemZRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
|
||||
virtual const SystemZTargetLowering *getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
|
||||
virtual const SystemZSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
}; // SystemZTargetMachine.
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_TARGET_SystemZ_TARGETMACHINE_H
|
@ -1,13 +0,0 @@
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||
|
||||
add_llvm_library(LLVMSystemZInfo
|
||||
SystemZTargetInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMSystemZInfo
|
||||
LLVMMC
|
||||
LLVMSupport
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_dependencies(LLVMSystemZInfo SystemZCommonTableGen)
|
@ -1,15 +0,0 @@
|
||||
##===- lib/Target/SystemZ/TargetInfo/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 = LLVMSystemZInfo
|
||||
|
||||
# Hack: we need to include 'main' target directory to grab private headers
|
||||
CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
@ -1,19 +0,0 @@
|
||||
//===-- SystemZTargetInfo.cpp - SystemZ Target Implementation -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SystemZ.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
Target llvm::TheSystemZTarget;
|
||||
|
||||
extern "C" void LLVMInitializeSystemZTargetInfo() {
|
||||
RegisterTarget<Triple::systemz> X(TheSystemZTarget, "systemz", "SystemZ");
|
||||
}
|
@ -301,7 +301,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
@ -438,7 +437,6 @@ else
|
||||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
@ -552,13 +550,13 @@ TARGETS_TO_BUILD=""
|
||||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, systemz, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
enableval=all)
|
||||
if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -571,7 +569,6 @@ case "$enableval" in
|
||||
spu) TARGETS_TO_BUILD="CellSPU $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" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
@ -589,7 +586,6 @@ case "$enableval" in
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) AC_MSG_ERROR([Can not set target to build]) ;;
|
||||
|
9
projects/sample/configure
vendored
9
projects/sample/configure
vendored
@ -1402,7 +1402,7 @@ Optional Features:
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, systemz, blackfin, ptx, cbe, and cpp
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp
|
||||
(default=all)
|
||||
--enable-cbe-printf-a Enable C Backend output with hex floating point via
|
||||
%a (default is YES)
|
||||
@ -3845,7 +3845,6 @@ else
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
s390x-*) llvm_cv_target_arch="SystemZ" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
@ -5049,8 +5048,6 @@ else
|
||||
XCore) TARGET_HAS_JIT=0
|
||||
;;
|
||||
MSP430) TARGET_HAS_JIT=0
|
||||
;;
|
||||
SystemZ) TARGET_HAS_JIT=0
|
||||
;;
|
||||
Blackfin) TARGET_HAS_JIT=0
|
||||
;;
|
||||
@ -5242,7 +5239,7 @@ if test "$enableval" = host-only ; then
|
||||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
|
||||
case "$a_target" in
|
||||
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
@ -5255,7 +5252,6 @@ case "$enableval" in
|
||||
spu) TARGETS_TO_BUILD="CellSPU $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" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
@ -5273,7 +5269,6 @@ case "$enableval" in
|
||||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
s390x) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5
|
||||
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
ret void
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
ret i64 %b
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep lghi | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llill | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llilh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llihl | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llihh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfi | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llilf | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llihf | count 1
|
||||
|
||||
|
||||
define i64 @foo1() {
|
||||
entry:
|
||||
ret i64 1
|
||||
}
|
||||
|
||||
define i64 @foo2() {
|
||||
entry:
|
||||
ret i64 65535
|
||||
}
|
||||
|
||||
define i64 @foo3() {
|
||||
entry:
|
||||
ret i64 131072
|
||||
}
|
||||
|
||||
define i64 @foo4() {
|
||||
entry:
|
||||
ret i64 8589934592
|
||||
}
|
||||
|
||||
define i64 @foo5() {
|
||||
entry:
|
||||
ret i64 562949953421312
|
||||
}
|
||||
|
||||
define i64 @foo6() {
|
||||
entry:
|
||||
ret i64 65537
|
||||
}
|
||||
|
||||
define i64 @foo7() {
|
||||
entry:
|
||||
ret i64 4294967295
|
||||
}
|
||||
|
||||
define i64 @foo8() {
|
||||
entry:
|
||||
ret i64 281483566645248
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | FileCheck %s
|
||||
|
||||
define signext i32 @foo1(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo1:
|
||||
; CHECK: a %r2, 4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = add i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo2:
|
||||
; CHECK: ay %r2, -4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = add i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i64 @foo3(i64 %a, i64 *%b, i64 %idx) {
|
||||
; CHECK: foo3:
|
||||
; CHECK: ag %r2, 8(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i64* %b, i64 %idx2 ; <i64*> [#uses=1]
|
||||
%c = load i64* %ptr
|
||||
%d = add i64 %a, %c
|
||||
ret i64 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo4(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo4:
|
||||
; CHECK: n %r2, 4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = and i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo5(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo5:
|
||||
; CHECK: ny %r2, -4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = and i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i64 @foo6(i64 %a, i64 *%b, i64 %idx) {
|
||||
; CHECK: foo6:
|
||||
; CHECK: ng %r2, 8(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i64* %b, i64 %idx2 ; <i64*> [#uses=1]
|
||||
%c = load i64* %ptr
|
||||
%d = and i64 %a, %c
|
||||
ret i64 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo7(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo7:
|
||||
; CHECK: o %r2, 4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = or i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo8(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo8:
|
||||
; CHECK: oy %r2, -4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = or i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i64 @foo9(i64 %a, i64 *%b, i64 %idx) {
|
||||
; CHECK: foo9:
|
||||
; CHECK: og %r2, 8(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i64* %b, i64 %idx2 ; <i64*> [#uses=1]
|
||||
%c = load i64* %ptr
|
||||
%d = or i64 %a, %c
|
||||
ret i64 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo10(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo10:
|
||||
; CHECK: x %r2, 4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = xor i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i32 @foo11(i32 %a, i32 *%b, i64 %idx) {
|
||||
; CHECK: foo11:
|
||||
; CHECK: xy %r2, -4(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i32* %b, i64 %idx2 ; <i32*> [#uses=1]
|
||||
%c = load i32* %ptr
|
||||
%d = xor i32 %a, %c
|
||||
ret i32 %d
|
||||
}
|
||||
|
||||
define signext i64 @foo12(i64 %a, i64 *%b, i64 %idx) {
|
||||
; CHECK: foo12:
|
||||
; CHECK: xg %r2, 8(%r1,%r3)
|
||||
entry:
|
||||
%idx2 = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%ptr = getelementptr i64* %b, i64 %idx2 ; <i64*> [#uses=1]
|
||||
%c = load i64* %ptr
|
||||
%d = xor i64 %a, %c
|
||||
ret i64 %d
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = add i64 %a, %b
|
||||
ret i64 %c
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = add i64 %a, 1
|
||||
ret i64 %c
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = and i64 %a, %b
|
||||
ret i64 %c
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ngr | count 4
|
||||
; RUN: llc < %s -march=systemz | grep llilh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llihl | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llihh | count 1
|
||||
|
||||
define i64 @foo1(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = and i64 %a, 1
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo2(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = and i64 %a, 131072
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo3(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = and i64 %a, 8589934592
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo4(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = and i64 %a, 562949953421312
|
||||
ret i64 %c
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep lcgr | count 1
|
||||
|
||||
define i64 @foo(i64 %a) {
|
||||
entry:
|
||||
%c = sub i64 0, %a
|
||||
ret i64 %c
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = or i64 %a, %b
|
||||
ret i64 %c
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep oill | count 1
|
||||
; RUN: llc < %s -march=systemz | grep oilh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep oihl | count 1
|
||||
; RUN: llc < %s -march=systemz | grep oihh | count 1
|
||||
|
||||
define i64 @foo1(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = or i64 %a, 1
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo2(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = or i64 %a, 131072
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo3(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = or i64 %a, 8589934592
|
||||
ret i64 %c
|
||||
}
|
||||
|
||||
define i64 @foo4(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = or i64 %a, 562949953421312
|
||||
ret i64 %c
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = sub i64 %a, %b
|
||||
ret i64 %c
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = sub i64 %a, 1
|
||||
ret i64 %c
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = xor i64 %a, %b
|
||||
ret i64 %c
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz
|
||||
define i64 @foo(i64 %a, i64 %b) {
|
||||
entry:
|
||||
%c = xor i64 %a, 1
|
||||
ret i64 %c
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ahi | count 3
|
||||
; RUN: llc < %s -march=systemz | grep afi | count 3
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 4
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 2
|
||||
|
||||
|
||||
define i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo4(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo5(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ar | count 3
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 2
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 1
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = add i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ngr | count 6
|
||||
|
||||
define i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo4(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo5(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ngr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep nihf | count 1
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = and i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep lgr | count 2
|
||||
; RUN: llc < %s -march=systemz | grep nihf | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 1
|
||||
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
ret i32 %b
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep lghi | count 2
|
||||
; RUN: llc < %s -march=systemz | grep llill | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llilh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfi | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llilf | count 2
|
||||
|
||||
|
||||
define i32 @foo1() {
|
||||
entry:
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
define i32 @foo2() {
|
||||
entry:
|
||||
ret i32 65535
|
||||
}
|
||||
|
||||
define i32 @foo3() {
|
||||
entry:
|
||||
ret i32 131072
|
||||
}
|
||||
|
||||
define i32 @foo4() {
|
||||
entry:
|
||||
ret i32 65537
|
||||
}
|
||||
|
||||
define i32 @foo5() {
|
||||
entry:
|
||||
ret i32 4294967295
|
||||
}
|
||||
|
||||
define zeroext i32 @foo6() {
|
||||
entry:
|
||||
ret i32 4294967295
|
||||
}
|
||||
|
||||
define signext i32 @foo7() {
|
||||
entry:
|
||||
ret i32 4294967295
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep lcr | count 1
|
||||
|
||||
define i32 @foo(i32 %a) {
|
||||
entry:
|
||||
%c = sub i32 0, %a
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep oill | count 3
|
||||
; RUN: llc < %s -march=systemz | grep oilh | count 3
|
||||
; RUN: llc < %s -march=systemz | grep oilf | count 3
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 6
|
||||
|
||||
define i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo7(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo8(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo4(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo5(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo9(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ogr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep nihf | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 1
|
||||
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = or i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep ahi | count 3
|
||||
; RUN: llc < %s -march=systemz | grep afi | count 3
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 4
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 2
|
||||
|
||||
|
||||
define i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo4(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo5(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep sr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 2
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = sub i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep xilf | count 9
|
||||
; RUN: llc < %s -march=systemz | grep llgfr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 6
|
||||
|
||||
define i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define i32 @foo7(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo3(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo8(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo4(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo5(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 1
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 131072
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo9(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, 123456
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep xgr | count 3
|
||||
; RUN: llc < %s -march=systemz | grep nihf | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgfr | count 1
|
||||
|
||||
|
||||
define i32 @foo(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define zeroext i32 @foo1(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %b) {
|
||||
entry:
|
||||
%c = xor i32 %a, %b
|
||||
ret i32 %c
|
||||
}
|
||||
|
@ -1,121 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep sra | count 6
|
||||
; RUN: llc < %s -march=systemz | grep srag | count 3
|
||||
; RUN: llc < %s -march=systemz | grep srl | count 6
|
||||
; RUN: llc < %s -march=systemz | grep srlg | count 3
|
||||
; RUN: llc < %s -march=systemz | grep sll | count 6
|
||||
; RUN: llc < %s -march=systemz | grep sllg | count 3
|
||||
|
||||
define signext i32 @foo1(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i32 %idx, 1 ; <i32> [#uses=1]
|
||||
%shr = ashr i32 %a, %add ; <i32> [#uses=1]
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo2(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i32 %idx, 1 ; <i32> [#uses=1]
|
||||
%shr = shl i32 %a, %add ; <i32> [#uses=1]
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo3(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i32 %idx, 1 ; <i32> [#uses=1]
|
||||
%shr = lshr i32 %a, %add ; <i32> [#uses=1]
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo4(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%shr = ashr i64 %a, %add ; <i64> [#uses=1]
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo5(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%shr = shl i64 %a, %add ; <i64> [#uses=1]
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo6(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%shr = lshr i64 %a, %add ; <i64> [#uses=1]
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo7(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = ashr i32 %a, 1
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo8(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = shl i32 %a, 1
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo9(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = lshr i32 %a, 1
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo10(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = ashr i32 %a, %idx
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo11(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = shl i32 %a, %idx
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i32 @foo12(i32 %a, i32 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = lshr i32 %a, %idx
|
||||
ret i32 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo13(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = ashr i64 %a, 1
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo14(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = shl i64 %a, 1
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo15(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = lshr i64 %a, 1
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo16(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = ashr i64 %a, %idx
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo17(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = shl i64 %a, %idx
|
||||
ret i64 %shr
|
||||
}
|
||||
|
||||
define signext i64 @foo18(i64 %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%shr = lshr i64 %a, %idx
|
||||
ret i64 %shr
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
; RUN: llc < %s | grep lay | count 1
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64* @foo(i64* %a, i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; <i64*> [#uses=1]
|
||||
ret i64* %add.ptr2
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
; RUN: llc < %s -mattr=+z10 | grep mvghi | count 1
|
||||
; RUN: llc < %s -mattr=+z10 | grep mvhi | count 1
|
||||
; RUN: llc < %s -mattr=+z10 | grep mvhhi | count 1
|
||||
; RUN: llc < %s | grep mvi | count 2
|
||||
; RUN: llc < %s | grep mviy | count 1
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo1(i64* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i64* %a, i64 1 ; <i64*> [#uses=1]
|
||||
store i64 1, i64* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i32* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i32* %a, i64 1 ; <i32*> [#uses=1]
|
||||
store i32 2, i32* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i16* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %a, i64 1 ; <i16*> [#uses=1]
|
||||
store i16 3, i16* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i8* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i8* %a, i64 1 ; <i8*> [#uses=1]
|
||||
store i8 4, i8* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i8* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i8* %a, i64 -1 ; <i8*> [#uses=1]
|
||||
store i8 4, i8* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i16* nocapture %a, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %a, i64 -1 ; <i16*> [#uses=1]
|
||||
store i16 3, i16* %add.ptr
|
||||
ret void
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
; RUN: llc < %s | grep ly | count 2
|
||||
; RUN: llc < %s | grep sty | count 2
|
||||
; RUN: llc < %s | grep {l %} | count 2
|
||||
; RUN: llc < %s | grep {st %} | count 2
|
||||
|
||||
target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
|
||||
target triple = "s390x-ibm-linux"
|
||||
|
||||
define void @foo1(i32* nocapture %foo, i32* nocapture %bar) nounwind {
|
||||
entry:
|
||||
%tmp1 = load i32* %foo ; <i32> [#uses=1]
|
||||
store i32 %tmp1, i32* %bar
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i32* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i32* %foo, i64 1 ; <i32*> [#uses=1]
|
||||
%tmp1 = load i32* %add.ptr ; <i32> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i32* %bar, i64 %add.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %tmp1, i32* %add.ptr5
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i32* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%sub.ptr = getelementptr i32* %foo, i64 -1 ; <i32*> [#uses=1]
|
||||
%tmp1 = load i32* %sub.ptr ; <i32> [#uses=1]
|
||||
%sub.ptr3.sum = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%add.ptr = getelementptr i32* %bar, i64 %sub.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %tmp1, i32* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i32* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i32* %foo, i64 8192 ; <i32*> [#uses=1]
|
||||
%tmp1 = load i32* %add.ptr ; <i32> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 8192 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i32* %bar, i64 %add.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %tmp1, i32* %add.ptr5
|
||||
ret void
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
; RUN: llc < %s | grep {sthy.%} | count 2
|
||||
; RUN: llc < %s | grep {lhy.%} | count 2
|
||||
; RUN: llc < %s | grep {lh.%} | count 6
|
||||
; RUN: llc < %s | grep {sth.%} | count 2
|
||||
|
||||
target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
|
||||
target triple = "s390x-ibm-linux"
|
||||
|
||||
define void @foo1(i16* nocapture %foo, i16* nocapture %bar) nounwind {
|
||||
entry:
|
||||
%tmp1 = load i16* %foo ; <i16> [#uses=1]
|
||||
store i16 %tmp1, i16* %bar
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i16* nocapture %foo, i16* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %foo, i64 1 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %add.ptr ; <i16> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i16* %bar, i64 %add.ptr3.sum ; <i16*> [#uses=1]
|
||||
store i16 %tmp1, i16* %add.ptr5
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i16* nocapture %foo, i16* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%sub.ptr = getelementptr i16* %foo, i64 -1 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %sub.ptr ; <i16> [#uses=1]
|
||||
%sub.ptr3.sum = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%add.ptr = getelementptr i16* %bar, i64 %sub.ptr3.sum ; <i16*> [#uses=1]
|
||||
store i16 %tmp1, i16* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i16* nocapture %foo, i16* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %foo, i64 8192 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %add.ptr ; <i16> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 8192 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i16* %bar, i64 %add.ptr3.sum ; <i16*> [#uses=1]
|
||||
store i16 %tmp1, i16* %add.ptr5
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i16* nocapture %foo, i32* nocapture %bar) nounwind {
|
||||
entry:
|
||||
%tmp1 = load i16* %foo ; <i16> [#uses=1]
|
||||
%conv = sext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||
store i32 %conv, i32* %bar
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i16* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %foo, i64 1 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %add.ptr ; <i16> [#uses=1]
|
||||
%conv = sext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i32* %bar, i64 %add.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %conv, i32* %add.ptr5
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i16* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%sub.ptr = getelementptr i16* %foo, i64 -1 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %sub.ptr ; <i16> [#uses=1]
|
||||
%conv = sext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||
%sub.ptr3.sum = add i64 %idx, -1 ; <i64> [#uses=1]
|
||||
%add.ptr = getelementptr i32* %bar, i64 %sub.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %conv, i32* %add.ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo8(i16* nocapture %foo, i32* nocapture %bar, i64 %idx) nounwind {
|
||||
entry:
|
||||
%add.ptr = getelementptr i16* %foo, i64 8192 ; <i16*> [#uses=1]
|
||||
%tmp1 = load i16* %add.ptr ; <i16> [#uses=1]
|
||||
%conv = sext i16 %tmp1 to i32 ; <i32> [#uses=1]
|
||||
%add.ptr3.sum = add i64 %idx, 8192 ; <i64> [#uses=1]
|
||||
%add.ptr5 = getelementptr i32* %bar, i64 %add.ptr3.sum ; <i32*> [#uses=1]
|
||||
store i32 %conv, i32* %add.ptr5
|
||||
ret void
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | not grep aghi
|
||||
; RUN: llc < %s -march=systemz | grep llgf | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llgh | count 1
|
||||
; RUN: llc < %s -march=systemz | grep llgc | count 1
|
||||
; RUN: llc < %s -march=systemz | grep lgf | count 2
|
||||
; RUN: llc < %s -march=systemz | grep lgh | count 2
|
||||
; RUN: llc < %s -march=systemz | grep lgb | count 1
|
||||
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define zeroext i64 @foo1(i64* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; <i64*> [#uses=1]
|
||||
%tmp3 = load i64* %add.ptr2 ; <i64> [#uses=1]
|
||||
ret i64 %tmp3
|
||||
}
|
||||
|
||||
define zeroext i32 @foo2(i32* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; <i32*> [#uses=1]
|
||||
%tmp3 = load i32* %add.ptr2 ; <i32> [#uses=1]
|
||||
ret i32 %tmp3
|
||||
}
|
||||
|
||||
define zeroext i16 @foo3(i16* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; <i16*> [#uses=1]
|
||||
%tmp3 = load i16* %add.ptr2 ; <i16> [#uses=1]
|
||||
ret i16 %tmp3
|
||||
}
|
||||
|
||||
define zeroext i8 @foo4(i8* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; <i8*> [#uses=1]
|
||||
%tmp3 = load i8* %add.ptr2 ; <i8> [#uses=1]
|
||||
ret i8 %tmp3
|
||||
}
|
||||
|
||||
define signext i64 @foo5(i64* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; <i64*> [#uses=1]
|
||||
%tmp3 = load i64* %add.ptr2 ; <i64> [#uses=1]
|
||||
ret i64 %tmp3
|
||||
}
|
||||
|
||||
define signext i32 @foo6(i32* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; <i32*> [#uses=1]
|
||||
%tmp3 = load i32* %add.ptr2 ; <i32> [#uses=1]
|
||||
ret i32 %tmp3
|
||||
}
|
||||
|
||||
define signext i16 @foo7(i16* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; <i16*> [#uses=1]
|
||||
%tmp3 = load i16* %add.ptr2 ; <i16> [#uses=1]
|
||||
ret i16 %tmp3
|
||||
}
|
||||
|
||||
define signext i8 @foo8(i8* nocapture %a, i64 %idx) nounwind readonly {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; <i8*> [#uses=1]
|
||||
%tmp3 = load i8* %add.ptr2 ; <i8> [#uses=1]
|
||||
ret i8 %tmp3
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
; RUN: llc < %s | not grep aghi
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo1(i64* nocapture %a, i64 %idx, i64 %val) nounwind {
|
||||
entry:
|
||||
|
||||
; CHECK: foo1:
|
||||
; CHECK: stg %r4, 8(%r1,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; <i64*> [#uses=1]
|
||||
store i64 %val, i64* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i32* nocapture %a, i64 %idx, i32 %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo2:
|
||||
; CHECK: st %r4, 4(%r1,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; <i32*> [#uses=1]
|
||||
store i32 %val, i32* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i16* nocapture %a, i64 %idx, i16 zeroext %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo3:
|
||||
; CHECK: sth %r4, 2(%r1,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; <i16*> [#uses=1]
|
||||
store i16 %val, i16* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i8* nocapture %a, i64 %idx, i8 zeroext %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo4:
|
||||
; CHECK: stc %r4, 1(%r3,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; <i8*> [#uses=1]
|
||||
store i8 %val, i8* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i8* nocapture %a, i64 %idx, i64 %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo5:
|
||||
; CHECK: stc %r4, 1(%r3,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; <i8*> [#uses=1]
|
||||
%conv = trunc i64 %val to i8 ; <i8> [#uses=1]
|
||||
store i8 %conv, i8* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i16* nocapture %a, i64 %idx, i64 %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo6:
|
||||
; CHECK: sth %r4, 2(%r1,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; <i16*> [#uses=1]
|
||||
%conv = trunc i64 %val to i16 ; <i16> [#uses=1]
|
||||
store i16 %conv, i16* %add.ptr2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i32* nocapture %a, i64 %idx, i64 %val) nounwind {
|
||||
entry:
|
||||
; CHECK: foo7:
|
||||
; CHECK: st %r4, 4(%r1,%r2)
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; <i32*> [#uses=1]
|
||||
%conv = trunc i64 %val to i32 ; <i32> [#uses=1]
|
||||
store i32 %conv, i32* %add.ptr2
|
||||
ret void
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
; RUN: llc < %s | grep 168 | count 1
|
||||
; RUN: llc < %s | grep 160 | count 3
|
||||
; RUN: llc < %s | grep 328 | count 1
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @foo(i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64 %g) nounwind {
|
||||
entry:
|
||||
%a = alloca i64, align 8 ; <i64*> [#uses=3]
|
||||
store i64 %g, i64* %a
|
||||
call void @bar(i64* %a) nounwind
|
||||
%tmp1 = load i64* %a ; <i64> [#uses=1]
|
||||
ret i64 %tmp1
|
||||
}
|
||||
|
||||
declare void @bar(i64*)
|
@ -1,16 +0,0 @@
|
||||
; RUN: llc < %s | grep 160 | count 1
|
||||
; RUN: llc < %s | grep 168 | count 1
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64* %g) nounwind readnone {
|
||||
entry:
|
||||
ret i64 %f
|
||||
}
|
||||
|
||||
define i64 @bar(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f, i64* %g) nounwind readnone {
|
||||
entry:
|
||||
%conv = ptrtoint i64* %g to i64 ; <i64> [#uses=1]
|
||||
ret i64 %conv
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
; RUN: llc < %s | grep 160 | count 1
|
||||
; RUN: llc < %s | grep 328 | count 1
|
||||
; RUN: llc < %s | grep 168 | count 1
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define noalias i64* @foo(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e, i64 %f) nounwind readnone {
|
||||
entry:
|
||||
%g = alloca i64, align 8 ; <i64*> [#uses=1]
|
||||
%add.ptr = getelementptr i64* %g, i64 %f ; <i64*> [#uses=1]
|
||||
ret i64* %add.ptr
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
; RUN: llc < %s
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo() nounwind {
|
||||
entry:
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
@ -1,141 +0,0 @@
|
||||
; RUN: llc < %s | grep je | count 1
|
||||
; RUN: llc < %s | grep jne | count 1
|
||||
; RUN: llc < %s | grep jhe | count 2
|
||||
; RUN: llc < %s | grep jle | count 2
|
||||
; RUN: llc < %s | grep jh | count 4
|
||||
; RUN: llc < %s | grep jl | count 4
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ult i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define void @foo1(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ult i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo8(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo9(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i64 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
; RUN: llc < %s | grep je | count 1
|
||||
; RUN: llc < %s | grep jne | count 1
|
||||
; RUN: llc < %s | grep jhe | count 2
|
||||
; RUN: llc < %s | grep jle | count 2
|
||||
; RUN: llc < %s | grep jh | count 4
|
||||
; RUN: llc < %s | grep jl | count 4
|
||||
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define void @foo1(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ult i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo8(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo9(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, %b ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
; RUN: llc < %s
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-ibm-linux"
|
||||
|
||||
define void @foo() noreturn nounwind {
|
||||
entry:
|
||||
tail call void @baz() nounwind
|
||||
br label %l1
|
||||
|
||||
l1: ; preds = %entry, %l1
|
||||
tail call void @bar() nounwind
|
||||
br label %l1
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
declare void @baz()
|
@ -1,137 +0,0 @@
|
||||
; RUN: llc < %s | grep cgfi | count 8
|
||||
; RUN: llc < %s | grep clgfi | count 2
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define void @foo1(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo8(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo9(i64 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i64 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
; RUN: llc < %s | grep jl | count 3
|
||||
; RUN: llc < %s | grep jh | count 3
|
||||
; RUN: llc < %s | grep je | count 2
|
||||
; RUN: llc < %s | grep jne | count 2
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define void @foo(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
||||
|
||||
define void @foo1(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2(i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp = icmp ugt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, 0 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo4(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo5(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp eq i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo6(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo7(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo8(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp sgt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo9(i32 %a) nounwind {
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, 1 ; <i1> [#uses=1]
|
||||
br i1 %cmp, label %if.end, label %if.then
|
||||
|
||||
if.then: ; preds = %entry
|
||||
tail call void @bar() nounwind
|
||||
ret void
|
||||
|
||||
if.end: ; preds = %entry
|
||||
ret void
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
; RUN: llc < %s | grep clgr
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%cmp = icmp ult i64 %a, %b ; <i1> [#uses=1]
|
||||
%cond = select i1 %cmp, i64 %a, i64 %b ; <i64> [#uses=1]
|
||||
ret i64 %cond
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
; RUN: llc < %s | grep dsgr | count 2
|
||||
; RUN: llc < %s | grep dsgfr | count 2
|
||||
; RUN: llc < %s | grep dlr | count 2
|
||||
; RUN: llc < %s | grep dlgr | count 2
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @div(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = sdiv i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i32 @div1(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = sdiv i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i64 @div2(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = udiv i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i32 @div3(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%div = udiv i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i64 @rem(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = srem i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %rem
|
||||
}
|
||||
|
||||
define i32 @rem1(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = srem i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %rem
|
||||
}
|
||||
|
||||
define i64 @rem2(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = urem i64 %a, %b ; <i64> [#uses=1]
|
||||
ret i64 %rem
|
||||
}
|
||||
|
||||
define i32 @rem3(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%rem = urem i32 %a, %b ; <i32> [#uses=1]
|
||||
ret i32 %rem
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
; RUN: llc < %s | grep {dsgf.%} | count 2
|
||||
; RUN: llc < %s | grep {dsg.%} | count 2
|
||||
; RUN: llc < %s | grep {dl.%} | count 2
|
||||
; RUN: llc < %s | grep dlg | count 2
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @div(i64 %a, i64* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i64* %b
|
||||
%div = sdiv i64 %a, %b1
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i64 @div1(i64 %a, i64* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i64* %b
|
||||
%div = udiv i64 %a, %b1
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i64 @rem(i64 %a, i64* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i64* %b
|
||||
%div = srem i64 %a, %b1
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i64 @rem1(i64 %a, i64* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i64* %b
|
||||
%div = urem i64 %a, %b1
|
||||
ret i64 %div
|
||||
}
|
||||
|
||||
define i32 @div2(i32 %a, i32* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i32* %b
|
||||
%div = sdiv i32 %a, %b1
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i32 @div3(i32 %a, i32* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i32* %b
|
||||
%div = udiv i32 %a, %b1
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i32 @rem2(i32 %a, i32* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i32* %b
|
||||
%div = srem i32 %a, %b1
|
||||
ret i32 %div
|
||||
}
|
||||
|
||||
define i32 @rem3(i32 %a, i32* %b) nounwind readnone {
|
||||
entry:
|
||||
%b1 = load i32* %b
|
||||
%div = urem i32 %a, %b1
|
||||
ret i32 %div
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
; RUN: llc < %s | grep msgr | count 2
|
||||
; RUN: llc < %s | grep msr | count 2
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-unknown-linux-gnu"
|
||||
|
||||
define i64 @foo(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%mul = mul i64 %b, %a ; <i64> [#uses=1]
|
||||
ret i64 %mul
|
||||
}
|
||||
|
||||
define i64 @foo2(i64 %a, i64 %b) nounwind readnone {
|
||||
entry:
|
||||
%mul = mul i64 %b, %a ; <i64> [#uses=1]
|
||||
ret i64 %mul
|
||||
}
|
||||
|
||||
define i32 @foo3(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%mul = mul i32 %b, %a ; <i32> [#uses=1]
|
||||
ret i32 %mul
|
||||
}
|
||||
|
||||
define i32 @foo4(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
%mul = mul i32 %b, %a ; <i32> [#uses=1]
|
||||
ret i32 %mul
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
; RUN: llc < %s
|
||||
|
||||
target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
|
||||
target triple = "s390x-ibm-linux"
|
||||
|
||||
define void @foo(i64 %N) nounwind {
|
||||
entry:
|
||||
%N3 = trunc i64 %N to i32 ; <i32> [#uses=1]
|
||||
%vla = alloca i8, i32 %N3, align 2 ; <i8*> [#uses=1]
|
||||
call void @bar(i8* %vla) nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar(i8*)
|
@ -1,23 +0,0 @@
|
||||
; RUN: llc < %s | grep larl | count 3
|
||||
|
||||
target 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"
|
||||
target triple = "s390x-ibm-linux"
|
||||
@bar = common global i64 0, align 8 ; <i64*> [#uses=3]
|
||||
|
||||
define i64 @foo() nounwind readonly {
|
||||
entry:
|
||||
%tmp = load i64* @bar ; <i64> [#uses=1]
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
||||
define i64* @foo2() nounwind readnone {
|
||||
entry:
|
||||
ret i64* @bar
|
||||
}
|
||||
|
||||
define i64* @foo3(i64 %idx) nounwind readnone {
|
||||
entry:
|
||||
%add.ptr.sum = add i64 %idx, 1 ; <i64> [#uses=1]
|
||||
%add.ptr2 = getelementptr i64* @bar, i64 %add.ptr.sum ; <i64*> [#uses=1]
|
||||
ret i64* %add.ptr2
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
; RUN: llc < %s -march=systemz | grep larl
|
||||
|
||||
define i32 @main(i32 %tmp158) {
|
||||
entry:
|
||||
switch i32 %tmp158, label %bb336 [
|
||||
i32 -2147483648, label %bb338
|
||||
i32 -2147483647, label %bb338
|
||||
i32 -2147483646, label %bb338
|
||||
i32 120, label %bb338
|
||||
i32 121, label %bb339
|
||||
i32 122, label %bb340
|
||||
i32 123, label %bb341
|
||||
i32 124, label %bb342
|
||||
i32 125, label %bb343
|
||||
i32 126, label %bb336
|
||||
i32 1024, label %bb338
|
||||
i32 0, label %bb338
|
||||
i32 1, label %bb338
|
||||
i32 2, label %bb338
|
||||
i32 3, label %bb338
|
||||
i32 4, label %bb338
|
||||
i32 5, label %bb338
|
||||
]
|
||||
bb336:
|
||||
ret i32 10
|
||||
bb338:
|
||||
ret i32 11
|
||||
bb339:
|
||||
ret i32 12
|
||||
bb340:
|
||||
ret i32 13
|
||||
bb341:
|
||||
ret i32 14
|
||||
bb342:
|
||||
ret i32 15
|
||||
bb343:
|
||||
ret i32 18
|
||||
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
; RUN: llc < %s -relocation-model=pic | grep GOTENT | count 3
|
||||
; RUN: llc < %s -relocation-model=pic | grep PLT | count 1
|
||||
|
||||
target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
|
||||
target triple = "s390x-ibm-linux"
|
||||
@ptr = external global void (...)* ; <void (...)**> [#uses=2]
|
||||
|
||||
define void @foo1() nounwind {
|
||||
entry:
|
||||
store void (...)* @func, void (...)** @ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @func(...)
|
||||
|
||||
define void @foo2() nounwind {
|
||||
entry:
|
||||
tail call void (...)* @func() nounwind
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3() nounwind {
|
||||
entry:
|
||||
%tmp = load void (...)** @ptr ; <void (...)*> [#uses=1]
|
||||
tail call void (...)* %tmp() nounwind
|
||||
ret void
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
; RUN: llc < %s -relocation-model=pic | grep GOTENT | count 6
|
||||
|
||||
target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
|
||||
target triple = "s390x-ibm-linux"
|
||||
@src = external global i32 ; <i32*> [#uses=2]
|
||||
@dst = external global i32 ; <i32*> [#uses=2]
|
||||
@ptr = external global i32* ; <i32**> [#uses=2]
|
||||
|
||||
define void @foo1() nounwind {
|
||||
entry:
|
||||
%tmp = load i32* @src ; <i32> [#uses=1]
|
||||
store i32 %tmp, i32* @dst
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo2() nounwind {
|
||||
entry:
|
||||
store i32* @dst, i32** @ptr
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @foo3() nounwind {
|
||||
entry:
|
||||
%tmp = load i32* @src ; <i32> [#uses=1]
|
||||
%tmp1 = load i32** @ptr ; <i32*> [#uses=1]
|
||||
%arrayidx = getelementptr i32* %tmp1, i64 1 ; <i32*> [#uses=1]
|
||||
store i32 %tmp, i32* %arrayidx
|
||||
ret void
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user