Subversion Repositories tendra.SVN

Rev

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

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