Remove the Blackfin backend.

llvm-svn: 142880
This commit is contained in:
Dan Gohman 2011-10-25 00:05:42 +00:00
parent 53bb0ff685
commit b43c36f391
101 changed files with 10 additions and 5820 deletions

View File

@ -66,7 +66,6 @@ endif()
set(LLVM_ALL_TARGETS
Alpha
ARM
Blackfin
CBackend
CellSPU
CppBackend

View File

@ -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 ;;

4
llvm/configure vendored
View File

@ -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" ;;

View File

@ -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&nbsp;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 -->

View File

@ -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>

View File

@ -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

View File

@ -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"))

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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]>
]>;

View File

@ -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));
}
}

View File

@ -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

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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

View File

@ -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> {
}

View File

@ -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");
}

View File

@ -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

View File

@ -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)>;

View File

@ -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));
}

View File

@ -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

View File

@ -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<[]>;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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)>;

View File

@ -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() {
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -1,11 +0,0 @@
add_llvm_library(LLVMBlackfinDesc
BlackfinMCTargetDesc.cpp
BlackfinMCAsmInfo.cpp
)
add_llvm_library_dependencies(LLVMBlackfinDesc
LLVMBlackfinInfo
LLVMMC
)
add_dependencies(LLVMBlackfinDesc BlackfinCommonTableGen)

View File

@ -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

View File

@ -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

View File

@ -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. |

View File

@ -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]");
}

View File

@ -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)

View File

@ -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

View File

@ -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 ;;

View File

@ -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;}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,6 +0,0 @@
; RUN: llc < %s -march=bfin > %t
define i1 @cmp3(i32 %A) {
%R = icmp uge i32 %A, 2
ret i1 %R
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,5 +0,0 @@
load_lib llvm.exp
if { [llvm_supports_target Blackfin] } {
RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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*, ...)

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)

View File

@ -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**)

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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