1 /* --------------------------------------------------------------- */
2 /* PLEASE DO NOT MODIFY THIS SECTION */
3 /* This prolog section is automatically generated. */
5 /* (C) Copyright 2001,2006, */
6 /* International Business Machines Corporation, */
8 /* All Rights Reserved. */
9 /* --------------------------------------------------------------- */
10 /* PROLOG END TAG zYx */
13 * Copyright (C) 2005 IBM Corp.
15 * Internal lookup operations for software
18 * See nway-opt.h for "optimized" nway
22 #ifndef __SPE_CACHE_NWAY_LOOKUP_H_
23 #define __SPE_CACHE_NWAY_LOOKUP_H_
28 * Load up set entries (by 4) from an n-way
29 * set associative cache. Mask off the dirty
32 #define _decl_set_entries_(set, name, index) \
33 vec_uint4 name = *((vec_uint4 *) &spe_cache_dir[set][index])
36 #define _spe_cache_4_way_lookup_(set, ea) \
38 _decl_set_entries_(set, e0123, 0); \
39 spu_gather(spu_cmpeq(e0123, ea)); \
43 * _spe_cache_set_lookup_
44 * Compare 'ea' against all entries of
45 * a set, and return a result that is
46 * consistent with spu_gather().
48 #define _spe_cache_set_lookup_(set, ea) \
49 _spe_cache_4_way_lookup_(set, ea)
53 * _spe_cache_nway_lookup_x4_
54 * Declare local variables and lookup four addresses
55 * in the n-way set associative cache. Upon return,
56 * 'idx_x4' contains the matching elements in the sets,
59 #define _spe_cache_nway_lookup_x4(ea_x4, set_x4, idx_x4) \
61 vector unsigned int ea_aligned_x4 = spu_and ((ea_x4), ~SPE_CACHELINE_MASK); \
62 vector unsigned char splat0 = VEC_LITERAL(vector unsigned char, \
63 0x00, 0x01, 0x02, 0x03, \
64 0x00, 0x01, 0x02, 0x03, \
65 0x00, 0x01, 0x02, 0x03, \
66 0x00, 0x01, 0x02, 0x03); \
67 vector unsigned char splat1 = VEC_LITERAL(vector unsigned char, \
68 0x04, 0x05, 0x06, 0x07, \
69 0x04, 0x05, 0x06, 0x07, \
70 0x04, 0x05, 0x06, 0x07, \
71 0x04, 0x05, 0x06, 0x07); \
72 vector unsigned char splat2 = VEC_LITERAL(vector unsigned char, \
73 0x08, 0x09, 0x0a, 0x0b, \
74 0x08, 0x09, 0x0a, 0x0b, \
75 0x08, 0x09, 0x0a, 0x0b, \
76 0x08, 0x09, 0x0a, 0x0b); \
77 vector unsigned char splat3 = VEC_LITERAL(vector unsigned char, \
78 0x0c, 0x0d, 0x0e, 0x0f, \
79 0x0c, 0x0d, 0x0e, 0x0f, \
80 0x0c, 0x0d, 0x0e, 0x0f, \
81 0x0c, 0x0d, 0x0e, 0x0f); \
82 vec_uint4 ea_aligned0 = spu_shuffle(ea_aligned_x4, ea_aligned_x4, splat0); \
83 vec_uint4 ea_aligned1 = spu_shuffle(ea_aligned_x4, ea_aligned_x4, splat1); \
84 vec_uint4 ea_aligned2 = spu_shuffle(ea_aligned_x4, ea_aligned_x4, splat2); \
85 vec_uint4 ea_aligned3 = spu_shuffle(ea_aligned_x4, ea_aligned_x4, splat3); \
86 vec_uint4 found0, found1, found2, found3; \
88 (set_x4) = _spe_cache_set_num_x4(ea_x4); \
89 found0 = _spe_cache_set_lookup_(spu_extract (set_x4, 0), ea_aligned0); \
90 found1 = _spe_cache_set_lookup_(spu_extract (set_x4, 1), ea_aligned1); \
91 found2 = _spe_cache_set_lookup_(spu_extract (set_x4, 2), ea_aligned2); \
92 found3 = _spe_cache_set_lookup_(spu_extract (set_x4, 3), ea_aligned3); \
93 found_x4 = _pack_vec_uint4 (found0, found1, found2, found3); \
94 (idx_x4) = (vector signed int)_spe_cache_idx_num_x4(found_x4); \
97 #define _spe_cache_nway_lookup_(ea, set, idx) \
99 unsigned int ea_aligned = (ea) & ~SPE_CACHELINE_MASK; \
100 vec_uint4 ea_aligned4 = spu_splats(ea_aligned); \
102 (set) = _spe_cache_set_num_(ea); \
103 found = _spe_cache_set_lookup_(set, ea_aligned4); \
104 (idx) = _spe_cache_idx_num_(found); \
109 * Lookup and return the LSA of an EA
110 * that is known to be in the cache.
112 #define _spe_cache_lookup_(ea, is_write) \
114 int set, idx, line, byte; \
115 _spe_cache_nway_lookup_(ea, set, idx); \
117 line = _spe_cacheline_num_(set, idx); \
118 byte = _spe_cacheline_byte_offset_(ea); \
119 (void *) &spe_cache_mem[line + byte]; \
124 * Wait for transfer of a cache line
127 #define _spe_cache_wait_(_lsa) \
129 spu_writech(22, _SPE_CACHELINE_TAGMASK(_lsa)); \
130 spu_mfcstat(MFC_TAG_UPDATE_ALL); \
134 * _spe_cache_lookup_wait_
135 * Lookup and return the LSA of an EA
136 * that is known to be in the cache,
137 * and guarantee that its transfer is
140 #define _spe_cache_lookup_wait_(ea, is_write) \
142 int set, idx, line, byte; \
143 _spe_cache_nway_lookup_(ea, set, idx); \
145 line = _spe_cacheline_num_(set, idx); \
146 byte = _spe_cacheline_byte_offset_(ea); \
147 spu_writech(22, SPE_CACHE_SET_TAGMASK(set)); \
148 spu_mfcstat(MFC_TAG_UPDATE_ALL); \
149 (void *) &spe_cache_mem[line + byte]; \
153 * _spe_cache_lookup_xfer_
154 * Lookup and return the LSA of an EA, where
155 * the line may either be in the cache or not.
156 * If not, initiate transfer but do not wait
159 #define _spe_cache_lookup_xfer_(ea, is_write, rb) \
161 int set, idx, line, byte; \
162 _spe_cache_nway_lookup_(ea, set, idx); \
164 if (unlikely(idx < 0)) { \
165 idx = _spe_cache_miss_(ea, set, -1); \
167 line = _spe_cacheline_num_(set, idx); \
168 byte = _spe_cacheline_byte_offset_(ea); \
169 (void *) &spe_cache_mem[line + byte]; \
173 * _spe_cache_lookup_xfer_wait_
174 * Lookup and return the LSA of an EA, where
175 * the line may either be in the cache or not.
176 * If not, initiate transfer and guarantee
179 #define _spe_cache_lookup_xfer_wait_(ea, is_write, rb) \
181 int set, idx, line, byte; \
182 _spe_cache_nway_lookup_(ea, set, idx); \
184 if (unlikely(idx < 0)) { \
185 idx = _spe_cache_miss_(ea, set, -1); \
186 spu_writech(22, SPE_CACHE_SET_TAGMASK(set)); \
187 spu_mfcstat(MFC_TAG_UPDATE_ALL); \
189 line = _spe_cacheline_num_(set, idx); \
190 byte = _spe_cacheline_byte_offset_(ea); \
191 (void *) &spe_cache_mem[line + byte]; \