This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[named-addr-spaces-branch][PATCH,committed] Support building newlib with ea support


This patch allows the newlib with ea patches to be built, and adds support for
testing to see if the newlib is present.  Note, I still have some bugs in
copying pointers.

[gcc]
2008-11-21  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* config/spu/spu.md (to_ea): Use convert_move to convert input
	operand to the appropriate type.  If the output is not a register,
	create a register, create the result in the register, and move to
	the output.

[gcc/testsuite]
2008-11-21  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/spu/ea/ea.exp (check_effective_target_ea64): New
	procedure to see if we have full support for -mea64.  Disable
	temporarily.
	(check_effective_target_ea32): Ditto.

	* gcc.target/spu/cache.c: Delete cache test from here, move it to
	the ea subdirectory.

	* gcc.target/spu/ea/cache-common.h: Move cache test here, split
	into -mea32 and -mea64 tests.
	* gcc.target/spu/ea/cache32.c: Ditto.
	* gcc.target/spu/ea/cache64.c: Ditto.

	* gcc.target/spu/ea/cast1.c: Use check_effective_target_ea32 to
	require support for -mea32.

Index: gcc/config/spu/spu.md
===================================================================
--- gcc/config/spu/spu.md	(revision 142041)
+++ gcc/config/spu/spu.md	(working copy)
@@ -5248,17 +5248,24 @@ DONE;
 
   ls_mem = gen_rtx_MEM (DImode, gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store"));
 
-  op0 = force_reg (mode, operands[0]);
-  op1 = force_reg (Pmode, operands[1]);
+  op0 = (REG_P (operands[0]) ? operands[0] : gen_reg_rtx (mode));
 
-  if (mode == Pmode)
-    emit_insn (gen_addsi3 (op0, op1, force_reg (mode, gen_lowpart (mode, ls_mem))));
+  if (GET_MODE (operands[1]) == mode)
+    op1 = force_reg (mode, operands[1]);
   else
     {
-      rtx tmp = gen_reg_rtx (DImode);
-      emit_move_insn (tmp, gen_rtx_ZERO_EXTEND (DImode, op1));
-      emit_insn (gen_adddi3 (op0, tmp, force_reg (mode, ls_mem)));
+      op1 = gen_reg_rtx (mode);
+      convert_move (op1, operands[1], true);
     }
+
+  if (mode == Pmode)
+    emit_insn (gen_addsi3 (op0, op1, force_reg (mode, gen_lowpart (mode, ls_mem))));
+  else
+    emit_insn (gen_adddi3 (op0, op1, force_reg (mode, ls_mem)));
+
+  if (op0 != operands[0])
+    emit_move_insn (operands[0], op0);
+
   DONE;
 })
 
@@ -5273,10 +5280,22 @@ DONE;
   ls_mem = gen_rtx_MEM (DImode, gen_rtx_SYMBOL_REF (Pmode, "__ea_local_store"));
   ls = force_reg (Pmode, gen_lowpart (Pmode, ls_mem));
 
-  op0 = force_reg (Pmode, operands[0]);
-  op1 = force_reg (mode, operands[1]);
+  op0 = (REG_P (operands[0]) ? operands[0] : gen_reg_rtx (mode));
+
+  if (GET_MODE (operands[1]) == mode)
+    op1 = force_reg (mode, operands[1]);
+  else
+    {
+      op1 = gen_reg_rtx (mode);
+      convert_move (op1, operands[1], true);
+    }
+
   tmp = (mode == Pmode) ? op1 : force_reg (Pmode, gen_lowpart (Pmode, op1));
 
   emit_insn (gen_subsi3 (op0, tmp, ls));
+
+  if (op0 != operands[0])
+    emit_move_insn (operands[0], op0);
+
   DONE;
 })
Index: gcc/testsuite/gcc.target/spu/cache.c
===================================================================
--- gcc/testsuite/gcc.target/spu/cache.c	(revision 142041)
+++ gcc/testsuite/gcc.target/spu/cache.c	(working copy)
@@ -1,220 +0,0 @@
-/* Copyright (C) 2008 Free Software Foundation, Inc.
-
-   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 2 of the License, 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.
-
-   You should have received a copy of the GNU General Public License
-   along with this file; see the file COPYING.  If not, write to the Free
-   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.  */
-
-/* { dg-do run } */
-/* { dg-options "-mcache-size=8" } */
-
-#include <stdlib.h>
-#include <string.h>
-#include <spu_cache.h>
-extern void *malloc (__SIZE_TYPE__);
-extern void *memset (void *, int, __SIZE_TYPE__);
-extern void abort (void);
-
-#ifdef __EA64__
-#define addr unsigned long long
-#else
-#define addr unsigned long
-#endif
-
-#ifdef __EA64__
-#define malloc_ea __malloc_ea64
-#define memset_ea __memset_ea64
-#define memcpy_ea __memcpy_ea64
-
-typedef unsigned long long size_ea_t;
-
-__ea void *__malloc_ea64 (size_ea_t);
-__ea void *__memset_ea64 (__ea void *, int, size_ea_t);
-__ea void *__memcpy_ea64 (__ea void *, __ea const void *, size_ea_t);
-#else
-#define malloc_ea __malloc_ea32
-#define memset_ea __memset_ea32
-#define memcpy_ea __memcpy_ea32
-
-typedef unsigned long size_ea_t;
-
-__ea void *__malloc_ea32 (size_ea_t size);
-__ea void *__memset_ea32 (__ea void *, int, size_ea_t);
-__ea void *__memcpy_ea32 (__ea void *, __ea const void *, size_ea_t);
-#endif
-
-static __ea void *bigblock;
-static __ea void *block;
-static int *ls_block;
-
-extern void __cache_tag_array_size;
-#define CACHE_SIZE (4 * (int) &__cache_tag_array_size)
-#define LINE_SIZE 128
-
-void
-init_mem ()
-{
-  bigblock = malloc_ea (CACHE_SIZE + 2 * LINE_SIZE);
-  block = malloc_ea (2 * LINE_SIZE);
-  ls_block = malloc (LINE_SIZE);
-
-  memset_ea (bigblock, 0, CACHE_SIZE + 2 * LINE_SIZE);
-  memset_ea (block, -1, 2 * LINE_SIZE);
-  memset (ls_block, -1, LINE_SIZE);
-  cache_flush ();
-}
-
-/* Test 1: Simple cache fetching.  */
-void
-test1 ()
-{
-  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
-  int *p1 = NULL;
-  int *p2 = NULL;
-  int i = 0;
-
-  /* First, check if the same addr give the same cache ptr.  */
-  p1 = cache_fetch ((__ea void *) aligned);
-  p2 = cache_fetch ((__ea void *) aligned);
-
-  if (p1 != p2)
-    abort ();
-
-  /* Check that the data actually is in the cache. */
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    {
-      if (p1[i] != -1)
-	abort ();
-    }
-
-  /* Check returning within the cache line. */
-  p2 = cache_fetch ((__ea void *) (aligned + sizeof (int)));
-
-  if (p2 - p1 != 1)
-    abort ();
-
-  /* Finally, check that fetching an LS pointer returns that pointer.  */
-  p1 = cache_fetch ((__ea char *) ls_block);
-  if (p1 != ls_block)
-    abort ();
-}
-
-/* Test 2: Eviction testing. */
-void
-test2 ()
-{
-  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
-  int *p = NULL;
-  int i = 0;
-
-  /* First check that clean evictions don't write back.  */
-  p = cache_fetch ((__ea void *) aligned);
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    p[i] = 0;
-
-  cache_evict ((__ea void *) aligned);
-  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
-
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    {
-      if (ls_block[i] == 0)
-	abort ();
-    }
-
-  /* Now check that dirty evictions do write back.  */
-  p = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    p[i] = 0;
-
-  cache_evict ((__ea void *) aligned);
-  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
-
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    {
-      if (ls_block[i] != 0)
-	abort ();
-    }
-
-  /* Finally, check that non-atomic writeback only writes dirty bytes.  */
-
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    {
-      p = cache_fetch_dirty ((__ea void *) (aligned + i * sizeof (int)),
-			     (i % 2) * sizeof (int));
-      p[0] = -1;
-    }
-
-  cache_evict ((__ea void *) aligned);
-  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
-
-  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
-    {
-      if ((ls_block[i] == -1) && (i % 2 == 0))
-	abort ();
-      if ((ls_block[i] == 0) && (i % 2 == 1))
-	abort ();
-    }
-}
-
-/* Test LS forced-eviction. */
-void
-test3 ()
-{
-  addr aligned = ((((addr) bigblock) + LINE_SIZE - 1) & -LINE_SIZE);
-  char *test = NULL;
-  char *ls = NULL;
-  int i = 0;
-
-  /* Init memory, fill the cache to capacity.  */
-  ls = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
-  for (i = 1; i < (CACHE_SIZE / LINE_SIZE); i++)
-    cache_fetch_dirty ((__ea void *) (aligned + i * LINE_SIZE), LINE_SIZE);
-
-  memset (ls, -1, LINE_SIZE);
-  test = cache_fetch ((__ea void *) (aligned + CACHE_SIZE));
-
-  /* test == ls indicates cache collision.  */
-  if (test != ls)
-    abort ();
-
-  /* Make sure it actually wrote the cache line.  */
-  for (i = 0; i < LINE_SIZE; i++)
-    {
-      if (ls[i] != 0)
-	abort ();
-    }
-
-  ls = cache_fetch ((__ea void *) aligned);
-
-  /* test != ls indicates another entry was evicted.  */
-  if (test == ls)
-    abort ();
-
-  /* Make sure that the previous eviction actually wrote back.  */
-  for (i = 0; i < LINE_SIZE; i++)
-    {
-      if (ls[i] != 0xFF)
-	abort ();
-    }
-}
-
-int
-main (int argc, char **argv)
-{
-  init_mem ();
-  test1 ();
-  test2 ();
-  test3 ();
-
-  return 0;
-}
Index: gcc/testsuite/gcc.target/spu/ea/cache-common.h
===================================================================
--- gcc/testsuite/gcc.target/spu/ea/cache-common.h	(revision 0)
+++ gcc/testsuite/gcc.target/spu/ea/cache-common.h	(revision 0)
@@ -0,0 +1,200 @@
+#include <stdlib.h>
+#include <string.h>
+#include <spu_cache.h>
+extern void *malloc (__SIZE_TYPE__);
+extern void *memset (void *, int, __SIZE_TYPE__);
+extern void abort (void);
+
+#ifdef __EA64__
+#define addr unsigned long long
+#else
+#define addr unsigned long
+#endif
+
+#ifdef __EA64__
+#define malloc_ea __malloc_ea64
+#define memset_ea __memset_ea64
+#define memcpy_ea __memcpy_ea64
+
+typedef unsigned long long size_ea_t;
+
+__ea void *__malloc_ea64 (size_ea_t);
+__ea void *__memset_ea64 (__ea void *, int, size_ea_t);
+__ea void *__memcpy_ea64 (__ea void *, __ea const void *, size_ea_t);
+#else
+#define malloc_ea __malloc_ea32
+#define memset_ea __memset_ea32
+#define memcpy_ea __memcpy_ea32
+
+typedef unsigned long size_ea_t;
+
+__ea void *__malloc_ea32 (size_ea_t size);
+__ea void *__memset_ea32 (__ea void *, int, size_ea_t);
+__ea void *__memcpy_ea32 (__ea void *, __ea const void *, size_ea_t);
+#endif
+
+static __ea void *bigblock;
+static __ea void *block;
+static int *ls_block;
+
+extern void __cache_tag_array_size;
+#define CACHE_SIZE (4 * (int) &__cache_tag_array_size)
+#define LINE_SIZE 128
+
+void
+init_mem ()
+{
+  bigblock = malloc_ea (CACHE_SIZE + 2 * LINE_SIZE);
+  block = malloc_ea (2 * LINE_SIZE);
+  ls_block = malloc (LINE_SIZE);
+
+  memset_ea (bigblock, 0, CACHE_SIZE + 2 * LINE_SIZE);
+  memset_ea (block, -1, 2 * LINE_SIZE);
+  memset (ls_block, -1, LINE_SIZE);
+  cache_flush ();
+}
+
+/* Test 1: Simple cache fetching.  */
+void
+test1 ()
+{
+  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
+  int *p1 = NULL;
+  int *p2 = NULL;
+  int i = 0;
+
+  /* First, check if the same addr give the same cache ptr.  */
+  p1 = cache_fetch ((__ea void *) aligned);
+  p2 = cache_fetch ((__ea void *) aligned);
+
+  if (p1 != p2)
+    abort ();
+
+  /* Check that the data actually is in the cache. */
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    {
+      if (p1[i] != -1)
+	abort ();
+    }
+
+  /* Check returning within the cache line. */
+  p2 = cache_fetch ((__ea void *) (aligned + sizeof (int)));
+
+  if (p2 - p1 != 1)
+    abort ();
+
+  /* Finally, check that fetching an LS pointer returns that pointer.  */
+  p1 = cache_fetch ((__ea char *) ls_block);
+  if (p1 != ls_block)
+    abort ();
+}
+
+/* Test 2: Eviction testing. */
+void
+test2 ()
+{
+  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
+  int *p = NULL;
+  int i = 0;
+
+  /* First check that clean evictions don't write back.  */
+  p = cache_fetch ((__ea void *) aligned);
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    p[i] = 0;
+
+  cache_evict ((__ea void *) aligned);
+  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
+
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    {
+      if (ls_block[i] == 0)
+	abort ();
+    }
+
+  /* Now check that dirty evictions do write back.  */
+  p = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    p[i] = 0;
+
+  cache_evict ((__ea void *) aligned);
+  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
+
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    {
+      if (ls_block[i] != 0)
+	abort ();
+    }
+
+  /* Finally, check that non-atomic writeback only writes dirty bytes.  */
+
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    {
+      p = cache_fetch_dirty ((__ea void *) (aligned + i * sizeof (int)),
+			     (i % 2) * sizeof (int));
+      p[0] = -1;
+    }
+
+  cache_evict ((__ea void *) aligned);
+  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
+
+  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
+    {
+      if ((ls_block[i] == -1) && (i % 2 == 0))
+	abort ();
+      if ((ls_block[i] == 0) && (i % 2 == 1))
+	abort ();
+    }
+}
+
+/* Test LS forced-eviction. */
+void
+test3 ()
+{
+  addr aligned = ((((addr) bigblock) + LINE_SIZE - 1) & -LINE_SIZE);
+  char *test = NULL;
+  char *ls = NULL;
+  int i = 0;
+
+  /* Init memory, fill the cache to capacity.  */
+  ls = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
+  for (i = 1; i < (CACHE_SIZE / LINE_SIZE); i++)
+    cache_fetch_dirty ((__ea void *) (aligned + i * LINE_SIZE), LINE_SIZE);
+
+  memset (ls, -1, LINE_SIZE);
+  test = cache_fetch ((__ea void *) (aligned + CACHE_SIZE));
+
+  /* test == ls indicates cache collision.  */
+  if (test != ls)
+    abort ();
+
+  /* Make sure it actually wrote the cache line.  */
+  for (i = 0; i < LINE_SIZE; i++)
+    {
+      if (ls[i] != 0)
+	abort ();
+    }
+
+  ls = cache_fetch ((__ea void *) aligned);
+
+  /* test != ls indicates another entry was evicted.  */
+  if (test == ls)
+    abort ();
+
+  /* Make sure that the previous eviction actually wrote back.  */
+  for (i = 0; i < LINE_SIZE; i++)
+    {
+      if (ls[i] != 0xFF)
+	abort ();
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  init_mem ();
+  test1 ();
+  test2 ();
+  test3 ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/spu/ea/ea.exp
===================================================================
--- gcc/testsuite/gcc.target/spu/ea/ea.exp	(revision 142041)
+++ gcc/testsuite/gcc.target/spu/ea/ea.exp	(working copy)
@@ -16,14 +16,52 @@
 
 # GCC testsuite that uses the `dg.exp' driver.
 
-# Load support procs.
-load_lib gcc-dg.exp
-
 # Exit immediately if this isn't a SPU target.
 if { ![istarget spu-*-*] } then {
   return
 }
 
+# Load support procs.
+load_lib gcc-dg.exp
+
+# Return 1 if -mea64 target library functions are available
+proc check_effective_target_ea64 { } {
+    return [check_no_compiler_messages ea64 executable {
+	#include <stdlib.h>
+	#include <string.h>
+	#include <spu_cache.h>
+	#error "disable test tempoarily"
+
+	__ea void *ptr;
+	__ea void *__malloc_ea64 (unsigned long long);
+
+	int main (void)
+	{
+	    ptr = __malloc_ea64 (1024LL);
+	    return 0;
+	}
+    } "-O2 -mea64" ]
+}
+
+# Return 1 if -mea32 target library functions are available
+proc check_effective_target_ea32 { } {
+    return [check_no_compiler_messages ea32 executable {
+	#include <stdlib.h>
+	#include <string.h>
+	#include <spu_cache.h>
+	#error "disable test tempoarily"
+
+	__ea void *ptr;
+	__ea void *__malloc_ea32 (unsigned long);
+
+	int main (void)
+	{
+	    ptr = __malloc_ea32 (1024L);
+	    return 0;
+	}
+    } "-O2 -mea32" ]
+}
+
 # If a testcase doesn't have special options, use these.
 global DEFAULT_CFLAGS
 if ![info exists DEFAULT_CFLAGS] then {
Index: gcc/testsuite/gcc.target/spu/ea/cache32.c
===================================================================
--- gcc/testsuite/gcc.target/spu/ea/cache32.c	(revision 0)
+++ gcc/testsuite/gcc.target/spu/ea/cache32.c	(revision 0)
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 2 of the License, 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* { dg-do run } */
+/* { dg-require-effective-target "ea32" } */
+/* { dg-options "-mcache-size=8 -O2 -mea32 -g" } */
+
+#ifndef __EA32__
+#error "You must use -mea32 for this test"
+#endif
+
+#include "cache-common.h"
Index: gcc/testsuite/gcc.target/spu/ea/cast1.c
===================================================================
--- gcc/testsuite/gcc.target/spu/ea/cast1.c	(revision 142053)
+++ gcc/testsuite/gcc.target/spu/ea/cast1.c	(working copy)
@@ -1,5 +1,6 @@
 /* { dg-do run { target spu-*-* } } */
-/* { dg-options "-std=gnu99" } */
+/* { dg-require-effective-target "ea32" } */
+/* { dg-options "-std=gnu99 -O2 -mea32" } */
 
 extern void abort (void);
 extern unsigned long long __ea_local_store;
Index: gcc/testsuite/gcc.target/spu/ea/cache64.c
===================================================================
--- gcc/testsuite/gcc.target/spu/ea/cache64.c	(revision 0)
+++ gcc/testsuite/gcc.target/spu/ea/cache64.c	(revision 0)
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008 Free Software Foundation, Inc.
+
+   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 2 of the License, 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this file; see the file COPYING.  If not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* { dg-do run } */
+/* { dg-require-effective-target "ea64" } */
+/* { dg-options "-mcache-size=8 -O2 -mea64 -g" } */
+
+#ifndef __EA64__
+#error "You must use -mea64 for this test"
+#endif
+
+#include "cache-common.h"

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]