1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

Remove the mblaze backend from llvm.

Approval in here http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/064169.html

llvm-svn: 187145
This commit is contained in:
Rafael Espindola 2013-07-25 18:55:05 +00:00
parent f3982a902a
commit 32f9d6abe2
129 changed files with 10 additions and 14686 deletions

View File

@ -79,7 +79,6 @@ set(LLVM_ALL_TARGETS
CppBackend
Hexagon
Mips
MBlaze
MSP430
NVPTX
PowerPC

View File

@ -407,7 +407,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
hexagon-*) llvm_cv_target_arch="Hexagon" ;;
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
nvptx-*) llvm_cv_target_arch="NVPTX" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
*) llvm_cv_target_arch="Unknown" ;;
@ -442,7 +441,6 @@ case $host in
xcore-*) host_arch="XCore" ;;
msp430-*) host_arch="MSP430" ;;
hexagon-*) host_arch="Hexagon" ;;
mblaze-*) host_arch="MBlaze" ;;
s390x-*) host_arch="SystemZ" ;;
*) host_arch="Unknown" ;;
esac
@ -674,7 +672,6 @@ else
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
Hexagon) AC_SUBST(TARGET_HAS_JIT,0) ;;
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
NVPTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
SystemZ) AC_SUBST(TARGET_HAS_JIT,1) ;;
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
@ -824,7 +821,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -841,7 +838,6 @@ case "$enableval" in
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
@ -853,7 +849,6 @@ case "$enableval" in
AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;

10
configure vendored
View File

@ -4033,7 +4033,6 @@ else
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
hexagon-*) llvm_cv_target_arch="Hexagon" ;;
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
nvptx-*) llvm_cv_target_arch="NVPTX" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
*) llvm_cv_target_arch="Unknown" ;;
@ -4068,7 +4067,6 @@ case $host in
xcore-*) host_arch="XCore" ;;
msp430-*) host_arch="MSP430" ;;
hexagon-*) host_arch="Hexagon" ;;
mblaze-*) host_arch="MBlaze" ;;
s390x-*) host_arch="SystemZ" ;;
*) host_arch="Unknown" ;;
esac
@ -5424,8 +5422,6 @@ else
MSP430) TARGET_HAS_JIT=0
;;
Hexagon) TARGET_HAS_JIT=0
;;
MBlaze) TARGET_HAS_JIT=0
;;
NVPTX) TARGET_HAS_JIT=0
;;
@ -5664,7 +5660,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -5681,7 +5677,6 @@ case "$enableval" in
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
@ -5693,7 +5688,6 @@ case "$enableval" in
AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
@ -10551,7 +10545,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10554 "configure"
#line 10548 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H

View File

@ -1788,7 +1788,6 @@ Here is the table:
:raw-html:`<th>Feature</th>`
:raw-html:`<th>ARM</th>`
:raw-html:`<th>Hexagon</th>`
:raw-html:`<th>MBlaze</th>`
:raw-html:`<th>MSP430</th>`
:raw-html:`<th>Mips</th>`
:raw-html:`<th>NVPTX</th>`
@ -1803,7 +1802,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_reliable">is generally reliable</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
:raw-html:`<td class="yes"></td> <!-- Mips -->`
:raw-html:`<td class="yes"></td> <!-- NVPTX -->`
@ -1818,7 +1816,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_asmparser">assembly parser</a></td>`
:raw-html:`<td class="no"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="no"></td> <!-- NVPTX -->`
@ -1833,7 +1830,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_disassembler">disassembler</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
@ -1848,7 +1844,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_inlineasm">inline asm</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="yes"></td> <!-- NVPTX -->`
@ -1863,7 +1858,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_jit">jit</a></td>`
:raw-html:`<td class="partial"><a href="#feat_jit_arm">*</a></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
:raw-html:`<td class="yes"></td> <!-- Mips -->`
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
@ -1878,7 +1872,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_objectwrite">.o&nbsp;file writing</a></td>`
:raw-html:`<td class="no"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="na"></td> <!-- NVPTX -->`
@ -1893,7 +1886,6 @@ Here is the table:
:raw-html:`<td><a hr:raw-html:`ef="#feat_tailcall">tail calls</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="no"></td> <!-- NVPTX -->`
@ -1908,7 +1900,6 @@ Here is the table:
:raw-html:`<td><a href="#feat_segstacks">segmented stacks</a></td>`
:raw-html:`<td class="no"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
:raw-html:`<td class="no"></td> <!-- Mips -->`
:raw-html:`<td class="no"></td> <!-- NVPTX -->`

View File

@ -758,7 +758,7 @@ The following options can be used to set or enable LLVM specific options:
target names that you want available in llc. The target names use all lower
case. The current set of targets is:
``arm, cpp, hexagon, mblaze, mips, mipsel, msp430, powerpc, ptx, sparc, spu,
``arm, cpp, hexagon, mips, mipsel, msp430, powerpc, ptx, sparc, spu,
systemz, x86, x86_64, xcore``.
``--enable-doxygen``

View File

@ -64,7 +64,6 @@ public:
x86, // X86: i[3-9]86
x86_64, // X86-64: amd64, x86_64
xcore, // XCore: xcore
mblaze, // MBlaze: mblaze
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)

View File

@ -93,13 +93,6 @@ namespace CallingConv {
/// Passes all arguments in register or parameter space.
PTX_Device = 72,
/// MBLAZE_INTR - Calling convention used for MBlaze interrupt routines.
MBLAZE_INTR = 73,
/// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
/// routines (i.e. GCC's save_volatiles attribute).
MBLAZE_SVOL = 74,
/// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
/// No lowering or expansion of arguments.
/// Structures are passed as a pointer to a struct with the byval attribute.

View File

@ -276,7 +276,6 @@ enum {
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
EM_CUDA = 190, // NVIDIA CUDA architecture
EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
EM_CLOUDSHIELD = 192, // CloudShield architecture family
@ -287,8 +286,7 @@ enum {
EM_RL78 = 197, // Renesas RL78 family
EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
EM_78KOR = 199, // Renesas 78KOR family
EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
EM_MBLAZE = 47787 // Xilinx MicroBlaze
EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
};
// Object file classes.
@ -418,32 +416,6 @@ enum {
R_386_NUM = 43
};
// MBlaze relocations.
enum {
R_MICROBLAZE_NONE = 0,
R_MICROBLAZE_32 = 1,
R_MICROBLAZE_32_PCREL = 2,
R_MICROBLAZE_64_PCREL = 3,
R_MICROBLAZE_32_PCREL_LO = 4,
R_MICROBLAZE_64 = 5,
R_MICROBLAZE_32_LO = 6,
R_MICROBLAZE_SRO32 = 7,
R_MICROBLAZE_SRW32 = 8,
R_MICROBLAZE_64_NONE = 9,
R_MICROBLAZE_32_SYM_OP_SYM = 10,
R_MICROBLAZE_GNU_VTINHERIT = 11,
R_MICROBLAZE_GNU_VTENTRY = 12,
R_MICROBLAZE_GOTPC_64 = 13,
R_MICROBLAZE_GOT_64 = 14,
R_MICROBLAZE_PLT_64 = 15,
R_MICROBLAZE_REL = 16,
R_MICROBLAZE_JUMP_SLOT = 17,
R_MICROBLAZE_GLOB_DAT = 18,
R_MICROBLAZE_GOTOFF_64 = 19,
R_MICROBLAZE_GOTOFF_32 = 20,
R_MICROBLAZE_COPY = 21
};
// ELF Relocation types for PPC32
enum {
R_PPC_NONE = 0, /* No relocation. */

View File

@ -176,7 +176,6 @@ ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO,
ECase(EM_STM8)
ECase(EM_TILE64)
ECase(EM_TILEPRO)
ECase(EM_MICROBLAZE)
ECase(EM_CUDA)
ECase(EM_TILEGX)
ECase(EM_CLOUDSHIELD)
@ -188,7 +187,6 @@ ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO,
ECase(EM_VIDEOCORE5)
ECase(EM_78KOR)
ECase(EM_56800EX)
ECase(EM_MBLAZE)
#undef ECase
}

View File

@ -38,7 +38,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case x86: return "i386";
case x86_64: return "x86_64";
case xcore: return "xcore";
case mblaze: return "mblaze";
case nvptx: return "nvptx";
case nvptx64: return "nvptx64";
case le32: return "le32";
@ -63,8 +62,6 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case ppc64:
case ppc: return "ppc";
case mblaze: return "mblaze";
case mips:
case mipsel:
case mips64:
@ -171,7 +168,6 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("ppc64", ppc64)
.Case("ppc32", ppc)
.Case("ppc", ppc)
.Case("mblaze", mblaze)
.Case("r600", r600)
.Case("hexagon", hexagon)
.Case("sparc", sparc)
@ -201,7 +197,6 @@ const char *Triple::getArchNameForAssembler() {
.Case("x86_64", "x86_64")
.Case("powerpc", "ppc")
.Case("powerpc64", "ppc64")
.Cases("mblaze", "microblaze", "mblaze")
.Case("arm", "arm")
.Cases("armv4t", "thumbv4t", "armv4t")
.Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
@ -225,7 +220,6 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Cases("amd64", "x86_64", Triple::x86_64)
.Case("powerpc", Triple::ppc)
.Cases("powerpc64", "ppu", Triple::ppc64)
.Case("mblaze", Triple::mblaze)
.Case("aarch64", Triple::aarch64)
.Cases("arm", "xscale", Triple::arm)
// FIXME: It would be good to replace these with explicit names for all the
@ -678,7 +672,6 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::arm:
case llvm::Triple::hexagon:
case llvm::Triple::le32:
case llvm::Triple::mblaze:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
case llvm::Triple::nvptx:
@ -733,7 +726,6 @@ Triple Triple::get32BitArchVariant() const {
case Triple::arm:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:
case Triple::mips:
case Triple::mipsel:
case Triple::nvptx:
@ -766,7 +758,6 @@ Triple Triple::get64BitArchVariant() const {
case Triple::arm:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:
case Triple::msp430:
case Triple::r600:
case Triple::tce:

View File

@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
subdirectories = AArch64 ARM CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC R600 Sparc SystemZ X86 XCore
subdirectories = AArch64 ARM CppBackend Hexagon MSP430 NVPTX Mips PowerPC R600 Sparc SystemZ X86 XCore
; This is a special group whose required libraries are extended (by llvm-build)
; with the best execution engine (the native JIT, if available, or the

View File

@ -1,8 +0,0 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMMBlazeAsmParser
MBlazeAsmParser.cpp
)
add_dependencies(LLVMMBlazeAsmParser MBlazeCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/MBlaze/AsmParser/LLVMBuild.txt --------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MBlazeAsmParser
parent = MBlaze
required_libraries = MBlazeInfo MC MCParser Support
add_to_library_groups = MBlaze

View File

@ -1,573 +0,0 @@
//===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/MBlazeBaseInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct MBlazeOperand;
class MBlazeAsmParser : public MCTargetAsmParser {
MCAsmParser &Parser;
MCAsmParser &getParser() const { return Parser; }
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
MBlazeOperand *ParseRegister();
MBlazeOperand *ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc);
MBlazeOperand *ParseImmediate();
MBlazeOperand *ParseFsl();
MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
bool ParseDirectiveWord(unsigned Size, SMLoc L);
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm);
/// @name Auto-generated Match Functions
/// {
#define GET_ASSEMBLER_HEADER
#include "MBlazeGenAsmMatcher.inc"
/// }
public:
MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
: MCTargetAsmParser(), Parser(_Parser) {}
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands);
virtual bool ParseDirective(AsmToken DirectiveID);
};
/// MBlazeOperand - Instances of this class represent a parsed MBlaze machine
/// instruction.
struct MBlazeOperand : public MCParsedAsmOperand {
enum KindTy {
Token,
Immediate,
Register,
Memory,
Fsl
} Kind;
SMLoc StartLoc, EndLoc;
struct TokOp {
const char *Data;
unsigned Length;
};
struct RegOp {
unsigned RegNum;
};
struct ImmOp {
const MCExpr *Val;
};
struct MemOp {
unsigned Base;
unsigned OffReg;
const MCExpr *Off;
};
struct FslImmOp {
const MCExpr *Val;
};
union {
struct TokOp Tok;
struct RegOp Reg;
struct ImmOp Imm;
struct MemOp Mem;
struct FslImmOp FslImm;
};
MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
public:
MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() {
Kind = o.Kind;
StartLoc = o.StartLoc;
EndLoc = o.EndLoc;
switch (Kind) {
case Register:
Reg = o.Reg;
break;
case Immediate:
Imm = o.Imm;
break;
case Token:
Tok = o.Tok;
break;
case Memory:
Mem = o.Mem;
break;
case Fsl:
FslImm = o.FslImm;
break;
}
}
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const { return StartLoc; }
/// getEndLoc - Get the location of the last token of this operand.
SMLoc getEndLoc() const { return EndLoc; }
unsigned getReg() const {
assert(Kind == Register && "Invalid access!");
return Reg.RegNum;
}
const MCExpr *getImm() const {
assert(Kind == Immediate && "Invalid access!");
return Imm.Val;
}
const MCExpr *getFslImm() const {
assert(Kind == Fsl && "Invalid access!");
return FslImm.Val;
}
unsigned getMemBase() const {
assert(Kind == Memory && "Invalid access!");
return Mem.Base;
}
const MCExpr* getMemOff() const {
assert(Kind == Memory && "Invalid access!");
return Mem.Off;
}
unsigned getMemOffReg() const {
assert(Kind == Memory && "Invalid access!");
return Mem.OffReg;
}
bool isToken() const { return Kind == Token; }
bool isImm() const { return Kind == Immediate; }
bool isMem() const { return Kind == Memory; }
bool isFsl() const { return Kind == Fsl; }
bool isReg() const { return Kind == Register; }
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
// Add as immediates when possible. Null MCExpr = 0.
if (Expr == 0)
Inst.addOperand(MCOperand::CreateImm(0));
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
else
Inst.addOperand(MCOperand::CreateExpr(Expr));
}
void addRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getReg()));
}
void addImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getImm());
}
void addFslOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
addExpr(Inst, getFslImm());
}
void addMemOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateReg(getMemBase()));
unsigned RegOff = getMemOffReg();
if (RegOff)
Inst.addOperand(MCOperand::CreateReg(RegOff));
else
addExpr(Inst, getMemOff());
}
StringRef getToken() const {
assert(Kind == Token && "Invalid access!");
return StringRef(Tok.Data, Tok.Length);
}
virtual void print(raw_ostream &OS) const;
static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) {
MBlazeOperand *Op = new MBlazeOperand(Token);
Op->Tok.Data = Str.data();
Op->Tok.Length = Str.size();
Op->StartLoc = S;
Op->EndLoc = S;
return Op;
}
static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
MBlazeOperand *Op = new MBlazeOperand(Register);
Op->Reg.RegNum = RegNum;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
MBlazeOperand *Op = new MBlazeOperand(Immediate);
Op->Imm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) {
MBlazeOperand *Op = new MBlazeOperand(Fsl);
Op->Imm.Val = Val;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
SMLoc E) {
MBlazeOperand *Op = new MBlazeOperand(Memory);
Op->Mem.Base = Base;
Op->Mem.Off = Off;
Op->Mem.OffReg = 0;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S,
SMLoc E) {
MBlazeOperand *Op = new MBlazeOperand(Memory);
Op->Mem.Base = Base;
Op->Mem.OffReg = Off;
Op->Mem.Off = 0;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
}
};
} // end anonymous namespace.
void MBlazeOperand::print(raw_ostream &OS) const {
switch (Kind) {
case Immediate:
getImm()->print(OS);
break;
case Register:
OS << "<register R";
OS << getMBlazeRegisterNumbering(getReg()) << ">";
break;
case Token:
OS << "'" << getToken() << "'";
break;
case Memory: {
OS << "<memory R";
OS << getMBlazeRegisterNumbering(getMemBase());
OS << ", ";
unsigned RegOff = getMemOffReg();
if (RegOff)
OS << "R" << getMBlazeRegisterNumbering(RegOff);
else
OS << getMemOff();
OS << ">";
}
break;
case Fsl:
getFslImm()->print(OS);
break;
}
}
/// @name Auto-generated Match Functions
/// {
static unsigned MatchRegisterName(StringRef Name);
/// }
//
bool MBlazeAsmParser::
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm) {
MCInst Inst;
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo,
MatchingInlineAsm)) {
default: break;
case Match_Success:
Out.EmitInstruction(Inst);
return false;
case Match_MissingFeature:
return Error(IDLoc, "instruction use requires an option to be enabled");
case Match_MnemonicFail:
return Error(IDLoc, "unrecognized instruction mnemonic");
case Match_InvalidOperand: {
SMLoc ErrorLoc = IDLoc;
if (ErrorInfo != ~0U) {
if (ErrorInfo >= Operands.size())
return Error(IDLoc, "too few operands for instruction");
ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc();
if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
}
return Error(ErrorLoc, "invalid operand for instruction");
}
}
llvm_unreachable("Implement any new match types added!");
}
MBlazeOperand *MBlazeAsmParser::
ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
if (Operands.size() != 4)
return 0;
MBlazeOperand &Base = *(MBlazeOperand*)Operands[2];
MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3];
SMLoc S = Base.getStartLoc();
SMLoc O = Offset.getStartLoc();
SMLoc E = Offset.getEndLoc();
if (!Base.isReg()) {
Error(S, "base address must be a register");
return 0;
}
if (!Offset.isReg() && !Offset.isImm()) {
Error(O, "offset must be a register or immediate");
return 0;
}
MBlazeOperand *Op;
if (Offset.isReg())
Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E);
else
Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E);
delete Operands.pop_back_val();
delete Operands.pop_back_val();
Operands.push_back(Op);
return Op;
}
bool MBlazeAsmParser::ParseRegister(unsigned &RegNo,
SMLoc &StartLoc, SMLoc &EndLoc) {
MBlazeOperand *Reg = ParseRegister(StartLoc, EndLoc);
if (!Reg)
return true;
RegNo = Reg->getReg();
return false;
}
MBlazeOperand *MBlazeAsmParser::ParseRegister() {
SMLoc S, E;
return ParseRegister(S, E);
}
MBlazeOperand *MBlazeAsmParser::ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc) {
StartLoc = Parser.getTok().getLoc();
EndLoc = Parser.getTok().getEndLoc();
if (getLexer().getKind() != AsmToken::Identifier)
return 0;
unsigned RegNo = MatchRegisterName(getLexer().getTok().getIdentifier());
if (RegNo == 0)
return 0;
getLexer().Lex();
return MBlazeOperand::CreateReg(RegNo, StartLoc, EndLoc);
}
static unsigned MatchFslRegister(StringRef String) {
if (!String.startswith("rfsl"))
return -1;
unsigned regNum;
if (String.substr(4).getAsInteger(10,regNum))
return -1;
return regNum;
}
MBlazeOperand *MBlazeAsmParser::ParseFsl() {
SMLoc S = Parser.getTok().getLoc();
SMLoc E = Parser.getTok().getEndLoc();
switch (getLexer().getKind()) {
default: return 0;
case AsmToken::Identifier:
unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier());
if (reg >= 16)
return 0;
getLexer().Lex();
const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
return MBlazeOperand::CreateFslImm(EVal,S,E);
}
}
MBlazeOperand *MBlazeAsmParser::ParseImmediate() {
SMLoc S = Parser.getTok().getLoc();
SMLoc E = Parser.getTok().getEndLoc();
const MCExpr *EVal;
switch (getLexer().getKind()) {
default: return 0;
case AsmToken::LParen:
case AsmToken::Plus:
case AsmToken::Minus:
case AsmToken::Integer:
case AsmToken::Identifier:
if (getParser().parseExpression(EVal))
return 0;
return MBlazeOperand::CreateImm(EVal, S, E);
}
}
MBlazeOperand *MBlazeAsmParser::
ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
MBlazeOperand *Op;
// Attempt to parse the next token as a register name
Op = ParseRegister();
// Attempt to parse the next token as an FSL immediate
if (!Op)
Op = ParseFsl();
// Attempt to parse the next token as an immediate
if (!Op)
Op = ParseImmediate();
// If the token could not be parsed then fail
if (!Op) {
Error(Parser.getTok().getLoc(), "unknown operand");
return 0;
}
// Push the parsed operand into the list of operands
Operands.push_back(Op);
return Op;
}
/// Parse an mblaze instruction mnemonic followed by its operands.
bool MBlazeAsmParser::
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
// The first operands is the token for the instruction name
size_t dotLoc = Name.find('.');
Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
if (dotLoc < Name.size())
Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
// If there are no more operands then finish
if (getLexer().is(AsmToken::EndOfStatement))
return false;
// Parse the first operand
if (!ParseOperand(Operands))
return true;
while (getLexer().isNot(AsmToken::EndOfStatement) &&
getLexer().is(AsmToken::Comma)) {
// Consume the comma token
getLexer().Lex();
// Parse the next operand
if (!ParseOperand(Operands))
return true;
}
// If the instruction requires a memory operand then we need to
// replace the last two operands (base+offset) with a single
// memory operand.
if (Name.startswith("lw") || Name.startswith("sw") ||
Name.startswith("lh") || Name.startswith("sh") ||
Name.startswith("lb") || Name.startswith("sb"))
return (ParseMemory(Operands) == NULL);
return false;
}
/// ParseDirective parses the MBlaze specific directives
bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
StringRef IDVal = DirectiveID.getIdentifier();
if (IDVal == ".word")
return ParseDirectiveWord(2, DirectiveID.getLoc());
return true;
}
/// ParseDirectiveWord
/// ::= .word [ expression (, expression)* ]
bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
const MCExpr *Value;
if (getParser().parseExpression(Value))
return true;
getParser().getStreamer().EmitValue(Value, Size);
if (getLexer().is(AsmToken::EndOfStatement))
break;
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return Error(L, "unexpected token in directive");
Parser.Lex();
}
}
Parser.Lex();
return false;
}
/// Force static initialization.
extern "C" void LLVMInitializeMBlazeAsmParser() {
RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget);
}
#define GET_REGISTER_MATCHER
#define GET_MATCHER_IMPLEMENTATION
#include "MBlazeGenAsmMatcher.inc"

View File

@ -1,15 +0,0 @@
##===- lib/Target/MBlaze/AsmParser/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 = LLVMMBlazeAsmParser
# Hack: we need to include 'main' MBlaze target directory for private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -1,37 +0,0 @@
set(LLVM_TARGET_DEFINITIONS MBlaze.td)
tablegen(LLVM MBlazeGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM MBlazeGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM MBlazeGenCodeEmitter.inc -gen-emitter)
tablegen(LLVM MBlazeGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM MBlazeGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM MBlazeGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM MBlazeGenCallingConv.inc -gen-callingconv)
tablegen(LLVM MBlazeGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
add_public_tablegen_target(MBlazeCommonTableGen)
add_llvm_target(MBlazeCodeGen
MBlazeDelaySlotFiller.cpp
MBlazeInstrInfo.cpp
MBlazeISelDAGToDAG.cpp
MBlazeISelLowering.cpp
MBlazeFrameLowering.cpp
MBlazeMachineFunction.cpp
MBlazeRegisterInfo.cpp
MBlazeSubtarget.cpp
MBlazeTargetMachine.cpp
MBlazeTargetObjectFile.cpp
MBlazeIntrinsicInfo.cpp
MBlazeSelectionDAGInfo.cpp
MBlazeAsmPrinter.cpp
MBlazeMCInstLower.cpp
)
add_dependencies(LLVMMBlazeCodeGen intrinsics_gen)
add_subdirectory(AsmParser)
add_subdirectory(Disassembler)
add_subdirectory(InstPrinter)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)

View File

@ -1,16 +0,0 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMMBlazeDisassembler
MBlazeDisassembler.cpp
)
# workaround for hanging compilation on MSVC9 and 10
if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
set_property(
SOURCE MBlazeDisassembler.cpp
PROPERTY COMPILE_FLAGS "/Od"
)
endif()
add_dependencies(LLVMMBlazeDisassembler MBlazeCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/MBlaze/Disassembler/LLVMBuild.txt -----------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MBlazeDisassembler
parent = MBlaze
required_libraries = MBlazeDesc MBlazeInfo MC Support
add_to_library_groups = MBlaze

View File

@ -1,718 +0,0 @@
//===-- MBlazeDisassembler.cpp - Disassembler for MicroBlaze -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the MBlaze Disassembler. It contains code to translate
// the data produced by the decoder into MCInsts.
//
//===----------------------------------------------------------------------===//
#include "MBlazeDisassembler.h"
#include "MBlaze.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
// #include "MBlazeGenDecoderTables.inc"
// #include "MBlazeGenRegisterNames.inc"
namespace llvm {
extern const MCInstrDesc MBlazeInsts[];
}
using namespace llvm;
const uint16_t UNSUPPORTED = -1;
static const uint16_t mblazeBinary2Opcode[] = {
MBlaze::ADD, MBlaze::RSUB, MBlaze::ADDC, MBlaze::RSUBC, //00,01,02,03
MBlaze::ADDK, MBlaze::RSUBK, MBlaze::ADDKC, MBlaze::RSUBKC, //04,05,06,07
MBlaze::ADDI, MBlaze::RSUBI, MBlaze::ADDIC, MBlaze::RSUBIC, //08,09,0A,0B
MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
MBlaze::MUL, MBlaze::BSRL, MBlaze::IDIV, MBlaze::GETD, //10,11,12,13
UNSUPPORTED, UNSUPPORTED, MBlaze::FADD, UNSUPPORTED, //14,15,16,17
MBlaze::MULI, MBlaze::BSRLI, UNSUPPORTED, MBlaze::GET, //18,19,1A,1B
UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, //1C,1D,1E,1F
MBlaze::OR, MBlaze::AND, MBlaze::XOR, MBlaze::ANDN, //20,21,22,23
MBlaze::SEXT8, MBlaze::MFS, MBlaze::BR, MBlaze::BEQ, //24,25,26,27
MBlaze::ORI, MBlaze::ANDI, MBlaze::XORI, MBlaze::ANDNI, //28,29,2A,2B
MBlaze::IMM, MBlaze::RTSD, MBlaze::BRI, MBlaze::BEQI, //2C,2D,2E,2F
MBlaze::LBU, MBlaze::LHU, MBlaze::LW, UNSUPPORTED, //30,31,32,33
MBlaze::SB, MBlaze::SH, MBlaze::SW, UNSUPPORTED, //34,35,36,37
MBlaze::LBUI, MBlaze::LHUI, MBlaze::LWI, UNSUPPORTED, //38,39,3A,3B
MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F
};
static unsigned getRD(uint32_t insn) {
if (!isMBlazeRegister((insn>>21)&0x1F))
return UNSUPPORTED;
return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
}
static unsigned getRA(uint32_t insn) {
if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
return UNSUPPORTED;
return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
}
static unsigned getRB(uint32_t insn) {
if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
return UNSUPPORTED;
return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
}
static int64_t getRS(uint32_t insn) {
if (!isSpecialMBlazeRegister(insn&0x3FFF))
return UNSUPPORTED;
return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
}
static int64_t getIMM(uint32_t insn) {
int16_t val = (insn & 0xFFFF);
return val;
}
static int64_t getSHT(uint32_t insn) {
int16_t val = (insn & 0x1F);
return val;
}
static unsigned getFLAGS(int32_t insn) {
return (insn & 0x7FF);
}
static int64_t getFSL(uint32_t insn) {
int16_t val = (insn & 0xF);
return val;
}
static unsigned decodeMUL(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0: return MBlaze::MUL;
case 1: return MBlaze::MULH;
case 2: return MBlaze::MULHSU;
case 3: return MBlaze::MULHU;
}
}
static unsigned decodeSEXT(uint32_t insn) {
switch (insn&0x7FF) {
default: return UNSUPPORTED;
case 0x60: return MBlaze::SEXT8;
case 0x68: return MBlaze::WIC;
case 0x64: return MBlaze::WDC;
case 0x66: return MBlaze::WDCC;
case 0x74: return MBlaze::WDCF;
case 0x61: return MBlaze::SEXT16;
case 0x41: return MBlaze::SRL;
case 0x21: return MBlaze::SRC;
case 0x01: return MBlaze::SRA;
case 0xE0: return MBlaze::CLZ;
}
}
static unsigned decodeBEQ(uint32_t insn) {
switch ((insn>>21)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BEQ;
case 0x10: return MBlaze::BEQD;
case 0x05: return MBlaze::BGE;
case 0x15: return MBlaze::BGED;
case 0x04: return MBlaze::BGT;
case 0x14: return MBlaze::BGTD;
case 0x03: return MBlaze::BLE;
case 0x13: return MBlaze::BLED;
case 0x02: return MBlaze::BLT;
case 0x12: return MBlaze::BLTD;
case 0x01: return MBlaze::BNE;
case 0x11: return MBlaze::BNED;
}
}
static unsigned decodeBEQI(uint32_t insn) {
switch ((insn>>21)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BEQI;
case 0x10: return MBlaze::BEQID;
case 0x05: return MBlaze::BGEI;
case 0x15: return MBlaze::BGEID;
case 0x04: return MBlaze::BGTI;
case 0x14: return MBlaze::BGTID;
case 0x03: return MBlaze::BLEI;
case 0x13: return MBlaze::BLEID;
case 0x02: return MBlaze::BLTI;
case 0x12: return MBlaze::BLTID;
case 0x01: return MBlaze::BNEI;
case 0x11: return MBlaze::BNEID;
}
}
static unsigned decodeBR(uint32_t insn) {
switch ((insn>>16)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BR;
case 0x08: return MBlaze::BRA;
case 0x0C: return MBlaze::BRK;
case 0x10: return MBlaze::BRD;
case 0x14: return MBlaze::BRLD;
case 0x18: return MBlaze::BRAD;
case 0x1C: return MBlaze::BRALD;
}
}
static unsigned decodeBRI(uint32_t insn) {
switch (insn&0x3FFFFFF) {
default: break;
case 0x0020004: return MBlaze::IDMEMBAR;
case 0x0220004: return MBlaze::DMEMBAR;
case 0x0420004: return MBlaze::IMEMBAR;
}
switch ((insn>>16)&0x1F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::BRI;
case 0x08: return MBlaze::BRAI;
case 0x0C: return MBlaze::BRKI;
case 0x10: return MBlaze::BRID;
case 0x14: return MBlaze::BRLID;
case 0x18: return MBlaze::BRAID;
case 0x1C: return MBlaze::BRALID;
}
}
static unsigned decodeBSRL(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
case 0x2: return MBlaze::BSLL;
case 0x1: return MBlaze::BSRA;
case 0x0: return MBlaze::BSRL;
}
}
static unsigned decodeBSRLI(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
case 0x2: return MBlaze::BSLLI;
case 0x1: return MBlaze::BSRAI;
case 0x0: return MBlaze::BSRLI;
}
}
static unsigned decodeRSUBK(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::RSUBK;
case 0x1: return MBlaze::CMP;
case 0x3: return MBlaze::CMPU;
}
}
static unsigned decodeFADD(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0x000: return MBlaze::FADD;
case 0x080: return MBlaze::FRSUB;
case 0x100: return MBlaze::FMUL;
case 0x180: return MBlaze::FDIV;
case 0x200: return MBlaze::FCMP_UN;
case 0x210: return MBlaze::FCMP_LT;
case 0x220: return MBlaze::FCMP_EQ;
case 0x230: return MBlaze::FCMP_LE;
case 0x240: return MBlaze::FCMP_GT;
case 0x250: return MBlaze::FCMP_NE;
case 0x260: return MBlaze::FCMP_GE;
case 0x280: return MBlaze::FLT;
case 0x300: return MBlaze::FINT;
case 0x380: return MBlaze::FSQRT;
}
}
static unsigned decodeGET(uint32_t insn) {
switch ((insn>>10)&0x3F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::GET;
case 0x01: return MBlaze::EGET;
case 0x02: return MBlaze::AGET;
case 0x03: return MBlaze::EAGET;
case 0x04: return MBlaze::TGET;
case 0x05: return MBlaze::TEGET;
case 0x06: return MBlaze::TAGET;
case 0x07: return MBlaze::TEAGET;
case 0x08: return MBlaze::CGET;
case 0x09: return MBlaze::ECGET;
case 0x0A: return MBlaze::CAGET;
case 0x0B: return MBlaze::ECAGET;
case 0x0C: return MBlaze::TCGET;
case 0x0D: return MBlaze::TECGET;
case 0x0E: return MBlaze::TCAGET;
case 0x0F: return MBlaze::TECAGET;
case 0x10: return MBlaze::NGET;
case 0x11: return MBlaze::NEGET;
case 0x12: return MBlaze::NAGET;
case 0x13: return MBlaze::NEAGET;
case 0x14: return MBlaze::TNGET;
case 0x15: return MBlaze::TNEGET;
case 0x16: return MBlaze::TNAGET;
case 0x17: return MBlaze::TNEAGET;
case 0x18: return MBlaze::NCGET;
case 0x19: return MBlaze::NECGET;
case 0x1A: return MBlaze::NCAGET;
case 0x1B: return MBlaze::NECAGET;
case 0x1C: return MBlaze::TNCGET;
case 0x1D: return MBlaze::TNECGET;
case 0x1E: return MBlaze::TNCAGET;
case 0x1F: return MBlaze::TNECAGET;
case 0x20: return MBlaze::PUT;
case 0x22: return MBlaze::APUT;
case 0x24: return MBlaze::TPUT;
case 0x26: return MBlaze::TAPUT;
case 0x28: return MBlaze::CPUT;
case 0x2A: return MBlaze::CAPUT;
case 0x2C: return MBlaze::TCPUT;
case 0x2E: return MBlaze::TCAPUT;
case 0x30: return MBlaze::NPUT;
case 0x32: return MBlaze::NAPUT;
case 0x34: return MBlaze::TNPUT;
case 0x36: return MBlaze::TNAPUT;
case 0x38: return MBlaze::NCPUT;
case 0x3A: return MBlaze::NCAPUT;
case 0x3C: return MBlaze::TNCPUT;
case 0x3E: return MBlaze::TNCAPUT;
}
}
static unsigned decodeGETD(uint32_t insn) {
switch ((insn>>5)&0x3F) {
default: return UNSUPPORTED;
case 0x00: return MBlaze::GETD;
case 0x01: return MBlaze::EGETD;
case 0x02: return MBlaze::AGETD;
case 0x03: return MBlaze::EAGETD;
case 0x04: return MBlaze::TGETD;
case 0x05: return MBlaze::TEGETD;
case 0x06: return MBlaze::TAGETD;
case 0x07: return MBlaze::TEAGETD;
case 0x08: return MBlaze::CGETD;
case 0x09: return MBlaze::ECGETD;
case 0x0A: return MBlaze::CAGETD;
case 0x0B: return MBlaze::ECAGETD;
case 0x0C: return MBlaze::TCGETD;
case 0x0D: return MBlaze::TECGETD;
case 0x0E: return MBlaze::TCAGETD;
case 0x0F: return MBlaze::TECAGETD;
case 0x10: return MBlaze::NGETD;
case 0x11: return MBlaze::NEGETD;
case 0x12: return MBlaze::NAGETD;
case 0x13: return MBlaze::NEAGETD;
case 0x14: return MBlaze::TNGETD;
case 0x15: return MBlaze::TNEGETD;
case 0x16: return MBlaze::TNAGETD;
case 0x17: return MBlaze::TNEAGETD;
case 0x18: return MBlaze::NCGETD;
case 0x19: return MBlaze::NECGETD;
case 0x1A: return MBlaze::NCAGETD;
case 0x1B: return MBlaze::NECAGETD;
case 0x1C: return MBlaze::TNCGETD;
case 0x1D: return MBlaze::TNECGETD;
case 0x1E: return MBlaze::TNCAGETD;
case 0x1F: return MBlaze::TNECAGETD;
case 0x20: return MBlaze::PUTD;
case 0x22: return MBlaze::APUTD;
case 0x24: return MBlaze::TPUTD;
case 0x26: return MBlaze::TAPUTD;
case 0x28: return MBlaze::CPUTD;
case 0x2A: return MBlaze::CAPUTD;
case 0x2C: return MBlaze::TCPUTD;
case 0x2E: return MBlaze::TCAPUTD;
case 0x30: return MBlaze::NPUTD;
case 0x32: return MBlaze::NAPUTD;
case 0x34: return MBlaze::TNPUTD;
case 0x36: return MBlaze::TNAPUTD;
case 0x38: return MBlaze::NCPUTD;
case 0x3A: return MBlaze::NCAPUTD;
case 0x3C: return MBlaze::TNCPUTD;
case 0x3E: return MBlaze::TNCAPUTD;
}
}
static unsigned decodeIDIV(uint32_t insn) {
switch (insn&0x3) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::IDIV;
case 0x2: return MBlaze::IDIVU;
}
}
static unsigned decodeLBU(uint32_t insn) {
switch ((insn>>9)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::LBU;
case 0x1: return MBlaze::LBUR;
}
}
static unsigned decodeLHU(uint32_t insn) {
switch ((insn>>9)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::LHU;
case 0x1: return MBlaze::LHUR;
}
}
static unsigned decodeLW(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::LW;
case 0x1: return MBlaze::LWR;
case 0x2: return MBlaze::LWX;
}
}
static unsigned decodeSB(uint32_t insn) {
switch ((insn>>9)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::SB;
case 0x1: return MBlaze::SBR;
}
}
static unsigned decodeSH(uint32_t insn) {
switch ((insn>>9)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::SH;
case 0x1: return MBlaze::SHR;
}
}
static unsigned decodeSW(uint32_t insn) {
switch ((insn>>9)&0x3) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::SW;
case 0x1: return MBlaze::SWR;
case 0x2: return MBlaze::SWX;
}
}
static unsigned decodeMFS(uint32_t insn) {
switch ((insn>>15)&0x1) {
default: return UNSUPPORTED;
case 0x0:
switch ((insn>>16)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::MSRSET;
case 0x1: return MBlaze::MSRCLR;
}
case 0x1:
switch ((insn>>14)&0x1) {
default: return UNSUPPORTED;
case 0x0: return MBlaze::MFS;
case 0x1: return MBlaze::MTS;
}
}
}
static unsigned decodeOR(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0x000: return MBlaze::OR;
case 0x400: return MBlaze::PCMPBF;
}
}
static unsigned decodeXOR(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0x000: return MBlaze::XOR;
case 0x400: return MBlaze::PCMPEQ;
}
}
static unsigned decodeANDN(uint32_t insn) {
switch (getFLAGS(insn)) {
default: return UNSUPPORTED;
case 0x000: return MBlaze::ANDN;
case 0x400: return MBlaze::PCMPNE;
}
}
static unsigned decodeRTSD(uint32_t insn) {
switch ((insn>>21)&0x1F) {
default: return UNSUPPORTED;
case 0x10: return MBlaze::RTSD;
case 0x11: return MBlaze::RTID;
case 0x12: return MBlaze::RTBD;
case 0x14: return MBlaze::RTED;
}
}
static unsigned getOPCODE(uint32_t insn) {
unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
switch (opcode) {
case MBlaze::MUL: return decodeMUL(insn);
case MBlaze::SEXT8: return decodeSEXT(insn);
case MBlaze::BEQ: return decodeBEQ(insn);
case MBlaze::BEQI: return decodeBEQI(insn);
case MBlaze::BR: return decodeBR(insn);
case MBlaze::BRI: return decodeBRI(insn);
case MBlaze::BSRL: return decodeBSRL(insn);
case MBlaze::BSRLI: return decodeBSRLI(insn);
case MBlaze::RSUBK: return decodeRSUBK(insn);
case MBlaze::FADD: return decodeFADD(insn);
case MBlaze::GET: return decodeGET(insn);
case MBlaze::GETD: return decodeGETD(insn);
case MBlaze::IDIV: return decodeIDIV(insn);
case MBlaze::LBU: return decodeLBU(insn);
case MBlaze::LHU: return decodeLHU(insn);
case MBlaze::LW: return decodeLW(insn);
case MBlaze::SB: return decodeSB(insn);
case MBlaze::SH: return decodeSH(insn);
case MBlaze::SW: return decodeSW(insn);
case MBlaze::MFS: return decodeMFS(insn);
case MBlaze::OR: return decodeOR(insn);
case MBlaze::XOR: return decodeXOR(insn);
case MBlaze::ANDN: return decodeANDN(insn);
case MBlaze::RTSD: return decodeRTSD(insn);
default: return opcode;
}
}
//
// Public interface for the disassembler
//
MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
uint64_t &size,
const MemoryObject &region,
uint64_t address,
raw_ostream &vStream,
raw_ostream &cStream) const {
// The machine instruction.
uint32_t insn;
uint8_t bytes[4];
// By default we consume 1 byte on failure
size = 1;
// We want to read exactly 4 bytes of data.
if (region.readBytes(address, 4, bytes) == -1)
return Fail;
// Encoded as a big-endian 32-bit word in the stream.
insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
// Get the MCInst opcode from the binary instruction and make sure
// that it is a valid instruction.
unsigned opcode = getOPCODE(insn);
if (opcode == UNSUPPORTED)
return Fail;
instr.setOpcode(opcode);
unsigned RD = getRD(insn);
unsigned RA = getRA(insn);
unsigned RB = getRB(insn);
unsigned RS = getRS(insn);
uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
switch ((tsFlags & MBlazeII::FormMask)) {
default:
return Fail;
case MBlazeII::FC:
break;
case MBlazeII::FRRRR:
if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RB));
instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FRRR:
if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FRR:
if (RD == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FRI:
switch (opcode) {
default:
return Fail;
case MBlaze::MFS:
if (RD == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
break;
case MBlaze::MTS:
if (RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlaze::MSRSET:
case MBlaze::MSRCLR:
if (RD == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
break;
}
break;
case MBlazeII::FRRI:
if (RD == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RA));
switch (opcode) {
default:
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlaze::BSRLI:
case MBlaze::BSRAI:
case MBlaze::BSLLI:
instr.addOperand(MCOperand::CreateImm(insn&0x1F));
break;
}
break;
case MBlazeII::FCRR:
if (RA == UNSUPPORTED || RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FCRI:
if (RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlazeII::FRCR:
if (RD == UNSUPPORTED || RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FRCI:
if (RD == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlazeII::FCCR:
if (RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FCCI:
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
break;
case MBlazeII::FRRCI:
if (RD == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
break;
case MBlazeII::FRRC:
if (RD == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FRCX:
if (RD == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
break;
case MBlazeII::FRCS:
if (RD == UNSUPPORTED || RS == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateReg(RS));
break;
case MBlazeII::FCRCS:
if (RS == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RS));
instr.addOperand(MCOperand::CreateReg(RA));
break;
case MBlazeII::FCRCX:
if (RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RA));
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
break;
case MBlazeII::FCX:
instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
break;
case MBlazeII::FCR:
if (RB == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RB));
break;
case MBlazeII::FRIR:
if (RD == UNSUPPORTED || RA == UNSUPPORTED)
return Fail;
instr.addOperand(MCOperand::CreateReg(RD));
instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
instr.addOperand(MCOperand::CreateReg(RA));
break;
}
// We always consume 4 bytes of data on success
size = 4;
return Success;
}
static MCDisassembler *createMBlazeDisassembler(const Target &T,
const MCSubtargetInfo &STI) {
return new MBlazeDisassembler(STI);
}
extern "C" void LLVMInitializeMBlazeDisassembler() {
// Register the disassembler.
TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
createMBlazeDisassembler);
}

View File

@ -1,49 +0,0 @@
//===-- MBlazeDisassembler.h - Disassembler for MicroBlaze -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is part of the MBlaze Disassembler. It it the header for
// MBlazeDisassembler, a subclass of MCDisassembler.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEDISASSEMBLER_H
#define MBLAZEDISASSEMBLER_H
#include "llvm/MC/MCDisassembler.h"
namespace llvm {
class MCInst;
class MemoryObject;
class raw_ostream;
/// MBlazeDisassembler - Disassembler for all MBlaze platforms.
class MBlazeDisassembler : public MCDisassembler {
public:
/// Constructor - Initializes the disassembler.
///
MBlazeDisassembler(const MCSubtargetInfo &STI) :
MCDisassembler(STI) {
}
~MBlazeDisassembler() {
}
/// getInstruction - See MCDisassembler.
MCDisassembler::DecodeStatus getInstruction(MCInst &instr,
uint64_t &size,
const MemoryObject &region,
uint64_t address,
raw_ostream &vStream,
raw_ostream &cStream) const;
};
} // namespace llvm
#endif

View File

@ -1,16 +0,0 @@
##===- lib/Target/MBlaze/Disassembler/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 = LLVMMBlazeDisassembler
# Hack: we need to include 'main' MBlaze target directory to grab headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -1,8 +0,0 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMMBlazeAsmPrinter
MBlazeInstPrinter.cpp
)
add_dependencies(LLVMMBlazeAsmPrinter MBlazeCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/MBlaze/InstPrinter/LLVMBuild.txt ------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MBlazeAsmPrinter
parent = MBlaze
required_libraries = MC Support
add_to_library_groups = MBlaze

View File

@ -1,71 +0,0 @@
//===-- MBlazeInstPrinter.cpp - Convert MBlaze MCInst to assembly syntax --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an MBlaze MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asm-printer"
#include "MBlazeInstPrinter.h"
#include "MBlaze.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
// Include the auto-generated portion of the assembly writer.
#include "MBlazeGenAsmWriter.inc"
void MBlazeInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
StringRef Annot) {
printInstruction(MI, O);
printAnnotation(O, Annot);
}
void MBlazeInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
O << getRegisterName(Op.getReg());
} else if (Op.isImm()) {
O << (int32_t)Op.getImm();
} else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
O << *Op.getExpr();
}
}
void MBlazeInstPrinter::printFSLImm(const MCInst *MI, int OpNo,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);
if (MO.isImm())
O << "rfsl" << MO.getImm();
else
printOperand(MI, OpNo, O, NULL);
}
void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);
if (MO.isImm())
O << (uint32_t)MO.getImm();
else
printOperand(MI, OpNo, O, NULL);
}
void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo,
raw_ostream &O, const char *Modifier) {
printOperand(MI, OpNo, O, NULL);
O << ", ";
printOperand(MI, OpNo+1, O, NULL);
}

View File

@ -1,43 +0,0 @@
//= MBlazeInstPrinter.h - Convert MBlaze MCInst to assembly syntax -*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints a MBlaze MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEINSTPRINTER_H
#define MBLAZEINSTPRINTER_H
#include "llvm/MC/MCInstPrinter.h"
namespace llvm {
class MCOperand;
class MBlazeInstPrinter : public MCInstPrinter {
public:
MBlazeInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo);
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
void printFSLImm(const MCInst *MI, int OpNo, raw_ostream &O);
void printUnsignedImm(const MCInst *MI, int OpNo, raw_ostream &O);
void printMemOperand(const MCInst *MI, int OpNo,raw_ostream &O,
const char *Modifier = 0);
};
}
#endif

View File

@ -1,16 +0,0 @@
##===- lib/Target/MBlaze/AsmPrinter/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 = LLVMMBlazeAsmPrinter
# Hack: we need to include 'main' MBlaze target directory to grab
# private headers
CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common

View File

@ -1,34 +0,0 @@
;===- ./lib/Target/MBlaze/LLVMBuild.txt ------------------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[common]
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
name = MBlaze
parent = Target
has_asmparser = 1
has_asmprinter = 1
has_disassembler = 1
[component_1]
type = Library
name = MBlazeCodeGen
parent = MBlaze
required_libraries = AsmPrinter CodeGen Core MBlazeAsmPrinter MBlazeDesc MBlazeInfo MC SelectionDAG Support Target
add_to_library_groups = MBlaze

View File

@ -1,32 +0,0 @@
//===-- MBlaze.h - Top-level interface for MBlaze ---------------*- 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 MBlaze back-end.
//
//===----------------------------------------------------------------------===//
#ifndef TARGET_MBLAZE_H
#define TARGET_MBLAZE_H
#include "MCTargetDesc/MBlazeBaseInfo.h"
#include "MCTargetDesc/MBlazeMCTargetDesc.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MBlazeTargetMachine;
class FunctionPass;
class MachineCodeEmitter;
FunctionPass *createMBlazeISelDag(MBlazeTargetMachine &TM);
FunctionPass *createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &TM);
} // end namespace llvm;
#endif

View File

@ -1,73 +0,0 @@
//===-- MBlaze.td - Describe the MBlaze Target Machine -----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This is the top level entry point for the MBlaze target.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Target-independent interfaces
//===----------------------------------------------------------------------===//
include "llvm/Target/Target.td"
//===----------------------------------------------------------------------===//
// Register File, Calling Conv, Instruction Descriptions
//===----------------------------------------------------------------------===//
include "MBlazeRegisterInfo.td"
include "MBlazeSchedule.td"
include "MBlazeIntrinsics.td"
include "MBlazeInstrInfo.td"
include "MBlazeCallingConv.td"
def MBlazeInstrInfo : InstrInfo;
//===----------------------------------------------------------------------===//
// Microblaze Subtarget features //
//===----------------------------------------------------------------------===//
def FeatureBarrel : SubtargetFeature<"barrel", "HasBarrel", "true",
"Implements barrel shifter">;
def FeatureDiv : SubtargetFeature<"div", "HasDiv", "true",
"Implements hardware divider">;
def FeatureMul : SubtargetFeature<"mul", "HasMul", "true",
"Implements hardware multiplier">;
def FeaturePatCmp : SubtargetFeature<"patcmp", "HasPatCmp", "true",
"Implements pattern compare instruction">;
def FeatureFPU : SubtargetFeature<"fpu", "HasFPU", "true",
"Implements floating point unit">;
def FeatureMul64 : SubtargetFeature<"mul64", "HasMul64", "true",
"Implements multiplier with 64-bit result">;
def FeatureSqrt : SubtargetFeature<"sqrt", "HasSqrt", "true",
"Implements sqrt and floating point convert">;
//===----------------------------------------------------------------------===//
// MBlaze processors supported.
//===----------------------------------------------------------------------===//
def : Processor<"mblaze", NoItineraries, []>;
def : Processor<"mblaze3", MBlazePipe3Itineraries, []>;
def : Processor<"mblaze5", MBlazePipe5Itineraries, []>;
//===----------------------------------------------------------------------===//
// Instruction Descriptions
//===----------------------------------------------------------------------===//
def MBlazeAsmWriter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
bit isMCAsmWriter = 1;
}
//===----------------------------------------------------------------------===//
// Target Declaration
//===----------------------------------------------------------------------===//
def MBlaze : Target {
let InstructionSet = MBlazeInstrInfo;
let AssemblyWriters = [MBlazeAsmWriter];
}

View File

@ -1,326 +0,0 @@
//===-- MBlazeAsmPrinter.cpp - MBlaze 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 MBlaze assembly language.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-asm-printer"
#include "MBlaze.h"
#include "InstPrinter/MBlazeInstPrinter.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeMCInstLower.h"
#include "MBlazeMachineFunction.h"
#include "MBlazeSubtarget.h"
#include "MBlazeTargetMachine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include <cctype>
using namespace llvm;
namespace {
class MBlazeAsmPrinter : public AsmPrinter {
const MBlazeSubtarget *Subtarget;
public:
explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
: AsmPrinter(TM, Streamer) {
Subtarget = &TM.getSubtarget<MBlazeSubtarget>();
}
virtual const char *getPassName() const {
return "MBlaze Assembly Printer";
}
void printSavedRegsBitmask();
void emitFrameDirective();
virtual void EmitFunctionBodyStart();
virtual void EmitFunctionBodyEnd();
virtual void EmitFunctionEntryLabel();
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
const;
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O);
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
void EmitInstruction(const MachineInstr *MI);
};
} // end of anonymous namespace
// #include "MBlazeGenAsmWriter.inc"
//===----------------------------------------------------------------------===//
//
// MBlaze Asm Directives
//
// -- Frame directive "frame Stackpointer, Stacksize, RARegister"
// Describe the stack frame.
//
// -- Mask directives "mask bitmask, offset"
// Tells the assembler which registers are saved and where.
// bitmask - contain a little endian bitset indicating which registers are
// saved on function prologue (e.g. with a 0x80000000 mask, the
// assembler knows the register 31 (RA) is saved at prologue.
// offset - the position before stack pointer subtraction indicating where
// the first saved register on prologue is located. (e.g. with a
//
// Consider the following function prologue:
//
// .frame R19,48,R15
// .mask 0xc0000000,-8
// addiu R1, R1, -48
// sw R15, 40(R1)
// sw R19, 36(R1)
//
// With a 0xc0000000 mask, the assembler knows the register 15 (R15) and
// 19 (R19) are saved at prologue. As the save order on prologue is from
// left to right, R15 is saved first. A -8 offset means that after the
// stack pointer subtration, the first register in the mask (R15) will be
// saved at address 48-8=40.
//
//===----------------------------------------------------------------------===//
// Print a 32 bit hex number with all numbers.
static void printHex32(unsigned int Value, raw_ostream &O) {
O << "0x";
for (int i = 7; i >= 0; i--)
O.write_hex((Value & (0xF << (i*4))) >> (i*4));
}
// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
void MBlazeAsmPrinter::printSavedRegsBitmask() {
const TargetFrameLowering *TFI = TM.getFrameLowering();
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
// CPU Saved Registers Bitmasks
unsigned int CPUBitmask = 0;
// Set the CPU Bitmasks
const MachineFrameInfo *MFI = MF->getFrameInfo();
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
unsigned RegNum = getMBlazeRegisterNumbering(Reg);
if (MBlaze::GPRRegClass.contains(Reg))
CPUBitmask |= (1 << RegNum);
}
// Return Address and Frame registers must also be set in CPUBitmask.
if (TFI->hasFP(*MF))
CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getFrameRegister(*MF)));
if (MFI->adjustsStack())
CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getRARegister()));
// Print CPUBitmask
OutStreamer.EmitRawText("\t.mask\t0x" + Twine::utohexstr(CPUBitmask));
}
/// Frame Directive
void MBlazeAsmPrinter::emitFrameDirective() {
if (!OutStreamer.hasRawTextSupport())
return;
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
unsigned stkReg = RI.getFrameRegister(*MF);
unsigned retReg = RI.getRARegister();
unsigned stkSze = MF->getFrameInfo()->getStackSize();
OutStreamer.EmitRawText("\t.frame\t" +
Twine(MBlazeInstPrinter::getRegisterName(stkReg)) +
"," + Twine(stkSze) + "," +
Twine(MBlazeInstPrinter::getRegisterName(retReg)));
}
void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
if (OutStreamer.hasRawTextSupport())
OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
AsmPrinter::EmitFunctionEntryLabel();
}
void MBlazeAsmPrinter::EmitFunctionBodyStart() {
if (!OutStreamer.hasRawTextSupport())
return;
emitFrameDirective();
printSavedRegsBitmask();
}
void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
if (OutStreamer.hasRawTextSupport())
OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
}
//===----------------------------------------------------------------------===//
void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MBlazeMCInstLower MCInstLowering(OutContext, *this);
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
OutStreamer.EmitInstruction(TmpInst);
}
// Print out an operand for an inline asm expression.
bool MBlazeAsmPrinter::
PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0])
if (ExtraCode[1] != 0) return true; // Unknown modifier.
switch (ExtraCode[0]) {
default:
// See if this is a generic print operand
return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
}
printOperand(MI, OpNo, O);
return false;
}
void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
switch (MO.getType()) {
case MachineOperand::MO_Register:
O << MBlazeInstPrinter::getRegisterName(MO.getReg());
break;
case MachineOperand::MO_Immediate:
O << (int32_t)MO.getImm();
break;
case MachineOperand::MO_FPImmediate: {
const ConstantFP *fp = MO.getFPImm();
printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O);
O << ";\t# immediate = " << *fp;
break;
}
case MachineOperand::MO_MachineBasicBlock:
O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_GlobalAddress:
O << *Mang->getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << MO.getIndex();
break;
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI"
<< getFunctionNumber() << "_" << MO.getIndex();
if (MO.getOffset())
O << "+" << MO.getOffset();
break;
default:
llvm_unreachable("<unknown operand type>");
}
}
void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.isImm())
O << (uint32_t)MO.getImm();
else
printOperand(MI, opNum, O);
}
void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum,
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.isImm())
O << "rfsl" << (unsigned int)MO.getImm();
else
printOperand(MI, opNum, O);
}
void MBlazeAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier) {
printOperand(MI, opNum, O);
O << ", ";
printOperand(MI, opNum+1, O);
}
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
bool MBlazeAsmPrinter::
isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isLandingPad() || MBB->pred_empty())
return false;
// If there isn't exactly one predecessor, it can't be a fall through.
MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
++PI2;
if (PI2 != MBB->pred_end())
return false;
// The predecessor has to be immediately before this block.
const MachineBasicBlock *Pred = *PI;
if (!Pred->isLayoutSuccessor(MBB))
return false;
// If the block is completely empty, then it definitely does fall through.
if (Pred->empty())
return true;
// Check if the last terminator is an unconditional branch.
MachineBasicBlock::const_iterator I = Pred->end();
while (I != Pred->begin() && !(--I)->isTerminator())
; // Noop
return I == Pred->end() || !I->isBarrier();
}
// Force static initialization.
extern "C" void LLVMInitializeMBlazeAsmPrinter() {
RegisterAsmPrinter<MBlazeAsmPrinter> X(TheMBlazeTarget);
}

View File

@ -1,24 +0,0 @@
//===- MBlazeCallingConv.td - Calling Conventions for MBlaze -*- 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 MBlaze architecture.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze ABI Calling Convention
//===----------------------------------------------------------------------===//
def RetCC_MBlaze : CallingConv<[
// i32 are returned in registers R3, R4
CCIfType<[i32,f32], CCAssignToReg<[R3, R4]>>
]>;
def CC_MBlaze : CallingConv<[
CCIfType<[i32,f32], CCCustom<"CC_MBlaze_AssignReg">>,
CCIfType<[i32,f32], CCAssignToStack<4, 4>>
]>;

View File

@ -1,252 +0,0 @@
//===-- DelaySlotFiller.cpp - MBlaze delay slot filler --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// A pass that attempts to fill instructions with delay slots. If no
// instructions can be moved into the delay slot then a NOP is placed there.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "delay-slot-filler"
#include "MBlaze.h"
#include "MBlazeTargetMachine.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;
STATISTIC(FilledSlots, "Number of delay slots filled");
static cl::opt<bool> MBDisableDelaySlotFiller(
"disable-mblaze-delay-filler",
cl::init(false),
cl::desc("Disable the MBlaze delay slot filter."),
cl::Hidden);
namespace {
struct Filler : public MachineFunctionPass {
TargetMachine &TM;
static char ID;
Filler(TargetMachine &tm)
: MachineFunctionPass(ID), TM(tm) { }
virtual const char *getPassName() const {
return "MBlaze Delay Slot Filler";
}
bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
bool runOnMachineFunction(MachineFunction &F) {
bool Changed = false;
for (MachineFunction::iterator FI = F.begin(), FE = F.end();
FI != FE; ++FI)
Changed |= runOnMachineBasicBlock(*FI);
return Changed;
}
};
char Filler::ID = 0;
} // end of anonymous namespace
static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
// Any instruction with an immediate mode operand greater than
// 16-bits requires an implicit IMM instruction.
unsigned numOper = candidate->getNumOperands();
for (unsigned op = 0; op < numOper; ++op) {
MachineOperand &mop = candidate->getOperand(op);
// The operand requires more than 16-bits to represent.
if (mop.isImm() && (mop.getImm() < -0x8000 || mop.getImm() > 0x7fff))
return true;
// We must assume that unknown immediate values require more than
// 16-bits to represent.
if (mop.isGlobal() || mop.isSymbol() || mop.isJTI() || mop.isCPI())
return true;
// FIXME: we could probably check to see if the FP value happens
// to not need an IMM instruction. For now we just always
// assume that FP values do.
if (mop.isFPImm())
return true;
}
return false;
}
static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) {
switch (instr->getOpcode()) {
default: return instr->getNumOperands();
// These instructions have a variable number of operands but the first two
// are the "real" operands that we care about during hazard detection.
case MBlaze::BRLID:
case MBlaze::BRALID:
case MBlaze::BRLD:
case MBlaze::BRALD:
return 2;
}
}
static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
MachineBasicBlock::iterator &slot) {
// Hazard check
MachineBasicBlock::iterator a = candidate;
MachineBasicBlock::iterator b = slot;
// MBB layout:-
// candidate := a0 = operation(a1, a2)
// ...middle bit...
// slot := b0 = operation(b1, b2)
// Possible hazards:-/
// 1. a1 or a2 was written during the middle bit
// 2. a0 was read or written during the middle bit
// 3. a0 is one or more of {b0, b1, b2}
// 4. b0 is one or more of {a1, a2}
// 5. a accesses memory, and the middle bit
// contains a store operation.
bool a_is_memory = candidate->mayLoad() || candidate->mayStore();
// Determine the number of operands in the slot instruction and in the
// candidate instruction.
const unsigned aend = getLastRealOperand(a);
const unsigned bend = getLastRealOperand(b);
// Check hazards type 1, 2 and 5 by scanning the middle bit
MachineBasicBlock::iterator m = a;
for (++m; m != b; ++m) {
for (unsigned aop = 0; aop<aend; ++aop) {
bool aop_is_reg = a->getOperand(aop).isReg();
if (!aop_is_reg) continue;
bool aop_is_def = a->getOperand(aop).isDef();
unsigned aop_reg = a->getOperand(aop).getReg();
const unsigned mend = getLastRealOperand(m);
for (unsigned mop = 0; mop<mend; ++mop) {
bool mop_is_reg = m->getOperand(mop).isReg();
if (!mop_is_reg) continue;
bool mop_is_def = m->getOperand(mop).isDef();
unsigned mop_reg = m->getOperand(mop).getReg();
if (aop_is_def && (mop_reg == aop_reg))
return true; // Hazard type 2, because aop = a0
else if (mop_is_def && (mop_reg == aop_reg))
return true; // Hazard type 1, because aop in {a1, a2}
}
}
// Check hazard type 5
if (a_is_memory && m->mayStore())
return true;
}
// Check hazard type 3 & 4
for (unsigned aop = 0; aop<aend; ++aop) {
if (a->getOperand(aop).isReg()) {
unsigned aop_reg = a->getOperand(aop).getReg();
for (unsigned bop = 0; bop<bend; ++bop) {
if (b->getOperand(bop).isReg() && !b->getOperand(bop).isImplicit()) {
unsigned bop_reg = b->getOperand(bop).getReg();
if (aop_reg == bop_reg)
return true;
}
}
}
}
return false;
}
static bool isDelayFiller(MachineBasicBlock &MBB,
MachineBasicBlock::iterator candidate) {
if (candidate == MBB.begin())
return false;
--candidate;
return (candidate->hasDelaySlot());
}
static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I) {
if (!I->hasUnmodeledSideEffects())
return false;
unsigned op = I->getOpcode();
if (op == MBlaze::ADDK || op == MBlaze::ADDIK ||
op == MBlaze::ADDC || op == MBlaze::ADDIC ||
op == MBlaze::ADDKC || op == MBlaze::ADDIKC ||
op == MBlaze::RSUBK || op == MBlaze::RSUBIK ||
op == MBlaze::RSUBC || op == MBlaze::RSUBIC ||
op == MBlaze::RSUBKC || op == MBlaze::RSUBIKC)
return false;
return true;
}
static MachineBasicBlock::iterator
findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator slot) {
MachineBasicBlock::iterator I = slot;
while (true) {
if (I == MBB.begin())
break;
--I;
if (I->hasDelaySlot() || I->isBranch() || isDelayFiller(MBB,I) ||
I->isCall() || I->isReturn() || I->isBarrier() ||
hasUnknownSideEffects(I))
break;
if (hasImmInstruction(I) || delayHasHazard(I,slot))
continue;
return I;
}
return MBB.end();
}
/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
/// Currently, we fill delay slots with NOPs. We assume there is only one
/// delay slot per delayed instruction.
bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
bool Changed = false;
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
if (I->hasDelaySlot()) {
MachineBasicBlock::iterator D = MBB.end();
MachineBasicBlock::iterator J = I;
if (!MBDisableDelaySlotFiller)
D = findDelayInstr(MBB,I);
++FilledSlots;
Changed = true;
if (D == MBB.end())
BuildMI(MBB, ++J, I->getDebugLoc(),TM.getInstrInfo()->get(MBlaze::NOP));
else
MBB.splice(++J, &MBB, D);
}
return Changed;
}
/// createMBlazeDelaySlotFillerPass - Returns a pass that fills in delay
/// slots in MBlaze MachineFunctions
FunctionPass *llvm::createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &tm) {
return new Filler(tm);
}

View File

@ -1,488 +0,0 @@
//===-- MBlazeFrameLowering.cpp - MBlaze Frame Information ---------------====//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MBlaze implementation of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-frame-lowering"
#include "MBlazeFrameLowering.h"
#include "InstPrinter/MBlazeInstPrinter.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeMachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
static cl::opt<bool> MBDisableStackAdjust(
"disable-mblaze-stack-adjust",
cl::init(false),
cl::desc("Disable MBlaze stack layout adjustment."),
cl::Hidden);
static void replaceFrameIndexes(MachineFunction &MF,
SmallVectorImpl<std::pair<int,int64_t> > &FR) {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
const SmallVectorImpl<std::pair<int,int64_t> >::iterator FRB = FR.begin();
const SmallVectorImpl<std::pair<int,int64_t> >::iterator FRE = FR.end();
SmallVectorImpl<std::pair<int,int64_t> >::iterator FRI = FRB;
for (; FRI != FRE; ++FRI) {
MFI->RemoveStackObject(FRI->first);
int NFI = MFI->CreateFixedObject(4, FRI->second, true);
MBlazeFI->recordReplacement(FRI->first, NFI);
for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) {
MachineBasicBlock::iterator MBB = MB->begin();
const MachineBasicBlock::iterator MBE = MB->end();
for (; MBB != MBE; ++MBB) {
MachineInstr::mop_iterator MIB = MBB->operands_begin();
const MachineInstr::mop_iterator MIE = MBB->operands_end();
for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) {
if (!MII->isFI() || MII->getIndex() != FRI->first) continue;
DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n");
MII->setIndex(NFI);
}
}
}
}
}
//===----------------------------------------------------------------------===//
//
// Stack Frame Processing methods
// +----------------------------+
//
// The stack is allocated decrementing the stack pointer on
// the first instruction of a function prologue. Once decremented,
// all stack references are are done through a positive offset
// from the stack/frame pointer, so the stack is considered
// to grow up.
//
//===----------------------------------------------------------------------===//
static void analyzeFrameIndexes(MachineFunction &MF) {
if (MBDisableStackAdjust) return;
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
const MachineRegisterInfo &MRI = MF.getRegInfo();
MachineRegisterInfo::livein_iterator LII = MRI.livein_begin();
MachineRegisterInfo::livein_iterator LIE = MRI.livein_end();
const SmallVectorImpl<int> &LiveInFI = MBlazeFI->getLiveIn();
SmallVector<MachineInstr*, 16> EraseInstr;
SmallVector<std::pair<int,int64_t>, 16> FrameRelocate;
MachineBasicBlock *MBB = MF.getBlockNumbered(0);
MachineBasicBlock::iterator MIB = MBB->begin();
MachineBasicBlock::iterator MIE = MBB->end();
int StackAdjust = 0;
int StackOffset = -28;
// In this loop we are searching frame indexes that corrospond to incoming
// arguments that are already in the stack. We look for instruction sequences
// like the following:
//
// LWI REG, FI1, 0
// ...
// SWI REG, FI2, 0
//
// As long as there are no defs of REG in the ... part, we can eliminate
// the SWI instruction because the value has already been stored to the
// stack by the caller. All we need to do is locate FI at the correct
// stack location according to the calling convensions.
//
// Additionally, if the SWI operation kills the def of REG then we don't
// need the LWI operation so we can erase it as well.
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
I->getOperand(1).getIndex() != LiveInFI[i]) continue;
unsigned FIReg = I->getOperand(0).getReg();
MachineBasicBlock::iterator SI = I;
for (SI++; SI != MIE; ++SI) {
if (!SI->getOperand(0).isReg() ||
!SI->getOperand(1).isFI() ||
SI->getOpcode() != MBlaze::SWI) continue;
int FI = SI->getOperand(1).getIndex();
if (SI->getOperand(0).getReg() != FIReg ||
MFI->isFixedObjectIndex(FI) ||
MFI->getObjectSize(FI) != 4) continue;
if (SI->getOperand(0).isDef()) break;
if (SI->getOperand(0).isKill()) {
DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex()
<< " removed\n");
EraseInstr.push_back(I);
}
EraseInstr.push_back(SI);
DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n");
FrameRelocate.push_back(std::make_pair(FI,StackOffset));
DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n");
StackOffset -= 4;
StackAdjust += 4;
break;
}
}
}
// In this loop we are searching for frame indexes that corrospond to
// incoming arguments that are in registers. We look for instruction
// sequences like the following:
//
// ... SWI REG, FI, 0
//
// As long as the ... part does not define REG and if REG is an incoming
// parameter register then we know that, according to ABI convensions, the
// caller has allocated stack space for it already. Instead of allocating
// stack space on our frame, we record the correct location in the callers
// frame.
for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
if (I->definesRegister(LI->first))
break;
if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
!I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
I->getOperand(1).getIndex() < 0) continue;
if (I->getOperand(0).getReg() == LI->first) {
int FI = I->getOperand(1).getIndex();
MBlazeFI->recordLiveIn(FI);
int FILoc = 0;
switch (LI->first) {
default: llvm_unreachable("invalid incoming parameter!");
case MBlaze::R5: FILoc = -4; break;
case MBlaze::R6: FILoc = -8; break;
case MBlaze::R7: FILoc = -12; break;
case MBlaze::R8: FILoc = -16; break;
case MBlaze::R9: FILoc = -20; break;
case MBlaze::R10: FILoc = -24; break;
}
StackAdjust += 4;
FrameRelocate.push_back(std::make_pair(FI,FILoc));
DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n");
break;
}
}
}
// Go ahead and erase all of the instructions that we determined were
// no longer needed.
for (int i = 0, e = EraseInstr.size(); i < e; ++i)
MBB->erase(EraseInstr[i]);
// Replace all of the frame indexes that we have relocated with new
// fixed object frame indexes.
replaceFrameIndexes(MF, FrameRelocate);
}
static void interruptFrameLayout(MachineFunction &MF) {
const Function *F = MF.getFunction();
CallingConv::ID CallConv = F->getCallingConv();
// If this function is not using either the interrupt_handler
// calling convention or the save_volatiles calling convention
// then we don't need to do any additional frame layout.
if (CallConv != CallingConv::MBLAZE_INTR &&
CallConv != CallingConv::MBLAZE_SVOL)
return;
MachineFrameInfo *MFI = MF.getFrameInfo();
const MachineRegisterInfo &MRI = MF.getRegInfo();
const MBlazeInstrInfo &TII =
*static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
// Determine if the calling convention is the interrupt_handler
// calling convention. Some pieces of the prologue and epilogue
// only need to be emitted if we are lowering and interrupt handler.
bool isIntr = CallConv == CallingConv::MBLAZE_INTR;
// Determine where to put prologue and epilogue additions
MachineBasicBlock &MENT = MF.front();
MachineBasicBlock &MEXT = MF.back();
MachineBasicBlock::iterator MENTI = MENT.begin();
MachineBasicBlock::iterator MEXTI = prior(MEXT.end());
DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc();
DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc();
// Store the frame indexes generated during prologue additions for use
// when we are generating the epilogue additions.
SmallVector<int, 10> VFI;
// Build the prologue SWI for R3 - R12 if needed. Note that R11 must
// always have a SWI because it is used when processing RMSR.
for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) {
if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue;
int FI = MFI->CreateStackObject(4,4,false,false);
VFI.push_back(FI);
BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r)
.addFrameIndex(FI).addImm(0);
}
// Build the prologue SWI for R17, R18
int R17FI = MFI->CreateStackObject(4,4,false,false);
int R18FI = MFI->CreateStackObject(4,4,false,false);
BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17)
.addFrameIndex(R17FI).addImm(0);
BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18)
.addFrameIndex(R18FI).addImm(0);
// Buid the prologue SWI and the epilogue LWI for RMSR if needed
if (isIntr) {
int MSRFI = MFI->CreateStackObject(4,4,false,false);
BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11)
.addReg(MBlaze::RMSR);
BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11)
.addFrameIndex(MSRFI).addImm(0);
BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11)
.addFrameIndex(MSRFI).addImm(0);
BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR)
.addReg(MBlaze::R11);
}
// Build the epilogue LWI for R17, R18
BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18)
.addFrameIndex(R18FI).addImm(0);
BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17)
.addFrameIndex(R17FI).addImm(0);
// Build the epilogue LWI for R3 - R12 if needed
for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) {
if (!MRI.isPhysRegUsed(r)) continue;
BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r)
.addFrameIndex(VFI[--i]).addImm(0);
}
}
static void determineFrameLayout(MachineFunction &MF) {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
// Replace the dummy '0' SPOffset by the negative offsets, as explained on
// LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
// the approach done by calculateFrameObjectOffsets to the stack frame.
MBlazeFI->adjustLoadArgsFI(MFI);
MBlazeFI->adjustStoreVarArgsFI(MFI);
// Get the number of bytes to allocate from the FrameInfo
unsigned FrameSize = MFI->getStackSize();
DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" );
// Get the alignments provided by the target, and the maximum alignment
// (if any) of the fixed frame objects.
// unsigned MaxAlign = MFI->getMaxAlignment();
unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
unsigned AlignMask = TargetAlign - 1;
// Make sure the frame is aligned.
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
MFI->setStackSize(FrameSize);
DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" );
}
int MBlazeFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI)
const {
const MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
if (MBlazeFI->hasReplacement(FI))
FI = MBlazeFI->getReplacement(FI);
return TargetFrameLowering::getFrameIndexOffset(MF,FI);
}
// 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 MBlazeFrameLowering::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
MFI->hasVarSizedObjects();
}
void MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
const MBlazeInstrInfo &TII =
*static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
// Determine the correct frame layout
determineFrameLayout(MF);
// Get the number of bytes to allocate from the FrameInfo.
unsigned StackSize = MFI->getStackSize();
// No need to allocate space on the stack.
if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return;
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
// Adjust stack : addi R1, R1, -imm
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1)
.addReg(MBlaze::R1).addImm(-StackSize);
// swi R15, R1, stack_loc
if (MFI->adjustsStack() || requiresRA) {
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset);
}
if (hasFP(MF)) {
// swi R19, R1, stack_loc
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
.addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset);
// add R19, R1, R0
BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
.addReg(MBlaze::R1).addReg(MBlaze::R0);
}
}
void MBlazeFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
const MBlazeInstrInfo &TII =
*static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
DebugLoc dl = MBBI->getDebugLoc();
CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
// Get the FI's where RA and FP are saved.
int FPOffset = MBlazeFI->getFPStackOffset();
int RAOffset = MBlazeFI->getRAStackOffset();
if (hasFP(MF)) {
// add R1, R19, R0
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
.addReg(MBlaze::R19).addReg(MBlaze::R0);
// lwi R19, R1, stack_loc
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
.addReg(MBlaze::R1).addImm(FPOffset);
}
// lwi R15, R1, stack_loc
if (MFI->adjustsStack() || requiresRA) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
.addReg(MBlaze::R1).addImm(RAOffset);
}
// Get the number of bytes from FrameInfo
int StackSize = (int) MFI->getStackSize();
// addi R1, R1, imm
if (StackSize) {
BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1)
.addReg(MBlaze::R1).addImm(StackSize);
}
}
// Eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
void MBlazeFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MBlazeInstrInfo &TII =
*static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
// If we have a frame pointer, turn the adjcallstackup instruction into a
// 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into
// 'addi r1, r1, <amt>'
MachineInstr *Old = I;
int Amount = Old->getOperand(0).getImm() + 4;
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
MachineInstr *New;
if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(-Amount);
} else {
assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(Amount);
}
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
void MBlazeFrameLowering::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
if (MFI->adjustsStack() || requiresRA) {
MBlazeFI->setRAStackOffset(0);
MFI->CreateFixedObject(4,0,true);
}
if (hasFP(MF)) {
MBlazeFI->setFPStackOffset(4);
MFI->CreateFixedObject(4,4,true);
}
interruptFrameLayout(MF);
analyzeFrameIndexes(MF);
}

View File

@ -1,56 +0,0 @@
//=- MBlazeFrameLowering.h - Define frame lowering for MicroBlaze -*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZE_FRAMEINFO_H
#define MBLAZE_FRAMEINFO_H
#include "MBlaze.h"
#include "llvm/Target/TargetFrameLowering.h"
namespace llvm {
class MBlazeSubtarget;
class MBlazeFrameLowering : public TargetFrameLowering {
protected:
const MBlazeSubtarget &STI;
public:
explicit MBlazeFrameLowering(const MBlazeSubtarget &sti)
: TargetFrameLowering(TargetFrameLowering::StackGrowsUp, 4, 0), STI(sti) {
}
/// targetHandlesStackFrameRounding - Returns true if the target is
/// responsible for rounding up the stack frame (probably at emitPrologue
/// time).
bool targetHandlesStackFrameRounding() const { return true; }
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool hasFP(const MachineFunction &MF) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const;
};
} // End llvm namespace
#endif

View File

@ -1,278 +0,0 @@
//===-- MBlazeISelDAGToDAG.cpp - A dag to dag inst selector for MBlaze ----===//
//
// 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 MBlaze target.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-isel"
#include "MBlaze.h"
#include "MBlazeMachineFunction.h"
#include "MBlazeRegisterInfo.h"
#include "MBlazeSubtarget.h"
#include "MBlazeTargetMachine.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine
// instructions for SelectionDAG operations.
//===----------------------------------------------------------------------===//
namespace {
class MBlazeDAGToDAGISel : public SelectionDAGISel {
/// TM - Keep a reference to MBlazeTargetMachine.
MBlazeTargetMachine &TM;
/// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can
/// make the right decision when generating code for different targets.
const MBlazeSubtarget &Subtarget;
public:
explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) :
SelectionDAGISel(tm),
TM(tm), Subtarget(tm.getSubtarget<MBlazeSubtarget>()) {}
// Pass Name
virtual const char *getPassName() const {
return "MBlaze DAG->DAG Pattern Instruction Selection";
}
private:
// Include the pieces autogenerated from the target description.
#include "MBlazeGenDAGISel.inc"
/// getTargetMachine - Return a reference to the TargetMachine, casted
/// to the target-specific type.
const MBlazeTargetMachine &getTargetMachine() {
return static_cast<const MBlazeTargetMachine &>(TM);
}
/// getInstrInfo - Return a reference to the TargetInstrInfo, casted
/// to the target-specific type.
const MBlazeInstrInfo *getInstrInfo() {
return getTargetMachine().getInstrInfo();
}
SDNode *getGlobalBaseReg();
SDNode *Select(SDNode *N);
// Address Selection
bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index);
bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base);
// getI32Imm - Return a target constant with the specified value, of type i32.
inline SDValue getI32Imm(unsigned Imm) {
return CurDAG->getTargetConstant(Imm, MVT::i32);
}
};
}
/// isIntS32Immediate - This method tests to see if the node is either a 32-bit
/// or 64-bit immediate, and if the value can be accurately represented as a
/// sign extension from a 32-bit value. If so, this returns true and the
/// immediate.
static bool isIntS32Immediate(SDNode *N, int32_t &Imm) {
unsigned Opc = N->getOpcode();
if (Opc != ISD::Constant)
return false;
Imm = (int32_t)cast<ConstantSDNode>(N)->getZExtValue();
if (N->getValueType(0) == MVT::i32)
return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue();
else
return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue();
}
static bool isIntS32Immediate(SDValue Op, int32_t &Imm) {
return isIntS32Immediate(Op.getNode(), Imm);
}
/// SelectAddressRegReg - Given the specified addressed, check to see if it
/// can be represented as an indexed [r+r] operation. Returns false if it
/// can be more efficiently represented with [r+imm].
bool MBlazeDAGToDAGISel::
SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
if (N.getOpcode() == ISD::FrameIndex) return false;
if (N.getOpcode() == ISD::TargetExternalSymbol ||
N.getOpcode() == ISD::TargetGlobalAddress)
return false; // direct calls.
int32_t imm = 0;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
if (isIntS32Immediate(N.getOperand(1), imm))
return false; // r+i
if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
return false; // jump tables.
Base = N.getOperand(0);
Index = N.getOperand(1);
return true;
}
return false;
}
/// Returns true if the address N can be represented by a base register plus
/// a signed 32-bit displacement [r+imm], and if it is not better
/// represented as reg+reg.
bool MBlazeDAGToDAGISel::
SelectAddrRegImm(SDValue N, SDValue &Base, SDValue &Disp) {
// If this can be more profitably realized as r+r, fail.
if (SelectAddrRegReg(N, Base, Disp))
return false;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
int32_t imm = 0;
if (isIntS32Immediate(N.getOperand(1), imm)) {
Disp = CurDAG->getTargetConstant(imm, MVT::i32);
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
} else {
Base = N.getOperand(0);
}
return true; // [r+i]
}
} else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
// Loading from a constant address.
uint32_t Imm = CN->getZExtValue();
Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0));
Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0));
return true;
}
Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy());
if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
else
Base = N;
return true; // [r+0]
}
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
SDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() {
unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
return CurDAG->getRegister(GlobalBaseReg,
getTargetLowering()->getPointerTy()).getNode();
}
/// Select instructions not customized! Used for
/// expanded, promoted and normal instructions
SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
unsigned Opcode = Node->getOpcode();
SDLoc dl(Node);
// If we have a custom node, we already have selected!
if (Node->isMachineOpcode())
return NULL;
///
// Instruction Selection not handled by the auto-generated
// tablegen selection should be handled here.
///
switch (Opcode) {
default: break;
// Get target GOT address.
case ISD::GLOBAL_OFFSET_TABLE:
return getGlobalBaseReg();
case ISD::FrameIndex: {
SDValue imm = CurDAG->getTargetConstant(0, MVT::i32);
int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex();
EVT VT = Node->getValueType(0);
SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
unsigned Opc = MBlaze::ADDIK;
if (Node->hasOneUse())
return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm);
return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm);
}
/// Handle direct and indirect calls when using PIC. On PIC, when
/// GOT is smaller than about 64k (small code) the GA target is
/// loaded with only one instruction. Otherwise GA's target must
/// be loaded with 3 instructions.
case MBlazeISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
SDValue Chain = Node->getOperand(0);
SDValue Callee = Node->getOperand(1);
SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32);
SDValue InFlag(0, 0);
if ((isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)))
{
/// Direct call for global addresses and external symbols
SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32);
// Use load to get GOT target
SDValue Ops[] = { Callee, GPReg, Chain };
SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl,
MVT::i32, MVT::Other, Ops), 0);
Chain = Load.getValue(1);
// Call target must be on T9
Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag);
} else
/// Indirect call
Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag);
// Emit Jump and Link Register
SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other,
MVT::Glue, R20Reg, Chain);
Chain = SDValue(ResNode, 0);
InFlag = SDValue(ResNode, 1);
ReplaceUses(SDValue(Node, 0), Chain);
ReplaceUses(SDValue(Node, 1), InFlag);
return ResNode;
}
}
}
// Select the default instruction
SDNode *ResNode = SelectCode(Node);
DEBUG(errs() << "=> ");
if (ResNode == NULL || ResNode == Node)
DEBUG(Node->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DEBUG(errs() << "\n");
return ResNode;
}
/// createMBlazeISelDag - This pass converts a legalized DAG into a
/// MBlaze-specific DAG, ready for instruction scheduling.
FunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) {
return new MBlazeDAGToDAGISel(TM);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +0,0 @@
//===-- MBlazeISelLowering.h - MBlaze 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 MBlaze uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//
#ifndef MBlazeISELLOWERING_H
#define MBlazeISELLOWERING_H
#include "MBlaze.h"
#include "MBlazeSubtarget.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetLowering.h"
namespace llvm {
namespace MBlazeCC {
enum CC {
FIRST = 0,
EQ,
NE,
GT,
LT,
GE,
LE
};
inline static CC getOppositeCondition(CC cc) {
switch (cc) {
default: llvm_unreachable("Unknown condition code");
case EQ: return NE;
case NE: return EQ;
case GT: return LE;
case LT: return GE;
case GE: return LT;
case LE: return GE;
}
}
inline static const char *MBlazeCCToString(CC cc) {
switch (cc) {
default: llvm_unreachable("Unknown condition code");
case EQ: return "eq";
case NE: return "ne";
case GT: return "gt";
case LT: return "lt";
case GE: return "ge";
case LE: return "le";
}
}
}
namespace MBlazeISD {
enum NodeType {
// Start the numbering from where ISD NodeType finishes.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
// Jump and link (call)
JmpLink,
// Handle gp_rel (small data/bss sections) relocation.
GPRel,
// Select CC Pseudo Instruction
Select_CC,
// Wrap up multiple types of instructions
Wrap,
// Integer Compare
ICmp,
// Return from subroutine
Ret,
// Return from interrupt
IRet
};
}
//===--------------------------------------------------------------------===//
// TargetLowering Implementation
//===--------------------------------------------------------------------===//
class MBlazeTargetLowering : public TargetLowering {
public:
explicit MBlazeTargetLowering(MBlazeTargetMachine &TM);
/// LowerOperation - Provide custom lowering hooks for some operations.
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
/// getTargetNodeName - This method returns the name of a target specific
// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
/// getSetCCResultType - get the ISD::SETCC result ValueType
EVT getSetCCResultType(LLVMContext &Context, EVT VT) const;
private:
// Subtarget Info
const MBlazeSubtarget *Subtarget;
// Lower Operand helpers
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
// Lower Operand specifics
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
virtual SDValue
LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
virtual SDValue
LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const;
virtual SDValue
LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
SDLoc dl, SelectionDAG &DAG) const;
virtual MachineBasicBlock*
EmitCustomShift(MachineInstr *MI, MachineBasicBlock *MBB) const;
virtual MachineBasicBlock*
EmitCustomSelect(MachineInstr *MI, MachineBasicBlock *MBB) const;
virtual MachineBasicBlock*
EmitCustomAtomic(MachineInstr *MI, MachineBasicBlock *MBB) const;
virtual MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB) const;
// Inline asm support
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,
MVT VT) const;
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
/// isFPImmLegal - Returns true if the target can instruction select the
/// specified FP immediate natively. If false, the legalizer will
/// materialize the FP immediate as a load from a constant pool.
virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
};
}
#endif // MBlazeISELLOWERING_H

View File

@ -1,219 +0,0 @@
//===-- MBlazeInstrFPU.td - MBlaze FPU Instruction defs ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze profiles and nodes
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze Operand, Complex Patterns and Transformations Definitions.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Memory Access Instructions
//===----------------------------------------------------------------------===//
class LoadFM<bits<6> op, string instr_asm, PatFrag OpNode> :
TA<op, 0x000, (outs GPR:$dst), (ins memrr:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[(set (f32 GPR:$dst), (OpNode xaddr:$addr))], IIC_MEMl>;
class LoadFMI<bits<6> op, string instr_asm, PatFrag OpNode> :
TB<op, (outs GPR:$dst), (ins memri:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[(set (f32 GPR:$dst), (OpNode iaddr:$addr))], IIC_MEMl>;
class StoreFM<bits<6> op, string instr_asm, PatFrag OpNode> :
TA<op, 0x000, (outs), (ins GPR:$dst, memrr:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[(OpNode (f32 GPR:$dst), xaddr:$addr)], IIC_MEMs>;
class StoreFMI<bits<6> op, string instr_asm, PatFrag OpNode> :
TB<op, (outs), (ins GPR:$dst, memrr:$addr),
!strconcat(instr_asm, " $dst, $addr"),
[(OpNode (f32 GPR:$dst), iaddr:$addr)], IIC_MEMs>;
class ArithF<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
InstrItinClass itin> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
!strconcat(instr_asm, " $dst, $b, $c"),
[(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>;
class CmpFN<bits<6> op, bits<11> flags, string instr_asm,
InstrItinClass itin> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
!strconcat(instr_asm, " $dst, $b, $c"),
[], itin>;
class ArithFR<bits<6> op, bits<11> flags, string instr_asm, SDNode OpNode,
InstrItinClass itin> :
TAR<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
!strconcat(instr_asm, " $dst, $c, $b"),
[(set GPR:$dst, (OpNode GPR:$b, GPR:$c))], itin>;
class LogicFI<bits<6> op, string instr_asm> :
TB<op, (outs GPR:$dst), (ins GPR:$b, fimm:$c),
!strconcat(instr_asm, " $dst, $b, $c"),
[], IIC_ALU>;
let rb=0 in {
class ArithF2<bits<6> op, bits<11> flags, string instr_asm,
InstrItinClass itin> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b),
!strconcat(instr_asm, " $dst, $b"),
[], itin>;
class ArithIF<bits<6> op, bits<11> flags, string instr_asm,
InstrItinClass itin> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b),
!strconcat(instr_asm, " $dst, $b"),
[], itin>;
class ArithFI<bits<6> op, bits<11> flags, string instr_asm,
InstrItinClass itin> :
TA<op, flags, (outs GPR:$dst), (ins GPR:$b),
!strconcat(instr_asm, " $dst, $b"),
[], itin>;
}
//===----------------------------------------------------------------------===//
// Pseudo instructions
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// FPU Arithmetic Instructions
//===----------------------------------------------------------------------===//
let Predicates=[HasFPU] in {
def FORI : LogicFI<0x28, "ori ">;
def FADD : ArithF<0x16, 0x000, "fadd ", fadd, IIC_FPU>;
def FRSUB : ArithFR<0x16, 0x080, "frsub ", fsub, IIC_FPU>;
def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIC_FPU>;
def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIC_FPUd>;
}
let Predicates=[HasFPU], isCodeGenOnly=1 in {
def LWF : LoadFM<0x32, "lw ", load>;
def LWFI : LoadFMI<0x3A, "lwi ", load>;
def SWF : StoreFM<0x36, "sw ", store>;
def SWFI : StoreFMI<0x3E, "swi ", store>;
}
let Predicates=[HasFPU,HasSqrt] in {
def FLT : ArithIF<0x16, 0x280, "flt ", IIC_FPUf>;
def FINT : ArithFI<0x16, 0x300, "fint ", IIC_FPUi>;
def FSQRT : ArithF2<0x16, 0x380, "fsqrt ", IIC_FPUs>;
}
let isAsCheapAsAMove = 1 in {
def FCMP_UN : CmpFN<0x16, 0x200, "fcmp.un", IIC_FPUc>;
def FCMP_LT : CmpFN<0x16, 0x210, "fcmp.lt", IIC_FPUc>;
def FCMP_EQ : CmpFN<0x16, 0x220, "fcmp.eq", IIC_FPUc>;
def FCMP_LE : CmpFN<0x16, 0x230, "fcmp.le", IIC_FPUc>;
def FCMP_GT : CmpFN<0x16, 0x240, "fcmp.gt", IIC_FPUc>;
def FCMP_NE : CmpFN<0x16, 0x250, "fcmp.ne", IIC_FPUc>;
def FCMP_GE : CmpFN<0x16, 0x260, "fcmp.ge", IIC_FPUc>;
}
let usesCustomInserter = 1 in {
def Select_FCC : MBlazePseudo<(outs GPR:$dst),
(ins GPR:$T, GPR:$F, GPR:$CMP, i32imm:$CC),
"; SELECT_FCC PSEUDO!",
[]>;
}
// Floating point conversions
let Predicates=[HasFPU] in {
def : Pat<(sint_to_fp GPR:$V), (FLT GPR:$V)>;
def : Pat<(fp_to_sint GPR:$V), (FINT GPR:$V)>;
def : Pat<(fsqrt GPR:$V), (FSQRT GPR:$V)>;
}
// SET_CC operations
let Predicates=[HasFPU] in {
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETEQ),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_EQ GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETNE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_EQ GPR:$L, GPR:$R), 1)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETOEQ),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_EQ GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETONE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(XOR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_EQ GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETONE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_EQ GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETGT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_GT GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETLT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_LT GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETGE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_GE GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETLE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_LE GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETOGT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_GT GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETOLT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_LT GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETOGE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_GE GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETOLE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_LE GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETUEQ),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_EQ GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETUNE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_NE GPR:$L, GPR:$R), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETUGT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_GT GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETULT),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_LT GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETUGE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_GE GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETULE),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(OR (FCMP_UN GPR:$L, GPR:$R),
(FCMP_LE GPR:$L, GPR:$R)), 2)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETO),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_UN GPR:$L, GPR:$R), 1)>;
def : Pat<(setcc (f32 GPR:$L), (f32 GPR:$R), SETUO),
(Select_CC (ADDIK (i32 R0), 1), (ADDIK (i32 R0), 0),
(FCMP_UN GPR:$L, GPR:$R), 2)>;
}
// SELECT operations
def : Pat<(select (i32 GPR:$C), (f32 GPR:$T), (f32 GPR:$F)),
(Select_FCC GPR:$T, GPR:$F, GPR:$C, 2)>;
//===----------------------------------------------------------------------===//
// Patterns for Floating Point Instructions
//===----------------------------------------------------------------------===//
def : Pat<(f32 fpimm:$imm), (FORI (i32 R0), fpimm:$imm)>;

View File

@ -1,229 +0,0 @@
//===-- MBlazeInstrFSL.td - MBlaze FSL Instruction defs ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// FSL Instruction Formats
//===----------------------------------------------------------------------===//
class FSLGet<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FRCX, (outs GPR:$dst), (ins fslimm:$b),
!strconcat(instr_asm, " $dst, $b"),
[(set GPR:$dst, (OpNode immZExt4:$b))],IIC_FSLg>
{
bits<5> rd;
bits<4> fslno;
let Inst{6-10} = rd;
let Inst{11-15} = 0x0;
let Inst{16} = 0x0;
let Inst{17-21} = flags; // NCTAE
let Inst{22-27} = 0x0;
let Inst{28-31} = fslno;
}
class FSLGetD<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FRCR, (outs GPR:$dst), (ins GPR:$b),
!strconcat(instr_asm, " $dst, $b"),
[(set GPR:$dst, (OpNode GPR:$b))], IIC_FSLg>
{
bits<5> rd;
bits<5> rb;
let Inst{6-10} = rd;
let Inst{11-15} = 0x0;
let Inst{16-20} = rb;
let Inst{21} = 0x0;
let Inst{22-26} = flags; // NCTAE
let Inst{27-31} = 0x0;
}
class FSLPut<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FCRCX, (outs), (ins GPR:$v, fslimm:$b),
!strconcat(instr_asm, " $v, $b"),
[(OpNode GPR:$v, immZExt4:$b)], IIC_FSLp>
{
bits<5> ra;
bits<4> fslno;
let Inst{6-10} = 0x0;
let Inst{11-15} = ra;
let Inst{16} = 0x1;
let Inst{17-20} = flags; // NCTA
let Inst{21-27} = 0x0;
let Inst{28-31} = fslno;
}
class FSLPutD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FCRR, (outs), (ins GPR:$v, GPR:$b),
!strconcat(instr_asm, " $v, $b"),
[(OpNode GPR:$v, GPR:$b)], IIC_FSLp>
{
bits<5> ra;
bits<5> rb;
let Inst{6-10} = 0x0;
let Inst{11-15} = ra;
let Inst{16-20} = rb;
let Inst{21} = 0x1;
let Inst{22-25} = flags; // NCTA
let Inst{26-31} = 0x0;
}
class FSLPutT<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FCX, (outs), (ins fslimm:$b),
!strconcat(instr_asm, " $b"),
[(OpNode immZExt4:$b)], IIC_FSLp>
{
bits<4> fslno;
let Inst{6-10} = 0x0;
let Inst{11-15} = 0x0;
let Inst{16} = 0x1;
let Inst{17-20} = flags; // NCTA
let Inst{21-27} = 0x0;
let Inst{28-31} = fslno;
}
class FSLPutTD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> :
MBlazeInst<op, FCR, (outs), (ins GPR:$b),
!strconcat(instr_asm, " $b"),
[(OpNode GPR:$b)], IIC_FSLp>
{
bits<5> rb;
let Inst{6-10} = 0x0;
let Inst{11-15} = 0x0;
let Inst{16-20} = rb;
let Inst{21} = 0x1;
let Inst{22-25} = flags; // NCTA
let Inst{26-31} = 0x0;
}
//===----------------------------------------------------------------------===//
// FSL Get Instructions
//===----------------------------------------------------------------------===//
def GET : FSLGet<0x1B, 0x00, "get ", int_mblaze_fsl_get>;
def AGET : FSLGet<0x1B, 0x02, "aget ", int_mblaze_fsl_aget>;
def CGET : FSLGet<0x1B, 0x08, "cget ", int_mblaze_fsl_cget>;
def CAGET : FSLGet<0x1B, 0x0A, "caget ", int_mblaze_fsl_caget>;
def EGET : FSLGet<0x1B, 0x01, "eget ", int_mblaze_fsl_eget>;
def EAGET : FSLGet<0x1B, 0x03, "eaget ", int_mblaze_fsl_eaget>;
def ECGET : FSLGet<0x1B, 0x09, "ecget ", int_mblaze_fsl_ecget>;
def ECAGET : FSLGet<0x1B, 0x0B, "ecaget ", int_mblaze_fsl_ecaget>;
def TGET : FSLGet<0x1B, 0x04, "tget ", int_mblaze_fsl_tget>;
def TAGET : FSLGet<0x1B, 0x06, "taget ", int_mblaze_fsl_taget>;
def TCGET : FSLGet<0x1B, 0x0C, "tcget ", int_mblaze_fsl_tcget>;
def TCAGET : FSLGet<0x1B, 0x0E, "tcaget ", int_mblaze_fsl_tcaget>;
def TEGET : FSLGet<0x1B, 0x05, "teget ", int_mblaze_fsl_teget>;
def TEAGET : FSLGet<0x1B, 0x07, "teaget ", int_mblaze_fsl_teaget>;
def TECGET : FSLGet<0x1B, 0x0D, "tecget ", int_mblaze_fsl_tecget>;
def TECAGET : FSLGet<0x1B, 0x0F, "tecaget ", int_mblaze_fsl_tecaget>;
let Defs = [CARRY] in {
def NGET : FSLGet<0x1B, 0x10, "nget ", int_mblaze_fsl_nget>;
def NAGET : FSLGet<0x1B, 0x12, "naget ", int_mblaze_fsl_naget>;
def NCGET : FSLGet<0x1B, 0x18, "ncget ", int_mblaze_fsl_ncget>;
def NCAGET : FSLGet<0x1B, 0x1A, "ncaget ", int_mblaze_fsl_ncaget>;
def NEGET : FSLGet<0x1B, 0x11, "neget ", int_mblaze_fsl_neget>;
def NEAGET : FSLGet<0x1B, 0x13, "neaget ", int_mblaze_fsl_neaget>;
def NECGET : FSLGet<0x1B, 0x19, "necget ", int_mblaze_fsl_necget>;
def NECAGET : FSLGet<0x1B, 0x1B, "necaget ", int_mblaze_fsl_necaget>;
def TNGET : FSLGet<0x1B, 0x14, "tnget ", int_mblaze_fsl_tnget>;
def TNAGET : FSLGet<0x1B, 0x16, "tnaget ", int_mblaze_fsl_tnaget>;
def TNCGET : FSLGet<0x1B, 0x1C, "tncget ", int_mblaze_fsl_tncget>;
def TNCAGET : FSLGet<0x1B, 0x1E, "tncaget ", int_mblaze_fsl_tncaget>;
def TNEGET : FSLGet<0x1B, 0x15, "tneget ", int_mblaze_fsl_tneget>;
def TNEAGET : FSLGet<0x1B, 0x17, "tneaget ", int_mblaze_fsl_tneaget>;
def TNECGET : FSLGet<0x1B, 0x1D, "tnecget ", int_mblaze_fsl_tnecget>;
def TNECAGET : FSLGet<0x1B, 0x1F, "tnecaget ", int_mblaze_fsl_tnecaget>;
}
//===----------------------------------------------------------------------===//
// FSL Dynamic Get Instructions
//===----------------------------------------------------------------------===//
def GETD : FSLGetD<0x13, 0x00, "getd ", int_mblaze_fsl_get>;
def AGETD : FSLGetD<0x13, 0x02, "agetd ", int_mblaze_fsl_aget>;
def CGETD : FSLGetD<0x13, 0x08, "cgetd ", int_mblaze_fsl_cget>;
def CAGETD : FSLGetD<0x13, 0x0A, "cagetd ", int_mblaze_fsl_caget>;
def EGETD : FSLGetD<0x13, 0x01, "egetd ", int_mblaze_fsl_eget>;
def EAGETD : FSLGetD<0x13, 0x03, "eagetd ", int_mblaze_fsl_eaget>;
def ECGETD : FSLGetD<0x13, 0x09, "ecgetd ", int_mblaze_fsl_ecget>;
def ECAGETD : FSLGetD<0x13, 0x0B, "ecagetd ", int_mblaze_fsl_ecaget>;
def TGETD : FSLGetD<0x13, 0x04, "tgetd ", int_mblaze_fsl_tget>;
def TAGETD : FSLGetD<0x13, 0x06, "tagetd ", int_mblaze_fsl_taget>;
def TCGETD : FSLGetD<0x13, 0x0C, "tcgetd ", int_mblaze_fsl_tcget>;
def TCAGETD : FSLGetD<0x13, 0x0E, "tcagetd ", int_mblaze_fsl_tcaget>;
def TEGETD : FSLGetD<0x13, 0x05, "tegetd ", int_mblaze_fsl_teget>;
def TEAGETD : FSLGetD<0x13, 0x07, "teagetd ", int_mblaze_fsl_teaget>;
def TECGETD : FSLGetD<0x13, 0x0D, "tecgetd ", int_mblaze_fsl_tecget>;
def TECAGETD : FSLGetD<0x13, 0x0F, "tecagetd ", int_mblaze_fsl_tecaget>;
let Defs = [CARRY] in {
def NGETD : FSLGetD<0x13, 0x10, "ngetd ", int_mblaze_fsl_nget>;
def NAGETD : FSLGetD<0x13, 0x12, "nagetd ", int_mblaze_fsl_naget>;
def NCGETD : FSLGetD<0x13, 0x18, "ncgetd ", int_mblaze_fsl_ncget>;
def NCAGETD : FSLGetD<0x13, 0x1A, "ncagetd ", int_mblaze_fsl_ncaget>;
def NEGETD : FSLGetD<0x13, 0x11, "negetd ", int_mblaze_fsl_neget>;
def NEAGETD : FSLGetD<0x13, 0x13, "neagetd ", int_mblaze_fsl_neaget>;
def NECGETD : FSLGetD<0x13, 0x19, "necgetd ", int_mblaze_fsl_necget>;
def NECAGETD : FSLGetD<0x13, 0x1B, "necagetd ", int_mblaze_fsl_necaget>;
def TNGETD : FSLGetD<0x13, 0x14, "tngetd ", int_mblaze_fsl_tnget>;
def TNAGETD : FSLGetD<0x13, 0x16, "tnagetd ", int_mblaze_fsl_tnaget>;
def TNCGETD : FSLGetD<0x13, 0x1C, "tncgetd ", int_mblaze_fsl_tncget>;
def TNCAGETD : FSLGetD<0x13, 0x1E, "tncagetd ", int_mblaze_fsl_tncaget>;
def TNEGETD : FSLGetD<0x13, 0x15, "tnegetd ", int_mblaze_fsl_tneget>;
def TNEAGETD : FSLGetD<0x13, 0x17, "tneagetd ", int_mblaze_fsl_tneaget>;
def TNECGETD : FSLGetD<0x13, 0x1D, "tnecgetd ", int_mblaze_fsl_tnecget>;
def TNECAGETD : FSLGetD<0x13, 0x1F, "tnecagetd", int_mblaze_fsl_tnecaget>;
}
//===----------------------------------------------------------------------===//
// FSL Put Instructions
//===----------------------------------------------------------------------===//
def PUT : FSLPut<0x1B, 0x0, "put ", int_mblaze_fsl_put>;
def APUT : FSLPut<0x1B, 0x1, "aput ", int_mblaze_fsl_aput>;
def CPUT : FSLPut<0x1B, 0x4, "cput ", int_mblaze_fsl_cput>;
def CAPUT : FSLPut<0x1B, 0x5, "caput ", int_mblaze_fsl_caput>;
def TPUT : FSLPutT<0x1B, 0x2, "tput ", int_mblaze_fsl_tput>;
def TAPUT : FSLPutT<0x1B, 0x3, "taput ", int_mblaze_fsl_taput>;
def TCPUT : FSLPutT<0x1B, 0x6, "tcput ", int_mblaze_fsl_tcput>;
def TCAPUT : FSLPutT<0x1B, 0x7, "tcaput ", int_mblaze_fsl_tcaput>;
let Defs = [CARRY] in {
def NPUT : FSLPut<0x1B, 0x8, "nput ", int_mblaze_fsl_nput>;
def NAPUT : FSLPut<0x1B, 0x9, "naput ", int_mblaze_fsl_naput>;
def NCPUT : FSLPut<0x1B, 0xC, "ncput ", int_mblaze_fsl_ncput>;
def NCAPUT : FSLPut<0x1B, 0xD, "ncaput ", int_mblaze_fsl_ncaput>;
def TNPUT : FSLPutT<0x1B, 0xA, "tnput ", int_mblaze_fsl_tnput>;
def TNAPUT : FSLPutT<0x1B, 0xB, "tnaput ", int_mblaze_fsl_tnaput>;
def TNCPUT : FSLPutT<0x1B, 0xE, "tncput ", int_mblaze_fsl_tncput>;
def TNCAPUT : FSLPutT<0x1B, 0xF, "tncaput ", int_mblaze_fsl_tncaput>;
}
//===----------------------------------------------------------------------===//
// FSL Dynamic Put Instructions
//===----------------------------------------------------------------------===//
def PUTD : FSLPutD<0x13, 0x0, "putd ", int_mblaze_fsl_put>;
def APUTD : FSLPutD<0x13, 0x1, "aputd ", int_mblaze_fsl_aput>;
def CPUTD : FSLPutD<0x13, 0x4, "cputd ", int_mblaze_fsl_cput>;
def CAPUTD : FSLPutD<0x13, 0x5, "caputd ", int_mblaze_fsl_caput>;
def TPUTD : FSLPutTD<0x13, 0x2, "tputd ", int_mblaze_fsl_tput>;
def TAPUTD : FSLPutTD<0x13, 0x3, "taputd ", int_mblaze_fsl_taput>;
def TCPUTD : FSLPutTD<0x13, 0x6, "tcputd ", int_mblaze_fsl_tcput>;
def TCAPUTD : FSLPutTD<0x13, 0x7, "tcaputd ", int_mblaze_fsl_tcaput>;
let Defs = [CARRY] in {
def NPUTD : FSLPutD<0x13, 0x8, "nputd ", int_mblaze_fsl_nput>;
def NAPUTD : FSLPutD<0x13, 0x9, "naputd ", int_mblaze_fsl_naput>;
def NCPUTD : FSLPutD<0x13, 0xC, "ncputd ", int_mblaze_fsl_ncput>;
def NCAPUTD : FSLPutD<0x13, 0xD, "ncaputd ", int_mblaze_fsl_ncaput>;
def TNPUTD : FSLPutTD<0x13, 0xA, "tnputd ", int_mblaze_fsl_tnput>;
def TNAPUTD : FSLPutTD<0x13, 0xB, "tnaputd ", int_mblaze_fsl_tnaput>;
def TNCPUTD : FSLPutTD<0x13, 0xE, "tncputd ", int_mblaze_fsl_tncput>;
def TNCAPUTD : FSLPutTD<0x13, 0xF, "tncaputd ", int_mblaze_fsl_tncaput>;
}

View File

@ -1,228 +0,0 @@
//===-- MBlazeInstrFormats.td - MB Instruction defs --------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Format specifies the encoding used by the instruction. This is part of the
// ad-hoc solution used to emit machine instruction encodings by our machine
// code emitter.
class Format<bits<6> val> {
bits<6> Value = val;
}
def FPseudo : Format<0>;
def FRRR : Format<1>; // ADD, OR, etc.
def FRRI : Format<2>; // ADDI, ORI, etc.
def FCRR : Format<3>; // PUTD, WDC, WIC, BEQ, BNE, BGE, etc.
def FCRI : Format<4>; // RTID, RTED, RTSD, BEQI, BNEI, BGEI, etc.
def FRCR : Format<5>; // BRLD, BRALD, GETD
def FRCI : Format<6>; // BRLID, BRALID, MSRCLR, MSRSET
def FCCR : Format<7>; // BR, BRA, BRD, etc.
def FCCI : Format<8>; // IMM, BRI, BRAI, BRID, etc.
def FRRCI : Format<9>; // BSRLI, BSRAI, BSLLI
def FRRC : Format<10>; // SEXT8, SEXT16, SRA, SRC, SRL, FLT, FINT, FSQRT
def FRCX : Format<11>; // GET
def FRCS : Format<12>; // MFS
def FCRCS : Format<13>; // MTS
def FCRCX : Format<14>; // PUT
def FCX : Format<15>; // TPUT
def FCR : Format<16>; // TPUTD
def FRIR : Format<17>; // RSUBI
def FRRRR : Format<18>; // RSUB, FRSUB
def FRI : Format<19>; // RSUB, FRSUB
def FC : Format<20>; // NOP
def FRR : Format<21>; // CLZ
//===----------------------------------------------------------------------===//
// Describe MBlaze instructions format
//
// CPU INSTRUCTION FORMATS
//
// opcode - operation code.
// rd - dst reg.
// ra - first src. reg.
// rb - second src. reg.
// imm16 - 16-bit immediate value.
//
//===----------------------------------------------------------------------===//
// Generic MBlaze Format
class MBlazeInst<bits<6> op, Format form, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> : Instruction {
let Namespace = "MBlaze";
field bits<32> Inst;
bits<6> opcode = op;
Format Form = form;
bits<6> FormBits = Form.Value;
// Top 6 bits are the 'opcode' field
let Inst{0-5} = opcode;
// If the instruction is marked as a pseudo, set isCodeGenOnly so that the
// assembler and disassmbler ignore it.
let isCodeGenOnly = !eq(!cast<string>(form), "FPseudo");
dag OutOperandList = outs;
dag InOperandList = ins;
let AsmString = asmstr;
let Pattern = pattern;
let Itinerary = itin;
// TSFlags layout should be kept in sync with MBlazeInstrInfo.h.
let TSFlags{5-0} = FormBits;
}
//===----------------------------------------------------------------------===//
// Pseudo instruction class
//===----------------------------------------------------------------------===//
class MBlazePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
MBlazeInst<0x0, FPseudo, outs, ins, asmstr, pattern, IIC_Pseudo>;
//===----------------------------------------------------------------------===//
// Type A instruction class in MBlaze : <|opcode|rd|ra|rb|flags|>
//===----------------------------------------------------------------------===//
class TA<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op,FRRR,outs, ins, asmstr, pattern, itin>
{
bits<5> rd;
bits<5> ra;
bits<5> rb;
let Inst{6-10} = rd;
let Inst{11-15} = ra;
let Inst{16-20} = rb;
let Inst{21-31} = flags;
}
//===----------------------------------------------------------------------===//
// Type B instruction class in MBlaze : <|opcode|rd|ra|immediate|>
//===----------------------------------------------------------------------===//
class TB<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
InstrItinClass itin> :
MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin>
{
bits<5> rd;
bits<5> ra;
bits<16> imm16;
let Inst{6-10} = rd;
let Inst{11-15} = ra;
let Inst{16-31} = imm16;
}
//===----------------------------------------------------------------------===//
// Type A instruction class in MBlaze but with the operands reversed
// in the LLVM DAG : <|opcode|rd|ra|rb|flags|>
//===----------------------------------------------------------------------===//
class TAR<bits<6> op, bits<11> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
TA<op, flags, outs, ins, asmstr, pattern, itin>
{
bits<5> rrd;
bits<5> rrb;
bits<5> rra;
let Form = FRRRR;
let rd = rrd;
let ra = rra;
let rb = rrb;
}
//===----------------------------------------------------------------------===//
// Type B instruction class in MBlaze but with the operands reversed in
// the LLVM DAG : <|opcode|rd|ra|immediate|>
//===----------------------------------------------------------------------===//
class TBR<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
InstrItinClass itin> :
TB<op, outs, ins, asmstr, pattern, itin> {
bits<5> rrd;
bits<16> rimm16;
bits<5> rra;
let Form = FRIR;
let rd = rrd;
let ra = rra;
let imm16 = rimm16;
}
//===----------------------------------------------------------------------===//
// Shift immediate instruction class in MBlaze : <|opcode|rd|ra|immediate|>
//===----------------------------------------------------------------------===//
class SHT<bits<6> op, bits<2> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op, FRRI, outs, ins, asmstr, pattern, itin> {
bits<5> rd;
bits<5> ra;
bits<5> imm5;
let Inst{6-10} = rd;
let Inst{11-15} = ra;
let Inst{16-20} = 0x0;
let Inst{21-22} = flags;
let Inst{23-26} = 0x0;
let Inst{27-31} = imm5;
}
//===----------------------------------------------------------------------===//
// Special instruction class in MBlaze : <|opcode|rd|imm14|>
//===----------------------------------------------------------------------===//
class SPC<bits<6> op, bits<2> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op, FRI, outs, ins, asmstr, pattern, itin> {
bits<5> rd;
bits<14> imm14;
let Inst{6-10} = rd;
let Inst{11-15} = 0x0;
let Inst{16-17} = flags;
let Inst{18-31} = imm14;
}
//===----------------------------------------------------------------------===//
// MSR instruction class in MBlaze : <|opcode|rd|imm15|>
//===----------------------------------------------------------------------===//
class MSR<bits<6> op, bits<6> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op, FRI, outs, ins, asmstr, pattern, itin> {
bits<5> rd;
bits<15> imm15;
let Inst{6-10} = rd;
let Inst{11-16} = flags;
let Inst{17-31} = imm15;
}
//===----------------------------------------------------------------------===//
// TCLZ instruction class in MBlaze : <|opcode|rd|imm15|>
//===----------------------------------------------------------------------===//
class TCLZ<bits<6> op, bits<16> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op, FRR, outs, ins, asmstr, pattern, itin> {
bits<5> rd;
bits<5> ra;
let Inst{6-10} = rd;
let Inst{11-15} = ra;
let Inst{16-31} = flags;
}
//===----------------------------------------------------------------------===//
// MBAR instruction class in MBlaze : <|opcode|rd|imm15|>
//===----------------------------------------------------------------------===//
class MBAR<bits<6> op, bits<26> flags, dag outs, dag ins, string asmstr,
list<dag> pattern, InstrItinClass itin> :
MBlazeInst<op, FC, outs, ins, asmstr, pattern, itin> {
let Inst{6-31} = flags;
}

View File

@ -1,297 +0,0 @@
//===-- MBlazeInstrInfo.cpp - MBlaze Instruction Information --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MBlaze implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#include "MBlazeInstrInfo.h"
#include "MBlazeMachineFunction.h"
#include "MBlazeTargetMachine.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_CTOR
#include "MBlazeGenInstrInfo.inc"
using namespace llvm;
MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
: MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP),
TM(tm), RI(*TM.getSubtargetImpl()) {}
static bool isZeroImm(const MachineOperand &op) {
return op.isImm() && op.getImm() == 0;
}
/// 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 MBlazeInstrInfo::
isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
if (MI->getOpcode() == MBlaze::LWI) {
if ((MI->getOperand(1).isFI()) && // is a stack slot
(MI->getOperand(2).isImm()) && // the imm is zero
(isZeroImm(MI->getOperand(2)))) {
FrameIndex = MI->getOperand(1).getIndex();
return MI->getOperand(0).getReg();
}
}
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 MBlazeInstrInfo::
isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
if (MI->getOpcode() == MBlaze::SWI) {
if ((MI->getOperand(1).isFI()) && // is a stack slot
(MI->getOperand(2).isImm()) && // the imm is zero
(isZeroImm(MI->getOperand(2)))) {
FrameIndex = MI->getOperand(1).getIndex();
return MI->getOperand(0).getReg();
}
}
return 0;
}
/// insertNoop - If data hazard condition is found insert the target nop
/// instruction.
void MBlazeInstrInfo::
insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
DebugLoc DL;
BuildMI(MBB, MI, DL, get(MBlaze::NOP));
}
void MBlazeInstrInfo::
copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0);
}
void MBlazeInstrInfo::
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned SrcReg, bool isKill, int FI,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
.addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
}
void MBlazeInstrInfo::
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
unsigned DestReg, int FI,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
DebugLoc DL;
BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg)
.addFrameIndex(FI).addImm(0); //.addFrameIndex(FI);
}
//===----------------------------------------------------------------------===//
// Branch Analysis
//===----------------------------------------------------------------------===//
bool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// If the block has no terminators, it just falls into the block after it.
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin())
return false;
--I;
while (I->isDebugValue()) {
if (I == MBB.begin())
return false;
--I;
}
if (!isUnpredicatedTerminator(I))
return false;
// Get the last instruction in the block.
MachineInstr *LastInst = I;
// If there is only one terminator instruction, process it.
unsigned LastOpc = LastInst->getOpcode();
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
if (MBlaze::isUncondBranchOpcode(LastOpc)) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
if (MBlaze::isCondBranchOpcode(LastOpc)) {
// Block ends with fall-through condbranch.
TBB = LastInst->getOperand(1).getMBB();
Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Cond.push_back(LastInst->getOperand(0));
return false;
}
// Otherwise, don't know what this is.
return true;
}
// Get the instruction before it if it's a terminator.
MachineInstr *SecondLastInst = I;
// If there are three terminators, we don't know what sort of block this is.
if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I))
return true;
// If the block ends with something like BEQID then BRID, handle it.
if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) &&
MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
TBB = SecondLastInst->getOperand(1).getMBB();
Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
return false;
}
// If the block ends with two unconditional branches, handle it.
// The second one is not executed, so remove it.
if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) &&
MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
I->eraseFromParent();
return false;
}
// Otherwise, can't handle this.
return true;
}
unsigned MBlazeInstrInfo::
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() == 2 || Cond.size() == 0) &&
"MBlaze branch conditions have two components!");
unsigned Opc = MBlaze::BRID;
if (!Cond.empty())
Opc = (unsigned)Cond[0].getImm();
if (FBB == 0) {
if (Cond.empty()) // Unconditional branch
BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
else // Conditional branch
BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
return 1;
}
BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB);
BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB);
return 2;
}
unsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
--I;
while (I->isDebugValue()) {
if (I == MBB.begin())
return 0;
--I;
}
if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) &&
!MBlaze::isCondBranchOpcode(I->getOpcode()))
return 0;
// Remove the branch.
I->eraseFromParent();
I = MBB.end();
if (I == MBB.begin()) return 1;
--I;
if (!MBlaze::isCondBranchOpcode(I->getOpcode()))
return 1;
// Remove the branch.
I->eraseFromParent();
return 2;
}
bool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand>
&Cond) const {
assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!");
switch (Cond[0].getImm()) {
default: return true;
case MBlaze::BEQ: Cond[0].setImm(MBlaze::BNE); return false;
case MBlaze::BNE: Cond[0].setImm(MBlaze::BEQ); return false;
case MBlaze::BGT: Cond[0].setImm(MBlaze::BLE); return false;
case MBlaze::BGE: Cond[0].setImm(MBlaze::BLT); return false;
case MBlaze::BLT: Cond[0].setImm(MBlaze::BGE); return false;
case MBlaze::BLE: Cond[0].setImm(MBlaze::BGT); return false;
case MBlaze::BEQI: Cond[0].setImm(MBlaze::BNEI); return false;
case MBlaze::BNEI: Cond[0].setImm(MBlaze::BEQI); return false;
case MBlaze::BGTI: Cond[0].setImm(MBlaze::BLEI); return false;
case MBlaze::BGEI: Cond[0].setImm(MBlaze::BLTI); return false;
case MBlaze::BLTI: Cond[0].setImm(MBlaze::BGEI); return false;
case MBlaze::BLEI: Cond[0].setImm(MBlaze::BGTI); return false;
case MBlaze::BEQD: Cond[0].setImm(MBlaze::BNED); return false;
case MBlaze::BNED: Cond[0].setImm(MBlaze::BEQD); return false;
case MBlaze::BGTD: Cond[0].setImm(MBlaze::BLED); return false;
case MBlaze::BGED: Cond[0].setImm(MBlaze::BLTD); return false;
case MBlaze::BLTD: Cond[0].setImm(MBlaze::BGED); return false;
case MBlaze::BLED: Cond[0].setImm(MBlaze::BGTD); return false;
case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false;
case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false;
case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false;
case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false;
case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false;
case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false;
}
}
/// getGlobalBaseReg - Return a virtual register initialized with the
/// the global base register value. Output instructions required to
/// initialize the register in the function entry block, if necessary.
///
unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
if (GlobalBaseReg != 0)
return GlobalBaseReg;
// Insert the set of GlobalBaseReg into the first MBB of the function
MachineBasicBlock &FirstMBB = MF->front();
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
MachineRegisterInfo &RegInfo = MF->getRegInfo();
const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
GlobalBaseReg = RegInfo.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
GlobalBaseReg).addReg(MBlaze::R20);
RegInfo.addLiveIn(MBlaze::R20);
MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;
}

View File

@ -1,240 +0,0 @@
//===-- MBlazeInstrInfo.h - MBlaze 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 MBlaze implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEINSTRUCTIONINFO_H
#define MBLAZEINSTRUCTIONINFO_H
#include "MBlaze.h"
#include "MBlazeRegisterInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "MBlazeGenInstrInfo.inc"
namespace llvm {
namespace MBlaze {
// MBlaze Branch Codes
enum FPBranchCode {
BRANCH_F,
BRANCH_T,
BRANCH_FL,
BRANCH_TL,
BRANCH_INVALID
};
// MBlaze Condition Codes
enum CondCode {
// To be used with float branch True
FCOND_F,
FCOND_UN,
FCOND_EQ,
FCOND_UEQ,
FCOND_OLT,
FCOND_ULT,
FCOND_OLE,
FCOND_ULE,
FCOND_SF,
FCOND_NGLE,
FCOND_SEQ,
FCOND_NGL,
FCOND_LT,
FCOND_NGE,
FCOND_LE,
FCOND_NGT,
// To be used with float branch False
// This conditions have the same mnemonic as the
// above ones, but are used with a branch False;
FCOND_T,
FCOND_OR,
FCOND_NEQ,
FCOND_OGL,
FCOND_UGE,
FCOND_OGE,
FCOND_UGT,
FCOND_OGT,
FCOND_ST,
FCOND_GLE,
FCOND_SNE,
FCOND_GL,
FCOND_NLT,
FCOND_GE,
FCOND_NLE,
FCOND_GT,
// Only integer conditions
COND_EQ,
COND_GT,
COND_GE,
COND_LT,
COND_LE,
COND_NE,
COND_INVALID
};
// Turn condition code into conditional branch opcode.
inline static unsigned GetCondBranchFromCond(CondCode CC) {
switch (CC) {
default: llvm_unreachable("Unknown condition code");
case COND_EQ: return MBlaze::BEQID;
case COND_NE: return MBlaze::BNEID;
case COND_GT: return MBlaze::BGTID;
case COND_GE: return MBlaze::BGEID;
case COND_LT: return MBlaze::BLTID;
case COND_LE: return MBlaze::BLEID;
}
}
/// GetOppositeBranchCondition - Return the inverse of the specified cond,
/// e.g. turning COND_E to COND_NE.
// CondCode GetOppositeBranchCondition(MBlaze::CondCode CC);
/// MBlazeCCToString - Map each FP condition code to its string
inline static const char *MBlazeFCCToString(MBlaze::CondCode CC) {
switch (CC) {
default: llvm_unreachable("Unknown condition code");
case FCOND_F:
case FCOND_T: return "f";
case FCOND_UN:
case FCOND_OR: return "un";
case FCOND_EQ:
case FCOND_NEQ: return "eq";
case FCOND_UEQ:
case FCOND_OGL: return "ueq";
case FCOND_OLT:
case FCOND_UGE: return "olt";
case FCOND_ULT:
case FCOND_OGE: return "ult";
case FCOND_OLE:
case FCOND_UGT: return "ole";
case FCOND_ULE:
case FCOND_OGT: return "ule";
case FCOND_SF:
case FCOND_ST: return "sf";
case FCOND_NGLE:
case FCOND_GLE: return "ngle";
case FCOND_SEQ:
case FCOND_SNE: return "seq";
case FCOND_NGL:
case FCOND_GL: return "ngl";
case FCOND_LT:
case FCOND_NLT: return "lt";
case FCOND_NGE:
case FCOND_GE: return "ge";
case FCOND_LE:
case FCOND_NLE: return "nle";
case FCOND_NGT:
case FCOND_GT: return "gt";
}
}
inline static bool isUncondBranchOpcode(int Opc) {
switch (Opc) {
default: return false;
case MBlaze::BRI:
case MBlaze::BRAI:
case MBlaze::BRID:
case MBlaze::BRAID:
return true;
}
}
inline static bool isCondBranchOpcode(int Opc) {
switch (Opc) {
default: return false;
case MBlaze::BEQI: case MBlaze::BEQID:
case MBlaze::BNEI: case MBlaze::BNEID:
case MBlaze::BGTI: case MBlaze::BGTID:
case MBlaze::BGEI: case MBlaze::BGEID:
case MBlaze::BLTI: case MBlaze::BLTID:
case MBlaze::BLEI: case MBlaze::BLEID:
return true;
}
}
}
class MBlazeInstrInfo : public MBlazeGenInstrInfo {
MBlazeTargetMachine &TM;
const MBlazeRegisterInfo RI;
public:
explicit MBlazeInstrInfo(MBlazeTargetMachine &TM);
/// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
/// such, whenever a client has an instance of instruction info, it should
/// always be able to get register info as well (through this method).
///
virtual const MBlazeRegisterInfo &getRegisterInfo() const { return RI; }
/// 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.
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
/// 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.
virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
/// Branch Analysis
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const;
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const;
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
virtual bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
const;
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const;
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
/// Insert nop instruction when hazard condition is found
virtual void insertNoop(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
/// getGlobalBaseReg - Return a virtual register initialized with the
/// the global base register value. Output instructions required to
/// initialize the register in the function entry block, if necessary.
///
unsigned getGlobalBaseReg(MachineFunction *MF) const;
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,111 +0,0 @@
//===-- MBlazeIntrinsicInfo.cpp - Intrinsic Information -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MBlaze implementation of TargetIntrinsicInfo.
//
//===----------------------------------------------------------------------===//
#include "MBlazeIntrinsicInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
using namespace llvm;
namespace mblazeIntrinsic {
enum ID {
last_non_mblaze_intrinsic = Intrinsic::num_intrinsics-1,
#define GET_INTRINSIC_ENUM_VALUES
#include "MBlazeGenIntrinsics.inc"
#undef GET_INTRINSIC_ENUM_VALUES
, num_mblaze_intrinsics
};
#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
#include "MBlazeGenIntrinsics.inc"
#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN
}
std::string MBlazeIntrinsicInfo::getName(unsigned IntrID, Type **Tys,
unsigned numTys) const {
static const char *const names[] = {
#define GET_INTRINSIC_NAME_TABLE
#include "MBlazeGenIntrinsics.inc"
#undef GET_INTRINSIC_NAME_TABLE
};
assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
if (IntrID < Intrinsic::num_intrinsics)
return 0;
assert(IntrID < mblazeIntrinsic::num_mblaze_intrinsics &&
"Invalid intrinsic ID");
std::string Result(names[IntrID - Intrinsic::num_intrinsics]);
return Result;
}
unsigned MBlazeIntrinsicInfo::
lookupName(const char *Name, unsigned Len) const {
if (!StringRef(Name, Len).startswith("llvm."))
return 0; // All intrinsics start with 'llvm.'
#define GET_FUNCTION_RECOGNIZER
#include "MBlazeGenIntrinsics.inc"
#undef GET_FUNCTION_RECOGNIZER
return 0;
}
unsigned MBlazeIntrinsicInfo::
lookupGCCName(const char *Name) const {
return mblazeIntrinsic::getIntrinsicForGCCBuiltin("mblaze",Name);
}
bool MBlazeIntrinsicInfo::isOverloaded(unsigned IntrID) const {
if (IntrID == 0)
return false;
unsigned id = IntrID - Intrinsic::num_intrinsics + 1;
#define GET_INTRINSIC_OVERLOAD_TABLE
#include "MBlazeGenIntrinsics.inc"
#undef GET_INTRINSIC_OVERLOAD_TABLE
}
/// This defines the "getAttributes(LLVMContext &C, ID id)" method.
#define GET_INTRINSIC_ATTRIBUTES
#include "MBlazeGenIntrinsics.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 "MBlazeGenIntrinsics.inc"
#undef GET_INTRINSIC_GENERATOR
return FunctionType::get(ResultTy, ArgTys, IsVarArg);
}
Function *MBlazeIntrinsicInfo::getDeclaration(Module *M, unsigned IntrID,
Type **Tys,
unsigned numTy) const {
assert(!isOverloaded(IntrID) && "MBlaze intrinsics are not overloaded");
AttributeSet AList = getAttributes(M->getContext(),
(mblazeIntrinsic::ID) IntrID);
return cast<Function>(M->getOrInsertFunction(getName(IntrID),
getType(M->getContext(), IntrID),
AList));
}

View File

@ -1,33 +0,0 @@
//===-- MBlazeIntrinsicInfo.h - MBlaze 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 MBlaze implementation of TargetIntrinsicInfo.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEINTRINSICS_H
#define MBLAZEINTRINSICS_H
#include "llvm/Target/TargetIntrinsicInfo.h"
namespace llvm {
class MBlazeIntrinsicInfo : public TargetIntrinsicInfo {
public:
std::string getName(unsigned IntrID, Type **Tys = 0,
unsigned numTys = 0) const;
unsigned lookupName(const char *Name, unsigned Len) const;
unsigned lookupGCCName(const char *Name) const;
bool isOverloaded(unsigned IID) const;
Function *getDeclaration(Module *M, unsigned ID, Type **Tys = 0,
unsigned numTys = 0) const;
};
}
#endif

View File

@ -1,131 +0,0 @@
//===-- IntrinsicsMBlaze.td - Defines MBlaze 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 MicroBlaze-specific intrinsics.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Definitions for all MBlaze intrinsics.
//
// MBlaze intrinsic classes.
let TargetPrefix = "mblaze", isTarget = 1 in {
class MBFSL_Get_Intrinsic : Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
class MBFSL_Put_Intrinsic : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], []>;
class MBFSL_PutT_Intrinsic : Intrinsic<[], [llvm_i32_ty], []>;
}
//===----------------------------------------------------------------------===//
// MicroBlaze FSL Get Intrinsic Definitions.
//
def int_mblaze_fsl_get : GCCBuiltin<"__builtin_mblaze_fsl_get">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_aget : GCCBuiltin<"__builtin_mblaze_fsl_aget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_cget : GCCBuiltin<"__builtin_mblaze_fsl_cget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_caget : GCCBuiltin<"__builtin_mblaze_fsl_caget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_eget : GCCBuiltin<"__builtin_mblaze_fsl_eget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_eaget : GCCBuiltin<"__builtin_mblaze_fsl_eaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_ecget : GCCBuiltin<"__builtin_mblaze_fsl_ecget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_ecaget : GCCBuiltin<"__builtin_mblaze_fsl_ecaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_nget : GCCBuiltin<"__builtin_mblaze_fsl_nget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_naget : GCCBuiltin<"__builtin_mblaze_fsl_naget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_ncget : GCCBuiltin<"__builtin_mblaze_fsl_ncget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_ncaget : GCCBuiltin<"__builtin_mblaze_fsl_ncaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_neget : GCCBuiltin<"__builtin_mblaze_fsl_neget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_neaget : GCCBuiltin<"__builtin_mblaze_fsl_neaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_necget : GCCBuiltin<"__builtin_mblaze_fsl_necget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_necaget : GCCBuiltin<"__builtin_mblaze_fsl_necaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tget : GCCBuiltin<"__builtin_mblaze_fsl_tget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_taget : GCCBuiltin<"__builtin_mblaze_fsl_taget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tcget : GCCBuiltin<"__builtin_mblaze_fsl_tcget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tcaget : GCCBuiltin<"__builtin_mblaze_fsl_tcaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_teget : GCCBuiltin<"__builtin_mblaze_fsl_teget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_teaget : GCCBuiltin<"__builtin_mblaze_fsl_teaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tecget : GCCBuiltin<"__builtin_mblaze_fsl_tecget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tecaget : GCCBuiltin<"__builtin_mblaze_fsl_tecaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tnget : GCCBuiltin<"__builtin_mblaze_fsl_tnget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tnaget : GCCBuiltin<"__builtin_mblaze_fsl_tnaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tncget : GCCBuiltin<"__builtin_mblaze_fsl_tncget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tncaget : GCCBuiltin<"__builtin_mblaze_fsl_tncaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tneget : GCCBuiltin<"__builtin_mblaze_fsl_tneget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tneaget : GCCBuiltin<"__builtin_mblaze_fsl_tneaget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tnecget : GCCBuiltin<"__builtin_mblaze_fsl_tnecget">,
MBFSL_Get_Intrinsic;
def int_mblaze_fsl_tnecaget : GCCBuiltin<"__builtin_mblaze_fsl_tnecaget">,
MBFSL_Get_Intrinsic;
//===----------------------------------------------------------------------===//
// MicroBlaze FSL Put Intrinsic Definitions.
//
def int_mblaze_fsl_put : GCCBuiltin<"__builtin_mblaze_fsl_put">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_aput : GCCBuiltin<"__builtin_mblaze_fsl_aput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_cput : GCCBuiltin<"__builtin_mblaze_fsl_cput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_caput : GCCBuiltin<"__builtin_mblaze_fsl_caput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_nput : GCCBuiltin<"__builtin_mblaze_fsl_nput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_naput : GCCBuiltin<"__builtin_mblaze_fsl_naput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_ncput : GCCBuiltin<"__builtin_mblaze_fsl_ncput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_ncaput : GCCBuiltin<"__builtin_mblaze_fsl_ncaput">,
MBFSL_Put_Intrinsic;
def int_mblaze_fsl_tput : GCCBuiltin<"__builtin_mblaze_fsl_tput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_taput : GCCBuiltin<"__builtin_mblaze_fsl_taput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tcput : GCCBuiltin<"__builtin_mblaze_fsl_tcput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tcaput : GCCBuiltin<"__builtin_mblaze_fsl_tcaput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tnput : GCCBuiltin<"__builtin_mblaze_fsl_tnput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tnaput : GCCBuiltin<"__builtin_mblaze_fsl_tnaput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tncput : GCCBuiltin<"__builtin_mblaze_fsl_tncput">,
MBFSL_PutT_Intrinsic;
def int_mblaze_fsl_tncaput : GCCBuiltin<"__builtin_mblaze_fsl_tncaput">,
MBFSL_PutT_Intrinsic;

View File

@ -1,167 +0,0 @@
//===-- MBlazeMCInstLower.cpp - Convert MBlaze MachineInstr to an MCInst---===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains code to lower MBlaze MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//
#include "MBlazeMCInstLower.h"
#include "MBlazeInstrInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/Constants.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/Mangler.h"
using namespace llvm;
MCSymbol *MBlazeMCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
return Printer.Mang->getSymbol(MO.getGlobal());
}
MCSymbol *MBlazeMCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}
MCSymbol *MBlazeMCInstLower::
GetJumpTableSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
<< Printer.getFunctionNumber() << '_'
<< MO.getIndex();
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
// Create a symbol for the name.
return Ctx.GetOrCreateSymbol(Name.str());
}
MCSymbol *MBlazeMCInstLower::
GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
<< Printer.getFunctionNumber() << '_'
<< MO.getIndex();
switch (MO.getTargetFlags()) {
default:
llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
// Create a symbol for the name.
return Ctx.GetOrCreateSymbol(Name.str());
}
MCSymbol *MBlazeMCInstLower::
GetBlockAddressSymbol(const MachineOperand &MO) const {
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
}
MCOperand MBlazeMCInstLower::
LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
switch (MO.getTargetFlags()) {
default:
llvm_unreachable("Unknown target flag on GV operand");
case 0: break;
}
if (!MO.isJTI() && MO.getOffset())
Expr = MCBinaryExpr::CreateAdd(Expr,
MCConstantExpr::Create(MO.getOffset(), Ctx),
Ctx);
return MCOperand::CreateExpr(Expr);
}
void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
OutMI.setOpcode(MI->getOpcode());
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
MCOperand MCOp;
switch (MO.getType()) {
default: llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit()) continue;
MCOp = MCOperand::CreateReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
MCOp = MCOperand::CreateImm(MO.getImm());
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
break;
case MachineOperand::MO_ExternalSymbol:
MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
break;
case MachineOperand::MO_JumpTableIndex:
MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
break;
case MachineOperand::MO_ConstantPoolIndex:
MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
break;
case MachineOperand::MO_BlockAddress:
MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
break;
case MachineOperand::MO_FPImmediate: {
bool ignored;
APFloat FVal = MO.getFPImm()->getValueAPF();
FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored);
APInt IVal = FVal.bitcastToAPInt();
uint64_t Val = *IVal.getRawData();
MCOp = MCOperand::CreateImm(Val);
break;
}
case MachineOperand::MO_RegisterMask:
continue;
}
OutMI.addOperand(MCOp);
}
}

View File

@ -1,47 +0,0 @@
//===-- MBlazeMCInstLower.h - Lower MachineInstr to MCInst ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZE_MCINSTLOWER_H
#define MBLAZE_MCINSTLOWER_H
#include "llvm/Support/Compiler.h"
namespace llvm {
class AsmPrinter;
class MCContext;
class MCInst;
class MCOperand;
class MCSymbol;
class MachineInstr;
class MachineModuleInfoMachO;
class MachineOperand;
/// MBlazeMCInstLower - This class is used to lower an MachineInstr
/// into an MCInst.
class LLVM_LIBRARY_VISIBILITY MBlazeMCInstLower {
MCContext &Ctx;
AsmPrinter &Printer;
public:
MBlazeMCInstLower(MCContext &ctx, AsmPrinter &printer)
: Ctx(ctx), Printer(printer) {}
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const;
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const;
MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const;
MCSymbol *GetBlockAddressSymbol(const MachineOperand &MO) const;
};
}
#endif

View File

@ -1,14 +0,0 @@
//===-- MBlazeMachineFunctionInfo.cpp - Private data ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MBlazeMachineFunction.h"
using namespace llvm;
void MBlazeFunctionInfo::anchor() { }

View File

@ -1,169 +0,0 @@
//===-- MBlazeMachineFunctionInfo.h - Private data --------------*- 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 MBlaze specific subclass of MachineFunctionInfo.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZE_MACHINE_FUNCTION_INFO_H
#define MBLAZE_MACHINE_FUNCTION_INFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
/// MBlazeFunctionInfo - This class is derived from MachineFunction private
/// MBlaze target-specific information for each MachineFunction.
class MBlazeFunctionInfo : public MachineFunctionInfo {
virtual void anchor();
/// Holds for each function where on the stack the Frame Pointer must be
/// saved. This is used on Prologue and Epilogue to emit FP save/restore
int FPStackOffset;
/// Holds for each function where on the stack the Return Address must be
/// saved. This is used on Prologue and Epilogue to emit RA save/restore
int RAStackOffset;
/// MBlazeFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
struct MBlazeFIHolder {
int FI;
int SPOffset;
MBlazeFIHolder(int FrameIndex, int StackPointerOffset)
: FI(FrameIndex), SPOffset(StackPointerOffset) {}
};
/// When PIC is used the GP must be saved on the stack on the function
/// prologue and must be reloaded from this stack location after every
/// call. A reference to its stack location and frame index must be kept
/// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
MBlazeFIHolder GPHolder;
/// On LowerFormalArguments the stack size is unknown, so the Stack
/// Pointer Offset calculation of "not in register arguments" must be
/// postponed to emitPrologue.
SmallVector<MBlazeFIHolder, 16> FnLoadArgs;
bool HasLoadArgs;
// When VarArgs, we must write registers back to caller stack, preserving
// on register arguments. Since the stack size is unknown on
// LowerFormalArguments, the Stack Pointer Offset calculation must be
// postponed to emitPrologue.
SmallVector<MBlazeFIHolder, 4> FnStoreVarArgs;
bool HasStoreVarArgs;
// When determining the final stack layout some of the frame indexes may
// be replaced by new frame indexes that reside in the caller's stack
// frame. The replacements are recorded in this structure.
DenseMap<int,int> FIReplacements;
/// SRetReturnReg - Some subtargets require that sret lowering includes
/// returning the value of the returned struct in a register. This field
/// holds the virtual register into which the sret argument is passed.
unsigned SRetReturnReg;
/// GlobalBaseReg - keeps track of the virtual register initialized for
/// use as the global base register. This is used for PIC in some PIC
/// relocation models.
unsigned GlobalBaseReg;
// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex;
/// LiveInFI - keeps track of the frame indexes in a callers stack
/// frame that are live into a function.
SmallVector<int, 16> LiveInFI;
public:
MBlazeFunctionInfo(MachineFunction& MF)
: FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1), HasLoadArgs(false),
HasStoreVarArgs(false), SRetReturnReg(0), GlobalBaseReg(0),
VarArgsFrameIndex(0), LiveInFI()
{}
int getFPStackOffset() const { return FPStackOffset; }
void setFPStackOffset(int Off) { FPStackOffset = Off; }
int getRAStackOffset() const { return RAStackOffset; }
void setRAStackOffset(int Off) { RAStackOffset = Off; }
int getGPStackOffset() const { return GPHolder.SPOffset; }
int getGPFI() const { return GPHolder.FI; }
void setGPStackOffset(int Off) { GPHolder.SPOffset = Off; }
void setGPFI(int FI) { GPHolder.FI = FI; }
bool needGPSaveRestore() const { return GPHolder.SPOffset != -1; }
bool hasLoadArgs() const { return HasLoadArgs; }
bool hasStoreVarArgs() const { return HasStoreVarArgs; }
void recordLiveIn(int FI) {
LiveInFI.push_back(FI);
}
bool isLiveIn(int FI) {
for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i)
if (FI == LiveInFI[i]) return true;
return false;
}
const SmallVectorImpl<int> &getLiveIn() const { return LiveInFI; }
void recordReplacement(int OFI, int NFI) {
FIReplacements.insert(std::make_pair(OFI,NFI));
}
bool hasReplacement(int OFI) const {
return FIReplacements.find(OFI) != FIReplacements.end();
}
int getReplacement(int OFI) const {
return FIReplacements.lookup(OFI);
}
void recordLoadArgsFI(int FI, int SPOffset) {
if (!HasLoadArgs) HasLoadArgs=true;
FnLoadArgs.push_back(MBlazeFIHolder(FI, SPOffset));
}
void recordStoreVarArgsFI(int FI, int SPOffset) {
if (!HasStoreVarArgs) HasStoreVarArgs=true;
FnStoreVarArgs.push_back(MBlazeFIHolder(FI, SPOffset));
}
void adjustLoadArgsFI(MachineFrameInfo *MFI) const {
if (!hasLoadArgs()) return;
for (unsigned i = 0, e = FnLoadArgs.size(); i != e; ++i)
MFI->setObjectOffset(FnLoadArgs[i].FI, FnLoadArgs[i].SPOffset);
}
void adjustStoreVarArgsFI(MachineFrameInfo *MFI) const {
if (!hasStoreVarArgs()) return;
for (unsigned i = 0, e = FnStoreVarArgs.size(); i != e; ++i)
MFI->setObjectOffset(FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset);
}
unsigned getSRetReturnReg() const { return SRetReturnReg; }
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
unsigned getGlobalBaseReg() const { return GlobalBaseReg; }
void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; }
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
};
} // end of namespace llvm
#endif // MBLAZE_MACHINE_FUNCTION_INFO_H

View File

@ -1,145 +0,0 @@
//===-- MBlazeRegisterInfo.cpp - MBlaze Register Information --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MBlaze implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-frame-info"
#include "MBlazeRegisterInfo.h"
#include "MBlaze.h"
#include "MBlazeMachineFunction.h"
#include "MBlazeSubtarget.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#define GET_REGINFO_TARGET_DESC
#include "MBlazeGenRegisterInfo.inc"
using namespace llvm;
MBlazeRegisterInfo::
MBlazeRegisterInfo(const MBlazeSubtarget &ST)
: MBlazeGenRegisterInfo(MBlaze::R15), Subtarget(ST) {}
unsigned MBlazeRegisterInfo::getPICCallReg() {
return MBlaze::R20;
}
//===----------------------------------------------------------------------===//
// Callee Saved Registers methods
//===----------------------------------------------------------------------===//
/// MBlaze Callee Saved Registers
const uint16_t* MBlazeRegisterInfo::
getCalleeSavedRegs(const MachineFunction *MF) const {
// MBlaze callee-save register range is R20 - R31
static const uint16_t CalleeSavedRegs[] = {
MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23,
MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27,
MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31,
0
};
return CalleeSavedRegs;
}
BitVector MBlazeRegisterInfo::
getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
Reserved.set(MBlaze::R0);
Reserved.set(MBlaze::R1);
Reserved.set(MBlaze::R2);
Reserved.set(MBlaze::R13);
Reserved.set(MBlaze::R14);
Reserved.set(MBlaze::R15);
Reserved.set(MBlaze::R16);
Reserved.set(MBlaze::R17);
Reserved.set(MBlaze::R18);
Reserved.set(MBlaze::R19);
return Reserved;
}
// FrameIndex represent objects inside a abstract stack.
// We must replace FrameIndex with an stack/frame pointer
// direct reference.
void MBlazeRegisterInfo::
eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
unsigned FIOperandNum, RegScavenger *RS) const {
MachineInstr &MI = *II;
MachineFunction &MF = *MI.getParent()->getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
unsigned OFIOperandNum = FIOperandNum == 2 ? 1 : 2;
DEBUG(dbgs() << "\nFunction : " << MF.getName() << "\n";
dbgs() << "<--------->\n" << MI);
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
int stackSize = MFI->getStackSize();
int spOffset = MFI->getObjectOffset(FrameIndex);
DEBUG(MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
dbgs() << "FrameIndex : " << FrameIndex << "\n"
<< "spOffset : " << spOffset << "\n"
<< "stackSize : " << stackSize << "\n"
<< "isFixed : " << MFI->isFixedObjectIndex(FrameIndex) << "\n"
<< "isLiveIn : " << MBlazeFI->isLiveIn(FrameIndex) << "\n"
<< "isSpill : " << MFI->isSpillSlotObjectIndex(FrameIndex)
<< "\n" );
// as explained on LowerFormalArguments, detect negative offsets
// and adjust SPOffsets considering the final stack size.
int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
Offset += MI.getOperand(OFIOperandNum).getImm();
DEBUG(dbgs() << "Offset : " << Offset << "\n" << "<--------->\n");
MI.getOperand(OFIOperandNum).ChangeToImmediate(Offset);
MI.getOperand(FIOperandNum).ChangeToRegister(getFrameRegister(MF), false);
}
void MBlazeRegisterInfo::
processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *) const {
// Set the stack offset where GP must be saved/loaded from.
MachineFrameInfo *MFI = MF.getFrameInfo();
MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
if (MBlazeFI->needGPSaveRestore())
MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset());
}
unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
return TFI->hasFP(MF) ? MBlaze::R19 : MBlaze::R1;
}
unsigned MBlazeRegisterInfo::getEHExceptionRegister() const {
llvm_unreachable("What is the exception register");
}
unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
llvm_unreachable("What is the exception handler register");
}

View File

@ -1,69 +0,0 @@
//===-- MBlazeRegisterInfo.h - MBlaze Register Information Impl -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the MBlaze implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEREGISTERINFO_H
#define MBLAZEREGISTERINFO_H
#include "MBlaze.h"
#include "llvm/Target/TargetRegisterInfo.h"
#define GET_REGINFO_HEADER
#include "MBlazeGenRegisterInfo.inc"
namespace llvm {
class MBlazeSubtarget;
class TargetInstrInfo;
class Type;
namespace MBlaze {
/// SubregIndex - The index of various sized subregister classes. Note that
/// these indices must be kept in sync with the class indices in the
/// MBlazeRegisterInfo.td file.
enum SubregIndex {
SUBREG_FPEVEN = 1, SUBREG_FPODD = 2
};
}
struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
const MBlazeSubtarget &Subtarget;
MBlazeRegisterInfo(const MBlazeSubtarget &Subtarget);
/// Get PIC indirect call register
static unsigned getPICCallReg();
/// Code Generation virtual methods...
const uint16_t *getCalleeSavedRegs(const MachineFunction* MF = 0) const;
BitVector getReservedRegs(const MachineFunction &MF) const;
/// Stack Frame Processing Methods
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = NULL) const;
/// Debug information queries.
unsigned getFrameRegister(const MachineFunction &MF) const;
/// Exception handling queries.
unsigned getEHExceptionRegister() const;
unsigned getEHHandlerRegister() const;
};
} // end namespace llvm
#endif

View File

@ -1,148 +0,0 @@
//===-- MBlazeRegisterInfo.td - MBlaze 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 MicroBlaze register file
//===----------------------------------------------------------------------===//
// We have banks of 32 registers each.
class MBlazeReg<string n> : Register<n> {
field bits<5> Num;
let Namespace = "MBlaze";
}
// Special purpose registers have 15-bit values
class MBlazeSReg<string n> : Register<n> {
field bits<15> Num;
let Namespace = "MBlaze";
}
// MBlaze general purpose registers
class MBlazeGPRReg<bits<5> num, string n> : MBlazeReg<n> {
let Num = num;
}
// MBlaze special purpose registers
class MBlazeSPRReg<bits<15> num, string n> : MBlazeSReg<n> {
let Num = num;
}
//===----------------------------------------------------------------------===//
// Registers
//===----------------------------------------------------------------------===//
let Namespace = "MBlaze" in {
// General Purpose Registers
def R0 : MBlazeGPRReg< 0, "r0">, DwarfRegNum<[0]>;
def R1 : MBlazeGPRReg< 1, "r1">, DwarfRegNum<[1]>;
def R2 : MBlazeGPRReg< 2, "r2">, DwarfRegNum<[2]>;
def R3 : MBlazeGPRReg< 3, "r3">, DwarfRegNum<[3]>;
def R4 : MBlazeGPRReg< 4, "r4">, DwarfRegNum<[4]>;
def R5 : MBlazeGPRReg< 5, "r5">, DwarfRegNum<[5]>;
def R6 : MBlazeGPRReg< 6, "r6">, DwarfRegNum<[6]>;
def R7 : MBlazeGPRReg< 7, "r7">, DwarfRegNum<[7]>;
def R8 : MBlazeGPRReg< 8, "r8">, DwarfRegNum<[8]>;
def R9 : MBlazeGPRReg< 9, "r9">, DwarfRegNum<[9]>;
def R10 : MBlazeGPRReg< 10, "r10">, DwarfRegNum<[10]>;
def R11 : MBlazeGPRReg< 11, "r11">, DwarfRegNum<[11]>;
def R12 : MBlazeGPRReg< 12, "r12">, DwarfRegNum<[12]>;
def R13 : MBlazeGPRReg< 13, "r13">, DwarfRegNum<[13]>;
def R14 : MBlazeGPRReg< 14, "r14">, DwarfRegNum<[14]>;
def R15 : MBlazeGPRReg< 15, "r15">, DwarfRegNum<[15]>;
def R16 : MBlazeGPRReg< 16, "r16">, DwarfRegNum<[16]>;
def R17 : MBlazeGPRReg< 17, "r17">, DwarfRegNum<[17]>;
def R18 : MBlazeGPRReg< 18, "r18">, DwarfRegNum<[18]>;
def R19 : MBlazeGPRReg< 19, "r19">, DwarfRegNum<[19]>;
def R20 : MBlazeGPRReg< 20, "r20">, DwarfRegNum<[20]>;
def R21 : MBlazeGPRReg< 21, "r21">, DwarfRegNum<[21]>;
def R22 : MBlazeGPRReg< 22, "r22">, DwarfRegNum<[22]>;
def R23 : MBlazeGPRReg< 23, "r23">, DwarfRegNum<[23]>;
def R24 : MBlazeGPRReg< 24, "r24">, DwarfRegNum<[24]>;
def R25 : MBlazeGPRReg< 25, "r25">, DwarfRegNum<[25]>;
def R26 : MBlazeGPRReg< 26, "r26">, DwarfRegNum<[26]>;
def R27 : MBlazeGPRReg< 27, "r27">, DwarfRegNum<[27]>;
def R28 : MBlazeGPRReg< 28, "r28">, DwarfRegNum<[28]>;
def R29 : MBlazeGPRReg< 29, "r29">, DwarfRegNum<[29]>;
def R30 : MBlazeGPRReg< 30, "r30">, DwarfRegNum<[30]>;
def R31 : MBlazeGPRReg< 31, "r31">, DwarfRegNum<[31]>;
// Special Purpose Registers
def RPC : MBlazeSPRReg<0x0000, "rpc">, DwarfRegNum<[32]>;
def RMSR : MBlazeSPRReg<0x0001, "rmsr">, DwarfRegNum<[33]>;
def REAR : MBlazeSPRReg<0x0003, "rear">, DwarfRegNum<[34]>;
def RESR : MBlazeSPRReg<0x0005, "resr">, DwarfRegNum<[35]>;
def RFSR : MBlazeSPRReg<0x0007, "rfsr">, DwarfRegNum<[36]>;
def RBTR : MBlazeSPRReg<0x000B, "rbtr">, DwarfRegNum<[37]>;
def REDR : MBlazeSPRReg<0x000D, "redr">, DwarfRegNum<[38]>;
def RPID : MBlazeSPRReg<0x1000, "rpid">, DwarfRegNum<[39]>;
def RZPR : MBlazeSPRReg<0x1001, "rzpr">, DwarfRegNum<[40]>;
def RTLBX : MBlazeSPRReg<0x1002, "rtlbx">, DwarfRegNum<[41]>;
def RTLBLO : MBlazeSPRReg<0x1003, "rtlblo">, DwarfRegNum<[42]>;
def RTLBHI : MBlazeSPRReg<0x1004, "rtlbhi">, DwarfRegNum<[43]>;
def RTLBSX : MBlazeSPRReg<0x1004, "rtlbsx">, DwarfRegNum<[44]>;
def RPVR0 : MBlazeSPRReg<0x2000, "rpvr0">, DwarfRegNum<[45]>;
def RPVR1 : MBlazeSPRReg<0x2001, "rpvr1">, DwarfRegNum<[46]>;
def RPVR2 : MBlazeSPRReg<0x2002, "rpvr2">, DwarfRegNum<[47]>;
def RPVR3 : MBlazeSPRReg<0x2003, "rpvr3">, DwarfRegNum<[48]>;
def RPVR4 : MBlazeSPRReg<0x2004, "rpvr4">, DwarfRegNum<[49]>;
def RPVR5 : MBlazeSPRReg<0x2005, "rpvr5">, DwarfRegNum<[50]>;
def RPVR6 : MBlazeSPRReg<0x2006, "rpvr6">, DwarfRegNum<[51]>;
def RPVR7 : MBlazeSPRReg<0x2007, "rpvr7">, DwarfRegNum<[52]>;
def RPVR8 : MBlazeSPRReg<0x2008, "rpvr8">, DwarfRegNum<[53]>;
def RPVR9 : MBlazeSPRReg<0x2009, "rpvr9">, DwarfRegNum<[54]>;
def RPVR10 : MBlazeSPRReg<0x200A, "rpvr10">, DwarfRegNum<[55]>;
def RPVR11 : MBlazeSPRReg<0x200B, "rpvr11">, DwarfRegNum<[56]>;
// The carry bit. In the Microblaze this is really bit 29 of the
// MSR register but this is the only bit of that register that we
// are interested in modeling.
def CARRY : MBlazeSPRReg<0x0000, "rmsr[c]">;
}
//===----------------------------------------------------------------------===//
// Register Classes
//===----------------------------------------------------------------------===//
def GPR : RegisterClass<"MBlaze", [i32,f32], 32, (sequence "R%u", 0, 31)>;
def SPR : RegisterClass<"MBlaze", [i32], 32, (add
// Reserved
RPC,
RMSR,
REAR,
RESR,
RFSR,
RBTR,
REDR,
RPID,
RZPR,
RTLBX,
RTLBLO,
RTLBHI,
RPVR0,
RPVR1,
RPVR2,
RPVR3,
RPVR4,
RPVR5,
RPVR6,
RPVR7,
RPVR8,
RPVR9,
RPVR10,
RPVR11
)>
{
// None of the special purpose registers are allocatable.
let isAllocatable = 0;
}
def CRC : RegisterClass<"MBlaze", [i32], 32, (add CARRY)> {
let CopyCost = -1;
}

View File

@ -1,47 +0,0 @@
//===-- MBlazeRelocations.h - MBlaze Code Relocations -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MBlaze target-specific relocation types.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZERELOCATIONS_H
#define MBLAZERELOCATIONS_H
#include "llvm/CodeGen/MachineRelocation.h"
namespace llvm {
namespace MBlaze {
enum RelocationType {
/// reloc_pcrel_word - PC relative relocation, add the relocated value to
/// the value already in memory, after we adjust it for where the PC is.
reloc_pcrel_word = 0,
/// reloc_picrel_word - PIC base relative relocation, add the relocated
/// value to the value already in memory, after we adjust it for where the
/// PIC base is.
reloc_picrel_word = 1,
/// reloc_absolute_word - absolute relocation, just add the relocated
/// value to the value already in memory.
reloc_absolute_word = 2,
/// reloc_absolute_word_sext - absolute relocation, just add the relocated
/// value to the value already in memory. In object files, it represents a
/// value which must be sign-extended when resolving the relocation.
reloc_absolute_word_sext = 3,
/// reloc_absolute_dword - absolute relocation, just add the relocated
/// value to the value already in memory.
reloc_absolute_dword = 4
};
}
}
#endif

View File

@ -1,50 +0,0 @@
//===-- MBlazeSchedule.td - MBlaze Scheduling Definitions --*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze functional units.
//===----------------------------------------------------------------------===//
def IF : FuncUnit;
def ID : FuncUnit;
def EX : FuncUnit;
def MA : FuncUnit;
def WB : FuncUnit;
//===----------------------------------------------------------------------===//
// Instruction Itinerary classes used for MBlaze
//===----------------------------------------------------------------------===//
def IIC_ALU : InstrItinClass;
def IIC_ALUm : InstrItinClass;
def IIC_ALUd : InstrItinClass;
def IIC_SHT : InstrItinClass;
def IIC_FSLg : InstrItinClass;
def IIC_FSLp : InstrItinClass;
def IIC_MEMs : InstrItinClass;
def IIC_MEMl : InstrItinClass;
def IIC_FPU : InstrItinClass;
def IIC_FPUd : InstrItinClass;
def IIC_FPUf : InstrItinClass;
def IIC_FPUi : InstrItinClass;
def IIC_FPUs : InstrItinClass;
def IIC_FPUc : InstrItinClass;
def IIC_BR : InstrItinClass;
def IIC_BRc : InstrItinClass;
def IIC_BRl : InstrItinClass;
def IIC_WDC : InstrItinClass;
def IIC_Pseudo : InstrItinClass;
//===----------------------------------------------------------------------===//
// MBlaze instruction itineraries for three stage pipeline.
//===----------------------------------------------------------------------===//
include "MBlazeSchedule3.td"
//===----------------------------------------------------------------------===//
// MBlaze instruction itineraries for five stage pipeline.
//===----------------------------------------------------------------------===//
include "MBlazeSchedule5.td"

View File

@ -1,236 +0,0 @@
//===-- MBlazeSchedule3.td - MBlaze Scheduling Definitions -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze instruction itineraries for the three stage pipeline.
//===----------------------------------------------------------------------===//
def MBlazePipe3Itineraries : ProcessorItineraries<
[IF,ID,EX], [], [
// ALU instruction with one destination register and either two register
// source operands or one register source operand and one immediate operand.
// The instruction takes one cycle to execute in each of the stages. The
// two source operands are read during the decode stage and the result is
// ready after the execute stage.
InstrItinData< IIC_ALU,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]>], // one cycle in execute stage
[ 2 // result ready after two cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// ALU multiply instruction with one destination register and either two
// register source operands or one register source operand and one immediate
// operand. The instruction takes one cycle to execute in each of the
// pipeline stages except the execute stage, which takes three cycles. The
// two source operands are read during the decode stage and the result is
// ready after the execute stage.
InstrItinData< IIC_ALUm,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<3,[EX]>], // three cycles in execute stage
[ 4 // result ready after four cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// ALU divide instruction with one destination register two register source
// operands. The instruction takes one cycle to execute in each the pipeline
// stages except the execute stage, which takes 34 cycles. The two
// source operands are read during the decode stage and the result is ready
// after the execute stage.
InstrItinData< IIC_ALUd,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<34,[EX]>], // 34 cycles in execute stage
[ 35 // result ready after 35 cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Shift instruction with one destination register and either two register
// source operands or one register source operand and one immediate operand.
// The instruction takes one cycle to execute in each of the pipeline stages
// except the execute stage, which takes two cycles. The two source operands
// are read during the decode stage and the result is ready after the execute
// stage.
InstrItinData< IIC_SHT,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 3 // result ready after three cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Branch instruction with one source operand register. The instruction takes
// one cycle to execute in each of the pipeline stages. The source operand is
// read during the decode stage.
InstrItinData< IIC_BR,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]>], // one cycle in execute stage
[ 1 ]>, // first operand read after one cycle
// Conditional branch instruction with two source operand registers. The
// instruction takes one cycle to execute in each of the pipeline stages. The
// two source operands are read during the decode stage.
InstrItinData< IIC_BRc,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]>], // one cycle in execute stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Branch and link instruction with one destination register and one source
// operand register. The instruction takes one cycle to execute in each of
// the pipeline stages. The source operand is read during the decode stage
// and the destination register is ready after the execute stage.
InstrItinData< IIC_BRl,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]>], // one cycle in execute stage
[ 2 // result ready after two cycles
, 1 ]>, // first operand read after one cycle
// Cache control instruction with two source operand registers. The
// instruction takes one cycle to execute in each of the pipeline stages
// except the memory access stage, which takes two cycles. The source
// operands are read during the decode stage.
InstrItinData< IIC_WDC,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Floating point instruction with one destination register and two source
// operand registers. The instruction takes one cycle to execute in each of
// the pipeline stages except the execute stage, which takes six cycles. The
// source operands are read during the decode stage and the results are ready
// after the execute stage.
InstrItinData< IIC_FPU,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<6,[EX]>], // six cycles in execute stage
[ 7 // result ready after seven cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Floating point divide instruction with one destination register and two
// source operand registers. The instruction takes one cycle to execute in
// each of the pipeline stages except the execute stage, which takes 30
// cycles. The source operands are read during the decode stage and the
// results are ready after the execute stage.
InstrItinData< IIC_FPUd,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<30,[EX]>], // one cycle in execute stage
[ 31 // result ready after 31 cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Convert floating point to integer instruction with one destination
// register and one source operand register. The instruction takes one cycle
// to execute in each of the pipeline stages except the execute stage,
// which takes seven cycles. The source operands are read during the decode
// stage and the results are ready after the execute stage.
InstrItinData< IIC_FPUi,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<7,[EX]>], // seven cycles in execute stage
[ 8 // result ready after eight cycles
, 1 ]>, // first operand read after one cycle
// Convert integer to floating point instruction with one destination
// register and one source operand register. The instruction takes one cycle
// to execute in each of the pipeline stages except the execute stage,
// which takes six cycles. The source operands are read during the decode
// stage and the results are ready after the execute stage.
InstrItinData< IIC_FPUf,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<6,[EX]>], // six cycles in execute stage
[ 7 // result ready after seven cycles
, 1 ]>, // first operand read after one cycle
// Floating point square root instruction with one destination register and
// one source operand register. The instruction takes one cycle to execute in
// each of the pipeline stages except the execute stage, which takes 29
// cycles. The source operands are read during the decode stage and the
// results are ready after the execute stage.
InstrItinData< IIC_FPUs,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<29,[EX]>], // 29 cycles in execute stage
[ 30 // result ready after 30 cycles
, 1 ]>, // first operand read after one cycle
// Floating point comparison instruction with one destination register and
// two source operand registers. The instruction takes one cycle to execute
// in each of the pipeline stages except the execute stage, which takes three
// cycles. The source operands are read during the decode stage and the
// results are ready after the execute stage.
InstrItinData< IIC_FPUc,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<3,[EX]>], // three cycles in execute stage
[ 4 // result ready after four cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// FSL get instruction with one register or immediate source operand and one
// destination register. The instruction takes one cycle to execute in each
// of the pipeline stages except the execute stage, which takes two cycles.
// The one source operand is read during the decode stage and the result is
// ready after the execute stage.
InstrItinData< IIC_FSLg,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 3 // result ready after two cycles
, 1 ]>, // first operand read after one cycle
// FSL put instruction with either two register source operands or one
// register source operand and one immediate operand. There is no result
// produced by the instruction. The instruction takes one cycle to execute in
// each of the pipeline stages except the execute stage, which takes two
// cycles. The two source operands are read during the decode stage.
InstrItinData< IIC_FSLp,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Memory store instruction with either three register source operands or two
// register source operands and one immediate operand. There is no result
// produced by the instruction. The instruction takes one cycle to execute in
// each of the pipeline stages except the execute stage, which takes two
// cycles. All of the source operands are read during the decode stage.
InstrItinData< IIC_MEMs,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 1 // first operand read after one cycle
, 1 // second operand read after one cycle
, 1 ]>, // third operand read after one cycle
// Memory load instruction with one destination register and either two
// register source operands or one register source operand and one immediate
// operand. The instruction takes one cycle to execute in each of the
// pipeline stages except the execute stage, which takes two cycles. All of
// the source operands are read during the decode stage and the result is
// ready after the execute stage.
InstrItinData< IIC_MEMl,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<2,[EX]>], // two cycles in execute stage
[ 3 // result ready after four cycles
, 1 // second operand read after one cycle
, 1 ]> // third operand read after one cycle
]>;

View File

@ -1,267 +0,0 @@
//===-- MBlazeSchedule5.td - MBlaze Scheduling Definitions -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// MBlaze instruction itineraries for the five stage pipeline.
//===----------------------------------------------------------------------===//
def MBlazePipe5Itineraries : ProcessorItineraries<
[IF,ID,EX,MA,WB], [], [
// ALU instruction with one destination register and either two register
// source operands or one register source operand and one immediate operand.
// The instruction takes one cycle to execute in each of the stages. The
// two source operands are read during the decode stage and the result is
// ready after the execute stage.
InstrItinData< IIC_ALU,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 2 // result ready after two cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// ALU multiply instruction with one destination register and either two
// register source operands or one register source operand and one immediate
// operand. The instruction takes one cycle to execute in each of the
// pipeline stages. The two source operands are read during the decode stage
// and the result is ready after the execute stage.
InstrItinData< IIC_ALUm,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 2 // result ready after two cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// ALU divide instruction with one destination register two register source
// operands. The instruction takes one cycle to execute in each the pipeline
// stages except the memory access stage, which takes 31 cycles. The two
// source operands are read during the decode stage and the result is ready
// after the memory access stage.
InstrItinData< IIC_ALUd,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<31,[MA]> // 31 cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 33 // result ready after 33 cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Shift instruction with one destination register and either two register
// source operands or one register source operand and one immediate operand.
// The instruction takes one cycle to execute in each of the pipeline stages.
// The two source operands are read during the decode stage and the result is
// ready after the memory access stage.
InstrItinData< IIC_SHT,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 3 // result ready after three cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Branch instruction with one source operand register. The instruction takes
// one cycle to execute in each of the pipeline stages. The source operand is
// read during the decode stage.
InstrItinData< IIC_BR,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 1 ]>, // first operand read after one cycle
// Conditional branch instruction with two source operand registers. The
// instruction takes one cycle to execute in each of the pipeline stages. The
// two source operands are read during the decode stage.
InstrItinData< IIC_BRc,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Branch and link instruction with one destination register and one source
// operand register. The instruction takes one cycle to execute in each of
// the pipeline stages. The source operand is read during the decode stage
// and the destination register is ready after the writeback stage.
InstrItinData< IIC_BRl,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 4 // result ready after four cycles
, 1 ]>, // first operand read after one cycle
// Cache control instruction with two source operand registers. The
// instruction takes one cycle to execute in each of the pipeline stages
// except the memory access stage, which takes two cycles. The source
// operands are read during the decode stage.
InstrItinData< IIC_WDC,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<2,[MA]> // two cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Floating point instruction with one destination register and two source
// operand registers. The instruction takes one cycle to execute in each of
// the pipeline stages except the memory access stage, which takes two
// cycles. The source operands are read during the decode stage and the
// results are ready after the writeback stage.
InstrItinData< IIC_FPU,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<2,[MA]> // two cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 5 // result ready after five cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Floating point divide instruction with one destination register and two
// source operand registers. The instruction takes one cycle to execute in
// each of the pipeline stages except the memory access stage, which takes 26
// cycles. The source operands are read during the decode stage and the
// results are ready after the writeback stage.
InstrItinData< IIC_FPUd,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<26,[MA]> // 26 cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 29 // result ready after 29 cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Convert floating point to integer instruction with one destination
// register and one source operand register. The instruction takes one cycle
// to execute in each of the pipeline stages except the memory access stage,
// which takes three cycles. The source operands are read during the decode
// stage and the results are ready after the writeback stage.
InstrItinData< IIC_FPUi,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<3,[MA]> // three cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 6 // result ready after six cycles
, 1 ]>, // first operand read after one cycle
// Convert integer to floating point instruction with one destination
// register and one source operand register. The instruction takes one cycle
// to execute in each of the pipeline stages except the memory access stage,
// which takes two cycles. The source operands are read during the decode
// stage and the results are ready after the writeback stage.
InstrItinData< IIC_FPUf,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<2,[MA]> // two cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 5 // result ready after five cycles
, 1 ]>, // first operand read after one cycle
// Floating point square root instruction with one destination register and
// one source operand register. The instruction takes one cycle to execute in
// each of the pipeline stages except the memory access stage, which takes 25
// cycles. The source operands are read during the decode stage and the
// results are ready after the writeback stage.
InstrItinData< IIC_FPUs,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<25,[MA]> // 25 cycles in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 28 // result ready after 28 cycles
, 1 ]>, // first operand read after one cycle
// Floating point comparison instruction with one destination register and
// two source operand registers. The instruction takes one cycle to execute
// in each of the pipeline stages. The source operands are read during the
// decode stage and the results are ready after the execute stage.
InstrItinData< IIC_FPUc,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 2 // result ready after two cycles
, 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// FSL get instruction with one register or immediate source operand and one
// destination register. The instruction takes one cycle to execute in each
// of the pipeline stages. The one source operand is read during the decode
// stage and the result is ready after the execute stage.
InstrItinData< IIC_FSLg,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 2 // result ready after two cycles
, 1 ]>, // first operand read after one cycle
// FSL put instruction with either two register source operands or one
// register source operand and one immediate operand. There is no result
// produced by the instruction. The instruction takes one cycle to execute in
// each of the pipeline stages. The two source operands are read during the
// decode stage.
InstrItinData< IIC_FSLp,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 1 // first operand read after one cycle
, 1 ]>, // second operand read after one cycle
// Memory store instruction with either three register source operands or two
// register source operands and one immediate operand. There is no result
// produced by the instruction. The instruction takes one cycle to execute in
// each of the pipeline stages. All of the source operands are read during
// the decode stage.
InstrItinData< IIC_MEMs,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 1 // first operand read after one cycle
, 1 // second operand read after one cycle
, 1 ]>, // third operand read after one cycle
// Memory load instruction with one destination register and either two
// register source operands or one register source operand and one immediate
// operand. The instruction takes one cycle to execute in each of the
// pipeline stages. All of the source operands are read during the decode
// stage and the result is ready after the writeback stage.
InstrItinData< IIC_MEMl,
[ InstrStage<1,[IF]> // one cycle in fetch stage
, InstrStage<1,[ID]> // one cycle in decode stage
, InstrStage<1,[EX]> // one cycle in execute stage
, InstrStage<1,[MA]> // one cycle in memory access stage
, InstrStage<1,[WB]>], // one cycle in write back stage
[ 4 // result ready after four cycles
, 1 // second operand read after one cycle
, 1 ]> // third operand read after one cycle
]>;

View File

@ -1,23 +0,0 @@
//===-- MBlazeSelectionDAGInfo.cpp - MBlaze 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 MBlazeSelectionDAGInfo class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mblaze-selectiondag-info"
#include "MBlazeTargetMachine.h"
using namespace llvm;
MBlazeSelectionDAGInfo::MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM)
: TargetSelectionDAGInfo(TM) {
}
MBlazeSelectionDAGInfo::~MBlazeSelectionDAGInfo() {
}

View File

@ -1,31 +0,0 @@
//===-- MBlazeSelectionDAGInfo.h - MBlaze 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 MBlaze subclass for TargetSelectionDAGInfo.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZESELECTIONDAGINFO_H
#define MBLAZESELECTIONDAGINFO_H
#include "llvm/Target/TargetSelectionDAGInfo.h"
namespace llvm {
class MBlazeTargetMachine;
class MBlazeSelectionDAGInfo : public TargetSelectionDAGInfo {
public:
explicit MBlazeSelectionDAGInfo(const MBlazeTargetMachine &TM);
~MBlazeSelectionDAGInfo();
};
}
#endif

View File

@ -1,56 +0,0 @@
//===-- MBlazeSubtarget.cpp - MBlaze 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 MBlaze specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#include "MBlazeSubtarget.h"
#include "MBlaze.h"
#include "MBlazeRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "MBlazeGenSubtargetInfo.inc"
using namespace llvm;
MBlazeSubtarget::MBlazeSubtarget(const std::string &TT,
const std::string &CPU,
const std::string &FS):
MBlazeGenSubtargetInfo(TT, CPU, FS),
HasBarrel(false), HasDiv(false), HasMul(false), HasPatCmp(false),
HasFPU(false), HasMul64(false), HasSqrt(false)
{
// Parse features string.
std::string CPUName = CPU;
if (CPUName.empty())
CPUName = "mblaze";
ParseSubtargetFeatures(CPUName, FS);
// Only use instruction scheduling if the selected CPU has an instruction
// itinerary (the default CPU is the only one that doesn't).
HasItin = CPUName != "mblaze";
DEBUG(dbgs() << "CPU " << CPUName << "(" << HasItin << ")\n");
// Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(CPUName);
}
bool MBlazeSubtarget::
enablePostRAScheduler(CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const {
Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL;
CriticalPathRCs.clear();
CriticalPathRCs.push_back(&MBlaze::GPRRegClass);
return HasItin && OptLevel >= CodeGenOpt::Default;
}

View File

@ -1,75 +0,0 @@
//===-- MBlazeSubtarget.h - Define Subtarget for the MBlaze ----*- 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 MBlaze specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZESUBTARGET_H
#define MBLAZESUBTARGET_H
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
#include "MBlazeGenSubtargetInfo.inc"
namespace llvm {
class StringRef;
class MBlazeSubtarget : public MBlazeGenSubtargetInfo {
protected:
bool HasBarrel;
bool HasDiv;
bool HasMul;
bool HasPatCmp;
bool HasFPU;
bool HasMul64;
bool HasSqrt;
bool HasItin;
InstrItineraryData InstrItins;
public:
/// This constructor initializes the data members to match that
/// of the specified triple.
MBlazeSubtarget(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);
/// Compute the number of maximum number of issues per cycle for the
/// MBlaze scheduling itineraries.
void computeIssueWidth();
/// enablePostRAScheduler - True at 'More' optimization.
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const;
/// getInstrItins - Return the instruction itineraies based on subtarget.
const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
bool hasItin() const { return HasItin; }
bool hasPCMP() const { return HasPatCmp; }
bool hasFPU() const { return HasFPU; }
bool hasSqrt() const { return HasSqrt; }
bool hasMul() const { return HasMul; }
bool hasMul64() const { return HasMul64; }
bool hasDiv() const { return HasDiv; }
bool hasBarrel() const { return HasBarrel; }
};
} // End llvm namespace
#endif

View File

@ -1,82 +0,0 @@
//===-- MBlazeTargetMachine.cpp - Define TargetMachine for MBlaze ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements the info about MBlaze target spec.
//
//===----------------------------------------------------------------------===//
#include "MBlazeTargetMachine.h"
#include "MBlaze.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/PassManager.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
extern "C" void LLVMInitializeMBlazeTarget() {
// Register the target.
RegisterTargetMachine<MBlazeTargetMachine> X(TheMBlazeTarget);
}
// DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
// The stack is always 8 byte aligned
// On function prologue, the stack is created by decrementing
// its pointer. Once decremented, all references are done with positive
// offset from the stack/frame pointer, using StackGrowsUp enables
// an easier handling.
MBlazeTargetMachine::
MBlazeTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS),
DL("E-p:32:32:32-i8:8:8-i16:16:16"),
InstrInfo(*this),
FrameLowering(Subtarget),
TLInfo(*this), TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()) {
initAsmInfo();
}
namespace {
/// MBlaze Code Generator Pass Configuration Options.
class MBlazePassConfig : public TargetPassConfig {
public:
MBlazePassConfig(MBlazeTargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
MBlazeTargetMachine &getMBlazeTargetMachine() const {
return getTM<MBlazeTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *MBlazeTargetMachine::createPassConfig(PassManagerBase &PM) {
return new MBlazePassConfig(this, PM);
}
// Install an instruction selector pass using
// the ISelDag to gen MBlaze code.
bool MBlazePassConfig::addInstSelector() {
addPass(createMBlazeISelDag(getMBlazeTargetMachine()));
return false;
}
// Implemented by targets that want to run passes immediately before
// machine code is emitted. return true if -print-machineinstrs should
// print out the code after the passes.
bool MBlazePassConfig::addPreEmitPass() {
addPass(createMBlazeDelaySlotFillerPass(getMBlazeTargetMachine()));
return true;
}

View File

@ -1,80 +0,0 @@
//===-- MBlazeTargetMachine.h - Define TargetMachine for MBlaze -*- 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 MBlaze specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZE_TARGETMACHINE_H
#define MBLAZE_TARGETMACHINE_H
#include "MBlazeFrameLowering.h"
#include "MBlazeISelLowering.h"
#include "MBlazeInstrInfo.h"
#include "MBlazeIntrinsicInfo.h"
#include "MBlazeSelectionDAGInfo.h"
#include "MBlazeSubtarget.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class formatted_raw_ostream;
class MBlazeTargetMachine : public LLVMTargetMachine {
MBlazeSubtarget Subtarget;
const DataLayout DL; // Calculates type size & alignment
MBlazeInstrInfo InstrInfo;
MBlazeFrameLowering FrameLowering;
MBlazeTargetLowering TLInfo;
MBlazeSelectionDAGInfo TSInfo;
MBlazeIntrinsicInfo IntrinsicInfo;
InstrItineraryData InstrItins;
public:
MBlazeTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
virtual const MBlazeInstrInfo *getInstrInfo() const
{ return &InstrInfo; }
virtual const InstrItineraryData *getInstrItineraryData() const
{ return &InstrItins; }
virtual const TargetFrameLowering *getFrameLowering() const
{ return &FrameLowering; }
virtual const MBlazeSubtarget *getSubtargetImpl() const
{ return &Subtarget; }
virtual const DataLayout *getDataLayout() const
{ return &DL;}
virtual const MBlazeRegisterInfo *getRegisterInfo() const
{ return &InstrInfo.getRegisterInfo(); }
virtual const MBlazeTargetLowering *getTargetLowering() const
{ return &TLInfo; }
virtual const MBlazeSelectionDAGInfo* getSelectionDAGInfo() const
{ return &TSInfo; }
const TargetIntrinsicInfo *getIntrinsicInfo() const
{ return &IntrinsicInfo; }
// Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
};
} // End llvm namespace
#endif

View File

@ -1,90 +0,0 @@
//===-- MBlazeTargetObjectFile.cpp - MBlaze object files ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MBlazeTargetObjectFile.h"
#include "MBlazeSubtarget.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ELF.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
void MBlazeTargetObjectFile::
Initialize(MCContext &Ctx, const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
SmallDataSection =
getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
ELF::SHF_WRITE |ELF::SHF_ALLOC,
SectionKind::getDataRel());
SmallBSSSection =
getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
ELF::SHF_WRITE |ELF::SHF_ALLOC,
SectionKind::getBSS());
}
// A address must be loaded from a small section if its size is less than the
// small section size threshold. Data in this section must be addressed using
// gp_rel operator.
static bool IsInSmallSection(uint64_t Size) {
return Size > 0 && Size <= 8;
}
bool MBlazeTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
return false;
return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
}
/// IsGlobalInSmallSection - Return true if this global address should be
/// placed into small data/bss section.
bool MBlazeTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
SectionKind Kind) const {
// Only global variables, not functions.
const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
if (!GVA)
return false;
// We can only do this for datarel or BSS objects for now.
if (!Kind.isBSS() && !Kind.isDataRel())
return false;
// If this is a internal constant string, there is a special
// section for it, but not in small data/bss.
if (Kind.isMergeable1ByteCString())
return false;
Type *Ty = GV->getType()->getElementType();
return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
}
const MCSection *MBlazeTargetObjectFile::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
// TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
// sections?
// Handle Small Section classification here.
if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
return SmallBSSSection;
if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
return SmallDataSection;
// Otherwise, we work the same as ELF.
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
}

View File

@ -1,40 +0,0 @@
//===-- llvm/Target/MBlazeTargetObjectFile.h - MBlaze Obj. Info -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_MBLAZE_TARGETOBJECTFILE_H
#define LLVM_TARGET_MBLAZE_TARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
namespace llvm {
class MBlazeTargetObjectFile : public TargetLoweringObjectFileELF {
const MCSection *SmallDataSection;
const MCSection *SmallBSSSection;
public:
void Initialize(MCContext &Ctx, const TargetMachine &TM);
/// IsGlobalInSmallSection - Return true if this global address should be
/// placed into small data/bss section.
bool IsGlobalInSmallSection(const GlobalValue *GV,
const TargetMachine &TM,
SectionKind Kind) const;
bool IsGlobalInSmallSection(const GlobalValue *GV,
const TargetMachine &TM) const;
const MCSection *SelectSectionForGlobal(const GlobalValue *GV,
SectionKind Kind,
Mangler *Mang,
const TargetMachine &TM) const;
};
} // end namespace llvm
#endif

View File

@ -1,9 +0,0 @@
add_llvm_library(LLVMMBlazeDesc
MBlazeAsmBackend.cpp
MBlazeMCAsmInfo.cpp
MBlazeMCCodeEmitter.cpp
MBlazeMCTargetDesc.cpp
MBlazeELFObjectWriter.cpp
)
add_dependencies(LLVMMBlazeDesc MBlazeCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/MBlaze/MCTargetDesc/LLVMBuild.txt -----------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MBlazeDesc
parent = MBlaze
required_libraries = MBlazeAsmPrinter MBlazeInfo MC Support
add_to_library_groups = MBlaze

View File

@ -1,171 +0,0 @@
//===-- MBlazeAsmBackend.cpp - MBlaze Assembler Backend -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/MBlazeMCTargetDesc.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCELFSymbolFlags.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
static unsigned getFixupKindSize(unsigned Kind) {
switch (Kind) {
default: llvm_unreachable("invalid fixup kind!");
case FK_Data_1: return 1;
case FK_PCRel_2:
case FK_Data_2: return 2;
case FK_PCRel_4:
case FK_Data_4: return 4;
case FK_Data_8: return 8;
}
}
namespace {
class MBlazeAsmBackend : public MCAsmBackend {
public:
MBlazeAsmBackend(const Target &T)
: MCAsmBackend() {
}
unsigned getNumFixupKinds() const {
return 2;
}
bool mayNeedRelaxation(const MCInst &Inst) const;
bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const;
void relaxInstruction(const MCInst &Inst, MCInst &Res) const;
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const;
unsigned getPointerSize() const {
return 4;
}
};
static unsigned getRelaxedOpcode(unsigned Op) {
switch (Op) {
default: return Op;
case MBlaze::ADDIK: return MBlaze::ADDIK32;
case MBlaze::ORI: return MBlaze::ORI32;
case MBlaze::BRLID: return MBlaze::BRLID32;
}
}
bool MBlazeAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
if (getRelaxedOpcode(Inst.getOpcode()) == Inst.getOpcode())
return false;
bool hasExprOrImm = false;
for (unsigned i = 0; i < Inst.getNumOperands(); ++i)
hasExprOrImm |= Inst.getOperand(i).isExpr();
return hasExprOrImm;
}
bool MBlazeAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const {
// FIXME: Is this right? It's what the "generic" code was doing before,
// but is X86 specific. Is it actually true for MBlaze also, or was it
// just close enough to not be a big deal?
//
// Relax if the value is too big for a (signed) i8.
return int64_t(Value) != int64_t(int8_t(Value));
}
void MBlazeAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
Res = Inst;
Res.setOpcode(getRelaxedOpcode(Inst.getOpcode()));
}
bool MBlazeAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
if ((Count % 4) != 0)
return false;
for (uint64_t i = 0; i < Count; i += 4)
OW->Write32(0x00000000);
return true;
}
} // end anonymous namespace
namespace {
class ELFMBlazeAsmBackend : public MBlazeAsmBackend {
public:
uint8_t OSABI;
ELFMBlazeAsmBackend(const Target &T, uint8_t _OSABI)
: MBlazeAsmBackend(T), OSABI(_OSABI) { }
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value) const;
MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
return createMBlazeELFObjectWriter(OS, OSABI);
}
};
void ELFMBlazeAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
unsigned DataSize, uint64_t Value) const {
unsigned Size = getFixupKindSize(Fixup.getKind());
assert(Fixup.getOffset() + Size <= DataSize &&
"Invalid fixup offset!");
char *data = Data + Fixup.getOffset();
switch (Size) {
default: llvm_unreachable("Cannot fixup unknown value.");
case 1: llvm_unreachable("Cannot fixup 1 byte value.");
case 8: llvm_unreachable("Cannot fixup 8 byte value.");
case 4:
*(data+7) = uint8_t(Value);
*(data+6) = uint8_t(Value >> 8);
*(data+3) = uint8_t(Value >> 16);
*(data+2) = uint8_t(Value >> 24);
break;
case 2:
*(data+3) = uint8_t(Value >> 0);
*(data+2) = uint8_t(Value >> 8);
}
}
} // end anonymous namespace
MCAsmBackend *llvm::createMBlazeAsmBackend(const Target &T, StringRef TT,
StringRef CPU) {
Triple TheTriple(TT);
if (TheTriple.isOSDarwin())
assert(0 && "Mac not supported on MBlaze");
if (TheTriple.isOSWindows())
assert(0 && "Windows not supported on MBlaze");
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
return new ELFMBlazeAsmBackend(T, OSABI);
}

View File

@ -1,237 +0,0 @@
//===-- MBlazeBaseInfo.h - Top level definitions for MBlaze -- --*- 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 small standalone helper functions and enum definitions for
// the MBlaze target useful for the compiler back-end and the MC libraries.
// As such, it deliberately does not include references to LLVM core
// code gen types, passes, etc..
//
//===----------------------------------------------------------------------===//
#ifndef MBlazeBASEINFO_H
#define MBlazeBASEINFO_H
#include "MBlazeMCTargetDesc.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
/// MBlazeII - This namespace holds all of the target specific flags that
/// instruction info tracks.
///
namespace MBlazeII {
enum {
// PseudoFrm - This represents an instruction that is a pseudo instruction
// or one that has not been implemented yet. It is illegal to code generate
// it, but tolerated for intermediate implementation stages.
FPseudo = 0,
FRRR,
FRRI,
FCRR,
FCRI,
FRCR,
FRCI,
FCCR,
FCCI,
FRRCI,
FRRC,
FRCX,
FRCS,
FCRCS,
FCRCX,
FCX,
FCR,
FRIR,
FRRRR,
FRI,
FC,
FRR,
FormMask = 63
//===------------------------------------------------------------------===//
// MBlaze Specific MachineOperand flags.
// MO_NO_FLAG,
/// MO_GOT - Represents the offset into the global offset table at which
/// the address the relocation entry symbol resides during execution.
// MO_GOT,
/// MO_GOT_CALL - Represents the offset into the global offset table at
/// which the address of a call site relocation entry symbol resides
/// during execution. This is different from the above since this flag
/// can only be present in call instructions.
// MO_GOT_CALL,
/// MO_GPREL - Represents the offset from the current gp value to be used
/// for the relocatable object file being produced.
// MO_GPREL,
/// MO_ABS_HILO - Represents the hi or low part of an absolute symbol
/// address.
// MO_ABS_HILO
};
}
static inline bool isMBlazeRegister(unsigned Reg) {
return Reg <= 31;
}
static inline bool isSpecialMBlazeRegister(unsigned Reg) {
switch (Reg) {
case 0x0000 : case 0x0001 : case 0x0003 : case 0x0005 :
case 0x0007 : case 0x000B : case 0x000D : case 0x1000 :
case 0x1001 : case 0x1002 : case 0x1003 : case 0x1004 :
case 0x2000 : case 0x2001 : case 0x2002 : case 0x2003 :
case 0x2004 : case 0x2005 : case 0x2006 : case 0x2007 :
case 0x2008 : case 0x2009 : case 0x200A : case 0x200B :
return true;
default:
return false;
}
}
/// getMBlazeRegisterNumbering - Given the enum value for some register, e.g.
/// MBlaze::R0, return the number that it corresponds to (e.g. 0).
static inline unsigned getMBlazeRegisterNumbering(unsigned RegEnum) {
switch (RegEnum) {
case MBlaze::R0 : return 0;
case MBlaze::R1 : return 1;
case MBlaze::R2 : return 2;
case MBlaze::R3 : return 3;
case MBlaze::R4 : return 4;
case MBlaze::R5 : return 5;
case MBlaze::R6 : return 6;
case MBlaze::R7 : return 7;
case MBlaze::R8 : return 8;
case MBlaze::R9 : return 9;
case MBlaze::R10 : return 10;
case MBlaze::R11 : return 11;
case MBlaze::R12 : return 12;
case MBlaze::R13 : return 13;
case MBlaze::R14 : return 14;
case MBlaze::R15 : return 15;
case MBlaze::R16 : return 16;
case MBlaze::R17 : return 17;
case MBlaze::R18 : return 18;
case MBlaze::R19 : return 19;
case MBlaze::R20 : return 20;
case MBlaze::R21 : return 21;
case MBlaze::R22 : return 22;
case MBlaze::R23 : return 23;
case MBlaze::R24 : return 24;
case MBlaze::R25 : return 25;
case MBlaze::R26 : return 26;
case MBlaze::R27 : return 27;
case MBlaze::R28 : return 28;
case MBlaze::R29 : return 29;
case MBlaze::R30 : return 30;
case MBlaze::R31 : return 31;
case MBlaze::RPC : return 0x0000;
case MBlaze::RMSR : return 0x0001;
case MBlaze::REAR : return 0x0003;
case MBlaze::RESR : return 0x0005;
case MBlaze::RFSR : return 0x0007;
case MBlaze::RBTR : return 0x000B;
case MBlaze::REDR : return 0x000D;
case MBlaze::RPID : return 0x1000;
case MBlaze::RZPR : return 0x1001;
case MBlaze::RTLBX : return 0x1002;
case MBlaze::RTLBLO : return 0x1003;
case MBlaze::RTLBHI : return 0x1004;
case MBlaze::RPVR0 : return 0x2000;
case MBlaze::RPVR1 : return 0x2001;
case MBlaze::RPVR2 : return 0x2002;
case MBlaze::RPVR3 : return 0x2003;
case MBlaze::RPVR4 : return 0x2004;
case MBlaze::RPVR5 : return 0x2005;
case MBlaze::RPVR6 : return 0x2006;
case MBlaze::RPVR7 : return 0x2007;
case MBlaze::RPVR8 : return 0x2008;
case MBlaze::RPVR9 : return 0x2009;
case MBlaze::RPVR10 : return 0x200A;
case MBlaze::RPVR11 : return 0x200B;
default: llvm_unreachable("Unknown register number!");
}
}
/// getRegisterFromNumbering - Given the enum value for some register, e.g.
/// MBlaze::R0, return the number that it corresponds to (e.g. 0).
static inline unsigned getMBlazeRegisterFromNumbering(unsigned Reg) {
switch (Reg) {
case 0 : return MBlaze::R0;
case 1 : return MBlaze::R1;
case 2 : return MBlaze::R2;
case 3 : return MBlaze::R3;
case 4 : return MBlaze::R4;
case 5 : return MBlaze::R5;
case 6 : return MBlaze::R6;
case 7 : return MBlaze::R7;
case 8 : return MBlaze::R8;
case 9 : return MBlaze::R9;
case 10 : return MBlaze::R10;
case 11 : return MBlaze::R11;
case 12 : return MBlaze::R12;
case 13 : return MBlaze::R13;
case 14 : return MBlaze::R14;
case 15 : return MBlaze::R15;
case 16 : return MBlaze::R16;
case 17 : return MBlaze::R17;
case 18 : return MBlaze::R18;
case 19 : return MBlaze::R19;
case 20 : return MBlaze::R20;
case 21 : return MBlaze::R21;
case 22 : return MBlaze::R22;
case 23 : return MBlaze::R23;
case 24 : return MBlaze::R24;
case 25 : return MBlaze::R25;
case 26 : return MBlaze::R26;
case 27 : return MBlaze::R27;
case 28 : return MBlaze::R28;
case 29 : return MBlaze::R29;
case 30 : return MBlaze::R30;
case 31 : return MBlaze::R31;
default: llvm_unreachable("Unknown register number!");
}
}
static inline unsigned getSpecialMBlazeRegisterFromNumbering(unsigned Reg) {
switch (Reg) {
case 0x0000 : return MBlaze::RPC;
case 0x0001 : return MBlaze::RMSR;
case 0x0003 : return MBlaze::REAR;
case 0x0005 : return MBlaze::RESR;
case 0x0007 : return MBlaze::RFSR;
case 0x000B : return MBlaze::RBTR;
case 0x000D : return MBlaze::REDR;
case 0x1000 : return MBlaze::RPID;
case 0x1001 : return MBlaze::RZPR;
case 0x1002 : return MBlaze::RTLBX;
case 0x1003 : return MBlaze::RTLBLO;
case 0x1004 : return MBlaze::RTLBHI;
case 0x2000 : return MBlaze::RPVR0;
case 0x2001 : return MBlaze::RPVR1;
case 0x2002 : return MBlaze::RPVR2;
case 0x2003 : return MBlaze::RPVR3;
case 0x2004 : return MBlaze::RPVR4;
case 0x2005 : return MBlaze::RPVR5;
case 0x2006 : return MBlaze::RPVR6;
case 0x2007 : return MBlaze::RPVR7;
case 0x2008 : return MBlaze::RPVR8;
case 0x2009 : return MBlaze::RPVR9;
case 0x200A : return MBlaze::RPVR10;
case 0x200B : return MBlaze::RPVR11;
default: llvm_unreachable("Unknown register number!");
}
}
} // end namespace llvm;
#endif

View File

@ -1,77 +0,0 @@
//===-- MBlazeELFObjectWriter.cpp - MBlaze ELF Writer ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/MBlazeMCTargetDesc.h"
#include "llvm/MC/MCELFObjectWriter.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
namespace {
class MBlazeELFObjectWriter : public MCELFObjectTargetWriter {
public:
MBlazeELFObjectWriter(uint8_t OSABI);
virtual ~MBlazeELFObjectWriter();
protected:
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const;
};
}
MBlazeELFObjectWriter::MBlazeELFObjectWriter(uint8_t OSABI)
: MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_MBLAZE,
/*HasRelocationAddend*/ false) {}
MBlazeELFObjectWriter::~MBlazeELFObjectWriter() {
}
unsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel,
bool IsRelocWithSymbol,
int64_t Addend) const {
// determine the type of the relocation
unsigned Type;
if (IsPCRel) {
switch ((unsigned)Fixup.getKind()) {
default:
llvm_unreachable("Unimplemented");
case FK_PCRel_4:
Type = ELF::R_MICROBLAZE_64_PCREL;
break;
case FK_PCRel_2:
Type = ELF::R_MICROBLAZE_32_PCREL;
break;
}
} else {
switch ((unsigned)Fixup.getKind()) {
default: llvm_unreachable("invalid fixup kind!");
case FK_Data_4:
Type = ((IsRelocWithSymbol || Addend !=0)
? ELF::R_MICROBLAZE_32
: ELF::R_MICROBLAZE_64);
break;
case FK_Data_2:
Type = ELF::R_MICROBLAZE_32;
break;
}
}
return Type;
}
MCObjectWriter *llvm::createMBlazeELFObjectWriter(raw_ostream &OS,
uint8_t OSABI) {
MCELFObjectTargetWriter *MOTW = new MBlazeELFObjectWriter(OSABI);
return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/ false);
}

View File

@ -1,26 +0,0 @@
//===-- MBlazeMCAsmInfo.cpp - MBlaze 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 MBlazeMCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
#include "MBlazeMCAsmInfo.h"
using namespace llvm;
void MBlazeMCAsmInfo::anchor() { }
MBlazeMCAsmInfo::MBlazeMCAsmInfo() {
IsLittleEndian = false;
StackGrowsUp = false;
SupportsDebugInformation = true;
AlignmentIsInBytes = false;
PrivateGlobalPrefix = "$";
GPRel32Directive = "\t.gpword\t";
}

View File

@ -1,30 +0,0 @@
//===-- MBlazeMCAsmInfo.h - MBlaze 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 MBlazeMCAsmInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZETARGETASMINFO_H
#define MBLAZETARGETASMINFO_H
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
class Target;
class MBlazeMCAsmInfo : public MCAsmInfo {
virtual void anchor();
public:
explicit MBlazeMCAsmInfo();
};
} // namespace llvm
#endif

View File

@ -1,222 +0,0 @@
//===-- MBlazeMCCodeEmitter.cpp - Convert MBlaze code to machine code -----===//
//
// 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 MBlazeMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mccodeemitter"
#include "MCTargetDesc/MBlazeMCTargetDesc.h"
#include "MCTargetDesc/MBlazeBaseInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
namespace {
class MBlazeMCCodeEmitter : public MCCodeEmitter {
MBlazeMCCodeEmitter(const MBlazeMCCodeEmitter &) LLVM_DELETED_FUNCTION;
void operator=(const MBlazeMCCodeEmitter &) LLVM_DELETED_FUNCTION;
const MCInstrInfo &MCII;
public:
MBlazeMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
MCContext &ctx)
: MCII(mcii) {
}
~MBlazeMCCodeEmitter() {}
// getBinaryCodeForInstr - TableGen'erated function for getting the
// binary encoding for an instruction.
uint64_t getBinaryCodeForInstr(const MCInst &MI) const;
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO) const;
unsigned getMachineOpValue(const MCInst &MI, unsigned OpIdx) const {
return getMachineOpValue(MI, MI.getOperand(OpIdx));
}
static unsigned GetMBlazeRegNum(const MCOperand &MO) {
// FIXME: getMBlazeRegisterNumbering() is sufficient?
llvm_unreachable("MBlazeMCCodeEmitter::GetMBlazeRegNum() not yet "
"implemented.");
}
void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
// The MicroBlaze uses a bit reversed format so we need to reverse the
// order of the bits. Taken from:
// http://graphics.stanford.edu/~seander/bithacks.html
C = ((C * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
OS << (char)C;
++CurByte;
}
void EmitRawByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
OS << (char)C;
++CurByte;
}
void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte,
raw_ostream &OS) const {
assert(Size <= 8 && "size too big in emit constant");
for (unsigned i = 0; i != Size; ++i) {
EmitByte(Val & 255, CurByte, OS);
Val >>= 8;
}
}
void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const;
void EmitIMM(const MCInst &MI, unsigned &CurByte, raw_ostream &OS) const;
void EmitImmediate(const MCInst &MI, unsigned opNo, bool pcrel,
unsigned &CurByte, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const;
void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const;
};
} // end anonymous namespace
MCCodeEmitter *llvm::createMBlazeMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new MBlazeMCCodeEmitter(MCII, STI, Ctx);
}
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI,
const MCOperand &MO) const {
if (MO.isReg())
return getMBlazeRegisterNumbering(MO.getReg());
if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
if (MO.isExpr())
return 0; // The relocation has already been recorded at this point.
#ifndef NDEBUG
errs() << MO;
#endif
llvm_unreachable(0);
}
void MBlazeMCCodeEmitter::
EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const {
int32_t val = (int32_t)imm.getImm();
if (val > 32767 || val < -32768) {
EmitByte(0x0D, CurByte, OS);
EmitByte(0x00, CurByte, OS);
EmitRawByte((val >> 24) & 0xFF, CurByte, OS);
EmitRawByte((val >> 16) & 0xFF, CurByte, OS);
}
}
void MBlazeMCCodeEmitter::
EmitIMM(const MCInst &MI, unsigned &CurByte,raw_ostream &OS) const {
switch (MI.getOpcode()) {
default: break;
case MBlaze::ADDIK32:
case MBlaze::ORI32:
case MBlaze::BRLID32:
EmitByte(0x0D, CurByte, OS);
EmitByte(0x00, CurByte, OS);
EmitRawByte(0, CurByte, OS);
EmitRawByte(0, CurByte, OS);
}
}
void MBlazeMCCodeEmitter::
EmitImmediate(const MCInst &MI, unsigned opNo, bool pcrel, unsigned &CurByte,
raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const {
assert(MI.getNumOperands()>opNo && "Not enought operands for instruction");
MCOperand oper = MI.getOperand(opNo);
if (oper.isImm()) {
EmitIMM(oper, CurByte, OS);
} else if (oper.isExpr()) {
MCFixupKind FixupKind;
switch (MI.getOpcode()) {
default:
FixupKind = pcrel ? FK_PCRel_2 : FK_Data_2;
Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind));
break;
case MBlaze::ORI32:
case MBlaze::ADDIK32:
case MBlaze::BRLID32:
FixupKind = pcrel ? FK_PCRel_4 : FK_Data_4;
Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind));
break;
}
}
}
void MBlazeMCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
unsigned Opcode = MI.getOpcode();
const MCInstrDesc &Desc = MCII.get(Opcode);
uint64_t TSFlags = Desc.TSFlags;
// Keep track of the current byte being emitted.
unsigned CurByte = 0;
// Emit an IMM instruction if the instruction we are encoding requires it
EmitIMM(MI,CurByte,OS);
switch ((TSFlags & MBlazeII::FormMask)) {
default: break;
case MBlazeII::FPseudo:
// Pseudo instructions don't get encoded.
return;
case MBlazeII::FRRI:
EmitImmediate(MI, 2, false, CurByte, OS, Fixups);
break;
case MBlazeII::FRIR:
EmitImmediate(MI, 1, false, CurByte, OS, Fixups);
break;
case MBlazeII::FCRI:
EmitImmediate(MI, 1, true, CurByte, OS, Fixups);
break;
case MBlazeII::FRCI:
EmitImmediate(MI, 1, true, CurByte, OS, Fixups);
case MBlazeII::FCCI:
EmitImmediate(MI, 0, true, CurByte, OS, Fixups);
break;
}
++MCNumEmitted; // Keep track of the # of mi's emitted
unsigned Value = getBinaryCodeForInstr(MI);
EmitConstant(Value, 4, CurByte, OS);
}
// FIXME: These #defines shouldn't be necessary. Instead, tblgen should
// be able to generate code emitter helpers for either variant, like it
// does for the AsmWriter.
#define MBlazeCodeEmitter MBlazeMCCodeEmitter
#define MachineInstr MCInst
#include "MBlazeGenCodeEmitter.inc"
#undef MBlazeCodeEmitter
#undef MachineInstr

View File

@ -1,137 +0,0 @@
//===-- MBlazeMCTargetDesc.cpp - MBlaze Target Descriptions ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides MBlaze specific target descriptions.
//
//===----------------------------------------------------------------------===//
#include "MBlazeMCTargetDesc.h"
#include "InstPrinter/MBlazeInstPrinter.h"
#include "MBlazeMCAsmInfo.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#include "MBlazeGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "MBlazeGenSubtargetInfo.inc"
#define GET_REGINFO_MC_DESC
#include "MBlazeGenRegisterInfo.inc"
using namespace llvm;
static MCInstrInfo *createMBlazeMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitMBlazeMCInstrInfo(X);
return X;
}
static MCRegisterInfo *createMBlazeMCRegisterInfo(StringRef TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitMBlazeMCRegisterInfo(X, MBlaze::R15);
return X;
}
static MCSubtargetInfo *createMBlazeMCSubtargetInfo(StringRef TT, StringRef CPU,
StringRef FS) {
MCSubtargetInfo *X = new MCSubtargetInfo();
InitMBlazeMCSubtargetInfo(X, TT, CPU, FS);
return X;
}
static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
return new MBlazeMCAsmInfo();
}
static MCCodeGenInfo *createMBlazeMCCodeGenInfo(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
if (RM == Reloc::Default)
RM = Reloc::Static;
if (CM == CodeModel::Default)
CM = CodeModel::Small;
X->InitMCCodeGenInfo(RM, CM, OL);
return X;
}
static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
MCContext &Ctx, MCAsmBackend &MAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
bool RelaxAll,
bool NoExecStack) {
Triple TheTriple(TT);
if (TheTriple.isOSDarwin()) {
llvm_unreachable("MBlaze does not support Darwin MACH-O format");
}
if (TheTriple.isOSWindows()) {
llvm_unreachable("MBlaze does not support Windows COFF format");
}
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
}
static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI) {
if (SyntaxVariant == 0)
return new MBlazeInstPrinter(MAI, MII, MRI);
return 0;
}
// Force static initialization.
extern "C" void LLVMInitializeMBlazeTargetMC() {
// Register the MC asm info.
RegisterMCAsmInfoFn X(TheMBlazeTarget, createMCAsmInfo);
// Register the MC codegen info.
TargetRegistry::RegisterMCCodeGenInfo(TheMBlazeTarget,
createMBlazeMCCodeGenInfo);
// Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(TheMBlazeTarget, createMBlazeMCInstrInfo);
// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(TheMBlazeTarget,
createMBlazeMCRegisterInfo);
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(TheMBlazeTarget,
createMBlazeMCSubtargetInfo);
// Register the MC code emitter
TargetRegistry::RegisterMCCodeEmitter(TheMBlazeTarget,
llvm::createMBlazeMCCodeEmitter);
// Register the asm backend
TargetRegistry::RegisterMCAsmBackend(TheMBlazeTarget,
createMBlazeAsmBackend);
// Register the object streamer
TargetRegistry::RegisterMCObjectStreamer(TheMBlazeTarget,
createMCStreamer);
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(TheMBlazeTarget,
createMBlazeMCInstPrinter);
}

View File

@ -1,56 +0,0 @@
//===-- MBlazeMCTargetDesc.h - MBlaze 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 MBlaze specific target descriptions.
//
//===----------------------------------------------------------------------===//
#ifndef MBLAZEMCTARGETDESC_H
#define MBLAZEMCTARGETDESC_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCAsmBackend;
class MCContext;
class MCCodeEmitter;
class MCInstrInfo;
class MCObjectWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class Target;
class StringRef;
class raw_ostream;
extern Target TheMBlazeTarget;
MCCodeEmitter *createMBlazeMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx);
MCAsmBackend *createMBlazeAsmBackend(const Target &T, StringRef TT,
StringRef CPU);
MCObjectWriter *createMBlazeELFObjectWriter(raw_ostream &OS, uint8_t OSABI);
} // End llvm namespace
// Defines symbolic names for MBlaze registers. This defines a mapping from
// register name to register number.
#define GET_REGINFO_ENUM
#include "MBlazeGenRegisterInfo.inc"
// Defines symbolic names for the MBlaze instructions.
#define GET_INSTRINFO_ENUM
#include "MBlazeGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM
#include "MBlazeGenSubtargetInfo.inc"
#endif

View File

@ -1,16 +0,0 @@
##===- lib/Target/MBlaze/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 = LLVMMBlazeDesc
# 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/MBlaze/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 = LLVMMBlazeCodeGen
TARGET = MBlaze
# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MBlazeGenRegisterInfo.inc MBlazeGenInstrInfo.inc \
MBlazeGenAsmWriter.inc \
MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \
MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \
MBlazeGenSubtargetInfo.inc MBlazeGenIntrinsics.inc
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
include $(LEVEL)/Makefile.common

View File

@ -1,21 +0,0 @@
* Writing out ELF files is close to working but the following needs to
be examined more closely:
- Relocations use 2-byte / 4-byte to terminology in reference to
the size of the immediate value being changed. The Xilinx
terminology seems to be (???) 4-byte / 8-byte in reference
to the number of bytes of instructions that are being changed.
* Code generation seems to work relatively well now but the following
needs to be examined more closely:
- The stack layout needs to be examined to make sure it meets
the standard, especially in regards to var arg functions.
- Look at the MBlazeGenFastISel.inc stuff and make use of it
if appropriate.
* A basic assembly parser is present now and seems to parse most things.
There are a few things that need to be looked at:
- There are some instructions that are not generated by the backend
and have not been tested as far as the parser is concerned.
- The assembly parser does not use many MicroBlaze specific directives.
I should investigate if there are MicroBlaze specific directive and,
if there are, add them.

View File

@ -1,8 +0,0 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMMBlazeInfo
MBlazeTargetInfo.cpp
)
add_dependencies(LLVMMBlazeInfo MBlazeCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/MBlaze/TargetInfo/LLVMBuild.txt -------------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
; This file is distributed under the University of Illinois Open Source
; License. See LICENSE.TXT for details.
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;
[component_0]
type = Library
name = MBlazeInfo
parent = MBlaze
required_libraries = MC Support Target
add_to_library_groups = MBlaze

View File

@ -1,19 +0,0 @@
//===-- MBlazeTargetInfo.cpp - MBlaze Target Implementation ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MBlaze.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
Target llvm::TheMBlazeTarget;
extern "C" void LLVMInitializeMBlazeTargetInfo() {
RegisterTarget<Triple::mblaze> X(TheMBlazeTarget, "mblaze", "MBlaze");
}

View File

@ -1,15 +0,0 @@
##===- lib/Target/MBlaze/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 = LLVMMBlazeInfo
# 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

@ -310,7 +310,6 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
hexagon-*) llvm_cv_target_arch="Hexagon" ;;
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
nvptx-*) llvm_cv_target_arch="NVPTX" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
*) llvm_cv_target_arch="Unknown" ;;
@ -481,7 +480,6 @@ else
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
Hexagon) AC_SUBST(TARGET_HAS_JIT,0) ;;
MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
NVPTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
SystemZ) AC_SUBST(TARGET_HAS_JIT,1) ;;
*) AC_SUBST(TARGET_HAS_JIT,0) ;;
@ -600,7 +598,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -617,7 +615,6 @@ case "$enableval" in
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
@ -629,7 +626,6 @@ case "$enableval" in
AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;

View File

@ -3850,7 +3850,6 @@ else
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
hexagon-*) llvm_cv_target_arch="Hexagon" ;;
mblaze-*) llvm_cv_target_arch="MBlaze" ;;
nvptx-*) llvm_cv_target_arch="NVPTX" ;;
s390x-*) llvm_cv_target_arch="SystemZ" ;;
*) llvm_cv_target_arch="Unknown" ;;
@ -5112,8 +5111,6 @@ else
MSP430) TARGET_HAS_JIT=0
;;
Hexagon) TARGET_HAS_JIT=0
;;
MBlaze) TARGET_HAS_JIT=0
;;
NVPTX) TARGET_HAS_JIT=0
;;
@ -5303,7 +5300,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -5320,7 +5317,6 @@ case "$enableval" in
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
@ -5332,7 +5328,6 @@ case "$enableval" in
AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
@ -10344,7 +10339,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10347 "configure"
#line 10342 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H

View File

@ -1 +0,0 @@
RUN: llc -O0 -march=mblaze -asm-verbose < %S/../Inputs/DbgValueOtherTargets.ll | FileCheck %S/../Inputs/DbgValueOtherTargets.ll

View File

@ -1,72 +0,0 @@
; Ensure that the select instruction is supported and is lowered to
; some sort of branch instruction.
;
; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
declare i32 @printf(i8*, ...)
@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
@BLKS = private constant [5 x i8*]
[ i8* blockaddress(@brind, %L1),
i8* blockaddress(@brind, %L2),
i8* blockaddress(@brind, %L3),
i8* blockaddress(@brind, %L4),
i8* blockaddress(@brind, %L5) ]
define i32 @brind(i32 %a, i32 %b)
{
; CHECK-LABEL: brind:
entry:
br label %loop
loop:
%tmp.0 = phi i32 [ 0, %entry ], [ %tmp.8, %finish ]
%dst.0 = getelementptr [5 x i8*]* @BLKS, i32 0, i32 %tmp.0
%dst.1 = load i8** %dst.0
indirectbr i8* %dst.1, [ label %L1,
label %L2,
label %L3,
label %L4,
label %L5 ]
; CHECK: brad {{r[0-9]*}}
L1:
%tmp.1 = add i32 %a, %b
br label %finish
; CHECK: brid
L2:
%tmp.2 = sub i32 %a, %b
br label %finish
; CHECK: brid
L3:
%tmp.3 = mul i32 %a, %b
br label %finish
; CHECK: brid
L4:
%tmp.4 = sdiv i32 %a, %b
br label %finish
; CHECK: brid
L5:
%tmp.5 = srem i32 %a, %b
br label %finish
finish:
%tmp.6 = phi i32 [ %tmp.1, %L1 ],
[ %tmp.2, %L2 ],
[ %tmp.3, %L3 ],
[ %tmp.4, %L4 ],
[ %tmp.5, %L5 ]
call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0),
i32 %tmp.6)
%tmp.7 = add i32 %tmp.0, 1
%tmp.8 = urem i32 %tmp.7, 5
br label %loop
; CHECK: brad {{r[0-9]*}}
}

View File

@ -1,80 +0,0 @@
; Ensure that indirect calls work and that they are lowered to some
; sort of branch and link instruction.
;
; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
declare i32 @printf(i8*, ...)
@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
@FUNS = private constant [5 x i32 (i32,i32)*]
[ i32 (i32,i32)* @doadd,
i32 (i32,i32)* @dosub,
i32 (i32,i32)* @domul,
i32 (i32,i32)* @dodiv,
i32 (i32,i32)* @dorem ]
define i32 @doadd(i32 %a, i32 %b)
{
; CHECK-LABEL: doadd:
%tmp.0 = add i32 %a, %b
ret i32 %tmp.0
; CHECK: rtsd
}
define i32 @dosub(i32 %a, i32 %b)
{
; CHECK-LABEL: dosub:
%tmp.0 = sub i32 %a, %b
ret i32 %tmp.0
; CHECK: rtsd
}
define i32 @domul(i32 %a, i32 %b)
{
; CHECK-LABEL: domul:
%tmp.0 = mul i32 %a, %b
ret i32 %tmp.0
; CHECK: rtsd
}
define i32 @dodiv(i32 %a, i32 %b)
{
; CHECK-LABEL: dodiv:
%tmp.0 = sdiv i32 %a, %b
ret i32 %tmp.0
; CHECK: rtsd
}
define i32 @dorem(i32 %a, i32 %b)
{
; CHECK-LABEL: dorem:
%tmp.0 = srem i32 %a, %b
ret i32 %tmp.0
; CHECK: rtsd
}
define i32 @callind(i32 %a, i32 %b)
{
; CHECK-LABEL: callind:
entry:
br label %loop
loop:
%tmp.0 = phi i32 [ 0, %entry ], [ %tmp.3, %loop ]
%dst.0 = getelementptr [5 x i32 (i32,i32)*]* @FUNS, i32 0, i32 %tmp.0
%dst.1 = load i32 (i32,i32)** %dst.0
%tmp.1 = call i32 %dst.1(i32 %a, i32 %b)
; CHECK-NOT: brli
; CHECK-NOT: brlai
; CHECK: brl
call i32 (i8*,...)* @printf( i8* getelementptr([13 x i8]* @MSG,i32 0,i32 0),
i32 %tmp.1)
; CHECK: brl
%tmp.2 = add i32 %tmp.0, 1
%tmp.3 = urem i32 %tmp.2, 5
br label %loop
; CHECK: br
}

View File

@ -1,266 +0,0 @@
; Test some of the calling convention lowering done by the MBlaze backend.
; We test that integer values are passed in the correct registers and
; returned in the correct registers. Additionally, we test that the stack
; is used as appropriate for passing arguments that cannot be placed into
; registers.
;
; RUN: llc < %s -march=mblaze | FileCheck %s
declare i32 @printf(i8*, ...)
@MSG = internal constant [13 x i8] c"Message: %d\0A\00"
define void @params0_noret() {
; CHECK-LABEL: params0_noret:
ret void
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
}
define i8 @params0_8bitret() {
; CHECK-LABEL: params0_8bitret:
ret i8 1
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r0, 1}}
}
define i16 @params0_16bitret() {
; CHECK-LABEL: params0_16bitret:
ret i16 1
; CHECK: rtsd
; CHECK: {{.* r3, r0, 1}}
; CHECK-NOT: {{.* r4, .*, .*}}
}
define i32 @params0_32bitret() {
; CHECK-LABEL: params0_32bitret:
ret i32 1
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r0, 1}}
}
define i64 @params0_64bitret() {
; CHECK-LABEL: params0_64bitret:
ret i64 1
; CHECK: {{.* r3, r0, .*}}
; CHECK: rtsd
; CHECK: {{.* r4, r0, 1}}
}
define i32 @params1_32bitret(i32 %a) {
; CHECK-LABEL: params1_32bitret:
ret i32 %a
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r5, r0}}
}
define i32 @params2_32bitret(i32 %a, i32 %b) {
; CHECK-LABEL: params2_32bitret:
ret i32 %b
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r6, r0}}
}
define i32 @params3_32bitret(i32 %a, i32 %b, i32 %c) {
; CHECK-LABEL: params3_32bitret:
ret i32 %c
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r7, r0}}
}
define i32 @params4_32bitret(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: params4_32bitret:
ret i32 %d
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r8, r0}}
}
define i32 @params5_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
; CHECK-LABEL: params5_32bitret:
ret i32 %e
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r9, r0}}
}
define i32 @params6_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) {
; CHECK-LABEL: params6_32bitret:
ret i32 %f
; CHECK-NOT: {{.* r3, .*, .*}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
; CHECK: {{.* r3, r10, r0}}
}
define i32 @params7_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
i32 %g) {
; CHECK-LABEL: params7_32bitret:
ret i32 %g
; CHECK: {{lwi? r3, r1, 32}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
}
define i32 @params8_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
i32 %g, i32 %h) {
; CHECK-LABEL: params8_32bitret:
ret i32 %h
; CHECK: {{lwi? r3, r1, 36}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
}
define i32 @params9_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
i32 %g, i32 %h, i32 %i) {
; CHECK-LABEL: params9_32bitret:
ret i32 %i
; CHECK: {{lwi? r3, r1, 40}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
}
define i32 @params10_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f,
i32 %g, i32 %h, i32 %i, i32 %j) {
; CHECK-LABEL: params10_32bitret:
ret i32 %j
; CHECK: {{lwi? r3, r1, 44}}
; CHECK-NOT: {{.* r4, .*, .*}}
; CHECK: rtsd
}
define void @testing() {
%MSG.1 = getelementptr [13 x i8]* @MSG, i32 0, i32 0
call void @params0_noret()
; CHECK: brlid
%tmp.1 = call i8 @params0_8bitret()
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i8 %tmp.1)
%tmp.2 = call i16 @params0_16bitret()
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i16 %tmp.2)
%tmp.3 = call i32 @params0_32bitret()
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.3)
%tmp.4 = call i64 @params0_64bitret()
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i64 %tmp.4)
%tmp.5 = call i32 @params1_32bitret(i32 1)
; CHECK: {{.* r5, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.5)
%tmp.6 = call i32 @params2_32bitret(i32 1, i32 2)
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.6)
%tmp.7 = call i32 @params3_32bitret(i32 1, i32 2, i32 3)
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.7)
%tmp.8 = call i32 @params4_32bitret(i32 1, i32 2, i32 3, i32 4)
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.8)
%tmp.9 = call i32 @params5_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5)
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.9)
%tmp.10 = call i32 @params6_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
i32 6)
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: {{.* r10, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.10)
%tmp.11 = call i32 @params7_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
i32 6, i32 7)
; CHECK: {{swi? .*, r1, 28}}
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: {{.* r10, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.11)
%tmp.12 = call i32 @params8_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
i32 6, i32 7, i32 8)
; CHECK: {{swi? .*, r1, 32}}
; CHECK: {{swi? .*, r1, 28}}
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: {{.* r10, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.12)
%tmp.13 = call i32 @params9_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
i32 6, i32 7, i32 8, i32 9)
; CHECK: {{swi? .*, r1, 36}}
; CHECK: {{swi? .*, r1, 32}}
; CHECK: {{swi? .*, r1, 28}}
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: {{.* r10, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.13)
%tmp.14 = call i32 @params10_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5,
i32 6, i32 7, i32 8, i32 9, i32 10)
; CHECK: {{swi? .*, r1, 40}}
; CHECK: {{swi? .*, r1, 36}}
; CHECK: {{swi? .*, r1, 32}}
; CHECK: {{swi? .*, r1, 28}}
; CHECK: {{.* r5, .*, .*}}
; CHECK: {{.* r6, .*, .*}}
; CHECK: {{.* r7, .*, .*}}
; CHECK: {{.* r8, .*, .*}}
; CHECK: {{.* r9, .*, .*}}
; CHECK: {{.* r10, .*, .*}}
; CHECK: brlid
call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.14)
ret void
}

View File

@ -1,75 +0,0 @@
; Ensure that multiplication is lowered to function calls when the multiplier
; unit is not available in the hardware and that function calls are not used
; when the multiplier unit is available in the hardware.
;
; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
; RUN: llc < %s -march=mblaze -mattr=+div | FileCheck -check-prefix=DIV %s
define i8 @test_i8(i8 %a, i8 %b) {
; FUN-LABEL: test_i8:
; DIV-LABEL: test_i8:
%tmp.1 = udiv i8 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV: idiv
%tmp.2 = sdiv i8 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV-NOT: idiv
; DIV: idivu
%tmp.3 = add i8 %tmp.1, %tmp.2
ret i8 %tmp.3
; FUN: rtsd
; DIV: rtsd
}
define i16 @test_i16(i16 %a, i16 %b) {
; FUN-LABEL: test_i16:
; DIV-LABEL: test_i16:
%tmp.1 = udiv i16 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV: idiv
%tmp.2 = sdiv i16 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV-NOT: idiv
; DIV: idivu
%tmp.3 = add i16 %tmp.1, %tmp.2
ret i16 %tmp.3
; FUN: rtsd
; DIV: rtsd
}
define i32 @test_i32(i32 %a, i32 %b) {
; FUN-LABEL: test_i32:
; DIV-LABEL: test_i32:
%tmp.1 = udiv i32 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV: idiv
%tmp.2 = sdiv i32 %a, %b
; FUN-NOT: idiv
; FUN: brlid
; DIV-NOT: brlid
; DIV-NOT: idiv
; DIV: idivu
%tmp.3 = add i32 %tmp.1, %tmp.2
ret i32 %tmp.3
; FUN: rtsd
; DIV: rtsd
}

View File

@ -1,66 +0,0 @@
; Ensure that floating point operations are lowered to function calls when the
; FPU is not available in the hardware and that function calls are not used
; when the FPU is available in the hardware.
;
; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s
define float @test_add(float %a, float %b) {
; FUN-LABEL: test_add:
; FPU-LABEL: test_add:
%tmp.1 = fadd float %a, %b
; FUN: brlid
; FPU-NOT: brlid
ret float %tmp.1
; FUN: rtsd
; FPU: rtsd
; FUN-NOT: fadd
; FPU-NEXT: fadd
}
define float @test_sub(float %a, float %b) {
; FUN-LABEL: test_sub:
; FPU-LABEL: test_sub:
%tmp.1 = fsub float %a, %b
; FUN: brlid
; FPU-NOT: brlid
ret float %tmp.1
; FUN: rtsd
; FPU: rtsd
; FUN-NOT: frsub
; FPU-NEXT: frsub
}
define float @test_mul(float %a, float %b) {
; FUN-LABEL: test_mul:
; FPU-LABEL: test_mul:
%tmp.1 = fmul float %a, %b
; FUN: brlid
; FPU-NOT: brlid
ret float %tmp.1
; FUN: rtsd
; FPU: rtsd
; FUN-NOT: fmul
; FPU-NEXT: fmul
}
define float @test_div(float %a, float %b) {
; FUN-LABEL: test_div:
; FPU-LABEL: test_div:
%tmp.1 = fdiv float %a, %b
; FUN: brlid
; FPU-NOT: brlid
ret float %tmp.1
; FUN: rtsd
; FPU: rtsd
; FUN-NOT: fdiv
; FPU-NEXT: fdiv
}

View File

@ -1,319 +0,0 @@
; Ensure that the FSL instrinsic instruction generate single FSL instructions
; at the machine level. Additionally, ensure that dynamic values use the
; dynamic version of the instructions and that constant values use the
; constant version of the instructions.
;
; RUN: llc -O3 < %s -march=mblaze | FileCheck %s
declare i32 @llvm.mblaze.fsl.get(i32 %port)
declare i32 @llvm.mblaze.fsl.aget(i32 %port)
declare i32 @llvm.mblaze.fsl.cget(i32 %port)
declare i32 @llvm.mblaze.fsl.caget(i32 %port)
declare i32 @llvm.mblaze.fsl.eget(i32 %port)
declare i32 @llvm.mblaze.fsl.eaget(i32 %port)
declare i32 @llvm.mblaze.fsl.ecget(i32 %port)
declare i32 @llvm.mblaze.fsl.ecaget(i32 %port)
declare i32 @llvm.mblaze.fsl.nget(i32 %port)
declare i32 @llvm.mblaze.fsl.naget(i32 %port)
declare i32 @llvm.mblaze.fsl.ncget(i32 %port)
declare i32 @llvm.mblaze.fsl.ncaget(i32 %port)
declare i32 @llvm.mblaze.fsl.neget(i32 %port)
declare i32 @llvm.mblaze.fsl.neaget(i32 %port)
declare i32 @llvm.mblaze.fsl.necget(i32 %port)
declare i32 @llvm.mblaze.fsl.necaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tget(i32 %port)
declare i32 @llvm.mblaze.fsl.taget(i32 %port)
declare i32 @llvm.mblaze.fsl.tcget(i32 %port)
declare i32 @llvm.mblaze.fsl.tcaget(i32 %port)
declare i32 @llvm.mblaze.fsl.teget(i32 %port)
declare i32 @llvm.mblaze.fsl.teaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tecget(i32 %port)
declare i32 @llvm.mblaze.fsl.tecaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tnget(i32 %port)
declare i32 @llvm.mblaze.fsl.tnaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tncget(i32 %port)
declare i32 @llvm.mblaze.fsl.tncaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tneget(i32 %port)
declare i32 @llvm.mblaze.fsl.tneaget(i32 %port)
declare i32 @llvm.mblaze.fsl.tnecget(i32 %port)
declare i32 @llvm.mblaze.fsl.tnecaget(i32 %port)
declare void @llvm.mblaze.fsl.put(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.aput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.cput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.caput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.nput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.naput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port)
declare void @llvm.mblaze.fsl.tput(i32 %port)
declare void @llvm.mblaze.fsl.taput(i32 %port)
declare void @llvm.mblaze.fsl.tcput(i32 %port)
declare void @llvm.mblaze.fsl.tcaput(i32 %port)
declare void @llvm.mblaze.fsl.tnput(i32 %port)
declare void @llvm.mblaze.fsl.tnaput(i32 %port)
declare void @llvm.mblaze.fsl.tncput(i32 %port)
declare void @llvm.mblaze.fsl.tncaput(i32 %port)
define void @fsl_get(i32 %port) {
; CHECK-LABEL: fsl_get:
%v0 = call i32 @llvm.mblaze.fsl.get(i32 %port)
; CHECK: getd
%v1 = call i32 @llvm.mblaze.fsl.aget(i32 %port)
; CHECK-NEXT: agetd
%v2 = call i32 @llvm.mblaze.fsl.cget(i32 %port)
; CHECK-NEXT: cgetd
%v3 = call i32 @llvm.mblaze.fsl.caget(i32 %port)
; CHECK-NEXT: cagetd
%v4 = call i32 @llvm.mblaze.fsl.eget(i32 %port)
; CHECK-NEXT: egetd
%v5 = call i32 @llvm.mblaze.fsl.eaget(i32 %port)
; CHECK-NEXT: eagetd
%v6 = call i32 @llvm.mblaze.fsl.ecget(i32 %port)
; CHECK-NEXT: ecgetd
%v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 %port)
; CHECK-NEXT: ecagetd
%v8 = call i32 @llvm.mblaze.fsl.nget(i32 %port)
; CHECK-NEXT: ngetd
%v9 = call i32 @llvm.mblaze.fsl.naget(i32 %port)
; CHECK-NEXT: nagetd
%v10 = call i32 @llvm.mblaze.fsl.ncget(i32 %port)
; CHECK-NEXT: ncgetd
%v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 %port)
; CHECK-NEXT: ncagetd
%v12 = call i32 @llvm.mblaze.fsl.neget(i32 %port)
; CHECK-NEXT: negetd
%v13 = call i32 @llvm.mblaze.fsl.neaget(i32 %port)
; CHECK-NEXT: neagetd
%v14 = call i32 @llvm.mblaze.fsl.necget(i32 %port)
; CHECK-NEXT: necgetd
%v15 = call i32 @llvm.mblaze.fsl.necaget(i32 %port)
; CHECK-NEXT: necagetd
%v16 = call i32 @llvm.mblaze.fsl.tget(i32 %port)
; CHECK-NEXT: tgetd
%v17 = call i32 @llvm.mblaze.fsl.taget(i32 %port)
; CHECK-NEXT: tagetd
%v18 = call i32 @llvm.mblaze.fsl.tcget(i32 %port)
; CHECK-NEXT: tcgetd
%v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 %port)
; CHECK-NEXT: tcagetd
%v20 = call i32 @llvm.mblaze.fsl.teget(i32 %port)
; CHECK-NEXT: tegetd
%v21 = call i32 @llvm.mblaze.fsl.teaget(i32 %port)
; CHECK-NEXT: teagetd
%v22 = call i32 @llvm.mblaze.fsl.tecget(i32 %port)
; CHECK-NEXT: tecgetd
%v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 %port)
; CHECK-NEXT: tecagetd
%v24 = call i32 @llvm.mblaze.fsl.tnget(i32 %port)
; CHECK-NEXT: tngetd
%v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 %port)
; CHECK-NEXT: tnagetd
%v26 = call i32 @llvm.mblaze.fsl.tncget(i32 %port)
; CHECK-NEXT: tncgetd
%v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 %port)
; CHECK-NEXT: tncagetd
%v28 = call i32 @llvm.mblaze.fsl.tneget(i32 %port)
; CHECK-NEXT: tnegetd
%v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 %port)
; CHECK-NEXT: tneagetd
%v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 %port)
; CHECK-NEXT: tnecgetd
%v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 %port)
; CHECK-NEXT: tnecagetd
ret void
; CHECK: rtsd
}
define void @fslc_get() {
; CHECK-LABEL: fslc_get:
%v0 = call i32 @llvm.mblaze.fsl.get(i32 1)
; CHECK: get
%v1 = call i32 @llvm.mblaze.fsl.aget(i32 1)
; CHECK-NOT: agetd
; CHECK: aget
%v2 = call i32 @llvm.mblaze.fsl.cget(i32 1)
; CHECK-NOT: cgetd
; CHECK: cget
%v3 = call i32 @llvm.mblaze.fsl.caget(i32 1)
; CHECK-NOT: cagetd
; CHECK: caget
%v4 = call i32 @llvm.mblaze.fsl.eget(i32 1)
; CHECK-NOT: egetd
; CHECK: eget
%v5 = call i32 @llvm.mblaze.fsl.eaget(i32 1)
; CHECK-NOT: eagetd
; CHECK: eaget
%v6 = call i32 @llvm.mblaze.fsl.ecget(i32 1)
; CHECK-NOT: ecgetd
; CHECK: ecget
%v7 = call i32 @llvm.mblaze.fsl.ecaget(i32 1)
; CHECK-NOT: ecagetd
; CHECK: ecaget
%v8 = call i32 @llvm.mblaze.fsl.nget(i32 1)
; CHECK-NOT: ngetd
; CHECK: nget
%v9 = call i32 @llvm.mblaze.fsl.naget(i32 1)
; CHECK-NOT: nagetd
; CHECK: naget
%v10 = call i32 @llvm.mblaze.fsl.ncget(i32 1)
; CHECK-NOT: ncgetd
; CHECK: ncget
%v11 = call i32 @llvm.mblaze.fsl.ncaget(i32 1)
; CHECK-NOT: ncagetd
; CHECK: ncaget
%v12 = call i32 @llvm.mblaze.fsl.neget(i32 1)
; CHECK-NOT: negetd
; CHECK: neget
%v13 = call i32 @llvm.mblaze.fsl.neaget(i32 1)
; CHECK-NOT: neagetd
; CHECK: neaget
%v14 = call i32 @llvm.mblaze.fsl.necget(i32 1)
; CHECK-NOT: necgetd
; CHECK: necget
%v15 = call i32 @llvm.mblaze.fsl.necaget(i32 1)
; CHECK-NOT: necagetd
; CHECK: necaget
%v16 = call i32 @llvm.mblaze.fsl.tget(i32 1)
; CHECK-NOT: tgetd
; CHECK: tget
%v17 = call i32 @llvm.mblaze.fsl.taget(i32 1)
; CHECK-NOT: tagetd
; CHECK: taget
%v18 = call i32 @llvm.mblaze.fsl.tcget(i32 1)
; CHECK-NOT: tcgetd
; CHECK: tcget
%v19 = call i32 @llvm.mblaze.fsl.tcaget(i32 1)
; CHECK-NOT: tcagetd
; CHECK: tcaget
%v20 = call i32 @llvm.mblaze.fsl.teget(i32 1)
; CHECK-NOT: tegetd
; CHECK: teget
%v21 = call i32 @llvm.mblaze.fsl.teaget(i32 1)
; CHECK-NOT: teagetd
; CHECK: teaget
%v22 = call i32 @llvm.mblaze.fsl.tecget(i32 1)
; CHECK-NOT: tecgetd
; CHECK: tecget
%v23 = call i32 @llvm.mblaze.fsl.tecaget(i32 1)
; CHECK-NOT: tecagetd
; CHECK: tecaget
%v24 = call i32 @llvm.mblaze.fsl.tnget(i32 1)
; CHECK-NOT: tngetd
; CHECK: tnget
%v25 = call i32 @llvm.mblaze.fsl.tnaget(i32 1)
; CHECK-NOT: tnagetd
; CHECK: tnaget
%v26 = call i32 @llvm.mblaze.fsl.tncget(i32 1)
; CHECK-NOT: tncgetd
; CHECK: tncget
%v27 = call i32 @llvm.mblaze.fsl.tncaget(i32 1)
; CHECK-NOT: tncagetd
; CHECK: tncaget
%v28 = call i32 @llvm.mblaze.fsl.tneget(i32 1)
; CHECK-NOT: tnegetd
; CHECK: tneget
%v29 = call i32 @llvm.mblaze.fsl.tneaget(i32 1)
; CHECK-NOT: tneagetd
; CHECK: tneaget
%v30 = call i32 @llvm.mblaze.fsl.tnecget(i32 1)
; CHECK-NOT: tnecgetd
; CHECK: tnecget
%v31 = call i32 @llvm.mblaze.fsl.tnecaget(i32 1)
; CHECK-NOT: tnecagetd
; CHECK: tnecaget
ret void
; CHECK: rtsd
}
define void @putfsl(i32 %value, i32 %port) {
; CHECK-LABEL: putfsl:
call void @llvm.mblaze.fsl.put(i32 %value, i32 %port)
; CHECK: putd
call void @llvm.mblaze.fsl.aput(i32 %value, i32 %port)
; CHECK-NEXT: aputd
call void @llvm.mblaze.fsl.cput(i32 %value, i32 %port)
; CHECK-NEXT: cputd
call void @llvm.mblaze.fsl.caput(i32 %value, i32 %port)
; CHECK-NEXT: caputd
call void @llvm.mblaze.fsl.nput(i32 %value, i32 %port)
; CHECK-NEXT: nputd
call void @llvm.mblaze.fsl.naput(i32 %value, i32 %port)
; CHECK-NEXT: naputd
call void @llvm.mblaze.fsl.ncput(i32 %value, i32 %port)
; CHECK-NEXT: ncputd
call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 %port)
; CHECK-NEXT: ncaputd
call void @llvm.mblaze.fsl.tput(i32 %port)
; CHECK-NEXT: tputd
call void @llvm.mblaze.fsl.taput(i32 %port)
; CHECK-NEXT: taputd
call void @llvm.mblaze.fsl.tcput(i32 %port)
; CHECK-NEXT: tcputd
call void @llvm.mblaze.fsl.tcaput(i32 %port)
; CHECK-NEXT: tcaputd
call void @llvm.mblaze.fsl.tnput(i32 %port)
; CHECK-NEXT: tnputd
call void @llvm.mblaze.fsl.tnaput(i32 %port)
; CHECK-NEXT: tnaputd
call void @llvm.mblaze.fsl.tncput(i32 %port)
; CHECK-NEXT: tncputd
call void @llvm.mblaze.fsl.tncaput(i32 %port)
; CHECK-NEXT: tncaputd
ret void
; CHECK: rtsd
}
define void @putfsl_const(i32 %value) {
; CHECK-LABEL: putfsl_const:
call void @llvm.mblaze.fsl.put(i32 %value, i32 1)
; CHECK-NOT: putd
; CHECK: put
call void @llvm.mblaze.fsl.aput(i32 %value, i32 1)
; CHECK-NOT: aputd
; CHECK: aput
call void @llvm.mblaze.fsl.cput(i32 %value, i32 1)
; CHECK-NOT: cputd
; CHECK: cput
call void @llvm.mblaze.fsl.caput(i32 %value, i32 1)
; CHECK-NOT: caputd
; CHECK: caput
call void @llvm.mblaze.fsl.nput(i32 %value, i32 1)
; CHECK-NOT: nputd
; CHECK: nput
call void @llvm.mblaze.fsl.naput(i32 %value, i32 1)
; CHECK-NOT: naputd
; CHECK: naput
call void @llvm.mblaze.fsl.ncput(i32 %value, i32 1)
; CHECK-NOT: ncputd
; CHECK: ncput
call void @llvm.mblaze.fsl.ncaput(i32 %value, i32 1)
; CHECK-NOT: ncaputd
; CHECK: ncaput
call void @llvm.mblaze.fsl.tput(i32 1)
; CHECK-NOT: tputd
; CHECK: tput
call void @llvm.mblaze.fsl.taput(i32 1)
; CHECK-NOT: taputd
; CHECK: taput
call void @llvm.mblaze.fsl.tcput(i32 1)
; CHECK-NOT: tcputd
; CHECK: tcput
call void @llvm.mblaze.fsl.tcaput(i32 1)
; CHECK-NOT: tcaputd
; CHECK: tcaput
call void @llvm.mblaze.fsl.tnput(i32 1)
; CHECK-NOT: tnputd
; CHECK: tnput
call void @llvm.mblaze.fsl.tnaput(i32 1)
; CHECK-NOT: tnaputd
; CHECK: tnaput
call void @llvm.mblaze.fsl.tncput(i32 1)
; CHECK-NOT: tncputd
; CHECK: tncput
call void @llvm.mblaze.fsl.tncaput(i32 1)
; CHECK-NOT: tncaputd
; CHECK: tncaput
ret void
; CHECK: rtsd
}

View File

@ -1,70 +0,0 @@
; Ensure that all immediate values that are 32-bits or less can be loaded
; using a single instruction and that immediate values 64-bits or less can
; be loaded using two instructions.
;
; RUN: llc < %s -march=mblaze | FileCheck %s
; RUN: llc < %s -march=mblaze -mattr=+fpu | FileCheck -check-prefix=FPU %s
define i8 @retimm_i8() {
; CHECK-LABEL: retimm_i8:
; CHECK: rtsd
; CHECK-NEXT: add
; FPU-LABEL: retimm_i8:
; FPU: rtsd
; FPU-NEXT: add
ret i8 123
}
define i16 @retimm_i16() {
; CHECK-LABEL: retimm_i16:
; CHECK: rtsd
; CHECK-NEXT: add
; FPU-LABEL: retimm_i16:
; FPU: rtsd
; FPU-NEXT: add
ret i16 31212
}
define i32 @retimm_i32() {
; CHECK-LABEL: retimm_i32:
; CHECK: add
; CHECK-NEXT: rtsd
; FPU-LABEL: retimm_i32:
; FPU: add
; FPU-NEXT: rtsd
ret i32 2938128
}
define i64 @retimm_i64() {
; CHECK-LABEL: retimm_i64:
; CHECK: add
; CHECK-NEXT: rtsd
; CHECK-NEXT: add
; FPU-LABEL: retimm_i64:
; FPU: add
; FPU-NEXT: rtsd
; FPU-NEXT: add
ret i64 94581823
}
define float @retimm_float() {
; CHECK-LABEL: retimm_float:
; CHECK: add
; CHECK-NEXT: rtsd
; FPU-LABEL: retimm_float:
; FPU: or
; FPU-NEXT: rtsd
ret float 12.0
}
define double @retimm_double() {
; CHECK-LABEL: retimm_double:
; CHECK: add
; CHECK-NEXT: add
; CHECK-NEXT: rtsd
; FPU-LABEL: retimm_double:
; FPU: add
; FPU-NEXT: add
; FPU-NEXT: rtsd
ret double 598382.39283873
}

View File

@ -1,48 +0,0 @@
; Ensure that the MBlaze interrupt_handler calling convention (cc73) is handled
; correctly correctly by the MBlaze backend.
;
; RUN: llc < %s -march=mblaze | FileCheck %s
@.str = private constant [28 x i8] c"The interrupt has gone off\0A\00"
@_interrupt_handler = alias void ()* @myintr
define cc73 void @myintr() nounwind noinline {
; CHECK-LABEL: myintr:
; CHECK: swi r3, r1
; CHECK: swi r4, r1
; CHECK: swi r5, r1
; CHECK: swi r6, r1
; CHECK: swi r7, r1
; CHECK: swi r8, r1
; CHECK: swi r9, r1
; CHECK: swi r10, r1
; CHECK: swi r11, r1
; CHECK: swi r12, r1
; CHECK: swi r17, r1
; CHECK: swi r18, r1
; CHECK: mfs r11, rmsr
; CHECK: swi r11, r1
entry:
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([28 x i8]* @.str, i32 0, i32 0))
ret void
; CHECK: lwi r11, r1
; CHECK: mts rmsr, r11
; CHECK: lwi r18, r1
; CHECK: lwi r17, r1
; CHECK: lwi r12, r1
; CHECK: lwi r11, r1
; CHECK: lwi r10, r1
; CHECK: lwi r9, r1
; CHECK: lwi r8, r1
; CHECK: lwi r7, r1
; CHECK: lwi r6, r1
; CHECK: lwi r5, r1
; CHECK: lwi r4, r1
; CHECK: lwi r3, r1
; CHECK: rtid r14, 0
}
; CHECK: .globl _interrupt_handler
; CHECK: _interrupt_handler = myintr
declare i32 @printf(i8*, ...)

View File

@ -1,79 +0,0 @@
; Ensure that jump tables can be handled by the mblaze backend. The
; jump table should be lowered to a "br" instruction using one of the
; available registers.
;
; RUN: llc < %s -march=mblaze | FileCheck %s
define i32 @jmptable(i32 %arg)
{
; CHECK-LABEL: jmptable:
switch i32 %arg, label %DEFAULT [ i32 0, label %L0
i32 1, label %L1
i32 2, label %L2
i32 3, label %L3
i32 4, label %L4
i32 5, label %L5
i32 6, label %L6
i32 7, label %L7
i32 8, label %L8
i32 9, label %L9 ]
; CHECK: lw [[REG:r[0-9]*]]
; CHECK: brad [[REG]]
L0:
%var0 = add i32 %arg, 0
br label %DONE
L1:
%var1 = add i32 %arg, 1
br label %DONE
L2:
%var2 = add i32 %arg, 2
br label %DONE
L3:
%var3 = add i32 %arg, 3
br label %DONE
L4:
%var4 = add i32 %arg, 4
br label %DONE
L5:
%var5 = add i32 %arg, 5
br label %DONE
L6:
%var6 = add i32 %arg, 6
br label %DONE
L7:
%var7 = add i32 %arg, 7
br label %DONE
L8:
%var8 = add i32 %arg, 8
br label %DONE
L9:
%var9 = add i32 %arg, 9
br label %DONE
DEFAULT:
unreachable
DONE:
%rval = phi i32 [ %var0, %L0 ],
[ %var1, %L1 ],
[ %var2, %L2 ],
[ %var3, %L3 ],
[ %var4, %L4 ],
[ %var5, %L5 ],
[ %var6, %L6 ],
[ %var7, %L7 ],
[ %var8, %L8 ],
[ %var9, %L9 ]
ret i32 %rval
; CHECK: rtsd
}

View File

@ -1,6 +0,0 @@
config.suffixes = ['.ll', '.c', '.cpp', '.test']
targets = set(config.root.targets_to_build.split())
if not 'MBlaze' in targets:
config.unsupported = True

View File

@ -1,44 +0,0 @@
; Test some complicated looping constructs to ensure that they
; compile successfully and that some sort of branching is used
; in the resulting code.
;
; RUN: llc < %s -march=mblaze -mattr=+mul,+fpu,+barrel | FileCheck %s
declare i32 @printf(i8*, ...)
@MSG = internal constant [19 x i8] c"Message: %d %d %d\0A\00"
define i32 @loop(i32 %a, i32 %b)
{
; CHECK-LABEL: loop:
entry:
br label %loop_outer
loop_outer:
%outer.0 = phi i32 [ 0, %entry ], [ %outer.2, %loop_outer_finish ]
br label %loop_inner
loop_inner:
%inner.0 = phi i32 [ %a, %loop_outer ], [ %inner.3, %loop_inner_finish ]
%inner.1 = phi i32 [ %b, %loop_outer ], [ %inner.4, %loop_inner_finish ]
%inner.2 = phi i32 [ 0, %loop_outer ], [ %inner.5, %loop_inner_finish ]
%inner.3 = add i32 %inner.0, %inner.1
%inner.4 = mul i32 %inner.2, 11
br label %loop_inner_finish
loop_inner_finish:
%inner.5 = add i32 %inner.2, 1
call i32 (i8*,...)* @printf( i8* getelementptr([19 x i8]* @MSG,i32 0,i32 0),
i32 %inner.0, i32 %inner.1, i32 %inner.2 )
%inner.6 = icmp eq i32 %inner.5, 100
; CHECK: cmp [[REG:r[0-9]*]]
br i1 %inner.6, label %loop_inner, label %loop_outer_finish
; CHECK: {{beqid|bneid}} [[REG]]
loop_outer_finish:
%outer.1 = add i32 %outer.0, 1
%outer.2 = urem i32 %outer.1, 1500
br label %loop_outer
; CHECK: br
}

View File

@ -1,51 +0,0 @@
; Ensure that multiplication is lowered to function calls when the multiplier
; unit is not available in the hardware and that function calls are not used
; when the multiplier unit is available in the hardware.
;
; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
; RUN: llc < %s -march=mblaze -mattr=+mul | FileCheck -check-prefix=MUL %s
define i8 @test_i8(i8 %a, i8 %b) {
; FUN-LABEL: test_i8:
; MUL-LABEL: test_i8:
%tmp.1 = mul i8 %a, %b
; FUN-NOT: mul
; FUN: brlid
; MUL-NOT: brlid
ret i8 %tmp.1
; FUN: rtsd
; MUL: rtsd
; MUL: mul
}
define i16 @test_i16(i16 %a, i16 %b) {
; FUN-LABEL: test_i16:
; MUL-LABEL: test_i16:
%tmp.1 = mul i16 %a, %b
; FUN-NOT: mul
; FUN: brlid
; MUL-NOT: brlid
ret i16 %tmp.1
; FUN: rtsd
; MUL: rtsd
; MUL: mul
}
define i32 @test_i32(i32 %a, i32 %b) {
; FUN-LABEL: test_i32:
; MUL-LABEL: test_i32:
%tmp.1 = mul i32 %a, %b
; FUN-NOT: mul
; FUN: brlid
; MUL-NOT: brlid
ret i32 %tmp.1
; FUN: rtsd
; MUL: rtsd
; MUL: mul
}

View File

@ -1,23 +0,0 @@
; Ensure that multiplication is lowered to function calls when the 64-bit
; multiplier unit is not available in the hardware and that function calls
; are not used when the 64-bit multiplier unit is available in the hardware.
;
; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
; RUN: llc < %s -march=mblaze -mattr=+mul,+mul64 | \
; RUN: FileCheck -check-prefix=MUL %s
define i64 @test_i64(i64 %a, i64 %b) {
; FUN-LABEL: test_i64:
; MUL-LABEL: test_i64:
%tmp.1 = mul i64 %a, %b
; FUN-NOT: mul
; FUN: brlid
; MUL-NOT: brlid
; MUL: mulh
; MUL: mul
ret i64 %tmp.1
; FUN: rtsd
; MUL: rtsd
}

View File

@ -1,15 +0,0 @@
; Ensure that the select instruction is supported and is lowered to
; some sort of branch instruction.
;
; RUN: llc < %s -march=mblaze | FileCheck %s
define i32 @testsel(i32 %a, i32 %b)
{
; CHECK-LABEL: testsel:
%tmp.1 = icmp eq i32 %a, %b
; CHECK: cmp
%tmp.2 = select i1 %tmp.1, i32 %a, i32 %b
; CHECK: {{bne|beq}}
ret i32 %tmp.2
; CHECK: rtsd
}

View File

@ -1,115 +0,0 @@
; Ensure that shifts are lowered to loops when the barrel shifter unit is
; not available in the hardware and that loops are not used when the
; barrel shifter unit is available in the hardware.
;
; RUN: llc < %s -march=mblaze | FileCheck -check-prefix=FUN %s
; RUN: llc < %s -march=mblaze -mattr=+barrel | FileCheck -check-prefix=SHT %s
define i8 @test_i8(i8 %a, i8 %b) {
; FUN-LABEL: test_i8:
; SHT-LABEL: test_i8:
%tmp.1 = shl i8 %a, %b
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: bnei
ret i8 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bsll
}
define i8 @testc_i8(i8 %a, i8 %b) {
; FUN-LABEL: testc_i8:
; SHT-LABEL: testc_i8:
%tmp.1 = shl i8 %a, 5
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: andi
; SHT-NOT: add
; SHT-NOT: bnei
ret i8 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bslli
}
define i16 @test_i16(i16 %a, i16 %b) {
; FUN-LABEL: test_i16:
; SHT-LABEL: test_i16:
%tmp.1 = shl i16 %a, %b
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: bnei
ret i16 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bsll
}
define i16 @testc_i16(i16 %a, i16 %b) {
; FUN-LABEL: testc_i16:
; SHT-LABEL: testc_i16:
%tmp.1 = shl i16 %a, 5
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: andi
; SHT-NOT: add
; SHT-NOT: bnei
ret i16 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bslli
}
define i32 @test_i32(i32 %a, i32 %b) {
; FUN-LABEL: test_i32:
; SHT-LABEL: test_i32:
%tmp.1 = shl i32 %a, %b
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: andi
; SHT-NOT: bnei
ret i32 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bsll
}
define i32 @testc_i32(i32 %a, i32 %b) {
; FUN-LABEL: testc_i32:
; SHT-LABEL: testc_i32:
%tmp.1 = shl i32 %a, 5
; FUN: andi
; FUN: add
; FUN: bnei
; SHT-NOT: andi
; SHT-NOT: add
; SHT-NOT: bnei
ret i32 %tmp.1
; FUN: rtsd
; SHT: rtsd
; FUN-NOT: bsll
; SHT-NEXT: bslli
}

Some files were not shown because too many files have changed in this diff Show More