Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | 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
translat.c,v
33
 * Revision 1.8  1996/09/06  10:38:21  wfs
34
 * bug fixes to "offset.pl" and cosmetic changes to the dynamic initialization
35
 * code.
36
 *
37
 * Revision 1.7  1996/09/05  11:05:13  wfs
38
 * "dynamic_init" boolean variable removed - must always be considered true.
39
 *
40
 * Revision 1.6  1996/08/30  09:02:35  wfs
41
 * Various fixes of bugs arising from avs and pl_tdf tests.
42
 *
43
 * Revision 1.5  1996/03/22  13:34:14  wfs
44
 * Corrections to the dynamic initialization stuff in translat.c + bad
45
 * needscan.c code deleted.
46
 *
47
 * Revision 1.4  1996/01/30  15:36:32  wfs
48
 * Added the dynamic initialization files "dyn_begin.s" and "dyn_end.s" to
49
 * the hppatrans repository. The bl_install and bl_update scripts were
50
 * expanded to deal with these new "initcode" files.
51
 *
52
 * Revision 1.3  1995/12/19  16:52:54  wfs
53
 * Reinstated the "__main" call and a ".CODE" directive when producing gdb
54
 * diagnostic code.
55
 *
56
 * Revision 1.2  1995/12/18  13:12:42  wfs
57
 * Put hppatrans uder cvs control. Major Changes made since last release
58
 * include:
59
 * (i) PIC code generation.
60
 * (ii) Profiling.
61
 * (iii) Dynamic Initialization.
62
 * (iv) Debugging of Exception Handling and Diagnostics.
63
 *
64
 * Revision 5.10  1995/10/25  14:37:12  wfs
65
 * Removed references to nonexistant diag_info of unused static procs.
66
 *
67
 * Revision 5.9  1995/10/20  14:15:44  wfs
68
 * gcc compilation changes.
69
 *
70
 * Revision 5.8  1995/10/16  14:43:24  wfs
71
 * *** empty log message ***
72
 *
73
 * Revision 5.7  1995/10/09  12:54:58  wfs
74
 * Cosmetic changes.
75
 *
76
 * Revision 5.6  1995/10/05  09:03:06  wfs
77
 * Refinements to procedure translation ordering - can now translate
78
 * according to source file ordering (for XDB) or can translate global
79
 * procedures first (aids compilation and linking of large programs such
80
 * as tdfc's "trans_unit.c").
81
 *
82
 * Revision 5.5  1995/09/27  13:42:43  wfs
83
 * Changes to "translate_capsule()". Can now more easily choose the order
84
 * of procedure translation - necessary for XDB diagnostics. Tidied up.
85
 *
86
 * Revision 5.4  1995/09/26  12:52:00  wfs
87
 * Removal of some temporary code related to XDB diagnostics.
88
 *
89
 * Revision 5.3  1995/09/25  10:59:21  wfs
90
 * Added "#ifdef _SYMTAB_INCLUDED" provisios around any code which refers
91
 * to "hpux-symtab.h". We cannot legally distribute this header file.
92
 *
93
 * Revision 5.2  1995/09/21  14:13:36  wfs
94
 * Removed a superfluous printf.
95
 *
96
 * Revision 5.1  1995/09/15  13:20:41  wfs
97
 * Minor name changes to avoid conflict with variables in system
98
 * headers during gcc compilation.
99
 *
100
 * Revision 5.0  1995/08/25  13:42:58  wfs
101
 * Preperation for August 25 Glue release
102
 *
103
 * Revision 3.3  1995/08/25  10:37:30  wfs
104
 * "find_tg" added. Changes to the diagnostics interface. Cosmetic
105
 * changes. Register allocation is done differently now.
106
 *
107
 * Revision 3.3  1995/08/25  10:37:30  wfs
108
 * "find_tg" added. Changes to the diagnostics interface. Cosmetic
109
 * changes. Register allocation is done differently now.
110
 *
111
 * Revision 3.1  95/04/10  16:28:36  16:28:36  wfs (William Simmonds)
112
 * Apr95 tape version.
113
 * 
114
 * Revision 3.0  95/03/30  11:19:09  11:19:09  wfs (William Simmonds)
115
 * Mar95 tape version with CRCR95_178 bug fix.
116
 * 
117
 * Revision 2.0  95/03/15  15:29:03  15:29:03  wfs (William Simmonds)
118
 * spec 3.1 changes implemented, tests outstanding.
119
 * 
120
 * Revision 1.3  95/02/10  11:38:54  11:38:54  wfs (William Simmonds)
121
 * Rewrote the inner level initializations previously handled by calls
122
 * to evaluated().
123
 * 
124
 * Revision 1.2  95/01/17  17:31:02  17:31:02  wfs (William Simmonds)
125
 * Changed name of an included header file.
126
 * 
127
 * Revision 1.1  95/01/11  12:59:09  12:59:09  wfs (William Simmonds)
128
 * Initial revision
129
 * 
130
*/
131
 
132
 
133
#define HPPATRANS_CODE
134
/*
135
 *  Translation is controlled by translate() in this module. *  Code generation follows the following phases:
136
 *
137
 *  1. The TDF is read in, applying bottom-up optimisations.
138
 *  2. Top-down optimisations are performed.
139
 *  3. Register allocation is performed, and TDF idents introduced
140
 *     so code generation can be performed with no register spills.
141
 *  4. Code is generated for each procedure, and global declarations processed.
142
 *  5. Currently assembler source is generated directly, and the
143
 *     assembler optimiser (as -O) used for delay slot filling,
144
 *     instruction scheduling and peep-hole optimisation.
145
 *
146
 *  In a little more detail:
147
 *
148
 *  1) During the TDF reading process for tag declarations and tag
149
 *  definitions, applications of tokens are expanded as they are
150
 *  encountered, using the token definitions.  Every token used must have
151
 *  been previously defined in the bitstream.
152
 *
153
 *  The reading of the tag definitions creates a data structure in memory
154
 *  which directly represents the TDF.  At present, all the tag definitions
155
 *  are read into memory in this way before any further translation is
156
 *  performed.  This will shortly be changed, so that translation is
157
 *  performed in smaller units.  The translator is set up already so that
158
 *  the change to translate in units of single global definitions (or
159
 *  groups of these) can easily be made.
160
 *
161
 *  During the creation of the data structure bottom-up optimisations
162
 *  are performed.  These are the optimisations which can be done when a
163
 *  complete sub-tree of TDF is present, and are independent of the context
164
 *  in which the sub-tree is used.  They are defined in check.c and
165
 *  check_id.c.  These optimisation do such things as use the commutative
166
 *  and associative laws for plus to collect together and evaluate
167
 *  constants.  More ambitious examples of these bottom-up optimisations
168
 *  include all constant evaluation, elimination of inaccessible code, and
169
 *  forward propagation of assignments of constants.
170
 *
171
 *  2) After reading in the TDF various optimisations are performed which
172
 *  cannot be done until the whole context is present.  For example,
173
 *  constants cannot be extracted from a loop when we just have the loop
174
 *  itself, because we cannot tell whether the variables used in it are
175
 *  aliased.
176
 *
177
 *  These optimisations are invoked by opt_all_exps which is defined in
178
 *  indep.c.  They include extraction of constants from loops, common
179
 *  expression elimination on them and strength reduction for indexing.
180
 *
181
 *  3) Allocatable registers are partitioned into two sets, the s regs
182
 *  which are preserved over calls, and the t regs which are not.
183
 *
184
 *  The TDF is scanned introducing TDF idents so that expressions can be
185
 *  evaluated within the available t regs with no spills.  These new idents
186
 *  may be later allocated to a s reg later, if the weighting algorithm
187
 *  (below) considers this worth while.  Otherwise they will be on the stack.
188
 *
189
 *  Information is collected to help in global register allocation.  During
190
 *  a forward recursive scan of the TDF the number of accesses to each
191
 *  variable is computed (making assumptions about the frequency of
192
 *  execution of loops).  Then on the return scan of this recursion, for
193
 *  each declaration, the number of registers which must be free for it to
194
 *  be worthwhile to use a register is computed, and put into the TDF as
195
 *  the"break" point.  The procedures to do this are defined in weights.c.
196
 *
197
 *  Suitable idents not alive over a procedure call are allocated to a t reg,
198
 *  and others to s regs.  At the same time stack space requirements are
199
 *  calculated, so this is known before code for a procedure is generated.
200
 *
201
 *  4) Finally the code is generated without register spills.  The code is
202
 *  generated by make_code() in makecode.c, and make_XXX_code() in proc.c.
203
 *
204
 *  Note that procedure inlining and loop unrolling optimisations are not
205
 *  currently implemented.  Library procedures such as memcpy() and
206
 *  strcpy() are not treated specially.  Integer multiply, divide and
207
 *  remainder use the standard support procedures .mul, .div, .rem and
208
 *  unsigned variants.
209
 */
210
 
211
 
212
#include "config.h"
213
#include "myassert.h"
214
#include "flpt.h"
215
#include "frames.h"
216
#include "expmacs.h"
217
#include "tags.h"
218
#include "exptypes.h"
219
#include "exp.h"
220
#include "shapemacs.h"
221
#include "tempdecs.h"
222
#include "weights.h"
223
#include "proctypes.h"
224
#include "procrec.h"
225
#include "regalloc.h"
226
#include "codehere.h"
227
#include "makecode.h"
228
#include "eval.h"
229
#include "toktypes.h"
230
#include "flags.h"
231
#include "basicread.h"
232
#include "tags.h"
233
#include "bitsmacs.h"
234
#include "needscan.h"
235
#include "getregs.h"
236
#include "regmacs.h"
237
#include "labels.h"
238
#include "xalloc.h"
239
#include "comment.h"
240
#include "hppadiags.h"
241
#include "installglob.h"
242
#include "externs.h"
243
#include "out.h"
244
#include "translat.h"
245
#include "version.h"
246
#include "inst_fmt.h"
247
#include "optimise.h"
248
#include "getregs.h"
249
#include "special.h"
250
#include "oprators.h"
251
#include "time.h"
252
 
253
extern dec *diag_def ;
254
 
255
 
256
 
257
int optim_level;		/* optimisation level from -O# option */
258
int maxfix_tregs;		/* the number of t regs allocatable */
259
 
260
char *proc_name;
261
char export[128];
262
labexp current,first;
263
 
264
int nexps;
265
 
266
extern baseoff boff PROTO_S ( ( exp ) ) ;
267
extern int res_label;
268
 
269
FILE *outf = NULL;/* assembler output file */
270
dec **main_globals;
271
int main_globals_index;
272
 
273
procrec *procrecs,*cpr;
274
 
275
dec *diag_def = NULL ;	/* diagnostics definition */
276
 
277
#define is_zero( e ) is_comm( e )
278
#define TRANSLATE_GLOBALS_FIRST 1
279
 
280
ash ashof 
281
    PROTO_N ( ( s ) )
282
    PROTO_T ( shape s )
283
{
284
  ash a;
285
 
286
  a.ashsize = shape_size(s);
287
  a.ashalign = shape_align(s);
288
  return a;
289
}
290
 
291
 
292
/* is shape 'sha' of unknown size? */
293
static bool varsize 
294
    PROTO_N ( ( sha ) )
295
    PROTO_T ( shape sha )
296
{
297
  switch (name(sha))
298
  {
299
    case cpdhd:
300
    {
301
      shape t = son(sha);
302
 
303
      if (t == nilexp)
304
	return 1;
305
      if (varsize(sh(t)))
306
	return 1;
307
      while (!last(t))
308
      {
309
	t = bro(t);
310
	if (varsize(sh(t)))
311
	  return 1;
312
      }
313
      return 0;
314
    }
315
 
316
  case nofhd:
317
    return 1;
318
 
319
  default:
320
    return 0;
321
  }
322
}
323
 
324
void insection 
325
    PROTO_N ( ( s ) )
326
    PROTO_T ( enum section s )
327
{
328
  static enum section current_section = no_section;
329
 
330
  if (s == current_section)
331
    return;
332
 
333
  current_section = s;
334
 
335
    switch (s)
336
    {
337
       case shortdata_section:
338
       {
339
	 outs("\t.SHORTDATA\n");
340
	 return;
341
       }
342
       case data_section:
343
       {
344
	 outs("\t.DATA\n");  
345
	 return;
346
       }
347
       case text_section:
348
       {
349
	 outs("\t.CODE\n");
350
	 return;
351
       }
352
       case bss_section:
353
       case shortbss_section:
354
       {
355
	  if (gcc_assembler)
356
	  {
357
	     /* gcc does not recognise .BSS directive */
358
	     outs("\t.SPACE\t$PRIVATE$\n");
359
	     outs("\t.SUBSPA\t$BSS$\n");
360
	  }
361
	  else
362
	     outs("\t.BSS\n");
363
	  return;
364
       }
365
       case no_section:
366
       {
367
	  current_section = no_section;
368
	  return;
369
       }
370
       case rodata_section:
371
       default: {}
372
    }
373
    failer("bad \".section\" name");
374
}
375
 
376
void mark_unaliased 
377
    PROTO_N ( ( e ) )
378
    PROTO_T ( exp e )
379
{
380
  exp p = pt(e);
381
  bool ca = 1;
382
  assert(!separate_units);	/* don't know about aliases in other units */
383
  while (p != nilexp && ca)
384
  {
385
     if (bro(p) == nilexp)
386
     {
387
	ca = 0;
388
     }
389
     else
390
     {
391
	if (!(last(p) && name(bro(p)) == cont_tag) &&
392
  	    !(!last(p) && last(bro(p)) && name(bro(bro(p))) == ass_tag))
393
	   ca = 0;
394
     }
395
     p = pt(p);
396
  };
397
  if (ca)
398
    setcaonly(e);
399
  return;
400
}
401
 
402
baseoff find_tg
403
    PROTO_N ( (n) )
404
    PROTO_T ( char *n )
405
{
406
   int i;
407
   for(i=0;i<main_globals_index;i++) 
408
   {
409
      exp tg = main_globals[i] -> dec_u.dec_val.dec_exp;
410
      char *id = main_globals[i] -> dec_u.dec_val.dec_id;
411
      if ( strcmp(id,n)==0 )
412
      {
413
	 return boff(tg); 
414
      }
415
   }
416
   failer("Extension name not declared ");
417
   exit(EXIT_FAILURE);
418
}	
419
 
420
 
421
/* translate the TDF */
422
void translate_capsule 
423
    PROTO_Z ()
424
{
425
  int noprocs;
426
  int procno;
427
  int i;
428
  dec *crt_def,**proc_def_trans_order;
429
  int *src_line=0,next_proc_def;
430
  space tempregs;
431
  int r;
432
  static int capn=0;
433
  capn++;
434
 
435
  /* mark the as output as TDF compiled */
436
  outs("\t;  Produced by the DERA TDF->HP PA-RISC translator ") ;
437
  fprintf(outf,"%d.%d",MAJOR,MINOR) ;
438
  outnl();
439
  outnl();
440
  outnl();
441
  outs("\t.SPACE  $TEXT$,SORT=8\n" );
442
  outs("\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY,SORT=24\n" );
443
  outnl();
444
  outs("\t.SPACE  $PRIVATE$,SORT=16\n");
445
  outs("\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31,SORT=16\n\n");
446
  outs("\t.IMPORT\t$$dyncall,CODE\n");
447
  if (do_profile)
448
     outs("\t.IMPORT\t_mcount,CODE\n");
449
  outs("\t.IMPORT\t$global$,DATA\n");
450
  outnl();
451
 
452
#if 0
453
  outs("LB\t.MACRO\tTARGET\n");
454
  outs("\tldil\tL'TARGET,%r1\n");
455
  outs("\tldo\tR'TARGET(%r1),%r1\n");
456
  outs("\tbv\t0(%r1)\n");
457
  outs("\tnop\n");
458
  outnl();
459
#endif
460
 
461
  /* Begin diagnostics if necessary. */
462
  if ( diagnose )
463
  {
464
     outs("\t.CODE\n");
465
     outnl();
466
     init_stab_aux() ;
467
     outnl();
468
     outnl();
469
  }
470
 
471
  setregalt(nowhere.answhere, 0);
472
  nowhere.ashwhere.ashsize = 0;
473
  nowhere.ashwhere.ashsize = 0;
474
 
475
  if ( !diagnose )
476
     opt_all_exps();  /* optimise */
477
  /* mark static unaliased; count procs */
478
  noprocs = 0;
479
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
480
  {
481
    exp crt_exp = crt_def->dec_u.dec_val.dec_exp;
482
    exp scexp = son( crt_exp );
483
    if ( scexp != nilexp)
484
    {
485
      if ( !diagnose && !separate_units && 
486
	  !crt_def->dec_u.dec_val.extnamed && isvar(crt_exp))
487
	mark_unaliased(crt_exp);
488
      if (name(scexp) == proc_tag || name(scexp)== general_proc_tag )
489
      {
490
	noprocs++;
491
	if ( !strncmp("__I.TDF",crt_def->dec_u.dec_val.dec_id,7) )
492
	{
493
	   char *s;
494
	   static char dyn = 0;
495
	   if (!dyn)
496
	   {
497
	      outs("\t.SPACE  $PRIVATE$,SORT=16\n");
498
	      outs("\t.SUBSPA $DYNDATA$,QUAD=1,ALIGN=4,ACCESS=31,SORT=16\n");
499
	      outnl();
500
	      dyn = 1;
501
	   }
502
	   s = (char*) xcalloc(64,sizeof(char));
503
	   sprintf(s,"_GLOBAL_$I%d",capn);
504
	   strcat(s,crt_def->dec_u.dec_val.dec_id+7);
505
	   crt_def->dec_u.dec_val.dec_id = s;
506
	   if (!gcc_assembler)
507
	      fprintf(outf,"\t.WORD\t%s\n",s);
508
	}
509
      }
510
    }
511
  };
512
  outnl();
513
 
514
  /* alloc memory */
515
  procrecs = (procrec *) xcalloc(noprocs, sizeof (procrec));
516
 
517
  proc_def_trans_order = (dec**) xcalloc(noprocs, sizeof (dec*));
518
  if ( xdb )
519
  {
520
     src_line = (int*) xcalloc(noprocs,sizeof(int));
521
  }
522
 
523
  /* number proc defs */
524
  procno = 0;
525
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
526
  {
527
    exp crt_exp = crt_def->dec_u.dec_val.dec_exp;
528
 
529
    if (son(crt_exp) != nilexp && ( name(son(crt_exp)) == proc_tag ||
530
				    name(son(crt_exp))== general_proc_tag ) )
531
    {
532
      procrec *pr = &procrecs[procno];
533
      proc_def_trans_order[procno] = crt_def; 
534
      if (xdb)
535
      {
536
	 /* Retrieve diagnostic info neccessary to comply with xdb's
537
	    requirement that procedures be compiled in source file order. */
538
	 diag_descriptor * dd =  crt_def -> dec_u.dec_val.diag_info;
539
	 if ( dd != (diag_descriptor*)0 )
540
	 {
541
	    sourcemark *sm = &dd -> data.id.whence;
542
	    src_line[procno] = sm->line_no.nat_val.small_nat; 
543
	 }
544
	 else
545
	    src_line[procno] = 0;
546
      }
547
      pr->nameproc = bro(crt_exp);
548
      no(son(crt_exp)) = procno++;/* index into procrecs in no(proc) */
549
    }
550
  }
551
 
552
 
553
  /*
554
   * Scan to put everything in HP_PA form, and calculate register and stack
555
   * space needs.
556
   */
557
 
558
  /*
559
   *      First work out which fixed point t-regs, i.e. those not preserved
560
   *  over calls, can be used. This needs to be done before scan() which 
561
   *  adds idents so temp reg needs are within available temp reg set.
562
   *
563
   */
564
 
565
  /* initial reg sets */
566
  tempregs.fixed = PROC_TREGS;
567
  tempregs.flt = PROC_FLT_TREGS;
568
 
569
  /* GR0,GR1,SP,DP are NEVER allocatable */
570
  tempregs.fixed |= RMASK(GR0);
571
  tempregs.fixed |= RMASK(GR1);
572
  tempregs.fixed |= RMASK(SP);
573
  tempregs.fixed |= RMASK(DP);
574
  if (PIC_code)
575
  {
576
     tempregs.fixed |= RMASK(GR19); /* %r19 is reserved in PIC mode */
577
  }
578
 
579
  /* count t fixed point regs we can use, and set the global maxfix_tregs */
580
  maxfix_tregs = 0;
581
  for (r = R_FIRST; r <= R_LAST; r++)
582
  {
583
    /* bit clear means allocatable */
584
    if (IS_TREG(r) && (tempregs.fixed & RMASK(r)) == 0)
585
      maxfix_tregs++;
586
  }
587
  comment4("maxfix_tregs=%d(%#x) maxfloat_tregs=%d(%#x)",
588
	   maxfix_tregs, tempregs.fixed, MAXFLOAT_TREGS, tempregs.flt);
589
 
590
  /* scan all the procs, to put everything in HP_PA form */
591
  nexps = 0;
592
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
593
  {
594
    exp crt_exp = crt_def->dec_u.dec_val.dec_exp;
595
    if (son(crt_exp) != nilexp && ( name(son(crt_exp)) == proc_tag ||
596
				    name(son(crt_exp))== general_proc_tag ) )
597
    {
598
      procrec *pr = &procrecs[no(son(crt_exp))];
599
      exp *st = &son(crt_exp);
600
      cpr = pr;
601
      cpr->Has_ll = 0;
602
      cpr->Has_checkalloc = 0;
603
      builtin=0;
604
      pr->needsproc = scan(st, &st);
605
      pr->callee_sz = callee_sz;
606
      pr->needsproc.builtin=builtin;
607
    }
608
  }
609
 
610
  /* calculate the break points for register allocation */
611
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
612
  {
613
    exp crt_exp = crt_def->dec_u.dec_val.dec_exp;
614
 
615
    if (son(crt_exp) != nilexp && ( name(son(crt_exp)) == proc_tag ||
616
				    name(son(crt_exp))== general_proc_tag ) )
617
    {
618
      procrec *pr = &procrecs[no(son(crt_exp))];
619
      needs * ndpr = & pr->needsproc;
620
      long pprops = (ndpr->propsneeds);
621
      bool leaf = (pprops & anyproccall) == 0;
622
      weights w;
623
      spacereq forrest;
624
      int freefixed, freefloat;
625
      int No_S = (!leaf && proc_uses_crt_env(son(crt_exp)) && proc_has_lv(son(crt_exp)));
626
      proc_name = crt_def->dec_u.dec_val.dec_id;
627
 
628
      setframe_flags(son(crt_exp),leaf);
629
 
630
      /* free s registers = GR3,GR4,..,GR18 */
631
      freefixed = 16;
632
 
633
      if (Has_fp) /* Has frame pointer */
634
      { 
635
	 freefixed--;
636
	 /* reserve GR3 as frame pointer (i.e. points to bottom of stack) */
637
      }
638
      if (Has_vsp) /* Has variable stack pointer */
639
      { 
640
	 freefixed--;
641
	 /* reserve GR4 for use as copy of the original stack pointer */
642
      }
643
      if (is_PIC_and_calls)
644
      {
645
	 freefixed--;
646
	 /* best reserve GR5 for use as a copy of GR19 */
647
      }
648
      if (Has_vcallees)
649
      {
650
	 pr->callee_sz = 0; /*  Don't know callee_sz  */
651
      }
652
 
653
      real_reg[1] = GR4;
654
      real_reg[2] = GR5;
655
      if (Has_fp)
656
      {
657
	 if (is_PIC_and_calls && !Has_vsp)
658
	    real_reg[2] = GR4;
659
      }
660
      else
661
      {
662
	 if (Has_vsp)
663
	 {
664
	    if (is_PIC_and_calls)
665
	       real_reg[2] = GR3;
666
	    else
667
	       real_reg[1] = GR3;
668
	 }
669
	 else
670
	 if (is_PIC_and_calls)
671
	 {
672
	    real_reg[1] = GR3;
673
	    real_reg[2] = GR4;
674
	 }
675
      }
676
 
677
      /* +++ create float s regs for leaf? */
678
      freefloat = 0;		/* none, always the same */
679
 
680
      /* estimate usage of tags in body of proc */
681
      if (!No_S)
682
	 w = weightsv(UNITWEIGHT, bro(son(son(crt_exp))));
683
 
684
      /* reg and stack allocation for tags */
685
      forrest = regalloc(bro(son(son(crt_exp))), freefixed, freefloat, 0);
686
 
687
      /* reg and stack allocation for tags */
688
      pr->spacereqproc = forrest;
689
 
690
      set_up_frame(son(crt_exp));
691
    }
692
  }
693
 
694
 
695
  /*  Set up main_globals and output global definitions. */
696
  i = 0;
697
  for(crt_def=top_def; crt_def!=(dec*)0; crt_def=crt_def->def_next)
698
  {
699
     i++;
700
  }
701
  main_globals_index = i;
702
  main_globals = (dec**) xcalloc(main_globals_index,sizeof(dec*));
703
  i = 0;
704
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
705
  {
706
     main_globals[i] = crt_def;
707
     main_globals[i]->dec_u.dec_val.sym_number = i;
708
     i++;
709
  }
710
 
711
  for (crt_def = top_def; crt_def != (dec *) 0; crt_def = crt_def->def_next)
712
  {
713
     exp tg = crt_def->dec_u.dec_val.dec_exp;
714
     char *id = crt_def->dec_u.dec_val.dec_id;
715
     bool extnamed = (bool) crt_def->dec_u.dec_val.extnamed;
716
     if ( son(tg)==nilexp && no(tg)!=0 && extnamed )
717
     {
718
	outs("\t.IMPORT\t");
719
	outs(id);
720
	outs( name(sh(tg))==prokhd ? (isvar(tg) ? ",DATA\n" : ",CODE\n") : ",DATA\n" );
721
     }
722
     else
723
     if ( son(tg) != nilexp && (extnamed || no(tg) != 0))
724
     {
725
	if (name(son(tg)) != proc_tag && name(son(tg)) != general_proc_tag)
726
	{
727
	   /* evaluate all outer level constants */
728
	   instore is;
729
	   long symdef = crt_def->dec_u.dec_val.sym_number + 1;
730
	   if ( isvar ( tg ) )
731
	      symdef = -symdef ;
732
	   if (extnamed && !(is_zero(son(tg))))
733
	   {
734
     	      outs("\t.EXPORT\t");
735
	      outs(id ) ;
736
	      outs(",DATA\n"); 
737
	   }
738
	   is = evaluated(son(tg),symdef);
739
	   if (diagnose)
740
	   {
741
	      diag_def = crt_def ;
742
	      stab_global(son(tg), id, extnamed);
743
	   }
744
 
745
	   if (is.adval)
746
	   {
747
	      setvar(tg);
748
	   }
749
	} 
750
     }
751
  }
752
 
753
 
754
  /* Uninitialized data local to module. */
755
 
756
  for ( crt_def=top_def; crt_def != (dec *) 0; crt_def=crt_def->def_next )
757
  {
758
     exp tg = crt_def->dec_u.dec_val.dec_exp;
759
     char *id = crt_def->dec_u.dec_val.dec_id;
760
     bool extnamed = (bool) crt_def->dec_u.dec_val.extnamed;
761
     if (son(tg) == nilexp && no(tg)!=0 && !extnamed )
762
     {
763
	shape s = crt_def->dec_u.dec_val.dec_shape;
764
	ash a;
765
	long size;
766
	int align;
767
	a = ashof(s);
768
	size = (a.ashsize + 7) >> 3;
769
	align = ( ( a.ashalign > 32 || a.ashsize > 32 ) ? 8 : 4 ) ;
770
	if (size>8)
771
	   insection( bss_section );
772
	else
773
	   insection( shortbss_section );
774
	outs("\t.ALIGN\t");
775
	outn( align);
776
	outs(id);
777
	outs("\t.BLOCKZ\t");
778
	outn( size) ;
779
     }
780
  }
781
 
782
  /* Translate the procedures. */
783
 
784
  if (xdb)
785
  {
786
     /*  XDB requires the procedures to be translated in the order
787
	 that they appear in the c source file.  */
788
     int n,j;
789
     for (n=0; n<noprocs; n++)
790
	for (j=n+1; j<noprocs; j++)
791
	{
792
	   if ( src_line[n] > src_line[j] )
793
	   {
794
	      int srcl = src_line[n];
795
	      dec *pdef;
796
	      src_line[n] = src_line[j];
797
	      src_line[j] = srcl;
798
	      pdef = proc_def_trans_order[n];
799
	      proc_def_trans_order[n] = proc_def_trans_order[j];
800
	      proc_def_trans_order[j] = pdef;
801
 
802
	   }
803
	}
804
   }
805
   else
806
   {
807
#if TRANSLATE_GLOBALS_FIRST
808
      /*  Translate the global procedures first.  */  
809
      int fstat = 0, lglob = noprocs-1;
810
      while ( fstat<lglob )
811
      {
812
	 while( fstat<noprocs && proc_def_trans_order[fstat]->dec_u.dec_val.extnamed )
813
	    fstat++;
814
	 while( lglob>0 && !proc_def_trans_order[lglob]->dec_u.dec_val.extnamed )
815
	    lglob--;
816
	 if ( fstat<lglob )
817
	 {
818
	    dec *pdef;
819
	    pdef = proc_def_trans_order[fstat];
820
	    proc_def_trans_order[fstat] = proc_def_trans_order[lglob];
821
	    proc_def_trans_order[lglob] = pdef;
822
	    fstat++;
823
	    lglob--;
824
	 }
825
      }
826
#endif
827
   }
828
 
829
  for( next_proc_def=0; next_proc_def < procno; next_proc_def++ )
830
  {
831
     exp tg, crt_exp;
832
     char *id;
833
     bool extnamed;
834
     procrec *pr;
835
     crt_def = proc_def_trans_order[next_proc_def];
836
     tg = crt_def->dec_u.dec_val.dec_exp;
837
     id = crt_def->dec_u.dec_val.dec_id;
838
     extnamed = (bool) crt_def->dec_u.dec_val.extnamed;
839
 
840
     if ( no(tg)!=0 || extnamed )
841
     {
842
	crt_exp = crt_def->dec_u.dec_val.dec_exp;
843
	pr = & procrecs[no(son(crt_exp))];
844
	insection(text_section);    
845
	outnl();
846
	outnl();
847
	if (diagnose)
848
	{
849
	   diag_def = crt_def ;
850
	   stab_proc(son(tg), id, extnamed);
851
	}
852
	seed_label();		/* reset label sequence */
853
	settempregs(son(tg));	/* reset getreg sequence */
854
 
855
	first = (labexp) malloc(sizeof(struct labexp_t));
856
	first->e = (exp) 0;
857
	first->next = (labexp) 0;
858
	current = first;
859
 
860
	proc_name=id;
861
	code_here(son(tg), tempregs, nowhere);
862
 
863
	outs( "\t.PROCEND\n\t;" ) ;  
864
	outs(id);
865
	if (xdb)
866
	{
867
#if _SYMTAB_INCLUDED
868
	   close_function_scope(res_label);
869
	   outnl();
870
	   outs("_" ) ;  
871
	   outs(id);
872
	   outs("_end_" ) ;  
873
#endif
874
	}
875
	outnl();
876
	outnl();
877
	if (extnamed)
878
	{
879
	   outs("\t.EXPORT ");
880
	   outs(id);
881
	   outs(",ENTRY");
882
	   outs(export);
883
	   outnl();
884
	   outnl();
885
	   outnl();
886
	}
887
	if ( first->next != (labexp)0 )
888
	{ 
889
	   exp e,z;
890
	   labexp p,next;
891
	   ash a;
892
	   int lab,byte_size;
893
	   outs("\n\n");
894
	   next = first->next;
895
	   do
896
	   {
897
	      e = next->e;
898
	      z = e;
899
	      a = ashof(sh(e));
900
	      lab = next->lab;
901
	      if (is_zero(e))
902
	      {
903
		 byte_size = (a.ashsize+7) >> 3;
904
		 if (byte_size>8)
905
		    insection(bss_section);
906
		 else
907
		    insection(shortbss_section);
908
		 if (a.ashalign > 32 || a.ashsize > 32 )
909
		    set_align(64);
910
		 else
911
		    set_align(32);
912
		 outs( ext_name(lab) );
913
		 outs("\t.BLOCK\t");
914
		 outn(byte_size);
915
		 outnl();
916
	      }
917
	      else
918
	      {
919
		 insection(data_section);
920
		 if (a.ashalign > 32 || a.ashsize > 32 )
921
		    set_align(64);
922
		 else
923
		    set_align(32);
924
		 outs( ext_name(lab) );
925
		 outnl();
926
		 evalone(z,0);
927
		 if (a.ashalign>32)
928
		    set_align(64);
929
	      }
930
	      next = next->next;
931
	   }
932
	   while (next!=0);
933
	   next = first;
934
	   do
935
	   {
936
	      p = next->next;
937
	      free(next);
938
	      next = p;
939
	   }
940
	   while (next!=0);
941
	   outs("\t.CODE\n\n\n");
942
	}
943
	else
944
	   free(first);
945
     } 
946
  }
947
 
948
  return;
949
}
950
 
951
void translate_tagdef 
952
    PROTO_Z ()
953
{
954
  return;
955
}
956
 
957
void translate_unit 
958
    PROTO_Z ()
959
{
960
  if (separate_units)
961
  {
962
    dec *crt_def;
963
 
964
    translate_capsule();
965
    crt_def = top_def;
966
    while (crt_def != (dec *) 0)
967
    {
968
      exp crt_exp = crt_def->dec_u.dec_val.dec_exp;
969
 
970
      no(crt_exp) = 0;
971
      pt(crt_exp) = nilexp;
972
      crt_def = crt_def->def_next;
973
    };
974
    crt_repeat = nilexp;
975
    repeat_list = nilexp;
976
  };
977
  return;
978
}
979
 
980
 
981
 
982
/*
983
    EXIT TRANSLATOR
984
*/
985
 
986
void exit_translator
987
    PROTO_Z ()
988
{
989
    outnl();
990
    outnl();
991
    outnl();
992
    outnl();
993
    import_millicode();
994
#if use_long_double
995
    import_long_double_lib();
996
#endif
997
    outnl();
998
    outnl();
999
    if (xdb)
1000
    {
1001
#ifdef _SYMTAB_INCLUDED
1002
       output_DEBUG();
1003
       outnl();
1004
       outnl();
1005
#endif
1006
    }
1007
    outs("\t.END\n");
1008
    return ;
1009
}
1010
 
1011
 
1012
 
1013
 
1014
 
1015
 
1016
 
1017
 
1018
 
1019
 
1020
 
1021
 
1022
 
1023
 
1024
 
1025
 
1026
 
1027
 
1028