Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
	(1) Its Recipients shall ensure that this Notice is
14
	reproduced upon any copies or amended versions of it;
15
 
16
	(2) Any amended version of it shall be clearly marked to
17
	show both the nature of and the organisation responsible
18
	for the relevant amendment or amendments;
19
 
20
	(3) Its onward transfer from a recipient to another
21
	party shall be deemed to be that party's acceptance of
22
	these conditions;
23
 
24
	(4) DERA gives no warranty or assurance as to its
25
	quality or suitability for any purpose and DERA accepts
26
	no liability whatsoever in relation to any use to which
27
	it may be put.
28
*/
29
 
30
 
31
/*
32
$Log: eval.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:02  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.5  1996/08/30  09:02:17  wfs
37
 * Various fixes of bugs arising from avs and pl_tdf tests.
38
 *
39
 * Revision 1.4  1996/03/22  16:02:29  wfs
40
 * bigval bug fix.
41
 *
42
 * Revision 1.3  1996/03/15  15:04:13  wfs
43
 * 64 bit int corrections.
44
 *
45
 * Revision 1.2  1995/12/18  13:11:09  wfs
46
 * Put hppatrans uder cvs control. Major Changes made since last release
47
 * include:
48
 * (i) PIC code generation.
49
 * (ii) Profiling.
50
 * (iii) Dynamic Initialization.
51
 * (iv) Debugging of Exception Handling and Diagnostics.
52
 *
53
 * Revision 5.5  1995/10/20  13:43:11  wfs
54
 * gcc compilation changes.
55
 *
56
 * Revision 5.4  1995/10/11  15:51:09  wfs
57
 * Changed the evaluation of "env_size_tag".
58
 *
59
 * Revision 5.3  1995/10/09  13:02:39  wfs
60
 * Cosmetic changes.
61
 *
62
 * Revision 5.2  1995/09/20  11:22:55  wfs
63
 * Corrected a "switch" parameter which was causing problems with
64
 * "eqntott" and "espresso".
65
 *
66
 * Revision 5.1  1995/09/15  12:12:53  wfs
67
 * Minor changes to stop gcc complaining + 64 bit int stuff.
68
 *
69
 * Revision 5.0  1995/08/25  13:42:58  wfs
70
 * Preperation for August 25 Glue release
71
 *
72
 * Revision 3.4  1995/08/25  09:14:08  wfs
73
 * included extra check to ensure global general_proc plabels were
74
 * output correctly
75
 *
76
 * Revision 3.4  1995/08/25  09:14:08  wfs
77
 * included extra check to ensure global general_proc plabels were
78
 * output correctly
79
 *
80
 * Revision 3.1  95/04/10  16:26:06  16:26:06  wfs (William Simmonds)
81
 * Apr95 tape version.
82
 * 
83
 * Revision 3.0  95/03/30  11:16:31  11:16:31  wfs (William Simmonds)
84
 * Mar95 tape version with CRCR95_178 bug fix.
85
 * 
86
 * Revision 2.0  95/03/15  15:25:38  15:25:38  wfs (William Simmonds)
87
 * spec 3.1 changes implemented, tests outstanding.
88
 * 
89
 * Revision 1.3  95/01/27  09:30:13  09:30:13  wfs (William Simmonds)
90
 * Corrected bug in evaluated which was preventing the initialization
91
 * of global id_tags.
92
 * 
93
 * Revision 1.2  95/01/17  17:22:16  17:22:16  wfs (William Simmonds)
94
 * Name of included header file changed.
95
 * 
96
 * Revision 1.1  95/01/11  13:04:22  13:04:22  wfs (William Simmonds)
97
 * Initial revision.
98
 * 
99
*/
100
 
101
 
102
#define HPPATRANS_CODE
103
/*****************************************************************
104
		eval.c
105
 
106
	The main procedure defined here is evaluated which outputs
107
assembler for data. The parameters are an evaluated exp and an index
108
into the table of externals (or 0 meaning anonymous).
109
*****************************************************************/
110
 
111
#include "config.h"
112
#include <ctype.h>
113
#include "addrtypes.h"
114
#include "common_types.h"
115
#include "tags.h"
116
#include "expmacs.h"
117
#include "exp.h"
118
#include "exptypes.h"
119
#include "maxminmacs.h"
120
#include "shapemacs.h"
121
#include "flpttypes.h"
122
#include "flpt.h"
123
#include "fbase.h"
124
#include "translat.h"
125
#include "comment.h"
126
#include "myassert.h"
127
#include "inst_fmt.h"
128
#include "szs_als.h"		/* for MAX_BF_SIZE */
129
#include "out.h"
130
#include "f64.h"
131
#include "frames.h"
132
#include "procrec.h"
133
#include "basicread.h"
134
#include "eval.h"
135
 
136
 
137
#define proc_tag 118
138
#define is_zero( e ) is_comm( e )
139
 
140
/*************************************************************
141
maxmin
142
 
143
finds the data size from the range of an integer shape
144
**************************************************************/
145
 
146
/* various pieces of info for outputting data depending on shape */
147
static mm scmm = {127, -128, "\t.BYTE\t%ld\n"};
148
static mm uscmm = {255, 0, "\t.BYTE\t%ld\n"};
149
static mm shmm = {0x7fff, 0xffff8000, "\t.HALF\t%ld\n"};
150
static mm ushmm = {0xffff, 0, "\t.HALF\t%ld\n"};
151
static mm swmm = {0x7fffffff, 0x80000000, "\t.WORD\t%ld\n"};
152
static mm uswmm = {0xffffffff, 0, "\t.WORD\t%ld\n"};
153
 
154
 
155
 
156
mm maxmin 
157
    PROTO_N ( ( s ) )
158
    PROTO_T ( shape s )
159
{
160
  switch (name(s))
161
  {
162
    case scharhd:
163
    return scmm;
164
  case ucharhd:
165
    return uscmm;
166
  case swordhd:
167
    return shmm;
168
  case uwordhd:
169
    return ushmm;
170
  case slonghd:
171
    return swmm;
172
  case ulonghd:
173
    return uswmm;
174
  default:
175
    {
176
      return uswmm;
177
    }
178
  }
179
 
180
}
181
 
182
int next_data_lab 
183
    PROTO_Z ()
184
{
185
  static int n = 100;
186
  return ++n;
187
}
188
 
189
int next_PIC_pcrel_lab 
190
    PROTO_Z ()
191
{
192
  static int n = 100;
193
  return ++n;
194
}
195
 
196
 
197
/*
198
  Output a unary representation of the number val.  val should be 
199
  less than or equal to 31 as it represent the number of bits
200
  in a bitfield which does not occupy a whole machine word.
201
*/
202
long unary 
203
    PROTO_N ( ( val ) )
204
    PROTO_T ( int val )
205
{
206
   int loop;
207
   long result=0;
208
   assert (val <=31);
209
   for(loop=0;loop<val;++loop)
210
   {
211
      result <<=1;
212
      result |= 1;
213
   }
214
   return result;
215
}
216
 
217
#if !use_long_double
218
/* output assembler representation of floating number */
219
static void outfloat(f)
220
flpt f;
221
{
222
#if ( FBASE == 10 )
223
  int i;
224
  int n;
225
  unsigned char *frac = (flptnos[f].mant);
226
  char *exppos;
227
  static char fltrepr[120];
228
  insection(data_section);
229
 
230
  for (n = MANT_SIZE - 1; n > 1 && frac[n] == 0; n--)
231
     /* BLOCKZ */ ;
232
  fltrepr[0] = (flptnos[f].sign < 0) ? '-' : '+';
233
  fltrepr[1] = frac[0] + '0';
234
  fltrepr[2] = '.';
235
  for (i = 1; i <= n; ++i)
236
  {
237
    fltrepr[i + 2] = frac[i] + '0';
238
  }
239
  exppos = &fltrepr[i + 2];
240
  if (flptnos[f].exp != 0)
241
  {
242
    sprintf(exppos, "e%ld", flptnos[f].exp);
243
  }
244
  else
245
  {
246
    exppos[0] = 0;
247
  }
248
  outs(fltrepr);
249
#else
250
  fail ( "Illegal floating point constant" ) ;
251
#endif
252
}
253
#endif /* !use_long_double */
254
 
255
/*
256
    CONVERT A REAL VALUE TO A BITPATTERN
257
 
258
    This routine converts the real constant e into an array of longs
259
    giving the bitpattern corresponding to this constant.  Although
260
    care has been taken, this may not work properly on all machines
261
    (although it should for all IEEE machines).  It returns NULL if
262
    it cannot convert the number sufficiently accurately.
263
*/
264
 
265
long *realrep 
266
    PROTO_N ( ( e ) )
267
    PROTO_T ( exp e )
268
{
269
    int i, ex ;
270
    char bits [128] ;
271
    static long longs [4] ;
272
    int exp_bits, mant_bits ;
273
    long sz = shape_size ( sh ( e ) ) ;
274
 
275
#if ( FBASE == 10 )
276
    return ( NULL ) ;
277
#else
278
 
279
    /* Find size of exponent and mantissa */
280
    if ( sz == 32 ) {
281
	exp_bits = 8 ;
282
	mant_bits = 23 ;
283
    } else if ( sz == 64 ) {
284
	exp_bits = 11 ;
285
	mant_bits = 52 ;
286
    } else {
287
	exp_bits = 15 ;
288
	mant_bits = 96 /* or 112? */ ;
289
    }
290
 
291
    if ( name ( e ) == real_tag ) {
292
	int j, k = -1 ;
293
	flt *f = flptnos + no ( e ) ;
294
 
295
	/* Deal with 0 */
296
	if ( f->sign == 0 ) {
297
	    for ( i = 0 ; i < sz / 32 ; i++ ) longs [i] = 0 ;
298
	    return ( longs ) ;
299
	}
300
 
301
	/* Fill in sign */
302
	bits [0] = ( f->sign < 0 ? 1 : 0 ) ;
303
 
304
	/* Work out exponent */
305
	ex = FBITS * ( f->exp ) + ( FBITS - 1 ) ;
306
 
307
	/* Fill in mantissa */
308
	for ( i = 0 ; i < MANT_SIZE ; i++ ) {
309
	    for ( j = FBITS - 1 ; j >= 0 ; j-- ) {
310
		if ( ( f->mant [i] ) & ( 1 << j ) ) {
311
		    if ( k >= 0 ) {
312
			if ( k < sz ) bits [k] = 1 ;
313
			k++ ;
314
		    } else {
315
			/* Ignore first 1 */
316
			k = exp_bits + 1 ;
317
		    }
318
		} else {
319
		    if ( k >= 0 ) {
320
			if ( k < sz ) bits [k] = 0 ;
321
			k++ ;
322
		    } else {
323
			/* Step over initial zeros */
324
			ex-- ;
325
		    }
326
		}
327
	    }
328
	}
329
 
330
    } else {
331
	fail ( "Illegal floating-point constant" ) ;
332
	return ( NULL ) ;
333
    }
334
 
335
    /* Fill in exponent */
336
    ex += ( 1 << ( exp_bits - 1 ) ) - 1 ;
337
    if ( ex <= 0 || ex >= ( 1 << exp_bits ) - 1 ) {
338
	fail ( "Floating point constant out of range" ) ;
339
    }
340
    for ( i = 0 ; i < exp_bits ; i++ ) {
341
	int j = exp_bits - i ;
342
	bits [j] = ( ( ex & ( 1 << i ) ) ? 1 : 0 ) ;
343
    }
344
 
345
    /* Convert bits to longs */
346
    for ( i = 0 ; i < sz / 32 ; i++ ) {
347
	int j ;
348
	long b0 = 0, b1 = 0, b2 = 0, b3 = 0 ;
349
	for ( j = 0 ; j < 8 ; j++ ) b0 = 2 * b0 + bits [ 32 * i + j ] ;
350
	for ( j = 8 ; j < 16 ; j++ ) b1 = 2 * b1 + bits [ 32 * i + j ] ;
351
	for ( j = 16 ; j < 24 ; j++ ) b2 = 2 * b2 + bits [ 32 * i + j ] ;
352
	for ( j = 24 ; j < 32 ; j++ ) b3 = 2 * b3 + bits [ 32 * i + j ] ;
353
#if little_end
354
	longs [i] = b0 + ( b1 << 8 ) + ( b2 << 16 ) + ( b3 << 24 ) ;
355
#else
356
	longs [i] = ( b0 << 24 ) + ( b1 << 16 ) + ( b2 << 8 ) + b3 ;
357
#endif
358
    }
359
    return ( longs ) ;
360
#endif
361
}
362
 
363
 
364
long evalexp 
365
    PROTO_N ( ( e ) )
366
    PROTO_T ( exp e )
367
{
368
  switch (name(e))
369
  {
370
  case top_tag:
371
     return 0;
372
  case val_tag: case null_tag:
373
  {
374
     if (name(sh(e)) == offsethd && al2(sh(e)) >= 8) 
375
     {
376
	return (no(e)>>3);
377
     }
378
     else
379
	return no(e);
380
  }
381
  case bitf_to_int_tag:
382
    {
383
      return evalexp(son(e));
384
    }
385
  case int_to_bitf_tag:
386
    {
387
      ash a;
388
      unsigned long w = evalexp(son(e));
389
 
390
      a = ashof(sh(e));
391
      if (a.ashalign != 1 && !(name(sh(e)) == cpdhd && a.ashalign == 32))
392
      {
393
	fail("should be align 1");
394
      }
395
      if (a.ashsize != 32)
396
      {
397
	w &= ((1 << a.ashsize) - 1);
398
      }
399
      return w;
400
    }
401
  case not_tag:
402
    {
403
      return (evalexp(son(e)));
404
    }
405
  case and_tag:
406
    {
407
      return (evalexp(son(e)) & evalexp(bro(son(e))));
408
    }
409
  case or_tag:
410
    {
411
      return (evalexp(son(e)) | evalexp(bro(son(e))));
412
    }
413
  case xor_tag:
414
    {
415
      return (evalexp(son(e)) ^ evalexp(bro(son(e))));
416
    }
417
 
418
  case shr_tag:
419
    {
420
      bool sgned = is_signed(sh(e));
421
 
422
      FULLCOMMENT1("evalexp() shr_tag: sgned=%d", sgned);
423
      if (sgned)
424
	return (((long) evalexp(son(e))) >> evalexp(bro(son(e))));
425
      else
426
	return (((unsigned long) evalexp(son(e))) >> evalexp(bro(son(e))));
427
    }
428
 
429
  case shl_tag:
430
    {
431
      return (evalexp(son(e)) << evalexp(bro(son(e))));
432
    }
433
 
434
  case concatnof_tag:
435
    {
436
      unsigned long w_lhs = evalexp(son(e));
437
      unsigned long w_rhs = evalexp(bro(son(e)));
438
      ash ash_lhs, ash_rhs ;
439
      ash_lhs = ashof(sh(son(e)));
440
      ash_rhs = ashof(sh(bro(son(e))));
441
 
442
      assert(ash_lhs.ashalign == 1 && ash_lhs.ashsize <= 32);
443
      assert(ash_rhs.ashalign == 1 && ash_rhs.ashsize <= 32);
444
      assert(ash_lhs.ashsize + ash_rhs.ashsize <= 32);
445
 
446
      FULLCOMMENT4("evalexp() concatnof_tag: lhs,rhs=%#x,%#x ash(rhs)=%d,%d",
447
		   w_lhs, w_rhs, ash_rhs.ashalign, ash_rhs.ashsize);
448
 
449
      if (ash_rhs.ashsize == 32)
450
      {
451
	/* avoid illegal shift by 32 */
452
	assert(w_lhs == 0);
453
	return w_rhs;
454
      }
455
      return (w_lhs << ash_rhs.ashsize) | w_rhs;
456
    }
457
 
458
  case env_offset_tag:
459
  case general_env_offset_tag: 
460
  {
461
     return frame_offset(son(e));
462
  }
463
  case env_size_tag:
464
  {
465
     exp tg = son(son(e));
466
     procrec * pr = &procrecs[no(son(tg))];
467
     return((pr->frame_sz+0) >> 3);
468
  }
469
 
470
   case offset_add_tag:
471
   {
472
    	return(evalexp(son(e))+evalexp(bro(son(e))));
473
   }
474
   case offset_max_tag:
475
   {
476
    	return(MAX_OF(evalexp(son(e)),evalexp(bro(son(e)))));
477
   }   
478
   case offset_pad_tag:
479
   {
480
	return( rounder(evalexp(son(e)), shape_align(sh(e))));
481
   }
482
   case offset_mult_tag:
483
   {
484
    	return(evalexp(son(e))*evalexp(bro(son(e))));
485
   }
486
   case offset_div_tag:case offset_div_by_int_tag:
487
   {
488
    	return(evalexp(son(e))/evalexp(bro(son(e))));
489
   }
490
   case offset_subtract_tag:
491
   {
492
    	return(evalexp(son(e))-evalexp(bro(son(e))));
493
   }
494
   case offset_negate_tag: 
495
   {
496
	return(-evalexp(son(e)));
497
   }     
498
 
499
  case clear_tag:
500
    {
501
      ash a;
502
 
503
      a = ashof(sh(e));
504
 
505
      FULLCOMMENT2("evalexp() clear_tag: ash=%d,%d", a.ashalign, a.ashsize);
506
 
507
      return 0;
508
    }
509
 
510
 
511
  default:
512
    fail("tag not in evalexp");
513
    return 0;
514
  }
515
  /* NOTREACHED */
516
}
517
 
518
void oneval 
519
    PROTO_N ( ( val, al, rep ) )
520
    PROTO_T ( int val X int al X int rep )
521
{
522
    assert ( rep == 1 ) ;     
523
    outs( (al<9 ? "\t.BYTE\t" : ( al<17 ? "\t.HALF\t" : "\t.WORD\t")) );
524
    outn( val);
525
    outnl();
526
    return ;
527
}
528
 
529
/*
530
 * Output as ascii for the human reader (48 bytes to the line).
531
 */
532
static void outascii 
533
    PROTO_N ( ( str, strsize ) )
534
    PROTO_T ( char * str X int strsize )
535
{
536
    while ( strsize > 0 ) {
537
	int i ;
538
	outs("\t.STRING\t\"");
539
	for ( i = 0 ; strsize > 0 && i < 48 ; i++ ) {
540
	    unsigned char c = ( ( unsigned char ) *str ) ;
541
	    switch ( c ) {
542
		case '"' : {
543
		    outs( "\\\"") ;
544
		    break ;
545
		}
546
		case '\\' : {
547
		    outs( "\\\\" ) ;
548
		    break ;
549
		}
550
		case 7 : {
551
		    outs( "\\x07" ) ;
552
		    break ;
553
		}
554
		case '\b' : {
555
		    outs( "\\x08" ) ;
556
		    break ;
557
		}
558
		case '\f' : {
559
		    outs( "\\x0c" ) ;
560
		    break ;
561
		}
562
		case '\n' : {
563
		    outs( "\\x0a" ) ;
564
		    break ;
565
		}	
566
		case '\r' : {
567
		    outs( "\\x0d" ) ;
568
		    break ;
569
		}
570
		case '\t' : {
571
		    outs( "\\x09" ) ;
572
		    break ;
573
		}
574
		case 11 : {
575
		    outs( "\\x0b" ) ;
576
		    break ;
577
		}
578
		default :
579
		{
580
		    if (isprint(c))
581
		       outc(c);
582
		    else 
583
			/* output as a hexadecimal  */
584
		    {
585
		       if (c<16)
586
			   fprintf(outf,"\\x0%x", c) ;
587
		       else
588
			   fprintf(outf,"\\x%x", c) ;
589
		    }
590
  	            break ;
591
		}
592
	    }
593
	    str++ ;
594
	    strsize-- ;
595
	}
596
	outs("\"\n");
597
    }
598
    return ;
599
  }
600
 
601
 
602
struct concbittypet
603
{
604
  int bitposn;
605
  int value_size;
606
  unsigned long value;
607
};
608
typedef struct concbittypet concbittype;
609
 
610
 
611
static concbittype emptyconcbit 
612
    PROTO_N ( ( bitposn ) )
613
    PROTO_T ( int bitposn )
614
{
615
  concbittype start;
616
 
617
  start.bitposn = bitposn;
618
  start.value_size = 0;
619
  start.value = 0;
620
 
621
  return start;
622
}
623
 
624
 
625
static void outconcbit 
626
    PROTO_N ( ( c ) )
627
    PROTO_T ( concbittype c )
628
{
629
  unsigned long w = c.value;
630
  int bytes = (c.value_size + 7) / 8;
631
  int i;
632
 
633
  insection(data_section);
634
 
635
  comment2("outconcbit: bits=%d w=%#lx", c.value_size, w);
636
 
637
  if (c.value_size == 0)
638
    return;			/* avoid .BYTE with no data */
639
 
640
  assert(c.value_size <= 32);
641
 
642
  /* to left end of word */
643
  if (c.value_size != 32)
644
    w = w << (32 - c.value_size);
645
 
646
  /* HPPA assembler only permits .WORD for 32-bit aligned values */
647
 
648
  /* output enough bytes */
649
  outs("\t.BYTE\t") ;
650
  for (i = 0; i < bytes; i++)
651
  {
652
    if (i != 0)
653
       outc(',') ;
654
    fprintf(outf,"%#lx", ( w >> 24 ) & 255 ) ;
655
    w = w << 8;
656
  }
657
  outnl();
658
  assert(w == 0);
659
}
660
 
661
 
662
/*
663
    ADD A VALUE TO A BIT PATTERN
664
*/
665
static concbittype addconcbitaux
666
    PROTO_N ( (w,sz,before) )
667
    PROTO_T ( unsigned long w X int sz X concbittype before )
668
{
669
   int wordpos;  /* bit position in word */
670
 
671
   if ( before.value_size == 32 || (before.value_size != 0 && (before.bitposn & 31) == 0) )
672
   {
673
      assert((before.bitposn & 31) == 0);
674
      wordpos = 32;
675
   }
676
   else
677
   {
678
      wordpos = (before.bitposn & 31);
679
   }
680
   assert(sz > 0);
681
   assert(sz <= 32);
682
   assert(before.value_size <= 32);
683
   assert(wordpos == 0 || before.value_size <= wordpos);
684
   if ( (sz == 0 && (wordpos != 0 || before.value_size != 0)) ||
685
	((wordpos+sz) > 32) )
686
   {
687
/*      int pad_bits = 32 - wordpos;    gcc complains*/
688
      assert ( wordpos == 32 ); /* should be aligned automatically */
689
      outconcbit(before);
690
      /* clear before, as it has been output */
691
      before.value_size = 0;
692
      before.value = 0;
693
      /* should be at word boundary */
694
      assert((before.bitposn & 31) == 0);
695
   }
696
 
697
   if (sz == 0)
698
      return before;
699
 
700
   /* add to before */
701
   if (sz == 32)
702
      before.value = w;
703
   else
704
   {
705
#if little_end
706
      before.value = before.value | ( w << before.value_size ) ;
707
#else
708
      before.value = ( before.value << sz ) | (w & unary(sz));
709
#endif
710
   }
711
   before.bitposn += sz;
712
   before.value_size += sz;
713
   assert(before.value_size <= 32);
714
   return before;
715
}
716
 
717
 
718
static concbittype evalconcbitaux 
719
    PROTO_N ( ( e, before ) )
720
    PROTO_T ( exp e X concbittype before )
721
{
722
  switch (name(e))
723
  {
724
    case concatnof_tag:
725
    {
726
      concbittype lhs, rhs ;
727
      lhs = evalconcbitaux(son(e), before);
728
      rhs = evalconcbitaux(bro(son(e)), lhs);
729
      return rhs;
730
    }
731
 
732
  default:
733
    {
734
      assert(shape_align(sh(e)) == 1);
735
 
736
      return addconcbitaux(evalexp(e), shape_size(sh(e)), before);
737
    }
738
  }
739
}
740
 
741
 
742
static void evalconcbit 
743
    PROTO_N ( ( e, bitposn ) )
744
    PROTO_T ( exp e X int bitposn )
745
{
746
  concbittype start ;
747
  start = emptyconcbit(bitposn);
748
  outconcbit(evalconcbitaux(e, start));
749
}
750
 
751
/*
752
 * Determine whether an exp is definitely zero valued.
753
 * Zero-valued initialisers can be put in the bss section.
754
 * Does not exhaust all possibilities, some zero valued expressions
755
 * may have "is_zero(e)==0".
756
 */
757
 
758
#if 0
759
bool is_zero 
760
    PROTO_N ( ( e ) )
761
    PROTO_T ( exp e )
762
{
763
  if (e == nilexp)
764
    return 1;
765
 
766
  switch (name(e))
767
  {
768
    /* +++ real values always explicitly initialised, which is not necessary */
769
  case null_tag:
770
    return 1;
771
  case val_tag:
772
    return (no(e) == 0 ? 1 : 0);
773
  case ncopies_tag:
774
  case int_to_bitf_tag:
775
    return is_zero(son(e));
776
  case compound_tag:
777
    {
778
      /* (compound_tag <offset> <initialiser> ... ) */
779
      e = bro(son(e));
780
      while (1)
781
      {
782
	if (is_zero(e) == 0)
783
	  return 0;		/* found non-zero */
784
 
785
	if (last(e))
786
	  return 1;		/* all done, all zero */
787
 
788
	e = bro(bro(e));
789
      }
790
      /*NOTREACHED*/
791
    }
792
 case real_tag:
793
    {
794
      /* correct because bit representation of real zero is all zero bits */
795
      flt f ;
796
      f = flptnos[no(e)];
797
      if (f.exp == 0)
798
      {
799
	int i;
800
	for (i = 0; i < MANT_SIZE; i++)
801
	    if (f.mant[i] != 0)
802
		return 0;	/* non-zero */
803
 
804
	return 1;		/* all zero */
805
      }
806
      return 0;
807
    }
808
  default:
809
      return 0;
810
  }
811
}
812
#endif
813
 
814
void set_align 
815
    PROTO_N ( ( al ) )
816
    PROTO_T ( int al )
817
{
818
    assert ( al >= 8 && al <= 64 ) ;
819
    if ( al > 8 ) {
820
       outs("\t.ALIGN\t");
821
       outn(al/8);
822
       outnl();
823
    }
824
    return ;
825
}
826
 
827
/***************************************************************
828
This procedure outputs all expressions.
829
***************************************************************/
830
 
831
void evalone 
832
    PROTO_N ( ( e, bitposn ) )
833
    PROTO_T ( exp e X int bitposn )
834
{
835
  ash a;
836
/*  long al = ( long ) shape_align ( sh ( e ) ) ; gcc complains */
837
  long sz = ( long ) shape_size ( sh ( e ) ) ;
838
 
839
  insection(data_section);
840
 
841
  a = ashof(sh(e));
842
 
843
  comment4("evalone: name(e)=%d, bitposn=%d, ash=%d,%d", name(e), bitposn, a.ashsize, a.ashalign);
844
 
845
  set_align(a.ashalign);
846
 
847
  /* align bitposn */
848
  if (a.ashalign != 0)
849
    bitposn = (bitposn / a.ashalign) * a.ashalign;
850
 
851
  /* generate data initialiser for e */
852
  switch (name(e))
853
  {
854
    case string_tag:
855
      {
856
	  long char_size=props(e);
857
	  long strsize=shape_size(sh(e))/char_size;
858
	  char *st=nostr(e);
859
	  int i,j;
860
 
861
	  if (char_size==8)
862
	  {
863
	    outascii(st,strsize);
864
	    return;
865
	  }
866
 
867
	  if (strsize>0)
868
	     set_align(char_size);
869
 
870
	  for (j=0; j<strsize;)
871
	  {
872
	     outs( char_size==8 ? "\t.BYTE\t" :
873
				  ( char_size==16 ? "\t.HALF\t" : "\t.WORD\t") );
874
	  /* output chars in batches */
875
	  for (i = j; i < strsize && i-j < 8; i++)
876
	  {
877
	    if (i != j)
878
	       outc(',');
879
/*	    switch (ptno(e)) */
880
	    switch ( char_size )
881
	    {
882
	  case 8:
883
	      fprintf(outf,"0x%x", st[i]);
884
	      break;
885
	  case 16:
886
	      fprintf(outf,"0x%x", ((short *) st)[i]);
887
	      break;
888
	  case 32:
889
	      fprintf(outf,"0x%x", ((int *) st)[i]);
890
	    break;
891
	    }
892
	  }/*for i*/
893
	  outnl();
894
	  j = i;
895
	}/*for j*/
896
      return;
897
    }
898
 
899
#if use_long_double
900
	case real_tag : {
901
	    /* Floating point constant */
902
	  flt *f = flptnos + no ( e ) ;
903
	  r2l v;
904
 
905
	  if ( sz == 32 ) {
906
	    v = real2longs_IEEE(f,0);
907
 
908
	    outs ( "\t.WORD\t" ) ;
909
	    outn ( v.i1 ) ;
910
	  } else if ( sz == 64 ) {
911
	    v = real2longs_IEEE(f,1);
912
 
913
	    outs ( "\t.WORD\t" ) ;
914
	    outn ( v.i2 ) ;
915
	    outc ( ',' ) ;
916
	    outn ( v.i1 ) ;
917
	  } else {
918
	    v = real2longs_IEEE(f,2);
919
	    outs ( "\t.WORD\t" ) ;
920
	    outn ( v.i4 ) ;
921
	    outc ( ',' ) ;
922
	    outn ( v.i3 ) ;
923
	    outc ( ',' ) ;
924
	    outn ( v.i2 ) ;
925
	    outc ( ',' ) ;
926
	    outn ( v.i1 ) ;
927
	  }
928
	  outnl () ;
929
	  return ;
930
	}
931
#else
932
    case real_tag: {
933
	long sz = a.ashsize ;
934
	long *p = realrep ( e ) ;
935
	if ( p )
936
	{
937
	    outs("\t.WORD\t");
938
	    outn(p[0]);
939
	    if ( sz > 32 )
940
	    {
941
		outc(',') ;
942
		outn(p[1]);
943
	    }
944
	    outnl();
945
	}
946
	else
947
	{
948
	    if (sz==32)
949
	       outs( sz==32 ? "\t.FLOAT\t0r" : "\t.DOUBLE\t0r");
950
	    outfloat(no(e));
951
	    outnl();
952
	}
953
	return ;
954
    }
955
#endif
956
 
957
    case null_tag: case top_tag:
958
    no(e) = 0;
959
    /* FALLTHROUGH */
960
  case val_tag:
961
    {
962
       if ( shape_size(sh(e))>32 ) 
963
       {
964
	  flt64 t;
965
	  int ov;
966
	  if (isbigval(e)) 
967
	  {
968
	     t = flt_to_f64(no(e),0,&ov);
969
	  }
970
	  else
971
	  {
972
	     t.big = (is_signed(sh(e)) && no(e)<0)?-1:0;
973
	     t.small = no(e);
974
	  }
975
	  oneval(t.big,32,1);
976
	  oneval(t.small,32,1);
977
	  return;
978
       }
979
       if ( a.ashalign==1 )
980
	  evalconcbit(e, bitposn);
981
       else
982
	  oneval(evalexp(e),a.ashalign,1);
983
       return;
984
    }
985
 
986
    case name_tag : {
987
	dec *globdec = brog(son(e)) ;	/* must be global name */
988
	char *nm = globdec->dec_u.dec_val.dec_id ;
989
 
990
	assert(isglob(son(e)));
991
 
992
	if ( son(globdec->dec_u.dec_val.dec_exp)!=nilexp &&
993
	     ( name(son(globdec->dec_u.dec_val.dec_exp))==proc_tag ||
994
	       name(son(globdec->dec_u.dec_val.dec_exp))==general_proc_tag ) )
995
	{
996
	   /* It's a plabel */
997
	   outs( "\t.WORD\tP%" ) ;
998
	}
999
	else
1000
	   outs( "\t.WORD\t" ) ;
1001
	outs(nm) ;
1002
	if ( no ( e ) ) {
1003
	    outc('+') ;
1004
	    outn(no(e)/8);
1005
	}
1006
	outnl();
1007
	return ;
1008
    }
1009
 
1010
  case compound_tag:
1011
  {
1012
      /* Compound values */
1013
      exp off = son(e);
1014
      exp tup = bro(off);
1015
      ash tupa;
1016
      concbittype left;
1017
      long last_offset = 0;
1018
      long last_align = 0;
1019
      tupa = ashof(sh(tup));
1020
      left = emptyconcbit(bitposn);
1021
 
1022
      /* output elements of aggregate recursively */
1023
      while (1)
1024
      {
1025
	 int gap = no(off) - left.bitposn;
1026
 
1027
 	 /* check that component's alignment matches offset in struct */
1028
	 assert((no(off)/ta)*ta <= no(off));
1029
	 /* and is no greater than struct's alignment */
1030
	 assert(tupa.ashalign <= maxalign);
1031
 
1032
	 if ( shape_size(sh(tup)) == 0 )
1033
	 {
1034
	    if (last(tup)) 
1035
	       return;
1036
	    else
1037
	    {
1038
	       off = bro(bro(off));
1039
	       assert(!last(off));
1040
	       tup = bro(off);
1041
	       tupa = ashof(sh(tup));
1042
	       continue;
1043
	    }
1044
	 }
1045
 
1046
 	 if (no(off) < last_offset)
1047
	 {
1048
	    fail( "Compound components badly ordered" ) ;
1049
	 }
1050
	 if (last_align <= 1 || tupa.ashalign <= 1 || gap >= tupa.ashalign)
1051
	 {
1052
	    /* get gap down */
1053
	    while (gap > 0)
1054
	    {
1055
	       left = addconcbitaux(0,1,left);
1056
	       gap--;
1057
	    }
1058
	 }
1059
 	 else
1060
	 {
1061
	    /* alignment will handle gap */
1062
	    left.bitposn = (int) rounder(left.bitposn,tupa.ashalign);
1063
	 }
1064
 	 last_offset = no(off);
1065
	 last_align = tupa.ashalign;
1066
	 assert(left.bitposn - bitposn == no(off));
1067
 	 if (tupa.ashalign == 1)
1068
	 {
1069
	    /* collect bitfields */
1070
 	    left = evalconcbitaux(tup,left);
1071
	 }
1072
	 else
1073
	 {
1074
	    /* output final bits from any previous field */
1075
	    outconcbit(left);
1076
	    left = emptyconcbit(left.bitposn);
1077
 	    evalone(tup,left.bitposn);
1078
	    left.bitposn += tupa.ashsize;
1079
	 }
1080
 	 if (last(tup))
1081
	 {
1082
	    /* output final bits from any previous field */
1083
	    long databits = no(off) + tupa.ashsize;
1084
	    long trailing_bytes = (a.ashsize-databits) / 8;
1085
	    outconcbit(left);
1086
	    assert(a.ashsize >= databits);
1087
 
1088
	    /* pad out trailing unitialised space, eg union */
1089
	    if (a.ashsize > databits && trailing_bytes > 0)
1090
	    {
1091
	       outs( "\t.BLOCKZ\t" ) ;
1092
	       outn(trailing_bytes);
1093
	       outnl();
1094
	    }
1095
 	    return;
1096
	 }
1097
 	 off = bro(bro(off));
1098
	 assert(!last(off));
1099
	 tup = bro(off);
1100
	 tupa = ashof(sh(tup));
1101
      }
1102
      /*  NOT REACHED  */
1103
    }
1104
 
1105
  case nof_tag:
1106
    {
1107
      exp s = son(e);
1108
      set_align(a.ashalign);
1109
      for (;;)
1110
      {
1111
	evalone(s, bitposn);
1112
	if (last(s))
1113
	  return;
1114
	s = bro(s);
1115
      }
1116
    }
1117
 
1118
  case ncopies_tag:
1119
   {
1120
      int n = no(e);
1121
      ash copya;
1122
      int bitsize;
1123
      int i;
1124
 
1125
      while (name(son(e)) == ncopies_tag)
1126
      {
1127
	e = son(e);
1128
	n *= no(e);
1129
      }
1130
 
1131
      e = son(e);
1132
 
1133
      copya = ashof(sh(e));
1134
      if (copya.ashalign != 0)
1135
	bitsize = (copya.ashsize / copya.ashalign) * copya.ashalign;
1136
      else
1137
	bitsize = 0;		/* probably never happen! */
1138
 
1139
      for (i = 0; i < n; i++)
1140
      {
1141
	evalone(e, bitposn);
1142
      }
1143
      return;
1144
    }
1145
 
1146
  case concatnof_tag:
1147
    {
1148
      comment2("concatnof_tag: ashalign=%d, ashsize=%d", a.ashalign, a.ashsize);
1149
 
1150
      /* allow for bitfields */
1151
      if (a.ashalign == 1)
1152
      {
1153
	evalconcbit(e, bitposn);
1154
      }
1155
      else
1156
      {
1157
	ash a;
1158
 
1159
	a = ashof(sh(son(e)));
1160
	evalone(son(e), bitposn);
1161
	bitposn += a.ashsize;
1162
 
1163
	a = ashof(sh(bro(son(e))));
1164
	if (a.ashalign != 0)
1165
	  bitposn = (bitposn / a.ashalign) * a.ashalign;
1166
	evalone(bro(son(e)), bitposn);
1167
      }
1168
      return;
1169
    }
1170
 
1171
    case clear_tag : {
1172
	if ( a.ashalign == 1 ) {
1173
	    /* allow for bitfields */
1174
	    evalconcbit ( e, bitposn ) ;
1175
	    return ;
1176
	}
1177
	outs( "\t.BLOCKZ\t" ) ;
1178
	outn((a.ashsize+7)>>3);
1179
	outnl();
1180
	return ;
1181
    }
1182
 
1183
  case not_tag:
1184
  case and_tag:
1185
  case or_tag:
1186
  case shl_tag:
1187
  case shr_tag:
1188
  case bitf_to_int_tag:
1189
  case int_to_bitf_tag:
1190
  case env_offset_tag: 
1191
  case general_env_offset_tag: 
1192
    {
1193
	outs( "\t.WORD\t" ) ;
1194
	outn(evalexp(e));
1195
	outnl();
1196
	return ;
1197
    }
1198
   case env_size_tag:
1199
    {
1200
	exp tg = son(son(e));
1201
	procrec * pr = &procrecs[no(son(tg))];
1202
	outs( "\t.WORD\t" ) ;
1203
	outn((pr->frame_sz+0) >> 3);
1204
	outnl();
1205
	return ;
1206
    }
1207
 
1208
   case offset_add_tag:
1209
   {
1210
	outs( "\t.WORD\t" ) ;
1211
    	outn(evalexp(son(e))+evalexp(bro(son(e))));
1212
	outnl();
1213
	return ;
1214
   }
1215
   case offset_max_tag:
1216
   {
1217
	outs( "\t.WORD\t" ) ;
1218
    	outn(MAX_OF(evalexp(son(e)),evalexp(bro(son(e)))));
1219
	outnl();
1220
	return ;
1221
   }   
1222
   case offset_pad_tag:
1223
   {
1224
	outs( "\t.WORD\t" ) ;
1225
	outn( rounder(evalexp(son(e)), shape_align(sh(e))));
1226
	outnl();
1227
	return ;
1228
   }
1229
   case offset_mult_tag:
1230
   {
1231
	outs( "\t.WORD\t" ) ;
1232
    	outn(evalexp(son(e))*evalexp(bro(son(e))));
1233
	outnl();
1234
	return ;
1235
   }
1236
   case offset_div_tag:case offset_div_by_int_tag:
1237
   {
1238
	outs( "\t.WORD\t" ) ;
1239
    	outn(evalexp(son(e))/evalexp(bro(son(e))));
1240
	outnl();
1241
	return ;
1242
   }
1243
   case offset_subtract_tag:
1244
   {
1245
	outs( "\t.WORD\t" ) ;
1246
    	outn(evalexp(son(e))-evalexp(bro(son(e))));
1247
	outnl();
1248
	return ;
1249
   }
1250
   case offset_negate_tag: 
1251
   {
1252
	outs( "\t.WORD\t" ) ;
1253
	outn(-evalexp(son(e)));
1254
	outnl();
1255
	return ;
1256
   }     
1257
 
1258
  case chvar_tag : {
1259
	    if ( shape_size ( sh ( e ) ) == shape_size ( sh ( son ( e ) ) ) ) {
1260
		sh ( son ( e ) ) = sh ( e ) ;
1261
		evalone ( son ( e ), bitposn ) ;
1262
	    } else {
1263
		fail ( "Illegal chvar constant" ) ;
1264
	    }
1265
	    return ;
1266
	}
1267
 
1268
    default: 
1269
       fail("tag not in evaluated");
1270
 
1271
  }				/* end switch */
1272
}
1273
 
1274
 
1275
 
1276
/*
1277
 * Outputs data initialisers for the evaluated exp.
1278
 * The result is the instore "address" of the constant.
1279
 * A negative l implies that this is the initialisation of a global variable.
1280
 */
1281
instore evaluated 
1282
    PROTO_N ( ( e, l ) )
1283
    PROTO_T ( exp e X long l )
1284
{
1285
  int lab = (l == 0) ? next_data_lab() : (l < 0) ? l : -l;
1286
  int lab0 = lab;
1287
  instore isa;
1288
  exp z = e;
1289
  ash a ;
1290
  bool extnamed = (l == 0) ? 0 : main_globals[-lab - 1]->dec_u.dec_val.extnamed;
1291
  a = ashof(sh(e));
1292
 
1293
  FULLCOMMENT2("evaluated: %s %ld", (int)TAG_NAME(name(e)), l);
1294
 
1295
  isa.adval = 0;
1296
  isa.b.offset = 0;
1297
  isa.b.base = lab0;
1298
 
1299
  if (is_zero(e))
1300
  {
1301
    int byte_size = (a.ashsize + 7) >> 3;
1302
    int align = ((a.ashalign > 32 || a.ashsize > 32) ? 8 : 4);
1303
    if (!extnamed)
1304
    {
1305
       /* uninitialised global */
1306
       if (byte_size>8)
1307
	  insection(bss_section);
1308
       else
1309
	  insection(shortbss_section);
1310
       outs("\t.ALIGN\t");
1311
       outn(align);
1312
       outnl();
1313
       outs( ext_name(lab) ) ;
1314
       outs("\t.BLOCK\t");
1315
       outn(byte_size);
1316
       outnl();
1317
    }
1318
    else
1319
    {
1320
      /* align at least to word for speed of access */
1321
      /* if size greater than 4 bytes, align on double boundry for speed */
1322
      if (a.ashalign > 32 || a.ashsize > 32)
1323
	  set_align(64);
1324
      else
1325
	  set_align(32);
1326
 
1327
      if (byte_size>8)
1328
	 insection(bss_section);
1329
      else
1330
	 insection(shortbss_section);
1331
      outs( ext_name(lab) ) ;
1332
      outs("\t.COMM\t");
1333
      outn(byte_size);
1334
      outnl();
1335
    }
1336
  }
1337
  else
1338
  {
1339
     insection(data_section);
1340
     /* align at least to word for speed of access */
1341
     /* if size greater than 4 bytes, align on double boundry for speed */
1342
     if (a.ashalign > 32 || a.ashsize > 32)
1343
	set_align(64);
1344
     else
1345
	set_align(32);
1346
     outs( ext_name(lab) ) ;
1347
     outnl();
1348
     evalone(z, 0);
1349
     /* evalone does not output .BLOCKZ to finish off up to size, so protect next one */
1350
     if (a.ashalign > 32)
1351
	set_align(64);
1352
  }
1353
  return isa;
1354
}
1355
 
1356
 
1357
 
1358
 
1359
 
1360
 
1361
 
1362
 
1363
 
1364
 
1365
 
1366
 
1367
 
1368