Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/* 80x86/evaluate.c */
32
 
33
/**********************************************************************
34
$Author: release $
35
$Date: 1998/01/17 15:55:51 $
36
$Revision: 1.1.1.1 $
37
$Log: evaluate.c,v $
38
 * Revision 1.1.1.1  1998/01/17  15:55:51  release
39
 * First version to be checked into rolling release.
40
 *
41
 * Revision 1.14  1997/04/21  08:07:04  pwe
42
 * init large arrays
43
 *
44
 * Revision 1.13  1997/03/20  16:23:38  pwe
45
 * dwarf2
46
 *
47
 * Revision 1.12  1996/02/01  09:34:36  pwe
48
 * PIC oddities for AVS
49
 *
50
 * Revision 1.11  1996/01/22  14:31:05  pwe
51
 * PIC const*const, contop top_tag & linux 64-bit ints
52
 *
53
 * Revision 1.10  1996/01/10  17:54:07  pwe
54
 * PIC constant array offsets
55
 *
56
 * Revision 1.9  1996/01/10  09:19:08  pwe
57
 * profile const & envoffset correction
58
 *
59
 * Revision 1.8  1996/01/05  16:25:30  pwe
60
 * env_size and env_offset within constant expressions
61
 *
62
 * Revision 1.7  1995/08/30  16:06:27  pwe
63
 * prepare exception trapping
64
 *
65
 * Revision 1.6  1995/08/04  08:29:15  pwe
66
 * 4.0 general procs implemented
67
 *
68
 * Revision 1.5  1995/03/10  17:45:13  pwe
69
 * collection of signed/unsigned small bitfields
70
 *
71
 * Revision 1.4  1995/02/20  13:37:19  pwe
72
 * correct alignment within n_of bitfield
73
 *
74
 * Revision 1.3  1995/02/20  12:19:21  pwe
75
 * alignment within n_of bitfield
76
 *
77
 * Revision 1.2  1995/01/30  12:56:07  pwe
78
 * Ownership -> PWE, tidy banners
79
 *
80
 * Revision 1.1  1994/10/27  14:15:22  jmf
81
 * Initial revision
82
 *
83
 * Revision 1.1  1994/07/12  14:30:23  jmf
84
 * Initial revision
85
 *
86
**********************************************************************/
87
 
88
 
89
#include "config.h"
90
#include "common_types.h"
91
 
92
#include "tags.h"
93
#include "basicread.h"
94
#include "expmacs.h"
95
#include "exp.h"
96
#include "shapemacs.h"
97
#include "flpt.h"
98
#include "coder.h"
99
#include "instr.h"
100
#include "out.h"
101
#include "check.h"
102
#include "codermacs.h"
103
#include "externs.h"
104
#include "install_fns.h"
105
#include "table_fns.h"
106
#include "flags.h"
107
#include "instr386.h"
108
#include "machine.h"
109
#include "localflags.h"
110
#include "assembler.h"
111
#include "messages_8.h"
112
#include "diag_fns.h"
113
#include "f64.h"
114
 
115
#include "evaluate.h"
116
 
117
 
118
/* PROCEDURES */
119
 
120
 
121
static void outsize
122
    PROTO_N ( (n) )
123
    PROTO_T ( int n )
124
{
125
  switch ((n+7)/8) {
126
    case 1:
127
	outbyte();
128
	break;
129
    case 2:
130
	outshort();
131
	break;
132
    default:
133
	outlong();
134
	break;
135
  };
136
  return;
137
}
138
 
139
 
140
long  evalexp
141
    PROTO_N ( (e) )
142
    PROTO_T ( exp e )
143
{
144
  switch (name(e)) {
145
    case  val_tag:
146
    case null_tag:
147
    case top_tag:
148
      {
149
	if (name(sh(e)) == offsethd && al2(sh(e)) >= 8) {
150
		return (no(e)>>3);
151
	}
152
        return (no (e));
153
      }
154
    case bitf_to_int_tag:
155
      {
156
	return evalexp (son (e));
157
      }
158
    case int_to_bitf_tag:
159
      {
160
	long  w = evalexp (son (e));
161
	if (shape_align(sh(e)) != 1) {
162
	  failer ("should be align 1");
163
	}
164
	if (shape_size(sh(e)) != 32) {
165
	  w &= ((1 << shape_size(sh(e))) - 1);
166
	}
167
	return w;
168
      }
169
    case not_tag:
170
      {
171
	return (~evalexp (son (e)));
172
      }
173
    case and_tag:
174
      {
175
	return (evalexp (son (e)) & evalexp (bro (son (e))));
176
      }
177
    case or_tag:
178
      {
179
	return (evalexp (son (e)) | evalexp (bro (son (e))));
180
      }
181
    case xor_tag:
182
      {
183
	return (evalexp (son (e)) ^ evalexp (bro (son (e))));
184
      }
185
 
186
    case shr_tag:
187
      {
188
	return (evalexp (son (e)) >> evalexp (bro (son (e))));
189
      }
190
 
191
    case shl_tag:
192
      {
193
	return (evalexp (son (e)) << evalexp (bro (son (e))));
194
      }
195
 
196
    case concatnof_tag:
197
      {
198
	long  wd = evalexp (son (e));
199
	return (wd | (evalexp (bro (son (e))) << shape_size(sh(son(e)))));
200
      }
201
 
202
    case clear_tag:
203
      {
204
	if (shape_size(sh(e)) <= 32)
205
	  return 0;
206
	break;
207
      }
208
    case env_offset_tag:
209
      {
210
	if (name(son(e)) == 0)
211
   	  return (no(son(e)) / 8);
212
	break;
213
      }
214
    case env_size_tag:
215
      {
216
	dec * et = brog(son(son(e)));
217
	if (et -> dec_u.dec_val.processed)
218
	  return (et -> dec_u.dec_val.index);
219
	break;
220
      }
221
    case offset_add_tag:
222
      {
223
    	return (evalexp(son(e))+evalexp(bro(son(e))));
224
      }
225
    case offset_max_tag:
226
      {
227
	long a = evalexp(son(e));
228
	long b = evalexp(bro(son(e)));
229
    	return (a > b ? a : b);
230
      }
231
    case offset_pad_tag:
232
      {
233
	return( rounder(evalexp(son(e)), shape_align(sh(e)) / 8));
234
      }
235
    case offset_mult_tag:
236
      {
237
    	return (evalexp(son(e))*evalexp(bro(son(e))));
238
      }
239
    case offset_div_tag:
240
    case offset_div_by_int_tag:
241
      {
242
    	return (evalexp(son(e))/evalexp(bro(son(e))));
243
      }
244
    case offset_subtract_tag:
245
      {
246
    	return (evalexp(son(e))-evalexp(bro(son(e))));
247
      }
248
    case offset_negate_tag:
249
      {
250
	return (- evalexp(son(e)));
251
      }
252
    case seq_tag:
253
      {
254
	if (name(son(son(e))) == prof_tag && last(son(son(e))))
255
	   return (evalexp(bro(son(e))));
256
	break;
257
      }
258
    case cont_tag:
259
      {
260
	if (PIC_code && name(son(e)) == name_tag && isglob(son(son(e)))
261
		&& son(son(son(e))) != nilexp
262
		&& !(brog(son(son(e))) -> dec_u.dec_val.dec_var))
263
	   return (evalexp(son(son(son(e)))));
264
	break;
265
      }
266
  }
267
  failer(BAD_VAL);
268
  return (0);
269
}
270
 
271
 
272
/* outputs a value */
273
static void evalval
274
    PROTO_N ( (e) )
275
    PROTO_T ( exp e )
276
{
277
  int e_size = shape_size(sh(e));
278
  unsigned char  n = name (e);
279
  int ov;
280
 
281
  if (n == val_tag) {
282
    int k = (name(sh(e)) == offsethd && al2(sh(e)) != 1)
283
                  ? no(e)/8 : no(e);
284
    flt64 x;
285
    if (isbigval(e)) {
286
      x = flt_to_f64(k, is_signed(sh(e)), &ov);
287
      k = x.small;
288
    }
289
    switch (e_size) {
290
      case 8:
291
	outn ((long)k & 0xff);
292
	break;
293
      case 16:
294
	outn ((long)k & 0xffff);
295
	break;
296
      case 32:
297
	outn ((long)k);
298
	break;
299
      case 64:
300
	outn ((long)k);
301
	outs (", ");
302
	if (isbigval(e)) {
303
	  SET (x);
304
	  outn((long)x.big);
305
	} else
306
	if (is_signed(sh(e)) && k < 0)
307
	  outn((long)-1);
308
	else
309
	  outn((long)0);
310
	break;
311
      default:
312
	outn((long)k);
313
	break;
314
    };
315
    return;
316
  };
317
 
318
  if (n == real_tag) {
319
    outreal (e);
320
    return;
321
  };
322
 
323
  if (n == reff_tag && name(son(e)) == name_tag && isglob(son(son(e)))) {
324
    outopenbr();
325
    outs (brog (son (son (e))) -> dec_u.dec_val.dec_id);
326
    outs (" + ");
327
    outn ((long)(no (e) + no (son (e))) / 8);
328
    outclosebr();
329
    return;
330
  };
331
 
332
  if (n == name_tag) {
333
    if (no (e) != 0) {
334
      outopenbr();
335
      outs (brog (son (e)) -> dec_u.dec_val.dec_id);
336
      outs (" + ");
337
      outn ((long)no (e) / 8);
338
      outclosebr();
339
    }
340
    else
341
      outs (brog (son (e)) -> dec_u.dec_val.dec_id);
342
    return;
343
  };
344
 
345
  {
346
    int k = evalexp (e);
347
    switch (e_size) {
348
      case 8:
349
	outn ((long)k & 0xff);
350
	break;
351
      case 16:
352
	outn ((long)k & 0xffff);
353
	break;
354
      case 32:
355
	outn ((long)k);
356
	break;
357
      default:
358
	outn((long)k);
359
	break;
360
    };
361
  }
362
  return;
363
}
364
 
365
 
366
 
367
/* auxiliary for evalaux */
368
static  void clear_out
369
    PROTO_N ( (n, isconst, al) )
370
    PROTO_T ( int n X int isconst X int al )
371
{
372
  if (n == 0)
373
     return;
374
 
375
  if (isconst) {
376
    while (al >= 32 && n >= 4) {
377
      outlong();
378
      outs ("0");
379
      outnl ();
380
      n -= 4;
381
    };
382
    while (n > 0) {
383
      outbyte();
384
      outs ("0");
385
      outnl ();
386
      --n;
387
    };
388
  }
389
  else {
390
    outs (".set .,.+");
391
    outn ((long)n);
392
    outnl ();
393
  };
394
 
395
  return;
396
}
397
 
398
/* does the work of outputting of constants recursively */
399
static void evalaux
400
    PROTO_N ( (e, isconst, al) )
401
    PROTO_T ( exp e X int isconst X int al )
402
{
403
  int e_size = shape_size(sh(e));
404
  unsigned char  n = name (e);
405
 
406
  if (n == compound_tag) {		/* output components in turn */
407
    int work = 0;
408
    exp offe;
409
    exp val;
410
    int bits_left = 0;
411
    int crt_off = 0;
412
    int off, offn, sz, nx, i;
413
 
414
    if (son(e) == nilexp)
415
      return;
416
 
417
    offe = son(e);
418
 
419
    while (1)
420
     {
421
       off = no(offe);
422
       val = bro(offe);
423
       if (bits_left &&
424
            off >= (crt_off + 8))
425
         {
426
	    outbyte();
427
	    outn ((long)work & 0xff);
428
            outnl();
429
            crt_off += 8;
430
            work = 0;
431
            bits_left = 0;
432
         };
433
 
434
       if (off < crt_off)
435
              failer(CPD_ORDER);
436
       if (off >= (crt_off + 8))
437
           {
438
              clear_out((off-crt_off)/8, isconst, al);
439
              crt_off = off & -8;
440
           };
441
 
442
       if (name(sh(val)) != bitfhd)
443
         {
444
           evalaux(val, isconst, (crt_off + al) & 56);
445
           crt_off += shape_size(sh(val));
446
         }
447
       else
448
         {
449
           offn = off - crt_off;
450
           sz = shape_size(sh(val));
451
           nx = (name(val)==int_to_bitf_tag) ? no(son(val)) : no(val);
452
           work += nx << offn;
453
           bits_left = offn+sz;
454
           if ((offn + sz) <= 32)
455
              { while ((offn+sz) >= 8)
456
                 {
457
	           outbyte();
458
	           outn ((long)work & 0xff);
459
                   outnl();
460
                   crt_off += 8;
461
                   work >>= 8;
462
                   offn -= 8;
463
                   bits_left = offn+sz;
464
                 };
465
               work &= ((1 << bits_left) - 1);
466
              }
467
           else
468
            {
469
              for (i=0; i<4; ++i)
470
                 {
471
	           outbyte();
472
	           outn ((long)work & 0xff);
473
                   outnl();
474
                   crt_off += 8;
475
                   work >>= 8;
476
                   offn -= 8;
477
                   bits_left = offn+sz;
478
                 };
479
               work = nx >> bits_left;
480
             };
481
         };
482
 
483
       if (last(val))   /* CLEAR OUT SHAPE size_shape(e) - crt_off */
484
        {
485
          if (bits_left)
486
            {
487
	       outbyte();
488
	       outn ((long)work & 0xff);
489
               outnl();
490
               crt_off += 8;
491
            };
492
          clear_out((shape_size(sh(e)) - crt_off)/8, isconst,
493
			8);
494
          return;
495
        };
496
       offe = bro(val);
497
     };
498
  };
499
 
500
  if (n == string_tag) {
501
    char *s = nostr(e);
502
    int  goon;
503
    int  i,
504
          j;
505
    int char_size = (int)string_char_size(e);
506
    goon = shape_size(sh(e)) / char_size;
507
    for (i = 0; goon; i += 10) {
508
      switch (char_size)
509
       {
510
         case 8: outbyte(); break;
511
         case 16:outshort(); break;
512
         case 32:outlong(); break;
513
         case 64:outlong(); break;
514
       };
515
 
516
      for (j = i; goon && j < i + 10; ++j) {
517
        switch (props(e))
518
         {
519
           case 8: outn ((long) s[j]); break;
520
           case 16: outn ((long) ((short*)(void*)s)[j]); break;
521
		/* the pun to short* is correct: jmf */
522
           case 32: outn ((long) ((int*)(void*)s)[j]); break;
523
		/* the pun to int* is correct: jmf */
524
	   case 64: {
525
	     flt64 x;
526
	     int ov;
527
	     x = flt_to_f64(((int*)(void*)s)[j], 0, &ov);
528
	     outn((long)x.small); outs (", "); outn((long)x.big);
529
	   };
530
         };
531
	--goon;
532
	if (goon && j < i + 9)
533
	  outs (", ");
534
      };
535
      outnl ();
536
    };
537
    return;
538
  };
539
 
540
  if (n == res_tag) {
541
    int  nb;
542
    nb = shape_size(sh(son(e))) / 8;
543
    clear_out (nb, isconst, shape_align(sh(son(e))));
544
    return;
545
  };
546
 
547
  if (n == ncopies_tag) {
548
    int  m = no (e);
549
    int  sz, i;
550
    exp val = son(e);
551
    while ( name ( val ) == ncopies_tag ) {
552
	m *= no ( val ) ;
553
	val = son ( val ) ;
554
    }
555
    sz = shape_size(sh(val)) / 8;
556
    if ((name(val) == null_tag ||
557
	 name(val) == val_tag) && !isbigval(val) && no(val) == 0)
558
      clear_out (m * sz, isconst, shape_align(sh(val)));
559
    else {
560
      for (i = 0; i < m; i++)
561
	evalaux(val, isconst, al);
562
    }
563
    return;
564
  };
565
 
566
  if (n == nof_tag)
567
   {
568
     exp t = son(e);
569
     if (t == nilexp)
570
       return;
571
     while (1)
572
      {
573
        evalaux(t, isconst, al);
574
        if (last(t))
575
          return;
576
        t = bro(t);
577
        dot_align((shape_align(sh(t))<=8) ? 1 : shape_align(sh(t))/8);
578
      };
579
   };
580
 
581
  if (n == concatnof_tag) {
582
    evalaux (son (e), isconst, al);
583
    evalaux (bro (son (e)), isconst, (al +shape_size(son(e))) & 63);
584
    return;
585
  };
586
 
587
  if (n == clear_tag)
588
   {
589
     int sz = shape_size ( sh ( e ) ) / 8;
590
     clear_out (sz, isconst, al);
591
     return;
592
   };
593
 
594
  if (n == chvar_tag && shape_size(sh(e)) == shape_size(sh(son(e)))) {
595
    sh(son(e)) = sh(e);
596
    evalaux(son(e), isconst, al);
597
    return;
598
  };
599
 
600
 
601
  outsize(e_size);
602
  evalval(e);
603
  outnl();
604
  return;
605
}
606
 
607
/* output a constant of given label number
608
   cname, or identifier s cname==-1 means
609
   use s */
610
void evaluate
611
    PROTO_N ( (c, cname, s, isconst, global, diag_props) )
612
    PROTO_T ( exp c X int cname X char *s X int isconst X int global X diag_global * diag_props )
613
{
614
  int al = shape_align(sh(c));
615
 
616
  if (global && cname == -1) {
617
    outs (".globl ");
618
    outs (s);
619
    outnl ();
620
  };
621
 
622
  if (name(sh(c)) == realhd ||
623
        (name(sh(c)) == nofhd && ptno(sh(c)) == realhd) ||
624
      shape_size(sh(c)) >= 512)
625
    al = 64;
626
 
627
  if (al <= 8)
628
    dot_align(4);
629
  else
630
    dot_align(al/8);
631
 
632
  if (diag_props)
633
#ifdef NEWDWARF
634
    DIAG_VAL_BEGIN (diag_props, global, cname, s);
635
#else
636
    diag_val_begin(diag_props, global, cname, s);
637
#endif
638
 
639
  if (cname == -1) {
640
    outs (s);
641
  }
642
  else {
643
    outs(local_prefix);
644
    outn ((long)cname);
645
  };
646
 
647
  outs (":");
648
  outnl();
649
 
650
  evalaux (c, isconst, al);
651
 
652
  if (global)
653
    eval_postlude(s, c);
654
 
655
  outnl ();
656
 
657
  if (diag_props) {
658
#ifdef NEWDWARF
659
    DIAG_VAL_END (diag_props);
660
#else
661
    diag_val_end(diag_props);
662
#endif
663
  }
664
 
665
  return;
666
}