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