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
 
33
/*
34
			    VERSION INFORMATION
35
			    ===================
36
 
37
--------------------------------------------------------------------------
38
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/translat.c,v 1.2 1998/03/11 11:04:00 pwe Exp $
39
--------------------------------------------------------------------------
40
$Log: translat.c,v $
41
 * Revision 1.2  1998/03/11  11:04:00  pwe
42
 * DWARF optimisation info
43
 *
44
 * Revision 1.1.1.1  1998/01/17  15:55:55  release
45
 * First version to be checked into rolling release.
46
 *
47
 * Revision 1.27  1997/12/04  19:54:30  pwe
48
 * ANDF-DE V1.9
49
 *
50
 * Revision 1.26  1997/10/10  18:33:10  pwe
51
 * prep ANDF-DE revision
52
 *
53
 * Revision 1.25  1997/08/23  13:54:43  pwe
54
 * initial ANDF-DE
55
 *
56
 * Revision 1.24  1997/04/17  12:00:03  pwe
57
 * dwarf2 support
58
 *
59
 * Revision 1.23  1997/04/04  15:23:15  pwe
60
 * tidy re old DWARF interface
61
 *
62
 * Revision 1.22  1997/03/26  13:04:55  pwe
63
 * general proc compatibility
64
 *
65
 * Revision 1.21  1997/03/24  17:09:40  pwe
66
 * reorganise solaris/sunos split
67
 *
68
 * Revision 1.20  1997/02/18  11:48:36  pwe
69
 * NEWDIAGS for debugging optimised code
70
 *
71
 * Revision 1.19  1996/09/18  12:04:04  pwe
72
 * fixed PIC_code
73
 *
74
 * Revision 1.18  1996/08/27  14:09:18  pwe
75
 * ensure all varargs are stored, and ptr is not64bit
76
 *
77
 * Revision 1.17  1996/08/15  15:34:57  pwe
78
 * mod for PWE ownership
79
 *
80
 * Revision 1.16  1995/12/15  11:14:57  john
81
 * Change for dynamic initialisations on SunOS
82
 *
83
 * Revision 1.15  1995/11/14  14:25:05  john
84
 * Fix to dynamic initialisations
85
 *
86
 * Revision 1.14  1995/11/07  09:53:53  john
87
 * Change to register allocation for general procs
88
 *
89
 * Revision 1.13  1995/10/25  17:13:50  john
90
 * Fixed error in init segment
91
 *
92
 * Revision 1.12  1995/10/06  10:22:09  john
93
 * Changed optimisation level for general procs (SunOS only).
94
 *
95
 * Revision 1.11  1995/10/04  09:01:22  john
96
 * Added dynamic initialisation on Solaris
97
 *
98
 * Revision 1.10  1995/09/22  13:07:48  john
99
 * Change for new exception handling
100
 *
101
 * Revision 1.9  1995/09/13  11:01:44  john
102
 * compilation fixes
103
 *
104
 * Revision 1.8  1995/08/04  15:47:14  john
105
 * Minor change
106
 *
107
 * Revision 1.7  1995/07/17  16:46:16  john
108
 * Fixed error on SunOS
109
 *
110
 * Revision 1.6  1995/07/14  16:34:26  john
111
 * Changes for new spec
112
 *
113
 * Revision 1.5  1995/06/30  08:29:50  john
114
 * Changed size of callee area
115
 *
116
 * Revision 1.4  1995/06/14  15:36:38  john
117
 * Added support for trap error treatment & stack limits.  Also, some
118
 * reformatting.
119
 *
120
 * Revision 1.3  1995/05/26  13:02:20  john
121
 * Change for new spec
122
 *
123
 * Revision 1.2  1995/04/20  08:07:08  john
124
 * Moved source stabs record before initial text section
125
 *
126
 * Revision 1.1.1.1  1995/03/13  10:19:00  john
127
 * Entered into CVS
128
 *
129
 * Revision 1.4  1994/07/07  16:11:33  djch
130
 * Jul94 tape
131
 *
132
 * Revision 1.3  1994/07/04  08:31:36  djch
133
 * changes for new versioning info.
134
 *
135
 * Revision 1.2  1994/05/03  15:12:43  djch
136
 * removed extract.h and the inner procs stuff, now done in the common section
137
 *
138
 * Revision 1.11  94/02/21  16:13:59  16:13:59  ra (Robert Andrews)
139
 * Correct unit weight in weightsv.
140
 * 
141
 * Revision 1.10  93/09/27  14:57:41  14:57:41  ra (Robert Andrews)
142
 * Added support for weak linking.  Added support for DWARF diagnostic
143
 * routines.
144
 * 
145
 * Revision 1.9  93/08/27  11:40:10  11:40:10  ra (Robert Andrews)
146
 * A couple of lint-like changes.
147
 * 
148
 * Revision 1.8  93/08/18  11:17:49  11:17:49  ra (Robert Andrews)
149
 * Removed stray spaces from outs command.
150
 * 
151
 * Revision 1.7  93/08/13  14:48:20  14:48:20  ra (Robert Andrews)
152
 * Removed a comment.
153
 * 
154
 * Revision 1.6  93/07/12  15:20:32  15:20:32  ra (Robert Andrews)
155
 * The exit_translator routine now outputs any special_routines which
156
 * have been used but are not defined in the system libraries.
157
 * 
158
 * Revision 1.5  93/07/05  18:29:07  18:29:07  ra (Robert Andrews)
159
 * Made distinction between the System V assembler and the System V ABI.
160
 * Added support for PIC by setting avoid_L7 if necessary.
161
 * 
162
 * Revision 1.4  93/06/29  14:49:03  14:49:03  ra (Robert Andrews)
163
 * Messed up version control header.  Revision 1.2 was the important one.
164
 * It involved a minor reorganisation and reformat.  The routines
165
 * init_translator and exit_translator were introduced.
166
 * 
167
 * Revision 1.1  93/06/24  14:59:37  14:59:37  ra (Robert Andrews)
168
 * Initial revision
169
 * 
170
--------------------------------------------------------------------------
171
*/
172
 
173
 
174
#define SPARCTRANS_CODE
175
/*
176
 * Translation is controlled by translate () in this module.
177
 * Code generation follows the following phases :
178
 *
179
 * 1. The TDF is read in, applying bottom-up optimisations.
180
 * 2. Top-down optimisations are performed.
181
 * 3. Register allocation is performed, and TDF idents introduced
182
 * so code generation can be performed with no register spills.
183
 * 4. Code is generated for each procedure, and global declarations processed.
184
 * 5. Currently assembler source is generated directly, and the
185
 * assembler optimiser ( as -O ) used for delay slot filling,
186
 * instruction scheduling and peep-hole optimisation.
187
 *
188
 * In a little more detail :
189
 *
190
 * 1 ) During the TDF reading process for tag declarations and tag
191
 * definitions, applications of tokens are expanded as they are
192
 * encountered, using the token definitions. Every token used must have
193
 * been previously defined in the bitstream.
194
 *
195
 * The reading of the tag definitions creates a data structure in memory
196
 * which directly represents the TDF. At present, all the tag definitions
197
 * are read into memory in this way before any further translation is
198
 * performed. This will shortly be changed, so that translation is
199
 * performed in smaller units. The translator is set up already so that
200
 * the change to translate in units of single global definitions ( or
201
 * groups of these ) can easily be made.
202
 *
203
 * During the creation of the data structure bottom-up optimisations
204
 * are performed. These are the optimisations which can be done when a
205
 * complete sub-tree of TDF is present, and are independent of the context
206
 * in which the sub-tree is used. They are defined in check.c and
207
 * check_id.c. These optimisation do such things as use the commutative
208
 * and associative laws for plus to collect together and evaluate
209
 * constants. More ambitious examples of these bottom-up optimisations
210
 * include all constant evaluation, elimination of inaccessible code, and
211
 * forward propagation of assignments of constants.
212
 *
213
 * 2 ) After reading in the TDF various optimisations are performed which
214
 * cannot be done until the whole context is present. For example,
215
 * constants cannot be extracted from a loop when we just have the loop
216
 * itself, because we cannot tell whether the variables used in it are
217
 * aliased.
218
 *
219
 * These optimisations are invoked by opt_all_exps which is defined in
220
 * indep.c. They include extraction of constants from loops, common
221
 * expression elimination on them and strength reduction for indexing.
222
 *
223
 * 3 ) Allocatable registers are partitioned into two sets, the s regs
224
 * which are preserved over calls, and the t regs which are not.
225
 *
226
 * The TDF is scanned introducing TDF idents so that expressions can be
227
 * evaluated within the available t regs with no spills. These new idents
228
 * may be later allocated to a s reg later, if the weighting algorithm
229
 * ( below ) considers this worth while. Otherwise they will be on the stack.
230
 *
231
 * Information is collected to help in global register allocation. During
232
 * a forward recursive scan of the TDF the number of accesses to each
233
 * variable is computed ( making assumptions about the frequency of
234
 * execution of loops ) . Then on the return scan of this recursion, for
235
 * each declaration, the number of registers which must be free for it to
236
 * be worthwhile to use a register is computed, and put into the TDF as
237
 * the "break" point. The procedures to do this are defined in weights.c.
238
 *
239
 * Suitable idents not alive over a procedure call are allocated to a t reg,
240
 * and others to s regs. At the same time stack space requirements are
241
 * calculated, so this is known before code for a procedure is generated.
242
 *
243
 * 4 ) Finally the code is generated without register spills. The code is
244
 * generated by make_code () in makecode.c, and make_XXX_code () in proc.c.
245
 *
246
 * Note that procedure inlining and loop unrolling optimisations are not
247
 * currently implemented. Library procedures such as memcpy () and
248
 * strcpy () are not treated specially. Integer multiply, divide and
249
 * remainder use the standard support procedures .mul, .div, .rem and
250
 * unsigned variants.
251
 */
252
 
253
#include "config.h"
254
#include "common_types.h"
255
#include "myassert.h"
256
#include "flpt.h"
257
#include "expmacs.h"
258
#include "tags.h"
259
#include "exptypes.h"
260
#include "exp.h"
261
#include "shapemacs.h"
262
#include "tempdecs.h"
263
#include "weights.h"
264
#include "proctypes.h"
265
#include "procrec.h"
266
#include "regalloc.h"
267
#include "codehere.h"
268
#include "makecode.h"
269
#include "eval.h"
270
#include "toktypes.h"
271
#include "flags.h"
272
#include "basicread.h"
273
#include "tags.h"
274
#include "bitsmacs.h"
275
#include "needscan.h"
276
#include "getregs.h"
277
#include "regmacs.h"
278
#include "labels.h"
279
#include "xalloc.h"
280
#include "comment.h"
281
#include "sparcdiags.h"
282
#include "installglob.h"
283
#include "externs.h"
284
#include "out.h"
285
#include "translat.h"
286
#include "optimise.h"
287
#include "proc.h"
288
#include "special.h"
289
 
290
#include "target_v.h"
291
#include "locate.h"
292
#include "sparctrans.h"
293
#ifdef NEWDWARF
294
#include "dw2_iface.h"
295
#include "dw2_config.h"
296
#endif
297
 
298
 
299
extern bool know_size ;
300
 
301
char * proc_name;
302
 
303
 
304
#if ADDUNDERSCORE
305
#define isINITproc(id) (!strncmp("___I.TDF",id,8))
306
#else
307
#define isINITproc(id) (!strncmp("__I.TDF",id,7))
308
#endif /* ADDUNDERSCORE */
309
 
310
 
311
 
312
/*
313
  VARIABLES
314
*/
315
 
316
int sysV_abi ;		/* System V version? */
317
int sysV_assembler ;	/* System V version? */
318
int optim_level ;	/* optimisation level */
319
int g_reg_max ;		/* the maximum number of G registers */
320
int maxfix_tregs ;	/* the maximum number of T registers */
321
FILE *as_file = NULL ;	/* assembler output file */
322
dec **main_globals ;	/* global declarations */
323
procrec *procrecs ;	/* procedure records */
324
dec *diag_def = NULL ;	/* diagnostics definition */
325
int main_globals_index = 0;	/* number of globals */
326
int caller_offset_used = 0;
327
enum section current_section = no_section ;
328
 
329
 
330
/*
331
    FIND THE SIZE AND ALIGNMENT OF A SHAPE
332
*/
333
 
334
ash ashof 
335
    PROTO_N ( ( s ) )
336
    PROTO_T ( shape s ){
337
  ash a ;
338
  a.ashsize =  shape_size ( s ) ;
339
  a.ashalign = shape_align ( s ) ;
340
  return ( a ) ;
341
}
342
 
343
 
344
 
345
 
346
 
347
 
348
 
349
 
350
/*
351
  IS A SHAPE OF KNOWN SIZE?
352
*/
353
 
354
#define varsize( s )	1
355
 
356
 
357
/*
358
  OUTPUT A SECTION DIRECTIVE
359
*/
360
 
361
void insection 
362
    PROTO_N ( ( s ) )
363
    PROTO_T ( enum section s ){
364
  if (!sysV_assembler && s == rodata_section)
365
    s = data_section;
366
  if ( s == current_section ) return ;
367
  current_section = s ;
368
  if ( sysV_assembler ) {
369
    switch ( s ) {
370
      case data_section : {
371
	if (do_prom)
372
	  failer ("prom .data");
373
	outs ( "\t.section\t\".data\"\n" ) ;
374
	return ;
375
      }
376
      case text_section : {
377
	outs ( "\t.section\t\".text\"\n" ) ;
378
	return ;
379
      }
380
      case rodata_section : {
381
	outs ( "\t.section\t\".rodata\"\n" ) ;
382
	return ;
383
      }
384
      case init_section : {
385
	outs ("\t.section\t\".init\"\n");
386
	return;
387
      }
388
      default : {
389
	break ;
390
      }
391
    } 
392
  }
393
  else {
394
    switch ( s ) {
395
      case data_section : {
396
	outs ( "\t.seg\t\"data\"\n" ) ;
397
	return ;
398
      }
399
      case text_section : {
400
	outs ( "\t.seg\t\"text\"\n" ) ;
401
	return ;
402
      }
403
      default : {
404
	break ;
405
      }
406
    }
407
  }
408
  current_section = no_section ;
409
  fail ( "bad \".section\" name" ) ;
410
  return ;
411
}	
412
 
413
 
414
/*
415
  MARK AN EXPRESSION AS UNALIASED
416
*/
417
 
418
void mark_unaliased 
419
    PROTO_N ( ( e ) )
420
    PROTO_T ( exp e ){
421
  exp p = pt ( e ) ;
422
  bool ca = 1 ;
423
  assert ( !separate_units ) ;
424
  while ( p != nilexp && ca ) {
425
    exp q = bro ( p ) ;
426
    if ( q == nilexp ) {
427
#ifdef NEWDIAGS
428
      if (!isdiaginfo(p))
429
#endif
430
        ca = 0 ;
431
    } 
432
    else {
433
      if ( !( last ( p ) && name ( q ) == cont_tag ) &&
434
	   !( !last ( p ) && last ( q ) &&
435
	      name ( bro ( q ) ) == ass_tag ) ) {
436
#ifdef NEWDIAGS
437
        if (!isdiaginfo(p))
438
#endif
439
	  ca = 0 ;
440
      }
441
    }
442
    p = pt ( p ) ;
443
  }
444
  if ( ca ) setcaonly ( e ) ;
445
  return ;
446
}	
447
 
448
 
449
/*
450
  RENAMING ROUTINE
451
*/
452
 
453
void out_rename 
454
    PROTO_N ( ( oldid, newid ) )
455
    PROTO_T ( char * oldid X char * newid ){
456
#if 0
457
  outs ( "\t" ) ;
458
  outs ( oldid ) ;
459
  outs ( "=" ) ;
460
  outs ( newid ) ;
461
  outnl () ;
462
#endif
463
  return ;
464
}
465
 
466
 
467
/*
468
  LIST OF WEAK SYMBOLS
469
*/
470
 
471
weak_cell *weak_list = null ;
472
 
473
 
474
/*
475
  INITIALISE TRANSLATOR
476
*/
477
void init_translator 
478
    PROTO_Z (){
479
  /* initialise nowhere */
480
  setregalt ( nowhere.answhere, 0 ) ;
481
  nowhere.ashwhere.ashsize = 0 ;
482
  nowhere.ashwhere.ashsize = 0 ;
483
 
484
  /* mark the as output as TDF compiled */
485
  outs ( lab_prefix ) ;
486
  outs ( "TDF.translated:\n" ) ;
487
  outs ( "!\tTDF->SPARC, " ) ;
488
  outn ( target_version ) ;
489
  outs ( " , " ) ;
490
  outn ( target_revision ) ;
491
  if ( sysV_assembler ) outs ( " (SysV)" ) ;
492
  outnl () ;
493
 
494
 
495
  /* start diagnostics if necessary */
496
#ifdef NEWDWARF
497
  if (dwarf2)
498
    init_dwarf2 ();
499
  else
500
#endif
501
  if ( diagnose ) {
502
#if DWARF
503
    out_diagnose_prelude () ;
504
#else
505
    init_stab () ;
506
#endif
507
  }
508
    /* start in text section */
509
  insection ( text_section ) ;
510
  return ;
511
}
512
 
513
 
514
/*
515
  Return the tag with name 'tag_name'
516
*/
517
baseoff find_tag 
518
    PROTO_N ( ( tag_name ) )
519
    PROTO_T ( char * tag_name ){
520
  int i;
521
  for (i=0; i<main_globals_index; ++i){
522
    exp newtag = main_globals[i]->dec_u.dec_val.dec_exp;
523
    char * id = main_globals[i]->dec_u.dec_val.dec_id;
524
    if(!strcmp(id,tag_name)) return boff(newtag);
525
  }
526
  printf("%s\n: ",tag_name);
527
  fail("tag not declared");
528
  exit(1);
529
}
530
 
531
 
532
/*
533
  EXIT TRANSLATOR
534
*/
535
void exit_translator 
536
    PROTO_Z (){
537
  output_special_routines () ;
538
  insection ( text_section ) ;
539
 
540
#ifdef NEWDWARF
541
  if (dwarf2)
542
    end_dwarf2 ();
543
  else
544
#endif
545
  if ( diagnose ) {
546
#if DWARF
547
    out_diagnose_postlude () ;
548
#else
549
    /* do nothing */
550
#endif
551
  }
552
  return ;
553
}
554
 
555
 
556
/*
557
  TRANSLATE AN ENTIRE TDF CAPSULE
558
*/
559
void translate_capsule 
560
    PROTO_Z (){
561
  int i ;
562
  int r ;
563
  dec *d ;
564
  int procno ;
565
  int noprocs ;
566
  space tempregs ;
567
 
568
  /* initialize diagnostics */
569
#ifdef NEWDWARF
570
  if ( diagnose && !dwarf2 ) {
571
#else
572
  if ( diagnose ) {
573
#endif
574
#if DWARF
575
    /* do nothing */
576
#else
577
    init_stab_aux () ;
578
#endif
579
  }
580
 
581
 
582
  /* apply all optimisations */
583
#ifdef NEWDIAGS
584
  if ( !diag_visible ) opt_all_exps () ;
585
#else
586
  if ( !diagnose ) opt_all_exps () ;
587
#endif
588
 
589
  /* mark all statics as unaliased and count procedures */
590
  noprocs = 0 ;
591
  for ( d = top_def ; d != null ; d = d->def_next ) {
592
    exp c = d->dec_u.dec_val.dec_exp ;
593
    if ( son ( c ) != nilexp ) {
594
#ifdef NEWDIAGS
595
      if ( !diag_visible && !separate_units && !d->dec_u.dec_val.extnamed
596
#else
597
      if ( !diagnose && !separate_units && !d->dec_u.dec_val.extnamed
598
#endif
599
	   && isvar ( c ) ) {
600
	mark_unaliased ( c ) ;
601
      }
602
      if ( name ( son ( c ) ) == proc_tag || 
603
	   name(son(c))==general_proc_tag) noprocs++ ;
604
    }	
605
  }	
606
 
607
#ifdef NEWDWARF
608
  if (dwarf2) {
609
    dwarf2_prelude ();
610
  }
611
#endif
612
 
613
  /* output weak symbols */
614
  while ( weak_list ) {
615
    outs ( "\t" ) ;
616
    outs ( weak_list->weak_id ) ;
617
    outs ( "=" ) ;
618
    outs ( weak_list->val_id ) ;
619
    outnl () ;
620
    weak_list = weak_list->next ;
621
  }
622
 
623
  /* allocate memory for procedures */
624
  procrecs = ( procrec * ) xcalloc ( noprocs, sizeof ( procrec ) ) ;
625
 
626
  /* number procedure definitions */
627
  procno = 0 ;
628
  for ( d = top_def ; d != null ; d = d->def_next ) {
629
    exp c = d->dec_u.dec_val.dec_exp ;
630
    exp s = son ( c ) ;
631
    if ( s != nilexp && (name ( s ) == proc_tag || 
632
			 name(s) == general_proc_tag)) {
633
      procrec *pr = &procrecs [ procno ] ;
634
      pr->nameproc = bro ( c ) ;
635
      no ( s ) = procno++ ;
636
    }
637
  }
638
 
639
    /*
640
      Scan to put everything in SPARC form, and calculate register 
641
      and stack space needs.  First work out which t fixed point 
642
      registers	(those not preserved over calls) can be used.  This 
643
      needs to be done before scan () which adds identities so that 
644
      temporary	register needs are within the available temporary 
645
      register set.  We dynamically calculate g registers we can use
646
      as temporaries so	that we can support :
647
	    SUNOS 4 : %g1..%g7 can be used,
648
	    SYSV SPARC ABI : %g1..%g4 can be used.
649
    */
650
 
651
    /* initialise register sets */
652
  tempregs.fixed = PROC_TREGS ;
653
  tempregs.flt = PROC_FLT_TREGS ;
654
 
655
  /*permit use of valid g registers(%g0 is not a proper register)*/
656
 
657
  /* ensure R_TMP not allocatable */
658
 
659
  /* scan all the procedures, to put everything in SPARC operand form */
660
  for ( d = top_def ; d != null ; d = d->def_next ) {
661
    exp c = d->dec_u.dec_val.dec_exp ;
662
    exp s = son ( c ) ;
663
    if ( s != nilexp && (name ( s ) == proc_tag ||
664
			 name(s) == general_proc_tag)) {
665
      exp *st = &s ;
666
      procrec *pr = &procrecs [ no ( s ) ] ;
667
 
668
      if (d->dec_u.dec_val.extnamed && isINITproc(d->dec_u.dec_val.dec_id))
669
	set_proc_uses_external (s);    /* for PIC_code, should be done in install_fns? */
670
 
671
      Has_vcallees = (name(s) == general_proc_tag) && 
672
	proc_has_vcallees(s);
673
      for (r=R_G1; r <= R_G0 + g_reg_max ; r++ ) {
674
	tempregs.fixed &= ~RMASK ( r ) ;
675
      }
676
      tempregs.fixed |= RMASK ( R_TMP ) ;
677
      /* count the number of fixed t registers */
678
      maxfix_tregs = 0 ;
679
      for ( r = R_FIRST ; r <= R_LAST ; r++ ) {
680
	if ( IS_TREG ( r ) && ( tempregs.fixed & RMASK ( r ) ) == 0 ) {
681
	  maxfix_tregs++ ;
682
	}
683
      }
684
      if (name(s) == general_proc_tag) {
685
	int any_envoff = 0;
686
	exp a = son (s);
687
	while (name(a) == ident_tag && isparam(a) && name(son(a)) != formal_callee_tag) {
688
	  if (isenvoff(a) && caller_offset_used)
689
	    any_envoff = 1;
690
	  else if (any_envoff) {
691
	    setvis(a);
692
	    setenvoff(a);
693
	  }
694
	  a = bro(son(a));
695
	}
696
#ifdef GENCOMPAT
697
	if ((name(a) == ident_tag && isparam(a)) || Has_vcallees) {
698
	  set_proc_may_have_callees(s);
699
	}
700
#endif
701
      }	
702
      pr->needsproc = scan ( st, &st ) ;
703
      pr->needsproc.callee_size = (callee_size+63)&~63;
704
    }
705
  }
706
 
707
#if 0
708
    /* apply dead variable analysis (not currently implemented) */
709
  if ( do_deadvars ) {
710
    init_dead () ;
711
    dead_flag = 0 ;
712
    for ( d = top_def ; d != null ; d = d->def_next ) {
713
      exp c = d->dec_u.dec_val.dec_exp ;
714
      exp s = son ( c ) ;
715
      if ( s != nilexp && (name ( s ) == proc_tag || 
716
			   name(s) == general_proc_tag)){
717
	deadvar ( s ) ;
718
      }
719
    }
720
  }
721
#endif
722
 
723
 
724
  /* calculate the break points for register allocation */
725
  for ( d = top_def ; d != null ; d = d->def_next ) {
726
    exp c = d->dec_u.dec_val.dec_exp ;
727
    exp s = son ( c ) ;
728
    if ( s != nilexp && (name ( s ) == proc_tag || 
729
			 name(s) == general_proc_tag)) {
730
      weights w ;	
731
      spacereq forrest ;
732
      int freefixed, freefloat ;
733
      procrec *pr = &procrecs [ no ( s ) ] ;
734
 
735
      avoid_L7 = ( bool )( PIC_code && proc_uses_external ( s ) ) ;
736
      Has_vcallees = (name(s) == general_proc_tag) && 
737
	proc_has_vcallees(s);
738
      in_general_proc = (name(s) == general_proc_tag);
739
#ifdef GENCOMPAT
740
      May_have_callees = proc_may_have_callees(s);
741
#endif
742
      /* calculate number of free registers */
743
      freefixed = ( R_L7 - R_L0 + 1 ) + ( R_I5 - R_I0 + 1 ) ;
744
      freefloat = 0 ;
745
      if ( avoid_L7 ) freefixed-- ;
746
#ifdef GENCOMPAT
747
      if (May_have_callees) freefixed--;
748
#else
749
      if(in_general_proc) freefixed--;
750
#endif
751
      if(Has_vcallees) freefixed --;
752
      /* estimate tag usage */
753
      w = weightsv ( 1.0, bro ( son ( s ) ) ) ;
754
      /* calculate register and stack allocation for tags */
755
      forrest = regalloc ( bro ( son ( s ) ), freefixed, freefloat, 0 ) ;
756
      pr->spacereqproc = forrest ;
757
    }
758
  }
759
  /* set up main_globals */
760
  i = 0 ;
761
  for ( d = top_def ; d != null ; d = d->def_next ) i++ ;
762
  main_globals_index = i;
763
  if ( i ) main_globals = ( dec ** ) xcalloc ( i, sizeof ( dec * ) ) ;
764
  i = 0 ;
765
  for ( d = top_def ; d != null ; d = d->def_next ) {
766
    main_globals [i] = d ;
767
    main_globals [i]->dec_u.dec_val.sym_number = i ;
768
    i++ ;
769
  }
770
  /* output global definitions */
771
  for ( d = top_def ; d != null ; d = d->def_next ) {
772
    exp tg = d->dec_u.dec_val.dec_exp ;
773
    exp stg = son ( tg ) ;
774
    char *id = d->dec_u.dec_val.dec_id ;
775
    bool extnamed = ( bool ) d->dec_u.dec_val.extnamed ;
776
    if ( stg != nilexp && (extnamed || no(tg)!= 0 ||
777
	 !strcmp(id,TDF_HANDLER) || !strcmp(id,TDF_STACKLIM))) {
778
      if ( extnamed ) {
779
	assert ( id [ 0 ] != '$' ) ;
780
	if ( name ( stg ) != proc_tag && name(stg)!=general_proc_tag) {
781
	  if (!isvar (tg) || (d -> dec_u.dec_val.acc & f_constant) || do_prom) 
782
	    insection ( rodata_section ) ;
783
	  else
784
	    insection ( data_section ) ;
785
	} 
786
	else if (isINITproc(id) && sysV_assembler) {
787
	  /* On solaris, this is easy.  Insert a call to the procedure
788
	     into the init segment */
789
	  insection (init_section);
790
	  fprintf(as_file,"\tcall %s\n",id);
791
	  outs("\tnop\n");
792
	  insection (text_section);
793
	}
794
	else{
795
	  insection ( text_section ) ;
796
	}
797
	outs ( "\t.global\t" ) ;
798
	outs ( id ) ;
799
	outnl () ;
800
      }
801
      if ( name ( stg ) != proc_tag && name(stg)!=general_proc_tag) {
802
	  /* evaluate all outer level constants */
803
	instore is ;
804
	long symdef = d->dec_u.dec_val.sym_number + 1 ;
805
	diag_global *diag_props = d->dec_u.dec_val.diag_info ;
806
	if ( isvar ( tg ) ) symdef = -symdef ;
807
	if ( diag_props ) {
808
	  DIAG_VAL_BEGIN ( diag_props, extnamed, symdef, id, stg ) ;
809
	}
810
	is = evaluated ( stg, symdef, 
811
		(!isvar (tg) || (d -> dec_u.dec_val.acc & f_constant)) ) ;
812
	if ( diag_props ) {
813
	  DIAG_VAL_END ( diag_props ) ;
814
	}
815
	if ( is.adval ) setvar ( tg ) ;
816
	if ( sysV_assembler ) {
817
	  outs ( "\t.type\t" ) ;
818
	  outs ( id ) ;
819
	  outs ( ",#object\n" ) ;
820
	  if ( !know_size ) {
821
	    outs ( "\t.size\t" ) ;
822
	    outs ( id ) ;
823
	    outs ( "," ) ;
824
	    outn ( shape_size ( sh ( stg ) ) / 8 ) ;
825
	    outnl () ;
826
	  }
827
	}
828
      }
829
    }
830
  }	
831
 
832
    /* translate procedures */
833
  for ( d = top_def ; d != null ; d = d->def_next ) {
834
    exp tg = d->dec_u.dec_val.dec_exp ;
835
    exp stg = son ( tg ) ;
836
    char *id = d->dec_u.dec_val.dec_id ;
837
    bool extnamed = ( bool ) d->dec_u.dec_val.extnamed ;
838
 
839
    if ( stg != nilexp && shape_size (sh(stg)) == 0 && name(stg) == asm_tag) {
840
      if (props(stg) != 0)
841
	failer ("~asm not in ~asm_sequence");
842
      check_asm_seq (son(stg), 1);
843
      insection ( text_section ) ;
844
      (void)code_here ( stg, tempregs, nowhere ) ;
845
      outnl ();
846
    }
847
 
848
    if ( no ( tg ) == 0 && !extnamed ) continue ;
849
    if ( stg != nilexp ) {
850
      if ( name ( stg ) == proc_tag || name(stg)==general_proc_tag) {
851
	/* translate code for procedure */
852
	int proc_directive ;
853
	exp c = d->dec_u.dec_val.dec_exp ;
854
	prop p = procrecs [ no ( son ( c ) ) ].needsproc.prps ;
855
	diag_global *diag_props = d->dec_u.dec_val.diag_info ;
856
	insection ( text_section ) ;
857
 
858
	if(!sysV_assembler){
859
#ifdef GENCOMPAT
860
	  optim_level = (proc_may_have_callees(stg))?0:2;
861
#else
862
	  optim_level = (name(stg) == general_proc_tag)?0:2;
863
#endif
864
	}
865
 
866
	/*
867
	  The .proc directive number tells Sun's assembler
868
	  optimiser which register are live at the end of the
869
	  procedure. We must get it right, or be conservative.
870
       */
871
	if ( p & longrealresult_bit ) {
872
	  proc_directive = 7 ;	    /* %f0 and %f1 */
873
	} 
874
	else if ( p & realresult_bit ) {
875
	  proc_directive = 6 ;	    /* %f0 */
876
	} 
877
	else if ( p & long_result_bit ) {
878
	  proc_directive = 0 ;	    /* compound */
879
	} 
880
	else if ( p & has_result_bit ) {
881
	  proc_directive = 4 ;	    /* %i0 or (leaf) %o0 */
882
	} 
883
	else {
884
	  proc_directive = 0 ;
885
	}
886
	outs ( "\t.proc\t" ) ;
887
	outn ( proc_directive ) ;
888
	outnl () ;
889
#ifdef DO_COMMENT
890
	if ( p & long_result_bit ) outs ( "!\tstruct result\n" ) ;
891
#endif
892
 
893
	if ( diagnose ) {
894
	  DIAG_PROC_BEGIN ( diag_props, extnamed, -1, id, stg ) ;
895
	}
896
	if ( optim_level >= 0 ) {
897
	  /* .optim must go after .proc */
898
	  if ( ( p & long_result_bit ) || ( p & dont_optimise ) ) {
899
	    outs ( "\t.optim\t\"-O0\"\n" ) ;
900
	  } 
901
	  else {
902
	    outs ( "\t.optim\t\"-O" ) ;
903
	    outn ( optim_level ) ;
904
	    outs ( "\"\n" ) ;
905
	  }
906
	}
907
 
908
 
909
	outs ( id ) ;
910
	outs ( ":\n" ) ;
911
	seed_label () ;		/* reset label sequence */
912
	settempregs ( stg ) ;	/* reset getreg sequence */
913
	/* generate code for this proc */
914
 
915
	proc_name = id;
916
	(void)code_here ( stg, tempregs, nowhere ) ;
917
	if ( sysV_assembler ) {
918
	  outs ( "\t.type\t" ) ;
919
	  outs ( id ) ;
920
	  outs ( ",#function\n" ) ;
921
	  outs ( "\t.size\t" ) ;
922
	  outs ( id ) ;
923
	  outs ( ",.-" ) ;
924
	  outs ( id ) ;
925
	  outnl () ;
926
	} 
927
	else {
928
#ifdef DO_COMMENT
929
	  outs ( "!\t.end\t" ) ;
930
	  outs ( id ) ;
931
	  outnl () ;
932
#endif	
933
	}
934
	if ( diagnose ) {
935
	  DIAG_PROC_END ( stg ) ;
936
	}
937
      }
938
    } 
939
  }	
940
 
941
 
942
#ifdef NEWDWARF
943
  if (dwarf2) {
944
    dwarf2_postlude ();
945
  }
946
#endif
947
  return ;
948
}
949
 
950
 
951
/*	
952
  TRANSLATE A SINGLE TAG DEFINITION
953
*/
954
 
955
void translate_tagdef 
956
    PROTO_Z (){
957
  /* not implemented */
958
  return ;
959
}
960
 
961
 
962
/*
963
  TRANSLATE A SINGLE UNIT
964
*/	
965
void translate_unit 
966
    PROTO_Z (){
967
  if ( separate_units ) {
968
    dec *d ;
969
    translate_capsule () ;
970
    d = top_def ;
971
    while ( d != null ) {
972
      exp c = d->dec_u.dec_val.dec_exp ;
973
      no ( c ) = 0 ;
974
      pt ( c ) = nilexp ;
975
      d = d->def_next ;
976
    }
977
    crt_repeat = nilexp ;
978
    repeat_list = nilexp ;
979
  }
980
  return ;
981
}
982
 
983
 
984
 
985
 
986
 
987