Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    Copyright (c) 1993 Open Software Foundation, Inc.
3
 
4
 
5
    All Rights Reserved
6
 
7
 
8
    Permission to use, copy, modify, and distribute this software
9
    and its documentation for any purpose and without fee is hereby
10
    granted, provided that the above copyright notice appears in all
11
    copies and that both the copyright notice and this permission
12
    notice appear in supporting documentation.
13
 
14
 
15
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
16
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17
    PARTICULAR PURPOSE.
18
 
19
 
20
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
21
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
23
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
*/
26
 
27
/*
28
    		 Crown Copyright (c) 1997
29
 
30
    This TenDRA(r) Computer Program is subject to Copyright
31
    owned by the United Kingdom Secretary of State for Defence
32
    acting through the Defence Evaluation and Research Agency
33
    (DERA).  It is made available to Recipients with a
34
    royalty-free licence for its use, reproduction, transfer
35
    to other parties and amendment for any purpose not excluding
36
    product development provided that any such use et cetera
37
    shall be deemed to be acceptance of the following conditions:-
38
 
39
        (1) Its Recipients shall ensure that this Notice is
40
        reproduced upon any copies or amended versions of it;
41
 
42
        (2) Any amended version of it shall be clearly marked to
43
        show both the nature of and the organisation responsible
44
        for the relevant amendment or amendments;
45
 
46
        (3) Its onward transfer from a recipient to another
47
        party shall be deemed to be that party's acceptance of
48
        these conditions;
49
 
50
        (4) DERA gives no warranty or assurance as to its
51
        quality or suitability for any purpose and DERA accepts
52
        no liability whatsoever in relation to any use to which
53
        it may be put.
54
*/
55
 
56
 
57
 
58
/**********************************************************************
59
$Author: release $
60
$Date: 1998/02/04 15:48:46 $
61
$Revision: 1.2 $
62
$Log: frames.c,v $
63
 * Revision 1.2  1998/02/04  15:48:46  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:56  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.3  1996/10/14  17:31:47  pwe
70
 * include called callees in env_size
71
 *
72
 * Revision 1.2  1996/10/04  16:00:52  pwe
73
 * add banners and mod for PWE ownership
74
 *
75
**********************************************************************/
76
 
77
 
78
#include "config.h"
79
#include "memtdf.h"
80
#include "codegen.h"
81
#include "installglob.h"
82
#include "basicread.h"
83
#include "main_reads.h"
84
#include "optimise.h"
85
#include "exp.h"
86
#include "flpt.h"	
87
#include "externs.h"	    
88
#include "myassert.h"
89
#include "tempdecs.h"
90
#include "weights.h"
91
#include "procrecs.h"
92
#include "regalloc.h"
93
#include "makecode.h"
94
#include "eval.h"
95
#include "flags.h"
96
#include "needscan.h"
97
#include "machine.h"
98
#include "diagout.h"
99
#include "xalloc.h"
100
#include "comment.h"
101
#include "translat.h"
102
#include "readglob.h"
103
#include "stack.h"
104
#include "frames.h"
105
long frame_offset PROTO_N ((id)) PROTO_T (exp id)
106
{
107
  exp init_exp = son(id);
108
  exp p;
109
  procrec *pr;
110
  long n = no (id);
111
  long off = n>>6;
112
 
113
  ASSERT(name(id) == ident_tag);
114
  for (p = father(id); !IS_A_PROC(p); p = father(p));
115
 
116
  pr = & procrecs[no(p)];
117
 
118
 
119
  if (isparam(id))
120
  {
121
    if( name(init_exp)==formal_callee_tag)
122
    {
123
      /* Callee parameter accessed through R_FP */
124
      return (no(init_exp)>>3) + EXTRA_CALLEE_BYTES;
125
    }
126
    else
127
    {
128
      /* Caller parameter accessed through R_TP */
129
      return (no(init_exp)>>3) + STACK_ARG_AREA;
130
    }
131
  }
132
  else if (name(init_exp)==caller_name_tag)
133
  {
134
    fail("Taking env_offset of an identified caller within a postlude");
135
    return 0;
136
  }
137
  else
138
  {
139
    /* Local */
140
    return ( off + (pr->locals_offset>>3) - (pr->frame_size>>3) );
141
  }
142
}
143
 
144
 
145
void set_up_frame_pointer PROTO_N ((pr,e)) PROTO_T (procrec * pr X exp e )
146
{
147
  long pprops = pr->needsproc.propsneeds;
148
  /* Initialize a few of the fields */
149
  pr->alloca_proc = proc_has_alloca(e);
150
  pr->leaf_proc = ( ( pprops & anyproccall ) == 0);
151
  pr->has_fp = 0;
152
  pr->has_saved_sp = 0;
153
  pr->save_all_sregs = 0;
154
  pr->has_vcallees = 0;
155
  pr->has_no_vcallers = 0;
156
  pr->has_tp = 0;
157
 
158
  /* 
159
   * This choosing of what is needed within the proc is very important
160
   * For a procedure which is not a leaf proc and has had someone loading
161
   * the value of a label, and someone has grabbed the current_env
162
   * It means, that they could potentially long jump into this proc.
163
   * In this case we must save all the s-regs, and also we must insist
164
   * on a frame pointer.
165
   * The reason for this, is that there is no way of telling when coding
166
   * up the long jump whether the proc it is long jumping into has a
167
   * frame pointer or not.
168
   * So to make a convention we say that it must have a frame pointer,
169
   * since this is the only way we can code up the long jump.(by loading fp )
170
   *
171
   * In the event of us having a procedure which could be long jumped
172
   * back to, and the proc has calls to alloca, then the stack pointer can
173
   * not be restored from the frame pointer, by simply subtracting the 
174
   * p_frame_size, so it is necessary to save the last value of the stack pointer
175
   * at a designated place on the stack relative to the frame pointer.
176
   */
177
  if( !(pr->leaf_proc) && proc_has_lv(e) && proc_uses_crt_env(e) )
178
  {
179
    /* This means someone could call long jump back to this proc */
180
    pr->save_all_sregs = 1;
181
    pr->has_fp = 1;
182
  }
183
  if ( pr->alloca_proc )
184
  {
185
    /* alloca procedures require a frame pointer */
186
    pr->has_fp = 1;
187
  }
188
  if ( pr->alloca_proc && pr->save_all_sregs )
189
  {
190
    /* alloca proc which could be long jumped to */
191
    pr->has_saved_sp = 1;
192
  }
193
 
194
  if (name(e)==general_proc_tag)
195
  {
196
    /* All general_proc_tag's have a frame pointer */
197
    pr->has_tp = 1;/* +++ is this only really needed for vcallees */
198
    pr->has_fp = 1;
199
    pr->has_vcallees = proc_has_vcallees(e);
200
    pr->has_no_vcallers = !proc_has_vcallers(e);
201
    /* If has_no_vcallers==1 => Not a varargs
202
       however has_no_vcallers==0 does not imply varargs it tells us nothing*/
203
  }
204
  if (gen_call!=0)
205
  {
206
    /* It could be a normal proc with a tail call */
207
    pr->has_fp = 1;
208
  }
209
  pr->no_of_returns = no_of_returns;  
210
  pr->callee_size = callee_size;
211
  if (max_callees < 0)
212
    pr->max_callee_bytes = 0;
213
  else
214
    pr->max_callee_bytes = ALIGNNEXT ((max_callees >> 3) + EXTRA_CALLEE_BYTES, 8);
215
  return;
216
}
217
 
218
void set_up_frame_info PROTO_N ((pr,e)) PROTO_T (procrec * pr X exp e )
219
{
220
  int r;
221
  long maxargs;
222
 
223
  /*
224
   * Initialize more fields
225
   */
226
  maxargs = pr->needsproc.maxargs;
227
  pr->locals_space = pr->spacereqproc.stack;      
228
  if (do_profile)
229
  {
230
    pr->leaf_proc = 0;
231
  }
232
  if (pr->leaf_proc)
233
  {
234
    COMMENT("leaf_proc");
235
    ASSERT(maxargs==0);
236
  }
237
  else
238
  {
239
    ASSERT(maxargs >=0);
240
 
241
    if (maxargs < STACK_MIN_MAXARGS*8)
242
    {
243
      maxargs = STACK_MIN_MAXARGS*8;	/* at least reg param dump for calls */
244
    }
245
  }
246
 
247
  /* put on 64 bit boundaries */
248
  maxargs = ALIGNNEXT(maxargs, 64);
249
  pr->locals_space = ALIGNNEXT(pr->locals_space, 64);
250
 
251
 
252
  /* find lowest s-reg used for i_stm and i_lm */
253
  pr->sreg_first_save = R_NO_REG;
254
  for (r = R_FIRST; r <= R_LAST; r++)
255
  {
256
    if ((pr->spacereqproc.fixdump & RMASK(r)) != 0)
257
    {
258
      pr->sreg_first_save = r;
259
      break;
260
    }
261
  }
262
 
263
 
264
  COMMENT2("gpr use mask = %#x, lowest = %d", pr->spacereqproc.fixdump, pr->sreg_first_save);
265
  ASSERT(pr->sreg_first_save==R_NO_REG || IS_SREG(pr->sreg_first_save));
266
 
267
 
268
 
269
  /* find lowest float s-reg used */
270
  pr->sfreg_first_save = FR_NO_REG;
271
 
272
  for (r = FR_FIRST; r <= FR_LAST; r++)
273
  {
274
    if ((pr->spacereqproc.fltdump & RMASK(r)) != 0)
275
    {
276
      pr->sfreg_first_save = r;
277
      break;
278
    }
279
  }
280
 
281
 
282
  COMMENT2("fpr use mask = %#x, lowest = %d", pr->spacereqproc.fltdump, pr->sfreg_first_save);
283
  ASSERT(pr->sfreg_first_save==FR_NO_REG || IS_FLT_SREG(pr->sfreg_first_save));
284
  if (pr->leaf_proc)
285
  {
286
    pr->locals_offset = 0;
287
  }
288
  else
289
  {
290
    pr->locals_offset = STACK_LINK_AREA_SIZE*8 + maxargs;
291
  }
292
  pr->frame_size= pr->locals_offset + pr->locals_space;
293
  /* GRAB TWO WORDS FOR THE SAVED SP */
294
  if (pr->has_saved_sp)
295
  {
296
    pr->frame_size += 64;
297
    /* Two extra words */
298
  }
299
 
300
  /* grab space for fixed s-reg dump area */
301
  if (pr->sreg_first_save != R_NO_REG)
302
  {
303
    pr->frame_size += ALIGNNEXT((R_LAST-pr->sreg_first_save+1)*32, 64);
304
  }
305
 
306
  /* grab space for float s-reg dump area */
307
  if (pr->sfreg_first_save != FR_NO_REG)
308
  {
309
    pr->frame_size += (FR_LAST-pr->sfreg_first_save+1)*64;
310
  }
311
  pr->params_offset = pr->frame_size + STACK_ARG_AREA*8;
312
  pr->maxargs=maxargs;
313
 
314
 
315
  return;
316
}