Add ports for TILE-Gx and TILEPro.

.
	* MAINTAINERS (tilegx port): Add myself.
	(tilepro port): Add myself.

contrib
	* config-list.mk (LIST): Add tilegx-linux-gnu and
	tilepro-linux-gnu.
	* gcc_update (gcc/config/tilegx/mul-tables.c): New dependencies.
	(gcc/config/tilepro/mul-tables.c): New dependencies.

gcc
	* config.gcc: Handle tilegx and tilepro.
	* configure.ac (gcc_cv_as_dwarf2_debug_line): Enable test for
	tilegx and tilepro.
	Add HAVE_AS_TLS check for tilegx and tilepro.
	* configure: Regenerate.
	* doc/contrib.texi: Add Mat Hostetter and self.
	* doc/extend.texi (TILE-Gx Built-in Functions): New node.
	Document instruction intrinsics and network accessing intrinsics.
	(TILEPro Built-in Functions): New node.	 Document instruction
	intrinsics and network accessing intrinsics.
	* doc/install.texi (Specific, tilegx-*-linux*): Document it.
	(Specific, tilepro-*-linux*): Likewise.
	* doc/invoke.texi (TILE-Gx Options): New section.
	(TILEPro Options): New section.
	* doc/md.texi (TILE-Gx): New section.
	(TILEPro): New section.
	* common/config/tilegx: New directory for tilegx.
	* common/config/tilepro: New directory for tilepro.
	* config/tilegx: New directory for tilegx.
	* config/tilepro: New directory for tilepro.

gcc/testsuite
	* g++.dg/other/PR23205.C: Disable test on tile.
	* g++.dg/other/pr23205-2.C: Disable test on tile.
	* gcc.dg/20020312-2.c: Add a condition for __tile__.
	* gcc.dg/20040813-1.c: Disable test on tile.
	* gcc.dg/lower-subreg-1.c: Disable test on tilegx.
	* gcc.misc-tests/linkage.exp: Handle tilegx.

libcpp
	* configure.ac: Require 64-bit hwint for tilegx and tilepro.
	* configure: Regenerate.

libgcc
	* config.host: Handle tilegx and tilepro.
	* config/tilegx: New directory for tilegx.
	* config/tilepro: New directory for tilepro.

libgomp
	* configure.tgt: Handle tilegx and tilepro.
	* config/linux/tile: New directory for tilegx and tilepro.

Added:
     trunk/gcc/common/config/tilegx/tilegx-common.c
     trunk/gcc/common/config/tilepro/tilepro-common.c
     trunk/gcc/config/tilegx/constraints.md
     trunk/gcc/config/tilegx/linux.h
     trunk/gcc/config/tilegx/mul-tables.c
     trunk/gcc/config/tilegx/predicates.md
     trunk/gcc/config/tilegx/sync.md
     trunk/gcc/config/tilegx/t-tilegx
     trunk/gcc/config/tilegx/tilegx-builtins.h
     trunk/gcc/config/tilegx/tilegx-c.c
     trunk/gcc/config/tilegx/tilegx-generic.md
     trunk/gcc/config/tilegx/tilegx-modes.def
     trunk/gcc/config/tilegx/tilegx-multiply.h
     trunk/gcc/config/tilegx/tilegx-protos.h
     trunk/gcc/config/tilegx/tilegx.c
     trunk/gcc/config/tilegx/tilegx.h
     trunk/gcc/config/tilegx/tilegx.md
     trunk/gcc/config/tilegx/tilegx.opt
     trunk/gcc/config/tilepro/constraints.md
     trunk/gcc/config/tilepro/gen-mul-tables.cc
     trunk/gcc/config/tilepro/linux.h
     trunk/gcc/config/tilepro/mul-tables.c
     trunk/gcc/config/tilepro/predicates.md
     trunk/gcc/config/tilepro/t-tilepro
     trunk/gcc/config/tilepro/tilepro-builtins.h
     trunk/gcc/config/tilepro/tilepro-c.c
     trunk/gcc/config/tilepro/tilepro-generic.md
     trunk/gcc/config/tilepro/tilepro-modes.def
     trunk/gcc/config/tilepro/tilepro-multiply.h
     trunk/gcc/config/tilepro/tilepro-protos.h
     trunk/gcc/config/tilepro/tilepro.c
     trunk/gcc/config/tilepro/tilepro.h
     trunk/gcc/config/tilepro/tilepro.md
     trunk/gcc/config/tilepro/tilepro.opt
     trunk/libgcc/config/tilegx/sfp-machine.h
     trunk/libgcc/config/tilegx/sfp-machine32.h
     trunk/libgcc/config/tilegx/sfp-machine64.h
     trunk/libgcc/config/tilegx/t-crtstuff
     trunk/libgcc/config/tilegx/t-softfp
     trunk/libgcc/config/tilegx/t-tilegx
     trunk/libgcc/config/tilepro/atomic.c
     trunk/libgcc/config/tilepro/atomic.h
     trunk/libgcc/config/tilepro/linux-unwind.h
     trunk/libgcc/config/tilepro/sfp-machine.h
     trunk/libgcc/config/tilepro/softdivide.c
     trunk/libgcc/config/tilepro/softmpy.S
     trunk/libgcc/config/tilepro/t-crtstuff
     trunk/libgcc/config/tilepro/t-tilepro
     trunk/libgomp/config/linux/tile/futex.h
Modified:
     trunk/MAINTAINERS
     trunk/contrib/config-list.mk
     trunk/contrib/gcc_update
     trunk/gcc/config.gcc
     trunk/gcc/configure
     trunk/gcc/configure.ac
     trunk/gcc/doc/contrib.texi
     trunk/gcc/doc/extend.texi
     trunk/gcc/doc/install.texi
     trunk/gcc/doc/invoke.texi
     trunk/gcc/doc/md.texi
     trunk/gcc/testsuite/g++.dg/other/PR23205.C
     trunk/gcc/testsuite/g++.dg/other/pr23205-2.C
     trunk/gcc/testsuite/gcc.dg/20020312-2.c
     trunk/gcc/testsuite/gcc.dg/20040813-1.c
     trunk/gcc/testsuite/gcc.dg/lower-subreg-1.c
     trunk/gcc/testsuite/gcc.misc-tests/linkage.exp
     trunk/libcpp/configure
     trunk/libcpp/configure.ac
     trunk/libgcc/config.host
     trunk/libgomp/configure.tgt

From-SVN: r184203
This commit is contained in:
Walter Lee 2012-02-14 10:02:21 +00:00 committed by Walter Lee
parent 62513f7bed
commit dd552284fd
77 changed files with 71556 additions and 10 deletions

View File

@ -1,6 +1,8 @@
2012-02-14 Walter Lee <walt@tilera.com>
* MAINTAINERS (Write After Approval): Add myself.
* MAINTAINERS (tilegx port): Add myself.
(tilepro port): Add myself.
(Write After Approval): Add myself.
2012-02-12 Gerald Pfeifer <gerald@pfeifer.com>

View File

@ -104,6 +104,8 @@ sparc port Eric Botcazou ebotcazou@libertysurf.fr
spu port Trevor Smigiel trevor_smigiel@playstation.sony.com
spu port David Edelsohn dje.gcc@gmail.com
spu port Ulrich Weigand uweigand@de.ibm.com
tilegx port Walter Lee walt@tilera.com
tilepro port Walter Lee walt@tilera.com
v850 port Nick Clifton nickc@redhat.com
vax port Matt Thomas matt@3am-software.com
x86-64 port Jan Hubicka jh@suse.cz

View File

@ -1,3 +1,10 @@
2012-02-14 Walter Lee <walt@tilera.com>
* config-list.mk (LIST): Add tilegx-linux-gnu and
tilepro-linux-gnu.
* gcc_update (gcc/config/tilegx/mul-tables.c): New dependencies.
(gcc/config/tilepro/mul-tables.c): New dependencies.
2012-02-11 Mike Stump <mikestump@comcast.net>
* compare_tests (exit_status): Fix.

View File

@ -60,7 +60,8 @@ LIST = alpha-linux-gnu alpha-freebsd6 alpha-netbsd alpha-openbsd \
sparc-leon3-linux-gnuOPT-enable-target=all sparc-netbsdelf \
sparc64-sun-solaris2.10OPT-with-gnu-ldOPT-with-gnu-asOPT-enable-threads=posix \
sparc-wrs-vxworks sparc64-elf sparc64-rtems sparc64-linux sparc64-freebsd6 \
sparc64-netbsd sparc64-openbsd spu-elf v850e-elf v850-elf vax-linux-gnu \
sparc64-netbsd sparc64-openbsd spu-elf tilegx-linux-gnu tilepro-linux-gnu \
v850e-elf v850-elf vax-linux-gnu \
vax-netbsdelf vax-openbsd x86_64-apple-darwin \
x86_64-pc-linux-gnuOPT-with-fpmath=avx \
x86_64-elfOPT-with-fpmath=sse x86_64-freebsd6 x86_64-netbsd \

View File

@ -90,6 +90,8 @@ gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in gcc/config/c6x/genmult
gcc/config/m68k/m68k-tables.opt: gcc/config/m68k/m68k-devices.def gcc/config/m68k/m68k-isas.def gcc/config/m68k/m68k-microarchs.def gcc/config/m68k/genopt.sh
gcc/config/mips/mips-tables.opt: gcc/config/mips/mips-cpus.def gcc/config/mips/genopt.sh
gcc/config/rs6000/rs6000-tables.opt: gcc/config/rs6000/rs6000-cpus.def gcc/config/rs6000/genopt.sh
gcc/config/tilegx/mul-tables.c: gcc/config/tilepro/gen-mul-tables.cc
gcc/config/tilepro/mul-tables.c: gcc/config/tilepro/gen-mul-tables.cc
# And then, language-specific files
gcc/cp/cfns.h: gcc/cp/cfns.gperf
gcc/java/keyword.h: gcc/java/keyword.gperf

View File

@ -1,3 +1,56 @@
2012-02-14 Walter Lee <walt@tilera.com>
* config.gcc: Handle tilegx and tilepro.
* configure.ac (gcc_cv_as_dwarf2_debug_line): Enable test for
tilegx and tilepro.
Add HAVE_AS_TLS check for tilegx and tilepro.
* configure: Regenerate.
* doc/contrib.texi: Add Mat Hostetter and self.
* doc/extend.texi (TILE-Gx Built-in Functions): New node.
Document instruction intrinsics and network accessing intrinsics.
(TILEPro Built-in Functions): New node. Document instruction
intrinsics and network accessing intrinsics.
* doc/install.texi (Specific, tilegx-*-linux*): Document it.
(Specific, tilepro-*-linux*): Likewise.
* doc/invoke.texi (TILE-Gx Options): New section.
(TILEPro Options): New section.
* doc/md.texi (TILE-Gx): New section.
(TILEPro): New section.
* common/config/tilegx/tilegx-common.c: New file.
* common/config/tilepro/tilepro-common.c: New file.
* config/tilegx/constraints.md: New file.
* config/tilegx/linux.h: New file.
* config/tilegx/mul-tables.c: New file.
* config/tilegx/predicates.md: New file.
* config/tilegx/sync.md: New file.
* config/tilegx/t-tilegx: New file.
* config/tilegx/tilegx-builtins.h: New file.
* config/tilegx/tilegx-c.c: New file.
* config/tilegx/tilegx-generic.md: New file.
* config/tilegx/tilegx-modes.def: New file.
* config/tilegx/tilegx-multiply.h: New file.
* config/tilegx/tilegx-protos.h: New file.
* config/tilegx/tilegx.c: New file.
* config/tilegx/tilegx.h: New file.
* config/tilegx/tilegx.md: New file.
* config/tilegx/tilegx.opt: New file.
* config/tilepro/constraints.md: New file.
* config/tilepro/gen-mul-tables.cc: New file.
* config/tilepro/linux.h: New file.
* config/tilepro/mul-tables.c: New file.
* config/tilepro/predicates.md: New file.
* config/tilepro/t-tilepro: New file.
* config/tilepro/tilepro-builtins.h: New file.
* config/tilepro/tilepro-c.c: New file.
* config/tilepro/tilepro-generic.md: New file.
* config/tilepro/tilepro-modes.def: New file.
* config/tilepro/tilepro-multiply.h: New file.
* config/tilepro/tilepro-protos.h: New file.
* config/tilepro/tilepro.c: New file.
* config/tilepro/tilepro.h: New file.
* config/tilepro/tilepro.md: New file.
* config/tilepro/tilepro.opt: New file.
2012-02-14 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/52210

View File

@ -0,0 +1,55 @@
/* Common hooks for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tm.h"
#include "common/common-target.h"
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
static const struct default_options tilegx_option_optimization_table[] = {
{OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1},
/* Scheduling and bundling are super important for our architecture, so
enable them at -O1. */
{OPT_LEVELS_1_PLUS, OPT_fschedule_insns, NULL, 1},
{OPT_LEVELS_1_PLUS, OPT_fschedule_insns2, NULL, 1},
{OPT_LEVELS_NONE, 0, NULL, 0}
};
static void
tilegx_option_init_struct (struct gcc_options *opts)
{
opts->x_flag_asynchronous_unwind_tables = 1;
}
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE tilegx_option_optimization_table
#undef TARGET_OPTION_INIT_STRUCT
#define TARGET_OPTION_INIT_STRUCT tilegx_option_init_struct
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;

View File

@ -0,0 +1,56 @@
/* Common hooks for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic-core.h"
#include "tm.h"
#include "common/common-target.h"
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
static const struct default_options tilepro_option_optimization_table[] = {
{OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1},
/* Scheduling and bundling are super important for our architecture, so
enable them at -O1. */
{OPT_LEVELS_1_PLUS, OPT_fschedule_insns, NULL, 1},
{OPT_LEVELS_1_PLUS, OPT_fschedule_insns2, NULL, 1},
{OPT_LEVELS_NONE, 0, NULL, 0}
};
static void
tilepro_option_init_struct (struct gcc_options *opts)
{
opts->x_flag_asynchronous_unwind_tables = 1;
}
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE tilepro_option_optimization_table
#undef TARGET_OPTION_INIT_STRUCT
#define TARGET_OPTION_INIT_STRUCT tilepro_option_init_struct
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;

View File

@ -448,6 +448,14 @@ tic6x-*-*)
xtensa*-*-*)
extra_options="${extra_options} fused-madd.opt"
;;
tilegx*-*-*)
cpu_type=tilegx
need_64bit_hwint=yes
;;
tilepro-*-*)
cpu_type=tilepro
need_64bit_hwint=yes
;;
esac
tm_file=${cpu_type}/${cpu_type}.h
@ -2468,6 +2476,20 @@ tic6x-*-uclinux)
tmake_file="${tmake_file} c6x/t-c6x c6x/t-c6x-elf c6x/t-c6x-uclinux"
use_collect2=no
;;
tilegx-*-linux*)
tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilegx/linux.h ${tm_file}"
tmake_file="${tmake_file} tilegx/t-tilegx"
extra_objs="mul-tables.o"
c_target_objs="tilegx-c.o"
cxx_target_objs="tilegx-c.o"
;;
tilepro-*-linux*)
tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h tilepro/linux.h ${tm_file}"
tmake_file="${tmake_file} tilepro/t-tilepro"
extra_objs="mul-tables.o"
c_target_objs="tilepro-c.o"
cxx_target_objs="tilepro-c.o"
;;
v850*-*-*)
case ${target} in
v850e2v3-*-*)

View File

@ -0,0 +1,123 @@
;; Constraint definitions for Tilera TILE-Gx.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_register_constraint "R00" "R0_REGS" "r0")
(define_register_constraint "R01" "R1_REGS" "r1")
(define_register_constraint "R02" "R2_REGS" "r2")
(define_register_constraint "R03" "R3_REGS" "r3")
(define_register_constraint "R04" "R4_REGS" "r4")
(define_register_constraint "R05" "R5_REGS" "r5")
(define_register_constraint "R06" "R6_REGS" "r6")
(define_register_constraint "R07" "R7_REGS" "r7")
(define_register_constraint "R08" "R8_REGS" "r8")
(define_register_constraint "R09" "R9_REGS" "r9")
(define_register_constraint "R10" "R10_REGS" "r10")
(define_constraint "I"
"A signed 8 bit constant"
(and (match_code "const_int")
(match_test "ival >= -128 && ival <= 127")))
(define_constraint "J"
"Signed 16-bit integer constant"
(and (match_code "const_int")
(match_test "ival >= -32768 && ival <= 32767")))
(define_constraint "K"
"Unsigned 16-bit integer constant"
(and (match_code "const_int")
(match_test "(ival >= 0 && ival <= 65535)")))
(define_constraint "L"
"Integer constant that fits in one signed byte when incremented"
(and (match_code "const_int")
(match_test "ival >= -129 && ival <= 126")))
(define_constraint "M"
"A bit mask suitable for 'bfins'"
(and (match_code "const_int")
(match_test "tilegx_bitfield_operand_p (ival, NULL, NULL)")))
(define_constraint "N"
"Integer constant that is a byte tiled out eight times"
(and (match_code "const_int")
(match_test "(ival == (ival & 0xFF) * 0x0101010101010101LL)")))
(define_constraint "O"
"The integer zero constant"
(and (match_code "const_int")
(match_test "ival == 0")))
(define_constraint "P"
"Integer constant that is a sign-extended byte tiled out as four shorts"
(and (match_code "const_int")
(match_test "(ival
== ((trunc_int_for_mode (ival, QImode) & 0xFFFF)
* 0x0001000100010001LL))")))
(define_constraint "Q"
"Integer constant that fits in one signed byte when incremented, but not -1"
(and (match_code "const_int")
(match_test "ival >= -129 && ival <= 126 && ival != -1")))
(define_constraint "S"
"Integer constant that has all 1 bits consecutive and starting at bit 0"
(and (match_code "const_int")
(match_test "ival != 0 && (ival & (ival + 1)) == 0")))
(define_constraint "T"
"An unspec wrapper for a symbolc operand"
(ior (match_operand 0 "const_last_symbolic_operand")
(match_operand 0 "const_symbolic_operand")))
(define_memory_constraint "U"
"Non-auto-incrementing memory"
(and (match_code "mem")
(match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
(define_constraint "W"
"An 8-element vector constant with identical elements"
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 8")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 4)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 5)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 6)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 7)")))
(define_constraint "Y"
"A 4-element vector constant with identical elements"
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 4")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)")))
(define_constraint "Z0"
"The integer constant 0xffffffff"
(and (match_code "const_int")
(match_test "ival == 0xffffffff")))
(define_constraint "Z1"
"The integer constant 0xffffffff00000000"
(and (match_code "const_int")
(match_test "ival == (HOST_WIDE_INT)0xffffffff00000000LL")))

72
gcc/config/tilegx/linux.h Normal file
View File

@ -0,0 +1,72 @@
/* Definitions for TILE-Gx running Linux-based GNU systems with ELF.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#undef CPP_SPEC
#define CPP_SPEC "%{pthread:-D_REENTRANT}"
#undef ASM_SPEC
#define ASM_SPEC "%{m32:--32} %{m64:--64}"
#undef LINK_SPEC
#define LINK_SPEC "%{m64:-m elf64tilegx} %{m32:-m elf32tilegx} \
%{shared:-shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
-dynamic-linker \
%{ m32: /lib32/ld.so.1} \
%{!m32: /lib/ld.so.1}} \
%{static:-static}}"
#define MULTILIB_DEFAULTS { "m64" }
#define NO_PROFILE_COUNTERS 1
#undef MCOUNT_NAME
#define MCOUNT_NAME "__mcount"
#undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1
#ifdef TARGET_LIBC_PROVIDES_SSP
/* TILE-Gx glibc provides __stack_chk_guard two pointer-size words before
tp. */
#define TARGET_THREAD_SSP_OFFSET (-2 * GET_MODE_SIZE (ptr_mode))
#endif
/* For __clear_cache in libgcc2.c. */
#ifdef IN_LIBGCC2
#include <arch/icache.h>
/* Use the minimum page size of 4K. Alternatively we can call
getpagesize() but it introduces a libc dependence. */
#undef CLEAR_INSN_CACHE
#define CLEAR_INSN_CACHE(beg, end) invalidate_icache (beg, end - beg, 4096)
#else
/* define CLEAR_INSN_CACHE so that gcc knows to expand __builtin__clear_cache
to the libraray call. */
#undef CLEAR_INSN_CACHE
#define CLEAR_INSN_CACHE 1
#endif

27244
gcc/config/tilegx/mul-tables.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,293 @@
;; Predicate definitions for Tilera TILE-Gx.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; Return true if OP is the zero constant for MODE.
(define_predicate "const_zero_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
;; Returns true if OP is either the constant zero or a register.
(define_predicate "reg_or_0_operand"
(and (ior (match_operand 0 "register_operand")
(match_operand 0 "const_zero_operand"))
(match_test "GET_MODE_SIZE (mode) <= UNITS_PER_WORD")))
; Return 1 if OP is a valid Pmode pointer.
(define_predicate "pointer_operand"
(and (match_operand 0 "address_operand")
(ior (match_operand 0 "pmode_register_operand")
(match_operand 0 "const_zero_operand"))))
; Return 1 if OP is a network register identifier.
(define_predicate "netreg_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 5)")))
; Return 1 if OP is an unsigned 6-bit constant.
(define_predicate "u6bit_cint_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) == (INTVAL (op) & 0x3F)")))
;; Return 1 if OP is an unsigned 16-bit constant.
(define_predicate "u16bit_cint_operand"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT)INTVAL (op) < (1U << 16)")))
;; Return 1 if OP is a signed 8-bit constant.
(define_predicate "s8bit_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_I (op)")))
;; Return 1 if OP is a signed 16-bit constant.
(define_predicate "s16bit_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_J (op)")))
;; Return 1 if OP is an unsigned 14-bit constant.
(define_predicate "u14bit_cint_operand"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT)INTVAL (op) < (1U << 14)")))
;; Return 1 if OP is a constant or any register.
(define_predicate "reg_or_cint_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_int_operand")))
;; Returns 1 if OP is a "last" unspec wrapper for a symbol, got, or
;; tls reference.
(define_predicate "const_last_symbolic_operand"
(and (match_code "const")
(match_test "GET_CODE (XEXP (op,0)) == UNSPEC")
(ior (match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_LAST")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2_LAST")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_PCREL")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_LAST_GOT")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_GOT")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_GD")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_IE")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1_LAST_TLS_LE"))))
;; Returns 1 if OP is an unspec wrapper for a symbol, got, or tls
;; reference.
(define_predicate "const_symbolic_operand"
(and (match_code "const")
(match_test "GET_CODE (XEXP (op,0)) == UNSPEC")
(ior (match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW1")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW2")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW3")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_PCREL")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_GOT")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_GD")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_IE")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_HW0_TLS_LE"))))
;; Return 1 if OP is a 8-element vector constant with identical signed
;; 8-bit elements or any register.
(define_predicate "reg_or_v8s8bit_operand"
(ior (match_operand 0 "register_operand")
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 8
&& satisfies_constraint_I (CONST_VECTOR_ELT (op, 0))
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 4)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 5)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 6)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 7)"))))
;; Return 1 if OP is a 4-element vector constant with identical signed
;; 8-bit elements or any register.
(define_predicate "reg_or_v4s8bit_operand"
(ior (match_operand 0 "register_operand")
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 4
&& satisfies_constraint_I (CONST_VECTOR_ELT (op, 0))
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)"))))
;; Return 1 if the operand is a valid second operand to an add insn.
(define_predicate "add_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_J (op)")
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_last_symbolic_operand"))))
;; Return 1 if the operand is a register or signed 8-bit immediate operand.
(define_predicate "reg_or_s8bit_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_I (op)")
(match_operand 0 "register_operand")))
;; Return 1 if the operand is a register or unsigned 5-bit immediate operand.
(define_predicate "reg_or_u5bit_operand"
(if_then_else (match_code "const_int")
(match_test "INTVAL (op) == (INTVAL (op) & 0x1F)")
(match_operand 0 "register_operand")))
;; Return 1 if the operand is a register or unsigned 6-bit immediate operand.
(define_predicate "reg_or_u6bit_operand"
(if_then_else (match_code "const_int")
(match_test "INTVAL (op) == (INTVAL (op) & 0x3F)")
(match_operand 0 "register_operand")))
;; Return 1 for an operand suitable for ANDing with a register.
(define_predicate "and_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_I (op) || satisfies_constraint_M (op)")
(match_operand 0 "register_operand")))
; Return 1 if the operand is 2, 4 or 8.
(define_predicate "cint_248_operand"
(and (match_code "const_int")
(match_test
"INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8")))
;; Return true if OP is a TLS symbolic operand.
(define_predicate "tls_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) != TLS_MODEL_NONE")))
;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
(define_predicate "tls_gd_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
(define_predicate "tls_ld_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
;; Return true if OP is a symbolic operand that can be used for the
;; TLS Initial Exec model.
(define_predicate "tls_ie_symbolic_operand"
(and (match_code "symbol_ref")
(ior (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC"))))
;; Return true if OP is a symbolic operand for the TLS Local Exec model.
(define_predicate "tls_le_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
;; Returns true if OP is any general operand except for an
;; auto-incrementing address operand.
(define_predicate "nonautoinc_operand"
(and (match_operand 0 "general_operand")
(not (ior (match_code "pre_dec") (match_code "pre_inc")
(match_code "post_dec") (match_code "post_inc")
(match_code "post_modify") (match_code "pre_modify")))))
;; Returns true if OP is a non-auto-incrementing memory operand.
(define_predicate "nonautoincmem_operand"
(match_operand 0 "memory_operand")
{
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
})
;; Returns true if OP is a non-auto-incrementing memory, general
;; operand.
(define_predicate "nonautoincmem_general_operand"
(match_operand 0 "general_operand")
{
if (memory_operand (op, mode))
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
else
return true;
})
;; Returns true if OP is a non-auto-incrementing memory, non-immediate
;; operand.
(define_predicate "nonautoincmem_nonimmediate_operand"
(match_operand 0 "nonimmediate_operand")
{
if (memory_operand (op, mode))
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
else
return true;
})
;; Return true if OP is a valid operand for the source of a move insn.
(define_predicate "move_operand"
(match_operand 0 "general_operand")
{
/* If both modes are non-void they must be the same. */
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return false;
switch (GET_CODE (op))
{
case CONST_INT:
return (satisfies_constraint_J (op)
|| satisfies_constraint_K (op)
|| (mode == DImode &&
(satisfies_constraint_N (op)
|| satisfies_constraint_P (op))));
case MEM:
return memory_address_p (mode, XEXP (op, 0));
case CONST:
return const_last_symbolic_operand (op, mode);
default:
return register_operand (op, mode);
}
})
;; Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
;; possibly with an offset.
(define_predicate "symbolic_operand"
(ior (match_code "symbol_ref,label_ref")
(and (match_code "const")
(match_test "GET_CODE (XEXP (op,0)) == PLUS
&& (GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
|| GET_CODE (XEXP (XEXP (op,0), 0)) == LABEL_REF)
&& CONST_INT_P (XEXP (XEXP (op,0), 1))"))))
;; Return 1 for an unsigned 16 bit or a const symbolc operand.
(define_predicate "u16bit_or_const_symbolic_operand"
(ior (match_operand 0 "u16bit_cint_operand")
(match_operand 0 "const_symbolic_operand")))
;; Return true if OP is an address suitable for a call insn.
;; Call insn on TILE can take a PC-relative constant address
;; or any regular memory address.
(define_predicate "call_address_operand"
(ior (match_operand 0 "symbolic_operand")
(match_test "memory_address_p (Pmode, op)")))
;; Return true if OP is an operand suitable for a call insn.
(define_predicate "call_operand"
(and (match_code "mem")
(match_test "call_address_operand (XEXP (op, 0), mode)")))
;; Return 1 if OP is a signed comparison operation.
;; We can use these directly in compares against zero.
(define_predicate "signed_comparison_operator"
(match_code "eq,ne,le,lt,ge,gt"))
;; Return 1 if OP is a equal or not-equal operation.
(define_predicate "eqne_operator"
(match_code "eq,ne"))

165
gcc/config/tilegx/sync.md Normal file
View File

@ -0,0 +1,165 @@
;; GCC machine description for Tilera TILE-Gx synchronization
;; instructions.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_code_iterator fetchop [plus ior and])
(define_code_attr fetchop_name [(plus "add") (ior "or") (and "and")])
(define_insn "mtspr_cmpexch<mode>"
[(set (reg:I48MODE TILEGX_CMPEXCH_REG)
(unspec_volatile:I48MODE
[(match_operand:I48MODE 0 "reg_or_0_operand" "rO")]
UNSPEC_SPR_MOVE))]
""
"mtspr\tCMPEXCH_VALUE, %r0"
[(set_attr "type" "X1")])
(define_expand "atomic_compare_and_swap<mode>"
[(match_operand:DI 0 "register_operand" "") ;; bool output
(match_operand:I48MODE 1 "register_operand" "") ;; val output
(match_operand:I48MODE 2 "nonautoincmem_operand" "") ;; memory
(match_operand:I48MODE 3 "reg_or_0_operand" "") ;; expected value
(match_operand:I48MODE 4 "reg_or_0_operand" "") ;; desired value
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; mod_s
(match_operand:SI 7 "const_int_operand" "")] ;; mod_f
""
{
enum memmodel mod_s = (enum memmodel) INTVAL (operands[6]);
if (operands[3] != const0_rtx)
operands[3] = force_reg (<MODE>mode, operands[3]);
if (operands[4] != const0_rtx)
operands[4] = force_reg (<MODE>mode, operands[4]);
tilegx_pre_atomic_barrier (mod_s);
emit_insn (gen_mtspr_cmpexch<mode> (operands[3]));
emit_insn (gen_atomic_compare_and_swap_bare<mode> (operands[1], operands[2],
operands[4]));
tilegx_post_atomic_barrier (mod_s);
emit_insn (gen_insn_cmpeq_<mode>di (operands[0], operands[1], operands[3]));
DONE;
})
(define_insn "atomic_compare_and_swap_bare<mode>"
[(set (match_operand:I48MODE 0 "register_operand" "=r")
(match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
(set (match_dup 1)
(unspec_volatile:I48MODE
[(match_dup 1)
(reg:I48MODE TILEGX_CMPEXCH_REG)
(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
UNSPEC_CMPXCHG))]
""
"cmpexch<four_if_si>\t%0, %1, %r2"
[(set_attr "type" "X1_L2")])
(define_expand "atomic_exchange<mode>"
[(match_operand:I48MODE 0 "register_operand" "") ;; result
(match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
(match_operand:I48MODE 2 "reg_or_0_operand" "") ;; input
(match_operand:SI 3 "const_int_operand" "")] ;; model
""
{
enum memmodel model = (enum memmodel) INTVAL (operands[3]);
tilegx_pre_atomic_barrier (model);
emit_insn (gen_atomic_exchange_bare<mode> (operands[0], operands[1],
operands[2]));
tilegx_post_atomic_barrier (model);
DONE;
})
(define_insn "atomic_exchange_bare<mode>"
[(set (match_operand:I48MODE 0 "register_operand" "=r")
(match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
(set (match_dup 1)
(unspec_volatile:I48MODE
[(match_operand:I48MODE 2 "reg_or_0_operand" "rO")]
UNSPEC_XCHG))]
""
"exch<four_if_si>\t%0, %1, %r2"
[(set_attr "type" "X1_2cycle")])
(define_expand "atomic_fetch_<fetchop_name><mode>"
[(match_operand:I48MODE 0 "register_operand" "") ;; result
(match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
(unspec_volatile:I48MODE
[(fetchop:I48MODE
(match_dup 1)
(match_operand:I48MODE 2 "reg_or_0_operand" ""))] ;; value
UNSPEC_ATOMIC)
(match_operand:SI 3 "const_int_operand" "")] ;; model
""
{
enum memmodel model = (enum memmodel) INTVAL (operands[3]);
tilegx_pre_atomic_barrier (model);
emit_insn (gen_atomic_fetch_<fetchop_name>_bare<mode> (operands[0],
operands[1],
operands[2]));
tilegx_pre_atomic_barrier (model);
DONE;
})
(define_insn "atomic_fetch_<fetchop_name>_bare<mode>"
[(set (match_operand:I48MODE 0 "register_operand" "=r")
(match_operand:I48MODE 1 "nonautoincmem_operand" "+U"))
(set (match_dup 1)
(unspec_volatile:I48MODE
[(fetchop:I48MODE
(match_dup 1)
(match_operand:I48MODE 2 "reg_or_0_operand" "rO"))]
UNSPEC_ATOMIC))]
""
"fetch<fetchop_name><four_if_si>\t%0, %1, %r2"
[(set_attr "type" "X1_2cycle")])
(define_expand "atomic_fetch_sub<mode>"
[(match_operand:I48MODE 0 "register_operand" "") ;; result
(match_operand:I48MODE 1 "nonautoincmem_operand" "") ;; memory
(unspec_volatile:I48MODE
[(minus:I48MODE
(match_dup 1)
(match_operand:I48MODE 2 "reg_or_0_operand" ""))] ;; value
UNSPEC_ATOMIC)
(match_operand:SI 3 "const_int_operand" "")] ;; model
""
{
enum memmodel model = (enum memmodel) INTVAL (operands[3]);
if (operands[2] != const0_rtx)
emit_move_insn (operands[2], gen_rtx_NEG (<MODE>mode, operands[2]));
tilegx_pre_atomic_barrier (model);
emit_insn (gen_atomic_fetch_add_bare<mode> (operands[0],
operands[1],
operands[2]));
tilegx_pre_atomic_barrier (model);
DONE;
})

View File

@ -0,0 +1,21 @@
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
MULTILIB_OSDIRNAMES = ../lib ../lib32
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
tilegx-c.o: $(srcdir)/config/tilegx/tilegx-c.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(MACHMODE_H) \
$(TM_H) $(TM_P_H) $(CPPLIB_H) $(TREE_H) $(C_COMMON_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
$(srcdir)/config/tilegx/mul-tables.c: \
$(srcdir)/config/tilepro/gen-mul-tables.cc
$(CC_FOR_BUILD) $(BUILD_CPPFLAGS) -O2 -o gen-mul-tables -lstdc++ $<;
./gen-mul-tables > $@
mul-tables.o: $(srcdir)/config/tilegx/mul-tables.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(EXPR_H) $(OPTABS_H) \
$(srcdir)/config/tilegx/tilegx-multiply.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<

View File

@ -0,0 +1,325 @@
/* Enum for builtin intrinsics for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TILEGX_BUILTINS_H
#define GCC_TILEGX_BUILTINS_H
enum tilegx_builtin
{
TILEGX_INSN_ADD,
TILEGX_INSN_ADDX,
TILEGX_INSN_ADDXSC,
TILEGX_INSN_AND,
TILEGX_INSN_BFEXTS,
TILEGX_INSN_BFEXTU,
TILEGX_INSN_BFINS,
TILEGX_INSN_CLZ,
TILEGX_INSN_CMOVEQZ,
TILEGX_INSN_CMOVNEZ,
TILEGX_INSN_CMPEQ,
TILEGX_INSN_CMPEXCH,
TILEGX_INSN_CMPEXCH4,
TILEGX_INSN_CMPLES,
TILEGX_INSN_CMPLEU,
TILEGX_INSN_CMPLTS,
TILEGX_INSN_CMPLTU,
TILEGX_INSN_CMPNE,
TILEGX_INSN_CMUL,
TILEGX_INSN_CMULA,
TILEGX_INSN_CMULAF,
TILEGX_INSN_CMULF,
TILEGX_INSN_CMULFR,
TILEGX_INSN_CMULH,
TILEGX_INSN_CMULHR,
TILEGX_INSN_CRC32_32,
TILEGX_INSN_CRC32_8,
TILEGX_INSN_CTZ,
TILEGX_INSN_DBLALIGN,
TILEGX_INSN_DBLALIGN2,
TILEGX_INSN_DBLALIGN4,
TILEGX_INSN_DBLALIGN6,
TILEGX_INSN_DRAIN,
TILEGX_INSN_DTLBPR,
TILEGX_INSN_EXCH,
TILEGX_INSN_EXCH4,
TILEGX_INSN_FDOUBLE_ADD_FLAGS,
TILEGX_INSN_FDOUBLE_ADDSUB,
TILEGX_INSN_FDOUBLE_MUL_FLAGS,
TILEGX_INSN_FDOUBLE_PACK1,
TILEGX_INSN_FDOUBLE_PACK2,
TILEGX_INSN_FDOUBLE_SUB_FLAGS,
TILEGX_INSN_FDOUBLE_UNPACK_MAX,
TILEGX_INSN_FDOUBLE_UNPACK_MIN,
TILEGX_INSN_FETCHADD,
TILEGX_INSN_FETCHADD4,
TILEGX_INSN_FETCHADDGEZ,
TILEGX_INSN_FETCHADDGEZ4,
TILEGX_INSN_FETCHAND,
TILEGX_INSN_FETCHAND4,
TILEGX_INSN_FETCHOR,
TILEGX_INSN_FETCHOR4,
TILEGX_INSN_FINV,
TILEGX_INSN_FLUSH,
TILEGX_INSN_FLUSHWB,
TILEGX_INSN_FNOP,
TILEGX_INSN_FSINGLE_ADD1,
TILEGX_INSN_FSINGLE_ADDSUB2,
TILEGX_INSN_FSINGLE_MUL1,
TILEGX_INSN_FSINGLE_MUL2,
TILEGX_INSN_FSINGLE_PACK1,
TILEGX_INSN_FSINGLE_PACK2,
TILEGX_INSN_FSINGLE_SUB1,
TILEGX_INSN_ICOH,
TILEGX_INSN_ILL,
TILEGX_INSN_INFO,
TILEGX_INSN_INFOL,
TILEGX_INSN_INV,
TILEGX_INSN_LD,
TILEGX_INSN_LD1S,
TILEGX_INSN_LD1U,
TILEGX_INSN_LD2S,
TILEGX_INSN_LD2U,
TILEGX_INSN_LD4S,
TILEGX_INSN_LD4U,
TILEGX_INSN_LDNA,
TILEGX_INSN_LDNT,
TILEGX_INSN_LDNT1S,
TILEGX_INSN_LDNT1U,
TILEGX_INSN_LDNT2S,
TILEGX_INSN_LDNT2U,
TILEGX_INSN_LDNT4S,
TILEGX_INSN_LDNT4U,
TILEGX_INSN_LD_L2,
TILEGX_INSN_LD1S_L2,
TILEGX_INSN_LD1U_L2,
TILEGX_INSN_LD2S_L2,
TILEGX_INSN_LD2U_L2,
TILEGX_INSN_LD4S_L2,
TILEGX_INSN_LD4U_L2,
TILEGX_INSN_LDNA_L2,
TILEGX_INSN_LDNT_L2,
TILEGX_INSN_LDNT1S_L2,
TILEGX_INSN_LDNT1U_L2,
TILEGX_INSN_LDNT2S_L2,
TILEGX_INSN_LDNT2U_L2,
TILEGX_INSN_LDNT4S_L2,
TILEGX_INSN_LDNT4U_L2,
TILEGX_INSN_LD_MISS,
TILEGX_INSN_LD1S_MISS,
TILEGX_INSN_LD1U_MISS,
TILEGX_INSN_LD2S_MISS,
TILEGX_INSN_LD2U_MISS,
TILEGX_INSN_LD4S_MISS,
TILEGX_INSN_LD4U_MISS,
TILEGX_INSN_LDNA_MISS,
TILEGX_INSN_LDNT_MISS,
TILEGX_INSN_LDNT1S_MISS,
TILEGX_INSN_LDNT1U_MISS,
TILEGX_INSN_LDNT2S_MISS,
TILEGX_INSN_LDNT2U_MISS,
TILEGX_INSN_LDNT4S_MISS,
TILEGX_INSN_LDNT4U_MISS,
TILEGX_INSN_LNK,
TILEGX_INSN_MF,
TILEGX_INSN_MFSPR,
TILEGX_INSN_MM,
TILEGX_INSN_MNZ,
TILEGX_INSN_MOVE,
TILEGX_INSN_MTSPR,
TILEGX_INSN_MUL_HS_HS,
TILEGX_INSN_MUL_HS_HU,
TILEGX_INSN_MUL_HS_LS,
TILEGX_INSN_MUL_HS_LU,
TILEGX_INSN_MUL_HU_HU,
TILEGX_INSN_MUL_HU_LS,
TILEGX_INSN_MUL_HU_LU,
TILEGX_INSN_MUL_LS_LS,
TILEGX_INSN_MUL_LS_LU,
TILEGX_INSN_MUL_LU_LU,
TILEGX_INSN_MULA_HS_HS,
TILEGX_INSN_MULA_HS_HU,
TILEGX_INSN_MULA_HS_LS,
TILEGX_INSN_MULA_HS_LU,
TILEGX_INSN_MULA_HU_HU,
TILEGX_INSN_MULA_HU_LS,
TILEGX_INSN_MULA_HU_LU,
TILEGX_INSN_MULA_LS_LS,
TILEGX_INSN_MULA_LS_LU,
TILEGX_INSN_MULA_LU_LU,
TILEGX_INSN_MULAX,
TILEGX_INSN_MULX,
TILEGX_INSN_MZ,
TILEGX_INSN_NAP,
TILEGX_INSN_NOP,
TILEGX_INSN_NOR,
TILEGX_INSN_OR,
TILEGX_INSN_PCNT,
TILEGX_INSN_PREFETCH_L1,
TILEGX_INSN_PREFETCH_L1_FAULT,
TILEGX_INSN_PREFETCH_L2,
TILEGX_INSN_PREFETCH_L2_FAULT,
TILEGX_INSN_PREFETCH_L3,
TILEGX_INSN_PREFETCH_L3_FAULT,
TILEGX_INSN_REVBITS,
TILEGX_INSN_REVBYTES,
TILEGX_INSN_ROTL,
TILEGX_INSN_SHL,
TILEGX_INSN_SHL16INSLI,
TILEGX_INSN_SHL1ADD,
TILEGX_INSN_SHL1ADDX,
TILEGX_INSN_SHL2ADD,
TILEGX_INSN_SHL2ADDX,
TILEGX_INSN_SHL3ADD,
TILEGX_INSN_SHL3ADDX,
TILEGX_INSN_SHLX,
TILEGX_INSN_SHRS,
TILEGX_INSN_SHRU,
TILEGX_INSN_SHRUX,
TILEGX_INSN_SHUFFLEBYTES,
TILEGX_INSN_ST,
TILEGX_INSN_ST1,
TILEGX_INSN_ST2,
TILEGX_INSN_ST4,
TILEGX_INSN_STNT,
TILEGX_INSN_STNT1,
TILEGX_INSN_STNT2,
TILEGX_INSN_STNT4,
TILEGX_INSN_SUB,
TILEGX_INSN_SUBX,
TILEGX_INSN_SUBXSC,
TILEGX_INSN_TBLIDXB0,
TILEGX_INSN_TBLIDXB1,
TILEGX_INSN_TBLIDXB2,
TILEGX_INSN_TBLIDXB3,
TILEGX_INSN_V1ADD,
TILEGX_INSN_V1ADDI,
TILEGX_INSN_V1ADDUC,
TILEGX_INSN_V1ADIFFU,
TILEGX_INSN_V1AVGU,
TILEGX_INSN_V1CMPEQ,
TILEGX_INSN_V1CMPEQI,
TILEGX_INSN_V1CMPLES,
TILEGX_INSN_V1CMPLEU,
TILEGX_INSN_V1CMPLTS,
TILEGX_INSN_V1CMPLTSI,
TILEGX_INSN_V1CMPLTU,
TILEGX_INSN_V1CMPLTUI,
TILEGX_INSN_V1CMPNE,
TILEGX_INSN_V1DDOTPU,
TILEGX_INSN_V1DDOTPUA,
TILEGX_INSN_V1DDOTPUS,
TILEGX_INSN_V1DDOTPUSA,
TILEGX_INSN_V1DOTP,
TILEGX_INSN_V1DOTPA,
TILEGX_INSN_V1DOTPU,
TILEGX_INSN_V1DOTPUA,
TILEGX_INSN_V1DOTPUS,
TILEGX_INSN_V1DOTPUSA,
TILEGX_INSN_V1INT_H,
TILEGX_INSN_V1INT_L,
TILEGX_INSN_V1MAXU,
TILEGX_INSN_V1MAXUI,
TILEGX_INSN_V1MINU,
TILEGX_INSN_V1MINUI,
TILEGX_INSN_V1MNZ,
TILEGX_INSN_V1MULTU,
TILEGX_INSN_V1MULU,
TILEGX_INSN_V1MULUS,
TILEGX_INSN_V1MZ,
TILEGX_INSN_V1SADAU,
TILEGX_INSN_V1SADU,
TILEGX_INSN_V1SHL,
TILEGX_INSN_V1SHLI,
TILEGX_INSN_V1SHRS,
TILEGX_INSN_V1SHRSI,
TILEGX_INSN_V1SHRU,
TILEGX_INSN_V1SHRUI,
TILEGX_INSN_V1SUB,
TILEGX_INSN_V1SUBUC,
TILEGX_INSN_V2ADD,
TILEGX_INSN_V2ADDI,
TILEGX_INSN_V2ADDSC,
TILEGX_INSN_V2ADIFFS,
TILEGX_INSN_V2AVGS,
TILEGX_INSN_V2CMPEQ,
TILEGX_INSN_V2CMPEQI,
TILEGX_INSN_V2CMPLES,
TILEGX_INSN_V2CMPLEU,
TILEGX_INSN_V2CMPLTS,
TILEGX_INSN_V2CMPLTSI,
TILEGX_INSN_V2CMPLTU,
TILEGX_INSN_V2CMPLTUI,
TILEGX_INSN_V2CMPNE,
TILEGX_INSN_V2DOTP,
TILEGX_INSN_V2DOTPA,
TILEGX_INSN_V2INT_H,
TILEGX_INSN_V2INT_L,
TILEGX_INSN_V2MAXS,
TILEGX_INSN_V2MAXSI,
TILEGX_INSN_V2MINS,
TILEGX_INSN_V2MINSI,
TILEGX_INSN_V2MNZ,
TILEGX_INSN_V2MULFSC,
TILEGX_INSN_V2MULS,
TILEGX_INSN_V2MULTS,
TILEGX_INSN_V2MZ,
TILEGX_INSN_V2PACKH,
TILEGX_INSN_V2PACKL,
TILEGX_INSN_V2PACKUC,
TILEGX_INSN_V2SADAS,
TILEGX_INSN_V2SADAU,
TILEGX_INSN_V2SADS,
TILEGX_INSN_V2SADU,
TILEGX_INSN_V2SHL,
TILEGX_INSN_V2SHLI,
TILEGX_INSN_V2SHLSC,
TILEGX_INSN_V2SHRS,
TILEGX_INSN_V2SHRSI,
TILEGX_INSN_V2SHRU,
TILEGX_INSN_V2SHRUI,
TILEGX_INSN_V2SUB,
TILEGX_INSN_V2SUBSC,
TILEGX_INSN_V4ADD,
TILEGX_INSN_V4ADDSC,
TILEGX_INSN_V4INT_H,
TILEGX_INSN_V4INT_L,
TILEGX_INSN_V4PACKSC,
TILEGX_INSN_V4SHL,
TILEGX_INSN_V4SHLSC,
TILEGX_INSN_V4SHRS,
TILEGX_INSN_V4SHRU,
TILEGX_INSN_V4SUB,
TILEGX_INSN_V4SUBSC,
TILEGX_INSN_WH64,
TILEGX_INSN_XOR,
TILEGX_NETWORK_BARRIER,
TILEGX_IDN0_RECEIVE,
TILEGX_IDN1_RECEIVE,
TILEGX_IDN_SEND,
TILEGX_UDN0_RECEIVE,
TILEGX_UDN1_RECEIVE,
TILEGX_UDN2_RECEIVE,
TILEGX_UDN3_RECEIVE,
TILEGX_UDN_SEND,
TILEGX_BUILTIN_max
};
#endif /* !GCC_TILEGX_BUILTINS_H */

View File

@ -0,0 +1,55 @@
/* Definitions of C specific functions for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "machmode.h"
#include "tm.h"
#include "tm_p.h"
#include "cpplib.h"
#include "tree.h"
#include "c-family/c-common.h"
/* copy defines in c-cppbuiltin.c */
# define builtin_define(TXT) cpp_define (pfile, TXT)
# define builtin_assert(TXT) cpp_assert (pfile, TXT)
/* Implement TARGET_CPU_CPP_BUILTINS. */
void
tilegx_cpu_cpp_builtins (struct cpp_reader *pfile)
{
builtin_define ("__tile__");
builtin_define ("__tilegx__");
builtin_define ("__tile_chip__=10");
builtin_define ("__tile_chip_rev__=0");
builtin_assert ("cpu=tilegx");
builtin_assert ("machine=tilegx");
if (TARGET_32BIT)
builtin_define ("__tilegx32__");
TILEGX_CPU_CPP_ENDIAN_BUILTINS ();
GNU_USER_TARGET_OS_CPP_BUILTINS ();
}

View File

@ -0,0 +1,112 @@
;; Scheduling description for Tilera TILE-Gx chip.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_automaton "tile")
; Make the scheduling automaton an ndfa.
(automata_option "ndfa")
; Name the three pipes.
(define_cpu_unit "X0" "tile")
(define_cpu_unit "X1" "tile")
(define_cpu_unit "Y0" "tile")
(define_cpu_unit "Y1" "tile")
(define_cpu_unit "Y2" "tile")
(define_insn_reservation "X0" 1
(eq_attr "type" "X0")
"X0")
(define_insn_reservation "X0_2cycle" 2
(eq_attr "type" "X0_2cycle")
"X0,nothing")
(define_insn_reservation "X1" 1
(eq_attr "type" "X1,X1_branch")
"X1")
(define_insn_reservation "X1_2cycle" 2
(eq_attr "type" "X1_2cycle")
"X1,nothing")
(define_insn_reservation "X1_L2" 11
(eq_attr "type" "X1_L2")
"X1")
(define_insn_reservation "X1_miss" 80
(eq_attr "type" "X1_miss")
"X1")
(define_insn_reservation "X01" 1
(eq_attr "type" "X01")
"X0|X1")
(define_insn_reservation "Y0" 1
(eq_attr "type" "Y0")
"Y0|X0")
(define_insn_reservation "Y0_2cycle" 2
(eq_attr "type" "Y0_2cycle")
"Y0|X0,nothing")
(define_insn_reservation "Y1" 1
(eq_attr "type" "Y1")
"Y1|X1")
(define_insn_reservation "Y2" 1
(eq_attr "type" "Y2")
"Y2|X1")
(define_insn_reservation "Y2_2cycle" 2
(eq_attr "type" "Y2_2cycle")
"Y2|X1,nothing")
(define_insn_reservation "Y2_L2" 11
(eq_attr "type" "Y2_L2")
"Y2|X1")
(define_insn_reservation "Y2_miss" 80
(eq_attr "type" "Y2_miss")
"Y2|X1")
(define_insn_reservation "Y01" 1
(eq_attr "type" "Y01")
"Y0|Y1|X0|X1")
(define_insn_reservation "nothing" 0
(eq_attr "type" "nothing")
"nothing")
(define_insn_reservation "cannot_bundle" 1
(eq_attr "type" "cannot_bundle")
"X0+X1")
(define_insn_reservation "cannot_bundle_3cycle" 3
(eq_attr "type" "cannot_bundle_3cycle")
"X0+X1")
(define_insn_reservation "cannot_bundle_4cycle" 4
(eq_attr "type" "cannot_bundle_4cycle")
"X0+X1")
; A bundle must be in either X format or Y format.
(exclusion_set "X0,X1" "Y0,Y1,Y2")

View File

@ -0,0 +1,38 @@
/* TILE-Gx extra machine modes.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Extra modes for handling struct returns in up to 10 registers. */
INT_MODE (R3I, 24);
INT_MODE (R5I, 40);
INT_MODE (R6I, 48);
INT_MODE (R7I, 56);
INT_MODE (R8I, 64);
INT_MODE (R9I, 72);
INT_MODE (R10I, 80);
/* Vector modes. */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODE (INT, QI, 16); /* V16QI */
VECTOR_MODE (INT, HI, 8); /* V8HI */
VECTOR_MODE (INT, SI, 4); /* V4SI */
VECTOR_MODE (INT, HI, 2); /* V2HI */
VECTOR_MODE (INT, QI, 4); /* V4QI */

View File

@ -0,0 +1,79 @@
/* Header for constant multiple table for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TILEGX_MULTIPLY_H
#define GCC_TILEGX_MULTIPLY_H
/* A node of a tilegx_multiply_insn_seq, corresponding to a single
machine instruction such as 'add', 's1a', or an shl by a constant. */
struct tilegx_multiply_insn_seq_entry
{
/* Which operation this node performs (e.g. an add or sub).
Don't use this directly, call get_opcode() table to get a insn_code. */
unsigned char compressed_opcode;
/* The left-hand side of this expression tree.
If equal to 0, it refers to 'zero'.
If equal to 1, it refers to the original input to the multiply operation.
Otherwise, subtract two and it is an index into the containing
tilegx_multiply_insn_seq's 'op' array. Since it can only point to some
value that has already been computed it will always point to an
earlier entry in the array. */
unsigned char lhs;
/* This is like lhs, but for the right-hand side. However, for shift
opcodes this is a shift count rather than an operand index. */
unsigned char rhs;
};
/* Maximum size of op array. */
#define tilegx_multiply_insn_seq_MAX_OPERATIONS 4
/* This defines a DAG describing how to multiply by a constant in
terms of one or more machine instructions. */
struct tilegx_multiply_insn_seq
{
/* The constant factor by which this expression tree multiplies its input. */
long long multiplier;
/* The nodes of the parse tree. These are ordered so that instructions
can be emitted in the same order that they appear in this array.
Entry entry in this array can only refer to earlier entries in
the array. */
struct tilegx_multiply_insn_seq_entry
op[tilegx_multiply_insn_seq_MAX_OPERATIONS];
};
/* A mapping from the compressed opcode to the corresponding enum
insn_code. */
extern const enum insn_code tilegx_multiply_insn_seq_decode_opcode[];
/* Table mapping constant int multipliers to an expression
tree that efficiently performs that multiplication.
This is sorted by its 'multiplier' field so a binary search
can look for matches. */
extern const struct tilegx_multiply_insn_seq tilegx_multiply_insn_seq_table[];
/* The number of elements in multiply_insn_seq_table. */
extern const int tilegx_multiply_insn_seq_table_size;
#endif /* !GCC_TILEGX_MULTIPLY_H */

View File

@ -0,0 +1,74 @@
/* Prototypes of target machine for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TILEGX_PROTOS_H
#define GCC_TILEGX_PROTOS_H
extern void tilegx_init_expanders (void);
extern bool tilegx_legitimate_pic_operand_p (rtx);
extern rtx tilegx_simd_int (rtx, enum machine_mode);
#ifdef RTX_CODE
extern bool tilegx_bitfield_operand_p (HOST_WIDE_INT, int *, int *);
extern void tilegx_expand_set_const64 (rtx, rtx);
extern bool tilegx_expand_mov (enum machine_mode, rtx *);
extern void tilegx_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT, bool);
extern void tilegx_expand_movmisalign (enum machine_mode, rtx *);
extern void tilegx_allocate_stack (rtx, rtx);
extern bool tilegx_expand_muldi (rtx, rtx, rtx);
extern void tilegx_expand_smuldi3_highpart (rtx, rtx, rtx);
extern void tilegx_expand_umuldi3_highpart (rtx, rtx, rtx);
extern bool tilegx_emit_setcc (rtx[], enum machine_mode);
extern void tilegx_emit_conditional_branch (rtx[], enum machine_mode);
extern rtx tilegx_emit_conditional_move (rtx);
extern const char *tilegx_output_cbranch_with_opcode (rtx, rtx *,
const char *,
const char *, int);
extern const char *tilegx_output_cbranch (rtx, rtx *, bool);
extern void tilegx_expand_tablejump (rtx, rtx);
extern void tilegx_expand_builtin_vector_binop (rtx (*)(rtx, rtx, rtx),
enum machine_mode, rtx,
enum machine_mode, rtx, rtx,
bool);
extern void tilegx_pre_atomic_barrier (enum memmodel);
extern void tilegx_post_atomic_barrier (enum memmodel);
#endif /* RTX_CODE */
extern bool tilegx_can_use_return_insn_p (void);
extern void tilegx_expand_prologue (void);
extern void tilegx_expand_epilogue (bool);
extern int tilegx_initial_elimination_offset (int, int);
extern rtx tilegx_return_addr (int, rtx);
extern rtx tilegx_eh_return_handler_rtx (void);
extern int tilegx_adjust_insn_length (rtx, int);
extern int tilegx_asm_preferred_eh_data_format (int, int);
extern void tilegx_final_prescan_insn (rtx);
extern const char *tilegx_asm_output_opcode (FILE *, const char *);
extern void tilegx_function_profiler (FILE *, int);
/* Declare functions in tilegx-c.c */
extern void tilegx_cpu_cpp_builtins (struct cpp_reader *);
#endif /* GCC_TILEGX_PROTOS_H */

5501
gcc/config/tilegx/tilegx.c Normal file

File diff suppressed because it is too large Load Diff

505
gcc/config/tilegx/tilegx.h Normal file
View File

@ -0,0 +1,505 @@
/* Definitions of target machine for GNU compiler for TILE-Gx.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* This is used by tilegx_cpu_cpp_builtins to indicate the byte order
we're compiling for. */
#define TILEGX_CPU_CPP_ENDIAN_BUILTINS() \
do \
{ \
if (TARGET_BIG_ENDIAN) \
builtin_define ("__BIG_ENDIAN__"); \
else \
builtin_define ("__LITTLE_ENDIAN__"); \
} \
while (0)
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
tilegx_cpu_cpp_builtins (pfile)
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE (TARGET_32BIT ? "int" : "long int")
#undef SIZE_TYPE
#define SIZE_TYPE (TARGET_32BIT ? "unsigned int" : "long unsigned int")
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
/* Target machine storage layout */
#define TARGET_BIG_ENDIAN 0
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN TARGET_BIG_ENDIAN
#define WORDS_BIG_ENDIAN TARGET_BIG_ENDIAN
#define UNITS_PER_WORD 8
#define PARM_BOUNDARY BITS_PER_WORD
#define STACK_BOUNDARY 64
#define FUNCTION_BOUNDARY 64
#define BIGGEST_ALIGNMENT 64
#define STRICT_ALIGNMENT 1
#define INT_TYPE_SIZE 32
#define LONG_TYPE_SIZE (TARGET_32BIT ? 32 : 64)
#define LONG_LONG_TYPE_SIZE 64
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 64
#define POINTER_SIZE LONG_TYPE_SIZE
#define PCC_BITFIELD_TYPE_MATTERS 1
#define FASTEST_ALIGNMENT 64
#define BIGGEST_FIELD_ALIGNMENT 64
#define WIDEST_HARDWARE_FP_SIZE 64
/* Unaligned moves trap and are very slow. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
/* Make strings word-aligned so strcpy from constants will be
faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < FASTEST_ALIGNMENT) \
? FASTEST_ALIGNMENT : (ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Make local arrays of chars word-aligned for the same reasons. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
/* Standard register usage. */
#define FIRST_PSEUDO_REGISTER (64 + 4)
#define FIXED_REGISTERS \
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1}
#define CALL_USED_REGISTERS \
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1}
#define CALL_REALLY_USED_REGISTERS \
CALL_USED_REGISTERS
#define REG_ALLOC_ORDER { \
10, 11, 12, 13, 14, /* call used */ \
15, 16, 17, 18, 19, \
20, 21, 22, 23, 24, \
25, 26, 27, 28, 29, \
\
9, 8, 7, 6, 5, /* argument */ \
4, 3, 2, 1, 0, \
\
55, /* return address */ \
\
30, 31, 32, 33, 34, /* call saved registers */ \
35, 36, 37, 38, 39, \
40, 41, 42, 43, 44, \
45, 46, 47, 48, 49, \
50, 51, \
\
52, /* hard frame pointer */ \
53, 54, /* tp, sp */ \
\
56, 57, 58, 59, 60, /* special purpose */ \
61, 62, 63, 64, 65, /* or fake registers */ \
66, 67 \
}
#define HARD_REGNO_NREGS(REGNO, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
#define MODES_TIEABLE_P(MODE1, MODE2) 1
/* Register that holds an address into the text segment that can be
used by pic code. */
#define TILEGX_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 51 : INVALID_REGNUM)
#define HARD_FRAME_POINTER_REGNUM 52
#define THREAD_POINTER_REGNUM 53
#define STACK_POINTER_REGNUM 54
#define TILEGX_LINK_REGNUM 55
#define FRAME_POINTER_REGNUM 64
#define ARG_POINTER_REGNUM 65
/* SPR storing the comparison value for compare and exchange. */
#define TILEGX_CMPEXCH_REGNUM 66
/* Pseudo registers used to enforce order between instructions that
touch the networks. */
#define TILEGX_NETORDER_REGNUM 67
#define STATIC_CHAIN_REGNUM 10
enum reg_class
{
NO_REGS,
R0_REGS,
R1_REGS,
R2_REGS,
R3_REGS,
R4_REGS,
R5_REGS,
R6_REGS,
R7_REGS,
R8_REGS,
R9_REGS,
R10_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Since GENERAL_REGS is the same class as ALL_REGS, don't give it a
different class number; just make it an alias. */
#define GENERAL_REGS ALL_REGS
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
"R0_REGS", \
"R1_REGS", \
"R2_REGS", \
"R3_REGS", \
"R4_REGS", \
"R5_REGS", \
"R6_REGS", \
"R7_REGS", \
"R8_REGS", \
"R9_REGS", \
"R10_REGS", \
"ALL_REGS" \
}
#define REG_CLASS_CONTENTS \
{ \
{ 0 }, \
{ 1 << 0 }, \
{ 1 << 1 }, \
{ 1 << 2 }, \
{ 1 << 3 }, \
{ 1 << 4 }, \
{ 1 << 5 }, \
{ 1 << 6 }, \
{ 1 << 7 }, \
{ 1 << 8 }, \
{ 1 << 9 }, \
{ 1 << 10 }, \
{ 0xffffffff, 0xffffffff } \
}
#define REGNO_REG_CLASS(REGNO) \
((unsigned)(REGNO) <= 10 ? \
(enum reg_class)(R0_REGS + (REGNO)) : ALL_REGS)
#define INDEX_REG_CLASS NO_REGS
#define BASE_REG_CLASS ALL_REGS
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD
#define FRAME_GROWS_DOWNWARD 1
#define STARTING_FRAME_OFFSET 0
#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant ((FRAME), UNITS_PER_WORD)
#define FIRST_PARM_OFFSET(FNDECL) 0
#define ACCUMULATE_OUTGOING_ARGS 1
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
#define INCOMING_FRAME_SP_OFFSET 0
#define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD)
#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
#define DEFAULT_PCC_STRUCT_RETURN 0
/* The first 10 registers may hold return value. */
#define TILEGX_NUM_RETURN_REGS 10
/* The first 10 registers hold function arguments. */
#define TILEGX_NUM_ARG_REGS 10
#define FUNCTION_ARG_REGNO_P(N) ((N) < TILEGX_NUM_ARG_REGS)
/* The type used to store the number of words of arguments scanned so
far during argument scanning. This includes any space that is
skipped. */
#define CUMULATIVE_ARGS int
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
((CUM) = 0)
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
((OFFSET) = tilegx_initial_elimination_offset((FROM),(TO)))
#define FUNCTION_PROFILER(FILE, LABELNO) \
tilegx_function_profiler (FILE, LABELNO)
#define TRAMPOLINE_SIZE (TARGET_32BIT ? 48 : 56)
#define TRAMPOLINE_ALIGNMENT 64
#define TRAMPOLINE_SECTION text_section
/* Call frame debugging information. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, TILEGX_LINK_REGNUM)
#define RETURN_ADDR_RTX tilegx_return_addr
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (TILEGX_LINK_REGNUM)
#define DWARF_ZERO_REG 63
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N + 12) : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 11)
#define EH_RETURN_HANDLER_RTX tilegx_eh_return_handler_rtx ()
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
tilegx_asm_preferred_eh_data_format ((CODE), (GLOBAL))
/* Addressing modes, and classification of registers for them. */
#define HAVE_POST_INCREMENT 1
#define HAVE_POST_DECREMENT 1
#define HAVE_POST_MODIFY_DISP 1
#define REGNO_OK_FOR_INDEX_P(regno) 0
#define REGNO_OK_FOR_BASE_P(regno) \
((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
#define MAX_REGS_PER_ADDRESS 1
#define CONSTANT_ADDRESS_P(X) 0
#define LEGITIMATE_PIC_OPERAND_P(X) tilegx_legitimate_pic_operand_p (X)
#define CASE_VECTOR_MODE Pmode
#define CASE_VECTOR_PC_RELATIVE 0
#define JUMP_TABLES_IN_TEXT_SECTION 0
#define DEFAULT_SIGNED_CHAR 1
#define MOVE_MAX UNITS_PER_WORD
/* Use a value of 11 for MOVE_RATIO and friends, because TILEPro
returns structs as large as 10 words in registers. Because of some
some code generation inefficiency, we never get smaller code for
turning that into a memcpy, so pick a value that guarantees this
doesn't happen. */
#define TILEGX_CALL_RATIO 11
#define MOVE_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
#define CLEAR_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
#define SET_RATIO(speed) ((speed) ? 15 : TILEGX_CALL_RATIO)
#define WORD_REGISTER_OPERATIONS
#define LOAD_EXTEND_OP(MODE) ((MODE) == SImode ? SIGN_EXTEND : ZERO_EXTEND)
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
{ \
if ((MODE) == SImode) \
(UNSIGNEDP) = 0; \
(MODE) = DImode; \
}
/* Define SLOW_BYTE_ACCESS to avoid making a QI or HI mode
register. */
#define SLOW_BYTE_ACCESS 1
#define SHIFT_COUNT_TRUNCATED 0
#define SHORT_IMMEDIATES_SIGN_EXTEND
/* We represent all SI values as sign-extended DI values in
registers. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) \
((INPREC) <= 32 || (OUTPREC) > 32)
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1)
#define Pmode (TARGET_32BIT ? SImode : DImode)
#define STACK_SIZE_MODE Pmode
#define STORE_FLAG_VALUE 1
#define FUNCTION_MODE DImode
#define NO_FUNCTION_CSE 1
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
((LENGTH) = tilegx_adjust_insn_length ((INSN), (LENGTH)))
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
#define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6)
/* Control the assembler format that we output. */
#undef NO_DOLLAR_IN_LABEL
#define ASM_COMMENT_START "##"
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#undef READONLY_DATA_SECTION_ASM_OP
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\""
#undef BSS_SECTION_ASM_OP
#define BSS_SECTION_ASM_OP "\t.section\t.bss, \"wa\""
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP "\t.section\t.init, \"ax\""
#undef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP "\t.section\t.fini, \"ax\""
#define GLOBAL_ASM_OP ".global "
#define SUPPORTS_WEAK 1
#define USER_LABEL_PREFIX ""
#define REGISTER_PREFIX ""
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "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", "tp", "sp", "lr", \
"?r56?","idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero", \
"?FRAME?", "?ARG?", "?CMPEXCH?", "?NET?" }
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
tilegx_final_prescan_insn (insn)
#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
(PTR = tilegx_asm_output_opcode (STREAM, PTR))
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do \
{ \
char label[256]; \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
fprintf (FILE, "\t%s ", \
integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \
assemble_name (FILE, label); \
fprintf (FILE, "\n"); \
} \
while (0)
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
do \
{ \
char label[256]; \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
fprintf (FILE, "\t%s ", \
integer_asm_op (GET_MODE_SIZE (Pmode), TRUE)); \
assemble_name (FILE, label); \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \
fprintf (FILE, "-"); \
assemble_name (FILE, label); \
fprintf (FILE, "\n"); \
} \
while (0)
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
#define INIT_EXPANDERS tilegx_init_expanders ()
/* A C structure for machine-specific, per-function data. This is
added to the cfun structure. */
typedef struct GTY(()) machine_function
{
/* Symbol for the text label used for pic. */
rtx text_label_symbol;
/* Register for the text label. */
rtx text_label_rtx;
/* Register for the pic offset table. */
rtx got_rtx;
/* The function calls tls_get_addr. */
int calls_tls_get_addr;
} machine_function;
#ifndef HAVE_AS_TLS
#define HAVE_AS_TLS 0
#endif

5121
gcc/config/tilegx/tilegx.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
; Options for the TILE-Gx port of the compiler.
; Copyright (C) 2011, 2012
; Free Software Foundation, Inc.
; Contributed by Walter Lee (walt@tilera.com)
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 3, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
mcpu=
Target RejectNegative Joined Enum(tilegx_cpu) Var(tilegx_cpu) Init(0)
-mcpu=CPU Use features of and schedule code for given CPU
Enum
Name(tilegx_cpu) Type(int)
Known TILE-Gx CPUs (for use with the -mcpu= option):
EnumValue
Enum(tilegx_cpu) String(tilegx) Value(0)
m32
Target Report RejectNegative Negative(m64) Mask(32BIT)
Compile with 32 bit longs and pointers.
m64
Target Report RejectNegative Negative(m32) InverseMask(32BIT, 64BIT)
Compile with 64 bit longs and pointers.

View File

@ -0,0 +1,102 @@
;; Constraint definitions for Tilera TILEPro chip.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_register_constraint "R00" "R0_REGS" "r0")
(define_register_constraint "R01" "R1_REGS" "r1")
(define_register_constraint "R02" "R2_REGS" "r2")
(define_register_constraint "R03" "R3_REGS" "r3")
(define_register_constraint "R04" "R4_REGS" "r4")
(define_register_constraint "R05" "R5_REGS" "r5")
(define_register_constraint "R06" "R6_REGS" "r6")
(define_register_constraint "R07" "R7_REGS" "r7")
(define_register_constraint "R08" "R8_REGS" "r8")
(define_register_constraint "R09" "R9_REGS" "r9")
(define_register_constraint "R10" "R10_REGS" "r10")
(define_constraint "I"
"A signed 8 bit constant"
(and (match_code "const_int")
(match_test "ival >= -128 && ival <= 127")))
(define_constraint "J"
"Signed 16-bit integer constant"
(and (match_code "const_int")
(match_test "ival >= -32768 && ival <= 32767")))
(define_constraint "K"
"Nonzero integer constant with low 16 bits zero"
(and (match_code "const_int")
(match_test "ival && (ival & 0xFFFF) == 0")))
(define_constraint "L"
"Integer constant that fits in one signed byte when incremented"
(and (match_code "const_int")
(match_test "ival >= -129 && ival <= 126")))
(define_constraint "M"
"A bit mask suitable for 'mm'"
(and (match_code "const_int")
(match_test "tilepro_bitfield_operand_p (ival, NULL, NULL)")))
(define_constraint "N"
"Integer constant that is a byte tiled out four times"
(and (match_code "const_int")
(match_test "(ival & 0xFFFFFFFF) == (ival & 0xFF) * 0x01010101")))
(define_constraint "O"
"The integer zero constant"
(and (match_code "const_int")
(match_test "ival == 0")))
(define_constraint "P"
"Integer constant that is a sign-extended byte tiled out as two shorts"
(and (match_code "const_int")
(match_test "((ival & 0xFFFFFFFF)
== ((trunc_int_for_mode (ival, QImode) & 0xFFFF)
* 0x00010001))")))
(define_constraint "Q"
"Integer constant that fits in one signed byte when incremented, but not -1"
(and (match_code "const_int")
(match_test "ival >= -129 && ival <= 126 && ival != -1")))
(define_constraint "T"
"A const symbolc operand"
(match_operand 0 "const_symbolic_operand"))
(define_memory_constraint "U"
"Non-auto-incrementing memory"
(and (match_code "mem")
(match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC")))
(define_constraint "W"
"A 4-element vector constant with identical elements"
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 4")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)")))
(define_constraint "Y"
"A 2-element vector constant with identical elements"
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 2")
(match_test "CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)")))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
/* Definitions for TILEPro running Linux-based GNU systems with ELF.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#undef CPP_SPEC
#define CPP_SPEC "%{pthread:-D_REENTRANT}"
#undef LINK_SPEC
#define LINK_SPEC "\
%{shared:-shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
-dynamic-linker /lib/ld.so.1} \
%{static:-static}}"
#define NO_PROFILE_COUNTERS 1
#undef MCOUNT_NAME
#define MCOUNT_NAME "__mcount"
#undef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 1
#ifdef TARGET_LIBC_PROVIDES_SSP
/* TILEPro glibc provides __stack_chk_guard two pointer-size words before
tp. */
#define TARGET_THREAD_SSP_OFFSET (-2 * GET_MODE_SIZE (ptr_mode))
#endif
/* For __clear_cache in libgcc2.c. */
#ifdef IN_LIBGCC2
#include <arch/icache.h>
/* Use the minimum page size of 4K. Alternatively we can call getpagesize()
but it introduces a libc dependence. */
#undef CLEAR_INSN_CACHE
#define CLEAR_INSN_CACHE(beg, end) invalidate_icache (beg, end - beg, 4096)
#else
/* define CLEAR_INSN_CACHE so that gcc knows to expand __builtin__clear_cache
to the libraray call. */
#undef CLEAR_INSN_CACHE
#define CLEAR_INSN_CACHE 1
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,261 @@
;; Predicate definitions for Tilera TILEPro chip.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; Return true if OP is the zero constant for MODE.
(define_predicate "const_zero_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (mode)")))
;; Returns true if OP is either the constant zero or a register.
(define_predicate "reg_or_0_operand"
(and (ior (match_operand 0 "register_operand")
(match_operand 0 "const_zero_operand"))
(match_test "GET_MODE_SIZE (mode) <= UNITS_PER_WORD")))
; Return 1 if OP is a network register identifier.
(define_predicate "netreg_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 6)")))
; Return 1 if OP is an unsigned 5-bit constant.
(define_predicate "u5bit_cint_operand"
(and (match_code "const_int")
(match_test "INTVAL (op) == (INTVAL (op) & 0x1F)")))
;; Return 1 if OP is an unsigned 16-bit constant.
(define_predicate "u16bit_cint_operand"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT)INTVAL (op) < (1U << 16)")))
;; Return 1 if OP is a signed 8-bit constant.
(define_predicate "s8bit_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_I (op)")))
;; Return 1 if OP is a signed 16-bit constant.
(define_predicate "s16bit_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_J (op)")))
;; Return 1 if OP is a nonzero integer constant whose low 16 bits are zero.
(define_predicate "auli_cint_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_K (op)")))
;; Return 1 if OP is an unsigned 15-bit constant.
(define_predicate "u15bit_cint_operand"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT)INTVAL (op) < (1U << 15)")))
;; Return 1 if OP is a constant or any register.
(define_predicate "reg_or_cint_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_int_operand")))
;; Return 1 if OP is a 4-element vector constant with identical signed
;; 8-bit elements or any register.
(define_predicate "reg_or_v4s8bit_operand"
(ior (match_operand 0 "register_operand")
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 4
&& satisfies_constraint_I (CONST_VECTOR_ELT (op, 0))
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 2)
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 3)"))))
;; Return 1 if OP is a 2-element vector constant with identical signed
;; 8-bit elements or any register.
(define_predicate "reg_or_v2s8bit_operand"
(ior (match_operand 0 "register_operand")
(and (match_code "const_vector")
(match_test "CONST_VECTOR_NUNITS (op) == 2
&& satisfies_constraint_I (CONST_VECTOR_ELT (op, 0))
&& CONST_VECTOR_ELT (op, 0) == CONST_VECTOR_ELT (op, 1)"))))
;; Return 1 if the operand is a valid second operand to an add insn.
(define_predicate "add_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_J (op) || satisfies_constraint_K (op)")
(match_operand 0 "register_operand")))
;; Return 1 if the operand is a register or signed 8-bit immediate operand.
(define_predicate "reg_or_s8bit_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_I (op)")
(match_operand 0 "register_operand")))
;; Return 1 for an operand suitable for ANDing with a register.
(define_predicate "and_operand"
(if_then_else (match_code "const_int")
(match_test "satisfies_constraint_I (op) || satisfies_constraint_M (op)")
(match_operand 0 "register_operand")))
;; Return 1 if the operand is a register or unsigned 5-bit immediate operand.
(define_predicate "reg_or_u5bit_operand"
(if_then_else (match_code "const_int")
(match_test "INTVAL (op) == (INTVAL (op) & 0x1F)")
(match_operand 0 "register_operand")))
; Return 1 if the operand is 2, 4 or 8.
(define_predicate "cint_248_operand"
(and (match_code "const_int")
(match_test
"INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8")))
;; Return true if OP is a TLS symbolic operand.
(define_predicate "tls_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) != TLS_MODEL_NONE")))
;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
(define_predicate "tls_gd_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
(define_predicate "tls_ld_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
;; Return true if OP is a symbolic operand that can be used for the
;; TLS Initial Exec model.
(define_predicate "tls_ie_symbolic_operand"
(and (match_code "symbol_ref")
(ior (match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC"))))
;; Return true if OP is a symbolic operand for the TLS Local Exec model.
(define_predicate "tls_le_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
;; Returns true if OP is any general operand except for an
;; auto-incrementing address operand.
(define_predicate "nonautoinc_operand"
(and (match_operand 0 "general_operand")
(not (ior (match_code "pre_dec") (match_code "pre_inc")
(match_code "post_dec") (match_code "post_inc")
(match_code "post_modify") (match_code "pre_modify")))))
;; Returns true if OP is a non-auto-incrementing memory operand.
(define_predicate "nonautoincmem_operand"
(match_operand 0 "memory_operand")
{
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
})
;; Returns true if OP is a non-auto-incrementing memory, general
;; operand.
(define_predicate "nonautoincmem_general_operand"
(match_operand 0 "general_operand")
{
if (memory_operand (op, mode))
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
else
return true;
})
;; Returns true if OP is a non-auto-incrementing memory, non-immediate
;; operand.
(define_predicate "nonautoincmem_nonimmediate_operand"
(match_operand 0 "nonimmediate_operand")
{
if (memory_operand (op, mode))
return nonautoinc_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)));
else
return true;
})
;; Return true if OP is a valid operand for the source of a move insn.
(define_predicate "move_operand"
(match_operand 0 "general_operand")
{
/* If both modes are non-void they must be the same. */
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return false;
if (GET_MODE_SIZE (mode) > 4)
return false;
switch (GET_CODE (op))
{
case CONST_INT:
return (satisfies_constraint_J (op)
|| satisfies_constraint_K (op)
|| satisfies_constraint_N (op)
|| satisfies_constraint_P (op));
case HIGH:
return true;
case MEM:
return memory_address_p (mode, XEXP (op, 0));
default:
return register_operand (op, mode);
}
})
;; Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
;; possibly with an offset.
(define_predicate "symbolic_operand"
(ior (match_code "symbol_ref,label_ref")
(and (match_code "const")
(match_test "GET_CODE (XEXP (op,0)) == PLUS
&& (GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
|| GET_CODE (XEXP (XEXP (op,0), 0)) == LABEL_REF)
&& CONST_INT_P (XEXP (XEXP (op,0), 1))"))))
;; Returns 1 if OP is a symbolic operand, or a const unspec wrapper
;; representing a got reference, a tls reference, or pc-relative
;; reference.
(define_predicate "const_symbolic_operand"
(ior (match_operand 0 "symbolic_operand")
(and (match_code "const")
(match_test "GET_CODE (XEXP (op,0)) == UNSPEC")
(ior (match_test "XINT (XEXP (op,0), 1) == UNSPEC_GOT16_SYM")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_GOT32_SYM")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_PCREL_SYM")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_TLS_GD")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_TLS_IE")
(match_test "XINT (XEXP (op,0), 1) == UNSPEC_TLS_LE")))))
;; Return true if OP is an address suitable for a call insn.
;; Call insn on TILE can take a PC-relative constant address
;; or any regular memory address.
(define_predicate "call_address_operand"
(ior (match_operand 0 "symbolic_operand")
(match_test "memory_address_p (Pmode, op)")))
;; Return true if OP is an operand suitable for a call insn.
(define_predicate "call_operand"
(and (match_code "mem")
(match_test "call_address_operand (XEXP (op, 0), mode)")))
;; Return 1 if OP is a signed comparison operation.
;; We can use these directly in compares against zero.
(define_predicate "signed_comparison_operator"
(match_code "eq,ne,le,lt,ge,gt"))
;; Return 1 if OP is a equal or not-equal operation.
(define_predicate "eqne_operator"
(match_code "eq,ne"))

View File

@ -0,0 +1,15 @@
tilepro-c.o: $(srcdir)/config/tilepro/tilepro-c.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(MACHMODE_H) \
$(TM_H) $(TM_P_H) $(CPPLIB_H) $(TREE_H) $(C_COMMON_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
$(srcdir)/config/tilepro/mul-tables.c: \
$(srcdir)/config/tilepro/gen-mul-tables.cc
$(CC_FOR_BUILD) $(BUILD_CPPFLAGS) -O2 -DTILEPRO \
-o gen-mul-tables -lstdc++ $<;
./gen-mul-tables > $@
mul-tables.o: $(srcdir)/config/tilepro/mul-tables.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(EXPR_H) $(OPTABS_H) \
$(srcdir)/config/tilepro/tilepro-multiply.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<

View File

@ -0,0 +1,217 @@
/* Enum for builtin intrinsics for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TILEPRO_BUILTINS_H
#define GCC_TILEPRO_BUILTINS_H
enum tilepro_builtin
{
TILEPRO_INSN_ADD,
TILEPRO_INSN_ADDB,
TILEPRO_INSN_ADDBS_U,
TILEPRO_INSN_ADDH,
TILEPRO_INSN_ADDHS,
TILEPRO_INSN_ADDIB,
TILEPRO_INSN_ADDIH,
TILEPRO_INSN_ADDLIS,
TILEPRO_INSN_ADDS,
TILEPRO_INSN_ADIFFB_U,
TILEPRO_INSN_ADIFFH,
TILEPRO_INSN_AND,
TILEPRO_INSN_AULI,
TILEPRO_INSN_AVGB_U,
TILEPRO_INSN_AVGH,
TILEPRO_INSN_BITX,
TILEPRO_INSN_BYTEX,
TILEPRO_INSN_CLZ,
TILEPRO_INSN_CRC32_32,
TILEPRO_INSN_CRC32_8,
TILEPRO_INSN_CTZ,
TILEPRO_INSN_DRAIN,
TILEPRO_INSN_DTLBPR,
TILEPRO_INSN_DWORD_ALIGN,
TILEPRO_INSN_FINV,
TILEPRO_INSN_FLUSH,
TILEPRO_INSN_FNOP,
TILEPRO_INSN_ICOH,
TILEPRO_INSN_ILL,
TILEPRO_INSN_INFO,
TILEPRO_INSN_INFOL,
TILEPRO_INSN_INTHB,
TILEPRO_INSN_INTHH,
TILEPRO_INSN_INTLB,
TILEPRO_INSN_INTLH,
TILEPRO_INSN_INV,
TILEPRO_INSN_LB,
TILEPRO_INSN_LB_U,
TILEPRO_INSN_LH,
TILEPRO_INSN_LH_U,
TILEPRO_INSN_LNK,
TILEPRO_INSN_LW,
TILEPRO_INSN_LW_NA,
TILEPRO_INSN_LB_L2,
TILEPRO_INSN_LB_U_L2,
TILEPRO_INSN_LH_L2,
TILEPRO_INSN_LH_U_L2,
TILEPRO_INSN_LW_L2,
TILEPRO_INSN_LW_NA_L2,
TILEPRO_INSN_LB_MISS,
TILEPRO_INSN_LB_U_MISS,
TILEPRO_INSN_LH_MISS,
TILEPRO_INSN_LH_U_MISS,
TILEPRO_INSN_LW_MISS,
TILEPRO_INSN_LW_NA_MISS,
TILEPRO_INSN_MAXB_U,
TILEPRO_INSN_MAXH,
TILEPRO_INSN_MAXIB_U,
TILEPRO_INSN_MAXIH,
TILEPRO_INSN_MF,
TILEPRO_INSN_MFSPR,
TILEPRO_INSN_MINB_U,
TILEPRO_INSN_MINH,
TILEPRO_INSN_MINIB_U,
TILEPRO_INSN_MINIH,
TILEPRO_INSN_MM,
TILEPRO_INSN_MNZ,
TILEPRO_INSN_MNZB,
TILEPRO_INSN_MNZH,
TILEPRO_INSN_MOVE,
TILEPRO_INSN_MOVELIS,
TILEPRO_INSN_MTSPR,
TILEPRO_INSN_MULHH_SS,
TILEPRO_INSN_MULHH_SU,
TILEPRO_INSN_MULHH_UU,
TILEPRO_INSN_MULHHA_SS,
TILEPRO_INSN_MULHHA_SU,
TILEPRO_INSN_MULHHA_UU,
TILEPRO_INSN_MULHHSA_UU,
TILEPRO_INSN_MULHL_SS,
TILEPRO_INSN_MULHL_SU,
TILEPRO_INSN_MULHL_US,
TILEPRO_INSN_MULHL_UU,
TILEPRO_INSN_MULHLA_SS,
TILEPRO_INSN_MULHLA_SU,
TILEPRO_INSN_MULHLA_US,
TILEPRO_INSN_MULHLA_UU,
TILEPRO_INSN_MULHLSA_UU,
TILEPRO_INSN_MULLL_SS,
TILEPRO_INSN_MULLL_SU,
TILEPRO_INSN_MULLL_UU,
TILEPRO_INSN_MULLLA_SS,
TILEPRO_INSN_MULLLA_SU,
TILEPRO_INSN_MULLLA_UU,
TILEPRO_INSN_MULLLSA_UU,
TILEPRO_INSN_MVNZ,
TILEPRO_INSN_MVZ,
TILEPRO_INSN_MZ,
TILEPRO_INSN_MZB,
TILEPRO_INSN_MZH,
TILEPRO_INSN_NAP,
TILEPRO_INSN_NOP,
TILEPRO_INSN_NOR,
TILEPRO_INSN_OR,
TILEPRO_INSN_PACKBS_U,
TILEPRO_INSN_PACKHB,
TILEPRO_INSN_PACKHS,
TILEPRO_INSN_PACKLB,
TILEPRO_INSN_PCNT,
TILEPRO_INSN_PREFETCH,
TILEPRO_INSN_PREFETCH_L1,
TILEPRO_INSN_RL,
TILEPRO_INSN_S1A,
TILEPRO_INSN_S2A,
TILEPRO_INSN_S3A,
TILEPRO_INSN_SADAB_U,
TILEPRO_INSN_SADAH,
TILEPRO_INSN_SADAH_U,
TILEPRO_INSN_SADB_U,
TILEPRO_INSN_SADH,
TILEPRO_INSN_SADH_U,
TILEPRO_INSN_SB,
TILEPRO_INSN_SEQ,
TILEPRO_INSN_SEQB,
TILEPRO_INSN_SEQH,
TILEPRO_INSN_SEQIB,
TILEPRO_INSN_SEQIH,
TILEPRO_INSN_SH,
TILEPRO_INSN_SHL,
TILEPRO_INSN_SHLB,
TILEPRO_INSN_SHLH,
TILEPRO_INSN_SHLIB,
TILEPRO_INSN_SHLIH,
TILEPRO_INSN_SHR,
TILEPRO_INSN_SHRB,
TILEPRO_INSN_SHRH,
TILEPRO_INSN_SHRIB,
TILEPRO_INSN_SHRIH,
TILEPRO_INSN_SLT,
TILEPRO_INSN_SLT_U,
TILEPRO_INSN_SLTB,
TILEPRO_INSN_SLTB_U,
TILEPRO_INSN_SLTE,
TILEPRO_INSN_SLTE_U,
TILEPRO_INSN_SLTEB,
TILEPRO_INSN_SLTEB_U,
TILEPRO_INSN_SLTEH,
TILEPRO_INSN_SLTEH_U,
TILEPRO_INSN_SLTH,
TILEPRO_INSN_SLTH_U,
TILEPRO_INSN_SLTIB,
TILEPRO_INSN_SLTIB_U,
TILEPRO_INSN_SLTIH,
TILEPRO_INSN_SLTIH_U,
TILEPRO_INSN_SNE,
TILEPRO_INSN_SNEB,
TILEPRO_INSN_SNEH,
TILEPRO_INSN_SRA,
TILEPRO_INSN_SRAB,
TILEPRO_INSN_SRAH,
TILEPRO_INSN_SRAIB,
TILEPRO_INSN_SRAIH,
TILEPRO_INSN_SUB,
TILEPRO_INSN_SUBB,
TILEPRO_INSN_SUBBS_U,
TILEPRO_INSN_SUBH,
TILEPRO_INSN_SUBHS,
TILEPRO_INSN_SUBS,
TILEPRO_INSN_SW,
TILEPRO_INSN_TBLIDXB0,
TILEPRO_INSN_TBLIDXB1,
TILEPRO_INSN_TBLIDXB2,
TILEPRO_INSN_TBLIDXB3,
TILEPRO_INSN_TNS,
TILEPRO_INSN_WH64,
TILEPRO_INSN_XOR,
TILEPRO_NETWORK_BARRIER,
TILEPRO_IDN0_RECEIVE,
TILEPRO_IDN1_RECEIVE,
TILEPRO_IDN_SEND,
TILEPRO_SN_RECEIVE,
TILEPRO_SN_SEND,
TILEPRO_UDN0_RECEIVE,
TILEPRO_UDN1_RECEIVE,
TILEPRO_UDN2_RECEIVE,
TILEPRO_UDN3_RECEIVE,
TILEPRO_UDN_SEND,
TILEPRO_BUILTIN_max
};
#endif /* !GCC_TILEPRO_BUILTINS_H */

View File

@ -0,0 +1,52 @@
/* Definitions of C specific functions for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "machmode.h"
#include "tm.h"
#include "tm_p.h"
#include "cpplib.h"
#include "tree.h"
#include "c-family/c-common.h"
/* copy defines in c-cppbuiltin.c */
# define builtin_define(TXT) cpp_define (pfile, TXT)
# define builtin_assert(TXT) cpp_assert (pfile, TXT)
/* Implement TARGET_CPU_CPP_BUILTINS. */
void
tilepro_cpu_cpp_builtins (struct cpp_reader *pfile)
{
builtin_define ("__tile__");
builtin_define ("__tilepro__");
builtin_assert ("cpu=tile");
builtin_assert ("machine=tile");
builtin_define ("__tile_chip__=1");
builtin_define ("__tile_chip_rev__=0");
TILEPRO_CPU_CPP_ENDIAN_BUILTINS ();
GNU_USER_TARGET_OS_CPP_BUILTINS ();
}

View File

@ -0,0 +1,108 @@
;; Scheduling description for Tilera TILEPro chip.
;; Copyright (C) 2011, 2012
;; Free Software Foundation, Inc.
;; Contributed by Walter Lee (walt@tilera.com)
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_automaton "tile")
; Make the scheduling automaton an ndfa.
(automata_option "ndfa")
; Name the three pipes.
(define_cpu_unit "X0" "tile")
(define_cpu_unit "X1" "tile")
(define_cpu_unit "Y0" "tile")
(define_cpu_unit "Y1" "tile")
(define_cpu_unit "Y2" "tile")
(define_insn_reservation "X0" 1
(eq_attr "type" "X0")
"X0")
(define_insn_reservation "X0_2cycle" 2
(eq_attr "type" "X0_2cycle")
"X0,nothing")
(define_insn_reservation "X1" 1
(eq_attr "type" "X1,X1_branch")
"X1")
(define_insn_reservation "X1_2cycle" 2
(eq_attr "type" "X1_2cycle")
"X1,nothing")
(define_insn_reservation "X1_L2" 8
(eq_attr "type" "X1_L2")
"X1")
(define_insn_reservation "X1_miss" 80
(eq_attr "type" "X1_miss")
"X1")
(define_insn_reservation "X01" 1
(eq_attr "type" "X01")
"X0|X1")
(define_insn_reservation "Y0" 1
(eq_attr "type" "Y0")
"Y0|X0")
(define_insn_reservation "Y0_2cycle" 2
(eq_attr "type" "Y0_2cycle")
"Y0|X0,nothing")
(define_insn_reservation "Y2" 1
(eq_attr "type" "Y2")
"Y2|X1")
(define_insn_reservation "Y2_2cycle" 2
(eq_attr "type" "Y2_2cycle")
"Y2|X1,nothing")
(define_insn_reservation "Y2_L2" 8
(eq_attr "type" "Y2_L2")
"Y2|X1")
(define_insn_reservation "Y2_miss" 80
(eq_attr "type" "Y2_miss")
"Y2|X1")
(define_insn_reservation "Y01" 1
(eq_attr "type" "Y01")
"Y0|Y1|X0|X1")
(define_insn_reservation "nothing" 0
(eq_attr "type" "nothing")
"nothing")
(define_insn_reservation "cannot_bundle" 1
(eq_attr "type" "cannot_bundle")
"X0+X1")
(define_insn_reservation "cannot_bundle_3cycle" 3
(eq_attr "type" "cannot_bundle_3cycle")
"X0+X1")
(define_insn_reservation "cannot_bundle_4cycle" 4
(eq_attr "type" "cannot_bundle_4cycle")
"X0+X1")
; A bundle must be in either X format or Y format.
(exclusion_set "X0,X1" "Y0,Y1,Y2")

View File

@ -0,0 +1,35 @@
/* TILEPro extra machine modes.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Extra modes for handling struct returns in up to 10 registers. */
INT_MODE (R3I, 12);
INT_MODE (R5I, 20);
INT_MODE (R6I, 24);
INT_MODE (R7I, 28);
INT_MODE (R8I, 32);
INT_MODE (R9I, 36);
INT_MODE (R10I, 40);
/* Vector modes. */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODE (INT, QI, 8); /* V8QI */
VECTOR_MODE (INT, HI, 4); /* V4HI */
VECTOR_MODE (INT, QI, 2); /* V2QI */

View File

@ -0,0 +1,83 @@
/* Header for constant multiple table for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TILEPRO_MULTIPLY_H
#define GCC_TILEPRO_MULTIPLY_H
/* A node of a tilepro_multiply_insn_seq, corresponding to a single
machine instruction such as 'add', 's1a', or an shl by a
constant. */
struct tilepro_multiply_insn_seq_entry
{
/* Which operation this node performs (e.g. an add or sub). Don't
use this directly, call get_opcode() table to get a
insn_code. */
unsigned char compressed_opcode;
/* The left-hand side of this expression tree.
If equal to 0, it refers to 'zero'.
If equal to 1, it refers to the original input to the multiply
operation.
Otherwise, subtract two and it is an index into the containing
tilepro_multiply_insn_seq's 'op' array. Since it can only point
to some value that has already been computed it will always point
to an earlier entry in the array. */
unsigned char lhs;
/* This is like lhs, but for the right-hand side. However, for shift
opcodes this is a shift count rather than an operand index. */
unsigned char rhs;
};
/* Maximum size of op array. */
#define tilepro_multiply_insn_seq_MAX_OPERATIONS 4
/* This defines a DAG describing how to multiply by a constant in
terms of one or more machine instructions. */
struct tilepro_multiply_insn_seq
{
/* The constant factor by which this expression tree multiplies its
input. */
int multiplier;
/* The nodes of the parse tree. These are ordered so that
instructions can be emitted in the same order that they appear in
this array. Entry entry in this array can only refer to earlier
entries in the array. */
struct tilepro_multiply_insn_seq_entry
op[tilepro_multiply_insn_seq_MAX_OPERATIONS];
};
/* A mapping from the compressed opcode to the corresponding enum
insn_code. */
extern const enum insn_code tilepro_multiply_insn_seq_decode_opcode[];
/* Table mapping constant int multipliers to an expression tree that
efficiently performs that multiplication. This is sorted by its
'multiplier' field so a binary search can look for matches. */
extern const struct tilepro_multiply_insn_seq
tilepro_multiply_insn_seq_table[];
/* The number of elements in multiply_insn_seq_table. */
extern const int tilepro_multiply_insn_seq_table_size;
#endif /* !GCC_TILEPRO_MULTIPLY_H */

View File

@ -0,0 +1,77 @@
/* Prototypes of target machine for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC__TILEPRO_PROTOS_H
#define GCC__TILEPRO_PROTOS_H
extern void tilepro_init_expanders (void);
extern bool tilepro_legitimate_pic_operand_p (rtx);
extern rtx tilepro_simd_int (rtx, enum machine_mode);
#ifdef RTX_CODE
extern void split_di (rtx[], int, rtx[], rtx[]);
extern bool tilepro_bitfield_operand_p (HOST_WIDE_INT, int *, int *);
extern void tilepro_expand_set_const32 (rtx, rtx);
extern bool tilepro_expand_mov (enum machine_mode, rtx *);
extern void tilepro_expand_insv (rtx operands[4]);
extern void tilepro_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT, bool);
extern void tilepro_expand_movmisalign (enum machine_mode, rtx *);
extern bool tilepro_expand_addsi (rtx, rtx, rtx);
extern void tilepro_allocate_stack (rtx, rtx);
extern bool tilepro_expand_mulsi (rtx, rtx, rtx);
extern void tilepro_expand_smulsi3_highpart (rtx, rtx, rtx);
extern void tilepro_expand_umulsi3_highpart (rtx, rtx, rtx);
extern bool tilepro_emit_setcc (rtx[], enum machine_mode);
extern void tilepro_emit_conditional_branch (rtx[], enum machine_mode);
extern rtx tilepro_emit_conditional_move (rtx);
extern const char *tilepro_output_cbranch_with_opcode (rtx, rtx *,
const char *,
const char *, int,
bool);
extern const char *tilepro_output_cbranch (rtx, rtx *, bool);
extern void tilepro_expand_tablejump (rtx, rtx);
extern void tilepro_expand_builtin_vector_binop (rtx (*)(rtx, rtx, rtx),
enum machine_mode, rtx,
enum machine_mode, rtx, rtx,
bool);
#endif /* RTX_CODE */
extern bool tilepro_can_use_return_insn_p (void);
extern void tilepro_expand_prologue (void);
extern void tilepro_expand_epilogue (bool);
extern int tilepro_initial_elimination_offset (int, int);
extern rtx tilepro_return_addr (int, rtx);
extern rtx tilepro_eh_return_handler_rtx (void);
extern int tilepro_adjust_insn_length (rtx, int);
extern int tilepro_asm_preferred_eh_data_format (int, int);
extern void tilepro_final_prescan_insn (rtx);
extern const char *tilepro_asm_output_opcode (FILE *, const char *);
extern void tilepro_function_profiler (FILE *, int);
/* Declare functions in tile-c.c */
extern void tilepro_cpu_cpp_builtins (struct cpp_reader *);
#endif /* GCC_TILEPRO_PROTOS_H */

5084
gcc/config/tilepro/tilepro.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,479 @@
/* Definitions of target machine for GNU compiler for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* This is used by tilepro_cpu_cpp_builtins to indicate the byte order
we're compiling for. */
#define TILEPRO_CPU_CPP_ENDIAN_BUILTINS() \
do \
{ \
if (BYTES_BIG_ENDIAN) \
builtin_define ("__BIG_ENDIAN__"); \
else \
builtin_define ("__LITTLE_ENDIAN__"); \
} \
while (0)
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
tilepro_cpu_cpp_builtins (pfile)
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
/* Target machine storage layout */
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
#define UNITS_PER_WORD 4
#define PARM_BOUNDARY 32
#define STACK_BOUNDARY 64
#define FUNCTION_BOUNDARY 64
#define BIGGEST_ALIGNMENT 64
#define STRICT_ALIGNMENT 1
#define PCC_BITFIELD_TYPE_MATTERS 1
#define FASTEST_ALIGNMENT 32
#define BIGGEST_FIELD_ALIGNMENT 64
/* Unaligned moves trap and are very slow. */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1
/* Make strings word-aligned so strcpy from constants will be
faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < FASTEST_ALIGNMENT) \
? FASTEST_ALIGNMENT : (ALIGN))
/* Make arrays of chars word-aligned for the same reasons. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
/* Make local arrays of chars word-aligned for the same reasons. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) DATA_ALIGNMENT (TYPE, ALIGN)
/* Standard register usage. */
#define FIRST_PSEUDO_REGISTER (64 + 3)
#define FIXED_REGISTERS \
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1}
#define CALL_USED_REGISTERS \
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1}
#define CALL_REALLY_USED_REGISTERS \
CALL_USED_REGISTERS
#define REG_ALLOC_ORDER { \
10, 11, 12, 13, 14, /* call used */ \
15, 16, 17, 18, 19, \
20, 21, 22, 23, 24, \
25, 26, 27, 28, 29, \
\
9, 8, 7, 6, 5, /* argument */ \
4, 3, 2, 1, 0, \
\
55, /* return address */ \
\
30, 31, 32, 33, 34, /* call saved registers */ \
35, 36, 37, 38, 39, \
40, 41, 42, 43, 44, \
45, 46, 47, 48, 49, \
50, 51, \
\
52, /* hard frame pointer */ \
53, 54, /* tp, sp */ \
\
56, 57, 58, 59, 60, /* special purpose */ \
61, 62, 63, 64, 65, /* or fake registers */ \
66 \
}
#define HARD_REGNO_NREGS(REGNO, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* All registers can hold all modes. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
#define MODES_TIEABLE_P(MODE1, MODE2) 1
/* Register that holds an address into the text segment that can be
used by pic code. */
#define TILEPRO_PIC_TEXT_LABEL_REGNUM (flag_pic ? 50 : INVALID_REGNUM)
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 51 : INVALID_REGNUM)
#define HARD_FRAME_POINTER_REGNUM 52
#define THREAD_POINTER_REGNUM 53
#define STACK_POINTER_REGNUM 54
#define TILEPRO_LINK_REGNUM 55
#define FRAME_POINTER_REGNUM 64
#define ARG_POINTER_REGNUM 65
/* Pseudo register used to enforce order between instructions that
touch the networks. */
#define TILEPRO_NETORDER_REGNUM 66
#define STATIC_CHAIN_REGNUM 10
enum reg_class
{
NO_REGS,
R0_REGS,
R1_REGS,
R2_REGS,
R3_REGS,
R4_REGS,
R5_REGS,
R6_REGS,
R7_REGS,
R8_REGS,
R9_REGS,
R10_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
/* Since GENERAL_REGS is the same class as ALL_REGS, don't give it a
different class number; just make it an alias. */
#define GENERAL_REGS ALL_REGS
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
"R0_REGS", \
"R1_REGS", \
"R2_REGS", \
"R3_REGS", \
"R4_REGS", \
"R5_REGS", \
"R6_REGS", \
"R7_REGS", \
"R8_REGS", \
"R9_REGS", \
"R10_REGS", \
"ALL_REGS" \
}
#define REG_CLASS_CONTENTS \
{ \
{ 0 }, \
{ 1 << 0 }, \
{ 1 << 1 }, \
{ 1 << 2 }, \
{ 1 << 3 }, \
{ 1 << 4 }, \
{ 1 << 5 }, \
{ 1 << 6 }, \
{ 1 << 7 }, \
{ 1 << 8 }, \
{ 1 << 9 }, \
{ 1 << 10 }, \
{ 0xffffffff, 0xffffffff } \
}
#define REGNO_REG_CLASS(REGNO) \
((unsigned)(REGNO) <= 10 ? \
(enum reg_class)(R0_REGS + (REGNO)) : ALL_REGS)
#define INDEX_REG_CLASS NO_REGS
#define BASE_REG_CLASS ALL_REGS
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* Stack layout; function entry, exit and calling. */
#define STACK_GROWS_DOWNWARD
#define FRAME_GROWS_DOWNWARD 1
#define STARTING_FRAME_OFFSET 0
#define DYNAMIC_CHAIN_ADDRESS(FRAME) plus_constant ((FRAME), UNITS_PER_WORD)
#define FIRST_PARM_OFFSET(FNDECL) 0
#define ACCUMULATE_OUTGOING_ARGS 1
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
#define INCOMING_FRAME_SP_OFFSET 0
#define STACK_POINTER_OFFSET (2 * UNITS_PER_WORD)
#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
#define DEFAULT_PCC_STRUCT_RETURN 0
/* The first 10 registers may hold return value. */
#define TILEPRO_NUM_RETURN_REGS 10
/* The first 10 registers hold function arguments. */
#define TILEPRO_NUM_ARG_REGS 10
#define FUNCTION_ARG_REGNO_P(N) ((N) < TILEPRO_NUM_ARG_REGS)
/* The type used to store the number of words of arguments scanned so
far during argument scanning. This includes any space that is
skipped. */
#define CUMULATIVE_ARGS int
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
((CUM) = 0)
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
((OFFSET) = tilepro_initial_elimination_offset((FROM),(TO)))
#define FUNCTION_PROFILER(FILE, LABELNO) \
tilepro_function_profiler (FILE, LABELNO)
#define TRAMPOLINE_SIZE 48
#define TRAMPOLINE_ALIGNMENT 64
#define TRAMPOLINE_SECTION text_section
/* Call frame debugging information. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, TILEPRO_LINK_REGNUM)
#define RETURN_ADDR_RTX tilepro_return_addr
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (TILEPRO_LINK_REGNUM)
#define DWARF_ZERO_REG 63
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N + 12) : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 11)
#define EH_RETURN_HANDLER_RTX tilepro_eh_return_handler_rtx ()
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
tilepro_asm_preferred_eh_data_format ((CODE), (GLOBAL))
/* Addressing modes, and classification of registers for them. */
#define HAVE_POST_INCREMENT 1
#define HAVE_POST_DECREMENT 1
#define HAVE_POST_MODIFY_DISP 1
#define REGNO_OK_FOR_INDEX_P(regno) 0
#define REGNO_OK_FOR_BASE_P(regno) \
((regno) < FIRST_PSEUDO_REGISTER || reg_renumber[regno] >= 0)
#define MAX_REGS_PER_ADDRESS 1
#define CONSTANT_ADDRESS_P(X) 0
#define LEGITIMATE_PIC_OPERAND_P(X) tilepro_legitimate_pic_operand_p (X)
#define CASE_VECTOR_MODE SImode
#define CASE_VECTOR_PC_RELATIVE 0
#define JUMP_TABLES_IN_TEXT_SECTION 0
#define DEFAULT_SIGNED_CHAR 1
#define MOVE_MAX UNITS_PER_WORD
/* Use a value of 11 for MOVE_RATIO and friends, because TILEPro
returns structs as large as 10 words in registers. Because of some
some code generation inefficiency, we never get smaller code for
turning that into a memcpy, so pick a value that guarantees this
doesn't happen. */
#define TILEPRO_CALL_RATIO 11
#define MOVE_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
#define CLEAR_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
#define SET_RATIO(speed) ((speed) ? 15 : TILEPRO_CALL_RATIO)
#define WORD_REGISTER_OPERATIONS
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
(MODE) = SImode;
/* Define SLOW_BYTE_ACCESS to avoid making a QI or HI mode
register. */
#define SLOW_BYTE_ACCESS 1
#define SHIFT_COUNT_TRUNCATED 1
#define SHORT_IMMEDIATES_SIGN_EXTEND
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define Pmode SImode
#define STORE_FLAG_VALUE 1
#define FUNCTION_MODE SImode
#define NO_FUNCTION_CSE 1
#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
((LENGTH) = tilepro_adjust_insn_length ((INSN), (LENGTH)))
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
#define BRANCH_COST(speed_p, predictable_p) ((predictable_p) ? 2 : 6)
/* Control the assembler format that we output. */
#undef NO_DOLLAR_IN_LABEL
#define ASM_COMMENT_START "##"
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#undef READONLY_DATA_SECTION_ASM_OP
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata, \"a\""
#undef BSS_SECTION_ASM_OP
#define BSS_SECTION_ASM_OP "\t.section\t.bss, \"wa\""
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP "\t.section\t.init, \"ax\""
#undef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP "\t.section\t.fini, \"ax\""
#define GLOBAL_ASM_OP ".global "
#define SUPPORTS_WEAK 1
#define USER_LABEL_PREFIX ""
#define REGISTER_PREFIX ""
#define REGISTER_NAMES \
{ "r0", "r1", "r2", "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", "tp", "sp", "lr", \
"sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero", \
"?FRAME?", "?ARG?", "?NET?" }
/* This is used to help emit bundles. */
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
tilepro_final_prescan_insn (insn)
/* This is used to help emit bundles. */
#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
(PTR = tilepro_asm_output_opcode (STREAM, PTR))
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do \
{ \
char label[256]; \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE));\
fprintf (FILE, "\t.word "); \
assemble_name (FILE, label); \
fprintf (FILE, "\n"); \
} \
while (0)
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
do \
{ \
char label[256]; \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \
fprintf (FILE, "\t.word "); \
assemble_name (FILE, label); \
ASM_GENERATE_INTERNAL_LABEL (label, "L", (REL)); \
fprintf (FILE, "-"); \
assemble_name (FILE, label); \
fprintf (FILE, "\n"); \
} \
while (0)
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (unsigned int)(ROUNDED)))
#define INIT_EXPANDERS tilepro_init_expanders ()
/* A C structure for machine-specific, per-function data. This is
added to the cfun structure. */
typedef struct GTY(()) machine_function
{
/* Symbol for the text label used for pic. */
rtx text_label_symbol;
/* Register for the text label. */
rtx text_label_rtx;
/* Register for the pic offset table. */
rtx got_rtx;
/* The function calls tls_get_addr. */
int calls_tls_get_addr;
} machine_function;
#ifndef HAVE_AS_TLS
#define HAVE_AS_TLS 0
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,37 @@
; Options for the TILEPro port of the compiler.
; Copyright (C) 2011, 2012
; Free Software Foundation, Inc.
; Contributed by Walter Lee (walt@tilera.com)
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 3, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
m32
Target Report RejectNegative
Compile with 32 bit longs and pointers, which is the only supported
behavior and thus the flag is ignored.
mcpu=
Target RejectNegative Joined Enum(tilepro_cpu) Var(tilepro_cpu) Init(0)
-mcpu=CPU Use features of and schedule code for given CPU
Enum
Name(tilepro_cpu) Type(int)
Known TILEPro CPUs (for use with the -mcpu= option):
EnumValue
Enum(tilepro_cpu) String(tilepro) Value(0)

33
gcc/configure vendored
View File

@ -23491,6 +23491,37 @@ foo: .long 25
xor %l1, %tle_lox10(foo), %o5
ld [%g7 + %o5], %o1"
;;
tilepro*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
addli r0, zero, tls_gd(foo)
auli r0, zero, tls_gd_ha16(foo)
addli r0, r0, tls_gd_lo16(foo)
jal __tls_get_addr
addli r0, zero, tls_ie(foo)
auli r0, r0, tls_ie_ha16(foo)
addli r0, r0, tls_ie_lo16(foo)'
tls_first_major=2
tls_first_minor=22
tls_as_opt="--fatal-warnings"
;;
tilegx*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
shl16insli r0, zero, hw0_last_tls_gd(foo)
shl16insli r0, zero, hw1_last_tls_gd(foo)
shl16insli r0, r0, hw0_tls_gd(foo)
jal __tls_get_addr
shl16insli r0, zero, hw1_last_tls_ie(foo)
shl16insli r0, r0, hw0_tls_ie(foo)'
tls_first_major=2
tls_first_minor=22
tls_as_opt="--fatal-warnings"
;;
xtensa*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
@ -25835,7 +25866,7 @@ esac
# version to the per-target configury.
case "$cpu_type" in
alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
| pa | rs6000 | score | sparc | spu | xstormy16 | xtensa)
| pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
insn="nop"
;;
ia64 | s390)

View File

@ -3125,6 +3125,37 @@ foo: .long 25
xor %l1, %tle_lox10(foo), %o5
ld [%g7 + %o5], %o1"
;;
tilepro*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
addli r0, zero, tls_gd(foo)
auli r0, zero, tls_gd_ha16(foo)
addli r0, r0, tls_gd_lo16(foo)
jal __tls_get_addr
addli r0, zero, tls_ie(foo)
auli r0, r0, tls_ie_ha16(foo)
addli r0, r0, tls_ie_lo16(foo)'
tls_first_major=2
tls_first_minor=22
tls_as_opt="--fatal-warnings"
;;
tilegx*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
foo: .long 25
.text
shl16insli r0, zero, hw0_last_tls_gd(foo)
shl16insli r0, zero, hw1_last_tls_gd(foo)
shl16insli r0, r0, hw0_tls_gd(foo)
jal __tls_get_addr
shl16insli r0, zero, hw1_last_tls_ie(foo)
shl16insli r0, r0, hw0_tls_ie(foo)'
tls_first_major=2
tls_first_minor=22
tls_as_opt="--fatal-warnings"
;;
xtensa*-*-*)
conftest_s='
.section ".tdata","awT",@progbits
@ -4071,7 +4102,7 @@ esac
# version to the per-target configury.
case "$cpu_type" in
alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
| pa | rs6000 | score | sparc | spu | xstormy16 | xtensa)
| pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
insn="nop"
;;
ia64 | s390)

View File

@ -394,6 +394,9 @@ of testing and bug fixing, particularly of GCC configury code.
@item
Steve Holmgren for MachTen patches.
@item
Mat Hostetter for work on the TILE-Gx and TILEPro ports.
@item
Jan Hubicka for his x86 port improvements.
@ -505,6 +508,9 @@ entire egcs project and GCC 2.95, rolling out snapshots and releases,
handling merges from GCC2, reviewing tons of patches that might have
fallen through the cracks else, and random but extensive hacking.
@item
Walter Lee for work on the TILE-Gx and TILEPro ports.
@item
Marc Lehmann for his direction via the steering committee and helping
with analysis and improvements of x86 performance.

View File

@ -8531,6 +8531,8 @@ instructions, but allow the compiler to schedule those calls.
* SPARC VIS Built-in Functions::
* SPU Built-in Functions::
* TI C6X Built-in Functions::
* TILE-Gx Built-in Functions::
* TILEPro Built-in Functions::
@end menu
@node Alpha Built-in Functions
@ -13718,6 +13720,78 @@ int _abs2 (int)
@end smallexample
@node TILE-Gx Built-in Functions
@subsection TILE-Gx Built-in Functions
GCC provides intrinsics to access every instruction of the TILE-Gx
processor. The intrinsics are of the form:
@smallexample
unsigned long long __insn_@var{op} (...)
@end smallexample
Where @var{op} is the name of the instruction. Refer to the ISA manual
for the complete list of instructions.
GCC also provides intrinsics to directly access the network registers.
The intrinsics are:
@smallexample
unsigned long long __tile_idn0_receive (void)
unsigned long long __tile_idn1_receive (void)
unsigned long long __tile_udn0_receive (void)
unsigned long long __tile_udn1_receive (void)
unsigned long long __tile_udn2_receive (void)
unsigned long long __tile_udn3_receive (void)
void __tile_idn_send (unsigned long long)
void __tile_udn_send (unsigned long long)
@end smallexample
The intrinsic @code{void __tile_network_barrier (void)} is used to
guarantee that no network operatons before it will be reordered with
those after it.
@node TILEPro Built-in Functions
@subsection TILEPro Built-in Functions
GCC provides intrinsics to access every instruction of the TILEPro
processor. The intrinsics are of the form:
@smallexample
unsigned __insn_@var{op} (...)
@end smallexample
Where @var{op} is the name of the instruction. Refer to the ISA manual
for the complete list of instructions.
GCC also provides intrinsics to directly access the network registers.
The intrinsics are:
@smallexample
unsigned __tile_idn0_receive (void)
unsigned __tile_idn1_receive (void)
unsigned __tile_sn_receive (void)
unsigned __tile_udn0_receive (void)
unsigned __tile_udn1_receive (void)
unsigned __tile_udn2_receive (void)
unsigned __tile_udn3_receive (void)
void __tile_idn_send (unsigned)
void __tile_sn_send (unsigned)
void __tile_udn_send (unsigned)
@end smallexample
The intrinsic @code{void __tile_network_barrier (void)} is used to
guarantee that no network operatons before it will be reordered with
those after it.
@node Target Format Checks
@section Format Checks Specific to Particular Target Machines

View File

@ -3096,6 +3096,10 @@ information are.
@item
@uref{#c6x-x-x,,c6x-*-*}
@item
@uref{#tilegx-x-linux,,tilegx-*-linux*}
@item
@uref{#tilepro-x-linux,,tilepro-*-linux*}
@item
@uref{#x-x-vxworks,,*-*-vxworks*}
@item
@uref{#x86-64-x-x,,x86_64-*-*, amd64-*-*}
@ -4457,6 +4461,22 @@ This is a synonym for @samp{sparc64-*-solaris2*}.
The C6X family of processors. This port requires binutils-2.22 or newer.
@html
<hr />
@end html
@heading @anchor{tilegx-*-linux}tilegx-*-linux*
The TILE-Gx processor running GNU/Linux. This port requires
binutils-2.22 or newer.
@html
<hr />
@end html
@heading @anchor{tilepro-*-linux}tilepro-*-linux*
The TILEPro processor running GNU/Linux. This port requires
binutils-2.22 or newer.
@html
<hr />
@end html

View File

@ -923,6 +923,12 @@ See RS/6000 and PowerPC Options.
@emph{System V Options}
@gccoptlist{-Qy -Qn -YP,@var{paths} -Ym,@var{dir}}
@emph{TILE-Gx Options}
@gccoptlist{-mcpu=CPU -m32 -m64}
@emph{TILEPro Options}
@gccoptlist{-mcpu=CPU -m32}
@emph{V850 Options}
@gccoptlist{-mlong-calls -mno-long-calls -mep -mno-ep @gol
-mprolog-function -mno-prolog-function -mspace @gol
@ -10349,6 +10355,8 @@ platform.
* SPARC Options::
* SPU Options::
* System V Options::
* TILE-Gx Options::
* TILEPro Options::
* V850 Options::
* VAX Options::
* VxWorks Options::
@ -18479,6 +18487,46 @@ The assembler uses this option.
@c the generic assembler that comes with Solaris takes just -Ym.
@end table
@node TILE-Gx Options
@subsection TILE-Gx Options
@cindex TILE-Gx options
These @samp{-m} options are supported on the TILE-Gx:
@table @gcctabopt
@item -mcpu=@var{name}
@opindex mcpu
Selects the type of CPU to be targeted. Currently the only supported
type is @samp{tilegx}.
@item -m32
@itemx -m64
@opindex m32
@opindex m64
Generate code for a 32-bit or 64-bit environment. The 32-bit
environment sets int, long, and pointer to 32 bits. The 64-bit
environment sets int to 32 bits and long and pointer to 64 bits.
@end table
@node TILEPro Options
@subsection TILEPro Options
@cindex TILEPro options
These @samp{-m} options are supported on the TILEPro:
@table @gcctabopt
@item -mcpu=@var{name}
@opindex mcpu
Selects the type of CPU to be targeted. Currently the only supported
type is @samp{tilepro}.
@item -m32
@opindex m32
Generate code for a 32-bit environment, which sets int, long, and
pointer to 32 bits. This is the only supported behavior so the flag
is essentially ignored.
@end table
@node V850 Options
@subsection V850 Options
@cindex V850 Options

View File

@ -3576,6 +3576,154 @@ Register B14 (aka DP).
@end table
@item TILE-Gx---@file{config/tilegx/constraints.md}
@table @code
@item R00
@itemx R01
@itemx R02
@itemx R03
@itemx R04
@itemx R05
@itemx R06
@itemx R07
@itemx R08
@itemx R09
@itemx R010
Each of these represents a register constraint for an individual
register, from r0 to r10.
@item I
Signed 8-bit integer constant.
@item J
Signed 16-bit integer constant.
@item K
Unsigned 16-bit integer constant.
@item L
Integer constant that fits in one signed byte when incremented by one
(@minus{}129 @dots{} 126).
@item m
Memory operand. If used together with @samp{<} or @samp{>}, the
operand can have postincrement which requires printing with @samp{%In}
and @samp{%in} on TILE-Gx. For example:
@smallexample
asm ("st_add %I0,%1,%i0" : "=m<>" (*mem) : "r" (val));
@end smallexample
@item M
A bit mask suitable for the BFINS instruction.
@item N
Integer constant that is a byte tiled out eight times.
@item O
The integer zero constant.
@item P
Integer constant that is a sign-extended byte tiled out as four shorts.
@item Q
Integer constant that fits in one signed byte when incremented
(@minus{}129 @dots{} 126), but excluding -1.
@item S
Integer constant that has all 1 bits consecutive and starting at bit 0.
@item T
A 16-bit fragment of a got, tls, or pc-relative reference.
@item U
Memory operand except postincrement. This is roughly the same as
@samp{m} when not used together with @samp{<} or @samp{>}.
@item W
An 8-element vector constant with identical elements.
@item Y
A 4-element vector constant with identical elements.
@item Z0
The integer constant 0xffffffff.
@item Z1
The integer constant 0xffffffff00000000.
@end table
@item TILEPro---@file{config/tilepro/constraints.md}
@table @code
@item R00
@itemx R01
@itemx R02
@itemx R03
@itemx R04
@itemx R05
@itemx R06
@itemx R07
@itemx R08
@itemx R09
@itemx R010
Each of these represents a register constraint for an individual
register, from r0 to r10.
@item I
Signed 8-bit integer constant.
@item J
Signed 16-bit integer constant.
@item K
Nonzero integer constant with low 16 bits zero.
@item L
Integer constant that fits in one signed byte when incremented by one
(@minus{}129 @dots{} 126).
@item m
Memory operand. If used together with @samp{<} or @samp{>}, the
operand can have postincrement which requires printing with @samp{%In}
and @samp{%in} on TILEPro. For example:
@smallexample
asm ("swadd %I0,%1,%i0" : "=m<>" (mem) : "r" (val));
@end smallexample
@item M
A bit mask suitable for the MM instruction.
@item N
Integer constant that is a byte tiled out four times.
@item O
The integer zero constant.
@item P
Integer constant that is a sign-extended byte tiled out as two shorts.
@item Q
Integer constant that fits in one signed byte when incremented
(@minus{}129 @dots{} 126), but excluding -1.
@item T
A symbolic operand, or a 16-bit fragment of a got, tls, or pc-relative
reference.
@item U
Memory operand except postincrement. This is roughly the same as
@samp{m} when not used together with @samp{<} or @samp{>}.
@item W
A 4-element vector constant with identical elements.
@item Y
A 2-element vector constant with identical elements.
@end table
@item Xtensa---@file{config/xtensa/constraints.md}
@table @code
@item a

View File

@ -1,3 +1,12 @@
2012-02-14 Walter Lee <walt@tilera.com>
* g++.dg/other/PR23205.C: Disable test on tile.
* g++.dg/other/pr23205-2.C: Disable test on tile.
* gcc.dg/20020312-2.c: Add a condition for __tile__.
* gcc.dg/20040813-1.c: Disable test on tile.
* gcc.dg/lower-subreg-1.c: Disable test on tilegx.
* gcc.misc-tests/linkage.exp: Handle tilegx.
2012-02-14 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/52210

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-vxworks } { "*" } { "" } } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* tile*-*-* *-*-vxworks } { "*" } { "" } } */
/* { dg-options "-gstabs+ -fno-eliminate-unused-debug-types" } */
const int foobar = 4;

View File

@ -1,5 +1,5 @@
/* { dg-do compile } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* } { "*" } { "" } } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* tile*-*-* } { "*" } { "" } } */
/* { dg-options "-gstabs+ -fno-eliminate-unused-debug-types -ftoplevel-reorder" } */
const int foobar = 4;

View File

@ -66,6 +66,8 @@ extern void abort (void);
# define PIC_REG "12"
#elif defined(__sparc__)
# define PIC_REG "l7"
#elif defined(__tile__)
# define PIC_REG "r51"
#elif defined(__TMS320C6X__)
# define PIC_REG "B14"
#elif defined(__v850)

View File

@ -2,7 +2,7 @@
/* Contributed by Devang Patel <dpatel@apple.com> */
/* { dg-do compile } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-vxworks* } { "*" } { "" } } */
/* { dg-skip-if "No stabs" { mmix-*-* *-*-aix* alpha*-*-* hppa*64*-*-* ia64-*-* tile*-*-* *-*-vxworks* } { "*" } { "" } } */
/* { dg-options "-gstabs" } */
int

View File

@ -1,4 +1,4 @@
/* { dg-do compile { target { { { ! mips64 } && { ! ia64-*-* } } && { ! spu-*-* } } } } */
/* { dg-do compile { target { { { ! mips64 } && { ! ia64-*-* } } && { ! spu-*-* } && { ! tilegx-*-* } } } } */
/* { dg-options "-O -fdump-rtl-subreg1" } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */
/* { dg-require-effective-target ilp32 } */

View File

@ -88,6 +88,13 @@ if { [isnative] && ![is_remote host] } then {
} elseif [ string match "*ppc" $file_string ] {
set native_cflags "-m32"
}
} elseif [istarget "tilegx-*-linux*"] {
set file_string [exec file "linkage-x.o"]
if [ string match "*64-bit*" $file_string ] {
set native_cflags "-m64"
} elseif [ string match "*32-bit*" $file_string ] {
set native_cflags "-m32"
}
} elseif [istarget "*86*-*-darwin*"] {
set file_string [exec file "linkage-x.o"]
if [ string match "*64*" $file_string ] {

View File

@ -1,3 +1,8 @@
2012-02-14 Walter Lee <walt@tilera.com>
* configure.ac: Require 64-bit hwint for tilegx and tilepro.
* configure: Regenerate.
2012-01-09 Richard Guenther <rguenther@suse.de>
* macro.c (_cpp_builtin_macro_text): Remove unused variable map.

3
libcpp/configure vendored
View File

@ -7382,7 +7382,8 @@ case $target in
s390*-*-* | \
sparc*-*-* | \
spu-*-* | \
sh[123456789lbe]*-*-* | sh-*-*)
sh[123456789lbe]*-*-* | sh-*-* | \
tilegx-*-* | tilepro-*-* )
need_64bit_hwint=yes ;;
*)
need_64bit_hwint=no ;;

View File

@ -162,7 +162,8 @@ case $target in
s390*-*-* | \
sparc*-*-* | \
spu-*-* | \
sh[123456789lbe]*-*-* | sh-*-*)
sh[123456789lbe]*-*-* | sh-*-* | \
tilegx-*-* | tilepro-*-* )
need_64bit_hwint=yes ;;
*)
need_64bit_hwint=no ;;

View File

@ -1,3 +1,21 @@
2012-02-14 Walter Lee <walt@tilera.com>
* config.host: Handle tilegx and tilepro.
* config/tilegx/sfp-machine.h: New file.
* config/tilegx/sfp-machine32.h: New file.
* config/tilegx/sfp-machine64.h: New file.
* config/tilegx/t-crtstuff: New file.
* config/tilegx/t-softfp: New file.
* config/tilegx/t-tilegx: New file.
* config/tilepro/atomic.c: New file.
* config/tilepro/atomic.h: New file.
* config/tilepro/linux-unwind.h: New file.
* config/tilepro/sfp-machine.h: New file.
* config/tilepro/softdivide.c: New file.
* config/tilepro/softmpy.S: New file.
* config/tilepro/t-crtstuff: New file.
* config/tilepro/t-tilepro: New file.
2012-02-07 Jonathan Wakely <jwakely.gcc@gmail.com>
PR libstdc++/51296

View File

@ -1090,6 +1090,14 @@ tic6x-*-elf)
extra_parts="$extra_parts crtbeginS.o crtendS.o crti.o crtn.o"
unwind_header=config/c6x/unwind-c6x.h
;;
tilegx-*-linux*)
tmake_file="${tmake_file} tilegx/t-crtstuff t-softfp-sfdf tilegx/t-softfp t-softfp tilegx/t-tilegx"
md_unwind_header=tilepro/linux-unwind.h
;;
tilepro-*-linux*)
tmake_file="${tmake_file} tilepro/t-crtstuff t-softfp-sfdf t-softfp tilepro/t-tilepro"
md_unwind_header=tilepro/linux-unwind.h
;;
v850*-*-*)
tmake_file="v850/t-v850 t-fdpbit"
;;

View File

@ -0,0 +1,5 @@
#ifdef __tilegx32__
#include "config/tilegx/sfp-machine32.h"
#else
#include "config/tilegx/sfp-machine64.h"
#endif

View File

@ -0,0 +1,61 @@
#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S _FP_QNANBIT_S
#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
#define _FP_NANSIGN_S 1
#define _FP_NANSIGN_D 1
#define _FP_NANSIGN_Q 1
#define _FP_KEEPNANFRACP 1
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));

View File

@ -0,0 +1,61 @@
#define _FP_W_TYPE_SIZE 64
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S _FP_QNANBIT_S
#define _FP_NANFRAC_D _FP_QNANBIT_D
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0
#define _FP_NANSIGN_S 1
#define _FP_NANSIGN_D 1
#define _FP_NANSIGN_Q 1
#define _FP_KEEPNANFRACP 1
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));

View File

@ -0,0 +1,4 @@
# crtend*.o cannot be compiled without -fno-asynchronous-unwind-tables,
# because then __FRAME_END__ might not be the last thing in .eh_frame
# section.
CRTSTUFF_T_CFLAGS += -fno-asynchronous-unwind-tables

View File

@ -0,0 +1 @@
softfp_int_modes += ti

View File

@ -0,0 +1,26 @@
LIB2ADD += \
$(srcdir)/config/tilepro/atomic.c
SOFTDIVIDE_FUNCS := \
_tile_udivsi3 \
_tile_divsi3 \
_tile_udivdi3 \
_tile_divdi3 \
_tile_umodsi3 \
_tile_modsi3 \
_tile_umoddi3 \
_tile_moddi3
softdivide-o = $(patsubst %,%$(objext),$(SOFTDIVIDE_FUNCS))
$(softdivide-o): %$(objext): $(srcdir)/config/tilepro/softdivide.c
$(gcc_compile) -ffunction-sections -DMAYBE_STATIC= -DL$* -c $< \
$(vis_hide)
libgcc-objects += $(softdivide-o)
ifeq ($(enable_shared),yes)
softdivide-s-o = $(patsubst %,%_s$(objext),$(SOFTDIVIDE_FUNCS))
$(softdivide-s-o): %_s$(objext): $(srcdir)/config/tilepro/softdivide.c
$(gcc_s_compile) -ffunction-sections -DMAYBE_STATIC= -DL$* -c $<
libgcc-s-objects += $(softdivide-s-o)
libgcc-eh-objects += _tile_divdi3.o _tile_umoddi3.o
endif

View File

@ -0,0 +1,232 @@
/* TILE atomics.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "system.h"
#include "coretypes.h"
#include "atomic.h"
/* This code should be inlined by the compiler, but for now support
it as out-of-line methods in libgcc. */
static void
pre_atomic_barrier (int model)
{
switch ((enum memmodel) model)
{
case MEMMODEL_RELEASE:
case MEMMODEL_ACQ_REL:
case MEMMODEL_SEQ_CST:
__atomic_thread_fence (model);
break;
default:
break;
}
return;
}
static void
post_atomic_barrier (int model)
{
switch ((enum memmodel) model)
{
case MEMMODEL_ACQUIRE:
case MEMMODEL_ACQ_REL:
case MEMMODEL_SEQ_CST:
__atomic_thread_fence (model);
break;
default:
break;
}
return;
}
#define __unused __attribute__((unused))
/* Provide additional methods not implemented by atomic.h. */
#define atomic_xor(mem, mask) \
__atomic_update_cmpxchg(mem, mask, __old ^ __value)
#define atomic_nand(mem, mask) \
__atomic_update_cmpxchg(mem, mask, ~(__old & __value))
#define __atomic_fetch_and_do(type, size, opname) \
type \
__atomic_fetch_##opname##_##size(type* p, type i, int model) \
{ \
pre_atomic_barrier(model); \
type rv = atomic_##opname(p, i); \
post_atomic_barrier(model); \
return rv; \
}
__atomic_fetch_and_do (int, 4, add)
__atomic_fetch_and_do (int, 4, sub)
__atomic_fetch_and_do (int, 4, or)
__atomic_fetch_and_do (int, 4, and)
__atomic_fetch_and_do (int, 4, xor)
__atomic_fetch_and_do (int, 4, nand)
__atomic_fetch_and_do (long long, 8, add)
__atomic_fetch_and_do (long long, 8, sub)
__atomic_fetch_and_do (long long, 8, or)
__atomic_fetch_and_do (long long, 8, and)
__atomic_fetch_and_do (long long, 8, xor)
__atomic_fetch_and_do (long long, 8, nand)
#define __atomic_do_and_fetch(type, size, opname, op) \
type \
__atomic_##opname##_fetch_##size(type* p, type i, int model) \
{ \
pre_atomic_barrier(model); \
type rv = atomic_##opname(p, i) op i; \
post_atomic_barrier(model); \
return rv; \
}
__atomic_do_and_fetch (int, 4, add, +)
__atomic_do_and_fetch (int, 4, sub, -)
__atomic_do_and_fetch (int, 4, or, |)
__atomic_do_and_fetch (int, 4, and, &)
__atomic_do_and_fetch (int, 4, xor, |)
__atomic_do_and_fetch (int, 4, nand, &)
__atomic_do_and_fetch (long long, 8, add, +)
__atomic_do_and_fetch (long long, 8, sub, -)
__atomic_do_and_fetch (long long, 8, or, |)
__atomic_do_and_fetch (long long, 8, and, &)
__atomic_do_and_fetch (long long, 8, xor, |)
__atomic_do_and_fetch (long long, 8, nand, &)
#define __atomic_exchange_methods(type, size) \
bool \
__atomic_compare_exchange_##size(volatile type* ptr, type* oldvalp, \
type newval, bool weak __unused, \
int models, int modelf __unused) \
{ \
type oldval = *oldvalp; \
pre_atomic_barrier(models); \
type retval = atomic_val_compare_and_exchange(ptr, oldval, newval); \
post_atomic_barrier(models); \
bool success = (retval == oldval); \
*oldvalp = retval; \
return success; \
} \
\
type \
__atomic_exchange_##size(volatile type* ptr, type val, int model) \
{ \
pre_atomic_barrier(model); \
type retval = atomic_exchange(ptr, val); \
post_atomic_barrier(model); \
return retval; \
}
__atomic_exchange_methods (int, 4)
__atomic_exchange_methods (long long, 8)
/* Subword methods require the same approach for both TILEPro and
TILE-Gx. We load the background data for the word, insert the
desired subword piece, then compare-and-exchange it into place. */
#define u8 unsigned char
#define u16 unsigned short
#define __atomic_subword_cmpxchg(type, size) \
\
bool \
__atomic_compare_exchange_##size(volatile type* ptr, type* guess, \
type val, bool weak __unused, int models, \
int modelf __unused) \
{ \
pre_atomic_barrier(models); \
unsigned int *p = (unsigned int *)((unsigned long)ptr & ~3UL); \
const int shift = ((unsigned long)ptr & 3UL) * 8; \
const unsigned int valmask = (1 << (sizeof(type) * 8)) - 1; \
const unsigned int bgmask = ~(valmask << shift); \
unsigned int oldword = *p; \
type oldval = (oldword >> shift) & valmask; \
if (__builtin_expect((oldval == *guess), 1)) { \
unsigned int word = (oldword & bgmask) | ((val & valmask) << shift); \
oldword = atomic_val_compare_and_exchange(p, oldword, word); \
oldval = (oldword >> shift) & valmask; \
} \
post_atomic_barrier(models); \
bool success = (oldval == *guess); \
*guess = oldval; \
return success; \
}
__atomic_subword_cmpxchg (u8, 1)
__atomic_subword_cmpxchg (u16, 2)
/* For the atomic-update subword methods, we use the same approach as
above, but we retry until we succeed if the compare-and-exchange
fails. */
#define __atomic_subword(type, proto, top, expr, bottom) \
proto \
{ \
top \
unsigned int *p = (unsigned int *)((unsigned long)ptr & ~3UL); \
const int shift = ((unsigned long)ptr & 3UL) * 8; \
const unsigned int valmask = (1 << (sizeof(type) * 8)) - 1; \
const unsigned int bgmask = ~(valmask << shift); \
unsigned int oldword, xword = *p; \
type val, oldval; \
do { \
oldword = xword; \
oldval = (oldword >> shift) & valmask; \
val = expr; \
unsigned int word = (oldword & bgmask) | ((val & valmask) << shift); \
xword = atomic_val_compare_and_exchange(p, oldword, word); \
} while (__builtin_expect(xword != oldword, 0)); \
bottom \
}
#define __atomic_subword_fetch(type, funcname, expr, retval) \
__atomic_subword(type, \
type __atomic_ ## funcname(volatile type *ptr, type i, int model), \
pre_atomic_barrier(model);, \
expr, \
post_atomic_barrier(model); return retval;)
__atomic_subword_fetch (u8, fetch_add_1, oldval + i, oldval)
__atomic_subword_fetch (u8, fetch_sub_1, oldval - i, oldval)
__atomic_subword_fetch (u8, fetch_or_1, oldval | i, oldval)
__atomic_subword_fetch (u8, fetch_and_1, oldval & i, oldval)
__atomic_subword_fetch (u8, fetch_xor_1, oldval ^ i, oldval)
__atomic_subword_fetch (u8, fetch_nand_1, ~(oldval & i), oldval)
__atomic_subword_fetch (u16, fetch_add_2, oldval + i, oldval)
__atomic_subword_fetch (u16, fetch_sub_2, oldval - i, oldval)
__atomic_subword_fetch (u16, fetch_or_2, oldval | i, oldval)
__atomic_subword_fetch (u16, fetch_and_2, oldval & i, oldval)
__atomic_subword_fetch (u16, fetch_xor_2, oldval ^ i, oldval)
__atomic_subword_fetch (u16, fetch_nand_2, ~(oldval & i), oldval)
__atomic_subword_fetch (u8, add_fetch_1, oldval + i, val)
__atomic_subword_fetch (u8, sub_fetch_1, oldval - i, val)
__atomic_subword_fetch (u8, or_fetch_1, oldval | i, val)
__atomic_subword_fetch (u8, and_fetch_1, oldval & i, val)
__atomic_subword_fetch (u8, xor_fetch_1, oldval ^ i, val)
__atomic_subword_fetch (u8, nand_fetch_1, ~(oldval & i), val)
__atomic_subword_fetch (u16, add_fetch_2, oldval + i, val)
__atomic_subword_fetch (u16, sub_fetch_2, oldval - i, val)
__atomic_subword_fetch (u16, or_fetch_2, oldval | i, val)
__atomic_subword_fetch (u16, and_fetch_2, oldval & i, val)
__atomic_subword_fetch (u16, xor_fetch_2, oldval ^ i, val)
__atomic_subword_fetch (u16, nand_fetch_2, ~(oldval & i), val)
#define __atomic_subword_lock(type, size) \
\
__atomic_subword(type, \
type __atomic_exchange_##size(volatile type* ptr, type nval, int model), \
pre_atomic_barrier(model);, \
nval, \
post_atomic_barrier(model); return oldval;)
__atomic_subword_lock (u8, 1)
__atomic_subword_lock (u16, 2)

View File

@ -0,0 +1,428 @@
/* Macros for atomic functionality for tile.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Provides macros for common atomic functionality. */
#ifndef _ATOMIC_H_
#define _ATOMIC_H_
#ifdef __tilegx__
/* Atomic instruction macros
The macros provided by atomic.h simplify access to the TILE-Gx
architecture's atomic instructions. The architecture provides a
variety of atomic instructions, including "exchange", "compare and
exchange", "fetch and ADD", "fetch and AND", "fetch and OR", and
"fetch and ADD if greater than or equal to zero".
No barrier or fence semantics are implied by any of the atomic
instructions for manipulating memory; you must specify the barriers
that you wish explicitly, using the provided macros.
Any integral 32- or 64-bit value can be used as the argument
to these macros, such as "int", "long long", "unsigned long", etc.
The pointers must be aligned to 4 or 8 bytes for 32- or 64-bit data.
The "exchange" and "compare and exchange" macros may also take
pointer values. We use the pseudo-type "VAL" in the documentation
to indicate the use of an appropriate type. */
#else
/* Atomic instruction macros
The macros provided by atomic.h simplify access to the Tile
architecture's atomic instructions. Since the architecture
supports test-and-set as its only in-silicon atomic operation, many
of the operations provided by this header are implemented as
fast-path calls to Linux emulation routines.
Using the kernel for atomic operations allows userspace to take
advantage of the kernel's existing atomic-integer support (managed
by a distributed array of locks). The kernel provides proper
ordering among simultaneous atomic operations on different cores,
and guarantees a process can not be context-switched part way
through an atomic operation. By virtue of sharing the kernel
atomic implementation, the userspace atomic operations
are compatible with the atomic methods provided by the kernel's
futex() syscall API. Note that these operations never cause Linux
kernel scheduling, and are in fact invisible to the kernel; they
simply act as regular function calls but with an elevated privilege
level. Note that the kernel's distributed lock array is hashed by
using only VA bits from the atomic value's address (to avoid the
performance hit of page table locking and multiple page-table
lookups to get the PA) and only the VA bits that are below page
granularity (to properly lock simultaneous accesses to the same
page mapped at different VAs). As a result, simultaneous atomic
operations on values whose addresses are at the same offset on a
page will contend in the kernel for the same lock array element.
No barrier or fence semantics are implied by any of the atomic
instructions for manipulating memory; you must specify the barriers
that you wish explicitly, using the provided macros.
Any integral 32- or 64-bit value can be used as the argument
to these macros, such as "int", "long long", "unsigned long", etc.
The pointers must be aligned to 4 or 8 bytes for 32- or 64-bit data.
The "exchange" and "compare and exchange" macros may also take
pointer values. We use the pseudo-type "VAL" in the documentation
to indicate the use of an appropriate type.
The 32-bit routines are implemented using a single kernel fast
syscall, as is the 64-bit compare-and-exchange. The other 64-bit
routines are implemented by looping over the 64-bit
compare-and-exchange routine, so may be potentially less efficient. */
#endif
#include <stdint.h>
#include <features.h>
#ifdef __tilegx__
#include <arch/spr_def.h>
#else
#include <asm/unistd.h>
#endif
/* 32-bit integer compare-and-exchange. */
static __inline __attribute__ ((always_inline))
int atomic_val_compare_and_exchange_4 (volatile int *mem,
int oldval, int newval)
{
#ifdef __tilegx__
__insn_mtspr (SPR_CMPEXCH_VALUE, oldval);
return __insn_cmpexch4 (mem, newval);
#else
int result;
__asm__ __volatile__ ("swint1":"=R00" (result),
"=m" (*mem):"R10" (__NR_FAST_cmpxchg), "R00" (mem),
"R01" (oldval), "R02" (newval), "m" (*mem):"r20",
"r21", "r22", "r23", "r24", "r25", "r26", "r27",
"r28", "r29", "memory");
return result;
#endif
}
/* 64-bit integer compare-and-exchange. */
static __inline __attribute__ ((always_inline))
int64_t atomic_val_compare_and_exchange_8 (volatile int64_t * mem,
int64_t oldval,
int64_t newval)
{
#ifdef __tilegx__
__insn_mtspr (SPR_CMPEXCH_VALUE, oldval);
return __insn_cmpexch (mem, newval);
#else
unsigned int result_lo, result_hi;
unsigned int oldval_lo = oldval & 0xffffffffu, oldval_hi = oldval >> 32;
unsigned int newval_lo = newval & 0xffffffffu, newval_hi = newval >> 32;
__asm__ __volatile__ ("swint1":"=R00" (result_lo), "=R01" (result_hi),
"=m" (*mem):"R10" (__NR_FAST_cmpxchg64), "R00" (mem),
"R02" (oldval_lo), "R03" (oldval_hi),
"R04" (newval_lo), "R05" (newval_hi),
"m" (*mem):"r20", "r21", "r22", "r23", "r24", "r25",
"r26", "r27", "r28", "r29", "memory");
return ((uint64_t) result_hi) << 32 | result_lo;
#endif
}
/* This non-existent symbol is called for sizes other than "4" and "8",
indicating a bug in the caller. */
extern int __atomic_error_bad_argument_size (void)
__attribute__ ((warning ("sizeof atomic argument not 4 or 8")));
#define atomic_val_compare_and_exchange(mem, o, n) \
({ \
(__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \
((sizeof(*(mem)) == 8) ? \
atomic_val_compare_and_exchange_8( \
(volatile int64_t*)(mem), (__typeof((o)-(o)))(o), \
(__typeof((n)-(n)))(n)) : \
(sizeof(*(mem)) == 4) ? \
atomic_val_compare_and_exchange_4( \
(volatile int*)(mem), (__typeof((o)-(o)))(o), \
(__typeof((n)-(n)))(n)) : \
__atomic_error_bad_argument_size()); \
})
#define atomic_bool_compare_and_exchange(mem, o, n) \
({ \
__typeof(o) __o = (o); \
__builtin_expect( \
__o == atomic_val_compare_and_exchange((mem), __o, (n)), 1); \
})
/* Loop with compare_and_exchange until we guess the correct value.
Normally "expr" will be an expression using __old and __value. */
#define __atomic_update_cmpxchg(mem, value, expr) \
({ \
__typeof(value) __value = (value); \
__typeof(*(mem)) *__mem = (mem), __old = *__mem, __guess; \
do { \
__guess = __old; \
__old = atomic_val_compare_and_exchange(__mem, __old, (expr)); \
} while (__builtin_expect(__old != __guess, 0)); \
__old; \
})
#ifdef __tilegx__
/* Generic atomic op with 8- or 4-byte variant.
The _mask, _addend, and _expr arguments are ignored on tilegx. */
#define __atomic_update(mem, value, op, _mask, _addend, _expr) \
({ \
((__typeof(*(mem))) \
((sizeof(*(mem)) == 8) ? (__typeof(*(mem)-*(mem)))__insn_##op( \
(void *)(mem), (int64_t)(__typeof((value)-(value)))(value)) : \
(sizeof(*(mem)) == 4) ? (int)__insn_##op##4( \
(void *)(mem), (int32_t)(__typeof((value)-(value)))(value)) : \
__atomic_error_bad_argument_size())); \
})
#else
/* This uses TILEPro's fast syscall support to atomically compute:
int old = *ptr;
*ptr = (old & mask) + addend;
return old;
This primitive can be used for atomic exchange, add, or, and.
Only 32-bit support is provided. */
static __inline __attribute__ ((always_inline))
int
__atomic_update_4 (volatile int *mem, int mask, int addend)
{
int result;
__asm__ __volatile__ ("swint1":"=R00" (result),
"=m" (*mem):"R10" (__NR_FAST_atomic_update),
"R00" (mem), "R01" (mask), "R02" (addend),
"m" (*mem):"r20", "r21", "r22", "r23", "r24", "r25",
"r26", "r27", "r28", "r29", "memory");
return result;
}
/* Generic atomic op with 8- or 4-byte variant.
The _op argument is ignored on tilepro. */
#define __atomic_update(mem, value, _op, mask, addend, expr) \
({ \
(__typeof(*(mem)))(__typeof(*(mem)-*(mem))) \
((sizeof(*(mem)) == 8) ? \
__atomic_update_cmpxchg((mem), (value), (expr)) : \
(sizeof(*(mem)) == 4) ? \
__atomic_update_4((volatile int*)(mem), (__typeof((mask)-(mask)))(mask), \
(__typeof((addend)-(addend)))(addend)) : \
__atomic_error_bad_argument_size()); \
})
#endif /* __tilegx__ */
#define atomic_exchange(mem, newvalue) \
__atomic_update(mem, newvalue, exch, 0, newvalue, __value)
#define atomic_add(mem, value) \
__atomic_update(mem, value, fetchadd, -1, value, __old + __value)
#define atomic_sub(mem, value) atomic_add((mem), -(value))
#define atomic_increment(mem) atomic_add((mem), 1)
#define atomic_decrement(mem) atomic_add((mem), -1)
#define atomic_and(mem, mask) \
__atomic_update(mem, mask, fetchand, mask, 0, __old & __value)
#define atomic_or(mem, mask) \
__atomic_update(mem, mask, fetchor, ~mask, mask, __old | __value)
#define atomic_bit_set(mem, bit) \
({ \
__typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \
__mask & atomic_or((mem), __mask); \
})
#define atomic_bit_clear(mem, bit) \
({ \
__typeof(*(mem)) __mask = (__typeof(*(mem)))1 << (bit); \
__mask & atomic_and((mem), ~__mask); \
})
#ifdef __tilegx__
/* Atomically store a new value to memory.
Note that you can freely use types of any size here, unlike the
other atomic routines, which require 32- or 64-bit types.
This accessor is provided for compatibility with TILEPro, which
required an explicit atomic operation for stores that needed
to be atomic with respect to other atomic methods in this header. */
#define atomic_write(mem, value) ((void) (*(mem) = (value)))
#else
#define atomic_write(mem, value) \
do { \
__typeof(mem) __aw_mem = (mem); \
__typeof(value) __aw_val = (value); \
unsigned int *__aw_mem32, __aw_intval, __aw_val32, __aw_off, __aw_mask; \
__aw_intval = (__typeof((value) - (value)))__aw_val; \
switch (sizeof(*__aw_mem)) { \
case 8: \
__atomic_update_cmpxchg(__aw_mem, __aw_val, __value); \
break; \
case 4: \
__atomic_update_4((int *)__aw_mem, 0, __aw_intval); \
break; \
case 2: \
__aw_off = 8 * ((long)__aw_mem & 0x2); \
__aw_mask = 0xffffU << __aw_off; \
__aw_mem32 = (unsigned int *)((long)__aw_mem & ~0x2); \
__aw_val32 = (__aw_intval << __aw_off) & __aw_mask; \
__atomic_update_cmpxchg(__aw_mem32, __aw_val32, \
(__old & ~__aw_mask) | __value); \
break; \
case 1: \
__aw_off = 8 * ((long)__aw_mem & 0x3); \
__aw_mask = 0xffU << __aw_off; \
__aw_mem32 = (unsigned int *)((long)__aw_mem & ~0x3); \
__aw_val32 = (__aw_intval << __aw_off) & __aw_mask; \
__atomic_update_cmpxchg(__aw_mem32, __aw_val32, \
(__old & ~__aw_mask) | __value); \
break; \
} \
} while (0)
#endif
/* Compiler barrier.
This macro prevents loads or stores from being moved by the compiler
across the macro. Any loaded value that was loaded before this
macro must then be reloaded by the compiler. */
#define atomic_compiler_barrier() __asm__ __volatile__("" ::: "memory")
/* Full memory barrier.
This macro has the semantics of atomic_compiler_barrer(), but also
ensures that previous stores are visible to other cores, and that
all previous loaded values have been placed into their target
register on this core. */
#define atomic_full_barrier() __insn_mf()
/* Read memory barrier.
Ensure that all reads by this processor that occurred prior to the
read memory barrier have completed, and that no reads that occur
after the read memory barrier on this processor are initiated
before the barrier.
On current TILE chips a read barrier is implemented as a full barrier,
but this may not be true in later versions of the architecture.
See also atomic_acquire_barrier() for the appropriate idiom to use
to ensure no reads are lifted above an atomic lock instruction. */
#define atomic_read_barrier() atomic_full_barrier()
/* Write memory barrier.
Ensure that all writes by this processor that occurred prior to the
write memory barrier have completed, and that no writes that occur
after the write memory barrier on this processor are initiated
before the barrier.
On current TILE chips a write barrier is implemented as a full barrier,
but this may not be true in later versions of the architecture.
See also atomic_release_barrier() for the appropriate idiom to use
to ensure all writes are complete prior to an atomic unlock instruction. */
#define atomic_write_barrier() atomic_full_barrier()
/* Lock acquisition barrier.
Ensure that no load operations that follow this macro in the
program can issue prior to the barrier. Without such a barrier,
the compiler can reorder them to issue earlier, or the hardware can
issue them speculatively. The latter is not currently done in the
Tile microarchitecture, but using this operation improves
portability to future implementations.
This operation is intended to be used as part of the "acquire"
path for locking, that is, when entering a critical section.
This should be done after the atomic operation that actually
acquires the lock, and in conjunction with a "control dependency"
that checks the atomic operation result to see if the lock was
in fact acquired. See the atomic_read_barrier() macro
for a heavier-weight barrier to use in certain unusual constructs,
or atomic_acquire_barrier_value() if no control dependency exists. */
#define atomic_acquire_barrier() atomic_compiler_barrier()
/* Lock release barrier.
Ensure that no store operations that precede this macro in the
program complete subsequent to the barrier. Without such a
barrier, the compiler can reorder stores to issue later, or stores
can be still outstanding in the memory network.
This operation is intended to be used as part of the "release" path
for locking, that is, when leaving a critical section. This should
be done before the operation (such as a store of zero) that
actually releases the lock. */
#define atomic_release_barrier() atomic_write_barrier()
/* Barrier until the read of a particular value is complete.
This is occasionally useful when constructing certain locking
scenarios. For example, you might write a routine that issues an
atomic instruction to enter a critical section, then reads one or
more values within the critical section without checking to see if
the critical section was in fact acquired, and only later checks
the atomic instruction result to see if the lock was acquired. If
so the routine could properly release the lock and know that the
values that were read were valid.
In this scenario, it is required to wait for the result of the
atomic instruction, even if the value itself is not checked. This
guarantees that if the atomic instruction succeeded in taking the lock,
the lock was held before any reads in the critical section issued. */
#define atomic_acquire_barrier_value(val) \
__asm__ __volatile__("move %0, %0" :: "r"(val))
/* Access the given variable in memory exactly once.
In some contexts, an algorithm may need to force access to memory,
since otherwise the compiler may think it can optimize away a
memory load or store; for example, in a loop when polling memory to
see if another cpu has updated it yet. Generally this is only
required for certain very carefully hand-tuned algorithms; using it
unnecessarily may result in performance losses.
A related use of this macro is to ensure that the compiler does not
rematerialize the value of "x" by reloading it from memory
unexpectedly; the "volatile" marking will prevent the compiler from
being able to rematerialize. This is helpful if an algorithm needs
to read a variable without locking, but needs it to have the same
value if it ends up being used several times within the algorithm.
Note that multiple uses of this macro are guaranteed to be ordered,
i.e. the compiler will not reorder stores or loads that are wrapped
in atomic_access_once(). */
#define atomic_access_once(x) (*(volatile __typeof(x) *)&(x))
#endif /* !_ATOMIC_H_ */

View File

@ -0,0 +1,100 @@
/* DWARF2 EH unwinding support for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef inhibit_libc
#include <arch/abi.h>
#include <signal.h>
#include <sys/ucontext.h>
#include <linux/unistd.h>
/* Macro to define a copy of the kernel's __rt_sigreturn function
(in arch/tile/kernel/entry.S). If that function is changed,
this one needs to be changed to match it. */
#define _sigreturn_asm(REG, NR) asm( \
".pushsection .text.__rt_sigreturn,\"a\"\n" \
".global __rt_sigreturn\n" \
".type __rt_sigreturn,@function\n" \
"__rt_sigreturn:\n" \
"moveli " #REG ", " #NR "\n" \
"swint1\n" \
".size __rt_sigreturn, . - __rt_sigreturn\n" \
".popsection")
#define sigreturn_asm(REG, NR) _sigreturn_asm(REG, NR)
sigreturn_asm (TREG_SYSCALL_NR_NAME, __NR_rt_sigreturn);
#define SIGRETURN_LEN 16
extern char __rt_sigreturn[];
#define MD_FALLBACK_FRAME_STATE_FOR tile_fallback_frame_state
static _Unwind_Reason_Code
tile_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned char *pc = context->ra;
struct sigcontext *sc;
long new_cfa;
int i;
struct rt_sigframe {
unsigned char save_area[C_ABI_SAVE_AREA_SIZE];
struct siginfo info;
struct ucontext uc;
} *rt_;
/* Return if this is not a signal handler. */
if (memcmp (pc, __rt_sigreturn, SIGRETURN_LEN) != 0)
return _URC_END_OF_STACK;
/* It was a signal handler; update the reported PC to point to our
copy, since that will be findable with dladdr() and therefore
somewhat easier to help understand what actually happened. */
context->ra = __rt_sigreturn;
rt_ = context->cfa;
sc = &rt_->uc.uc_mcontext;
new_cfa = sc->sp;
fs->regs.cfa_how = CFA_REG_OFFSET;
fs->regs.cfa_reg = STACK_POINTER_REGNUM;
fs->regs.cfa_offset = new_cfa - (long) context->cfa;
for (i = 0; i < 56; ++i)
{
fs->regs.reg[i].how = REG_SAVED_OFFSET;
fs->regs.reg[i].loc.offset
= (long)&sc->gregs[i] - new_cfa;
}
fs->regs.reg[56].how = REG_SAVED_OFFSET;
fs->regs.reg[56].loc.offset = (long)&sc->pc - new_cfa;
fs->retaddr_column = 56;
fs->signal_frame = 1;
return _URC_NO_REASON;
}
#endif /* ifdef inhibit_libc */

View File

@ -0,0 +1,56 @@
#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long
/* The type of the result of a floating point comparison. This must
match `__libgcc_cmp_return__' in GCC for the target. */
typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
#define CMPtype __gcc_CMPtype
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S _FP_QNANBIT_S
#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
#define _FP_NANSIGN_S 1
#define _FP_NANSIGN_D 1
#define _FP_NANSIGN_Q 1
#define _FP_KEEPNANFRACP 1
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));

View File

@ -0,0 +1,354 @@
/* Division and remainder routines for Tile.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
typedef int int32_t;
typedef unsigned uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
/* Raise signal 8 (SIGFPE) with code 1 (FPE_INTDIV). */
static inline void
raise_intdiv (void)
{
asm ("{ raise; moveli zero, 8 + (1 << 6) }");
}
#ifndef __tilegx__
/*__udivsi3 - 32 bit integer unsigned divide */
static inline uint32_t __attribute__ ((always_inline))
__udivsi3_inline (uint32_t dividend, uint32_t divisor)
{
/* Divide out any power of two factor from dividend and divisor.
Note that when dividing by zero the divisor will remain zero,
which is all we need to detect that case below. */
const int power_of_two_factor = __insn_ctz (divisor);
divisor >>= power_of_two_factor;
dividend >>= power_of_two_factor;
/* Checks for division by power of two or division by zero. */
if (divisor <= 1)
{
if (divisor == 0)
{
raise_intdiv ();
return 0;
}
return dividend;
}
/* Compute (a / b) by repeatedly finding the largest N
such that (b << N) <= a. For each such N, set bit N in the
quotient, subtract (b << N) from a, and keep going. Think of this as
the reverse of the "shift-and-add" that a multiply does. The values
of N are precisely those shift counts.
Finding N is easy. First, use clz(b) - clz(a) to find the N
that lines up the high bit of (b << N) with the high bit of a.
Any larger value of N would definitely make (b << N) > a,
which is too big.
Then, if (b << N) > a (because it has larger low bits), decrement
N by one. This adjustment will definitely make (b << N) less
than a, because a's high bit is now one higher than b's. */
/* Precomputing the max_ values allows us to avoid a subtract
in the inner loop and just right shift by clz(remainder). */
const int divisor_clz = __insn_clz (divisor);
const uint32_t max_divisor = divisor << divisor_clz;
const uint32_t max_qbit = 1 << divisor_clz;
uint32_t quotient = 0;
uint32_t remainder = dividend;
while (remainder >= divisor)
{
int shift = __insn_clz (remainder);
uint32_t scaled_divisor = max_divisor >> shift;
uint32_t quotient_bit = max_qbit >> shift;
int too_big = (scaled_divisor > remainder);
scaled_divisor >>= too_big;
quotient_bit >>= too_big;
remainder -= scaled_divisor;
quotient |= quotient_bit;
}
return quotient;
}
#endif /* !__tilegx__ */
/* __udivdi3 - 64 bit integer unsigned divide */
static inline uint64_t __attribute__ ((always_inline))
__udivdi3_inline (uint64_t dividend, uint64_t divisor)
{
/* Divide out any power of two factor from dividend and divisor.
Note that when dividing by zero the divisor will remain zero,
which is all we need to detect that case below. */
const int power_of_two_factor = __builtin_ctzll (divisor);
divisor >>= power_of_two_factor;
dividend >>= power_of_two_factor;
/* Checks for division by power of two or division by zero. */
if (divisor <= 1)
{
if (divisor == 0)
{
raise_intdiv ();
return 0;
}
return dividend;
}
#ifndef __tilegx__
if (((uint32_t) (dividend >> 32) | ((uint32_t) (divisor >> 32))) == 0)
{
/* Operands both fit in 32 bits, so use faster 32 bit algorithm. */
return __udivsi3_inline ((uint32_t) dividend, (uint32_t) divisor);
}
#endif /* !__tilegx__ */
/* See algorithm description in __udivsi3 */
const int divisor_clz = __builtin_clzll (divisor);
const uint64_t max_divisor = divisor << divisor_clz;
const uint64_t max_qbit = 1ULL << divisor_clz;
uint64_t quotient = 0;
uint64_t remainder = dividend;
while (remainder >= divisor)
{
int shift = __builtin_clzll (remainder);
uint64_t scaled_divisor = max_divisor >> shift;
uint64_t quotient_bit = max_qbit >> shift;
int too_big = (scaled_divisor > remainder);
scaled_divisor >>= too_big;
quotient_bit >>= too_big;
remainder -= scaled_divisor;
quotient |= quotient_bit;
}
return quotient;
}
#ifndef __tilegx__
/* __umodsi3 - 32 bit integer unsigned modulo */
static inline uint32_t __attribute__ ((always_inline))
__umodsi3_inline (uint32_t dividend, uint32_t divisor)
{
/* Shortcircuit mod by a power of two (and catch mod by zero). */
const uint32_t mask = divisor - 1;
if ((divisor & mask) == 0)
{
if (divisor == 0)
{
raise_intdiv ();
return 0;
}
return dividend & mask;
}
/* We compute the remainder (a % b) by repeatedly subtracting off
multiples of b from a until a < b. The key is that subtracting
off a multiple of b does not affect the result mod b.
To make the algorithm run efficiently, we need to subtract
off a large multiple of b at each step. We subtract the largest
(b << N) that is <= a.
Finding N is easy. First, use clz(b) - clz(a) to find the N
that lines up the high bit of (b << N) with the high bit of a.
Any larger value of N would definitely make (b << N) > a,
which is too big.
Then, if (b << N) > a (because it has larger low bits), decrement
N by one. This adjustment will definitely make (b << N) less
than a, because a's high bit is now one higher than b's. */
const uint32_t max_divisor = divisor << __insn_clz (divisor);
uint32_t remainder = dividend;
while (remainder >= divisor)
{
const int shift = __insn_clz (remainder);
uint32_t scaled_divisor = max_divisor >> shift;
scaled_divisor >>= (scaled_divisor > remainder);
remainder -= scaled_divisor;
}
return remainder;
}
#endif /* !__tilegx__ */
/* __umoddi3 - 64 bit integer unsigned modulo */
static inline uint64_t __attribute__ ((always_inline))
__umoddi3_inline (uint64_t dividend, uint64_t divisor)
{
#ifndef __tilegx__
if (((uint32_t) (dividend >> 32) | ((uint32_t) (divisor >> 32))) == 0)
{
/* Operands both fit in 32 bits, so use faster 32 bit algorithm. */
return __umodsi3_inline ((uint32_t) dividend, (uint32_t) divisor);
}
#endif /* !__tilegx__ */
/* Shortcircuit mod by a power of two (and catch mod by zero). */
const uint64_t mask = divisor - 1;
if ((divisor & mask) == 0)
{
if (divisor == 0)
{
raise_intdiv ();
return 0;
}
return dividend & mask;
}
/* See algorithm description in __umodsi3 */
const uint64_t max_divisor = divisor << __builtin_clzll (divisor);
uint64_t remainder = dividend;
while (remainder >= divisor)
{
const int shift = __builtin_clzll (remainder);
uint64_t scaled_divisor = max_divisor >> shift;
scaled_divisor >>= (scaled_divisor > remainder);
remainder -= scaled_divisor;
}
return remainder;
}
uint32_t __udivsi3 (uint32_t dividend, uint32_t divisor);
#ifdef L_tile_udivsi3
uint32_t
__udivsi3 (uint32_t dividend, uint32_t divisor)
{
#ifndef __tilegx__
return __udivsi3_inline (dividend, divisor);
#else /* !__tilegx__ */
uint64_t n = __udivdi3_inline (((uint64_t) dividend), ((uint64_t) divisor));
return (uint32_t) n;
#endif /* !__tilegx__ */
}
#endif
#define ABS(x) ((x) >= 0 ? (x) : -(x))
int32_t __divsi3 (int32_t dividend, int32_t divisor);
#ifdef L_tile_divsi3
/* __divsi3 - 32 bit integer signed divide */
int32_t
__divsi3 (int32_t dividend, int32_t divisor)
{
#ifndef __tilegx__
uint32_t n = __udivsi3_inline (ABS (dividend), ABS (divisor));
#else /* !__tilegx__ */
uint64_t n =
__udivdi3_inline (ABS ((int64_t) dividend), ABS ((int64_t) divisor));
#endif /* !__tilegx__ */
if ((dividend ^ divisor) < 0)
n = -n;
return (int32_t) n;
}
#endif
uint64_t __udivdi3 (uint64_t dividend, uint64_t divisor);
#ifdef L_tile_udivdi3
uint64_t
__udivdi3 (uint64_t dividend, uint64_t divisor)
{
return __udivdi3_inline (dividend, divisor);
}
#endif
/*__divdi3 - 64 bit integer signed divide */
int64_t __divdi3 (int64_t dividend, int64_t divisor);
#ifdef L_tile_divdi3
int64_t
__divdi3 (int64_t dividend, int64_t divisor)
{
uint64_t n = __udivdi3_inline (ABS (dividend), ABS (divisor));
if ((dividend ^ divisor) < 0)
n = -n;
return (int64_t) n;
}
#endif
uint32_t __umodsi3 (uint32_t dividend, uint32_t divisor);
#ifdef L_tile_umodsi3
uint32_t
__umodsi3 (uint32_t dividend, uint32_t divisor)
{
#ifndef __tilegx__
return __umodsi3_inline (dividend, divisor);
#else /* !__tilegx__ */
return __umoddi3_inline ((uint64_t) dividend, (uint64_t) divisor);
#endif /* !__tilegx__ */
}
#endif
/* __modsi3 - 32 bit integer signed modulo */
int32_t __modsi3 (int32_t dividend, int32_t divisor);
#ifdef L_tile_modsi3
int32_t
__modsi3 (int32_t dividend, int32_t divisor)
{
#ifndef __tilegx__
uint32_t remainder = __umodsi3_inline (ABS (dividend), ABS (divisor));
#else /* !__tilegx__ */
uint64_t remainder =
__umoddi3_inline (ABS ((int64_t) dividend), ABS ((int64_t) divisor));
#endif /* !__tilegx__ */
return (int32_t) ((dividend >= 0) ? remainder : -remainder);
}
#endif
uint64_t __umoddi3 (uint64_t dividend, uint64_t divisor);
#ifdef L_tile_umoddi3
uint64_t
__umoddi3 (uint64_t dividend, uint64_t divisor)
{
return __umoddi3_inline (dividend, divisor);
}
#endif
/* __moddi3 - 64 bit integer signed modulo */
int64_t __moddi3 (int64_t dividend, int64_t divisor);
#ifdef L_tile_moddi3
int64_t
__moddi3 (int64_t dividend, int64_t divisor)
{
uint64_t remainder = __umoddi3_inline (ABS (dividend), ABS (divisor));
return (int64_t) ((dividend >= 0) ? remainder : -remainder);
}
#endif

View File

@ -0,0 +1,95 @@
/* 64-bit multiplication support for TILEPro.
Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* 64-bit multiplication support. */
.file "softmpy.S"
/* Parameters */
#define lo0 r9 /* low 32 bits of n0 */
#define hi0 r1 /* high 32 bits of n0 */
#define lo1 r2 /* low 32 bits of n1 */
#define hi1 r3 /* high 32 bits of n1 */
/* temps */
#define result1_a r4
#define result1_b r5
#define tmp0 r6
#define tmp0_left_16 r7
#define tmp1 r8
.section .text.__muldi3, "ax"
.align 8
.globl __muldi3
.type __muldi3, @function
__muldi3:
{
move lo0, r0 /* so we can write "out r0" while "in r0" alive */
mulhl_uu tmp0, lo1, r0
}
{
mulll_uu result1_a, lo1, hi0
}
{
move tmp1, tmp0
mulhla_uu tmp0, lo0, lo1
}
{
mulhlsa_uu result1_a, lo1, hi0
}
{
mulll_uu result1_b, lo0, hi1
slt_u tmp1, tmp0, tmp1
}
{
mulhlsa_uu result1_a, lo0, hi1
shli r0, tmp0, 16
}
{
move tmp0_left_16, r0
mulhha_uu result1_b, lo0, lo1
}
{
mullla_uu r0, lo1, lo0
shli tmp1, tmp1, 16
}
{
mulhlsa_uu result1_b, hi0, lo1
inthh tmp1, tmp1, tmp0
}
{
mulhlsa_uu result1_a, hi1, lo0
slt_u tmp0, r0, tmp0_left_16
}
/* NOTE: this will stall for a cycle here. Oh well. */
{
add r1, tmp0, tmp1
add result1_a, result1_a, result1_b
}
{
add r1, r1, result1_a
jrp lr
}
.size __muldi3,.-__muldi3

View File

@ -0,0 +1,4 @@
# crtend*.o cannot be compiled without -fno-asynchronous-unwind-tables,
# because then __FRAME_END__ might not be the last thing in .eh_frame
# section.
CRTSTUFF_T_CFLAGS += -fno-asynchronous-unwind-tables

View File

@ -0,0 +1,33 @@
LIB2ADD += \
$(srcdir)/config/tilepro/softmpy.S \
$(srcdir)/config/tilepro/atomic.c
LIB2FUNCS_EXCLUDE += \
_divdi3 \
_moddi3 \
_muldi3 \
_udivdi3 \
_umoddi3
SOFTDIVIDE_FUNCS := \
_tile_udivsi3 \
_tile_divsi3 \
_tile_udivdi3 \
_tile_divdi3 \
_tile_umodsi3 \
_tile_modsi3 \
_tile_umoddi3 \
_tile_moddi3
softdivide-o = $(patsubst %,%$(objext),$(SOFTDIVIDE_FUNCS))
$(softdivide-o): %$(objext): $(srcdir)/config/tilepro/softdivide.c
$(gcc_compile) -ffunction-sections -DMAYBE_STATIC= -DL$* -c $< \
$(vis_hide)
libgcc-objects += $(softdivide-o)
ifeq ($(enable_shared),yes)
softdivide-s-o = $(patsubst %,%_s$(objext),$(SOFTDIVIDE_FUNCS))
$(softdivide-s-o): %_s$(objext): $(srcdir)/config/tilepro/softdivide.c
$(gcc_s_compile) -ffunction-sections -DMAYBE_STATIC= -DL$* -c $<
libgcc-s-objects += $(softdivide-s-o)
endif

View File

@ -1,3 +1,8 @@
2012-02-14 Walter Lee <walt@tilera.com>
* configure.tgt: Handle tilegx and tilepro.
* config/linux/tile/futex.h: New file.
2012-02-08 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46886

View File

@ -0,0 +1,73 @@
/* Copyright (C) 2011, 2012
Free Software Foundation, Inc.
Contributed by Walter Lee (walt@tilera.com)
This file is part of the GNU OpenMP Library (libgomp).
Libgomp is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Provide target-specific access to the futex system call. */
#include <sys/syscall.h>
#include <linux/futex.h>
static inline void
sys_futex0 (int *addr, int op, int val)
{
long _sys_result;
long _clobber_r2, _clobber_r3, _clobber_r4, _clobber_r5, _clobber_r10;
int err;
__asm__ __volatile__ (
"swint1"
: "=R00" (_sys_result), "=R01" (err), "=R02" (_clobber_r2),
"=R03" (_clobber_r3), "=R04" (_clobber_r4), "=R05" (_clobber_r5),
"=R10" (_clobber_r10)
: "R10" (SYS_futex), "R00" (addr), "R01" (op), "R02" (val),
"R03" (0)
: "r6", "r7",
"r8", "r9", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "memory");
}
static inline void
futex_wait (int *addr, int val)
{
sys_futex0 (addr, FUTEX_WAIT, val);
}
static inline void
futex_wake (int *addr, int count)
{
sys_futex0 (addr, FUTEX_WAKE, count);
}
static inline void
cpu_relax (void)
{
__asm volatile ("" : : : "memory");
}
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}

View File

@ -51,6 +51,10 @@ if test $enable_linux_futex = yes; then
config_path="linux/s390 linux posix"
;;
tile*-*-linux*)
config_path="linux/tile linux posix"
;;
# Note that bare i386 is not included here. We need cmpxchg.
i[456]86-*-linux*)
config_path="linux/x86 linux posix"