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
$Author: release $
33
$Date: 1998/01/17 15:56:05 $
34
$Revision: 1.1.1.1 $
35
$Log: eval.c,v $
36
 * Revision 1.1.1.1  1998/01/17  15:56:05  release
37
 * First version to be checked into rolling release.
38
 *
39
 * Revision 1.13  1996/07/16  15:59:47  currie
40
 * alloca alignment
41
 *
42
Revision 1.12  1996/06/17 12:38:31  currie
43
Bitsfield in eval
44
 
45
Revision 1.11  1996/06/13 09:20:37  currie
46
Bitf compound starting at non-0 offset
47
 
48
Revision 1.10  1996/06/04 15:42:05  currie
49
include general_proc_tag in make_compound
50
 
51
 * Revision 1.9  1996/01/09  12:00:36  currie
52
 * var callee par in reg
53
 *
54
 * Revision 1.8  1995/12/08  11:20:04  currie
55
 * Constant offsets + allocaerr_lab
56
 *
57
 * Revision 1.7  1995/10/25  13:48:19  currie
58
 * change to position of .glob
59
 *
60
 * Revision 1.6  1995/09/12  10:59:18  currie
61
 * gcc pedanttry
62
 *
63
 * Revision 1.5  1995/08/16  16:06:35  currie
64
 * Shortened some .h names
65
 *
66
 * Revision 1.4  1995/08/15  09:19:14  currie
67
 * Dynamic callees + trap_tag
68
 *
69
 * Revision 1.3  1995/08/09  10:53:36  currie
70
 * apply_general bug
71
 *
72
 * Revision 1.2  1995/06/28  12:15:19  currie
73
 * New make_stack_limit etc
74
 *
75
 * Revision 1.1  1995/04/13  09:08:06  currie
76
 * Initial revision
77
 *
78
***********************************************************************/
79
/*****************************************************************
80
		eval.c
81
 
82
	The main procedure defined here is evaluated which ouputs
83
assembler for data. The parameters are an evaluated exp and an index
84
into the table of externals (or 0 meaning anonymous). XXX
85
*****************************************************************/
86
 
87
#include "config.h"
88
#include "common_types.h"
89
#include "addrtypes.h"
90
#include "tags.h"
91
#include "expmacs.h"
92
#include "exp.h"
93
#include "exptypes.h"
94
#include "maxminmacs.h"
95
#include "shapemacs.h"
96
#include "flpttypes.h"
97
#include "flpt.h"
98
#include "syms.h"
99
#include "out_ba.h"
100
#include "main.h"
101
#include "ibinasm.h"
102
#include "frames.h"
103
#include "procrectypes.h"
104
#include "f64.h"
105
#include "eval.h"
106
#include "basicread.h"
107
 
108
extern void globalise_name PROTO_S ((dec*));
109
extern  procrec * procrecs;
110
 
111
long  G_number = 64;		/* to give choice of .sdata or data */
112
 
113
int   data_lab = 33;
114
 
115
int next_data_lab
116
    PROTO_Z ()
117
{	/*  anonymous label in data space - $$n in assember o/p */
118
        return data_lab++;
119
}
120
 
121
int next_dlab_sym
122
    PROTO_Z ()
123
{	/* as above - but also gives it a symno for .G output */
124
        symnofordata (data_lab);
125
  return data_lab++;
126
}
127
 
128
 
129
/* various pieces of info for outputting data depending on shape */
130
mm scmm = {
131
  127, -128, "\t.byte %ld :%ld\n"
132
};
133
mm uscmm = {
134
  255, 0, "\t.byte %ld :%ld\n"
135
};
136
mm shmm = {
137
  0x7fff, 0xffff8000, "\t.half %ld :%ld\n"
138
};
139
mm ushmm = {
140
  0xffff, 0, "\t.half %ld :%ld\n"
141
};
142
mm swmm = {
143
  0x7fffffff, 0x80000000, "\t.word %ld :%ld\n"
144
};
145
mm uswmm = {
146
  0xffffffff, 0, "\t.word %ld :%ld\n"
147
};
148
 
149
/*************************************************************
150
maxmin
151
 
152
finds the data size from the range of an integer shape
153
**************************************************************/
154
mm maxmin
155
    PROTO_N ( (s) )
156
    PROTO_T ( shape s )
157
{
158
  switch (name (s)) {
159
    case scharhd:
160
      return scmm;
161
    case ucharhd:
162
      return uscmm;
163
    case swordhd:
164
      return shmm;
165
    case uwordhd:
166
      return ushmm;
167
    case slonghd:
168
      return swmm;
169
    case ulonghd:
170
      return uswmm;
171
    default: {
172
 
173
	return uswmm;
174
      }
175
  }
176
 
177
}
178
 
179
 
180
/**************************************************************
181
outlab
182
 
183
outputs the label parameter if non negative else interprets it
184
to be an index into the externals and outputs the identifier.
185
**************************************************************/
186
 
187
void outlab
188
    PROTO_N ( (l) )
189
    PROTO_T ( int l )
190
{
191
  if (l >= 0) {
192
    fprintf (as_file, "$$%d", l);
193
  }
194
  else {
195
    char *extname = main_globals[-l - 1] -> dec_u.dec_val.dec_id;
196
    fprintf (as_file, "%s", extname);
197
  }
198
}
199
 
200
 
201
 
202
 
203
 
204
/***************************************************************
205
evalone
206
 
207
This procedure outputs all non-pack expressions and puts in label
208
values for the pack exps (putting new label numbers into their number
209
fields) which it accumulates for later application in the ptr parameter
210
of evalone. This is done to cope with the fact that the exp to evaluated
211
may contain pack operations which are graph-like .
212
***************************************************************/
213
long  evalexp
214
    PROTO_N ( (e) )
215
    PROTO_T ( exp e )
216
{
217
  switch (name(e)) {
218
    case  val_tag: case null_tag: case top_tag:{
219
	if (name(sh(e)) == offsethd && al2(sh(e)) >= 8) {
220
		return (no(e)>>3);
221
	}
222
        return (no (e));
223
    }
224
    case bitf_to_int_tag:
225
      {
226
	return evalexp (son (e));
227
      }
228
    case int_to_bitf_tag:
229
      {
230
	ash a;
231
	long  w = evalexp (son (e));
232
	a = ashof (sh (e));
233
	if (a.ashalign != 1) {
234
	  failer ("should be align 1");
235
	}
236
	if (a.ashsize != 32) {
237
	  w &= ((1 << a.ashsize) - 1);
238
	}
239
	return w;
240
      }
241
    case not_tag:
242
      {
243
	return (~evalexp (son (e)));
244
      }
245
    case and_tag:
246
      {
247
	return (evalexp (son (e)) & evalexp (bro (son (e))));
248
      }
249
    case or_tag:
250
      {
251
	return (evalexp (son (e)) | evalexp (bro (son (e))));
252
      }
253
    case xor_tag:
254
      {
255
	return (evalexp (son (e)) ^ evalexp (bro (son (e))));
256
      }
257
 
258
    case shr_tag:
259
      {
260
	return (evalexp (son (e)) >> evalexp (bro (son (e))));
261
      }
262
 
263
    case shl_tag:
264
      {
265
	return (evalexp (son (e)) << evalexp (bro (son (e))));
266
      }
267
 
268
    case concatnof_tag:
269
      {
270
	ash a;
271
	long  wd = evalexp (son (e));
272
	a = ashof (sh (son (e)));
273
	return (wd | (evalexp (bro (son (e))) << a.ashsize));
274
      }
275
 
276
    case clear_tag:
277
      {
278
	ash a;
279
	a = ashof (sh (e));
280
	if (a.ashsize > 32)
281
	  failer ("clearshape");
282
	return 0;
283
      }
284
   case env_offset_tag:
285
   case general_env_offset_tag: {
286
   	return frame_offset(son(e));
287
   }
288
   case env_size_tag: {
289
	exp tg = son(son(e));
290
	procrec * pr = &procrecs[no(son(tg))];
291
	return((pr->frame_size+pr->callee_size) >> 3);
292
   }
293
   case offset_add_tag:{
294
    	return (evalexp(son(e))+evalexp(bro(son(e))));
295
   }
296
   case offset_max_tag:{
297
    	return (max(evalexp(son(e)),evalexp(bro(son(e)))));
298
   }
299
   case offset_pad_tag:{
300
	return( rounder(evalexp(son(e)), shape_align(sh(e))));
301
   }
302
   case offset_mult_tag:{
303
    	return (evalexp(son(e))*evalexp(bro(son(e))));
304
   }
305
   case offset_div_tag:case offset_div_by_int_tag:{
306
    	return (evalexp(son(e))/evalexp(bro(son(e))));
307
   }
308
   case offset_subtract_tag:{
309
    	return (evalexp(son(e))-evalexp(bro(son(e))));
310
   }
311
   case offset_negate_tag: {
312
	return (- evalexp(son(e)));
313
   }
314
    default:
315
      failer ("tag not in evalexp");
316
  }
317
  return 0;
318
}
319
 
320
void set_align
321
    PROTO_N ( (al) )
322
    PROTO_T ( int al )
323
{
324
	if (al<16) return;
325
	if (as_file)
326
	  fprintf (as_file, "\t.align%s\n",
327
	      (al == 16) ? " 1" :
328
	      ((al == 32) ? " 2" :
329
		((al == 64) ? " 3" : " 0")));
330
	out_value (0, ialign, (al == 16) ? 1 :
331
	    ((al == 32) ? 2 :
332
	      ((al == 64) ? 3 : 0)), 0);
333
 
334
}
335
 
336
int eval_al
337
    PROTO_N ( (s) )
338
    PROTO_T ( shape s )
339
{
340
	if (shape_align(s)!=1) return shape_align(s);
341
	if (shape_size(s) <=8) return 8;
342
	if (shape_size(s) <=16) return 16;
343
	return 32;
344
}
345
 
346
void oneval
347
    PROTO_N ( (val, al, rep) )
348
    PROTO_T ( int val X int al X int rep )
349
{
350
	char *as = (al <= 8) ? "\t.byte %ld :%ld\n"
351
	:     ((al <= 16) ? "\t.half %ld :%ld\n"
352
	  :     "\t.word %ld :%ld\n");
353
	set_align(al);
354
	if (as_file)
355
	  fprintf (as_file, as, val, rep);
356
	out_value (0, (al <= 8) ? ibyte : ((al <= 16) ? ihalf : iword), val, rep);
357
}
358
 
359
 
360
 
361
void evalone
362
    PROTO_N ( (e, rep) )
363
    PROTO_T ( exp e X long rep )
364
{
365
				/* outputs constant expression e, rep
366
				   times;  */
367
  ash a;
368
  a = ashof (sh (e));
369
  switch (name (e)) {
370
 
371
    case string_tag:
372
      {
373
        long char_size = props(e);
374
	long  strsize = shape_size(sh(e))/char_size;
375
	char *st = nostr(e);
376
	long  strs = shape_size(sh(e))>>3;
377
	int   i,j;
378
	if (rep != 1 && as_file)
379
	  fprintf (as_file, "\t.repeat %ld\n", rep);
380
	set_align(char_size);
381
	if (as_file) {
382
	  for (j=0; j< strsize; ) {
383
	    switch(char_size) {
384
	      case 8: fprintf (as_file, "\t.byte "); break;
385
	      case 16: fprintf (as_file, "\t.half "); break;
386
	      case 32: fprintf (as_file, "\t.word "); break;
387
	    }
388
	    for (i = j; i < strsize && i-j < 8; i++) {
389
	      switch (char_size) {
390
	        case 8:fprintf (as_file, "0x%x ", st[i]); break;
391
	        case 16:fprintf (as_file, "0x%x ", ((short *)st)[i]); break;
392
	        case 32:fprintf (as_file, "0x%lx ", ((long *)st)[i]); break;
393
	      }
394
	    }
395
	    j =i;
396
	    fprintf (as_file, "\n");
397
	  }
398
	}
399
	if (rep != 1 && as_file)
400
	  fprintf (as_file, "\t.endr\n");
401
	out_chars (0, iascii, strs, rep);
402
	out_data (st, strs);
403
	return;
404
      }
405
    case real_tag:
406
      {
407
	r2l   n;
408
	int i;
409
	n = real2longs_IEEE(&flptnos[no (e)], (a.ashsize>32)?1:0);
410
	set_align(a.ashalign);
411
	for(i=0; i<rep; i++) {
412
		if (BIGEND) {
413
			if(a.ashsize>32)  oneval(n.i2, 32, 1);
414
			oneval(n.i1, 32, 1);
415
		}
416
		else {
417
              		oneval(n.i1, 32, 1);
418
          		if(a.ashsize>32) oneval(n.i2, 32, 1);
419
		}
420
        }
421
	return;
422
      }
423
    case null_tag: case top_tag:
424
      no (e) = 0;
425
    case val_tag:
426
      {
427
	if (shape_size(sh(e)) > 32) {
428
		flt64 temp;
429
		int ov;
430
		int i;
431
		if (isbigval(e)) {
432
			temp = flt_to_f64(no(e), 0, &ov);
433
		}
434
		else {
435
			temp.big = (is_signed(sh(e)) && no(e)<0)?-1:0;
436
			temp.small = no(e);
437
		}
438
		for(i=0; i<rep; i++) {
439
			oneval(temp.small, 32, 1);
440
			oneval(temp.big, 32, 1);
441
		}
442
		return;
443
	}
444
 
445
	oneval(evalexp(e), eval_al(sh(e)), rep);
446
	return;
447
      }
448
 
449
    case name_tag:
450
      {
451
	exp dc = son(e);
452
	dec * globdec= brog(dc);/* must be global name */
453
	char *nm = globdec -> dec_u.dec_val.dec_id;
454
	long symdef = globdec ->dec_u.dec_val.sym_number;
455
	if (!isvar(dc) && son(dc) != nilexp
456
		&& name(son(dc)) != proc_tag && name(son(dc)) != general_proc_tag
457
		&& no(e)==0
458
		&& shape_size(sh(e)) == shape_size(sh(son(dc)))  ) {
459
		evalone(son(dc), rep);
460
		return;
461
	}
462
  	set_align(32);
463
	if (as_file) {
464
	  if (no (e) == 0) {
465
	    fprintf (as_file, "\t.word %s : %ld\n", nm, rep);
466
	  }
467
	  else {
468
	    fprintf (as_file, "\t.word %s + %d :%ld\n", nm, no (e) / 8, rep);
469
	  }
470
	}
471
	out_value (symnos[symdef], iword, no (e) / 8, rep);
472
	return;
473
      }
474
    case compound_tag:  {
475
	exp tup = son (e);
476
	unsigned long val;
477
	bool first_bits=1;
478
	long bits_start =0;
479
	long offs =0;
480
 
481
	if (rep != 1)
482
	  failer ("CAN'T REP TUPLES");
483
	set_align(a.ashalign);
484
 
485
 
486
	for(;;) {
487
	     ash ae;
488
	     ae = ashof(sh(bro(tup)));
489
	     offs = no(tup);
490
	     if (ae.ashalign == 1) {
491
		unsigned long vb = evalexp(bro(tup));
492
		if (ae.ashsize != 32) {
493
		  vb = vb & ((1<<ae.ashsize)-1);
494
		}
495
                if (first_bits) {
496
		     val = 0;
497
                     first_bits=0;
498
                }
499
 
500
                if (offs - bits_start +ae.ashsize > 32) {
501
                   if (BIGEND) {
502
                      for(;;) {
503
                              oneval(val>>24, 8, 1);
504
                              val <<=8;
505
                              bits_start+=8;
506
                              if (offs-bits_start < 8) break;
507
                      }
508
                   }
509
                   else {
510
                     for(;;) {
511
                        oneval(val &255, 8,1);
512
                        val >>= 8;
513
                        bits_start += 8;
514
                        if (offs - bits_start  < 8)
515
                                 break;
516
                     }
517
                   }
518
                }
519
 
520
                if (offs - bits_start +ae.ashsize <= 32) {
521
                     if (BIGEND) {
522
			val |= (vb << (32 -offs+bits_start-ae.ashsize));
523
		     }
524
		     else {
525
                     	val |= (vb <<(offs-bits_start));
526
		     }
527
                }
528
                else {
529
                   failer("Constant bitfield does not fit into 32 bits");
530
                }
531
	     }
532
	     else {
533
	     	if (!first_bits) {
534
		    first_bits=1;
535
		    if (BIGEND) {
536
		   	for(;;) {
537
		   		oneval(val>>24, 8, 1);
538
		   		val <<=8;
539
		   		bits_start+=8;
540
		   		if (offs-bits_start <= 0) break;
541
		   	}
542
		     }
543
		     else {
544
                       for(;;) {
545
                          oneval(val &255, 8,1);
546
                          val >>=8;
547
                          bits_start += 8;
548
                          if ( offs - bits_start  <=0)
549
                                   break;
550
                       }
551
                     }
552
	  	}
553
		while (bits_start < offs) {
554
			oneval(0, 0, 1);
555
			bits_start+=8;
556
		}
557
		evalone(bro(tup),1);
558
		bits_start += shape_size(sh(bro(tup)));
559
	     }
560
 
561
	     if (last(bro(tup))) {
562
	     	     offs += ae.ashsize;
563
		     offs = (offs+7)&~7;
564
		     for(;!first_bits;) {
565
                      if (BIGEND) {
566
                            oneval(val>>24, 8, 1);
567
                            val <<=8;
568
                            bits_start+=8;
569
                            if (offs-bits_start<= 0) break;
570
                       }
571
                       else {
572
                            oneval(val &255, 8,1);
573
                            val >>= 8;
574
                            bits_start +=8;
575
                            if ( offs - bits_start <=0)
576
                                     break;
577
                       }
578
		     }
579
		     Assert(a.ashsize >= offs);
580
		     while (a.ashsize > offs) { /* pad out unions etc */
581
		     	oneval(0,8,1);
582
		     	offs+=8;
583
		     }
584
		     return;
585
	     }
586
	     tup = bro(bro(tup));
587
	}
588
 
589
   }
590
 
591
   case nof_tag: {
592
   	exp s = son(e);
593
	if (s==nilexp) return;
594
	if (rep != 1)
595
	  failer ("CAN'T REP TUPLES");
596
   	set_align(a.ashalign);
597
   	for(;;) {
598
   		evalone(s,1);
599
   		if (last(s)) return;
600
   		s = bro(s);
601
   	}
602
   }
603
 
604
 
605
    case ncopies_tag:
606
      {
607
        if (name(son(e)) == compound_tag || name(son(e)) == concatnof_tag ||
608
               name(son(e)) == nof_tag) {
609
             int n;
610
             for (n = rep*no(e); n > 0; n--) {
611
             	evalone(son(e), 1);
612
             }
613
        }
614
	else evalone (son (e), rep * no (e));
615
	return;
616
      }
617
 
618
    case concatnof_tag:
619
      {
620
	if (a.ashalign == 1) {
621
	  long  ee = evalexp (e);
622
	  exp dad = father(e);
623
	  ash abits;
624
	  abits = ashof(sh(dad));
625
	  oneval(ee, abits.ashalign, rep);
626
	}
627
	else {
628
	  if (rep != 1)
629
	    failer ("CAN'T REP concat");
630
	  evalone (son (e), 1);
631
	  evalone (bro (son (e)), 1);
632
	}
633
	return;
634
      }
635
 
636
    case clear_tag:
637
      {
638
	int s = eval_al(sh(e));
639
	if (as_file)
640
	  fprintf (as_file, "\t.space %ld\n", (s>>3) * rep);
641
	out_value (0, ispace, (s>>3) * rep, 1);
642
	return;
643
      }
644
 
645
 
646
 
647
    case not_tag:
648
    case and_tag:
649
    case or_tag:
650
    case shl_tag:
651
    case shr_tag:
652
    case bitf_to_int_tag:
653
    case int_to_bitf_tag:
654
    case env_offset_tag:
655
    case general_env_offset_tag:
656
   case env_size_tag: case offset_add_tag: case offset_max_tag:
657
   case offset_pad_tag: case offset_mult_tag: case offset_div_tag:
658
   case offset_div_by_int_tag: case offset_subtract_tag: case offset_negate_tag:
659
      {
660
	long  ee = evalexp (e);
661
	oneval(ee, eval_al(sh(e)) , rep);
662
	return;
663
      }
664
   case seq_tag:
665
      {
666
	if (name(son(son(e))) == prof_tag && last(son(son(e))))
667
	   { evalone(bro(son(e)),rep); return;}
668
      }		/* otherwise drop through to failure */
669
 
670
 
671
    default:
672
      failer ("tag not in evaluated");
673
 
674
  }				/* end switch */
675
}
676
 
677
 
678
/*****************************************************************
679
evaluated
680
 
681
This outputs data from the evaluated exp into either .sdata or .data
682
depending on size and labels this data either with either id in main_globals
683
or an anonymous label derived from l. The result is the instore "address"
684
of the constant. A negative l implies that this is the initialisation of a global
685
variable.
686
 
687
*****************************************************************/
688
 
689
instore evaluated
690
    PROTO_N ( (e, l, dc) )
691
    PROTO_T ( exp e X long l X dec * dc )
692
{
693
 
694
  int   lab = (l == 0) ? next_dlab_sym ()
695
  				: (l< 0)? l: -l;
696
  int   lab0 = lab;
697
  ash a;
698
  instore isa;
699
  exp z = e;
700
 
701
  isa.adval = 0;
702
  isa.b.offset = 0;
703
  isa.b.base = lab0;
704
 
705
 
706
  if (name (e) == clear_tag) {/* uninitialised global */
707
    int   size = (ashof (sh (e)).ashsize + 7) >> 3;
708
    bool temp = (l == 0 ||
709
	(main_globals[-lab - 1] -> dec_u.dec_val.dec_id)[0] == '$');
710
    if (dc != (dec*)0) globalise_name(dc);
711
    if (as_file) {
712
      fprintf (as_file, (temp) ? "\t.lcomm\t" : "\t.comm\t");
713
      outlab (lab);
714
      fprintf (as_file, " %d\n", size);
715
    }
716
    out_value ((lab >= 0) ? tempsnos[lab - 32] : symnos[-lab - 1],
717
	(temp) ? ilcomm : icomm, size, 1);
718
 
719
    return isa;
720
  }
721
 
722
 
723
    a = ashof (sh (z));
724
    if (a.ashsize <= G_number) {
725
      if (as_file)
726
	fprintf (as_file, "\t.sdata\n");
727
      out_common (0, isdata);
728
    }
729
    else {
730
      if (as_file)
731
	fprintf (as_file, "\t.data\n");
732
      out_common (0, idata);
733
    }
734
    set_align(a.ashalign);   /* I think this is unnecessary ? bug in as */
735
    if (dc != (dec*)0) globalise_name(dc);
736
    if (as_file) {
737
      outlab (lab);
738
      fprintf (as_file, ":\n");
739
    }
740
    out_common ((lab > 0) ? tempsnos[lab - 32] : symnos[-lab - 1], ilabel);
741
    evalone (z, 1);
742
 
743
  return isa;
744
}