Subversion Repositories tendra.SVN

Rev

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

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