Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/installers/sparc/common/eval.c – Rev 5

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
 
33
/*
34
			    VERSION INFORMATION
35
			    ===================
36
 
37
--------------------------------------------------------------------------
38
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/eval.c,v 1.1.1.1 1998/01/17 15:55:54 release Exp $
39
--------------------------------------------------------------------------
40
$Log: eval.c,v $
41
 * Revision 1.1.1.1  1998/01/17  15:55:54  release
42
 * First version to be checked into rolling release.
43
 *
44
 * Revision 1.15  1997/10/23  09:32:48  pwe
45
 * prep extra_diags
46
 *
47
 * Revision 1.14  1997/10/10  18:32:13  pwe
48
 * prep ANDF-DE revision
49
 *
50
 * Revision 1.13  1997/04/18  11:47:50  pwe
51
 * init large arrays
52
 *
53
 * Revision 1.12  1997/04/17  11:59:35  pwe
54
 * dwarf2 support
55
 *
56
 * Revision 1.11  1997/02/18  11:47:42  pwe
57
 * NEWDIAGS for debugging optimised code
58
 *
59
 * Revision 1.10  1996/12/19  12:59:53  pwe
60
 * SUNOS link from library with dynamic init
61
 *
62
 * Revision 1.9  1996/03/20  16:14:04  john
63
 * Reformatting
64
 *
65
 * Revision 1.8  1996/01/24  18:10:51  john
66
 * Added several constructs to eval
67
 *
68
 * Revision 1.7  1995/12/15  10:12:05  john
69
 * portability change
70
 *
71
 * Revision 1.6  1995/10/04  09:00:24  john
72
 * Added 64 bit constants
73
 *
74
 * Revision 1.5  1995/08/24  16:38:49  john
75
 * Changed to string_tag
76
 *
77
 * Revision 1.4  1995/07/14  16:30:21  john
78
 * Reformatting
79
 *
80
 * Revision 1.3  1995/05/26  12:57:27  john
81
 * Changes for new spec (3.1)
82
 *
83
 * Revision 1.2  1995/04/20  08:04:57  john
84
 * Fix to bitfields
85
 *
86
 * Revision 1.1.1.1  1995/03/13  10:18:32  john
87
 * Entered into CVS
88
 *
89
 * Revision 1.5  1995/01/06  13:54:51  john
90
 * Changed name of variable, because of clash with identical type name.
91
 *
92
 * Revision 1.4  1994/12/01  13:28:00  djch
93
 * Globals can be inited to env_offsets. Call boff_env_offset to get this
94
 *
95
 * Revision 1.3  1994/07/07  16:11:33  djch
96
 * Jul94 tape
97
 *
98
 * Revision 1.2  1994/05/25  14:16:36  djch
99
 * removed realrep, now use jmf's real2longs_IEEE
100
 *
101
 * Revision 1.1  1994/05/03  14:49:34  djch
102
 * Initial revision
103
 *
104
 * Revision 1.9  93/11/19  16:28:46  16:28:46  ra (Robert Andrews)
105
 * Added chvar_tag case.
106
 * 
107
 * Revision 1.8  93/09/27  14:42:49  14:42:49  ra (Robert Andrews)
108
 * Extend floating-point constants to deal with long doubles.  Add
109
 * know_size flag (see translat.c).
110
 * 
111
 * Revision 1.7  93/08/27  11:23:50  11:23:50  ra (Robert Andrews)
112
 * A number of lint-like changes.
113
 * 
114
 * Revision 1.6  93/08/18  11:10:06  11:10:06  ra (Robert Andrews)
115
 * Added minptr case to constant evaluation routine (Grenoble bug) to
116
 * allow constants of the form external - external.
117
 * 
118
 * Revision 1.5  93/07/12  15:12:25  15:12:25  ra (Robert Andrews)
119
 * Minor reformatting.
120
 * 
121
 * Revision 1.4  93/07/09  16:12:31  16:12:31  ra (Robert Andrews)
122
 * Reformatted.  Added support for little-endian machines (I've heard that
123
 * a little-endian SPARC is in the pipeline).  Changed is_zero to use
124
 * is_comm.
125
 * 
126
 * Revision 1.3  93/07/05  18:18:47  18:18:47  ra (Robert Andrews)
127
 * Made distinction between the System V assembler and the System V ABI.
128
 * 
129
 * Revision 1.2  93/06/29  14:24:07  14:24:07  ra (Robert Andrews)
130
 * Changed method of representing characters in strings.
131
 * 
132
 * Revision 1.1  93/06/24  14:58:09  14:58:09  ra (Robert Andrews)
133
 * Initial revision
134
 * 
135
--------------------------------------------------------------------------
136
*/
137
 
138
 
139
#define SPARCTRANS_CODE
140
 
141
/*
142
    This file contains routines for outputting constant initialisations.
143
*/
144
 
145
#include "config.h"
146
#include <ctype.h>
147
#include "addrtypes.h"
148
#include "common_types.h"
149
#include "tags.h"
150
#include "expmacs.h"
151
#include "exp.h"
152
#include "exptypes.h"
153
#include "maxminmacs.h"
154
#include "shapemacs.h"
155
#include "flpttypes.h"
156
#include "flpt.h"
157
#include "fbase.h"
158
#include "translat.h"
159
#include "comment.h"
160
#include "myassert.h"
161
#include "inst_fmt.h"
162
#include "szs_als.h"
163
#include "out.h"
164
#include "locate.h"
165
#include "regmacs.h"
166
#include "f64.h"
167
#include "procrec.h"
168
#include "bitsmacs.h"
169
#include "installglob.h"
170
#include "eval.h"
171
#ifdef NEWDWARF
172
#include "dw2_config.h"
173
#endif
174
/*
175
    INFORMATION FOR OUTPUTTING DATA
176
 
177
    The values are maximum, minimum, output directive.
178
*/
179
 
180
static mm scmm = { 127, -128, "\t.byte\t%ld\n" } ;
181
static mm uscmm = { 255, 0, "\t.byte\t%ld\n" } ;
182
static mm shmm = { 0x7fff, 0xffff8000, "\t.half\t%ld\n" } ;
183
static mm ushmm = { 0xffff, 0, "\t.half\t%ld\n" } ;
184
static mm swmm = { 0x7fffffff, 0x80000000, "\t.word\t%ld\n" } ;
185
static mm uswmm = { 0xffffffff, 0, "\t.word\t%ld\n" } ;
186
 
187
#define max(X,Y) ((X>Y)?X:Y)
188
 
189
/*
190
    FIND THE OUTPUT DATA CORRESPONDING TO A SHAPE
191
*/
192
 
193
mm maxmin 
194
    PROTO_N ( ( s ) )
195
    PROTO_T ( shape s ){
196
  switch ( name ( s ) ) {
197
    case scharhd : return ( scmm ) ;
198
    case ucharhd : return ( uscmm ) ;
199
    case swordhd : return ( shmm ) ;
200
    case uwordhd : return ( ushmm ) ;
201
    case slonghd : return ( swmm ) ;
202
    case ulonghd : return ( uswmm ) ;
203
  }
204
  return ( uswmm ) ;
205
}
206
 
207
 
208
/*
209
    FIND THE NEXT DATA LABEL
210
*/
211
 
212
int next_data_lab 
213
    PROTO_Z (){
214
  static int data_lab = 100 ;
215
  return ( ++data_lab ) ;
216
}
217
 
218
 
219
/*
220
    OUTPUT A LABEL
221
*/
222
 
223
void outlab 
224
    PROTO_N ( ( ll ) )
225
    PROTO_T ( int ll ){
226
  /* no preference for section here */
227
  outs ( ext_name ( ll ) ) ;
228
  return ;
229
}
230
 
231
 
232
/*
233
  OUTPUT A FLOATING POINT CONSTANT
234
 
235
  This routine should only be called if FBASE is 10.
236
*/
237
 
238
#if 0
239
static void outfloat 
240
    PROTO_N ( ( f, ro ) )
241
    PROTO_T ( flpt f X bool ro ){
242
#if ( FBASE == 10 )
243
  int i, n ;
244
  unsigned char *frac = flptnos [f].mant ;
245
  char *exppos ;
246
  char fltrepr [120] ;
247
  if (ro)
248
    insection ( rodata_section ) ;
249
  else
250
    insection ( data_section ) ;
251
  for ( n = MANT_SIZE - 1 ; n > 1 && frac [n] == 0 ; n-- ) /* SKIP */ ;
252
  fltrepr [0] = ( ( flptnos [f].sign < 0 ) ? '-' : '+' ) ;
253
  fltrepr [1] = frac [0] + '0' ;
254
  fltrepr [2] = '.' ;
255
  for ( i = 1 ; i <= n ; ++i ) fltrepr [ i + 2 ] = frac [i] + '0' ;
256
  exppos = &fltrepr [ i + 2 ] ;
257
  if ( flptnos [f].exp != 0 ) {
258
    sprintf ( exppos, "e%ld", flptnos [f].exp ) ;
259
  } 
260
  else {
261
    exppos [0] = 0 ;
262
  }
263
  outs ( fltrepr ) ;
264
#else
265
  fail ( "Illegal floating point constant" ) ;
266
#endif
267
  return ;
268
}
269
#endif
270
 
271
 
272
 
273
/*
274
  FIND THE VALUE OF AN INTEGER CONSTANT EXPRESSION
275
*/
276
long evalexp 
277
    PROTO_N ( ( e ) )
278
    PROTO_T ( exp e ){
279
  switch ( name ( e ) ) {
280
    case val_tag : {
281
      if(name(sh(e)) == offsethd && al2(sh(e))>=8) {
282
	return no(e)>>3;
283
      }
284
      else {
285
	return ( no ( e ) ) ;
286
      }
287
    }	
288
    case general_env_offset_tag :
289
    case env_offset_tag : {
290
      exp id = son(e);	/* as per tags.h, son is ident, not name */
291
 
292
      assert (name(id) == ident_tag);
293
 
294
      return boff_env_offset(id);
295
    }
296
    case env_size_tag : {
297
      exp tg = son(son(e));
298
      procrec *pr = &procrecs[no(son(tg))];
299
      bool leaf = (long)((pr->needsproc.prps & anyproccall) == 0);
300
      int arg_space;
301
      if(leaf) {
302
	arg_space = 16*32;
303
      }
304
      else {
305
	arg_space = ((max(pr->needsproc.maxargs,6*32)+((16+1)*32))+63)&~63;
306
      }
307
      return ( ((pr->spacereqproc.stack+63)&~63) + 
308
	       pr->needsproc.callee_size +arg_space)>>3;
309
    }
310
 
311
    case offset_add_tag : {
312
      return (evalexp(son(e)) + evalexp(bro(son(e))));
313
    }
314
    case offset_max_tag : {
315
      return (max(evalexp(son(e)),evalexp(bro(son(e)))));
316
    }
317
    case offset_pad_tag : {
318
      return (rounder(evalexp(son(e)),shape_align(sh(e))));
319
    }
320
    case offset_mult_tag : {
321
      return (evalexp(son(e))*evalexp(bro(son(e))));
322
    }
323
    case offset_div_tag :
324
    case offset_div_by_int_tag : {
325
      return (evalexp(son(e))/evalexp(bro(son(e))));
326
    }
327
    case offset_subtract_tag : {
328
      return (evalexp(son(e))-evalexp(bro(son(e))));
329
    }
330
    case offset_negate_tag : {
331
      return (- evalexp(son(e)));
332
    }
333
 
334
    case bitf_to_int_tag : {
335
      return ( evalexp ( son ( e ) ) ) ;
336
    }
337
 
338
    case int_to_bitf_tag : {
339
      ash a ;
340
      unsigned long w = ( unsigned long ) evalexp ( son ( e ) ) ;
341
      a = ashof ( sh ( e ) ) ;
342
      if ( a.ashalign != 1 && !( name ( sh ( e ) ) == cpdhd &&
343
				 a.ashalign == 32 ) ) {
344
	fail ( "Illegal bitfield constant" ) ;
345
      }
346
				 if ( a.ashsize != 32 ) {
347
				   w &= ( ( 1 << a.ashsize ) - 1 ) ;
348
				 }
349
				 return ( ( long ) w ) ;
350
    }
351
 
352
    case not_tag : {
353
      long a1 = evalexp ( son ( e ) ) ;
354
      return ( ~a1 ) ;
355
    }
356
 
357
    case and_tag : {
358
      long a1 = evalexp ( son ( e ) ) ;
359
      long a2 = evalexp ( bro ( son ( e ) ) ) ;
360
      return ( a1 & a2 ) ;
361
    }
362
 
363
    case or_tag : {
364
      long a1 = evalexp ( son ( e ) ) ;
365
      long a2 = evalexp ( bro ( son ( e ) ) ) ;
366
      return ( a1 | a2 ) ;
367
    }
368
 
369
    case xor_tag : {
370
      long a1 = evalexp ( son ( e ) ) ;
371
      long a2 = evalexp ( bro ( son ( e ) ) ) ;
372
      return ( a1 ^ a2 ) ;
373
    }
374
 
375
    case shr_tag : {
376
      bool sgned = ( bool ) ( name ( sh ( e ) ) & 1 ) ;
377
      long a1 = evalexp ( son ( e ) ) ;
378
      long a2 = evalexp ( bro ( son ( e ) ) ) ;
379
      if ( sgned ) {
380
	return ( a1 >> a2 ) ;
381
      } 
382
      else {
383
	unsigned long b1 = ( unsigned long ) a1 ;
384
	return ( ( long ) ( b1 >> a2 ) ) ;
385
      }
386
    }
387
 
388
    case shl_tag : {
389
      long a1 = evalexp ( son ( e ) ) ;
390
      long a2 = evalexp ( bro ( son ( e ) ) ) ;
391
      return ( a1 << a2 ) ;
392
    }
393
 
394
    case concatnof_tag : {
395
      ash s1, s2 ;
396
      unsigned long a1 = ( unsigned long ) evalexp ( son ( e ) ) ;
397
      unsigned long a2 = ( unsigned long ) evalexp ( bro ( son ( e ) ) ) ;
398
      s1 = ashof ( sh ( son ( e ) ) ) ;
399
      s2 = ashof ( sh ( bro ( son ( e ) ) ) ) ;
400
 
401
      /* We should only be concatenating bitfields */
402
      assert ( s1.ashalign == 1 && s1.ashsize <= 32 ) ;
403
      assert ( s2.ashalign == 1 && s2.ashsize <= 32 ) ;
404
      assert ( s1.ashsize + s2.ashsize <= 32 ) ;
405
 
406
      if ( s2.ashsize == 32 ) {
407
	/* avoid illegal shift by 32 */
408
	assert ( a1 == 0 ) ;
409
	return ( ( long ) a2 ) ;
410
      }
411
      return ( ( long ) ( ( a1 << s2.ashsize ) | a2 ) ) ;
412
    }
413
 
414
    case clear_tag : {
415
      return ( 0 ) ;
416
    }
417
  }
418
  fail ( "Illegal integer constant" ) ;
419
  return ( 0 ) ;
420
}
421
 
422
 
423
/*
424
  OUTPUT A SIMPLE VALUE
425
*/
426
static void oneval 
427
    PROTO_N ( ( val, al, rep ) )
428
    PROTO_T ( int val X long al X int rep ){
429
  char *as ;
430
  if ( al <= 8 ) {
431
    as = "\t.byte\t" ;
432
  } 
433
  else if ( al <= 16 ) {
434
    as = "\t.half\t" ;
435
  } 
436
  else {
437
    as = "\t.word\t" ;
438
  }
439
  assert ( rep == 1 ) ;
440
  outs ( as ) ;
441
  outn ( val ) ;
442
  outnl () ;
443
  return ;
444
}
445
 
446
 
447
/*
448
  OUTPUT A STRING
449
*/
450
static void outascii 
451
    PROTO_N ( ( s, strsize ) )
452
    PROTO_T ( char * s X long strsize ){
453
  while ( strsize > 0 ) {
454
    int i ;
455
    outs ( "\t.ascii\t\"" ) ;
456
    for ( i = 0 ; strsize > 0 && i < 48 ; i++ ) {
457
      int c = ( int ) *s ;
458
      switch ( c ) {
459
	case '"'  : outs ( "\\\"" ) ; break ;
460
	case '\\' : outs ( "\\\\" ) ; break ;
461
	case '\t' : outs ( "\\t" ) ; break ;
462
	case '\n' : outs ( "\\n" ) ; break ;
463
	case '\r' : outs ( "\\r" ) ; break ;
464
	case '\f' : outs ( "\\f" ) ; break ;
465
	case '\b' : outs ( "\\b" ) ; break ;
466
	default : {
467
	  if ( c >= 0 && isprint ( c ) ) {
468
	    outc ( c ) ;
469
	  } 
470
	  else {
471
	    /* octal representation */
472
	    outf ( "\\%.3o", (unsigned)c & 0xff ) ;
473
	  }
474
	  break ;
475
	}
476
      }
477
      s++ ;
478
      strsize-- ;
479
    }
480
    outs ( "\"\n" ) ;
481
  }
482
  return ;
483
}
484
 
485
 
486
/*
487
    TYPE REPRESENTING BIT PATTERNS
488
*/
489
 
490
typedef struct {
491
  int bitposn ;
492
  int value_size ;
493
  unsigned long value ;
494
} concbittype ;
495
 
496
 
497
/*
498
    FORM AN EMPTY BIT PATTERN
499
*/
500
static concbittype emptyconcbit 
501
    PROTO_N ( ( bitposn ) )
502
    PROTO_T ( int bitposn ){
503
  concbittype start ;
504
  start.bitposn = bitposn ;
505
  start.value_size = 0 ;
506
  start.value = 0 ;
507
  return ( start ) ;
508
}	
509
 
510
 
511
/*
512
  OUTPUT A BIT PATTERN
513
*/
514
static void outconcbit 
515
    PROTO_N ( ( c, ro ) )
516
    PROTO_T ( concbittype c X bool ro ){
517
  unsigned long w = c.value ;
518
  int sz = c.value_size ;
519
  int i, bytes = ( sz + 7 ) / 8 ;
520
  if (ro)
521
    insection ( rodata_section ) ;
522
  else
523
    insection ( data_section ) ;
524
  if ( sz == 0 ) return ;
525
  assert ( sz <= 32 ) ;
526
 
527
  /* output as a series of bytes */
528
  outs ( "\t.byte\t" ) ;
529
#if little_end
530
  for ( i = 0 ; i < bytes ; i++ ) {
531
    if ( i != 0 ) outc ( ',' ) ;
532
    outf ( "%#lx", w & 0xff ) ;
533
    w = w >> 8 ;
534
  }
535
#else
536
    /* shift to left end of word */
537
  if ( sz != 32 ) w = w << ( 32 - sz ) ;
538
  for ( i = 0 ; i < bytes ; i++ ) {
539
    if ( i != 0 ) outc ( ',' ) ;
540
    outf ( "%#lx", ( w >> 24 ) & 0xff ) ;
541
    w = w << 8 ;
542
  }
543
#endif
544
  outnl () ;
545
  assert ( w == 0 ) ;
546
  return ;
547
}
548
 
549
/*
550
  Output a unary representation of the number val.  val should be 
551
  less than or equal to 31 as it represent the number of bits
552
  in a bitfield which does not occupy a whole machine word.
553
*/
554
long unary 
555
    PROTO_N ( ( val ) )
556
    PROTO_T ( int val ){
557
  int loop;
558
  long result=0;
559
  assert (val <=31);
560
  for(loop=0;loop<val;++loop){
561
    result <<=1;
562
    result |= 1;
563
  }
564
  return result;
565
}
566
 
567
 
568
 
569
/*
570
  ADD A VALUE TO A BIT PATTERN
571
*/
572
 
573
static concbittype addconcbitaux 
574
    PROTO_N ( ( w, size, b4, ro ) )
575
    PROTO_T ( unsigned long w X int size X concbittype b4 X bool ro ){
576
  int wordpos ; /* bit position within word */
577
  if ( b4.value_size == 32 ||
578
       ( b4.value_size != 0 && ( b4.bitposn & 31 ) == 0 ) ) {
579
    assert ( ( b4.bitposn & 31 ) == 0 ) ;
580
    wordpos = 32 ;
581
  } 
582
  else {
583
    wordpos = ( b4.bitposn & 31 ) ;
584
  }
585
  assert ( size > 0 ) ;
586
  assert ( size <= 32 ) ;
587
  assert ( b4.value_size <= 32 ) ;
588
  assert ( wordpos == 0 || b4.value_size <= wordpos ) ;
589
  if ( ( size == 0 && ( wordpos != 0 || b4.value_size != 0 ) ) ||
590
       ( wordpos + size > 32 ) ) {
591
    assert ( wordpos == 32 ) ; /* should be aligned automatically */
592
 
593
    /* crossed boundary : output value */
594
    outconcbit ( b4, ro ) ;
595
 
596
    /* start new value */
597
    b4.value_size = 0 ;
598
    b4.value = 0 ;
599
    assert ( ( b4.bitposn & 31 ) == 0 ) ;
600
  }
601
  if ( size == 0 ) return ( b4 ) ;
602
  /* add to b4 */
603
  if ( size == 32 ) {
604
    b4.value = w ;
605
  } 	
606
  else {
607
#if little_end
608
    b4.value = b4.value | ( w << b4.value_size ) ;
609
#else
610
    b4.value = ( b4.value << size ) | (w & unary(size));
611
#endif
612
  }
613
  b4.bitposn += size ;
614
  b4.value_size += size ;
615
  assert ( b4.value_size <= 32 ) ;
616
  return ( b4 ) ;
617
}	
618
 
619
 
620
/*
621
  EVALUATE A CONSTANT BIT PATTERN
622
*/
623
static concbittype evalconcbitaux 
624
    PROTO_N ( ( e, b4, ro ) )
625
    PROTO_T ( exp e X concbittype b4 X bool ro ){
626
  switch ( name ( e ) )    {
627
    case concatnof_tag : {
628
      concbittype lhs, rhs ;
629
      lhs = evalconcbitaux ( son ( e ), b4, ro ) ;
630
      rhs = evalconcbitaux ( bro ( son ( e ) ), lhs, ro ) ;
631
      return ( rhs ) ;
632
    }
633
    default : {
634
      int size = shape_size ( sh ( e ) ) ;
635
      unsigned ev = ( unsigned ) evalexp ( e ) ;
636
      assert ( shape_align ( sh ( e ) ) == 1 ) ;
637
      return ( addconcbitaux ( ev, size, b4, ro ) ) ;
638
    }
639
  }
640
}
641
 
642
 
643
/*
644
  OUTPUT A CONSTANT BIT PATTERN
645
*/
646
static void evalconcbit 
647
    PROTO_N ( ( e, bitposn, ro ) )
648
    PROTO_T ( exp e X int bitposn X bool ro ){
649
  concbittype start ;
650
  start = emptyconcbit ( bitposn ) ;
651
  outconcbit ( evalconcbitaux ( e, start, ro ), ro ) ;
652
  return ;
653
}
654
 
655
 
656
/*
657
  DOES AN EXPRESSION REPRESENT ZERO?
658
*/
659
 
660
#if 1
661
 
662
#define is_zero( e )	is_comm ( e )
663
 
664
#else
665
 
666
bool is_zero 
667
    PROTO_N ( ( e ) )
668
    PROTO_T ( exp e ){
669
  if ( e == nilexp ) return ( 1 );
670
  switch ( name ( e ) ) {
671
    case null_tag : return ( 1 ) ;
672
    case val_tag : return ( no ( e ) == 0 ? 1 : 0 ) ;
673
    case ncopies_tag :
674
    case int_to_bitf_tag : {
675
      return ( is_zero ( son ( e ) ) ) ;
676
    }
677
    case compound_tag : {
678
      e = bro ( son ( e ) ) ;
679
      while ( 1 ) {
680
	if ( is_zero ( e ) == 0 ) return ( 0 ) ;
681
	if ( last ( e ) ) return ( 1 ) ;
682
	e = bro ( bro ( e ) ) ;
683
      }
684
      /* NOT REACHED */
685
    }
686
    case real_tag : {
687
      flt f ;
688
      f = flptnos [ no ( e ) ] ;
689
      if ( f.exp == 0 ) {
690
	int i ;
691
	for ( i = 0 ; i < MANT_SIZE ; i++ ) {
692
	  if ( f.mant [i] != 0 ) return ( 0 ) ;
693
	}
694
	return ( 1 ) ;	 /* all zero */
695
      }
696
      return ( 0 ) ;
697
    }
698
  }
699
  return ( 0 ) ;
700
}
701
 
702
#endif
703
 
704
 
705
/*
706
    OUTPUT AN ALIGNMENT
707
*/
708
static void set_align 
709
    PROTO_N ( ( al ) )
710
    PROTO_T ( long al ){
711
#if 0
712
  assert ( al >= 8 && al <= 64 ) ;
713
#endif
714
  if ( al > 8 ) {
715
    outs ( "\t.align\t" ) ;
716
    outn ( al / 8 ) ;
717
    outnl () ;
718
  }
719
  return ;
720
}
721
 
722
 
723
/*
724
    EVALUATE AN EXPRESSION
725
*/
726
void evalone 
727
    PROTO_N ( ( e, bitposn, ro ) )
728
    PROTO_T ( exp e X int bitposn X bool ro ){
729
  long al = ( long ) shape_align ( sh ( e ) ) ;
730
  long sz = ( long ) shape_size ( sh ( e ) ) ;
731
  if (ro)
732
    insection ( rodata_section ) ;
733
  else
734
    insection ( data_section ) ;
735
  set_align ( al ) ;
736
  if ( al != 0 ) bitposn = ( int ) ( ( bitposn / al ) * al ) ;
737
  switch ( name ( e ) ) {
738
    case string_tag : {
739
      /* Strings or arrays of integers */
740
      int i, j ;
741
      long char_size = ( long ) props ( e ) ;
742
      long strsize = sz / char_size ;
743
      char *st = nostr ( e ) ;
744
      if ( char_size == 8 ) {
745
	outascii ( st, strsize ) ;
746
	return ;
747
      }
748
      if ( strsize > 0 ) set_align ( char_size ) ;
749
      for ( j = 0 ; j < strsize ; /**/ ) {
750
	switch ( char_size ) {
751
	  case 8 : {
752
	    outs ( "\t.byte\t" ) ;
753
	    break ;
754
	  }
755
	  case 16 : {
756
	    outs ( "\t.half\t" ) ;
757
	    break ;
758
	  }
759
	  case 32 : {
760
	    outs ( "\t.word\t" ) ;
761
	    break ;
762
	  }
763
	}
764
	/* output chars in batches */
765
	for ( i = j ; i < strsize && i - j < 8 ; i++ ) {
766
	  if ( i != j ) outc ( ',' ) ;
767
	  switch ( char_size ) {
768
	    case 8 : {
769
	      outf ( "0x%x", st [i] ) ;
770
	      break ;
771
	    }
772
	    case 16 : {
773
	      outf ( "0x%x", ( ( short * ) st ) [i] ) ;
774
	      break ;
775
	    }
776
	    case 32 : {
777
	      outf ( "0x%x", ( ( int * ) st ) [i] ) ;
778
	      break ;
779
	    }
780
	  }
781
	}
782
	outnl () ;
783
	j = i ;
784
      }
785
    return ;
786
    }
787
    case real_tag : {
788
      /* Floating point constant */
789
      flt *f = flptnos + no ( e ) ;
790
      r2l v;
791
      if ( sz == 32 ) {
792
	v = real2longs_IEEE(f,0);
793
	outs ( "\t.word\t" ) ;
794
	outn ( v.i1 ) ;
795
      } 
796
      else if ( sz == 64 ) {
797
	v = real2longs_IEEE(f,1);
798
	outs ( "\t.word\t" ) ;
799
	outn ( v.i2 ) ;
800
      outc ( ',' ) ;
801
      outn ( v.i1 ) ;
802
      } 
803
      else {
804
	v = real2longs_IEEE(f,2);
805
	outs ( "\t.word\t" ) ;
806
	outn ( v.i4 ) ;
807
	outc ( ',' ) ;
808
	outn ( v.i3 ) ;
809
	outc ( ',' ) ;
810
	outn ( v.i2 ) ;
811
	outc ( ',' ) ;
812
	outn ( v.i1 ) ;
813
      }
814
      outnl () ;
815
      return ;
816
    }
817
    case null_tag : {
818
      /* Zero */
819
      no ( e ) = 0 ;
820
      /* Fall through */
821
    }
822
    case val_tag : {
823
      if(name(sh(e)) == s64hd || name(sh(e)) == u64hd){
824
	flt64 bval;
825
	bval = exp_to_f64(e);
826
	oneval(bval.small,32,1);
827
	oneval(bval.big,32,1);
828
      }
829
      /* Integer constant */
830
      if(al2(sh(e))>=8 && name(sh(e)) == offsethd){
831
	no(e) = no(e)>>3;
832
      }
833
      if ( al == 1 ) {
834
	evalconcbit ( e, bitposn, ro ) ;
835
      } 
836
      else {
837
	oneval ( no ( e ), al, 1 ) ;
838
      }
839
      return ;
840
    }
841
    case name_tag : {
842
      /* Global name */
843
      dec *globdec = brog ( son ( e ) ) ;
844
      char *nm = globdec->dec_u.dec_val.dec_id ;
845
      outs ( "\t.word " ) ;
846
      outs ( nm ) ;
847
      if ( no ( e ) ) {
848
	outc ( '+' ) ;
849
	outn ( no ( e ) / 8 ) ;
850
      }
851
      outnl () ;
852
      return ;
853
    }
854
    case compound_tag : {
855
      /* Compound values */
856
      exp off = son ( e ) ;
857
      exp tup = bro ( off ) ;
858
      concbittype left ;
859
      long last_offset = 0 ;
860
      long last_align = 0 ;
861
      long ta = ( long ) shape_align ( sh ( tup ) ) ;
862
      long ts = shape_size ( sh ( tup ) ) ;
863
      left = emptyconcbit ( bitposn ) ;
864
      /* output elements of aggregate recursively */
865
      while ( 1 ) {
866
	long noff = no ( off ) ;
867
	long gap = noff - left.bitposn ;
868
	/* check that component's alignment matches offset in struct */
869
	assert ( ( noff / ta ) * ta <= noff ) ;
870
	assert ( ta <= al ) ;
871
	if(ts == 0){
872
	  if(last(tup)) return;
873
	  else {
874
	    off = bro ( bro ( off ) ) ;
875
	    assert ( !last ( off ) ) ;
876
	    tup = bro ( off ) ;
877
	    ta = ( long ) shape_align ( sh ( tup ) ) ;
878
	    ts = shape_size ( sh ( tup ) ) ;
879
	    continue;
880
	  }
881
	}
882
	/* and is no greater that struct's alignment */
883
	if ( noff < last_offset ) {
884
	  fail ( "Compound components badly ordered" ) ;
885
	}
886
	if ( last_align <= 1 || ta <= 1 || gap >= ta ) {
887
	  /* get gap down */
888
	  while ( gap > 0 ) {
889
	    left = addconcbitaux ( 0, 1, left, ro ) ;
890
	    gap-- ;
891
	  }
892
	} 
893
        else {
894
	  /* alignment will handle gap */
895
	  left.bitposn = ( int ) rounder ( left.bitposn, ta ) ;
896
	}
897
	last_offset = noff ;
898
	last_align = ta ;
899
	assert ( left.bitposn - bitposn == noff ) ;
900
	if ( ta == 1 ) {
901
	  /* collect bitfields */
902
	  left = evalconcbitaux ( tup, left, ro ) ;
903
	} 
904
        else {
905
	/* output final bits from any previous field */
906
	  int lb ;
907
	  outconcbit ( left, ro ) ;
908
	  lb = left.bitposn ;
909
	  left = emptyconcbit ( lb ) ;
910
	  evalone ( tup, left.bitposn, ro ) ;
911
	  left.bitposn = ( int ) ( left.bitposn + ts ) ;
912
	}
913
	if ( last ( tup ) ) {
914
	  /* output final bits from any previous field */
915
	  long databits = no ( off ) + ts ;
916
	  long trailing_bytes = ( sz - databits ) / 8 ;
917
	  outconcbit ( left, ro ) ;
918
	  assert ( sz >= databits ) ;
919
	  /* pad out trailing uninitialised space, eg union */
920
	  if ( sz > databits && trailing_bytes > 0 ) {
921
	    outs ( "\t.skip\t" ) ;
922
	    outn ( trailing_bytes ) ;
923
	    outnl () ;
924
	  }
925
	  return ;
926
	}
927
	off = bro ( bro ( off ) ) ;
928
	assert ( !last ( off ) ) ;
929
	tup = bro ( off ) ;
930
	ta = ( long ) shape_align ( sh ( tup ) ) ;
931
	ts = shape_size ( sh ( tup ) ) ;
932
      }
933
      /* NOT REACHED */
934
    }
935
    case nof_tag : {
936
      /* Arrays */
937
      exp s = son ( e ) ;
938
      set_align ( al ) ;
939
      for ( ; ; ) {
940
	evalone ( s, bitposn, ro ) ;
941
	if ( last ( s ) ) return ;
942
	s = bro ( s ) ;
943
      }
944
      /* NOT REACHED */
945
    }
946
    case ncopies_tag : {
947
      /* Multiple copies */
948
      ash c ;
949
      int i, n = no ( e ) ;
950
      while ( name ( son ( e ) ) == ncopies_tag ) {
951
	e = son ( e ) ;
952
	n *= no ( e ) ;
953
      }
954
      e = son ( e ) ;
955
      c = ashof ( sh ( e ) ) ;
956
#if 0
957
      if ( c.ashalign != 0 ) {
958
	bitsize = ( c.ashsize / c.ashalign ) * c.ashalign ;
959
      } 
960
      else {
961
	bitsize = 0 ;
962
      }
963
#endif
964
      if ( is_zero ( e ) ) {
965
	set_align ( al ) ;
966
	outs ( "\t.skip\t" ) ;
967
	outn ( ( sz + 7 ) >> 3 ) ;
968
	outnl () ;
969
      }
970
      else
971
        for ( i = 0 ; i < n ; i++ ) evalone ( e, bitposn, ro ) ;
972
      return ;
973
    }
974
    case concatnof_tag : {
975
      /* Concatenation of arrays */
976
      if ( al == 1 ) {
977
	/* allow for bitfields */
978
	evalconcbit ( e, bitposn, ro ) ;
979
      } 
980
      else {
981
	ash a ;
982
	a = ashof ( sh ( son ( e ) ) ) ;
983
	evalone ( son ( e ), bitposn, ro ) ;
984
	bitposn = ( int ) ( bitposn + a.ashsize ) ;
985
	a = ashof ( sh ( bro ( son ( e ) ) ) ) ;
986
	if ( a.ashalign != 0 ) {
987
	  bitposn = ( int ) ( ( bitposn / a.ashalign ) *
988
			      a.ashalign ) ;
989
	}	
990
	evalone ( bro ( son ( e ) ), bitposn, ro ) ;
991
      }
992
      return ;
993
    }
994
    case clear_tag : {
995
      if ( al == 1 ) {
996
	/* allow for bitfields */
997
	evalconcbit ( e, bitposn, ro ) ;
998
	return ;
999
      }
1000
      outs ( "\t.skip\t" ) ;
1001
      outn ( ( sz + 7 ) >> 3 ) ;
1002
      outnl () ;
1003
      return ;
1004
    }
1005
    case not_tag :
1006
    case and_tag :
1007
    case or_tag :
1008
    case shl_tag :
1009
    case shr_tag :
1010
    case bitf_to_int_tag :
1011
    case int_to_bitf_tag :
1012
    case general_env_offset_tag :
1013
    case env_offset_tag : 
1014
    case env_size_tag : case offset_add_tag : case offset_max_tag :
1015
    case offset_pad_tag : case offset_mult_tag : case offset_div_tag :
1016
    case offset_div_by_int_tag : case offset_subtract_tag : 
1017
    case offset_negate_tag : {
1018
      outs ( "\t.word\t" ) ;
1019
      outn ( evalexp ( e ) ) ;
1020
      outnl () ;
1021
      return ;
1022
    }
1023
 
1024
    case chvar_tag : {
1025
      if ( shape_size ( sh ( e ) ) == shape_size ( sh ( son ( e ) ) ) ) {
1026
	sh ( son ( e ) ) = sh ( e ) ;
1027
	evalone ( son ( e ), bitposn, ro ) ;
1028
      } 
1029
      else {
1030
	fail ( "Illegal chvar constant" ) ;
1031
      }
1032
      return ;
1033
    }
1034
 
1035
    case minptr_tag : {
1036
      exp p1 = son ( e ) ;
1037
      exp p2 = bro ( p1 ) ;
1038
      if ( name ( p1 ) == name_tag && name ( p2 ) == name_tag ) {
1039
	long n = no ( p1 ) - no ( p2 ) ;
1040
	char *n1 = brog ( son ( p1 ) )->dec_u.dec_val.dec_id ;
1041
	char *n2 = brog ( son ( p2 ) )->dec_u.dec_val.dec_id ;
1042
	outs ( "\t.word\t" ) ;
1043
	outs ( n1 ) ;
1044
	outs ( "-" ) ;
1045
	outs ( n2 ) ;
1046
	if ( n < 0 ) {
1047
	  outn ( n ) ;
1048
	} 
1049
        else if ( n > 0 ) {
1050
	  outc ( '+' ) ;
1051
	  outn ( n ) ;
1052
	}
1053
	outnl () ;
1054
	return ;
1055
      }
1056
      /* FALL THROUGH */
1057
    }
1058
 
1059
    default : {
1060
      fail ( "Illegal constant" ) ;
1061
      return ;
1062
    }
1063
  }
1064
}
1065
 
1066
 
1067
/*
1068
  FLAG
1069
*/
1070
bool know_size = 0 ;
1071
 
1072
 
1073
/*
1074
  OUTPUT DATA INITIALISERS FOR AN EXPRESSION
1075
  The result is the instore address of the constant.  A negative 
1076
  value of ll indicates the initialisation of a global variable.
1077
*/
1078
instore evaluated 
1079
    PROTO_N ( ( e, ll, ro ) )
1080
    PROTO_T ( exp e X long ll X bool ro ){
1081
  ash a ;
1082
  int lab ;
1083
  exp z = e ;
1084
  instore isa ;
1085
  bool extnamed ;
1086
  know_size = 0 ;
1087
  if ( ll == 0 ) {
1088
    lab = next_data_lab () ;
1089
    extnamed = 0 ;
1090
  } 
1091
  else if ( ll < 0 ) {
1092
    lab = ( int ) ll ;
1093
    extnamed = ( bool ) main_globals [ -lab - 1 ]->dec_u.dec_val.extnamed ;
1094
  } 
1095
  else /* if ( ll > 0 ) */ {
1096
    lab = ( int ) ( -ll ) ;
1097
    extnamed = ( bool ) main_globals [ -lab - 1 ]->dec_u.dec_val.extnamed ;
1098
  }
1099
  a = ashof ( sh ( e ) ) ;
1100
 
1101
  isa.adval = 0 ;
1102
  isa.b.offset = 0 ;
1103
  isa.b.base = lab ;
1104
  if ( is_zero ( e ) ) {
1105
    int byte_size = ( int ) ( ( a.ashsize + 7 ) >> 3 ) ;
1106
    int align = ( ( a.ashalign > 32 || a.ashsize > 32 ) ? 8 : 4 ) ;
1107
    if ( !extnamed || (name(e) == clear_tag && no(e) == -1) ||
1108
		/* SUNOS simplifies extraction of .common from library modules */
1109
	 (!sysV_assembler && dynamic_init_proc != (char *)0 &&
1110
		!(main_globals [ -lab - 1 ]->dec_u.dec_val.is_common))
1111
	) {
1112
      outs ( "\t.reserve\t" ) ;
1113
      outlab ( lab ) ;
1114
      if ( sysV_assembler ) {
1115
	outc ( ',' ) ;
1116
	outn ( byte_size ) ;
1117
	outs ( ",\".bss\"," ) ;
1118
	outn ( align ) ;
1119
	outnl () ;
1120
      } 
1121
      else {
1122
	outc ( ',' ) ;
1123
	outn ( byte_size ) ;
1124
	outs ( ",\"bss\"," ) ;
1125
	outn ( align ) ;
1126
	outnl () ;
1127
      }
1128
#ifdef NEWDWARF
1129
      if (dwarf2 && (name(e) == clear_tag && no(e) == -1))
1130
        note_data (lab, ro);	/* do_prom */
1131
#endif
1132
    } 
1133
    else {
1134
      if ( a.ashalign > 32 || a.ashsize > 32 ) {
1135
	set_align ( 64L ) ;
1136
      } 
1137
      else {
1138
	set_align ( 32L ) ;
1139
      }
1140
      outs ( "\t.common\t" ) ;
1141
      outlab ( lab ) ;
1142
      if ( sysV_assembler ) {
1143
	outc ( ',' ) ;
1144
	outn ( byte_size ) ;
1145
	outc ( ',' ) ;
1146
	outn ( align ) ;
1147
	outnl () ;
1148
      } 
1149
      else {
1150
	outc ( ',' ) ;
1151
	outn ( byte_size ) ;
1152
	outnl () ;
1153
      }
1154
    }
1155
    know_size = 1 ;
1156
  } 
1157
  else {
1158
#ifdef NEWDWARF
1159
    if (dwarf2)
1160
      note_data (lab, ro);
1161
#endif
1162
    if (ro)
1163
      insection ( rodata_section ) ;
1164
    else
1165
      insection ( data_section ) ;
1166
    if ( a.ashalign > 32 || a.ashsize > 32 ) {
1167
      set_align ( 64L ) ;
1168
    } 
1169
    else {
1170
      set_align ( 32L ) ;
1171
    }
1172
    outlab ( lab ) ;
1173
    outs ( ":\n" ) ;
1174
    if(a.ashsize != 0){
1175
      evalone ( z, 0, ro ) ;
1176
    }
1177
    /* evalone does not output .skip to finish off */
1178
    if ( a.ashalign > 32 ) set_align ( 64L ) ;
1179
    /* return to .text for local values */
1180
    if ( ll >= 0 ) insection ( text_section ) ;
1181
  }
1182
  return ( isa ) ;
1183
}