Subversion Repositories tendra.SVN

Rev

Rev 6 | 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
    		 Crown Copyright (c) 1996
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
			    VERSION INFORMATION
61
			    ===================
62
 
63
--------------------------------------------------------------------------
64
$Header: /u/g/release/CVSROOT/Source/src/installers/680x0/common/evaluate.c,v 1.1.1.1 1998/01/17 15:55:49 release Exp $
65
--------------------------------------------------------------------------
66
$Log: evaluate.c,v $
67
 * Revision 1.1.1.1  1998/01/17  15:55:49  release
68
 * First version to be checked into rolling release.
69
 *
70
Revision 1.3  1997/11/09 14:09:29  ma
71
Fixed init with null_tag.
72
 
73
Revision 1.2  1997/10/29 10:22:13  ma
74
Replaced use_alloca with has_alloca.
75
 
76
Revision 1.1.1.1  1997/10/13 12:42:50  ma
77
First version.
78
 
79
Revision 1.5  1997/10/13 08:49:23  ma
80
Made all pl_tests for general proc & exception handling pass.
81
 
82
Revision 1.4  1997/09/25 06:44:57  ma
83
All general_proc tests passed
84
 
85
Revision 1.3  1997/06/18 10:09:27  ma
86
Checking in before merging with Input Baseline changes.
87
 
88
Revision 1.2  1997/04/20 11:30:24  ma
89
Introduced gcproc.c & general_proc.[ch].
90
Added cases for apply_general_proc next to apply_proc in all files.
91
 
92
Revision 1.1.1.1  1997/03/14 07:50:11  ma
93
Imported from DRA
94
 
95
 * Revision 1.1.1.1  1996/09/20  10:56:53  john
96
 *
97
 * Revision 1.2  1996/07/05  14:20:08  john
98
 * Changes for spec 3.1
99
 *
100
 * Revision 1.1.1.1  1996/03/26  15:45:11  john
101
 *
102
 * Revision 1.5  94/06/29  14:20:32  14:20:32  ra (Robert Andrews)
103
 * Turn out of range floating point constants to infinity if
104
 * flpt_const_overflow_fail is false.
105
 *
106
 * Revision 1.4  94/02/21  15:58:07  15:58:07  ra (Robert Andrews)
107
 * is_comm now returns int, not bool.
108
 *
109
 * Revision 1.3  93/11/19  16:18:46  16:18:46  ra (Robert Andrews)
110
 * Added minptr_tag case.  Corrected floating point bit pattern routines
111
 * for little endian case.
112
 *
113
 * Revision 1.2  93/05/24  15:56:15  15:56:15  ra (Robert Andrews)
114
 * Added ext_eval_name, which is meant to help in illegal constant error
115
 * messages.
116
 *
117
 * Revision 1.1  93/02/22  17:15:32  17:15:32  ra (Robert Andrews)
118
 * Initial revision
119
 *
120
--------------------------------------------------------------------------
121
*/
122
 
123
 
124
#include "config.h"
125
#if FS_NO_ANSI_ENVIRON
126
#include <floatingpoint.h>
127
#else
128
#include <float.h>
129
#endif
130
#include "common_types.h"
131
#include "assembler.h"
132
#include "basicread.h"
133
#include "expmacs.h"
134
#include "instrs.h"
135
#include "shapemacs.h"
136
#include "fbase.h"
137
#include "flpt.h"
138
#include "evaluate.h"
139
#include "mach.h"
140
#include "mach_ins.h"
141
#include "mach_op.h"
142
#include "codex.h"
143
#include "tags.h"
144
#include "translate.h"
145
#include "utility.h"
146
#include "f64.h"
147
#if have_diagnostics
148
#include "xdb_basics.h"
149
#endif
150
 
6 7u83 151
extern int is_comm(exp);
152
extern char *get_pointer_name(void *);
153
extern int flpt_const_overflow_fail;
154
extern double atof(CONST char *);
155
extern double frexp(double, int *);
2 7u83 156
 
157
 
158
#define  par_pl		1	/* On the stack (procedure argument) */
159
#define  var_pl		2	/* On the stack (allocated variable) */
160
 
161
#ifndef tdf3
162
#define  par2_pl        4       /* Caller arguments accessed by use of A5 */
163
#define  par3_pl        5       /* Caller arguments accessed by use of SP */
164
#endif
165
 
166
/*
167
    NAME OF THE CONSTANT BEING EVALUATED
168
*/
169
 
6 7u83 170
static char *ext_eval_name = "???";
2 7u83 171
 
172
 
173
/*
174
    LIST OF EXTERNAL CONSTANTS
175
 
176
    All external constants created are formed into a bro-list.
177
*/
178
 
6 7u83 179
exp const_list = nilexp;
2 7u83 180
 
181
 
182
/*
183
    DATA CONSTANTS
184
 
185
    In outputting data constants, current_op is the list of values currently
186
    being built up.  These values are all of size current_sz.  Values not
187
    yet of this size are built up in pvalue, which contains psz bits.
188
*/
189
 
6 7u83 190
static mach_op *current_op = null;
191
static long current_sz = 0;
2 7u83 192
 
193
 
194
/*
195
    OUTPUT AN EVALUATION INSTRUCTION
196
 
197
    An instruction corresponding to current_op is output, and current_op
198
    is reset.
199
*/
200
 
201
static void eval_instr
6 7u83 202
(void)
2 7u83 203
{
6 7u83 204
    if (current_op) {
205
	int s = ins(current_sz, m_as_byte, m_as_short, m_as_long);
206
	make_instr(s, current_op, null, 0);
207
	current_op = null;
2 7u83 208
    }
6 7u83 209
    current_sz = 0;
210
    return;
2 7u83 211
}
212
 
213
 
214
/*
215
    OUTPUT AN OPERAND
216
 
217
    The operand op of size sz is added to current_op.
218
*/
219
 
220
void eval_op
6 7u83 221
(long sz, mach_op *op)
2 7u83 222
{
6 7u83 223
    static mach_op *last_op;
224
    if (sz != current_sz) {
225
	eval_instr();
226
	current_op = op;
227
	current_sz = sz;
2 7u83 228
    } else {
6 7u83 229
	last_op->of = op;
2 7u83 230
    }
6 7u83 231
    last_op = op;
232
    return;
2 7u83 233
}
234
 
235
/*
236
    EVALUATE AN EXPRESSION
237
 
238
    The expression e, is evaluated and the integer result is returned.
239
    (from trans386)
240
*/
6 7u83 241
extern int PIC_code;
2 7u83 242
 
243
long  evalexp
6 7u83 244
(exp e)
2 7u83 245
{
246
   switch (name(e)) {
247
   case  val_tag:
248
   case null_tag:
249
   case top_tag:
250
    {
6 7u83 251
       int k = no(e);
252
       if (is_offset(e))k /= 8;
253
       return(k);
2 7u83 254
    }
255
   case bitf_to_int_tag:
256
    {
6 7u83 257
       return evalexp(son(e));
2 7u83 258
    }
259
   case int_to_bitf_tag:
260
    {
6 7u83 261
       long  w = evalexp(son(e));
262
       if (shape_align(sh(e))!= 1) {
263
	  failer("should be align 1");
2 7u83 264
       }
6 7u83 265
       if (shape_size(sh(e))!= 32) {
2 7u83 266
	  w &= ((1 << shape_size(sh(e))) - 1);
267
       }
268
       return w;
269
    }
270
   case not_tag:
271
    {
6 7u83 272
       return(~evalexp(son(e)));
2 7u83 273
    }
274
   case and_tag:
275
    {
6 7u83 276
       return(evalexp(son(e)) & evalexp(bro(son(e))));
2 7u83 277
    }
278
   case or_tag:
279
    {
6 7u83 280
       return(evalexp(son(e)) | evalexp(bro(son(e))));
2 7u83 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
    {
6 7u83 289
       return(evalexp(son(e)) >> evalexp(bro(son(e))));
2 7u83 290
    }
291
 
292
   case shl_tag:
293
    {
6 7u83 294
       return(evalexp(son(e)) << evalexp(bro(son(e))));
2 7u83 295
    }
296
 
297
   case concatnof_tag:
298
    {
6 7u83 299
       long  wd = evalexp(son(e));
300
       return(wd | (evalexp(bro(son(e))) << shape_size(sh(son(e)))));
2 7u83 301
    }
302
 
303
   case clear_tag:
304
    {
305
       if (shape_size(sh(e)) <= 32)
306
       return 0;
307
       break;
308
    }
309
   case env_offset_tag:
310
    {
6 7u83 311
       exp ident_exp = son(e);
2 7u83 312
 
313
       if (ismarked(ident_exp)) {
6 7u83 314
          long offval;
2 7u83 315
          switch (ptno(ident_exp)) {
316
          case var_pl:
6 7u83 317
             offval = -no(ident_exp) /8;
2 7u83 318
             break;
319
          case par2_pl:
6 7u83 320
             offval = no(ident_exp) /8;
2 7u83 321
             break;
322
          case par3_pl:
323
          case par_pl:
324
          default:
6 7u83 325
             offval = no(ident_exp) /8 + 8;
2 7u83 326
          }
6 7u83 327
          return offval;
2 7u83 328
       }
329
       break;
330
    }
331
   case env_size_tag:
332
    {
333
       dec * et = brog(son(son(e)));
334
       if (et -> dec_u.dec_val.processed)
6 7u83 335
       return(et -> dec_u.dec_val.index);
2 7u83 336
       break;
337
    }
338
   case offset_add_tag:
339
    {
6 7u83 340
       return(evalexp(son(e)) +evalexp(bro(son(e))));
2 7u83 341
    }
342
   case offset_max_tag:
343
    {
344
       long a = evalexp(son(e));
345
       long b = evalexp(bro(son(e)));
6 7u83 346
       return(a > b ? a : b);
2 7u83 347
    }
348
   case offset_pad_tag:
349
    {
6 7u83 350
       return(rounder(evalexp(son(e)), shape_align(sh(e)) / 8));
2 7u83 351
    }
352
   case offset_mult_tag:
353
    {
6 7u83 354
       return(evalexp(son(e))*evalexp(bro(son(e))));
2 7u83 355
    }
356
   case offset_div_tag:
357
   case offset_div_by_int_tag:
358
    {
6 7u83 359
       long n = evalexp(bro(son(e)));
360
       if (n == 0) {
2 7u83 361
          n++;
362
          error("evalexp: divide by zero");
363
       }
6 7u83 364
       return(evalexp(son(e)) / n);
2 7u83 365
    }
366
   case offset_subtract_tag:
367
    {
6 7u83 368
       return(evalexp(son(e)) -evalexp(bro(son(e))));
2 7u83 369
    }
370
   case offset_negate_tag:
371
    {
6 7u83 372
       return(- evalexp(son(e)));
2 7u83 373
    }
374
   case seq_tag:
375
    {
376
       if (name(son(son(e))) == prof_tag && last(son(son(e))))
6 7u83 377
	   return(evalexp(bro(son(e))));
2 7u83 378
       break;
379
    }
380
   case cont_tag:
381
    {
382
       if (PIC_code && name(son(e)) == name_tag && isglob(son(son(e)))
6 7u83 383
           && son(son(son(e)))!= nilexp
2 7u83 384
           && !(brog(son(son(e))) -> dec_u.dec_val.dec_var))
6 7u83 385
       return(evalexp(son(son(son(e)))));
2 7u83 386
       break;
387
    }
388
   }
6 7u83 389
   error("Illegal constant expression in %s", ext_eval_name);
390
   return(0);
2 7u83 391
}
392
 
393
/*
394
    EVALUATE AN INTEGER VALUE
395
 
396
    The expression e, representing an integer value, is evaluated.
397
*/
398
 
399
static void evalno
6 7u83 400
(exp e)
2 7u83 401
{
6 7u83 402
    mach_op *op;
403
    long sz = shape_size(sh(e));
2 7u83 404
    long k = evalexp(e);
405
 
6 7u83 406
    switch (sz) {
2 7u83 407
 
6 7u83 408
      case 8: {
409
	op = make_value(k & 0xff);
410
	eval_op(L8, op);
411
	return;
2 7u83 412
      }
413
 
6 7u83 414
      case 16: {
415
	op = make_value((k >> 8) & 0xff);
416
	eval_op(L8, op);
417
	op = make_value(k & 0xff);
418
	eval_op(L8, op);
419
	return;
2 7u83 420
      }
421
 
6 7u83 422
      case 32: {
423
	op = make_value((k >> 24) & 0xff);
424
	eval_op(L8, op);
425
	op = make_value((k >> 16) & 0xff);
426
	eval_op(L8, op);
427
	op = make_value((k >> 8) & 0xff);
428
	eval_op(L8, op);
429
	op = make_value(k & 0xff);
430
	eval_op(L8, op);
431
	return;
2 7u83 432
      }
6 7u83 433
      case 64: {
2 7u83 434
	flt64 bval;
435
	bval = exp_to_f64(e);
436
	op = make_value((bval.small>>24) & 0xff);
437
	eval_op(L8,op);
438
	op = make_value((bval.small>>16) & 0xff);
439
	eval_op(L8,op);
440
	op = make_value((bval.small>>8) & 0xff);
441
	eval_op(L8,op);
442
	op = make_value(bval.small & 0xff);
443
	eval_op(L8,op);
444
 
445
	op = make_value((bval.big>>24) & 0xff);
446
	eval_op(L8,op);
447
	op = make_value((bval.big>>16) & 0xff);
448
	eval_op(L8,op);
449
	op = make_value((bval.big>>8) & 0xff);
450
	eval_op(L8,op);
451
	op = make_value(bval.big & 0xff);
452
	eval_op(L8,op);
453
	return;
454
      }
455
    }
6 7u83 456
    error("Illegal integer value in %s", ext_eval_name);
457
    return;
2 7u83 458
}
459
 
460
 
461
/*
462
    CONVERT A REAL VALUE TO A BITPATTERN
463
 
464
    This routine converts the real constant e into an array of longs
465
    giving the bitpattern corresponding to this constant.  Although
466
    care has been taken, this may not work properly on all machines
467
    (although it should for all IEEE machines).  It returns NULL if
468
    it cannot convert the number sufficiently accurately.
469
*/
470
 
471
long *realrep
6 7u83 472
(exp e)
2 7u83 473
{
6 7u83 474
    int i, n, ex;
475
    double d, m;
476
    char bits[128];
477
    static long longs[4];
478
    int exp_bits, mant_bits;
479
    long sz = shape_size(sh(e));
2 7u83 480
 
481
    /* Find size of exponent and mantissa */
6 7u83 482
    if (sz == 32) {
483
	exp_bits = 8;
484
	mant_bits = 23;
485
    } else if (sz == 64) {
486
	exp_bits = 11;
487
	mant_bits = 52;
2 7u83 488
    } else {
6 7u83 489
	exp_bits = 15;
2 7u83 490
	mant_bits = 96 /* or 112? */ ;
491
    }
492
 
6 7u83 493
#if (FBASE == 10)
2 7u83 494
 
6 7u83 495
    if (!convert_floats) return(NULL);
2 7u83 496
 
6 7u83 497
    if (name(e) == real_tag) {
2 7u83 498
	/* Calculate value */
6 7u83 499
	flt *f = flptnos + no(e);
500
	char fbuff[100];
501
	char *p = fbuff;
502
	if (f->exp <= DBL_MIN_10_EXP || f->exp >= DBL_MAX_10_EXP) {
2 7u83 503
	    /* Reject anything that won't fit into a double */
6 7u83 504
	    return(NULL);
2 7u83 505
	}
6 7u83 506
	if (f->sign < 0)*(p++) = '-';
507
	*(p++) = '0' + f->mant[0];
508
	*(p++) = '.';
509
	for (i = 1; i < MANT_SIZE; i++)*(p++) = '0' + f->mant[i];
510
	sprintf(p, "e%d",(int)f->exp);
511
	d = atof(fbuff);
512
	if (sz == 32) {
2 7u83 513
	    /* Round floats */
6 7u83 514
	    static float fd;
515
	    fd = (float)d;
516
	    d = (double)fd;
2 7u83 517
	}
518
    } else {
6 7u83 519
	error("Illegal floating-point constant");
520
	return(NULL);
2 7u83 521
    }
522
 
523
    /* Deal with 0 */
6 7u83 524
    if (d == 0.0) {
525
	for (i = 0; i < sz / 32; i++)longs[i] = 0;
526
	return(longs);
2 7u83 527
    }
528
 
529
    /* Fill in sign */
6 7u83 530
    if (d < 0.0) {
531
	bits[0] = 1;
532
	d = -d;
2 7u83 533
    } else {
6 7u83 534
	bits[0] = 0;
2 7u83 535
    }
536
 
537
    /* Work out mantissa and exponent */
6 7u83 538
    m = frexp(d, &ex);
539
    m = 2.0 * m - 1.0;
540
    ex--;
2 7u83 541
 
542
    /* Fill in mantissa */
6 7u83 543
    for (i = 1; i <= mant_bits; i++) {
544
	int j = exp_bits + i;
545
	m *= 2.0;
546
	if (m >= 1.0) {
547
	    m -= 1.0;
548
	    bits[j] = 1;
2 7u83 549
	} else {
6 7u83 550
	    bits[j] = 0;
2 7u83 551
	}
552
    }
553
 
554
#else
555
 
6 7u83 556
    if (name(e) == real_tag) {
557
	int j, k = -1;
558
	flt *f = flptnos + no(e);
2 7u83 559
 
560
	/* Deal with 0 */
6 7u83 561
	if (f->sign == 0) {
562
	    for (i = 0; i < sz / 32; i++)longs[i] = 0;
563
	    return(longs);
2 7u83 564
	}
565
 
566
	/* Fill in sign */
6 7u83 567
	bits[0] = (f->sign < 0 ? 1 : 0);
2 7u83 568
 
569
	/* Work out exponent */
6 7u83 570
	ex = FBITS *(f->exp) + (FBITS - 1);
2 7u83 571
 
572
	/* Fill in mantissa */
6 7u83 573
	for (i = 0; i < MANT_SIZE; i++) {
574
	    for (j = FBITS - 1; j >= 0; j--) {
575
		if ((f->mant[i]) & (1 << j)) {
576
		    if (k >= 0) {
577
			if (k < sz)bits[k] = 1;
578
			k++;
2 7u83 579
		    } else {
580
			/* Ignore first 1 */
6 7u83 581
			k = exp_bits + 1;
2 7u83 582
		    }
583
		} else {
6 7u83 584
		    if (k >= 0) {
585
			if (k < sz)bits[k] = 0;
586
			k++;
2 7u83 587
		    } else {
588
			/* Step over initial zeros */
6 7u83 589
			ex--;
2 7u83 590
		    }
591
		}
592
	    }
593
	}
594
 
595
    } else {
6 7u83 596
	error("Illegal floating-point constant");
597
	return(NULL);
2 7u83 598
    }
599
 
600
#endif
601
 
602
    /* Fill in exponent */
6 7u83 603
    ex += (1 << (exp_bits - 1)) - 1;
604
    if (ex <= 0 || ex >= (1 << exp_bits) - 1) {
605
	if (flpt_const_overflow_fail) {
606
	    error("Floating point constant out of range");
2 7u83 607
	}
6 7u83 608
	if (sz == 32) {
609
	    if (bits[0])longs[0] = 0x80000000;
610
	    longs[0] += 0x7f800000;
2 7u83 611
	} else {
6 7u83 612
	    if (bits[0])longs[0] = 0x80000000;
613
	    longs[0] += 0x7ff00000;
614
	    longs[1] = 0;
2 7u83 615
	}
6 7u83 616
	return(longs);
2 7u83 617
    }
6 7u83 618
    for (i = 0; i < exp_bits; i++) {
619
	int j = exp_bits - i;
620
	bits[j] = ((ex & (1 << i))? 1 : 0);
2 7u83 621
    }
622
 
623
    /* Convert bits to longs */
6 7u83 624
    n = (sz / 32) - 1;
625
    for (i = 0; i <= n; i++) {
626
	int j;
627
	long b0 = 0, b1 = 0, b2 = 0, b3 = 0;
628
	for (j = 0; j < 8; j++)b0 = 2 * b0 + bits[32 * i + j];
629
	for (j = 8; j < 16; j++)b1 = 2 * b1 + bits[32 * i + j];
630
	for (j = 16; j < 24; j++)b2 = 2 * b2 + bits[32 * i + j];
631
	for (j = 24; j < 32; j++)b3 = 2 * b3 + bits[32 * i + j];
2 7u83 632
#if little_end
6 7u83 633
	longs[n - i] = (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
2 7u83 634
#else
6 7u83 635
	longs[i] = (b0 << 24) + (b1 << 16) + (b2 << 8) + b3;
2 7u83 636
#endif
637
    }
6 7u83 638
    return(longs);
2 7u83 639
}
640
 
641
 
642
/*
643
    EVALUATE A REAL VALUE
644
 
645
    The expression e, representing a real value, is evaluated.  There
646
    are two cases, depending on the macro convert_floats.  Either the
647
    number itself or its representation in bits is output.
648
*/
649
 
650
static void evalreal
6 7u83 651
(exp e)
2 7u83 652
{
6 7u83 653
    long *p;
654
    long sz = shape_size(sh(e));
655
    eval_instr();
656
    p = realrep(e);
657
    if (p) {
658
	int i;
659
	for (i = 0; i < sz / 32; i++) {
660
	    mach_op *op = make_value(p[i]);
661
	    eval_op(L32, op);
2 7u83 662
	}
663
    } else {
6 7u83 664
	flt *f = flptnos + no(e);
665
	mach_op *op = make_float_data(f);
666
	int instr = insf(sz, m_as_float, m_as_double, m_dont_know);
667
	make_instr(instr, op, null, 0);
668
	current_sz = 0;
2 7u83 669
    }
6 7u83 670
    return;
2 7u83 671
}
672
 
673
 
674
/*
675
    CLEAR A NUMBER OF BYTES
676
 
677
    The next n bits are cleared, either by padding with zeros or by
678
    using a space instruction.
679
*/
680
 
681
static void clear_out
6 7u83 682
(long n, bool isconst, long al)
2 7u83 683
{
6 7u83 684
    mach_op *op;
685
    if (isconst) {
686
	while (n > 0) {
687
	    op = make_value(0);
688
	    eval_op(L8, op);
689
	    n--;
2 7u83 690
	}
691
    } else {
6 7u83 692
	eval_instr();
693
	current_sz = 0;
694
	if (n > 0) {
695
	  op = make_int_data(n);
696
	  make_instr(m_as_space, op, null, 0);
2 7u83 697
	}
6 7u83 698
	current_sz = 0;
2 7u83 699
    }
6 7u83 700
    return;
2 7u83 701
}
702
 
703
 
704
/*
705
    OUTPUT A CONSTANT
706
 
707
    This is the main constant evaluation routine.  The expression e is
708
    evaluated.  al gives the alignment of e.
709
*/
710
 
711
void evalaux
6 7u83 712
(exp e, bool isconst, long al)
2 7u83 713
{
6 7u83 714
    switch (name(e)) {
2 7u83 715
 
6 7u83 716
	case real_tag: {
2 7u83 717
	    /* Real values */
6 7u83 718
	    evalreal(e);
719
	    return;
2 7u83 720
	}
721
 
6 7u83 722
	case compound_tag: {
2 7u83 723
	    /* Compound values - deal with each component */
6 7u83 724
	    exp val;
725
	    mach_op *op;
726
	    exp offe = son(e);
727
	    long off;
728
	    long work = 0;
729
	    long crt_off = 0;
730
	    long bits_left = 0;
731
            int pad;
732
            bool param_aligned = 0;
2 7u83 733
 
6 7u83 734
	    if (offe == nilexp) return;
2 7u83 735
 
736
            /* look ahead to determine if it is parameter aligned */
6 7u83 737
            val = bro(offe);
738
            if (! last(val)) {
739
               offe = bro(val);
740
               if (offe->shf->sonf.ald->al.al_val.al == 32) {
741
                  param_aligned = 1;
2 7u83 742
               }
743
            }
6 7u83 744
            offe = son(e);
2 7u83 745
 
6 7u83 746
	    while (1) {
747
		off = no(offe);
748
		val = bro(offe);
2 7u83 749
 
6 7u83 750
		if (bits_left && off >= (crt_off + 8)) {
751
		    op = make_value((work >> 24) & 0xff);
752
		    eval_op(L8, op);
753
		    crt_off += 8;
754
		    work = 0;
755
		    bits_left = 0;
2 7u83 756
		}
757
 
6 7u83 758
		if (off < crt_off) {
759
		    error("Compound constants out of order in %s",
760
			    ext_eval_name);
2 7u83 761
		}
762
 
6 7u83 763
		if (off > crt_off && !bits_left) {
764
		    clear_out((off - crt_off) / 8, 1, al);
765
		    crt_off = off;
2 7u83 766
		}
767
 
6 7u83 768
		if (name(sh(val))!= bitfhd) {
769
                   pad = 0;
770
                   if (param_aligned) {
771
                      switch (name(sh(val))) {
2 7u83 772
                      case scharhd:
773
                      case ucharhd:
6 7u83 774
                         clear_out(3, 1, al);
775
                         crt_off += 3*8;
2 7u83 776
                         break;
777
                      case swordhd:
778
                      case uwordhd:
6 7u83 779
                         clear_out(2, 1, al);
780
                         crt_off += 2*8;
2 7u83 781
                         break;
782
                      }
783
                   }
784
 
6 7u83 785
		    evalaux(val, isconst,(crt_off + al) & 56);
786
		    crt_off += shape_size(sh(val));
2 7u83 787
		} else {
6 7u83 788
		    long sz = shape_size(sh(val));
789
		    long offn = off - crt_off;
790
		    long nx, enx;
791
		    long extra_byte = 0;
792
		    if (name(val) == val_tag) {
793
			nx = no(val);
2 7u83 794
		    } else {
6 7u83 795
			nx = no(son(val));
2 7u83 796
		    }
6 7u83 797
		    if (sz > 32 - offn) {
798
			enx = (nx & 0xff);
799
			extra_byte = 1;
800
			nx >>= 8;
801
			sz -= 8;
2 7u83 802
		    }
6 7u83 803
		    nx = (nx & lo_bits[sz]) << (32 - offn - sz);
804
		    work += nx;
805
		    bits_left = offn + sz;
806
		    while (bits_left >= 8) {
807
			long v;
808
			bits_left -= 8;
809
			v = (work >> 24) & 0xff;
810
			work <<= 8;
811
			if (extra_byte) {
812
			    bits_left += 8;
813
			    work += (enx << (32 - bits_left));
814
			    extra_byte = 0;
2 7u83 815
			}
6 7u83 816
			op = make_value(v);
817
			eval_op(L8, op);
818
			crt_off += 8;
2 7u83 819
		    }
820
		}
821
 
6 7u83 822
		if (last(val)) {
823
		    long left;
824
		    if (bits_left) {
825
			op = make_value((work >> 24) & 0xff);
826
			eval_op(L8, op);
827
			crt_off += 8;
2 7u83 828
		    }
6 7u83 829
		    left = shape_size(sh(e)) - crt_off;
830
		    if (left > 0)clear_out(left / 8, 1, al);
831
		    return;
2 7u83 832
		}
6 7u83 833
		offe = bro(val);
2 7u83 834
	    }
835
	    /* Not reached */
836
	}
837
 
6 7u83 838
	case name_tag: {
2 7u83 839
	    /* External names */
6 7u83 840
	    mach_op *op;
841
	    long n = no(e);
842
	    long sz = shape_size(sh(e));
843
	    char *nm = brog(son(e)) ->dec_u.dec_val.dec_id;
844
	    op = make_extern_data(nm, n / 8);
845
	    eval_op(sz, op);
846
	    return;
2 7u83 847
	}
848
 
6 7u83 849
	case string_tag: {
2 7u83 850
	    /* Strings */
6 7u83 851
	    long i;
852
	    long char_size = (long)props(e);
853
	    long n = shape_size(sh(e)) / char_size;
854
	    switch (char_size) {
2 7u83 855
 
6 7u83 856
		case 8: {
857
		    char *s = nostr(e);
858
		    for (i = 0; i < n; i++) {
859
			long ch = (long)s[i];
860
			eval_op(char_size, make_value(ch));
2 7u83 861
		    }
6 7u83 862
		    break;
2 7u83 863
		}
864
 
6 7u83 865
		case 16: {
866
		    short *s = (short *)nostr(e);
867
		    for (i = 0; i < n; i++) {
868
			long ch = (long)s[i];
869
			eval_op(char_size, make_value(ch));
2 7u83 870
		    }
6 7u83 871
		    break;
2 7u83 872
		}
873
 
6 7u83 874
		case 32: {
875
		    long *s = (long *)nostr(e);
876
		    for (i = 0; i < n; i++) {
877
			long ch = s[i];
878
			eval_op(char_size, make_value(ch));
2 7u83 879
		    }
6 7u83 880
		    break;
2 7u83 881
		}
882
 
883
		default : {
6 7u83 884
		    error("Illegal string size in %s", ext_eval_name);
885
		    break;
2 7u83 886
		}
887
	    }
6 7u83 888
	    return;
2 7u83 889
	}
890
 
6 7u83 891
	case res_tag: {
2 7u83 892
	    /* Result values */
6 7u83 893
	    shape ss = sh(son(e));
894
	    long sz = shape_size(ss) / 8;
895
	    long sa = shape_align(ss);
896
	    clear_out(sz, isconst, sa);
897
	    return;
2 7u83 898
	}
6 7u83 899
      case top_tag:
900
      case null_tag: {
2 7u83 901
	    /* Null values */
6 7u83 902
	    shape ss = sh(e);
903
	    long sz = shape_size(ss) / 8;
904
	    long sa = shape_align(ss);
905
	    clear_out(sz, isconst, sa);
906
	    return;
2 7u83 907
	}
908
 
6 7u83 909
	case ncopies_tag: {
2 7u83 910
	    /* Multiple copies */
6 7u83 911
	    long i;
912
	    exp t = son(e);
913
	    long sa = shape_align(sh(t));
914
	    if (is_comm(t)) {
915
		long sz = rounder(shape_size(sh(t)), sa) / 8;
916
		clear_out(sz * no(e), isconst, sa);
917
		return;
2 7u83 918
	    }
6 7u83 919
	    for (i = 0; i < no(e); i++)evalaux(t, isconst, sa);
920
	    return;
2 7u83 921
	}
922
 
6 7u83 923
	case nof_tag: {
2 7u83 924
	    /* Array values */
6 7u83 925
	    exp t = son(e);
926
	    if (t == nilexp) return;
927
	    while (1) {
928
		evalaux(t, isconst, al);
929
		if (last(t)) return;
930
		t = bro(t);
2 7u83 931
	    }
932
	    /* Not reached */
933
	}
934
 
6 7u83 935
	case concatnof_tag: {
2 7u83 936
	    /* Concatenated arrays */
6 7u83 937
	    long a2 = (al + shape_size(son(e))) & 63;
938
	    evalaux(son(e), isconst, al);
939
	    evalaux(bro(son(e)), isconst, a2);
940
	    return;
2 7u83 941
	}
942
 
6 7u83 943
	case chvar_tag:
944
	case int_to_bitf_tag: {
2 7u83 945
	    /* Change variety */
6 7u83 946
	    if (name(son(e)) == val_tag) {
947
		sh(son(e)) = sh(e);
948
		evalaux(son(e), isconst, al);
949
		return;
2 7u83 950
	    }
6 7u83 951
	    error("Illegal change variety constant in %s", ext_eval_name);
952
	    return;
2 7u83 953
	}
954
 
6 7u83 955
	case chfl_tag: {
2 7u83 956
	    /* Change floating variety */
6 7u83 957
	    if (name(son(e)) == real_tag) {
958
		sh(son(e)) = sh(e);
959
		evalaux(son(e), isconst, al);
960
		return;
2 7u83 961
	    }
6 7u83 962
	    error("Illegal change floating variety constant in %s",
963
		    ext_eval_name);
964
	    return;
2 7u83 965
	}
966
 
6 7u83 967
	case clear_tag: {
968
	    long sz = shape_size(sh(e)) / 8;
969
	    clear_out(sz, isconst, al);
970
	    return;
2 7u83 971
	}
972
#if 0
973
        case env_size_tag: {
974
           dec* d = brog(son(son(e)));
6 7u83 975
           mach_op* op = make_lab_data((long)d, 0);
2 7u83 976
           eval_op(L32,op);
6 7u83 977
           return;
2 7u83 978
        }
979
 
6 7u83 980
	case env_offset_tag: {
2 7u83 981
           /* Offsets */
982
           long offval;
983
           mach_op *op;
6 7u83 984
           exp ident_exp = son(e);
985
           op = make_lab_data((long)ident_exp, 0);
2 7u83 986
           eval_op(L32,op);
987
 
6 7u83 988
           return;
2 7u83 989
	}
990
#endif
6 7u83 991
	case ident_tag: {
2 7u83 992
	     /* Simple identifications */
6 7u83 993
	     exp body = bro(son(e));
994
	     if (name(body) == name_tag && son(body) == e) {
995
		evalaux(son(e), isconst, al);
996
		return;
2 7u83 997
	     }
6 7u83 998
	     break;
2 7u83 999
	}
1000
 
6 7u83 1001
	case minptr_tag: {
1002
	    exp p1 = son(e);
1003
	    exp p2 = bro(p1);
1004
	    if (name(p1) == name_tag && name(p2) == name_tag) {
1005
		long n = no(p1) - no(p2);
1006
		long sz = shape_size(sh(e));
1007
		char *n1 = brog(son(p1)) ->dec_u.dec_val.dec_id;
1008
		char *n2 = brog(son(p2)) ->dec_u.dec_val.dec_id;
1009
		mach_op *op1 = new_mach_op();
1010
		mach_op *op2 = new_mach_op();
1011
		mach_op *op3 = new_mach_op();
1012
		op1->type = MACH_EXT;
1013
		op1->def.str = n1;
1014
		op1->plus = op2;
1015
		op2->type = MACH_NEG;
1016
		op2->plus = op3;
1017
		op3->type = MACH_EXT;
1018
		op3->def.str = n2;
1019
		if (n) {
1020
		    mach_op *op4 = new_mach_op();
1021
		    op4->type = MACH_VAL;
1022
		    op4->def.num = n;
1023
		    op3->plus = op4;
2 7u83 1024
		}
6 7u83 1025
		eval_op(sz, op1);
1026
		return;
2 7u83 1027
	    }
6 7u83 1028
	    break;
2 7u83 1029
	}
1030
	default:
6 7u83 1031
            evalno(e);
2 7u83 1032
    }
1033
}
1034
 
1035
 
1036
#if 0
1037
 
1038
/*
1039
    IS A VALUE ZERO?
1040
 
1041
    If so it can be put into the common area.
1042
*/
1043
 
1044
static int is_comm
6 7u83 1045
(exp e)
2 7u83 1046
{
6 7u83 1047
    switch (name(e)) {
2 7u83 1048
 
6 7u83 1049
	case val_tag: return(no(e)? 0 : 1);
2 7u83 1050
 
6 7u83 1051
	case int_to_bitf_tag:
1052
	case chvar_tag: return(is_comm(son(e)));
2 7u83 1053
 
6 7u83 1054
	case real_tag: {
1055
	    flpt f = no(e);
1056
	    return(flptnos[f].sign ? 0 : 1);
2 7u83 1057
	}
1058
 
6 7u83 1059
	case compound_tag: {
1060
	    exp t = son(e);
1061
	    if (t == nilexp) return(1);
1062
	    while (1) {
1063
		t = bro(t);
1064
		if (name(sh(t))!= bitfhd) {
1065
		    if (!is_comm(t)) return(0);
2 7u83 1066
		} else {
6 7u83 1067
		    if (name(t) == val_tag) {
1068
			if (no(t)) return(0);
2 7u83 1069
		    } else {
6 7u83 1070
			if (no(son(t))) return(0);
2 7u83 1071
		    }
1072
		}
6 7u83 1073
		if (last(t)) return(1);
1074
		t = bro(t);
2 7u83 1075
	    }
1076
	    /* Not reached */
1077
	}
1078
 
6 7u83 1079
	case ncopies_tag: return(is_comm(son(e)));
2 7u83 1080
 
6 7u83 1081
	case nof_tag: {
1082
	    exp t = son(e);
1083
	    if (t == nilexp) return(1);
1084
	    while (1) {
1085
		if (!is_comm(t)) return(0);
1086
		if (last(t)) return(1);
1087
		t = bro(t);
2 7u83 1088
	    }
1089
	    /* Not reached */
1090
	}
1091
 
6 7u83 1092
	case concatnof_tag: {
1093
	    exp t = son(e);
1094
	    return(is_comm(t) && is_comm(bro(t)));
2 7u83 1095
	}
1096
 
6 7u83 1097
	case clear_tag:
1098
	case res_tag:
1099
	case null_tag: return(1);
2 7u83 1100
    }
6 7u83 1101
    return(0);
2 7u83 1102
}
1103
 
1104
#endif
1105
 
1106
 
1107
/*
1108
    OUTPUT A CONSTANT
1109
*/
1110
 
1111
void evaluate
6 7u83 1112
(exp c, long cname, char *s, int isconst, int global, diag_global *di)
2 7u83 1113
{
6 7u83 1114
    mach_op *op1, *op2;
1115
    long al = (long)shape_align(sh(c));
2 7u83 1116
 
6 7u83 1117
    if (is_comm(c) ||
1118
       ((name(c) == name_tag) && (son(son(c))) && (name(son(son(c))) == null_tag))) {
2 7u83 1119
 
6 7u83 1120
	long sz = rounder(shape_size(sh(c)), 32);
2 7u83 1121
 
1122
	/* Common global values */
6 7u83 1123
	if (global && cname == -1 && !is_local(s)) {
1124
	    op1 = make_extern_data(s, 0);
1125
	    op2 = make_int_data(sz / 8);
1126
	    make_instr(m_as_common, op1, op2, 0);
2 7u83 1127
#if have_diagnostics
6 7u83 1128
	    if (di)xdb_diag_val_begin(di, s, cname, global);
2 7u83 1129
#endif
6 7u83 1130
	    return;
2 7u83 1131
	}
1132
 
1133
#ifdef asm_uses_lcomm
1134
	/* Common local value */
6 7u83 1135
	if (cname == -1) {
1136
	    op1 = make_extern_data(s, 0);
2 7u83 1137
	} else {
6 7u83 1138
	    op1 = make_lab_data(cname, 0);
2 7u83 1139
	}
6 7u83 1140
	op2 = make_int_data(sz / 8);
1141
	make_instr(m_as_local, op1, op2, 0);
2 7u83 1142
#if have_diagnostics
6 7u83 1143
	if (di)xdb_diag_val_begin(di, s, cname, global);
2 7u83 1144
#endif
1145
#else
1146
	/* Common local value */
6 7u83 1147
	area(pbss);
1148
	if (cname == -1) {
1149
	     make_external_label(s);
2 7u83 1150
	} else {
6 7u83 1151
	     make_label(cname);
2 7u83 1152
	}
1153
#if have_diagnostics
6 7u83 1154
	if (di)xdb_diag_val_begin(di, s, cname, global);
2 7u83 1155
#endif
6 7u83 1156
	op1 = make_int_data(sz / 8);
1157
	make_instr(m_as_space, op1, null, 0);
2 7u83 1158
#endif
6 7u83 1159
	return;
2 7u83 1160
    }
1161
 
1162
    /* Data values */
6 7u83 1163
    if (global && cname == -1 && !is_local(s)) {
1164
	op1 = make_extern_data(s, 0);
1165
	make_instr(m_as_global, op1, null, 0);
2 7u83 1166
    }
1167
 
1168
#if have_diagnostics
6 7u83 1169
    if (di)xdb_diag_val_begin(di, s, cname, global);
2 7u83 1170
#endif
1171
 
6 7u83 1172
    if (al <= 32)al = 32;
2 7u83 1173
 
6 7u83 1174
    ext_eval_name = "statically declared object";
1175
    if (cname == -1) {
1176
	make_external_label(s);
1177
	if (!is_local(s))ext_eval_name = s;
2 7u83 1178
    } else {
6 7u83 1179
	make_label(cname);
2 7u83 1180
    }
6 7u83 1181
    evalaux(c,(bool)isconst, al);
1182
    eval_instr();
1183
    return;
2 7u83 1184
}
1185
 
1186