Remove the CellSPU port.

Approved by Chris Lattner.

llvm-svn: 167984
This commit is contained in:
Eric Christopher 2012-11-14 22:09:20 +00:00
parent fd081ca50a
commit 950d8703b1
120 changed files with 9 additions and 22263 deletions

View File

@ -697,14 +697,14 @@ dnl Allow specific targets to be specified for building (or not)
TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
[Build specific host targets: all or target1,target2,... Valid targets are:
host, x86, x86_64, sparc, powerpc, arm, mips, spu, hexagon,
host, x86, x86_64, sparc, powerpc, arm, mips, hexagon,
xcore, msp430, nvptx, and cpp (default=all)]),,
enableval=all)
if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 CppBackend MBlaze NVPTX Hexagon" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -716,7 +716,6 @@ case "$enableval" in
mipsel) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64el) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
@ -731,7 +730,6 @@ case "$enableval" in
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;

10
llvm/configure vendored
View File

@ -1426,8 +1426,8 @@ Optional Features:
YES)
--enable-targets Build specific host targets: all or
target1,target2,... Valid targets are: host, x86,
x86_64, sparc, powerpc, arm, mips, spu, hexagon,
xcore, msp430, nvptx, and cpp (default=all)
x86_64, sparc, powerpc, arm, mips, hexagon, xcore,
msp430, nvptx, and cpp (default=all)
--enable-experimental-targets
Build experimental host targets: disable or
target1,target2,... (default=disable)
@ -5418,7 +5418,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips CellSPU XCore MSP430 CppBackend MBlaze NVPTX Hexagon" ;;
all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@ -5430,7 +5430,6 @@ case "$enableval" in
mipsel) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
mips64el) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
@ -5445,7 +5444,6 @@ case "$enableval" in
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
@ -10315,7 +10313,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10318 "configure"
#line 10316 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H

View File

@ -1762,7 +1762,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<th>Feature</th>`
:raw-html:`<th>ARM</th>`
:raw-html:`<th>CellSPU</th>`
:raw-html:`<th>Hexagon</th>`
:raw-html:`<th>MBlaze</th>`
:raw-html:`<th>MSP430</th>`
@ -1777,7 +1776,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<td><a href="#feat_reliable">is generally reliable</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
@ -1792,7 +1790,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<td><a href="#feat_asmparser">assembly parser</a></td>`
:raw-html:`<td class="no"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
@ -1807,7 +1804,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<td><a href="#feat_disassembler">disassembler</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
@ -1822,7 +1818,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<td><a href="#feat_inlineasm">inline asm</a></td>`
:raw-html:`<td class="yes"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
@ -1837,7 +1832,6 @@ Here is the table:
:raw-html:`<tr>`
: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> <!-- CellSPU -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
@ -1852,7 +1846,6 @@ Here is the table:
:raw-html:`<tr>`
: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> <!-- CellSPU -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="yes"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`
@ -1867,7 +1860,6 @@ Here is the table:
:raw-html:`<tr>`
: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="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="yes"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="unknown"></td> <!-- MSP430 -->`
@ -1882,7 +1874,6 @@ Here is the table:
:raw-html:`<tr>`
:raw-html:`<td><a href="#feat_segstacks">segmented stacks</a></td>`
:raw-html:`<td class="no"></td> <!-- ARM -->`
:raw-html:`<td class="no"></td> <!-- CellSPU -->`
:raw-html:`<td class="no"></td> <!-- Hexagon -->`
:raw-html:`<td class="no"></td> <!-- MBlaze -->`
:raw-html:`<td class="no"></td> <!-- MSP430 -->`

View File

@ -44,7 +44,6 @@ public:
UnknownArch,
arm, // ARM; arm, armv.*, xscale
cellspu, // CellSPU: spu, cellspu
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel

View File

@ -464,7 +464,6 @@ def int_convertuu : Intrinsic<[llvm_anyint_ty],
include "llvm/IntrinsicsPowerPC.td"
include "llvm/IntrinsicsX86.td"
include "llvm/IntrinsicsARM.td"
include "llvm/IntrinsicsCellSPU.td"
include "llvm/IntrinsicsXCore.td"
include "llvm/IntrinsicsHexagon.td"
include "llvm/IntrinsicsNVVM.td"

View File

@ -1,242 +0,0 @@
//==- IntrinsicsCellSPU.td - Cell SDK intrinsics -*- tablegen -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// Department at The Aerospace Corporation and is distributed under the
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Cell SPU Instructions:
//===----------------------------------------------------------------------===//
// TODO Items (not urgent today, but would be nice, low priority)
//
// ANDBI, ORBI: SPU constructs a 4-byte constant for these instructions by
// concatenating the byte argument b as "bbbb". Could recognize this bit pattern
// in 16-bit and 32-bit constants and reduce instruction count.
//===----------------------------------------------------------------------===//
// 7-bit integer type, used as an immediate:
def cell_i7_ty: LLVMType<i8>;
def cell_i8_ty: LLVMType<i8>;
// Keep this here until it's actually supported:
def llvm_i128_ty : LLVMType<i128>;
class v16i8_u7imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, cell_i7_ty],
[IntrNoMem]>;
class v16i8_u8imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i8_ty],
[IntrNoMem]>;
class v16i8_s10imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
[IntrNoMem]>;
class v16i8_u16imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i16_ty],
[IntrNoMem]>;
class v16i8_rr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
class v8i16_s10imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
[IntrNoMem]>;
class v8i16_u16imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i16_ty],
[IntrNoMem]>;
class v8i16_rr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
class v4i32_rr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
class v4i32_u7imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, cell_i7_ty],
[IntrNoMem]>;
class v4i32_s10imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
[IntrNoMem]>;
class v4i32_u16imm<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i16_ty],
[IntrNoMem]>;
class v4f32_rr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
class v4f32_rrr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
class v2f64_rr<string builtin_suffix> :
GCCBuiltin<!strconcat("__builtin_si_", builtin_suffix)>,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty],
[IntrNoMem]>;
// All Cell SPU intrinsics start with "llvm.spu.".
let TargetPrefix = "spu" in {
def int_spu_si_fsmbi : v8i16_u16imm<"fsmbi">;
def int_spu_si_ah : v8i16_rr<"ah">;
def int_spu_si_ahi : v8i16_s10imm<"ahi">;
def int_spu_si_a : v4i32_rr<"a">;
def int_spu_si_ai : v4i32_s10imm<"ai">;
def int_spu_si_sfh : v8i16_rr<"sfh">;
def int_spu_si_sfhi : v8i16_s10imm<"sfhi">;
def int_spu_si_sf : v4i32_rr<"sf">;
def int_spu_si_sfi : v4i32_s10imm<"sfi">;
def int_spu_si_addx : v4i32_rr<"addx">;
def int_spu_si_cg : v4i32_rr<"cg">;
def int_spu_si_cgx : v4i32_rr<"cgx">;
def int_spu_si_sfx : v4i32_rr<"sfx">;
def int_spu_si_bg : v4i32_rr<"bg">;
def int_spu_si_bgx : v4i32_rr<"bgx">;
def int_spu_si_mpy : // This is special:
GCCBuiltin<"__builtin_si_mpy">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyu : // This is special:
GCCBuiltin<"__builtin_si_mpyu">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyi : // This is special:
GCCBuiltin<"__builtin_si_mpyi">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyui : // This is special:
GCCBuiltin<"__builtin_si_mpyui">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_i16_ty],
[IntrNoMem]>;
def int_spu_si_mpya : // This is special:
GCCBuiltin<"__builtin_si_mpya">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyh : // This is special:
GCCBuiltin<"__builtin_si_mpyh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpys : // This is special:
GCCBuiltin<"__builtin_si_mpys">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyhh : // This is special:
GCCBuiltin<"__builtin_si_mpyhh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyhha : // This is special:
GCCBuiltin<"__builtin_si_mpyhha">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyhhu : // This is special:
GCCBuiltin<"__builtin_si_mpyhhu">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_mpyhhau : // This is special:
GCCBuiltin<"__builtin_si_mpyhhau">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
def int_spu_si_shli: v4i32_u7imm<"shli">;
def int_spu_si_shlqbi:
GCCBuiltin<!strconcat("__builtin_si_", "shlqbi")>,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_spu_si_shlqbii: v16i8_u7imm<"shlqbii">;
def int_spu_si_shlqby:
GCCBuiltin<!strconcat("__builtin_si_", "shlqby")>,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_spu_si_shlqbyi: v16i8_u7imm<"shlqbyi">;
def int_spu_si_ceq: v4i32_rr<"ceq">;
def int_spu_si_ceqi: v4i32_s10imm<"ceqi">;
def int_spu_si_ceqb: v16i8_rr<"ceqb">;
def int_spu_si_ceqbi: v16i8_u8imm<"ceqbi">;
def int_spu_si_ceqh: v8i16_rr<"ceqh">;
def int_spu_si_ceqhi: v8i16_s10imm<"ceqhi">;
def int_spu_si_cgt: v4i32_rr<"cgt">;
def int_spu_si_cgti: v4i32_s10imm<"cgti">;
def int_spu_si_cgtb: v16i8_rr<"cgtb">;
def int_spu_si_cgtbi: v16i8_u8imm<"cgtbi">;
def int_spu_si_cgth: v8i16_rr<"cgth">;
def int_spu_si_cgthi: v8i16_s10imm<"cgthi">;
def int_spu_si_clgtb: v16i8_rr<"clgtb">;
def int_spu_si_clgtbi: v16i8_u8imm<"clgtbi">;
def int_spu_si_clgth: v8i16_rr<"clgth">;
def int_spu_si_clgthi: v8i16_s10imm<"clgthi">;
def int_spu_si_clgt: v4i32_rr<"clgt">;
def int_spu_si_clgti: v4i32_s10imm<"clgti">;
def int_spu_si_and: v4i32_rr<"and">;
def int_spu_si_andbi: v16i8_u8imm<"andbi">;
def int_spu_si_andc: v4i32_rr<"andc">;
def int_spu_si_andhi: v8i16_s10imm<"andhi">;
def int_spu_si_andi: v4i32_s10imm<"andi">;
def int_spu_si_or: v4i32_rr<"or">;
def int_spu_si_orbi: v16i8_u8imm<"orbi">;
def int_spu_si_orc: v4i32_rr<"orc">;
def int_spu_si_orhi: v8i16_s10imm<"orhi">;
def int_spu_si_ori: v4i32_s10imm<"ori">;
def int_spu_si_xor: v4i32_rr<"xor">;
def int_spu_si_xorbi: v16i8_u8imm<"xorbi">;
def int_spu_si_xorhi: v8i16_s10imm<"xorhi">;
def int_spu_si_xori: v4i32_s10imm<"xori">;
def int_spu_si_nor: v4i32_rr<"nor">;
def int_spu_si_nand: v4i32_rr<"nand">;
def int_spu_si_fa: v4f32_rr<"fa">;
def int_spu_si_fs: v4f32_rr<"fs">;
def int_spu_si_fm: v4f32_rr<"fm">;
def int_spu_si_fceq: v4f32_rr<"fceq">;
def int_spu_si_fcmeq: v4f32_rr<"fcmeq">;
def int_spu_si_fcgt: v4f32_rr<"fcgt">;
def int_spu_si_fcmgt: v4f32_rr<"fcmgt">;
def int_spu_si_fma: v4f32_rrr<"fma">;
def int_spu_si_fnms: v4f32_rrr<"fnms">;
def int_spu_si_fms: v4f32_rrr<"fms">;
def int_spu_si_dfa: v2f64_rr<"dfa">;
def int_spu_si_dfs: v2f64_rr<"dfs">;
def int_spu_si_dfm: v2f64_rr<"dfm">;
//def int_spu_si_dfceq: v2f64_rr<"dfceq">;
//def int_spu_si_dfcmeq: v2f64_rr<"dfcmeq">;
//def int_spu_si_dfcgt: v2f64_rr<"dfcgt">;
//def int_spu_si_dfcmgt: v2f64_rr<"dfcmgt">;
def int_spu_si_dfnma: v2f64_rr<"dfnma">;
def int_spu_si_dfma: v2f64_rr<"dfma">;
def int_spu_si_dfnms: v2f64_rr<"dfnms">;
def int_spu_si_dfms: v2f64_rr<"dfms">;
}

View File

@ -20,7 +20,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case UnknownArch: return "unknown";
case arm: return "arm";
case cellspu: return "cellspu";
case hexagon: return "hexagon";
case mips: return "mips";
case mipsel: return "mipsel";
@ -56,8 +55,6 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case arm:
case thumb: return "arm";
case cellspu: return "spu";
case ppc64:
case ppc: return "ppc";
@ -153,7 +150,6 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return StringSwitch<Triple::ArchType>(Name)
.Case("arm", arm)
.Case("cellspu", cellspu)
.Case("mips", mips)
.Case("mipsel", mipsel)
.Case("mips64", mips64)
@ -220,7 +216,6 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.StartsWith("armv", Triple::arm)
.Case("thumb", Triple::thumb)
.StartsWith("thumbv", Triple::thumb)
.Cases("spu", "cellspu", Triple::cellspu)
.Case("msp430", Triple::msp430)
.Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
.Cases("mipsel", "mipsallegrexel", Triple::mipsel)
@ -659,7 +654,6 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::amdil:
case llvm::Triple::arm:
case llvm::Triple::cellspu:
case llvm::Triple::hexagon:
case llvm::Triple::le32:
case llvm::Triple::mblaze:
@ -709,7 +703,6 @@ Triple Triple::get32BitArchVariant() const {
case Triple::amdil:
case Triple::spir:
case Triple::arm:
case Triple::cellspu:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:
@ -742,7 +735,6 @@ Triple Triple::get64BitArchVariant() const {
case Triple::UnknownArch:
case Triple::amdil:
case Triple::arm:
case Triple::cellspu:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:

View File

@ -1,30 +0,0 @@
set(LLVM_TARGET_DEFINITIONS SPU.td)
tablegen(LLVM SPUGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM SPUGenCodeEmitter.inc -gen-emitter)
tablegen(LLVM SPUGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM SPUGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM SPUGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM SPUGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM SPUGenCallingConv.inc -gen-callingconv)
add_public_tablegen_target(CellSPUCommonTableGen)
add_llvm_target(CellSPUCodeGen
SPUAsmPrinter.cpp
SPUHazardRecognizers.cpp
SPUInstrInfo.cpp
SPUISelDAGToDAG.cpp
SPUISelLowering.cpp
SPUFrameLowering.cpp
SPUMachineFunction.cpp
SPURegisterInfo.cpp
SPUSubtarget.cpp
SPUTargetMachine.cpp
SPUSelectionDAGInfo.cpp
SPUNopFiller.cpp
)
add_dependencies(LLVMCellSPUCodeGen intrinsics_gen)
add_subdirectory(TargetInfo)
add_subdirectory(MCTargetDesc)

View File

@ -1,449 +0,0 @@
//===-- CellSDKIntrinsics.td - Cell SDK Intrinsics ---------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///--==-- Arithmetic ops intrinsics --==--
def CellSDKah:
RR_Int_v8i16<0b00010011000, "ah", IntegerOp, int_spu_si_ah>;
def CellSDKahi:
RI10_Int_v8i16<0b00010011000, "ahi", IntegerOp, int_spu_si_ahi>;
def CellSDKa:
RR_Int_v4i32<0b00000011000, "a", IntegerOp, int_spu_si_a>;
def CellSDKai:
RI10_Int_v4i32<0b00111000, "ai", IntegerOp, int_spu_si_ai>;
def CellSDKsfh:
RR_Int_v8i16<0b00010010000, "sfh", IntegerOp, int_spu_si_sfh>;
def CellSDKsfhi:
RI10_Int_v8i16<0b10110000, "sfhi", IntegerOp, int_spu_si_sfhi>;
def CellSDKsf:
RR_Int_v4i32<0b00000010000, "sf", IntegerOp, int_spu_si_sf>;
def CellSDKsfi:
RI10_Int_v4i32<0b00110000, "sfi", IntegerOp, int_spu_si_sfi>;
def CellSDKaddx:
RR_Int_v4i32<0b00000010110, "addx", IntegerOp, int_spu_si_addx>;
def CellSDKcg:
RR_Int_v4i32<0b0100001100, "cg", IntegerOp, int_spu_si_cg>;
def CellSDKcgx:
RR_Int_v4i32<0b01000010110, "cgx", IntegerOp, int_spu_si_cgx>;
def CellSDKsfx:
RR_Int_v4i32<0b10000010110, "sfx", IntegerOp, int_spu_si_sfx>;
def CellSDKbg:
RR_Int_v4i32<0b01000010000, "bg", IntegerOp, int_spu_si_bg>;
def CellSDKbgx:
RR_Int_v4i32<0b11000010110, "bgx", IntegerOp, int_spu_si_bgx>;
def CellSDKmpy:
RRForm<0b00100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpy $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpy (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKmpyu:
RRForm<0b00110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyu $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyu (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))] >;
def CellSDKmpyi:
RI10Form<0b00101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"mpyi $rT, $rA, $val", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyi (v8i16 VECREG:$rA),
i16ImmSExt10:$val))]>;
def CellSDKmpyui:
RI10Form<0b10101110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"mpyui $rT, $rA, $val", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyui (v8i16 VECREG:$rA),
i16ImmSExt10:$val))]>;
def CellSDKmpya:
RRRForm<0b0011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
"mpya $rT, $rA, $rB, $rC", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpya (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB),
(v8i16 VECREG:$rC)))]>;
def CellSDKmpyh:
RRForm<0b10100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyh $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyh (v4i32 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKmpys:
RRForm<0b11100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpys $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpys (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKmpyhh:
RRForm<0b01100011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyhh $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyhh (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKmpyhha:
RRForm<0b01100010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyhha $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyhha (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
// Not sure how to match a (set $rT, (add $rT (mpyhh $rA, $rB)))... so leave
// as an intrinsic for the time being
def CellSDKmpyhhu:
RRForm<0b01110011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyhhu $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyhhu (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKmpyhhau:
RRForm<0b01110010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"mpyhhau $rT, $rA, $rB", IntegerMulDiv,
[(set (v4i32 VECREG:$rT), (int_spu_si_mpyhhau (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))]>;
def CellSDKand:
RRForm<0b1000011000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"and\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKandc:
RRForm<0b10000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"andc\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_andc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKandbi:
RI10Form<0b01101000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"andbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_andbi (v16i8 VECREG:$rA), immU8:$val))]>;
def CellSDKandhi:
RI10Form<0b10101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"andhi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_andhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKandi:
RI10Form<0b00101000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"andi\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_andi (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKor:
RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"or\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKorc:
RRForm<0b10010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"addc\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_orc (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKorbi:
RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"orbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_orbi (v16i8 VECREG:$rA), immU8:$val))]>;
def CellSDKorhi:
RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"orhi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_orhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKori:
RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"ori\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_ori (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKxor:
RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"xor\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKxorbi:
RI10Form<0b01100000, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"xorbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT), (int_spu_si_xorbi (v16i8 VECREG:$rA), immU8:$val))]>;
def CellSDKxorhi:
RI10Form<0b10100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"xorhi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_xorhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKxori:
RI10Form<0b00100000, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"xori\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_xori (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKnor:
RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"nor\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_nor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKnand:
RRForm<0b10000010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"nand\t $rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT),
(int_spu_si_nand (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
//===----------------------------------------------------------------------===//
// Shift/rotate intrinsics:
//===----------------------------------------------------------------------===//
def CellSDKshli:
Pat<(int_spu_si_shli (v4i32 VECREG:$rA), uimm7:$val),
(SHLIv4i32 VECREG:$rA, (TO_IMM32 imm:$val))>;
def CellSDKshlqbi:
Pat<(int_spu_si_shlqbi VECREG:$rA, R32C:$rB),
(SHLQBIv16i8 VECREG:$rA, R32C:$rB)>;
def CellSDKshlqii:
Pat<(int_spu_si_shlqbii VECREG:$rA, uimm7:$val),
(SHLQBIIv16i8 VECREG:$rA, (TO_IMM32 imm:$val))>;
def CellSDKshlqby:
Pat<(int_spu_si_shlqby VECREG:$rA, R32C:$rB),
(SHLQBYv16i8 VECREG:$rA, R32C:$rB)>;
def CellSDKshlqbyi:
Pat<(int_spu_si_shlqbyi VECREG:$rA, uimm7:$val),
(SHLQBYIv16i8 VECREG:$rA, (TO_IMM32 imm:$val))>;
//===----------------------------------------------------------------------===//
// Branch/compare intrinsics:
//===----------------------------------------------------------------------===//
def CellSDKceq:
RRForm<0b00000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"ceq\t $rT, $rA, $rB", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_ceq (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKceqi:
RI10Form<0b00111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"ceqi\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_ceqi (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKceqb:
RRForm<0b00001011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"ceqb\t $rT, $rA, $rB", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_ceqb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
def CellSDKceqbi:
RI10Form<0b01111110, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"ceqbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT), (int_spu_si_ceqbi (v16i8 VECREG:$rA), immU8:$val))]>;
def CellSDKceqh:
RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"ceqh\t $rT, $rA, $rB", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_ceqh (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
def CellSDKceqhi:
RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"ceqhi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_ceqhi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKcgth:
RRForm<0b00010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"cgth\t $rT, $rA, $rB", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_cgth (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
def CellSDKcgthi:
RI10Form<0b10111110, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"cgthi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_cgthi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKcgt:
RRForm<0b00000010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"cgt\t $rT, $rA, $rB", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_cgt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKcgti:
RI10Form<0b00110010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"cgti\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_cgti (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKcgtb:
RRForm<0b00001010010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"cgtb\t $rT, $rA, $rB", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_cgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
def CellSDKcgtbi:
RI10Form<0b01110010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"cgtbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT), (int_spu_si_cgtbi (v16i8 VECREG:$rA), immU8:$val))]>;
def CellSDKclgth:
RRForm<0b00010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"clgth\t $rT, $rA, $rB", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_clgth (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>;
def CellSDKclgthi:
RI10Form<0b10111010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"clgthi\t $rT, $rA, $val", BranchResolv,
[(set (v8i16 VECREG:$rT),
(int_spu_si_clgthi (v8i16 VECREG:$rA), i16ImmSExt10:$val))]>;
def CellSDKclgt:
RRForm<0b00000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"clgt\t $rT, $rA, $rB", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_clgt (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>;
def CellSDKclgti:
RI10Form<0b00111010, (outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val),
"clgti\t $rT, $rA, $val", BranchResolv,
[(set (v4i32 VECREG:$rT),
(int_spu_si_clgti (v4i32 VECREG:$rA), i32ImmSExt10:$val))]>;
def CellSDKclgtb:
RRForm<0b00001011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"clgtb\t $rT, $rA, $rB", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_clgtb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>;
def CellSDKclgtbi:
RI10Form<0b01111010, (outs VECREG:$rT), (ins VECREG:$rA, u10imm_i8:$val),
"clgtbi\t $rT, $rA, $val", BranchResolv,
[(set (v16i8 VECREG:$rT),
(int_spu_si_clgtbi (v16i8 VECREG:$rA), immU8:$val))]>;
//===----------------------------------------------------------------------===//
// Floating-point intrinsics:
//===----------------------------------------------------------------------===//
def CellSDKfa:
RRForm<0b00100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fa\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fa (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfs:
RRForm<0b10100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fs\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fs (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfm:
RRForm<0b01100011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fm\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fm (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfceq:
RRForm<0b01000011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fceq\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fceq (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfcgt:
RRForm<0b01000011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fcgt\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fcgt (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfcmeq:
RRForm<0b01010011110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fcmeq\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fcmeq (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfcmgt:
RRForm<0b01010011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"fcmgt\t $rT, $rA, $rB", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fcmgt (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB)))]>;
def CellSDKfma:
RRRForm<0b0111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
"fma\t $rT, $rA, $rB, $rC", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fma (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB),
(v4f32 VECREG:$rC)))]>;
def CellSDKfnms:
RRRForm<0b1011, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
"fnms\t $rT, $rA, $rB, $rC", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fnms (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB),
(v4f32 VECREG:$rC)))]>;
def CellSDKfms:
RRRForm<0b1111, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC),
"fms\t $rT, $rA, $rB, $rC", SPrecFP,
[(set (v4f32 VECREG:$rT), (int_spu_si_fms (v4f32 VECREG:$rA),
(v4f32 VECREG:$rB),
(v4f32 VECREG:$rC)))]>;
//===----------------------------------------------------------------------===//
// Double precision floating-point intrinsics:
//===----------------------------------------------------------------------===//
def CellSDKdfa:
RRForm<0b00110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfa\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfa (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfs:
RRForm<0b10110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfs\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfs (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfm:
RRForm<0b01110011010, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfm\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfm (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfma:
RRForm<0b00111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfma\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfma (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfnma:
RRForm<0b11111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfnma\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfnma (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfnms:
RRForm<0b01111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfnms\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfnms (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;
def CellSDKdfms:
RRForm<0b10111010110, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
"dfms\t $rT, $rA, $rB", DPrecFP,
[(set (v2f64 VECREG:$rT), (int_spu_si_dfms (v2f64 VECREG:$rA),
(v2f64 VECREG:$rB)))]>;

View File

@ -1,32 +0,0 @@
;===- ./lib/Target/CellSPU/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 = MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
name = CellSPU
parent = Target
has_asmprinter = 1
[component_1]
type = Library
name = CellSPUCodeGen
parent = CellSPU
required_libraries = AsmPrinter CellSPUDesc CellSPUInfo CodeGen Core MC SelectionDAG Support Target
add_to_library_groups = CellSPU

View File

@ -1,6 +0,0 @@
add_llvm_library(LLVMCellSPUDesc
SPUMCTargetDesc.cpp
SPUMCAsmInfo.cpp
)
add_dependencies(LLVMCellSPUDesc CellSPUCommonTableGen)

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/CellSPU/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 = CellSPUDesc
parent = CellSPU
required_libraries = CellSPUInfo MC
add_to_library_groups = CellSPU

View File

@ -1,16 +0,0 @@
##===- lib/Target/CellSPU/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 = LLVMCellSPUDesc
# 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,43 +0,0 @@
//===-- SPUMCAsmInfo.cpp - Cell SPU 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 SPUMCAsmInfo properties.
//
//===----------------------------------------------------------------------===//
#include "SPUMCAsmInfo.h"
using namespace llvm;
void SPULinuxMCAsmInfo::anchor() { }
SPULinuxMCAsmInfo::SPULinuxMCAsmInfo(const Target &T, StringRef TT) {
IsLittleEndian = false;
ZeroDirective = "\t.space\t";
Data64bitsDirective = "\t.quad\t";
AlignmentIsInBytes = false;
PCSymbol = ".";
CommentString = "#";
GlobalPrefix = "";
PrivateGlobalPrefix = ".L";
// Has leb128
HasLEB128 = true;
SupportsDebugInformation = true;
// Exception handling is not supported on CellSPU (think about it: you only
// have 256K for code+data. Would you support exception handling?)
ExceptionsType = ExceptionHandling::None;
// SPU assembly requires ".section" before ".bss"
UsesELFSectionDirectiveForBSS = true;
}

View File

@ -1,30 +0,0 @@
//===-- SPUMCAsmInfo.h - Cell SPU 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 SPUMCAsmInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef SPUTARGETASMINFO_H
#define SPUTARGETASMINFO_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfo.h"
namespace llvm {
class Target;
class SPULinuxMCAsmInfo : public MCAsmInfo {
virtual void anchor();
public:
explicit SPULinuxMCAsmInfo(const Target &T, StringRef TT);
};
} // namespace llvm
#endif /* SPUTARGETASMINFO_H */

View File

@ -1,94 +0,0 @@
//===-- SPUMCTargetDesc.cpp - Cell SPU 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 Cell SPU specific target descriptions.
//
//===----------------------------------------------------------------------===//
#include "SPUMCTargetDesc.h"
#include "SPUMCAsmInfo.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_INSTRINFO_MC_DESC
#include "SPUGenInstrInfo.inc"
#define GET_SUBTARGETINFO_MC_DESC
#include "SPUGenSubtargetInfo.inc"
#define GET_REGINFO_MC_DESC
#include "SPUGenRegisterInfo.inc"
using namespace llvm;
static MCInstrInfo *createSPUMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitSPUMCInstrInfo(X);
return X;
}
static MCRegisterInfo *createCellSPUMCRegisterInfo(StringRef TT) {
MCRegisterInfo *X = new MCRegisterInfo();
InitSPUMCRegisterInfo(X, SPU::R0);
return X;
}
static MCSubtargetInfo *createSPUMCSubtargetInfo(StringRef TT, StringRef CPU,
StringRef FS) {
MCSubtargetInfo *X = new MCSubtargetInfo();
InitSPUMCSubtargetInfo(X, TT, CPU, FS);
return X;
}
static MCAsmInfo *createSPUMCAsmInfo(const Target &T, StringRef TT) {
MCAsmInfo *MAI = new SPULinuxMCAsmInfo(T, TT);
// Initial state of the frame pointer is R1.
MachineLocation Dst(MachineLocation::VirtualFP);
MachineLocation Src(SPU::R1, 0);
MAI->addInitialFrameState(0, Dst, Src);
return MAI;
}
static MCCodeGenInfo *createSPUMCCodeGenInfo(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
// For the time being, use static relocations, since there's really no
// support for PIC yet.
X->InitMCCodeGenInfo(Reloc::Static, CM, OL);
return X;
}
// Force static initialization.
extern "C" void LLVMInitializeCellSPUTargetMC() {
// Register the MC asm info.
RegisterMCAsmInfoFn X(TheCellSPUTarget, createSPUMCAsmInfo);
// Register the MC codegen info.
TargetRegistry::RegisterMCCodeGenInfo(TheCellSPUTarget,
createSPUMCCodeGenInfo);
// Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(TheCellSPUTarget, createSPUMCInstrInfo);
// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(TheCellSPUTarget,
createCellSPUMCRegisterInfo);
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(TheCellSPUTarget,
createSPUMCSubtargetInfo);
}

View File

@ -1,38 +0,0 @@
//===-- SPUMCTargetDesc.h - CellSPU 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 CellSPU specific target descriptions.
//
//===----------------------------------------------------------------------===//
#ifndef SPUMCTARGETDESC_H
#define SPUMCTARGETDESC_H
namespace llvm {
class Target;
extern Target TheCellSPUTarget;
} // End llvm namespace
// Define symbolic names for Cell registers. This defines a mapping from
// register name to register number.
//
#define GET_REGINFO_ENUM
#include "SPUGenRegisterInfo.inc"
// Defines symbolic names for the SPU instructions.
//
#define GET_INSTRINFO_ENUM
#include "SPUGenInstrInfo.inc"
#define GET_SUBTARGETINFO_ENUM
#include "SPUGenSubtargetInfo.inc"
#endif

View File

@ -1,20 +0,0 @@
##===- lib/Target/CellSPU/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 = LLVMCellSPUCodeGen
TARGET = SPU
BUILT_SOURCES = SPUGenInstrInfo.inc SPUGenRegisterInfo.inc \
SPUGenAsmWriter.inc SPUGenCodeEmitter.inc \
SPUGenDAGISel.inc \
SPUGenSubtargetInfo.inc SPUGenCallingConv.inc
DIRS = TargetInfo MCTargetDesc
include $(LEVEL)/Makefile.common

View File

@ -1,106 +0,0 @@
//===- README.txt - Notes for improving CellSPU-specific code gen ---------===//
This code was contributed by a team from the Computer Systems Research
Department in The Aerospace Corporation:
- Scott Michel (head bottle washer and much of the non-floating point
instructions)
- Mark Thomas (floating point instructions)
- Michael AuYeung (intrinsics)
- Chandler Carruth (LLVM expertise)
- Nehal Desai (debugging, i32 operations, RoadRunner SPU expertise)
Some minor fixes added by Kalle Raiskila.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR
OTHERWISE. IN NO EVENT SHALL THE AEROSPACE CORPORATION BE LIABLE FOR DAMAGES
OF ANY KIND OR NATURE WHETHER BASED IN CONTRACT, TORT, OR OTHERWISE ARISING
OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE INCLUDING, WITHOUT
LIMITATION, DAMAGES RESULTING FROM LOST OR CONTAMINATED DATA, LOST PROFITS OR
REVENUE, COMPUTER MALFUNCTION, OR FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL,
OR PUNITIVE DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR
SUCH DAMAGES ARE FORESEEABLE.
---------------------------------------------------------------------------
--WARNING--:
--WARNING--: The CellSPU work is work-in-progress and "alpha" quality code.
--WARNING--:
If you are brave enough to try this code or help to hack on it, be sure
to add 'spu' to configure's --enable-targets option, e.g.:
./configure <your_configure_flags_here> \
--enable-targets=x86,x86_64,powerpc,spu
---------------------------------------------------------------------------
TODO:
* In commit r142152 vector legalization was set to element promotion per
default. This breaks half vectors (e.g. v2i32) badly as they get element
promoted to much slower types (v2i64).
* Many CellSPU specific codegen tests only grep & count the number of
instructions, not checking their place with FileCheck. There have also
been some commits that change the CellSPU checks, some of which might
have not been thoroughly scrutinized w.r.t. to the changes they cause in SPU
assembly. (especially since about the time of r142152)
* Some of the i64 math have huge tablegen rules, which sometime cause
tablegen to run out of memory. See e.g. bug 8850. i64 arithmetics
should probably be done with libraries.
* Create a machine pass for performing dual-pipeline scheduling specifically
for CellSPU, and insert branch prediction instructions as needed.
* i32 instructions:
* i32 division (work-in-progress)
* i64 support (see i64operations.c test harness):
* shifts and comparison operators: done
* sign and zero extension: done
* addition: done
* subtraction: needed
* multiplication: done
* i128 support:
* zero extension, any extension: done
* sign extension: done
* arithmetic operators (add, sub, mul, div): needed
* logical operations (and, or, shl, srl, sra, xor, nor, nand): needed
* or: done
* f64 support
* Comparison operators:
SETOEQ unimplemented
SETOGT unimplemented
SETOGE unimplemented
SETOLT unimplemented
SETOLE unimplemented
SETONE unimplemented
SETO done (lowered)
SETUO done (lowered)
SETUEQ unimplemented
SETUGT unimplemented
SETUGE unimplemented
SETULT unimplemented
SETULE unimplemented
SETUNE unimplemented
* LLVM vector suport
* VSETCC needs to be implemented. It's pretty straightforward to code, but
needs implementation.
* Intrinsics
* spu.h instrinsics added but not tested. Need to have an operational
llvm-spu-gcc in order to write a unit test harness.
===-------------------------------------------------------------------------===

View File

@ -1,31 +0,0 @@
//===-- SPU.h - Top-level interface for Cell SPU Target ---------*- 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
// Cell SPU back-end.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_IBMCELLSPU_H
#define LLVM_TARGET_IBMCELLSPU_H
#include "MCTargetDesc/SPUMCTargetDesc.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class SPUTargetMachine;
class FunctionPass;
class formatted_raw_ostream;
FunctionPass *createSPUISelDag(SPUTargetMachine &TM);
FunctionPass *createSPUNopFillerPass(SPUTargetMachine &tm);
}
#endif /* LLVM_TARGET_IBMCELLSPU_H */

View File

@ -1,66 +0,0 @@
//===-- SPU.td - Describe the STI Cell SPU 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 STI Cell SPU target machine.
//
//===----------------------------------------------------------------------===//
// Get the target-independent interfaces which we are implementing.
//
include "llvm/Target/Target.td"
// Holder of code fragments (you'd think this'd already be in
// a td file somewhere... :-)
class CodeFrag<dag frag> {
dag Fragment = frag;
}
//===----------------------------------------------------------------------===//
// Register File Description
//===----------------------------------------------------------------------===//
include "SPURegisterInfo.td"
//===----------------------------------------------------------------------===//
// Instruction formats, instructions
//===----------------------------------------------------------------------===//
include "SPUNodes.td"
include "SPUOperands.td"
include "SPUSchedule.td"
include "SPUInstrFormats.td"
include "SPUInstrInfo.td"
//===----------------------------------------------------------------------===//
// Subtarget features:
//===----------------------------------------------------------------------===//
def DefaultProc: SubtargetFeature<"", "ProcDirective", "SPU::DEFAULT_PROC", "">;
def LargeMemFeature:
SubtargetFeature<"large_mem","UseLargeMem", "true",
"Use large (>256) LSA memory addressing [default = false]">;
def SPURev0 : Processor<"v0", SPUItineraries, [DefaultProc]>;
//===----------------------------------------------------------------------===//
// Calling convention:
//===----------------------------------------------------------------------===//
include "SPUCallingConv.td"
// Target:
def SPUInstrInfo : InstrInfo {
let isLittleEndianEncoding = 1;
}
def SPU : Target {
let InstructionSet = SPUInstrInfo;
}

View File

@ -1,41 +0,0 @@
//===-- SPU128InstrInfo.td - Cell SPU 128-bit operations --*- tablegen -*--===//
//
// Cell SPU 128-bit operations
//
//===----------------------------------------------------------------------===//
// zext 32->128: Zero extend 32-bit to 128-bit
def : Pat<(i128 (zext R32C:$rSrc)),
(ROTQMBYIr128_zext_r32 R32C:$rSrc, 12)>;
// zext 64->128: Zero extend 64-bit to 128-bit
def : Pat<(i128 (zext R64C:$rSrc)),
(ROTQMBYIr128_zext_r64 R64C:$rSrc, 8)>;
// zext 16->128: Zero extend 16-bit to 128-bit
def : Pat<(i128 (zext R16C:$rSrc)),
(ROTQMBYIr128_zext_r32 (ANDi16i32 R16C:$rSrc, (ILAr32 0xffff)), 12)>;
// zext 8->128: Zero extend 8-bit to 128-bit
def : Pat<(i128 (zext R8C:$rSrc)),
(ROTQMBYIr128_zext_r32 (ANDIi8i32 R8C:$rSrc, 0xf), 12)>;
// anyext 32->128: Zero extend 32-bit to 128-bit
def : Pat<(i128 (anyext R32C:$rSrc)),
(ROTQMBYIr128_zext_r32 R32C:$rSrc, 12)>;
// anyext 64->128: Zero extend 64-bit to 128-bit
def : Pat<(i128 (anyext R64C:$rSrc)),
(ROTQMBYIr128_zext_r64 R64C:$rSrc, 8)>;
// anyext 16->128: Zero extend 16-bit to 128-bit
def : Pat<(i128 (anyext R16C:$rSrc)),
(ROTQMBYIr128_zext_r32 (ANDi16i32 R16C:$rSrc, (ILAr32 0xffff)), 12)>;
// anyext 8->128: Zero extend 8-bit to 128-bit
def : Pat<(i128 (anyext R8C:$rSrc)),
(ROTQMBYIr128_zext_r32 (ANDIi8i32 R8C:$rSrc, 0xf), 12)>;
// Shift left
def : Pat<(shl GPRC:$rA, R32C:$rB),
(SHLQBYBIr128 (SHLQBIr128 GPRC:$rA, R32C:$rB), R32C:$rB)>;

View File

@ -1,408 +0,0 @@
//====-- SPU64InstrInfo.td - Cell SPU 64-bit operations ---*- tablegen -*--===//
//
// Cell SPU 64-bit operations
//
//===----------------------------------------------------------------------===//
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// 64-bit comparisons:
//
// 1. The instruction sequences for vector vice scalar differ by a
// constant. In the scalar case, we're only interested in the
// top two 32-bit slots, whereas we're interested in an exact
// all-four-slot match in the vector case.
//
// 2. There are no "immediate" forms, since loading 64-bit constants
// could be a constant pool load.
//
// 3. i64 setcc results are i32, which are subsequently converted to a FSM
// mask when used in a select pattern.
//
// 4. v2i64 setcc results are v4i32, which can be converted to a FSM mask (TODO)
// [Note: this may be moot, since gb produces v4i32 or r32.]
//
// 5. The code sequences for r64 and v2i64 are probably overly conservative,
// compared to the code that gcc produces.
//
// M00$E B!tes Kan be Pretty N@sTi!!!!! (apologies to Monty!)
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// selb instruction definition for i64. Note that the selection mask is
// a vector, produced by various forms of FSM:
def SELBr64_cond:
SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC),
[/* no pattern */]>;
// The generic i64 select pattern, which assumes that the comparison result
// is in a 32-bit register that contains a select mask pattern (i.e., gather
// bits result):
def : Pat<(select R32C:$rCond, R64C:$rFalse, R64C:$rTrue),
(SELBr64_cond R64C:$rTrue, R64C:$rFalse, (FSMr32 R32C:$rCond))>;
// select the negative condition:
class I64SELECTNegCond<PatFrag cond, CodeFrag compare>:
Pat<(select (i32 (cond R64C:$rA, R64C:$rB)), R64C:$rTrue, R64C:$rFalse),
(SELBr64_cond R64C:$rTrue, R64C:$rFalse, (FSMr32 compare.Fragment))>;
// setcc the negative condition:
class I64SETCCNegCond<PatFrag cond, CodeFrag compare>:
Pat<(cond R64C:$rA, R64C:$rB),
(XORIr32 compare.Fragment, -1)>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// The i64 seteq fragment that does the scalar->vector conversion and
// comparison:
def CEQr64compare:
CodeFrag<(CGTIv4i32 (GBv4i32 (CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG))), 0xb)>;
// The i64 seteq fragment that does the vector comparison
def CEQv2i64compare:
CodeFrag<(CEQIv4i32 (GBv4i32 (CEQv4i32 VECREG:$rA, VECREG:$rB)), 0xf)>;
// i64 seteq (equality): the setcc result is i32, which is converted to a
// vector FSM mask when used in a select pattern.
//
// v2i64 seteq (equality): the setcc result is v4i32
multiclass CompareEqual64 {
// Plain old comparison, converts back to i32 scalar
def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CEQr64compare.Fragment, R32C))>;
def v2i64: CodeFrag<(i32 (COPY_TO_REGCLASS CEQv2i64compare.Fragment, R32C))>;
// SELB mask from FSM:
def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CEQr64compare.Fragment), R32C))>;
def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CEQv2i64compare.Fragment), R32C))>;
}
defm I64EQ: CompareEqual64;
def : Pat<(seteq R64C:$rA, R64C:$rB), I64EQr64.Fragment>;
def : Pat<(seteq (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)), I64EQv2i64.Fragment>;
// i64 setne:
def : I64SETCCNegCond<setne, I64EQr64>;
def : I64SELECTNegCond<setne, I64EQr64>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// i64 setugt/setule:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def CLGTr64ugt:
CodeFrag<(CLGTv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG))>;
def CLGTr64eq:
CodeFrag<(CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG))>;
def CLGTr64compare:
CodeFrag<(SELBv2i64 CLGTr64ugt.Fragment,
(XSWDv2i64 CLGTr64ugt.Fragment),
CLGTr64eq.Fragment)>;
def CLGTv2i64ugt:
CodeFrag<(CLGTv4i32 VECREG:$rA, VECREG:$rB)>;
def CLGTv2i64eq:
CodeFrag<(CEQv4i32 VECREG:$rA, VECREG:$rB)>;
def CLGTv2i64compare:
CodeFrag<(SELBv2i64 CLGTv2i64ugt.Fragment,
(XSWDv2i64 CLGTr64ugt.Fragment),
CLGTv2i64eq.Fragment)>;
multiclass CompareLogicalGreaterThan64 {
// Plain old comparison, converts back to i32 scalar
def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CLGTr64compare.Fragment, R32C))>;
def v2i64: CodeFrag<CLGTv2i64compare.Fragment>;
// SELB mask from FSM:
def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CLGTr64compare.Fragment), R32C))>;
def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CLGTv2i64compare.Fragment), R32C))>;
}
defm I64LGT: CompareLogicalGreaterThan64;
def : Pat<(setugt R64C:$rA, R64C:$rB), I64LGTr64.Fragment>;
//def : Pat<(setugt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
// I64LGTv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setule, I64LGTr64>;
def : I64SELECTNegCond<setule, I64LGTr64>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// i64 setuge/setult:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def CLGEr64compare:
CodeFrag<(CGTIv4i32 (GBv4i32 (ORv4i32 CLGTr64ugt.Fragment,
CLGTr64eq.Fragment)), 0xb)>;
def CLGEv2i64compare:
CodeFrag<(CEQIv4i32 (GBv4i32 (ORv4i32 CLGTv2i64ugt.Fragment,
CLGTv2i64eq.Fragment)), 0xf)>;
multiclass CompareLogicalGreaterEqual64 {
// Plain old comparison, converts back to i32 scalar
def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CLGEr64compare.Fragment, R32C))>;
def v2i64: CodeFrag<CLGEv2i64compare.Fragment>;
// SELB mask from FSM:
def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CLGEr64compare.Fragment), R32C))>;
def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CLGEv2i64compare.Fragment),R32C))>;
}
defm I64LGE: CompareLogicalGreaterEqual64;
def : Pat<(setuge R64C:$rA, R64C:$rB), I64LGEr64.Fragment>;
def : Pat<(v2i64 (setuge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))),
I64LGEv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setult, I64LGEr64>;
def : I64SELECTNegCond<setult, I64LGEr64>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// i64 setgt/setle:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def CGTr64sgt:
CodeFrag<(CGTv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG))>;
def CGTr64eq:
CodeFrag<(CEQv4i32 (COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG))>;
def CGTr64compare:
CodeFrag<(SELBv2i64 CGTr64sgt.Fragment,
(XSWDv2i64 CGTr64sgt.Fragment),
CGTr64eq.Fragment)>;
def CGTv2i64sgt:
CodeFrag<(CGTv4i32 VECREG:$rA, VECREG:$rB)>;
def CGTv2i64eq:
CodeFrag<(CEQv4i32 VECREG:$rA, VECREG:$rB)>;
def CGTv2i64compare:
CodeFrag<(SELBv2i64 CGTv2i64sgt.Fragment,
(XSWDv2i64 CGTr64sgt.Fragment),
CGTv2i64eq.Fragment)>;
multiclass CompareGreaterThan64 {
// Plain old comparison, converts back to i32 scalar
def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CGTr64compare.Fragment, R32C))>;
def v2i64: CodeFrag<CGTv2i64compare.Fragment>;
// SELB mask from FSM:
def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CGTr64compare.Fragment), R32C))>;
def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS
(FSMv4i32 CGTv2i64compare.Fragment), R32C))>;
}
defm I64GT: CompareLogicalGreaterThan64;
def : Pat<(setgt R64C:$rA, R64C:$rB), I64GTr64.Fragment>;
//def : Pat<(setgt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
// I64GTv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setle, I64GTr64>;
def : I64SELECTNegCond<setle, I64GTr64>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// i64 setge/setlt:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def CGEr64compare:
CodeFrag<(CGTIv4i32 (GBv4i32 (ORv4i32 CGTr64sgt.Fragment,
CGTr64eq.Fragment)), 0xb)>;
def CGEv2i64compare:
CodeFrag<(CEQIv4i32 (GBv4i32 (ORv4i32 CGTv2i64sgt.Fragment,
CGTv2i64eq.Fragment)), 0xf)>;
multiclass CompareGreaterEqual64 {
// Plain old comparison, converts back to i32 scalar
def r64: CodeFrag<(i32 (COPY_TO_REGCLASS CGEr64compare.Fragment, R32C))>;
def v2i64: CodeFrag<CGEv2i64compare.Fragment>;
// SELB mask from FSM:
def r64mask: CodeFrag<(i32 (COPY_TO_REGCLASS (FSMv4i32 CGEr64compare.Fragment),R32C))>;
def v2i64mask: CodeFrag<(i32 (COPY_TO_REGCLASS (FSMv4i32 CGEv2i64compare.Fragment),R32C))>;
}
defm I64GE: CompareGreaterEqual64;
def : Pat<(setge R64C:$rA, R64C:$rB), I64GEr64.Fragment>;
def : Pat<(v2i64 (setge (v2i64 VECREG:$rA), (v2i64 VECREG:$rB))),
I64GEv2i64.Fragment>;
// i64 setult:
def : I64SETCCNegCond<setlt, I64GEr64>;
def : I64SELECTNegCond<setlt, I64GEr64>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v2i64, i64 add
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
class v2i64_add_cg<dag lhs, dag rhs>:
CodeFrag<(CGv4i32 lhs, rhs)>;
class v2i64_add_1<dag lhs, dag rhs, dag cg, dag cg_mask>:
CodeFrag<(ADDXv4i32 lhs, rhs, (SHUFBv4i32 cg, cg, cg_mask))>;
class v2i64_add<dag lhs, dag rhs, dag cg_mask>:
v2i64_add_1<lhs, rhs, v2i64_add_cg<lhs, rhs>.Fragment, cg_mask>;
def : Pat<(SPUadd64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)),
(COPY_TO_REGCLASS v2i64_add<(COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG),
(v4i32 VECREG:$rCGmask)>.Fragment, R64C)>;
def : Pat<(SPUadd64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB),
(v4i32 VECREG:$rCGmask)),
v2i64_add<(v2i64 VECREG:$rA),
(v2i64 VECREG:$rB),
(v4i32 VECREG:$rCGmask)>.Fragment>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v2i64, i64 subtraction
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
class v2i64_sub_bg<dag lhs, dag rhs>: CodeFrag<(BGv4i32 lhs, rhs)>;
class v2i64_sub<dag lhs, dag rhs, dag bg, dag bg_mask>:
CodeFrag<(SFXv4i32 lhs, rhs, (SHUFBv4i32 bg, bg, bg_mask))>;
def : Pat<(SPUsub64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)),
(COPY_TO_REGCLASS
v2i64_sub<(COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG),
v2i64_sub_bg<(COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG)>.Fragment,
(v4i32 VECREG:$rCGmask)>.Fragment, R64C)>;
def : Pat<(SPUsub64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB),
(v4i32 VECREG:$rCGmask)),
v2i64_sub<(v2i64 VECREG:$rA),
(v2i64 VECREG:$rB),
v2i64_sub_bg<(v2i64 VECREG:$rA),
(v2i64 VECREG:$rB)>.Fragment,
(v4i32 VECREG:$rCGmask)>.Fragment>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v2i64, i64 multiply
//
// Note: i64 multiply is simply the vector->scalar conversion of the
// full-on v2i64 multiply, since the entire vector has to be manipulated
// anyway.
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
class v2i64_mul_ahi64<dag rA> :
CodeFrag<(SELBv4i32 rA, (ILv4i32 0), (FSMBIv4i32 0x0f0f))>;
class v2i64_mul_bhi64<dag rB> :
CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0x0f0f))>;
class v2i64_mul_alo64<dag rB> :
CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0xf0f0))>;
class v2i64_mul_blo64<dag rB> :
CodeFrag<(SELBv4i32 rB, (ILv4i32 0), (FSMBIv4i32 0xf0f0))>;
class v2i64_mul_ashlq2<dag rA>:
CodeFrag<(SHLQBYIv4i32 rA, 0x2)>;
class v2i64_mul_ashlq4<dag rA>:
CodeFrag<(SHLQBYIv4i32 rA, 0x4)>;
class v2i64_mul_bshlq2<dag rB> :
CodeFrag<(SHLQBYIv4i32 rB, 0x2)>;
class v2i64_mul_bshlq4<dag rB> :
CodeFrag<(SHLQBYIv4i32 rB, 0x4)>;
class v2i64_highprod<dag rA, dag rB>:
CodeFrag<(Av4i32
(Av4i32
(MPYUv4i32 v2i64_mul_bshlq4<rB>.Fragment, // a1 x b3
v2i64_mul_ahi64<rA>.Fragment),
(MPYHv4i32 v2i64_mul_ahi64<rA>.Fragment, // a0 x b3
v2i64_mul_bshlq4<rB>.Fragment)),
(Av4i32
(MPYHv4i32 v2i64_mul_bhi64<rB>.Fragment,
v2i64_mul_ashlq4<rA>.Fragment),
(Av4i32
(MPYHv4i32 v2i64_mul_ashlq4<rA>.Fragment,
v2i64_mul_bhi64<rB>.Fragment),
(Av4i32
(MPYUv4i32 v2i64_mul_ashlq4<rA>.Fragment,
v2i64_mul_bhi64<rB>.Fragment),
(Av4i32
(MPYHv4i32 v2i64_mul_ashlq2<rA>.Fragment,
v2i64_mul_bshlq2<rB>.Fragment),
(MPYUv4i32 v2i64_mul_ashlq2<rA>.Fragment,
v2i64_mul_bshlq2<rB>.Fragment))))))>;
class v2i64_mul_a3_b3<dag rA, dag rB>:
CodeFrag<(MPYUv4i32 v2i64_mul_alo64<rA>.Fragment,
v2i64_mul_blo64<rB>.Fragment)>;
class v2i64_mul_a2_b3<dag rA, dag rB>:
CodeFrag<(SELBv4i32 (SHLQBYIv4i32
(MPYHHUv4i32 v2i64_mul_alo64<rA>.Fragment,
v2i64_mul_bshlq2<rB>.Fragment), 0x2),
(ILv4i32 0),
(FSMBIv4i32 0xc3c3))>;
class v2i64_mul_a3_b2<dag rA, dag rB>:
CodeFrag<(SELBv4i32 (SHLQBYIv4i32
(MPYHHUv4i32 v2i64_mul_blo64<rB>.Fragment,
v2i64_mul_ashlq2<rA>.Fragment), 0x2),
(ILv4i32 0),
(FSMBIv4i32 0xc3c3))>;
class v2i64_lowsum<dag rA, dag rB, dag rCGmask>:
v2i64_add<v2i64_add<v2i64_mul_a3_b3<rA, rB>.Fragment,
v2i64_mul_a2_b3<rA, rB>.Fragment, rCGmask>.Fragment,
v2i64_mul_a3_b2<rA, rB>.Fragment, rCGmask>;
class v2i64_mul<dag rA, dag rB, dag rCGmask>:
v2i64_add<v2i64_lowsum<rA, rB, rCGmask>.Fragment,
(SELBv4i32 v2i64_highprod<rA, rB>.Fragment,
(ILv4i32 0),
(FSMBIv4i32 0x0f0f)),
rCGmask>;
def : Pat<(SPUmul64 R64C:$rA, R64C:$rB, (v4i32 VECREG:$rCGmask)),
(COPY_TO_REGCLASS v2i64_mul<(COPY_TO_REGCLASS R64C:$rA, VECREG),
(COPY_TO_REGCLASS R64C:$rB, VECREG),
(v4i32 VECREG:$rCGmask)>.Fragment, R64C)>;
def : Pat<(SPUmul64 (v2i64 VECREG:$rA), (v2i64 VECREG:$rB),
(v4i32 VECREG:$rCGmask)),
v2i64_mul<(v2i64 VECREG:$rA), (v2i64 VECREG:$rB),
(v4i32 VECREG:$rCGmask)>.Fragment>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// f64 comparisons
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// selb instruction definition for i64. Note that the selection mask is
// a vector, produced by various forms of FSM:
def SELBf64_cond:
SELBInst<(outs R64FP:$rT), (ins R64FP:$rA, R64FP:$rB, R32C:$rC),
[(set R64FP:$rT,
(select R32C:$rC, R64FP:$rB, R64FP:$rA))]>;

View File

@ -1,333 +0,0 @@
//===-- SPUAsmPrinter.cpp - Print machine instrs to Cell SPU assembly -----===//
//
// 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 Cell SPU assembly language. This printer
// is the output mechanism used by `llc'.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "asmprinter"
#include "SPU.h"
#include "SPUTargetMachine.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
class SPUAsmPrinter : public AsmPrinter {
public:
explicit SPUAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) :
AsmPrinter(TM, Streamer) {}
virtual const char *getPassName() const {
return "STI CBEA SPU Assembly Printer";
}
/// printInstruction - This method is automatically generated by tablegen
/// from the instruction set description.
void printInstruction(const MachineInstr *MI, raw_ostream &OS);
static const char *getRegisterName(unsigned RegNo);
void EmitInstruction(const MachineInstr *MI) {
SmallString<128> Str;
raw_svector_ostream OS(Str);
printInstruction(MI, OS);
OutStreamer.EmitRawText(OS.str());
}
void printOp(const MachineOperand &MO, raw_ostream &OS);
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
O << getRegisterName(MO.getReg());
} else if (MO.isImm()) {
O << MO.getImm();
} else {
printOp(MO, O);
}
}
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
void
printU7ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
unsigned int value = MI->getOperand(OpNo).getImm();
assert(value < (1 << 8) && "Invalid u7 argument");
O << value;
}
void
printShufAddr(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
char value = MI->getOperand(OpNo).getImm();
O << (int) value;
O << "(";
printOperand(MI, OpNo+1, O);
O << ")";
}
void
printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
O << (short) MI->getOperand(OpNo).getImm();
}
void
printU16ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
O << (unsigned short)MI->getOperand(OpNo).getImm();
}
void
printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// When used as the base register, r0 reads constant zero rather than
// the value contained in the register. For this reason, the darwin
// assembler requires that we print r0 as 0 (no r) when used as the base.
const MachineOperand &MO = MI->getOperand(OpNo);
O << getRegisterName(MO.getReg()) << ", ";
printOperand(MI, OpNo+1, O);
}
void
printU18ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
unsigned int value = MI->getOperand(OpNo).getImm();
assert(value <= (1 << 19) - 1 && "Invalid u18 argument");
O << value;
}
void
printS10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
short value = MI->getOperand(OpNo).getImm();
assert((value >= -(1 << 9) && value <= (1 << 9) - 1)
&& "Invalid s10 argument");
O << value;
}
void
printU10ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
short value = MI->getOperand(OpNo).getImm();
assert((value <= (1 << 10) - 1) && "Invalid u10 argument");
O << value;
}
void
printDFormAddr(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
assert(MI->getOperand(OpNo).isImm() &&
"printDFormAddr first operand is not immediate");
int64_t value = int64_t(MI->getOperand(OpNo).getImm());
int16_t value16 = int16_t(value);
assert((value16 >= -(1 << (9+4)) && value16 <= (1 << (9+4)) - 1)
&& "Invalid dform s10 offset argument");
O << (value16 & ~0xf) << "(";
printOperand(MI, OpNo+1, O);
O << ")";
}
void
printAddr256K(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
{
/* Note: operand 1 is an offset or symbol name. */
if (MI->getOperand(OpNo).isImm()) {
printS16ImmOperand(MI, OpNo, O);
} else {
printOp(MI->getOperand(OpNo), O);
if (MI->getOperand(OpNo+1).isImm()) {
int displ = int(MI->getOperand(OpNo+1).getImm());
if (displ > 0)
O << "+" << displ;
else if (displ < 0)
O << displ;
}
}
}
void printCallOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
printOp(MI->getOperand(OpNo), O);
}
void printHBROperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
printOp(MI->getOperand(OpNo), O);
}
void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
// Used to generate a ".-<target>", but it turns out that the assembler
// really wants the target.
//
// N.B.: This operand is used for call targets. Branch hints are another
// animal entirely.
printOp(MI->getOperand(OpNo), O);
}
void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
printS16ImmOperand(MI, OpNo, O);
} else {
printOp(MI->getOperand(OpNo), O);
O << "@h";
}
}
void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
printS16ImmOperand(MI, OpNo, O);
} else {
printOp(MI->getOperand(OpNo), O);
O << "@l";
}
}
/// Print local store address
void printSymbolLSA(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) {
printOp(MI->getOperand(OpNo), O);
}
void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo,
raw_ostream &O) {
if (MI->getOperand(OpNo).isImm()) {
int value = (int) MI->getOperand(OpNo).getImm();
assert((value >= 0 && value < 16)
&& "Invalid negated immediate rotate 7-bit argument");
O << -value;
} else {
llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
}
}
void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O){
assert(MI->getOperand(OpNo).isImm() &&
"Invalid/non-immediate rotate amount in printRotateNeg7Imm");
int value = (int) MI->getOperand(OpNo).getImm();
assert((value >= 0 && value <= 32)
&& "Invalid negated immediate rotate 7-bit argument");
O << -value;
}
};
} // end of anonymous namespace
// Include the auto-generated portion of the assembly writer
#include "SPUGenAsmWriter.inc"
void SPUAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) {
switch (MO.getType()) {
case MachineOperand::MO_Immediate:
report_fatal_error("printOp() does not handle immediate values");
case MachineOperand::MO_MachineBasicBlock:
O << *MO.getMBB()->getSymbol();
return;
case MachineOperand::MO_JumpTableIndex:
O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
<< '_' << MO.getIndex();
return;
case MachineOperand::MO_ConstantPoolIndex:
O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
<< '_' << MO.getIndex();
return;
case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
if (TM.getRelocationModel() != Reloc::Static) {
O << "L" << MAI->getGlobalPrefix() << MO.getSymbolName()
<< "$non_lazy_ptr";
return;
}
O << *GetExternalSymbolSymbol(MO.getSymbolName());
return;
case MachineOperand::MO_GlobalAddress:
// External or weakly linked global variables need non-lazily-resolved
// stubs
if (TM.getRelocationModel() != Reloc::Static) {
const GlobalValue *GV = MO.getGlobal();
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
O << *GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
return;
}
}
O << *Mang->getSymbol(MO.getGlobal());
return;
case MachineOperand::MO_MCSymbol:
O << *(MO.getMCSymbol());
return;
default:
O << "<unknown operand type: " << MO.getType() << ">";
return;
}
}
/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool SPUAsmPrinter::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);
case 'L': // Write second word of DImode reference.
// Verify that this operand has two consecutive registers.
if (!MI->getOperand(OpNo).isReg() ||
OpNo+1 == MI->getNumOperands() ||
!MI->getOperand(OpNo+1).isReg())
return true;
++OpNo; // Return the high-part.
break;
}
}
printOperand(MI, OpNo, O);
return false;
}
bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNo, unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
if (ExtraCode && ExtraCode[0])
return true; // Unknown modifier.
printMemRegReg(MI, OpNo, O);
return false;
}
// Force static initialization.
extern "C" void LLVMInitializeCellSPUAsmPrinter() {
RegisterAsmPrinter<SPUAsmPrinter> X(TheCellSPUTarget);
}

View File

@ -1,53 +0,0 @@
//===- SPUCallingConv.td - Calling Conventions for CellSPU -*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This describes the calling conventions for the STI Cell SPU architecture.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Return Value Calling Convention
//===----------------------------------------------------------------------===//
// Return-value convention for Cell SPU: return value to be passed in reg 3-74
def RetCC_SPU : CallingConv<[
CCIfType<[i8,i16,i32,i64,i128,f32,f64,v16i8,v8i16,v4i32,v2i64,v4f32,v2f64],
CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11,
R12, R13, R14, R15, R16, R17, R18, R19, R20,
R21, R22, R23, R24, R25, R26, R27, R28, R29,
R30, R31, R32, R33, R34, R35, R36, R37, R38,
R39, R40, R41, R42, R43, R44, R45, R46, R47,
R48, R49, R50, R51, R52, R53, R54, R55, R56,
R57, R58, R59, R60, R61, R62, R63, R64, R65,
R66, R67, R68, R69, R70, R71, R72, R73, R74]>>
]>;
//===----------------------------------------------------------------------===//
// CellSPU Argument Calling Conventions
//===----------------------------------------------------------------------===//
def CCC_SPU : CallingConv<[
CCIfType<[i8, i16, i32, i64, i128, f32, f64,
v16i8, v8i16, v4i32, v4f32, v2i64, v2f64],
CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11,
R12, R13, R14, R15, R16, R17, R18, R19, R20,
R21, R22, R23, R24, R25, R26, R27, R28, R29,
R30, R31, R32, R33, R34, R35, R36, R37, R38,
R39, R40, R41, R42, R43, R44, R45, R46, R47,
R48, R49, R50, R51, R52, R53, R54, R55, R56,
R57, R58, R59, R60, R61, R62, R63, R64, R65,
R66, R67, R68, R69, R70, R71, R72, R73, R74]>>,
// Integer/FP values get stored in stack slots that are 8 bytes in size and
// 8-byte aligned if there are no more registers to hold them.
CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>,
// Vectors get 16-byte stack slots that are 16-byte aligned.
CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
CCAssignToStack<16, 16>>
]>;

View File

@ -1,256 +0,0 @@
//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Top-level implementation for the Cell SPU target.
//
//===----------------------------------------------------------------------===//
#include "SPUFrameLowering.h"
#include "SPU.h"
#include "SPUInstrBuilder.h"
#include "SPUInstrInfo.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/DataLayout.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// SPUFrameLowering:
//===----------------------------------------------------------------------===//
SPUFrameLowering::SPUFrameLowering(const SPUSubtarget &sti)
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 16, 0),
Subtarget(sti) {
LR[0].first = SPU::R0;
LR[0].second = 16;
}
//--------------------------------------------------------------------------
// hasFP - Return true if the specified function actually has a dedicated frame
// pointer register. This is true if the function needs a frame pointer and has
// a non-zero stack size.
bool SPUFrameLowering::hasFP(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
return MFI->getStackSize() &&
(MF.getTarget().Options.DisableFramePointerElim(MF) ||
MFI->hasVarSizedObjects());
}
/// determineFrameLayout - Determine the size of the frame and maximum call
/// frame size.
void SPUFrameLowering::determineFrameLayout(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
// Get the number of bytes to allocate from the FrameInfo
unsigned FrameSize = MFI->getStackSize();
// Get the alignments provided by the target, and the maximum alignment
// (if any) of the fixed frame objects.
unsigned TargetAlign = getStackAlignment();
unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment());
assert(isPowerOf2_32(Align) && "Alignment is not power of 2");
unsigned AlignMask = Align - 1;
// Get the maximum call frame size of all the calls.
unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
// If we have dynamic alloca then maxCallFrameSize needs to be aligned so
// that allocations will be aligned.
if (MFI->hasVarSizedObjects())
maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
// Update maximum call frame size.
MFI->setMaxCallFrameSize(maxCallFrameSize);
// Include call frame size in total.
FrameSize += maxCallFrameSize;
// Make sure the frame is aligned.
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
// Update frame info.
MFI->setStackSize(FrameSize);
}
void SPUFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
const SPUInstrInfo &TII =
*static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo());
MachineModuleInfo &MMI = MF.getMMI();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
// Prepare for debug frame info.
bool hasDebugInfo = MMI.hasDebugInfo();
MCSymbol *FrameLabel = 0;
// Move MBBI back to the beginning of the function.
MBBI = MBB.begin();
// Work out frame sizes.
determineFrameLayout(MF);
int FrameSize = MFI->getStackSize();
assert((FrameSize & 0xf) == 0
&& "SPURegisterInfo::emitPrologue: FrameSize not aligned");
// the "empty" frame size is 16 - just the register scavenger spill slot
if (FrameSize > 16 || MFI->adjustsStack()) {
FrameSize = -(FrameSize + SPUFrameLowering::minStackSize());
if (hasDebugInfo) {
// Mark effective beginning of when frame pointer becomes valid.
FrameLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(FrameLabel);
}
// Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp)
// for the ABI
BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R0).addImm(16)
.addReg(SPU::R1);
if (isInt<10>(FrameSize)) {
// Spill $sp to adjusted $sp
BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr32), SPU::R1).addImm(FrameSize)
.addReg(SPU::R1);
// Adjust $sp by required amout
BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1).addReg(SPU::R1)
.addImm(FrameSize);
} else if (isInt<16>(FrameSize)) {
// Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
// $r2 to adjust $sp:
BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2)
.addImm(-16)
.addReg(SPU::R1);
BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2)
.addImm(FrameSize);
BuildMI(MBB, MBBI, dl, TII.get(SPU::STQXr32), SPU::R1)
.addReg(SPU::R2)
.addReg(SPU::R1);
BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1)
.addReg(SPU::R1)
.addReg(SPU::R2);
BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2)
.addReg(SPU::R2)
.addImm(16);
BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2)
.addReg(SPU::R2)
.addReg(SPU::R1);
} else {
report_fatal_error("Unhandled frame size: " + Twine(FrameSize));
}
if (hasDebugInfo) {
std::vector<MachineMove> &Moves = MMI.getFrameMoves();
// Show update of SP.
MachineLocation SPDst(MachineLocation::VirtualFP);
MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize);
Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
// Add callee saved registers to move list.
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
unsigned Reg = CSI[I].getReg();
if (Reg == SPU::R0) continue;
MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
MachineLocation CSSrc(Reg);
Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc));
}
// Mark effective beginning of when frame pointer is ready.
MCSymbol *ReadyLabel = MMI.getContext().CreateTempSymbol();
BuildMI(MBB, MBBI, dl, TII.get(SPU::PROLOG_LABEL)).addSym(ReadyLabel);
MachineLocation FPDst(SPU::R1);
MachineLocation FPSrc(MachineLocation::VirtualFP);
Moves.push_back(MachineMove(ReadyLabel, FPDst, FPSrc));
}
}
}
void SPUFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const SPUInstrInfo &TII =
*static_cast<const SPUInstrInfo*>(MF.getTarget().getInstrInfo());
const MachineFrameInfo *MFI = MF.getFrameInfo();
int FrameSize = MFI->getStackSize();
int LinkSlotOffset = SPUFrameLowering::stackSlotSize();
DebugLoc dl = MBBI->getDebugLoc();
assert(MBBI->getOpcode() == SPU::RET &&
"Can only insert epilog into returning blocks");
assert((FrameSize & 0xf) == 0 && "FrameSize not aligned");
// the "empty" frame size is 16 - just the register scavenger spill slot
if (FrameSize > 16 || MFI->adjustsStack()) {
FrameSize = FrameSize + SPUFrameLowering::minStackSize();
if (isInt<10>(FrameSize + LinkSlotOffset)) {
// Reload $lr, adjust $sp by required amount
// Note: We do this to slightly improve dual issue -- not by much, but it
// is an opportunity for dual issue.
BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0)
.addImm(FrameSize + LinkSlotOffset)
.addReg(SPU::R1);
BuildMI(MBB, MBBI, dl, TII.get(SPU::AIr32), SPU::R1)
.addReg(SPU::R1)
.addImm(FrameSize);
} else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) {
// Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
// $r2 to adjust $sp:
BuildMI(MBB, MBBI, dl, TII.get(SPU::STQDr128), SPU::R2)
.addImm(16)
.addReg(SPU::R1);
BuildMI(MBB, MBBI, dl, TII.get(SPU::ILr32), SPU::R2)
.addImm(FrameSize);
BuildMI(MBB, MBBI, dl, TII.get(SPU::Ar32), SPU::R1)
.addReg(SPU::R1)
.addReg(SPU::R2);
BuildMI(MBB, MBBI, dl, TII.get(SPU::LQDr128), SPU::R0)
.addImm(16)
.addReg(SPU::R1);
BuildMI(MBB, MBBI, dl, TII.get(SPU::SFIr32), SPU::R2).
addReg(SPU::R2)
.addImm(16);
BuildMI(MBB, MBBI, dl, TII.get(SPU::LQXr128), SPU::R2)
.addReg(SPU::R2)
.addReg(SPU::R1);
} else {
report_fatal_error("Unhandled frame size: " + Twine(FrameSize));
}
}
}
void SPUFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const{
// Mark LR and SP unused, since the prolog spills them to stack and
// we don't want anyone else to spill them for us.
//
// Also, unless R2 is really used someday, don't spill it automatically.
MF.getRegInfo().setPhysRegUnused(SPU::R0);
MF.getRegInfo().setPhysRegUnused(SPU::R1);
MF.getRegInfo().setPhysRegUnused(SPU::R2);
MachineFrameInfo *MFI = MF.getFrameInfo();
const TargetRegisterClass *RC = &SPU::R32CRegClass;
RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
RC->getAlignment(),
false));
}

View File

@ -1,80 +0,0 @@
//===-- SPUFrameLowering.h - SPU Frame Lowering stuff ----------*- 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 CellSPU frame information that doesn't fit anywhere else
// cleanly...
//
//===----------------------------------------------------------------------===//
#ifndef SPU_FRAMEINFO_H
#define SPU_FRAMEINFO_H
#include "SPURegisterInfo.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class SPUSubtarget;
class SPUFrameLowering: public TargetFrameLowering {
const SPUSubtarget &Subtarget;
std::pair<unsigned, int> LR[1];
public:
SPUFrameLowering(const SPUSubtarget &sti);
//! Determine the frame's layour
void determineFrameLayout(MachineFunction &MF) const;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
//! Prediate: Target has dedicated frame pointer
bool hasFP(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS = NULL) const;
//! Return a function's saved spill slots
/*!
For CellSPU, a function's saved spill slots is just the link register.
*/
const std::pair<unsigned, int> *
getCalleeSaveSpillSlots(unsigned &NumEntries) const;
//! Stack slot size (16 bytes)
static int stackSlotSize() {
return 16;
}
//! Maximum frame offset representable by a signed 10-bit integer
/*!
This is the maximum frame offset that can be expressed as a 10-bit
integer, used in D-form addresses.
*/
static int maxFrameOffset() {
return ((1 << 9) - 1) * stackSlotSize();
}
//! Minimum frame offset representable by a signed 10-bit integer
static int minFrameOffset() {
return -(1 << 9) * stackSlotSize();
}
//! Minimum frame size (enough to spill LR + SP)
static int minStackSize() {
return (2 * stackSlotSize());
}
//! Convert frame index to stack offset
static int FItoStackOffset(int frame_index) {
return frame_index * stackSlotSize();
}
};
}
#endif

View File

@ -1,135 +0,0 @@
//===-- SPUHazardRecognizers.cpp - Cell Hazard Recognizer Impls -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements hazard recognizers for scheduling on Cell SPU
// processors.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "sched"
#include "SPUHazardRecognizers.h"
#include "SPU.h"
#include "SPUInstrInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Cell SPU hazard recognizer
//
// This is the pipeline hazard recognizer for the Cell SPU processor. It does
// very little right now.
//===----------------------------------------------------------------------===//
/// Return the pipeline hazard type encountered or generated by this
/// instruction. Currently returns NoHazard.
///
/// \return NoHazard
ScheduleHazardRecognizer::HazardType
SPUHazardRecognizer::getHazardType(SUnit *SU, int Stalls)
{
// Initial thoughts on how to do this, but this code cannot work unless the
// function's prolog and epilog code are also being scheduled so that we can
// accurately determine which pipeline is being scheduled.
#if 0
assert(Stalls == 0 && "SPU hazards don't yet support scoreboard lookahead");
const SDNode *Node = SU->getNode()->getFlaggedMachineNode();
ScheduleHazardRecognizer::HazardType retval = NoHazard;
bool mustBeOdd = false;
switch (Node->getOpcode()) {
case SPU::LQDv16i8:
case SPU::LQDv8i16:
case SPU::LQDv4i32:
case SPU::LQDv4f32:
case SPU::LQDv2f64:
case SPU::LQDr128:
case SPU::LQDr64:
case SPU::LQDr32:
case SPU::LQDr16:
case SPU::LQAv16i8:
case SPU::LQAv8i16:
case SPU::LQAv4i32:
case SPU::LQAv4f32:
case SPU::LQAv2f64:
case SPU::LQAr128:
case SPU::LQAr64:
case SPU::LQAr32:
case SPU::LQXv4i32:
case SPU::LQXr128:
case SPU::LQXr64:
case SPU::LQXr32:
case SPU::LQXr16:
case SPU::STQDv16i8:
case SPU::STQDv8i16:
case SPU::STQDv4i32:
case SPU::STQDv4f32:
case SPU::STQDv2f64:
case SPU::STQDr128:
case SPU::STQDr64:
case SPU::STQDr32:
case SPU::STQDr16:
case SPU::STQDr8:
case SPU::STQAv16i8:
case SPU::STQAv8i16:
case SPU::STQAv4i32:
case SPU::STQAv4f32:
case SPU::STQAv2f64:
case SPU::STQAr128:
case SPU::STQAr64:
case SPU::STQAr32:
case SPU::STQAr16:
case SPU::STQAr8:
case SPU::STQXv16i8:
case SPU::STQXv8i16:
case SPU::STQXv4i32:
case SPU::STQXv4f32:
case SPU::STQXv2f64:
case SPU::STQXr128:
case SPU::STQXr64:
case SPU::STQXr32:
case SPU::STQXr16:
case SPU::STQXr8:
case SPU::RET:
mustBeOdd = true;
break;
default:
// Assume that this instruction can be on the even pipe
break;
}
if (mustBeOdd && !EvenOdd)
retval = Hazard;
DEBUG(errs() << "SPUHazardRecognizer EvenOdd " << EvenOdd << " Hazard "
<< retval << "\n");
EvenOdd ^= 1;
return retval;
#else
return NoHazard;
#endif
}
void SPUHazardRecognizer::EmitInstruction(SUnit *SU)
{
}
void SPUHazardRecognizer::AdvanceCycle()
{
DEBUG(errs() << "SPUHazardRecognizer::AdvanceCycle\n");
}
void SPUHazardRecognizer::EmitNoop()
{
AdvanceCycle();
}

View File

@ -1,37 +0,0 @@
//===-- SPUHazardRecognizers.h - Cell SPU Hazard Recognizer -----*- 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 hazard recognizers for scheduling on the Cell SPU
// processor.
//
//===----------------------------------------------------------------------===//
#ifndef SPUHAZRECS_H
#define SPUHAZRECS_H
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
namespace llvm {
class TargetInstrInfo;
/// SPUHazardRecognizer
class SPUHazardRecognizer : public ScheduleHazardRecognizer
{
public:
SPUHazardRecognizer(const TargetInstrInfo &/*TII*/) {}
virtual HazardType getHazardType(SUnit *SU, int Stalls);
virtual void EmitInstruction(SUnit *SU);
virtual void AdvanceCycle();
virtual void EmitNoop();
};
} // end namespace llvm
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,178 +0,0 @@
//===-- SPUISelLowering.h - Cell SPU 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 Cell SPU uses to lower LLVM code into
// a selection DAG.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_ISELLOWERING_H
#define SPU_ISELLOWERING_H
#include "SPU.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/CodeGen/SelectionDAG.h"
namespace llvm {
namespace SPUISD {
enum NodeType {
// Start the numbering where the builting ops and target ops leave off.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
// Pseudo instructions:
RET_FLAG, ///< Return with flag, matched by bi instruction
Hi, ///< High address component (upper 16)
Lo, ///< Low address component (lower 16)
PCRelAddr, ///< Program counter relative address
AFormAddr, ///< A-form address (local store)
IndirectAddr, ///< D-Form "imm($r)" and X-form "$r($r)"
LDRESULT, ///< Load result (value, chain)
CALL, ///< CALL instruction
SHUFB, ///< Vector shuffle (permute)
SHUFFLE_MASK, ///< Shuffle mask
CNTB, ///< Count leading ones in bytes
PREFSLOT2VEC, ///< Promote scalar->vector
VEC2PREFSLOT, ///< Extract element 0
SHL_BITS, ///< Shift quad left, by bits
SHL_BYTES, ///< Shift quad left, by bytes
SRL_BYTES, ///< Shift quad right, by bytes. Insert zeros.
VEC_ROTL, ///< Vector rotate left
VEC_ROTR, ///< Vector rotate right
ROTBYTES_LEFT, ///< Rotate bytes (loads -> ROTQBYI)
ROTBYTES_LEFT_BITS, ///< Rotate bytes left by bit shift count
SELECT_MASK, ///< Select Mask (FSM, FSMB, FSMH, FSMBI)
SELB, ///< Select bits -> (b & mask) | (a & ~mask)
// Markers: These aren't used to generate target-dependent nodes, but
// are used during instruction selection.
ADD64_MARKER, ///< i64 addition marker
SUB64_MARKER, ///< i64 subtraction marker
MUL64_MARKER, ///< i64 multiply marker
LAST_SPUISD ///< Last user-defined instruction
};
}
//! Utility functions specific to CellSPU:
namespace SPU {
SDValue get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
EVT ValueType);
SDValue get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
EVT ValueType);
SDValue get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
EVT ValueType);
SDValue get_vec_i8imm(SDNode *N, SelectionDAG &DAG,
EVT ValueType);
SDValue get_ILHUvec_imm(SDNode *N, SelectionDAG &DAG,
EVT ValueType);
SDValue get_v4i32_imm(SDNode *N, SelectionDAG &DAG);
SDValue get_v2i64_imm(SDNode *N, SelectionDAG &DAG);
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG,
const SPUTargetMachine &TM);
//! Simplify a EVT::v2i64 constant splat to CellSPU-ready form
SDValue LowerV2I64Splat(EVT OpVT, SelectionDAG &DAG, uint64_t splat,
DebugLoc dl);
}
class SPUTargetMachine; // forward dec'l.
class SPUTargetLowering :
public TargetLowering
{
SPUTargetMachine &SPUTM;
public:
//! The venerable constructor
/*!
This is where the CellSPU backend sets operation handling (i.e., legal,
custom, expand or promote.)
*/
SPUTargetLowering(SPUTargetMachine &TM);
//! Get the target machine
SPUTargetMachine &getSPUTargetMachine() {
return SPUTM;
}
/// getTargetNodeName() - This method returns the name of a target specific
/// DAG node.
virtual const char *getTargetNodeName(unsigned Opcode) const;
/// getSetCCResultType - Return the ValueType for ISD::SETCC
virtual EVT getSetCCResultType(EVT VT) const;
virtual MVT getShiftAmountTy(EVT LHSTy) const { return MVT::i32; }
//! Custom lowering hooks
virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
//! Custom lowering hook for nodes with illegal result types.
virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
SelectionDAG &DAG) const;
virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
virtual void computeMaskedBitsForTargetNode(const SDValue Op,
APInt &KnownZero,
APInt &KnownOne,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
unsigned Depth = 0) const;
ConstraintType getConstraintType(const std::string &ConstraintLetter) const;
/// Examine constraint string and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
ConstraintWeight getSingleConstraintMatchWeight(
AsmOperandInfo &info, const char *constraint) const;
std::pair<unsigned, const TargetRegisterClass*>
getRegForInlineAsmConstraint(const std::string &Constraint,
EVT VT) const;
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const;
/// isLegalAddressImmediate - Return true if the integer value can be used
/// as the offset of the target addressing mode.
virtual bool isLegalAddressImmediate(int64_t V, Type *Ty) const;
virtual bool isLegalAddressImmediate(GlobalValue *) const;
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
virtual SDValue
LowerFormalArguments(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
DebugLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
virtual SDValue
LowerCall(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,
DebugLoc dl, SelectionDAG &DAG) const;
virtual bool isLegalICmpImmediate(int64_t Imm) const;
virtual bool isLegalAddressingMode(const AddrMode &AM,
Type *Ty) const;
};
}
#endif

View File

@ -1,43 +0,0 @@
//===-- SPUInstrBuilder.h - Aides for building Cell SPU insts ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file exposes functions that may be used with BuildMI from the
// MachineInstrBuilder.h file to simplify generating frame and constant pool
// references.
//
// For reference, the order of operands for memory references is:
// (Operand), Dest Reg, Base Reg, and either Reg Index or Immediate
// Displacement.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_INSTRBUILDER_H
#define SPU_INSTRBUILDER_H
#include "llvm/CodeGen/MachineInstrBuilder.h"
namespace llvm {
/// addFrameReference - This function is used to add a reference to the base of
/// an abstract object on the stack frame of the current function. This
/// reference has base register as the FrameIndex offset until it is resolved.
/// This allows a constant offset to be specified as well...
///
inline const MachineInstrBuilder&
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0,
bool mem = true) {
if (mem)
return MIB.addImm(Offset).addFrameIndex(FI);
else
return MIB.addFrameIndex(FI).addImm(Offset);
}
} // End llvm namespace
#endif

View File

@ -1,320 +0,0 @@
//===-- SPUInstrFormats.td - Cell SPU Instruction Formats --*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//
// Cell SPU instruction formats. Note that these are notationally similar to
// PowerPC, like "A-Form". But the sizes of operands and fields differ.
// This was kiped from the PPC instruction formats (seemed like a good idea...)
class SPUInstr<dag OOL, dag IOL, string asmstr, InstrItinClass itin>
: Instruction {
field bits<32> Inst;
let Namespace = "SPU";
let OutOperandList = OOL;
let InOperandList = IOL;
let AsmString = asmstr;
let Itinerary = itin;
}
// RR Format
class RRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin> {
bits<7> RA;
bits<7> RB;
bits<7> RT;
let Pattern = pattern;
let Inst{0-10} = opcode;
let Inst{11-17} = RB;
let Inst{18-24} = RA;
let Inst{25-31} = RT;
}
let RB = 0 in {
// RR Format, where RB is zeroed (dont care):
class RRForm_1<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RRForm<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
let RA = 0 in {
// RR Format, where RA and RB are zeroed (dont care):
// Used for reads from status control registers (see FPSCRRr32)
class RRForm_2<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RRForm<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
}
}
let RT = 0 in {
// RR Format, where RT is zeroed (don't care), or as the instruction handbook
// says, "RT is a false target." Used in "Halt if" instructions
class RRForm_3<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RRForm<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
}
// RRR Format
class RRRForm<bits<4> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<7> RA;
bits<7> RB;
bits<7> RC;
bits<7> RT;
let Pattern = pattern;
let Inst{0-3} = opcode;
let Inst{4-10} = RT;
let Inst{11-17} = RB;
let Inst{18-24} = RA;
let Inst{25-31} = RC;
}
// RI7 Format
class RI7Form<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<7> i7;
bits<7> RA;
bits<7> RT;
let Pattern = pattern;
let Inst{0-10} = opcode;
let Inst{11-17} = i7;
let Inst{18-24} = RA;
let Inst{25-31} = RT;
}
// CVTIntFp Format
class CVTIntFPForm<bits<10> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<7> RA;
bits<7> RT;
let Pattern = pattern;
let Inst{0-9} = opcode;
let Inst{10-17} = 0;
let Inst{18-24} = RA;
let Inst{25-31} = RT;
}
let RA = 0 in {
class BICondForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, list<dag> pattern>
: RRForm<opcode, OOL, IOL, asmstr, BranchResolv, pattern>
{ }
let RT = 0 in {
// Branch instruction format (without D/E flag settings)
class BRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RRForm<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
class BIForm<bits<11> opcode, string asmstr, list<dag> pattern>
: RRForm<opcode, (outs), (ins R32C:$func), asmstr, BranchResolv,
pattern>
{ }
let RB = 0 in {
// Return instruction (bi, branch indirect), RA is zero (LR):
class RETForm<string asmstr, list<dag> pattern>
: BRForm<0b00010101100, (outs), (ins), asmstr, BranchResolv,
pattern>
{ }
}
}
}
// Branch indirect external data forms:
class BISLEDForm<bits<2> DE_flag, string asmstr, list<dag> pattern>
: SPUInstr<(outs), (ins indcalltarget:$func), asmstr, BranchResolv>
{
bits<7> Rcalldest;
let Pattern = pattern;
let Inst{0-10} = 0b11010101100;
let Inst{11} = 0;
let Inst{12-13} = DE_flag;
let Inst{14-17} = 0b0000;
let Inst{18-24} = Rcalldest;
let Inst{25-31} = 0b0000000;
}
// RI10 Format
class RI10Form<bits<8> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<10> i10;
bits<7> RA;
bits<7> RT;
let Pattern = pattern;
let Inst{0-7} = opcode;
let Inst{8-17} = i10;
let Inst{18-24} = RA;
let Inst{25-31} = RT;
}
// RI10 Format, where the constant is zero (or effectively ignored by the
// SPU)
let i10 = 0 in {
class RI10Form_1<bits<8> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RI10Form<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
}
// RI10 Format, where RT is ignored.
// This format is used primarily by the Halt If ... Immediate set of
// instructions
let RT = 0 in {
class RI10Form_2<bits<8> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: RI10Form<opcode, OOL, IOL, asmstr, itin, pattern>
{ }
}
// RI16 Format
class RI16Form<bits<9> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<16> i16;
bits<7> RT;
let Pattern = pattern;
let Inst{0-8} = opcode;
let Inst{9-24} = i16;
let Inst{25-31} = RT;
}
// Specialized version of the RI16 Format for unconditional branch relative and
// branch absolute, branch and set link. Note that for branch and set link, the
// link register doesn't have to be $lr, but this is actually hard coded into
// the instruction pattern.
let RT = 0 in {
class UncondBranch<bits<9> opcode, dag OOL, dag IOL, string asmstr,
list<dag> pattern>
: RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern>
{ }
class BranchSetLink<bits<9> opcode, dag OOL, dag IOL, string asmstr,
list<dag> pattern>
: RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern>
{ }
}
//===----------------------------------------------------------------------===//
// Specialized versions of RI16:
//===----------------------------------------------------------------------===//
// RI18 Format
class RI18Form<bits<7> opcode, dag OOL, dag IOL, string asmstr,
InstrItinClass itin, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, itin>
{
bits<18> i18;
bits<7> RT;
let Pattern = pattern;
let Inst{0-6} = opcode;
let Inst{7-24} = i18;
let Inst{25-31} = RT;
}
//===----------------------------------------------------------------------===//
// Instruction formats for intrinsics:
//===----------------------------------------------------------------------===//
// RI10 Format for v8i16 intrinsics
class RI10_Int_v8i16<bits<8> opcode, string opc, InstrItinClass itin,
Intrinsic IntID> :
RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA),
!strconcat(opc, " $rT, $rA, $val"), itin,
[(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA),
i16ImmSExt10:$val))] >;
class RI10_Int_v4i32<bits<8> opcode, string opc, InstrItinClass itin,
Intrinsic IntID> :
RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA),
!strconcat(opc, " $rT, $rA, $val"), itin,
[(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA),
i32ImmSExt10:$val))] >;
// RR Format for v8i16 intrinsics
class RR_Int_v8i16<bits<11> opcode, string opc, InstrItinClass itin,
Intrinsic IntID> :
RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
!strconcat(opc, " $rT, $rA, $rB"), itin,
[(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA),
(v8i16 VECREG:$rB)))] >;
// RR Format for v4i32 intrinsics
class RR_Int_v4i32<bits<11> opcode, string opc, InstrItinClass itin,
Intrinsic IntID> :
RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
!strconcat(opc, " $rT, $rA, $rB"), itin,
[(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA),
(v4i32 VECREG:$rB)))] >;
//===----------------------------------------------------------------------===//
// Pseudo instructions, like call frames:
//===----------------------------------------------------------------------===//
class Pseudo<dag OOL, dag IOL, string asmstr, list<dag> pattern>
: SPUInstr<OOL, IOL, asmstr, NoItinerary> {
let OutOperandList = OOL;
let InOperandList = IOL;
let AsmString = asmstr;
let Pattern = pattern;
let Inst{31-0} = 0;
}
//===----------------------------------------------------------------------===//
// Branch hint formats
//===----------------------------------------------------------------------===//
// For hbrr and hbra
class HBI16Form<bits<7> opcode, dag IOL, string asmstr>
: Instruction {
field bits<32> Inst;
bits<16>i16;
bits<9>RO;
let Namespace = "SPU";
let InOperandList = IOL;
let OutOperandList = (outs); //no output
let AsmString = asmstr;
let Itinerary = BranchHints;
let Inst{0-6} = opcode;
let Inst{7-8} = RO{8-7};
let Inst{9-24} = i16;
let Inst{25-31} = RO{6-0};
}

View File

@ -1,449 +0,0 @@
//===-- SPUInstrInfo.cpp - Cell SPU 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 Cell SPU implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#include "SPUInstrInfo.h"
#include "SPUInstrBuilder.h"
#include "SPUTargetMachine.h"
#include "SPUHazardRecognizers.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#define GET_INSTRINFO_CTOR
#include "SPUGenInstrInfo.inc"
using namespace llvm;
namespace {
//! Predicate for an unconditional branch instruction
inline bool isUncondBranch(const MachineInstr *I) {
unsigned opc = I->getOpcode();
return (opc == SPU::BR
|| opc == SPU::BRA
|| opc == SPU::BI);
}
//! Predicate for a conditional branch instruction
inline bool isCondBranch(const MachineInstr *I) {
unsigned opc = I->getOpcode();
return (opc == SPU::BRNZr32
|| opc == SPU::BRNZv4i32
|| opc == SPU::BRZr32
|| opc == SPU::BRZv4i32
|| opc == SPU::BRHNZr16
|| opc == SPU::BRHNZv8i16
|| opc == SPU::BRHZr16
|| opc == SPU::BRHZv8i16);
}
}
SPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm)
: SPUGenInstrInfo(SPU::ADJCALLSTACKDOWN, SPU::ADJCALLSTACKUP),
TM(tm),
RI(*TM.getSubtargetImpl(), *this)
{ /* NOP */ }
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
/// this target when scheduling the DAG.
ScheduleHazardRecognizer *SPUInstrInfo::CreateTargetHazardRecognizer(
const TargetMachine *TM,
const ScheduleDAG *DAG) const {
const TargetInstrInfo *TII = TM->getInstrInfo();
assert(TII && "No InstrInfo?");
return new SPUHazardRecognizer(*TII);
}
unsigned
SPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
switch (MI->getOpcode()) {
default: break;
case SPU::LQDv16i8:
case SPU::LQDv8i16:
case SPU::LQDv4i32:
case SPU::LQDv4f32:
case SPU::LQDv2f64:
case SPU::LQDr128:
case SPU::LQDr64:
case SPU::LQDr32:
case SPU::LQDr16: {
const MachineOperand MOp1 = MI->getOperand(1);
const MachineOperand MOp2 = MI->getOperand(2);
if (MOp1.isImm() && MOp2.isFI()) {
FrameIndex = MOp2.getIndex();
return MI->getOperand(0).getReg();
}
break;
}
}
return 0;
}
unsigned
SPUInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
switch (MI->getOpcode()) {
default: break;
case SPU::STQDv16i8:
case SPU::STQDv8i16:
case SPU::STQDv4i32:
case SPU::STQDv4f32:
case SPU::STQDv2f64:
case SPU::STQDr128:
case SPU::STQDr64:
case SPU::STQDr32:
case SPU::STQDr16:
case SPU::STQDr8: {
const MachineOperand MOp1 = MI->getOperand(1);
const MachineOperand MOp2 = MI->getOperand(2);
if (MOp1.isImm() && MOp2.isFI()) {
FrameIndex = MOp2.getIndex();
return MI->getOperand(0).getReg();
}
break;
}
}
return 0;
}
void SPUInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const
{
// We support cross register class moves for our aliases, such as R3 in any
// reg class to any other reg class containing R3. This is required because
// we instruction select bitconvert i64 -> f64 as a noop for example, so our
// types have no specific meaning.
BuildMI(MBB, I, DL, get(SPU::LRr128), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
}
void
SPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned SrcReg, bool isKill, int FrameIdx,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
unsigned opc;
bool isValidFrameIdx = (FrameIdx < SPUFrameLowering::maxFrameOffset());
if (RC == &SPU::GPRCRegClass)
opc = isValidFrameIdx ? SPU::STQDr128 : SPU::STQXr128;
else if (RC == &SPU::R64CRegClass)
opc = isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64;
else if (RC == &SPU::R64FPRegClass)
opc = isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64;
else if (RC == &SPU::R32CRegClass)
opc = isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32;
else if (RC == &SPU::R32FPRegClass)
opc = isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32;
else if (RC == &SPU::R16CRegClass)
opc = isValidFrameIdx ? SPU::STQDr16 : SPU::STQXr16;
else if (RC == &SPU::R8CRegClass)
opc = isValidFrameIdx ? SPU::STQDr8 : SPU::STQXr8;
else if (RC == &SPU::VECREGRegClass)
opc = isValidFrameIdx ? SPU::STQDv16i8 : SPU::STQXv16i8;
else
llvm_unreachable("Unknown regclass!");
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
addFrameReference(BuildMI(MBB, MI, DL, get(opc))
.addReg(SrcReg, getKillRegState(isKill)), FrameIdx);
}
void
SPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
unsigned DestReg, int FrameIdx,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
unsigned opc;
bool isValidFrameIdx = (FrameIdx < SPUFrameLowering::maxFrameOffset());
if (RC == &SPU::GPRCRegClass)
opc = isValidFrameIdx ? SPU::LQDr128 : SPU::LQXr128;
else if (RC == &SPU::R64CRegClass)
opc = isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64;
else if (RC == &SPU::R64FPRegClass)
opc = isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64;
else if (RC == &SPU::R32CRegClass)
opc = isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32;
else if (RC == &SPU::R32FPRegClass)
opc = isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32;
else if (RC == &SPU::R16CRegClass)
opc = isValidFrameIdx ? SPU::LQDr16 : SPU::LQXr16;
else if (RC == &SPU::R8CRegClass)
opc = isValidFrameIdx ? SPU::LQDr8 : SPU::LQXr8;
else if (RC == &SPU::VECREGRegClass)
opc = isValidFrameIdx ? SPU::LQDv16i8 : SPU::LQXv16i8;
else
llvm_unreachable("Unknown regclass in loadRegFromStackSlot!");
DebugLoc DL;
if (MI != MBB.end()) DL = MI->getDebugLoc();
addFrameReference(BuildMI(MBB, MI, DL, get(opc), DestReg), FrameIdx);
}
//! Branch analysis
/*!
\note This code was kiped from PPC. There may be more branch analysis for
CellSPU than what's currently done here.
*/
bool
SPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const {
// If the block has no terminators, it just falls into the block after it.
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin())
return false;
--I;
while (I->isDebugValue()) {
if (I == MBB.begin())
return false;
--I;
}
if (!isUnpredicatedTerminator(I))
return false;
// Get the last instruction in the block.
MachineInstr *LastInst = I;
// If there is only one terminator instruction, process it.
if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
if (isUncondBranch(LastInst)) {
// Check for jump tables
if (!LastInst->getOperand(0).isMBB())
return true;
TBB = LastInst->getOperand(0).getMBB();
return false;
} else if (isCondBranch(LastInst)) {
// Block ends with fall-through condbranch.
TBB = LastInst->getOperand(1).getMBB();
DEBUG(errs() << "Pushing LastInst: ");
DEBUG(LastInst->dump());
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 a conditional and unconditional branch, handle it.
if (isCondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
TBB = SecondLastInst->getOperand(1).getMBB();
DEBUG(errs() << "Pushing SecondLastInst: ");
DEBUG(SecondLastInst->dump());
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 (isUncondBranch(SecondLastInst) && isUncondBranch(LastInst)) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
I->eraseFromParent();
return false;
}
// Otherwise, can't handle this.
return true;
}
// search MBB for branch hint labels and branch hit ops
static void removeHBR( MachineBasicBlock &MBB) {
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I){
if (I->getOpcode() == SPU::HBRA ||
I->getOpcode() == SPU::HBR_LABEL){
I=MBB.erase(I);
if (I == MBB.end())
break;
}
}
}
unsigned
SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator I = MBB.end();
removeHBR(MBB);
if (I == MBB.begin())
return 0;
--I;
while (I->isDebugValue()) {
if (I == MBB.begin())
return 0;
--I;
}
if (!isCondBranch(I) && !isUncondBranch(I))
return 0;
// Remove the first branch.
DEBUG(errs() << "Removing branch: ");
DEBUG(I->dump());
I->eraseFromParent();
I = MBB.end();
if (I == MBB.begin())
return 1;
--I;
if (!(isCondBranch(I) || isUncondBranch(I)))
return 1;
// Remove the second branch.
DEBUG(errs() << "Removing second branch: ");
DEBUG(I->dump());
I->eraseFromParent();
return 2;
}
/** Find the optimal position for a hint branch instruction in a basic block.
* This should take into account:
* -the branch hint delays
* -congestion of the memory bus
* -dual-issue scheduling (i.e. avoid insertion of nops)
* Current implementation is rather simplistic.
*/
static MachineBasicBlock::iterator findHBRPosition(MachineBasicBlock &MBB)
{
MachineBasicBlock::iterator J = MBB.end();
for( int i=0; i<8; i++) {
if( J == MBB.begin() ) return J;
J--;
}
return J;
}
unsigned
SPUInstrInfo::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) &&
"SPU branch conditions have two components!");
MachineInstrBuilder MIB;
//TODO: make a more accurate algorithm.
bool haveHBR = MBB.size()>8;
removeHBR(MBB);
MCSymbol *branchLabel = MBB.getParent()->getContext().CreateTempSymbol();
// Add a label just before the branch
if (haveHBR)
MIB = BuildMI(&MBB, DL, get(SPU::HBR_LABEL)).addSym(branchLabel);
// One-way branch.
if (FBB == 0) {
if (Cond.empty()) {
// Unconditional branch
MIB = BuildMI(&MBB, DL, get(SPU::BR));
MIB.addMBB(TBB);
DEBUG(errs() << "Inserted one-way uncond branch: ");
DEBUG((*MIB).dump());
// basic blocks have just one branch so it is safe to add the hint a its
if (haveHBR) {
MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
MIB.addSym(branchLabel);
MIB.addMBB(TBB);
}
} else {
// Conditional branch
MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
MIB.addReg(Cond[1].getReg()).addMBB(TBB);
if (haveHBR) {
MIB = BuildMI(MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
MIB.addSym(branchLabel);
MIB.addMBB(TBB);
}
DEBUG(errs() << "Inserted one-way cond branch: ");
DEBUG((*MIB).dump());
}
return 1;
} else {
MIB = BuildMI(&MBB, DL, get(Cond[0].getImm()));
MachineInstrBuilder MIB2 = BuildMI(&MBB, DL, get(SPU::BR));
// Two-way Conditional Branch.
MIB.addReg(Cond[1].getReg()).addMBB(TBB);
MIB2.addMBB(FBB);
if (haveHBR) {
MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA));
MIB.addSym(branchLabel);
MIB.addMBB(FBB);
}
DEBUG(errs() << "Inserted conditional branch: ");
DEBUG((*MIB).dump());
DEBUG(errs() << "part 2: ");
DEBUG((*MIB2).dump());
return 2;
}
}
//! Reverses a branch's condition, returning false on success.
bool
SPUInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond)
const {
// Pretty brainless way of inverting the condition, but it works, considering
// there are only two conditions...
static struct {
unsigned Opc; //! The incoming opcode
unsigned RevCondOpc; //! The reversed condition opcode
} revconds[] = {
{ SPU::BRNZr32, SPU::BRZr32 },
{ SPU::BRNZv4i32, SPU::BRZv4i32 },
{ SPU::BRZr32, SPU::BRNZr32 },
{ SPU::BRZv4i32, SPU::BRNZv4i32 },
{ SPU::BRHNZr16, SPU::BRHZr16 },
{ SPU::BRHNZv8i16, SPU::BRHZv8i16 },
{ SPU::BRHZr16, SPU::BRHNZr16 },
{ SPU::BRHZv8i16, SPU::BRHNZv8i16 }
};
unsigned Opc = unsigned(Cond[0].getImm());
// Pretty dull mapping between the two conditions that SPU can generate:
for (int i = sizeof(revconds)/sizeof(revconds[0]) - 1; i >= 0; --i) {
if (revconds[i].Opc == Opc) {
Cond[0].setImm(revconds[i].RevCondOpc);
return false;
}
}
return true;
}

View File

@ -1,84 +0,0 @@
//===-- SPUInstrInfo.h - Cell SPU 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 CellSPU implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_INSTRUCTIONINFO_H
#define SPU_INSTRUCTIONINFO_H
#include "SPU.h"
#include "SPURegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "SPUGenInstrInfo.inc"
namespace llvm {
//! Cell SPU instruction information class
class SPUInstrInfo : public SPUGenInstrInfo {
SPUTargetMachine &TM;
const SPURegisterInfo RI;
public:
explicit SPUInstrInfo(SPUTargetMachine &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 SPURegisterInfo &getRegisterInfo() const { return RI; }
ScheduleHazardRecognizer *
CreateTargetHazardRecognizer(const TargetMachine *TM,
const ScheduleDAG *DAG) const;
unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
unsigned isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const;
//! Store a register to a stack slot, based on its register class.
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
//! Load a register from a stack slot, based on its register class.
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
unsigned DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const;
//! Reverses a branch's condition, returning false on success.
virtual
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const;
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const;
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const;
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,50 +0,0 @@
//===-- SPUMachineFunctionInfo.h - Private data used for CellSPU --*- 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 IBM Cell SPU specific subclass of MachineFunctionInfo.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_MACHINE_FUNCTION_INFO_H
#define SPU_MACHINE_FUNCTION_INFO_H
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
/// SPUFunctionInfo - Cell SPU target-specific information for each
/// MachineFunction
class SPUFunctionInfo : public MachineFunctionInfo {
virtual void anchor();
/// UsesLR - Indicates whether LR is used in the current function.
///
bool UsesLR;
// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex;
public:
SPUFunctionInfo(MachineFunction& MF)
: UsesLR(false),
VarArgsFrameIndex(0)
{}
void setUsesLR(bool U) { UsesLR = U; }
bool usesLR() { return UsesLR; }
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
};
} // end of namespace llvm
#endif

View File

@ -1,97 +0,0 @@
//===-- SPUMathInst.td - Cell SPU math operations ---------*- tablegen -*--===//
//
// Cell SPU math operations
//
// This target description file contains instruction sequences for various
// math operations, such as vector multiplies, i32 multiply, etc., for the
// SPU's i32, i16 i8 and corresponding vector types.
//
// Any resemblance to libsimdmath or the Cell SDK simdmath library is
// purely and completely coincidental.
//===----------------------------------------------------------------------===//
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v16i8 multiply instruction sequence:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def : Pat<(mul (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)),
(ORv4i32
(ANDv4i32
(SELBv4i32 (MPYv8i16 VECREG:$rA, VECREG:$rB),
(SHLHIv8i16 (MPYv8i16 (ROTMAHIv8i16 VECREG:$rA, 8),
(ROTMAHIv8i16 VECREG:$rB, 8)), 8),
(FSMBIv8i16 0x2222)),
(ILAv4i32 0x0000ffff)),
(SHLIv4i32
(SELBv4i32 (MPYv8i16 (ROTMAIv4i32_i32 VECREG:$rA, 16),
(ROTMAIv4i32_i32 VECREG:$rB, 16)),
(SHLHIv8i16 (MPYv8i16 (ROTMAIv4i32_i32 VECREG:$rA, 8),
(ROTMAIv4i32_i32 VECREG:$rB, 8)), 8),
(FSMBIv8i16 0x2222)), 16))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v8i16 multiply instruction sequence:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def : Pat<(mul (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)),
(SELBv8i16 (MPYv8i16 VECREG:$rA, VECREG:$rB),
(SHLIv4i32 (MPYHHv8i16 VECREG:$rA, VECREG:$rB), 16),
(FSMBIv8i16 0xcccc))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// v4i32, i32 multiply instruction sequence:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def MPYv4i32:
Pat<(mul (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)),
(Av4i32
(v4i32 (Av4i32 (v4i32 (MPYHv4i32 VECREG:$rA, VECREG:$rB)),
(v4i32 (MPYHv4i32 VECREG:$rB, VECREG:$rA)))),
(v4i32 (MPYUv4i32 VECREG:$rA, VECREG:$rB)))>;
def MPYi32:
Pat<(mul R32C:$rA, R32C:$rB),
(Ar32
(Ar32 (MPYHr32 R32C:$rA, R32C:$rB),
(MPYHr32 R32C:$rB, R32C:$rA)),
(MPYUr32 R32C:$rA, R32C:$rB))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// f32, v4f32 divide instruction sequence:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
// Reciprocal estimate and interpolation
def Interpf32: CodeFrag<(FIf32 R32FP:$rB, (FRESTf32 R32FP:$rB))>;
// Division estimate
def DivEstf32: CodeFrag<(FMf32 R32FP:$rA, Interpf32.Fragment)>;
// Newton-Raphson iteration
def NRaphf32: CodeFrag<(FMAf32 (FNMSf32 DivEstf32.Fragment, R32FP:$rB, R32FP:$rA),
Interpf32.Fragment,
DivEstf32.Fragment)>;
// Epsilon addition
def Epsilonf32: CodeFrag<(AIf32 NRaphf32.Fragment, 1)>;
def : Pat<(fdiv R32FP:$rA, R32FP:$rB),
(SELBf32_cond NRaphf32.Fragment,
Epsilonf32.Fragment,
(CGTIf32 (FNMSf32 R32FP:$rB, Epsilonf32.Fragment, R32FP:$rA), -1))>;
// Reciprocal estimate and interpolation
def Interpv4f32: CodeFrag<(FIv4f32 (v4f32 VECREG:$rB), (FRESTv4f32 (v4f32 VECREG:$rB)))>;
// Division estimate
def DivEstv4f32: CodeFrag<(FMv4f32 (v4f32 VECREG:$rA), Interpv4f32.Fragment)>;
// Newton-Raphson iteration
def NRaphv4f32: CodeFrag<(FMAv4f32 (FNMSv4f32 DivEstv4f32.Fragment,
(v4f32 VECREG:$rB),
(v4f32 VECREG:$rA)),
Interpv4f32.Fragment,
DivEstv4f32.Fragment)>;
// Epsilon addition
def Epsilonv4f32: CodeFrag<(AIv4f32 NRaphv4f32.Fragment, 1)>;
def : Pat<(fdiv (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)),
(SELBv4f32_cond NRaphv4f32.Fragment,
Epsilonv4f32.Fragment,
(CGTIv4f32 (FNMSv4f32 (v4f32 VECREG:$rB),
Epsilonv4f32.Fragment,
(v4f32 VECREG:$rA)), -1))>;

View File

@ -1,159 +0,0 @@
//=== SPUNodes.td - Specialized SelectionDAG nodes by CellSPU -*- tablegen -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Type profiles and SelectionDAG nodes used by CellSPU
//
//===----------------------------------------------------------------------===//
// Type profile for a call sequence
def SDT_SPUCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
// SPU_GenControl: Type profile for generating control words for insertions
def SPU_GenControl : SDTypeProfile<1, 1, []>;
def SPUshufmask : SDNode<"SPUISD::SHUFFLE_MASK", SPU_GenControl, []>;
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq,
[SDNPHasChain, SDNPOutGlue]>;
def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq,
[SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
//===----------------------------------------------------------------------===//
// Operand constraints:
//===----------------------------------------------------------------------===//
def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
// Operand type constraints for vector shuffle/permute operations
def SDT_SPUshuffle : SDTypeProfile<1, 3, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;
// Vector binary operator type constraints (needs a further constraint to
// ensure that operand 0 is a vector...):
def SPUVecBinop: SDTypeProfile<1, 2, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;
// Trinary operators, e.g., addx, carry generate
def SPUIntTrinaryOp : SDTypeProfile<1, 3, [
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisInt<0>
]>;
// SELECT_MASK type constraints: There are several variations for the various
// vector types (this avoids having to bit_convert all over the place.)
def SPUselmask_type: SDTypeProfile<1, 1, [
SDTCisInt<1>
]>;
// SELB type constraints:
def SPUselb_type: SDTypeProfile<1, 3, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<0, 3> ]>;
// SPU Vector shift pseudo-instruction type constraints
def SPUvecshift_type: SDTypeProfile<1, 2, [
SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
// "marker" type for i64 operators that need a shuffle mask
// (i.e., uses cg or bg or another instruction that needs to
// use shufb to get things in the right place.)
// Op0: The result
// Op1, 2: LHS, RHS
// Op3: Carry-generate shuffle mask
def SPUmarker_type : SDTypeProfile<1, 3, [
SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> ]>;
//===----------------------------------------------------------------------===//
// Synthetic/pseudo-instructions
//===----------------------------------------------------------------------===//
// SPU CNTB:
def SPUcntb : SDNode<"SPUISD::CNTB", SDTIntUnaryOp>;
// SPU vector shuffle node, matched by the SPUISD::SHUFB enum (see
// SPUISelLowering.h):
def SPUshuffle: SDNode<"SPUISD::SHUFB", SDT_SPUshuffle, []>;
// Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only):
def SPUvec_shl: SDNode<"ISD::SHL", SPUvecshift_type, []>;
def SPUvec_srl: SDNode<"ISD::SRL", SPUvecshift_type, []>;
def SPUvec_sra: SDNode<"ISD::SRA", SPUvecshift_type, []>;
def SPUvec_rotl: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type, []>;
def SPUvec_rotr: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type, []>;
// Vector rotate left, bits shifted out of the left are rotated in on the right
def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT",
SPUvecshift_type, []>;
// Vector rotate left by bytes, but the count is given in bits and the SPU
// internally converts it to bytes (saves an instruction to mask off lower
// three bits)
def SPUrotbytes_left_bits : SDNode<"SPUISD::ROTBYTES_LEFT_BITS",
SPUvecshift_type>;
// Shift entire quad left by bytes/bits. Zeros are shifted in on the right
// SHL_BITS the same as SHL for i128, but ISD::SHL is not implemented for i128
def SPUshlquad_l_bytes: SDNode<"SPUISD::SHL_BYTES", SPUvecshift_type, []>;
def SPUshlquad_l_bits: SDNode<"SPUISD::SHL_BITS", SPUvecshift_type, []>;
def SPUsrl_bytes: SDNode<"SPUISD::SRL_BYTES", SPUvecshift_type, []>;
// SPU form select mask for bytes, immediate
def SPUselmask: SDNode<"SPUISD::SELECT_MASK", SPUselmask_type, []>;
// SPU select bits instruction
def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;
def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;
def SPU_vec_demote : SDTypeProfile<1, 1, []>;
def SPUvec2prefslot: SDNode<"SPUISD::VEC2PREFSLOT", SPU_vec_demote, []>;
// Address high and low components, used for [r+r] type addressing
def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>;
def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>;
// PC-relative address
def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>;
// A-Form local store addresses
def SPUaform : SDNode<"SPUISD::AFormAddr", SDTIntBinOp, []>;
// Indirect [D-Form "imm($reg)" and X-Form "$reg($reg)"] addresses
def SPUindirect : SDNode<"SPUISD::IndirectAddr", SDTIntBinOp, []>;
// i64 markers: supplies extra operands used to generate the i64 operator
// instruction sequences
def SPUadd64 : SDNode<"SPUISD::ADD64_MARKER", SPUmarker_type, []>;
def SPUsub64 : SDNode<"SPUISD::SUB64_MARKER", SPUmarker_type, []>;
def SPUmul64 : SDNode<"SPUISD::MUL64_MARKER", SPUmarker_type, []>;
//===----------------------------------------------------------------------===//
// Constraints: (taken from PPCInstrInfo.td)
//===----------------------------------------------------------------------===//
class RegConstraint<string C> {
string Constraints = C;
}
class NoEncode<string E> {
string DisableEncoding = E;
}
//===----------------------------------------------------------------------===//
// Return (flag isn't quite what it means: the operations are flagged so that
// instruction scheduling doesn't disassociate them.)
//===----------------------------------------------------------------------===//
def retflag : SDNode<"SPUISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInGlue]>;

View File

@ -1,153 +0,0 @@
//===-- SPUNopFiller.cpp - Add nops/lnops to align the pipelines ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The final pass just before assembly printing. This pass is the last
// checkpoint where nops and lnops are added to the instruction stream to
// satisfy the dual issue requirements. The actual dual issue scheduling is
// done (TODO: nowhere, currently)
//
//===----------------------------------------------------------------------===//
#include "SPU.h"
#include "SPUTargetMachine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct SPUNopFiller : public MachineFunctionPass {
TargetMachine &TM;
const TargetInstrInfo *TII;
const InstrItineraryData *IID;
bool isEvenPlace; // the instruction slot (mem address) at hand is even/odd
static char ID;
SPUNopFiller(TargetMachine &tm)
: MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()),
IID(tm.getInstrItineraryData())
{
DEBUG( dbgs() << "********** SPU Nop filler **********\n" ; );
}
virtual const char *getPassName() const {
return "SPU nop/lnop Filler";
}
void runOnMachineBasicBlock(MachineBasicBlock &MBB);
bool runOnMachineFunction(MachineFunction &F) {
isEvenPlace = true; //all functions get an .align 3 directive at start
for (MachineFunction::iterator FI = F.begin(), FE = F.end();
FI != FE; ++FI)
runOnMachineBasicBlock(*FI);
return true; //never-ever do any more modifications, just print it!
}
typedef enum { none = 0, // no more instructions in this function / BB
pseudo = 1, // this does not get executed
even = 2,
odd = 3 } SPUOpPlace;
SPUOpPlace getOpPlacement( MachineInstr &instr );
};
char SPUNopFiller::ID = 0;
}
// Fill a BasicBlock to alignment.
// In the assebly we align the functions to 'even' adresses, but
// basic blocks have an implicit alignmnet. We hereby define
// basic blocks to have the same, even, alignment.
void SPUNopFiller::
runOnMachineBasicBlock(MachineBasicBlock &MBB)
{
assert( isEvenPlace && "basic block start from odd address");
for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
{
SPUOpPlace this_optype, next_optype;
MachineBasicBlock::iterator J = I;
J++;
this_optype = getOpPlacement( *I );
next_optype = none;
while (J!=MBB.end()){
next_optype = getOpPlacement( *J );
++J;
if (next_optype != pseudo )
break;
}
// padd: odd(wrong), even(wrong), ...
// to: nop(corr), odd(corr), even(corr)...
if( isEvenPlace && this_optype == odd && next_optype == even ) {
DEBUG( dbgs() <<"Adding NOP before: "; );
DEBUG( I->dump(); );
BuildMI(MBB, I, I->getDebugLoc(), TII->get(SPU::ENOP));
isEvenPlace=false;
}
// padd: even(wrong), odd(wrong), ...
// to: lnop(corr), even(corr), odd(corr)...
else if ( !isEvenPlace && this_optype == even && next_optype == odd){
DEBUG( dbgs() <<"Adding LNOP before: "; );
DEBUG( I->dump(); );
BuildMI(MBB, I, I->getDebugLoc(), TII->get(SPU::LNOP));
isEvenPlace=true;
}
// now go to next mem slot
if( this_optype != pseudo )
isEvenPlace = !isEvenPlace;
}
// padd basicblock end
if( !isEvenPlace ){
MachineBasicBlock::iterator J = MBB.end();
J--;
if (getOpPlacement( *J ) == odd) {
DEBUG( dbgs() <<"Padding basic block with NOP\n"; );
BuildMI(MBB, J, J->getDebugLoc(), TII->get(SPU::ENOP));
}
else {
J++;
DEBUG( dbgs() <<"Padding basic block with LNOP\n"; );
BuildMI(MBB, J, DebugLoc(), TII->get(SPU::LNOP));
}
isEvenPlace=true;
}
}
FunctionPass *llvm::createSPUNopFillerPass(SPUTargetMachine &tm) {
return new SPUNopFiller(tm);
}
// Figure out if 'instr' is executed in the even or odd pipeline
SPUNopFiller::SPUOpPlace
SPUNopFiller::getOpPlacement( MachineInstr &instr ) {
int sc = instr.getDesc().getSchedClass();
const InstrStage *stage = IID->beginStage(sc);
unsigned FUs = stage->getUnits();
SPUOpPlace retval;
switch( FUs ) {
case 0: retval = pseudo; break;
case 1: retval = odd; break;
case 2: retval = even; break;
default: retval= pseudo;
assert( false && "got unknown FuncUnit\n");
break;
};
return retval;
}

View File

@ -1,664 +0,0 @@
//===-- SPUOperands.td - Cell SPU Instruction Operands -----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Cell SPU Instruction Operands:
//===----------------------------------------------------------------------===//
// TO_IMM32 - Convert an i8/i16 to i32.
def TO_IMM32 : SDNodeXForm<imm, [{
return getI32Imm(N->getZExtValue());
}]>;
// TO_IMM16 - Convert an i8/i32 to i16.
def TO_IMM16 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i16);
}]>;
def LO16 : SDNodeXForm<imm, [{
unsigned val = N->getZExtValue();
// Transformation function: get the low 16 bits.
return getI32Imm(val & 0xffff);
}]>;
def LO16_vec : SDNodeXForm<scalar_to_vector, [{
SDValue OpVal(0, 0);
// Transformation function: get the low 16 bit immediate from a build_vector
// node.
assert(N->getOpcode() == ISD::BUILD_VECTOR
&& "LO16_vec got something other than a BUILD_VECTOR");
// Get first constant operand...
for (unsigned i = 0, e = N->getNumOperands();
OpVal.getNode() == 0 && i != e; ++i) {
if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
if (OpVal.getNode() == 0)
OpVal = N->getOperand(i);
}
assert(OpVal.getNode() != 0 && "LO16_vec did not locate a <defined> node");
ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
return getI32Imm((unsigned)CN->getZExtValue() & 0xffff);
}]>;
// Transform an immediate, returning the high 16 bits shifted down:
def HI16 : SDNodeXForm<imm, [{
return getI32Imm((unsigned)N->getZExtValue() >> 16);
}]>;
// Transformation function: shift the high 16 bit immediate from a build_vector
// node into the low 16 bits, and return a 16-bit constant.
def HI16_vec : SDNodeXForm<scalar_to_vector, [{
SDValue OpVal(0, 0);
assert(N->getOpcode() == ISD::BUILD_VECTOR
&& "HI16_vec got something other than a BUILD_VECTOR");
// Get first constant operand...
for (unsigned i = 0, e = N->getNumOperands();
OpVal.getNode() == 0 && i != e; ++i) {
if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
if (OpVal.getNode() == 0)
OpVal = N->getOperand(i);
}
assert(OpVal.getNode() != 0 && "HI16_vec did not locate a <defined> node");
ConstantSDNode *CN = cast<ConstantSDNode>(OpVal);
return getI32Imm((unsigned)CN->getZExtValue() >> 16);
}]>;
// simm7 predicate - True if the immediate fits in an 7-bit signed
// field.
def simm7: PatLeaf<(imm), [{
int sextVal = int(N->getSExtValue());
return (sextVal >= -64 && sextVal <= 63);
}]>;
// uimm7 predicate - True if the immediate fits in an 7-bit unsigned
// field.
def uimm7: PatLeaf<(imm), [{
return (N->getZExtValue() <= 0x7f);
}]>;
// immSExt8 predicate - True if the immediate fits in an 8-bit sign extended
// field.
def immSExt8 : PatLeaf<(imm), [{
int Value = int(N->getSExtValue());
return (Value >= -(1 << 8) && Value <= (1 << 8) - 1);
}]>;
// immU8: immediate, unsigned 8-bit quantity
def immU8 : PatLeaf<(imm), [{
return (N->getZExtValue() <= 0xff);
}]>;
// i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
// extended field. Used by RI10Form instructions like 'ldq'.
def i32ImmSExt10 : PatLeaf<(imm), [{
return isI32IntS10Immediate(N);
}]>;
// i32ImmUns10 predicate - True if the i32 immediate fits in a 10-bit unsigned
// field. Used by RI10Form instructions like 'ldq'.
def i32ImmUns10 : PatLeaf<(imm), [{
return isI32IntU10Immediate(N);
}]>;
// i16ImmSExt10 predicate - True if the i16 immediate fits in a 10-bit sign
// extended field. Used by RI10Form instructions like 'ldq'.
def i16ImmSExt10 : PatLeaf<(imm), [{
return isI16IntS10Immediate(N);
}]>;
// i16ImmUns10 predicate - True if the i16 immediate fits into a 10-bit unsigned
// value. Used by RI10Form instructions.
def i16ImmUns10 : PatLeaf<(imm), [{
return isI16IntU10Immediate(N);
}]>;
def immSExt16 : PatLeaf<(imm), [{
// immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
// field.
short Ignored;
return isIntS16Immediate(N, Ignored);
}]>;
def immZExt16 : PatLeaf<(imm), [{
// immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
// field.
return (uint64_t)N->getZExtValue() == (unsigned short)N->getZExtValue();
}], LO16>;
def immU16 : PatLeaf<(imm), [{
// immU16 predicate- True if the immediate fits into a 16-bit unsigned field.
return (uint64_t)N->getZExtValue() == (N->getZExtValue() & 0xffff);
}]>;
def imm18 : PatLeaf<(imm), [{
// imm18 predicate: True if the immediate fits into an 18-bit unsigned field.
int Value = (int) N->getZExtValue();
return isUInt<18>(Value);
}]>;
def lo16 : PatLeaf<(imm), [{
// lo16 predicate - returns true if the immediate has all zeros in the
// low order bits and is a 32-bit constant:
if (N->getValueType(0) == MVT::i32) {
uint32_t val = N->getZExtValue();
return ((val & 0x0000ffff) == val);
}
return false;
}], LO16>;
def hi16 : PatLeaf<(imm), [{
// hi16 predicate - returns true if the immediate has all zeros in the
// low order bits and is a 32-bit constant:
if (N->getValueType(0) == MVT::i32) {
uint32_t val = uint32_t(N->getZExtValue());
return ((val & 0xffff0000) == val);
} else if (N->getValueType(0) == MVT::i64) {
uint64_t val = N->getZExtValue();
return ((val & 0xffff0000ULL) == val);
}
return false;
}], HI16>;
def bitshift : PatLeaf<(imm), [{
// bitshift predicate - returns true if 0 < imm <= 7 for SHLQBII
// (shift left quadword by bits immediate)
int64_t Val = N->getZExtValue();
return (Val > 0 && Val <= 7);
}]>;
//===----------------------------------------------------------------------===//
// Floating point operands:
//===----------------------------------------------------------------------===//
// Transform a float, returning the high 16 bits shifted down, as if
// the float was really an unsigned integer:
def HI16_f32 : SDNodeXForm<fpimm, [{
float fval = N->getValueAPF().convertToFloat();
return getI32Imm(FloatToBits(fval) >> 16);
}]>;
// Transformation function on floats: get the low 16 bits as if the float was
// an unsigned integer.
def LO16_f32 : SDNodeXForm<fpimm, [{
float fval = N->getValueAPF().convertToFloat();
return getI32Imm(FloatToBits(fval) & 0xffff);
}]>;
def FPimm_sext16 : SDNodeXForm<fpimm, [{
float fval = N->getValueAPF().convertToFloat();
return getI32Imm((int) ((FloatToBits(fval) << 16) >> 16));
}]>;
def FPimm_u18 : SDNodeXForm<fpimm, [{
float fval = N->getValueAPF().convertToFloat();
return getI32Imm(FloatToBits(fval) & ((1 << 18) - 1));
}]>;
def fpimmSExt16 : PatLeaf<(fpimm), [{
short Ignored;
return isFPS16Immediate(N, Ignored);
}], FPimm_sext16>;
// Does the SFP constant only have upp 16 bits set?
def hi16_f32 : PatLeaf<(fpimm), [{
if (N->getValueType(0) == MVT::f32) {
uint32_t val = FloatToBits(N->getValueAPF().convertToFloat());
return ((val & 0xffff0000) == val);
}
return false;
}], HI16_f32>;
// Does the SFP constant fit into 18 bits?
def fpimm18 : PatLeaf<(fpimm), [{
if (N->getValueType(0) == MVT::f32) {
uint32_t Value = FloatToBits(N->getValueAPF().convertToFloat());
return isUInt<18>(Value);
}
return false;
}], FPimm_u18>;
//===----------------------------------------------------------------------===//
// 64-bit operands (TODO):
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// build_vector operands:
//===----------------------------------------------------------------------===//
// v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended
// immediate constant load for v16i8 vectors. N.B.: The incoming constant has
// to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
def v16i8SExt8Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
}]>;
// v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant
// load, works in conjunction with its transform function. N.B.: This relies the
// incoming constant being a 16-bit quantity, where the upper and lower bytes
// are EXACTLY the same (e.g., 0x2a2a)
def v16i8SExt8Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
}], v16i8SExt8Imm_xform>;
// v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit
// immediate constant load for v16i8 vectors. N.B.: The incoming constant has
// to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
def v16i8U8Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
}]>;
// v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant
// load, works in conjunction with its transform function. N.B.: This relies the
// incoming constant being a 16-bit quantity, where the upper and lower bytes
// are EXACTLY the same (e.g., 0x2a2a)
def v16i8U8Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).getNode() != 0;
}], v16i8U8Imm_xform>;
// v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended
// immediate constant load for v8i16 vectors.
def v8i16SExt8Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16);
}]>;
// v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v8i16SExt8Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).getNode() != 0;
}], v8i16SExt8Imm_xform>;
// v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended
// immediate constant load for v8i16 vectors.
def v8i16SExt10Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
}]>;
// v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v8i16SExt10Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
}], v8i16SExt10Imm_xform>;
// v8i16Uns10Imm_xform function: convert build_vector to 16-bit unsigned
// immediate constant load for v8i16 vectors.
def v8i16Uns10Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
}]>;
// v8i16Uns10Imm: Predicate test for 16-bit unsigned immediate constant
// load, works in conjunction with its transform function.
def v8i16Uns10Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).getNode() != 0;
}], v8i16Uns10Imm_xform>;
// v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended
// immediate constant load for v8i16 vectors.
def v8i16Uns16Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16);
}]>;
// v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v8i16SExt16Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).getNode() != 0;
}], v8i16Uns16Imm_xform>;
// v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended
// immediate constant load for v4i32 vectors.
def v4i32SExt10Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
}]>;
// v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v4i32SExt10Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
}], v4i32SExt10Imm_xform>;
// v4i32Uns10Imm_xform function: convert build_vector to 10-bit unsigned
// immediate constant load for v4i32 vectors.
def v4i32Uns10Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
}]>;
// v4i32Uns10Imm: Predicate test for 10-bit unsigned immediate constant
// load, works in conjunction with its transform function.
def v4i32Uns10Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).getNode() != 0;
}], v4i32Uns10Imm_xform>;
// v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended
// immediate constant load for v4i32 vectors.
def v4i32SExt16Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32);
}]>;
// v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v4i32SExt16Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).getNode() != 0;
}], v4i32SExt16Imm_xform>;
// v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned
// immediate constant load for v4i32 vectors.
def v4i32Uns18Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32);
}]>;
// v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
// works in conjunction with its transform function.
def v4i32Uns18Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).getNode() != 0;
}], v4i32Uns18Imm_xform>;
// ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant
// load.
def ILHUvec_get_imm: SDNodeXForm<build_vector, [{
return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32);
}]>;
/// immILHUvec: Predicate test for a ILHU constant vector.
def immILHUvec: PatLeaf<(build_vector), [{
return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).getNode() != 0;
}], ILHUvec_get_imm>;
// Catch-all for any other i32 vector constants
def v4i32_get_imm: SDNodeXForm<build_vector, [{
return SPU::get_v4i32_imm(N, *CurDAG);
}]>;
def v4i32Imm: PatLeaf<(build_vector), [{
return SPU::get_v4i32_imm(N, *CurDAG).getNode() != 0;
}], v4i32_get_imm>;
// v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended
// immediate constant load for v2i64 vectors.
def v2i64SExt10Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64);
}]>;
// v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v2i64SExt10Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).getNode() != 0;
}], v2i64SExt10Imm_xform>;
// v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended
// immediate constant load for v2i64 vectors.
def v2i64SExt16Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64);
}]>;
// v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant
// load, works in conjunction with its transform function.
def v2i64SExt16Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).getNode() != 0;
}], v2i64SExt16Imm_xform>;
// v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned
// immediate constant load for v2i64 vectors.
def v2i64Uns18Imm_xform: SDNodeXForm<build_vector, [{
return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64);
}]>;
// v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
// works in conjunction with its transform function.
def v2i64Uns18Imm: PatLeaf<(build_vector), [{
return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).getNode() != 0;
}], v2i64Uns18Imm_xform>;
/// immILHUvec: Predicate test for a ILHU constant vector.
def immILHUvec_i64: PatLeaf<(build_vector), [{
return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).getNode() != 0;
}], ILHUvec_get_imm>;
// Catch-all for any other i32 vector constants
def v2i64_get_imm: SDNodeXForm<build_vector, [{
return SPU::get_v2i64_imm(N, *CurDAG);
}]>;
def v2i64Imm: PatLeaf<(build_vector), [{
return SPU::get_v2i64_imm(N, *CurDAG).getNode() != 0;
}], v2i64_get_imm>;
//===----------------------------------------------------------------------===//
// Operand Definitions.
def s7imm: Operand<i8> {
let PrintMethod = "printS7ImmOperand";
}
def s7imm_i8: Operand<i8> {
let PrintMethod = "printS7ImmOperand";
}
def u7imm: Operand<i16> {
let PrintMethod = "printU7ImmOperand";
}
def u7imm_i8: Operand<i8> {
let PrintMethod = "printU7ImmOperand";
}
def u7imm_i32: Operand<i32> {
let PrintMethod = "printU7ImmOperand";
}
// Halfword, signed 10-bit constant
def s10imm : Operand<i16> {
let PrintMethod = "printS10ImmOperand";
}
def s10imm_i8: Operand<i8> {
let PrintMethod = "printS10ImmOperand";
}
def s10imm_i32: Operand<i32> {
let PrintMethod = "printS10ImmOperand";
}
def s10imm_i64: Operand<i64> {
let PrintMethod = "printS10ImmOperand";
}
// Unsigned 10-bit integers:
def u10imm: Operand<i16> {
let PrintMethod = "printU10ImmOperand";
}
def u10imm_i8: Operand<i8> {
let PrintMethod = "printU10ImmOperand";
}
def u10imm_i32: Operand<i32> {
let PrintMethod = "printU10ImmOperand";
}
def s16imm : Operand<i16> {
let PrintMethod = "printS16ImmOperand";
}
def s16imm_i8: Operand<i8> {
let PrintMethod = "printS16ImmOperand";
}
def s16imm_i32: Operand<i32> {
let PrintMethod = "printS16ImmOperand";
}
def s16imm_i64: Operand<i64> {
let PrintMethod = "printS16ImmOperand";
}
def s16imm_f32: Operand<f32> {
let PrintMethod = "printS16ImmOperand";
}
def s16imm_f64: Operand<f64> {
let PrintMethod = "printS16ImmOperand";
}
def u16imm_i64 : Operand<i64> {
let PrintMethod = "printU16ImmOperand";
}
def u16imm_i32 : Operand<i32> {
let PrintMethod = "printU16ImmOperand";
}
def u16imm : Operand<i16> {
let PrintMethod = "printU16ImmOperand";
}
def f16imm : Operand<f32> {
let PrintMethod = "printU16ImmOperand";
}
def s18imm : Operand<i32> {
let PrintMethod = "printS18ImmOperand";
}
def u18imm : Operand<i32> {
let PrintMethod = "printU18ImmOperand";
}
def u18imm_i64 : Operand<i64> {
let PrintMethod = "printU18ImmOperand";
}
def f18imm : Operand<f32> {
let PrintMethod = "printU18ImmOperand";
}
def f18imm_f64 : Operand<f64> {
let PrintMethod = "printU18ImmOperand";
}
// Negated 7-bit halfword rotate immediate operands
def rothNeg7imm : Operand<i32> {
let PrintMethod = "printROTHNeg7Imm";
}
def rothNeg7imm_i16 : Operand<i16> {
let PrintMethod = "printROTHNeg7Imm";
}
// Negated 7-bit word rotate immediate operands
def rotNeg7imm : Operand<i32> {
let PrintMethod = "printROTNeg7Imm";
}
def rotNeg7imm_i16 : Operand<i16> {
let PrintMethod = "printROTNeg7Imm";
}
def rotNeg7imm_i8 : Operand<i8> {
let PrintMethod = "printROTNeg7Imm";
}
def target : Operand<OtherVT> {
let PrintMethod = "printBranchOperand";
}
// Absolute address call target
def calltarget : Operand<iPTR> {
let PrintMethod = "printCallOperand";
let MIOperandInfo = (ops u18imm:$calldest);
}
// PC relative call target
def relcalltarget : Operand<iPTR> {
let PrintMethod = "printPCRelativeOperand";
let MIOperandInfo = (ops s16imm:$calldest);
}
// Branch targets:
def brtarget : Operand<OtherVT> {
let PrintMethod = "printPCRelativeOperand";
}
// Hint for branch target
def hbrtarget : Operand<OtherVT> {
let PrintMethod = "printHBROperand";
}
// Indirect call target
def indcalltarget : Operand<iPTR> {
let PrintMethod = "printCallOperand";
let MIOperandInfo = (ops ptr_rc:$calldest);
}
def symbolHi: Operand<i32> {
let PrintMethod = "printSymbolHi";
}
def symbolLo: Operand<i32> {
let PrintMethod = "printSymbolLo";
}
def symbolLSA: Operand<i32> {
let PrintMethod = "printSymbolLSA";
}
// Shuffle address memory operaand [s7imm(reg) d-format]
def shufaddr : Operand<iPTR> {
let PrintMethod = "printShufAddr";
let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg);
}
// memory s10imm(reg) operand
def dformaddr : Operand<iPTR> {
let PrintMethod = "printDFormAddr";
let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg);
}
// 256K local store address
// N.B.: The tblgen code generator expects to have two operands, an offset
// and a pointer. Of these, only the immediate is actually used.
def addr256k : Operand<iPTR> {
let PrintMethod = "printAddr256K";
let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg);
}
// memory s18imm(reg) operand
def memri18 : Operand<iPTR> {
let PrintMethod = "printMemRegImmS18";
let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg);
}
// memory register + register operand
def memrr : Operand<iPTR> {
let PrintMethod = "printMemRegReg";
let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b);
}
// Define SPU-specific addressing modes: These come in three basic
// flavors:
//
// D-form : [r+I10] (10-bit signed offset + reg)
// X-form : [r+r] (reg+reg)
// A-form : abs (256K LSA offset)
// D-form(2): [r+I7] (7-bit signed offset + reg)
def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr",
[], [SDNPWantRoot]>;
def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr",
[], [SDNPWantRoot]>;
def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr",
[], [SDNPWantRoot]>;
def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr",
[], [SDNPWantRoot]>;

View File

@ -1,357 +0,0 @@
//===-- SPURegisterInfo.cpp - Cell SPU 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 Cell implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "reginfo"
#include "SPURegisterInfo.h"
#include "SPU.h"
#include "SPUInstrBuilder.h"
#include "SPUSubtarget.h"
#include "SPUMachineFunction.h"
#include "SPUFrameLowering.h"
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include <cstdlib>
#define GET_REGINFO_TARGET_DESC
#include "SPUGenRegisterInfo.inc"
using namespace llvm;
/// getRegisterNumbering - Given the enum value for some register, e.g.
/// PPC::F14, return the number that it corresponds to (e.g. 14).
unsigned SPURegisterInfo::getRegisterNumbering(unsigned RegEnum) {
using namespace SPU;
switch (RegEnum) {
case SPU::R0: return 0;
case SPU::R1: return 1;
case SPU::R2: return 2;
case SPU::R3: return 3;
case SPU::R4: return 4;
case SPU::R5: return 5;
case SPU::R6: return 6;
case SPU::R7: return 7;
case SPU::R8: return 8;
case SPU::R9: return 9;
case SPU::R10: return 10;
case SPU::R11: return 11;
case SPU::R12: return 12;
case SPU::R13: return 13;
case SPU::R14: return 14;
case SPU::R15: return 15;
case SPU::R16: return 16;
case SPU::R17: return 17;
case SPU::R18: return 18;
case SPU::R19: return 19;
case SPU::R20: return 20;
case SPU::R21: return 21;
case SPU::R22: return 22;
case SPU::R23: return 23;
case SPU::R24: return 24;
case SPU::R25: return 25;
case SPU::R26: return 26;
case SPU::R27: return 27;
case SPU::R28: return 28;
case SPU::R29: return 29;
case SPU::R30: return 30;
case SPU::R31: return 31;
case SPU::R32: return 32;
case SPU::R33: return 33;
case SPU::R34: return 34;
case SPU::R35: return 35;
case SPU::R36: return 36;
case SPU::R37: return 37;
case SPU::R38: return 38;
case SPU::R39: return 39;
case SPU::R40: return 40;
case SPU::R41: return 41;
case SPU::R42: return 42;
case SPU::R43: return 43;
case SPU::R44: return 44;
case SPU::R45: return 45;
case SPU::R46: return 46;
case SPU::R47: return 47;
case SPU::R48: return 48;
case SPU::R49: return 49;
case SPU::R50: return 50;
case SPU::R51: return 51;
case SPU::R52: return 52;
case SPU::R53: return 53;
case SPU::R54: return 54;
case SPU::R55: return 55;
case SPU::R56: return 56;
case SPU::R57: return 57;
case SPU::R58: return 58;
case SPU::R59: return 59;
case SPU::R60: return 60;
case SPU::R61: return 61;
case SPU::R62: return 62;
case SPU::R63: return 63;
case SPU::R64: return 64;
case SPU::R65: return 65;
case SPU::R66: return 66;
case SPU::R67: return 67;
case SPU::R68: return 68;
case SPU::R69: return 69;
case SPU::R70: return 70;
case SPU::R71: return 71;
case SPU::R72: return 72;
case SPU::R73: return 73;
case SPU::R74: return 74;
case SPU::R75: return 75;
case SPU::R76: return 76;
case SPU::R77: return 77;
case SPU::R78: return 78;
case SPU::R79: return 79;
case SPU::R80: return 80;
case SPU::R81: return 81;
case SPU::R82: return 82;
case SPU::R83: return 83;
case SPU::R84: return 84;
case SPU::R85: return 85;
case SPU::R86: return 86;
case SPU::R87: return 87;
case SPU::R88: return 88;
case SPU::R89: return 89;
case SPU::R90: return 90;
case SPU::R91: return 91;
case SPU::R92: return 92;
case SPU::R93: return 93;
case SPU::R94: return 94;
case SPU::R95: return 95;
case SPU::R96: return 96;
case SPU::R97: return 97;
case SPU::R98: return 98;
case SPU::R99: return 99;
case SPU::R100: return 100;
case SPU::R101: return 101;
case SPU::R102: return 102;
case SPU::R103: return 103;
case SPU::R104: return 104;
case SPU::R105: return 105;
case SPU::R106: return 106;
case SPU::R107: return 107;
case SPU::R108: return 108;
case SPU::R109: return 109;
case SPU::R110: return 110;
case SPU::R111: return 111;
case SPU::R112: return 112;
case SPU::R113: return 113;
case SPU::R114: return 114;
case SPU::R115: return 115;
case SPU::R116: return 116;
case SPU::R117: return 117;
case SPU::R118: return 118;
case SPU::R119: return 119;
case SPU::R120: return 120;
case SPU::R121: return 121;
case SPU::R122: return 122;
case SPU::R123: return 123;
case SPU::R124: return 124;
case SPU::R125: return 125;
case SPU::R126: return 126;
case SPU::R127: return 127;
default:
report_fatal_error("Unhandled reg in SPURegisterInfo::getRegisterNumbering");
}
}
SPURegisterInfo::SPURegisterInfo(const SPUSubtarget &subtarget,
const TargetInstrInfo &tii) :
SPUGenRegisterInfo(SPU::R0), Subtarget(subtarget), TII(tii)
{
}
/// getPointerRegClass - Return the register class to use to hold pointers.
/// This is used for addressing modes.
const TargetRegisterClass *
SPURegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
const {
return &SPU::R32CRegClass;
}
const uint16_t *
SPURegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const
{
// Cell ABI calling convention
static const uint16_t SPU_CalleeSaveRegs[] = {
SPU::R80, SPU::R81, SPU::R82, SPU::R83,
SPU::R84, SPU::R85, SPU::R86, SPU::R87,
SPU::R88, SPU::R89, SPU::R90, SPU::R91,
SPU::R92, SPU::R93, SPU::R94, SPU::R95,
SPU::R96, SPU::R97, SPU::R98, SPU::R99,
SPU::R100, SPU::R101, SPU::R102, SPU::R103,
SPU::R104, SPU::R105, SPU::R106, SPU::R107,
SPU::R108, SPU::R109, SPU::R110, SPU::R111,
SPU::R112, SPU::R113, SPU::R114, SPU::R115,
SPU::R116, SPU::R117, SPU::R118, SPU::R119,
SPU::R120, SPU::R121, SPU::R122, SPU::R123,
SPU::R124, SPU::R125, SPU::R126, SPU::R127,
SPU::R2, /* environment pointer */
SPU::R1, /* stack pointer */
SPU::R0, /* link register */
0 /* end */
};
return SPU_CalleeSaveRegs;
}
/*!
R0 (link register), R1 (stack pointer) and R2 (environment pointer -- this is
generally unused) are the Cell's reserved registers
*/
BitVector SPURegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
Reserved.set(SPU::R0); // LR
Reserved.set(SPU::R1); // SP
Reserved.set(SPU::R2); // environment pointer
return Reserved;
}
//===----------------------------------------------------------------------===//
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//
//--------------------------------------------------------------------------
void
SPURegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I)
const
{
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
void
SPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
RegScavenger *RS) const
{
unsigned i = 0;
MachineInstr &MI = *II;
MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent();
MachineFrameInfo *MFI = MF.getFrameInfo();
DebugLoc dl = II->getDebugLoc();
while (!MI.getOperand(i).isFI()) {
++i;
assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
}
MachineOperand &SPOp = MI.getOperand(i);
int FrameIndex = SPOp.getIndex();
// Now add the frame object offset to the offset from r1.
int Offset = MFI->getObjectOffset(FrameIndex);
// Most instructions, except for generated FrameIndex additions using AIr32
// and ILAr32, have the immediate in operand 1. AIr32 and ILAr32 have the
// immediate in operand 2.
unsigned OpNo = 1;
if (MI.getOpcode() == SPU::AIr32 || MI.getOpcode() == SPU::ILAr32)
OpNo = 2;
MachineOperand &MO = MI.getOperand(OpNo);
// Offset is biased by $lr's slot at the bottom.
Offset += MO.getImm() + MFI->getStackSize() + SPUFrameLowering::minStackSize();
assert((Offset & 0xf) == 0
&& "16-byte alignment violated in eliminateFrameIndex");
// Replace the FrameIndex with base register with $sp (aka $r1)
SPOp.ChangeToRegister(SPU::R1, false);
// if 'Offset' doesn't fit to the D-form instruction's
// immediate, convert the instruction to X-form
// if the instruction is not an AI (which takes a s10 immediate), assume
// it is a load/store that can take a s14 immediate
if ((MI.getOpcode() == SPU::AIr32 && !isInt<10>(Offset))
|| !isInt<14>(Offset)) {
int newOpcode = convertDFormToXForm(MI.getOpcode());
unsigned tmpReg = findScratchRegister(II, RS, &SPU::R32CRegClass, SPAdj);
BuildMI(MBB, II, dl, TII.get(SPU::ILr32), tmpReg )
.addImm(Offset);
BuildMI(MBB, II, dl, TII.get(newOpcode), MI.getOperand(0).getReg())
.addReg(tmpReg, RegState::Kill)
.addReg(SPU::R1);
// remove the replaced D-form instruction
MBB.erase(II);
} else {
MO.ChangeToImmediate(Offset);
}
}
unsigned
SPURegisterInfo::getFrameRegister(const MachineFunction &MF) const
{
return SPU::R1;
}
int
SPURegisterInfo::convertDFormToXForm(int dFormOpcode) const
{
switch(dFormOpcode)
{
case SPU::AIr32: return SPU::Ar32;
case SPU::LQDr32: return SPU::LQXr32;
case SPU::LQDr128: return SPU::LQXr128;
case SPU::LQDv16i8: return SPU::LQXv16i8;
case SPU::LQDv4i32: return SPU::LQXv4i32;
case SPU::LQDv4f32: return SPU::LQXv4f32;
case SPU::STQDr32: return SPU::STQXr32;
case SPU::STQDr128: return SPU::STQXr128;
case SPU::STQDv16i8: return SPU::STQXv16i8;
case SPU::STQDv4i32: return SPU::STQXv4i32;
case SPU::STQDv4f32: return SPU::STQXv4f32;
default: assert( false && "Unhandled D to X-form conversion");
}
// default will assert, but need to return something to keep the
// compiler happy.
return dFormOpcode;
}
// TODO this is already copied from PPC. Could this convenience function
// be moved to the RegScavenger class?
unsigned
SPURegisterInfo::findScratchRegister(MachineBasicBlock::iterator II,
RegScavenger *RS,
const TargetRegisterClass *RC,
int SPAdj) const
{
assert(RS && "Register scavenging must be on");
unsigned Reg = RS->FindUnusedReg(RC);
if (Reg == 0)
Reg = RS->scavengeRegister(RC, II, SPAdj);
assert( Reg && "Register scavenger failed");
return Reg;
}

View File

@ -1,106 +0,0 @@
//===-- SPURegisterInfo.h - Cell SPU 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 Cell SPU implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_REGISTERINFO_H
#define SPU_REGISTERINFO_H
#include "SPU.h"
#define GET_REGINFO_HEADER
#include "SPUGenRegisterInfo.inc"
namespace llvm {
class SPUSubtarget;
class TargetInstrInfo;
class Type;
class SPURegisterInfo : public SPUGenRegisterInfo {
private:
const SPUSubtarget &Subtarget;
const TargetInstrInfo &TII;
//! Predicate: Does the machine function use the link register?
bool usesLR(MachineFunction &MF) const;
public:
SPURegisterInfo(const SPUSubtarget &subtarget, const TargetInstrInfo &tii);
//! Translate a register's enum value to a register number
/*!
This method translates a register's enum value to it's regiser number,
e.g. SPU::R14 -> 14.
*/
static unsigned getRegisterNumbering(unsigned RegEnum);
/// getPointerRegClass - Return the register class to use to hold pointers.
/// This is used for addressing modes.
virtual const TargetRegisterClass *
getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const;
/// After allocating this many registers, the allocator should feel
/// register pressure. The value is a somewhat random guess, based on the
/// number of non callee saved registers in the C calling convention.
virtual unsigned getRegPressureLimit( const TargetRegisterClass *RC,
MachineFunction &MF) const{
return 50;
}
//! Return the array of callee-saved registers
virtual const uint16_t* getCalleeSavedRegs(const MachineFunction *MF) const;
//! Allow for scavenging, so we can get scratch registers when needed.
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const
{ return true; }
//! Enable tracking of liveness after register allocation, since register
// scavenging is enabled.
virtual bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const
{ return true; }
//! Return the reserved registers
BitVector getReservedRegs(const MachineFunction &MF) const;
//! Eliminate the call frame setup pseudo-instructions
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
//! Convert frame indicies into machine operands
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
RegScavenger *RS = NULL) const;
//! Get the stack frame register (SP, aka R1)
unsigned getFrameRegister(const MachineFunction &MF) const;
//------------------------------------------------------------------------
// New methods added:
//------------------------------------------------------------------------
//! Convert D-form load/store to X-form load/store
/*!
Converts a regiser displacement load/store into a register-indexed
load/store for large stack frames, when the stack frame exceeds the
range of a s10 displacement.
*/
int convertDFormToXForm(int dFormOpcode) const;
//! Acquire an unused register in an emergency.
unsigned findScratchRegister(MachineBasicBlock::iterator II,
RegScavenger *RS,
const TargetRegisterClass *RC,
int SPAdj) const;
};
} // end namespace llvm
#endif

View File

@ -1,183 +0,0 @@
//===-- SPURegisterInfo.td - The Cell SPU Register File ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
class SPUReg<string n> : Register<n> {
let Namespace = "SPU";
}
// The SPU's register are all 128-bits wide, which makes specifying the
// registers relatively easy, if relatively mundane:
class SPUVecReg<bits<7> num, string n> : SPUReg<n> {
field bits<7> Num = num;
}
def R0 : SPUVecReg<0, "$lr">, DwarfRegNum<[0]>;
def R1 : SPUVecReg<1, "$sp">, DwarfRegNum<[1]>;
def R2 : SPUVecReg<2, "$2">, DwarfRegNum<[2]>;
def R3 : SPUVecReg<3, "$3">, DwarfRegNum<[3]>;
def R4 : SPUVecReg<4, "$4">, DwarfRegNum<[4]>;
def R5 : SPUVecReg<5, "$5">, DwarfRegNum<[5]>;
def R6 : SPUVecReg<6, "$6">, DwarfRegNum<[6]>;
def R7 : SPUVecReg<7, "$7">, DwarfRegNum<[7]>;
def R8 : SPUVecReg<8, "$8">, DwarfRegNum<[8]>;
def R9 : SPUVecReg<9, "$9">, DwarfRegNum<[9]>;
def R10 : SPUVecReg<10, "$10">, DwarfRegNum<[10]>;
def R11 : SPUVecReg<11, "$11">, DwarfRegNum<[11]>;
def R12 : SPUVecReg<12, "$12">, DwarfRegNum<[12]>;
def R13 : SPUVecReg<13, "$13">, DwarfRegNum<[13]>;
def R14 : SPUVecReg<14, "$14">, DwarfRegNum<[14]>;
def R15 : SPUVecReg<15, "$15">, DwarfRegNum<[15]>;
def R16 : SPUVecReg<16, "$16">, DwarfRegNum<[16]>;
def R17 : SPUVecReg<17, "$17">, DwarfRegNum<[17]>;
def R18 : SPUVecReg<18, "$18">, DwarfRegNum<[18]>;
def R19 : SPUVecReg<19, "$19">, DwarfRegNum<[19]>;
def R20 : SPUVecReg<20, "$20">, DwarfRegNum<[20]>;
def R21 : SPUVecReg<21, "$21">, DwarfRegNum<[21]>;
def R22 : SPUVecReg<22, "$22">, DwarfRegNum<[22]>;
def R23 : SPUVecReg<23, "$23">, DwarfRegNum<[23]>;
def R24 : SPUVecReg<24, "$24">, DwarfRegNum<[24]>;
def R25 : SPUVecReg<25, "$25">, DwarfRegNum<[25]>;
def R26 : SPUVecReg<26, "$26">, DwarfRegNum<[26]>;
def R27 : SPUVecReg<27, "$27">, DwarfRegNum<[27]>;
def R28 : SPUVecReg<28, "$28">, DwarfRegNum<[28]>;
def R29 : SPUVecReg<29, "$29">, DwarfRegNum<[29]>;
def R30 : SPUVecReg<30, "$30">, DwarfRegNum<[30]>;
def R31 : SPUVecReg<31, "$31">, DwarfRegNum<[31]>;
def R32 : SPUVecReg<32, "$32">, DwarfRegNum<[32]>;
def R33 : SPUVecReg<33, "$33">, DwarfRegNum<[33]>;
def R34 : SPUVecReg<34, "$34">, DwarfRegNum<[34]>;
def R35 : SPUVecReg<35, "$35">, DwarfRegNum<[35]>;
def R36 : SPUVecReg<36, "$36">, DwarfRegNum<[36]>;
def R37 : SPUVecReg<37, "$37">, DwarfRegNum<[37]>;
def R38 : SPUVecReg<38, "$38">, DwarfRegNum<[38]>;
def R39 : SPUVecReg<39, "$39">, DwarfRegNum<[39]>;
def R40 : SPUVecReg<40, "$40">, DwarfRegNum<[40]>;
def R41 : SPUVecReg<41, "$41">, DwarfRegNum<[41]>;
def R42 : SPUVecReg<42, "$42">, DwarfRegNum<[42]>;
def R43 : SPUVecReg<43, "$43">, DwarfRegNum<[43]>;
def R44 : SPUVecReg<44, "$44">, DwarfRegNum<[44]>;
def R45 : SPUVecReg<45, "$45">, DwarfRegNum<[45]>;
def R46 : SPUVecReg<46, "$46">, DwarfRegNum<[46]>;
def R47 : SPUVecReg<47, "$47">, DwarfRegNum<[47]>;
def R48 : SPUVecReg<48, "$48">, DwarfRegNum<[48]>;
def R49 : SPUVecReg<49, "$49">, DwarfRegNum<[49]>;
def R50 : SPUVecReg<50, "$50">, DwarfRegNum<[50]>;
def R51 : SPUVecReg<51, "$51">, DwarfRegNum<[51]>;
def R52 : SPUVecReg<52, "$52">, DwarfRegNum<[52]>;
def R53 : SPUVecReg<53, "$53">, DwarfRegNum<[53]>;
def R54 : SPUVecReg<54, "$54">, DwarfRegNum<[54]>;
def R55 : SPUVecReg<55, "$55">, DwarfRegNum<[55]>;
def R56 : SPUVecReg<56, "$56">, DwarfRegNum<[56]>;
def R57 : SPUVecReg<57, "$57">, DwarfRegNum<[57]>;
def R58 : SPUVecReg<58, "$58">, DwarfRegNum<[58]>;
def R59 : SPUVecReg<59, "$59">, DwarfRegNum<[59]>;
def R60 : SPUVecReg<60, "$60">, DwarfRegNum<[60]>;
def R61 : SPUVecReg<61, "$61">, DwarfRegNum<[61]>;
def R62 : SPUVecReg<62, "$62">, DwarfRegNum<[62]>;
def R63 : SPUVecReg<63, "$63">, DwarfRegNum<[63]>;
def R64 : SPUVecReg<64, "$64">, DwarfRegNum<[64]>;
def R65 : SPUVecReg<65, "$65">, DwarfRegNum<[65]>;
def R66 : SPUVecReg<66, "$66">, DwarfRegNum<[66]>;
def R67 : SPUVecReg<67, "$67">, DwarfRegNum<[67]>;
def R68 : SPUVecReg<68, "$68">, DwarfRegNum<[68]>;
def R69 : SPUVecReg<69, "$69">, DwarfRegNum<[69]>;
def R70 : SPUVecReg<70, "$70">, DwarfRegNum<[70]>;
def R71 : SPUVecReg<71, "$71">, DwarfRegNum<[71]>;
def R72 : SPUVecReg<72, "$72">, DwarfRegNum<[72]>;
def R73 : SPUVecReg<73, "$73">, DwarfRegNum<[73]>;
def R74 : SPUVecReg<74, "$74">, DwarfRegNum<[74]>;
def R75 : SPUVecReg<75, "$75">, DwarfRegNum<[75]>;
def R76 : SPUVecReg<76, "$76">, DwarfRegNum<[76]>;
def R77 : SPUVecReg<77, "$77">, DwarfRegNum<[77]>;
def R78 : SPUVecReg<78, "$78">, DwarfRegNum<[78]>;
def R79 : SPUVecReg<79, "$79">, DwarfRegNum<[79]>;
def R80 : SPUVecReg<80, "$80">, DwarfRegNum<[80]>;
def R81 : SPUVecReg<81, "$81">, DwarfRegNum<[81]>;
def R82 : SPUVecReg<82, "$82">, DwarfRegNum<[82]>;
def R83 : SPUVecReg<83, "$83">, DwarfRegNum<[83]>;
def R84 : SPUVecReg<84, "$84">, DwarfRegNum<[84]>;
def R85 : SPUVecReg<85, "$85">, DwarfRegNum<[85]>;
def R86 : SPUVecReg<86, "$86">, DwarfRegNum<[86]>;
def R87 : SPUVecReg<87, "$87">, DwarfRegNum<[87]>;
def R88 : SPUVecReg<88, "$88">, DwarfRegNum<[88]>;
def R89 : SPUVecReg<89, "$89">, DwarfRegNum<[89]>;
def R90 : SPUVecReg<90, "$90">, DwarfRegNum<[90]>;
def R91 : SPUVecReg<91, "$91">, DwarfRegNum<[91]>;
def R92 : SPUVecReg<92, "$92">, DwarfRegNum<[92]>;
def R93 : SPUVecReg<93, "$93">, DwarfRegNum<[93]>;
def R94 : SPUVecReg<94, "$94">, DwarfRegNum<[94]>;
def R95 : SPUVecReg<95, "$95">, DwarfRegNum<[95]>;
def R96 : SPUVecReg<96, "$96">, DwarfRegNum<[96]>;
def R97 : SPUVecReg<97, "$97">, DwarfRegNum<[97]>;
def R98 : SPUVecReg<98, "$98">, DwarfRegNum<[98]>;
def R99 : SPUVecReg<99, "$99">, DwarfRegNum<[99]>;
def R100 : SPUVecReg<100, "$100">, DwarfRegNum<[100]>;
def R101 : SPUVecReg<101, "$101">, DwarfRegNum<[101]>;
def R102 : SPUVecReg<102, "$102">, DwarfRegNum<[102]>;
def R103 : SPUVecReg<103, "$103">, DwarfRegNum<[103]>;
def R104 : SPUVecReg<104, "$104">, DwarfRegNum<[104]>;
def R105 : SPUVecReg<105, "$105">, DwarfRegNum<[105]>;
def R106 : SPUVecReg<106, "$106">, DwarfRegNum<[106]>;
def R107 : SPUVecReg<107, "$107">, DwarfRegNum<[107]>;
def R108 : SPUVecReg<108, "$108">, DwarfRegNum<[108]>;
def R109 : SPUVecReg<109, "$109">, DwarfRegNum<[109]>;
def R110 : SPUVecReg<110, "$110">, DwarfRegNum<[110]>;
def R111 : SPUVecReg<111, "$111">, DwarfRegNum<[111]>;
def R112 : SPUVecReg<112, "$112">, DwarfRegNum<[112]>;
def R113 : SPUVecReg<113, "$113">, DwarfRegNum<[113]>;
def R114 : SPUVecReg<114, "$114">, DwarfRegNum<[114]>;
def R115 : SPUVecReg<115, "$115">, DwarfRegNum<[115]>;
def R116 : SPUVecReg<116, "$116">, DwarfRegNum<[116]>;
def R117 : SPUVecReg<117, "$117">, DwarfRegNum<[117]>;
def R118 : SPUVecReg<118, "$118">, DwarfRegNum<[118]>;
def R119 : SPUVecReg<119, "$119">, DwarfRegNum<[119]>;
def R120 : SPUVecReg<120, "$120">, DwarfRegNum<[120]>;
def R121 : SPUVecReg<121, "$121">, DwarfRegNum<[121]>;
def R122 : SPUVecReg<122, "$122">, DwarfRegNum<[122]>;
def R123 : SPUVecReg<123, "$123">, DwarfRegNum<[123]>;
def R124 : SPUVecReg<124, "$124">, DwarfRegNum<[124]>;
def R125 : SPUVecReg<125, "$125">, DwarfRegNum<[125]>;
def R126 : SPUVecReg<126, "$126">, DwarfRegNum<[126]>;
def R127 : SPUVecReg<127, "$127">, DwarfRegNum<[127]>;
/* Need floating point status register here: */
/* def FPCSR : ... */
// The SPU's registers as 128-bit wide entities, and can function as general
// purpose registers, where the operands are in the "preferred slot":
// The non-volatile registers are allocated in reverse order, like PPC does it.
def GPRC : RegisterClass<"SPU", [i128], 128,
(add (sequence "R%u", 0, 79),
(sequence "R%u", 127, 80))>;
// The SPU's registers as 64-bit wide (double word integer) "preferred slot":
def R64C : RegisterClass<"SPU", [i64], 128, (add GPRC)>;
// The SPU's registers as 64-bit wide (double word) FP "preferred slot":
def R64FP : RegisterClass<"SPU", [f64], 128, (add GPRC)>;
// The SPU's registers as 32-bit wide (word) "preferred slot":
def R32C : RegisterClass<"SPU", [i32], 128, (add GPRC)>;
// The SPU's registers as single precision floating point "preferred slot":
def R32FP : RegisterClass<"SPU", [f32], 128, (add GPRC)>;
// The SPU's registers as 16-bit wide (halfword) "preferred slot":
def R16C : RegisterClass<"SPU", [i16], 128, (add GPRC)>;
// The SPU's registers as 8-bit wide (byte) "preferred slot":
def R8C : RegisterClass<"SPU", [i8], 128, (add GPRC)>;
// The SPU's registers as vector registers:
def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
(add GPRC)>;

View File

@ -1,19 +0,0 @@
//===- SPURegisterNames.h - Wrapper header for SPU register names -*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_REGISTER_NAMES_H
#define SPU_REGISTER_NAMES_H
// Define symbolic names for Cell registers. This defines a mapping from
// register name to register number.
//
#define GET_REGINFO_ENUM
#include "SPUGenRegisterInfo.inc"
#endif

View File

@ -1,59 +0,0 @@
//===-- SPUSchedule.td - Cell Scheduling Definitions -------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Even pipeline:
def EVEN_UNIT : FuncUnit; // Even execution unit: (PC & 0x7 == 000)
def ODD_UNIT : FuncUnit; // Odd execution unit: (PC & 0x7 == 100)
//===----------------------------------------------------------------------===//
// Instruction Itinerary classes used for Cell SPU
//===----------------------------------------------------------------------===//
def LoadStore : InstrItinClass; // ODD_UNIT
def BranchHints : InstrItinClass; // ODD_UNIT
def BranchResolv : InstrItinClass; // ODD_UNIT
def ChanOpSPR : InstrItinClass; // ODD_UNIT
def ShuffleOp : InstrItinClass; // ODD_UNIT
def SelectOp : InstrItinClass; // ODD_UNIT
def GatherOp : InstrItinClass; // ODD_UNIT
def LoadNOP : InstrItinClass; // ODD_UNIT
def ExecNOP : InstrItinClass; // EVEN_UNIT
def SPrecFP : InstrItinClass; // EVEN_UNIT
def DPrecFP : InstrItinClass; // EVEN_UNIT
def FPInt : InstrItinClass; // EVEN_UNIT (FP<->integer)
def ByteOp : InstrItinClass; // EVEN_UNIT
def IntegerOp : InstrItinClass; // EVEN_UNIT
def IntegerMulDiv: InstrItinClass; // EVEN_UNIT
def RotShiftVec : InstrItinClass; // EVEN_UNIT Inter vector
def RotShiftQuad : InstrItinClass; // ODD_UNIT Entire quad
def ImmLoad : InstrItinClass; // EVEN_UNIT
/* Note: The itinerary for the Cell SPU is somewhat contrived... */
def SPUItineraries : ProcessorItineraries<[ODD_UNIT, EVEN_UNIT], [], [
InstrItinData<LoadStore , [InstrStage<6, [ODD_UNIT]>]>,
InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>,
InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>,
InstrItinData<ChanOpSPR , [InstrStage<6, [ODD_UNIT]>]>,
InstrItinData<ShuffleOp , [InstrStage<4, [ODD_UNIT]>]>,
InstrItinData<SelectOp , [InstrStage<4, [ODD_UNIT]>]>,
InstrItinData<GatherOp , [InstrStage<4, [ODD_UNIT]>]>,
InstrItinData<LoadNOP , [InstrStage<1, [ODD_UNIT]>]>,
InstrItinData<ExecNOP , [InstrStage<1, [EVEN_UNIT]>]>,
InstrItinData<SPrecFP , [InstrStage<6, [EVEN_UNIT]>]>,
InstrItinData<DPrecFP , [InstrStage<13, [EVEN_UNIT]>]>,
InstrItinData<FPInt , [InstrStage<2, [EVEN_UNIT]>]>,
InstrItinData<ByteOp , [InstrStage<4, [EVEN_UNIT]>]>,
InstrItinData<IntegerOp , [InstrStage<2, [EVEN_UNIT]>]>,
InstrItinData<RotShiftVec , [InstrStage<4, [EVEN_UNIT]>]>,
InstrItinData<RotShiftQuad, [InstrStage<4, [ODD_UNIT]>]>,
InstrItinData<IntegerMulDiv,[InstrStage<7, [EVEN_UNIT]>]>,
InstrItinData<ImmLoad , [InstrStage<2, [EVEN_UNIT]>]>
]>;

View File

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

View File

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

View File

@ -1,65 +0,0 @@
//===-- SPUSubtarget.cpp - STI Cell SPU 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 CellSPU-specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#include "SPUSubtarget.h"
#include "SPU.h"
#include "SPURegisterInfo.h"
#include "llvm/Support/TargetRegistry.h"
#define GET_SUBTARGETINFO_TARGET_DESC
#define GET_SUBTARGETINFO_CTOR
#include "SPUGenSubtargetInfo.inc"
using namespace llvm;
SPUSubtarget::SPUSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS) :
SPUGenSubtargetInfo(TT, CPU, FS),
StackAlignment(16),
ProcDirective(SPU::DEFAULT_PROC),
UseLargeMem(false)
{
// Should be the target SPU processor type. For now, since there's only
// one, simply default to the current "v0" default:
std::string default_cpu("v0");
// Parse features string.
ParseSubtargetFeatures(default_cpu, FS);
// Initialize scheduling itinerary for the specified CPU.
InstrItins = getInstrItineraryForCPU(default_cpu);
}
/// SetJITMode - This is called to inform the subtarget info that we are
/// producing code for the JIT.
void SPUSubtarget::SetJITMode() {
}
/// Enable PostRA scheduling for optimization levels -O2 and -O3.
bool SPUSubtarget::enablePostRAScheduler(
CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const {
Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL;
// CriticalPathsRCs seems to be the set of
// RegisterClasses that antidep breakings are performed for.
// Do it for all register classes
CriticalPathRCs.clear();
CriticalPathRCs.push_back(&SPU::R8CRegClass);
CriticalPathRCs.push_back(&SPU::R16CRegClass);
CriticalPathRCs.push_back(&SPU::R32CRegClass);
CriticalPathRCs.push_back(&SPU::R32FPRegClass);
CriticalPathRCs.push_back(&SPU::R64CRegClass);
CriticalPathRCs.push_back(&SPU::VECREGRegClass);
return OptLevel >= CodeGenOpt::Default;
}

View File

@ -1,97 +0,0 @@
//===-- SPUSubtarget.h - Define Subtarget for the Cell SPU ------*- 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 Cell SPU-specific subclass of TargetSubtargetInfo.
//
//===----------------------------------------------------------------------===//
#ifndef CELLSUBTARGET_H
#define CELLSUBTARGET_H
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/MC/MCInstrItineraries.h"
#include <string>
#define GET_SUBTARGETINFO_HEADER
#include "SPUGenSubtargetInfo.inc"
namespace llvm {
class GlobalValue;
class StringRef;
namespace SPU {
enum {
PROC_NONE,
DEFAULT_PROC
};
}
class SPUSubtarget : public SPUGenSubtargetInfo {
protected:
/// stackAlignment - The minimum alignment known to hold of the stack frame
/// on entry to the function and which must be maintained by every function.
unsigned StackAlignment;
/// Selected instruction itineraries (one entry per itinerary class.)
InstrItineraryData InstrItins;
/// Which SPU processor (this isn't really used, but it's there to keep
/// the C compiler happy)
unsigned ProcDirective;
/// Use (assume) large memory -- effectively disables the LQA/STQA
/// instructions that assume 259K local store.
bool UseLargeMem;
public:
/// This constructor initializes the data members to match that
/// of the specified triple.
///
SPUSubtarget(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);
/// SetJITMode - This is called to inform the subtarget info that we are
/// producing code for the JIT.
void SetJITMode();
/// getStackAlignment - Returns the minimum alignment known to hold of the
/// stack frame on entry to the function and which must be maintained by
/// every function for this subtarget.
unsigned getStackAlignment() const { return StackAlignment; }
/// getInstrItins - Return the instruction itineraies based on subtarget
/// selection.
const InstrItineraryData &getInstrItineraryData() const {
return InstrItins;
}
/// Use large memory addressing predicate
bool usingLargeMem() const {
return UseLargeMem;
}
/// getDataLayoutString - Return the pointer size and type alignment
/// properties of this subtarget.
const char *getDataLayoutString() const {
return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
"-i16:16:128-i8:8:128-i1:8:128-a:0:128-v64:64:128-v128:128:128"
"-s:128:128-n32:64";
}
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const;
};
} // End llvm namespace
#endif

View File

@ -1,94 +0,0 @@
//===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Top-level implementation for the Cell SPU target.
//
//===----------------------------------------------------------------------===//
#include "SPUTargetMachine.h"
#include "SPU.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
extern "C" void LLVMInitializeCellSPUTarget() {
// Register the target.
RegisterTargetMachine<SPUTargetMachine> X(TheCellSPUTarget);
}
const std::pair<unsigned, int> *
SPUFrameLowering::getCalleeSaveSpillSlots(unsigned &NumEntries) const {
NumEntries = 1;
return &LR[0];
}
SPUTargetMachine::SPUTargetMachine(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(Subtarget.getDataLayoutString()),
InstrInfo(*this),
FrameLowering(Subtarget),
TLInfo(*this),
TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()),
STTI(&TLInfo), VTTI(&TLInfo) {
}
//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//
namespace {
/// SPU Code Generator Pass Configuration Options.
class SPUPassConfig : public TargetPassConfig {
public:
SPUPassConfig(SPUTargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
SPUTargetMachine &getSPUTargetMachine() const {
return getTM<SPUTargetMachine>();
}
virtual bool addInstSelector();
virtual bool addPreEmitPass();
};
} // namespace
TargetPassConfig *SPUTargetMachine::createPassConfig(PassManagerBase &PM) {
return new SPUPassConfig(this, PM);
}
bool SPUPassConfig::addInstSelector() {
// Install an instruction selector.
addPass(createSPUISelDag(getSPUTargetMachine()));
return false;
}
// passes to run just before printing the assembly
bool SPUPassConfig::addPreEmitPass() {
// load the TCE instruction scheduler, if available via
// loaded plugins
typedef llvm::FunctionPass* (*BuilderFunc)(const char*);
BuilderFunc schedulerCreator =
(BuilderFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
"createTCESchedulerPass");
if (schedulerCreator != NULL)
addPass(schedulerCreator("cellspu"));
//align instructions with nops/lnops for dual issue
addPass(createSPUNopFillerPass(getSPUTargetMachine()));
return true;
}

View File

@ -1,96 +0,0 @@
//===-- SPUTargetMachine.h - Define TargetMachine for Cell SPU --*- 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 CellSPU-specific subclass of TargetMachine.
//
//===----------------------------------------------------------------------===//
#ifndef SPU_TARGETMACHINE_H
#define SPU_TARGETMACHINE_H
#include "SPUSubtarget.h"
#include "SPUInstrInfo.h"
#include "SPUISelLowering.h"
#include "SPUSelectionDAGInfo.h"
#include "SPUFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetTransformImpl.h"
#include "llvm/DataLayout.h"
namespace llvm {
/// SPUTargetMachine
///
class SPUTargetMachine : public LLVMTargetMachine {
SPUSubtarget Subtarget;
const DataLayout DL;
SPUInstrInfo InstrInfo;
SPUFrameLowering FrameLowering;
SPUTargetLowering TLInfo;
SPUSelectionDAGInfo TSInfo;
InstrItineraryData InstrItins;
ScalarTargetTransformImpl STTI;
VectorTargetTransformImpl VTTI;
public:
SPUTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
/// Return the subtarget implementation object
virtual const SPUSubtarget *getSubtargetImpl() const {
return &Subtarget;
}
virtual const SPUInstrInfo *getInstrInfo() const {
return &InstrInfo;
}
virtual const SPUFrameLowering *getFrameLowering() const {
return &FrameLowering;
}
/*!
\note Cell SPU does not support JIT today. It could support JIT at some
point.
*/
virtual TargetJITInfo *getJITInfo() {
return NULL;
}
virtual const SPUTargetLowering *getTargetLowering() const {
return &TLInfo;
}
virtual const SPUSelectionDAGInfo* getSelectionDAGInfo() const {
return &TSInfo;
}
virtual const SPURegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}
virtual const DataLayout *getDataLayout() const {
return &DL;
}
virtual const InstrItineraryData *getInstrItineraryData() const {
return &InstrItins;
}
virtual const ScalarTargetTransformInfo *getScalarTargetTransformInfo()const {
return &STTI;
}
virtual const VectorTargetTransformInfo *getVectorTargetTransformInfo()const {
return &VTTI;
}
// Pass Pipeline Configuration
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);
};
} // end namespace llvm
#endif

View File

@ -1,7 +0,0 @@
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. )
add_llvm_library(LLVMCellSPUInfo
CellSPUTargetInfo.cpp
)
add_dependencies(LLVMCellSPUInfo CellSPUCommonTableGen)

View File

@ -1,20 +0,0 @@
//===-- CellSPUTargetInfo.cpp - CellSPU Target Implementation -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "SPU.h"
#include "llvm/Module.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
Target llvm::TheCellSPUTarget;
extern "C" void LLVMInitializeCellSPUTargetInfo() {
RegisterTarget<Triple::cellspu>
X(TheCellSPUTarget, "cellspu", "STI CBEA Cell SPU [experimental]");
}

View File

@ -1,23 +0,0 @@
;===- ./lib/Target/CellSPU/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 = CellSPUInfo
parent = CellSPU
required_libraries = MC Support Target
add_to_library_groups = CellSPU

View File

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

@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
subdirectories = ARM CellSPU CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC Sparc X86 XCore
subdirectories = ARM CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC Sparc 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,31 +0,0 @@
; RUN: llc < %s -march=cellspu -o - | grep brz
; PR3274
target datalayout = "E-p:32:32:128-i1:8:128-i8:8:128-i16:16:128-i32:32:128-i64:32:128-f32:32:128-f64:64:128-v64:64:64-v128:128:128-a0:0:128-s0:128:128"
target triple = "spu"
%struct.anon = type { i64 }
%struct.fp_number_type = type { i32, i32, i32, [4 x i8], %struct.anon }
define double @__floatunsidf(i32 %arg_a) nounwind {
entry:
%in = alloca %struct.fp_number_type, align 16
%0 = getelementptr %struct.fp_number_type* %in, i32 0, i32 1
store i32 0, i32* %0, align 4
%1 = icmp eq i32 %arg_a, 0
%2 = getelementptr %struct.fp_number_type* %in, i32 0, i32 0
br i1 %1, label %bb, label %bb1
bb: ; preds = %entry
store i32 2, i32* %2, align 8
br label %bb7
bb1: ; preds = %entry
ret double 0.0
bb7: ; preds = %bb5, %bb1, %bb
ret double 1.0
}
; declare i32 @llvm.ctlz.i32(i32) nounwind readnone
declare double @__pack_d(%struct.fp_number_type*)

View File

@ -1,28 +0,0 @@
; RUN: llc -O0 -march=cellspu -asm-verbose < %s | FileCheck %s
; Check that DEBUG_VALUE comments come through on a variety of targets.
define i32 @main() nounwind ssp {
entry:
; CHECK: DEBUG_VALUE
call void @llvm.dbg.value(metadata !6, i64 0, metadata !7), !dbg !9
ret i32 0, !dbg !10
}
declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
!llvm.dbg.sp = !{!0}
!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"main", metadata !"main", metadata !"", metadata !1, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, null, i32 0, i1 false, i32 ()* @main} ; [ DW_TAG_subprogram ]
!1 = metadata !{i32 589865, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !2} ; [ DW_TAG_file_type ]
!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/x.c", metadata !"/Users/manav", metadata !"clang version 2.9 (trunk 120996)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
!4 = metadata !{metadata !5}
!5 = metadata !{i32 589860, metadata !2, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!6 = metadata !{i32 0}
!7 = metadata !{i32 590080, metadata !8, metadata !"i", metadata !1, i32 3, metadata !5, i32 0} ; [ DW_TAG_auto_variable ]
!8 = metadata !{i32 589835, metadata !0, i32 2, i32 12, metadata !1, i32 0} ; [ DW_TAG_lexical_block ]
!9 = metadata !{i32 3, i32 11, metadata !8, null}
!10 = metadata !{i32 4, i32 2, metadata !8, null}

View File

@ -1,282 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep and %t1.s | count 234
; RUN: grep andc %t1.s | count 85
; RUN: grep andi %t1.s | count 37
; RUN: grep andhi %t1.s | count 30
; RUN: grep andbi %t1.s | count 4
; CellSPU legalization is over-sensitive to Legalize's traversal order.
; XFAIL: *
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; AND instruction generation:
define <4 x i32> @and_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = and <4 x i32> %arg1, %arg2
ret <4 x i32> %A
}
define <4 x i32> @and_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = and <4 x i32> %arg2, %arg1
ret <4 x i32> %A
}
define <8 x i16> @and_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = and <8 x i16> %arg1, %arg2
ret <8 x i16> %A
}
define <8 x i16> @and_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = and <8 x i16> %arg2, %arg1
ret <8 x i16> %A
}
define <16 x i8> @and_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = and <16 x i8> %arg2, %arg1
ret <16 x i8> %A
}
define <16 x i8> @and_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = and <16 x i8> %arg1, %arg2
ret <16 x i8> %A
}
define i32 @and_i32_1(i32 %arg1, i32 %arg2) {
%A = and i32 %arg2, %arg1
ret i32 %A
}
define i32 @and_i32_2(i32 %arg1, i32 %arg2) {
%A = and i32 %arg1, %arg2
ret i32 %A
}
define i16 @and_i16_1(i16 %arg1, i16 %arg2) {
%A = and i16 %arg2, %arg1
ret i16 %A
}
define i16 @and_i16_2(i16 %arg1, i16 %arg2) {
%A = and i16 %arg1, %arg2
ret i16 %A
}
define i8 @and_i8_1(i8 %arg1, i8 %arg2) {
%A = and i8 %arg2, %arg1
ret i8 %A
}
define i8 @and_i8_2(i8 %arg1, i8 %arg2) {
%A = and i8 %arg1, %arg2
ret i8 %A
}
; ANDC instruction generation:
define <4 x i32> @andc_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg2, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %arg1, %A
ret <4 x i32> %B
}
define <4 x i32> @andc_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg1, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %arg2, %A
ret <4 x i32> %B
}
define <4 x i32> @andc_v4i32_3(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg1, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %arg2
ret <4 x i32> %B
}
define <8 x i16> @andc_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = xor <8 x i16> %arg2, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %arg1, %A
ret <8 x i16> %B
}
define <8 x i16> @andc_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = xor <8 x i16> %arg1, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %arg2, %A
ret <8 x i16> %B
}
define <16 x i8> @andc_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg1, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %arg2, %A
ret <16 x i8> %B
}
define <16 x i8> @andc_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg2, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %arg1, %A
ret <16 x i8> %B
}
define <16 x i8> @andc_v16i8_3(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg2, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %A, %arg1
ret <16 x i8> %B
}
define i32 @andc_i32_1(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg2, -1
%B = and i32 %A, %arg1
ret i32 %B
}
define i32 @andc_i32_2(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg1, -1
%B = and i32 %A, %arg2
ret i32 %B
}
define i32 @andc_i32_3(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg2, -1
%B = and i32 %arg1, %A
ret i32 %B
}
define i16 @andc_i16_1(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg2, -1
%B = and i16 %A, %arg1
ret i16 %B
}
define i16 @andc_i16_2(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg1, -1
%B = and i16 %A, %arg2
ret i16 %B
}
define i16 @andc_i16_3(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg2, -1
%B = and i16 %arg1, %A
ret i16 %B
}
define i8 @andc_i8_1(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg2, -1
%B = and i8 %A, %arg1
ret i8 %B
}
define i8 @andc_i8_2(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg1, -1
%B = and i8 %A, %arg2
ret i8 %B
}
define i8 @andc_i8_3(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg2, -1
%B = and i8 %arg1, %A
ret i8 %B
}
; ANDI instruction generation (i32 data type):
define <4 x i32> @andi_v4i32_1(<4 x i32> %in) {
%tmp2 = and <4 x i32> %in, < i32 511, i32 511, i32 511, i32 511 >
ret <4 x i32> %tmp2
}
define <4 x i32> @andi_v4i32_2(<4 x i32> %in) {
%tmp2 = and <4 x i32> %in, < i32 510, i32 510, i32 510, i32 510 >
ret <4 x i32> %tmp2
}
define <4 x i32> @andi_v4i32_3(<4 x i32> %in) {
%tmp2 = and <4 x i32> %in, < i32 -1, i32 -1, i32 -1, i32 -1 >
ret <4 x i32> %tmp2
}
define <4 x i32> @andi_v4i32_4(<4 x i32> %in) {
%tmp2 = and <4 x i32> %in, < i32 -512, i32 -512, i32 -512, i32 -512 >
ret <4 x i32> %tmp2
}
define zeroext i32 @andi_u32(i32 zeroext %in) {
%tmp37 = and i32 %in, 37
ret i32 %tmp37
}
define signext i32 @andi_i32(i32 signext %in) {
%tmp38 = and i32 %in, 37
ret i32 %tmp38
}
define i32 @andi_i32_1(i32 %in) {
%tmp37 = and i32 %in, 37
ret i32 %tmp37
}
; ANDHI instruction generation (i16 data type):
define <8 x i16> @andhi_v8i16_1(<8 x i16> %in) {
%tmp2 = and <8 x i16> %in, < i16 511, i16 511, i16 511, i16 511,
i16 511, i16 511, i16 511, i16 511 >
ret <8 x i16> %tmp2
}
define <8 x i16> @andhi_v8i16_2(<8 x i16> %in) {
%tmp2 = and <8 x i16> %in, < i16 510, i16 510, i16 510, i16 510,
i16 510, i16 510, i16 510, i16 510 >
ret <8 x i16> %tmp2
}
define <8 x i16> @andhi_v8i16_3(<8 x i16> %in) {
%tmp2 = and <8 x i16> %in, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1 >
ret <8 x i16> %tmp2
}
define <8 x i16> @andhi_v8i16_4(<8 x i16> %in) {
%tmp2 = and <8 x i16> %in, < i16 -512, i16 -512, i16 -512, i16 -512,
i16 -512, i16 -512, i16 -512, i16 -512 >
ret <8 x i16> %tmp2
}
define zeroext i16 @andhi_u16(i16 zeroext %in) {
%tmp37 = and i16 %in, 37 ; <i16> [#uses=1]
ret i16 %tmp37
}
define signext i16 @andhi_i16(i16 signext %in) {
%tmp38 = and i16 %in, 37 ; <i16> [#uses=1]
ret i16 %tmp38
}
; i8 data type (s/b ANDBI if 8-bit registers were supported):
define <16 x i8> @and_v16i8(<16 x i8> %in) {
; ANDBI generated for vector types
%tmp2 = and <16 x i8> %in, < i8 42, i8 42, i8 42, i8 42, i8 42, i8 42,
i8 42, i8 42, i8 42, i8 42, i8 42, i8 42,
i8 42, i8 42, i8 42, i8 42 >
ret <16 x i8> %tmp2
}
define zeroext i8 @and_u8(i8 zeroext %in) {
; ANDBI generated:
%tmp37 = and i8 %in, 37
ret i8 %tmp37
}
define signext i8 @and_sext8(i8 signext %in) {
; ANDBI generated
%tmp38 = and i8 %in, 37
ret i8 %tmp38
}
define i8 @and_i8(i8 %in) {
; ANDBI generated
%tmp38 = and i8 %in, 205
ret i8 %tmp38
}

View File

@ -1,34 +0,0 @@
; Test parameter passing and return values
;RUN: llc --march=cellspu %s -o - | FileCheck %s
; this fits into registers r3-r74
%paramstruct = type { i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,
i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,
i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,
i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,
i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,
i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32,i32}
define ccc i32 @test_regs( %paramstruct %prm )
{
;CHECK: lr $3, $74
;CHECK: bi $lr
%1 = extractvalue %paramstruct %prm, 71
ret i32 %1
}
define ccc i32 @test_regs_and_stack( %paramstruct %prm, i32 %stackprm )
{
;CHECK-NOT: a $3, $74, $75
%1 = extractvalue %paramstruct %prm, 71
%2 = add i32 %1, %stackprm
ret i32 %2
}
define ccc %paramstruct @test_return( i32 %param, %paramstruct %prm )
{
;CHECK: lqd {{\$[0-9]+}}, 80($sp)
;CHECK-NOT: ori {{\$[0-9]+, \$[0-9]+, 0}}
;CHECK: lr $3, $4
ret %paramstruct %prm
}

View File

@ -1,17 +0,0 @@
; RUN: llc < %s -march=cellspu -o %t1.s
; RUN: grep lqx %t1.s | count 3
; RUN: grep il %t1.s | grep -v file | count 5
; RUN: grep stqx %t1.s | count 1
define i32 @bigstack() nounwind {
entry:
%avar = alloca i32
%big_data = alloca [2048 x i32]
store i32 3840, i32* %avar, align 4
br label %return
return:
%retval = load i32* %avar
ret i32 %retval
}

View File

@ -1,11 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
@bssVar = global i32 zeroinitializer
; CHECK: .section .bss
; CHECK-NEXT: .globl
@localVar= internal global i32 zeroinitializer
; CHECK-NOT: .lcomm
; CHECK: .local
; CHECK-NEXT: .comm

View File

@ -1,49 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i32 @main() {
entry:
%a = call i32 @stub_1(i32 1, float 0x400921FA00000000)
call void @extern_stub_1(i32 %a, i32 4)
ret i32 %a
}
declare void @extern_stub_1(i32, i32)
define i32 @stub_1(i32 %x, float %y) {
; CHECK: il $3, 0
; CHECK: bi $lr
entry:
ret i32 0
}
; vararg call: ensure that all caller-saved registers are spilled to the
; stack:
define i32 @stub_2(...) {
entry:
ret i32 0
}
; check that struct is passed in r3->
; assert this by changing the second field in the struct
%0 = type { i32, i32, i32 }
declare %0 @callee()
define %0 @test_structret()
{
;CHECK: stqd $lr, 16($sp)
;CHECK: stqd $sp, -48($sp)
;CHECK: ai $sp, $sp, -48
;CHECK: brasl $lr, callee
%rv = call %0 @callee()
;CHECK: ai $4, $4, 1
;CHECK: lqd $lr, 64($sp)
;CHECK: ai $sp, $sp, 48
;CHECK: bi $lr
%oldval = extractvalue %0 %rv, 1
%newval = add i32 %oldval,1
%newrv = insertvalue %0 %rv, i32 %newval, 1
ret %0 %newrv
}

View File

@ -1,8 +0,0 @@
; RUN: llc %s -march=cellspu -o -
declare i8 @return_i8()
declare i16 @return_i16()
define void @testfunc() {
%rv1 = call i8 @return_i8()
%rv2 = call i16 @return_i16()
ret void
}

View File

@ -1,30 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep cntb %t1.s | count 3
; RUN: grep andi %t1.s | count 3
; RUN: grep rotmi %t1.s | count 2
; RUN: grep rothmi %t1.s | count 1
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
declare i8 @llvm.ctpop.i8(i8)
declare i16 @llvm.ctpop.i16(i16)
declare i32 @llvm.ctpop.i32(i32)
define i32 @test_i8(i8 %X) {
call i8 @llvm.ctpop.i8(i8 %X)
%Y = zext i8 %1 to i32
ret i32 %Y
}
define i32 @test_i16(i16 %X) {
call i16 @llvm.ctpop.i16(i16 %X)
%Y = zext i16 %1 to i32
ret i32 %Y
}
define i32 @test_i32(i32 %X) {
call i32 @llvm.ctpop.i32(i32 %X)
%Y = bitcast i32 %1 to i32
ret i32 %Y
}

View File

@ -1,22 +0,0 @@
; RUN: llc --march=cellspu %s -o - | FileCheck %s
; signed division rounds towards zero, rotma don't.
define i32 @sdivide (i32 %val )
{
; CHECK: rotmai
; CHECK: rotmi
; CHECK: a
; CHECK: rotmai
; CHECK: bi $lr
%rv = sdiv i32 %val, 4
ret i32 %rv
}
define i32 @udivide (i32 %val )
{
; CHECK: rotmi
; CHECK: bi $lr
%rv = udiv i32 %val, 4
ret i32 %rv
}

View File

@ -1,102 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep dfa %t1.s | count 2
; RUN: grep dfs %t1.s | count 2
; RUN: grep dfm %t1.s | count 6
; RUN: grep dfma %t1.s | count 2
; RUN: grep dfms %t1.s | count 2
; RUN: grep dfnms %t1.s | count 4
;
; This file includes double precision floating point arithmetic instructions
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define double @fadd(double %arg1, double %arg2) {
%A = fadd double %arg1, %arg2
ret double %A
}
define <2 x double> @fadd_vec(<2 x double> %arg1, <2 x double> %arg2) {
%A = fadd <2 x double> %arg1, %arg2
ret <2 x double> %A
}
define double @fsub(double %arg1, double %arg2) {
%A = fsub double %arg1, %arg2
ret double %A
}
define <2 x double> @fsub_vec(<2 x double> %arg1, <2 x double> %arg2) {
%A = fsub <2 x double> %arg1, %arg2
ret <2 x double> %A
}
define double @fmul(double %arg1, double %arg2) {
%A = fmul double %arg1, %arg2
ret double %A
}
define <2 x double> @fmul_vec(<2 x double> %arg1, <2 x double> %arg2) {
%A = fmul <2 x double> %arg1, %arg2
ret <2 x double> %A
}
define double @fma(double %arg1, double %arg2, double %arg3) {
%A = fmul double %arg1, %arg2
%B = fadd double %A, %arg3
ret double %B
}
define <2 x double> @fma_vec(<2 x double> %arg1, <2 x double> %arg2, <2 x double> %arg3) {
%A = fmul <2 x double> %arg1, %arg2
%B = fadd <2 x double> %A, %arg3
ret <2 x double> %B
}
define double @fms(double %arg1, double %arg2, double %arg3) {
%A = fmul double %arg1, %arg2
%B = fsub double %A, %arg3
ret double %B
}
define <2 x double> @fms_vec(<2 x double> %arg1, <2 x double> %arg2, <2 x double> %arg3) {
%A = fmul <2 x double> %arg1, %arg2
%B = fsub <2 x double> %A, %arg3
ret <2 x double> %B
}
; - (a * b - c)
define double @d_fnms_1(double %arg1, double %arg2, double %arg3) {
%A = fmul double %arg1, %arg2
%B = fsub double %A, %arg3
%C = fsub double -0.000000e+00, %B ; <double> [#uses=1]
ret double %C
}
; Annother way of getting fnms
; - ( a * b ) + c => c - (a * b)
define double @d_fnms_2(double %arg1, double %arg2, double %arg3) {
%A = fmul double %arg1, %arg2
%B = fsub double %arg3, %A
ret double %B
}
; FNMS: - (a * b - c) => c - (a * b)
define <2 x double> @d_fnms_vec_1(<2 x double> %arg1, <2 x double> %arg2, <2 x double> %arg3) {
%A = fmul <2 x double> %arg1, %arg2
%B = fsub <2 x double> %arg3, %A
ret <2 x double> %B
}
; Another way to get fnms using a constant vector
; - ( a * b - c)
define <2 x double> @d_fnms_vec_2(<2 x double> %arg1, <2 x double> %arg2, <2 x double> %arg3) {
%A = fmul <2 x double> %arg1, %arg2 ; <<2 x double>> [#uses=1]
%B = fsub <2 x double> %A, %arg3 ; <<2 x double>> [#uses=1]
%C = fsub <2 x double> < double -0.00000e+00, double -0.00000e+00 >, %B
ret <2 x double> %C
}
;define double @fdiv_1(double %arg1, double %arg2) {
; %A = fdiv double %arg1, %arg2 ; <double> [#uses=1]
; ret double %A
;}

View File

@ -1,152 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep eqv %t1.s | count 18
; RUN: grep xshw %t1.s | count 6
; RUN: grep xsbh %t1.s | count 3
; RUN: grep andi %t1.s | count 3
; Test the 'eqv' instruction, whose boolean expression is:
; (a & b) | (~a & ~b), which simplifies to
; (a & b) | ~(a | b)
; Alternatively, a ^ ~b, which the compiler will also match.
; ModuleID = 'eqv.bc'
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define <4 x i32> @equiv_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = and <4 x i32> %arg1, %arg2
%B = or <4 x i32> %arg1, %arg2
%Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 >
%C = or <4 x i32> %A, %Bnot
ret <4 x i32> %C
}
define <4 x i32> @equiv_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%B = or <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1]
%Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1]
%A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1]
%C = or <4 x i32> %A, %Bnot ; <<4 x i32>> [#uses=1]
ret <4 x i32> %C
}
define <4 x i32> @equiv_v4i32_3(<4 x i32> %arg1, <4 x i32> %arg2) {
%B = or <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1]
%A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1]
%Bnot = xor <4 x i32> %B, < i32 -1, i32 -1, i32 -1, i32 -1 > ; <<4 x i32>> [#uses=1]
%C = or <4 x i32> %A, %Bnot ; <<4 x i32>> [#uses=1]
ret <4 x i32> %C
}
define <4 x i32> @equiv_v4i32_4(<4 x i32> %arg1, <4 x i32> %arg2) {
%arg2not = xor <4 x i32> %arg2, < i32 -1, i32 -1, i32 -1, i32 -1 >
%C = xor <4 x i32> %arg1, %arg2not
ret <4 x i32> %C
}
define i32 @equiv_i32_1(i32 %arg1, i32 %arg2) {
%A = and i32 %arg1, %arg2 ; <i32> [#uses=1]
%B = or i32 %arg1, %arg2 ; <i32> [#uses=1]
%Bnot = xor i32 %B, -1 ; <i32> [#uses=1]
%C = or i32 %A, %Bnot ; <i32> [#uses=1]
ret i32 %C
}
define i32 @equiv_i32_2(i32 %arg1, i32 %arg2) {
%B = or i32 %arg1, %arg2 ; <i32> [#uses=1]
%Bnot = xor i32 %B, -1 ; <i32> [#uses=1]
%A = and i32 %arg1, %arg2 ; <i32> [#uses=1]
%C = or i32 %A, %Bnot ; <i32> [#uses=1]
ret i32 %C
}
define i32 @equiv_i32_3(i32 %arg1, i32 %arg2) {
%B = or i32 %arg1, %arg2 ; <i32> [#uses=1]
%A = and i32 %arg1, %arg2 ; <i32> [#uses=1]
%Bnot = xor i32 %B, -1 ; <i32> [#uses=1]
%C = or i32 %A, %Bnot ; <i32> [#uses=1]
ret i32 %C
}
define i32 @equiv_i32_4(i32 %arg1, i32 %arg2) {
%arg2not = xor i32 %arg2, -1
%C = xor i32 %arg1, %arg2not
ret i32 %C
}
define i32 @equiv_i32_5(i32 %arg1, i32 %arg2) {
%arg1not = xor i32 %arg1, -1
%C = xor i32 %arg2, %arg1not
ret i32 %C
}
define signext i16 @equiv_i16_1(i16 signext %arg1, i16 signext %arg2) {
%A = and i16 %arg1, %arg2 ; <i16> [#uses=1]
%B = or i16 %arg1, %arg2 ; <i16> [#uses=1]
%Bnot = xor i16 %B, -1 ; <i16> [#uses=1]
%C = or i16 %A, %Bnot ; <i16> [#uses=1]
ret i16 %C
}
define signext i16 @equiv_i16_2(i16 signext %arg1, i16 signext %arg2) {
%B = or i16 %arg1, %arg2 ; <i16> [#uses=1]
%Bnot = xor i16 %B, -1 ; <i16> [#uses=1]
%A = and i16 %arg1, %arg2 ; <i16> [#uses=1]
%C = or i16 %A, %Bnot ; <i16> [#uses=1]
ret i16 %C
}
define signext i16 @equiv_i16_3(i16 signext %arg1, i16 signext %arg2) {
%B = or i16 %arg1, %arg2 ; <i16> [#uses=1]
%A = and i16 %arg1, %arg2 ; <i16> [#uses=1]
%Bnot = xor i16 %B, -1 ; <i16> [#uses=1]
%C = or i16 %A, %Bnot ; <i16> [#uses=1]
ret i16 %C
}
define signext i8 @equiv_i8_1(i8 signext %arg1, i8 signext %arg2) {
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}
define signext i8 @equiv_i8_2(i8 signext %arg1, i8 signext %arg2) {
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}
define signext i8 @equiv_i8_3(i8 signext %arg1, i8 signext %arg2) {
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}
define zeroext i8 @equiv_u8_1(i8 zeroext %arg1, i8 zeroext %arg2) {
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}
define zeroext i8 @equiv_u8_2(i8 zeroext %arg1, i8 zeroext %arg2) {
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}
define zeroext i8 @equiv_u8_3(i8 zeroext %arg1, i8 zeroext %arg2) {
%B = or i8 %arg1, %arg2 ; <i8> [#uses=1]
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%Bnot = xor i8 %B, -1 ; <i8> [#uses=1]
%C = or i8 %A, %Bnot ; <i8> [#uses=1]
ret i8 %C
}

View File

@ -1,277 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep shufb %t1.s | count 39
; RUN: grep ilhu %t1.s | count 27
; RUN: grep iohl %t1.s | count 27
; RUN: grep lqa %t1.s | count 10
; RUN: grep shlqby %t1.s | count 12
; RUN: grep 515 %t1.s | count 1
; RUN: grep 1029 %t1.s | count 2
; RUN: grep 1543 %t1.s | count 2
; RUN: grep 2057 %t1.s | count 2
; RUN: grep 2571 %t1.s | count 2
; RUN: grep 3085 %t1.s | count 2
; RUN: grep 3599 %t1.s | count 2
; RUN: grep 32768 %t1.s | count 1
; RUN: grep 32769 %t1.s | count 1
; RUN: grep 32770 %t1.s | count 1
; RUN: grep 32771 %t1.s | count 1
; RUN: grep 32772 %t1.s | count 1
; RUN: grep 32773 %t1.s | count 1
; RUN: grep 32774 %t1.s | count 1
; RUN: grep 32775 %t1.s | count 1
; RUN: grep 32776 %t1.s | count 1
; RUN: grep 32777 %t1.s | count 1
; RUN: grep 32778 %t1.s | count 1
; RUN: grep 32779 %t1.s | count 1
; RUN: grep 32780 %t1.s | count 1
; RUN: grep 32781 %t1.s | count 1
; RUN: grep 32782 %t1.s | count 1
; RUN: grep 32783 %t1.s | count 1
; RUN: grep 32896 %t1.s | count 24
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i32 @i32_extract_0(<4 x i32> %v) {
entry:
%a = extractelement <4 x i32> %v, i32 0
ret i32 %a
}
define i32 @i32_extract_1(<4 x i32> %v) {
entry:
%a = extractelement <4 x i32> %v, i32 1
ret i32 %a
}
define i32 @i32_extract_2(<4 x i32> %v) {
entry:
%a = extractelement <4 x i32> %v, i32 2
ret i32 %a
}
define i32 @i32_extract_3(<4 x i32> %v) {
entry:
%a = extractelement <4 x i32> %v, i32 3
ret i32 %a
}
define i16 @i16_extract_0(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 0
ret i16 %a
}
define i16 @i16_extract_1(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 1
ret i16 %a
}
define i16 @i16_extract_2(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 2
ret i16 %a
}
define i16 @i16_extract_3(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 3
ret i16 %a
}
define i16 @i16_extract_4(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 4
ret i16 %a
}
define i16 @i16_extract_5(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 5
ret i16 %a
}
define i16 @i16_extract_6(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 6
ret i16 %a
}
define i16 @i16_extract_7(<8 x i16> %v) {
entry:
%a = extractelement <8 x i16> %v, i32 7
ret i16 %a
}
define i8 @i8_extract_0(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 0
ret i8 %a
}
define i8 @i8_extract_1(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 1
ret i8 %a
}
define i8 @i8_extract_2(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 2
ret i8 %a
}
define i8 @i8_extract_3(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 3
ret i8 %a
}
define i8 @i8_extract_4(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 4
ret i8 %a
}
define i8 @i8_extract_5(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 5
ret i8 %a
}
define i8 @i8_extract_6(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 6
ret i8 %a
}
define i8 @i8_extract_7(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 7
ret i8 %a
}
define i8 @i8_extract_8(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 8
ret i8 %a
}
define i8 @i8_extract_9(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 9
ret i8 %a
}
define i8 @i8_extract_10(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 10
ret i8 %a
}
define i8 @i8_extract_11(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 11
ret i8 %a
}
define i8 @i8_extract_12(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 12
ret i8 %a
}
define i8 @i8_extract_13(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 13
ret i8 %a
}
define i8 @i8_extract_14(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 14
ret i8 %a
}
define i8 @i8_extract_15(<16 x i8> %v) {
entry:
%a = extractelement <16 x i8> %v, i32 15
ret i8 %a
}
;;--------------------------------------------------------------------------
;; extract element, variable index:
;;--------------------------------------------------------------------------
define i8 @extract_varadic_i8(i32 %i) nounwind readnone {
entry:
%0 = extractelement <16 x i8> < i8 0, i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15>, i32 %i
ret i8 %0
}
define i8 @extract_varadic_i8_1(<16 x i8> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <16 x i8> %v, i32 %i
ret i8 %0
}
define i16 @extract_varadic_i16(i32 %i) nounwind readnone {
entry:
%0 = extractelement <8 x i16> < i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, i32 %i
ret i16 %0
}
define i16 @extract_varadic_i16_1(<8 x i16> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <8 x i16> %v, i32 %i
ret i16 %0
}
define i32 @extract_varadic_i32(i32 %i) nounwind readnone {
entry:
%0 = extractelement <4 x i32> < i32 0, i32 1, i32 2, i32 3>, i32 %i
ret i32 %0
}
define i32 @extract_varadic_i32_1(<4 x i32> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <4 x i32> %v, i32 %i
ret i32 %0
}
define float @extract_varadic_f32(i32 %i) nounwind readnone {
entry:
%0 = extractelement <4 x float> < float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 >, i32 %i
ret float %0
}
define float @extract_varadic_f32_1(<4 x float> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <4 x float> %v, i32 %i
ret float %0
}
define i64 @extract_varadic_i64(i32 %i) nounwind readnone {
entry:
%0 = extractelement <2 x i64> < i64 0, i64 1>, i32 %i
ret i64 %0
}
define i64 @extract_varadic_i64_1(<2 x i64> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <2 x i64> %v, i32 %i
ret i64 %0
}
define double @extract_varadic_f64(i32 %i) nounwind readnone {
entry:
%0 = extractelement <2 x double> < double 1.000000e+00, double 2.000000e+00>, i32 %i
ret double %0
}
define double @extract_varadic_f64_1(<2 x double> %v, i32 %i) nounwind readnone {
entry:
%0 = extractelement <2 x double> %v, i32 %i
ret double %0
}

View File

@ -1,36 +0,0 @@
; RUN: llc --mtriple=cellspu-unknown-elf %s -o - | FileCheck %s
; Exercise the floating point comparison operators for f32:
declare double @fabs(double)
declare float @fabsf(float)
define i1 @fcmp_eq(float %arg1, float %arg2) {
; CHECK: fceq
; CHECK: bi $lr
%A = fcmp oeq float %arg1, %arg2
ret i1 %A
}
define i1 @fcmp_mag_eq(float %arg1, float %arg2) {
; CHECK: fcmeq
; CHECK: bi $lr
%1 = call float @fabsf(float %arg1) readnone
%2 = call float @fabsf(float %arg2) readnone
%3 = fcmp oeq float %1, %2
ret i1 %3
}
define i1 @test_ogt(float %a, float %b) {
; CHECK: fcgt
; CHECK: bi $lr
%cmp = fcmp ogt float %a, %b
ret i1 %cmp
}
define i1 @test_ugt(float %a, float %b) {
; CHECK: fcgt
; CHECK: bi $lr
%cmp = fcmp ugt float %a, %b
ret i1 %cmp
}

View File

@ -1,7 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
define i1 @fcmp_eq_setcc_f64(double %arg1, double %arg2) nounwind {
entry:
%A = fcmp oeq double %arg1, %arg2
ret i1 %A
}

View File

@ -1,22 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep frest %t1.s | count 2
; RUN: grep -w fi %t1.s | count 2
; RUN: grep -w fm %t1.s | count 2
; RUN: grep fma %t1.s | count 2
; RUN: grep fnms %t1.s | count 4
; RUN: grep cgti %t1.s | count 2
; RUN: grep selb %t1.s | count 2
;
; This file includes standard floating point arithmetic instructions
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define float @fdiv32(float %arg1, float %arg2) {
%A = fdiv float %arg1, %arg2
ret float %A
}
define <4 x float> @fdiv_v4f32(<4 x float> %arg1, <4 x float> %arg2) {
%A = fdiv <4 x float> %arg1, %arg2
ret <4 x float> %A
}

View File

@ -1,42 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep 32768 %t1.s | count 2
; RUN: grep xor %t1.s | count 4
; RUN: grep and %t1.s | count 2
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define double @fneg_dp(double %X) {
%Y = fsub double -0.000000e+00, %X
ret double %Y
}
define <2 x double> @fneg_dp_vec(<2 x double> %X) {
%Y = fsub <2 x double> < double -0.0000e+00, double -0.0000e+00 >, %X
ret <2 x double> %Y
}
define float @fneg_sp(float %X) {
%Y = fsub float -0.000000e+00, %X
ret float %Y
}
define <4 x float> @fneg_sp_vec(<4 x float> %X) {
%Y = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00,
float -0.000000e+00, float -0.000000e+00>, %X
ret <4 x float> %Y
}
declare double @fabs(double)
declare float @fabsf(float)
define double @fabs_dp(double %X) {
%Y = call double @fabs( double %X ) readnone
ret double %Y
}
define float @fabs_sp(float %X) {
%Y = call float @fabsf( float %X ) readnone
ret float %Y
}

View File

@ -1,57 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep xswd %t1.s | count 3
; RUN: grep xsbh %t1.s | count 1
; RUN: grep xshw %t1.s | count 2
; RUN: grep shufb %t1.s | count 7
; RUN: grep cg %t1.s | count 4
; RUN: grep addx %t1.s | count 4
; RUN: grep fsmbi %t1.s | count 3
; RUN: grep il %t1.s | count 2
; RUN: grep mpy %t1.s | count 10
; RUN: grep mpyh %t1.s | count 6
; RUN: grep mpyhhu %t1.s | count 2
; RUN: grep mpyu %t1.s | count 4
; ModuleID = 'stores.bc'
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i64 @sext_i64_i8(i8 %a) nounwind {
%1 = sext i8 %a to i64
ret i64 %1
}
define i64 @sext_i64_i16(i16 %a) nounwind {
%1 = sext i16 %a to i64
ret i64 %1
}
define i64 @sext_i64_i32(i32 %a) nounwind {
%1 = sext i32 %a to i64
ret i64 %1
}
define i64 @zext_i64_i8(i8 %a) nounwind {
%1 = zext i8 %a to i64
ret i64 %1
}
define i64 @zext_i64_i16(i16 %a) nounwind {
%1 = zext i16 %a to i64
ret i64 %1
}
define i64 @zext_i64_i32(i32 %a) nounwind {
%1 = zext i32 %a to i64
ret i64 %1
}
define i64 @add_i64(i64 %a, i64 %b) nounwind {
%1 = add i64 %a, %b
ret i64 %1
}
define i64 @mul_i64(i64 %a, i64 %b) nounwind {
%1 = mul i64 %a, %b
ret i64 %1
}

View File

@ -1,25 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; ModuleID = 'i8ops.bc'
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i8 @add_i8(i8 %a, i8 %b) nounwind {
%1 = add i8 %a, %b
ret i8 %1
}
define i8 @add_i8_imm(i8 %a, i8 %b) nounwind {
%1 = add i8 %a, 15
ret i8 %1
}
define i8 @sub_i8(i8 %a, i8 %b) nounwind {
%1 = sub i8 %a, %b
ret i8 %1
}
define i8 @sub_i8_imm(i8 %a, i8 %b) nounwind {
%1 = sub i8 %a, 15
ret i8 %1
}

View File

@ -1,574 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; $3 = %arg1, $4 = %arg2, $5 = %val1, $6 = %val2
; $3 = %arg1, $4 = %val1, $5 = %val2
;
; For "positive" comparisons:
; selb $3, $6, $5, <i1>
; selb $3, $5, $4, <i1>
;
; For "negative" comparisons, i.e., those where the result of the comparison
; must be inverted (setne, for example):
; selb $3, $5, $6, <i1>
; selb $3, $4, $5, <i1>
; i16 integer comparisons:
define i16 @icmp_eq_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_select_i16:
; CHECK: ceqh
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp eq i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_eq_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_setcc_i16:
; CHECK: ilhu
; CHECK: ceqh
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp eq i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_eq_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_immed01_i16:
; CHECK: ceqhi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i16 %arg1, 511
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_eq_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_immed02_i16:
; CHECK: ceqhi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i16 %arg1, -512
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_eq_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_immed03_i16:
; CHECK: ceqhi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i16 %arg1, -1
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_eq_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_eq_immed04_i16:
; CHECK: ilh
; CHECK: ceqh
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i16 %arg1, 32768
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ne_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_select_i16:
; CHECK: ceqh
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ne i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_ne_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_setcc_i16:
; CHECK: ceqh
; CHECK: ilhu
; CHECK: xorhi
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ne i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_ne_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_immed01_i16:
; CHECK: ceqhi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i16 %arg1, 511
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ne_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_immed02_i16:
; CHECK: ceqhi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i16 %arg1, -512
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ne_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_immed03_i16:
; CHECK: ceqhi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i16 %arg1, -1
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ne_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ne_immed04_i16:
; CHECK: ilh
; CHECK: ceqh
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i16 %arg1, 32768
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ugt_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_select_i16:
; CHECK: clgth
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ugt i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_ugt_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_setcc_i16:
; CHECK: ilhu
; CHECK: clgth
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ugt i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_ugt_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_immed01_i16:
; CHECK: clgthi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i16 %arg1, 500
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ugt_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_immed02_i16:
; CHECK: ceqhi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ugt i16 %arg1, 0
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ugt_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_immed03_i16:
; CHECK: clgthi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i16 %arg1, 65024
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ugt_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ugt_immed04_i16:
; CHECK: ilh
; CHECK: clgth
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i16 %arg1, 32768
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_uge_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_uge_select_i16:
; CHECK: ceqh
; CHECK: clgth
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp uge i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_uge_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_uge_setcc_i16:
; CHECK: ceqh
; CHECK: clgth
; CHECK: ilhu
; CHECK: or
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp uge i16 %arg1, %arg2
ret i1 %A
}
;; Note: icmp uge i16 %arg1, <immed> can always be transformed into
;; icmp ugt i16 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i16 @icmp_ult_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_select_i16:
; CHECK: ceqh
; CHECK: clgth
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ult i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_ult_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_setcc_i16:
; CHECK: ceqh
; CHECK: clgth
; CHECK: ilhu
; CHECK: nor
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ult i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_ult_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_immed01_i16:
; CHECK: ceqhi
; CHECK: clgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i16 %arg1, 511
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ult_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_immed02_i16:
; CHECK: ceqhi
; CHECK: clgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i16 %arg1, 65534
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ult_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_immed03_i16:
; CHECK: ceqhi
; CHECK: clgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i16 %arg1, 65024
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ult_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ult_immed04_i16:
; CHECK: ilh
; CHECK: ceqh
; CHECK: clgth
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i16 %arg1, 32769
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_ule_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ule_select_i16:
; CHECK: clgth
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ule i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_ule_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_ule_setcc_i16:
; CHECK: clgth
; CHECK: ilhu
; CHECK: xorhi
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ule i16 %arg1, %arg2
ret i1 %A
}
;; Note: icmp ule i16 %arg1, <immed> can always be transformed into
;; icmp ult i16 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i16 @icmp_sgt_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_select_i16:
; CHECK: cgth
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sgt i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_sgt_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_setcc_i16:
; CHECK: ilhu
; CHECK: cgth
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp sgt i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_sgt_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_immed01_i16:
; CHECK: cgthi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i16 %arg1, 511
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_sgt_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_immed02_i16:
; CHECK: cgthi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i16 %arg1, -1
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_sgt_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_immed03_i16:
; CHECK: cgthi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i16 %arg1, -512
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_sgt_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sgt_immed04_i16:
; CHECK: ilh
; CHECK: ceqh
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp sgt i16 %arg1, 32768
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_sge_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sge_select_i16:
; CHECK: ceqh
; CHECK: cgth
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sge i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_sge_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sge_setcc_i16:
; CHECK: ceqh
; CHECK: cgth
; CHECK: ilhu
; CHECK: or
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp sge i16 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sge i16 %arg1, <immed> can always be transformed into
;; icmp sgt i16 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i16 @icmp_slt_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_select_i16:
; CHECK: ceqh
; CHECK: cgth
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp slt i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_slt_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_setcc_i16:
; CHECK: ceqh
; CHECK: cgth
; CHECK: ilhu
; CHECK: nor
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp slt i16 %arg1, %arg2
ret i1 %A
}
define i16 @icmp_slt_immed01_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_immed01_i16:
; CHECK: ceqhi
; CHECK: cgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i16 %arg1, 511
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_slt_immed02_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_immed02_i16:
; CHECK: ceqhi
; CHECK: cgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i16 %arg1, -512
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_slt_immed03_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_immed03_i16:
; CHECK: ceqhi
; CHECK: cgthi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i16 %arg1, -1
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_slt_immed04_i16(i16 %arg1, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_slt_immed04_i16:
; CHECK: lr
; CHECK-NEXT: bi
entry:
%A = icmp slt i16 %arg1, 32768
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i16 @icmp_sle_select_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sle_select_i16:
; CHECK: cgth
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp sle i16 %arg1, %arg2
%B = select i1 %A, i16 %val1, i16 %val2
ret i16 %B
}
define i1 @icmp_sle_setcc_i16(i16 %arg1, i16 %arg2, i16 %val1, i16 %val2) nounwind {
; CHECK: icmp_sle_setcc_i16:
; CHECK: cgth
; CHECK: ilhu
; CHECK: xorhi
; CHECK: iohl
; CHECK: bi
entry:
%A = icmp sle i16 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sle i16 %arg1, <immed> can always be transformed into
;; icmp slt i16 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.

View File

@ -1,575 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; $3 = %arg1, $4 = %arg2, $5 = %val1, $6 = %val2
; $3 = %arg1, $4 = %val1, $5 = %val2
;
; For "positive" comparisons:
; selb $3, $6, $5, <i1>
; selb $3, $5, $4, <i1>
;
; For "negative" comparisons, i.e., those where the result of the comparison
; must be inverted (setne, for example):
; selb $3, $5, $6, <i1>
; selb $3, $4, $5, <i1>
; i32 integer comparisons:
define i32 @icmp_eq_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_select_i32:
; CHECK: ceq
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp eq i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_eq_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_setcc_i32:
; CHECK: ilhu
; CHECK: ceq
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp eq i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_eq_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_immed01_i32:
; CHECK: ceqi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_eq_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_immed02_i32:
; CHECK: ceqi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i32 %arg1, -512
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_eq_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_immed03_i32:
; CHECK: ceqi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i32 %arg1, -1
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_eq_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_eq_immed04_i32:
; CHECK: ila
; CHECK: ceq
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ne_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_select_i32:
; CHECK: ceq
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ne i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_ne_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_setcc_i32:
; CHECK: ceq
; CHECK: ilhu
; CHECK: xori
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ne i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_ne_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_immed01_i32:
; CHECK: ceqi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ne_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_immed02_i32:
; CHECK: ceqi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i32 %arg1, -512
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ne_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_immed03_i32:
; CHECK: ceqi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i32 %arg1, -1
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ne_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ne_immed04_i32:
; CHECK: ila
; CHECK: ceq
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ugt_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_select_i32:
; CHECK: clgt
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ugt i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_ugt_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_setcc_i32:
; CHECK: ilhu
; CHECK: clgt
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ugt i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_ugt_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_immed01_i32:
; CHECK: clgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ugt_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_immed02_i32:
; CHECK: clgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i32 %arg1, 4294966784
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ugt_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_immed03_i32:
; CHECK: clgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i32 %arg1, 4294967293
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ugt_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ugt_immed04_i32:
; CHECK: ila
; CHECK: clgt
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_uge_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_uge_select_i32:
; CHECK: ceq
; CHECK: clgt
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp uge i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_uge_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_uge_setcc_i32:
; CHECK: ceq
; CHECK: clgt
; CHECK: ilhu
; CHECK: or
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp uge i32 %arg1, %arg2
ret i1 %A
}
;; Note: icmp uge i32 %arg1, <immed> can always be transformed into
;; icmp ugt i32 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i32 @icmp_ult_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_select_i32:
; CHECK: ceq
; CHECK: clgt
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ult i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_ult_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_setcc_i32:
; CHECK: ceq
; CHECK: clgt
; CHECK: ilhu
; CHECK: nor
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ult i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_ult_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_immed01_i32:
; CHECK: ceqi
; CHECK: clgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ult_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_immed02_i32:
; CHECK: ceqi
; CHECK: clgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i32 %arg1, 4294966784
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ult_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_immed03_i32:
; CHECK: ceqi
; CHECK: clgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i32 %arg1, 4294967293
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ult_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ult_immed04_i32:
; CHECK: rotmi
; CHECK: ceqi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_ule_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ule_select_i32:
; CHECK: clgt
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ule i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_ule_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_ule_setcc_i32:
; CHECK: clgt
; CHECK: ilhu
; CHECK: xori
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp ule i32 %arg1, %arg2
ret i1 %A
}
;; Note: icmp ule i32 %arg1, <immed> can always be transformed into
;; icmp ult i32 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i32 @icmp_sgt_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_select_i32:
; CHECK: cgt
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sgt i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_sgt_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_setcc_i32:
; CHECK: ilhu
; CHECK: cgt
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp sgt i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_sgt_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_immed01_i32:
; CHECK: cgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_sgt_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_immed02_i32:
; CHECK: cgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i32 %arg1, 4294966784
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_sgt_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_immed03_i32:
; CHECK: cgti
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i32 %arg1, 4294967293
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_sgt_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sgt_immed04_i32:
; CHECK: ila
; CHECK: cgt
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_sge_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sge_select_i32:
; CHECK: ceq
; CHECK: cgt
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sge i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_sge_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sge_setcc_i32:
; CHECK: ceq
; CHECK: cgt
; CHECK: ilhu
; CHECK: or
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp sge i32 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sge i32 %arg1, <immed> can always be transformed into
;; icmp sgt i32 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i32 @icmp_slt_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_select_i32:
; CHECK: ceq
; CHECK: cgt
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp slt i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_slt_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_setcc_i32:
; CHECK: ceq
; CHECK: cgt
; CHECK: ilhu
; CHECK: nor
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp slt i32 %arg1, %arg2
ret i1 %A
}
define i32 @icmp_slt_immed01_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_immed01_i32:
; CHECK: ceqi
; CHECK: cgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i32 %arg1, 511
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_slt_immed02_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_immed02_i32:
; CHECK: ceqi
; CHECK: cgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i32 %arg1, -512
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_slt_immed03_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_immed03_i32:
; CHECK: ceqi
; CHECK: cgti
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i32 %arg1, -1
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_slt_immed04_i32(i32 %arg1, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_slt_immed04_i32:
; CHECK: ila
; CHECK: ceq
; CHECK: cgt
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i32 %arg1, 32768
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i32 @icmp_sle_select_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sle_select_i32:
; CHECK: cgt
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp sle i32 %arg1, %arg2
%B = select i1 %A, i32 %val1, i32 %val2
ret i32 %B
}
define i1 @icmp_sle_setcc_i32(i32 %arg1, i32 %arg2, i32 %val1, i32 %val2) nounwind {
; CHECK: icmp_sle_setcc_i32:
; CHECK: cgt
; CHECK: ilhu
; CHECK: xori
; CHECK: iohl
; CHECK: shufb
entry:
%A = icmp sle i32 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sle i32 %arg1, <immed> can always be transformed into
;; icmp slt i32 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.

View File

@ -1,146 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep ceq %t1.s | count 20
; RUN: grep cgti %t1.s | count 12
; RUN: grep cgt %t1.s | count 16
; RUN: grep clgt %t1.s | count 12
; RUN: grep gb %t1.s | count 12
; RUN: grep fsm %t1.s | count 10
; RUN: grep xori %t1.s | count 5
; RUN: grep selb %t1.s | count 18
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; $3 = %arg1, $4 = %arg2, $5 = %val1, $6 = %val2
; $3 = %arg1, $4 = %val1, $5 = %val2
;
; i64 integer comparisons:
define i64 @icmp_eq_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp eq i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_eq_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp eq i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_ne_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ne i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_ne_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ne i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_ugt_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ugt i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_ugt_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ugt i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_uge_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp uge i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_uge_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp uge i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_ult_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ult i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_ult_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ult i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_ule_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ule i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_ule_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp ule i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_sgt_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sgt i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_sgt_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sgt i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_sge_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sge i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_sge_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sge i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_slt_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp slt i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_slt_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp slt i64 %arg1, %arg2
ret i1 %A
}
define i64 @icmp_sle_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sle i64 %arg1, %arg2
%B = select i1 %A, i64 %val1, i64 %val2
ret i64 %B
}
define i1 @icmp_sle_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
entry:
%A = icmp sle i64 %arg1, %arg2
ret i1 %A
}

View File

@ -1,446 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; $3 = %arg1, $4 = %arg2, $5 = %val1, $6 = %val2
; $3 = %arg1, $4 = %val1, $5 = %val2
;
; For "positive" comparisons:
; selb $3, $6, $5, <i1>
; selb $3, $5, $4, <i1>
;
; For "negative" comparisons, i.e., those where the result of the comparison
; must be inverted (setne, for example):
; selb $3, $5, $6, <i1>
; selb $3, $4, $5, <i1>
; i8 integer comparisons:
define i8 @icmp_eq_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_eq_select_i8:
; CHECK: ceqb
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp eq i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_eq_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_eq_setcc_i8:
; CHECK: ceqb
; CHECK-NEXT: bi
entry:
%A = icmp eq i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_eq_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_eq_immed01_i8:
; CHECK: ceqbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i8 %arg1, 127
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_eq_immed02_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_eq_immed02_i8:
; CHECK: ceqbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i8 %arg1, -128
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_eq_immed03_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_eq_immed03_i8:
; CHECK: ceqbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp eq i8 %arg1, -1
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ne_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ne_select_i8:
; CHECK: ceqb
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ne i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_ne_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ne_setcc_i8:
; CHECK: ceqb
; CHECK: xorbi
; CHECK-NEXT: bi
entry:
%A = icmp ne i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_ne_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ne_immed01_i8:
; CHECK: ceqbi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i8 %arg1, 127
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ne_immed02_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ne_immed02_i8:
; CHECK: ceqbi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i8 %arg1, -128
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ne_immed03_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ne_immed03_i8:
; CHECK: ceqbi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp ne i8 %arg1, -1
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ugt_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ugt_select_i8:
; CHECK: clgtb
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ugt i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_ugt_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ugt_setcc_i8:
; CHECK: clgtb
; CHECK-NEXT: bi
entry:
%A = icmp ugt i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_ugt_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ugt_immed01_i8:
; CHECK: clgtbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ugt i8 %arg1, 126
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_uge_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_uge_select_i8:
; CHECK: ceqb
; CHECK: clgtb
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp uge i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_uge_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_uge_setcc_i8:
; CHECK: ceqb
; CHECK: clgtb
; CHECK: or
; CHECK-NEXT: bi
entry:
%A = icmp uge i8 %arg1, %arg2
ret i1 %A
}
;; Note: icmp uge i8 %arg1, <immed> can always be transformed into
;; icmp ugt i8 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i8 @icmp_ult_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ult_select_i8:
; CHECK: ceqb
; CHECK: clgtb
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp ult i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_ult_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ult_setcc_i8:
; CHECK: ceqb
; CHECK: clgtb
; CHECK: nor
; CHECK-NEXT: bi
entry:
%A = icmp ult i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_ult_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ult_immed01_i8:
; CHECK: ceqbi
; CHECK: clgtbi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i8 %arg1, 253
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ult_immed02_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ult_immed02_i8:
; CHECK: ceqbi
; CHECK: clgtbi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp ult i8 %arg1, 129
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_ule_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ule_select_i8:
; CHECK: clgtb
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp ule i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_ule_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_ule_setcc_i8:
; CHECK: clgtb
; CHECK: xorbi
; CHECK-NEXT: bi
entry:
%A = icmp ule i8 %arg1, %arg2
ret i1 %A
}
;; Note: icmp ule i8 %arg1, <immed> can always be transformed into
;; icmp ult i8 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i8 @icmp_sgt_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sgt_select_i8:
; CHECK: cgtb
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sgt i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_sgt_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sgt_setcc_i8:
; CHECK: cgtb
; CHECK-NEXT: bi
entry:
%A = icmp sgt i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_sgt_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sgt_immed01_i8:
; CHECK: cgtbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i8 %arg1, 96
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_sgt_immed02_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sgt_immed02_i8:
; CHECK: cgtbi
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp sgt i8 %arg1, -1
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_sgt_immed03_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sgt_immed03_i8:
; CHECK: ceqbi
; CHECK: selb $3, $4, $5, $3
entry:
%A = icmp sgt i8 %arg1, -128
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_sge_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sge_select_i8:
; CHECK: ceqb
; CHECK: cgtb
; CHECK: or
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp sge i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_sge_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sge_setcc_i8:
; CHECK: ceqb
; CHECK: cgtb
; CHECK: or
; CHECK-NEXT: bi
entry:
%A = icmp sge i8 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sge i8 %arg1, <immed> can always be transformed into
;; icmp sgt i8 %arg1, <immed>-1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.
define i8 @icmp_slt_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_slt_select_i8:
; CHECK: ceqb
; CHECK: cgtb
; CHECK: nor
; CHECK: selb $3, $6, $5, $3
entry:
%A = icmp slt i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_slt_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_slt_setcc_i8:
; CHECK: ceqb
; CHECK: cgtb
; CHECK: nor
; CHECK-NEXT: bi
entry:
%A = icmp slt i8 %arg1, %arg2
ret i1 %A
}
define i8 @icmp_slt_immed01_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_slt_immed01_i8:
; CHECK: ceqbi
; CHECK: cgtbi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i8 %arg1, 96
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_slt_immed02_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_slt_immed02_i8:
; CHECK: ceqbi
; CHECK: cgtbi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i8 %arg1, -120
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_slt_immed03_i8(i8 %arg1, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_slt_immed03_i8:
; CHECK: ceqbi
; CHECK: cgtbi
; CHECK: nor
; CHECK: selb $3, $5, $4, $3
entry:
%A = icmp slt i8 %arg1, -1
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i8 @icmp_sle_select_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sle_select_i8:
; CHECK: cgtb
; CHECK: selb $3, $5, $6, $3
entry:
%A = icmp sle i8 %arg1, %arg2
%B = select i1 %A, i8 %val1, i8 %val2
ret i8 %B
}
define i1 @icmp_sle_setcc_i8(i8 %arg1, i8 %arg2, i8 %val1, i8 %val2) nounwind {
; CHECK: icmp_sle_setcc_i8:
; CHECK: cgtb
; CHECK: xorbi
; CHECK-NEXT: bi
entry:
%A = icmp sle i8 %arg1, %arg2
ret i1 %A
}
;; Note: icmp sle i8 %arg1, <immed> can always be transformed into
;; icmp slt i8 %arg1, <immed>+1
;;
;; Consequently, even though the patterns exist to match, it's unlikely
;; they'll ever be generated.

View File

@ -1,40 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep "ilh" %t1.s | count 11
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i16 @test_1() {
%x = alloca i16, align 16
store i16 419, i16* %x ;; ILH via pattern
ret i16 0
}
define i16 @test_2() {
%x = alloca i16, align 16
store i16 1023, i16* %x ;; ILH via pattern
ret i16 0
}
define i16 @test_3() {
%x = alloca i16, align 16
store i16 -1023, i16* %x ;; ILH via pattern
ret i16 0
}
define i16 @test_4() {
%x = alloca i16, align 16
store i16 32767, i16* %x ;; ILH via pattern
ret i16 0
}
define i16 @test_5() {
%x = alloca i16, align 16
store i16 -32768, i16* %x ;; ILH via pattern
ret i16 0
}
define i16 @test_6() {
ret i16 0
}

View File

@ -1,83 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep ilhu %t1.s | count 9
; RUN: grep iohl %t1.s | count 7
; RUN: grep -w il %t1.s | count 3
; RUN: grep 16429 %t1.s | count 1
; RUN: grep 63572 %t1.s | count 1
; RUN: grep 128 %t1.s | count 1
; RUN: grep 32639 %t1.s | count 1
; RUN: grep 65535 %t1.s | count 1
; RUN: grep 16457 %t1.s | count 1
; RUN: grep 4059 %t1.s | count 1
; RUN: grep 49077 %t1.s | count 1
; RUN: grep 1267 %t1.s | count 2
; RUN: grep 16309 %t1.s | count 1
; RUN: cat %t1.s | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define i32 @test_1() {
ret i32 4784128 ;; ILHU via pattern (0x49000)
}
define i32 @test_2() {
ret i32 5308431 ;; ILHU/IOHL via pattern (0x5100f)
}
define i32 @test_3() {
ret i32 511 ;; IL via pattern
}
define i32 @test_4() {
ret i32 -512 ;; IL via pattern
}
define i32 @test_5()
{
;CHECK: test_5:
;CHECK-NOT: ila $3, 40000
;CHECK: ilhu
;CHECK: iohl
;CHECK: bi $lr
ret i32 400000
}
;; double float floatval
;; 0x4005bf0a80000000 0x402d|f854 2.718282
define float @float_const_1() {
ret float 0x4005BF0A80000000 ;; ILHU/IOHL
}
;; double float floatval
;; 0x3810000000000000 0x0080|0000 0.000000
define float @float_const_2() {
ret float 0x3810000000000000 ;; IL 128
}
;; double float floatval
;; 0x47efffffe0000000 0x7f7f|ffff NaN
define float @float_const_3() {
ret float 0x47EFFFFFE0000000 ;; ILHU/IOHL via pattern
}
;; double float floatval
;; 0x400921fb60000000 0x4049|0fdb 3.141593
define float @float_const_4() {
ret float 0x400921FB60000000 ;; ILHU/IOHL via pattern
}
;; double float floatval
;; 0xbff6a09e60000000 0xbfb5|04f3 -1.414214
define float @float_const_5() {
ret float 0xBFF6A09E60000000 ;; ILHU/IOHL via pattern
}
;; double float floatval
;; 0x3ff6a09e60000000 0x3fb5|04f3 1.414214
define float @float_const_6() {
ret float 0x3FF6A09E60000000 ;; ILHU/IOHL via pattern
}
define float @float_const_7() {
ret float 0.000000e+00 ;; IL 0 via pattern
}

View File

@ -1,95 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep lqa %t1.s | count 13
; RUN: grep ilhu %t1.s | count 15
; RUN: grep ila %t1.s | count 1
; RUN: grep -w il %t1.s | count 6
; RUN: grep shufb %t1.s | count 13
; RUN: grep 65520 %t1.s | count 1
; RUN: grep 43981 %t1.s | count 1
; RUN: grep 13702 %t1.s | count 1
; RUN: grep 28225 %t1.s | count 1
; RUN: grep 30720 %t1.s | count 1
; RUN: grep 3233857728 %t1.s | count 8
; RUN: grep 2155905152 %t1.s | count 6
; RUN: grep 66051 %t1.s | count 7
; RUN: grep 471670303 %t1.s | count 11
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; 1311768467750121234 => 0x 12345678 abcdef12 (4660,22136/43981,61202)
; 18446744073709551591 => 0x ffffffff ffffffe7 (-25)
; 18446744073708516742 => 0x ffffffff fff03586 (-1034874)
; 5308431 => 0x 00000000 0051000F
; 9223372038704560128 => 0x 80000000 6e417800
define i64 @i64_const_1() {
ret i64 1311768467750121234 ;; Constant pool spill
}
define i64 @i64_const_2() {
ret i64 18446744073709551591 ;; IL/SHUFB
}
define i64 @i64_const_3() {
ret i64 18446744073708516742 ;; IHLU/IOHL/SHUFB
}
define i64 @i64_const_4() {
ret i64 5308431 ;; ILHU/IOHL/SHUFB
}
define i64 @i64_const_5() {
ret i64 511 ;; IL/SHUFB
}
define i64 @i64_const_6() {
ret i64 -512 ;; IL/SHUFB
}
define i64 @i64_const_7() {
ret i64 9223372038704560128 ;; IHLU/IOHL/SHUFB
}
define i64 @i64_const_8() {
ret i64 0 ;; IL
}
define i64 @i64_const_9() {
ret i64 -1 ;; IL
}
define i64 @i64_const_10() {
ret i64 281470681808895 ;; IL 65535
}
; 0x4005bf0a8b145769 ->
; (ILHU 0x4005 [16389]/IOHL 0xbf0a [48906])
; (ILHU 0x8b14 [35604]/IOHL 0x5769 [22377])
define double @f64_const_1() {
ret double 0x4005bf0a8b145769 ;; ILHU/IOHL via pattern
}
define double @f64_const_2() {
ret double 0x0010000000000000
}
define double @f64_const_3() {
ret double 0x7fefffffffffffff
}
define double @f64_const_4() {
ret double 0x400921fb54442d18
}
define double @f64_const_5() {
ret double 0xbff6a09e667f3bcd ;; ILHU/IOHL via pattern
}
define double @f64_const_6() {
ret double 0x3ff6a09e667f3bcd
}
define double @f64_const_7() {
ret double 0.000000e+00
}

View File

@ -1,41 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep csflt %t1.s | count 5
; RUN: grep cuflt %t1.s | count 1
; RUN: grep xshw %t1.s | count 2
; RUN: grep xsbh %t1.s | count 1
; RUN: grep and %t1.s | count 2
; RUN: grep andi %t1.s | count 1
; RUN: grep ila %t1.s | count 1
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define float @sitofp_i32(i32 %arg1) {
%A = sitofp i32 %arg1 to float ; <float> [#uses=1]
ret float %A
}
define float @uitofp_u32(i32 %arg1) {
%A = uitofp i32 %arg1 to float ; <float> [#uses=1]
ret float %A
}
define float @sitofp_i16(i16 %arg1) {
%A = sitofp i16 %arg1 to float ; <float> [#uses=1]
ret float %A
}
define float @uitofp_i16(i16 %arg1) {
%A = uitofp i16 %arg1 to float ; <float> [#uses=1]
ret float %A
}
define float @sitofp_i8(i8 %arg1) {
%A = sitofp i8 %arg1 to float ; <float> [#uses=1]
ret float %A
}
define float @uitofp_i8(i8 %arg1) {
%A = uitofp i8 %arg1 to float ; <float> [#uses=1]
ret float %A
}

View File

@ -1,150 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep ceq %t1.s | count 30
; RUN: grep ceqb %t1.s | count 10
; RUN: grep ceqhi %t1.s | count 5
; RUN: grep ceqi %t1.s | count 5
; RUN: grep cgt %t1.s | count 30
; RUN: grep cgtb %t1.s | count 10
; RUN: grep cgthi %t1.s | count 5
; RUN: grep cgti %t1.s | count 5
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8)
declare <4 x i32> @llvm.spu.si.ceq(<4 x i32>, <4 x i32>)
declare <16 x i8> @llvm.spu.si.ceqb(<16 x i8>, <16 x i8>)
declare <8 x i16> @llvm.spu.si.ceqh(<8 x i16>, <8 x i16>)
declare <4 x i32> @llvm.spu.si.ceqi(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.ceqhi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.ceqbi(<16 x i8>, i8)
declare <4 x i32> @llvm.spu.si.cgt(<4 x i32>, <4 x i32>)
declare <16 x i8> @llvm.spu.si.cgtb(<16 x i8>, <16 x i8>)
declare <8 x i16> @llvm.spu.si.cgth(<8 x i16>, <8 x i16>)
declare <4 x i32> @llvm.spu.si.cgti(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.cgthi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.cgtbi(<16 x i8>, i8)
declare <4 x i32> @llvm.spu.si.clgt(<4 x i32>, <4 x i32>)
declare <16 x i8> @llvm.spu.si.clgtb(<16 x i8>, <16 x i8>)
declare <8 x i16> @llvm.spu.si.clgth(<8 x i16>, <8 x i16>)
declare <4 x i32> @llvm.spu.si.clgti(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.clgthi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.clgtbi(<16 x i8>, i8)
define <4 x i32> @test(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <4 x i32> @ceqtest(<4 x i32> %A, <4 x i32> %B) {
call <4 x i32> @llvm.spu.si.ceq(<4 x i32> %A, <4 x i32> %B)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @ceqhtest(<8 x i16> %A, <8 x i16> %B) {
call <8 x i16> @llvm.spu.si.ceqh(<8 x i16> %A, <8 x i16> %B)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @ceqbtest(<16 x i8> %A, <16 x i8> %B) {
call <16 x i8> @llvm.spu.si.ceqb(<16 x i8> %A, <16 x i8> %B)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}
define <4 x i32> @ceqitest(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.ceqi(<4 x i32> %A, i16 65)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @ceqhitest(<8 x i16> %A) {
call <8 x i16> @llvm.spu.si.ceqhi(<8 x i16> %A, i16 65)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @ceqbitest(<16 x i8> %A) {
call <16 x i8> @llvm.spu.si.ceqbi(<16 x i8> %A, i8 65)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}
define <4 x i32> @cgttest(<4 x i32> %A, <4 x i32> %B) {
call <4 x i32> @llvm.spu.si.cgt(<4 x i32> %A, <4 x i32> %B)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @cgthtest(<8 x i16> %A, <8 x i16> %B) {
call <8 x i16> @llvm.spu.si.cgth(<8 x i16> %A, <8 x i16> %B)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @cgtbtest(<16 x i8> %A, <16 x i8> %B) {
call <16 x i8> @llvm.spu.si.cgtb(<16 x i8> %A, <16 x i8> %B)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}
define <4 x i32> @cgtitest(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.cgti(<4 x i32> %A, i16 65)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @cgthitest(<8 x i16> %A) {
call <8 x i16> @llvm.spu.si.cgthi(<8 x i16> %A, i16 65)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @cgtbitest(<16 x i8> %A) {
call <16 x i8> @llvm.spu.si.cgtbi(<16 x i8> %A, i8 65)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}
define <4 x i32> @clgttest(<4 x i32> %A, <4 x i32> %B) {
call <4 x i32> @llvm.spu.si.clgt(<4 x i32> %A, <4 x i32> %B)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @clgthtest(<8 x i16> %A, <8 x i16> %B) {
call <8 x i16> @llvm.spu.si.clgth(<8 x i16> %A, <8 x i16> %B)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @clgtbtest(<16 x i8> %A, <16 x i8> %B) {
call <16 x i8> @llvm.spu.si.clgtb(<16 x i8> %A, <16 x i8> %B)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}
define <4 x i32> @clgtitest(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.clgti(<4 x i32> %A, i16 65)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @clgthitest(<8 x i16> %A) {
call <8 x i16> @llvm.spu.si.clgthi(<8 x i16> %A, i16 65)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}
define <16 x i8> @clgtbitest(<16 x i8> %A) {
call <16 x i8> @llvm.spu.si.clgtbi(<16 x i8> %A, i8 65)
%Y = bitcast <16 x i8> %1 to <16 x i8>
ret <16 x i8> %Y
}

View File

@ -1,94 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep fa %t1.s | count 5
; RUN: grep fs %t1.s | count 5
; RUN: grep fm %t1.s | count 15
; RUN: grep fceq %t1.s | count 5
; RUN: grep fcmeq %t1.s | count 5
; RUN: grep fcgt %t1.s | count 5
; RUN: grep fcmgt %t1.s | count 5
; RUN: grep fma %t1.s | count 5
; RUN: grep fnms %t1.s | count 5
; RUN: grep fms %t1.s | count 5
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
declare <4 x i32> @llvm.spu.si.shli(<4 x i32>, i8)
declare <4 x float> @llvm.spu.si.fa(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fs(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fm(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fceq(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fcmeq(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fcgt(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fcmgt(<4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fma(<4 x float>, <4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fnms(<4 x float>, <4 x float>, <4 x float>)
declare <4 x float> @llvm.spu.si.fms(<4 x float>, <4 x float>, <4 x float>)
define <4 x i32> @test(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.shli(<4 x i32> %A, i8 3)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <4 x float> @fatest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fa(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fstest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fs(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fmtest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fm(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fceqtest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fceq(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fcmeqtest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fcmeq(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fcgttest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fcgt(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fcmgttest(<4 x float> %A, <4 x float> %B) {
call <4 x float> @llvm.spu.si.fcmgt(<4 x float> %A, <4 x float> %B)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fmatest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
call <4 x float> @llvm.spu.si.fma(<4 x float> %A, <4 x float> %B, <4 x float> %C)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fnmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
call <4 x float> @llvm.spu.si.fnms(<4 x float> %A, <4 x float> %B, <4 x float> %C)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}
define <4 x float> @fmstest(<4 x float> %A, <4 x float> %B, <4 x float> %C) {
call <4 x float> @llvm.spu.si.fms(<4 x float> %A, <4 x float> %B, <4 x float> %C)
%Y = bitcast <4 x float> %1 to <4 x float>
ret <4 x float> %Y
}

View File

@ -1,49 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep and %t1.s | count 20
; RUN: grep andc %t1.s | count 5
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
declare <4 x i32> @llvm.spu.si.and(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.andc(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.andi(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.andhi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.andbi(<16 x i8>, i8)
declare <4 x i32> @llvm.spu.si.or(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.orc(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.ori(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.orhi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.orbi(<16 x i8>, i8)
declare <4 x i32> @llvm.spu.si.xor(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.xori(<4 x i32>, i16)
declare <8 x i16> @llvm.spu.si.xorhi(<8 x i16>, i16)
declare <16 x i8> @llvm.spu.si.xorbi(<16 x i8>, i8)
declare <4 x i32> @llvm.spu.si.nand(<4 x i32>, <4 x i32>)
declare <4 x i32> @llvm.spu.si.nor(<4 x i32>, <4 x i32>)
define <4 x i32> @andtest(<4 x i32> %A, <4 x i32> %B) {
call <4 x i32> @llvm.spu.si.and(<4 x i32> %A, <4 x i32> %B)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <4 x i32> @andctest(<4 x i32> %A, <4 x i32> %B) {
call <4 x i32> @llvm.spu.si.andc(<4 x i32> %A, <4 x i32> %B)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <4 x i32> @anditest(<4 x i32> %A) {
call <4 x i32> @llvm.spu.si.andi(<4 x i32> %A, i16 65)
%Y = bitcast <4 x i32> %1 to <4 x i32>
ret <4 x i32> %Y
}
define <8 x i16> @andhitest(<8 x i16> %A) {
call <8 x i16> @llvm.spu.si.andhi(<8 x i16> %A, i16 65)
%Y = bitcast <8 x i16> %1 to <8 x i16>
ret <8 x i16> %Y
}

View File

@ -1,21 +0,0 @@
;RUN: llc --march=cellspu -disable-cgp-branch-opts %s -o - | FileCheck %s
; This is to check that emitting jumptables doesn't crash llc
define i32 @test(i32 %param) {
entry:
;CHECK: ai {{\$.}}, $3, -1
;CHECK: clgti {{\$., \$.}}, 3
;CHECK: brnz {{\$.}},.LBB0_
switch i32 %param, label %bb2 [
i32 1, label %bb1
i32 2, label %bb2
i32 3, label %bb3
i32 4, label %bb2
]
;CHECK-NOT: # BB#2
bb1:
ret i32 1
bb2:
ret i32 2
bb3:
ret i32 %param
}

View File

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

View File

@ -1,59 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
; ModuleID = 'loads.bc'
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define <4 x float> @load_v4f32_1(<4 x float>* %a) nounwind readonly {
entry:
%tmp1 = load <4 x float>* %a
ret <4 x float> %tmp1
; CHECK: lqd $3, 0($3)
}
define <4 x float> @load_v4f32_2(<4 x float>* %a) nounwind readonly {
entry:
%arrayidx = getelementptr <4 x float>* %a, i32 1
%tmp1 = load <4 x float>* %arrayidx
ret <4 x float> %tmp1
; CHECK: lqd $3, 16($3)
}
declare <4 x i32>* @getv4f32ptr()
define <4 x i32> @func() {
;CHECK: brasl
; we need to have some instruction to move the result to safety.
; which instruction (lr, stqd...) depends on the regalloc
;CHECK: {{.*}}
;CHECK: brasl
%rv1 = call <4 x i32>* @getv4f32ptr()
%rv2 = call <4 x i32>* @getv4f32ptr()
%rv3 = load <4 x i32>* %rv1
ret <4 x i32> %rv3
}
define <4 x float> @load_undef(){
; CHECK: lqd $3, 0($3)
%val = load <4 x float>* undef
ret <4 x float> %val
}
;check that 'misaligned' loads that may span two memory chunks
;have two loads. Don't check for the bitmanipulation, as that
;might change with improved algorithms or scheduling
define i32 @load_misaligned( i32* %ptr ){
;CHECK: load_misaligned
;CHECK: lqd
;CHECK: lqd
;CHECK: bi $lr
%rv = load i32* %ptr, align 2
ret i32 %rv
}
define <4 x i32> @load_null_vec( ) {
;CHECK: lqa
;CHECK: bi $lr
%rv = load <4 x i32>* null
ret <4 x i32> %rv
}

View File

@ -1,15 +0,0 @@
; RUN: llc < %s -march=cellspu
declare {i16, i1} @llvm.smul.with.overflow.i16(i16 %a, i16 %b)
define zeroext i1 @a(i16 %x) nounwind {
%res = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %x, i16 3)
%obil = extractvalue {i16, i1} %res, 1
ret i1 %obil
}
declare {i16, i1} @llvm.umul.with.overflow.i16(i16 %a, i16 %b)
define zeroext i1 @b(i16 %x) nounwind {
%res = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %x, i16 3)
%obil = extractvalue {i16, i1} %res, 1
ret i1 %obil
}

View File

@ -1,88 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep mpy %t1.s | count 44
; RUN: grep mpyu %t1.s | count 4
; RUN: grep mpyh %t1.s | count 10
; RUN: grep mpyhh %t1.s | count 2
; RUN: grep rotma %t1.s | count 12
; RUN: grep rotmahi %t1.s | count 4
; RUN: grep and %t1.s | count 2
; RUN: grep selb %t1.s | count 6
; RUN: grep fsmbi %t1.s | count 4
; RUN: grep shli %t1.s | count 4
; RUN: grep shlhi %t1.s | count 4
; RUN: grep ila %t1.s | count 2
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; 32-bit multiply instruction generation:
define <4 x i32> @mpy_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
entry:
%A = mul <4 x i32> %arg1, %arg2
ret <4 x i32> %A
}
define <4 x i32> @mpy_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
entry:
%A = mul <4 x i32> %arg2, %arg1
ret <4 x i32> %A
}
define <8 x i16> @mpy_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
entry:
%A = mul <8 x i16> %arg1, %arg2
ret <8 x i16> %A
}
define <8 x i16> @mpy_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
entry:
%A = mul <8 x i16> %arg2, %arg1
ret <8 x i16> %A
}
define <16 x i8> @mul_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
entry:
%A = mul <16 x i8> %arg2, %arg1
ret <16 x i8> %A
}
define <16 x i8> @mul_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
entry:
%A = mul <16 x i8> %arg1, %arg2
ret <16 x i8> %A
}
define i32 @mul_i32_1(i32 %arg1, i32 %arg2) {
entry:
%A = mul i32 %arg2, %arg1
ret i32 %A
}
define i32 @mul_i32_2(i32 %arg1, i32 %arg2) {
entry:
%A = mul i32 %arg1, %arg2
ret i32 %A
}
define i16 @mul_i16_1(i16 %arg1, i16 %arg2) {
entry:
%A = mul i16 %arg2, %arg1
ret i16 %A
}
define i16 @mul_i16_2(i16 %arg1, i16 %arg2) {
entry:
%A = mul i16 %arg1, %arg2
ret i16 %A
}
define i8 @mul_i8_1(i8 %arg1, i8 %arg2) {
entry:
%A = mul i8 %arg2, %arg1
ret i8 %A
}
define i8 @mul_i8_2(i8 %arg1, i8 %arg2) {
entry:
%A = mul i8 %arg1, %arg2
ret i8 %A
}

View File

@ -1,125 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep nand %t1.s | count 90
; RUN: grep and %t1.s | count 94
; RUN: grep xsbh %t1.s | count 2
; RUN: grep xshw %t1.s | count 4
; CellSPU legalization is over-sensitive to Legalize's traversal order.
; XFAIL: *
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
define <4 x i32> @nand_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = and <4 x i32> %arg2, %arg1 ; <<4 x i32>> [#uses=1]
%B = xor <4 x i32> %A, < i32 -1, i32 -1, i32 -1, i32 -1 >
ret <4 x i32> %B
}
define <4 x i32> @nand_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = and <4 x i32> %arg1, %arg2 ; <<4 x i32>> [#uses=1]
%B = xor <4 x i32> %A, < i32 -1, i32 -1, i32 -1, i32 -1 >
ret <4 x i32> %B
}
define <8 x i16> @nand_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = and <8 x i16> %arg2, %arg1 ; <<8 x i16>> [#uses=1]
%B = xor <8 x i16> %A, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
ret <8 x i16> %B
}
define <8 x i16> @nand_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = and <8 x i16> %arg1, %arg2 ; <<8 x i16>> [#uses=1]
%B = xor <8 x i16> %A, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
ret <8 x i16> %B
}
define <16 x i8> @nand_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = and <16 x i8> %arg2, %arg1 ; <<16 x i8>> [#uses=1]
%B = xor <16 x i8> %A, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
ret <16 x i8> %B
}
define <16 x i8> @nand_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = and <16 x i8> %arg1, %arg2 ; <<16 x i8>> [#uses=1]
%B = xor <16 x i8> %A, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
ret <16 x i8> %B
}
define i32 @nand_i32_1(i32 %arg1, i32 %arg2) {
%A = and i32 %arg2, %arg1 ; <i32> [#uses=1]
%B = xor i32 %A, -1 ; <i32> [#uses=1]
ret i32 %B
}
define i32 @nand_i32_2(i32 %arg1, i32 %arg2) {
%A = and i32 %arg1, %arg2 ; <i32> [#uses=1]
%B = xor i32 %A, -1 ; <i32> [#uses=1]
ret i32 %B
}
define signext i16 @nand_i16_1(i16 signext %arg1, i16 signext %arg2) {
%A = and i16 %arg2, %arg1 ; <i16> [#uses=1]
%B = xor i16 %A, -1 ; <i16> [#uses=1]
ret i16 %B
}
define signext i16 @nand_i16_2(i16 signext %arg1, i16 signext %arg2) {
%A = and i16 %arg1, %arg2 ; <i16> [#uses=1]
%B = xor i16 %A, -1 ; <i16> [#uses=1]
ret i16 %B
}
define zeroext i16 @nand_i16u_1(i16 zeroext %arg1, i16 zeroext %arg2) {
%A = and i16 %arg2, %arg1 ; <i16> [#uses=1]
%B = xor i16 %A, -1 ; <i16> [#uses=1]
ret i16 %B
}
define zeroext i16 @nand_i16u_2(i16 zeroext %arg1, i16 zeroext %arg2) {
%A = and i16 %arg1, %arg2 ; <i16> [#uses=1]
%B = xor i16 %A, -1 ; <i16> [#uses=1]
ret i16 %B
}
define zeroext i8 @nand_i8u_1(i8 zeroext %arg1, i8 zeroext %arg2) {
%A = and i8 %arg2, %arg1 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}
define zeroext i8 @nand_i8u_2(i8 zeroext %arg1, i8 zeroext %arg2) {
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}
define signext i8 @nand_i8_1(i8 signext %arg1, i8 signext %arg2) {
%A = and i8 %arg2, %arg1 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}
define signext i8 @nand_i8_2(i8 signext %arg1, i8 signext %arg2) {
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}
define i8 @nand_i8_3(i8 %arg1, i8 %arg2) {
%A = and i8 %arg2, %arg1 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}
define i8 @nand_i8_4(i8 %arg1, i8 %arg2) {
%A = and i8 %arg1, %arg2 ; <i8> [#uses=1]
%B = xor i8 %A, -1 ; <i8> [#uses=1]
ret i8 %B
}

View File

@ -1,278 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep and %t1.s | count 2
; RUN: grep orc %t1.s | count 85
; RUN: grep ori %t1.s | count 34
; RUN: grep orhi %t1.s | count 30
; RUN: grep orbi %t1.s | count 15
; RUN: FileCheck %s < %t1.s
; CellSPU legalization is over-sensitive to Legalize's traversal order.
; XFAIL: *
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; OR instruction generation:
define <4 x i32> @or_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = or <4 x i32> %arg1, %arg2
ret <4 x i32> %A
}
define <4 x i32> @or_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = or <4 x i32> %arg2, %arg1
ret <4 x i32> %A
}
define <8 x i16> @or_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = or <8 x i16> %arg1, %arg2
ret <8 x i16> %A
}
define <8 x i16> @or_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = or <8 x i16> %arg2, %arg1
ret <8 x i16> %A
}
define <16 x i8> @or_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = or <16 x i8> %arg2, %arg1
ret <16 x i8> %A
}
define <16 x i8> @or_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = or <16 x i8> %arg1, %arg2
ret <16 x i8> %A
}
define i32 @or_i32_1(i32 %arg1, i32 %arg2) {
%A = or i32 %arg2, %arg1
ret i32 %A
}
define i32 @or_i32_2(i32 %arg1, i32 %arg2) {
%A = or i32 %arg1, %arg2
ret i32 %A
}
define i16 @or_i16_1(i16 %arg1, i16 %arg2) {
%A = or i16 %arg2, %arg1
ret i16 %A
}
define i16 @or_i16_2(i16 %arg1, i16 %arg2) {
%A = or i16 %arg1, %arg2
ret i16 %A
}
define i8 @or_i8_1(i8 %arg1, i8 %arg2) {
%A = or i8 %arg2, %arg1
ret i8 %A
}
define i8 @or_i8_2(i8 %arg1, i8 %arg2) {
%A = or i8 %arg1, %arg2
ret i8 %A
}
; ORC instruction generation:
define <4 x i32> @orc_v4i32_1(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg2, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = or <4 x i32> %arg1, %A
ret <4 x i32> %B
}
define <4 x i32> @orc_v4i32_2(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg1, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = or <4 x i32> %arg2, %A
ret <4 x i32> %B
}
define <4 x i32> @orc_v4i32_3(<4 x i32> %arg1, <4 x i32> %arg2) {
%A = xor <4 x i32> %arg1, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = or <4 x i32> %A, %arg2
ret <4 x i32> %B
}
define <8 x i16> @orc_v8i16_1(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = xor <8 x i16> %arg2, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = or <8 x i16> %arg1, %A
ret <8 x i16> %B
}
define <8 x i16> @orc_v8i16_2(<8 x i16> %arg1, <8 x i16> %arg2) {
%A = xor <8 x i16> %arg1, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = or <8 x i16> %arg2, %A
ret <8 x i16> %B
}
define <16 x i8> @orc_v16i8_1(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg1, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = or <16 x i8> %arg2, %A
ret <16 x i8> %B
}
define <16 x i8> @orc_v16i8_2(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg2, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = or <16 x i8> %arg1, %A
ret <16 x i8> %B
}
define <16 x i8> @orc_v16i8_3(<16 x i8> %arg1, <16 x i8> %arg2) {
%A = xor <16 x i8> %arg2, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = or <16 x i8> %A, %arg1
ret <16 x i8> %B
}
define i32 @orc_i32_1(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg2, -1
%B = or i32 %A, %arg1
ret i32 %B
}
define i32 @orc_i32_2(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg1, -1
%B = or i32 %A, %arg2
ret i32 %B
}
define i32 @orc_i32_3(i32 %arg1, i32 %arg2) {
%A = xor i32 %arg2, -1
%B = or i32 %arg1, %A
ret i32 %B
}
define i16 @orc_i16_1(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg2, -1
%B = or i16 %A, %arg1
ret i16 %B
}
define i16 @orc_i16_2(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg1, -1
%B = or i16 %A, %arg2
ret i16 %B
}
define i16 @orc_i16_3(i16 %arg1, i16 %arg2) {
%A = xor i16 %arg2, -1
%B = or i16 %arg1, %A
ret i16 %B
}
define i8 @orc_i8_1(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg2, -1
%B = or i8 %A, %arg1
ret i8 %B
}
define i8 @orc_i8_2(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg1, -1
%B = or i8 %A, %arg2
ret i8 %B
}
define i8 @orc_i8_3(i8 %arg1, i8 %arg2) {
%A = xor i8 %arg2, -1
%B = or i8 %arg1, %A
ret i8 %B
}
; ORI instruction generation (i32 data type):
define <4 x i32> @ori_v4i32_1(<4 x i32> %in) {
%tmp2 = or <4 x i32> %in, < i32 511, i32 511, i32 511, i32 511 >
ret <4 x i32> %tmp2
}
define <4 x i32> @ori_v4i32_2(<4 x i32> %in) {
%tmp2 = or <4 x i32> %in, < i32 510, i32 510, i32 510, i32 510 >
ret <4 x i32> %tmp2
}
define <4 x i32> @ori_v4i32_3(<4 x i32> %in) {
%tmp2 = or <4 x i32> %in, < i32 -1, i32 -1, i32 -1, i32 -1 >
ret <4 x i32> %tmp2
}
define <4 x i32> @ori_v4i32_4(<4 x i32> %in) {
%tmp2 = or <4 x i32> %in, < i32 -512, i32 -512, i32 -512, i32 -512 >
ret <4 x i32> %tmp2
}
define zeroext i32 @ori_u32(i32 zeroext %in) {
%tmp37 = or i32 %in, 37 ; <i32> [#uses=1]
ret i32 %tmp37
}
define signext i32 @ori_i32(i32 signext %in) {
%tmp38 = or i32 %in, 37 ; <i32> [#uses=1]
ret i32 %tmp38
}
define i32 @ori_i32_600(i32 %in) {
;600 does not fit into 'ori' immediate field
;CHECK: ori_i32_600
;CHECK: il
;CHECK: ori
%tmp = or i32 %in, 600
ret i32 %tmp
}
; ORHI instruction generation (i16 data type):
define <8 x i16> @orhi_v8i16_1(<8 x i16> %in) {
%tmp2 = or <8 x i16> %in, < i16 511, i16 511, i16 511, i16 511,
i16 511, i16 511, i16 511, i16 511 >
ret <8 x i16> %tmp2
}
define <8 x i16> @orhi_v8i16_2(<8 x i16> %in) {
%tmp2 = or <8 x i16> %in, < i16 510, i16 510, i16 510, i16 510,
i16 510, i16 510, i16 510, i16 510 >
ret <8 x i16> %tmp2
}
define <8 x i16> @orhi_v8i16_3(<8 x i16> %in) {
%tmp2 = or <8 x i16> %in, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1 >
ret <8 x i16> %tmp2
}
define <8 x i16> @orhi_v8i16_4(<8 x i16> %in) {
%tmp2 = or <8 x i16> %in, < i16 -512, i16 -512, i16 -512, i16 -512,
i16 -512, i16 -512, i16 -512, i16 -512 >
ret <8 x i16> %tmp2
}
define zeroext i16 @orhi_u16(i16 zeroext %in) {
%tmp37 = or i16 %in, 37 ; <i16> [#uses=1]
ret i16 %tmp37
}
define signext i16 @orhi_i16(i16 signext %in) {
%tmp38 = or i16 %in, 37 ; <i16> [#uses=1]
ret i16 %tmp38
}
; ORBI instruction generation (i8 data type):
define <16 x i8> @orbi_v16i8(<16 x i8> %in) {
%tmp2 = or <16 x i8> %in, < i8 42, i8 42, i8 42, i8 42, i8 42, i8 42,
i8 42, i8 42, i8 42, i8 42, i8 42, i8 42,
i8 42, i8 42, i8 42, i8 42 >
ret <16 x i8> %tmp2
}
define zeroext i8 @orbi_u8(i8 zeroext %in) {
%tmp37 = or i8 %in, 37 ; <i8> [#uses=1]
ret i8 %tmp37
}
define signext i8 @orbi_i8(i8 signext %in) {
%tmp38 = or i8 %in, 37 ; <i8> [#uses=1]
ret i8 %tmp38
}

View File

@ -1,19 +0,0 @@
; Test to make sure that the 'private' is used correctly.
;
; RUN: llc < %s -march=cellspu > %t
; RUN: grep .Lfoo: %t
; RUN: grep brsl.*\.Lfoo %t
; RUN: grep .Lbaz: %t
; RUN: grep ila.*\.Lbaz %t
define private void @foo() {
ret void
}
@baz = private global i32 4
define i32 @bar() {
call void @foo()
%1 = load i32* @baz, align 4
ret i32 %1
}

View File

@ -1,172 +0,0 @@
; RUN: llc < %s -march=cellspu -o %t1.s
; RUN: grep rot %t1.s | count 86
; RUN: grep roth %t1.s | count 8
; RUN: grep roti.*5 %t1.s | count 1
; RUN: grep roti.*27 %t1.s | count 1
; RUN: grep rothi.*5 %t1.s | count 2
; RUN: grep rothi.*11 %t1.s | count 1
; RUN: grep rothi.*,.3 %t1.s | count 1
; RUN: grep andhi %t1.s | count 4
; RUN: grep shlhi %t1.s | count 4
; RUN: cat %t1.s | FileCheck %s
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
; Vector rotates are not currently supported in gcc or llvm assembly. These are
; not tested.
; 32-bit rotates:
define i32 @rotl32_1a(i32 %arg1, i8 %arg2) {
%tmp1 = zext i8 %arg2 to i32 ; <i32> [#uses=1]
%B = shl i32 %arg1, %tmp1 ; <i32> [#uses=1]
%arg22 = sub i8 32, %arg2 ; <i8> [#uses=1]
%tmp2 = zext i8 %arg22 to i32 ; <i32> [#uses=1]
%C = lshr i32 %arg1, %tmp2 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotl32_1b(i32 %arg1, i16 %arg2) {
%tmp1 = zext i16 %arg2 to i32 ; <i32> [#uses=1]
%B = shl i32 %arg1, %tmp1 ; <i32> [#uses=1]
%arg22 = sub i16 32, %arg2 ; <i8> [#uses=1]
%tmp2 = zext i16 %arg22 to i32 ; <i32> [#uses=1]
%C = lshr i32 %arg1, %tmp2 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotl32_2(i32 %arg1, i32 %arg2) {
%B = shl i32 %arg1, %arg2 ; <i32> [#uses=1]
%tmp1 = sub i32 32, %arg2 ; <i32> [#uses=1]
%C = lshr i32 %arg1, %tmp1 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotl32_3(i32 %arg1, i32 %arg2) {
%tmp1 = sub i32 32, %arg2 ; <i32> [#uses=1]
%B = shl i32 %arg1, %arg2 ; <i32> [#uses=1]
%C = lshr i32 %arg1, %tmp1 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotl32_4(i32 %arg1, i32 %arg2) {
%tmp1 = sub i32 32, %arg2 ; <i32> [#uses=1]
%C = lshr i32 %arg1, %tmp1 ; <i32> [#uses=1]
%B = shl i32 %arg1, %arg2 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotr32_1(i32 %A, i8 %Amt) {
%tmp1 = zext i8 %Amt to i32 ; <i32> [#uses=1]
%B = lshr i32 %A, %tmp1 ; <i32> [#uses=1]
%Amt2 = sub i8 32, %Amt ; <i8> [#uses=1]
%tmp2 = zext i8 %Amt2 to i32 ; <i32> [#uses=1]
%C = shl i32 %A, %tmp2 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
define i32 @rotr32_2(i32 %A, i8 %Amt) {
%Amt2 = sub i8 32, %Amt ; <i8> [#uses=1]
%tmp1 = zext i8 %Amt to i32 ; <i32> [#uses=1]
%B = lshr i32 %A, %tmp1 ; <i32> [#uses=1]
%tmp2 = zext i8 %Amt2 to i32 ; <i32> [#uses=1]
%C = shl i32 %A, %tmp2 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
; Rotate left with immediate
define i32 @rotli32(i32 %A) {
%B = shl i32 %A, 5 ; <i32> [#uses=1]
%C = lshr i32 %A, 27 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
; Rotate right with immediate
define i32 @rotri32(i32 %A) {
%B = lshr i32 %A, 5 ; <i32> [#uses=1]
%C = shl i32 %A, 27 ; <i32> [#uses=1]
%D = or i32 %B, %C ; <i32> [#uses=1]
ret i32 %D
}
; 16-bit rotates:
define i16 @rotr16_1(i16 %arg1, i8 %arg) {
%tmp1 = zext i8 %arg to i16 ; <i16> [#uses=1]
%B = lshr i16 %arg1, %tmp1 ; <i16> [#uses=1]
%arg2 = sub i8 16, %arg ; <i8> [#uses=1]
%tmp2 = zext i8 %arg2 to i16 ; <i16> [#uses=1]
%C = shl i16 %arg1, %tmp2 ; <i16> [#uses=1]
%D = or i16 %B, %C ; <i16> [#uses=1]
ret i16 %D
}
define i16 @rotr16_2(i16 %arg1, i16 %arg) {
%B = lshr i16 %arg1, %arg ; <i16> [#uses=1]
%tmp1 = sub i16 16, %arg ; <i16> [#uses=1]
%C = shl i16 %arg1, %tmp1 ; <i16> [#uses=1]
%D = or i16 %B, %C ; <i16> [#uses=1]
ret i16 %D
}
define i16 @rotli16(i16 %A) {
%B = shl i16 %A, 5 ; <i16> [#uses=1]
%C = lshr i16 %A, 11 ; <i16> [#uses=1]
%D = or i16 %B, %C ; <i16> [#uses=1]
ret i16 %D
}
define i16 @rotri16(i16 %A) {
%B = lshr i16 %A, 5 ; <i16> [#uses=1]
%C = shl i16 %A, 11 ; <i16> [#uses=1]
%D = or i16 %B, %C ; <i16> [#uses=1]
ret i16 %D
}
define i8 @rotl8(i8 %A, i8 %Amt) {
%B = shl i8 %A, %Amt ; <i8> [#uses=1]
%Amt2 = sub i8 8, %Amt ; <i8> [#uses=1]
%C = lshr i8 %A, %Amt2 ; <i8> [#uses=1]
%D = or i8 %B, %C ; <i8> [#uses=1]
ret i8 %D
}
define i8 @rotr8(i8 %A, i8 %Amt) {
%B = lshr i8 %A, %Amt ; <i8> [#uses=1]
%Amt2 = sub i8 8, %Amt ; <i8> [#uses=1]
%C = shl i8 %A, %Amt2 ; <i8> [#uses=1]
%D = or i8 %B, %C ; <i8> [#uses=1]
ret i8 %D
}
define i8 @rotli8(i8 %A) {
%B = shl i8 %A, 5 ; <i8> [#uses=1]
%C = lshr i8 %A, 3 ; <i8> [#uses=1]
%D = or i8 %B, %C ; <i8> [#uses=1]
ret i8 %D
}
define i8 @rotri8(i8 %A) {
%B = lshr i8 %A, 5 ; <i8> [#uses=1]
%C = shl i8 %A, 3 ; <i8> [#uses=1]
%D = or i8 %B, %C ; <i8> [#uses=1]
ret i8 %D
}
define <2 x float> @test1(<4 x float> %param )
{
; CHECK: test1
; CHECK: shufb
%el = extractelement <4 x float> %param, i32 1
%vec1 = insertelement <1 x float> undef, float %el, i32 0
%rv = shufflevector <1 x float> %vec1, <1 x float> undef, <2 x i32><i32 0,i32 0>
; CHECK: bi $lr
ret <2 x float> %rv
}

View File

@ -1,572 +0,0 @@
; RUN: llc < %s -march=cellspu > %t1.s
; RUN: grep selb %t1.s | count 56
; CellSPU legalization is over-sensitive to Legalize's traversal order.
; XFAIL: *
target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
target triple = "spu"
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; v2i64
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define <2 x i64> @selectbits_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rC, %rB
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and rB, rC), (and (not rC), rA))
define <2 x i64> @selectbits_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rB, %rC
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and (not rC), rA), (and rB, rC))
define <2 x i64> @selectbits_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%C = and <2 x i64> %rB, %rC
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and (not rC), rA), (and rC, rB))
define <2 x i64> @selectbits_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %A, %rA
%C = and <2 x i64> %rC, %rB
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and rC, rB), (and rA, (not rC)))
define <2 x i64> @selectbits_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rC, %rB
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and rB, rC), (and rA, (not rC)))
define <2 x i64> @selectbits_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%C = and <2 x i64> %rB, %rC
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and rA, (not rC)), (and rB, rC))
define <2 x i64> @selectbits_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%C = and <2 x i64> %rB, %rC
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
; (or (and rA, (not rC)), (and rC, rB))
define <2 x i64> @selectbits_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) {
%A = xor <2 x i64> %rC, < i64 -1, i64 -1 >
%B = and <2 x i64> %rA, %A
%C = and <2 x i64> %rC, %rB
%D = or <2 x i64> %C, %B
ret <2 x i64> %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; v4i32
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define <4 x i32> @selectbits_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rC, %rB
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and rB, rC), (and (not rC), rA))
define <4 x i32> @selectbits_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rB, %rC
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and (not rC), rA), (and rB, rC))
define <4 x i32> @selectbits_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 >
%B = and <4 x i32> %A, %rA
%C = and <4 x i32> %rB, %rC
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and (not rC), rA), (and rC, rB))
define <4 x i32> @selectbits_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %A, %rA
%C = and <4 x i32> %rC, %rB
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and rC, rB), (and rA, (not rC)))
define <4 x i32> @selectbits_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rC, %rB
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and rB, rC), (and rA, (not rC)))
define <4 x i32> @selectbits_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%C = and <4 x i32> %rB, %rC
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and rA, (not rC)), (and rB, rC))
define <4 x i32> @selectbits_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%C = and <4 x i32> %rB, %rC
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
; (or (and rA, (not rC)), (and rC, rB))
define <4 x i32> @selectbits_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) {
%A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1>
%B = and <4 x i32> %rA, %A
%C = and <4 x i32> %rC, %rB
%D = or <4 x i32> %C, %B
ret <4 x i32> %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; v8i16
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define <8 x i16> @selectbits_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rC, %rB
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and rB, rC), (and (not rC), rA))
define <8 x i16> @selectbits_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rB, %rC
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and (not rC), rA), (and rB, rC))
define <8 x i16> @selectbits_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
%C = and <8 x i16> %rB, %rC
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and (not rC), rA), (and rC, rB))
define <8 x i16> @selectbits_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %A, %rA
%C = and <8 x i16> %rC, %rB
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and rC, rB), (and rA, (not rC)))
define <8 x i16> @selectbits_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rC, %rB
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and rB, rC), (and rA, (not rC)))
define <8 x i16> @selectbits_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%C = and <8 x i16> %rB, %rC
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and rA, (not rC)), (and rB, rC))
define <8 x i16> @selectbits_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
%C = and <8 x i16> %rB, %rC
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
; (or (and rA, (not rC)), (and rC, rB))
define <8 x i16> @selectbits_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) {
%A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1,
i16 -1, i16 -1, i16 -1, i16 -1 >
%B = and <8 x i16> %rA, %A
%C = and <8 x i16> %rC, %rB
%D = or <8 x i16> %C, %B
ret <8 x i16> %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; v16i8
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define <16 x i8> @selectbits_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rC, %rB
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %A, %rA
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and rB, rC), (and (not rC), rA))
define <16 x i8> @selectbits_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rB, %rC
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %A, %rA
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and (not rC), rA), (and rB, rC))
define <16 x i8> @selectbits_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %A, %rA
%C = and <16 x i8> %rB, %rC
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and (not rC), rA), (and rC, rB))
define <16 x i8> @selectbits_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %A, %rA
%C = and <16 x i8> %rC, %rB
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and rC, rB), (and rA, (not rC)))
define <16 x i8> @selectbits_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rC, %rB
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %rA, %A
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and rB, rC), (and rA, (not rC)))
define <16 x i8> @selectbits_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%C = and <16 x i8> %rB, %rC
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %rA, %A
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and rA, (not rC)), (and rB, rC))
define <16 x i8> @selectbits_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %rA, %A
%C = and <16 x i8> %rB, %rC
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
; (or (and rA, (not rC)), (and rC, rB))
define <16 x i8> @selectbits_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) {
%A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1,
i8 -1, i8 -1, i8 -1, i8 -1 >
%B = and <16 x i8> %rA, %A
%C = and <16 x i8> %rC, %rB
%D = or <16 x i8> %C, %B
ret <16 x i8> %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; i32
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define i32 @selectbits_i32_01(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rC, %rB
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%D = or i32 %C, %B
ret i32 %D
}
; (or (and rB, rC), (and (not rC), rA))
define i32 @selectbits_i32_02(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rB, %rC
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%D = or i32 %C, %B
ret i32 %D
}
; (or (and (not rC), rA), (and rB, rC))
define i32 @selectbits_i32_03(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%C = and i32 %rB, %rC
%D = or i32 %C, %B
ret i32 %D
}
; (or (and (not rC), rA), (and rC, rB))
define i32 @selectbits_i32_04(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %A, %rA
%C = and i32 %rC, %rB
%D = or i32 %C, %B
ret i32 %D
}
; (or (and rC, rB), (and rA, (not rC)))
define i32 @selectbits_i32_05(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rC, %rB
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%D = or i32 %C, %B
ret i32 %D
}
; (or (and rB, rC), (and rA, (not rC)))
define i32 @selectbits_i32_06(i32 %rA, i32 %rB, i32 %rC) {
%C = and i32 %rB, %rC
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%D = or i32 %C, %B
ret i32 %D
}
; (or (and rA, (not rC)), (and rB, rC))
define i32 @selectbits_i32_07(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%C = and i32 %rB, %rC
%D = or i32 %C, %B
ret i32 %D
}
; (or (and rA, (not rC)), (and rC, rB))
define i32 @selectbits_i32_08(i32 %rA, i32 %rB, i32 %rC) {
%A = xor i32 %rC, -1
%B = and i32 %rA, %A
%C = and i32 %rC, %rB
%D = or i32 %C, %B
ret i32 %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; i16
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define i16 @selectbits_i16_01(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rC, %rB
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%D = or i16 %C, %B
ret i16 %D
}
; (or (and rB, rC), (and (not rC), rA))
define i16 @selectbits_i16_02(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rB, %rC
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%D = or i16 %C, %B
ret i16 %D
}
; (or (and (not rC), rA), (and rB, rC))
define i16 @selectbits_i16_03(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%C = and i16 %rB, %rC
%D = or i16 %C, %B
ret i16 %D
}
; (or (and (not rC), rA), (and rC, rB))
define i16 @selectbits_i16_04(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %A, %rA
%C = and i16 %rC, %rB
%D = or i16 %C, %B
ret i16 %D
}
; (or (and rC, rB), (and rA, (not rC)))
define i16 @selectbits_i16_05(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rC, %rB
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%D = or i16 %C, %B
ret i16 %D
}
; (or (and rB, rC), (and rA, (not rC)))
define i16 @selectbits_i16_06(i16 %rA, i16 %rB, i16 %rC) {
%C = and i16 %rB, %rC
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%D = or i16 %C, %B
ret i16 %D
}
; (or (and rA, (not rC)), (and rB, rC))
define i16 @selectbits_i16_07(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%C = and i16 %rB, %rC
%D = or i16 %C, %B
ret i16 %D
}
; (or (and rA, (not rC)), (and rC, rB))
define i16 @selectbits_i16_08(i16 %rA, i16 %rB, i16 %rC) {
%A = xor i16 %rC, -1
%B = and i16 %rA, %A
%C = and i16 %rC, %rB
%D = or i16 %C, %B
ret i16 %D
}
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; i8
;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
; (or (and rC, rB), (and (not rC), rA))
define i8 @selectbits_i8_01(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rC, %rB
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%D = or i8 %C, %B
ret i8 %D
}
; (or (and rB, rC), (and (not rC), rA))
define i8 @selectbits_i8_02(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rB, %rC
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%D = or i8 %C, %B
ret i8 %D
}
; (or (and (not rC), rA), (and rB, rC))
define i8 @selectbits_i8_03(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%C = and i8 %rB, %rC
%D = or i8 %C, %B
ret i8 %D
}
; (or (and (not rC), rA), (and rC, rB))
define i8 @selectbits_i8_04(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %A, %rA
%C = and i8 %rC, %rB
%D = or i8 %C, %B
ret i8 %D
}
; (or (and rC, rB), (and rA, (not rC)))
define i8 @selectbits_i8_05(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rC, %rB
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%D = or i8 %C, %B
ret i8 %D
}
; (or (and rB, rC), (and rA, (not rC)))
define i8 @selectbits_i8_06(i8 %rA, i8 %rB, i8 %rC) {
%C = and i8 %rB, %rC
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%D = or i8 %C, %B
ret i8 %D
}
; (or (and rA, (not rC)), (and rB, rC))
define i8 @selectbits_i8_07(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%C = and i8 %rB, %rC
%D = or i8 %C, %B
ret i8 %D
}
; (or (and rA, (not rC)), (and rC, rB))
define i8 @selectbits_i8_08(i8 %rA, i8 %rB, i8 %rC) {
%A = xor i8 %rC, -1
%B = and i8 %rA, %A
%C = and i8 %rC, %rB
%D = or i8 %C, %B
ret i8 %D
}

View File

@ -1,71 +0,0 @@
; RUN: llc < %s -march=cellspu | FileCheck %s
; ModuleID = 'sext128.bc'
target datalayout = "E-p:32:32:128-i1:8:128-i8:8:128-i16:16:128-i32:32:128-i64:32:128-f32:32:128-f64:64:128-v64:128:128-v128:128:128-a0:0:128-s0:128:128"
target triple = "spu"
define i128 @sext_i64_i128(i64 %a) {
entry:
%0 = sext i64 %a to i128
ret i128 %0
; CHECK: long 269488144
; CHECK: long 269488144
; CHECK: long 66051
; CHECK: long 67438087
; CHECK-NOT: rotqmbyi
; CHECK: lqa
; CHECK: rotmai
; CHECK: shufb
}
define i128 @sext_i32_i128(i32 %a) {
entry:
%0 = sext i32 %a to i128
ret i128 %0
; CHECK: long 269488144
; CHECK: long 269488144
; CHECK: long 269488144
; CHECK: long 66051
; CHECK-NOT: rotqmbyi
; CHECK: lqa
; CHECK: rotmai
; CHECK: shufb
}
define i128 @sext_i32_i128a(float %a) {
entry:
%0 = call i32 @myfunc(float %a)
%1 = sext i32 %0 to i128
ret i128 %1
; CHECK: long 269488144
; CHECK: long 269488144
; CHECK: long 269488144
; CHECK: long 66051
; CHECK-NOT: rotqmbyi
; CHECK: lqa
; CHECK: rotmai
; CHECK: shufb
}
declare i32 @myfunc(float)
define i128 @func1(i8 %u) {
entry:
; CHECK: xsbh
; CHECK: xshw
; CHECK: rotmai
; CHECK: shufb
; CHECK: bi $lr
%0 = sext i8 %u to i128
ret i128 %0
}
define i128 @func2(i16 %u) {
entry:
; CHECK: xshw
; CHECK: rotmai
; CHECK: shufb
; CHECK: bi $lr
%0 = sext i16 %u to i128
ret i128 %0
}

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