Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 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
    		 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
7 7u83 152
(int n)
2 7u83 153
{
7 7u83 154
  switch ((n+7) /8) {
2 7u83 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
7 7u83 170
(exp e)
2 7u83 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) {
7 7u83 178
		return(no(e) >>3);
2 7u83 179
	}
7 7u83 180
        return(no(e));
2 7u83 181
      }
182
    case bitf_to_int_tag:
183
      {
7 7u83 184
	return evalexp(son(e));
2 7u83 185
      }
186
    case int_to_bitf_tag:
187
      {
7 7u83 188
	long  w = evalexp(son(e));
189
	if (shape_align(sh(e))!= 1) {
190
	  failer("should be align 1");
2 7u83 191
	}
7 7u83 192
	if (shape_size(sh(e))!= 32) {
2 7u83 193
	  w &= ((1 << shape_size(sh(e))) - 1);
194
	}
195
	return w;
196
      }
197
    case not_tag:
198
      {
7 7u83 199
	return(~evalexp(son(e)));
2 7u83 200
      }
201
    case and_tag:
202
      {
7 7u83 203
	return(evalexp(son(e)) & evalexp(bro(son(e))));
2 7u83 204
      }
205
    case or_tag:
206
      {
7 7u83 207
	return(evalexp(son(e)) | evalexp(bro(son(e))));
2 7u83 208
      }
209
    case xor_tag:
210
      {
7 7u83 211
	return(evalexp(son(e))^ evalexp(bro(son(e))));
2 7u83 212
      }
213
 
214
    case shr_tag:
215
      {
7 7u83 216
	return(evalexp(son(e)) >> evalexp(bro(son(e))));
2 7u83 217
      }
218
 
219
    case shl_tag:
220
      {
7 7u83 221
	return(evalexp(son(e)) << evalexp(bro(son(e))));
2 7u83 222
      }
223
 
224
    case concatnof_tag:
225
      {
7 7u83 226
	long  wd = evalexp(son(e));
227
	return(wd | (evalexp(bro(son(e))) << shape_size(sh(son(e)))));
2 7u83 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)
7 7u83 239
   	  return(no(son(e)) / 8);
2 7u83 240
	break;
241
      }
242
    case env_size_tag:
243
      {
244
	dec * et = brog(son(son(e)));
245
	if (et -> dec_u.dec_val.processed)
7 7u83 246
	  return(et -> dec_u.dec_val.index);
2 7u83 247
	break;
248
      }
249
    case offset_add_tag:
250
      {
7 7u83 251
    	return(evalexp(son(e)) +evalexp(bro(son(e))));
2 7u83 252
      }
253
    case offset_max_tag:
254
      {
255
	long a = evalexp(son(e));
256
	long b = evalexp(bro(son(e)));
7 7u83 257
    	return(a > b ? a : b);
2 7u83 258
      }
259
    case offset_pad_tag:
260
      {
7 7u83 261
	return(rounder(evalexp(son(e)), shape_align(sh(e)) / 8));
2 7u83 262
      }
263
    case offset_mult_tag:
264
      {
7 7u83 265
    	return(evalexp(son(e))*evalexp(bro(son(e))));
2 7u83 266
      }
267
    case offset_div_tag:
268
    case offset_div_by_int_tag:
269
      {
7 7u83 270
    	return(evalexp(son(e)) /evalexp(bro(son(e))));
2 7u83 271
      }
272
    case offset_subtract_tag:
273
      {
7 7u83 274
    	return(evalexp(son(e)) -evalexp(bro(son(e))));
2 7u83 275
      }
276
    case offset_negate_tag:
277
      {
7 7u83 278
	return(- evalexp(son(e)));
2 7u83 279
      }
280
    case seq_tag:
281
      {
282
	if (name(son(son(e))) == prof_tag && last(son(son(e))))
7 7u83 283
	   return(evalexp(bro(son(e))));
2 7u83 284
	break;
285
      }
286
    case cont_tag:
287
      {
288
	if (PIC_code && name(son(e)) == name_tag && isglob(son(son(e)))
7 7u83 289
		&& son(son(son(e)))!= nilexp
2 7u83 290
		&& !(brog(son(son(e))) -> dec_u.dec_val.dec_var))
7 7u83 291
	   return(evalexp(son(son(son(e)))));
2 7u83 292
	break;
293
      }
294
  }
295
  failer(BAD_VAL);
7 7u83 296
  return(0);
2 7u83 297
}
298
 
299
 
300
/* outputs a value */
301
static void evalval
7 7u83 302
(exp e)
2 7u83 303
{
304
  int e_size = shape_size(sh(e));
7 7u83 305
  unsigned char  n = name(e);
2 7u83 306
  int ov;
307
 
308
  if (n == val_tag) {
7 7u83 309
    int k = (name(sh(e)) == offsethd && al2(sh(e))!= 1)
310
                  ? no(e) /8 : no(e);
2 7u83 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:
7 7u83 318
	outn((long)k & 0xff);
2 7u83 319
	break;
320
      case 16:
7 7u83 321
	outn((long)k & 0xffff);
2 7u83 322
	break;
323
      case 32:
7 7u83 324
	outn((long)k);
2 7u83 325
	break;
326
      case 64:
7 7u83 327
	outn((long)k);
328
	outs(", ");
2 7u83 329
	if (isbigval(e)) {
7 7u83 330
	  SET(x);
2 7u83 331
	  outn((long)x.big);
332
	} else
333
	if (is_signed(sh(e)) && k < 0)
7 7u83 334
	  outn((long) -1);
2 7u83 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) {
7 7u83 346
    outreal(e);
2 7u83 347
    return;
348
  };
349
 
350
  if (n == reff_tag && name(son(e)) == name_tag && isglob(son(son(e)))) {
351
    outopenbr();
7 7u83 352
    outs(brog(son(son(e))) -> dec_u.dec_val.dec_id);
353
    outs(" + ");
354
    outn((long)(no(e) + no(son(e))) / 8);
2 7u83 355
    outclosebr();
356
    return;
357
  };
358
 
359
  if (n == name_tag) {
7 7u83 360
    if (no(e)!= 0) {
2 7u83 361
      outopenbr();
7 7u83 362
      outs(brog(son(e)) -> dec_u.dec_val.dec_id);
363
      outs(" + ");
364
      outn((long)no(e) / 8);
2 7u83 365
      outclosebr();
366
    }
367
    else
7 7u83 368
      outs(brog(son(e)) -> dec_u.dec_val.dec_id);
2 7u83 369
    return;
370
  };
371
 
372
  {
7 7u83 373
    int k = evalexp(e);
2 7u83 374
    switch (e_size) {
375
      case 8:
7 7u83 376
	outn((long)k & 0xff);
2 7u83 377
	break;
378
      case 16:
7 7u83 379
	outn((long)k & 0xffff);
2 7u83 380
	break;
381
      case 32:
7 7u83 382
	outn((long)k);
2 7u83 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
7 7u83 396
(int n, int isconst, int al)
2 7u83 397
{
398
  if (n == 0)
399
     return;
400
 
401
  if (isconst) {
402
    while (al >= 32 && n >= 4) {
403
      outlong();
7 7u83 404
      outs("0");
405
      outnl();
2 7u83 406
      n -= 4;
407
    };
408
    while (n > 0) {
409
      outbyte();
7 7u83 410
      outs("0");
411
      outnl();
2 7u83 412
      --n;
413
    };
414
  }
415
  else {
7 7u83 416
    outs(".set .,.+");
417
    outn((long)n);
418
    outnl();
2 7u83 419
  };
420
 
421
  return;
422
}
423
 
424
/* does the work of outputting of constants recursively */
425
static void evalaux
7 7u83 426
(exp e, int isconst, int al)
2 7u83 427
{
428
  int e_size = shape_size(sh(e));
7 7u83 429
  unsigned char  n = name(e);
2 7u83 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();
7 7u83 452
	    outn((long)work & 0xff);
2 7u83 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
           {
7 7u83 463
              clear_out((off-crt_off) /8, isconst, al);
2 7u83 464
              crt_off = off & -8;
465
           };
466
 
7 7u83 467
       if (name(sh(val))!= bitfhd)
2 7u83 468
         {
7 7u83 469
           evalaux(val, isconst,(crt_off + al) & 56);
2 7u83 470
           crt_off += shape_size(sh(val));
471
         }
472
       else
473
         {
474
           offn = off - crt_off;
475
           sz = shape_size(sh(val));
7 7u83 476
           nx = (name(val) ==int_to_bitf_tag)? no(son(val)): no(val);
2 7u83 477
           work += nx << offn;
478
           bits_left = offn+sz;
479
           if ((offn + sz) <= 32)
480
              { while ((offn+sz) >= 8)
481
                 {
482
	           outbyte();
7 7u83 483
	           outn((long)work & 0xff);
2 7u83 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();
7 7u83 497
	           outn((long)work & 0xff);
2 7u83 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();
7 7u83 513
	       outn((long)work & 0xff);
2 7u83 514
               outnl();
515
               crt_off += 8;
516
            };
7 7u83 517
          clear_out((shape_size(sh(e)) - crt_off) /8, isconst,
2 7u83 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
         {
7 7u83 544
           case 8: outn((long)s[j]); break;
545
           case 16: outn((long)((short*)(void*)s)[j]); break;
2 7u83 546
		/* the pun to short* is correct: jmf */
7 7u83 547
           case 32: outn((long)((int*)(void*)s)[j]); break;
2 7u83 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);
7 7u83 553
	     outn((long)x.small); outs(", "); outn((long)x.big);
2 7u83 554
	   };
555
         };
556
	--goon;
557
	if (goon && j < i + 9)
7 7u83 558
	  outs(", ");
2 7u83 559
      };
7 7u83 560
      outnl();
2 7u83 561
    };
562
    return;
563
  };
564
 
565
  if (n == res_tag) {
566
    int  nb;
567
    nb = shape_size(sh(son(e))) / 8;
7 7u83 568
    clear_out(nb, isconst, shape_align(sh(son(e))));
2 7u83 569
    return;
570
  };
571
 
572
  if (n == ncopies_tag) {
7 7u83 573
    int  m = no(e);
2 7u83 574
    int  sz, i;
575
    exp val = son(e);
7 7u83 576
    while (name(val) == ncopies_tag) {
577
	m *= no(val);
578
	val = son(val);
2 7u83 579
    }
580
    sz = shape_size(sh(val)) / 8;
581
    if ((name(val) == null_tag ||
582
	 name(val) == val_tag) && !isbigval(val) && no(val) == 0)
7 7u83 583
      clear_out(m * sz, isconst, shape_align(sh(val)));
2 7u83 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);
7 7u83 602
        dot_align((shape_align(sh(t)) <=8)? 1 : shape_align(sh(t)) /8);
2 7u83 603
      };
604
   };
605
 
606
  if (n == concatnof_tag) {
7 7u83 607
    evalaux(son(e), isconst, al);
608
    evalaux(bro(son(e)), isconst,(al +shape_size(son(e))) & 63);
2 7u83 609
    return;
610
  };
611
 
612
  if (n == clear_tag)
613
   {
7 7u83 614
     int sz = shape_size(sh(e)) / 8;
615
     clear_out(sz, isconst, al);
2 7u83 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
7 7u83 636
(exp c, int cname, char *s, int isconst, int global, diag_global * diag_props)
2 7u83 637
{
638
  int al = shape_align(sh(c));
639
 
640
  if (global && cname == -1) {
7 7u83 641
    outs(".globl ");
642
    outs(s);
643
    outnl();
2 7u83 644
  };
645
 
646
  if (name(sh(c)) == realhd ||
7 7u83 647
       (name(sh(c)) == nofhd && ptno(sh(c)) == realhd) ||
2 7u83 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
7 7u83 658
    DIAG_VAL_BEGIN(diag_props, global, cname, s);
2 7u83 659
#else
660
    diag_val_begin(diag_props, global, cname, s);
661
#endif
662
 
663
  if (cname == -1) {
7 7u83 664
    outs(s);
2 7u83 665
  }
666
  else {
667
    outs(local_prefix);
7 7u83 668
    outn((long)cname);
2 7u83 669
  };
670
 
7 7u83 671
  outs(":");
2 7u83 672
  outnl();
673
 
7 7u83 674
  evalaux(c, isconst, al);
2 7u83 675
 
676
  if (global)
677
    eval_postlude(s, c);
678
 
7 7u83 679
  outnl();
2 7u83 680
 
681
  if (diag_props) {
682
#ifdef NEWDWARF
7 7u83 683
    DIAG_VAL_END(diag_props);
2 7u83 684
#else
685
    diag_val_end(diag_props);
686
#endif
687
  }
688
 
689
  return;
690
}