Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 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
$Author: release $
33
$Date: 1998/02/04 10:43:45 $
34
$Revision: 1.2 $
35
$Log: translate.c,v $
36
 * Revision 1.2  1998/02/04  10:43:45  release
37
 * Changes during testing.
38
 *
39
 * Revision 1.1.1.1  1998/01/17  15:56:07  release
40
 * First version to be checked into rolling release.
41
 *
42
 * Revision 1.11  1996/04/24  08:55:54  currie
43
 * Case may require 3 regs
44
 *
45
 * Revision 1.10  1996/01/17  11:27:11  currie
46
 * proc with no diagnostics
47
 *
48
 * Revision 1.9  1996/01/12  10:06:14  currie
49
 * AVS - env_offset + main declared but not d3efined
50
 *
51
 * Revision 1.8  1995/10/25  13:48:29  currie
52
 * change to position of .glob
53
 *
54
 * Revision 1.7  1995/10/02  10:30:35  currie
55
 * env_offset + -g (PIC)
56
 *
57
 * Revision 1.6  1995/09/20  14:23:10  currie
58
 * callee-list blunder + fix for silliness in ultrix assembler
59
 *
60
 * Revision 1.4  1995/09/12  10:59:45  currie
61
 * gcc pedanttry
62
 *
63
 * Revision 1.3  1995/08/16  16:07:14  currie
64
 * Shortened some .h names
65
 *
66
 * Revision 1.2  1995/06/28  12:15:26  currie
67
 * New make_stack_limit etc
68
 *
69
 * Revision 1.1  1995/04/13  09:08:06  currie
70
 * Initial revision
71
 *
72
***********************************************************************/
73
#include "config.h"
74
#include "cross_config.h"
75
 
76
#ifndef CROSS_INCLUDE
77
#include <symconst.h>
78
#else
79
#include CROSS_INCLUDE/symconst.h>
80
#endif
81
 
82
#include "common_types.h"
83
#include "symtab.h"
84
#include "installglob.h"
85
#include "tags.h"
86
#include "exp.h"
87
#include "expmacs.h"
88
#include "optimise.h"
89
#include "flags.h"
90
#include "shapemacs.h"
91
#include "tempdecs.h"
92
#include "weights.h"
93
#include "procrectypes.h"
94
#include "regalloc.h"
95
#include "new_code.h"
96
#include "code_here.h"
97
#include "eval.h"
98
#include "bitsmacs.h"
99
#include "needs_scan.h"
100
#include "ibinasm.h"
101
#include "syms.h"
102
#include "out_ba.h"
103
#include "xalloc.h"
104
#include "new_symbol.h"
105
#include "mipsdiags.h"
106
#include "extern_adds.h"
107
#include "mips_ins.h"
108
#include "machine.h"
109
#include "main.h"
110
#include "frames.h"
111
#include "basicread.h"
112
#include "getregs.h"
113
#include "locate.h"
114
#include "me_fns.h"
115
 
116
extern long aritherr_lab;
117
extern long stackerr_lab;
118
 
119
 
120
extern exp find_named_tg PROTO_S ((char*, shape));
121
extern shape f_top;
122
extern shape f_proc;
123
 
124
procrec * procrecs;
125
dec ** main_globals;
126
int main_globals_index;
127
 
128
extern long fscopefile;
129
extern bool do_extern_adds;
130
 
131
ash ashof
132
    PROTO_N ( (s) )
133
    PROTO_T ( shape s )
134
{
135
	ash a;
136
	a.ashsize = shape_size(s);
137
	a.ashalign = shape_align(s);
138
	return a;
139
}
140
 
141
 
142
bool not_reserved
143
    PROTO_N ( (id) )
144
    PROTO_T ( char *id )
145
{
146
  /* various identifier reserved by MIPS */
147
  if (!strcmp (id, "edata"))
148
    return (0);
149
  if (!strcmp (id, "etext"))
150
    return (0);
151
  if (!strcmp (id, "end"))
152
    return (0);
153
  if (!strcmp (id, "_ftext"))
154
    return (0);
155
  if (!strcmp (id, "_fdata"))
156
    return (0);
157
  if (!strcmp (id, "_fbss"))
158
    return (0);
159
  if (!strcmp (id, "_gp"))
160
    return (0);
161
  if (!strcmp (id, "_procedure_table"))
162
    return (0);
163
  if (!strcmp (id, "_procedure_string_table"))
164
    return (0);
165
  return (1);
166
}
167
 
168
 
169
 
170
 
171
 
172
char varsize
173
    PROTO_N ( (sha) )
174
    PROTO_T ( shape sha )
175
{
176
  return (name(sha)==nofhd);
177
}
178
 
179
int current_symno;
180
 
181
void globalise_name
182
    PROTO_N ( (my_def) )
183
    PROTO_T ( dec * my_def )
184
{
185
	char *id = my_def -> dec_u.dec_val.dec_id;
186
        if (!my_def -> dec_u.dec_val.extnamed) return;
187
	if (as_file)
188
	  fprintf (as_file, "\t.globl\t%s\n", id);
189
	out_common (symnos[my_def->dec_u.dec_val.sym_number], iglobal);
190
 
191
}
192
 
193
void code_it
194
    PROTO_N ( (my_def) )
195
    PROTO_T ( dec * my_def )
196
{
197
  exp tg = my_def -> dec_u.dec_val.dec_exp;
198
  char *id = my_def -> dec_u.dec_val.dec_id;
199
  long symdef = my_def ->dec_u.dec_val.sym_number;
200
  bool extnamed =  my_def -> dec_u.dec_val.extnamed;
201
 
202
  static  space tempspace = {
203
      0, 0
204
    };
205
  if (symnos[symdef] <0) goto end; /* ? unused symbols */
206
 
207
  if (son (tg) != nilexp && (!extnamed || !is_comm(son(tg)))) {
208
    if (name (son (tg)) == proc_tag
209
		|| name(son(tg)) == general_proc_tag) {
210
        diag_descriptor * dd =  my_def -> dec_u.dec_val.diag_info;
211
	/* compile code for proc */
212
	if (as_file) {
213
	  fprintf (as_file,"\t.text\n\t.align 3\n");
214
	}
215
 
216
 
217
	out_common (0, itext);
218
	out_value (0, ialign, 3, 0);
219
	if (diagnose) {
220
	 if ( dd != (diag_descriptor*)0) {
221
	    sourcemark *sm = &dd -> data.id.whence;
222
	    stabd(fscopefile = find_file(sm->file->file.ints.chars),
223
	               sm->line_no.nat_val.small_nat);
224
	 }
225
	 else { stabd(0,1); /*no diagnostics for this proc */ }
226
	}
227
 
228
	globalise_name(my_def);
229
 
230
	if (as_file) fprintf(as_file, "\t.ent\t%s\n%s:\n", id, id);
231
 
232
	out_ent (current_symno = symnos[symdef], ient, 2);/* why 2? */
233
	out_common (symnos[symdef], ilabel);
234
	if (as_file) {
235
		fprintf (as_file,
236
			(diagnose) ? "\t.option O1\n" : "\t.option O2\n");
237
	}
238
 
239
	out_option (1, (diagnose) ? 1 : 2);
240
 
241
	symnoforstart (symdef, currentfile);
242
	settempregs (son(tg));
243
	code_here (son (tg), tempspace, nowhere);
244
	if (diagnose && dd != (diag_descriptor*)0) {
245
		stabd(fscopefile, currentlno+1);
246
	}
247
	if (as_file)
248
	  fprintf (as_file, "\t.end\t%s\n", id);
249
	out_common (symnoforend (my_def, currentfile), iend);
250
    }
251
    else {			/* global values */
252
 
253
	exp c = son (tg);
254
	IGNORE evaluated (c, (isvar (tg)) ? (-symdef - 1) : symdef + 1, my_def);
255
 
256
 
257
    };
258
  }
259
  else {	/* global declarations but no definitions or is_comm */
260
      long  size;
261
      shape s = (son(tg)==nilexp)?my_def -> dec_u.dec_val.dec_shape :
262
				sh(son(tg));
263
      size = (shape_size(s) + 7) >> 3;
264
 
265
      if ((isvar(tg) || name(s) != prokhd) && not_reserved (id)) {
266
	if ((son(tg) != nilexp && is_comm(son(tg)))
267
		|| (son(tg)==nilexp && varsize(sh(tg))) ) {
268
	  if (size !=0) { /* ? ? ! ? */
269
	     globalise_name(my_def);
270
	     if (as_file)
271
	        fprintf (as_file, "\t.comm\t%s %ld\n", id, size);
272
	      out_value (symnos[symdef], icomm, size, 1);
273
	  }
274
	}
275
	else {
276
	  if (as_file)
277
	    fprintf (as_file, "\t.extern\t%s %ld\n", id,
278
		size);
279
	  out_value (symnos[symdef], iextern, size, 1);
280
	}
281
      }
282
      else
283
	if (son (tg) == nilexp && !extnamed) {
284
	  if (size !=0) { /* ? ? ! ? */
285
	      if (as_file)
286
	        fprintf (as_file, "\t.lcomm\t%s %ld\n", id, size);
287
	      out_value (symnos[symdef], ilcomm, size, 1);
288
	  }
289
	}
290
 
291
  }
292
 
293
 
294
end:
295
  my_def -> dec_u.dec_val.processed = 1;
296
  return;
297
}
298
 
299
void mark_unaliased
300
    PROTO_N ( (e) )
301
    PROTO_T ( exp e )
302
{
303
  exp p = pt (e);
304
  bool ca = 1;
305
  while (p != nilexp && ca) {
306
    if (bro(p)==nilexp ||
307
       (!(last (p) && name (bro (p)) == cont_tag) &&
308
	!(!last (p) && last (bro (p)) && name (bro (bro (p))) == ass_tag)))
309
      ca = 0;
310
    p = pt (p);
311
  };
312
  if (ca)
313
    setcaonly (e);
314
  return;
315
}
316
 
317
void remove_unused
318
    PROTO_Z ()
319
{ dec ** sdef = &top_def;
320
  while (*sdef != (dec *) 0) {
321
    exp crt_exp = (*sdef) -> dec_u.dec_val.dec_exp;
322
    bool extnamed = (*sdef) -> dec_u.dec_val.extnamed;
323
    if (no(crt_exp) == 0 && !extnamed) {
324
	*sdef = (*sdef)->def_next;
325
    }
326
    else sdef = &((*sdef)->def_next);
327
  }
328
}
329
 
330
 
331
 
332
void translate_capsule
333
    PROTO_Z ()
334
{
335
  dec * my_def;
336
  int noprocs;
337
  int i;
338
 
339
  opt_all_exps ();
340
  remove_unused();
341
 
342
#ifdef INCLUDE_INITS
343
  my_def = top_def;
344
  while (my_def != (dec *) 0) {
345
        exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
346
	char * id = my_def -> dec_u.dec_val.dec_id;
347
	if (strcmp(id, "main")==0 && son(crt_exp)!= nilexp &&
348
		name(son(crt_exp)) == proc_tag) {
349
	   exp fn = me_obtain(find_named_tg("__DO_I_TDF", f_proc));
350
	   exp cll = getexp(f_top, nilexp, 0, fn, nilexp, 0, 0, apply_tag);
351
	   exp * dm = &son(son(crt_exp));
352
	   exp hld, seq;
353
	   bro(fn) = cll; setlast(fn);
354
	   while (name(*dm)==ident_tag && isparam(*dm)) dm = &bro(son(*dm));
355
	   /* dm is body of main after params */
356
	   hld = getexp(f_top, *dm, 0, cll, nilexp, 0, 1, 0);
357
	   seq = getexp(sh(*dm), bro(*dm), last(*dm), hld, nilexp, 0, 0, seq_tag);
358
	   bro(*dm) = seq; setlast(*dm);
359
	   bro(cll) = hld; setlast(cll);
360
	   *dm = seq;
361
	   break;
362
	}
363
        my_def = my_def -> def_next;
364
   }
365
#endif
366
 
367
    /* mark static unaliased */
368
  my_def = top_def;
369
  while (my_def != (dec *) 0) {
370
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
371
    if (son (crt_exp) != nilexp &&
372
	!my_def -> dec_u.dec_val.extnamed &&
373
	isvar (crt_exp))
374
      mark_unaliased (crt_exp);
375
    my_def = my_def -> def_next;
376
  };
377
 
378
  noprocs = 0;
379
  my_def = top_def;
380
  while (my_def != (dec *) 0) {
381
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
382
    if (son (crt_exp) != nilexp
383
        && (name (son (crt_exp)) == proc_tag ||
384
		name(son(crt_exp)) == general_proc_tag)) {
385
      noprocs++;
386
    }
387
    my_def = my_def -> def_next;
388
  }
389
  /* count procs */
390
 
391
  procrecs = (procrec *) xcalloc (noprocs, sizeof (procrec));
392
  noprocs = 0;
393
 
394
  my_def = top_def;
395
  while (my_def != (dec *) 0) {
396
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
397
    if (son (crt_exp) != nilexp &&
398
	(name (son (crt_exp)) == proc_tag || name(son(crt_exp)) == general_proc_tag)) {
399
      no (son (crt_exp)) = noprocs++;
400
      /* put index into procrecs in no(proc) */
401
    }
402
    my_def = my_def -> def_next;
403
  }
404
 
405
  if (do_extern_adds) {
406
	usages = (exp*)xcalloc(noprocs, sizeof(exp));
407
	my_def = top_def;
408
  	while (my_def != (dec *) 0) {
409
		exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
410
		if (son(crt_exp) == nilexp && isvar(crt_exp) ) {
411
			global_usages(crt_exp, noprocs);
412
			/* try to identify globals ptrs in procs */
413
		}
414
		my_def = my_def -> def_next;
415
	}
416
  }
417
 
418
  if (diagnose && nofds !=0) {
419
      init_table_space (nofds, noprocs);
420
      add_dense_no (0, 0);
421
      add_dense_no (0, 0);	/* dont know why!! */
422
      symnosforfiles ();
423
      stab_types();
424
  }
425
  else {
426
    init_table_space (1,noprocs);
427
    add_dense_no (0, 0);
428
    add_dense_no (0, 0);	/* dont know why!! */
429
    IGNORE new_lsym_d ("NOFILE.c", 0, stFile, scText, 0, 0);
430
  };
431
 
432
  /* scan to put everything in MIPS form */
433
 
434
  my_def = top_def;
435
  while (my_def != (dec *) 0) {
436
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
437
    if (son (crt_exp) != nilexp
438
	&& (name (son (crt_exp)) == proc_tag ||
439
		name(son(crt_exp))== general_proc_tag)) {
440
      procrec * pr = &procrecs[no (son (crt_exp))];
441
      exp * st = &son(crt_exp);
442
      pr -> needsproc = scan (st, &st);
443
      pr->callee_size = (callee_size+63)&~63;
444
    }
445
    my_def = my_def -> def_next;
446
  }
447
 
448
 
449
  /* calculate the break points for register allocation and do it */
450
  my_def = top_def;
451
  while (my_def != (dec *) 0) {
452
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
453
    if (son (crt_exp) != nilexp
454
        && ( name (son (crt_exp)) == proc_tag ||
455
		name(son(crt_exp))== general_proc_tag)) {
456
      procrec * pr = &procrecs[no (son (crt_exp))];
457
      needs * ndpr = & pr->needsproc;
458
      long pprops = (ndpr->propsneeds);
459
      bool leaf = (pprops & anyproccall) == 0;
460
      spacereq forrest;
461
      int   freefixed = 8;	/* NO OF S_REGISTERS */
462
      int   freefloat = 6;	/* NO OF S $f REGISTERS */
463
 
464
      setframe_flags(son(crt_exp), leaf);
465
      if (!Has_fp) freefixed++; /* can use $30 as normal caller save */
466
 
467
      if (Has_vcallees) { freefixed--; }
468
 
469
      if (!No_S) IGNORE weightsv (1.0, bro (son (son (crt_exp))));
470
      /* estimate usage of tags in body of proc */
471
 
472
      forrest = regalloc (bro (son (son (crt_exp))), freefixed, freefloat,
473
				(PIC_code && !leaf)?32:0);
474
      /* reg and stack allocation for tags */
475
 
476
      pr -> spacereqproc = forrest;
477
 
478
      setframe_info(son(crt_exp));
479
    }
480
    my_def = my_def -> def_next;
481
  }
482
 
483
  /* put defs in main globals and set up symnos*/
484
  my_def = top_def;
485
  main_globals_index = 0;
486
  while (my_def != (dec*) 0) {
487
  	main_globals_index++;
488
  	my_def = my_def -> def_next;
489
  }
490
 
491
  data_lab = (main_globals_index > 33)?main_globals_index:33;
492
  main_globals = (dec**)xcalloc(main_globals_index, sizeof(dec*));
493
  symnos = (int *) xcalloc (main_globals_index, sizeof (int));
494
 
495
  my_def = top_def;
496
  for (i=0; i < main_globals_index; i++) {
497
  	main_globals[i] = my_def;
498
  	my_def = my_def -> def_next;
499
  }
500
 
501
 
502
    /* ... and set in the position and "addresses" of the externals */
503
  for (i = 0; i < main_globals_index; i++) {
504
    exp tg = main_globals[i] -> dec_u.dec_val.dec_exp;
505
    char *id = main_globals[i] -> dec_u.dec_val.dec_id;
506
    bool extnamed = main_globals[i] -> dec_u.dec_val.extnamed;
507
    diag_descriptor * dinf = main_globals[i] -> dec_u.dec_val.diag_info;
508
    main_globals[i] ->dec_u.dec_val.sym_number = i;
509
    if ( no (tg) != 0 || (extnamed && son(tg) != nilexp)
510
		|| strcmp(id,"__TDFhandler") == 0
511
		|| strcmp(id,"__TDFstacklim")==0
512
	) {
513
     	if(no(tg)==1 && son(tg)==nilexp && dinf != (diag_descriptor *)0
514
 		 /* diagnostics only! */ ) {
515
    		symnos[i]= -1;
516
    	}
517
    	else {
518
          no (tg) = (i + 1) * 64 + 32;
519
          symnos[i] = symnoforext (main_globals[i], mainfile);
520
        }
521
    }
522
    else
523
      symnos[i] = -1;
524
  };
525
 
526
 
527
 
528
  setregalt (nowhere.answhere, 0);
529
  nowhere.ashwhere.ashsize = 0;
530
  nowhere.ashwhere.ashsize = 0;
531
 
532
  if (as_file) {
533
    fprintf (as_file, "\t.verstamp %d %d\n", majorno, minorno);
534
 
535
    if (PIC_code) {
536
	fprintf (as_file, "\t.option pic2\n");
537
    }
538
    else {
539
        fprintf (as_file, (diagnose) ? "\t.option O1\n" : "\t.option O2\n");
540
    }
541
  }
542
 
543
  out_verstamp (majorno, minorno);
544
				/* this is the only? use of these nos, to
545
				   satisfy as1 */
546
  if (PIC_code) {
547
	out_option(2, 2);
548
  }
549
  else
550
  { out_option (1, (diagnose) ? 1 : 2); }
551
 
552
  if (diagnose && nofds!=0) {
553
    stab_file (0);
554
  }
555
  else
556
  {
557
    currentfile = 0;
558
  }
559
 
560
 
561
  /* compile procedures, evaluate constants, put in the .comm entries for
562
     undefined objects */
563
 
564
  my_def = top_def;
565
 
566
/*
567
  while (my_def != (dec *) 0) {
568
    exp tg = my_def -> dec_u.dec_val.dec_exp;
569
    char *id = my_def -> dec_u.dec_val.dec_id;
570
    bool extnamed = my_def -> dec_u.dec_val.extnamed;
571
    if (son (tg) != nilexp && (extnamed || no (tg) != 0 || !strcmp (id, "main"))) {
572
      if (extnamed) {
573
	if (as_file)
574
	  fprintf (as_file, "\t.globl\t%s\n", id);
575
	out_common (symnos[my_def->dec_u.dec_val.sym_number], iglobal);
576
      }
577
    }
578
    my_def = my_def -> def_next;
579
  }
580
*/
581
  my_def = top_def;
582
 
583
  while (my_def != (dec *) 0) {
584
    if (!my_def -> dec_u.dec_val.processed)
585
       code_it (my_def);
586
    my_def = my_def -> def_next;
587
  };
588
 
589
 
590
  return;		/* return 1 for error, 0 for good */
591
 
592
 
593
}
594
void translate_unit
595
    PROTO_Z ()
596
{
597
  if (separate_units)
598
   {
599
     dec * my_def;
600
     translate_capsule();
601
     my_def = top_def;
602
     while (my_def != (dec *) 0) {
603
       exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
604
       no(crt_exp) = 0;
605
       pt(crt_exp) = nilexp;
606
       my_def = my_def -> def_next;
607
     };
608
     crt_repeat = nilexp;
609
     repeat_list = nilexp;
610
   };
611
  return;
612
}
613
 
614
 
615
void translate_tagdef
616
    PROTO_Z ()
617
{
618
  return;
619
}