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/tendra4/src/installers/power/common/eval.c – Rev 2

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
    Copyright (c) 1993 Open Software Foundation, Inc.
3
 
4
 
5
    All Rights Reserved
6
 
7
 
8
    Permission to use, copy, modify, and distribute this software
9
    and its documentation for any purpose and without fee is hereby
10
    granted, provided that the above copyright notice appears in all
11
    copies and that both the copyright notice and this permission
12
    notice appear in supporting documentation.
13
 
14
 
15
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
16
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17
    PARTICULAR PURPOSE.
18
 
19
 
20
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
21
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
23
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
*/
26
 
27
/*
28
    		 Crown Copyright (c) 1997
29
 
30
    This TenDRA(r) Computer Program is subject to Copyright
31
    owned by the United Kingdom Secretary of State for Defence
32
    acting through the Defence Evaluation and Research Agency
33
    (DERA).  It is made available to Recipients with a
34
    royalty-free licence for its use, reproduction, transfer
35
    to other parties and amendment for any purpose not excluding
36
    product development provided that any such use et cetera
37
    shall be deemed to be acceptance of the following conditions:-
38
 
39
        (1) Its Recipients shall ensure that this Notice is
40
        reproduced upon any copies or amended versions of it;
41
 
42
        (2) Any amended version of it shall be clearly marked to
43
        show both the nature of and the organisation responsible
44
        for the relevant amendment or amendments;
45
 
46
        (3) Its onward transfer from a recipient to another
47
        party shall be deemed to be that party's acceptance of
48
        these conditions;
49
 
50
        (4) DERA gives no warranty or assurance as to its
51
        quality or suitability for any purpose and DERA accepts
52
        no liability whatsoever in relation to any use to which
53
        it may be put.
54
*/
55
 
56
 
57
 
58
/**********************************************************************
59
$Author: release $
60
$Date: 1998/02/04 15:48:44 $
61
$Revision: 1.2 $
62
$Log: eval.c,v $
63
 * Revision 1.2  1998/02/04  15:48:44  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:56  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.3  1996/10/14  17:31:42  pwe
70
 * include called callees in env_size
71
 *
72
 * Revision 1.2  1996/10/04  16:00:31  pwe
73
 * add banners and mod for PWE ownership
74
 *
75
**********************************************************************/
76
 
77
 
78
/*****************************************************************
79
		eval.c
80
 
81
	The main procedure defined here is evaluated which outputs
82
assembler for data. The parameters are an evaluated exp and an index
83
into the table of externals (or 0 meaning anonymous).
84
*****************************************************************/
85
 
86
#include "config.h"
87
#include <ctype.h>
88
#include "memtdf.h"
89
#include "codegen.h"
90
#include "geninst.h"
91
 
92
#include "myassert.h"
93
#include "maxminmacs.h"
94
#include "flpttypes.h"
95
#include "flpt.h"
96
#include "machine.h"
97
#include "translat.h"
98
#include "comment.h"
99
 
100
#include "eval.h"
101
#include "frames.h"
102
#include "f64.h"
103
extern FILE *as_file;
104
 
105
long correct_shape PROTO_S ((long, int));
106
 
107
/* various pieces of info for outputting data depending on shape */
108
static	mm scmm	=	{127,		-128,		"\t.byte\t%ld\n"};
109
static	mm uscmm =	{255,		0,		"\t.byte\t%ld\n"};
110
static	mm shmm	=	{0x7fff,	0xffff8000,	"\t.short\t%ld\n"};
111
static	mm ushmm =	{0xffff,	0,		"\t.short\t%ld\n"};
112
static	mm swmm	=	{0x7fffffff,	0x80000000,	"\t.long\t%ld\n"};
113
static	mm uswmm =	{0xffffffff,	0,		"\t.long\t%ld\n"};
114
 
115
 
116
/* number for anonymous label in data space - L.Dnnn */
117
int next_data_lab PROTO_Z ()
118
{
119
  static int data_lab = 100;
120
 
121
  return ++data_lab;
122
}
123
 
124
 
125
/*************************************************************
126
maxmin
127
 
128
finds the data size from the range of an integer shape
129
**************************************************************/
130
mm maxmin PROTO_N ((s)) PROTO_T (shape s)
131
{
132
  switch (name(s))
133
  {
134
  case scharhd:
135
    return scmm;
136
  case ucharhd:
137
    return uscmm;
138
  case swordhd:
139
    return shmm;
140
  case uwordhd:
141
    return ushmm;
142
  case slonghd:
143
    return swmm;
144
  case ulonghd:
145
    return uswmm;
146
  default:
147
    return uswmm;
148
  }
149
 
150
}
151
 
152
 
153
/**************************************************************
154
outlab
155
 
156
outputs the label parameter if non negative else interprets it
157
to be an index into the externals and outputs the identifier.
158
**************************************************************/
159
 
160
void outlab PROTO_N ((l)) PROTO_T (int l)
161
{
162
  fprintf(as_file, "%s", ext_name(l));
163
}
164
 
165
/* translate time evaluate integer exp 'e' */
166
long evalexp PROTO_N ((e)) PROTO_T (exp e)
167
{
168
  switch (name(e))
169
  {
170
   case null_tag:case top_tag:
171
    return 0;
172
   case val_tag:
173
    {
174
      /* offsets appear as bits, but are converted to bytes if alignment 
175
       is not bits */
176
      if (name(sh(e)) == offsethd && al2(sh(e)) >= 8) 
177
      {
178
	return (no(e)>>3);
179
      }
180
      return no(e);
181
    }
182
    case env_size_tag :
183
    {
184
      exp tg = son(son(e));
185
      procrec *pr = &procrecs[no(son(tg))];
186
      return ((pr->frame_size)>>3) + pr->max_callee_bytes;
187
    }
188
    case offset_add_tag : {
189
      return (evalexp(son(e)) + evalexp(bro(son(e))));
190
    }
191
    case offset_max_tag : {
192
      return (max(evalexp(son(e)),evalexp(bro(son(e)))));
193
    }
194
    case offset_pad_tag : {
195
      return (rounder(evalexp(son(e)),shape_align(sh(e))));
196
    }
197
    case offset_mult_tag : {
198
      return (evalexp(son(e))*evalexp(bro(son(e))));
199
    }
200
    case offset_div_tag :
201
    case offset_div_by_int_tag : {
202
      return (evalexp(son(e))/evalexp(bro(son(e))));
203
    }
204
    case offset_subtract_tag : {
205
      return (evalexp(son(e))-evalexp(bro(son(e))));
206
    }
207
    case offset_negate_tag : {
208
      return (- evalexp(son(e)));
209
    }
210
 
211
 
212
   case chvar_tag:
213
    {
214
      return correct_shape(evalexp(son(e)),name(sh(e)));
215
    }
216
   case bitf_to_int_tag:
217
    {
218
      return evalexp(son(e));
219
    }
220
 
221
   case int_to_bitf_tag:
222
    {
223
      ash a;
224
      unsigned long w = evalexp(son(e));
225
 
226
      a = ashof(sh(e));
227
      if (a.ashalign != 1)
228
      {
229
	fail("should be align 1");
230
      }
231
      if (a.ashsize != 32)
232
      {
233
	w &= ((1 << a.ashsize) - 1);
234
      }
235
      return w;
236
    }
237
   case not_tag:
238
    {
239
      return correct_shape(~evalexp(son(e)),name(sh(e)));
240
    }
241
 
242
   case and_tag:
243
    {
244
      return (evalexp(son(e)) & evalexp(bro(son(e))));
245
    }
246
 
247
   case or_tag:
248
    {
249
      return (evalexp(son(e)) | evalexp(bro(son(e))));
250
    }
251
 
252
   case xor_tag:
253
    {
254
      return (evalexp(son(e)) ^ evalexp(bro(son(e))));
255
    }
256
 
257
   case shr_tag:
258
    {
259
      bool sgned = is_signed(sh(e));
260
      long sl;
261
      unsigned long ul;
262
      if (sgned)
263
      {
264
	sl = (long)correct_shape(evalexp(son(e)),name(sh(e)));
265
	return ( sl >> evalexp(bro(son(e))) );
266
      }
267
      else
268
      {
269
	ul = (unsigned long)correct_shape(evalexp(son(e)),name(sh(e)));
270
	return ( ul >> evalexp(bro(son(e))) );
271
      }
272
    }
273
 
274
  case shl_tag:
275
    {
276
      return correct_shape(evalexp(son(e))<<evalexp(bro(son(e))),name(sh(e)));
277
    }
278
 
279
  case concatnof_tag:
280
    {
281
      unsigned long w_lhs = evalexp(son(e));
282
      unsigned long w_rhs = evalexp(bro(son(e)));
283
      ash ash_lhs, ash_rhs;
284
      ash_lhs = ashof(sh(son(e)));
285
      ash_rhs = ashof(sh(bro(son(e))));
286
 
287
      ASSERT(ash_lhs.ashalign==1 && ash_lhs.ashsize<=32);
288
      ASSERT(ash_rhs.ashalign==1 && ash_rhs.ashsize<=32);
289
      ASSERT(ash_lhs.ashsize+ash_rhs.ashsize<=32);
290
 
291
      FULLCOMMENT4("evalexp() concatnof_tag: lhs,rhs=%#x,%#x ash(rhs)=%d,%d",
292
		w_lhs, w_rhs, ash_rhs.ashalign, ash_rhs.ashsize);
293
 
294
      if (ash_rhs.ashsize == 32)
295
      {
296
	/* avoid illegal shift by 32 */
297
	ASSERT(w_lhs==0);
298
	return w_rhs;
299
      }
300
      return (w_lhs << ash_rhs.ashsize) | w_rhs;
301
    }
302
 
303
  case clear_tag:
304
    {
305
      ash a;
306
 
307
      a = ashof(sh(e));
308
 
309
      FULLCOMMENT2("evalexp() clearshape_tag: ash=%d,%d", a.ashalign, a.ashsize);
310
      if (a.ashsize > 32)
311
	fail("clear for more than 32 bits");
312
 
313
      return 0;
314
    }
315
 
316
   case env_offset_tag:
317
   case general_env_offset_tag:
318
    {
319
      return frame_offset(son(e));
320
    }
321
 
322
  default:
323
    COMMENT1("tag not in evalexp: %d", name(e));
324
    fail("tag not in evalexp");
325
    return 0;
326
  }
327
  /*NOTREACHED*/
328
}
329
 
330
 
331
 
332
struct concbittypet {
333
  int			bitposn;
334
  int			value_size;
335
  unsigned long		value;
336
};
337
typedef struct concbittypet	concbittype;
338
 
339
 
340
static concbittype emptyconcbit PROTO_N ((bitposn)) PROTO_T (int bitposn)
341
{
342
  concbittype start;
343
 
344
  start.bitposn = bitposn;
345
  start.value_size = 0;
346
  start.value = 0;
347
 
348
  return start;
349
}
350
 
351
 
352
static void outconcbit PROTO_N ((c)) PROTO_T (concbittype c)
353
{
354
  unsigned long w = c.value;
355
  int bytes = (c.value_size + 7) / 8;
356
  int i;
357
 
358
  COMMENT2("outconcbit: bits=%d w=%#lx", c.value_size, w);
359
 
360
  if (c.value_size==0)
361
    return;			/* avoid .byte with no data */
362
 
363
  ASSERT(c.value_size<=32);
364
 
365
  /* to left end of word */
366
  if (c.value_size != 32)
367
    w = w << (32-c.value_size);
368
 
369
  /* POWER assembler only permits .long for 32-bit aligned values */
370
 
371
  /* output enough bytes */
372
  fprintf(as_file, "\t.byte\t");
373
  for (i = 0; i < bytes; i++)
374
  {
375
    if (i != 0)
376
      fprintf(as_file, ",");
377
    fprintf(as_file, "%#lx", (w >> 24) & 255);
378
    w = w << 8;
379
  }
380
  fprintf(as_file, "\n");
381
  ASSERT(w == 0);
382
}
383
/*
384
  Output a unary representation of the number val.  val should be 
385
  less than or equal to 31 as it represent the number of bits
386
  in a bitfield which does not occupy a whole machine word.
387
*/
388
long unary PROTO_N ((val)) PROTO_T (int val)
389
{
390
  int loop;
391
  long result=0;
392
  ASSERT(val <=31);
393
  for(loop=0;loop<val;++loop)
394
  {
395
    result <<=1;
396
    result |= 1;
397
  }
398
  return result;
399
}
400
 
401
 
402
 
403
static concbittype addconcbitaux PROTO_N ((w,size,before)) PROTO_T (unsigned long w X int size X concbittype before)
404
{
405
  int wordbitposn;			/* 0..32 bit position in current word,
406
					 * 0 only at start of bit sequence */
407
 
408
  if (before.value_size==32 || (before.value_size != 0 && (before.bitposn&31)==0))
409
  {
410
    ASSERT((before.bitposn&31)==0);
411
    wordbitposn = 32;
412
  }
413
  else
414
  {
415
    wordbitposn = (before.bitposn&31);
416
  }
417
 
418
  FULLCOMMENT2("addconcbitaux() sz=%d w=%d",
419
	       size, w);
420
  FULLCOMMENT4("\tbefore=%d(%d) %#x:%d",
421
	       before.bitposn, wordbitposn, before.value, before.value_size);
422
#if 0
423
  ASSERT(size>0);		/* no longer have to handle zero for C */
424
#endif
425
  ASSERT(size<=32);
426
 
427
  ASSERT(before.value_size<=32);
428
  ASSERT(wordbitposn==0 || before.value_size<=wordbitposn);
429
 
430
  if (
431
      (size == 0 && (wordbitposn != 0 || before.value_size != 0))
432
      ||
433
      (wordbitposn + size > 32)
434
      )
435
  {
436
    /*
437
     * C zero size bitfield, align to word boundary; or
438
     * would go over word boundary, so output before and padding.
439
     */
440
    int pad_bits = 32 - wordbitposn;
441
 
442
#if 1
443
    ASSERT(pad_bits==0);		/* padding should now be explicit */
444
 
445
    before.value_size += pad_bits;
446
    before.value <<= pad_bits;
447
#endif
448
 
449
    outconcbit(before);
450
 
451
    /* clear before, as it has been output */
452
    before.bitposn += pad_bits;
453
    before.value_size = 0;
454
    before.value = 0;
455
 
456
    /* should be at word boundary */
457
    ASSERT((before.bitposn&31)==0);
458
  }
459
 
460
  if (size == 0)
461
    return before;
462
 
463
  /* add to before */
464
  before.bitposn += size;
465
  before.value_size += size;
466
  if (size == 32)
467
    before.value = w;
468
  else
469
    before.value = (before.value << size) | (w & unary(size));
470
 
471
  FULLCOMMENT4("\t after=%d(%d) %#x:%d",
472
	       before.bitposn, wordbitposn, before.value, before.value_size);
473
 
474
  ASSERT(before.value_size<=32);
475
 
476
  return before;
477
}
478
 
479
 
480
static concbittype evalconcbitaux PROTO_N ((e,before)) PROTO_T (exp e X concbittype before)
481
{
482
  switch (name(e))
483
  {
484
  case concatnof_tag:
485
    {
486
      concbittype lhs, rhs;
487
      lhs = evalconcbitaux(son(e), before);
488
      rhs = evalconcbitaux(bro(son(e)), lhs);
489
 
490
      return rhs;
491
    }
492
 
493
  default:
494
    {
495
      ASSERT(shape_align(sh(e))==1);
496
 
497
      return addconcbitaux(evalexp(e), shape_size(sh(e)), before);
498
    }
499
  }
500
}
501
 
502
 
503
static void evalconcbit PROTO_N ((e,bitposn)) PROTO_T (exp e X int bitposn)
504
{
505
  concbittype start;
506
  start = emptyconcbit(bitposn);
507
 
508
  outconcbit(evalconcbitaux(e, start));
509
}
510
 
511
 
512
 
513
static void set_align PROTO_N ((al)) PROTO_T (int al)
514
{
515
  /* output .align if needed */
516
  switch (al)
517
  {
518
  case 0:
519
  case 1:
520
  case 8:
521
    break;
522
 
523
  case 16:
524
    fprintf(as_file, "\t.align\t1\n");
525
    break;
526
 
527
  case 32:
528
    fprintf(as_file, "\t.align\t2\n");
529
    break;
530
 
531
  case 64:
532
    fprintf(as_file, "\t.align\t3\n");
533
    break;
534
 
535
  default:
536
    fail("unexpected alignment");
537
  }
538
}
539
 
540
 
541
 
542
static void evalone PROTO_N ((e,bitposn)) PROTO_T (exp e X int bitposn)
543
{
544
  ash a;
545
 
546
  a = ashof(sh(e));
547
 
548
  COMMENT4("evalone: name(e)=%d, bitposn=%d, ash=%d,%d", name(e), 
549
	   bitposn, a.ashsize, a.ashalign);
550
  COMMENT1("evalone no(e)=%d",no(e));
551
 
552
  set_align(a.ashalign);
553
 
554
  /* align bitposn */
555
  if (a.ashalign != 0)
556
  {
557
    bitposn = (bitposn / a.ashalign) * a.ashalign;
558
  }
559
 
560
  /* generate data initialiser for e */
561
  switch (name(e))
562
  {
563
   case string_tag:
564
    {
565
      long char_size = props(e);	/* bits width of each output char */
566
      long strsize = shape_size(sh(e)) / char_size;
567
      unsigned char *st = (unsigned char *)nostr(e);
568
      int i;
569
 
570
      if (char_size != 8 )
571
      {
572
	/* wide chars, generate a .XXX line for each */
573
	for (i = 0; i <strsize; i++)
574
	{
575
	  unsigned int c;
576
	  char *directive;
577
 
578
	  switch(char_size)
579
	  {
580
	   case 16:	
581
	    c = ((unsigned short *)st)[i];
582
	    directive = ".short";
583
	    break;
584
	   case 32:	
585
	    c = ((unsigned int *)st)[i]; 
586
	    directive = ".long";
587
	    break;
588
	    /* +++ case 64 ??? */
589
	   default:	
590
	    fail("unexpected wide char data width");
591
	  }
592
	  fprintf(as_file, "\t%s\t%#x\n", directive, c);
593
	}
594
 
595
	return;
596
      }
597
 
598
      /* output as ascii where possible for the human reader */
599
      while (strsize > 0)
600
      {
601
	int c = *st;
602
 
603
	if (c >= 32 && c < 127)
604
	{
605
	  fprintf(as_file, "\t.byte\t\"");
606
 
607
	  for (i = 0; strsize > 0 && i < 48 && c >= 32 && c < 127; i++)
608
	  {
609
	    if (c != '"')
610
	      putc(c, as_file);
611
	    else
612
	      fprintf(as_file, "\"\"");		/* " represented as "" */
613
 
614
	    st++;
615
	    strsize--;
616
	    c = *st;
617
	  }
618
 
619
	  fprintf(as_file, "\"\n");
620
	}
621
	else
622
	{
623
	  fprintf(as_file, "\t.byte\t");
624
 
625
	  for (i = 0; strsize > 0 && i < 16 && !(c >= 32 && c < 127); i++)
626
	  {
627
	    if (i != 0)
628
	      fprintf(as_file, ",");
629
 
630
	    fprintf(as_file, "%d", c);
631
 
632
	    st++;
633
	    strsize--;
634
	    c = *st;
635
	  }
636
 
637
	  fprintf(as_file, "\n");
638
	}
639
      }
640
      return;
641
    }
642
 
643
  case real_tag:
644
    {
645
      flt *f = flptnos + no(e);
646
      r2l v;
647
 
648
      if (a.ashsize==32) 
649
      {
650
	v=real2longs_IEEE(f,0);
651
	fprintf(as_file,"\t.long\t");
652
	fprintf(as_file,"%ld",(long)v.i1);
653
      } 
654
      else if (a.ashsize==64) 
655
      {
656
	v=real2longs_IEEE(f,1);
657
	fprintf(as_file,"\t.long\t");
658
	fprintf(as_file,"%ld",(long)v.i2);
659
	fprintf(as_file,",");   
660
	fprintf(as_file,"%ld",(long)v.i1);
661
      } 
662
      else 
663
      {
664
	v=real2longs_IEEE(f,2);
665
	fprintf(as_file,"\t.long\t");
666
	fprintf(as_file,"%ld",(long)v.i4);
667
	fprintf(as_file,",");
668
	fprintf(as_file,"%ld",(long)v.i3);
669
	fprintf(as_file,",") ;
670
	fprintf(as_file,"%ld",(long)v.i2);	
671
	fprintf(as_file,",");
672
	fprintf(as_file,"%ld",(long)v.i1);
673
      }
674
      fprintf(as_file, "\n") ;
675
      return;
676
    }
677
   case null_tag:case top_tag:
678
    no(e) = 0;
679
    /* FALLTHROUGH */
680
   case val_tag:
681
    {
682
      char *asdata;
683
 
684
      FULLCOMMENT1("evalone() val_tag: %d", val_tag);
685
 
686
      /* allow 64 bit integers */
687
      if (shape_size(sh(e))>32)
688
      {
689
	flt64 temp;
690
	int ov;
691
	if (isbigval(e)) 
692
	{
693
	  temp = flt_to_f64(no(e), 0, &ov);
694
	}
695
	else 
696
	{
697
	  temp.big = (is_signed(sh(e)) && no(e)<0)?-1:0;
698
	  temp.small = no(e);
699
	}
700
	fprintf(as_file,"\t.long\t%ld\n",(long)temp.small);
701
	fprintf(as_file,"\t.long\t%ld\n",(long)temp.big);
702
	return;
703
      }
704
      /* allow for bitfields */
705
      if (a.ashalign == 1)
706
      {
707
	evalconcbit(e, bitposn);
708
	return;
709
      }
710
 
711
      if (a.ashalign <= 8)
712
      {
713
	asdata = ".byte";
714
      }
715
      else if (a.ashalign <= 16)
716
      {
717
	asdata = ".short";
718
      }
719
      else
720
      {
721
	asdata = ".long";
722
      }
723
      fprintf(as_file, "\t%s\t%ld\n", asdata, evalexp(e));
724
      return;
725
    }
726
  case name_tag:
727
    {
728
      dec *globdec = brog(son(e));
729
      char *nm = globdec->dec_u.dec_val.dec_id;
730
 
731
      ASSERT(isglob(son(e)));
732
 
733
      /* no() is offset */
734
      if (no(e) == 0)
735
      {
736
	fprintf(as_file, "\t.long\t%s\n", nm);
737
      }
738
      else
739
      {
740
	fprintf(as_file, "\t.long\t%s+%ld\n", nm, (long)(no(e)/8));
741
      }
742
 
743
      return;
744
    }
745
 
746
  case compound_tag:
747
    {
748
      /*
749
       * There is a lot of history in the following code, dating from
750
       * when tuples were without specified offsets for each field.
751
       * Really, this code should be totally rewritten.
752
       */
753
      int maxalign = a.ashalign;
754
      exp off = son(e);
755
      exp tup = bro(off);
756
      ash tupa;
757
      concbittype remainderbits;
758
      long last_offset = 0;
759
      long last_align = 0;
760
      tupa = ashof(sh(tup));
761
      remainderbits = emptyconcbit(bitposn);
762
 
763
      /* output elements of aggregate recursively */
764
      while (1)
765
      {
766
	int gap = no(off) - remainderbits.bitposn;
767
 
768
	COMMENT4("evalone compound_tag: gap=%d off=%d ash=%d,%d",
769
		gap, no(off), tupa.ashsize, tupa.ashalign);
770
 
771
	/* check that component's alignment matches offset in struct */
772
	ASSERT((no(off)/tupa.ashalign)*tupa.ashalign <= no(off));
773
 
774
	/* and is no greater that struct's alignment */
775
	ASSERT(tupa.ashalign<=maxalign);
776
 
777
	if (no(off) < last_offset)
778
	  fail("eval compound_tag: not ascending order");
779
 
780
	if (last_align <= 1 || tupa.ashalign <= 1 || gap >= tupa.ashalign)
781
	{
782
	  /* gap can be bigger than 32, but addconcbitaux can only handle <= 32 */
783
	  while (gap > 0)
784
	  {
785
	    remainderbits = addconcbitaux(0, 1, remainderbits);
786
	    gap--;
787
	  }
788
	}
789
	else
790
	{
791
	  /* alignment will handle gap */
792
	  remainderbits.bitposn = ((remainderbits.bitposn + (tupa.ashalign-1)) / tupa.ashalign) * tupa.ashalign;
793
	}
794
 
795
	last_offset = no(off);
796
	last_align = tupa.ashalign;
797
 
798
	ASSERT(remainderbits.bitposn - bitposn == no(off));
799
 
800
	/* consecutive bitfields must be collected together for .byte */
801
	if (tupa.ashalign == 1)
802
	{
803
	  remainderbits = evalconcbitaux(tup, remainderbits);
804
	}
805
	else
806
	{
807
	  /* output final bits from any previous field */
808
	  outconcbit(remainderbits);
809
	  remainderbits = emptyconcbit(remainderbits.bitposn);
810
 
811
	  evalone(tup, remainderbits.bitposn);
812
	  remainderbits.bitposn += tupa.ashsize;
813
	}
814
 
815
	if (last(tup))
816
	{
817
	  /* output final bits from any previous field */
818
	  long databits = no(off) + tupa.ashsize;
819
	  long trailing_bytes = (a.ashsize-databits) / 8;
820
 
821
	  outconcbit(remainderbits);
822
 
823
	  ASSERT(a.ashsize >= databits);
824
 
825
	  /* pad out trailing unitialised space, eg union */
826
	  if (a.ashsize > databits && trailing_bytes > 0)
827
	  {
828
	    fprintf(as_file, "\t.space\t%d\n", (int)trailing_bytes);
829
	  }
830
	  return;
831
	}
832
 
833
	off = bro(bro(off));
834
	ASSERT(!last(off));
835
	tup = bro(off);
836
 
837
	tupa = ashof(sh(tup));
838
      }
839
      /*NOTREACHED*/
840
    }
841
 
842
  case nof_tag:
843
    {
844
      exp s = son(e);
845
 
846
      for (;;)
847
      {
848
	evalone(s, bitposn);
849
	if (last(s))
850
	  return;
851
	s = bro(s);
852
      }
853
      /*NOTREACED*/
854
    }
855
 
856
  case ncopies_tag:
857
    {
858
      int n = no(e);
859
      ash copya;
860
      int bitsize;
861
      int i;
862
 
863
      COMMENT1("ncopies_tag: n=%d", n);
864
 
865
      while (name(son(e)) == ncopies_tag)
866
      {
867
	e = son(e);
868
	n *= no(e);
869
      }
870
 
871
      e = son(e);
872
      copya = ashof(sh(e));
873
      if (copya.ashalign != 0)
874
	bitsize = (copya.ashsize / copya.ashalign) * copya.ashalign;
875
      else
876
	bitsize = 0;		/* probably never happen! */
877
 
878
      for (i = 0; i < n; i++)
879
      {
880
	COMMENT3("ncopies_tag: i=%d n=%d bitposn=%d", i, n, bitposn);
881
	evalone(e, bitposn);
882
	bitposn += bitsize;
883
      }
884
      return;
885
    }
886
 
887
  case concatnof_tag:
888
    {
889
      COMMENT2("concatnof_tag: ashalign=%d, ashsize=%d", a.ashalign, a.ashsize);
890
 
891
      /* allow for bitfields */
892
      if (a.ashalign == 1)
893
      {
894
	evalconcbit(e, bitposn);
895
      }
896
      else
897
      {
898
	ash a;
899
 
900
	a = ashof(sh(son(e)));
901
	evalone(son(e), bitposn);
902
	bitposn += a.ashsize;
903
 
904
	a = ashof(sh(bro(son(e))));
905
	if (a.ashalign != 0)
906
	  bitposn = (bitposn / a.ashalign) * a.ashalign;
907
	evalone(bro(son(e)), bitposn);
908
      }
909
      return;
910
    }
911
 
912
  case clear_tag:
913
    {
914
      /* allow for bitfields */
915
      if (a.ashalign == 1)
916
      {
917
	evalconcbit(e, bitposn);
918
	return;
919
      }
920
 
921
      fprintf(as_file, "\t.space\t%ld\n", (a.ashsize + 7) >> 3);
922
      return;
923
    }
924
 
925
   case not_tag:
926
   case and_tag:
927
   case or_tag:
928
   case shl_tag:
929
   case shr_tag:
930
   case bitf_to_int_tag:
931
   case int_to_bitf_tag:
932
   case chvar_tag:
933
    case env_offset_tag:case env_size_tag:
934
    case general_env_offset_tag:
935
    case offset_add_tag : case offset_max_tag :
936
    case offset_pad_tag : case offset_mult_tag : case offset_div_tag :
937
    case offset_div_by_int_tag : case offset_subtract_tag : 
938
    case offset_negate_tag:
939
 
940
    {
941
      fprintf(as_file, "\t.long\t%ld\n", evalexp(e));
942
      return;
943
    }
944
   case minptr_tag:
945
    {
946
      exp p1 = son(e);
947
      exp p2 = bro(p1);
948
      if (name(p1)==name_tag && name(p2)==name_tag)
949
      {
950
	long n = no(p1)-no(p2);
951
	char *n1 = brog(son(p1))->dec_u.dec_val.dec_id ;
952
	char *n2 = brog(son(p2))->dec_u.dec_val.dec_id ;
953
	fprintf(as_file,"\t.long\t(%s-%s)",n1,n2);
954
	if(n<0)
955
	{
956
	  fprintf(as_file,"%ld",n);
957
	}
958
	else if (n>0)
959
	{
960
	  fprintf(as_file,"+%ld",n);
961
	}
962
	fprintf(as_file,"\n");
963
      }
964
      return;
965
    }
966
 
967
   default:
968
    COMMENT1("tag not in evaluated: %d", name(e));
969
    fail("illegal constant");
970
  }				/* end switch */
971
}
972
 
973
 
974
 
975
/*
976
 * Outputs data initialisers for the evaluated exp.
977
 * The result is the instore "address" of the constant.
978
 * A negative l implies that this is the initialisation of a global variable.
979
 */
980
instore evaluated PROTO_N ((e,l)) PROTO_T (exp e X int l)
981
{
982
  int lab = (l == 0) ? next_data_lab() : (l < 0) ? l : -l;
983
  instore isa;
984
  ash a;
985
  char *extname = ext_name(lab);
986
  a = ashof(sh(e));
987
 
988
 
989
  isa.adval = 0;
990
  isa.b.offset = 0;
991
  isa.b.base = lab;
992
 
993
 
994
  ASSERT(name(e) != clear_tag);	/* +++ history */
995
  if (name(e) == clear_tag)	/* uninitialised global */
996
  {
997
    long byte_size = (a.ashsize + 7) >> 3;
998
    bool temp = (l == 0 || (extname[0] == local_prefix[0] && extname[1] == local_prefix[1]));
999
 
1000
    if (temp)
1001
    {
1002
      fprintf(as_file, "\t.lcomm\t");
1003
    }
1004
    else
1005
    {
1006
      fprintf(as_file, "\t.comm\t");
1007
    }
1008
    outlab(lab);
1009
    fprintf(as_file, ",%ld\n", byte_size);
1010
 
1011
    return isa;
1012
  }
1013
 
1014
 
1015
  {
1016
 
1017
    /* align at least to word for speed of access */
1018
    /* if size greater than 4 bytes, align on double boundry for speed */
1019
    if (a.ashalign > 32 || a.ashsize > 32)
1020
      fprintf(as_file, "\t.align\t3\n");
1021
    else
1022
      fprintf(as_file, "\t.align\t2\n");
1023
    fprintf(as_file, "%s:\n", extname);
1024
 
1025
    evalone(e, 0);
1026
 
1027
    /* evalone does not always output .space to finish off up to size, so protect next one */
1028
    set_align(a.ashalign);
1029
  }
1030
 
1031
  return isa;
1032
}
1033
 
1034
 
1035
instore evaluated_const PROTO_N ((e)) PROTO_T (exp e)
1036
{
1037
  instore isa;
1038
  int lab;
1039
  char *id;
1040
 
1041
  /* +++ to share consts */
1042
 
1043
  /* generate read only data */
1044
  fprintf(as_file, "\t.csect\t[RO]\n");
1045
 
1046
  isa = evaluated(e, 0);
1047
 
1048
  lab = isa.b.base;
1049
 
1050
  id = ext_name(lab);
1051
 
1052
  /* generate .toc entry */
1053
  fprintf(as_file, "\t.toc\n");
1054
  fprintf(as_file, "T.%s:\n\t.tc\t%s[TC],%s\n", id, id, id);
1055
 
1056
  /* reset to default text segment */
1057
  fprintf(as_file, "\t.csect\t[PR]\n");
1058
 
1059
  return isa;
1060
}
1061
long correct_shape PROTO_N ((n,shpe)) PROTO_T (long n X int shpe)
1062
{
1063
  switch(shpe)
1064
  {
1065
   case scharhd:
1066
    n = n<<24;
1067
    n = n>>24;
1068
    return n;
1069
   case ucharhd:
1070
    n = n & 0xff;
1071
    return n;
1072
   case swordhd:
1073
    n = n<<16;
1074
    n = n>>16;
1075
    return n;
1076
   case uwordhd:
1077
    n = n & 0xffff;
1078
    return n;
1079
   case slonghd:
1080
   case ulonghd:
1081
    return n;
1082
  }
1083
  fail("Unknown shape in correct_shape");
1084
  return 0;
1085
}
1086