OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [gcc.target/] [spu/] [ea/] [cache1.c] - Blame information for rev 691

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 691 jeremybenn
/* Copyright (C) 2009 Free Software Foundation, Inc.
2
 
3
   This file is free software; you can redistribute it and/or modify it under
4
   the terms of the GNU General Public License as published by the Free
5
   Software Foundation; either version 3 of the License, or (at your option)
6
   any later version.
7
 
8
   This file is distributed in the hope that it will be useful, but WITHOUT
9
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11
   for more details.
12
 
13
   You should have received a copy of the GNU General Public License
14
   along with this file; see the file COPYING3.  If not see
15
   <http://www.gnu.org/licenses/>.  */
16
 
17
/* { dg-do run } */
18
/* { dg-require-effective-target "ealib" } */
19
 
20
#include <stdlib.h>
21
#include <string.h>
22
#include <ea.h>
23
#include <spu_cache.h>
24
 
25
#ifdef __EA64__
26
#define addr unsigned long long
27
#else
28
#define addr unsigned long
29
#endif
30
 
31
static __ea void *bigblock;
32
static __ea void *block;
33
static int *ls_block;
34
 
35
extern char __cache_tag_array_size[];
36
#define CACHE_SIZE (4 * (int) &__cache_tag_array_size[0])
37
#define LINE_SIZE ((addr)128)
38
 
39
void
40
init_mem (void)
41
{
42
  bigblock = malloc_ea (CACHE_SIZE + 2 * LINE_SIZE);
43
  block = malloc_ea (2 * LINE_SIZE);
44
  ls_block = malloc (LINE_SIZE);
45
 
46
  memset_ea (bigblock, 0, CACHE_SIZE + 2 * LINE_SIZE);
47
  memset_ea (block, -1, 2 * LINE_SIZE);
48
  memset (ls_block, -1, LINE_SIZE);
49
  cache_flush ();
50
}
51
 
52
/* Test 1: Simple cache fetching.  */
53
void
54
test1 (void)
55
{
56
  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
57
  int *p1 = NULL;
58
  int *p2 = NULL;
59
  int i = 0;
60
 
61
  /* First, check if the same addr give the same cache ptr.  */
62
  p1 = cache_fetch ((__ea void *) aligned);
63
  p2 = cache_fetch ((__ea void *) aligned);
64
 
65
  if (p1 != p2)
66
    abort ();
67
 
68
  /* Check that the data actually is in the cache. */
69
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
70
    {
71
      if (p1[i] != -1)
72
        abort ();
73
    }
74
 
75
  /* Check returning within the cache line. */
76
  p2 = cache_fetch ((__ea void *) (aligned + sizeof (int)));
77
 
78
  if (p2 - p1 != 1)
79
    abort ();
80
 
81
  /* Finally, check that fetching an LS pointer returns that pointer.  */
82
  p1 = cache_fetch ((__ea char *) ls_block);
83
  if (p1 != ls_block)
84
    abort ();
85
}
86
 
87
/* Test 2: Eviction testing. */
88
void
89
test2 (void)
90
{
91
  addr aligned = ((((addr) block) + LINE_SIZE - 1) & -LINE_SIZE);
92
  int *p = NULL;
93
  int i = 0;
94
 
95
  /* First check that clean evictions don't write back.  */
96
  p = cache_fetch ((__ea void *) aligned);
97
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
98
    p[i] = 0;
99
 
100
  cache_evict ((__ea void *) aligned);
101
  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
102
 
103
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
104
    {
105
      if (ls_block[i] == 0)
106
        abort ();
107
    }
108
 
109
  /* Now check that dirty evictions do write back.  */
110
  p = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
111
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
112
    p[i] = 0;
113
 
114
  cache_evict ((__ea void *) aligned);
115
  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
116
 
117
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
118
    {
119
      if (ls_block[i] != 0)
120
        abort ();
121
    }
122
 
123
  /* Finally, check that non-atomic writeback only writes dirty bytes.  */
124
 
125
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
126
    {
127
      p = cache_fetch_dirty ((__ea void *) (aligned + i * sizeof (int)),
128
                             (i % 2) * sizeof (int));
129
      p[0] = -1;
130
    }
131
 
132
  cache_evict ((__ea void *) aligned);
133
  memcpy_ea ((__ea char *) ls_block, (__ea void *) aligned, LINE_SIZE);
134
 
135
  for (i = 0; i < LINE_SIZE / sizeof (int); i++)
136
    {
137
      if ((ls_block[i] == -1) && (i % 2 == 0))
138
        abort ();
139
      if ((ls_block[i] == 0) && (i % 2 == 1))
140
        abort ();
141
    }
142
}
143
 
144
/* Test LS forced-eviction. */
145
void
146
test3 (void)
147
{
148
  addr aligned = ((((addr) bigblock) + LINE_SIZE - 1) & -LINE_SIZE);
149
  char *test = NULL;
150
  char *ls = NULL;
151
  int i = 0;
152
 
153
  /* Init memory, fill the cache to capacity.  */
154
  ls = cache_fetch_dirty ((__ea void *) aligned, LINE_SIZE);
155
  for (i = 1; i < (CACHE_SIZE / LINE_SIZE); i++)
156
    cache_fetch_dirty ((__ea void *) (aligned + i * LINE_SIZE), LINE_SIZE);
157
 
158
  memset (ls, -1, LINE_SIZE);
159
  test = cache_fetch ((__ea void *) (aligned + CACHE_SIZE));
160
 
161
  /* test == ls indicates cache collision.  */
162
  if (test != ls)
163
    abort ();
164
 
165
  /* Make sure it actually wrote the cache line.  */
166
  for (i = 0; i < LINE_SIZE; i++)
167
    {
168
      if (ls[i] != 0)
169
        abort ();
170
    }
171
 
172
  ls = cache_fetch ((__ea void *) aligned);
173
 
174
  /* test != ls indicates another entry was evicted.  */
175
  if (test == ls)
176
    abort ();
177
 
178
  /* Make sure that the previous eviction actually wrote back.  */
179
  for (i = 0; i < LINE_SIZE; i++)
180
    {
181
      if (ls[i] != 0xFF)
182
        abort ();
183
    }
184
}
185
 
186
int
187
main (int argc, char **argv)
188
{
189
  init_mem ();
190
  test1 ();
191
  test2 ();
192
  test3 ();
193
 
194
  return 0;
195
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.