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
$Log: regalloc.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.2  1995/12/18  13:12:27  wfs
37
 * Put hppatrans uder cvs control. Major Changes made since last release
38
 * include:
39
 * (i) PIC code generation.
40
 * (ii) Profiling.
41
 * (iii) Dynamic Initialization.
42
 * (iv) Debugging of Exception Handling and Diagnostics.
43
 *
44
 * Revision 5.0  1995/08/25  13:42:58  wfs
45
 * Preperation for August 25 Glue release
46
 *
47
 * Revision 3.4  1995/08/25  10:27:07  wfs
48
 * Fairly major revision - register allocation is more like the "mips"
49
 * and more suited to the hppa. Register synonyms changed.
50
 *
51
 * Revision 3.4  1995/08/25  10:27:07  wfs
52
 * Fairly major revision - register allocation is more like the "mips"
53
 * and more suited to the hppa. Register synonyms changed.
54
 *
55
 * Revision 3.1  95/04/10  16:27:59  16:27:59  wfs (William Simmonds)
56
 * Apr95 tape version.
57
 * 
58
 * Revision 3.0  95/03/30  11:18:50  11:18:50  wfs (William Simmonds)
59
 * Mar95 tape version with CRCR95_178 bug fix.
60
 * 
61
 * Revision 2.0  95/03/15  15:28:40  15:28:40  wfs (William Simmonds)
62
 * spec 3.1 changes implemented, tests outstanding.
63
 * 
64
 * Revision 1.1  95/01/11  13:15:26  13:15:26  wfs (William Simmonds)
65
 * Initial revision
66
 * 
67
*/
68
 
69
 
70
#define HPPATRANS_CODE
71
/****************************************************************
72
		regalloc.c
73
 
74
	The main procedure defined here is reg_alloc which
75
allocates registers and stack space for a proc exp. After the application of
76
weights to the body reg_alloc re-codes the number field of each ident within it.
77
	At the end of reg_alloc:-
78
1) props of ident contains inreg_bits or infreg_bits and number = 0
79
then the value will be in a t reg to be chosen in make_code
80
2) if props contains the reg bits then number of ident is fixpt s reg
81
or floatpnt s reg (divided by 2)
82
3) value is on the stack and:
83
number of ident = (word displacement in locals)*64 + GR17
84
 
85
*****************************************************************/
86
 
87
 
88
 
89
#include "config.h"
90
#include "expmacs.h"
91
#include "tags.h"
92
#include "proctypes.h"
93
#include "procrec.h"
94
#include "bitsmacs.h"
95
#include "maxminmacs.h"
96
#include "regable.h"
97
#include "regmacs.h"
98
#include "comment.h"
99
#include "myassert.h"
100
#include "frames.h"
101
#include "regalloc.h"
102
 
103
/* map fixreg s number 16,..,1 onto real callee-saves registers GR3,...,GR18 */
104
#define SREG_TO_REALREG(n) real_reg[16-(n)];
105
 
106
int real_reg[16] =
107
{ GR3,
108
  0,
109
  0,
110
  GR6,
111
  GR7,
112
  GR8,
113
  GR9,
114
  GR10,
115
  GR11,
116
  GR12,
117
  GR13,
118
  GR14,
119
  GR15,
120
  GR16,
121
  GR17,
122
  GR18 };
123
 
124
 
125
 
126
#define ALIGNNEXT(bitposn, bitalign)	(((bitposn)+(bitalign)-1) & ~((bitalign)-1))
127
 
128
spacereq zerospace = {0, 0, 0};
129
 
130
/*****************************************************************
131
	maxspace
132
 
133
Procedure to find the total spacereq of two spacereqs. The bit
134
representations of the s regs used are simply 'or'ed so that the
135
resulting dump fields contain all the regs of the parameters.
136
The largest of the two stack sizes is returned as the stack of the result.
137
 
138
*****************************************************************/
139
 
140
spacereq maxspace 
141
    PROTO_N ( ( a, b ) )
142
    PROTO_T ( spacereq a X spacereq b )
143
{
144
  a.fixdump |= b.fixdump;
145
  a.fltdump |= b.fltdump;
146
  a.stack = MAX_OF(a.stack, b.stack);
147
  return a;
148
}
149
 
150
 
151
/******************************************************************
152
	reg_alloc
153
 
154
Delivers a spacereq which gives the local stack bit requirement in the
155
stack field and the s regs used as bit positions in the fixdump, sdump and
156
ddump fields for fixed point, single and double floats respectively.
157
 
158
******************************************************************/
159
 
160
spacereq regalloc 
161
    PROTO_N ( ( e, freefixed, freefloat, stack ) )
162
    PROTO_T ( exp e X int freefixed X int freefloat X long stack )
163
/*
164
 * e is a proc body.
165
 * freefixed and freefloat are the number of fixed and floating s regs
166
 * available. These are initialised at the outer level but may be reduced
167
 * by usage in paralloc.
168
 */
169
{
170
  int n = name(e);
171
  exp s = son(e);
172
  spacereq def;
173
  if (n == ident_tag)
174
  {
175
    int ffix = freefixed;
176
    int ffloat = freefloat;
177
    long st = stack;
178
    spacereq body;
179
    ash a;
180
 
181
    FULLCOMMENT4("regalloc ident_tag(%d):	freefixed,freefloat,stack = %d %d %ld",
182
		 EXP_NUM(e), freefixed, freefloat, stack);
183
 
184
    assert(freefixed >= 0);
185
    assert(freefloat >= 0);
186
 
187
    if (props(e) & defer_bit)
188
    {
189
      /* the tag declared is transparent to code production */
190
      def = zerospace;
191
    }
192
    else
193
    if (
194
	  !isvar(e) && !isparam(e)
195
	  && name(s) == name_tag
196
	  && !isvar(son(s))
197
	  && !isvis(son(s))
198
	  && !isparam(son(s))
199
	  && (props(son(s)) & inreg_bits)
200
       )
201
    {
202
      /*
203
       * dont take space for this constant dec,
204
       * initialiser is another simple constant ident
205
       * (eg from double nested loop optimisation)
206
       */
207
      props(e) |= defer_bit;
208
      def = zerospace;
209
    }
210
    else
211
    {
212
      a = ashof(sh(s));
213
 
214
      if (name(s) == compound_tag || name(s) == nof_tag || name(s) == concatnof_tag )
215
      {
216
	/*
217
	 * elements of tuples are done separately so evaluate above dec
218
	 * using stack space
219
	 * stack - bit address for current allocation
220
	 * st - bit address for next allocation
221
	 */
222
 
223
	assert((stack&31)==0);	/* we expect stack to be word aligned */
224
 
225
	st = ALIGNNEXT(stack, a.ashalign);
226
	st = ALIGNNEXT(st+a.ashsize, 32);	/* maintain word alignment */
227
 
228
	assert(st-stack>=a.ashsize);
229
	assert((st&31)==0);
230
 
231
	def = regalloc (s, freefixed, freefloat, st);
232
      }
233
      else
234
      {
235
	def = regalloc(s, freefixed, freefloat, stack);
236
      }
237
 
238
      FULLCOMMENT4("regalloc ident_tag:	props=%#x,fixregable=%d,no(e)=%d,ffix=%d",
239
		   props(e), fixregable(e), no(e), ffix);
240
 
241
 
242
      if ((props(e) & inreg_bits) == 0 && fixregable(e) && no(e) < ffix)
243
      {
244
	/* suitable for s reg, no(e) has been set up by weights */
245
	props(e) |= inreg_bits;
246
	no(e) = SREG_TO_REALREG(ffix);	/* will be an s reg */
247
	ffix -= 1;
248
	def.fixdump |= RMASK(no(e));
249
	FULLCOMMENT1("regalloc suitable for reg no %ld", no(e));
250
	assert(ffix >= 0);
251
	assert(IS_SREG(no(e)));
252
	assert(a.ashsize <= 32);
253
      }
254
      else if ((props(e) & infreg_bits) == 0 && floatregable(e) && no(e) < ffloat)
255
      {
256
	/* suitable for float s reg , no(e) has been set up by weights */
257
	fail("regalloc: no float point s regs acknowledged");
258
      }
259
      else if ((props(e) & inanyreg) == 0)
260
      {
261
 
262
	/*
263
	 * not suitable for reg allocation
264
	 */
265
	if (name(son(e)) == val_tag && !isvar(e) && !isenvoff(e))
266
	{
267
 
268
	  /*
269
	   * must have been forced by const optimisation - replace uses by the
270
	   * value
271
	   */
272
	  exp t = pt(e);
273
 
274
	  for (; t != nilexp;)
275
	  {
276
	    exp p = pt(t);
277
 
278
	    setname(t, val_tag);
279
	    son(t) = nilexp;
280
	    no(t) = no(son(e));
281
	    props(t) = 0;
282
	    pt(t) = nilexp;
283
	    t = p;
284
	  }
285
	  pt(e) = nilexp;
286
 
287
	  FULLCOMMENT("regalloc heavily used const: no spare regs - replace use by value");
288
	  props(e) |= defer_bit;
289
	  def = zerospace;
290
	}
291
	else if (name(son(e)) == name_tag && !isvar(e) && !isenvoff(e))
292
	{
293
	  /* must have been forced  - defer it */
294
	  FULLCOMMENT("regalloc heavily used address: no spare regs - replace use by value");
295
	  props(e) |= defer_bit;
296
	  def = zerospace;
297
	}
298
	else if (isparam(e))
299
	{
300
	  /* don't know framesize yet; displacement in no(son(e)) */
301
	  no(e) = 0;		/* set correctly in make_code ident_tag */
302
	}
303
	else
304
	{
305
 
306
	  /*
307
	   * allocate on stack stack - bit address for current allocation st -
308
	   * bit address for next allocation
309
	   */
310
 
311
	  assert((stack & 31) == 0);	/* we expect stack to be word aligned */
312
 
313
	  stack = ALIGNNEXT(stack, a.ashalign);
314
	  st = ALIGNNEXT(stack + a.ashsize, 32);	/* maintain word
315
							 * alignment */
316
 
317
	  assert(st - stack >= a.ashsize);
318
	  assert((stack & 31) == 0);
319
 
320
	  def.stack = MAX_OF(def.stack, st);
321
	  no(e) = stack * 2 + GR17;
322
	  FULLCOMMENT3("regalloc allocate on stack:	stack,st=%ld,%ld	no(e)=%ld", stack, st, no(e));
323
	}
324
      }
325
      else if (no(e) == R_USE_RES_REG)
326
      {
327
 
328
	/*
329
	 * optimisation: use result reg for ident_tag to avoid reg move
330
	 */
331
	assert (!isenvoff(e));
332
	FULLCOMMENT2("regalloc no(e)==R_USE_RES_REG:	no(e)=%ld, inreg_bits=%d", no(e), (props(e) & inreg_bits) != 0);
333
	no(e) = ((props(e) & inreg_bits) != 0) ? RET0 : R_DEFER_FR4;
334
	/* set up result of proc as declared id ( R_DEFER_FR4 = %fr4 later) */
335
      }
336
      else
337
      {
338
	/* allocation of stack like regs in make_code */
339
	assert (!isenvoff(e));
340
	FULLCOMMENT1("regalloc no(e)==%d: allocation of stack like regs in make_code", no(e));
341
      }
342
    }
343
    body = regalloc(bro(s), ffix, ffloat, st);
344
    FULLCOMMENT3("regalloc return:	ffix,ffloat,st = %d %d %ld", ffix, ffloat, st);
345
    return maxspace(body, def);
346
  }
347
  else if (n == case_tag)
348
  {
349
    /* recurse on all expressions in tree */
350
    return regalloc(s, freefixed, freefloat, stack);
351
  }
352
  else
353
  if (n != name_tag && n != env_offset_tag && n!=general_env_offset_tag                            && s != nilexp)
354
  {
355
    /* recurse on all expressions in tree */
356
    def = regalloc(s, freefixed, freefloat, stack);
357
    while (!last(s))
358
    {
359
      s = bro(s);
360
      def = maxspace(def, regalloc(s, freefixed, freefloat, stack));
361
    }
362
    return def;
363
  }
364
  else
365
  {
366
    def = zerospace;
367
    def.stack = stack;
368
    return def;
369
  }
370
}
371
 
372
 
373
 
374
 
375
 
376