forked from OSchip/llvm-project
parent
53bb0ff685
commit
b43c36f391
|
@ -66,7 +66,6 @@ endif()
|
|||
set(LLVM_ALL_TARGETS
|
||||
Alpha
|
||||
ARM
|
||||
Blackfin
|
||||
CBackend
|
||||
CellSPU
|
||||
CppBackend
|
||||
|
|
|
@ -357,7 +357,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
|||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
|
@ -493,7 +492,6 @@ else
|
|||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
|
@ -606,13 +604,13 @@ TARGETS_TO_BUILD=""
|
|||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
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 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha 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" ;;
|
||||
|
@ -625,7 +623,6 @@ case "$enableval" in
|
|||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -642,7 +639,6 @@ case "$enableval" in
|
|||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) AC_MSG_ERROR([Can not set target to build]) ;;
|
||||
esac ;;
|
||||
|
|
|
@ -1416,7 +1416,7 @@ Optional Features:
|
|||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp
|
||||
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)
|
||||
|
@ -3880,7 +3880,6 @@ else
|
|||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
|
@ -5287,7 +5286,6 @@ case "$enableval" in
|
|||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
|
|
@ -2209,7 +2209,6 @@ is the key:</p>
|
|||
<th>Feature</th>
|
||||
<th>ARM</th>
|
||||
<th>Alpha</th>
|
||||
<th>Blackfin</th>
|
||||
<th>CellSPU</th>
|
||||
<th>MBlaze</th>
|
||||
<th>MSP430</th>
|
||||
|
@ -2225,7 +2224,6 @@ is the key:</p>
|
|||
<td><a href="#feat_reliable">is generally reliable</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
|
@ -2241,7 +2239,6 @@ is the key:</p>
|
|||
<td><a href="#feat_asmparser">assembly parser</a></td>
|
||||
<td class="no"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
|
@ -2257,7 +2254,6 @@ is the key:</p>
|
|||
<td><a href="#feat_disassembler">disassembler</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
|
@ -2273,7 +2269,6 @@ is the key:</p>
|
|||
<td><a href="#feat_inlineasm">inline asm</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="yes"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
|
@ -2289,7 +2284,6 @@ is the key:</p>
|
|||
<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> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
|
@ -2305,7 +2299,6 @@ is the key:</p>
|
|||
<td><a href="#feat_objectwrite">.o file writing</a></td>
|
||||
<td class="no"></td> <!-- ARM -->
|
||||
<td class="no"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="yes"></td> <!-- MBlaze -->
|
||||
<td class="no"></td> <!-- MSP430 -->
|
||||
|
@ -2321,7 +2314,6 @@ is the key:</p>
|
|||
<td><a href="#feat_tailcall">tail calls</a></td>
|
||||
<td class="yes"></td> <!-- ARM -->
|
||||
<td class="unknown"></td> <!-- Alpha -->
|
||||
<td class="no"></td> <!-- Blackfin -->
|
||||
<td class="no"></td> <!-- CellSPU -->
|
||||
<td class="no"></td> <!-- MBlaze -->
|
||||
<td class="unknown"></td> <!-- MSP430 -->
|
||||
|
|
|
@ -759,7 +759,7 @@ components, please contact us on the <a
|
|||
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
|
||||
|
||||
<ul>
|
||||
<li>The Alpha, Blackfin, CellSPU, MicroBlaze, MSP430, MIPS, PTX,
|
||||
<li>The Alpha, CellSPU, MicroBlaze, MSP430, MIPS, PTX,
|
||||
and XCore backends are experimental.</li>
|
||||
<li><tt>llc</tt> "<tt>-filetype=obj</tt>" is experimental on all targets
|
||||
other than darwin and ELF X86 systems.</li>
|
||||
|
|
|
@ -45,7 +45,6 @@ public:
|
|||
|
||||
alpha, // Alpha: alpha
|
||||
arm, // ARM; arm, armv.*, xscale
|
||||
bfin, // Blackfin: bfin
|
||||
cellspu, // CellSPU: spu, cellspu
|
||||
mips, // MIPS: mips, mipsallegrex
|
||||
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
|
||||
|
|
|
@ -20,7 +20,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
|
|||
|
||||
case alpha: return "alpha";
|
||||
case arm: return "arm";
|
||||
case bfin: return "bfin";
|
||||
case cellspu: return "cellspu";
|
||||
case mips: return "mips";
|
||||
case mipsel: return "mipsel";
|
||||
|
@ -56,8 +55,6 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
|
|||
case arm:
|
||||
case thumb: return "arm";
|
||||
|
||||
case bfin: return "bfin";
|
||||
|
||||
case cellspu: return "spu";
|
||||
|
||||
case ppc64:
|
||||
|
@ -138,8 +135,6 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
|
|||
return alpha;
|
||||
if (Name == "arm")
|
||||
return arm;
|
||||
if (Name == "bfin")
|
||||
return bfin;
|
||||
if (Name == "cellspu")
|
||||
return cellspu;
|
||||
if (Name == "mips")
|
||||
|
@ -278,8 +273,6 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
|
|||
return x86;
|
||||
else if (ArchName == "amd64" || ArchName == "x86_64")
|
||||
return x86_64;
|
||||
else if (ArchName == "bfin")
|
||||
return bfin;
|
||||
else if (ArchName == "powerpc")
|
||||
return ppc;
|
||||
else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
//=== Blackfin.h - Top-level interface for Blackfin backend -----*- 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
|
||||
// Blackfin back-end.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TARGET_BLACKFIN_H
|
||||
#define TARGET_BLACKFIN_H
|
||||
|
||||
#include "MCTargetDesc/BlackfinMCTargetDesc.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FunctionPass;
|
||||
class BlackfinTargetMachine;
|
||||
|
||||
FunctionPass *createBlackfinISelDag(BlackfinTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,202 +0,0 @@
|
|||
//===- Blackfin.td - Describe the Blackfin Target Machine --*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Target-independent interfaces which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Blackfin Subtarget features.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def FeatureSDRAM : SubtargetFeature<"sdram", "sdram", "true",
|
||||
"Build for SDRAM">;
|
||||
|
||||
def FeatureICPLB : SubtargetFeature<"icplb", "icplb", "true",
|
||||
"Assume instruction cache lookaside buffers are enabled at runtime">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Bugs in the silicon becomes workarounds in the compiler.
|
||||
// See http://www.analog.com/ for the full list of IC anomalies.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def WA_MI_SHIFT : SubtargetFeature<"mi-shift-anomaly","wa_mi_shift", "true",
|
||||
"Work around 05000074 - "
|
||||
"Multi-Issue Instruction with dsp32shiftimm and P-reg Store">;
|
||||
|
||||
def WA_CSYNC : SubtargetFeature<"csync-anomaly","wa_csync", "true",
|
||||
"Work around 05000244 - "
|
||||
"If I-Cache Is On, CSYNC/SSYNC/IDLE Around Change of Control">;
|
||||
|
||||
def WA_SPECLD : SubtargetFeature<"specld-anomaly","wa_specld", "true",
|
||||
"Work around 05000245 - "
|
||||
"Access in the Shadow of a Conditional Branch">;
|
||||
|
||||
def WA_HWLOOP : SubtargetFeature<"hwloop-anomaly","wa_hwloop", "true",
|
||||
"Work around 05000257 - "
|
||||
"Interrupt/Exception During Short Hardware Loop">;
|
||||
|
||||
def WA_MMR_STALL : SubtargetFeature<"mmr-stall-anomaly","wa_mmr_stall", "true",
|
||||
"Work around 05000283 - "
|
||||
"System MMR Write Is Stalled Indefinitely when Killed">;
|
||||
|
||||
def WA_LCREGS : SubtargetFeature<"lcregs-anomaly","wa_lcregs", "true",
|
||||
"Work around 05000312 - "
|
||||
"SSYNC, CSYNC, or Loads to LT, LB and LC Registers Are Interrupted">;
|
||||
|
||||
def WA_KILLED_MMR : SubtargetFeature<"killed-mmr-anomaly",
|
||||
"wa_killed_mmr", "true",
|
||||
"Work around 05000315 - "
|
||||
"Killed System MMR Write Completes Erroneously on Next System MMR Access">;
|
||||
|
||||
def WA_RETS : SubtargetFeature<"rets-anomaly", "wa_rets", "true",
|
||||
"Work around 05000371 - "
|
||||
"Possible RETS Register Corruption when Subroutine Is under 5 Cycles">;
|
||||
|
||||
def WA_IND_CALL : SubtargetFeature<"ind-call-anomaly", "wa_ind_call", "true",
|
||||
"Work around 05000426 - "
|
||||
"Speculative Fetches of Indirect-Pointer Instructions">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register File, Calling Conv, Instruction Descriptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "BlackfinRegisterInfo.td"
|
||||
include "BlackfinCallingConv.td"
|
||||
include "BlackfinIntrinsics.td"
|
||||
include "BlackfinInstrInfo.td"
|
||||
|
||||
def BlackfinInstrInfo : InstrInfo {}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Blackfin processors supported.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Proc<string Name, string Suffix, list<SubtargetFeature> Features>
|
||||
: Processor<!strconcat(Name, Suffix), NoItineraries, Features>;
|
||||
|
||||
def : Proc<"generic", "", []>;
|
||||
|
||||
multiclass Core<string Name,string Suffix,
|
||||
list<SubtargetFeature> Features> {
|
||||
def : Proc<Name, Suffix, Features>;
|
||||
def : Proc<Name, "", Features>;
|
||||
def : Proc<Name, "-none", []>;
|
||||
}
|
||||
|
||||
multiclass CoreEdinburgh<string Name>
|
||||
: Core<Name, "-0.6", [WA_MI_SHIFT, WA_SPECLD, WA_LCREGS]> {
|
||||
def : Proc<Name, "-0.5",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_MMR_STALL, WA_LCREGS, WA_KILLED_MMR,
|
||||
WA_RETS]>;
|
||||
def : Proc<Name, "-0.4",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS]>;
|
||||
def : Proc<Name, "-0.3",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS]>;
|
||||
def : Proc<Name, "-any",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS]>;
|
||||
}
|
||||
multiclass CoreBraemar<string Name>
|
||||
: Core<Name, "-0.3",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_LCREGS, WA_RETS, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.2",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreStirling<string Name>
|
||||
: Core<Name, "-0.5", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.4",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_LCREGS, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-0.3",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_MMR_STALL, WA_LCREGS, WA_KILLED_MMR,
|
||||
WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_MMR_STALL, WA_LCREGS, WA_KILLED_MMR,
|
||||
WA_RETS, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreMoab<string Name>
|
||||
: Core<Name, "-0.3", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.2", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-0.1", [WA_MI_SHIFT, WA_SPECLD, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-0.0",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_LCREGS, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_LCREGS, WA_RETS, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreTeton<string Name>
|
||||
: Core<Name, "-0.5",
|
||||
[WA_MI_SHIFT, WA_SPECLD, WA_MMR_STALL, WA_LCREGS, WA_KILLED_MMR,
|
||||
WA_RETS, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.3",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any",
|
||||
[WA_MI_SHIFT, WA_CSYNC, WA_SPECLD, WA_HWLOOP, WA_MMR_STALL, WA_LCREGS,
|
||||
WA_KILLED_MMR, WA_RETS, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreKookaburra<string Name>
|
||||
: Core<Name, "-0.2", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.1", [WA_MI_SHIFT, WA_SPECLD, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-0.0", [WA_MI_SHIFT, WA_SPECLD, WA_RETS, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any", [WA_MI_SHIFT, WA_SPECLD, WA_RETS, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreMockingbird<string Name>
|
||||
: Core<Name, "-0.1", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.0", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]>;
|
||||
}
|
||||
multiclass CoreBrodie<string Name>
|
||||
: Core<Name, "-0.1", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]> {
|
||||
def : Proc<Name, "-0.0", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]>;
|
||||
def : Proc<Name, "-any", [WA_MI_SHIFT, WA_SPECLD, WA_IND_CALL]>;
|
||||
}
|
||||
|
||||
defm BF512 : CoreBrodie<"bf512">;
|
||||
defm BF514 : CoreBrodie<"bf514">;
|
||||
defm BF516 : CoreBrodie<"bf516">;
|
||||
defm BF518 : CoreBrodie<"bf518">;
|
||||
defm BF522 : CoreMockingbird<"bf522">;
|
||||
defm BF523 : CoreKookaburra<"bf523">;
|
||||
defm BF524 : CoreMockingbird<"bf524">;
|
||||
defm BF525 : CoreKookaburra<"bf525">;
|
||||
defm BF526 : CoreMockingbird<"bf526">;
|
||||
defm BF527 : CoreKookaburra<"bf527">;
|
||||
defm BF531 : CoreEdinburgh<"bf531">;
|
||||
defm BF532 : CoreEdinburgh<"bf532">;
|
||||
defm BF533 : CoreEdinburgh<"bf533">;
|
||||
defm BF534 : CoreBraemar<"bf534">;
|
||||
defm BF536 : CoreBraemar<"bf536">;
|
||||
defm BF537 : CoreBraemar<"bf537">;
|
||||
defm BF538 : CoreStirling<"bf538">;
|
||||
defm BF539 : CoreStirling<"bf539">;
|
||||
defm BF542 : CoreMoab<"bf542">;
|
||||
defm BF544 : CoreMoab<"bf544">;
|
||||
defm BF548 : CoreMoab<"bf548">;
|
||||
defm BF549 : CoreMoab<"bf549">;
|
||||
defm BF561 : CoreTeton<"bf561">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declare the target which we are implementing
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def Blackfin : Target {
|
||||
// Pull in Instruction Info:
|
||||
let InstructionSet = BlackfinInstrInfo;
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
//===-- BlackfinAsmPrinter.cpp - Blackfin 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 BLACKFIN assembly language.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "Blackfin.h"
|
||||
#include "BlackfinInstrInfo.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/CodeGen/AsmPrinter.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/Mangler.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetLoweringObjectFile.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class BlackfinAsmPrinter : public AsmPrinter {
|
||||
public:
|
||||
BlackfinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
|
||||
: AsmPrinter(TM, Streamer) {}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Blackfin Assembly Printer";
|
||||
}
|
||||
|
||||
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
|
||||
void printMemoryOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
|
||||
void printInstruction(const MachineInstr *MI, raw_ostream &O);// autogen'd.
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
void EmitInstruction(const MachineInstr *MI) {
|
||||
SmallString<128> Str;
|
||||
raw_svector_ostream OS(Str);
|
||||
printInstruction(MI, OS);
|
||||
OutStreamer.EmitRawText(OS.str());
|
||||
}
|
||||
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 "BlackfinGenAsmWriter.inc"
|
||||
|
||||
extern "C" void LLVMInitializeBlackfinAsmPrinter() {
|
||||
RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
|
||||
}
|
||||
|
||||
void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
switch (MO.getType()) {
|
||||
case MachineOperand::MO_Register:
|
||||
assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
|
||||
"Virtual registers should be already mapped!");
|
||||
O << getRegisterName(MO.getReg());
|
||||
break;
|
||||
|
||||
case MachineOperand::MO_Immediate:
|
||||
O << MO.getImm();
|
||||
break;
|
||||
case MachineOperand::MO_MachineBasicBlock:
|
||||
O << *MO.getMBB()->getSymbol();
|
||||
return;
|
||||
case MachineOperand::MO_GlobalAddress:
|
||||
O << *Mang->getSymbol(MO.getGlobal());
|
||||
printOffset(MO.getOffset(), O);
|
||||
break;
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
O << *GetExternalSymbolSymbol(MO.getSymbolName());
|
||||
break;
|
||||
case MachineOperand::MO_ConstantPoolIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
|
||||
<< MO.getIndex();
|
||||
break;
|
||||
case MachineOperand::MO_JumpTableIndex:
|
||||
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
|
||||
<< '_' << MO.getIndex();
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("<unknown operand type>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BlackfinAsmPrinter::printMemoryOperand(const MachineInstr *MI, int opNum,
|
||||
raw_ostream &O) {
|
||||
printOperand(MI, opNum, O);
|
||||
|
||||
if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
|
||||
return;
|
||||
|
||||
O << " + ";
|
||||
printOperand(MI, opNum+1, O);
|
||||
}
|
||||
|
||||
/// PrintAsmOperand - Print out an operand for an inline asm expression.
|
||||
///
|
||||
bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
|
||||
unsigned OpNo, unsigned AsmVariant,
|
||||
const char *ExtraCode,
|
||||
raw_ostream &O) {
|
||||
if (ExtraCode && ExtraCode[0]) {
|
||||
if (ExtraCode[1] != 0) return true; // Unknown modifier.
|
||||
|
||||
switch (ExtraCode[0]) {
|
||||
default: return true; // Unknown modifier.
|
||||
case 'r':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printOperand(MI, OpNo, O);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BlackfinAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
||||
unsigned OpNo,
|
||||
unsigned AsmVariant,
|
||||
const char *ExtraCode,
|
||||
raw_ostream &O) {
|
||||
if (ExtraCode && ExtraCode[0])
|
||||
return true; // Unknown modifier
|
||||
|
||||
O << '[';
|
||||
printOperand(MI, OpNo, O);
|
||||
O << ']';
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
//===--- BlackfinCallingConv.td - Calling Conventions ------*- 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 the Blackfin architectures.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Blackfin C Calling convention.
|
||||
def CC_Blackfin : CallingConv<[
|
||||
CCIfType<[i16], CCPromoteToType<i32>>,
|
||||
CCIfSRet<CCAssignToReg<[P0]>>,
|
||||
CCAssignToReg<[R0, R1, R2]>,
|
||||
CCAssignToStack<4, 4>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Return Value Calling Conventions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Blackfin C return-value convention.
|
||||
def RetCC_Blackfin : CallingConv<[
|
||||
CCIfType<[i16], CCPromoteToType<i32>>,
|
||||
CCAssignToReg<[R0, R1]>
|
||||
]>;
|
|
@ -1,130 +0,0 @@
|
|||
//====- BlackfinFrameLowering.cpp - Blackfin 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 Blackfin implementation of TargetFrameLowering class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinFrameLowering.h"
|
||||
#include "BlackfinInstrInfo.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
// 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 BlackfinFrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
return DisableFramePointerElim(MF) ||
|
||||
MFI->adjustsStack() || MFI->hasVarSizedObjects();
|
||||
}
|
||||
|
||||
// Always reserve a call frame. We dont have enough registers to adjust SP.
|
||||
bool BlackfinFrameLowering::
|
||||
hasReservedCallFrame(const MachineFunction &MF) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Emit a prologue that sets up a stack frame.
|
||||
// On function entry, R0-R2 and P0 may hold arguments.
|
||||
// R3, P1, and P2 may be used as scratch registers
|
||||
void BlackfinFrameLowering::emitPrologue(MachineFunction &MF) const {
|
||||
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const BlackfinRegisterInfo *RegInfo =
|
||||
static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
|
||||
const BlackfinInstrInfo &TII =
|
||||
*static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
|
||||
|
||||
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
|
||||
|
||||
int FrameSize = MFI->getStackSize();
|
||||
if (FrameSize%4) {
|
||||
FrameSize = (FrameSize+3) & ~3;
|
||||
MFI->setStackSize(FrameSize);
|
||||
}
|
||||
|
||||
if (!hasFP(MF)) {
|
||||
assert(!MFI->adjustsStack() &&
|
||||
"FP elimination on a non-leaf function is not supported");
|
||||
RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, -FrameSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// emit a LINK instruction
|
||||
if (FrameSize <= 0x3ffff) {
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::LINK)).addImm(FrameSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// Frame is too big, do a manual LINK:
|
||||
// [--SP] = RETS;
|
||||
// [--SP] = FP;
|
||||
// FP = SP;
|
||||
// P1 = -FrameSize;
|
||||
// SP = SP + P1;
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
|
||||
.addReg(BF::RETS, RegState::Kill);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::PUSH))
|
||||
.addReg(BF::FP, RegState::Kill);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::MOVE), BF::FP)
|
||||
.addReg(BF::SP);
|
||||
RegInfo->loadConstant(MBB, MBBI, dl, BF::P1, -FrameSize);
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::ADDpp), BF::SP)
|
||||
.addReg(BF::SP, RegState::Kill)
|
||||
.addReg(BF::P1, RegState::Kill);
|
||||
|
||||
}
|
||||
|
||||
void BlackfinFrameLowering::emitEpilogue(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const BlackfinRegisterInfo *RegInfo =
|
||||
static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
|
||||
const BlackfinInstrInfo &TII =
|
||||
*static_cast<const BlackfinInstrInfo*>(MF.getTarget().getInstrInfo());
|
||||
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
|
||||
DebugLoc dl = MBBI->getDebugLoc();
|
||||
|
||||
int FrameSize = MFI->getStackSize();
|
||||
assert(FrameSize%4 == 0 && "Misaligned frame size");
|
||||
|
||||
if (!hasFP(MF)) {
|
||||
assert(!MFI->adjustsStack() &&
|
||||
"FP elimination on a non-leaf function is not supported");
|
||||
RegInfo->adjustRegister(MBB, MBBI, dl, BF::SP, BF::P1, FrameSize);
|
||||
return;
|
||||
}
|
||||
|
||||
// emit an UNLINK instruction
|
||||
BuildMI(MBB, MBBI, dl, TII.get(BF::UNLINK));
|
||||
}
|
||||
|
||||
void BlackfinFrameLowering::
|
||||
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const {
|
||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||
const BlackfinRegisterInfo *RegInfo =
|
||||
static_cast<const BlackfinRegisterInfo*>(MF.getTarget().getRegisterInfo());
|
||||
const TargetRegisterClass *RC = BF::DPRegisterClass;
|
||||
|
||||
if (RegInfo->requiresRegisterScavenging(MF)) {
|
||||
// Reserve a slot close to SP or frame pointer.
|
||||
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
|
||||
RC->getAlignment(),
|
||||
false));
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
//=- BlackfinFrameLowering.h - Define frame lowering for Blackfin -*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFIN_FRAMEINFO_H
|
||||
#define BLACKFIN_FRAMEINFO_H
|
||||
|
||||
#include "Blackfin.h"
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
class BlackfinSubtarget;
|
||||
|
||||
class BlackfinFrameLowering : public TargetFrameLowering {
|
||||
protected:
|
||||
const BlackfinSubtarget &STI;
|
||||
|
||||
public:
|
||||
explicit BlackfinFrameLowering(const BlackfinSubtarget &sti)
|
||||
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0), STI(sti) {
|
||||
}
|
||||
|
||||
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
|
||||
/// the function.
|
||||
void emitPrologue(MachineFunction &MF) const;
|
||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||
|
||||
bool hasFP(const MachineFunction &MF) const;
|
||||
bool hasReservedCallFrame(const MachineFunction &MF) const;
|
||||
|
||||
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
||||
RegScavenger *RS) const;
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
|
@ -1,180 +0,0 @@
|
|||
//===- BlackfinISelDAGToDAG.cpp - A dag to dag inst selector for Blackfin -===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines an instruction selector for the Blackfin target.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Blackfin.h"
|
||||
#include "BlackfinTargetMachine.h"
|
||||
#include "BlackfinRegisterInfo.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Selector Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// BlackfinDAGToDAGISel - Blackfin specific code to select blackfin machine
|
||||
/// instructions for SelectionDAG operations.
|
||||
namespace {
|
||||
class BlackfinDAGToDAGISel : public SelectionDAGISel {
|
||||
/// Subtarget - Keep a pointer to the Blackfin Subtarget around so that we
|
||||
/// can make the right decision when generating code for different targets.
|
||||
//const BlackfinSubtarget &Subtarget;
|
||||
public:
|
||||
BlackfinDAGToDAGISel(BlackfinTargetMachine &TM, CodeGenOpt::Level OptLevel)
|
||||
: SelectionDAGISel(TM, OptLevel) {}
|
||||
|
||||
virtual void PostprocessISelDAG();
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "Blackfin DAG->DAG Pattern Instruction Selection";
|
||||
}
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "BlackfinGenDAGISel.inc"
|
||||
|
||||
private:
|
||||
SDNode *Select(SDNode *N);
|
||||
bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
|
||||
|
||||
// Walk the DAG after instruction selection, fixing register class issues.
|
||||
void FixRegisterClasses(SelectionDAG &DAG);
|
||||
|
||||
const BlackfinInstrInfo &getInstrInfo() {
|
||||
return *static_cast<const BlackfinTargetMachine&>(TM).getInstrInfo();
|
||||
}
|
||||
const BlackfinRegisterInfo *getRegisterInfo() {
|
||||
return static_cast<const BlackfinTargetMachine&>(TM).getRegisterInfo();
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
FunctionPass *llvm::createBlackfinISelDag(BlackfinTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
return new BlackfinDAGToDAGISel(TM, OptLevel);
|
||||
}
|
||||
|
||||
void BlackfinDAGToDAGISel::PostprocessISelDAG() {
|
||||
FixRegisterClasses(*CurDAG);
|
||||
}
|
||||
|
||||
SDNode *BlackfinDAGToDAGISel::Select(SDNode *N) {
|
||||
if (N->isMachineOpcode())
|
||||
return NULL; // Already selected.
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: break;
|
||||
case ISD::FrameIndex: {
|
||||
// Selects to ADDpp FI, 0 which in turn will become ADDimm7 SP, imm or ADDpp
|
||||
// SP, Px
|
||||
int FI = cast<FrameIndexSDNode>(N)->getIndex();
|
||||
SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i32);
|
||||
return CurDAG->SelectNodeTo(N, BF::ADDpp, MVT::i32, TFI,
|
||||
CurDAG->getTargetConstant(0, MVT::i32));
|
||||
}
|
||||
}
|
||||
|
||||
return SelectCode(N);
|
||||
}
|
||||
|
||||
bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Addr,
|
||||
SDValue &Base,
|
||||
SDValue &Offset) {
|
||||
FrameIndexSDNode *FIN = 0;
|
||||
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
|
||||
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
|
||||
Offset = CurDAG->getTargetConstant(0, MVT::i32);
|
||||
return true;
|
||||
}
|
||||
if (Addr.getOpcode() == ISD::ADD) {
|
||||
ConstantSDNode *CN = 0;
|
||||
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) &&
|
||||
(CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) &&
|
||||
(CN->getSExtValue() % 4 == 0 && CN->getSExtValue() >= 0)) {
|
||||
// Constant positive word offset from frame index
|
||||
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
|
||||
Offset = CurDAG->getTargetConstant(CN->getSExtValue(), MVT::i32);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool isCC(const TargetRegisterClass *RC) {
|
||||
return BF::AnyCCRegClass.hasSubClassEq(RC);
|
||||
}
|
||||
|
||||
static inline bool isDCC(const TargetRegisterClass *RC) {
|
||||
return BF::DRegClass.hasSubClassEq(RC) || isCC(RC);
|
||||
}
|
||||
|
||||
static void UpdateNodeOperand(SelectionDAG &DAG,
|
||||
SDNode *N,
|
||||
unsigned Num,
|
||||
SDValue Val) {
|
||||
SmallVector<SDValue, 8> ops(N->op_begin(), N->op_end());
|
||||
ops[Num] = Val;
|
||||
SDNode *New = DAG.UpdateNodeOperands(N, ops.data(), ops.size());
|
||||
DAG.ReplaceAllUsesWith(N, New);
|
||||
}
|
||||
|
||||
// After instruction selection, insert COPY_TO_REGCLASS nodes to help in
|
||||
// choosing the proper register classes.
|
||||
void BlackfinDAGToDAGISel::FixRegisterClasses(SelectionDAG &DAG) {
|
||||
const BlackfinInstrInfo &TII = getInstrInfo();
|
||||
const BlackfinRegisterInfo *TRI = getRegisterInfo();
|
||||
DAG.AssignTopologicalOrder();
|
||||
HandleSDNode Dummy(DAG.getRoot());
|
||||
|
||||
for (SelectionDAG::allnodes_iterator NI = DAG.allnodes_begin();
|
||||
NI != DAG.allnodes_end(); ++NI) {
|
||||
if (NI->use_empty() || !NI->isMachineOpcode())
|
||||
continue;
|
||||
const MCInstrDesc &DefMCID = TII.get(NI->getMachineOpcode());
|
||||
for (SDNode::use_iterator UI = NI->use_begin(); !UI.atEnd(); ++UI) {
|
||||
if (!UI->isMachineOpcode())
|
||||
continue;
|
||||
|
||||
if (UI.getUse().getResNo() >= DefMCID.getNumDefs())
|
||||
continue;
|
||||
const TargetRegisterClass *DefRC =
|
||||
TII.getRegClass(DefMCID, UI.getUse().getResNo(), TRI);
|
||||
|
||||
const MCInstrDesc &UseMCID = TII.get(UI->getMachineOpcode());
|
||||
if (UseMCID.getNumDefs()+UI.getOperandNo() >= UseMCID.getNumOperands())
|
||||
continue;
|
||||
const TargetRegisterClass *UseRC =
|
||||
TII.getRegClass(UseMCID, UseMCID.getNumDefs()+UI.getOperandNo(), TRI);
|
||||
if (!DefRC || !UseRC)
|
||||
continue;
|
||||
// We cannot copy CC <-> !(CC/D)
|
||||
if ((isCC(DefRC) && !isDCC(UseRC)) || (isCC(UseRC) && !isDCC(DefRC))) {
|
||||
SDNode *Copy =
|
||||
DAG.getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
|
||||
NI->getDebugLoc(),
|
||||
MVT::i32,
|
||||
UI.getUse().get(),
|
||||
DAG.getTargetConstant(BF::DRegClassID, MVT::i32));
|
||||
UpdateNodeOperand(DAG, *UI, UI.getOperandNo(), SDValue(Copy, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
DAG.setRoot(Dummy.getValue());
|
||||
}
|
||||
|
|
@ -1,645 +0,0 @@
|
|||
//===- BlackfinISelLowering.cpp - Blackfin 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 interfaces that Blackfin uses to lower LLVM code
|
||||
// into a selection DAG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinISelLowering.h"
|
||||
#include "BlackfinTargetMachine.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
||||
#include "llvm/ADT/VectorExtras.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
using namespace llvm;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinGenCallingConv.inc"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TargetLowering Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
BlackfinTargetLowering::BlackfinTargetLowering(TargetMachine &TM)
|
||||
: TargetLowering(TM, new TargetLoweringObjectFileELF()) {
|
||||
setBooleanContents(ZeroOrOneBooleanContent);
|
||||
setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
|
||||
setStackPointerRegisterToSaveRestore(BF::SP);
|
||||
setIntDivIsCheap(false);
|
||||
|
||||
// Set up the legal register classes.
|
||||
addRegisterClass(MVT::i32, BF::DRegisterClass);
|
||||
addRegisterClass(MVT::i16, BF::D16RegisterClass);
|
||||
|
||||
computeRegisterProperties();
|
||||
|
||||
// Blackfin doesn't have i1 loads or stores
|
||||
setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
|
||||
setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
||||
|
||||
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
|
||||
|
||||
// i16 registers don't do much
|
||||
setOperationAction(ISD::AND, MVT::i16, Promote);
|
||||
setOperationAction(ISD::OR, MVT::i16, Promote);
|
||||
setOperationAction(ISD::XOR, MVT::i16, Promote);
|
||||
setOperationAction(ISD::CTPOP, MVT::i16, Promote);
|
||||
// The expansion of CTLZ/CTTZ uses AND/OR, so we might as well promote
|
||||
// immediately.
|
||||
setOperationAction(ISD::CTLZ, MVT::i16, Promote);
|
||||
setOperationAction(ISD::CTTZ, MVT::i16, Promote);
|
||||
setOperationAction(ISD::SETCC, MVT::i16, Promote);
|
||||
|
||||
// Blackfin has no division
|
||||
setOperationAction(ISD::SDIV, MVT::i16, Expand);
|
||||
setOperationAction(ISD::SDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
|
||||
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SREM, MVT::i16, Expand);
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i16, Expand);
|
||||
setOperationAction(ISD::UDIV, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIVREM, MVT::i16, Expand);
|
||||
setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UREM, MVT::i16, Expand);
|
||||
setOperationAction(ISD::UREM, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
|
||||
setOperationAction(ISD::MULHU, MVT::i32, Expand);
|
||||
setOperationAction(ISD::MULHS, MVT::i32, Expand);
|
||||
|
||||
// No carry-in operations.
|
||||
setOperationAction(ISD::ADDE, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SUBE, MVT::i32, Custom);
|
||||
|
||||
// Blackfin has no intrinsics for these particular operations.
|
||||
setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
|
||||
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
|
||||
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
|
||||
// i32 has native CTPOP, but not CTLZ/CTTZ
|
||||
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
|
||||
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
|
||||
|
||||
// READCYCLECOUNTER needs special type legalization.
|
||||
setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
|
||||
|
||||
setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
|
||||
|
||||
// Use the default implementation.
|
||||
setOperationAction(ISD::VACOPY, MVT::Other, Expand);
|
||||
setOperationAction(ISD::VAEND, MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
|
||||
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
|
||||
|
||||
setMinFunctionAlignment(2);
|
||||
}
|
||||
|
||||
const char *BlackfinTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch (Opcode) {
|
||||
default: return 0;
|
||||
case BFISD::CALL: return "BFISD::CALL";
|
||||
case BFISD::RET_FLAG: return "BFISD::RET_FLAG";
|
||||
case BFISD::Wrapper: return "BFISD::Wrapper";
|
||||
}
|
||||
}
|
||||
|
||||
EVT BlackfinTargetLowering::getSetCCResultType(EVT VT) const {
|
||||
// SETCC always sets the CC register. Technically that is an i1 register, but
|
||||
// that type is not legal, so we treat it as an i32 register.
|
||||
return MVT::i32;
|
||||
}
|
||||
|
||||
SDValue BlackfinTargetLowering::LowerGlobalAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc DL = Op.getDebugLoc();
|
||||
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
|
||||
|
||||
Op = DAG.getTargetGlobalAddress(GV, DL, MVT::i32);
|
||||
return DAG.getNode(BFISD::Wrapper, DL, MVT::i32, Op);
|
||||
}
|
||||
|
||||
SDValue BlackfinTargetLowering::LowerJumpTable(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc DL = Op.getDebugLoc();
|
||||
int JTI = cast<JumpTableSDNode>(Op)->getIndex();
|
||||
|
||||
Op = DAG.getTargetJumpTable(JTI, MVT::i32);
|
||||
return DAG.getNode(BFISD::Wrapper, DL, MVT::i32, Op);
|
||||
}
|
||||
|
||||
SDValue
|
||||
BlackfinTargetLowering::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();
|
||||
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
getTargetMachine(), ArgLocs, *DAG.getContext());
|
||||
CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space
|
||||
CCInfo.AnalyzeFormalArguments(Ins, CC_Blackfin);
|
||||
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
EVT RegVT = VA.getLocVT();
|
||||
TargetRegisterClass *RC = VA.getLocReg() == BF::P0 ?
|
||||
BF::PRegisterClass : BF::DRegisterClass;
|
||||
assert(RC->contains(VA.getLocReg()) && "Unexpected regclass in CCState");
|
||||
assert(RC->hasType(RegVT) && "Unexpected regclass in CCState");
|
||||
|
||||
unsigned Reg = MF.getRegInfo().createVirtualRegister(RC);
|
||||
MF.getRegInfo().addLiveIn(VA.getLocReg(), Reg);
|
||||
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
|
||||
|
||||
// If this is an 8 or 16-bit value, it is really passed promoted to 32
|
||||
// bits. Insert an assert[sz]ext to capture this, then truncate to the
|
||||
// right size.
|
||||
if (VA.getLocInfo() == CCValAssign::SExt)
|
||||
ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
else if (VA.getLocInfo() == CCValAssign::ZExt)
|
||||
ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
|
||||
DAG.getValueType(VA.getValVT()));
|
||||
|
||||
if (VA.getLocInfo() != CCValAssign::Full)
|
||||
ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
|
||||
|
||||
InVals.push_back(ArgValue);
|
||||
} else {
|
||||
assert(VA.isMemLoc() && "CCValAssign must be RegLoc or MemLoc");
|
||||
unsigned ObjSize = VA.getLocVT().getStoreSize();
|
||||
int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
|
||||
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
|
||||
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
|
||||
MachinePointerInfo(),
|
||||
false, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue
|
||||
BlackfinTargetLowering::LowerReturn(SDValue Chain,
|
||||
CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
DebugLoc dl, SelectionDAG &DAG) const {
|
||||
|
||||
// CCValAssign - represent the assignment of the return value to locations.
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
|
||||
// CCState - Info about the registers and stack slot.
|
||||
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
DAG.getTarget(), RVLocs, *DAG.getContext());
|
||||
|
||||
// Analize return values.
|
||||
CCInfo.AnalyzeReturn(Outs, RetCC_Blackfin);
|
||||
|
||||
// If this is the first return lowered for this function, add the regs to the
|
||||
// liveout set for the function.
|
||||
if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i)
|
||||
DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
|
||||
}
|
||||
|
||||
SDValue Flag;
|
||||
|
||||
// Copy the result values into the output registers.
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
CCValAssign &VA = RVLocs[i];
|
||||
assert(VA.isRegLoc() && "Can only return in registers!");
|
||||
SDValue Opi = OutVals[i];
|
||||
|
||||
// Expand to i32 if necessary
|
||||
switch (VA.getLocInfo()) {
|
||||
default: llvm_unreachable("Unknown loc info!");
|
||||
case CCValAssign::Full: break;
|
||||
case CCValAssign::SExt:
|
||||
Opi = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Opi);
|
||||
break;
|
||||
case CCValAssign::ZExt:
|
||||
Opi = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Opi);
|
||||
break;
|
||||
case CCValAssign::AExt:
|
||||
Opi = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Opi);
|
||||
break;
|
||||
}
|
||||
Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), Opi, SDValue());
|
||||
// Guarantee that all emitted copies are stuck together with flags.
|
||||
Flag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
if (Flag.getNode()) {
|
||||
return DAG.getNode(BFISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
|
||||
} else {
|
||||
return DAG.getNode(BFISD::RET_FLAG, dl, MVT::Other, Chain);
|
||||
}
|
||||
}
|
||||
|
||||
SDValue
|
||||
BlackfinTargetLowering::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 {
|
||||
// Blackfin 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(),
|
||||
DAG.getTarget(), ArgLocs, *DAG.getContext());
|
||||
CCInfo.AllocateStack(12, 4); // ABI requires 12 bytes stack space
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_Blackfin);
|
||||
|
||||
// Get the size of the outgoing arguments stack space requirement.
|
||||
unsigned ArgsSize = CCInfo.getNextStackOffset();
|
||||
|
||||
Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize, true));
|
||||
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
|
||||
SmallVector<SDValue, 8> MemOpChains;
|
||||
|
||||
// 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: llvm_unreachable("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() && "CCValAssign must be RegLoc or MemLoc");
|
||||
int Offset = VA.getLocMemOffset();
|
||||
assert(Offset%4 == 0 && "Unaligned LocMemOffset");
|
||||
assert(VA.getLocVT()==MVT::i32 && "Illegal CCValAssign type");
|
||||
SDValue SPN = DAG.getCopyFromReg(Chain, dl, BF::SP, MVT::i32);
|
||||
SDValue OffsetN = DAG.getIntPtrConstant(Offset);
|
||||
OffsetN = DAG.getNode(ISD::ADD, dl, MVT::i32, SPN, OffsetN);
|
||||
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, OffsetN,
|
||||
MachinePointerInfo(),false, false, 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Transform all store nodes into one single node because
|
||||
// all store nodes are independent of each other.
|
||||
if (!MemOpChains.empty())
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
|
||||
&MemOpChains[0], MemOpChains.size());
|
||||
|
||||
// Build a sequence of copy-to-reg nodes chained together with token
|
||||
// chain and flag operands which copy the outgoing args into registers.
|
||||
// The InFlag in necessary since all emitted instructions must be
|
||||
// stuck together.
|
||||
SDValue InFlag;
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
}
|
||||
|
||||
// If the callee is a GlobalAddress node (quite common, every direct call is)
|
||||
// turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
|
||||
// Likewise ExternalSymbol -> TargetExternalSymbol.
|
||||
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
|
||||
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
|
||||
else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
|
||||
Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
|
||||
|
||||
std::vector<EVT> NodeTys;
|
||||
NodeTys.push_back(MVT::Other); // Returns a chain
|
||||
NodeTys.push_back(MVT::Glue); // Returns a flag for retval copy to use.
|
||||
SDValue Ops[] = { Chain, Callee, InFlag };
|
||||
Chain = DAG.getNode(BFISD::CALL, dl, NodeTys, Ops,
|
||||
InFlag.getNode() ? 3 : 2);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(ArgsSize, true),
|
||||
DAG.getIntPtrConstant(0, true), InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
// Assign locations to each value returned by this call.
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
CCState RVInfo(CallConv, isVarArg, DAG.getMachineFunction(),
|
||||
DAG.getTarget(), RVLocs, *DAG.getContext());
|
||||
|
||||
RVInfo.AnalyzeCallResult(Ins, RetCC_Blackfin);
|
||||
|
||||
// Copy all of the result registers out of their specified physreg.
|
||||
for (unsigned i = 0; i != RVLocs.size(); ++i) {
|
||||
CCValAssign &RV = RVLocs[i];
|
||||
unsigned Reg = RV.getLocReg();
|
||||
|
||||
Chain = DAG.getCopyFromReg(Chain, dl, Reg,
|
||||
RVLocs[i].getLocVT(), InFlag);
|
||||
SDValue Val = Chain.getValue(0);
|
||||
InFlag = Chain.getValue(2);
|
||||
Chain = Chain.getValue(1);
|
||||
|
||||
// Callee is responsible for extending any i16 return values.
|
||||
switch (RV.getLocInfo()) {
|
||||
case CCValAssign::SExt:
|
||||
Val = DAG.getNode(ISD::AssertSext, dl, RV.getLocVT(), Val,
|
||||
DAG.getValueType(RV.getValVT()));
|
||||
break;
|
||||
case CCValAssign::ZExt:
|
||||
Val = DAG.getNode(ISD::AssertZext, dl, RV.getLocVT(), Val,
|
||||
DAG.getValueType(RV.getValVT()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Truncate to valtype
|
||||
if (RV.getLocInfo() != CCValAssign::Full)
|
||||
Val = DAG.getNode(ISD::TRUNCATE, dl, RV.getValVT(), Val);
|
||||
InVals.push_back(Val);
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
// Expansion of ADDE / SUBE. This is a bit involved since blackfin doesn't have
|
||||
// add-with-carry instructions.
|
||||
SDValue BlackfinTargetLowering::LowerADDE(SDValue Op, SelectionDAG &DAG) const {
|
||||
// Operands: lhs, rhs, carry-in (AC0 flag)
|
||||
// Results: sum, carry-out (AC0 flag)
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
|
||||
unsigned Opcode = Op.getOpcode()==ISD::ADDE ? BF::ADD : BF::SUB;
|
||||
|
||||
// zext incoming carry flag in AC0 to 32 bits
|
||||
SDNode* CarryIn = DAG.getMachineNode(BF::MOVE_cc_ac0, dl, MVT::i32,
|
||||
/* flag= */ Op.getOperand(2));
|
||||
CarryIn = DAG.getMachineNode(BF::MOVECC_zext, dl, MVT::i32,
|
||||
SDValue(CarryIn, 0));
|
||||
|
||||
// Add operands, produce sum and carry flag
|
||||
SDNode *Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
|
||||
Op.getOperand(0), Op.getOperand(1));
|
||||
|
||||
// Store intermediate carry from Sum
|
||||
SDNode* Carry1 = DAG.getMachineNode(BF::MOVE_cc_ac0, dl, MVT::i32,
|
||||
/* flag= */ SDValue(Sum, 1));
|
||||
|
||||
// Add incoming carry, again producing an output flag
|
||||
Sum = DAG.getMachineNode(Opcode, dl, MVT::i32, MVT::Glue,
|
||||
SDValue(Sum, 0), SDValue(CarryIn, 0));
|
||||
|
||||
// Update AC0 with the intermediate carry, producing a flag.
|
||||
SDNode *CarryOut = DAG.getMachineNode(BF::OR_ac0_cc, dl, MVT::Glue,
|
||||
SDValue(Carry1, 0));
|
||||
|
||||
// Compose (i32, flag) pair
|
||||
SDValue ops[2] = { SDValue(Sum, 0), SDValue(CarryOut, 0) };
|
||||
return DAG.getMergeValues(ops, 2, dl);
|
||||
}
|
||||
|
||||
SDValue BlackfinTargetLowering::LowerOperation(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
switch (Op.getOpcode()) {
|
||||
default:
|
||||
Op.getNode()->dump();
|
||||
llvm_unreachable("Should not custom lower this!");
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::GlobalTLSAddress:
|
||||
llvm_unreachable("TLS not implemented for Blackfin.");
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
// Frame & Return address. Currently unimplemented
|
||||
case ISD::FRAMEADDR: return SDValue();
|
||||
case ISD::RETURNADDR: return SDValue();
|
||||
case ISD::ADDE:
|
||||
case ISD::SUBE: return LowerADDE(Op, DAG);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BlackfinTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue> &Results,
|
||||
SelectionDAG &DAG) const {
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
switch (N->getOpcode()) {
|
||||
default:
|
||||
llvm_unreachable("Do not know how to custom type legalize this operation!");
|
||||
return;
|
||||
case ISD::READCYCLECOUNTER: {
|
||||
// The low part of the cycle counter is in CYCLES, the high part in
|
||||
// CYCLES2. Reading CYCLES will latch the value of CYCLES2, so we must read
|
||||
// CYCLES2 last.
|
||||
SDValue TheChain = N->getOperand(0);
|
||||
SDValue lo = DAG.getCopyFromReg(TheChain, dl, BF::CYCLES, MVT::i32);
|
||||
SDValue hi = DAG.getCopyFromReg(lo.getValue(1), dl, BF::CYCLES2, MVT::i32);
|
||||
// Use a buildpair to merge the two 32-bit values into a 64-bit one.
|
||||
Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, lo, hi));
|
||||
// Outgoing chain. If we were to use the chain from lo instead, it would be
|
||||
// possible to entirely eliminate the CYCLES2 read in (i32 (trunc
|
||||
// readcyclecounter)). Unfortunately this could possibly delay the CYCLES2
|
||||
// read beyond the next CYCLES read, leading to invalid results.
|
||||
Results.push_back(hi.getValue(1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Blackfin Inline Assembly Support
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// getConstraintType - Given a constraint letter, return the type of
|
||||
/// constraint it is for this target.
|
||||
BlackfinTargetLowering::ConstraintType
|
||||
BlackfinTargetLowering::getConstraintType(const std::string &Constraint) const {
|
||||
if (Constraint.size() != 1)
|
||||
return TargetLowering::getConstraintType(Constraint);
|
||||
|
||||
switch (Constraint[0]) {
|
||||
// Standard constraints
|
||||
case 'r':
|
||||
return C_RegisterClass;
|
||||
|
||||
// Blackfin-specific constraints
|
||||
case 'a':
|
||||
case 'd':
|
||||
case 'z':
|
||||
case 'D':
|
||||
case 'W':
|
||||
case 'e':
|
||||
case 'b':
|
||||
case 'v':
|
||||
case 'f':
|
||||
case 'c':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'k':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'w':
|
||||
return C_RegisterClass;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'Z':
|
||||
case 'Y':
|
||||
return C_Register;
|
||||
}
|
||||
|
||||
// Not implemented: q0-q7, qA. Use {R2} etc instead
|
||||
|
||||
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
|
||||
BlackfinTargetLowering::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;
|
||||
|
||||
// Blackfin-specific constraints
|
||||
case 'a':
|
||||
case 'd':
|
||||
case 'z':
|
||||
case 'D':
|
||||
case 'W':
|
||||
case 'e':
|
||||
case 'b':
|
||||
case 'v':
|
||||
case 'f':
|
||||
case 'c':
|
||||
case 't':
|
||||
case 'u':
|
||||
case 'k':
|
||||
case 'x':
|
||||
case 'y':
|
||||
case 'w':
|
||||
return CW_Register;
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'Z':
|
||||
case 'Y':
|
||||
return CW_SpecificReg;
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
/// getRegForInlineAsmConstraint - Return register no and class for a C_Register
|
||||
/// constraint.
|
||||
std::pair<unsigned, const TargetRegisterClass*> BlackfinTargetLowering::
|
||||
getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
|
||||
typedef std::pair<unsigned, const TargetRegisterClass*> Pair;
|
||||
using namespace BF;
|
||||
|
||||
if (Constraint.size() != 1)
|
||||
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
|
||||
|
||||
switch (Constraint[0]) {
|
||||
// Standard constraints
|
||||
case 'r':
|
||||
return Pair(0U, VT == MVT::i16 ? D16RegisterClass : DPRegisterClass);
|
||||
|
||||
// Blackfin-specific constraints
|
||||
case 'a': return Pair(0U, PRegisterClass);
|
||||
case 'd': return Pair(0U, DRegisterClass);
|
||||
case 'e': return Pair(0U, AccuRegisterClass);
|
||||
case 'A': return Pair(A0, AccuRegisterClass);
|
||||
case 'B': return Pair(A1, AccuRegisterClass);
|
||||
case 'b': return Pair(0U, IRegisterClass);
|
||||
case 'v': return Pair(0U, BRegisterClass);
|
||||
case 'f': return Pair(0U, MRegisterClass);
|
||||
case 'C': return Pair(CC, JustCCRegisterClass);
|
||||
case 'x': return Pair(0U, GRRegisterClass);
|
||||
case 'w': return Pair(0U, ALLRegisterClass);
|
||||
case 'Z': return Pair(P3, PRegisterClass);
|
||||
case 'Y': return Pair(P1, PRegisterClass);
|
||||
case 'z': return Pair(0U, zConsRegisterClass);
|
||||
case 'D': return Pair(0U, DConsRegisterClass);
|
||||
case 'W': return Pair(0U, WConsRegisterClass);
|
||||
case 'c': return Pair(0U, cConsRegisterClass);
|
||||
case 't': return Pair(0U, tConsRegisterClass);
|
||||
case 'u': return Pair(0U, uConsRegisterClass);
|
||||
case 'k': return Pair(0U, kConsRegisterClass);
|
||||
case 'y': return Pair(0U, yConsRegisterClass);
|
||||
}
|
||||
|
||||
// Not implemented: q0-q7, qA. Use {R2} etc instead.
|
||||
|
||||
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
|
||||
}
|
||||
|
||||
bool BlackfinTargetLowering::
|
||||
isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
// The Blackfin target isn't yet aware of offsets.
|
||||
return false;
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
//===- BlackfinISelLowering.h - Blackfin 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 Blackfin uses to lower LLVM code into a
|
||||
// selection DAG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFIN_ISELLOWERING_H
|
||||
#define BLACKFIN_ISELLOWERING_H
|
||||
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "Blackfin.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace BFISD {
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
CALL, // A call instruction.
|
||||
RET_FLAG, // Return with a flag operand.
|
||||
Wrapper // Address wrapper
|
||||
};
|
||||
}
|
||||
|
||||
class BlackfinTargetLowering : public TargetLowering {
|
||||
public:
|
||||
BlackfinTargetLowering(TargetMachine &TM);
|
||||
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i16; }
|
||||
virtual EVT getSetCCResultType(EVT VT) const;
|
||||
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
|
||||
virtual void ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue> &Results,
|
||||
SelectionDAG &DAG) 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;
|
||||
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
|
||||
const char *getTargetNodeName(unsigned Opcode) const;
|
||||
|
||||
private:
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerADDE(SDValue Op, 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;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // BLACKFIN_ISELLOWERING_H
|
|
@ -1,34 +0,0 @@
|
|||
//===--- BlackfinInstrFormats.td ---------------------------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction format superclass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class InstBfin<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: Instruction {
|
||||
field bits<32> Inst;
|
||||
|
||||
let Namespace = "BF";
|
||||
|
||||
dag OutOperandList = outs;
|
||||
dag InOperandList = ins;
|
||||
let AsmString = asmstr;
|
||||
let Pattern = pattern;
|
||||
}
|
||||
|
||||
// Single-word (16-bit) instructions
|
||||
class F1<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstBfin<outs, ins, asmstr, pattern> {
|
||||
}
|
||||
|
||||
// Double-word (32-bit) instructions
|
||||
class F2<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstBfin<outs, ins, asmstr, pattern> {
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
//===- BlackfinInstrInfo.cpp - Blackfin 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 Blackfin implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinInstrInfo.h"
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "Blackfin.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#define GET_INSTRINFO_CTOR
|
||||
#include "BlackfinGenInstrInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget &ST)
|
||||
: BlackfinGenInstrInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP),
|
||||
RI(ST, *this),
|
||||
Subtarget(ST) {}
|
||||
|
||||
/// isLoadFromStackSlot - If the specified machine instruction is a direct
|
||||
/// load from a stack slot, return the virtual or physical register number of
|
||||
/// the destination along with the FrameIndex of the loaded stack slot. If
|
||||
/// not, return 0. This predicate must return 0 if the instruction has
|
||||
/// any side effects other than loading from the stack slot.
|
||||
unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case BF::LOAD32fi:
|
||||
case BF::LOAD16fi:
|
||||
if (MI->getOperand(1).isFI() &&
|
||||
MI->getOperand(2).isImm() &&
|
||||
MI->getOperand(2).getImm() == 0) {
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// isStoreToStackSlot - If the specified machine instruction is a direct
|
||||
/// store to a stack slot, return the virtual or physical register number of
|
||||
/// the source reg along with the FrameIndex of the loaded stack slot. If
|
||||
/// not, return 0. This predicate must return 0 if the instruction has
|
||||
/// any side effects other than storing to the stack slot.
|
||||
unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
||||
int &FrameIndex) const {
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case BF::STORE32fi:
|
||||
case BF::STORE16fi:
|
||||
if (MI->getOperand(1).isFI() &&
|
||||
MI->getOperand(2).isImm() &&
|
||||
MI->getOperand(2).getImm() == 0) {
|
||||
FrameIndex = MI->getOperand(1).getIndex();
|
||||
return MI->getOperand(0).getReg();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned BlackfinInstrInfo::
|
||||
InsertBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *TBB,
|
||||
MachineBasicBlock *FBB,
|
||||
const SmallVectorImpl<MachineOperand> &Cond,
|
||||
DebugLoc DL) const {
|
||||
// Shouldn't be a fall through.
|
||||
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
|
||||
assert((Cond.size() == 1 || Cond.size() == 0) &&
|
||||
"Branch conditions have one component!");
|
||||
|
||||
if (Cond.empty()) {
|
||||
// Unconditional branch?
|
||||
assert(!FBB && "Unconditional branch with multiple successors!");
|
||||
BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Conditional branch.
|
||||
llvm_unreachable("Implement conditional branches!");
|
||||
}
|
||||
|
||||
void BlackfinInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I, DebugLoc DL,
|
||||
unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const {
|
||||
if (BF::ALLRegClass.contains(DestReg, SrcReg)) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVE), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (BF::D16RegClass.contains(DestReg, SrcReg)) {
|
||||
BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc))
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (BF::DRegClass.contains(DestReg)) {
|
||||
if (SrcReg == BF::NCC) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
|
||||
return;
|
||||
}
|
||||
if (SrcReg == BF::CC) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (BF::DRegClass.contains(SrcReg)) {
|
||||
if (DestReg == BF::NCC) {
|
||||
BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc)).addImm(0);
|
||||
return;
|
||||
}
|
||||
if (DestReg == BF::CC) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (DestReg == BF::NCC && SrcReg == BF::CC) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
|
||||
if (DestReg == BF::CC && SrcReg == BF::NCC) {
|
||||
BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg)
|
||||
.addReg(SrcReg, getKillRegState(KillSrc));
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_unreachable("Bad reg-to-reg copy");
|
||||
}
|
||||
|
||||
static bool inClass(const TargetRegisterClass &Test,
|
||||
unsigned Reg,
|
||||
const TargetRegisterClass *RC) {
|
||||
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||
return Test.contains(Reg);
|
||||
else
|
||||
return Test.hasSubClassEq(RC);
|
||||
}
|
||||
|
||||
void
|
||||
BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned SrcReg,
|
||||
bool isKill,
|
||||
int FI,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
|
||||
|
||||
if (inClass(BF::DPRegClass, SrcReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::STORE32fi))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inClass(BF::D16RegClass, SrcReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::STORE16fi))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::STORE8fi))
|
||||
.addReg(SrcReg, getKillRegState(isKill))
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
|
||||
RC->getName()).c_str());
|
||||
}
|
||||
|
||||
void BlackfinInstrInfo::
|
||||
storeRegToAddr(MachineFunction &MF,
|
||||
unsigned SrcReg,
|
||||
bool isKill,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const {
|
||||
llvm_unreachable("storeRegToAddr not implemented");
|
||||
}
|
||||
|
||||
void
|
||||
BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
unsigned DestReg,
|
||||
int FI,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const {
|
||||
DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
|
||||
if (inClass(BF::DPRegClass, DestReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inClass(BF::D16RegClass, DestReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
|
||||
BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
|
||||
.addFrameIndex(FI)
|
||||
.addImm(0);
|
||||
return;
|
||||
}
|
||||
|
||||
llvm_unreachable("Cannot load regclass from stack slot");
|
||||
}
|
||||
|
||||
void BlackfinInstrInfo::
|
||||
loadRegFromAddr(MachineFunction &MF,
|
||||
unsigned DestReg,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const {
|
||||
llvm_unreachable("loadRegFromAddr not implemented");
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
//===- BlackfinInstrInfo.h - Blackfin 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 Blackfin implementation of the TargetInstrInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFININSTRUCTIONINFO_H
|
||||
#define BLACKFININSTRUCTIONINFO_H
|
||||
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "BlackfinRegisterInfo.h"
|
||||
|
||||
#define GET_INSTRINFO_HEADER
|
||||
#include "BlackfinGenInstrInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinInstrInfo : public BlackfinGenInstrInfo {
|
||||
const BlackfinRegisterInfo RI;
|
||||
const BlackfinSubtarget& Subtarget;
|
||||
public:
|
||||
explicit BlackfinInstrInfo(BlackfinSubtarget &ST);
|
||||
|
||||
/// 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 BlackfinRegisterInfo &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 storeRegToAddr(MachineFunction &MF,
|
||||
unsigned SrcReg, bool isKill,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
|
||||
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator MBBI,
|
||||
unsigned DestReg, int FrameIndex,
|
||||
const TargetRegisterClass *RC,
|
||||
const TargetRegisterInfo *TRI) const;
|
||||
|
||||
virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
|
||||
SmallVectorImpl<MachineOperand> &Addr,
|
||||
const TargetRegisterClass *RC,
|
||||
SmallVectorImpl<MachineInstr*> &NewMIs) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,862 +0,0 @@
|
|||
//===- BlackfinInstrInfo.td - Target Description for Blackfin Target ------===//
|
||||
//
|
||||
// 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 Blackfin instructions in TableGen format.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction format superclass
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "BlackfinInstrFormats.td"
|
||||
|
||||
// These are target-independent nodes, but have target-specific formats.
|
||||
def SDT_BfinCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
|
||||
def SDT_BfinCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>,
|
||||
SDTCisVT<1, i32> ]>;
|
||||
|
||||
def BfinCallseqStart : SDNode<"ISD::CALLSEQ_START", SDT_BfinCallSeqStart,
|
||||
[SDNPHasChain, SDNPOutGlue]>;
|
||||
def BfinCallseqEnd : SDNode<"ISD::CALLSEQ_END", SDT_BfinCallSeqEnd,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
|
||||
|
||||
def SDT_BfinCall : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||
def BfinCall : SDNode<"BFISD::CALL", SDT_BfinCall,
|
||||
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
|
||||
SDNPVariadic]>;
|
||||
|
||||
def BfinRet: SDNode<"BFISD::RET_FLAG", SDTNone,
|
||||
[SDNPHasChain, SDNPOptInGlue]>;
|
||||
|
||||
def BfinWrapper: SDNode<"BFISD::Wrapper", SDTIntUnaryOp>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Transformations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def trailingZeros_xform : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingZeros(),
|
||||
MVT::i32);
|
||||
}]>;
|
||||
|
||||
def trailingOnes_xform : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant(N->getAPIntValue().countTrailingOnes(),
|
||||
MVT::i32);
|
||||
}]>;
|
||||
|
||||
def LO16 : SDNodeXForm<imm, [{
|
||||
return CurDAG->getTargetConstant((unsigned short)N->getZExtValue(), MVT::i16);
|
||||
}]>;
|
||||
|
||||
def HI16 : SDNodeXForm<imm, [{
|
||||
// Transformation function: shift the immediate value down into the low bits.
|
||||
return CurDAG->getTargetConstant((unsigned)N->getZExtValue() >> 16, MVT::i16);
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Immediates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def imm3 : PatLeaf<(imm), [{return isInt<3>(N->getSExtValue());}]>;
|
||||
def uimm3 : PatLeaf<(imm), [{return isUInt<3>(N->getZExtValue());}]>;
|
||||
def uimm4 : PatLeaf<(imm), [{return isUInt<4>(N->getZExtValue());}]>;
|
||||
def uimm5 : PatLeaf<(imm), [{return isUInt<5>(N->getZExtValue());}]>;
|
||||
|
||||
def uimm5m2 : PatLeaf<(imm), [{
|
||||
uint64_t value = N->getZExtValue();
|
||||
return value % 2 == 0 && isUInt<5>(value);
|
||||
}]>;
|
||||
|
||||
def uimm6m4 : PatLeaf<(imm), [{
|
||||
uint64_t value = N->getZExtValue();
|
||||
return value % 4 == 0 && isUInt<6>(value);
|
||||
}]>;
|
||||
|
||||
def imm7 : PatLeaf<(imm), [{return isInt<7>(N->getSExtValue());}]>;
|
||||
def imm16 : PatLeaf<(imm), [{return isInt<16>(N->getSExtValue());}]>;
|
||||
def uimm16 : PatLeaf<(imm), [{return isUInt<16>(N->getZExtValue());}]>;
|
||||
|
||||
def ximm16 : PatLeaf<(imm), [{
|
||||
int64_t value = N->getSExtValue();
|
||||
return value < (1<<16) && value >= -(1<<15);
|
||||
}]>;
|
||||
|
||||
def imm17m2 : PatLeaf<(imm), [{
|
||||
int64_t value = N->getSExtValue();
|
||||
return value % 2 == 0 && isInt<17>(value);
|
||||
}]>;
|
||||
|
||||
def imm18m4 : PatLeaf<(imm), [{
|
||||
int64_t value = N->getSExtValue();
|
||||
return value % 4 == 0 && isInt<18>(value);
|
||||
}]>;
|
||||
|
||||
// 32-bit bitmask transformed to a bit number
|
||||
def uimm5mask : Operand<i32>, PatLeaf<(imm), [{
|
||||
return isPowerOf2_32(N->getZExtValue());
|
||||
}], trailingZeros_xform>;
|
||||
|
||||
// 32-bit inverse bitmask transformed to a bit number
|
||||
def uimm5imask : Operand<i32>, PatLeaf<(imm), [{
|
||||
return isPowerOf2_32(~N->getZExtValue());
|
||||
}], trailingOnes_xform>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operands
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def calltarget : Operand<iPTR>;
|
||||
|
||||
def brtarget : Operand<OtherVT>;
|
||||
|
||||
// Addressing modes
|
||||
def ADDRspii : ComplexPattern<i32, 2, "SelectADDRspii", [add, frameindex], []>;
|
||||
|
||||
// Address operands
|
||||
def MEMii : Operand<i32> {
|
||||
let PrintMethod = "printMemoryOperand";
|
||||
let MIOperandInfo = (ops i32imm, i32imm);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Pseudo instructions.
|
||||
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstBfin<outs, ins, asmstr, pattern>;
|
||||
|
||||
let Defs = [SP], Uses = [SP] in {
|
||||
def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt),
|
||||
"${:comment}ADJCALLSTACKDOWN $amt",
|
||||
[(BfinCallseqStart timm:$amt)]>;
|
||||
def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
|
||||
"${:comment}ADJCALLSTACKUP $amt1 $amt2",
|
||||
[(BfinCallseqEnd timm:$amt1, timm:$amt2)]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-9. Program Flow Control Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let isBranch = 1, isTerminator = 1 in {
|
||||
|
||||
let isIndirectBranch = 1 in
|
||||
def JUMPp : F1<(outs), (ins P:$target),
|
||||
"JUMP ($target);",
|
||||
[(brind P:$target)]>;
|
||||
|
||||
// TODO JUMP (PC-P)
|
||||
|
||||
// NOTE: assembler chooses between JUMP.S and JUMP.L
|
||||
def JUMPa : F1<(outs), (ins brtarget:$target),
|
||||
"jump $target;",
|
||||
[(br bb:$target)]>;
|
||||
|
||||
def JUMPcc : F1<(outs), (ins AnyCC:$cc, brtarget:$target),
|
||||
"if $cc jump $target;",
|
||||
[(brcond AnyCC:$cc, bb:$target)]>;
|
||||
}
|
||||
|
||||
let isCall = 1,
|
||||
Defs = [R0, R1, R2, R3, P0, P1, P2, LB0, LB1, LC0, LC1, RETS, ASTAT] in {
|
||||
def CALLa: F1<(outs), (ins calltarget:$func, variable_ops),
|
||||
"call $func;", []>;
|
||||
def CALLp: F1<(outs), (ins P:$func, variable_ops),
|
||||
"call ($func);", [(BfinCall P:$func)]>;
|
||||
}
|
||||
|
||||
let isReturn = 1,
|
||||
isTerminator = 1,
|
||||
isBarrier = 1,
|
||||
Uses = [RETS] in
|
||||
def RTS: F1<(outs), (ins), "rts;", [(BfinRet)]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-10. Load / Store Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Immediate constant loads
|
||||
|
||||
// sext immediate, i32 D/P regs
|
||||
def LOADimm7: F1<(outs DP:$dst), (ins i32imm:$src),
|
||||
"$dst = $src (x);",
|
||||
[(set DP:$dst, imm7:$src)]>;
|
||||
|
||||
// zext immediate, i32 reg groups 0-3
|
||||
def LOADuimm16: F2<(outs GR:$dst), (ins i32imm:$src),
|
||||
"$dst = $src (z);",
|
||||
[(set GR:$dst, uimm16:$src)]>;
|
||||
|
||||
// sext immediate, i32 reg groups 0-3
|
||||
def LOADimm16: F2<(outs GR:$dst), (ins i32imm:$src),
|
||||
"$dst = $src (x);",
|
||||
[(set GR:$dst, imm16:$src)]>;
|
||||
|
||||
// Pseudo-instruction for loading a general 32-bit constant.
|
||||
def LOAD32imm: Pseudo<(outs GR:$dst), (ins i32imm:$src),
|
||||
"$dst.h = ($src >> 16); $dst.l = ($src & 0xffff);",
|
||||
[(set GR:$dst, imm:$src)]>;
|
||||
|
||||
def LOAD32sym: Pseudo<(outs GR:$dst), (ins i32imm:$src),
|
||||
"$dst.h = $src; $dst.l = $src;", []>;
|
||||
|
||||
|
||||
// 16-bit immediate, i16 reg groups 0-3
|
||||
def LOAD16i: F2<(outs GR16:$dst), (ins i16imm:$src),
|
||||
"$dst = $src;", []>;
|
||||
|
||||
def : Pat<(BfinWrapper (i32 tglobaladdr:$addr)),
|
||||
(LOAD32sym tglobaladdr:$addr)>;
|
||||
|
||||
def : Pat<(BfinWrapper (i32 tjumptable:$addr)),
|
||||
(LOAD32sym tjumptable:$addr)>;
|
||||
|
||||
// We cannot copy from GR16 to D16, and codegen wants to insert copies if we
|
||||
// emit GR16 instructions. As a hack, we use this fake instruction instead.
|
||||
def LOAD16i_d16: F2<(outs D16:$dst), (ins i16imm:$src),
|
||||
"$dst = $src;",
|
||||
[(set D16:$dst, ximm16:$src)]>;
|
||||
|
||||
// Memory loads with patterns
|
||||
|
||||
def LOAD32p: F1<(outs DP:$dst), (ins P:$ptr),
|
||||
"$dst = [$ptr];",
|
||||
[(set DP:$dst, (load P:$ptr))]>;
|
||||
|
||||
// Pseudo-instruction for loading a stack slot
|
||||
def LOAD32fi: Pseudo<(outs DP:$dst), (ins MEMii:$mem),
|
||||
"${:comment}FI $dst = [$mem];",
|
||||
[(set DP:$dst, (load ADDRspii:$mem))]>;
|
||||
|
||||
// Note: Expands to multiple insns
|
||||
def LOAD16fi: Pseudo<(outs D16:$dst), (ins MEMii:$mem),
|
||||
"${:comment}FI $dst = [$mem];",
|
||||
[(set D16:$dst, (load ADDRspii:$mem))]>;
|
||||
|
||||
// Pseudo-instruction for loading a stack slot, used for AnyCC regs.
|
||||
// Replaced with Load D + CC=D
|
||||
def LOAD8fi: Pseudo<(outs AnyCC:$dst), (ins MEMii:$mem),
|
||||
"${:comment}FI $dst = B[$mem];",
|
||||
[(set AnyCC:$dst, (load ADDRspii:$mem))]>;
|
||||
|
||||
def LOAD32p_uimm6m4: F1<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = [$ptr + $off];",
|
||||
[(set DP:$dst, (load (add P:$ptr, uimm6m4:$off)))]>;
|
||||
|
||||
def LOAD32p_imm18m4: F2<(outs DP:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = [$ptr + $off];",
|
||||
[(set DP:$dst, (load (add P:$ptr, imm18m4:$off)))]>;
|
||||
|
||||
def LOAD32p_16z: F1<(outs D:$dst), (ins P:$ptr),
|
||||
"$dst = W[$ptr] (z);",
|
||||
[(set D:$dst, (zextloadi16 P:$ptr))]>;
|
||||
|
||||
def : Pat<(i32 (extloadi16 P:$ptr)),(LOAD32p_16z P:$ptr)>;
|
||||
|
||||
def LOAD32p_uimm5m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = w[$ptr + $off] (z);",
|
||||
[(set D:$dst, (zextloadi16 (add P:$ptr,
|
||||
uimm5m2:$off)))]>;
|
||||
|
||||
def : Pat<(i32 (extloadi16 (add P:$ptr, uimm5m2:$off))),
|
||||
(LOAD32p_uimm5m2_16z P:$ptr, imm:$off)>;
|
||||
|
||||
def LOAD32p_imm17m2_16z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = w[$ptr + $off] (z);",
|
||||
[(set D:$dst,
|
||||
(zextloadi16 (add P:$ptr, imm17m2:$off)))]>;
|
||||
|
||||
def : Pat<(i32 (extloadi16 (add P:$ptr, imm17m2:$off))),
|
||||
(LOAD32p_imm17m2_16z P:$ptr, imm:$off)>;
|
||||
|
||||
def LOAD32p_16s: F1<(outs D:$dst), (ins P:$ptr),
|
||||
"$dst = w[$ptr] (x);",
|
||||
[(set D:$dst, (sextloadi16 P:$ptr))]>;
|
||||
|
||||
def LOAD32p_uimm5m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = w[$ptr + $off] (x);",
|
||||
[(set D:$dst,
|
||||
(sextloadi16 (add P:$ptr, uimm5m2:$off)))]>;
|
||||
|
||||
def LOAD32p_imm17m2_16s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = w[$ptr + $off] (x);",
|
||||
[(set D:$dst,
|
||||
(sextloadi16 (add P:$ptr, imm17m2:$off)))]>;
|
||||
|
||||
def LOAD16pi: F1<(outs D16:$dst), (ins PI:$ptr),
|
||||
"$dst = w[$ptr];",
|
||||
[(set D16:$dst, (load PI:$ptr))]>;
|
||||
|
||||
def LOAD32p_8z: F1<(outs D:$dst), (ins P:$ptr),
|
||||
"$dst = B[$ptr] (z);",
|
||||
[(set D:$dst, (zextloadi8 P:$ptr))]>;
|
||||
|
||||
def : Pat<(i32 (extloadi8 P:$ptr)), (LOAD32p_8z P:$ptr)>;
|
||||
def : Pat<(i16 (extloadi8 P:$ptr)),
|
||||
(EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
|
||||
def : Pat<(i16 (zextloadi8 P:$ptr)),
|
||||
(EXTRACT_SUBREG (LOAD32p_8z P:$ptr), lo16)>;
|
||||
|
||||
def LOAD32p_imm16_8z: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = b[$ptr + $off] (z);",
|
||||
[(set D:$dst, (zextloadi8 (add P:$ptr, imm16:$off)))]>;
|
||||
|
||||
def : Pat<(i32 (extloadi8 (add P:$ptr, imm16:$off))),
|
||||
(LOAD32p_imm16_8z P:$ptr, imm:$off)>;
|
||||
def : Pat<(i16 (extloadi8 (add P:$ptr, imm16:$off))),
|
||||
(EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
|
||||
lo16)>;
|
||||
def : Pat<(i16 (zextloadi8 (add P:$ptr, imm16:$off))),
|
||||
(EXTRACT_SUBREG (LOAD32p_imm16_8z P:$ptr, imm:$off),
|
||||
lo16)>;
|
||||
|
||||
def LOAD32p_8s: F1<(outs D:$dst), (ins P:$ptr),
|
||||
"$dst = b[$ptr] (x);",
|
||||
[(set D:$dst, (sextloadi8 P:$ptr))]>;
|
||||
|
||||
def : Pat<(i16 (sextloadi8 P:$ptr)),
|
||||
(EXTRACT_SUBREG (LOAD32p_8s P:$ptr), lo16)>;
|
||||
|
||||
def LOAD32p_imm16_8s: F1<(outs D:$dst), (ins P:$ptr, i32imm:$off),
|
||||
"$dst = b[$ptr + $off] (x);",
|
||||
[(set D:$dst, (sextloadi8 (add P:$ptr, imm16:$off)))]>;
|
||||
|
||||
def : Pat<(i16 (sextloadi8 (add P:$ptr, imm16:$off))),
|
||||
(EXTRACT_SUBREG (LOAD32p_imm16_8s P:$ptr, imm:$off),
|
||||
lo16)>;
|
||||
// Memory loads without patterns
|
||||
|
||||
let mayLoad = 1 in {
|
||||
|
||||
multiclass LOAD_incdec<RegisterClass drc, RegisterClass prc,
|
||||
string mem="", string suf=";"> {
|
||||
def _inc : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
|
||||
!strconcat(!subst("M", mem, "$dst = M[$ptr++]"), suf), []>;
|
||||
def _dec : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr),
|
||||
!strconcat(!subst("M", mem, "$dst = M[$ptr--]"), suf), []>;
|
||||
}
|
||||
multiclass LOAD_incdecpost<RegisterClass drc, RegisterClass prc,
|
||||
string mem="", string suf=";">
|
||||
: LOAD_incdec<drc, prc, mem, suf> {
|
||||
def _post : F1<(outs drc:$dst, prc:$ptr_wb), (ins prc:$ptr, prc:$off),
|
||||
!strconcat(!subst("M", mem, "$dst = M[$ptr++$off]"), suf), []>;
|
||||
}
|
||||
|
||||
defm LOAD32p: LOAD_incdec<DP, P>;
|
||||
defm LOAD32i: LOAD_incdec<D, I>;
|
||||
defm LOAD8z32p: LOAD_incdec<D, P, "b", " (z);">;
|
||||
defm LOAD8s32p: LOAD_incdec<D, P, "b", " (x);">;
|
||||
defm LOADhi: LOAD_incdec<D16, I, "w">;
|
||||
defm LOAD16z32p: LOAD_incdecpost<D, P, "w", " (z);">;
|
||||
defm LOAD16s32p: LOAD_incdecpost<D, P, "w", " (x);">;
|
||||
|
||||
def LOAD32p_post: F1<(outs D:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
|
||||
"$dst = [$ptr ++ $off];", []>;
|
||||
|
||||
// Note: $fp MUST be FP
|
||||
def LOAD32fp_nimm7m4: F1<(outs DP:$dst), (ins P:$fp, i32imm:$off),
|
||||
"$dst = [$fp - $off];", []>;
|
||||
|
||||
def LOAD32i: F1<(outs D:$dst), (ins I:$ptr),
|
||||
"$dst = [$ptr];", []>;
|
||||
def LOAD32i_post: F1<(outs D:$dst, I:$ptr_wb), (ins I:$ptr, M:$off),
|
||||
"$dst = [$ptr ++ $off];", []>;
|
||||
|
||||
|
||||
|
||||
def LOADhp_post: F1<(outs D16:$dst, P:$ptr_wb), (ins P:$ptr, P:$off),
|
||||
"$dst = w[$ptr ++ $off];", []>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Memory stores with patterns
|
||||
def STORE32p: F1<(outs), (ins DP:$val, P:$ptr),
|
||||
"[$ptr] = $val;",
|
||||
[(store DP:$val, P:$ptr)]>;
|
||||
|
||||
// Pseudo-instructions for storing to a stack slot
|
||||
def STORE32fi: Pseudo<(outs), (ins DP:$val, MEMii:$mem),
|
||||
"${:comment}FI [$mem] = $val;",
|
||||
[(store DP:$val, ADDRspii:$mem)]>;
|
||||
|
||||
// Note: This stack-storing pseudo-instruction is expanded to multiple insns
|
||||
def STORE16fi: Pseudo<(outs), (ins D16:$val, MEMii:$mem),
|
||||
"${:comment}FI [$mem] = $val;",
|
||||
[(store D16:$val, ADDRspii:$mem)]>;
|
||||
|
||||
// Pseudo-instructions for storing AnyCC register to a stack slot.
|
||||
// Replaced with D=CC + STORE byte
|
||||
def STORE8fi: Pseudo<(outs), (ins AnyCC:$val, MEMii:$mem),
|
||||
"${:comment}FI b[$mem] = $val;",
|
||||
[(store AnyCC:$val, ADDRspii:$mem)]>;
|
||||
|
||||
def STORE32p_uimm6m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
|
||||
"[$ptr + $off] = $val;",
|
||||
[(store DP:$val, (add P:$ptr, uimm6m4:$off))]>;
|
||||
|
||||
def STORE32p_imm18m4: F1<(outs), (ins DP:$val, P:$ptr, i32imm:$off),
|
||||
"[$ptr + $off] = $val;",
|
||||
[(store DP:$val, (add P:$ptr, imm18m4:$off))]>;
|
||||
|
||||
def STORE16pi: F1<(outs), (ins D16:$val, PI:$ptr),
|
||||
"w[$ptr] = $val;",
|
||||
[(store D16:$val, PI:$ptr)]>;
|
||||
|
||||
def STORE8p: F1<(outs), (ins D:$val, P:$ptr),
|
||||
"b[$ptr] = $val;",
|
||||
[(truncstorei8 D:$val, P:$ptr)]>;
|
||||
|
||||
def STORE8p_imm16: F1<(outs), (ins D:$val, P:$ptr, i32imm:$off),
|
||||
"b[$ptr + $off] = $val;",
|
||||
[(truncstorei8 D:$val, (add P:$ptr, imm16:$off))]>;
|
||||
|
||||
let Constraints = "$ptr = $ptr_wb" in {
|
||||
|
||||
multiclass STORE_incdec<RegisterClass drc, RegisterClass prc,
|
||||
int off=4, string pre=""> {
|
||||
def _inc : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
|
||||
!strconcat(pre, "[$ptr++] = $val;"),
|
||||
[(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr, off))]>;
|
||||
def _dec : F1<(outs prc:$ptr_wb), (ins drc:$val, prc:$ptr),
|
||||
!strconcat(pre, "[$ptr--] = $val;"),
|
||||
[(set prc:$ptr_wb, (post_store drc:$val, prc:$ptr,
|
||||
(ineg off)))]>;
|
||||
}
|
||||
|
||||
defm STORE32p: STORE_incdec<DP, P>;
|
||||
defm STORE16i: STORE_incdec<D16, I, 2, "w">;
|
||||
defm STORE8p: STORE_incdec<D, P, 1, "b">;
|
||||
|
||||
def STORE32p_post: F1<(outs P:$ptr_wb), (ins D:$val, P:$ptr, P:$off),
|
||||
"[$ptr ++ $off] = $val;",
|
||||
[(set P:$ptr_wb, (post_store D:$val, P:$ptr, P:$off))]>;
|
||||
|
||||
def STORE16p_post: F1<(outs P:$ptr_wb), (ins D16:$val, P:$ptr, P:$off),
|
||||
"w[$ptr ++ $off] = $val;",
|
||||
[(set P:$ptr_wb, (post_store D16:$val, P:$ptr, P:$off))]>;
|
||||
}
|
||||
|
||||
// Memory stores without patterns
|
||||
|
||||
let mayStore = 1 in {
|
||||
|
||||
// Note: only works for $fp == FP
|
||||
def STORE32fp_nimm7m4: F1<(outs), (ins DP:$val, P:$fp, i32imm:$off),
|
||||
"[$fp - $off] = $val;", []>;
|
||||
|
||||
def STORE32i: F1<(outs), (ins D:$val, I:$ptr),
|
||||
"[$ptr] = $val;", []>;
|
||||
|
||||
def STORE32i_inc: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
|
||||
"[$ptr++] = $val;", []>;
|
||||
|
||||
def STORE32i_dec: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr),
|
||||
"[$ptr--] = $val;", []>;
|
||||
|
||||
def STORE32i_post: F1<(outs I:$ptr_wb), (ins D:$val, I:$ptr, M:$off),
|
||||
"[$ptr ++ $off] = $val;", []>;
|
||||
}
|
||||
|
||||
def : Pat<(truncstorei16 D:$val, PI:$ptr),
|
||||
(STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
|
||||
lo16), PI:$ptr)>;
|
||||
|
||||
def : Pat<(truncstorei16 (srl D:$val, (i16 16)), PI:$ptr),
|
||||
(STORE16pi (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$val, D)),
|
||||
hi16), PI:$ptr)>;
|
||||
|
||||
def : Pat<(truncstorei8 D16L:$val, P:$ptr),
|
||||
(STORE8p (INSERT_SUBREG (i32 (IMPLICIT_DEF)),
|
||||
(i16 (COPY_TO_REGCLASS D16L:$val, D16L)),
|
||||
lo16),
|
||||
P:$ptr)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-11. Move Instructions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def MOVE: F1<(outs ALL:$dst), (ins ALL:$src),
|
||||
"$dst = $src;",
|
||||
[]>;
|
||||
|
||||
let Constraints = "$src1 = $dst" in
|
||||
def MOVEcc: F1<(outs DP:$dst), (ins DP:$src1, DP:$src2, AnyCC:$cc),
|
||||
"if $cc $dst = $src2;",
|
||||
[(set DP:$dst, (select AnyCC:$cc, DP:$src2, DP:$src1))]>;
|
||||
|
||||
let Defs = [AZ, AN, AC0, V] in {
|
||||
def MOVEzext: F1<(outs D:$dst), (ins D16L:$src),
|
||||
"$dst = $src (z);",
|
||||
[(set D:$dst, (zext D16L:$src))]>;
|
||||
|
||||
def MOVEsext: F1<(outs D:$dst), (ins D16L:$src),
|
||||
"$dst = $src (x);",
|
||||
[(set D:$dst, (sext D16L:$src))]>;
|
||||
|
||||
def MOVEzext8: F1<(outs D:$dst), (ins D:$src),
|
||||
"$dst = $src.b (z);",
|
||||
[(set D:$dst, (and D:$src, 0xff))]>;
|
||||
|
||||
def MOVEsext8: F1<(outs D:$dst), (ins D:$src),
|
||||
"$dst = $src.b (x);",
|
||||
[(set D:$dst, (sext_inreg D:$src, i8))]>;
|
||||
|
||||
}
|
||||
|
||||
def : Pat<(sext_inreg D16L:$src, i8),
|
||||
(EXTRACT_SUBREG (MOVEsext8
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)),
|
||||
D16L:$src,
|
||||
lo16)),
|
||||
lo16)>;
|
||||
|
||||
def : Pat<(sext_inreg D:$src, i16),
|
||||
(MOVEsext (EXTRACT_SUBREG D:$src, lo16))>;
|
||||
|
||||
def : Pat<(and D:$src, 0xffff),
|
||||
(MOVEzext (EXTRACT_SUBREG D:$src, lo16))>;
|
||||
|
||||
def : Pat<(i32 (anyext D16L:$src)),
|
||||
(INSERT_SUBREG (i32 (IMPLICIT_DEF)),
|
||||
(i16 (COPY_TO_REGCLASS D16L:$src, D16L)),
|
||||
lo16)>;
|
||||
|
||||
// TODO Dreg = Dreg_byte (X/Z)
|
||||
|
||||
// TODO Accumulator moves
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-12. Stack Control Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Uses = [SP], Defs = [SP] in {
|
||||
def PUSH: F1<(outs), (ins ALL:$src),
|
||||
"[--sp] = $src;", []> { let mayStore = 1; }
|
||||
|
||||
// NOTE: POP does not work for DP regs, use LOAD instead
|
||||
def POP: F1<(outs ALL:$dst), (ins),
|
||||
"$dst = [sp++];", []> { let mayLoad = 1; }
|
||||
}
|
||||
|
||||
// TODO: push/pop multiple
|
||||
|
||||
def LINK: F2<(outs), (ins i32imm:$amount),
|
||||
"link $amount;", []>;
|
||||
|
||||
def UNLINK: F2<(outs), (ins),
|
||||
"unlink;", []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-13. Control Code Bit Management Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
multiclass SETCC<PatFrag opnode, PatFrag invnode, string cond, string suf=";"> {
|
||||
def dd : F1<(outs JustCC:$cc), (ins D:$a, D:$b),
|
||||
!strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
|
||||
[(set JustCC:$cc, (opnode D:$a, D:$b))]>;
|
||||
|
||||
def ri : F1<(outs JustCC:$cc), (ins DP:$a, i32imm:$b),
|
||||
!strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
|
||||
[(set JustCC:$cc, (opnode DP:$a, imm3:$b))]>;
|
||||
|
||||
def pp : F1<(outs JustCC:$cc), (ins P:$a, P:$b),
|
||||
!strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
|
||||
[]>;
|
||||
|
||||
def ri_not : F1<(outs NotCC:$cc), (ins DP:$a, i32imm:$b),
|
||||
!strconcat(!subst("XX", cond, "cc = $a XX $b"), suf),
|
||||
[(set NotCC:$cc, (invnode DP:$a, imm3:$b))]>;
|
||||
}
|
||||
|
||||
defm SETEQ : SETCC<seteq, setne, "==">;
|
||||
defm SETLT : SETCC<setlt, setge, "<">;
|
||||
defm SETLE : SETCC<setle, setgt, "<=">;
|
||||
defm SETULT : SETCC<setult, setuge, "<", " (iu);">;
|
||||
defm SETULE : SETCC<setule, setugt, "<=", " (iu);">;
|
||||
|
||||
def SETNEdd : F1<(outs NotCC:$cc), (ins D:$a, D:$b),
|
||||
"cc = $a == $b;",
|
||||
[(set NotCC:$cc, (setne D:$a, D:$b))]>;
|
||||
|
||||
def : Pat<(setgt D:$a, D:$b), (SETLTdd D:$b, D:$a)>;
|
||||
def : Pat<(setge D:$a, D:$b), (SETLEdd D:$b, D:$a)>;
|
||||
def : Pat<(setugt D:$a, D:$b), (SETULTdd D:$b, D:$a)>;
|
||||
def : Pat<(setuge D:$a, D:$b), (SETULEdd D:$b, D:$a)>;
|
||||
|
||||
// TODO: compare pointer for P-P comparisons
|
||||
// TODO: compare accumulator
|
||||
|
||||
let Defs = [AC0] in
|
||||
def OR_ac0_cc : F1<(outs), (ins JustCC:$cc),
|
||||
"ac0 \\|= cc;", []>;
|
||||
|
||||
let Uses = [AC0] in
|
||||
def MOVE_cc_ac0 : F1<(outs JustCC:$cc), (ins),
|
||||
"cc = ac0;", []>;
|
||||
|
||||
def MOVE_ccncc : F1<(outs JustCC:$cc), (ins NotCC:$sb),
|
||||
"cc = !cc;", []>;
|
||||
|
||||
def MOVE_ncccc : F1<(outs NotCC:$cc), (ins JustCC:$sb),
|
||||
"cc = !cc;", []>;
|
||||
|
||||
def MOVECC_zext : F1<(outs D:$dst), (ins JustCC:$cc),
|
||||
"$dst = $cc;", []>;
|
||||
|
||||
def MOVENCC_z : F1<(outs D:$dst), (ins NotCC:$cc),
|
||||
"$dst = cc;", []>;
|
||||
|
||||
def MOVECC_nz : F1<(outs AnyCC:$cc), (ins D:$src),
|
||||
"cc = $src;",
|
||||
[(set AnyCC:$cc, (setne D:$src, 0))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-14. Logical Operations Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def AND: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 & $src2;",
|
||||
[(set D:$dst, (and D:$src1, D:$src2))]>;
|
||||
|
||||
def NOT: F1<(outs D:$dst), (ins D:$src),
|
||||
"$dst = ~$src;",
|
||||
[(set D:$dst, (not D:$src))]>;
|
||||
|
||||
def OR: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 \\| $src2;",
|
||||
[(set D:$dst, (or D:$src1, D:$src2))]>;
|
||||
|
||||
def XOR: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 ^ $src2;",
|
||||
[(set D:$dst, (xor D:$src1, D:$src2))]>;
|
||||
|
||||
// missing: BXOR, BXORSHIFT
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-15. Bit Operations Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Constraints = "$src1 = $dst" in {
|
||||
def BITCLR: F1<(outs D:$dst), (ins D:$src1, uimm5imask:$src2),
|
||||
"bitclr($dst, $src2);",
|
||||
[(set D:$dst, (and D:$src1, uimm5imask:$src2))]>;
|
||||
|
||||
def BITSET: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2),
|
||||
"bitset($dst, $src2);",
|
||||
[(set D:$dst, (or D:$src1, uimm5mask:$src2))]>;
|
||||
|
||||
def BITTGL: F1<(outs D:$dst), (ins D:$src1, uimm5mask:$src2),
|
||||
"bittgl($dst, $src2);",
|
||||
[(set D:$dst, (xor D:$src1, uimm5mask:$src2))]>;
|
||||
}
|
||||
|
||||
def BITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2),
|
||||
"cc = bittst($src1, $src2);",
|
||||
[(set JustCC:$cc, (setne (and D:$src1, uimm5mask:$src2),
|
||||
(i32 0)))]>;
|
||||
|
||||
def NBITTST: F1<(outs JustCC:$cc), (ins D:$src1, uimm5mask:$src2),
|
||||
"cc = !bittst($src1, $src2);",
|
||||
[(set JustCC:$cc, (seteq (and D:$src1, uimm5mask:$src2),
|
||||
(i32 0)))]>;
|
||||
|
||||
// TODO: DEPOSIT, EXTRACT, BITMUX
|
||||
|
||||
def ONES: F2<(outs D16L:$dst), (ins D:$src),
|
||||
"$dst = ones $src;",
|
||||
[(set D16L:$dst, (trunc (ctpop D:$src)))]>;
|
||||
|
||||
def : Pat<(ctpop D:$src), (MOVEzext (ONES D:$src))>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-16. Shift / Rotate Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
multiclass SHIFT32<SDNode opnode, string ops> {
|
||||
def i : F1<(outs D:$dst), (ins D:$src, i16imm:$amount),
|
||||
!subst("XX", ops, "$dst XX= $amount;"),
|
||||
[(set D:$dst, (opnode D:$src, (i16 uimm5:$amount)))]>;
|
||||
def r : F1<(outs D:$dst), (ins D:$src, D:$amount),
|
||||
!subst("XX", ops, "$dst XX= $amount;"),
|
||||
[(set D:$dst, (opnode D:$src, D:$amount))]>;
|
||||
}
|
||||
|
||||
let Defs = [AZ, AN, V, VS],
|
||||
Constraints = "$src = $dst" in {
|
||||
defm SRA : SHIFT32<sra, ">>>">;
|
||||
defm SRL : SHIFT32<srl, ">>">;
|
||||
defm SLL : SHIFT32<shl, "<<">;
|
||||
}
|
||||
|
||||
// TODO: automatic switching between 2-addr and 3-addr (?)
|
||||
|
||||
let Defs = [AZ, AN, V, VS] in {
|
||||
def SLLr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount),
|
||||
"$dst = lshift $src by $amount;",
|
||||
[(set D:$dst, (shl D:$src, D16L:$amount))]>;
|
||||
|
||||
// Arithmetic left-shift = saturing overflow.
|
||||
def SLAr16: F2<(outs D:$dst), (ins D:$src, D16L:$amount),
|
||||
"$dst = ashift $src by $amount;",
|
||||
[(set D:$dst, (sra D:$src, (ineg D16L:$amount)))]>;
|
||||
|
||||
def SRA16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
|
||||
"$dst = $src >>> $amount;",
|
||||
[(set D16:$dst, (sra D16:$src, (i16 uimm4:$amount)))]>;
|
||||
|
||||
def SRL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
|
||||
"$dst = $src >> $amount;",
|
||||
[(set D16:$dst, (srl D16:$src, (i16 uimm4:$amount)))]>;
|
||||
|
||||
// Arithmetic left-shift = saturing overflow.
|
||||
def SLA16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount),
|
||||
"$dst = ashift $src BY $amount;",
|
||||
[(set D16:$dst, (srl D16:$src, (ineg D16L:$amount)))]>;
|
||||
|
||||
def SLL16i: F1<(outs D16:$dst), (ins D16:$src, i16imm:$amount),
|
||||
"$dst = $src << $amount;",
|
||||
[(set D16:$dst, (shl D16:$src, (i16 uimm4:$amount)))]>;
|
||||
|
||||
def SLL16r: F1<(outs D16:$dst), (ins D16:$src, D16L:$amount),
|
||||
"$dst = lshift $src by $amount;",
|
||||
[(set D16:$dst, (shl D16:$src, D16L:$amount))]>;
|
||||
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-17. Arithmetic Operations Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// TODO: ABS
|
||||
|
||||
let Defs = [AZ, AN, AC0, V, VS] in {
|
||||
|
||||
def ADD: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 + $src2;",
|
||||
[(set D:$dst, (add D:$src1, D:$src2))]>;
|
||||
|
||||
def ADD16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 + $src2;",
|
||||
[(set D16:$dst, (add D16:$src1, D16:$src2))]>;
|
||||
|
||||
let Constraints = "$src1 = $dst" in
|
||||
def ADDimm7: F1<(outs D:$dst), (ins D:$src1, i32imm:$src2),
|
||||
"$dst += $src2;",
|
||||
[(set D:$dst, (add D:$src1, imm7:$src2))]>;
|
||||
|
||||
def SUB: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 - $src2;",
|
||||
[(set D:$dst, (sub D:$src1, D:$src2))]>;
|
||||
|
||||
def SUB16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 - $src2;",
|
||||
[(set D16:$dst, (sub D16:$src1, D16:$src2))]>;
|
||||
|
||||
}
|
||||
|
||||
def : Pat<(addc D:$src1, D:$src2), (ADD D:$src1, D:$src2)>;
|
||||
def : Pat<(subc D:$src1, D:$src2), (SUB D:$src1, D:$src2)>;
|
||||
|
||||
let Defs = [AZ, AN, V, VS] in
|
||||
def NEG: F1<(outs D:$dst), (ins D:$src),
|
||||
"$dst = -$src;",
|
||||
[(set D:$dst, (ineg D:$src))]>;
|
||||
|
||||
// No pattern, it would confuse isel to have two i32 = i32+i32 patterns
|
||||
def ADDpp: F1<(outs P:$dst), (ins P:$src1, P:$src2),
|
||||
"$dst = $src1 + $src2;", []>;
|
||||
|
||||
let Constraints = "$src1 = $dst" in
|
||||
def ADDpp_imm7: F1<(outs P:$dst), (ins P:$src1, i32imm:$src2),
|
||||
"$dst += $src2;", []>;
|
||||
|
||||
let Defs = [AZ, AN, V] in
|
||||
def ADD_RND20: F2<(outs D16:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = $src1 + $src2 (rnd20);", []>;
|
||||
|
||||
let Defs = [V, VS] in {
|
||||
def MUL16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 * $src2 (is);",
|
||||
[(set D16:$dst, (mul D16:$src1, D16:$src2))]>;
|
||||
|
||||
def MULHS16: F2<(outs D16:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 * $src2 (ih);",
|
||||
[(set D16:$dst, (mulhs D16:$src1, D16:$src2))]>;
|
||||
|
||||
def MULhh32s: F2<(outs D:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 * $src2 (is);",
|
||||
[(set D:$dst, (mul (sext D16:$src1), (sext D16:$src2)))]>;
|
||||
|
||||
def MULhh32u: F2<(outs D:$dst), (ins D16:$src1, D16:$src2),
|
||||
"$dst = $src1 * $src2 (is);",
|
||||
[(set D:$dst, (mul (zext D16:$src1), (zext D16:$src2)))]>;
|
||||
}
|
||||
|
||||
|
||||
let Constraints = "$src1 = $dst" in
|
||||
def MUL32: F1<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst *= $src2;",
|
||||
[(set D:$dst, (mul D:$src1, D:$src2))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-18. External Exent Management Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def IDLE : F1<(outs), (ins), "idle;", [(int_bfin_idle)]>;
|
||||
def CSYNC : F1<(outs), (ins), "csync;", [(int_bfin_csync)]>;
|
||||
def SSYNC : F1<(outs), (ins), "ssync;", [(int_bfin_ssync)]>;
|
||||
def EMUEXCPT : F1<(outs), (ins), "emuexcpt;", []>;
|
||||
def CLI : F1<(outs D:$mask), (ins), "cli $mask;", []>;
|
||||
def STI : F1<(outs), (ins D:$mask), "sti $mask;", []>;
|
||||
def RAISE : F1<(outs), (ins i32imm:$itr), "raise $itr;", []>;
|
||||
def EXCPT : F1<(outs), (ins i32imm:$exc), "excpt $exc;", []>;
|
||||
def NOP : F1<(outs), (ins), "nop;", []>;
|
||||
def MNOP : F2<(outs), (ins), "mnop;", []>;
|
||||
def ABORT : F1<(outs), (ins), "abort;", []>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-19. Cache Control Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Table C-20. Video Pixel Operations Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def ALIGN8 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = align8($src1, $src2);",
|
||||
[(set D:$dst, (or (shl D:$src1, (i32 24)),
|
||||
(srl D:$src2, (i32 8))))]>;
|
||||
|
||||
def ALIGN16 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = align16($src1, $src2);",
|
||||
[(set D:$dst, (or (shl D:$src1, (i32 16)),
|
||||
(srl D:$src2, (i32 16))))]>;
|
||||
|
||||
def ALIGN24 : F2<(outs D:$dst), (ins D:$src1, D:$src2),
|
||||
"$dst = align16($src1, $src2);",
|
||||
[(set D:$dst, (or (shl D:$src1, (i32 8)),
|
||||
(srl D:$src2, (i32 24))))]>;
|
||||
|
||||
def DISALGNEXCPT : F2<(outs), (ins), "disalignexcpt;", []>;
|
||||
|
||||
// TODO: BYTEOP3P, BYTEOP16P, BYTEOP1P, BYTEOP2P, BYTEOP16M, SAA,
|
||||
// BYTEPACK, BYTEUNPACK
|
||||
|
||||
// Table C-21. Vector Operations Instructions
|
||||
|
||||
// Patterns
|
||||
def : Pat<(BfinCall (i32 tglobaladdr:$dst)),
|
||||
(CALLa tglobaladdr:$dst)>;
|
||||
def : Pat<(BfinCall (i32 texternalsym:$dst)),
|
||||
(CALLa texternalsym:$dst)>;
|
||||
def : Pat<(i16 (trunc D:$src)),
|
||||
(EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS D:$src, D)), lo16)>;
|
|
@ -1,104 +0,0 @@
|
|||
//===- BlackfinIntrinsicInfo.cpp - Intrinsic 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 Blackfin implementation of TargetIntrinsicInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinIntrinsicInfo.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Intrinsics.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace bfinIntrinsic {
|
||||
|
||||
enum ID {
|
||||
last_non_bfin_intrinsic = Intrinsic::num_intrinsics-1,
|
||||
#define GET_INTRINSIC_ENUM_VALUES
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_ENUM_VALUES
|
||||
, num_bfin_intrinsics
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
std::string BlackfinIntrinsicInfo::getName(unsigned IntrID, Type **Tys,
|
||||
unsigned numTys) const {
|
||||
static const char *const names[] = {
|
||||
#define GET_INTRINSIC_NAME_TABLE
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_NAME_TABLE
|
||||
};
|
||||
|
||||
assert(!isOverloaded(IntrID) && "Blackfin intrinsics are not overloaded");
|
||||
if (IntrID < Intrinsic::num_intrinsics)
|
||||
return 0;
|
||||
assert(IntrID < bfinIntrinsic::num_bfin_intrinsics && "Invalid intrinsic ID");
|
||||
|
||||
std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
|
||||
return Result;
|
||||
}
|
||||
|
||||
unsigned
|
||||
BlackfinIntrinsicInfo::lookupName(const char *Name, unsigned Len) const {
|
||||
if (Len < 5 || Name[4] != '.' || Name[0] != 'l' || Name[1] != 'l'
|
||||
|| Name[2] != 'v' || Name[3] != 'm')
|
||||
return 0; // All intrinsics start with 'llvm.'
|
||||
|
||||
#define GET_FUNCTION_RECOGNIZER
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_FUNCTION_RECOGNIZER
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool BlackfinIntrinsicInfo::isOverloaded(unsigned IntrID) const {
|
||||
// Overload Table
|
||||
const bool OTable[] = {
|
||||
#define GET_INTRINSIC_OVERLOAD_TABLE
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_OVERLOAD_TABLE
|
||||
};
|
||||
if (IntrID == 0)
|
||||
return false;
|
||||
else
|
||||
return OTable[IntrID - Intrinsic::num_intrinsics];
|
||||
}
|
||||
|
||||
/// This defines the "getAttributes(ID id)" method.
|
||||
#define GET_INTRINSIC_ATTRIBUTES
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_ATTRIBUTES
|
||||
|
||||
static FunctionType *getType(LLVMContext &Context, unsigned id) {
|
||||
Type *ResultTy = NULL;
|
||||
SmallVector<Type*, 8> ArgTys;
|
||||
bool IsVarArg = false;
|
||||
|
||||
#define GET_INTRINSIC_GENERATOR
|
||||
#include "BlackfinGenIntrinsics.inc"
|
||||
#undef GET_INTRINSIC_GENERATOR
|
||||
|
||||
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
|
||||
}
|
||||
|
||||
Function *BlackfinIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
|
||||
Type **Tys,
|
||||
unsigned numTy) const {
|
||||
assert(!isOverloaded(IntrID) && "Blackfin intrinsics are not overloaded");
|
||||
AttrListPtr AList = getAttributes((bfinIntrinsic::ID) IntrID);
|
||||
return cast<Function>(M->getOrInsertFunction(getName(IntrID),
|
||||
getType(M->getContext(), IntrID),
|
||||
AList));
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
//===- BlackfinIntrinsicInfo.h - Blackfin Intrinsic 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 Blackfin implementation of TargetIntrinsicInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef BLACKFININTRINSICS_H
|
||||
#define BLACKFININTRINSICS_H
|
||||
|
||||
#include "llvm/Target/TargetIntrinsicInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinIntrinsicInfo : public TargetIntrinsicInfo {
|
||||
public:
|
||||
std::string getName(unsigned IntrID, Type **Tys = 0,
|
||||
unsigned numTys = 0) const;
|
||||
unsigned lookupName(const char *Name, unsigned Len) const;
|
||||
bool isOverloaded(unsigned IID) const;
|
||||
Function *getDeclaration(Module *M, unsigned ID, Type **Tys = 0,
|
||||
unsigned numTys = 0) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
//===- BlackfinIntrinsics.td - Defines Blackfin 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 blackfin-specific intrinsics.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let TargetPrefix = "bfin", isTarget = 1 in {
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Core synchronisation etc.
|
||||
//
|
||||
// These intrinsics have sideeffects. Each represent a single instruction, but
|
||||
// workarounds are sometimes required depending on the cpu.
|
||||
|
||||
// Execute csync instruction with workarounds
|
||||
def int_bfin_csync : GCCBuiltin<"__builtin_bfin_csync">,
|
||||
Intrinsic<[]>;
|
||||
|
||||
// Execute ssync instruction with workarounds
|
||||
def int_bfin_ssync : GCCBuiltin<"__builtin_bfin_ssync">,
|
||||
Intrinsic<[]>;
|
||||
|
||||
// Execute idle instruction with workarounds
|
||||
def int_bfin_idle : GCCBuiltin<"__builtin_bfin_idle">,
|
||||
Intrinsic<[]>;
|
||||
|
||||
}
|
|
@ -1,344 +0,0 @@
|
|||
//===- BlackfinRegisterInfo.cpp - Blackfin 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 Blackfin implementation of the TargetRegisterInfo
|
||||
// class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Blackfin.h"
|
||||
#include "BlackfinRegisterInfo.h"
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/RegisterScavenging.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
#define GET_REGINFO_TARGET_DESC
|
||||
#include "BlackfinGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
|
||||
const TargetInstrInfo &tii)
|
||||
: BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {}
|
||||
|
||||
const unsigned*
|
||||
BlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
using namespace BF;
|
||||
static const unsigned CalleeSavedRegs[] = {
|
||||
FP,
|
||||
R4, R5, R6, R7,
|
||||
P3, P4, P5,
|
||||
0 };
|
||||
return CalleeSavedRegs;
|
||||
}
|
||||
|
||||
BitVector
|
||||
BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
using namespace BF;
|
||||
BitVector Reserved(getNumRegs());
|
||||
Reserved.set(AZ);
|
||||
Reserved.set(AN);
|
||||
Reserved.set(AQ);
|
||||
Reserved.set(AC0);
|
||||
Reserved.set(AC1);
|
||||
Reserved.set(AV0);
|
||||
Reserved.set(AV0S);
|
||||
Reserved.set(AV1);
|
||||
Reserved.set(AV1S);
|
||||
Reserved.set(V);
|
||||
Reserved.set(VS);
|
||||
Reserved.set(CYCLES).set(CYCLES2);
|
||||
Reserved.set(L0);
|
||||
Reserved.set(L1);
|
||||
Reserved.set(L2);
|
||||
Reserved.set(L3);
|
||||
Reserved.set(SP);
|
||||
Reserved.set(RETS);
|
||||
if (TFI->hasFP(MF))
|
||||
Reserved.set(FP);
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
bool BlackfinRegisterInfo::
|
||||
requiresRegisterScavenging(const MachineFunction &MF) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Emit instructions to add delta to D/P register. ScratchReg must be of the
|
||||
// same class as Reg (P).
|
||||
void BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
unsigned Reg,
|
||||
unsigned ScratchReg,
|
||||
int delta) const {
|
||||
if (!delta)
|
||||
return;
|
||||
if (isInt<7>(delta)) {
|
||||
BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg)
|
||||
.addReg(Reg) // No kill on two-addr operand
|
||||
.addImm(delta);
|
||||
return;
|
||||
}
|
||||
|
||||
// We must load delta into ScratchReg and add that.
|
||||
loadConstant(MBB, I, DL, ScratchReg, delta);
|
||||
if (BF::PRegClass.contains(Reg)) {
|
||||
assert(BF::PRegClass.contains(ScratchReg) &&
|
||||
"ScratchReg must be a P register");
|
||||
BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg)
|
||||
.addReg(Reg, RegState::Kill)
|
||||
.addReg(ScratchReg, RegState::Kill);
|
||||
} else {
|
||||
assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register");
|
||||
assert(BF::DRegClass.contains(ScratchReg) &&
|
||||
"ScratchReg must be a D register");
|
||||
BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg)
|
||||
.addReg(Reg, RegState::Kill)
|
||||
.addReg(ScratchReg, RegState::Kill);
|
||||
}
|
||||
}
|
||||
|
||||
// Emit instructions to load a constant into D/P register
|
||||
void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
unsigned Reg,
|
||||
int value) const {
|
||||
if (isInt<7>(value)) {
|
||||
BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUInt<16>(value)) {
|
||||
BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isInt<16>(value)) {
|
||||
BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// We must split into halves
|
||||
BuildMI(MBB, I, DL,
|
||||
TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
|
||||
.addImm((value >> 16) & 0xffff)
|
||||
.addReg(Reg, RegState::ImplicitDefine);
|
||||
BuildMI(MBB, I, DL,
|
||||
TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
|
||||
.addImm(value & 0xffff)
|
||||
.addReg(Reg, RegState::ImplicitKill)
|
||||
.addReg(Reg, RegState::ImplicitDefine);
|
||||
}
|
||||
|
||||
void BlackfinRegisterInfo::
|
||||
eliminateCallFramePseudoInstr(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
if (!TFI->hasReservedCallFrame(MF)) {
|
||||
int64_t Amount = I->getOperand(0).getImm();
|
||||
if (Amount != 0) {
|
||||
assert(Amount%4 == 0 && "Unaligned call frame size");
|
||||
if (I->getOpcode() == BF::ADJCALLSTACKDOWN) {
|
||||
adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount);
|
||||
} else {
|
||||
assert(I->getOpcode() == BF::ADJCALLSTACKUP &&
|
||||
"Unknown call frame pseudo instruction");
|
||||
adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
MBB.erase(I);
|
||||
}
|
||||
|
||||
/// findScratchRegister - Find a 'free' register. Try for a call-clobbered
|
||||
/// register first and then a spilled callee-saved register if that fails.
|
||||
static unsigned findScratchRegister(MachineBasicBlock::iterator II,
|
||||
RegScavenger *RS,
|
||||
const TargetRegisterClass *RC,
|
||||
int SPAdj) {
|
||||
assert(RS && "Register scavenging must be on");
|
||||
unsigned Reg = RS->FindUnusedReg(RC);
|
||||
if (Reg == 0)
|
||||
Reg = RS->scavengeRegister(RC, II, SPAdj);
|
||||
return Reg;
|
||||
}
|
||||
|
||||
void
|
||||
BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||
int SPAdj, RegScavenger *RS) const {
|
||||
MachineInstr &MI = *II;
|
||||
MachineBasicBlock &MBB = *MI.getParent();
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
|
||||
unsigned FIPos;
|
||||
for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
|
||||
assert(FIPos < MI.getNumOperands() &&
|
||||
"Instr doesn't have FrameIndex operand!");
|
||||
}
|
||||
int FrameIndex = MI.getOperand(FIPos).getIndex();
|
||||
assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm());
|
||||
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex)
|
||||
+ MI.getOperand(FIPos+1).getImm();
|
||||
unsigned BaseReg = BF::FP;
|
||||
if (TFI->hasFP(MF)) {
|
||||
assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer");
|
||||
} else {
|
||||
BaseReg = BF::SP;
|
||||
Offset += MF.getFrameInfo()->getStackSize() + SPAdj;
|
||||
}
|
||||
|
||||
bool isStore = false;
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
case BF::STORE32fi:
|
||||
isStore = true;
|
||||
case BF::LOAD32fi: {
|
||||
assert(Offset%4 == 0 && "Unaligned i32 stack access");
|
||||
assert(FIPos==1 && "Bad frame index operand");
|
||||
MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
|
||||
MI.getOperand(FIPos+1).setImm(Offset);
|
||||
if (isUInt<6>(Offset)) {
|
||||
MI.setDesc(TII.get(isStore
|
||||
? BF::STORE32p_uimm6m4
|
||||
: BF::LOAD32p_uimm6m4));
|
||||
return;
|
||||
}
|
||||
if (BaseReg == BF::FP && isUInt<7>(-Offset)) {
|
||||
MI.setDesc(TII.get(isStore
|
||||
? BF::STORE32fp_nimm7m4
|
||||
: BF::LOAD32fp_nimm7m4));
|
||||
MI.getOperand(FIPos+1).setImm(-Offset);
|
||||
return;
|
||||
}
|
||||
if (isInt<18>(Offset)) {
|
||||
MI.setDesc(TII.get(isStore
|
||||
? BF::STORE32p_imm18m4
|
||||
: BF::LOAD32p_imm18m4));
|
||||
return;
|
||||
}
|
||||
// Use RegScavenger to calculate proper offset...
|
||||
MI.dump();
|
||||
llvm_unreachable("Stack frame offset too big");
|
||||
break;
|
||||
}
|
||||
case BF::ADDpp: {
|
||||
assert(MI.getOperand(0).isReg() && "ADD instruction needs a register");
|
||||
unsigned DestReg = MI.getOperand(0).getReg();
|
||||
// We need to produce a stack offset in a P register. We emit:
|
||||
// P0 = offset;
|
||||
// P0 = BR + P0;
|
||||
assert(FIPos==1 && "Bad frame index operand");
|
||||
loadConstant(MBB, II, DL, DestReg, Offset);
|
||||
MI.getOperand(1).ChangeToRegister(DestReg, false, false, true);
|
||||
MI.getOperand(2).ChangeToRegister(BaseReg, false);
|
||||
break;
|
||||
}
|
||||
case BF::STORE16fi:
|
||||
isStore = true;
|
||||
case BF::LOAD16fi: {
|
||||
assert(Offset%2 == 0 && "Unaligned i16 stack access");
|
||||
assert(FIPos==1 && "Bad frame index operand");
|
||||
// We need a P register to use as an address
|
||||
unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj);
|
||||
assert(ScratchReg && "Could not scavenge register");
|
||||
loadConstant(MBB, II, DL, ScratchReg, Offset);
|
||||
BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg)
|
||||
.addReg(ScratchReg, RegState::Kill)
|
||||
.addReg(BaseReg);
|
||||
MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi));
|
||||
MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true);
|
||||
MI.RemoveOperand(2);
|
||||
break;
|
||||
}
|
||||
case BF::STORE8fi: {
|
||||
// This is an AnyCC spill, we need a scratch register.
|
||||
assert(FIPos==1 && "Bad frame index operand");
|
||||
MachineOperand SpillReg = MI.getOperand(0);
|
||||
unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
|
||||
assert(ScratchReg && "Could not scavenge register");
|
||||
if (SpillReg.getReg()==BF::NCC) {
|
||||
BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg)
|
||||
.addOperand(SpillReg);
|
||||
BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg)
|
||||
.addReg(ScratchReg).addImm(0);
|
||||
} else {
|
||||
BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg)
|
||||
.addOperand(SpillReg);
|
||||
}
|
||||
// STORE D
|
||||
MI.setDesc(TII.get(BF::STORE8p_imm16));
|
||||
MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true);
|
||||
MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
|
||||
MI.getOperand(FIPos+1).setImm(Offset);
|
||||
break;
|
||||
}
|
||||
case BF::LOAD8fi: {
|
||||
// This is an restore, we need a scratch register.
|
||||
assert(FIPos==1 && "Bad frame index operand");
|
||||
MachineOperand SpillReg = MI.getOperand(0);
|
||||
unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
|
||||
assert(ScratchReg && "Could not scavenge register");
|
||||
MI.setDesc(TII.get(BF::LOAD32p_imm16_8z));
|
||||
MI.getOperand(0).ChangeToRegister(ScratchReg, true);
|
||||
MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
|
||||
MI.getOperand(FIPos+1).setImm(Offset);
|
||||
++II;
|
||||
if (SpillReg.getReg()==BF::CC) {
|
||||
// CC = D
|
||||
BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC)
|
||||
.addReg(ScratchReg, RegState::Kill);
|
||||
} else {
|
||||
// Restore NCC (CC = D==0)
|
||||
BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC)
|
||||
.addReg(ScratchReg, RegState::Kill)
|
||||
.addImm(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Cannot eliminate frame index");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
||||
|
||||
return TFI->hasFP(MF) ? BF::FP : BF::SP;
|
||||
}
|
||||
|
||||
unsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
|
||||
llvm_unreachable("What is the exception register");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
|
||||
llvm_unreachable("What is the exception handler register");
|
||||
return 0;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
//===- BlackfinRegisterInfo.h - Blackfin 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 Blackfin implementation of the TargetRegisterInfo
|
||||
// class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFINREGISTERINFO_H
|
||||
#define BLACKFINREGISTERINFO_H
|
||||
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#define GET_REGINFO_HEADER
|
||||
#include "BlackfinGenRegisterInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinSubtarget;
|
||||
class TargetInstrInfo;
|
||||
class Type;
|
||||
|
||||
struct BlackfinRegisterInfo : public BlackfinGenRegisterInfo {
|
||||
BlackfinSubtarget &Subtarget;
|
||||
const TargetInstrInfo &TII;
|
||||
|
||||
BlackfinRegisterInfo(BlackfinSubtarget &st, const TargetInstrInfo &tii);
|
||||
|
||||
/// Code Generation virtual methods...
|
||||
const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
|
||||
|
||||
BitVector getReservedRegs(const MachineFunction &MF) const;
|
||||
|
||||
// getSubReg implemented by tablegen
|
||||
|
||||
const TargetRegisterClass *getPointerRegClass(unsigned Kind = 0) const {
|
||||
return &BF::PRegClass;
|
||||
}
|
||||
|
||||
bool requiresRegisterScavenging(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;
|
||||
|
||||
unsigned getFrameRegister(const MachineFunction &MF) const;
|
||||
|
||||
// Exception handling queries.
|
||||
unsigned getEHExceptionRegister() const;
|
||||
unsigned getEHHandlerRegister() const;
|
||||
|
||||
// Utility functions
|
||||
void adjustRegister(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
unsigned Reg,
|
||||
unsigned ScratchReg,
|
||||
int delta) const;
|
||||
void loadConstant(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL,
|
||||
unsigned Reg,
|
||||
int value) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,277 +0,0 @@
|
|||
//===- BlackfinRegisterInfo.td - Blackfin Register defs ----*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Declarations that describe the Blackfin register file
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Subregs are:
|
||||
// 1: .L
|
||||
// 2: .H
|
||||
// 3: .W (32 low bits of 40-bit accu)
|
||||
let Namespace = "BF" in {
|
||||
def lo16 : SubRegIndex;
|
||||
def hi16 : SubRegIndex;
|
||||
def lo32 : SubRegIndex;
|
||||
def hi32 : SubRegIndex;
|
||||
}
|
||||
|
||||
// Registers are identified with 3-bit group and 3-bit ID numbers.
|
||||
class BlackfinReg<string n> : Register<n> {
|
||||
field bits<3> Group;
|
||||
field bits<3> Num;
|
||||
let Namespace = "BF";
|
||||
}
|
||||
|
||||
// Rc - 1-bit registers
|
||||
class Rc<bits<5> bitno, string n> : BlackfinReg<n> {
|
||||
field bits<5> BitNum = bitno;
|
||||
}
|
||||
|
||||
// Rs - 16-bit integer registers
|
||||
class Rs<bits<3> group, bits<3> num, bits<1> hi, string n> : BlackfinReg<n> {
|
||||
let Group = group;
|
||||
let Num = num;
|
||||
field bits<1> High = hi;
|
||||
}
|
||||
|
||||
// Ri - 32-bit integer registers with subregs
|
||||
class Ri<bits<3> group, bits<3> num, string n> : BlackfinReg<n> {
|
||||
let Group = group;
|
||||
let Num = num;
|
||||
}
|
||||
|
||||
// Ra 40-bit accumulator registers
|
||||
class Ra<bits<3> num, string n, list<Register> subs> : BlackfinReg<n> {
|
||||
let SubRegs = subs;
|
||||
let SubRegIndices = [hi32, lo32];
|
||||
let Group = 4;
|
||||
let Num = num;
|
||||
}
|
||||
|
||||
// Two halves of 32-bit register
|
||||
multiclass Rss<bits<3> group, bits<3> num, string n> {
|
||||
def H : Rs<group, num, 1, !strconcat(n, ".h")>;
|
||||
def L : Rs<group, num, 0, !strconcat(n, ".l")>;
|
||||
}
|
||||
|
||||
// Rii - 32-bit integer registers with subregs
|
||||
class Rii<bits<3> group, bits<3> num, string n, list<Register> subs>
|
||||
: BlackfinReg<n> {
|
||||
let SubRegs = subs;
|
||||
let SubRegIndices = [hi16, lo16];
|
||||
let Group = group;
|
||||
let Num = num;
|
||||
}
|
||||
|
||||
// Status bits are all part of ASTAT
|
||||
def AZ : Rc<0, "az">;
|
||||
def AN : Rc<1, "an">;
|
||||
def CC : Rc<5, "cc">, DwarfRegNum<[34]>;
|
||||
def NCC : Rc<5, "!cc"> { let Aliases = [CC]; }
|
||||
def AQ : Rc<6, "aq">;
|
||||
def AC0 : Rc<12, "ac0">;
|
||||
def AC1 : Rc<13, "ac1">;
|
||||
def AV0 : Rc<16, "av0">;
|
||||
def AV0S : Rc<17, "av0s">;
|
||||
def AV1 : Rc<18, "av1">;
|
||||
def AV1S : Rc<19, "av1s">;
|
||||
def V : Rc<24, "v">;
|
||||
def VS : Rc<25, "vs">;
|
||||
// Skipped non-status bits: AC0_COPY, V_COPY, RND_MOD
|
||||
|
||||
// Group 0: Integer registers
|
||||
defm R0 : Rss<0, 0, "r0">;
|
||||
def R0 : Rii<0, 0, "r0", [R0H, R0L]>, DwarfRegNum<[0]>;
|
||||
defm R1 : Rss<0, 1, "r1">;
|
||||
def R1 : Rii<0, 1, "r1", [R1H, R1L]>, DwarfRegNum<[1]>;
|
||||
defm R2 : Rss<0, 2, "r2">;
|
||||
def R2 : Rii<0, 2, "r2", [R2H, R2L]>, DwarfRegNum<[2]>;
|
||||
defm R3 : Rss<0, 3, "r3">;
|
||||
def R3 : Rii<0, 3, "r3", [R3H, R3L]>, DwarfRegNum<[3]>;
|
||||
defm R4 : Rss<0, 4, "r4">;
|
||||
def R4 : Rii<0, 4, "r4", [R4H, R4L]>, DwarfRegNum<[4]>;
|
||||
defm R5 : Rss<0, 5, "r5">;
|
||||
def R5 : Rii<0, 5, "r5", [R5H, R5L]>, DwarfRegNum<[5]>;
|
||||
defm R6 : Rss<0, 6, "r6">;
|
||||
def R6 : Rii<0, 6, "r6", [R6H, R6L]>, DwarfRegNum<[6]>;
|
||||
defm R7 : Rss<0, 7, "r7">;
|
||||
def R7 : Rii<0, 7, "r7", [R7H, R7L]>, DwarfRegNum<[7]>;
|
||||
|
||||
// Group 1: Pointer registers
|
||||
defm P0 : Rss<1, 0, "p0">;
|
||||
def P0 : Rii<1, 0, "p0", [P0H, P0L]>, DwarfRegNum<[8]>;
|
||||
defm P1 : Rss<1, 1, "p1">;
|
||||
def P1 : Rii<1, 1, "p1", [P1H, P1L]>, DwarfRegNum<[9]>;
|
||||
defm P2 : Rss<1, 2, "p2">;
|
||||
def P2 : Rii<1, 2, "p2", [P2H, P2L]>, DwarfRegNum<[10]>;
|
||||
defm P3 : Rss<1, 3, "p3">;
|
||||
def P3 : Rii<1, 3, "p3", [P3H, P3L]>, DwarfRegNum<[11]>;
|
||||
defm P4 : Rss<1, 4, "p4">;
|
||||
def P4 : Rii<1, 4, "p4", [P4H, P4L]>, DwarfRegNum<[12]>;
|
||||
defm P5 : Rss<1, 5, "p5">;
|
||||
def P5 : Rii<1, 5, "p5", [P5H, P5L]>, DwarfRegNum<[13]>;
|
||||
defm SP : Rss<1, 6, "sp">;
|
||||
def SP : Rii<1, 6, "sp", [SPH, SPL]>, DwarfRegNum<[14]>;
|
||||
defm FP : Rss<1, 7, "fp">;
|
||||
def FP : Rii<1, 7, "fp", [FPH, FPL]>, DwarfRegNum<[15]>;
|
||||
|
||||
// Group 2: Index registers
|
||||
defm I0 : Rss<2, 0, "i0">;
|
||||
def I0 : Rii<2, 0, "i0", [I0H, I0L]>, DwarfRegNum<[16]>;
|
||||
defm I1 : Rss<2, 1, "i1">;
|
||||
def I1 : Rii<2, 1, "i1", [I1H, I1L]>, DwarfRegNum<[17]>;
|
||||
defm I2 : Rss<2, 2, "i2">;
|
||||
def I2 : Rii<2, 2, "i2", [I2H, I2L]>, DwarfRegNum<[18]>;
|
||||
defm I3 : Rss<2, 3, "i3">;
|
||||
def I3 : Rii<2, 3, "i3", [I3H, I3L]>, DwarfRegNum<[19]>;
|
||||
defm M0 : Rss<2, 4, "m0">;
|
||||
def M0 : Rii<2, 4, "m0", [M0H, M0L]>, DwarfRegNum<[20]>;
|
||||
defm M1 : Rss<2, 5, "m1">;
|
||||
def M1 : Rii<2, 5, "m1", [M1H, M1L]>, DwarfRegNum<[21]>;
|
||||
defm M2 : Rss<2, 6, "m2">;
|
||||
def M2 : Rii<2, 6, "m2", [M2H, M2L]>, DwarfRegNum<[22]>;
|
||||
defm M3 : Rss<2, 7, "m3">;
|
||||
def M3 : Rii<2, 7, "m3", [M3H, M3L]>, DwarfRegNum<[23]>;
|
||||
|
||||
// Group 3: Cyclic indexing registers
|
||||
defm B0 : Rss<3, 0, "b0">;
|
||||
def B0 : Rii<3, 0, "b0", [B0H, B0L]>, DwarfRegNum<[24]>;
|
||||
defm B1 : Rss<3, 1, "b1">;
|
||||
def B1 : Rii<3, 1, "b1", [B1H, B1L]>, DwarfRegNum<[25]>;
|
||||
defm B2 : Rss<3, 2, "b2">;
|
||||
def B2 : Rii<3, 2, "b2", [B2H, B2L]>, DwarfRegNum<[26]>;
|
||||
defm B3 : Rss<3, 3, "b3">;
|
||||
def B3 : Rii<3, 3, "b3", [B3H, B3L]>, DwarfRegNum<[27]>;
|
||||
defm L0 : Rss<3, 4, "l0">;
|
||||
def L0 : Rii<3, 4, "l0", [L0H, L0L]>, DwarfRegNum<[28]>;
|
||||
defm L1 : Rss<3, 5, "l1">;
|
||||
def L1 : Rii<3, 5, "l1", [L1H, L1L]>, DwarfRegNum<[29]>;
|
||||
defm L2 : Rss<3, 6, "l2">;
|
||||
def L2 : Rii<3, 6, "l2", [L2H, L2L]>, DwarfRegNum<[30]>;
|
||||
defm L3 : Rss<3, 7, "l3">;
|
||||
def L3 : Rii<3, 7, "l3", [L3H, L3L]>, DwarfRegNum<[31]>;
|
||||
|
||||
// Accumulators
|
||||
def A0X : Ri <4, 0, "a0.x">;
|
||||
defm A0 : Rss<4, 1, "a0">;
|
||||
def A0W : Rii<4, 1, "a0.w", [A0H, A0L]>, DwarfRegNum<[32]>;
|
||||
def A0 : Ra <0, "a0", [A0X, A0W]>;
|
||||
|
||||
def A1X : Ri <4, 2, "a1.x">;
|
||||
defm A1 : Rss<4, 3, "a1">;
|
||||
def A1W : Rii<4, 3, "a1.w", [A1H, A1L]>, DwarfRegNum<[33]>;
|
||||
def A1 : Ra <2, "a1", [A1X, A1W]>;
|
||||
|
||||
def RETS : Ri<4, 7, "rets">, DwarfRegNum<[35]>;
|
||||
def RETI : Ri<7, 3, "reti">, DwarfRegNum<[36]>;
|
||||
def RETX : Ri<7, 4, "retx">, DwarfRegNum<[37]>;
|
||||
def RETN : Ri<7, 5, "retn">, DwarfRegNum<[38]>;
|
||||
def RETE : Ri<7, 6, "rete">, DwarfRegNum<[39]>;
|
||||
|
||||
def ASTAT : Ri<4, 6, "astat">, DwarfRegNum<[40]> {
|
||||
let Aliases = [AZ, AN, CC, NCC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS];
|
||||
}
|
||||
|
||||
def SEQSTAT : Ri<7, 1, "seqstat">, DwarfRegNum<[41]>;
|
||||
def USP : Ri<7, 0, "usp">, DwarfRegNum<[42]>;
|
||||
def EMUDAT : Ri<7, 7, "emudat">, DwarfRegNum<[43]>;
|
||||
def SYSCFG : Ri<7, 2, "syscfg">;
|
||||
def CYCLES : Ri<6, 6, "cycles">;
|
||||
def CYCLES2 : Ri<6, 7, "cycles2">;
|
||||
|
||||
// Hardware loops
|
||||
def LT0 : Ri<6, 1, "lt0">, DwarfRegNum<[44]>;
|
||||
def LT1 : Ri<6, 4, "lt1">, DwarfRegNum<[45]>;
|
||||
def LC0 : Ri<6, 0, "lc0">, DwarfRegNum<[46]>;
|
||||
def LC1 : Ri<6, 3, "lc1">, DwarfRegNum<[47]>;
|
||||
def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>;
|
||||
def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>;
|
||||
|
||||
// Register classes.
|
||||
def D16L : RegisterClass<"BF", [i16], 16, (sequence "R%uL", 0, 7)>;
|
||||
|
||||
def D16H : RegisterClass<"BF", [i16], 16, (sequence "R%uH", 0, 7)>;
|
||||
|
||||
def D16 : RegisterClass<"BF", [i16], 16, (add D16L, D16H)>;
|
||||
|
||||
def P16L : RegisterClass<"BF", [i16], 16,
|
||||
(add (sequence "P%uL", 0, 5), SPL, FPL)>;
|
||||
|
||||
def P16H : RegisterClass<"BF", [i16], 16,
|
||||
(add (sequence "P%uH", 0, 5), SPH, FPH)>;
|
||||
|
||||
def P16 : RegisterClass<"BF", [i16], 16, (add P16L, P16H)>;
|
||||
|
||||
def DP16 : RegisterClass<"BF", [i16], 16, (add D16, P16)>;
|
||||
|
||||
def DP16L : RegisterClass<"BF", [i16], 16, (add D16L, P16L)>;
|
||||
|
||||
def DP16H : RegisterClass<"BF", [i16], 16, (add D16H, P16H)>;
|
||||
|
||||
def GR16 : RegisterClass<"BF", [i16], 16,
|
||||
(add DP16,
|
||||
I0H, I0L, I1H, I1L, I2H, I2L, I3H, I3L,
|
||||
M0H, M0L, M1H, M1L, M2H, M2L, M3H, M3L,
|
||||
B0H, B0L, B1H, B1L, B2H, B2L, B3H, B3L,
|
||||
L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L)>;
|
||||
|
||||
def D : RegisterClass<"BF", [i32], 32, (sequence "R%u", 0, 7)> {
|
||||
let SubRegClasses = [(D16L lo16), (D16H hi16)];
|
||||
}
|
||||
|
||||
def P : RegisterClass<"BF", [i32], 32, (add (sequence "P%u", 0, 5), FP, SP)> {
|
||||
let SubRegClasses = [(P16L lo16), (P16H hi16)];
|
||||
}
|
||||
|
||||
def DP : RegisterClass<"BF", [i32], 32, (add D, P)> {
|
||||
let SubRegClasses = [(DP16L lo16), (DP16H hi16)];
|
||||
}
|
||||
|
||||
def I : RegisterClass<"BF", [i32], 32, (add I0, I1, I2, I3)>;
|
||||
def M : RegisterClass<"BF", [i32], 32, (add M0, M1, M2, M3)>;
|
||||
def B : RegisterClass<"BF", [i32], 32, (add B0, B1, B2, B3)>;
|
||||
def L : RegisterClass<"BF", [i32], 32, (add L0, L1, L2, L3)>;
|
||||
|
||||
def GR : RegisterClass<"BF", [i32], 32, (add DP, I, M, B, L)>;
|
||||
|
||||
def ALL : RegisterClass<"BF", [i32], 32,
|
||||
(add GR,
|
||||
A0X, A0W, A1X, A1W, ASTAT, RETS,
|
||||
LC0, LT0, LB0, LC1, LT1, LB1, CYCLES, CYCLES2,
|
||||
USP, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, EMUDAT)>;
|
||||
|
||||
def PI : RegisterClass<"BF", [i32], 32, (add P, I)>;
|
||||
|
||||
// We are going to pretend that CC and !CC are 32-bit registers, even though
|
||||
// they only can hold 1 bit.
|
||||
let CopyCost = -1, Size = 8 in {
|
||||
def JustCC : RegisterClass<"BF", [i32], 8, (add CC)>;
|
||||
def NotCC : RegisterClass<"BF", [i32], 8, (add NCC)>;
|
||||
def AnyCC : RegisterClass<"BF", [i32], 8, (add CC, NCC)>;
|
||||
def StatBit : RegisterClass<"BF", [i1], 8,
|
||||
(add AZ, AN, CC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS)>;
|
||||
}
|
||||
|
||||
// Should be i40, but that isn't defined. It is not a legal type yet anyway.
|
||||
def Accu : RegisterClass<"BF", [i64], 64, (add A0, A1)>;
|
||||
|
||||
// Register classes to match inline asm constraints.
|
||||
def zCons : RegisterClass<"BF", [i32], 32, (add P0, P1, P2)>;
|
||||
def DCons : RegisterClass<"BF", [i32], 32, (add R0, R2, R4, R6)>;
|
||||
def WCons : RegisterClass<"BF", [i32], 32, (add R1, R3, R5, R7)>;
|
||||
def cCons : RegisterClass<"BF", [i32], 32, (add I0, I1, I2, I3,
|
||||
B0, B1, B2, B3,
|
||||
L0, L1, L2, L3)>;
|
||||
def tCons : RegisterClass<"BF", [i32], 32, (add LT0, LT1)>;
|
||||
def uCons : RegisterClass<"BF", [i32], 32, (add LB0, LB1)>;
|
||||
def kCons : RegisterClass<"BF", [i32], 32, (add LC0, LC1)>;
|
||||
def yCons : RegisterClass<"BF", [i32], 32, (add RETS, RETN, RETI, RETX,
|
||||
RETE, ASTAT, SEQSTAT,
|
||||
USP)>;
|
|
@ -1,24 +0,0 @@
|
|||
//===-- BlackfinSelectionDAGInfo.cpp - Blackfin 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 BlackfinSelectionDAGInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "blackfin-selectiondag-info"
|
||||
#include "BlackfinTargetMachine.h"
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinSelectionDAGInfo::BlackfinSelectionDAGInfo(
|
||||
const BlackfinTargetMachine &TM)
|
||||
: TargetSelectionDAGInfo(TM) {
|
||||
}
|
||||
|
||||
BlackfinSelectionDAGInfo::~BlackfinSelectionDAGInfo() {
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
//===-- BlackfinSelectionDAGInfo.h - Blackfin 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 Blackfin subclass for TargetSelectionDAGInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFINSELECTIONDAGINFO_H
|
||||
#define BLACKFINSELECTIONDAGINFO_H
|
||||
|
||||
#include "llvm/Target/TargetSelectionDAGInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinTargetMachine;
|
||||
|
||||
class BlackfinSelectionDAGInfo : public TargetSelectionDAGInfo {
|
||||
public:
|
||||
explicit BlackfinSelectionDAGInfo(const BlackfinTargetMachine &TM);
|
||||
~BlackfinSelectionDAGInfo();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
//===- BlackfinSubtarget.cpp - BLACKFIN Subtarget Information -------------===//
|
||||
//
|
||||
// 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 blackfin specific subclass of TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "Blackfin.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
#define GET_SUBTARGETINFO_TARGET_DESC
|
||||
#define GET_SUBTARGETINFO_CTOR
|
||||
#include "BlackfinGenSubtargetInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinSubtarget::BlackfinSubtarget(const std::string &TT,
|
||||
const std::string &CPU,
|
||||
const std::string &FS)
|
||||
: BlackfinGenSubtargetInfo(TT, CPU, FS), sdram(false),
|
||||
icplb(false),
|
||||
wa_mi_shift(false),
|
||||
wa_csync(false),
|
||||
wa_specld(false),
|
||||
wa_mmr_stall(false),
|
||||
wa_lcregs(false),
|
||||
wa_hwloop(false),
|
||||
wa_ind_call(false),
|
||||
wa_killed_mmr(false),
|
||||
wa_rets(false)
|
||||
{
|
||||
std::string CPUName = CPU;
|
||||
if (CPUName.empty())
|
||||
CPUName = "generic";
|
||||
// Parse features string.
|
||||
ParseSubtargetFeatures(CPUName, FS);
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
//===- BlackfinSubtarget.h - Define Subtarget for the Blackfin -*- 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 BLACKFIN specific subclass of TargetSubtargetInfo.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFIN_SUBTARGET_H
|
||||
#define BLACKFIN_SUBTARGET_H
|
||||
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <string>
|
||||
|
||||
#define GET_SUBTARGETINFO_HEADER
|
||||
#include "BlackfinGenSubtargetInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
|
||||
class BlackfinSubtarget : public BlackfinGenSubtargetInfo {
|
||||
bool sdram;
|
||||
bool icplb;
|
||||
bool wa_mi_shift;
|
||||
bool wa_csync;
|
||||
bool wa_specld;
|
||||
bool wa_mmr_stall;
|
||||
bool wa_lcregs;
|
||||
bool wa_hwloop;
|
||||
bool wa_ind_call;
|
||||
bool wa_killed_mmr;
|
||||
bool wa_rets;
|
||||
public:
|
||||
BlackfinSubtarget(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);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,43 +0,0 @@
|
|||
//===-- BlackfinTargetMachine.cpp - Define TargetMachine for Blackfin -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinTargetMachine.h"
|
||||
#include "Blackfin.h"
|
||||
#include "llvm/PassManager.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
extern "C" void LLVMInitializeBlackfinTarget() {
|
||||
RegisterTargetMachine<BlackfinTargetMachine> X(TheBlackfinTarget);
|
||||
}
|
||||
|
||||
BlackfinTargetMachine::BlackfinTargetMachine(const Target &T,
|
||||
StringRef TT,
|
||||
StringRef CPU,
|
||||
StringRef FS,
|
||||
Reloc::Model RM,
|
||||
CodeModel::Model CM)
|
||||
: LLVMTargetMachine(T, TT, CPU, FS, RM, CM),
|
||||
DataLayout("e-p:32:32-i64:32-f64:32-n32"),
|
||||
Subtarget(TT, CPU, FS),
|
||||
TLInfo(*this),
|
||||
TSInfo(*this),
|
||||
InstrInfo(Subtarget),
|
||||
FrameLowering(Subtarget) {
|
||||
}
|
||||
|
||||
bool BlackfinTargetMachine::addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel) {
|
||||
PM.add(createBlackfinISelDag(*this, OptLevel));
|
||||
return false;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
//===-- BlackfinTargetMachine.h - TargetMachine for Blackfin ----*- 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 Blackfin specific subclass of TargetMachine.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFINTARGETMACHINE_H
|
||||
#define BLACKFINTARGETMACHINE_H
|
||||
|
||||
#include "BlackfinInstrInfo.h"
|
||||
#include "BlackfinIntrinsicInfo.h"
|
||||
#include "BlackfinISelLowering.h"
|
||||
#include "BlackfinFrameLowering.h"
|
||||
#include "BlackfinSubtarget.h"
|
||||
#include "BlackfinSelectionDAGInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class BlackfinTargetMachine : public LLVMTargetMachine {
|
||||
const TargetData DataLayout;
|
||||
BlackfinSubtarget Subtarget;
|
||||
BlackfinTargetLowering TLInfo;
|
||||
BlackfinSelectionDAGInfo TSInfo;
|
||||
BlackfinInstrInfo InstrInfo;
|
||||
BlackfinFrameLowering FrameLowering;
|
||||
BlackfinIntrinsicInfo IntrinsicInfo;
|
||||
public:
|
||||
BlackfinTargetMachine(const Target &T, StringRef TT,
|
||||
StringRef CPU, StringRef FS,
|
||||
Reloc::Model RM, CodeModel::Model CM);
|
||||
|
||||
virtual const BlackfinInstrInfo *getInstrInfo() const { return &InstrInfo; }
|
||||
virtual const TargetFrameLowering *getFrameLowering() const {
|
||||
return &FrameLowering;
|
||||
}
|
||||
virtual const BlackfinSubtarget *getSubtargetImpl() const {
|
||||
return &Subtarget;
|
||||
}
|
||||
virtual const BlackfinRegisterInfo *getRegisterInfo() const {
|
||||
return &InstrInfo.getRegisterInfo();
|
||||
}
|
||||
virtual const BlackfinTargetLowering* getTargetLowering() const {
|
||||
return &TLInfo;
|
||||
}
|
||||
virtual const BlackfinSelectionDAGInfo* getSelectionDAGInfo() const {
|
||||
return &TSInfo;
|
||||
}
|
||||
virtual const TargetData *getTargetData() const { return &DataLayout; }
|
||||
virtual bool addInstSelector(PassManagerBase &PM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
const TargetIntrinsicInfo *getIntrinsicInfo() const {
|
||||
return &IntrinsicInfo;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
set(LLVM_TARGET_DEFINITIONS Blackfin.td)
|
||||
|
||||
llvm_tablegen(BlackfinGenRegisterInfo.inc -gen-register-info)
|
||||
llvm_tablegen(BlackfinGenInstrInfo.inc -gen-instr-info)
|
||||
llvm_tablegen(BlackfinGenAsmWriter.inc -gen-asm-writer)
|
||||
llvm_tablegen(BlackfinGenDAGISel.inc -gen-dag-isel)
|
||||
llvm_tablegen(BlackfinGenSubtargetInfo.inc -gen-subtarget)
|
||||
llvm_tablegen(BlackfinGenCallingConv.inc -gen-callingconv)
|
||||
llvm_tablegen(BlackfinGenIntrinsics.inc -gen-tgt-intrinsic)
|
||||
add_public_tablegen_target(BlackfinCommonTableGen)
|
||||
|
||||
add_llvm_target(BlackfinCodeGen
|
||||
BlackfinAsmPrinter.cpp
|
||||
BlackfinInstrInfo.cpp
|
||||
BlackfinIntrinsicInfo.cpp
|
||||
BlackfinISelDAGToDAG.cpp
|
||||
BlackfinISelLowering.cpp
|
||||
BlackfinFrameLowering.cpp
|
||||
BlackfinRegisterInfo.cpp
|
||||
BlackfinSubtarget.cpp
|
||||
BlackfinTargetMachine.cpp
|
||||
BlackfinSelectionDAGInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMBlackfinCodeGen
|
||||
LLVMAsmPrinter
|
||||
LLVMBlackfinDesc
|
||||
LLVMBlackfinInfo
|
||||
LLVMCodeGen
|
||||
LLVMCore
|
||||
LLVMMC
|
||||
LLVMSelectionDAG
|
||||
LLVMSupport
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
|
@ -1,22 +0,0 @@
|
|||
//===-- BlackfinMCAsmInfo.cpp - Blackfin asm properties -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the declarations of the BlackfinMCAsmInfo properties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinMCAsmInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
BlackfinMCAsmInfo::BlackfinMCAsmInfo(const Target &T, StringRef TT) {
|
||||
GlobalPrefix = "_";
|
||||
CommentString = "//";
|
||||
HasSetDirective = false;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
//===-- BlackfinMCAsmInfo.h - Blackfin 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 BlackfinMCAsmInfo class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFINTARGETASMINFO_H
|
||||
#define BLACKFINTARGETASMINFO_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class Target;
|
||||
|
||||
struct BlackfinMCAsmInfo : public MCAsmInfo {
|
||||
explicit BlackfinMCAsmInfo(const Target &T, StringRef TT);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
|
@ -1,81 +0,0 @@
|
|||
//===-- BlackfinMCTargetDesc.cpp - Blackfin 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 Blackfin specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BlackfinMCTargetDesc.h"
|
||||
#include "BlackfinMCAsmInfo.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 "BlackfinGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_MC_DESC
|
||||
#include "BlackfinGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "BlackfinGenRegisterInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
||||
static MCInstrInfo *createBlackfinMCInstrInfo() {
|
||||
MCInstrInfo *X = new MCInstrInfo();
|
||||
InitBlackfinMCInstrInfo(X);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCRegisterInfo *createBlackfinMCRegisterInfo(StringRef TT) {
|
||||
MCRegisterInfo *X = new MCRegisterInfo();
|
||||
InitBlackfinMCRegisterInfo(X, BF::RETS);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCSubtargetInfo *createBlackfinMCSubtargetInfo(StringRef TT,
|
||||
StringRef CPU,
|
||||
StringRef FS) {
|
||||
MCSubtargetInfo *X = new MCSubtargetInfo();
|
||||
InitBlackfinMCSubtargetInfo(X, TT, CPU, FS);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCCodeGenInfo *createBlackfinMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
CodeModel::Model CM) {
|
||||
MCCodeGenInfo *X = new MCCodeGenInfo();
|
||||
X->InitMCCodeGenInfo(RM, CM);
|
||||
return X;
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeBlackfinTargetMC() {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfo<BlackfinMCAsmInfo> X(TheBlackfinTarget);
|
||||
|
||||
// Register the MC codegen info.
|
||||
TargetRegistry::RegisterMCCodeGenInfo(TheBlackfinTarget,
|
||||
createBlackfinMCCodeGenInfo);
|
||||
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(TheBlackfinTarget,
|
||||
createBlackfinMCInstrInfo);
|
||||
|
||||
// Register the MC register info.
|
||||
TargetRegistry::RegisterMCRegInfo(TheBlackfinTarget,
|
||||
createBlackfinMCRegisterInfo);
|
||||
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(TheBlackfinTarget,
|
||||
createBlackfinMCSubtargetInfo);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//===-- BlackfinMCTargetDesc.h - Blackfin 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 Blackfin specific target descriptions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BLACKFINMCTARGETDESC_H
|
||||
#define BLACKFINMCTARGETDESC_H
|
||||
|
||||
namespace llvm {
|
||||
class MCSubtargetInfo;
|
||||
class Target;
|
||||
class StringRef;
|
||||
|
||||
extern Target TheBlackfinTarget;
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
// Defines symbolic names for Blackfin registers. This defines a mapping from
|
||||
// register name to register number.
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "BlackfinGenRegisterInfo.inc"
|
||||
|
||||
// Defines symbolic names for the Blackfin instructions.
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "BlackfinGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "BlackfinGenSubtargetInfo.inc"
|
||||
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
add_llvm_library(LLVMBlackfinDesc
|
||||
BlackfinMCTargetDesc.cpp
|
||||
BlackfinMCAsmInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMBlackfinDesc
|
||||
LLVMBlackfinInfo
|
||||
LLVMMC
|
||||
)
|
||||
|
||||
add_dependencies(LLVMBlackfinDesc BlackfinCommonTableGen)
|
|
@ -1,16 +0,0 @@
|
|||
##===- lib/Target/Blackfin/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 = LLVMBlackfinDesc
|
||||
|
||||
# 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,23 +0,0 @@
|
|||
##===- lib/Target/Blackfin/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 = LLVMBlackfinCodeGen
|
||||
TARGET = Blackfin
|
||||
|
||||
# Make sure that tblgen is run, first thing.
|
||||
BUILT_SOURCES = BlackfinGenRegisterInfo.inc BlackfinGenInstrInfo.inc \
|
||||
BlackfinGenAsmWriter.inc \
|
||||
BlackfinGenDAGISel.inc BlackfinGenSubtargetInfo.inc \
|
||||
BlackfinGenCallingConv.inc BlackfinGenIntrinsics.inc
|
||||
|
||||
DIRS = TargetInfo MCTargetDesc
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
|
@ -1,244 +0,0 @@
|
|||
//===-- README.txt - Notes for Blackfin Target ------------------*- org -*-===//
|
||||
|
||||
* Condition codes
|
||||
** DONE Problem with asymmetric SETCC operations
|
||||
The instruction
|
||||
|
||||
CC = R0 < 2
|
||||
|
||||
is not symmetric - there is no R0 > 2 instruction. On the other hand, IF CC
|
||||
JUMP can take both CC and !CC as a condition. We cannot pattern-match (brcond
|
||||
(not cc), target), the DAG optimizer removes that kind of thing.
|
||||
|
||||
This is handled by creating a pseudo-register NCC that aliases CC. Register
|
||||
classes JustCC and NotCC are used to control the inversion of CC.
|
||||
|
||||
** DONE CC as an i32 register
|
||||
The AnyCC register class pretends to hold i32 values. It can only represent the
|
||||
values 0 and 1, but we can copy to and from the D class. This hack makes it
|
||||
possible to represent the setcc instruction without having i1 as a legal type.
|
||||
|
||||
In most cases, the CC register is set by a "CC = .." or BITTST instruction, and
|
||||
then used in a conditional branch or move. The code generator thinks it is
|
||||
moving 32 bits, but the value stays in CC. In other cases, the result of a
|
||||
comparison is actually used as am i32 number, and CC will be copied to a D
|
||||
register.
|
||||
|
||||
* Stack frames
|
||||
** TODO Use Push/Pop instructions
|
||||
We should use the push/pop instructions when saving callee-saved
|
||||
registers. The are smaller, and we may even use push multiple instructions.
|
||||
|
||||
** TODO requiresRegisterScavenging
|
||||
We need more intelligence in determining when the scavenger is needed. We
|
||||
should keep track of:
|
||||
- Spilling D16 registers
|
||||
- Spilling AnyCC registers
|
||||
|
||||
* Assembler
|
||||
** TODO Implement PrintGlobalVariable
|
||||
** TODO Remove LOAD32sym
|
||||
It's a hack combining two instructions by concatenation.
|
||||
|
||||
* Inline Assembly
|
||||
|
||||
These are the GCC constraints from bfin/constraints.md:
|
||||
|
||||
| Code | Register class | LLVM |
|
||||
|-------+-------------------------------------------+------|
|
||||
| a | P | C |
|
||||
| d | D | C |
|
||||
| z | Call clobbered P (P0, P1, P2) | X |
|
||||
| D | EvenD | X |
|
||||
| W | OddD | X |
|
||||
| e | Accu | C |
|
||||
| A | A0 | S |
|
||||
| B | A1 | S |
|
||||
| b | I | C |
|
||||
| v | B | C |
|
||||
| f | M | C |
|
||||
| c | Circular I, B, L | X |
|
||||
| C | JustCC | S |
|
||||
| t | LoopTop | X |
|
||||
| u | LoopBottom | X |
|
||||
| k | LoopCount | X |
|
||||
| x | GR | C |
|
||||
| y | RET*, ASTAT, SEQSTAT, USP | X |
|
||||
| w | ALL | C |
|
||||
| Z | The FD-PIC GOT pointer (P3) | S |
|
||||
| Y | The FD-PIC function pointer register (P1) | S |
|
||||
| q0-q7 | R0-R7 individually | |
|
||||
| qA | P0 | |
|
||||
|-------+-------------------------------------------+------|
|
||||
| Code | Constant | |
|
||||
|-------+-------------------------------------------+------|
|
||||
| J | 1<<N, N<32 | |
|
||||
| Ks3 | imm3 | |
|
||||
| Ku3 | uimm3 | |
|
||||
| Ks4 | imm4 | |
|
||||
| Ku4 | uimm4 | |
|
||||
| Ks5 | imm5 | |
|
||||
| Ku5 | uimm5 | |
|
||||
| Ks7 | imm7 | |
|
||||
| KN7 | -imm7 | |
|
||||
| Ksh | imm16 | |
|
||||
| Kuh | uimm16 | |
|
||||
| L | ~(1<<N) | |
|
||||
| M1 | 0xff | |
|
||||
| M2 | 0xffff | |
|
||||
| P0-P4 | 0-4 | |
|
||||
| PA | Macflag, not M | |
|
||||
| PB | Macflag, only M | |
|
||||
| Q | Symbol | |
|
||||
|
||||
** TODO Support all register classes
|
||||
* DAG combiner
|
||||
** Create test case for each Illegal SETCC case
|
||||
The DAG combiner may someimes produce illegal i16 SETCC instructions.
|
||||
|
||||
*** TODO SETCC (ctlz x), 5) == const
|
||||
*** TODO SETCC (and load, const) == const
|
||||
*** DONE SETCC (zext x) == const
|
||||
*** TODO SETCC (sext x) == const
|
||||
|
||||
* Instruction selection
|
||||
** TODO Better imediate constants
|
||||
Like ARM, build constants as small imm + shift.
|
||||
|
||||
** TODO Implement cycle counter
|
||||
We have CYCLES and CYCLES2 registers, but the readcyclecounter intrinsic wants
|
||||
to return i64, and the code generator doesn't know how to legalize that.
|
||||
|
||||
** TODO Instruction alternatives
|
||||
Some instructions come in different variants for example:
|
||||
|
||||
D = D + D
|
||||
P = P + P
|
||||
|
||||
Cross combinations are not allowed:
|
||||
|
||||
P = D + D (bad)
|
||||
|
||||
Similarly for the subreg pseudo-instructions:
|
||||
|
||||
D16L = EXTRACT_SUBREG D16, bfin_subreg_lo16
|
||||
P16L = EXTRACT_SUBREG P16, bfin_subreg_lo16
|
||||
|
||||
We want to take advantage of the alternative instructions. This could be done by
|
||||
changing the DAG after instruction selection.
|
||||
|
||||
|
||||
** Multipatterns for load/store
|
||||
We should try to identify multipatterns for load and store instructions. The
|
||||
available instruction matrix is a bit irregular.
|
||||
|
||||
Loads:
|
||||
|
||||
| Addr | D | P | D 16z | D 16s | D16 | D 8z | D 8s |
|
||||
|------------+---+---+-------+-------+-----+------+------|
|
||||
| P | * | * | * | * | * | * | * |
|
||||
| P++ | * | * | * | * | | * | * |
|
||||
| P-- | * | * | * | * | | * | * |
|
||||
| P+uimm5m2 | | | * | * | | | |
|
||||
| P+uimm6m4 | * | * | | | | | |
|
||||
| P+imm16 | | | | | | * | * |
|
||||
| P+imm17m2 | | | * | * | | | |
|
||||
| P+imm18m4 | * | * | | | | | |
|
||||
| P++P | * | | * | * | * | | |
|
||||
| FP-uimm7m4 | * | * | | | | | |
|
||||
| I | * | | | | * | | |
|
||||
| I++ | * | | | | * | | |
|
||||
| I-- | * | | | | * | | |
|
||||
| I++M | * | | | | | | |
|
||||
|
||||
Stores:
|
||||
|
||||
| Addr | D | P | D16H | D16L | D 8 |
|
||||
|------------+---+---+------+------+-----|
|
||||
| P | * | * | * | * | * |
|
||||
| P++ | * | * | | * | * |
|
||||
| P-- | * | * | | * | * |
|
||||
| P+uimm5m2 | | | | * | |
|
||||
| P+uimm6m4 | * | * | | | |
|
||||
| P+imm16 | | | | | * |
|
||||
| P+imm17m2 | | | | * | |
|
||||
| P+imm18m4 | * | * | | | |
|
||||
| P++P | * | | * | * | |
|
||||
| FP-uimm7m4 | * | * | | | |
|
||||
| I | * | | * | * | |
|
||||
| I++ | * | | * | * | |
|
||||
| I-- | * | | * | * | |
|
||||
| I++M | * | | | | |
|
||||
|
||||
* Workarounds and features
|
||||
Blackfin CPUs have bugs. Each model comes in a number of silicon revisions with
|
||||
different bugs. We learn about the CPU model from the -mcpu switch.
|
||||
|
||||
** Interpretation of -mcpu value
|
||||
- -mcpu=bf527 refers to the latest known BF527 revision
|
||||
- -mcpu=bf527-0.2 refers to silicon rev. 0.2
|
||||
- -mcpu=bf527-any refers to all known revisions
|
||||
- -mcpu=bf527-none disables all workarounds
|
||||
|
||||
The -mcpu setting affects the __SILICON_REVISION__ macro and enabled workarounds:
|
||||
|
||||
| -mcpu | __SILICON_REVISION__ | Workarounds |
|
||||
|------------+----------------------+--------------------|
|
||||
| bf527 | Def Latest | Specific to latest |
|
||||
| bf527-1.3 | Def 0x0103 | Specific to 1.3 |
|
||||
| bf527-any | Def 0xffff | All bf527-x.y |
|
||||
| bf527-none | Undefined | None |
|
||||
|
||||
These are the known cores and revisions:
|
||||
|
||||
| Core | Silicon | Processors |
|
||||
|-------------+--------------------+-------------------------|
|
||||
| Edinburgh | 0.3, 0.4, 0.5, 0.6 | BF531 BF532 BF533 |
|
||||
| Braemar | 0.2, 0.3 | BF534 BF536 BF537 |
|
||||
| Stirling | 0.3, 0.4, 0.5 | BF538 BF539 |
|
||||
| Moab | 0.0, 0.1, 0.2 | BF542 BF544 BF548 BF549 |
|
||||
| Teton | 0.3, 0.5 | BF561 |
|
||||
| Kookaburra | 0.0, 0.1, 0.2 | BF523 BF525 BF527 |
|
||||
| Mockingbird | 0.0, 0.1 | BF522 BF524 BF526 |
|
||||
| Brodie | 0.0, 0.1 | BF512 BF514 BF516 BF518 |
|
||||
|
||||
|
||||
** Compiler implemented workarounds
|
||||
Most workarounds are implemented in header files and source code using the
|
||||
__ADSPBF527__ macros. A few workarounds require compiler support.
|
||||
|
||||
| Anomaly | Macro | GCC Switch |
|
||||
|----------+--------------------------------+------------------|
|
||||
| Any | __WORKAROUNDS_ENABLED | |
|
||||
| 05000074 | WA_05000074 | |
|
||||
| 05000244 | __WORKAROUND_SPECULATIVE_SYNCS | -mcsync-anomaly |
|
||||
| 05000245 | __WORKAROUND_SPECULATIVE_LOADS | -mspecld-anomaly |
|
||||
| 05000257 | WA_05000257 | |
|
||||
| 05000283 | WA_05000283 | |
|
||||
| 05000312 | WA_LOAD_LCREGS | |
|
||||
| 05000315 | WA_05000315 | |
|
||||
| 05000371 | __WORKAROUND_RETS | |
|
||||
| 05000426 | __WORKAROUND_INDIRECT_CALLS | Not -micplb |
|
||||
|
||||
** GCC feature switches
|
||||
| Switch | Description |
|
||||
|---------------------------+----------------------------------------|
|
||||
| -msim | Use simulator runtime |
|
||||
| -momit-leaf-frame-pointer | Omit frame pointer for leaf functions |
|
||||
| -mlow64k | |
|
||||
| -mcsync-anomaly | |
|
||||
| -mspecld-anomaly | |
|
||||
| -mid-shared-library | |
|
||||
| -mleaf-id-shared-library | |
|
||||
| -mshared-library-id= | |
|
||||
| -msep-data | Enable separate data segment |
|
||||
| -mlong-calls | Use indirect calls |
|
||||
| -mfast-fp | |
|
||||
| -mfdpic | |
|
||||
| -minline-plt | |
|
||||
| -mstack-check-l1 | Do stack checking in L1 scratch memory |
|
||||
| -mmulticore | Enable multicore support |
|
||||
| -mcorea | Build for Core A |
|
||||
| -mcoreb | Build for Core B |
|
||||
| -msdram | Build for SDRAM |
|
||||
| -micplb | Assume ICPLBs are enabled at runtime. |
|
|
@ -1,21 +0,0 @@
|
|||
//===-- BlackfinTargetInfo.cpp - Blackfin Target Implementation -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Blackfin.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
Target llvm::TheBlackfinTarget;
|
||||
|
||||
extern "C" void LLVMInitializeBlackfinTargetInfo() {
|
||||
RegisterTarget<Triple::bfin> X(TheBlackfinTarget, "bfin",
|
||||
"Analog Devices Blackfin [experimental]");
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
|
||||
|
||||
add_llvm_library(LLVMBlackfinInfo
|
||||
BlackfinTargetInfo.cpp
|
||||
)
|
||||
|
||||
add_llvm_library_dependencies(LLVMBlackfinInfo
|
||||
LLVMMC
|
||||
LLVMSupport
|
||||
LLVMTarget
|
||||
)
|
||||
|
||||
add_dependencies(LLVMBlackfinInfo BlackfinCommonTableGen)
|
|
@ -1,15 +0,0 @@
|
|||
##===- lib/Target/Blackfin/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 = LLVMBlackfinInfo
|
||||
|
||||
# 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
|
|
@ -301,7 +301,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
|
|||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
|
@ -437,7 +436,6 @@ else
|
|||
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
|
||||
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
PTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
|
||||
|
@ -550,13 +548,13 @@ TARGETS_TO_BUILD=""
|
|||
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
|
||||
[Build specific host targets: all or target1,target2,... Valid targets are:
|
||||
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp (default=all)]),,
|
||||
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 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha 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" ;;
|
||||
|
@ -569,7 +567,6 @@ case "$enableval" in
|
|||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -586,7 +583,6 @@ case "$enableval" in
|
|||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) AC_MSG_ERROR([Can not set target to build]) ;;
|
||||
esac ;;
|
||||
|
|
|
@ -1402,7 +1402,7 @@ Optional Features:
|
|||
--enable-targets Build specific host targets: all or
|
||||
target1,target2,... Valid targets are: host, x86,
|
||||
x86_64, sparc, powerpc, alpha, arm, mips, spu,
|
||||
xcore, msp430, blackfin, ptx, cbe, and cpp
|
||||
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)
|
||||
|
@ -3845,7 +3845,6 @@ else
|
|||
mips-*) llvm_cv_target_arch="Mips" ;;
|
||||
xcore-*) llvm_cv_target_arch="XCore" ;;
|
||||
msp430-*) llvm_cv_target_arch="MSP430" ;;
|
||||
bfin-*) llvm_cv_target_arch="Blackfin" ;;
|
||||
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
|
||||
ptx-*) llvm_cv_target_arch="PTX" ;;
|
||||
*) llvm_cv_target_arch="Unknown" ;;
|
||||
|
@ -5048,8 +5047,6 @@ else
|
|||
XCore) TARGET_HAS_JIT=0
|
||||
;;
|
||||
MSP430) TARGET_HAS_JIT=0
|
||||
;;
|
||||
Blackfin) TARGET_HAS_JIT=0
|
||||
;;
|
||||
MBlaze) TARGET_HAS_JIT=0
|
||||
;;
|
||||
|
@ -5239,7 +5236,7 @@ if test "$enableval" = host-only ; then
|
|||
enableval=host
|
||||
fi
|
||||
case "$enableval" in
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU XCore MSP430 Blackfin CBackend CppBackend MBlaze PTX" ;;
|
||||
all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha 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" ;;
|
||||
|
@ -5252,7 +5249,6 @@ case "$enableval" in
|
|||
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
|
||||
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
|
||||
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
|
||||
|
@ -5269,7 +5265,6 @@ case "$enableval" in
|
|||
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
|
||||
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
|
||||
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
|
||||
Blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
|
||||
PTX) TARGETS_TO_BUILD="PTX $TARGETS_TO_BUILD" ;;
|
||||
*) { { echo "$as_me:$LINENO: error: Can not set target to build" >&5
|
||||
echo "$as_me: error: Can not set target to build" >&2;}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -join-liveintervals=0 -verify-machineinstrs
|
||||
; RUN: llc < %s -march=bfin -join-liveintervals=0 -verify-machineinstrs -regalloc=greedy
|
||||
|
||||
; Provoke an error in LowerSubregsPass::LowerExtract where the live range of a
|
||||
; super-register is illegally extended.
|
||||
|
||||
define i16 @f(i16 %x1, i16 %x2, i16 %x3, i16 %x4) {
|
||||
%y1 = add i16 %x1, 1
|
||||
%y2 = add i16 %x2, 2
|
||||
%y3 = add i16 %x3, 3
|
||||
%y4 = add i16 %x4, 4
|
||||
%z12 = add i16 %y1, %y2
|
||||
%z34 = add i16 %y3, %y4
|
||||
%p = add i16 %z12, %z34
|
||||
ret i16 %p
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
declare i64 @llvm.cttz.i64(i64) nounwind readnone
|
||||
|
||||
declare i16 @llvm.cttz.i16(i16) nounwind readnone
|
||||
|
||||
declare i8 @llvm.cttz.i8(i8) nounwind readnone
|
||||
|
||||
define void @cttztest(i8 %A, i16 %B, i32 %C, i64 %D, i8* %AP, i16* %BP, i32* %CP, i64* %DP) {
|
||||
%a = call i8 @llvm.cttz.i8(i8 %A) ; <i8> [#uses=1]
|
||||
%b = call i16 @llvm.cttz.i16(i16 %B) ; <i16> [#uses=1]
|
||||
%d = call i64 @llvm.cttz.i64(i64 %D) ; <i64> [#uses=1]
|
||||
store i8 %a, i8* %AP
|
||||
store i16 %b, i16* %BP
|
||||
store i64 %d, i64* %DP
|
||||
ret void
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
; When joining live intervals of sub-registers, an MBB live-in list is not
|
||||
; updated properly. The register scavenger asserts on an undefined register.
|
||||
|
||||
define i32 @foo(i8 %bar) {
|
||||
entry:
|
||||
switch i8 %bar, label %bb1203 [
|
||||
i8 117, label %bb1204
|
||||
i8 85, label %bb1204
|
||||
i8 106, label %bb1204
|
||||
]
|
||||
|
||||
bb1203: ; preds = %entry
|
||||
ret i32 1
|
||||
|
||||
bb1204: ; preds = %entry, %entry, %entry
|
||||
ret i32 2
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
; LocalRewriter can forget to transfer a <def,dead> flag when setting up call
|
||||
; argument registers. This then causes register scavenger asserts.
|
||||
|
||||
declare i32 @printf(i8*, i32, float)
|
||||
|
||||
define i32 @testissue(i32 %i, float %x, float %y) {
|
||||
br label %bb1
|
||||
|
||||
bb1: ; preds = %bb1, %0
|
||||
%x2 = fmul float %x, 5.000000e-01 ; <float> [#uses=1]
|
||||
%y2 = fmul float %y, 0x3FECCCCCC0000000 ; <float> [#uses=1]
|
||||
%z2 = fadd float %x2, %y2 ; <float> [#uses=1]
|
||||
%z3 = fadd float undef, %z2 ; <float> [#uses=1]
|
||||
%i1 = shl i32 %i, 3 ; <i32> [#uses=1]
|
||||
%j1 = add i32 %i, 7 ; <i32> [#uses=1]
|
||||
%m1 = add i32 %i1, %j1 ; <i32> [#uses=2]
|
||||
%b = icmp sle i32 %m1, 6 ; <i1> [#uses=1]
|
||||
br i1 %b, label %bb1, label %bb2
|
||||
|
||||
bb2: ; preds = %bb1
|
||||
%1 = call i32 @printf(i8* undef, i32 %m1, float %z3); <i32> [#uses=0]
|
||||
ret i32 0
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
; An undef argument causes a setugt node to escape instruction selection.
|
||||
|
||||
define void @bugt() {
|
||||
cond_next305:
|
||||
%tmp306307 = trunc i32 undef to i8 ; <i8> [#uses=1]
|
||||
%tmp308 = icmp ugt i8 %tmp306307, 6 ; <i1> [#uses=1]
|
||||
br i1 %tmp308, label %bb311, label %bb314
|
||||
|
||||
bb311: ; preds = %cond_next305
|
||||
unreachable
|
||||
|
||||
bb314: ; preds = %cond_next305
|
||||
ret void
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
%0 = type { i24, i1 } ; type %0
|
||||
|
||||
define i1 @func2(i24 zeroext %v1, i24 zeroext %v2) nounwind {
|
||||
entry:
|
||||
%t = call %0 @llvm.uadd.with.overflow.i24(i24 %v1, i24 %v2) ; <%0> [#uses=1]
|
||||
%obit = extractvalue %0 %t, 1 ; <i1> [#uses=1]
|
||||
br i1 %obit, label %carry, label %normal
|
||||
|
||||
normal: ; preds = %entry
|
||||
ret i1 true
|
||||
|
||||
carry: ; preds = %entry
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
declare %0 @llvm.uadd.with.overflow.i24(i24, i24) nounwind
|
|
@ -1,5 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
define i32 @add(i32 %A, i32 %B) {
|
||||
%R = add i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
; These functions have just the right size to annoy the register scavenger: They
|
||||
; use all the scratch registers, but not all the callee-saved registers.
|
||||
|
||||
define void @test_add(i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) {
|
||||
entry:
|
||||
%tmp1 = zext i64 %AL to i128 ; <i128> [#uses=1]
|
||||
%tmp23 = zext i64 %AH to i128 ; <i128> [#uses=1]
|
||||
%tmp4 = shl i128 %tmp23, 64 ; <i128> [#uses=1]
|
||||
%tmp5 = or i128 %tmp4, %tmp1 ; <i128> [#uses=1]
|
||||
%tmp67 = zext i64 %BL to i128 ; <i128> [#uses=1]
|
||||
%tmp89 = zext i64 %BH to i128 ; <i128> [#uses=1]
|
||||
%tmp11 = shl i128 %tmp89, 64 ; <i128> [#uses=1]
|
||||
%tmp12 = or i128 %tmp11, %tmp67 ; <i128> [#uses=1]
|
||||
%tmp15 = add i128 %tmp12, %tmp5 ; <i128> [#uses=2]
|
||||
%tmp1617 = trunc i128 %tmp15 to i64 ; <i64> [#uses=1]
|
||||
store i64 %tmp1617, i64* %RL
|
||||
%tmp21 = lshr i128 %tmp15, 64 ; <i128> [#uses=1]
|
||||
%tmp2122 = trunc i128 %tmp21 to i64 ; <i64> [#uses=1]
|
||||
store i64 %tmp2122, i64* %RH
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @test_sub(i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) {
|
||||
entry:
|
||||
%tmp1 = zext i64 %AL to i128 ; <i128> [#uses=1]
|
||||
%tmp23 = zext i64 %AH to i128 ; <i128> [#uses=1]
|
||||
%tmp4 = shl i128 %tmp23, 64 ; <i128> [#uses=1]
|
||||
%tmp5 = or i128 %tmp4, %tmp1 ; <i128> [#uses=1]
|
||||
%tmp67 = zext i64 %BL to i128 ; <i128> [#uses=1]
|
||||
%tmp89 = zext i64 %BH to i128 ; <i128> [#uses=1]
|
||||
%tmp11 = shl i128 %tmp89, 64 ; <i128> [#uses=1]
|
||||
%tmp12 = or i128 %tmp11, %tmp67 ; <i128> [#uses=1]
|
||||
%tmp15 = sub i128 %tmp5, %tmp12 ; <i128> [#uses=2]
|
||||
%tmp1617 = trunc i128 %tmp15 to i64 ; <i64> [#uses=1]
|
||||
store i64 %tmp1617, i64* %RL
|
||||
%tmp21 = lshr i128 %tmp15, 64 ; <i128> [#uses=1]
|
||||
%tmp2122 = trunc i128 %tmp21 to i64 ; <i64> [#uses=1]
|
||||
store i64 %tmp2122, i64* %RH
|
||||
ret void
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin > %t
|
||||
|
||||
define i1 @add(i1 %A, i1 %B) {
|
||||
%R = add i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @sub(i1 %A, i1 %B) {
|
||||
%R = sub i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @mul(i1 %A, i1 %B) {
|
||||
%R = mul i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @sdiv(i1 %A, i1 %B) {
|
||||
%R = sdiv i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @udiv(i1 %A, i1 %B) {
|
||||
%R = udiv i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @srem(i1 %A, i1 %B) {
|
||||
%R = srem i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @urem(i1 %A, i1 %B) {
|
||||
%R = urem i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @and(i1 %A, i1 %B) {
|
||||
%R = and i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @or(i1 %A, i1 %B) {
|
||||
%R = or i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
||||
|
||||
define i1 @xor(i1 %A, i1 %B) {
|
||||
%R = xor i1 %A, %B ; <i1> [#uses=1]
|
||||
ret i1 %R
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
define i16 @add(i16 %A, i16 %B) {
|
||||
%R = add i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @sub(i16 %A, i16 %B) {
|
||||
%R = sub i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @mul(i16 %A, i16 %B) {
|
||||
%R = mul i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @sdiv(i16 %A, i16 %B) {
|
||||
%R = sdiv i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @udiv(i16 %A, i16 %B) {
|
||||
%R = udiv i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @srem(i16 %A, i16 %B) {
|
||||
%R = srem i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @urem(i16 %A, i16 %B) {
|
||||
%R = urem i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
define i32 @add(i32 %A, i32 %B) {
|
||||
%R = add i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @sub(i32 %A, i32 %B) {
|
||||
%R = sub i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @mul(i32 %A, i32 %B) {
|
||||
%R = mul i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @sdiv(i32 %A, i32 %B) {
|
||||
%R = sdiv i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @udiv(i32 %A, i32 %B) {
|
||||
%R = udiv i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @srem(i32 %A, i32 %B) {
|
||||
%R = srem i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @urem(i32 %A, i32 %B) {
|
||||
%R = urem i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @and(i32 %A, i32 %B) {
|
||||
%R = and i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @or(i32 %A, i32 %B) {
|
||||
%R = or i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
define i32 @xor(i32 %A, i32 %B) {
|
||||
%R = xor i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
define i64 @add(i64 %A, i64 %B) {
|
||||
%R = add i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @sub(i64 %A, i64 %B) {
|
||||
%R = sub i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @mul(i64 %A, i64 %B) {
|
||||
%R = mul i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @sdiv(i64 %A, i64 %B) {
|
||||
%R = sdiv i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @udiv(i64 %A, i64 %B) {
|
||||
%R = udiv i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @srem(i64 %A, i64 %B) {
|
||||
%R = srem i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @urem(i64 %A, i64 %B) {
|
||||
%R = urem i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @and(i64 %A, i64 %B) {
|
||||
%R = and i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @or(i64 %A, i64 %B) {
|
||||
%R = or i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
||||
|
||||
define i64 @xor(i64 %A, i64 %B) {
|
||||
%R = xor i64 %A, %B ; <i64> [#uses=1]
|
||||
ret i64 %R
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
define i8 @add(i8 %A, i8 %B) {
|
||||
%R = add i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @sub(i8 %A, i8 %B) {
|
||||
%R = sub i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @mul(i8 %A, i8 %B) {
|
||||
%R = mul i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @sdiv(i8 %A, i8 %B) {
|
||||
%R = sdiv i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @udiv(i8 %A, i8 %B) {
|
||||
%R = udiv i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @srem(i8 %A, i8 %B) {
|
||||
%R = srem i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @urem(i8 %A, i8 %B) {
|
||||
%R = urem i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @and(i8 %A, i8 %B) {
|
||||
%R = and i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @or(i8 %A, i8 %B) {
|
||||
%R = or i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
||||
|
||||
define i8 @xor(i8 %A, i8 %B) {
|
||||
%R = xor i8 %A, %B ; <i8> [#uses=1]
|
||||
ret i8 %R
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
define void @void(i32, i32) {
|
||||
add i32 0, 0 ; <i32>:3 [#uses=2]
|
||||
sub i32 0, 4 ; <i32>:4 [#uses=2]
|
||||
br label %5
|
||||
|
||||
; <label>:5 ; preds = %5, %2
|
||||
add i32 %0, %1 ; <i32>:6 [#uses=2]
|
||||
sub i32 %6, %4 ; <i32>:7 [#uses=1]
|
||||
icmp sle i32 %7, %3 ; <i1>:8 [#uses=1]
|
||||
br i1 %8, label %9, label %5
|
||||
|
||||
; <label>:9 ; preds = %5
|
||||
add i32 %0, %1 ; <i32>:10 [#uses=0]
|
||||
sub i32 %6, %4 ; <i32>:11 [#uses=1]
|
||||
icmp sle i32 %11, %3 ; <i1>:12 [#uses=0]
|
||||
ret void
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin > %t
|
||||
|
||||
define i1 @cmp3(i32 %A) {
|
||||
%R = icmp uge i32 %A, 2
|
||||
ret i1 %R
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
; This test tries to use a JustCC register as a data operand for MOVEcc. It
|
||||
; copies (JustCC -> DP), failing because JustCC can only be copied to D.
|
||||
; The proper solution would be to restrict the virtual register to D only.
|
||||
|
||||
define i32 @main() {
|
||||
entry:
|
||||
br label %loopentry
|
||||
|
||||
loopentry:
|
||||
%done = icmp sle i64 undef, 5
|
||||
br i1 %done, label %loopentry, label %exit.1
|
||||
|
||||
exit.1:
|
||||
ret i32 0
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i32 @llvm.ctlz.i32(i32)
|
||||
declare i32 @llvm.cttz.i32(i32)
|
||||
declare i32 @llvm.ctpop.i32(i32)
|
||||
|
||||
define i32 @ctlztest(i32 %B) {
|
||||
%b = call i32 @llvm.ctlz.i32( i32 %B )
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define i32 @cttztest(i32 %B) {
|
||||
%b = call i32 @llvm.cttz.i32( i32 %B )
|
||||
ret i32 %b
|
||||
}
|
||||
|
||||
define i32 @ctpoptest(i32 %B) {
|
||||
%b = call i32 @llvm.ctpop.i32( i32 %B )
|
||||
ret i32 %b
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i64 @llvm.ctlz.i64(i64)
|
||||
declare i64 @llvm.cttz.i64(i64)
|
||||
declare i64 @llvm.ctpop.i64(i64)
|
||||
|
||||
define i64 @ctlztest(i64 %B) {
|
||||
%b = call i64 @llvm.ctlz.i64( i64 %B )
|
||||
ret i64 %b
|
||||
}
|
||||
|
||||
define i64 @cttztest(i64 %B) {
|
||||
%b = call i64 @llvm.cttz.i64( i64 %B )
|
||||
ret i64 %b
|
||||
}
|
||||
|
||||
define i64 @ctpoptest(i64 %B) {
|
||||
%b = call i64 @llvm.ctpop.i64( i64 %B )
|
||||
ret i64 %b
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i16 @llvm.ctlz.i16(i16)
|
||||
|
||||
define i16 @ctlztest(i16 %B) {
|
||||
%b = call i16 @llvm.ctlz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
define i16 @ctlztest_z(i16 zeroext %B) {
|
||||
%b = call i16 @llvm.ctlz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i16 @ctlztest_s(i16 signext %B) {
|
||||
%b = call i16 @llvm.ctlz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
@.str = external constant [14 x i8] ; <[14 x i8]*> [#uses=1]
|
||||
|
||||
define i32 @main(i64 %arg) nounwind {
|
||||
entry:
|
||||
%tmp47 = tail call i64 @llvm.cttz.i64(i64 %arg) ; <i64> [#uses=1]
|
||||
%tmp48 = trunc i64 %tmp47 to i32 ; <i32> [#uses=1]
|
||||
%tmp40 = tail call i32 (i8*, ...)* @printf(i8* noalias getelementptr ([14 x i8]* @.str, i32 0, i32 0), i64 %arg, i32 0, i32 %tmp48, i32 0) nounwind ; <i32> [#uses=0]
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare i32 @printf(i8* noalias, ...) nounwind
|
||||
|
||||
declare i64 @llvm.cttz.i64(i64) nounwind readnone
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i16 @llvm.ctpop.i16(i16)
|
||||
|
||||
define i16 @ctpoptest(i16 %B) {
|
||||
%b = call i16 @llvm.ctpop.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
define i16 @ctpoptest_z(i16 zeroext %B) {
|
||||
%b = call i16 @llvm.ctpop.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i16 @ctpoptest_s(i16 signext %B) {
|
||||
%b = call i16 @llvm.ctpop.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i16 @llvm.cttz.i16(i16)
|
||||
|
||||
define i16 @cttztest(i16 %B) {
|
||||
%b = call i16 @llvm.cttz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
define i16 @cttztest_z(i16 zeroext %B) {
|
||||
%b = call i16 @llvm.cttz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i16 @cttztest_s(i16 signext %B) {
|
||||
%b = call i16 @llvm.cttz.i16( i16 %B ) ; <i16> [#uses=1]
|
||||
ret i16 %b
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin | FileCheck %s
|
||||
|
||||
declare i64 @llvm.readcyclecounter()
|
||||
|
||||
; CHECK: cycles
|
||||
; CHECK: cycles2
|
||||
define i64 @cyc64() {
|
||||
%tmp.1 = call i64 @llvm.readcyclecounter()
|
||||
ret i64 %tmp.1
|
||||
}
|
||||
|
||||
; CHECK: cycles
|
||||
define i32@cyc32() {
|
||||
%tmp.1 = call i64 @llvm.readcyclecounter()
|
||||
%s = trunc i64 %tmp.1 to i32
|
||||
ret i32 %s
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
load_lib llvm.exp
|
||||
|
||||
if { [llvm_supports_target Blackfin] } {
|
||||
RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
||||
|
||||
define i32 @main() {
|
||||
%1 = call i32 (i8*, ...)* @printf(i8* undef, double undef)
|
||||
ret i32 0
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
declare i32 @SIM(i8*, i8*, i32, i32, i32, [256 x i32]*, i32, i32, i32)
|
||||
|
||||
define void @foo() {
|
||||
bb0:
|
||||
%V = alloca [256 x i32], i32 256 ; <[256 x i32]*> [#uses=1]
|
||||
%0 = call i32 @SIM(i8* null, i8* null, i32 0, i32 0, i32 0, [256 x i32]* %V, i32 0, i32 0, i32 2) ; <i32> [#uses=0]
|
||||
ret void
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i17_l = external global i17 ; <i17*> [#uses=1]
|
||||
@i17_s = external global i17 ; <i17*> [#uses=1]
|
||||
|
||||
define void @i17_ls() nounwind {
|
||||
%tmp = load i17* @i17_l ; <i17> [#uses=1]
|
||||
store i17 %tmp, i17* @i17_s
|
||||
ret void
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i1_l = external global i1 ; <i1*> [#uses=1]
|
||||
@i1_s = external global i1 ; <i1*> [#uses=1]
|
||||
|
||||
define void @i1_ls() nounwind {
|
||||
%tmp = load i1* @i1_l ; <i1> [#uses=1]
|
||||
store i1 %tmp, i1* @i1_s
|
||||
ret void
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
define i32 @adj(i32 %d.1, i32 %ct.1) {
|
||||
entry:
|
||||
%tmp.22.not = trunc i32 %ct.1 to i1 ; <i1> [#uses=1]
|
||||
%tmp.221 = xor i1 %tmp.22.not, true ; <i1> [#uses=1]
|
||||
%tmp.26 = or i1 false, %tmp.221 ; <i1> [#uses=1]
|
||||
%tmp.27 = zext i1 %tmp.26 to i32 ; <i32> [#uses=1]
|
||||
ret i32 %tmp.27
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i216_l = external global i216 ; <i216*> [#uses=1]
|
||||
@i216_s = external global i216 ; <i216*> [#uses=1]
|
||||
|
||||
define void @i216_ls() nounwind {
|
||||
%tmp = load i216* @i216_l ; <i216> [#uses=1]
|
||||
store i216 %tmp, i216* @i216_s
|
||||
ret void
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
@i248_l = external global i248 ; <i248*> [#uses=1]
|
||||
@i248_s = external global i248 ; <i248*> [#uses=1]
|
||||
|
||||
define void @i248_ls() nounwind {
|
||||
%tmp = load i248* @i248_l ; <i248> [#uses=1]
|
||||
store i248 %tmp, i248* @i248_s
|
||||
ret void
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i17_l = external global i17 ; <i17*> [#uses=1]
|
||||
@i17_s = external global i17 ; <i17*> [#uses=1]
|
||||
|
||||
define void @i17_ls() nounwind {
|
||||
%tmp = load i17* @i17_l ; <i17> [#uses=1]
|
||||
store i17 %tmp, i17* @i17_s
|
||||
ret void
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i256_s = external global i256 ; <i256*> [#uses=1]
|
||||
|
||||
define void @i256_ls(i256 %x) nounwind {
|
||||
store i256 %x, i256* @i256_s
|
||||
ret void
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@i56_l = external global i56 ; <i56*> [#uses=1]
|
||||
@i56_s = external global i56 ; <i56*> [#uses=1]
|
||||
|
||||
define void @i56_ls(i56 %x) nounwind {
|
||||
store i56 %x, i56* @i56_s
|
||||
ret void
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
@i8_l = external global i8 ; <i8*> [#uses=1]
|
||||
@i8_s = external global i8 ; <i8*> [#uses=1]
|
||||
|
||||
define void @i8_ls() nounwind {
|
||||
%tmp = load i8* @i8_l ; <i8> [#uses=1]
|
||||
store i8 %tmp, i8* @i8_s
|
||||
ret void
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin | FileCheck %s
|
||||
|
||||
; Standard "r"
|
||||
; CHECK: r0 = r0 + r1;
|
||||
define i32 @add_r(i32 %A, i32 %B) {
|
||||
%R = call i32 asm "$0 = $1 + $2;", "=r,r,r"( i32 %A, i32 %B ) nounwind
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
; Target "d"
|
||||
; CHECK: r0 = r0 - r1;
|
||||
define i32 @add_d(i32 %A, i32 %B) {
|
||||
%R = call i32 asm "$0 = $1 - $2;", "=d,d,d"( i32 %A, i32 %B ) nounwind
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
; Target "a" for P-regs
|
||||
; CHECK: p0 = (p0 + p1) << 1;
|
||||
define i32 @add_a(i32 %A, i32 %B) {
|
||||
%R = call i32 asm "$0 = ($1 + $2) << 1;", "=a,a,a"( i32 %A, i32 %B ) nounwind
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
; Target "z" for P0, P1, P2. This is not a real regclass
|
||||
; CHECK: p0 = (p0 + p1) << 2;
|
||||
define i32 @add_Z(i32 %A, i32 %B) {
|
||||
%R = call i32 asm "$0 = ($1 + $2) << 2;", "=z,z,z"( i32 %A, i32 %B ) nounwind
|
||||
ret i32 %R
|
||||
}
|
||||
|
||||
; Target "C" for CC. This is a single register
|
||||
; CHECK: cc = p0 < p1;
|
||||
; CHECK: r0 = cc;
|
||||
define i32 @add_C(i32 %A, i32 %B) {
|
||||
%R = call i32 asm "$0 = $1 < $2;", "=C,z,z"( i32 %A, i32 %B ) nounwind
|
||||
ret i32 %R
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
define fastcc void @Evaluate() {
|
||||
entry:
|
||||
br i1 false, label %cond_false186, label %cond_true
|
||||
|
||||
cond_true: ; preds = %entry
|
||||
ret void
|
||||
|
||||
cond_false186: ; preds = %entry
|
||||
br i1 false, label %cond_true293, label %bb203
|
||||
|
||||
bb203: ; preds = %cond_false186
|
||||
ret void
|
||||
|
||||
cond_true293: ; preds = %cond_false186
|
||||
br i1 false, label %cond_true298, label %cond_next317
|
||||
|
||||
cond_true298: ; preds = %cond_true293
|
||||
br i1 false, label %cond_next518, label %cond_true397.preheader
|
||||
|
||||
cond_next317: ; preds = %cond_true293
|
||||
ret void
|
||||
|
||||
cond_true397.preheader: ; preds = %cond_true298
|
||||
ret void
|
||||
|
||||
cond_next518: ; preds = %cond_true298
|
||||
br i1 false, label %bb1069, label %cond_true522
|
||||
|
||||
cond_true522: ; preds = %cond_next518
|
||||
ret void
|
||||
|
||||
bb1069: ; preds = %cond_next518
|
||||
br i1 false, label %cond_next1131, label %bb1096
|
||||
|
||||
bb1096: ; preds = %bb1069
|
||||
ret void
|
||||
|
||||
cond_next1131: ; preds = %bb1069
|
||||
br i1 false, label %cond_next1207, label %cond_true1150
|
||||
|
||||
cond_true1150: ; preds = %cond_next1131
|
||||
ret void
|
||||
|
||||
cond_next1207: ; preds = %cond_next1131
|
||||
br i1 false, label %cond_next1219, label %cond_true1211
|
||||
|
||||
cond_true1211: ; preds = %cond_next1207
|
||||
ret void
|
||||
|
||||
cond_next1219: ; preds = %cond_next1207
|
||||
br i1 false, label %cond_true1223, label %cond_next1283
|
||||
|
||||
cond_true1223: ; preds = %cond_next1219
|
||||
br i1 false, label %cond_true1254, label %cond_true1264
|
||||
|
||||
cond_true1254: ; preds = %cond_true1223
|
||||
br i1 false, label %bb1567, label %cond_true1369.preheader
|
||||
|
||||
cond_true1264: ; preds = %cond_true1223
|
||||
ret void
|
||||
|
||||
cond_next1283: ; preds = %cond_next1219
|
||||
ret void
|
||||
|
||||
cond_true1369.preheader: ; preds = %cond_true1254
|
||||
ret void
|
||||
|
||||
bb1567: ; preds = %cond_true1254
|
||||
%tmp1605 = load i8* null ; <i8> [#uses=1]
|
||||
%tmp1606 = icmp eq i8 %tmp1605, 0 ; <i1> [#uses=1]
|
||||
br i1 %tmp1606, label %cond_next1637, label %cond_true1607
|
||||
|
||||
cond_true1607: ; preds = %bb1567
|
||||
ret void
|
||||
|
||||
cond_next1637: ; preds = %bb1567
|
||||
ret void
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
; Assertion failed: (width < BitWidth && "Invalid APInt Truncate request"),
|
||||
; function trunc, file APInt.cpp, line 956.
|
||||
|
||||
@str2 = external global [29 x i8]
|
||||
|
||||
define void @printArgsNoRet(i32 %a1, float %a2, i8 %a3, double %a4, i8* %a5, i32 %a6, float %a7, i8 %a8, double %a9, i8* %a10, i32 %a11, float %a12, i8 %a13, double %a14, i8* %a15) {
|
||||
entry:
|
||||
%tmp17 = sext i8 %a13 to i32
|
||||
%tmp23 = call i32 (i8*, ...)* @printf(i8* getelementptr ([29 x i8]* @str2, i32 0, i64 0), i32 %a11, double 0.000000e+00, i32 %tmp17, double %a14, i32 0)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
|
@ -1,53 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs | FileCheck %s
|
||||
|
||||
; CHECK: .section .rodata
|
||||
; CHECK: JTI0_0:
|
||||
; CHECK: .long .BB0_1
|
||||
|
||||
define i32 @oper(i32 %op, i32 %A, i32 %B) {
|
||||
entry:
|
||||
switch i32 %op, label %bbx [
|
||||
i32 1 , label %bb1
|
||||
i32 2 , label %bb2
|
||||
i32 3 , label %bb3
|
||||
i32 4 , label %bb4
|
||||
i32 5 , label %bb5
|
||||
i32 6 , label %bb6
|
||||
i32 7 , label %bb7
|
||||
i32 8 , label %bb8
|
||||
i32 9 , label %bb9
|
||||
i32 10, label %bb10
|
||||
]
|
||||
bb1:
|
||||
%R1 = add i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R1
|
||||
bb2:
|
||||
%R2 = sub i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R2
|
||||
bb3:
|
||||
%R3 = mul i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R3
|
||||
bb4:
|
||||
%R4 = sdiv i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R4
|
||||
bb5:
|
||||
%R5 = udiv i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R5
|
||||
bb6:
|
||||
%R6 = srem i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R6
|
||||
bb7:
|
||||
%R7 = urem i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R7
|
||||
bb8:
|
||||
%R8 = and i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R8
|
||||
bb9:
|
||||
%R9 = or i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R9
|
||||
bb10:
|
||||
%R10 = xor i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R10
|
||||
bbx:
|
||||
ret i32 0
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
; The switch expansion uses a dynamic shl, and it produces a jumptable
|
||||
|
||||
define void @athlon_fp_unit_ready_cost() {
|
||||
entry:
|
||||
switch i32 0, label %UnifiedReturnBlock [
|
||||
i32 -1, label %bb2063
|
||||
i32 19, label %bb2035
|
||||
i32 20, label %bb2035
|
||||
i32 21, label %bb2035
|
||||
i32 23, label %bb2035
|
||||
i32 24, label %bb2035
|
||||
i32 27, label %bb2035
|
||||
i32 32, label %bb2035
|
||||
i32 33, label %bb1994
|
||||
i32 35, label %bb2035
|
||||
i32 36, label %bb1994
|
||||
i32 90, label %bb1948
|
||||
i32 94, label %bb1948
|
||||
i32 95, label %bb1948
|
||||
i32 133, label %bb1419
|
||||
i32 135, label %bb1238
|
||||
i32 136, label %bb1238
|
||||
i32 137, label %bb1238
|
||||
i32 138, label %bb1238
|
||||
i32 139, label %bb1201
|
||||
i32 140, label %bb1201
|
||||
i32 141, label %bb1154
|
||||
i32 142, label %bb1126
|
||||
i32 144, label %bb1201
|
||||
i32 145, label %bb1126
|
||||
i32 146, label %bb1201
|
||||
i32 147, label %bb1126
|
||||
i32 148, label %bb1201
|
||||
i32 149, label %bb1126
|
||||
i32 150, label %bb1201
|
||||
i32 151, label %bb1126
|
||||
i32 152, label %bb1096
|
||||
i32 153, label %bb1096
|
||||
i32 154, label %bb1096
|
||||
i32 157, label %bb1096
|
||||
i32 158, label %bb1096
|
||||
i32 159, label %bb1096
|
||||
i32 162, label %bb1096
|
||||
i32 163, label %bb1096
|
||||
i32 164, label %bb1096
|
||||
i32 167, label %bb1201
|
||||
i32 168, label %bb1201
|
||||
i32 170, label %bb1201
|
||||
i32 171, label %bb1201
|
||||
i32 173, label %bb1201
|
||||
i32 174, label %bb1201
|
||||
i32 176, label %bb1201
|
||||
i32 177, label %bb1201
|
||||
i32 179, label %bb993
|
||||
i32 180, label %bb993
|
||||
i32 181, label %bb993
|
||||
i32 182, label %bb993
|
||||
i32 183, label %bb993
|
||||
i32 184, label %bb993
|
||||
i32 365, label %bb1126
|
||||
i32 366, label %bb1126
|
||||
i32 367, label %bb1126
|
||||
i32 368, label %bb1126
|
||||
i32 369, label %bb1126
|
||||
i32 370, label %bb1126
|
||||
i32 371, label %bb1126
|
||||
i32 372, label %bb1126
|
||||
i32 373, label %bb1126
|
||||
i32 384, label %bb1126
|
||||
i32 385, label %bb1126
|
||||
i32 386, label %bb1126
|
||||
i32 387, label %bb1126
|
||||
i32 388, label %bb1126
|
||||
i32 389, label %bb1126
|
||||
i32 390, label %bb1126
|
||||
i32 391, label %bb1126
|
||||
i32 392, label %bb1126
|
||||
i32 525, label %bb919
|
||||
i32 526, label %bb839
|
||||
i32 528, label %bb919
|
||||
i32 529, label %bb839
|
||||
i32 532, label %cond_next6.i97
|
||||
i32 533, label %cond_next6.i81
|
||||
i32 534, label %bb495
|
||||
i32 536, label %cond_next6.i81
|
||||
i32 537, label %cond_next6.i81
|
||||
i32 538, label %bb396
|
||||
i32 539, label %bb288
|
||||
i32 541, label %bb396
|
||||
i32 542, label %bb396
|
||||
i32 543, label %bb396
|
||||
i32 544, label %bb396
|
||||
i32 545, label %bb189
|
||||
i32 546, label %cond_next6.i
|
||||
i32 547, label %bb189
|
||||
i32 548, label %cond_next6.i
|
||||
i32 549, label %bb189
|
||||
i32 550, label %cond_next6.i
|
||||
i32 551, label %bb189
|
||||
i32 552, label %cond_next6.i
|
||||
i32 553, label %bb189
|
||||
i32 554, label %cond_next6.i
|
||||
i32 555, label %bb189
|
||||
i32 556, label %cond_next6.i
|
||||
i32 557, label %bb189
|
||||
i32 558, label %cond_next6.i
|
||||
i32 618, label %bb40
|
||||
i32 619, label %bb18
|
||||
i32 620, label %bb40
|
||||
i32 621, label %bb10
|
||||
i32 622, label %bb10
|
||||
]
|
||||
|
||||
bb10:
|
||||
ret void
|
||||
|
||||
bb18:
|
||||
ret void
|
||||
|
||||
bb40:
|
||||
ret void
|
||||
|
||||
cond_next6.i:
|
||||
ret void
|
||||
|
||||
bb189:
|
||||
ret void
|
||||
|
||||
bb288:
|
||||
ret void
|
||||
|
||||
bb396:
|
||||
ret void
|
||||
|
||||
bb495:
|
||||
ret void
|
||||
|
||||
cond_next6.i81:
|
||||
ret void
|
||||
|
||||
cond_next6.i97:
|
||||
ret void
|
||||
|
||||
bb839:
|
||||
ret void
|
||||
|
||||
bb919:
|
||||
ret void
|
||||
|
||||
bb993:
|
||||
ret void
|
||||
|
||||
bb1096:
|
||||
ret void
|
||||
|
||||
bb1126:
|
||||
ret void
|
||||
|
||||
bb1154:
|
||||
ret void
|
||||
|
||||
bb1201:
|
||||
ret void
|
||||
|
||||
bb1238:
|
||||
ret void
|
||||
|
||||
bb1419:
|
||||
ret void
|
||||
|
||||
bb1948:
|
||||
ret void
|
||||
|
||||
bb1994:
|
||||
ret void
|
||||
|
||||
bb2035:
|
||||
ret void
|
||||
|
||||
bb2063:
|
||||
ret void
|
||||
|
||||
UnifiedReturnBlock:
|
||||
ret void
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
; This somewhat contrived function heavily exercises register classes
|
||||
; It can trick -join-cross-class-copies into making illegal joins
|
||||
|
||||
define void @f(i16** nocapture %p) nounwind readonly {
|
||||
entry:
|
||||
%tmp1 = load i16** %p ; <i16*> [#uses=1]
|
||||
%tmp2 = load i16* %tmp1 ; <i16> [#uses=1]
|
||||
%ptr = getelementptr i16* %tmp1, i16 %tmp2
|
||||
store i16 %tmp2, i16* %ptr
|
||||
ret void
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
define i16 @and(i16 %A, i16 %B) {
|
||||
%R = and i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @or(i16 %A, i16 %B) {
|
||||
%R = or i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
||||
|
||||
define i16 @xor(i16 %A, i16 %B) {
|
||||
%R = xor i16 %A, %B ; <i16> [#uses=1]
|
||||
ret i16 %R
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
|
||||
%0 = type { i32, float, float, float, float, float, float, float, float, float, float } ; type %0
|
||||
%struct..s_segment_inf = type { float, i32, i16, i16, float, float, i32, float, float }
|
||||
|
||||
define i32 @main(i32 %argc.1, i8** %argv.1) {
|
||||
entry:
|
||||
%tmp.218 = load float* null ; <float> [#uses=1]
|
||||
%tmp.219 = getelementptr %0* null, i64 0, i32 6 ; <float*> [#uses=1]
|
||||
%tmp.220 = load float* %tmp.219 ; <float> [#uses=1]
|
||||
%tmp.221 = getelementptr %0* null, i64 0, i32 7 ; <float*> [#uses=1]
|
||||
%tmp.222 = load float* %tmp.221 ; <float> [#uses=1]
|
||||
%tmp.223 = getelementptr %0* null, i64 0, i32 8 ; <float*> [#uses=1]
|
||||
%tmp.224 = load float* %tmp.223 ; <float> [#uses=1]
|
||||
%tmp.225 = getelementptr %0* null, i64 0, i32 9 ; <float*> [#uses=1]
|
||||
%tmp.226 = load float* %tmp.225 ; <float> [#uses=1]
|
||||
%tmp.227 = getelementptr %0* null, i64 0, i32 10 ; <float*> [#uses=1]
|
||||
%tmp.228 = load float* %tmp.227 ; <float> [#uses=1]
|
||||
call void @place_and_route(i32 0, i32 0, float 0.000000e+00, i32 0, i32 0, i8* null, i32 0, i32 0, i8* null, i8* null, i8* null, i8* null, i32 0, i32 0, i32 0, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, i32 0, i32 0, i32 0, i32 0, i32 0, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, i32 0, i32 0, i16 0, i16 0, i16 0, float 0.000000e+00, float 0.000000e+00, %struct..s_segment_inf* null, i32 0, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float %tmp.218, float %tmp.220, float %tmp.222, float %tmp.224, float %tmp.226, float %tmp.228)
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
declare void @place_and_route(i32, i32, float, i32, i32, i8*, i32, i32, i8*, i8*, i8*, i8*, i32, i32, i32, float, float, float, float, float, float, float, float, float, i32, i32, i32, i32, i32, float, float, float, i32, i32, i16, i16, i16, float, float, %struct..s_segment_inf*, i32, float, float, float, float, float, float, float, float, float, float)
|
|
@ -1,106 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
%struct.CUMULATIVE_ARGS = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 }
|
||||
%struct.VEC_edge = type { i32, i32, [1 x %struct.edge_def*] }
|
||||
%struct._obstack_chunk = type { i8*, %struct._obstack_chunk*, [4 x i8] }
|
||||
%struct.basic_block_def = type { %struct.rtx_def*, %struct.rtx_def*, %struct.tree_node*, %struct.VEC_edge*, %struct.VEC_edge*, %struct.bitmap_head_def*, %struct.bitmap_head_def*, i8*, %struct.loop*, [2 x %struct.et_node*], %struct.basic_block_def*, %struct.basic_block_def*, %struct.reorder_block_def*, %struct.bb_ann_d*, i64, i32, i32, i32, i32 }
|
||||
%struct.bb_ann_d = type { %struct.tree_node*, i8, %struct.edge_prediction* }
|
||||
%struct.bitmap_element_def = type { %struct.bitmap_element_def*, %struct.bitmap_element_def*, i32, [4 x i32] }
|
||||
%struct.bitmap_head_def = type { %struct.bitmap_element_def*, %struct.bitmap_element_def*, i32, %struct.bitmap_obstack* }
|
||||
%struct.bitmap_obstack = type { %struct.bitmap_element_def*, %struct.bitmap_head_def*, %struct.obstack }
|
||||
%struct.cost_pair = type { %struct.iv_cand*, i32, %struct.bitmap_head_def* }
|
||||
%struct.dataflow_d = type { %struct.varray_head_tag*, [2 x %struct.tree_node*] }
|
||||
%struct.def_operand_ptr = type { %struct.tree_node** }
|
||||
%struct.def_optype_d = type { i32, [1 x %struct.def_operand_ptr] }
|
||||
%struct.edge_def = type { %struct.basic_block_def*, %struct.basic_block_def*, %struct.edge_def_insns, i8*, %struct.location_t*, i32, i32, i64, i32 }
|
||||
%struct.edge_def_insns = type { %struct.rtx_def* }
|
||||
%struct.edge_prediction = type { %struct.edge_prediction*, %struct.edge_def*, i32, i32 }
|
||||
%struct.eh_status = type opaque
|
||||
%struct.emit_status = type { i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack*, i32, %struct.location_t, i32, i8*, %struct.rtx_def** }
|
||||
%struct.et_node = type opaque
|
||||
%struct.expr_status = type { i32, i32, i32, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def* }
|
||||
%struct.function = type { %struct.eh_status*, %struct.expr_status*, %struct.emit_status*, %struct.varasm_status*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.function*, i32, i32, i32, i32, %struct.rtx_def*, %struct.CUMULATIVE_ARGS, %struct.rtx_def*, %struct.rtx_def*, %struct.initial_value_struct*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, i8, i32, i64, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, %struct.varray_head_tag*, %struct.temp_slot*, i32, %struct.var_refs_queue*, i32, i32, %struct.rtvec_def*, %struct.tree_node*, i32, i32, i32, %struct.machine_function*, i32, i32, i1, i1, %struct.language_function*, %struct.rtx_def*, i32, i32, i32, i32, %struct.location_t, %struct.varray_head_tag*, %struct.tree_node*, i8, i8, i8 }
|
||||
%struct.htab = type { i32 (i8*)*, i32 (i8*, i8*)*, void (i8*)*, i8**, i32, i32, i32, i32, i32, i8* (i32, i32)*, void (i8*)*, i8*, i8* (i8*, i32, i32)*, void (i8*, i8*)*, i32 }
|
||||
%struct.initial_value_struct = type opaque
|
||||
%struct.iv = type { %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, i1, i1, i32 }
|
||||
%struct.iv_cand = type { i32, i1, i32, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.iv*, i32 }
|
||||
%struct.iv_use = type { i32, i32, %struct.iv*, %struct.tree_node*, %struct.tree_node**, %struct.bitmap_head_def*, i32, %struct.cost_pair*, %struct.iv_cand* }
|
||||
%struct.ivopts_data = type { %struct.loop*, %struct.htab*, i32, %struct.version_info*, %struct.bitmap_head_def*, i32, %struct.varray_head_tag*, %struct.varray_head_tag*, %struct.bitmap_head_def*, i1 }
|
||||
%struct.lang_decl = type opaque
|
||||
%struct.language_function = type opaque
|
||||
%struct.location_t = type { i8*, i32 }
|
||||
%struct.loop = type { i32, %struct.basic_block_def*, %struct.basic_block_def*, %struct.basic_block_def*, %struct.lpt_decision, i32, i32, %struct.edge_def**, i32, %struct.basic_block_def*, %struct.basic_block_def*, i32, %struct.edge_def**, i32, %struct.edge_def**, i32, %struct.simple_bitmap_def*, i32, %struct.loop**, i32, %struct.loop*, %struct.loop*, %struct.loop*, %struct.loop*, i32, i8*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, %struct.rtx_def*, i32, %struct.tree_node*, %struct.tree_node*, %struct.nb_iter_bound*, %struct.edge_def*, i1 }
|
||||
%struct.lpt_decision = type { i32, i32 }
|
||||
%struct.machine_function = type { %struct.stack_local_entry*, i8*, %struct.rtx_def*, i32, i32, i32, i32, i32 }
|
||||
%struct.nb_iter_bound = type { %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.nb_iter_bound* }
|
||||
%struct.obstack = type { i32, %struct._obstack_chunk*, i8*, i8*, i8*, i32, i32, %struct._obstack_chunk* (i8*, i32)*, void (i8*, %struct._obstack_chunk*)*, i8*, i8 }
|
||||
%struct.reorder_block_def = type { %struct.rtx_def*, %struct.rtx_def*, %struct.basic_block_def*, %struct.basic_block_def*, %struct.basic_block_def*, i32, i32, i32 }
|
||||
%struct.rtvec_def = type { i32, [1 x %struct.rtx_def*] }
|
||||
%struct.rtx_def = type { i16, i8, i8, %struct.u }
|
||||
%struct.sequence_stack = type { %struct.rtx_def*, %struct.rtx_def*, %struct.sequence_stack* }
|
||||
%struct.simple_bitmap_def = type { i32, i32, i32, [1 x i64] }
|
||||
%struct.stack_local_entry = type opaque
|
||||
%struct.stmt_ann_d = type { %struct.tree_ann_common_d, i8, %struct.basic_block_def*, %struct.stmt_operands_d, %struct.dataflow_d*, %struct.bitmap_head_def*, i32 }
|
||||
%struct.stmt_operands_d = type { %struct.def_optype_d*, %struct.def_optype_d*, %struct.v_may_def_optype_d*, %struct.vuse_optype_d*, %struct.v_may_def_optype_d* }
|
||||
%struct.temp_slot = type opaque
|
||||
%struct.tree_ann_common_d = type { i32, i8*, %struct.tree_node* }
|
||||
%struct.tree_ann_d = type { %struct.stmt_ann_d }
|
||||
%struct.tree_common = type { %struct.tree_node*, %struct.tree_node*, %struct.tree_ann_d*, i8, i8, i8, i8, i8 }
|
||||
%struct.tree_decl = type { %struct.tree_common, %struct.location_t, i32, %struct.tree_node*, i8, i8, i8, i8, i8, i8, i8, i32, %struct.tree_decl_u1, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.tree_node*, %struct.rtx_def*, i32, %struct.tree_decl_u2, %struct.tree_node*, %struct.tree_node*, i64, %struct.lang_decl* }
|
||||
%struct.tree_decl_u1 = type { i64 }
|
||||
%struct.tree_decl_u2 = type { %struct.function* }
|
||||
%struct.tree_node = type { %struct.tree_decl }
|
||||
%struct.u = type { [1 x i64] }
|
||||
%struct.v_def_use_operand_type_t = type { %struct.tree_node*, %struct.tree_node* }
|
||||
%struct.v_may_def_optype_d = type { i32, [1 x %struct.v_def_use_operand_type_t] }
|
||||
%struct.var_refs_queue = type { %struct.rtx_def*, i32, i32, %struct.var_refs_queue* }
|
||||
%struct.varasm_status = type opaque
|
||||
%struct.varray_head_tag = type { i32, i32, i32, i8*, %struct.u }
|
||||
%struct.version_info = type { %struct.tree_node*, %struct.iv*, i1, i32, i1 }
|
||||
%struct.vuse_optype_d = type { i32, [1 x %struct.tree_node*] }
|
||||
|
||||
define i1 @determine_use_iv_cost(%struct.ivopts_data* %data, %struct.iv_use* %use, %struct.iv_cand* %cand) {
|
||||
entry:
|
||||
switch i32 0, label %bb91 [
|
||||
i32 0, label %bb
|
||||
i32 1, label %bb6
|
||||
i32 3, label %cond_next135
|
||||
]
|
||||
|
||||
bb: ; preds = %entry
|
||||
ret i1 false
|
||||
|
||||
bb6: ; preds = %entry
|
||||
br i1 false, label %bb87, label %cond_next27
|
||||
|
||||
cond_next27: ; preds = %bb6
|
||||
br i1 false, label %cond_true30, label %cond_next55
|
||||
|
||||
cond_true30: ; preds = %cond_next27
|
||||
br i1 false, label %cond_next41, label %cond_true35
|
||||
|
||||
cond_true35: ; preds = %cond_true30
|
||||
ret i1 false
|
||||
|
||||
cond_next41: ; preds = %cond_true30
|
||||
%tmp44 = call i32 @force_var_cost(%struct.ivopts_data* %data, %struct.tree_node* null, %struct.bitmap_head_def** null) ; <i32> [#uses=1]
|
||||
%tmp46 = udiv i32 %tmp44, 5 ; <i32> [#uses=1]
|
||||
call void @set_use_iv_cost(%struct.ivopts_data* %data, %struct.iv_use* %use, %struct.iv_cand* %cand, i32 %tmp46, %struct.bitmap_head_def* null)
|
||||
br label %bb87
|
||||
|
||||
cond_next55: ; preds = %cond_next27
|
||||
ret i1 false
|
||||
|
||||
bb87: ; preds = %cond_next41, %bb6
|
||||
ret i1 false
|
||||
|
||||
bb91: ; preds = %entry
|
||||
ret i1 false
|
||||
|
||||
cond_next135: ; preds = %entry
|
||||
ret i1 false
|
||||
}
|
||||
|
||||
declare void @set_use_iv_cost(%struct.ivopts_data*, %struct.iv_use*, %struct.iv_cand*, i32, %struct.bitmap_head_def*)
|
||||
|
||||
declare i32 @force_var_cost(%struct.ivopts_data*, %struct.tree_node*, %struct.bitmap_head_def**)
|
|
@ -1,10 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
@.str_1 = external constant [42 x i8] ; <[42 x i8]*> [#uses=1]
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
||||
|
||||
define i32 @main(i32 %argc.1, i8** %argv.1) {
|
||||
entry:
|
||||
%tmp.16 = call i32 (i8*, ...)* @printf(i8* getelementptr ([42 x i8]* @.str_1, i64 0, i64 0), i32 0, i32 0, i64 0, i64 0)
|
||||
ret i32 0
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
declare i32 @printf(i8*, ...)
|
||||
|
||||
define i32 @main() {
|
||||
%1 = call i32 (i8*, ...)* @printf(i8* undef, i1 undef)
|
||||
ret i32 0
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin
|
||||
|
||||
; DAGCombiner::SimplifyBinOpWithSameOpcodeHands can produce an illegal i16 OR
|
||||
; operation after LegalizeOps.
|
||||
|
||||
define void @mng_display_bgr565() {
|
||||
entry:
|
||||
br i1 false, label %bb.preheader, label %return
|
||||
|
||||
bb.preheader:
|
||||
br i1 false, label %cond_true48, label %cond_next80
|
||||
|
||||
cond_true48:
|
||||
%tmp = load i8* null
|
||||
%tmp51 = zext i8 %tmp to i16
|
||||
%tmp99 = load i8* null
|
||||
%tmp54 = bitcast i8 %tmp99 to i8
|
||||
%tmp54.upgrd.1 = zext i8 %tmp54 to i32
|
||||
%tmp55 = lshr i32 %tmp54.upgrd.1, 3
|
||||
%tmp55.upgrd.2 = trunc i32 %tmp55 to i16
|
||||
%tmp52 = shl i16 %tmp51, 5
|
||||
%tmp56 = and i16 %tmp55.upgrd.2, 28
|
||||
%tmp57 = or i16 %tmp56, %tmp52
|
||||
%tmp60 = zext i16 %tmp57 to i32
|
||||
%tmp62 = xor i32 0, 65535
|
||||
%tmp63 = mul i32 %tmp60, %tmp62
|
||||
%tmp65 = add i32 0, %tmp63
|
||||
%tmp69 = add i32 0, %tmp65
|
||||
%tmp70 = lshr i32 %tmp69, 16
|
||||
%tmp70.upgrd.3 = trunc i32 %tmp70 to i16
|
||||
%tmp75 = lshr i16 %tmp70.upgrd.3, 8
|
||||
%tmp75.upgrd.4 = trunc i16 %tmp75 to i8
|
||||
%tmp76 = lshr i8 %tmp75.upgrd.4, 5
|
||||
store i8 %tmp76, i8* null
|
||||
ret void
|
||||
|
||||
cond_next80:
|
||||
ret void
|
||||
|
||||
return:
|
||||
ret void
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin > %t
|
||||
|
||||
; The DAG combiner may sometimes create illegal i16 SETCC operations when run
|
||||
; after LegalizeOps. Try to tease out all the optimizations in
|
||||
; TargetLowering::SimplifySetCC.
|
||||
|
||||
@x = external global i16
|
||||
@y = external global i16
|
||||
|
||||
declare i16 @llvm.ctlz.i16(i16)
|
||||
|
||||
; Case (srl (ctlz x), 5) == const
|
||||
; Note: ctlz is promoted, so this test does not catch the DAG combiner
|
||||
define i1 @srl_ctlz_const() {
|
||||
%x = load i16* @x
|
||||
%c = call i16 @llvm.ctlz.i16(i16 %x)
|
||||
%s = lshr i16 %c, 4
|
||||
%r = icmp eq i16 %s, 1
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Case (zext x) == const
|
||||
define i1 @zext_const() {
|
||||
%x = load i16* @x
|
||||
%r = icmp ugt i16 %x, 1
|
||||
ret i1 %r
|
||||
}
|
||||
|
||||
; Case (sext x) == const
|
||||
define i1 @sext_const() {
|
||||
%x = load i16* @x
|
||||
%y = add i16 %x, 1
|
||||
%x2 = sext i16 %y to i32
|
||||
%r = icmp ne i32 %x2, -1
|
||||
ret i1 %r
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs
|
||||
define i32 @sdiv(i32 %A, i32 %B) {
|
||||
%R = sdiv i32 %A, %B ; <i32> [#uses=1]
|
||||
ret i32 %R
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
declare i1 @foo()
|
||||
|
||||
define i32 @test(i32* %A, i32* %B) {
|
||||
%a = load i32* %A
|
||||
%b = load i32* %B
|
||||
%cond = call i1 @foo()
|
||||
%c = select i1 %cond, i32 %a, i32 %b
|
||||
ret i32 %c
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
define i32 @foo(i32 %A, i32 %B, i32 %C) {
|
||||
entry:
|
||||
switch i32 %A, label %out [
|
||||
i32 1, label %bb
|
||||
i32 0, label %bb13
|
||||
]
|
||||
|
||||
bb: ; preds = %entry
|
||||
ret i32 1
|
||||
|
||||
bb13: ; preds = %entry
|
||||
ret i32 1
|
||||
|
||||
out: ; preds = %entry
|
||||
ret i32 0
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs > %t
|
||||
|
||||
define i8* @FindChar(i8* %CurPtr) {
|
||||
entry:
|
||||
br label %bb
|
||||
|
||||
bb: ; preds = %bb, %entry
|
||||
%tmp = load i8* null ; <i8> [#uses=1]
|
||||
switch i8 %tmp, label %bb [
|
||||
i8 0, label %bb7
|
||||
i8 120, label %bb7
|
||||
]
|
||||
|
||||
bb7: ; preds = %bb, %bb
|
||||
ret i8* null
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
; RUN: llc < %s -march=bfin -verify-machineinstrs | FileCheck %s
|
||||
|
||||
define void @f() nounwind {
|
||||
entry:
|
||||
; CHECK-NOT: llvm.bfin
|
||||
; CHECK: csync;
|
||||
call void @llvm.bfin.csync()
|
||||
|
||||
; CHECK-NOT: llvm.bfin
|
||||
; CHECK: ssync;
|
||||
call void @llvm.bfin.ssync()
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @llvm.bfin.csync() nounwind
|
||||
declare void @llvm.bfin.ssync() nounwind
|
|
@ -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 Alpha ARM Mips CellSPU PIC16 XCore MSP430 CBackend MSIL CppBackend"
|
||||
set llvmgcc_langs "c,c++,objc,obj-c++"
|
||||
set prcontext "/usr/bin/tclsh8.4 /Volumes/Data/ddunbar/llvm/test/Scripts/prcontext.tcl"
|
||||
set llvmtoolsdir "/Users/ddunbar/llvm.obj.64/Debug/bin"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue