Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | 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
/*
32
			    VERSION INFORMATION
33
			    ===================
34
 
35
--------------------------------------------------------------------------
36
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/regalloc.c,v 1.1.1.1 1998/01/17 15:55:55 release Exp $
37
--------------------------------------------------------------------------
38
$Log: regalloc.c,v $
39
 * Revision 1.1.1.1  1998/01/17  15:55:55  release
40
 * First version to be checked into rolling release.
41
 *
42
 * Revision 1.9  1997/08/23  13:54:34  pwe
43
 * initial ANDF-DE
44
 *
45
 * Revision 1.8  1997/03/26  13:04:52  pwe
46
 * general proc compatibility
47
 *
48
 * Revision 1.7  1996/08/22  16:47:15  pwe
49
 * correct accessing for double params
50
 *
51
 * Revision 1.6  1995/11/07  09:53:31  john
52
 * Change to general procs
53
 *
54
 * Revision 1.5  1995/10/24  17:16:15  john
55
 * Fixed stupid mistake in register allocation
56
 *
57
 * Revision 1.4  1995/09/22  13:07:17  john
58
 * Protected local reg
59
 *
60
 * Revision 1.3  1995/08/22  15:29:15  john
61
 * Change to compound_tag
62
 *
63
 * Revision 1.2  1995/05/26  13:01:29  john
64
 * Change for new spec
65
 *
66
 * Revision 1.1.1.1  1995/03/13  10:18:53  john
67
 * Entered into CVS
68
 *
69
 * Revision 1.4  1994/12/01  13:25:47  djch
70
 * Alter allocator to ensure env_offset'd go on the stack.
71
 *
72
 * Revision 1.3  1994/10/26  13:44:54  djch
73
 * *** empty log message ***
74
 *
75
 * Revision 1.2  1994/05/03  15:10:48  djch
76
 * From the expt version, fixes bug where fixdump sometimes got real reg numbers,
77
 * sometimes sreg numbers
78
 *
79
 * Revision 1.2  1994/05/03  15:10:48  djch
80
 * From the expt version, fixes bug where fixdump sometimes got real reg numbers,
81
 * sometimes sreg numbers
82
 *
83
 * Revision 1.2  94/02/15  11:20:27  djch
84
 * fixed wrong bit set in fixdump for inreg_bits exps, added comments
85
 * 
86
 * Revision 1.1  94/01/13  12:13:56  djch
87
 * Initial revision
88
 * 
89
 * Revision 1.4  93/08/27  11:36:44  11:36:44  ra (Robert Andrews)
90
 * A couple of lint-like changes.  Use of pset etc to set properties.
91
 * 
92
 * Revision 1.3  93/08/13  14:44:36  14:44:36  ra (Robert Andrews)
93
 * Reformatted comment.
94
 * 
95
 * Revision 1.2  93/07/05  18:24:39  18:24:39  ra (Robert Andrews)
96
 * Reformatted file.  Added support for PIC by means of the avoid_L7
97
 * flag which causes register L7 not to be allocated.
98
 * 
99
 * Revision 1.1  93/06/24  14:59:11  14:59:11  ra (Robert Andrews)
100
 * Initial revision
101
 * 
102
--------------------------------------------------------------------------
103
*/
104
 
105
 
106
#define SPARCTRANS_CODE
107
/*
108
  The main procedure defined here is reg_alloc which allocates 
109
  registers and stack space for a procedure expression.  After the 
110
  application of weights to the body reg_alloc re-codes the number 
111
  field of each ident within it.  At the end of reg_alloc :
112
 
113
  1) If the props field of an ident contains inreg_bits or 
114
     infreg_bits and number = 0 then the value will be in a 
115
     t-register to be chosen in make_code,
116
 
117
  2) If the props contains the register bits then number of 
118
     the ident is a fixed point s-register number or a floating 
119
     point s-register number (divided by 2).
120
 
121
  3) Otherwise the value is on the stack and :
122
     number of ident = ( word displacement in locals ) * 64 + R_FP.
123
*/
124
 
125
#include "config.h"
126
#include "common_types.h"
127
#include "expmacs.h"
128
#include "tags.h"
129
#include "proctypes.h"
130
#include "procrec.h"
131
#include "bitsmacs.h"
132
#include "maxminmacs.h"
133
#include "regable.h"
134
#include "regmacs.h"
135
#include "comment.h"
136
#include "myassert.h"
137
#include "flags.h"
138
#include "proc.h"
139
#include "translat.h"
140
#include "regalloc.h"
141
 
142
/*
143
  FLAG : AVOID REGISTER L7 (USED IN PIC)
144
*/
145
 
146
bool avoid_L7 = 0 ;
147
 
148
 
149
/*
150
  MAP FIXREG NUMBER TO REAL REGISTER NUMBER
151
  The number n in the range 1...14 is mapped onto the corresponding
152
  register out of R_L0,...,R_L7,R_I5,...,R_I0.
153
*/
154
 
155
/* 
156
   we will see the parameters first, so won't call this until 
157
   the remaining Ix's are available...
158
*/
159
static int SREG_TO_REALREG 
160
    PROTO_N ( ( n ) )
161
    PROTO_T ( int n ){
162
  int m = ( avoid_L7 ? 7 : 8 ) ;
163
  int par_reg_max;
164
  if ( n <= m ) return ( R_L0 + ( n - 1 ) ) ;
165
#ifdef GENCOMPAT
166
  if (May_have_callees) {
167
#else
168
  if(in_general_proc) {
169
#endif
170
    if(Has_vcallees) {
171
      par_reg_max = R_I3;
172
    }
173
    else {
174
      par_reg_max = R_I4;
175
    }
176
  }
177
  else {
178
    par_reg_max = R_I5;
179
  }
180
  return par_reg_max-(n-m-1);
181
  /*return ( (Has_vcallees)?(R_I4-(n-m-1)):(R_I5 - ( n - m - 1 )) ) ;*/
182
}
183
 
184
 
185
/*
186
  ROUND b UP TO A MULTIPLE OF a
187
*/
188
 
189
#define ALIGNNEXT( b, a )      ( ( ( b ) + ( a ) - 1 ) & ~( ( a ) - 1 ) )
190
 
191
 
192
/*
193
  THE ZERO SPACEREQ
194
*/
195
 
196
spacereq zerospace = { 0, 0, 0 } ;
197
 
198
 
199
/*
200
  FIND THE MAXIMUM OF TWO SPACEREQS
201
  The register masks are just or'ed, the stack size is the larger of
202
  the two.
203
*/
204
 
205
spacereq maxspace 
206
    PROTO_N ( ( a, b ) )
207
    PROTO_T ( spacereq a X spacereq b ){
208
  a.fixdump |= b.fixdump ;
209
  a.fltdump |= b.fltdump ;
210
  a.stack = MAX_OF ( a.stack, b.stack ) ;
211
  return ( a ) ;
212
}
213
 
214
 
215
/*
216
  CALCULATE SPACE REQUIREMENTS FOR A PROCEDURE
217
  The expression e gives the procedure body, freefixed and freefloat
218
  are respectively the numbers to fixed and floating s-registers.
219
  The initial stack size is given by stack.
220
*/
221
 
222
spacereq regalloc 
223
    PROTO_N ( ( e, freefixed, freefloat, stack ) )
224
    PROTO_T ( exp e X int freefixed X int freefloat X long stack ){
225
  spacereq def ;
226
  exp s = son ( e ) ;
227
  unsigned char n = name ( e ) ;
228
  if ( n == ident_tag ) {
229
    int ffix = freefixed ;
230
    int ffloat = freefloat ;
231
    long st = stack ;
232
    spacereq body ;
233
    ash a ;
234
    assert ( freefixed >= 0 ) ;
235
    assert ( freefloat >= 0 ) ;
236
    if ( props ( e ) & defer_bit ) {
237
      /* the tag declared is transparent to code production */
238
      def = zerospace ;
239
    } 
240
    else {
241
      a = ashof ( sh ( s ) ) ;
242
#if 1
243
      if(name(s) != compound_tag && name(s) != nof_tag && 
244
	 name(s) != concatnof_tag) {
245
	def = regalloc ( s, freefixed, freefloat, stack ) ;
246
      }
247
      else {
248
	if(a.ashalign <= 32 || (stack & 0x20)==0) {
249
	  st = stack + ((a.ashsize + 31) & ~31);
250
	}
251
	else {
252
	  st = stack + 32 + ((a.ashsize+31)&~31);
253
	}
254
	def = regalloc(s,freefixed,freefloat,st);
255
      }
256
#else
257
      def = regalloc(s,freefixed,freefloat,stack);
258
#endif      
259
      if ( isparam ( e ) ) {
260
	/* ( some ) SPARC params in s-regs, reserve them here */
261
	int n2 = ( int ) props ( son ( e ) ) ;
262
	int start = no ( son ( e ) ) >> 5 ;
263
	if ( start <= 5 ) {
264
	  /* Some input registers (%i0 .. %i5) are used */
265
	  int nregs ;
266
	  /* "end" Word offset beyond end of param */
267
	  long sz = shape_size ( sh ( son ( e ) ) ) ;
268
	  int end = ( int ) ( start + ( rounder ( sz, 32 ) >> 5 ) ) ;
269
	  if ( end > 6 ) end = 6 ;
270
	  nregs = end - start ;
271
/*		    assert ( ( n2 - R_I0 ) == start ) ;*/
272
	  assert ( nregs <= 6 ) ;
273
	  ffix -= nregs ; /* this also prevents SREG_TO_REALREG
274
			     from using these regs...*/
275
	}	
276
	if ( ( props ( e ) & inreg_bits ) != 0 ) {
277
	  assert ( no ( e ) == n2 ) ;
278
	  assert ( IS_SREG ( no ( e ) ) ) ;
279
	  assert ( a.ashsize <= 32 ) ;
280
	  assert ( R_I0 <= n2 && n2 <= R_I5 ) ;
281
	  def.fixdump |= RMASK ( n2 ) ;
282
	}
283
	else
284
	  no ( e ) = 0 ;
285
	assert ( ffix >= 0 ) ;
286
      } 
287
      else if ( ( props ( e ) & inreg_bits ) == 0 &&
288
		fixregable ( e ) && no ( e ) < ffix ) {
289
	/* suitable for s reg, no(e) has been set up by weights */
290
	pset ( e, inreg_bits ) ;
291
	no ( e ) = SREG_TO_REALREG ( ffix ) ; /* will be in s reg */
292
	ffix -= 1 ;
293
	def.fixdump |= RMASK ( no(e) ) ;	/* was ffix */
294
	assert ( ffix >= 0 ) ;
295
	assert ( IS_SREG ( no ( e ) ) ) ;
296
	assert ( a.ashsize <= 32 ) ;
297
      } 
298
      else if ( ( props ( e ) & infreg_bits ) == 0 &&
299
		floatregable ( e ) && no ( e ) < ffloat ) {
300
	fail ( "regalloc : no float point s regs on SPARC" ) ;
301
      } 
302
      else if ( ( props ( e ) & inanyreg ) == 0 ) {
303
	if ( name ( son ( e ) ) == val_tag && !isvar ( e )
304
	     && !isenvoff(e)) {
305
	  /* must have been forced by const optimisation -
306
	     replace uses by the value */
307
	  exp t = pt ( e ) ;
308
	  for ( ; t != nilexp ; ) {
309
	    exp p = pt ( t ) ;
310
	    setname ( t, val_tag ) ;
311
	    son ( t ) = nilexp ;
312
	    no ( t ) = no ( son ( e ) ) ;
313
	    props ( t ) = 0 ;
314
	    pt ( t ) = nilexp ;
315
	    t = p ;
316
	  }
317
	  pt ( e ) = nilexp ;
318
	  pset ( e, defer_bit ) ;
319
	  def = zerospace ;
320
	} 
321
	else if ( name ( son ( e ) ) == name_tag && !isvar ( e ) 
322
		  & !isenvoff(e)) {
323
	  /* must have been forced - defer it */
324
	  pset ( e, defer_bit ) ;
325
	  def = zerospace ;
326
	} 
327
	else {	/* all envoffset MUST go on the stack */
328
	  /* allocate on stack */
329
	  /*int basereg = (Has_vcallees)?local_reg:R_FP;*/
330
	  int basereg = R_FP;
331
 
332
	  assert ( ( stack & 31 ) == 0 ) ;
333
	  stack = ALIGNNEXT ( stack, a.ashalign ) ;
334
	  st = ALIGNNEXT ( stack + a.ashsize, 32 ) ;
335
	  assert ( st - stack >= a.ashsize ) ;
336
	  assert ( ( stack & 31 ) == 0 ) ;
337
	  def.stack = MAX_OF ( def.stack, st ) ;
338
	  no ( e ) = ( int ) ( stack * 2 + basereg) ;
339
	}
340
      } 
341
      else if ( no ( e ) == R_USE_RES_REG ) {
342
	/* use result register */
343
	assert (!isenvoff(e));
344
	no ( e ) = ( ( ( props ( e ) & inreg_bits ) != 0 ) ?
345
		     R_O0 : R_DEFER_F0 ) ;
346
      } 
347
      else {
348
	/* allocation of stack like regs in make_code */
349
	assert (!isenvoff(e));	      
350
      }
351
    }	
352
    body = regalloc ( bro ( s ), ffix, ffloat, st ) ;
353
    return ( maxspace ( body, def ) ) ;
354
  } 
355
  else if ( n == case_tag ) {
356
    /* recurse on all expressions in tree */
357
    return ( regalloc ( s, freefixed, freefloat, stack ) ) ;
358
  } 
359
  else if ( n != name_tag && n != env_offset_tag && n!= general_env_offset_tag 
360
	    && s != nilexp ) {
361
    /* recurse on all expressions in tree */
362
    def = regalloc ( s, freefixed, freefloat, stack ) ;
363
    while ( !last ( s ) ) {
364
      spacereq sdef ;
365
      s = bro ( s ) ;
366
      sdef = regalloc ( s, freefixed, freefloat, stack ) ;
367
      def = maxspace ( def, sdef ) ;
368
    }
369
    return ( def ) ;
370
  } 
371
  else {
372
    def = zerospace ;
373
    def.stack = stack ;
374
    return ( def ) ;
375
  }
376
  /* NOT REACHED */
377
}
378
 
379
 
380