Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5/src/installers/power/common/stack.c – Rev 2

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | 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:49:09 $
61
$Revision: 1.2 $
62
$Log: stack.c,v $
63
 * Revision 1.2  1998/02/04  15:49:09  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:58  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1996/10/04  16:04:27  pwe
70
 * add banners and mod for PWE ownership
71
 *
72
**********************************************************************/
73
 
74
 
75
#include "config.h"
76
#include "memtdf.h"
77
#include "codegen.h"
78
#include "geninst.h"
79
#include "translat.h"
80
#include "makecode.h"
81
#include "machine.h"
82
#include "flags.h"
83
#include "myassert.h"
84
#include "comment.h"
85
#include "proc.h"
86
#include "stack.h"
87
/* All measurements in bytes */
88
long p_frame_size=0;		/* total size of frame */  
89
long p_locals_offset=0;	/* where the locals live  */
90
long p_maxargbytes=0;	/* the largest size of the param area */
91
long p_args_and_link_size=0;	/* used by alloca */
92
bool p_has_fp=0;
93
 
94
bool p_leaf=0;
95
bool p_has_back_chain=0;
96
bool p_save_all_sregs=0;
97
bool p_has_alloca=0;
98
bool p_has_vcallees=0;
99
bool p_has_no_vcallers=0;
100
 
101
long p_fixed_params=0;
102
long p_float_params=0;
103
long p_sreg_first_save=0;
104
long p_sfreg_first_save=0;
105
 
106
bool p_has_saved_sp=0;
107
long p_saved_sp_offset=0;
108
int p_return_label=0; /* the number of the label which contains the return */
109
ans p_result;
110
long p_callee_size;
111
 
112
bool p_has_tp;
113
 
114
exp p_current;
115
long p_no_of_returns =0;
116
 
117
/*
118
 * The function of this file is to keep a lot of the stack controlling 
119
 * functions in the same place, so that they can be easily and consistently
120
 * maintained. I have introduced several new variables to make things easier
121
 * to follow.
122
 *
123
	|              |
124
	|              |
125
------->|--------------|<======R_FP                v
126
	|   Saved      |                           |
127
	|    FPR       |                           |
128
	|              |                           |
129
	|--------------|                           |
130
	|   Saved      |                           |< p_frame_size(bytes)
131
	|    GPR       |                           |
132
	|              |                           |
133
	|--------------|                           |
134
	| Possible word|for 8 byte alignment       |
135
	|--------------|                           |
136
	|              |                           |
137
	|--------------|                           |
138
	|  Saved SP    |<-- If have saved_sp       |
139
	|--------------|  this is where it lives   |
140
	|              |                           | 
141
	|              |                           | 
142
	|              |                           | 
143
	|              |                           |
144
    >56 |--------------|         v                 | 
145
	|    Pn        |         |                 |                 
146
	|     .        |         |                 |       
147
	|     .        |         |                 |                 
148
	|     .        |         |                 |  
149
	|     .        |         |                 |     
150
	|    P1        |         |< PROC_ARGS_AND_ |                 
151
      24|--------------|         |     LINK_SIZE   |                 
152
	|   Saved TOC  |         |     (bytes)     |                 
153
      20|--------------|         |                 |                 
154
	|   Reserved2  |         |                 |                 
155
      16|--------------|         |                 |                 
156
	|   Reserved1  |         |                 |                 
157
      12|--------------|         |                 |                 
158
	|   Saved LR   |         |                 |                 
159
       8|--------------|         |                 |                 
160
	|   Saved CR   |         |                 |                 
161
       4|--------------|         |                 |                 
162
	|  Back Chain  |         |                 |                 
163
-----> 0|--------------|<=====R_SP                 ^
164
          STACK_TEMP
165
*/
166
void initialise_procedure PROTO_N ((pr)) PROTO_T ( procrec *pr )
167
{
168
  p_sreg_first_save= pr->sreg_first_save;
169
  p_sfreg_first_save = pr->sfreg_first_save;
170
  p_has_alloca = pr->alloca_proc;
171
  p_save_all_sregs = pr->save_all_sregs;
172
  p_frame_size = pr->frame_size>>3; /* in bytes */
173
  p_locals_offset = pr->locals_offset>>3; /* in bytes */
174
  p_maxargbytes = pr->maxargs>>3; /* in bytes */
175
  p_has_fp = pr->has_fp;
176
  p_has_tp = pr->has_tp;
177
  p_has_saved_sp = pr->has_saved_sp;
178
  p_leaf = pr->leaf_proc;
179
  p_callee_size = pr->callee_size>>3;
180
  p_has_vcallees = pr->has_vcallees;
181
  p_has_no_vcallers = pr->has_no_vcallers;
182
  p_no_of_returns = pr->no_of_returns;
183
 
184
  p_fixed_params = 0;		/* Updated in make_ident_tag_code */
185
  p_float_params = 0;		/* Updated in make_ident_tag_code */
186
  p_has_back_chain = p_leaf ? 0 : diagnose;
187
  p_args_and_link_size = p_leaf ? 0 : STACK_LINK_AREA_SIZE + p_maxargbytes;
188
  ASSERT(pr->frame_size>=0 && (pr->frame_size&63) == 0);
189
  ASSERT(pr->frame_size>=pr->maxargs);
190
  return;
191
}
192
 
193
 
194
void generate_procedure_prologue PROTO_Z ()
195
{
196
  int r;
197
  baseoff stackpos;
198
 
199
  stackpos.base = R_SP;
200
  stackpos.offset = 0;
201
 
202
  /* Get LR for non leaf */
203
  if( !p_leaf)
204
  {
205
    mf_ins(i_mflr,R_0);
206
  }
207
  /* 
208
   * Save floating point s-regs
209
   */
210
  if(p_sfreg_first_save != FR_NO_REG)
211
  {
212
    for(r = p_sfreg_first_save; r <= FR_LAST; r++)
213
    {
214
      if (IS_FLT_SREG(r))
215
      {
216
	stackpos.offset -= 8;
217
	stf_ro_ins(i_stfd, r, stackpos);
218
      }
219
    }
220
    ASSERT(stackpos.offset >= -STACK_FLOAT_REG_DUMP_AREA_SIZE);
221
  }
222
  /*
223
   * Save fixed point s-regs
224
   */
225
  if (p_sreg_first_save != R_NO_REG)
226
  {
227
    if (p_sreg_first_save < R_28)
228
    {
229
      /* Use the stm instruction */
230
      stackpos.offset -= 4*(R_31+1-p_sreg_first_save);
231
      st_ro_ins(i_stm, p_sreg_first_save, stackpos);comment("save fixed point s-regs");
232
    }
233
    else
234
    { 
235
      /* Less than or 4 stores so do individually */
236
      for (r=R_31;r>=p_sreg_first_save;r--)
237
      { 
238
	stackpos.offset -= 4;
239
	st_ro_ins(i_st,r,stackpos);comment("save fixed point s-reg");
240
      }
241
    }
242
    ASSERT(stackpos.offset >= -STACK_REG_DUMP_AREA_SIZE);
243
  }
244
  /* Align to next 8 byte boundary */
245
  stackpos.offset= -ALIGNNEXT(-stackpos.offset,8);
246
  /*
247
   * Make room for saved sp if we have one
248
   */
249
  if ( p_has_saved_sp )
250
  {
251
    stackpos.offset -= 8;
252
    p_saved_sp_offset = stackpos.offset;
253
  }
254
  /* 
255
   * Initialise the top pointer if needed 
256
   */
257
  if( p_has_tp )
258
  {
259
    baseoff a;
260
 
261
    /* This is where the backward pointing chain is held */
262
    a.base = R_SP;
263
    a.offset = 0;
264
    ld_ro_ins(i_l,a,R_TP);comment("set up TP");
265
  }
266
 
267
  /* 
268
   * Initialize the frame pointer if needed
269
   */
270
  if ( p_has_fp )
271
  {
272
    mov_rr_ins( R_SP, R_FP );comment("set up FP");
273
  }
274
 
275
 
276
  /*
277
   * Save the Link Register
278
   */
279
  if ( ! p_leaf )
280
  {
281
    if ( p_has_tp)
282
    {
283
      stackpos.base = R_TP;
284
    }
285
    else
286
    {
287
      stackpos.base = R_SP;
288
    }
289
 
290
    stackpos.offset = STACK_SAVED_LR;
291
    st_ro_ins(i_st, R_0, stackpos);comment("save LR");
292
  }
293
 
294
  /* 
295
   * Decrease the stack pointer
296
   */
297
 
298
  stackpos.base = R_SP;
299
 
300
  if( p_has_back_chain )
301
  {
302
    stackpos.offset = - p_frame_size;
303
    st_ro_ins( i_stu , R_SP , stackpos );comment("pull stack down with back chain");
304
  }
305
  else
306
  {
307
    if (p_frame_size !=0)
308
    {
309
      rir_ins(i_a, R_SP, -p_frame_size ,R_SP);
310
    }
311
  }
312
  /* Save sp on stack if necessary */
313
  if( p_has_saved_sp )
314
  {
315
    save_sp_on_stack();
316
  }
317
 
318
  return;
319
}
320
 
321
 
322
void generate_procedure_epilogue PROTO_Z ()
323
{
324
  baseoff saved_lr;
325
 
326
  if ( p_frame_size !=0 )
327
  {
328
    if ( p_has_fp )
329
    {
330
      /* Use frame pointer to collapse stack frame */
331
      mov_rr_ins( R_FP, R_SP );comment("collapse frame using FP");
332
    }
333
    else if ( p_has_back_chain )
334
    {
335
	/* Use back chain to collapse stack frame */
336
      baseoff back_chain;
337
      back_chain.base=R_SP;
338
      back_chain.offset=0;
339
      ld_ro_ins(i_l, back_chain, R_SP);comment("collapse stack frame");
340
    }
341
    else
342
    {
343
      /* Use frame size to collapse stack frame */
344
      rir_ins(i_a, R_SP, p_frame_size , R_SP );
345
    }
346
  }
347
  /* At this point the stack pointer is collapsed to where the s-regs 
348
     are stored */
349
  if(p_has_tp)
350
  {
351
    mov_rr_ins(R_TP,R_TEMP_TP);comment("copy TP to TEMP_TP");
352
    restore_sregs(R_SP,0);
353
    mov_rr_ins(R_TEMP_TP,R_SP);comment("collapse frame using TEMP_TP");
354
  }
355
  else
356
  {
357
    restore_sregs(R_SP,0);
358
  }
359
  /* At this point the stack pointer is in its return position */
360
  if (!p_leaf)
361
  {
362
    saved_lr.base = R_SP;
363
    saved_lr.offset = STACK_SAVED_LR;
364
    ld_ro_ins(i_l, saved_lr , R_TMP0);comment("restore LR");
365
    mt_ins(i_mtlr, R_TMP0);
366
  }	
367
  z_ins(i_br);
368
  return;
369
}
370
void generate_untidy_procedure_epilogue PROTO_Z ()
371
{
372
  baseoff saved_lr;
373
 
374
  /* The stack pointer is not collapsed at all */
375
  if (p_has_tp && !p_leaf)/*We need R_TP later for the link */
376
  {
377
    mov_rr_ins(R_TP,R_TEMP_TP);comment("copy TP to TEMP_TP");
378
  }
379
  /* load up R_TEMP_FP with the value of where the s-regs are stored */
380
  if(p_has_fp)
381
  {
382
    mov_rr_ins(R_FP,R_TEMP_FP);comment("copy FP ro TEMP_FP");
383
    restore_sregs(R_TEMP_FP,0);
384
  }
385
  else if (p_has_back_chain)
386
  {
387
    baseoff back_chain;
388
    back_chain.base = R_SP;
389
    back_chain.offset = 0;
390
    ld_ro_ins(i_l,back_chain,R_TEMP_FP);comment(NIL);
391
    restore_sregs(R_TEMP_FP,0);
392
  }
393
  else
394
  {
395
    restore_sregs(R_SP,p_frame_size);
396
  }
397
  /* s-regs are restored */
398
  if (!p_leaf)
399
  {
400
    if(p_has_tp)
401
    {
402
      saved_lr.base = R_TEMP_TP;
403
      saved_lr.offset = STACK_SAVED_LR;
404
    }
405
    else if(p_has_fp)
406
    {
407
      saved_lr.base = R_TEMP_FP;
408
      saved_lr.base = STACK_SAVED_LR;
409
    }
410
    else
411
    {
412
      saved_lr.base = R_SP;
413
      saved_lr.offset = STACK_SAVED_LR + p_frame_size;
414
    }
415
    ld_ro_ins(i_l,saved_lr,R_TMP0);comment("restore LR");
416
    mt_ins(i_mtlr,R_TMP0);
417
  }
418
  z_ins(i_br);
419
  return;
420
}
421
 
422
 
423
 
424
void save_sp_on_stack PROTO_Z ()
425
{
426
  baseoff saved_sp;
427
 
428
  /* Saves the value of the stack pointer on stack */
429
  ASSERT(p_has_saved_sp);
430
  ASSERT(p_has_fp);
431
  saved_sp.base = R_FP;
432
  saved_sp.offset = p_saved_sp_offset;
433
  st_ro_ins(i_st,R_SP,saved_sp);comment("save sp on stack");
434
  return;
435
}
436
void get_sp_from_stack PROTO_Z ()
437
{
438
  baseoff saved_sp;
439
 
440
  /* Restores the stack pointer from the stack */
441
  ASSERT(p_has_saved_sp);
442
  ASSERT(p_has_fp);
443
  saved_sp.base = R_FP;
444
  saved_sp.offset = p_saved_sp_offset;
445
  ld_ro_ins(i_l,saved_sp,R_SP);comment("get SP of stack");
446
  return;
447
}
448
void save_back_chain_using_frame_pointer PROTO_Z ()
449
{
450
  /* saves back chain using frame pointer */
451
  baseoff back_chain;
452
  back_chain.base = R_SP;
453
  back_chain.offset = 0;
454
  ASSERT(p_has_fp);
455
  st_ro_ins(i_st,R_FP,back_chain);comment("save back chain");
456
  return;
457
}
458
 
459
void restore_sregs PROTO_N ((start_base,start_offset)) PROTO_T (int start_base X int start_offset)
460
{
461
  baseoff stackpos;
462
  int r;
463
 
464
  ASSERT(IS_TREG(start_base) || start_base == R_SP);
465
  ASSERT(start_base!=R_TMP0);
466
  stackpos.base = start_base;
467
  stackpos.offset = start_offset;
468
  COMMENT2("restore s-regs using %d offset %d bytes",start_base,start_offset);
469
 
470
 
471
  if (p_sfreg_first_save != FR_NO_REG)
472
  {
473
    for (r = p_sfreg_first_save; r <= FR_LAST; r++)
474
    {
475
      if (IS_FLT_SREG(r))
476
      {
477
	stackpos.offset -= 8;
478
	ldf_ro_ins(i_lfd, stackpos, r);
479
      }
480
    }
481
  }
482
 
483
  /* 
484
   * Restore fixed point s-regs 
485
   */
486
  if (p_sreg_first_save != R_NO_REG)
487
  {
488
    if (p_sreg_first_save < R_28)
489
    {
490
      /* Use lm instruction */
491
      stackpos.offset -= 4*(R_31+1-p_sreg_first_save);
492
      ld_ro_ins(i_lm, stackpos, p_sreg_first_save);comment("restore fixed s-regs");
493
    }
494
    else
495
    {
496
      /* Less than or 4 loads so do individually */ 
497
      for (r=R_31;r>=p_sreg_first_save;r--)
498
      {
499
	stackpos.offset -=4;
500
	ld_ro_ins(i_l,stackpos,r);comment("restore fixed s-reg");
501
      }
502
    }
503
  }
504
  return;
505
}
506
void restore_link_register PROTO_Z ()
507
{
508
  /* this function is only used by tail_call */
509
  baseoff saved_lr;
510
  COMMENT("restore link register");
511
  if (!p_leaf)
512
  {
513
    if (p_has_tp)
514
    {
515
      saved_lr.base = R_TP;
516
      saved_lr.offset = STACK_SAVED_LR;
517
    }
518
    else if(p_has_fp)
519
    {
520
      saved_lr.base = R_FP;
521
      saved_lr.offset = STACK_SAVED_LR;
522
    }
523
    else 
524
    {
525
      fail("Shouldn't be calling this function without R_TP or R_FP");
526
    }
527
    ld_ro_ins(i_l,saved_lr,R_TMP0);comment("restore LR");
528
    mt_ins(i_mtlr,R_TMP0);
529
  }
530
}
531