2 * Copyright (c) 2002 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #ident "$Id: vector.c,v 1.15 2007/04/01 05:26:17 steve Exp $"
22 # include "vvp_priv.h"
25 /* Maximum vector bits in a thread. If a thread co-processor is
26 * implemented, this value may need to be reduced. At that time
27 * wider operations will need to be partitioned. For example
28 * shift operations on WIDE (say > 64k bit) registers.
30 #define MAX_VEC (256*1024)
32 static struct allocation_score_s
{
36 unsigned exp_bit
: 24;
37 unsigned sig_bit
: 24;
39 } allocation_map
[MAX_VEC
] = { {0} };
41 /* This is the largest bit to have lookaside values. */
42 static unsigned lookaside_top
= 0;
44 static inline ivl_expr_t
peek_exp(unsigned addr
)
46 return allocation_map
[addr
].exp
;
49 static inline unsigned peek_exp_bit(unsigned addr
)
51 return allocation_map
[addr
].exp_bit
;
54 static inline void set_exp(unsigned addr
, ivl_expr_t exp
, unsigned ebit
)
56 allocation_map
[addr
].exp
= exp
;
57 allocation_map
[addr
].exp_bit
= ebit
;
60 static inline void set_sig(unsigned addr
, ivl_signal_t exp
, unsigned sig_word
, unsigned ebit
)
62 allocation_map
[addr
].sig
= exp
;
63 allocation_map
[addr
].sig_word
= sig_word
;
64 allocation_map
[addr
].sig_bit
= ebit
;
68 * This clears a vector that was previously allocated by
69 * allocate_vector. That is, it unmarks all the bits of the map that
70 * represent this vector.
72 * If the vector is based in one of 4 constant bit values, then there
73 * are no bits to clear. If the vector is based in the 4-8 result
74 * area, then someone is broken.
76 void clr_vector(struct vector_info vec
)
81 assert(vec
.base
>= 8);
82 for (idx
= 0 ; idx
< vec
.wid
; idx
+= 1) {
83 assert( allocation_map
[vec
.base
+idx
].alloc
> 0);
84 allocation_map
[vec
.base
+idx
].alloc
-= 1;
88 static unsigned allocate_vector_no_lookaside(unsigned wid
, int skip_lookaside
)
94 if (base
+idx
>= MAX_VEC
)
97 assert((base
+ idx
) < MAX_VEC
);
98 if ((allocation_map
[base
+idx
].alloc
> 0)
99 || (skip_lookaside
&& peek_exp(base
+idx
))) {
100 base
= base
+ idx
+ 1;
108 for (idx
= 0 ; idx
< wid
; idx
+= 1) {
109 allocation_map
[base
+idx
].alloc
+= 1;
110 set_exp(base
+idx
, 0, 0);
111 set_sig(base
+idx
, 0, 0, 0);
118 * This unconditionally allocates a stretch of bits from the register
119 * set. It never returns a bit addressed <8 (0-3 are constant, 4-7 are
122 * First try to allocate a vector without interfering with any bits
123 * cached by the lookaside buffer. If that doesn't work, then try
124 * again without worrying about trashing lookaside results. This
125 * should lead to preferentially allocating new bits instead of
126 * constantly overwriting intermediate results.
128 * If there is no space for a vector of the given width, then give up
131 unsigned allocate_vector(unsigned wid
)
133 unsigned base
= allocate_vector_no_lookaside(wid
, 1);
136 base
= allocate_vector_no_lookaside(wid
, 0);
141 * This clears the expression cache of the allocation map. It is
142 * called to prevent reuse of existing expressions, normally at the
143 * start of a basic block, but also at the end of thread processing.
145 void clear_expression_lookaside(void)
149 for (idx
= 0 ; idx
< lookaside_top
; idx
+= 1) {
151 set_sig(idx
, 0, 0, 0);
157 static int test_expression_savable(ivl_expr_t exp
)
159 switch (ivl_expr_type(exp
)) {
170 void save_expression_lookaside(unsigned addr
, ivl_expr_t exp
, unsigned wid
)
174 assert((addr
+wid
) <= MAX_VEC
);
176 /* When saving an expression to the lookaside, also clear the
177 signal saved in the lookaside for these bits. The reason is
178 that an expression calculation will replace any signal
180 for (idx
= 0 ; idx
< wid
; idx
+= 1)
181 set_sig(addr
+idx
, 0, 0, 0);
183 /* Only certain types of expressions are savable. */
184 if ( ! test_expression_savable(exp
))
187 for (idx
= 0 ; idx
< wid
; idx
+= 1) {
188 set_exp(addr
+idx
, exp
, idx
);
191 if ((addr
+wid
) > lookaside_top
)
192 lookaside_top
= addr
+wid
;
195 static void clear_signal_lookaside_bit(unsigned idx
, ivl_signal_t sig
, unsigned sig_word
)
197 if (allocation_map
[idx
].alloc
> 0)
199 if (allocation_map
[idx
].sig
!= sig
)
201 if (allocation_map
[idx
].sig_word
!= sig_word
)
204 set_sig(idx
, 0, 0, 0);
207 void save_signal_lookaside(unsigned addr
, ivl_signal_t sig
, unsigned sig_word
, unsigned wid
)
210 /* Don't bind any of the low bits to a signal. */
211 if (addr
< 8 && wid
> 0)
214 assert((addr
+wid
) <= MAX_VEC
);
216 for (idx
= 8 ; idx
< addr
; idx
+= 1)
217 clear_signal_lookaside_bit(idx
, sig
, sig_word
);
219 for (idx
= 0 ; idx
< wid
; idx
+= 1)
220 set_sig(addr
+idx
, sig
, sig_word
, idx
);
222 if ((addr
+wid
) > lookaside_top
)
223 lookaside_top
= addr
+wid
;
225 for (idx
= addr
+wid
; idx
< lookaside_top
; idx
+= 1)
226 clear_signal_lookaside_bit(idx
, sig
, sig_word
);
229 static int compare_exp(ivl_expr_t l
, ivl_expr_t r
)
236 if (ivl_expr_type(l
) != ivl_expr_type(r
))
239 switch (ivl_expr_type(l
)) {
242 if (ivl_expr_width(l
) != ivl_expr_width(r
))
244 { const char*bitl
= ivl_expr_bits(l
);
245 const char*bitr
= ivl_expr_bits(r
);
247 for (idx
= 0 ; idx
< ivl_expr_width(l
) ; idx
+= 1) {
248 if (bitl
[idx
] != bitr
[idx
])
255 if (! compare_exp(ivl_expr_oper1(l
), ivl_expr_oper1(r
)))
258 if (ivl_expr_oper2(l
) == 0 && ivl_expr_oper1(r
) == 0)
261 if (! compare_exp(ivl_expr_oper2(l
), ivl_expr_oper2(r
)))
267 if (ivl_expr_signal(l
) != ivl_expr_signal(r
))
270 if (ivl_expr_width(l
) != ivl_expr_width(r
))
273 /* Don't match array words. */
274 if (ivl_expr_oper1(l
) || ivl_expr_oper1(r
))
286 static unsigned find_expression_lookaside(ivl_expr_t exp
, unsigned wid
)
292 if (lookaside_top
<= wid
)
295 top
= lookaside_top
- wid
+ 1;
297 /* Look in the expression lookaside for this expression. */
300 for (idx
= 8 ; idx
< lookaside_top
; idx
+= 1) {
301 if (! compare_exp(allocation_map
[idx
].exp
, exp
)) {
306 if (allocation_map
[idx
].exp_bit
!= match
) {
316 /* The general expression lookup failed. If this is an
317 IVL_EX_SIGNAL, then look again in the variable lookaside
318 (which is saved l-values) for the expression. */
319 if (ivl_expr_type(exp
) != IVL_EX_SIGNAL
)
322 sig
= ivl_expr_signal(exp
);
324 /* Only reg signals (variables) will be in the signal
325 lookaside, because only blocking assigned values are in the
327 if (ivl_signal_type(sig
) != IVL_SIT_REG
)
330 /* Now look for signal value matches in the signal lookaside. */
332 for (idx
= 8 ; idx
< lookaside_top
; idx
+= 1) {
333 if (sig
!= allocation_map
[idx
].sig
) {
338 if (allocation_map
[idx
].sig_bit
!= match
) {
353 * Look for the expression in the expression lookaside table. If it is
354 * there, then allocate it and return the base. In this case the
355 * caller will not need to evaluate the expression. If this function
356 * returns 0, then the expression is not found and nothing is allocated.
358 unsigned allocate_vector_exp(ivl_expr_t exp
, unsigned wid
,
362 unsigned la
= find_expression_lookaside(exp
, wid
);
366 if (exclusive_flag
) {
367 /* If the caller is requesting exclusive allocation of
368 the expression, then return not-found if a lookup
369 already matched the expression. */
370 for (idx
= 0 ; idx
< wid
; idx
+= 1)
371 if (allocation_map
[la
+idx
].alloc
)
375 for (idx
= 0 ; idx
< wid
; idx
+= 1)
376 allocation_map
[la
+idx
].alloc
+= 1;
383 * Revision 1.15 2007/04/01 05:26:17 steve
384 * Fix that save expression lookaside always clears cached variable values.
386 * Revision 1.14 2007/03/22 16:08:18 steve
387 * Spelling fixes from Larry
389 * Revision 1.13 2007/03/20 04:26:56 steve
390 * Clear lookaside even if source bit is a constant.
392 * Revision 1.12 2007/02/26 19:49:50 steve
393 * Spelling fixes (larry doolittle)
395 * Revision 1.11 2007/02/06 04:43:53 steve
396 * Expression lookaside cannot hold complex expressions
398 * Revision 1.10 2007/01/19 02:30:19 steve
399 * Fix bad lookaside references in vvp thread code generator.
401 * Revision 1.9 2007/01/18 00:59:48 steve
402 * Do not match array words in expression lookaside.
404 * Revision 1.8 2007/01/16 05:44:16 steve
405 * Major rework of array handling. Memories are replaced with the
406 * more general concept of arrays. The NetMemory and NetEMemory
407 * classes are removed from the ivl core program, and the IVL_LPM_RAM
408 * lpm type is removed from the ivl_target API.
410 * Revision 1.7 2005/09/17 01:01:00 steve
411 * More robust use of precalculated expressions, and
412 * Separate lookaside for written variables that can
415 * Revision 1.6 2005/09/15 02:50:13 steve
416 * Preserve precalculated expressions when possible.
418 * Revision 1.5 2005/01/24 05:08:02 steve
419 * Part selects are done in the compiler, not here.
421 * Revision 1.4 2003/07/03 17:44:10 steve
422 * Wider thread vector limit.
424 * Revision 1.3 2003/06/17 19:17:42 steve
425 * Remove short int restrictions from vvp opcodes.
427 * Revision 1.2 2003/06/05 04:18:50 steve
428 * Better width testing for thread vector allocation.
430 * Revision 1.1 2002/09/27 16:33:34 steve
431 * Add thread expression lookaside map.