mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Remove the Alpha backend.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143164 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
03e03b0984
commit
33ba8b0e96
@ -64,7 +64,6 @@ Please clean the source directory.")
|
||||
endif()
|
||||
|
||||
set(LLVM_ALL_TARGETS
|
||||
Alpha
|
||||
ARM
|
||||
CBackend
|
||||
CellSPU
|
||||
|
@ -352,7 +352,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
|
||||
sparc*-*) llvm_cv_target_arch="Sparc" ;;
|
||||
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
|
||||
alpha*-*) llvm_cv_target_arch="Alpha" ;;
|
||||
arm*-*) llvm_cv_target_arch="ARM" ;;
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
@ -487,7 +486,6 @@ else
|
||||
Sparc) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PowerPC) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
@ -603,21 +601,20 @@ dnl Allow specific targets to be specified for building (or not)
|
||||
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,
|
||||
host, x86, x86_64, sparc, powerpc, arm, mips, spu,
|
||||
xcore, msp430, 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 CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 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" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
@ -632,7 +629,6 @@ case "$enableval" in
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -309,8 +309,6 @@ elseif (LLVM_NATIVE_ARCH MATCHES "sparc")
|
||||
set(LLVM_NATIVE_ARCH Sparc)
|
||||
elseif (LLVM_NATIVE_ARCH MATCHES "powerpc")
|
||||
set(LLVM_NATIVE_ARCH PowerPC)
|
||||
elseif (LLVM_NATIVE_ARCH MATCHES "alpha")
|
||||
set(LLVM_NATIVE_ARCH Alpha)
|
||||
elseif (LLVM_NATIVE_ARCH MATCHES "arm")
|
||||
set(LLVM_NATIVE_ARCH ARM)
|
||||
elseif (LLVM_NATIVE_ARCH MATCHES "mips")
|
||||
|
9
configure
vendored
9
configure
vendored
@ -1415,7 +1415,7 @@ Optional Features:
|
||||
(default is YES)
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
x86_64, sparc, powerpc, arm, mips, spu,
|
||||
xcore, msp430, ptx, cbe, and cpp (default=all)
|
||||
--enable-cbe-printf-a Enable C Backend output with hex floating point via
|
||||
%a (default is YES)
|
||||
@ -3874,7 +3874,6 @@ else
|
||||
amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
|
||||
sparc*-*) llvm_cv_target_arch="Sparc" ;;
|
||||
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
|
||||
alpha*-*) llvm_cv_target_arch="Alpha" ;;
|
||||
arm*-*) llvm_cv_target_arch="ARM" ;;
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
@ -5071,8 +5070,6 @@ else
|
||||
PowerPC) TARGET_HAS_JIT=1
|
||||
;;
|
||||
x86_64) TARGET_HAS_JIT=1
|
||||
;;
|
||||
Alpha) TARGET_HAS_JIT=0
|
||||
;;
|
||||
ARM) TARGET_HAS_JIT=1
|
||||
;;
|
||||
@ -5270,14 +5267,13 @@ 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 CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 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" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
@ -5292,7 +5288,6 @@ case "$enableval" in
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -249,7 +249,7 @@
|
||||
<dd>Semicolon-separated list of targets to build, or <i>all</i> for
|
||||
building all targets. Case-sensitive. For Visual C++ defaults
|
||||
to <i>X86</i>. On the other cases defaults to <i>all</i>. Example:
|
||||
<i>-DLLVM_TARGETS_TO_BUILD="X86;PowerPC;Alpha"</i>.</dd>
|
||||
<i>-DLLVM_TARGETS_TO_BUILD="X86;PowerPC"</i>.</dd>
|
||||
|
||||
<dt><b>LLVM_BUILD_TOOLS</b>:BOOL</dt>
|
||||
<dd>Build LLVM tools. Defaults to ON. Targets for building each tool
|
||||
|
@ -2208,7 +2208,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<th>Feature</th>
|
||||
<th>ARM</th>
|
||||
<th>Alpha</th>
|
||||
<th>CellSPU</th>
|
||||
<th>MBlaze</th>
|
||||
<th>MSP430</th>
|
||||
@ -2223,7 +2222,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_reliable">is generally reliable</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
@ -2238,7 +2236,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_asmparser">assembly parser</a></td>
|
||||
<td class="no"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
@ -2253,7 +2250,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_disassembler">disassembler</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
@ -2268,7 +2264,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_inlineasm">inline asm</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
@ -2283,7 +2278,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_jit">jit</a></td>
|
||||
<td class="partial"><a href="#feat_jit_arm">*</a></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
@ -2298,7 +2292,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_objectwrite">.o file writing</a></td>
|
||||
<td class="no"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
@ -2313,7 +2306,6 @@ is the key:</p>
|
||||
<tr>
|
||||
<td><a href="#feat_tailcall">tail calls</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
|
@ -21,7 +21,6 @@
|
||||
<ol>
|
||||
<li><a href="#hw">Hardware</a>
|
||||
<ol>
|
||||
<li><a href="#alpha">Alpha</a></li>
|
||||
<li><a href="#arm">ARM</a></li>
|
||||
<li><a href="#ia64">Itanium</a></li>
|
||||
<li><a href="#mips">MIPS</a></li>
|
||||
@ -48,17 +47,6 @@
|
||||
|
||||
<div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3><a name="alpha">Alpha</a></h3>
|
||||
|
||||
<div>
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html">Alpha manuals</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h3><a name="arm">ARM</a></h3>
|
||||
|
||||
|
@ -126,8 +126,6 @@
|
||||
<td>Aggressive instruction selector for directed acyclic graphs</td></tr>
|
||||
|
||||
<tr><th colspan="3">Target Libraries</th></tr>
|
||||
<tr><td>LLVMAlpha</td><td><tt>.o</tt></td>
|
||||
<td>Code generation for Alpha architecture</td></tr>
|
||||
<tr><td>LLVMARM</td><td><tt>.o</tt></td>
|
||||
<td>Code generation for ARM architecture</td></tr>
|
||||
<tr><td>LLVMCBackend</td><td><tt>.o</tt></td>
|
||||
@ -333,14 +331,6 @@
|
||||
<li>libLLVMSystem.a</li>
|
||||
<li>libLLVMTarget.a</li>
|
||||
</ul></dd>
|
||||
<dt><b>LLVMAlpha.o</b></dt><dd><ul>
|
||||
<li>libLLVMCodeGen.a</li>
|
||||
<li>libLLVMCore.a</li>
|
||||
<li>libLLVMSelectionDAG.a</li>
|
||||
<li>libLLVMSupport.a</li>
|
||||
<li>libLLVMSystem.a</li>
|
||||
<li>libLLVMTarget.a</li>
|
||||
</ul></dd>
|
||||
<dt><b>LLVMCBackend.o</b></dt><dd><ul>
|
||||
<li>libLLVMAnalysis.a</li>
|
||||
<li>libLLVMCodeGen.a</li>
|
||||
|
@ -43,7 +43,6 @@ public:
|
||||
enum ArchType {
|
||||
UnknownArch,
|
||||
|
||||
alpha, // Alpha: alpha
|
||||
arm, // ARM; arm, armv.*, xscale
|
||||
cellspu, // CellSPU: spu, cellspu
|
||||
mips, // MIPS: mips, mipsallegrex
|
||||
|
@ -443,6 +443,5 @@ include "llvm/IntrinsicsPowerPC.td"
|
||||
include "llvm/IntrinsicsX86.td"
|
||||
include "llvm/IntrinsicsARM.td"
|
||||
include "llvm/IntrinsicsCellSPU.td"
|
||||
include "llvm/IntrinsicsAlpha.td"
|
||||
include "llvm/IntrinsicsXCore.td"
|
||||
include "llvm/IntrinsicsPTX.td"
|
||||
|
@ -1,18 +0,0 @@
|
||||
//===- IntrinsicsAlpha.td - Defines Alpha intrinsics -------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines all of the Alpha-specific intrinsics.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
let TargetPrefix = "alpha" in { // All intrinsics start with "llvm.alpha.".
|
||||
def int_alpha_umulh : GCCBuiltin<"__builtin_alpha_umulh">,
|
||||
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
|
||||
}
|
@ -18,7 +18,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
||||
case InvalidArch: return "<invalid>";
|
||||
case UnknownArch: return "unknown";
|
||||
|
||||
case alpha: return "alpha";
|
||||
case arm: return "arm";
|
||||
case cellspu: return "cellspu";
|
||||
case mips: return "mips";
|
||||
@ -50,8 +49,6 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case alpha: return "alpha";
|
||||
|
||||
case arm:
|
||||
case thumb: return "arm";
|
||||
|
||||
@ -131,8 +128,6 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
|
||||
}
|
||||
|
||||
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
||||
if (Name == "alpha")
|
||||
return alpha;
|
||||
if (Name == "arm")
|
||||
return arm;
|
||||
if (Name == "cellspu")
|
||||
@ -286,8 +281,6 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
|
||||
else if (ArchName == "thumb" ||
|
||||
ArchName.startswith("thumbv"))
|
||||
return thumb;
|
||||
else if (ArchName.startswith("alpha"))
|
||||
return alpha;
|
||||
else if (ArchName == "spu" || ArchName == "cellspu")
|
||||
return cellspu;
|
||||
else if (ArchName == "msp430")
|
||||
|
@ -1,43 +0,0 @@
|
||||
//===-- Alpha.h - Top-level interface for Alpha 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
|
||||
// Alpha back-end.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TARGET_ALPHA_H
|
||||
#define TARGET_ALPHA_H
|
||||
|
||||
#include "MCTargetDesc/AlphaMCTargetDesc.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace Alpha {
|
||||
// These describe LDAx
|
||||
|
||||
static const int IMM_LOW = -32768;
|
||||
static const int IMM_HIGH = 32767;
|
||||
static const int IMM_MULT = 65536;
|
||||
}
|
||||
|
||||
class AlphaTargetMachine;
|
||||
class FunctionPass;
|
||||
class formatted_raw_ostream;
|
||||
|
||||
FunctionPass *createAlphaISelDag(AlphaTargetMachine &TM);
|
||||
FunctionPass *createAlphaPatternInstructionSelector(TargetMachine &TM);
|
||||
FunctionPass *createAlphaJITCodeEmitterPass(AlphaTargetMachine &TM,
|
||||
JITCodeEmitter &JCE);
|
||||
FunctionPass *createAlphaLLRPPass(AlphaTargetMachine &tm);
|
||||
FunctionPass *createAlphaBranchSelectionPass();
|
||||
|
||||
} // end namespace llvm;
|
||||
|
||||
#endif
|
@ -1,68 +0,0 @@
|
||||
//===- Alpha.td - Describe the Alpha Target Machine --------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Get the target-independent interfaces which we are implementing...
|
||||
//
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
//Alpha is little endian
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Subtarget Features
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def FeatureCIX : SubtargetFeature<"cix", "HasCT", "true",
|
||||
"Enable CIX extensions">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "AlphaRegisterInfo.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "AlphaCallingConv.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Schedule Description
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "AlphaSchedule.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Descriptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "AlphaInstrInfo.td"
|
||||
|
||||
def AlphaInstrInfo : InstrInfo;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Alpha Processor Definitions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def : Processor<"generic", Alpha21264Itineraries, []>;
|
||||
def : Processor<"ev6" , Alpha21264Itineraries, []>;
|
||||
def : Processor<"ev67" , Alpha21264Itineraries, [FeatureCIX]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// The Alpha Target
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
def Alpha : Target {
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = AlphaInstrInfo;
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
//===-- AlphaAsmPrinter.cpp - Alpha 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 GAS-format Alpha assembly language.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "Alpha.h"
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaTargetMachine.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
struct AlphaAsmPrinter : public AsmPrinter {
|
||||
/// Unique incrementer for label values for referencing Global values.
|
||||
///
|
||||
|
||||
explicit AlphaAsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
|
||||
: AsmPrinter(tm, Streamer) {}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Alpha Assembly Printer";
|
||||
}
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &O);
|
||||
void EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
void printOp(const MachineOperand &MO, raw_ostream &O);
|
||||
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
|
||||
virtual void EmitFunctionBodyStart();
|
||||
virtual void EmitFunctionBodyEnd();
|
||||
void EmitStartOfAsmFile(Module &M);
|
||||
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode,
|
||||
raw_ostream &O);
|
||||
bool PrintAsmMemoryOperand(const MachineInstr *MI,
|
||||
unsigned OpNo, unsigned AsmVariant,
|
||||
const char *ExtraCode, raw_ostream &O);
|
||||
};
|
||||
} // end of anonymous namespace
|
||||
|
||||
#include "AlphaGenAsmWriter.inc"
|
||||
|
||||
void AlphaAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
if (MO.isReg()) {
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
||||
"Not physreg??");
|
||||
O << getRegisterName(MO.getReg());
|
||||
} else if (MO.isImm()) {
|
||||
O << MO.getImm();
|
||||
assert(MO.getImm() < (1 << 30));
|
||||
} else {
|
||||
printOp(MO, O);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AlphaAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
O << getRegisterName(MO.getReg());
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_Immediate:
|
||||
assert(0 && "printOp() does not handle immediate values");
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
O << *MO.getMBB()->getSymbol();
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
|
||||
<< MO.getIndex();
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
O << MO.getSymbolName();
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
O << *Mang->getSymbol(MO.getGlobal());
|
||||
return;
|
||||
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
|
||||
<< '_' << MO.getIndex();
|
||||
return;
|
||||
|
||||
default:
|
||||
O << "<unknown operand type: " << MO.getType() << ">";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyStart - Targets can override this to emit stuff before
|
||||
/// the first basic block in the function.
|
||||
void AlphaAsmPrinter::EmitFunctionBodyStart() {
|
||||
OutStreamer.EmitRawText("\t.ent " + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
|
||||
/// the last basic block in the function.
|
||||
void AlphaAsmPrinter::EmitFunctionBodyEnd() {
|
||||
OutStreamer.EmitRawText("\t.end " + Twine(CurrentFnSym->getName()));
|
||||
}
|
||||
|
||||
void AlphaAsmPrinter::EmitStartOfAsmFile(Module &M) {
|
||||
OutStreamer.EmitRawText(StringRef("\t.arch ev6"));
|
||||
OutStreamer.EmitRawText(StringRef("\t.set noat"));
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
///
|
||||
bool AlphaAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant,
|
||||
const char *ExtraCode, raw_ostream &O) {
|
||||
printOperand(MI, OpNo, O);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AlphaAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
||||
unsigned OpNo, unsigned AsmVariant,
|
||||
const char *ExtraCode,
|
||||
raw_ostream &O) {
|
||||
if (ExtraCode && ExtraCode[0])
|
||||
return true; // Unknown modifier.
|
||||
O << "0(";
|
||||
printOperand(MI, OpNo, O);
|
||||
O << ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeAlphaAsmPrinter() {
|
||||
RegisterAsmPrinter<AlphaAsmPrinter> X(TheAlphaTarget);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
//===-- AlphaBranchSelector.cpp - Convert Pseudo branchs ----------*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Replace Pseudo COND_BRANCH_* with their appropriate real branch
|
||||
// Simplified version of the PPC Branch Selector
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
struct AlphaBSel : public MachineFunctionPass {
|
||||
static char ID;
|
||||
AlphaBSel() : MachineFunctionPass(ID) {}
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &Fn);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Alpha Branch Selection";
|
||||
}
|
||||
};
|
||||
char AlphaBSel::ID = 0;
|
||||
}
|
||||
|
||||
/// createAlphaBranchSelectionPass - returns an instance of the Branch Selection
|
||||
/// Pass
|
||||
///
|
||||
FunctionPass *llvm::createAlphaBranchSelectionPass() {
|
||||
return new AlphaBSel();
|
||||
}
|
||||
|
||||
bool AlphaBSel::runOnMachineFunction(MachineFunction &Fn) {
|
||||
|
||||
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
|
||||
++MFI) {
|
||||
MachineBasicBlock *MBB = MFI;
|
||||
|
||||
for (MachineBasicBlock::iterator MBBI = MBB->begin(), EE = MBB->end();
|
||||
MBBI != EE; ++MBBI) {
|
||||
if (MBBI->getOpcode() == Alpha::COND_BRANCH_I ||
|
||||
MBBI->getOpcode() == Alpha::COND_BRANCH_F) {
|
||||
|
||||
// condbranch operands:
|
||||
// 0. bc opcode
|
||||
// 1. reg
|
||||
// 2. target MBB
|
||||
const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
|
||||
MBBI->setDesc(TII->get(MBBI->getOperand(0).getImm()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
//===- AlphaCallingConv.td - Calling Conventions for Alpha -*- 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 Alpha architecture.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Alpha Return Value Calling Convention
|
||||
//===----------------------------------------------------------------------===//
|
||||
def RetCC_Alpha : CallingConv<[
|
||||
// i64 is returned in register R0
|
||||
// R1 is an llvm extension, I don't know what gcc does
|
||||
CCIfType<[i64], CCAssignToReg<[R0,R1]>>,
|
||||
|
||||
// f32 / f64 are returned in F0/F1
|
||||
CCIfType<[f32, f64], CCAssignToReg<[F0, F1]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Alpha Argument Calling Conventions
|
||||
//===----------------------------------------------------------------------===//
|
||||
def CC_Alpha : CallingConv<[
|
||||
// The first 6 arguments are passed in registers, whether integer or
|
||||
// floating-point
|
||||
CCIfType<[i64], CCAssignToRegWithShadow<[R16, R17, R18, R19, R20, R21],
|
||||
[F16, F17, F18, F19, F20, F21]>>,
|
||||
|
||||
CCIfType<[f32, f64], CCAssignToRegWithShadow<[F16, F17, F18, F19, F20, F21],
|
||||
[R16, R17, R18, R19, R20, R21]>>,
|
||||
|
||||
// Stack slots are 8 bytes in size and 8-byte aligned.
|
||||
CCIfType<[i64, f32, f64], CCAssignToStack<8, 8>>
|
||||
]>;
|
@ -1,143 +0,0 @@
|
||||
//=====- AlphaFrameLowering.cpp - Alpha 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 Alpha implementation of TargetFrameLowering class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AlphaFrameLowering.h"
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaMachineFunctionInfo.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static long getUpper16(long l) {
|
||||
long y = l / Alpha::IMM_MULT;
|
||||
if (l % Alpha::IMM_MULT > Alpha::IMM_HIGH)
|
||||
++y;
|
||||
return y;
|
||||
}
|
||||
|
||||
static long getLower16(long l) {
|
||||
long h = getUpper16(l);
|
||||
return l - h * Alpha::IMM_MULT;
|
||||
}
|
||||
|
||||
// hasFP - 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 AlphaFrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
return MFI->hasVarSizedObjects();
|
||||
}
|
||||
|
||||
void AlphaFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
|
||||
DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc());
|
||||
bool FP = hasFP(MF);
|
||||
|
||||
// Handle GOP offset
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAHg), Alpha::R29)
|
||||
.addGlobalAddress(MF.getFunction()).addReg(Alpha::R27).addImm(++curgpdist);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAg), Alpha::R29)
|
||||
.addGlobalAddress(MF.getFunction()).addReg(Alpha::R29).addImm(curgpdist);
|
||||
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::ALTENT))
|
||||
.addGlobalAddress(MF.getFunction());
|
||||
|
||||
// Get the number of bytes to allocate from the FrameInfo
|
||||
long NumBytes = MFI->getStackSize();
|
||||
|
||||
if (FP)
|
||||
NumBytes += 8; //reserve space for the old FP
|
||||
|
||||
// Do we need to allocate space on the stack?
|
||||
if (NumBytes == 0) return;
|
||||
|
||||
unsigned Align = getStackAlignment();
|
||||
NumBytes = (NumBytes+Align-1)/Align*Align;
|
||||
|
||||
// Update frame info to pretend that this is part of the stack...
|
||||
MFI->setStackSize(NumBytes);
|
||||
|
||||
// adjust stack pointer: r30 -= numbytes
|
||||
NumBytes = -NumBytes;
|
||||
if (NumBytes >= Alpha::IMM_LOW) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
|
||||
.addReg(Alpha::R30);
|
||||
} else if (getUpper16(NumBytes) >= Alpha::IMM_LOW) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30)
|
||||
.addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30)
|
||||
.addImm(getLower16(NumBytes)).addReg(Alpha::R30);
|
||||
} else {
|
||||
report_fatal_error("Too big a stack frame at " + Twine(NumBytes));
|
||||
}
|
||||
|
||||
// Now if we need to, save the old FP and set the new
|
||||
if (FP) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::STQ))
|
||||
.addReg(Alpha::R15).addImm(0).addReg(Alpha::R30);
|
||||
// This must be the last instr in the prolog
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R15)
|
||||
.addReg(Alpha::R30).addReg(Alpha::R30);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AlphaFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
||||
const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
|
||||
|
||||
assert((MBBI->getOpcode() == Alpha::RETDAG ||
|
||||
MBBI->getOpcode() == Alpha::RETDAGp)
|
||||
&& "Can only insert epilog into returning blocks");
|
||||
DebugLoc dl = MBBI->getDebugLoc();
|
||||
|
||||
bool FP = hasFP(MF);
|
||||
|
||||
// Get the number of bytes allocated from the FrameInfo...
|
||||
long NumBytes = MFI->getStackSize();
|
||||
|
||||
//now if we need to, restore the old FP
|
||||
if (FP) {
|
||||
//copy the FP into the SP (discards allocas)
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15)
|
||||
.addReg(Alpha::R15);
|
||||
//restore the FP
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDQ), Alpha::R15)
|
||||
.addImm(0).addReg(Alpha::R15);
|
||||
}
|
||||
|
||||
if (NumBytes != 0) {
|
||||
if (NumBytes <= Alpha::IMM_HIGH) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
|
||||
.addReg(Alpha::R30);
|
||||
} else if (getUpper16(NumBytes) <= Alpha::IMM_HIGH) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDAH), Alpha::R30)
|
||||
.addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(Alpha::LDA), Alpha::R30)
|
||||
.addImm(getLower16(NumBytes)).addReg(Alpha::R30);
|
||||
} else {
|
||||
report_fatal_error("Too big a stack frame at " + Twine(NumBytes));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
//==-- AlphaFrameLowering.h - Define frame lowering for Alpha --*- C++ -*---==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHA_FRAMEINFO_H
|
||||
#define ALPHA_FRAMEINFO_H
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaSubtarget.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
class AlphaSubtarget;
|
||||
|
||||
class AlphaFrameLowering : public TargetFrameLowering {
|
||||
const AlphaSubtarget &STI;
|
||||
// FIXME: This should end in MachineFunctionInfo, not here!
|
||||
mutable int curgpdist;
|
||||
public:
|
||||
explicit AlphaFrameLowering(const AlphaSubtarget &sti)
|
||||
: TargetFrameLowering(StackGrowsDown, 16, 0), STI(sti), curgpdist(0) {
|
||||
}
|
||||
|
||||
/// 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 hasFP(const MachineFunction &MF) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,425 +0,0 @@
|
||||
//===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines a pattern matching instruction selector for Alpha,
|
||||
// converting from a legalized dag to a Alpha dag.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaTargetMachine.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/GlobalValue.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
|
||||
/// instructions for SelectionDAG operations.
|
||||
class AlphaDAGToDAGISel : public SelectionDAGISel {
|
||||
static const int64_t IMM_LOW = -32768;
|
||||
static const int64_t IMM_HIGH = 32767;
|
||||
static const int64_t IMM_MULT = 65536;
|
||||
static const int64_t IMM_FULLHIGH = IMM_HIGH + IMM_HIGH * IMM_MULT;
|
||||
static const int64_t IMM_FULLLOW = IMM_LOW + IMM_LOW * IMM_MULT;
|
||||
|
||||
static int64_t get_ldah16(int64_t x) {
|
||||
int64_t y = x / IMM_MULT;
|
||||
if (x % IMM_MULT > IMM_HIGH)
|
||||
++y;
|
||||
return y;
|
||||
}
|
||||
|
||||
static int64_t get_lda16(int64_t x) {
|
||||
return x - get_ldah16(x) * IMM_MULT;
|
||||
}
|
||||
|
||||
/// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
|
||||
/// instruction (if not, return 0). Note that this code accepts partial
|
||||
/// zap masks. For example (and LHS, 1) is a valid zap, as long we know
|
||||
/// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
|
||||
/// in checking mode. If LHS is null, we assume that the mask has already
|
||||
/// been validated before.
|
||||
uint64_t get_zapImm(SDValue LHS, uint64_t Constant) const {
|
||||
uint64_t BitsToCheck = 0;
|
||||
unsigned Result = 0;
|
||||
for (unsigned i = 0; i != 8; ++i) {
|
||||
if (((Constant >> 8*i) & 0xFF) == 0) {
|
||||
// nothing to do.
|
||||
} else {
|
||||
Result |= 1 << i;
|
||||
if (((Constant >> 8*i) & 0xFF) == 0xFF) {
|
||||
// If the entire byte is set, zapnot the byte.
|
||||
} else if (LHS.getNode() == 0) {
|
||||
// Otherwise, if the mask was previously validated, we know its okay
|
||||
// to zapnot this entire byte even though all the bits aren't set.
|
||||
} else {
|
||||
// Otherwise we don't know that the it's okay to zapnot this entire
|
||||
// byte. Only do this iff we can prove that the missing bits are
|
||||
// already null, so the bytezap doesn't need to really null them.
|
||||
BitsToCheck |= ~Constant & (0xFFULL << 8*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are missing bits in a byte (for example, X & 0xEF00), check to
|
||||
// see if the missing bits (0x1000) are already known zero if not, the zap
|
||||
// isn't okay to do, as it won't clear all the required bits.
|
||||
if (BitsToCheck &&
|
||||
!CurDAG->MaskedValueIsZero(LHS,
|
||||
APInt(LHS.getValueSizeInBits(),
|
||||
BitsToCheck)))
|
||||
return 0;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
static uint64_t get_zapImm(uint64_t x) {
|
||||
unsigned build = 0;
|
||||
for(int i = 0; i != 8; ++i) {
|
||||
if ((x & 0x00FF) == 0x00FF)
|
||||
build |= 1 << i;
|
||||
else if ((x & 0x00FF) != 0)
|
||||
return 0;
|
||||
x >>= 8;
|
||||
}
|
||||
return build;
|
||||
}
|
||||
|
||||
|
||||
static uint64_t getNearPower2(uint64_t x) {
|
||||
if (!x) return 0;
|
||||
unsigned at = CountLeadingZeros_64(x);
|
||||
uint64_t complow = 1ULL << (63 - at);
|
||||
uint64_t comphigh = complow << 1;
|
||||
if (x - complow <= comphigh - x)
|
||||
return complow;
|
||||
else
|
||||
return comphigh;
|
||||
}
|
||||
|
||||
static bool chkRemNearPower2(uint64_t x, uint64_t r, bool swap) {
|
||||
uint64_t y = getNearPower2(x);
|
||||
if (swap)
|
||||
return (y - x) == r;
|
||||
else
|
||||
return (x - y) == r;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit AlphaDAGToDAGISel(AlphaTargetMachine &TM)
|
||||
: SelectionDAGISel(TM)
|
||||
{}
|
||||
|
||||
/// getI64Imm - Return a target constant with the specified value, of type
|
||||
/// i64.
|
||||
inline SDValue getI64Imm(int64_t Imm) {
|
||||
return CurDAG->getTargetConstant(Imm, MVT::i64);
|
||||
}
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDNode *Select(SDNode *N);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Alpha DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
|
||||
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
|
||||
/// inline asm expressions.
|
||||
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
|
||||
char ConstraintCode,
|
||||
std::vector<SDValue> &OutOps) {
|
||||
SDValue Op0;
|
||||
switch (ConstraintCode) {
|
||||
default: return true;
|
||||
case 'm': // memory
|
||||
Op0 = Op;
|
||||
break;
|
||||
}
|
||||
|
||||
OutOps.push_back(Op0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "AlphaGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
/// getTargetMachine - Return a reference to the TargetMachine, casted
|
||||
/// to the target-specific type.
|
||||
const AlphaTargetMachine &getTargetMachine() {
|
||||
return static_cast<const AlphaTargetMachine &>(TM);
|
||||
}
|
||||
|
||||
/// getInstrInfo - Return a reference to the TargetInstrInfo, casted
|
||||
/// to the target-specific type.
|
||||
const AlphaInstrInfo *getInstrInfo() {
|
||||
return getTargetMachine().getInstrInfo();
|
||||
}
|
||||
|
||||
SDNode *getGlobalBaseReg();
|
||||
SDNode *getGlobalRetAddr();
|
||||
void SelectCALL(SDNode *Op);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/// getGlobalBaseReg - Output the instructions required to put the
|
||||
/// GOT address into a register.
|
||||
///
|
||||
SDNode *AlphaDAGToDAGISel::getGlobalBaseReg() {
|
||||
unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
|
||||
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
|
||||
}
|
||||
|
||||
/// getGlobalRetAddr - Grab the return address.
|
||||
///
|
||||
SDNode *AlphaDAGToDAGISel::getGlobalRetAddr() {
|
||||
unsigned GlobalRetAddr = getInstrInfo()->getGlobalRetAddr(MF);
|
||||
return CurDAG->getRegister(GlobalRetAddr, TLI.getPointerTy()).getNode();
|
||||
}
|
||||
|
||||
// Select - Convert the specified operand from a target-independent to a
|
||||
// target-specific node if it hasn't already been changed.
|
||||
SDNode *AlphaDAGToDAGISel::Select(SDNode *N) {
|
||||
if (N->isMachineOpcode())
|
||||
return NULL; // Already selected.
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case AlphaISD::CALL:
|
||||
SelectCALL(N);
|
||||
return NULL;
|
||||
|
||||
case ISD::FrameIndex: {
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64,
|
||||
CurDAG->getTargetFrameIndex(FI, MVT::i32),
|
||||
getI64Imm(0));
|
||||
}
|
||||
case ISD::GLOBAL_OFFSET_TABLE:
|
||||
return getGlobalBaseReg();
|
||||
case AlphaISD::GlobalRetAddr:
|
||||
return getGlobalRetAddr();
|
||||
|
||||
case AlphaISD::DivCall: {
|
||||
SDValue Chain = CurDAG->getEntryNode();
|
||||
SDValue N0 = N->getOperand(0);
|
||||
SDValue N1 = N->getOperand(1);
|
||||
SDValue N2 = N->getOperand(2);
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R24, N1,
|
||||
SDValue(0,0));
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R25, N2,
|
||||
Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, N0,
|
||||
Chain.getValue(1));
|
||||
SDNode *CNode =
|
||||
CurDAG->getMachineNode(Alpha::JSRs, dl, MVT::Other, MVT::Glue,
|
||||
Chain, Chain.getValue(1));
|
||||
Chain = CurDAG->getCopyFromReg(Chain, dl, Alpha::R27, MVT::i64,
|
||||
SDValue(CNode, 1));
|
||||
return CurDAG->SelectNodeTo(N, Alpha::BISr, MVT::i64, Chain, Chain);
|
||||
}
|
||||
|
||||
case ISD::READCYCLECOUNTER: {
|
||||
SDValue Chain = N->getOperand(0);
|
||||
return CurDAG->getMachineNode(Alpha::RPCC, dl, MVT::i64, MVT::Other,
|
||||
Chain);
|
||||
}
|
||||
|
||||
case ISD::Constant: {
|
||||
uint64_t uval = cast<ConstantSDNode>(N)->getZExtValue();
|
||||
|
||||
if (uval == 0) {
|
||||
SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
|
||||
Alpha::R31, MVT::i64);
|
||||
ReplaceUses(SDValue(N, 0), Result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int64_t val = (int64_t)uval;
|
||||
int32_t val32 = (int32_t)val;
|
||||
if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT &&
|
||||
val >= IMM_LOW + IMM_LOW * IMM_MULT)
|
||||
break; //(LDAH (LDA))
|
||||
if ((uval >> 32) == 0 && //empty upper bits
|
||||
val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT)
|
||||
// val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true
|
||||
break; //(zext (LDAH (LDA)))
|
||||
//Else use the constant pool
|
||||
ConstantInt *C = ConstantInt::get(
|
||||
Type::getInt64Ty(*CurDAG->getContext()), uval);
|
||||
SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
|
||||
SDNode *Tmp = CurDAG->getMachineNode(Alpha::LDAHr, dl, MVT::i64, CPI,
|
||||
SDValue(getGlobalBaseReg(), 0));
|
||||
return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other,
|
||||
CPI, SDValue(Tmp, 0), CurDAG->getEntryNode());
|
||||
}
|
||||
case ISD::TargetConstantFP:
|
||||
case ISD::ConstantFP: {
|
||||
ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
|
||||
bool isDouble = N->getValueType(0) == MVT::f64;
|
||||
EVT T = isDouble ? MVT::f64 : MVT::f32;
|
||||
if (CN->getValueAPF().isPosZero()) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
} else if (CN->getValueAPF().isNegZero()) {
|
||||
return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS,
|
||||
T, CurDAG->getRegister(Alpha::F31, T),
|
||||
CurDAG->getRegister(Alpha::F31, T));
|
||||
} else {
|
||||
report_fatal_error("Unhandled FP constant type");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::SETCC:
|
||||
if (N->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) {
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||
|
||||
unsigned Opc = Alpha::WTF;
|
||||
bool rev = false;
|
||||
bool inv = false;
|
||||
switch(CC) {
|
||||
default: DEBUG(N->dump(CurDAG)); llvm_unreachable("Unknown FP comparison!");
|
||||
case ISD::SETEQ: case ISD::SETOEQ: case ISD::SETUEQ:
|
||||
Opc = Alpha::CMPTEQ; break;
|
||||
case ISD::SETLT: case ISD::SETOLT: case ISD::SETULT:
|
||||
Opc = Alpha::CMPTLT; break;
|
||||
case ISD::SETLE: case ISD::SETOLE: case ISD::SETULE:
|
||||
Opc = Alpha::CMPTLE; break;
|
||||
case ISD::SETGT: case ISD::SETOGT: case ISD::SETUGT:
|
||||
Opc = Alpha::CMPTLT; rev = true; break;
|
||||
case ISD::SETGE: case ISD::SETOGE: case ISD::SETUGE:
|
||||
Opc = Alpha::CMPTLE; rev = true; break;
|
||||
case ISD::SETNE: case ISD::SETONE: case ISD::SETUNE:
|
||||
Opc = Alpha::CMPTEQ; inv = true; break;
|
||||
case ISD::SETO:
|
||||
Opc = Alpha::CMPTUN; inv = true; break;
|
||||
case ISD::SETUO:
|
||||
Opc = Alpha::CMPTUN; break;
|
||||
};
|
||||
SDValue tmp1 = N->getOperand(rev?1:0);
|
||||
SDValue tmp2 = N->getOperand(rev?0:1);
|
||||
SDNode *cmp = CurDAG->getMachineNode(Opc, dl, MVT::f64, tmp1, tmp2);
|
||||
if (inv)
|
||||
cmp = CurDAG->getMachineNode(Alpha::CMPTEQ, dl,
|
||||
MVT::f64, SDValue(cmp, 0),
|
||||
CurDAG->getRegister(Alpha::F31, MVT::f64));
|
||||
switch(CC) {
|
||||
case ISD::SETUEQ: case ISD::SETULT: case ISD::SETULE:
|
||||
case ISD::SETUNE: case ISD::SETUGT: case ISD::SETUGE:
|
||||
{
|
||||
SDNode* cmp2 = CurDAG->getMachineNode(Alpha::CMPTUN, dl, MVT::f64,
|
||||
tmp1, tmp2);
|
||||
cmp = CurDAG->getMachineNode(Alpha::ADDT, dl, MVT::f64,
|
||||
SDValue(cmp2, 0), SDValue(cmp, 0));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
SDNode* LD = CurDAG->getMachineNode(Alpha::FTOIT, dl,
|
||||
MVT::i64, SDValue(cmp, 0));
|
||||
return CurDAG->getMachineNode(Alpha::CMPULT, dl, MVT::i64,
|
||||
CurDAG->getRegister(Alpha::R31, MVT::i64),
|
||||
SDValue(LD,0));
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::AND: {
|
||||
ConstantSDNode* SC = NULL;
|
||||
ConstantSDNode* MC = NULL;
|
||||
if (N->getOperand(0).getOpcode() == ISD::SRL &&
|
||||
(MC = dyn_cast<ConstantSDNode>(N->getOperand(1))) &&
|
||||
(SC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1)))) {
|
||||
uint64_t sval = SC->getZExtValue();
|
||||
uint64_t mval = MC->getZExtValue();
|
||||
// If the result is a zap, let the autogened stuff handle it.
|
||||
if (get_zapImm(N->getOperand(0), mval))
|
||||
break;
|
||||
// given mask X, and shift S, we want to see if there is any zap in the
|
||||
// mask if we play around with the botton S bits
|
||||
uint64_t dontcare = (~0ULL) >> (64 - sval);
|
||||
uint64_t mask = mval << sval;
|
||||
|
||||
if (get_zapImm(mask | dontcare))
|
||||
mask = mask | dontcare;
|
||||
|
||||
if (get_zapImm(mask)) {
|
||||
SDValue Z =
|
||||
SDValue(CurDAG->getMachineNode(Alpha::ZAPNOTi, dl, MVT::i64,
|
||||
N->getOperand(0).getOperand(0),
|
||||
getI64Imm(get_zapImm(mask))), 0);
|
||||
return CurDAG->getMachineNode(Alpha::SRLr, dl, MVT::i64, Z,
|
||||
getI64Imm(sval));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return SelectCode(N);
|
||||
}
|
||||
|
||||
void AlphaDAGToDAGISel::SelectCALL(SDNode *N) {
|
||||
//TODO: add flag stuff to prevent nondeturministic breakage!
|
||||
|
||||
SDValue Chain = N->getOperand(0);
|
||||
SDValue Addr = N->getOperand(1);
|
||||
SDValue InFlag = N->getOperand(N->getNumOperands() - 1);
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
if (Addr.getOpcode() == AlphaISD::GPRelLo) {
|
||||
SDValue GOT = SDValue(getGlobalBaseReg(), 0);
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R29, GOT, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = SDValue(CurDAG->getMachineNode(Alpha::BSR, dl, MVT::Other,
|
||||
MVT::Glue, Addr.getOperand(0),
|
||||
Chain, InFlag), 0);
|
||||
} else {
|
||||
Chain = CurDAG->getCopyToReg(Chain, dl, Alpha::R27, Addr, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
Chain = SDValue(CurDAG->getMachineNode(Alpha::JSR, dl, MVT::Other,
|
||||
MVT::Glue, Chain, InFlag), 0);
|
||||
}
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
ReplaceUses(SDValue(N, 0), Chain);
|
||||
ReplaceUses(SDValue(N, 1), InFlag);
|
||||
}
|
||||
|
||||
|
||||
/// createAlphaISelDag - This pass converts a legalized DAG into a
|
||||
/// Alpha-specific DAG, ready for instruction scheduling.
|
||||
///
|
||||
FunctionPass *llvm::createAlphaISelDag(AlphaTargetMachine &TM) {
|
||||
return new AlphaDAGToDAGISel(TM);
|
||||
}
|
@ -1,962 +0,0 @@
|
||||
//===-- AlphaISelLowering.cpp - Alpha 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 AlphaISelLowering class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AlphaISelLowering.h"
|
||||
#include "AlphaTargetMachine.h"
|
||||
#include "AlphaMachineFunctionInfo.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/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
/// AddLiveIn - This helper function adds the specified physical register to the
|
||||
/// MachineFunction as a live in value. It also creates a corresponding virtual
|
||||
/// register for it.
|
||||
static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
|
||||
TargetRegisterClass *RC) {
|
||||
assert(RC->contains(PReg) && "Not the correct regclass!");
|
||||
unsigned VReg = MF.getRegInfo().createVirtualRegister(RC);
|
||||
MF.getRegInfo().addLiveIn(PReg, VReg);
|
||||
return VReg;
|
||||
}
|
||||
|
||||
AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM)
|
||||
: TargetLowering(TM, new TargetLoweringObjectFileELF()) {
|
||||
// Set up the TargetLowering object.
|
||||
//I am having problems with shr n i8 1
|
||||
setBooleanContents(ZeroOrOneBooleanContent);
|
||||
setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
|
||||
|
||||
addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass);
|
||||
addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass);
|
||||
addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass);
|
||||
|
||||
// We want to custom lower some of our intrinsics.
|
||||
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
|
||||
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
|
||||
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, Expand);
|
||||
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
|
||||
|
||||
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
|
||||
|
||||
// setOperationAction(ISD::BRIND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
|
||||
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
|
||||
setOperationAction(ISD::FREM, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FREM, MVT::f64, Expand);
|
||||
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||
|
||||
if (!TM.getSubtarget<AlphaSubtarget>().hasCT()) {
|
||||
setOperationAction(ISD::CTPOP , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
|
||||
}
|
||||
setOperationAction(ISD::BSWAP , MVT::i64, Expand);
|
||||
setOperationAction(ISD::ROTL , MVT::i64, Expand);
|
||||
setOperationAction(ISD::ROTR , MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::SREM , MVT::i64, Custom);
|
||||
setOperationAction(ISD::UREM , MVT::i64, Custom);
|
||||
setOperationAction(ISD::SDIV , MVT::i64, Custom);
|
||||
setOperationAction(ISD::UDIV , MVT::i64, Custom);
|
||||
|
||||
setOperationAction(ISD::ADDC , MVT::i64, Expand);
|
||||
setOperationAction(ISD::ADDE , MVT::i64, Expand);
|
||||
setOperationAction(ISD::SUBC , MVT::i64, Expand);
|
||||
setOperationAction(ISD::SUBE , MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
|
||||
|
||||
setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
|
||||
setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
|
||||
|
||||
// We don't support sin/cos/sqrt/pow
|
||||
setOperationAction(ISD::FSIN , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FCOS , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FSIN , MVT::f32, Expand);
|
||||
setOperationAction(ISD::FCOS , MVT::f32, Expand);
|
||||
|
||||
setOperationAction(ISD::FSQRT, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FSQRT, MVT::f32, Expand);
|
||||
|
||||
setOperationAction(ISD::FPOW , MVT::f32, Expand);
|
||||
setOperationAction(ISD::FPOW , MVT::f64, Expand);
|
||||
|
||||
setOperationAction(ISD::FMA, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FMA, MVT::f32, Expand);
|
||||
|
||||
setOperationAction(ISD::SETCC, MVT::f32, Promote);
|
||||
|
||||
setOperationAction(ISD::BITCAST, MVT::f32, Promote);
|
||||
|
||||
setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
|
||||
|
||||
// Not implemented yet.
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
|
||||
|
||||
// We want to legalize GlobalAddress and ConstantPool and
|
||||
// ExternalSymbols nodes into the appropriate instructions to
|
||||
// materialize the address.
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ConstantPool, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
|
||||
|
||||
setOperationAction(ISD::VASTART, MVT::Other, Custom);
|
||||
setOperationAction(ISD::VAEND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::VACOPY, MVT::Other, Custom);
|
||||
setOperationAction(ISD::VAARG, MVT::Other, Custom);
|
||||
setOperationAction(ISD::VAARG, MVT::i32, Custom);
|
||||
|
||||
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
||||
|
||||
setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Expand);
|
||||
setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Expand);
|
||||
|
||||
setStackPointerRegisterToSaveRestore(Alpha::R30);
|
||||
|
||||
setJumpBufSize(272);
|
||||
setJumpBufAlignment(16);
|
||||
|
||||
setMinFunctionAlignment(4);
|
||||
|
||||
setInsertFencesForAtomic(true);
|
||||
|
||||
computeRegisterProperties();
|
||||
}
|
||||
|
||||
EVT AlphaTargetLowering::getSetCCResultType(EVT VT) const {
|
||||
return MVT::i64;
|
||||
}
|
||||
|
||||
const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
default: return 0;
|
||||
case AlphaISD::CVTQT_: return "Alpha::CVTQT_";
|
||||
case AlphaISD::CVTQS_: return "Alpha::CVTQS_";
|
||||
case AlphaISD::CVTTQ_: return "Alpha::CVTTQ_";
|
||||
case AlphaISD::GPRelHi: return "Alpha::GPRelHi";
|
||||
case AlphaISD::GPRelLo: return "Alpha::GPRelLo";
|
||||
case AlphaISD::RelLit: return "Alpha::RelLit";
|
||||
case AlphaISD::GlobalRetAddr: return "Alpha::GlobalRetAddr";
|
||||
case AlphaISD::CALL: return "Alpha::CALL";
|
||||
case AlphaISD::DivCall: return "Alpha::DivCall";
|
||||
case AlphaISD::RET_FLAG: return "Alpha::RET_FLAG";
|
||||
case AlphaISD::COND_BRANCH_I: return "Alpha::COND_BRANCH_I";
|
||||
case AlphaISD::COND_BRANCH_F: return "Alpha::COND_BRANCH_F";
|
||||
}
|
||||
}
|
||||
|
||||
static SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
|
||||
EVT PtrVT = Op.getValueType();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
|
||||
// FIXME there isn't really any debug info here
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, JTI,
|
||||
DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
|
||||
SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, JTI, Hi);
|
||||
return Lo;
|
||||
}
|
||||
|
||||
//http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/
|
||||
//AA-PY8AC-TET1_html/callCH3.html#BLOCK21
|
||||
|
||||
//For now, just use variable size stack frame format
|
||||
|
||||
//In a standard call, the first six items are passed in registers $16
|
||||
//- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details
|
||||
//of argument-to-register correspondence.) The remaining items are
|
||||
//collected in a memory argument list that is a naturally aligned
|
||||
//array of quadwords. In a standard call, this list, if present, must
|
||||
//be passed at 0(SP).
|
||||
//7 ... n 0(SP) ... (n-7)*8(SP)
|
||||
|
||||
// //#define FP $15
|
||||
// //#define RA $26
|
||||
// //#define PV $27
|
||||
// //#define GP $29
|
||||
// //#define SP $30
|
||||
|
||||
#include "AlphaGenCallingConv.inc"
|
||||
|
||||
SDValue
|
||||
AlphaTargetLowering::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 {
|
||||
// Alpha target does not yet support tail call optimization.
|
||||
isTailCall = false;
|
||||
|
||||
// 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_Alpha);
|
||||
|
||||
// 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, Alpha::R30, MVT::i64);
|
||||
|
||||
SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
|
||||
StackPtr,
|
||||
DAG.getIntPtrConstant(VA.getLocMemOffset()));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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(AlphaISD::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
|
||||
AlphaTargetLowering::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_Alpha);
|
||||
|
||||
// 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
|
||||
AlphaTargetLowering::LowerFormalArguments(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();
|
||||
AlphaMachineFunctionInfo *FuncInfo = MF.getInfo<AlphaMachineFunctionInfo>();
|
||||
|
||||
unsigned args_int[] = {
|
||||
Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21};
|
||||
unsigned args_float[] = {
|
||||
Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21};
|
||||
|
||||
for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
|
||||
SDValue argt;
|
||||
EVT ObjectVT = Ins[ArgNo].VT;
|
||||
SDValue ArgVal;
|
||||
|
||||
if (ArgNo < 6) {
|
||||
switch (ObjectVT.getSimpleVT().SimpleTy) {
|
||||
default:
|
||||
assert(false && "Invalid value type!");
|
||||
case MVT::f64:
|
||||
args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo],
|
||||
&Alpha::F8RCRegClass);
|
||||
ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT);
|
||||
break;
|
||||
case MVT::f32:
|
||||
args_float[ArgNo] = AddLiveIn(MF, args_float[ArgNo],
|
||||
&Alpha::F4RCRegClass);
|
||||
ArgVal = DAG.getCopyFromReg(Chain, dl, args_float[ArgNo], ObjectVT);
|
||||
break;
|
||||
case MVT::i64:
|
||||
args_int[ArgNo] = AddLiveIn(MF, args_int[ArgNo],
|
||||
&Alpha::GPRCRegClass);
|
||||
ArgVal = DAG.getCopyFromReg(Chain, dl, args_int[ArgNo], MVT::i64);
|
||||
break;
|
||||
}
|
||||
} else { //more args
|
||||
// Create the frame index object for this incoming parameter...
|
||||
int FI = MFI->CreateFixedObject(8, 8 * (ArgNo - 6), true);
|
||||
|
||||
// Create the SelectionDAG nodes corresponding to a load
|
||||
//from this parameter
|
||||
SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
|
||||
ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
}
|
||||
InVals.push_back(ArgVal);
|
||||
}
|
||||
|
||||
// If the functions takes variable number of arguments, copy all regs to stack
|
||||
if (isVarArg) {
|
||||
FuncInfo->setVarArgsOffset(Ins.size() * 8);
|
||||
std::vector<SDValue> LS;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (TargetRegisterInfo::isPhysicalRegister(args_int[i]))
|
||||
args_int[i] = AddLiveIn(MF, args_int[i], &Alpha::GPRCRegClass);
|
||||
SDValue argt = DAG.getCopyFromReg(Chain, dl, args_int[i], MVT::i64);
|
||||
int FI = MFI->CreateFixedObject(8, -8 * (6 - i), true);
|
||||
if (i == 0) FuncInfo->setVarArgsBase(FI);
|
||||
SDValue SDFI = DAG.getFrameIndex(FI, MVT::i64);
|
||||
LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(),
|
||||
false, false, 0));
|
||||
|
||||
if (TargetRegisterInfo::isPhysicalRegister(args_float[i]))
|
||||
args_float[i] = AddLiveIn(MF, args_float[i], &Alpha::F8RCRegClass);
|
||||
argt = DAG.getCopyFromReg(Chain, dl, args_float[i], MVT::f64);
|
||||
FI = MFI->CreateFixedObject(8, - 8 * (12 - i), true);
|
||||
SDFI = DAG.getFrameIndex(FI, MVT::i64);
|
||||
LS.push_back(DAG.getStore(Chain, dl, argt, SDFI, MachinePointerInfo(),
|
||||
false, false, 0));
|
||||
}
|
||||
|
||||
//Set up a token factor with all the stack traffic
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LS[0], LS.size());
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AlphaTargetLowering::LowerReturn(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
DebugLoc dl, SelectionDAG &DAG) const {
|
||||
|
||||
SDValue Copy = DAG.getCopyToReg(Chain, dl, Alpha::R26,
|
||||
DAG.getNode(AlphaISD::GlobalRetAddr,
|
||||
DebugLoc(), MVT::i64),
|
||||
SDValue());
|
||||
switch (Outs.size()) {
|
||||
default:
|
||||
llvm_unreachable("Do not know how to return this many arguments!");
|
||||
case 0:
|
||||
break;
|
||||
//return SDValue(); // ret void is legal
|
||||
case 1: {
|
||||
EVT ArgVT = Outs[0].VT;
|
||||
unsigned ArgReg;
|
||||
if (ArgVT.isInteger())
|
||||
ArgReg = Alpha::R0;
|
||||
else {
|
||||
assert(ArgVT.isFloatingPoint());
|
||||
ArgReg = Alpha::F0;
|
||||
}
|
||||
Copy = DAG.getCopyToReg(Copy, dl, ArgReg,
|
||||
OutVals[0], Copy.getValue(1));
|
||||
if (DAG.getMachineFunction().getRegInfo().liveout_empty())
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
EVT ArgVT = Outs[0].VT;
|
||||
unsigned ArgReg1, ArgReg2;
|
||||
if (ArgVT.isInteger()) {
|
||||
ArgReg1 = Alpha::R0;
|
||||
ArgReg2 = Alpha::R1;
|
||||
} else {
|
||||
assert(ArgVT.isFloatingPoint());
|
||||
ArgReg1 = Alpha::F0;
|
||||
ArgReg2 = Alpha::F1;
|
||||
}
|
||||
Copy = DAG.getCopyToReg(Copy, dl, ArgReg1,
|
||||
OutVals[0], Copy.getValue(1));
|
||||
if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(),
|
||||
DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg1)
|
||||
== DAG.getMachineFunction().getRegInfo().liveout_end())
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg1);
|
||||
Copy = DAG.getCopyToReg(Copy, dl, ArgReg2,
|
||||
OutVals[1], Copy.getValue(1));
|
||||
if (std::find(DAG.getMachineFunction().getRegInfo().liveout_begin(),
|
||||
DAG.getMachineFunction().getRegInfo().liveout_end(), ArgReg2)
|
||||
== DAG.getMachineFunction().getRegInfo().liveout_end())
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(ArgReg2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DAG.getNode(AlphaISD::RET_FLAG, dl,
|
||||
MVT::Other, Copy, Copy.getValue(1));
|
||||
}
|
||||
|
||||
void AlphaTargetLowering::LowerVAARG(SDNode *N, SDValue &Chain,
|
||||
SDValue &DataPtr,
|
||||
SelectionDAG &DAG) const {
|
||||
Chain = N->getOperand(0);
|
||||
SDValue VAListP = N->getOperand(1);
|
||||
const Value *VAListS = cast<SrcValueSDNode>(N->getOperand(2))->getValue();
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
|
||||
SDValue Base = DAG.getLoad(MVT::i64, dl, Chain, VAListP,
|
||||
MachinePointerInfo(VAListS),
|
||||
false, false, 0);
|
||||
SDValue Tmp = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
SDValue Offset = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Base.getValue(1),
|
||||
Tmp, MachinePointerInfo(),
|
||||
MVT::i32, false, false, 0);
|
||||
DataPtr = DAG.getNode(ISD::ADD, dl, MVT::i64, Base, Offset);
|
||||
if (N->getValueType(0).isFloatingPoint())
|
||||
{
|
||||
//if fp && Offset < 6*8, then subtract 6*8 from DataPtr
|
||||
SDValue FPDataPtr = DAG.getNode(ISD::SUB, dl, MVT::i64, DataPtr,
|
||||
DAG.getConstant(8*6, MVT::i64));
|
||||
SDValue CC = DAG.getSetCC(dl, MVT::i64, Offset,
|
||||
DAG.getConstant(8*6, MVT::i64), ISD::SETLT);
|
||||
DataPtr = DAG.getNode(ISD::SELECT, dl, MVT::i64, CC, FPDataPtr, DataPtr);
|
||||
}
|
||||
|
||||
SDValue NewOffset = DAG.getNode(ISD::ADD, dl, MVT::i64, Offset,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
Chain = DAG.getTruncStore(Offset.getValue(1), dl, NewOffset, Tmp,
|
||||
MachinePointerInfo(),
|
||||
MVT::i32, false, false, 0);
|
||||
}
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
SDValue AlphaTargetLowering::LowerOperation(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
switch (Op.getOpcode()) {
|
||||
default: llvm_unreachable("Wasn't expecting to be able to lower this!");
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
|
||||
case ISD::INTRINSIC_WO_CHAIN: {
|
||||
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
|
||||
switch (IntNo) {
|
||||
default: break; // Don't custom lower most intrinsics.
|
||||
case Intrinsic::alpha_umulh:
|
||||
return DAG.getNode(ISD::MULHU, dl, MVT::i64,
|
||||
Op.getOperand(1), Op.getOperand(2));
|
||||
}
|
||||
}
|
||||
|
||||
case ISD::SRL_PARTS: {
|
||||
SDValue ShOpLo = Op.getOperand(0);
|
||||
SDValue ShOpHi = Op.getOperand(1);
|
||||
SDValue ShAmt = Op.getOperand(2);
|
||||
SDValue bm = DAG.getNode(ISD::SUB, dl, MVT::i64,
|
||||
DAG.getConstant(64, MVT::i64), ShAmt);
|
||||
SDValue BMCC = DAG.getSetCC(dl, MVT::i64, bm,
|
||||
DAG.getConstant(0, MVT::i64), ISD::SETLE);
|
||||
// if 64 - shAmt <= 0
|
||||
SDValue Hi_Neg = DAG.getConstant(0, MVT::i64);
|
||||
SDValue ShAmt_Neg = DAG.getNode(ISD::SUB, dl, MVT::i64,
|
||||
DAG.getConstant(0, MVT::i64), bm);
|
||||
SDValue Lo_Neg = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt_Neg);
|
||||
// else
|
||||
SDValue carries = DAG.getNode(ISD::SHL, dl, MVT::i64, ShOpHi, bm);
|
||||
SDValue Hi_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpHi, ShAmt);
|
||||
SDValue Lo_Pos = DAG.getNode(ISD::SRL, dl, MVT::i64, ShOpLo, ShAmt);
|
||||
Lo_Pos = DAG.getNode(ISD::OR, dl, MVT::i64, Lo_Pos, carries);
|
||||
// Merge
|
||||
SDValue Hi = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Hi_Neg, Hi_Pos);
|
||||
SDValue Lo = DAG.getNode(ISD::SELECT, dl, MVT::i64, BMCC, Lo_Neg, Lo_Pos);
|
||||
SDValue Ops[2] = { Lo, Hi };
|
||||
return DAG.getMergeValues(Ops, 2, dl);
|
||||
}
|
||||
// case ISD::SRA_PARTS:
|
||||
|
||||
// case ISD::SHL_PARTS:
|
||||
|
||||
|
||||
case ISD::SINT_TO_FP: {
|
||||
assert(Op.getOperand(0).getValueType() == MVT::i64 &&
|
||||
"Unhandled SINT_TO_FP type in custom expander!");
|
||||
SDValue LD;
|
||||
bool isDouble = Op.getValueType() == MVT::f64;
|
||||
LD = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Op.getOperand(0));
|
||||
SDValue FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_, dl,
|
||||
isDouble?MVT::f64:MVT::f32, LD);
|
||||
return FP;
|
||||
}
|
||||
case ISD::FP_TO_SINT: {
|
||||
bool isDouble = Op.getOperand(0).getValueType() == MVT::f64;
|
||||
SDValue src = Op.getOperand(0);
|
||||
|
||||
if (!isDouble) //Promote
|
||||
src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, src);
|
||||
|
||||
src = DAG.getNode(AlphaISD::CVTTQ_, dl, MVT::f64, src);
|
||||
|
||||
return DAG.getNode(ISD::BITCAST, dl, MVT::i64, src);
|
||||
}
|
||||
case ISD::ConstantPool: {
|
||||
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
|
||||
const Constant *C = CP->getConstVal();
|
||||
SDValue CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment());
|
||||
// FIXME there isn't really any debug info here
|
||||
|
||||
SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, CPI,
|
||||
DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
|
||||
SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, CPI, Hi);
|
||||
return Lo;
|
||||
}
|
||||
case ISD::GlobalTLSAddress:
|
||||
llvm_unreachable("TLS not implemented for Alpha.");
|
||||
case ISD::GlobalAddress: {
|
||||
GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
|
||||
const GlobalValue *GV = GSDN->getGlobal();
|
||||
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i64,
|
||||
GSDN->getOffset());
|
||||
// FIXME there isn't really any debug info here
|
||||
|
||||
// if (!GV->hasWeakLinkage() && !GV->isDeclaration()
|
||||
// && !GV->hasLinkOnceLinkage()) {
|
||||
if (GV->hasLocalLinkage()) {
|
||||
SDValue Hi = DAG.getNode(AlphaISD::GPRelHi, dl, MVT::i64, GA,
|
||||
DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
|
||||
SDValue Lo = DAG.getNode(AlphaISD::GPRelLo, dl, MVT::i64, GA, Hi);
|
||||
return Lo;
|
||||
} else
|
||||
return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64, GA,
|
||||
DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
|
||||
}
|
||||
case ISD::ExternalSymbol: {
|
||||
return DAG.getNode(AlphaISD::RelLit, dl, MVT::i64,
|
||||
DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)
|
||||
->getSymbol(), MVT::i64),
|
||||
DAG.getGLOBAL_OFFSET_TABLE(MVT::i64));
|
||||
}
|
||||
|
||||
case ISD::UREM:
|
||||
case ISD::SREM:
|
||||
//Expand only on constant case
|
||||
if (Op.getOperand(1).getOpcode() == ISD::Constant) {
|
||||
EVT VT = Op.getNode()->getValueType(0);
|
||||
SDValue Tmp1 = Op.getNode()->getOpcode() == ISD::UREM ?
|
||||
BuildUDIV(Op.getNode(), DAG, NULL) :
|
||||
BuildSDIV(Op.getNode(), DAG, NULL);
|
||||
Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Op.getOperand(1));
|
||||
Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Op.getOperand(0), Tmp1);
|
||||
return Tmp1;
|
||||
}
|
||||
//fall through
|
||||
case ISD::SDIV:
|
||||
case ISD::UDIV:
|
||||
if (Op.getValueType().isInteger()) {
|
||||
if (Op.getOperand(1).getOpcode() == ISD::Constant)
|
||||
return Op.getOpcode() == ISD::SDIV ? BuildSDIV(Op.getNode(), DAG, NULL)
|
||||
: BuildUDIV(Op.getNode(), DAG, NULL);
|
||||
const char* opstr = 0;
|
||||
switch (Op.getOpcode()) {
|
||||
case ISD::UREM: opstr = "__remqu"; break;
|
||||
case ISD::SREM: opstr = "__remq"; break;
|
||||
case ISD::UDIV: opstr = "__divqu"; break;
|
||||
case ISD::SDIV: opstr = "__divq"; break;
|
||||
}
|
||||
SDValue Tmp1 = Op.getOperand(0),
|
||||
Tmp2 = Op.getOperand(1),
|
||||
Addr = DAG.getExternalSymbol(opstr, MVT::i64);
|
||||
return DAG.getNode(AlphaISD::DivCall, dl, MVT::i64, Addr, Tmp1, Tmp2);
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::VAARG: {
|
||||
SDValue Chain, DataPtr;
|
||||
LowerVAARG(Op.getNode(), Chain, DataPtr, DAG);
|
||||
|
||||
SDValue Result;
|
||||
if (Op.getValueType() == MVT::i32)
|
||||
Result = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Chain, DataPtr,
|
||||
MachinePointerInfo(), MVT::i32, false, false, 0);
|
||||
else
|
||||
Result = DAG.getLoad(Op.getValueType(), dl, Chain, DataPtr,
|
||||
MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
return Result;
|
||||
}
|
||||
case ISD::VACOPY: {
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue DestP = Op.getOperand(1);
|
||||
SDValue SrcP = Op.getOperand(2);
|
||||
const Value *DestS = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
|
||||
const Value *SrcS = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
|
||||
|
||||
SDValue Val = DAG.getLoad(getPointerTy(), dl, Chain, SrcP,
|
||||
MachinePointerInfo(SrcS),
|
||||
false, false, 0);
|
||||
SDValue Result = DAG.getStore(Val.getValue(1), dl, Val, DestP,
|
||||
MachinePointerInfo(DestS),
|
||||
false, false, 0);
|
||||
SDValue NP = DAG.getNode(ISD::ADD, dl, MVT::i64, SrcP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
Val = DAG.getExtLoad(ISD::SEXTLOAD, dl, MVT::i64, Result,
|
||||
NP, MachinePointerInfo(), MVT::i32, false, false, 0);
|
||||
SDValue NPD = DAG.getNode(ISD::ADD, dl, MVT::i64, DestP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
return DAG.getTruncStore(Val.getValue(1), dl, Val, NPD,
|
||||
MachinePointerInfo(), MVT::i32,
|
||||
false, false, 0);
|
||||
}
|
||||
case ISD::VASTART: {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
AlphaMachineFunctionInfo *FuncInfo = MF.getInfo<AlphaMachineFunctionInfo>();
|
||||
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue VAListP = Op.getOperand(1);
|
||||
const Value *VAListS = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
|
||||
// vastart stores the address of the VarArgsBase and VarArgsOffset
|
||||
SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsBase(), MVT::i64);
|
||||
SDValue S1 = DAG.getStore(Chain, dl, FR, VAListP,
|
||||
MachinePointerInfo(VAListS), false, false, 0);
|
||||
SDValue SA2 = DAG.getNode(ISD::ADD, dl, MVT::i64, VAListP,
|
||||
DAG.getConstant(8, MVT::i64));
|
||||
return DAG.getTruncStore(S1, dl,
|
||||
DAG.getConstant(FuncInfo->getVarArgsOffset(),
|
||||
MVT::i64),
|
||||
SA2, MachinePointerInfo(),
|
||||
MVT::i32, false, false, 0);
|
||||
}
|
||||
case ISD::RETURNADDR:
|
||||
return DAG.getNode(AlphaISD::GlobalRetAddr, DebugLoc(), MVT::i64);
|
||||
//FIXME: implement
|
||||
case ISD::FRAMEADDR: break;
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
void AlphaTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue>&Results,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
assert(N->getValueType(0) == MVT::i32 &&
|
||||
N->getOpcode() == ISD::VAARG &&
|
||||
"Unknown node to custom promote!");
|
||||
|
||||
SDValue Chain, DataPtr;
|
||||
LowerVAARG(N, Chain, DataPtr, DAG);
|
||||
SDValue Res = DAG.getLoad(N->getValueType(0), dl, Chain, DataPtr,
|
||||
MachinePointerInfo(),
|
||||
false, false, 0);
|
||||
Results.push_back(Res);
|
||||
Results.push_back(SDValue(Res.getNode(), 1));
|
||||
}
|
||||
|
||||
|
||||
//Inline Asm
|
||||
|
||||
/// getConstraintType - Given a constraint letter, return the type of
|
||||
/// constraint it is for this target.
|
||||
AlphaTargetLowering::ConstraintType
|
||||
AlphaTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
if (Constraint.size() == 1) {
|
||||
switch (Constraint[0]) {
|
||||
default: break;
|
||||
case 'f':
|
||||
case 'r':
|
||||
return C_RegisterClass;
|
||||
}
|
||||
}
|
||||
return TargetLowering::getConstraintType(Constraint);
|
||||
}
|
||||
|
||||
/// Examine constraint type and operand type and determine a weight value.
|
||||
/// This object must already have been set up with the operand type
|
||||
/// and the current alternative constraint selected.
|
||||
TargetLowering::ConstraintWeight
|
||||
AlphaTargetLowering::getSingleConstraintMatchWeight(
|
||||
AsmOperandInfo &info, const char *constraint) const {
|
||||
ConstraintWeight weight = CW_Invalid;
|
||||
Value *CallOperandVal = info.CallOperandVal;
|
||||
// If we don't have a value, we can't do a match,
|
||||
// but allow it at the lowest weight.
|
||||
if (CallOperandVal == NULL)
|
||||
return CW_Default;
|
||||
// Look at the constraint type.
|
||||
switch (*constraint) {
|
||||
default:
|
||||
weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);
|
||||
break;
|
||||
case 'f':
|
||||
weight = CW_Register;
|
||||
break;
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
/// Given a register class constraint, like 'r', if this corresponds directly
|
||||
/// to an LLVM register class, return a register of 0 and the register class
|
||||
/// pointer.
|
||||
std::pair<unsigned, const TargetRegisterClass*> AlphaTargetLowering::
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const
|
||||
{
|
||||
if (Constraint.size() == 1) {
|
||||
switch (Constraint[0]) {
|
||||
case 'r':
|
||||
return std::make_pair(0U, Alpha::GPRCRegisterClass);
|
||||
case 'f':
|
||||
return VT == MVT::f64 ? std::make_pair(0U, Alpha::F8RCRegisterClass) :
|
||||
std::make_pair(0U, Alpha::F4RCRegisterClass);
|
||||
}
|
||||
}
|
||||
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Other Lowering Code
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MachineBasicBlock *
|
||||
AlphaTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const {
|
||||
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
|
||||
assert((MI->getOpcode() == Alpha::CAS32 ||
|
||||
MI->getOpcode() == Alpha::CAS64 ||
|
||||
MI->getOpcode() == Alpha::LAS32 ||
|
||||
MI->getOpcode() == Alpha::LAS64 ||
|
||||
MI->getOpcode() == Alpha::SWAP32 ||
|
||||
MI->getOpcode() == Alpha::SWAP64) &&
|
||||
"Unexpected instr type to insert");
|
||||
|
||||
bool is32 = MI->getOpcode() == Alpha::CAS32 ||
|
||||
MI->getOpcode() == Alpha::LAS32 ||
|
||||
MI->getOpcode() == Alpha::SWAP32;
|
||||
|
||||
//Load locked store conditional for atomic ops take on the same form
|
||||
//start:
|
||||
//ll
|
||||
//do stuff (maybe branch to exit)
|
||||
//sc
|
||||
//test sc and maybe branck to start
|
||||
//exit:
|
||||
const BasicBlock *LLVM_BB = BB->getBasicBlock();
|
||||
DebugLoc dl = MI->getDebugLoc();
|
||||
MachineFunction::iterator It = BB;
|
||||
++It;
|
||||
|
||||
MachineBasicBlock *thisMBB = BB;
|
||||
MachineFunction *F = BB->getParent();
|
||||
MachineBasicBlock *llscMBB = F->CreateMachineBasicBlock(LLVM_BB);
|
||||
MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
|
||||
|
||||
sinkMBB->splice(sinkMBB->begin(), thisMBB,
|
||||
llvm::next(MachineBasicBlock::iterator(MI)),
|
||||
thisMBB->end());
|
||||
sinkMBB->transferSuccessorsAndUpdatePHIs(thisMBB);
|
||||
|
||||
F->insert(It, llscMBB);
|
||||
F->insert(It, sinkMBB);
|
||||
|
||||
BuildMI(thisMBB, dl, TII->get(Alpha::BR)).addMBB(llscMBB);
|
||||
|
||||
unsigned reg_res = MI->getOperand(0).getReg(),
|
||||
reg_ptr = MI->getOperand(1).getReg(),
|
||||
reg_v2 = MI->getOperand(2).getReg(),
|
||||
reg_store = F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
|
||||
BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::LDL_L : Alpha::LDQ_L),
|
||||
reg_res).addImm(0).addReg(reg_ptr);
|
||||
switch (MI->getOpcode()) {
|
||||
case Alpha::CAS32:
|
||||
case Alpha::CAS64: {
|
||||
unsigned reg_cmp
|
||||
= F->getRegInfo().createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::CMPEQ), reg_cmp)
|
||||
.addReg(reg_v2).addReg(reg_res);
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::BEQ))
|
||||
.addImm(0).addReg(reg_cmp).addMBB(sinkMBB);
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store)
|
||||
.addReg(Alpha::R31).addReg(MI->getOperand(3).getReg());
|
||||
break;
|
||||
}
|
||||
case Alpha::LAS32:
|
||||
case Alpha::LAS64: {
|
||||
BuildMI(llscMBB, dl,TII->get(is32 ? Alpha::ADDLr : Alpha::ADDQr), reg_store)
|
||||
.addReg(reg_res).addReg(reg_v2);
|
||||
break;
|
||||
}
|
||||
case Alpha::SWAP32:
|
||||
case Alpha::SWAP64: {
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::BISr), reg_store)
|
||||
.addReg(reg_v2).addReg(reg_v2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
BuildMI(llscMBB, dl, TII->get(is32 ? Alpha::STL_C : Alpha::STQ_C), reg_store)
|
||||
.addReg(reg_store).addImm(0).addReg(reg_ptr);
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::BEQ))
|
||||
.addImm(0).addReg(reg_store).addMBB(llscMBB);
|
||||
BuildMI(llscMBB, dl, TII->get(Alpha::BR)).addMBB(sinkMBB);
|
||||
|
||||
thisMBB->addSuccessor(llscMBB);
|
||||
llscMBB->addSuccessor(llscMBB);
|
||||
llscMBB->addSuccessor(sinkMBB);
|
||||
MI->eraseFromParent(); // The pseudo instruction is gone now.
|
||||
|
||||
return sinkMBB;
|
||||
}
|
||||
|
||||
bool
|
||||
AlphaTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
// The Alpha target isn't yet aware of offsets.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AlphaTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
|
||||
if (VT != MVT::f32 && VT != MVT::f64)
|
||||
return false;
|
||||
// +0.0 F31
|
||||
// +0.0f F31
|
||||
// -0.0 -F31
|
||||
// -0.0f -F31
|
||||
return Imm.isZero() || Imm.isNegZero();
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
//===-- AlphaISelLowering.h - Alpha 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 Alpha uses to lower LLVM code into a
|
||||
// selection DAG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
|
||||
#define LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
|
||||
|
||||
#include "llvm/ADT/VectorExtras.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "Alpha.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace AlphaISD {
|
||||
enum NodeType {
|
||||
// Start the numbering where the builting ops and target ops leave off.
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
//These corrospond to the identical Instruction
|
||||
CVTQT_, CVTQS_, CVTTQ_,
|
||||
|
||||
/// GPRelHi/GPRelLo - These represent the high and low 16-bit
|
||||
/// parts of a global address respectively.
|
||||
GPRelHi, GPRelLo,
|
||||
|
||||
/// RetLit - Literal Relocation of a Global
|
||||
RelLit,
|
||||
|
||||
/// GlobalRetAddr - used to restore the return address
|
||||
GlobalRetAddr,
|
||||
|
||||
/// CALL - Normal call.
|
||||
CALL,
|
||||
|
||||
/// DIVCALL - used for special library calls for div and rem
|
||||
DivCall,
|
||||
|
||||
/// return flag operand
|
||||
RET_FLAG,
|
||||
|
||||
/// CHAIN = COND_BRANCH CHAIN, OPC, (G|F)PRC, DESTBB [, INFLAG] - This
|
||||
/// corresponds to the COND_BRANCH pseudo instruction.
|
||||
/// *PRC is the input register to compare to zero,
|
||||
/// OPC is the branch opcode to use (e.g. Alpha::BEQ),
|
||||
/// DESTBB is the destination block to branch to, and INFLAG is
|
||||
/// an optional input flag argument.
|
||||
COND_BRANCH_I, COND_BRANCH_F
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
class AlphaTargetLowering : public TargetLowering {
|
||||
public:
|
||||
explicit AlphaTargetLowering(TargetMachine &TM);
|
||||
|
||||
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i64; }
|
||||
|
||||
/// getSetCCResultType - Get the SETCC result ValueType
|
||||
virtual EVT getSetCCResultType(EVT VT) const;
|
||||
|
||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||
///
|
||||
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
/// ReplaceNodeResults - Replace the results of node with an illegal result
|
||||
/// type with new values built out of custom code.
|
||||
///
|
||||
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
|
||||
SelectionDAG &DAG) const;
|
||||
|
||||
// Friendly names for dumps
|
||||
const char *getTargetNodeName(unsigned Opcode) 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;
|
||||
|
||||
ConstraintType getConstraintType(const std::string &Constraint) const;
|
||||
|
||||
/// Examine constraint string and operand type and determine a weight value.
|
||||
/// The operand object must already have been set up with the operand type.
|
||||
ConstraintWeight getSingleConstraintMatchWeight(
|
||||
AsmOperandInfo &info, const char *constraint) const;
|
||||
|
||||
std::pair<unsigned, const TargetRegisterClass*>
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint,
|
||||
EVT VT) const;
|
||||
|
||||
MachineBasicBlock *
|
||||
EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
MachineBasicBlock *BB) const;
|
||||
|
||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) 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:
|
||||
// Helpers for custom lowering.
|
||||
void LowerVAARG(SDNode *N, SDValue &Chain, SDValue &DataPtr,
|
||||
SelectionDAG &DAG) 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;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LLVM_TARGET_ALPHA_ALPHAISELLOWERING_H
|
@ -1,268 +0,0 @@
|
||||
//===- AlphaInstrFormats.td - Alpha Instruction Formats ----*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//3.3:
|
||||
//Memory
|
||||
//Branch
|
||||
//Operate
|
||||
//Floating-point
|
||||
//PALcode
|
||||
|
||||
def u8imm : Operand<i64>;
|
||||
def s14imm : Operand<i64>;
|
||||
def s16imm : Operand<i64>;
|
||||
def s21imm : Operand<i64>;
|
||||
def s64imm : Operand<i64>;
|
||||
def u64imm : Operand<i64>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction format superclass
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Alpha instruction baseline
|
||||
class InstAlpha<bits<6> op, string asmstr, InstrItinClass itin> : Instruction {
|
||||
field bits<32> Inst;
|
||||
let Namespace = "Alpha";
|
||||
let AsmString = asmstr;
|
||||
let Inst{31-26} = op;
|
||||
let Itinerary = itin;
|
||||
}
|
||||
|
||||
|
||||
//3.3.1
|
||||
class MForm<bits<6> opcode, bit load, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let canFoldAsLoad = load;
|
||||
let Defs = [R28]; //We may use this for frame index calculations, so reserve it here
|
||||
|
||||
bits<5> Ra;
|
||||
bits<16> disp;
|
||||
bits<5> Rb;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-0} = disp;
|
||||
}
|
||||
class MfcForm<bits<6> opcode, bits<16> fc, string asmstr, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
bits<5> Ra;
|
||||
|
||||
let OutOperandList = (outs GPRC:$RA);
|
||||
let InOperandList = (ins);
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = 0;
|
||||
let Inst{15-0} = fc;
|
||||
}
|
||||
class MfcPForm<bits<6> opcode, bits<16> fc, string asmstr, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins);
|
||||
let Inst{25-21} = 0;
|
||||
let Inst{20-16} = 0;
|
||||
let Inst{15-0} = fc;
|
||||
}
|
||||
|
||||
class MbrForm<bits<6> opcode, bits<2> TB, dag OL, string asmstr, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
bits<5> Ra;
|
||||
bits<5> Rb;
|
||||
bits<14> disp;
|
||||
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = OL;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-14} = TB;
|
||||
let Inst{13-0} = disp;
|
||||
}
|
||||
class MbrpForm<bits<6> opcode, bits<2> TB, dag OL, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern=pattern;
|
||||
bits<5> Ra;
|
||||
bits<5> Rb;
|
||||
bits<14> disp;
|
||||
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = OL;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-14} = TB;
|
||||
let Inst{13-0} = disp;
|
||||
}
|
||||
|
||||
//3.3.2
|
||||
def target : Operand<OtherVT> {}
|
||||
|
||||
let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
|
||||
class BFormN<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = OL;
|
||||
bits<64> Opc; //dummy
|
||||
bits<5> Ra;
|
||||
bits<21> disp;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-0} = disp;
|
||||
}
|
||||
}
|
||||
|
||||
let isBranch = 1, isTerminator = 1 in
|
||||
class BFormD<bits<6> opcode, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins target:$DISP);
|
||||
bits<5> Ra;
|
||||
bits<21> disp;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-0} = disp;
|
||||
}
|
||||
|
||||
//3.3.3
|
||||
class OForm<bits<6> opcode, bits<7> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs GPRC:$RC);
|
||||
let InOperandList = (ins GPRC:$RA, GPRC:$RB);
|
||||
|
||||
bits<5> Rc;
|
||||
bits<5> Ra;
|
||||
bits<5> Rb;
|
||||
bits<7> Function = fun;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-13} = 0;
|
||||
let Inst{12} = 0;
|
||||
let Inst{11-5} = Function;
|
||||
let Inst{4-0} = Rc;
|
||||
}
|
||||
|
||||
class OForm2<bits<6> opcode, bits<7> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs GPRC:$RC);
|
||||
let InOperandList = (ins GPRC:$RB);
|
||||
|
||||
bits<5> Rc;
|
||||
bits<5> Rb;
|
||||
bits<7> Function = fun;
|
||||
|
||||
let Inst{25-21} = 31;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-13} = 0;
|
||||
let Inst{12} = 0;
|
||||
let Inst{11-5} = Function;
|
||||
let Inst{4-0} = Rc;
|
||||
}
|
||||
|
||||
class OForm4<bits<6> opcode, bits<7> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs GPRC:$RDEST);
|
||||
let InOperandList = (ins GPRC:$RCOND, GPRC:$RTRUE, GPRC:$RFALSE);
|
||||
let Constraints = "$RFALSE = $RDEST";
|
||||
let DisableEncoding = "$RFALSE";
|
||||
|
||||
bits<5> Rc;
|
||||
bits<5> Ra;
|
||||
bits<5> Rb;
|
||||
bits<7> Function = fun;
|
||||
|
||||
// let Constraints = "$RFALSE = $RDEST";
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-16} = Rb;
|
||||
let Inst{15-13} = 0;
|
||||
let Inst{12} = 0;
|
||||
let Inst{11-5} = Function;
|
||||
let Inst{4-0} = Rc;
|
||||
}
|
||||
|
||||
|
||||
class OFormL<bits<6> opcode, bits<7> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs GPRC:$RC);
|
||||
let InOperandList = (ins GPRC:$RA, u8imm:$L);
|
||||
|
||||
bits<5> Rc;
|
||||
bits<5> Ra;
|
||||
bits<8> LIT;
|
||||
bits<7> Function = fun;
|
||||
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-13} = LIT;
|
||||
let Inst{12} = 1;
|
||||
let Inst{11-5} = Function;
|
||||
let Inst{4-0} = Rc;
|
||||
}
|
||||
|
||||
class OForm4L<bits<6> opcode, bits<7> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
let OutOperandList = (outs GPRC:$RDEST);
|
||||
let InOperandList = (ins GPRC:$RCOND, s64imm:$RTRUE, GPRC:$RFALSE);
|
||||
let Constraints = "$RFALSE = $RDEST";
|
||||
let DisableEncoding = "$RFALSE";
|
||||
|
||||
bits<5> Rc;
|
||||
bits<5> Ra;
|
||||
bits<8> LIT;
|
||||
bits<7> Function = fun;
|
||||
|
||||
// let Constraints = "$RFALSE = $RDEST";
|
||||
let Inst{25-21} = Ra;
|
||||
let Inst{20-13} = LIT;
|
||||
let Inst{12} = 1;
|
||||
let Inst{11-5} = Function;
|
||||
let Inst{4-0} = Rc;
|
||||
}
|
||||
|
||||
//3.3.4
|
||||
class FPForm<bits<6> opcode, bits<11> fun, string asmstr, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let Pattern = pattern;
|
||||
|
||||
bits<5> Fc;
|
||||
bits<5> Fa;
|
||||
bits<5> Fb;
|
||||
bits<11> Function = fun;
|
||||
|
||||
let Inst{25-21} = Fa;
|
||||
let Inst{20-16} = Fb;
|
||||
let Inst{15-5} = Function;
|
||||
let Inst{4-0} = Fc;
|
||||
}
|
||||
|
||||
//3.3.5
|
||||
class PALForm<bits<6> opcode, dag OL, string asmstr, InstrItinClass itin>
|
||||
: InstAlpha<opcode, asmstr, itin> {
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = OL;
|
||||
bits<26> Function;
|
||||
|
||||
let Inst{25-0} = Function;
|
||||
}
|
||||
|
||||
|
||||
// Pseudo instructions.
|
||||
class PseudoInstAlpha<dag OOL, dag IOL, string nm, list<dag> pattern, InstrItinClass itin>
|
||||
: InstAlpha<0, nm, itin> {
|
||||
let OutOperandList = OOL;
|
||||
let InOperandList = IOL;
|
||||
let Pattern = pattern;
|
||||
|
||||
}
|
@ -1,382 +0,0 @@
|
||||
//===- AlphaInstrInfo.cpp - Alpha 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 Alpha implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaMachineFunctionInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
#define GET_INSTRINFO_CTOR
|
||||
#include "AlphaGenInstrInfo.inc"
|
||||
using namespace llvm;
|
||||
|
||||
AlphaInstrInfo::AlphaInstrInfo()
|
||||
: AlphaGenInstrInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP),
|
||||
RI(*this) {
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
case Alpha::LDL:
|
||||
case Alpha::LDQ:
|
||||
case Alpha::LDBU:
|
||||
case Alpha::LDWU:
|
||||
case Alpha::LDS:
|
||||
case Alpha::LDT:
|
||||
if (MI->getOperand(1).isFI()) {
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned
|
||||
AlphaInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
case Alpha::STL:
|
||||
case Alpha::STQ:
|
||||
case Alpha::STB:
|
||||
case Alpha::STW:
|
||||
case Alpha::STS:
|
||||
case Alpha::STT:
|
||||
if (MI->getOperand(1).isFI()) {
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool isAlphaIntCondCode(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case Alpha::BEQ:
|
||||
case Alpha::BNE:
|
||||
case Alpha::BGE:
|
||||
case Alpha::BGT:
|
||||
case Alpha::BLE:
|
||||
case Alpha::BLT:
|
||||
case Alpha::BLBC:
|
||||
case Alpha::BLBS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const {
|
||||
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
|
||||
assert((Cond.size() == 2 || Cond.size() == 0) &&
|
||||
"Alpha branch conditions have two components!");
|
||||
|
||||
// One-way branch.
|
||||
if (FBB == 0) {
|
||||
if (Cond.empty()) // Unconditional branch
|
||||
BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(TBB);
|
||||
else // Conditional branch
|
||||
if (isAlphaIntCondCode(Cond[0].getImm()))
|
||||
BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
else
|
||||
BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Two-way Conditional Branch.
|
||||
if (isAlphaIntCondCode(Cond[0].getImm()))
|
||||
BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
else
|
||||
BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
|
||||
.addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
|
||||
BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(FBB);
|
||||
return 2;
|
||||
}
|
||||
|
||||
void AlphaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const {
|
||||
if (Alpha::GPRCRegClass.contains(DestReg, SrcReg)) {
|
||||
BuildMI(MBB, MI, DL, get(Alpha::BISr), DestReg)
|
||||
.addReg(SrcReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
} else if (Alpha::F4RCRegClass.contains(DestReg, SrcReg)) {
|
||||
BuildMI(MBB, MI, DL, get(Alpha::CPYSS), DestReg)
|
||||
.addReg(SrcReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
} else if (Alpha::F8RCRegClass.contains(DestReg, SrcReg)) {
|
||||
BuildMI(MBB, MI, DL, get(Alpha::CPYST), DestReg)
|
||||
.addReg(SrcReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
} else {
|
||||
llvm_unreachable("Attempt to copy register that is not GPR or FPR");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned SrcReg, bool isKill, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
//cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
|
||||
// << FrameIdx << "\n";
|
||||
//BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
|
||||
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
if (RC == Alpha::F4RCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::STS))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else if (RC == Alpha::F8RCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::STT))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else if (RC == Alpha::GPRCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::STQ))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else
|
||||
llvm_unreachable("Unhandled register class");
|
||||
}
|
||||
|
||||
void
|
||||
AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI,
|
||||
unsigned DestReg, int FrameIdx,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
//cerr << "Trying to load " << getPrettyName(DestReg) << " to "
|
||||
// << FrameIdx << "\n";
|
||||
DebugLoc DL;
|
||||
if (MI != MBB.end()) DL = MI->getDebugLoc();
|
||||
|
||||
if (RC == Alpha::F4RCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::LDS), DestReg)
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else if (RC == Alpha::F8RCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::LDT), DestReg)
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else if (RC == Alpha::GPRCRegisterClass)
|
||||
BuildMI(MBB, MI, DL, get(Alpha::LDQ), DestReg)
|
||||
.addFrameIndex(FrameIdx).addReg(Alpha::F31);
|
||||
else
|
||||
llvm_unreachable("Unhandled register class");
|
||||
}
|
||||
|
||||
static unsigned AlphaRevCondCode(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case Alpha::BEQ: return Alpha::BNE;
|
||||
case Alpha::BNE: return Alpha::BEQ;
|
||||
case Alpha::BGE: return Alpha::BLT;
|
||||
case Alpha::BGT: return Alpha::BLE;
|
||||
case Alpha::BLE: return Alpha::BGT;
|
||||
case Alpha::BLT: return Alpha::BGE;
|
||||
case Alpha::BLBC: return Alpha::BLBS;
|
||||
case Alpha::BLBS: return Alpha::BLBC;
|
||||
case Alpha::FBEQ: return Alpha::FBNE;
|
||||
case Alpha::FBNE: return Alpha::FBEQ;
|
||||
case Alpha::FBGE: return Alpha::FBLT;
|
||||
case Alpha::FBGT: return Alpha::FBLE;
|
||||
case Alpha::FBLE: return Alpha::FBGT;
|
||||
case Alpha::FBLT: return Alpha::FBGE;
|
||||
default:
|
||||
llvm_unreachable("Unknown opcode");
|
||||
}
|
||||
return 0; // Not reached
|
||||
}
|
||||
|
||||
// Branch analysis.
|
||||
bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const {
|
||||
// If the block has no terminators, it just falls into the block after it.
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
if (I == MBB.begin())
|
||||
return false;
|
||||
--I;
|
||||
while (I->isDebugValue()) {
|
||||
if (I == MBB.begin())
|
||||
return false;
|
||||
--I;
|
||||
}
|
||||
if (!isUnpredicatedTerminator(I))
|
||||
return false;
|
||||
|
||||
// Get the last instruction in the block.
|
||||
MachineInstr *LastInst = I;
|
||||
|
||||
// If there is only one terminator instruction, process it.
|
||||
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
|
||||
if (LastInst->getOpcode() == Alpha::BR) {
|
||||
TBB = LastInst->getOperand(0).getMBB();
|
||||
return false;
|
||||
} else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
|
||||
LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
|
||||
// Block ends with fall-through condbranch.
|
||||
TBB = LastInst->getOperand(2).getMBB();
|
||||
Cond.push_back(LastInst->getOperand(0));
|
||||
Cond.push_back(LastInst->getOperand(1));
|
||||
return false;
|
||||
}
|
||||
// Otherwise, don't know what this is.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the instruction before it if it's a terminator.
|
||||
MachineInstr *SecondLastInst = I;
|
||||
|
||||
// If there are three terminators, we don't know what sort of block this is.
|
||||
if (SecondLastInst && I != MBB.begin() &&
|
||||
isUnpredicatedTerminator(--I))
|
||||
return true;
|
||||
|
||||
// If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
|
||||
if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
|
||||
SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) &&
|
||||
LastInst->getOpcode() == Alpha::BR) {
|
||||
TBB = SecondLastInst->getOperand(2).getMBB();
|
||||
Cond.push_back(SecondLastInst->getOperand(0));
|
||||
Cond.push_back(SecondLastInst->getOperand(1));
|
||||
FBB = LastInst->getOperand(0).getMBB();
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the block ends with two Alpha::BRs, handle it. The second one is not
|
||||
// executed, so remove it.
|
||||
if (SecondLastInst->getOpcode() == Alpha::BR &&
|
||||
LastInst->getOpcode() == Alpha::BR) {
|
||||
TBB = SecondLastInst->getOperand(0).getMBB();
|
||||
I = LastInst;
|
||||
if (AllowModify)
|
||||
I->eraseFromParent();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, can't handle this.
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
|
||||
MachineBasicBlock::iterator I = MBB.end();
|
||||
if (I == MBB.begin()) return 0;
|
||||
--I;
|
||||
while (I->isDebugValue()) {
|
||||
if (I == MBB.begin())
|
||||
return 0;
|
||||
--I;
|
||||
}
|
||||
if (I->getOpcode() != Alpha::BR &&
|
||||
I->getOpcode() != Alpha::COND_BRANCH_I &&
|
||||
I->getOpcode() != Alpha::COND_BRANCH_F)
|
||||
return 0;
|
||||
|
||||
// Remove the branch.
|
||||
I->eraseFromParent();
|
||||
|
||||
I = MBB.end();
|
||||
|
||||
if (I == MBB.begin()) return 1;
|
||||
--I;
|
||||
if (I->getOpcode() != Alpha::COND_BRANCH_I &&
|
||||
I->getOpcode() != Alpha::COND_BRANCH_F)
|
||||
return 1;
|
||||
|
||||
// Remove the branch.
|
||||
I->eraseFromParent();
|
||||
return 2;
|
||||
}
|
||||
|
||||
void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const {
|
||||
DebugLoc DL;
|
||||
BuildMI(MBB, MI, DL, get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31)
|
||||
.addReg(Alpha::R31);
|
||||
}
|
||||
|
||||
bool AlphaInstrInfo::
|
||||
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
|
||||
assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
|
||||
Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
|
||||
AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
|
||||
unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg();
|
||||
if (GlobalBaseReg != 0)
|
||||
return GlobalBaseReg;
|
||||
|
||||
// Insert the set of GlobalBaseReg into the first MBB of the function
|
||||
MachineBasicBlock &FirstMBB = MF->front();
|
||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
|
||||
|
||||
GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
|
||||
GlobalBaseReg).addReg(Alpha::R29);
|
||||
RegInfo.addLiveIn(Alpha::R29);
|
||||
|
||||
AlphaFI->setGlobalBaseReg(GlobalBaseReg);
|
||||
return GlobalBaseReg;
|
||||
}
|
||||
|
||||
/// getGlobalRetAddr - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
|
||||
AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
|
||||
unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
|
||||
if (GlobalRetAddr != 0)
|
||||
return GlobalRetAddr;
|
||||
|
||||
// Insert the set of GlobalRetAddr into the first MBB of the function
|
||||
MachineBasicBlock &FirstMBB = MF->front();
|
||||
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
||||
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
|
||||
|
||||
GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
|
||||
BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
|
||||
GlobalRetAddr).addReg(Alpha::R26);
|
||||
RegInfo.addLiveIn(Alpha::R26);
|
||||
|
||||
AlphaFI->setGlobalRetAddr(GlobalRetAddr);
|
||||
return GlobalRetAddr;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
//===- AlphaInstrInfo.h - Alpha 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 Alpha implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHAINSTRUCTIONINFO_H
|
||||
#define ALPHAINSTRUCTIONINFO_H
|
||||
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "AlphaRegisterInfo.h"
|
||||
|
||||
#define GET_INSTRINFO_HEADER
|
||||
#include "AlphaGenInstrInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AlphaInstrInfo : public AlphaGenInstrInfo {
|
||||
const AlphaRegisterInfo RI;
|
||||
public:
|
||||
AlphaInstrInfo();
|
||||
|
||||
/// 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 AlphaRegisterInfo &getRegisterInfo() const { return RI; }
|
||||
|
||||
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const;
|
||||
virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const;
|
||||
|
||||
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const;
|
||||
virtual void copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const;
|
||||
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned SrcReg, bool isKill, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
bool AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
bool AllowModify) const;
|
||||
unsigned RemoveBranch(MachineBasicBlock &MBB) const;
|
||||
void insertNoop(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MI) const;
|
||||
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
|
||||
/// getGlobalBaseReg - Return a virtual register initialized with the
|
||||
/// the global base register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned getGlobalBaseReg(MachineFunction *MF) const;
|
||||
|
||||
/// getGlobalRetAddr - Return a virtual register initialized with the
|
||||
/// the global return address register value. Output instructions required to
|
||||
/// initialize the register in the function entry block, if necessary.
|
||||
///
|
||||
unsigned getGlobalRetAddr(MachineFunction *MF) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,158 +0,0 @@
|
||||
//===-- AlphaLLRP.cpp - Alpha Load Load Replay Trap elimination pass. -- --===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Here we check for potential replay traps introduced by the spiller
|
||||
// We also align some branch targets if we can do so for free.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "alpha-nops"
|
||||
#include "Alpha.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/ADT/SetOperations.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
using namespace llvm;
|
||||
|
||||
STATISTIC(nopintro, "Number of nops inserted");
|
||||
STATISTIC(nopalign, "Number of nops inserted for alignment");
|
||||
|
||||
namespace {
|
||||
cl::opt<bool>
|
||||
AlignAll("alpha-align-all", cl::Hidden,
|
||||
cl::desc("Align all blocks"));
|
||||
|
||||
struct AlphaLLRPPass : public MachineFunctionPass {
|
||||
/// Target machine description which we query for reg. names, data
|
||||
/// layout, etc.
|
||||
///
|
||||
AlphaTargetMachine &TM;
|
||||
|
||||
static char ID;
|
||||
AlphaLLRPPass(AlphaTargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TM(tm) { }
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Alpha NOP inserter";
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &F) {
|
||||
const TargetInstrInfo *TII = F.getTarget().getInstrInfo();
|
||||
bool Changed = false;
|
||||
MachineInstr* prev[3] = {0,0,0};
|
||||
DebugLoc dl;
|
||||
unsigned count = 0;
|
||||
for (MachineFunction::iterator FI = F.begin(), FE = F.end();
|
||||
FI != FE; ++FI) {
|
||||
MachineBasicBlock& MBB = *FI;
|
||||
bool ub = false;
|
||||
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
|
||||
if (count%4 == 0)
|
||||
prev[0] = prev[1] = prev[2] = 0; //Slots cleared at fetch boundary
|
||||
++count;
|
||||
MachineInstr *MI = I++;
|
||||
switch (MI->getOpcode()) {
|
||||
case Alpha::LDQ: case Alpha::LDL:
|
||||
case Alpha::LDWU: case Alpha::LDBU:
|
||||
case Alpha::LDT: case Alpha::LDS:
|
||||
case Alpha::STQ: case Alpha::STL:
|
||||
case Alpha::STW: case Alpha::STB:
|
||||
case Alpha::STT: case Alpha::STS:
|
||||
if (MI->getOperand(2).getReg() == Alpha::R30) {
|
||||
if (prev[0] &&
|
||||
prev[0]->getOperand(2).getReg() == MI->getOperand(2).getReg()&&
|
||||
prev[0]->getOperand(1).getImm() == MI->getOperand(1).getImm()){
|
||||
prev[0] = prev[1];
|
||||
prev[1] = prev[2];
|
||||
prev[2] = 0;
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31)
|
||||
.addReg(Alpha::R31);
|
||||
Changed = true; nopintro += 1;
|
||||
count += 1;
|
||||
} else if (prev[1]
|
||||
&& prev[1]->getOperand(2).getReg() ==
|
||||
MI->getOperand(2).getReg()
|
||||
&& prev[1]->getOperand(1).getImm() ==
|
||||
MI->getOperand(1).getImm()) {
|
||||
prev[0] = prev[2];
|
||||
prev[1] = prev[2] = 0;
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31)
|
||||
.addReg(Alpha::R31);
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31)
|
||||
.addReg(Alpha::R31);
|
||||
Changed = true; nopintro += 2;
|
||||
count += 2;
|
||||
} else if (prev[2]
|
||||
&& prev[2]->getOperand(2).getReg() ==
|
||||
MI->getOperand(2).getReg()
|
||||
&& prev[2]->getOperand(1).getImm() ==
|
||||
MI->getOperand(1).getImm()) {
|
||||
prev[0] = prev[1] = prev[2] = 0;
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31).addReg(Alpha::R31);
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31).addReg(Alpha::R31);
|
||||
BuildMI(MBB, MI, dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31).addReg(Alpha::R31);
|
||||
Changed = true; nopintro += 3;
|
||||
count += 3;
|
||||
}
|
||||
prev[0] = prev[1];
|
||||
prev[1] = prev[2];
|
||||
prev[2] = MI;
|
||||
break;
|
||||
}
|
||||
prev[0] = prev[1];
|
||||
prev[1] = prev[2];
|
||||
prev[2] = 0;
|
||||
break;
|
||||
case Alpha::ALTENT:
|
||||
case Alpha::MEMLABEL:
|
||||
case Alpha::PCLABEL:
|
||||
--count;
|
||||
break;
|
||||
case Alpha::BR:
|
||||
case Alpha::JMP:
|
||||
ub = true;
|
||||
//fall through
|
||||
default:
|
||||
prev[0] = prev[1];
|
||||
prev[1] = prev[2];
|
||||
prev[2] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ub || AlignAll) {
|
||||
//we can align stuff for free at this point
|
||||
while (count % 4) {
|
||||
BuildMI(MBB, MBB.end(), dl, TII->get(Alpha::BISr), Alpha::R31)
|
||||
.addReg(Alpha::R31).addReg(Alpha::R31);
|
||||
++count;
|
||||
++nopalign;
|
||||
prev[0] = prev[1];
|
||||
prev[1] = prev[2];
|
||||
prev[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
};
|
||||
char AlphaLLRPPass::ID = 0;
|
||||
} // end of anonymous namespace
|
||||
|
||||
FunctionPass *llvm::createAlphaLLRPPass(AlphaTargetMachine &tm) {
|
||||
return new AlphaLLRPPass(tm);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//====- AlphaMachineFuctionInfo.h - Alpha 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 Alpha-specific per-machine-function information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHAMACHINEFUNCTIONINFO_H
|
||||
#define ALPHAMACHINEFUNCTIONINFO_H
|
||||
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// AlphaMachineFunctionInfo - This class is derived from MachineFunction
|
||||
/// private Alpha target-specific information for each MachineFunction.
|
||||
class AlphaMachineFunctionInfo : public MachineFunctionInfo {
|
||||
/// GlobalBaseReg - keeps track of the virtual register initialized for
|
||||
/// use as the global base register. This is used for PIC in some PIC
|
||||
/// relocation models.
|
||||
unsigned GlobalBaseReg;
|
||||
|
||||
/// GlobalRetAddr = keeps track of the virtual register initialized for
|
||||
/// the return address value.
|
||||
unsigned GlobalRetAddr;
|
||||
|
||||
/// VarArgsOffset - What is the offset to the first vaarg
|
||||
int VarArgsOffset;
|
||||
/// VarArgsBase - What is the base FrameIndex
|
||||
int VarArgsBase;
|
||||
|
||||
public:
|
||||
AlphaMachineFunctionInfo() : GlobalBaseReg(0), GlobalRetAddr(0),
|
||||
VarArgsOffset(0), VarArgsBase(0) {}
|
||||
|
||||
explicit AlphaMachineFunctionInfo(MachineFunction &MF) : GlobalBaseReg(0),
|
||||
GlobalRetAddr(0),
|
||||
VarArgsOffset(0),
|
||||
VarArgsBase(0) {}
|
||||
|
||||
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
|
||||
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
|
||||
|
||||
unsigned getGlobalRetAddr() const { return GlobalRetAddr; }
|
||||
void setGlobalRetAddr(unsigned Reg) { GlobalRetAddr = Reg; }
|
||||
|
||||
int getVarArgsOffset() const { return VarArgsOffset; }
|
||||
void setVarArgsOffset(int Offset) { VarArgsOffset = Offset; }
|
||||
|
||||
int getVarArgsBase() const { return VarArgsBase; }
|
||||
void setVarArgsBase(int Base) { VarArgsBase = Base; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,199 +0,0 @@
|
||||
//===- AlphaRegisterInfo.cpp - Alpha 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 Alpha implementation of the TargetRegisterInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "reginfo"
|
||||
#include "Alpha.h"
|
||||
#include "AlphaRegisterInfo.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <cstdlib>
|
||||
|
||||
#define GET_REGINFO_TARGET_DESC
|
||||
#include "AlphaGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii)
|
||||
: AlphaGenRegisterInfo(Alpha::R26), TII(tii) {
|
||||
}
|
||||
|
||||
static long getUpper16(long l) {
|
||||
long y = l / Alpha::IMM_MULT;
|
||||
if (l % Alpha::IMM_MULT > Alpha::IMM_HIGH)
|
||||
++y;
|
||||
return y;
|
||||
}
|
||||
|
||||
static long getLower16(long l) {
|
||||
long h = getUpper16(l);
|
||||
return l - h * Alpha::IMM_MULT;
|
||||
}
|
||||
|
||||
const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
|
||||
const {
|
||||
static const unsigned CalleeSavedRegs[] = {
|
||||
Alpha::R9, Alpha::R10,
|
||||
Alpha::R11, Alpha::R12,
|
||||
Alpha::R13, Alpha::R14,
|
||||
Alpha::F2, Alpha::F3,
|
||||
Alpha::F4, Alpha::F5,
|
||||
Alpha::F6, Alpha::F7,
|
||||
Alpha::F8, Alpha::F9, 0
|
||||
};
|
||||
return CalleeSavedRegs;
|
||||
}
|
||||
|
||||
BitVector AlphaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
BitVector Reserved(getNumRegs());
|
||||
Reserved.set(Alpha::R15);
|
||||
Reserved.set(Alpha::R29);
|
||||
Reserved.set(Alpha::R30);
|
||||
Reserved.set(Alpha::R31);
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Stack Frame Processing methods
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void AlphaRegisterInfo::
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
if (TFI->hasFP(MF)) {
|
||||
// If we have a frame pointer, turn the adjcallstackup instruction into a
|
||||
// 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
|
||||
// <amt>'
|
||||
MachineInstr *Old = I;
|
||||
uint64_t Amount = Old->getOperand(0).getImm();
|
||||
if (Amount != 0) {
|
||||
// We need to keep the stack aligned properly. To do this, we round the
|
||||
// amount of space needed for the outgoing arguments up to the next
|
||||
// alignment boundary.
|
||||
unsigned Align = TFI->getStackAlignment();
|
||||
Amount = (Amount+Align-1)/Align*Align;
|
||||
|
||||
MachineInstr *New;
|
||||
if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) {
|
||||
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Alpha::LDA), Alpha::R30)
|
||||
.addImm(-Amount).addReg(Alpha::R30);
|
||||
} else {
|
||||
assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP);
|
||||
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Alpha::LDA), Alpha::R30)
|
||||
.addImm(Amount).addReg(Alpha::R30);
|
||||
}
|
||||
|
||||
// Replace the pseudo instruction with a new instruction...
|
||||
MBB.insert(I, New);
|
||||
}
|
||||
}
|
||||
|
||||
MBB.erase(I);
|
||||
}
|
||||
|
||||
//Alpha has a slightly funny stack:
|
||||
//Args
|
||||
//<- incoming SP
|
||||
//fixed locals (and spills, callee saved, etc)
|
||||
//<- FP
|
||||
//variable locals
|
||||
//<- SP
|
||||
|
||||
void
|
||||
AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS) const {
|
||||
assert(SPAdj == 0 && "Unexpected");
|
||||
|
||||
unsigned i = 0;
|
||||
MachineInstr &MI = *II;
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
bool FP = TFI->hasFP(MF);
|
||||
|
||||
while (!MI.getOperand(i).isFI()) {
|
||||
++i;
|
||||
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
|
||||
}
|
||||
|
||||
int FrameIndex = MI.getOperand(i).getIndex();
|
||||
|
||||
// Add the base register of R30 (SP) or R15 (FP).
|
||||
MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30, false);
|
||||
|
||||
// Now add the frame object offset to the offset from the virtual frame index.
|
||||
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
||||
|
||||
DEBUG(errs() << "FI: " << FrameIndex << " Offset: " << Offset << "\n");
|
||||
|
||||
Offset += MF.getFrameInfo()->getStackSize();
|
||||
|
||||
DEBUG(errs() << "Corrected Offset " << Offset
|
||||
<< " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n");
|
||||
|
||||
if (Offset > Alpha::IMM_HIGH || Offset < Alpha::IMM_LOW) {
|
||||
DEBUG(errs() << "Unconditionally using R28 for evil purposes Offset: "
|
||||
<< Offset << "\n");
|
||||
//so in this case, we need to use a temporary register, and move the
|
||||
//original inst off the SP/FP
|
||||
//fix up the old:
|
||||
MI.getOperand(i + 1).ChangeToRegister(Alpha::R28, false);
|
||||
MI.getOperand(i).ChangeToImmediate(getLower16(Offset));
|
||||
//insert the new
|
||||
MachineInstr* nMI=BuildMI(MF, MI.getDebugLoc(),
|
||||
TII.get(Alpha::LDAH), Alpha::R28)
|
||||
.addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30);
|
||||
MBB.insert(II, nMI);
|
||||
} else {
|
||||
MI.getOperand(i).ChangeToImmediate(Offset);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned AlphaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
return TFI->hasFP(MF) ? Alpha::R15 : Alpha::R30;
|
||||
}
|
||||
|
||||
unsigned AlphaRegisterInfo::getEHExceptionRegister() const {
|
||||
llvm_unreachable("What is the exception register");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned AlphaRegisterInfo::getEHHandlerRegister() const {
|
||||
llvm_unreachable("What is the exception handler register");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string AlphaRegisterInfo::getPrettyName(unsigned reg)
|
||||
{
|
||||
std::string s(AlphaRegDesc[reg].Name);
|
||||
return s;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
//===- AlphaRegisterInfo.h - Alpha Register Information Impl ----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the Alpha implementation of the TargetRegisterInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHAREGISTERINFO_H
|
||||
#define ALPHAREGISTERINFO_H
|
||||
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#define GET_REGINFO_HEADER
|
||||
#include "AlphaGenRegisterInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetInstrInfo;
|
||||
class Type;
|
||||
|
||||
struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
|
||||
const TargetInstrInfo &TII;
|
||||
|
||||
AlphaRegisterInfo(const TargetInstrInfo &tii);
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const;
|
||||
|
||||
void eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const;
|
||||
|
||||
void eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS = NULL) const;
|
||||
|
||||
// Debug information queries.
|
||||
unsigned getFrameRegister(const MachineFunction &MF) const;
|
||||
|
||||
// Exception handling queries.
|
||||
unsigned getEHExceptionRegister() const;
|
||||
unsigned getEHHandlerRegister() const;
|
||||
|
||||
static std::string getPrettyName(unsigned reg);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,133 +0,0 @@
|
||||
//===- AlphaRegisterInfo.td - The Alpha Register File ------*- tablegen -*-===//
|
||||
//
|
||||
// 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 Alpha register set.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class AlphaReg<string n> : Register<n> {
|
||||
field bits<5> Num;
|
||||
let Namespace = "Alpha";
|
||||
}
|
||||
|
||||
// We identify all our registers with a 5-bit ID, for consistency's sake.
|
||||
|
||||
// GPR - One of the 32 32-bit general-purpose registers
|
||||
class GPR<bits<5> num, string n> : AlphaReg<n> {
|
||||
let Num = num;
|
||||
}
|
||||
|
||||
// FPR - One of the 32 64-bit floating-point registers
|
||||
class FPR<bits<5> num, string n> : AlphaReg<n> {
|
||||
let Num = num;
|
||||
}
|
||||
|
||||
//#define FP $15
|
||||
//#define RA $26
|
||||
//#define PV $27
|
||||
//#define GP $29
|
||||
//#define SP $30
|
||||
|
||||
// General-purpose registers
|
||||
def R0 : GPR< 0, "$0">, DwarfRegNum<[0]>;
|
||||
def R1 : GPR< 1, "$1">, DwarfRegNum<[1]>;
|
||||
def R2 : GPR< 2, "$2">, DwarfRegNum<[2]>;
|
||||
def R3 : GPR< 3, "$3">, DwarfRegNum<[3]>;
|
||||
def R4 : GPR< 4, "$4">, DwarfRegNum<[4]>;
|
||||
def R5 : GPR< 5, "$5">, DwarfRegNum<[5]>;
|
||||
def R6 : GPR< 6, "$6">, DwarfRegNum<[6]>;
|
||||
def R7 : GPR< 7, "$7">, DwarfRegNum<[7]>;
|
||||
def R8 : GPR< 8, "$8">, DwarfRegNum<[8]>;
|
||||
def R9 : GPR< 9, "$9">, DwarfRegNum<[9]>;
|
||||
def R10 : GPR<10, "$10">, DwarfRegNum<[10]>;
|
||||
def R11 : GPR<11, "$11">, DwarfRegNum<[11]>;
|
||||
def R12 : GPR<12, "$12">, DwarfRegNum<[12]>;
|
||||
def R13 : GPR<13, "$13">, DwarfRegNum<[13]>;
|
||||
def R14 : GPR<14, "$14">, DwarfRegNum<[14]>;
|
||||
def R15 : GPR<15, "$15">, DwarfRegNum<[15]>;
|
||||
def R16 : GPR<16, "$16">, DwarfRegNum<[16]>;
|
||||
def R17 : GPR<17, "$17">, DwarfRegNum<[17]>;
|
||||
def R18 : GPR<18, "$18">, DwarfRegNum<[18]>;
|
||||
def R19 : GPR<19, "$19">, DwarfRegNum<[19]>;
|
||||
def R20 : GPR<20, "$20">, DwarfRegNum<[20]>;
|
||||
def R21 : GPR<21, "$21">, DwarfRegNum<[21]>;
|
||||
def R22 : GPR<22, "$22">, DwarfRegNum<[22]>;
|
||||
def R23 : GPR<23, "$23">, DwarfRegNum<[23]>;
|
||||
def R24 : GPR<24, "$24">, DwarfRegNum<[24]>;
|
||||
def R25 : GPR<25, "$25">, DwarfRegNum<[25]>;
|
||||
def R26 : GPR<26, "$26">, DwarfRegNum<[26]>;
|
||||
def R27 : GPR<27, "$27">, DwarfRegNum<[27]>;
|
||||
def R28 : GPR<28, "$28">, DwarfRegNum<[28]>;
|
||||
def R29 : GPR<29, "$29">, DwarfRegNum<[29]>;
|
||||
def R30 : GPR<30, "$30">, DwarfRegNum<[30]>;
|
||||
def R31 : GPR<31, "$31">, DwarfRegNum<[31]>;
|
||||
|
||||
// Floating-point registers
|
||||
def F0 : FPR< 0, "$f0">, DwarfRegNum<[33]>;
|
||||
def F1 : FPR< 1, "$f1">, DwarfRegNum<[34]>;
|
||||
def F2 : FPR< 2, "$f2">, DwarfRegNum<[35]>;
|
||||
def F3 : FPR< 3, "$f3">, DwarfRegNum<[36]>;
|
||||
def F4 : FPR< 4, "$f4">, DwarfRegNum<[37]>;
|
||||
def F5 : FPR< 5, "$f5">, DwarfRegNum<[38]>;
|
||||
def F6 : FPR< 6, "$f6">, DwarfRegNum<[39]>;
|
||||
def F7 : FPR< 7, "$f7">, DwarfRegNum<[40]>;
|
||||
def F8 : FPR< 8, "$f8">, DwarfRegNum<[41]>;
|
||||
def F9 : FPR< 9, "$f9">, DwarfRegNum<[42]>;
|
||||
def F10 : FPR<10, "$f10">, DwarfRegNum<[43]>;
|
||||
def F11 : FPR<11, "$f11">, DwarfRegNum<[44]>;
|
||||
def F12 : FPR<12, "$f12">, DwarfRegNum<[45]>;
|
||||
def F13 : FPR<13, "$f13">, DwarfRegNum<[46]>;
|
||||
def F14 : FPR<14, "$f14">, DwarfRegNum<[47]>;
|
||||
def F15 : FPR<15, "$f15">, DwarfRegNum<[48]>;
|
||||
def F16 : FPR<16, "$f16">, DwarfRegNum<[49]>;
|
||||
def F17 : FPR<17, "$f17">, DwarfRegNum<[50]>;
|
||||
def F18 : FPR<18, "$f18">, DwarfRegNum<[51]>;
|
||||
def F19 : FPR<19, "$f19">, DwarfRegNum<[52]>;
|
||||
def F20 : FPR<20, "$f20">, DwarfRegNum<[53]>;
|
||||
def F21 : FPR<21, "$f21">, DwarfRegNum<[54]>;
|
||||
def F22 : FPR<22, "$f22">, DwarfRegNum<[55]>;
|
||||
def F23 : FPR<23, "$f23">, DwarfRegNum<[56]>;
|
||||
def F24 : FPR<24, "$f24">, DwarfRegNum<[57]>;
|
||||
def F25 : FPR<25, "$f25">, DwarfRegNum<[58]>;
|
||||
def F26 : FPR<26, "$f26">, DwarfRegNum<[59]>;
|
||||
def F27 : FPR<27, "$f27">, DwarfRegNum<[60]>;
|
||||
def F28 : FPR<28, "$f28">, DwarfRegNum<[61]>;
|
||||
def F29 : FPR<29, "$f29">, DwarfRegNum<[62]>;
|
||||
def F30 : FPR<30, "$f30">, DwarfRegNum<[63]>;
|
||||
def F31 : FPR<31, "$f31">, DwarfRegNum<[64]>;
|
||||
|
||||
// //#define FP $15
|
||||
// //#define RA $26
|
||||
// //#define PV $27
|
||||
// //#define GP $29
|
||||
// //#define SP $30
|
||||
// $28 is undefined after any and all calls
|
||||
|
||||
/// Register classes
|
||||
def GPRC : RegisterClass<"Alpha", [i64], 64, (add
|
||||
// Volatile
|
||||
R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
|
||||
R23, R24, R25, R28,
|
||||
//Special meaning, but volatile
|
||||
R27, //procedure address
|
||||
R26, //return address
|
||||
R29, //global offset table address
|
||||
// Non-volatile
|
||||
R9, R10, R11, R12, R13, R14,
|
||||
// Don't allocate 15, 30, 31
|
||||
R15, R30, R31)>; //zero
|
||||
|
||||
def F4RC : RegisterClass<"Alpha", [f32], 64, (add F0, F1,
|
||||
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
||||
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
|
||||
// Saved:
|
||||
F2, F3, F4, F5, F6, F7, F8, F9,
|
||||
F31)>; //zero
|
||||
|
||||
def F8RC : RegisterClass<"Alpha", [f64], 64, (add F4RC)>;
|
@ -1,31 +0,0 @@
|
||||
//===- AlphaRelocations.h - Alpha Code Relocations --------------*- 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 Alpha target-specific relocation types.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHARELOCATIONS_H
|
||||
#define ALPHARELOCATIONS_H
|
||||
|
||||
#include "llvm/CodeGen/MachineRelocation.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace Alpha {
|
||||
enum RelocationType {
|
||||
reloc_literal,
|
||||
reloc_gprellow,
|
||||
reloc_gprelhigh,
|
||||
reloc_gpdist,
|
||||
reloc_bsr
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,85 +0,0 @@
|
||||
//===- AlphaSchedule.td - Alpha Scheduling Definitions -----*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//This is table 2-2 from the 21264 compiler writers guide
|
||||
//modified some
|
||||
|
||||
//Pipelines
|
||||
|
||||
def L0 : FuncUnit;
|
||||
def L1 : FuncUnit;
|
||||
def FST0 : FuncUnit;
|
||||
def FST1 : FuncUnit;
|
||||
def U0 : FuncUnit;
|
||||
def U1 : FuncUnit;
|
||||
def FA : FuncUnit;
|
||||
def FM : FuncUnit;
|
||||
|
||||
def s_ild : InstrItinClass;
|
||||
def s_fld : InstrItinClass;
|
||||
def s_ist : InstrItinClass;
|
||||
def s_fst : InstrItinClass;
|
||||
def s_lda : InstrItinClass;
|
||||
def s_rpcc : InstrItinClass;
|
||||
def s_rx : InstrItinClass;
|
||||
def s_mxpr : InstrItinClass;
|
||||
def s_icbr : InstrItinClass;
|
||||
def s_ubr : InstrItinClass;
|
||||
def s_jsr : InstrItinClass;
|
||||
def s_iadd : InstrItinClass;
|
||||
def s_ilog : InstrItinClass;
|
||||
def s_ishf : InstrItinClass;
|
||||
def s_cmov : InstrItinClass;
|
||||
def s_imul : InstrItinClass;
|
||||
def s_imisc : InstrItinClass;
|
||||
def s_fbr : InstrItinClass;
|
||||
def s_fadd : InstrItinClass;
|
||||
def s_fmul : InstrItinClass;
|
||||
def s_fcmov : InstrItinClass;
|
||||
def s_fdivt : InstrItinClass;
|
||||
def s_fdivs : InstrItinClass;
|
||||
def s_fsqrts: InstrItinClass;
|
||||
def s_fsqrtt: InstrItinClass;
|
||||
def s_ftoi : InstrItinClass;
|
||||
def s_itof : InstrItinClass;
|
||||
def s_pseudo : InstrItinClass;
|
||||
|
||||
//Table 2-4 Instruction Class Latency in Cycles
|
||||
//modified some
|
||||
|
||||
def Alpha21264Itineraries : ProcessorItineraries<
|
||||
[L0, L1, FST0, FST1, U0, U1, FA, FM], [], [
|
||||
InstrItinData<s_ild , [InstrStage<3, [L0, L1]>]>,
|
||||
InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>,
|
||||
InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>,
|
||||
InstrItinData<s_fst , [InstrStage<0, [FST0, FST1, L0, L1]>]>,
|
||||
InstrItinData<s_lda , [InstrStage<1, [L0, L1, U0, U1]>]>,
|
||||
InstrItinData<s_rpcc , [InstrStage<1, [L1]>]>,
|
||||
InstrItinData<s_rx , [InstrStage<1, [L1]>]>,
|
||||
InstrItinData<s_mxpr , [InstrStage<1, [L0, L1]>]>,
|
||||
InstrItinData<s_icbr , [InstrStage<0, [U0, U1]>]>,
|
||||
InstrItinData<s_ubr , [InstrStage<3, [U0, U1]>]>,
|
||||
InstrItinData<s_jsr , [InstrStage<3, [L0]>]>,
|
||||
InstrItinData<s_iadd , [InstrStage<1, [L0, U0, L1, U1]>]>,
|
||||
InstrItinData<s_ilog , [InstrStage<1, [L0, U0, L1, U1]>]>,
|
||||
InstrItinData<s_ishf , [InstrStage<1, [U0, U1]>]>,
|
||||
InstrItinData<s_cmov , [InstrStage<1, [L0, U0, L1, U1]>]>,
|
||||
InstrItinData<s_imul , [InstrStage<7, [U1]>]>,
|
||||
InstrItinData<s_imisc , [InstrStage<3, [U0]>]>,
|
||||
InstrItinData<s_fbr , [InstrStage<0, [FA]>]>,
|
||||
InstrItinData<s_fadd , [InstrStage<6, [FA]>]>,
|
||||
InstrItinData<s_fmul , [InstrStage<6, [FM]>]>,
|
||||
InstrItinData<s_fcmov , [InstrStage<6, [FA]>]>,
|
||||
InstrItinData<s_fdivs , [InstrStage<12, [FA]>]>,
|
||||
InstrItinData<s_fdivt , [InstrStage<15, [FA]>]>,
|
||||
InstrItinData<s_fsqrts , [InstrStage<18, [FA]>]>,
|
||||
InstrItinData<s_fsqrtt , [InstrStage<33, [FA]>]>,
|
||||
InstrItinData<s_ftoi , [InstrStage<3, [FST0, FST1, L0, L1]>]>,
|
||||
InstrItinData<s_itof , [InstrStage<4, [L0, L1]>]>
|
||||
]>;
|
@ -1,23 +0,0 @@
|
||||
//===-- AlphaSelectionDAGInfo.cpp - Alpha 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 AlphaSelectionDAGInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "alpha-selectiondag-info"
|
||||
#include "AlphaTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
AlphaSelectionDAGInfo::AlphaSelectionDAGInfo(const AlphaTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
AlphaSelectionDAGInfo::~AlphaSelectionDAGInfo() {
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//===-- AlphaSelectionDAGInfo.h - Alpha 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 Alpha subclass for TargetSelectionDAGInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHASELECTIONDAGINFO_H
|
||||
#define ALPHASELECTIONDAGINFO_H
|
||||
|
||||
#include "llvm/Target/TargetSelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class AlphaTargetMachine;
|
||||
|
||||
class AlphaSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
explicit AlphaSelectionDAGInfo(const AlphaTargetMachine &TM);
|
||||
~AlphaSelectionDAGInfo();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,35 +0,0 @@
|
||||
//===- AlphaSubtarget.cpp - Alpha 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 Alpha specific subclass of TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AlphaSubtarget.h"
|
||||
#include "Alpha.h"
|
||||
|
||||
#define GET_SUBTARGETINFO_TARGET_DESC
|
||||
#define GET_SUBTARGETINFO_CTOR
|
||||
#include "AlphaGenSubtargetInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
AlphaSubtarget::AlphaSubtarget(const std::string &TT, const std::string &CPU,
|
||||
const std::string &FS)
|
||||
: AlphaGenSubtargetInfo(TT, CPU, FS), HasCT(false) {
|
||||
std::string CPUName = CPU;
|
||||
if (CPUName.empty())
|
||||
CPUName = "generic";
|
||||
|
||||
// Parse features string.
|
||||
ParseSubtargetFeatures(CPUName, FS);
|
||||
|
||||
// Initialize scheduling itinerary for the specified CPU.
|
||||
InstrItins = getInstrItineraryForCPU(CPUName);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//=====-- AlphaSubtarget.h - Define Subtarget for the Alpha --*- 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 Alpha specific subclass of TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHASUBTARGET_H
|
||||
#define ALPHASUBTARGET_H
|
||||
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
#include <string>
|
||||
|
||||
#define GET_SUBTARGETINFO_HEADER
|
||||
#include "AlphaGenSubtargetInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
class StringRe;
|
||||
|
||||
class AlphaSubtarget : public AlphaGenSubtargetInfo {
|
||||
protected:
|
||||
|
||||
bool HasCT;
|
||||
|
||||
InstrItineraryData InstrItins;
|
||||
|
||||
public:
|
||||
/// This constructor initializes the data members to match that
|
||||
/// of the specified triple.
|
||||
///
|
||||
AlphaSubtarget(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 hasCT() const { return HasCT; }
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -1,51 +0,0 @@
|
||||
//===-- AlphaTargetMachine.cpp - Define TargetMachine for Alpha -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "AlphaTargetMachine.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
extern "C" void LLVMInitializeAlphaTarget() {
|
||||
// Register the target.
|
||||
RegisterTargetMachine<AlphaTargetMachine> X(TheAlphaTarget);
|
||||
}
|
||||
|
||||
AlphaTargetMachine::AlphaTargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
Reloc::Model RM, CodeModel::Model CM)
|
||||
: LLVMTargetMachine(T, TT, CPU, FS, RM, CM),
|
||||
DataLayout("e-f128:128:128-n64"),
|
||||
FrameLowering(Subtarget),
|
||||
Subtarget(TT, CPU, FS),
|
||||
TLInfo(*this),
|
||||
TSInfo(*this) {
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pass Pipeline Configuration
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool AlphaTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createAlphaISelDag(*this));
|
||||
return false;
|
||||
}
|
||||
bool AlphaTargetMachine::addPreEmitPass(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
// Must run branch selection immediately preceding the asm printer
|
||||
PM.add(createAlphaBranchSelectionPass());
|
||||
PM.add(createAlphaLLRPPass(*this));
|
||||
return false;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
//===-- AlphaTargetMachine.h - Define TargetMachine for Alpha ---*- 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 Alpha-specific subclass of TargetMachine.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHA_TARGETMACHINE_H
|
||||
#define ALPHA_TARGETMACHINE_H
|
||||
|
||||
#include "AlphaInstrInfo.h"
|
||||
#include "AlphaISelLowering.h"
|
||||
#include "AlphaFrameLowering.h"
|
||||
#include "AlphaSelectionDAGInfo.h"
|
||||
#include "AlphaSubtarget.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class GlobalValue;
|
||||
|
||||
class AlphaTargetMachine : public LLVMTargetMachine {
|
||||
const TargetData DataLayout; // Calculates type size & alignment
|
||||
AlphaInstrInfo InstrInfo;
|
||||
AlphaFrameLowering FrameLowering;
|
||||
AlphaSubtarget Subtarget;
|
||||
AlphaTargetLowering TLInfo;
|
||||
AlphaSelectionDAGInfo TSInfo;
|
||||
|
||||
public:
|
||||
AlphaTargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
Reloc::Model RM, CodeModel::Model CM);
|
||||
|
||||
virtual const AlphaInstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetFrameLowering *getFrameLowering() const {
|
||||
return &FrameLowering;
|
||||
}
|
||||
virtual const AlphaSubtarget *getSubtargetImpl() const{ return &Subtarget; }
|
||||
virtual const AlphaRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
virtual const AlphaTargetLowering* getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const AlphaSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
|
||||
// Pass Pipeline Configuration
|
||||
virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,38 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS Alpha.td)
|
||||
|
||||
llvm_tablegen(AlphaGenRegisterInfo.inc -gen-register-info)
|
||||
llvm_tablegen(AlphaGenInstrInfo.inc -gen-instr-info)
|
||||
llvm_tablegen(AlphaGenAsmWriter.inc -gen-asm-writer)
|
||||
llvm_tablegen(AlphaGenDAGISel.inc -gen-dag-isel)
|
||||
llvm_tablegen(AlphaGenCallingConv.inc -gen-callingconv)
|
||||
llvm_tablegen(AlphaGenSubtargetInfo.inc -gen-subtarget)
|
||||
add_public_tablegen_target(AlphaCommonTableGen)
|
||||
|
||||
add_llvm_target(AlphaCodeGen
|
||||
AlphaAsmPrinter.cpp
|
||||
AlphaBranchSelector.cpp
|
||||
AlphaInstrInfo.cpp
|
||||
AlphaISelDAGToDAG.cpp
|
||||
AlphaISelLowering.cpp
|
||||
AlphaFrameLowering.cpp
|
||||
AlphaLLRP.cpp
|
||||
AlphaRegisterInfo.cpp
|
||||
AlphaSubtarget.cpp
|
||||
AlphaTargetMachine.cpp
|
||||
AlphaSelectionDAGInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMAlphaCodeGen
|
||||
LLVMAlphaDesc
|
||||
LLVMAlphaInfo
|
||||
LLVMAsmPrinter
|
||||
LLVMCodeGen
|
||||
LLVMCore
|
||||
LLVMMC
|
||||
LLVMSelectionDAG
|
||||
LLVMSupport
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
@ -1,23 +0,0 @@
|
||||
//===-- AlphaMCAsmInfo.cpp - Alpha 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 declarations of the AlphaMCAsmInfo properties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AlphaMCAsmInfo.h"
|
||||
using namespace llvm;
|
||||
|
||||
AlphaMCAsmInfo::AlphaMCAsmInfo(const Target &T, StringRef TT) {
|
||||
AlignmentIsInBytes = false;
|
||||
PrivateGlobalPrefix = "$";
|
||||
GPRel32Directive = ".gprel32";
|
||||
WeakRefDirective = "\t.weak\t";
|
||||
HasSetDirective = false;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
//=====-- AlphaMCAsmInfo.h - Alpha 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 AlphaMCAsmInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHATARGETASMINFO_H
|
||||
#define ALPHATARGETASMINFO_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class Target;
|
||||
|
||||
struct AlphaMCAsmInfo : public MCAsmInfo {
|
||||
explicit AlphaMCAsmInfo(const Target &T, StringRef TT);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -1,78 +0,0 @@
|
||||
//===-- AlphaMCTargetDesc.cpp - Alpha 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 Alpha specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AlphaMCTargetDesc.h"
|
||||
#include "AlphaMCAsmInfo.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 "AlphaGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_MC_DESC
|
||||
#include "AlphaGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "AlphaGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
static MCInstrInfo *createAlphaMCInstrInfo() {
|
||||
MCInstrInfo *X = new MCInstrInfo();
|
||||
InitAlphaMCInstrInfo(X);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCRegisterInfo *createAlphaMCRegisterInfo(StringRef TT) {
|
||||
MCRegisterInfo *X = new MCRegisterInfo();
|
||||
InitAlphaMCRegisterInfo(X, Alpha::R26);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCSubtargetInfo *createAlphaMCSubtargetInfo(StringRef TT, StringRef CPU,
|
||||
StringRef FS) {
|
||||
MCSubtargetInfo *X = new MCSubtargetInfo();
|
||||
InitAlphaMCSubtargetInfo(X, TT, CPU, FS);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCCodeGenInfo *createAlphaMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
CodeModel::Model CM) {
|
||||
MCCodeGenInfo *X = new MCCodeGenInfo();
|
||||
X->InitMCCodeGenInfo(Reloc::PIC_, CM);
|
||||
return X;
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeAlphaTargetMC() {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfo<AlphaMCAsmInfo> X(TheAlphaTarget);
|
||||
|
||||
// Register the MC codegen info.
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheAlphaTarget,
|
||||
createAlphaMCCodeGenInfo);
|
||||
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(TheAlphaTarget, createAlphaMCInstrInfo);
|
||||
|
||||
// Register the MC register info.
|
||||
TargetRegistry::RegisterMCRegInfo(TheAlphaTarget, createAlphaMCRegisterInfo);
|
||||
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(TheAlphaTarget,
|
||||
createAlphaMCSubtargetInfo);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
//===-- AlphaMCTargetDesc.h - Alpha 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 Alpha specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ALPHAMCTARGETDESC_H
|
||||
#define ALPHAMCTARGETDESC_H
|
||||
|
||||
namespace llvm {
|
||||
class MCSubtargetInfo;
|
||||
class Target;
|
||||
class StringRef;
|
||||
|
||||
extern Target TheAlphaTarget;
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
// Defines symbolic names for Alpha registers. This defines a mapping from
|
||||
// register name to register number.
|
||||
//
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "AlphaGenRegisterInfo.inc"
|
||||
|
||||
// Defines symbolic names for the Alpha instructions.
|
||||
//
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "AlphaGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "AlphaGenSubtargetInfo.inc"
|
||||
|
||||
#endif
|
@ -1,11 +0,0 @@
|
||||
add_llvm_library(LLVMAlphaDesc
|
||||
AlphaMCTargetDesc.cpp
|
||||
AlphaMCAsmInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMAlphaDesc
|
||||
LLVMAlphaInfo
|
||||
LLVMMC
|
||||
)
|
||||
|
||||
add_dependencies(LLVMAlphaDesc AlphaCommonTableGen)
|
@ -1,16 +0,0 @@
|
||||
##===- lib/Target/Alpha/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 = LLVMAlphaDesc
|
||||
|
||||
# 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,21 +0,0 @@
|
||||
##===- lib/Target/Alpha/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 = LLVMAlphaCodeGen
|
||||
TARGET = Alpha
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = AlphaGenRegisterInfo.inc AlphaGenInstrInfo.inc \
|
||||
AlphaGenAsmWriter.inc AlphaGenDAGISel.inc \
|
||||
AlphaGenCallingConv.inc AlphaGenSubtargetInfo.inc
|
||||
|
||||
DIRS = TargetInfo MCTargetDesc
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
@ -1,42 +0,0 @@
|
||||
***
|
||||
|
||||
add gcc builtins for alpha instructions
|
||||
|
||||
|
||||
***
|
||||
|
||||
custom expand byteswap into nifty
|
||||
extract/insert/mask byte/word/longword/quadword low/high
|
||||
sequences
|
||||
|
||||
***
|
||||
|
||||
see if any of the extract/insert/mask operations can be added
|
||||
|
||||
***
|
||||
|
||||
match more interesting things for cmovlbc cmovlbs (move if low bit clear/set)
|
||||
|
||||
***
|
||||
|
||||
lower srem and urem
|
||||
|
||||
remq(i,j): i - (j * divq(i,j)) if j != 0
|
||||
remqu(i,j): i - (j * divqu(i,j)) if j != 0
|
||||
reml(i,j): i - (j * divl(i,j)) if j != 0
|
||||
remlu(i,j): i - (j * divlu(i,j)) if j != 0
|
||||
|
||||
***
|
||||
|
||||
add crazy vector instructions (MVI):
|
||||
|
||||
(MIN|MAX)(U|S)(B8|W4) min and max, signed and unsigned, byte and word
|
||||
PKWB, UNPKBW pack/unpack word to byte
|
||||
PKLB UNPKBL pack/unpack long to byte
|
||||
PERR pixel error (sum across bytes of bytewise abs(i8v8 a - i8v8 b))
|
||||
|
||||
cmpbytes bytewise cmpeq of i8v8 a and i8v8 b (not part of MVI extensions)
|
||||
|
||||
this has some good examples for other operations that can be synthesised well
|
||||
from these rather meager vector ops (such as saturating add).
|
||||
http://www.alphalinux.org/docs/MVI-full.html
|
@ -1,20 +0,0 @@
|
||||
//===-- AlphaTargetInfo.cpp - Alpha Target Implementation -----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Alpha.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
llvm::Target llvm::TheAlphaTarget;
|
||||
|
||||
extern "C" void LLVMInitializeAlphaTargetInfo() {
|
||||
RegisterTarget<Triple::alpha, /*HasJIT=*/true>
|
||||
X(TheAlphaTarget, "alpha", "Alpha [experimental]");
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||
|
||||
add_llvm_library(LLVMAlphaInfo
|
||||
AlphaTargetInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMAlphaInfo
|
||||
LLVMMC
|
||||
LLVMSupport
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_dependencies(LLVMAlphaInfo AlphaCommonTableGen)
|
@ -1,15 +0,0 @@
|
||||
##===- lib/Target/Alpha/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 = LLVMAlphaInfo
|
||||
|
||||
# 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
|
@ -296,7 +296,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
||||
amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
|
||||
sparc*-*) llvm_cv_target_arch="Sparc" ;;
|
||||
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
|
||||
alpha*-*) llvm_cv_target_arch="Alpha" ;;
|
||||
arm*-*) llvm_cv_target_arch="ARM" ;;
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
@ -431,7 +430,6 @@ else
|
||||
Sparc) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PowerPC) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
@ -547,21 +545,20 @@ dnl Allow specific targets to be specified for building (or not)
|
||||
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,
|
||||
host, x86, x86_64, sparc, powerpc, arm, mips, spu,
|
||||
xcore, msp430, 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 CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 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" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
@ -576,7 +573,6 @@ case "$enableval" in
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
9
projects/sample/configure
vendored
9
projects/sample/configure
vendored
@ -1401,7 +1401,7 @@ Optional Features:
|
||||
(default is YES)
|
||||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
x86_64, sparc, powerpc, arm, mips, spu,
|
||||
xcore, msp430, ptx, cbe, and cpp
|
||||
(default=all)
|
||||
--enable-cbe-printf-a Enable C Backend output with hex floating point via
|
||||
@ -3840,7 +3840,6 @@ else
|
||||
amd64-* | x86_64-*) llvm_cv_target_arch="x86_64" ;;
|
||||
sparc*-*) llvm_cv_target_arch="Sparc" ;;
|
||||
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
|
||||
alpha*-*) llvm_cv_target_arch="Alpha" ;;
|
||||
arm*-*) llvm_cv_target_arch="ARM" ;;
|
||||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
@ -5037,8 +5036,6 @@ else
|
||||
PowerPC) TARGET_HAS_JIT=1
|
||||
;;
|
||||
x86_64) TARGET_HAS_JIT=1
|
||||
;;
|
||||
Alpha) TARGET_HAS_JIT=0
|
||||
;;
|
||||
ARM) TARGET_HAS_JIT=1
|
||||
;;
|
||||
@ -5236,14 +5233,13 @@ 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 CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 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" ;;
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
@ -5258,7 +5254,6 @@ case "$enableval" in
|
||||
x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
|
||||
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
|
||||
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
|
||||
Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
|
||||
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
|
||||
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
|
||||
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -1,40 +0,0 @@
|
||||
; This shouldn't crash
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
@.str_4 = external global [44 x i8] ; <[44 x i8]*> [#uses=0]
|
||||
|
||||
declare void @printf(i32, ...)
|
||||
|
||||
define void @main() {
|
||||
entry:
|
||||
%tmp.11861 = icmp slt i64 0, 1 ; <i1> [#uses=1]
|
||||
%tmp.19466 = icmp slt i64 0, 1 ; <i1> [#uses=1]
|
||||
%tmp.21571 = icmp slt i64 0, 1 ; <i1> [#uses=1]
|
||||
%tmp.36796 = icmp slt i64 0, 1 ; <i1> [#uses=1]
|
||||
br i1 %tmp.11861, label %loopexit.2, label %no_exit.2
|
||||
|
||||
no_exit.2: ; preds = %entry
|
||||
ret void
|
||||
|
||||
loopexit.2: ; preds = %entry
|
||||
br i1 %tmp.19466, label %loopexit.3, label %no_exit.3.preheader
|
||||
|
||||
no_exit.3.preheader: ; preds = %loopexit.2
|
||||
ret void
|
||||
|
||||
loopexit.3: ; preds = %loopexit.2
|
||||
br i1 %tmp.21571, label %no_exit.6, label %no_exit.4
|
||||
|
||||
no_exit.4: ; preds = %loopexit.3
|
||||
ret void
|
||||
|
||||
no_exit.6: ; preds = %no_exit.6, %loopexit.3
|
||||
%tmp.30793 = icmp sgt i64 0, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp.30793, label %loopexit.6, label %no_exit.6
|
||||
|
||||
loopexit.6: ; preds = %no_exit.6
|
||||
%Z.1 = select i1 %tmp.36796, double 1.000000e+00, double 0x3FEFFF7CEDE74EAE; <double> [#uses=2]
|
||||
tail call void (i32, ...)* @printf( i32 0, i64 0, i64 0, i64 0, double 1.000000e+00, double 1.000000e+00, double %Z.1, double %Z.1 )
|
||||
ret void
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
; The global symbol should be legalized
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
%struct.LIST_HELP = type { %struct.LIST_HELP*, i8* }
|
||||
%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i32, [44 x i8] }
|
||||
%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
|
||||
@clause_SORT = external global [21 x %struct.LIST_HELP*] ; <[21 x %struct.LIST_HELP*]*> [#uses=0]
|
||||
@ia_in = external global %struct._IO_FILE* ; <%struct._IO_FILE**> [#uses=1]
|
||||
@multvec_j = external global [100 x i32] ; <[100 x i32]*> [#uses=0]
|
||||
|
||||
define void @main(i32 %argc) {
|
||||
clock_Init.exit:
|
||||
%tmp.5.i575 = load i32* null ; <i32> [#uses=1]
|
||||
%tmp.309 = icmp eq i32 %tmp.5.i575, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp.309, label %UnifiedReturnBlock, label %then.17
|
||||
|
||||
then.17: ; preds = %clock_Init.exit
|
||||
store %struct._IO_FILE* null, %struct._IO_FILE** @ia_in
|
||||
%savedstack = call i8* @llvm.stacksave( ) ; <i8*> [#uses=0]
|
||||
ret void
|
||||
|
||||
UnifiedReturnBlock: ; preds = %clock_Init.exit
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i8* @llvm.stacksave()
|
@ -1,14 +0,0 @@
|
||||
; This shouldn't crash
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev6-unknown-linux-gnu"
|
||||
deplibs = [ "c", "crtend", "stdc++" ]
|
||||
%struct.__va_list_tag = type { i8*, i32 }
|
||||
|
||||
define i32 @emit_library_call_value(i32 %nargs, ...) {
|
||||
entry:
|
||||
%tmp.223 = va_arg %struct.__va_list_tag* null, i32 ; <i32> [#uses=1]
|
||||
ret i32 %tmp.223
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev67-unknown-linux-gnu"
|
||||
%struct._Callback_list = type { %struct._Callback_list*, void (i32, %struct.ios_base*, i32)*, i32, i32 }
|
||||
%struct._Impl = type { i32, %struct.facet**, i64, %struct.facet**, i8** }
|
||||
%struct._Words = type { i8*, i64 }
|
||||
%"struct.__codecvt_abstract_base<char,char,__mbstate_t>" = type { %struct.facet }
|
||||
%"struct.basic_streambuf<char,std::char_traits<char> >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %struct.locale }
|
||||
%struct.facet = type { i32 (...)**, i32 }
|
||||
%struct.ios_base = type { i32 (...)**, i64, i64, i32, i32, i32, %struct._Callback_list*, %struct._Words, [8 x %struct._Words], i32, %struct._Words*, %struct.locale }
|
||||
%struct.locale = type { %struct._Impl* }
|
||||
%"struct.ostreambuf_iterator<char,std::char_traits<char> >" = type { %"struct.basic_streambuf<char,std::char_traits<char> >"*, i1 }
|
||||
|
||||
define void @_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_() {
|
||||
entry:
|
||||
%tmp234 = icmp eq i8 0, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp234, label %cond_next243, label %cond_true235
|
||||
|
||||
cond_true235: ; preds = %entry
|
||||
ret void
|
||||
|
||||
cond_next243: ; preds = %entry
|
||||
%tmp428 = load i64* null ; <i64> [#uses=1]
|
||||
%tmp428.upgrd.1 = trunc i64 %tmp428 to i32 ; <i32> [#uses=1]
|
||||
%tmp429 = alloca i8, i32 %tmp428.upgrd.1 ; <i8*> [#uses=0]
|
||||
unreachable
|
||||
}
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev67-unknown-linux-gnu"
|
||||
|
||||
define i32 @_ZN9__gnu_cxx18__exchange_and_addEPVii(i32* %__mem, i32 %__val) {
|
||||
entry:
|
||||
%__tmp = alloca i32, align 4 ; <i32*> [#uses=1]
|
||||
%tmp3 = call i32 asm sideeffect "\0A$$Lxadd_0:\0A\09ldl_l $0,$3\0A\09addl $0,$4,$1\0A\09stl_c $1,$2\0A\09beq $1,$$Lxadd_0\0A\09mb", "=&r,=*&r,=*m,m,r"( i32* %__tmp, i32* %__mem, i32* %__mem, i32 %__val ) ; <i32> [#uses=1]
|
||||
ret i32 %tmp3
|
||||
}
|
||||
|
||||
define void @_ZN9__gnu_cxx12__atomic_addEPVii(i32* %__mem, i32 %__val) {
|
||||
entry:
|
||||
%tmp2 = call i32 asm sideeffect "\0A$$Ladd_1:\0A\09ldl_l $0,$2\0A\09addl $0,$3,$0\0A\09stl_c $0,$1\0A\09beq $0,$$Ladd_1\0A\09mb", "=&r,=*m,m,r"( i32* %__mem, i32* %__mem, i32 %__val ) ; <i32> [#uses=0]
|
||||
ret void
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev67-unknown-linux-gnu"
|
||||
%struct.va_list = type { i8*, i32, i32 }
|
||||
|
||||
define void @yyerror(i32, ...) {
|
||||
entry:
|
||||
%va.upgrd.1 = bitcast %struct.va_list* null to i8* ; <i8*> [#uses=1]
|
||||
call void @llvm.va_start( i8* %va.upgrd.1 )
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(i8*)
|
||||
|
@ -1,13 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
;FIXME: this should produce no mul inst. But not crashing will have to do for now
|
||||
|
||||
; ModuleID = 'Output/bugpoint-train/bugpoint-reduced-simplified.bc'
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f128:128:128"
|
||||
target triple = "alphaev6-unknown-linux-gnu"
|
||||
|
||||
define fastcc i32 @getcount(i32 %s) {
|
||||
cond_next43: ; preds = %bb27
|
||||
%tmp431 = mul i32 %s, -3
|
||||
ret i32 %tmp431
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f128:128:128"
|
||||
target triple = "alphaev6-unknown-linux-gnu"
|
||||
|
||||
define i64 @__mulvdi3(i64 %a, i64 %b) nounwind {
|
||||
entry:
|
||||
%0 = sext i64 %a to i128 ; <i128> [#uses=1]
|
||||
%1 = sext i64 %b to i128 ; <i128> [#uses=1]
|
||||
%2 = mul i128 %1, %0 ; <i128> [#uses=2]
|
||||
%3 = lshr i128 %2, 64 ; <i128> [#uses=1]
|
||||
%4 = trunc i128 %3 to i64 ; <i64> [#uses=1]
|
||||
%5 = trunc i128 %2 to i64 ; <i64> [#uses=1]
|
||||
%6 = icmp eq i64 %4, 0 ; <i1> [#uses=1]
|
||||
br i1 %6, label %bb1, label %bb
|
||||
|
||||
bb: ; preds = %entry
|
||||
unreachable
|
||||
|
||||
bb1: ; preds = %entry
|
||||
ret i64 %5
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
; RUN: llc < %s
|
||||
; PR3044
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f128:128:128"
|
||||
target triple = "alphaev6-unknown-linux-gnu"
|
||||
|
||||
define i128 @__mulvti3(i128 %u, i128 %v) nounwind {
|
||||
entry:
|
||||
%0 = load i128* null, align 16 ; <i128> [#uses=1]
|
||||
%1 = load i64* null, align 8 ; <i64> [#uses=1]
|
||||
%2 = zext i64 %1 to i128 ; <i128> [#uses=1]
|
||||
%3 = add i128 %2, %0 ; <i128> [#uses=1]
|
||||
store i128 %3, i128* null, align 16
|
||||
unreachable
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
define i1 @a(float %x) {
|
||||
%r = fcmp ult float %x, 1.0
|
||||
ret i1 %r
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
; RUN: llc -O0 -march=alpha -asm-verbose < %s | FileCheck %s
|
||||
; Check that DEBUG_VALUE comments come through on a variety of targets.
|
||||
|
||||
define i32 @main() nounwind ssp {
|
||||
entry:
|
||||
; CHECK: DEBUG_VALUE
|
||||
call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9
|
||||
ret i32 0, !dbg !10
|
||||
}
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
|
||||
|
||||
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
|
||||
|
||||
!llvm.dbg.sp = !{!0}
|
||||
|
||||
!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
|
||||
!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ]
|
||||
!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
|
||||
!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
|
||||
!6 = metadata !{i32 0}
|
||||
!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ]
|
||||
!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
|
||||
!9 = metadata !{i32 3, i32 11, metadata !8, null}
|
||||
!10 = metadata !{i32 4, i32 2, metadata !8, null}
|
||||
|
@ -1,11 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | FileCheck %s
|
||||
|
||||
define fastcc i64 @getcount(i64 %s) {
|
||||
%tmp431 = mul i64 %s, 12884901888
|
||||
ret i64 %tmp431
|
||||
}
|
||||
|
||||
; CHECK: sll $16,32,$0
|
||||
; CHECK-NEXT: sll $16,33,$1
|
||||
; CHECK-NEXT: addq $1,$0,$0
|
||||
|
@ -1,178 +0,0 @@
|
||||
;test all the shifted and signextending adds and subs with and without consts
|
||||
;
|
||||
; RUN: llc < %s -march=alpha -o %t.s
|
||||
; RUN: grep { addl} %t.s | count 2
|
||||
; RUN: grep { addq} %t.s | count 2
|
||||
; RUN: grep { subl} %t.s | count 2
|
||||
; RUN: grep { subq} %t.s | count 2
|
||||
;
|
||||
; RUN: grep {s4addl} %t.s | count 2
|
||||
; RUN: grep {s8addl} %t.s | count 2
|
||||
; RUN: grep {s4addq} %t.s | count 2
|
||||
; RUN: grep {s8addq} %t.s | count 2
|
||||
;
|
||||
; RUN: grep {s4subl} %t.s | count 2
|
||||
; RUN: grep {s8subl} %t.s | count 2
|
||||
; RUN: grep {s4subq} %t.s | count 2
|
||||
; RUN: grep {s8subq} %t.s | count 2
|
||||
|
||||
|
||||
define signext i32 @al(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.3.s = add i32 %y.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @ali(i32 signext %x.s) {
|
||||
entry:
|
||||
%tmp.3.s = add i32 100, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i64 @aq(i64 signext %x.s, i64 signext %y.s) {
|
||||
entry:
|
||||
%tmp.3.s = add i64 %y.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @aqi(i64 %x.s) {
|
||||
entry:
|
||||
%tmp.3.s = add i64 100, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @sl(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.3.s = sub i32 %y.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @sli(i32 signext %x.s) {
|
||||
entry:
|
||||
%tmp.3.s = sub i32 %x.s, 100 ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @sq(i64 %x.s, i64 %y.s) {
|
||||
entry:
|
||||
%tmp.3.s = sub i64 %y.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @sqi(i64 %x.s) {
|
||||
entry:
|
||||
%tmp.3.s = sub i64 %x.s, 100 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @a4l(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 2 ; <i32> [#uses=1]
|
||||
%tmp.3.s = add i32 %tmp.1.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @a8l(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 3 ; <i32> [#uses=1]
|
||||
%tmp.3.s = add i32 %tmp.1.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @a4q(i64 %x.s, i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 2 ; <i64> [#uses=1]
|
||||
%tmp.3.s = add i64 %tmp.1.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @a8q(i64 %x.s, i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 3 ; <i64> [#uses=1]
|
||||
%tmp.3.s = add i64 %tmp.1.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @a4li(i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 2 ; <i32> [#uses=1]
|
||||
%tmp.3.s = add i32 100, %tmp.1.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @a8li(i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 3 ; <i32> [#uses=1]
|
||||
%tmp.3.s = add i32 100, %tmp.1.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @a4qi(i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 2 ; <i64> [#uses=1]
|
||||
%tmp.3.s = add i64 100, %tmp.1.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @a8qi(i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 3 ; <i64> [#uses=1]
|
||||
%tmp.3.s = add i64 100, %tmp.1.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @s4l(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 2 ; <i32> [#uses=1]
|
||||
%tmp.3.s = sub i32 %tmp.1.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @s8l(i32 signext %x.s, i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 3 ; <i32> [#uses=1]
|
||||
%tmp.3.s = sub i32 %tmp.1.s, %x.s ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @s4q(i64 %x.s, i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 2 ; <i64> [#uses=1]
|
||||
%tmp.3.s = sub i64 %tmp.1.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @s8q(i64 %x.s, i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 3 ; <i64> [#uses=1]
|
||||
%tmp.3.s = sub i64 %tmp.1.s, %x.s ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @s4li(i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 2 ; <i32> [#uses=1]
|
||||
%tmp.3.s = sub i32 %tmp.1.s, 100 ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define signext i32 @s8li(i32 signext %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i32 %y.s, 3 ; <i32> [#uses=1]
|
||||
%tmp.3.s = sub i32 %tmp.1.s, 100 ; <i32> [#uses=1]
|
||||
ret i32 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @s4qi(i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 2 ; <i64> [#uses=1]
|
||||
%tmp.3.s = sub i64 %tmp.1.s, 100 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
||||
|
||||
define i64 @s8qi(i64 %y.s) {
|
||||
entry:
|
||||
%tmp.1.s = shl i64 %y.s, 3 ; <i64> [#uses=1]
|
||||
%tmp.3.s = sub i64 %tmp.1.s, 100 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.3.s
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
;test for ADDC and ADDE expansion
|
||||
;
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
define i128 @add128(i128 %x, i128 %y) {
|
||||
entry:
|
||||
%tmp = add i128 %y, %x
|
||||
ret i128 %tmp
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
; Make sure this testcase codegens to the bic instruction
|
||||
; RUN: llc < %s -march=alpha | grep {bic}
|
||||
|
||||
define i64 @bar(i64 %x, i64 %y) {
|
||||
entry:
|
||||
%tmp.1 = xor i64 %x, -1 ; <i64> [#uses=1]
|
||||
%tmp.2 = and i64 %y, %tmp.1 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.2
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
; Make sure this testcase codegens the bsr instruction
|
||||
; RUN: llc < %s -march=alpha | grep bsr
|
||||
|
||||
define internal i64 @abc(i32 %x) {
|
||||
%tmp.2 = add i32 %x, -1 ; <i32> [#uses=1]
|
||||
%tmp.0 = call i64 @abc( i32 %tmp.2 ) ; <i64> [#uses=1]
|
||||
%tmp.5 = add i32 %x, -2 ; <i32> [#uses=1]
|
||||
%tmp.3 = call i64 @abc( i32 %tmp.5 ) ; <i64> [#uses=1]
|
||||
%tmp.6 = add i64 %tmp.0, %tmp.3 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.6
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
;All this should do is not crash
|
||||
;RUN: llc < %s -march=alpha
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev67-unknown-linux-gnu"
|
||||
|
||||
define void @_ZNSt13basic_filebufIcSt11char_traitsIcEE22_M_convert_to_externalEPcl(i32 %f) {
|
||||
entry:
|
||||
%tmp49 = alloca i8, i32 %f ; <i8*> [#uses=0]
|
||||
%tmp = call i32 null( i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null ) ; <i32> [#uses=0]
|
||||
ret void
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | not grep cmovlt
|
||||
; RUN: llc < %s -march=alpha | grep cmoveq
|
||||
|
||||
define i64 @cmov_lt(i64 %a, i64 %c) {
|
||||
entry:
|
||||
%tmp.1 = icmp slt i64 %c, 0 ; <i1> [#uses=1]
|
||||
%retval = select i1 %tmp.1, i64 %a, i64 10 ; <i64> [#uses=1]
|
||||
ret i64 %retval
|
||||
}
|
||||
|
||||
define i64 @cmov_const(i64 %a, i64 %b, i64 %c) {
|
||||
entry:
|
||||
%tmp.1 = icmp slt i64 %a, %b ; <i1> [#uses=1]
|
||||
%retval = select i1 %tmp.1, i64 %c, i64 10 ; <i64> [#uses=1]
|
||||
ret i64 %retval
|
||||
}
|
||||
|
||||
define i64 @cmov_lt2(i64 %a, i64 %c) {
|
||||
entry:
|
||||
%tmp.1 = icmp sgt i64 %c, 0 ; <i1> [#uses=1]
|
||||
%retval = select i1 %tmp.1, i64 10, i64 %a ; <i64> [#uses=1]
|
||||
ret i64 %retval
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep cmpbge | count 2
|
||||
|
||||
define i1 @test1(i64 %A, i64 %B) {
|
||||
%C = and i64 %A, 255 ; <i64> [#uses=1]
|
||||
%D = and i64 %B, 255 ; <i64> [#uses=1]
|
||||
%E = icmp uge i64 %C, %D ; <i1> [#uses=1]
|
||||
ret i1 %E
|
||||
}
|
||||
|
||||
define i1 @test2(i64 %a, i64 %B) {
|
||||
%A = shl i64 %a, 1 ; <i64> [#uses=1]
|
||||
%C = and i64 %A, 254 ; <i64> [#uses=1]
|
||||
%D = and i64 %B, 255 ; <i64> [#uses=1]
|
||||
%E = icmp uge i64 %C, %D ; <i1> [#uses=1]
|
||||
ret i1 %E
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
; Make sure this testcase codegens to the ctlz instruction
|
||||
; RUN: llc < %s -march=alpha -mcpu=ev67 | grep -i ctlz
|
||||
; RUN: llc < %s -march=alpha -mattr=+CIX | grep -i ctlz
|
||||
; RUN: llc < %s -march=alpha -mcpu=ev6 | not grep -i ctlz
|
||||
; RUN: llc < %s -march=alpha -mattr=-CIX | not grep -i ctlz
|
||||
|
||||
declare i8 @llvm.ctlz.i8(i8)
|
||||
|
||||
define i32 @bar(i8 %x) {
|
||||
entry:
|
||||
%tmp.1 = call i8 @llvm.ctlz.i8( i8 %x )
|
||||
%tmp.2 = sext i8 %tmp.1 to i32
|
||||
ret i32 %tmp.2
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
; Make sure this testcase does not use ctpop
|
||||
; RUN: llc < %s -march=alpha | not grep -i ctpop
|
||||
|
||||
declare i64 @llvm.ctlz.i64(i64)
|
||||
|
||||
define i64 @bar(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = call i64 @llvm.ctlz.i64( i64 %x ) ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
; Make sure this testcase codegens to the ctpop instruction
|
||||
; RUN: llc < %s -march=alpha -mcpu=ev67 | grep -i ctpop
|
||||
; RUN: llc < %s -march=alpha -mattr=+CIX | \
|
||||
; RUN: grep -i ctpop
|
||||
; RUN: llc < %s -march=alpha -mcpu=ev6 | \
|
||||
; RUN: not grep -i ctpop
|
||||
; RUN: llc < %s -march=alpha -mattr=-CIX | \
|
||||
; RUN: not grep -i ctpop
|
||||
|
||||
declare i64 @llvm.ctpop.i64(i64)
|
||||
|
||||
define i64 @bar(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = call i64 @llvm.ctpop.i64( i64 %x ) ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
load_lib llvm.exp
|
||||
|
||||
if { [llvm_supports_target Alpha] } {
|
||||
RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]]
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
; Make sure this testcase codegens to the eqv instruction
|
||||
; RUN: llc < %s -march=alpha | grep eqv
|
||||
|
||||
define i64 @bar(i64 %x, i64 %y) {
|
||||
entry:
|
||||
%tmp.1 = xor i64 %x, -1 ; <i64> [#uses=1]
|
||||
%tmp.2 = xor i64 %y, %tmp.1 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.2
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
; Make sure this testcase codegens to the ctpop instruction
|
||||
; RUN: llc < %s -march=alpha | grep -i {subl \$16,1,\$0}
|
||||
|
||||
|
||||
define signext i32 @foo(i32 signext %x) {
|
||||
entry:
|
||||
%tmp.1 = add i32 %x, -1 ; <int> [#uses=1]
|
||||
ret i32 %tmp.1
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
; RUN: llc < %s -mtriple=alphaev6-unknown-linux-gnu
|
||||
|
||||
define void @foo() {
|
||||
entry:
|
||||
br label %bb
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
br i1 false, label %bb26, label %bb
|
||||
|
||||
bb19: ; preds = %bb26
|
||||
ret void
|
||||
|
||||
bb26: ; preds = %bb
|
||||
br i1 false, label %bb30, label %bb19
|
||||
|
||||
bb30: ; preds = %bb26
|
||||
br label %bb45
|
||||
|
||||
bb45: ; preds = %bb45, %bb30
|
||||
%V.0 = phi <8 x i16> [ %tmp42, %bb45 ], [ zeroinitializer, %bb30 ] ; <<8 x i16>> [#uses=1]
|
||||
%tmp42 = mul <8 x i16> zeroinitializer, %V.0 ; <<8 x i16>> [#uses=1]
|
||||
br label %bb45
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
; try to check that we have the most important instructions, which shouldn't
|
||||
; appear otherwise
|
||||
; RUN: llc < %s -march=alpha | grep jmp
|
||||
; RUN: llc < %s -march=alpha | grep gprel32
|
||||
; RUN: llc < %s -march=alpha | grep ldl
|
||||
; RUN: llc < %s -march=alpha | grep rodata
|
||||
; END.
|
||||
|
||||
target datalayout = "e-p:64:64"
|
||||
target triple = "alphaev67-unknown-linux-gnu"
|
||||
@str = internal constant [2 x i8] c"1\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str1 = internal constant [2 x i8] c"2\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str2 = internal constant [2 x i8] c"3\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str3 = internal constant [2 x i8] c"4\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str4 = internal constant [2 x i8] c"5\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str5 = internal constant [2 x i8] c"6\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str6 = internal constant [2 x i8] c"7\00" ; <[2 x i8]*> [#uses=1]
|
||||
@str7 = internal constant [2 x i8] c"8\00" ; <[2 x i8]*> [#uses=1]
|
||||
|
||||
define i32 @main(i32 %x, i8** %y) {
|
||||
entry:
|
||||
%x_addr = alloca i32 ; <i32*> [#uses=2]
|
||||
%y_addr = alloca i8** ; <i8***> [#uses=1]
|
||||
%retval = alloca i32, align 4 ; <i32*> [#uses=2]
|
||||
%tmp = alloca i32, align 4 ; <i32*> [#uses=2]
|
||||
%foo = alloca i8*, align 8 ; <i8**> [#uses=9]
|
||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||
store i32 %x, i32* %x_addr
|
||||
store i8** %y, i8*** %y_addr
|
||||
%tmp.upgrd.1 = load i32* %x_addr ; <i32> [#uses=1]
|
||||
switch i32 %tmp.upgrd.1, label %bb15 [
|
||||
i32 1, label %bb
|
||||
i32 2, label %bb1
|
||||
i32 3, label %bb3
|
||||
i32 4, label %bb5
|
||||
i32 5, label %bb7
|
||||
i32 6, label %bb9
|
||||
i32 7, label %bb11
|
||||
i32 8, label %bb13
|
||||
]
|
||||
|
||||
bb: ; preds = %entry
|
||||
%tmp.upgrd.2 = getelementptr [2 x i8]* @str, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp.upgrd.2, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb1: ; preds = %entry
|
||||
%tmp2 = getelementptr [2 x i8]* @str1, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp2, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb3: ; preds = %entry
|
||||
%tmp4 = getelementptr [2 x i8]* @str2, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp4, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb5: ; preds = %entry
|
||||
%tmp6 = getelementptr [2 x i8]* @str3, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp6, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb7: ; preds = %entry
|
||||
%tmp8 = getelementptr [2 x i8]* @str4, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp8, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb9: ; preds = %entry
|
||||
%tmp10 = getelementptr [2 x i8]* @str5, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp10, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb11: ; preds = %entry
|
||||
%tmp12 = getelementptr [2 x i8]* @str6, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp12, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb13: ; preds = %entry
|
||||
%tmp14 = getelementptr [2 x i8]* @str7, i32 0, i64 0 ; <i8*> [#uses=1]
|
||||
store i8* %tmp14, i8** %foo
|
||||
br label %bb16
|
||||
|
||||
bb15: ; preds = %entry
|
||||
br label %bb16
|
||||
|
||||
bb16: ; preds = %bb15, %bb13, %bb11, %bb9, %bb7, %bb5, %bb3, %bb1, %bb
|
||||
%tmp17 = load i8** %foo ; <i8*> [#uses=1]
|
||||
%tmp18 = call i32 (...)* @print( i8* %tmp17 ) ; <i32> [#uses=0]
|
||||
store i32 0, i32* %tmp
|
||||
%tmp19 = load i32* %tmp ; <i32> [#uses=1]
|
||||
store i32 %tmp19, i32* %retval
|
||||
br label %return
|
||||
|
||||
return: ; preds = %bb16
|
||||
%retval.upgrd.3 = load i32* %retval ; <i32> [#uses=1]
|
||||
ret i32 %retval.upgrd.3
|
||||
}
|
||||
|
||||
declare i32 @print(...)
|
||||
|
@ -1,6 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep mb
|
||||
|
||||
define void @test() {
|
||||
fence seq_cst
|
||||
ret void
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
define i128 @__mulvdi3(i128 %a, i128 %b) nounwind {
|
||||
entry:
|
||||
%r = mul i128 %a, %b
|
||||
ret i128 %r
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
; Make sure this testcase does not use mulq
|
||||
; RUN: llc < %s -march=alpha | not grep -i mul
|
||||
|
||||
define i64 @foo1(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = mul i64 %x, 9 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
||||
define i64 @foo3(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = mul i64 %x, 259 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
||||
define i64 @foo4l(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = mul i64 %x, 260 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
||||
define i64 @foo8l(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = mul i64 %x, 768 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
||||
define i64 @bar(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = mul i64 %x, 5 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
; Make sure this testcase codegens to the lda -1 instruction
|
||||
; RUN: llc < %s -march=alpha | grep {\\-1}
|
||||
|
||||
define i64 @bar() {
|
||||
entry:
|
||||
ret i64 -1
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
; Make sure this testcase codegens to the ornot instruction
|
||||
; RUN: llc < %s -march=alpha | grep eqv
|
||||
|
||||
define i64 @bar(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = xor i64 %x, -1 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
; Make sure this testcase codegens to the ornot instruction
|
||||
; RUN: llc < %s -march=alpha | grep ornot
|
||||
|
||||
define i64 @bar(i64 %x, i64 %y) {
|
||||
entry:
|
||||
%tmp.1 = xor i64 %x, -1 ; <i64> [#uses=1]
|
||||
%tmp.2 = or i64 %y, %tmp.1 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.2
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
; Test to make sure that the 'private' is used correctly.
|
||||
;
|
||||
; RUN: llc < %s -march=alpha > %t
|
||||
; RUN: grep \\\$foo: %t
|
||||
; RUN: grep bsr.*\\\$\\\$foo %t
|
||||
; RUN: grep \\\$baz: %t
|
||||
; RUN: grep ldah.*\\\$baz %t
|
||||
|
||||
define private void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
@baz = private global i32 4
|
||||
|
||||
define i32 @bar() {
|
||||
call void @foo()
|
||||
%1 = load i32* @baz, align 4
|
||||
ret i32 %1
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep rpcc
|
||||
|
||||
declare i64 @llvm.readcyclecounter()
|
||||
|
||||
define i64 @foo() {
|
||||
entry:
|
||||
%tmp.1 = call i64 @llvm.readcyclecounter( ) ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
; Make sure this testcase codegens to the zapnot instruction
|
||||
; RUN: llc < %s -march=alpha | grep zapnot
|
||||
|
||||
define i64 @foo(i64 %y) {
|
||||
entry:
|
||||
%tmp = lshr i64 %y, 3 ; <i64> [#uses=1]
|
||||
%tmp2 = and i64 %tmp, 8191 ; <i64> [#uses=1]
|
||||
ret i64 %tmp2
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
;test for SUBC and SUBE expansion
|
||||
;
|
||||
; RUN: llc < %s -march=alpha
|
||||
|
||||
define i128 @sub128(i128 %x, i128 %y) {
|
||||
entry:
|
||||
%tmp = sub i128 %y, %x
|
||||
ret i128 %tmp
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep .weak.*f
|
||||
; RUN: llc < %s -march=alpha | grep .weak.*h
|
||||
|
||||
define weak i32 @f() {
|
||||
entry:
|
||||
unreachable
|
||||
}
|
||||
|
||||
define void @g() {
|
||||
entry:
|
||||
tail call void @h( )
|
||||
ret void
|
||||
}
|
||||
|
||||
declare extern_weak void @h()
|
||||
|
@ -1,9 +0,0 @@
|
||||
; Make sure this testcase codegens to the bic instruction
|
||||
; RUN: llc < %s -march=alpha | grep zapnot
|
||||
|
||||
|
||||
define zeroext i16 @foo(i64 %y) {
|
||||
entry:
|
||||
%tmp.1 = trunc i64 %y to i16 ; <ushort> [#uses=1]
|
||||
ret i16 %tmp.1
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
; Make sure this testcase codegens to the zapnot instruction
|
||||
; RUN: llc < %s -march=alpha | grep zapnot
|
||||
|
||||
define i64 @bar(i64 %x) {
|
||||
entry:
|
||||
%tmp.1 = and i64 %x, 16711935 ; <i64> [#uses=1]
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep zapnot
|
||||
|
||||
;demanded bits mess up this mask in a hard to fix way
|
||||
;define i64 @foo(i64 %y) {
|
||||
; %tmp = and i64 %y, 65535
|
||||
; %tmp2 = shr i64 %tmp, i8 3
|
||||
; ret i64 %tmp2
|
||||
;}
|
||||
|
||||
define i64 @foo2(i64 %y) {
|
||||
%tmp = lshr i64 %y, 3 ; <i64> [#uses=1]
|
||||
%tmp2 = and i64 %tmp, 8191 ; <i64> [#uses=1]
|
||||
ret i64 %tmp2
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
; RUN: llc < %s -march=alpha | grep zapnot
|
||||
|
||||
define i64 @foo(i64 %y) {
|
||||
%tmp = shl i64 %y, 3 ; <i64> [#uses=1]
|
||||
%tmp2 = and i64 %tmp, 65535 ; <i64> [#uses=1]
|
||||
ret i64 %tmp2
|
||||
}
|
@ -920,8 +920,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
|
||||
} else
|
||||
GCCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others
|
||||
|
||||
if ((TargetTriple.getArch() == Triple::alpha) ||
|
||||
(TargetTriple.getArch() == Triple::x86_64))
|
||||
if (TargetTriple.getArch() == Triple::x86_64)
|
||||
GCCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC
|
||||
|
||||
if (TargetTriple.getArch() == Triple::sparc)
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Do not edit here. If you wish to override these values
|
||||
# edit the last section
|
||||
set target_triplet "x86_64-apple-darwin10"
|
||||
set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend"
|
||||
set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend"
|
||||
set srcroot "/Volumes/Data/ddunbar/llvm"
|
||||
set objroot "/Volumes/Data/ddunbar/llvm.obj.64"
|
||||
set srcdir "/Volumes/Data/ddunbar/llvm/test"
|
||||
|
@ -2,7 +2,7 @@
|
||||
# Do not edit here. If you wish to override these values
|
||||
# edit the last section
|
||||
set target_triplet "x86_64-apple-darwin10"
|
||||
set TARGETS_TO_BUILD "X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend"
|
||||
set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend"
|
||||
set srcroot "/Volumes/Data/ddunbar/llvm"
|
||||
set objroot "/Volumes/Data/ddunbar/llvm.obj.64"
|
||||
set srcdir "/Volumes/Data/ddunbar/llvm/test"
|
||||
|
Loading…
x
Reference in New Issue
Block a user