From 1bc5aee63eb72b341f506ad058502cd0361f0d10 Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Tue, 25 Mar 2014 22:37:19 -0700 Subject: Initial checkin of GCC 4.9.0 from trunk (r208799). Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba --- gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c | 195 +++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c (limited to 'gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c') diff --git a/gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c b/gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c new file mode 100644 index 000000000..3487ce980 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.target/spu/ea/cache1.c @@ -0,0 +1,195 @@ +/* Copyright (C) 2009 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 3 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 COPYING3. If not see + . */ + +/* { dg-do run } */ +/* { dg-require-effective-target "ealib" } */ + +#include +#include +#include +#include + +#ifdef __EA64__ +#define addr unsigned long long +#else +#define addr unsigned long +#endif + +static __ea void *bigblock; +static __ea void *block; +static int *ls_block; + +extern char __cache_tag_array_size[]; +#define CACHE_SIZE (4 * (int) &__cache_tag_array_size[0]) +#define LINE_SIZE ((addr)128) + +void +init_mem (void) +{ + 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 (void) +{ + 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 (void) +{ + 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 (void) +{ + 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; +} -- cgit v1.2.3