Skip to content

Commit

Permalink
TILE-Gx big endian support.
Browse files Browse the repository at this point in the history
/:
	* configure.ac (tilepro-*-*) Change to tilepro*-*-*.
	(tilegx-*-*): Change to tilegx*-*-*.
	* configure: Regenerate.

contrib/:
	* config-list.mk (LIST): Add tilegxbe-linux-gnu.

libcpp/:
	* configure.ac: Change "tilepro" triplet to "tilepro*".
	* configure: Regenerate.

libgcc/:
	* config.host: Support "tilegx*" and "tilepro*" triplets.
	* config/tilegx/sfp-machine32.h (__BYTE_ORDER): Handle big endian.
	* config/tilegx/sfp-machine64.h (__BYTE_ORDER): Handle big endian.

gcc/:
	* config.gcc (tilepro-*-*): Change to tilepro*-*-*.
	(tilegx-*-linux*): Change to tilegx*-*-linux*; Support tilegxbe
	triplet.
	* common/config/tilegx/tilegx-common.c
	(TARGET_DEFAULT_TARGET_FLAGS): Define.
	* config/tilegx/linux.h (ASM_SPEC): Add endian_spec.
	(LINK_SPEC): Ditto.
	* config/tilegx/sync.md (atomic_test_and_set): Handle big endian.
	* config/tilegx/tilegx.c (tilegx_return_in_msb): New.
	(tilegx_gimplify_va_arg_expr): Handle big endian.
	(tilegx_expand_unaligned_load): Ditto.
	(tilegx_expand_unaligned_store): Ditto.
	(TARGET_RETURN_IN_MSB): New.
	* config/tilegx/tilegx.h (TARGET_DEFAULT): New.
	(TARGET_ENDIAN_DEFAULT): New.
	(TARGET_BIG_ENDIAN): Handle big endian.
	(BYTES_BIG_ENDIAN): Ditto.
	(WORDS_BIG_ENDIAN): Ditto.
	(FLOAT_WORDS_BIG_ENDIAN): Ditto.
	(ENDIAN_SPEC): New.
	(EXTRA_SPECS): New.
	* config/tilegx/tilegx.md (extv): Handle big endian.
	(extzv): Ditto.
	(insn_st<n>): Ditto.
	(insn_st<n>_add<bitsuffix>): Ditto.
	(insn_stnt<n>): Ditto.
	(insn_stnt<n>_add<bitsuffix>):Ditto.
	(vec_interleave_highv8qi): Handle big endian.
	(vec_interleave_highv8qi_be): New.
	(vec_interleave_highv8qi_le): New.
	(insn_v1int_h): Handle big endian.
	(vec_interleave_lowv8qi): Handle big endian.
	(vec_interleave_lowv8qi_be): New.
	(vec_interleave_lowv8qi_le): New.
	(insn_v1int_l): Handle big endian.
	(vec_interleave_highv4hi): Handle big endian.
	(vec_interleave_highv4hi_be): New.
	(vec_interleave_highv4hi_le): New.
	(insn_v2int_h): Handle big endian.
	(vec_interleave_lowv4hi): Handle big endian.
	(vec_interleave_lowv4hi_be): New.
	(vec_interleave_lowv4hi_le): New.
	(insn_v2int_l): Handle big endian.
	(vec_interleave_highv2si): Handle big endian.
	(vec_interleave_highv2si_be): New.
	(vec_interleave_highv2si_le): New.
	(insn_v4int_h): Handle big endian.
	(vec_interleave_lowv2si): Handle big endian.
	(vec_interleave_lowv2si_be): New.
	(vec_interleave_lowv2si_le): New.
	(insn_v4int_l): Handle big endian.
	* config/tilegx/tilegx.opt (mbig-endian): New option.
	(mlittle-endian): New option.
	* doc/install.texi: Document tilegxbe-linux.
	* doc/invoke.texi: Document -mbig-endian and -mlittle-endian.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208069 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
walt committed Feb 24, 2014
1 parent 54c6250 commit 2da3551
Show file tree
Hide file tree
Showing 23 changed files with 502 additions and 81 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2014-02-24 Walter Lee <[email protected]>

* configure.ac (tilepro-*-*) Change to tilepro*-*-*.
(tilegx-*-*): Change to tilegx*-*-*.
* configure: Regenerate.

2014-02-17 Loren J. Rittle <[email protected]>

* MAINTAINERS (Various Maintainers: c++ runtime libs): Remove myself.
Expand Down
2 changes: 1 addition & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -3815,7 +3815,7 @@ case "${target}" in
tic6x-*-*)
noconfigdirs="$noconfigdirs sim"
;;
tilepro-*-* | tilegx-*-*)
tilepro*-*-* | tilegx*-*-*)
noconfigdirs="$noconfigdirs sim"
;;
v810-*-*)
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1145,7 +1145,7 @@ case "${target}" in
tic6x-*-*)
noconfigdirs="$noconfigdirs sim"
;;
tilepro-*-* | tilegx-*-*)
tilepro*-*-* | tilegx*-*-*)
noconfigdirs="$noconfigdirs sim"
;;
v810-*-*)
Expand Down
4 changes: 4 additions & 0 deletions contrib/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2014-02-24 Walter Lee <[email protected]>

* config-list.mk (LIST): Add tilegxbe-linux-gnu.

2014-02-13 Richard Biener <[email protected]>

* download_prerequisites: Update ISL and CLOOG versions.
Expand Down
3 changes: 2 additions & 1 deletion contrib/config-list.mk
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ LIST = aarch64-elf aarch64-linux-gnu \
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 tilegx-linux-gnu tilepro-linux-gnu \
sparc64-netbsd sparc64-openbsd spu-elf \
tilegx-linux-gnu tilegxbe-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 \
Expand Down
58 changes: 58 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,61 @@
2014-02-24 Walter Lee <[email protected]>

* config.gcc (tilepro-*-*): Change to tilepro*-*-*.
(tilegx-*-linux*): Change to tilegx*-*-linux*; Support tilegxbe
triplet.
* common/config/tilegx/tilegx-common.c
(TARGET_DEFAULT_TARGET_FLAGS): Define.
* config/tilegx/linux.h (ASM_SPEC): Add endian_spec.
(LINK_SPEC): Ditto.
* config/tilegx/sync.md (atomic_test_and_set): Handle big endian.
* config/tilegx/tilegx.c (tilegx_return_in_msb): New.
(tilegx_gimplify_va_arg_expr): Handle big endian.
(tilegx_expand_unaligned_load): Ditto.
(tilegx_expand_unaligned_store): Ditto.
(TARGET_RETURN_IN_MSB): New.
* config/tilegx/tilegx.h (TARGET_DEFAULT): New.
(TARGET_ENDIAN_DEFAULT): New.
(TARGET_BIG_ENDIAN): Handle big endian.
(BYTES_BIG_ENDIAN): Ditto.
(WORDS_BIG_ENDIAN): Ditto.
(FLOAT_WORDS_BIG_ENDIAN): Ditto.
(ENDIAN_SPEC): New.
(EXTRA_SPECS): New.
* config/tilegx/tilegx.md (extv): Handle big endian.
(extzv): Ditto.
(insn_st<n>): Ditto.
(insn_st<n>_add<bitsuffix>): Ditto.
(insn_stnt<n>): Ditto.
(insn_stnt<n>_add<bitsuffix>):Ditto.
(vec_interleave_highv8qi): Handle big endian.
(vec_interleave_highv8qi_be): New.
(vec_interleave_highv8qi_le): New.
(insn_v1int_h): Handle big endian.
(vec_interleave_lowv8qi): Handle big endian.
(vec_interleave_lowv8qi_be): New.
(vec_interleave_lowv8qi_le): New.
(insn_v1int_l): Handle big endian.
(vec_interleave_highv4hi): Handle big endian.
(vec_interleave_highv4hi_be): New.
(vec_interleave_highv4hi_le): New.
(insn_v2int_h): Handle big endian.
(vec_interleave_lowv4hi): Handle big endian.
(vec_interleave_lowv4hi_be): New.
(vec_interleave_lowv4hi_le): New.
(insn_v2int_l): Handle big endian.
(vec_interleave_highv2si): Handle big endian.
(vec_interleave_highv2si_be): New.
(vec_interleave_highv2si_le): New.
(insn_v4int_h): Handle big endian.
(vec_interleave_lowv2si): Handle big endian.
(vec_interleave_lowv2si_be): New.
(vec_interleave_lowv2si_le): New.
(insn_v4int_l): Handle big endian.
* config/tilegx/tilegx.opt (mbig-endian): New option.
(mlittle-endian): New option.
* doc/install.texi: Document tilegxbe-linux.
* doc/invoke.texi: Document -mbig-endian and -mlittle-endian.

2014-02-24 Martin Jambor <[email protected]>

PR ipa/60266
Expand Down
5 changes: 5 additions & 0 deletions gcc/common/config/tilegx/tilegx-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ tilegx_option_init_struct (struct gcc_options *opts)
}


#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS \
(TARGET_DEFAULT \
| TARGET_ENDIAN_DEFAULT)

#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE tilegx_option_optimization_table

Expand Down
11 changes: 8 additions & 3 deletions gcc/config.gcc
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ tilegx*-*-*)
cpu_type=tilegx
need_64bit_hwint=yes
;;
tilepro-*-*)
tilepro*-*-*)
cpu_type=tilepro
need_64bit_hwint=yes
;;
Expand Down Expand Up @@ -2764,15 +2764,20 @@ tic6x-*-uclinux)
tmake_file="${tmake_file} c6x/t-c6x c6x/t-c6x-elf c6x/t-c6x-uclinux"
use_collect2=no
;;
tilegx-*-linux*)
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="${extra_objs} mul-tables.o"
c_target_objs="${c_target_objs} tilegx-c.o"
cxx_target_objs="${cxx_target_objs} tilegx-c.o"
extra_headers="feedback.h"
case $target in
tilegxbe-*)
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
;;
esac
;;
tilepro-*-linux*)
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="${extra_objs} mul-tables.o"
Expand Down
5 changes: 3 additions & 2 deletions gcc/config/tilegx/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
#define CPP_SPEC "%{pthread:-D_REENTRANT}"

#undef ASM_SPEC
#define ASM_SPEC "%{m32:--32} %{m64:--64}"
#define ASM_SPEC "%(endian_spec) %{m32:--32} %{m64:--64}"

#undef LINK_SPEC
#define LINK_SPEC "%{m64:-m elf64tilegx} %{m32:-m elf32tilegx} \
#define LINK_SPEC "%(endian_spec) \
%{m64:-m elf64tilegx} %{m32:-m elf32tilegx} \
%{shared:-shared} \
%{!shared: \
%{!static: \
Expand Down
28 changes: 19 additions & 9 deletions gcc/config/tilegx/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@
(match_operand:SI 2 "const_int_operand" "")] ;; model
""
{
rtx addr, aligned_addr, aligned_mem, offset, word, shmt;
rtx tmp0, tmp1;
rtx addr, aligned_addr, aligned_mem, offset, word, shmt, tmp;
rtx result = operands[0];
rtx mem = operands[1];
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
Expand All @@ -191,27 +190,38 @@
aligned_mem = change_address (mem, DImode, aligned_addr);
set_mem_alias_set (aligned_mem, 0);

tmp = gen_reg_rtx (Pmode);
if (BYTES_BIG_ENDIAN)
{
emit_move_insn (gen_lowpart (DImode, tmp),
gen_rtx_NOT (DImode, gen_lowpart (DImode, addr)));
}
else
{
tmp = addr;
}

offset = gen_reg_rtx (DImode);
emit_move_insn (offset, gen_rtx_AND (DImode, gen_lowpart (DImode, addr),
emit_move_insn (offset, gen_rtx_AND (DImode, gen_lowpart (DImode, tmp),
GEN_INT (7)));

tmp0 = gen_reg_rtx (DImode);
emit_move_insn (tmp0, GEN_INT (1));
tmp = gen_reg_rtx (DImode);
emit_move_insn (tmp, GEN_INT (1));

shmt = gen_reg_rtx (DImode);
emit_move_insn (shmt, gen_rtx_ASHIFT (DImode, offset, GEN_INT (3)));

word = gen_reg_rtx (DImode);
emit_move_insn (word, gen_rtx_ASHIFT (DImode, tmp0,
emit_move_insn (word, gen_rtx_ASHIFT (DImode, tmp,
gen_lowpart (SImode, shmt)));

tmp1 = gen_reg_rtx (DImode);
tmp = gen_reg_rtx (DImode);
tilegx_pre_atomic_barrier (model);
emit_insn (gen_atomic_fetch_or_baredi (tmp1, aligned_mem, word));
emit_insn (gen_atomic_fetch_or_baredi (tmp, aligned_mem, word));
tilegx_post_atomic_barrier (model);

emit_move_insn (gen_lowpart (DImode, result),
gen_rtx_LSHIFTRT (DImode, tmp1,
gen_rtx_LSHIFTRT (DImode, tmp,
gen_lowpart (SImode, shmt)));
DONE;
})
74 changes: 58 additions & 16 deletions gcc/config/tilegx/tilegx.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ tilegx_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
}


/* Implement TARGET_RETURN_IN_MSB. We return a value in the most
significant part of a register if:
- the target is big-endian; and
- the value has an aggregate type (e.g., structure or union). */
static bool
tilegx_return_in_msb (const_tree valtype)
{
return (TARGET_BIG_ENDIAN && AGGREGATE_TYPE_P (valtype));
}


/* Implement TARGET_RETURN_IN_MEMORY. */
static bool
tilegx_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
Expand Down Expand Up @@ -440,7 +451,10 @@ tilegx_setup_incoming_varargs (cumulative_args_t cum,
else
addr = VALIST.__args;
VALIST.__args = addr + paddedsize;
ret = *(TYPE *)addr;
if (BYTES_BIG_ENDIAN)
ret = *(TYPE *)(addr + paddedsize - sizeof(TYPE));
else
ret = *(TYPE *)addr;
*/
static tree
tilegx_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
Expand Down Expand Up @@ -503,10 +517,17 @@ tilegx_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
size_int (STACK_POINTER_OFFSET)),
unshare_expr (args));

/* Adjust the address of va_arg if it is in big endian mode. */
if (BYTES_BIG_ENDIAN && rsize > size)
tmp = fold_build_pointer_plus_hwi (tmp, rsize - size);
gimplify_assign (addr, tmp, pre_p);

/* Update VALIST.__args. */
tmp = fold_build_pointer_plus_hwi (addr, rsize);

if (BYTES_BIG_ENDIAN && rsize > size)
tmp = fold_build_pointer_plus_hwi (addr, size);
else
tmp = fold_build_pointer_plus_hwi (addr, rsize);
gimplify_assign (unshare_expr (args), tmp, pre_p);

addr = fold_convert (build_pointer_type (type), addr);
Expand Down Expand Up @@ -1847,39 +1868,51 @@ tilegx_expand_unaligned_load (rtx dest_reg, rtx mem, HOST_WIDE_INT bitsize,

mode = GET_MODE (dest_reg);

hi = gen_reg_rtx (mode);

if (bitsize == 2 * BITS_PER_UNIT && (bit_offset % BITS_PER_UNIT) == 0)
{
rtx mem_left, mem_right;
rtx left = gen_reg_rtx (mode);

/* When just loading a two byte value, we can load the two bytes
individually and combine them efficiently. */

mem_lo = adjust_address (mem, QImode, byte_offset);
mem_hi = adjust_address (mem, QImode, byte_offset + 1);

if (BYTES_BIG_ENDIAN)
{
mem_left = mem_lo;
mem_right = mem_hi;
}
else
{
mem_left = mem_hi;
mem_right = mem_lo;
}

if (sign)
{
/* Do a signed load of the second byte and use bfins to set
the high bits of the result. */
emit_insn (gen_zero_extendqidi2 (gen_lowpart (DImode, dest_reg),
mem_lo));
emit_insn (gen_extendqidi2 (gen_lowpart (DImode, hi), mem_hi));
mem_right));
emit_insn (gen_extendqidi2 (gen_lowpart (DImode, left), mem_left));
emit_insn (gen_insv (gen_lowpart (DImode, dest_reg),
GEN_INT (64 - 8), GEN_INT (8),
gen_lowpart (DImode, hi)));
gen_lowpart (DImode, left)));
}
else
{
/* Do two unsigned loads and use v1int_l to interleave
them. */
rtx lo = gen_reg_rtx (mode);
emit_insn (gen_zero_extendqidi2 (gen_lowpart (DImode, lo),
mem_lo));
emit_insn (gen_zero_extendqidi2 (gen_lowpart (DImode, hi),
mem_hi));
rtx right = gen_reg_rtx (mode);
emit_insn (gen_zero_extendqidi2 (gen_lowpart (DImode, right),
mem_right));
emit_insn (gen_zero_extendqidi2 (gen_lowpart (DImode, left),
mem_left));
emit_insn (gen_insn_v1int_l (gen_lowpart (DImode, dest_reg),
gen_lowpart (DImode, hi),
gen_lowpart (DImode, lo)));
gen_lowpart (DImode, left),
gen_lowpart (DImode, right)));
}

return;
Expand Down Expand Up @@ -1917,6 +1950,7 @@ tilegx_expand_unaligned_load (rtx dest_reg, rtx mem, HOST_WIDE_INT bitsize,
}

/* Load hi first in case dest_reg is used in mema. */
hi = gen_reg_rtx (mode);
emit_move_insn (hi, mem_hi);
emit_move_insn (wide_result, mem_lo);

Expand Down Expand Up @@ -1945,12 +1979,17 @@ tilegx_expand_unaligned_store (rtx mem, rtx src, HOST_WIDE_INT bitsize,
{
HOST_WIDE_INT byte_offset = bit_offset / BITS_PER_UNIT;
HOST_WIDE_INT bytesize = bitsize / BITS_PER_UNIT;
HOST_WIDE_INT shift_amt;
HOST_WIDE_INT shift_init, shift_increment, shift_amt;
HOST_WIDE_INT i;
rtx mem_addr;
rtx store_val;

for (i = 0, shift_amt = 0; i < bytesize; i++, shift_amt += BITS_PER_UNIT)
shift_init = BYTES_BIG_ENDIAN ? (bitsize - BITS_PER_UNIT) : 0;
shift_increment = BYTES_BIG_ENDIAN ? -BITS_PER_UNIT : BITS_PER_UNIT;

for (i = 0, shift_amt = shift_init;
i < bytesize;
i++, shift_amt += shift_increment)
{
mem_addr = adjust_address (mem, QImode, byte_offset + i);

Expand Down Expand Up @@ -5530,6 +5569,9 @@ tilegx_file_end (void)
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE tilegx_pass_by_reference

#undef TARGET_RETURN_IN_MSB
#define TARGET_RETURN_IN_MSB tilegx_return_in_msb

#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY tilegx_return_in_memory

Expand Down
Loading

0 comments on commit 2da3551

Please sign in to comment.