Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/* 	$Id: regalloc.c,v 1.1.1.1 1998/01/17 15:56:01 release Exp $	 */
32
 
33
#ifndef lint
34
static char vcid[] = "$Id: regalloc.c,v 1.1.1.1 1998/01/17 15:56:01 release Exp $";
35
#endif /* lint */
36
 
37
 
38
/*
39
  regalloc.c
40
 
41
  functions to allocate register and stack space for a proc.
42
  The following changes are made to the ident tags:
43
 
44
  props(ident) contains inreg_bits or infreg_bits, no(ident)==0
45
  => value is a t reg (chosen in make_code()).
46
  props(ident) contains reg bits =>  no(ident) is sreg.
47
  props(ident) is instore => no = displacement*64+SP.
48
*/
49
 
50
/*
51
$Log: regalloc.c,v $
52
 * Revision 1.1.1.1  1998/01/17  15:56:01  release
53
 * First version to be checked into rolling release.
54
 *
55
 * Revision 1.5  1995/08/23  16:07:20  john
56
 * Changed comment
57
 *
58
 * Revision 1.4  1995/05/25  15:33:27  john
59
 * Fixed register allocation
60
 *
61
 * Revision 1.3  1995/05/23  13:25:44  john
62
 * Changed to use FIRST_S_REG rather than constant
63
 *
64
 * Revision 1.2  1995/05/16  10:55:06  john
65
 * Changes for spec 3.1
66
 *
67
 * Revision 1.1.1.1  1995/03/23  10:39:19  john
68
 * Entered into CVS
69
 *
70
 * Revision 1.7  1995/03/23  10:13:26  john
71
 * Fix to register allocation
72
 *
73
*/
74
 
75
#include "config.h"
76
#include "expmacs.h"
77
#include "tags.h"
78
#include "procrectypes.h"
79
#include "procrecs.h"
80
#include "bitsmacs.h"
81
#include "maxminmacs.h"
82
#include "regable.h"
83
#include "regmacs.h"
84
#include "common_types.h"
85
#include "frames.h"
86
#include "reg_defs.h"
87
#include "coder.h"
88
#include "regalloc.h"
89
 
90
spacereq zerospace = {
91
  0, 0, 0
92
};
93
 
94
spacereq maxspace
95
    PROTO_N ( (a,b) )
96
    PROTO_T ( spacereq a X spacereq b )
97
{
98
  a.fixdump |= b.fixdump;
99
  a.fltdump |= b.fltdump;
100
  a.stack = max (a.stack, b.stack);
101
  return a;
102
}
103
 
104
static int spareparregs = 0;
105
 
106
/*
107
  reg_alloc
108
  Delivers a spacereq which gives the local stack bit 
109
  requirement in the stack field and the s regs used as bit 
110
  positions in the fixdump, sdump and ddump fields for fixed 
111
  point, single and double floats respectively.
112
  e is a proc body . freefixed and freefloat are the number of 
113
  fixed and floating s regs available. These are initialised at 
114
  the outer level but may be reduced by usage in paralloc 
115
*/
116
spacereq regalloc
117
    PROTO_N ( ( e, freefixed, freefloat, stack ) )
118
    PROTO_T ( exp e X int freefixed X int freefloat X int stack )
119
{
120
  int   n = name (e);
121
  exp s = son (e);
122
  spacereq def;
123
 
124
  if (n == ident_tag) {
125
    int   ffix = freefixed;
126
    int   ffloat = freefloat;
127
    int  st = stack;
128
    int old_spareparregs = spareparregs;
129
    spacereq body;
130
    ash a;
131
    if (props (e) & defer_bit) {
132
       /* the tag declared is transparent to code production */
133
      def = zerospace;
134
    }
135
    else {
136
      a = ashof (sh (s));
137
      if (name(s) != compound_tag && name(s) != nof_tag 
138
	  && name(s) != concatnof_tag ) {
139
      	def = regalloc (s, freefixed, freefloat, stack);
140
      }
141
      else  { 
142
     /*elements of tuples are done separately so evaluate above dec*/
143
	if (a.ashalign <= 64 || (stack & 0x40) == 0) {
144
	  st = stack + ((a.ashsize + 63) & ~63);
145
	}	
146
	else {
147
	  st = stack + 64 + ((a.ashsize + 63) & ~63);
148
	}
149
	def = regalloc (s, freefixed, freefloat, st);
150
      }     
151
      if ((props (e) & inreg_bits) == 0 && fixregable (e) && no (e) < ffix) {
152
	/* suitable for s reg , no(e) has been set
153
	   up by weights */
154
	props (e) |= (inreg_bits | sreguse);
155
	no (e) = ffix + 8;	/* will be in s reg , note s0 = $9 */
156
	def.fixdump |= (1 << (no(e)-FIRST_S_REG)/*ffix*/);	
157
	ffix -= 1;
158
        /* def.fixdump |= (1<<no(e)); */
159
      }
160
      else
161
	if ((props (e) & infreg_bits) == 0
162
	    && floatregable (e) && no (e) < ffloat) {
163
	  /* suitable for float s reg , no(e) has
164
	     been set up by weights */
165
	  props (e) |= (infreg_bits | sreguse);
166
	  no (e) = ffloat + 1;	/* will be in s reg,note start from $f9*/
167
	  def.fltdump |=(1<<ffloat);
168
	  ffloat -= 1;
169
	  /* have another look at this */
170
	}
171
	else
172
	  if ((props (e) & inanyreg) == 0) {
173
	    if (fixregable(e) && PossParReg(e) && spareparregs > 0){
174
	      props(e) |= inreg_bits;
175
	      no(e) = NO_REG;
176
	      spareparregs--;
177
	    }	
178
	    else
179
	    /* not suitable for reg allocation */
180
	      if (name (son (e)) == val_tag && !isvar (e) && !isvis(e)) {
181
		exp t = pt (e);
182
		for (; t != nilexp;) {
183
		  exp p = pt(t);
184
		  setname (t, val_tag);
185
		  son(t) = nilexp;
186
		  no(t) = no (son (e));
187
		  props(t) = 0;
188
		  pt(t) = nilexp;
189
		  t = p;
190
		}
191
		pt (e) = nilexp;
192
		props (e) |= defer_bit;
193
		def = zerospace;
194
	      }
195
	      else
196
		if (name (son (e)) == name_tag && !isvar (e) && !isvis(e)) {
197
		  /* must have been forced  - defer it */
198
		  props (e) |= defer_bit;
199
		  def = zerospace;
200
		}
201
		else 
202
		  if (isparam(e)) {
203
		    if(props(son(e)) != 0){
204
		      spareparregs++;
205
		    }
206
		    no(e) = 0;
207
		    /* don't know framesize yet; 
208
		     displacement in no(son(e)) */
209
		  }
210
		  else {		/* allocate on stack */
211
		    int basereg = (Has_vcallees)?local_reg:((Has_fp)?FP:SP);
212
		    if (a.ashalign <= 64 || (stack & 0x40) == 0) {
213
		      st = stack + ((a.ashsize + 63) & ~63);
214
		    }
215
		    else { 
216
		      stack += 64;
217
		      st = stack + ((a.ashsize + 63) & ~63);
218
		    }	
219
		    def.stack = max (def.stack, st);
220
		    no (e) = stack * 2 + basereg;
221
		  }
222
	  }
223
	  else
224
	    if (no (e) == 101) {
225
	      no(e) = RESULT_REG;
226
	      /* Use the result register (the result register has the 
227
	     same number for both floating and fixed point results */
228
	    }
229
      /* else  allocation of stack like regs in make_code */
230
    }
231
    body = regalloc (bro (s), ffix, ffloat, st);
232
    spareparregs = old_spareparregs;
233
    return maxspace (body, def);
234
  }
235
  else				/* recurse on all expressions in tree */
236
    if (n == case_tag) {
237
      return regalloc (s, freefixed, freefloat, stack);
238
    }
239
    else
240
      if (n != name_tag && n!= env_offset_tag && n != general_env_offset_tag 
241
	  && s != nilexp) {
242
	def = regalloc (s, freefixed, freefloat, stack);
243
	while (!last (s)) {
244
	  s = bro (s);
245
	  def = maxspace (def, regalloc (s, freefixed, freefloat, stack));
246
	}
247
	return def;
248
      }
249
      else {
250
      	def = zerospace;
251
      	def.stack = stack;
252
	return def;
253
      }
254
}