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
    		 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/scan2.c,v 1.1.1.1 1998/01/17 15:55:50 release Exp $
65
--------------------------------------------------------------------------
66
$Log: scan2.c,v $
67
 * Revision 1.1.1.1  1998/01/17  15:55:50  release
68
 * First version to be checked into rolling release.
69
 *
70
Revision 1.1.1.1  1997/10/13 12:42:57  ma
71
First version.
72
 
73
Revision 1.4  1997/09/25 06:45:31  ma
74
All general_proc tests passed
75
 
76
Revision 1.3  1997/06/24 10:56:09  ma
77
Added changes for "Plumhall Patch"
78
 
79
Revision 1.2  1997/04/20 11:30:38  ma
80
Introduced gcproc.c & general_proc.[ch].
81
Added cases for apply_general_proc next to apply_proc in all files.
82
 
83
Revision 1.1.1.1  1997/03/14 07:50:17  ma
84
Imported from DRA
85
 
86
 * Revision 1.1.1.1  1996/09/20  10:56:58  john
87
 *
88
 * Revision 1.3  1996/07/30  16:32:16  john
89
 * Added offset conversion
90
 *
91
 * Revision 1.2  1996/07/05  14:26:12  john
92
 * Changes for spec 3.1
93
 *
94
 * Revision 1.1.1.1  1996/03/26  15:45:17  john
95
 *
96
 * Revision 1.5  94/11/16  10:37:51  10:37:51  ra (Robert Andrews)
97
 * Added support for integer absolute.
98
 *
99
 * Revision 1.4  94/06/29  14:25:38  14:25:38  ra (Robert Andrews)
100
 * Added div0, rem0, max and min for TDF 3.0.
101
 *
102
 * Revision 1.3  94/02/21  16:03:43  16:03:43  ra (Robert Andrews)
103
 * The long argument to ap_argsc is better as an int.
104
 *
105
 * Revision 1.2  93/04/19  13:36:21  13:36:21  ra (Robert Andrews)
106
 * offset_pad_exp has disappeared in March93 spec.
107
 *
108
 * Revision 1.1  93/02/22  17:16:39  17:16:39  ra (Robert Andrews)
109
 * Initial revision
110
 *
111
--------------------------------------------------------------------------
112
*/
113
 
114
 
115
/*
116
    SCAN2
117
 
118
    Scans through the program and puts all the arguments of operations
119
    into a suitable 68000 operand form.
120
 
121
*/
122
 
123
 
124
#include "config.h"
125
#include "common_types.h"
126
#include "exp.h"
127
#include "expmacs.h"
128
#include "exptypes.h"
129
#include "shapemacs.h"
130
#include "tags.h"
131
#include "install_fns.h"
132
#ifndef tdf3
133
#include "68k_globals.h"
134
#include "special_exps.h"
135
#endif
136
 
6 7u83 137
void scan2(bool, exp, exp);
2 7u83 138
 
139
/*
140
    MACROS TO SET OR GET THE SON OR BRO
141
*/
142
 
6 7u83 143
#define assexp(I, P, V)	if (I) setson(P, V); else setbro(P, V)
144
#define contexp(I, P)	((I) ? son(P): bro(P))
2 7u83 145
 
146
 
147
/*
148
  Transform a non-bit offset into a bit offset.
149
  (borrowed from trans386)
150
*/
6 7u83 151
static void
152
make_bitfield_offset(exp e, exp pe, int spe, shape sha)
2 7u83 153
{
6 7u83 154
	exp omul;
155
	exp val8;
156
	if (name(e) == val_tag) {
157
		no(e)*= 8;
158
		return;
159
	}
160
	omul = getexp(sha, bro(e), (int)(last(e)), e, nilexp, 0, 0,
161
		      offset_mult_tag);
162
	val8 = getexp(slongsh, omul, 1, nilexp, nilexp, 0, 8, val_tag);
163
	clearlast(e);
164
	setbro(e, val8);
165
	if (spe) {
166
		son(pe) = omul;
167
	} else{
168
		bro(pe) = omul;
169
	}
170
	return;
2 7u83 171
}
172
 
173
 
174
/*
175
    INSERT AN IDENTITY DECLARATION
176
 
177
    This routine inserts an identity declaration of x at to and replaces
178
    x by a use of this identity.
179
*/
180
 
6 7u83 181
static void
182
cca(bool sto, exp to, bool sx, exp x)
2 7u83 183
{
6 7u83 184
	exp d, a, id, tg;
185
	d = contexp(sx, x);
2 7u83 186
#ifndef tdf3
6 7u83 187
	if (name(d)==caller_tag) {	/* position sensitive */
188
		cca(sto, to, 1, d);
189
		return;
190
	}
2 7u83 191
#endif
6 7u83 192
	d = contexp(sx, x);
193
	a = contexp(sto, to);
194
	id = getexp(sh(a), bro(a), last(a), d, nilexp, 0, L1, ident_tag);
195
	tg = getexp(sh(d), bro(d), last(d), id, nilexp, 0, L0, name_tag);
196
	pt(id) = tg;
197
	clearlast(d);
198
	if (d != a) {
199
		bro(d) = a;
200
		bro(a) = id;
201
		setlast(a);
202
		assexp(sto, to, id);
203
		assexp(sx, x, tg);
204
	} else {
205
		bro(d) = tg;
206
		bro(tg) = id;
207
		setlast(tg);
208
		clearlast(d);
209
		assexp(sto, to, id);
210
	}
211
	return;
2 7u83 212
}
213
 
214
 
215
/*
216
    INSERT AN IDENTITY DECLARATION IN A BRO-LIST
217
 
218
    Keeping the same to, cc scans along the bro list e, applying cca to
219
    introduce an identity declaration when doit is 1.  It keeps count as
220
    the index position along the list in order to pass it to doit.  If it
221
    uses cca it scans the resulting declaration, using the same to.  If it
222
    doesn't, it scans the list element, still using the same to.  This keeps
223
    all operations in the same order.
224
*/
225
 
6 7u83 226
static void
227
cc(bool sto, exp to, bool se, exp e, bool(*doit)(exp, int), int count)
2 7u83 228
{
6 7u83 229
	exp ec = contexp(se, e);
2 7u83 230
 
6 7u83 231
	if (last(ec)) {
232
		if (doit(ec, count)) {
233
			cca(sto, to, se, e);
234
			ec = contexp(sto, to);
235
			scan2(1, ec, son(ec));
236
		} else {
237
			scan2(sto, to, ec);
238
		}
239
	} else {
240
		cc(sto, to, 0, ec, doit, count + 1);
241
		ec = contexp(se, e);
242
		if (doit(ec, count)) {
243
			cca(sto, to, se, e);
244
			ec = contexp(sto, to);
245
			scan2(1, ec, son(ec));
246
		} else {
247
			scan2(sto, to, ec);
248
		}
249
	}
250
	return;
2 7u83 251
}
252
 
253
 
254
/*
255
    INSERT AN IDENTITY DECLARATION
256
 
257
    This routine is the same as cca, but forces the declaration into
258
    a register.
259
*/
260
 
6 7u83 261
static void
262
ccp(bool sto, exp to, bool sx, exp x)
2 7u83 263
{
6 7u83 264
	exp xc = contexp(sx, x);
265
	exp toc;
266
	if (name(xc)!= name_tag || !isusereg(son(xc))) {
267
		cca(sto, to, sx, x);
268
		toc = contexp(sto, to);
269
		setusereg(toc);
270
		scan2(1, toc, son(toc));
271
	}
272
	return;
2 7u83 273
}
274
 
275
 
276
/*
277
    IS THE EXP e AN OPERAND?
278
*/
279
 
6 7u83 280
static bool
281
is_opnd(exp e)
2 7u83 282
{
6 7u83 283
	switch (name(e)) {
284
	case name_tag: {
285
		exp s = son(e);
286
		return (!isvar(s) && (son(son(e)) != nilexp) &&
287
			!isparam(son(son(e))));
2 7u83 288
	}
289
 
6 7u83 290
	case val_tag:
291
	case real_tag:
292
	case env_size_tag:
293
	case general_proc_tag:
294
	case proc_tag:
295
	case cont_tag:
296
	case string_tag:
297
	case null_tag:
298
		return (1);
2 7u83 299
	}
6 7u83 300
	return (0);
2 7u83 301
}
302
 
303
 
304
/*
305
    CHECK THE POINTER ARGUMENT OF AN ADDPTR
306
*/
307
 
6 7u83 308
static void
309
ap_arg1(bool sto, exp to, bool sa, exp a, bool b)
2 7u83 310
{
6 7u83 311
	exp ac = contexp(sa, a);
2 7u83 312
 
6 7u83 313
	if (!b && name(ac) == cont_tag && name(son(ac)) == name_tag &&
314
	    isvar(son(son(ac)))) {
315
		return;
316
	}
2 7u83 317
 
6 7u83 318
	if (!b && name(ac) == name_tag) {
319
		return;
320
	}
2 7u83 321
 
6 7u83 322
	/* The pointer has to go into a register */
323
	ccp(sto, to, sa, a);
324
	return;
2 7u83 325
}
326
 
327
 
328
/*
329
    CHECK THE INTEGER ARGUMENT OF AN ADDPTR
330
*/
331
 
6 7u83 332
static void
333
ap_argsc(bool sto, exp to, bool se, exp e, int sz, bool b)
2 7u83 334
{
6 7u83 335
	exp ec = contexp(se, e);
336
	exp p = son(ec);
337
	exp a = bro(p);
338
	exp temp;
2 7u83 339
 
6 7u83 340
	/* Check for multiplication by constant scale factor */
341
	if (name(a) == offset_mult_tag && name(bro(son(a))) == val_tag) {
342
		long k = no(bro(son(a)));
343
		if ((k == 8 || k == 16 || k == 32 || k == 64) && k == sz) {
344
			ccp(sto, to, 1, a);
345
			ap_arg1(sto, to, 1, ec, b);
346
			return;
347
		}
2 7u83 348
 
349
	}
350
 
6 7u83 351
	if (sz == 8) {
352
		ccp(sto, to, 0, son(ec));
353
		ap_arg1(sto, to, 1, ec, b);
354
		return;
355
	}
2 7u83 356
 
6 7u83 357
	if (b) {
358
		ccp(sto, to, se, e);
359
		return;
360
	}
2 7u83 361
 
6 7u83 362
	cca(sto, to, se, e);
363
	temp = contexp(sto, to);
364
	scan2(1, temp, son(temp));
365
	return;
2 7u83 366
}
367
 
368
 
369
/*
370
    CHECK THE ARGUMENT OF A CONT OR THE DESTINATION OF AN ASSIGN
371
*/
372
 
6 7u83 373
static void
374
cont_arg(bool sto, exp to, exp e, shape sa)
2 7u83 375
{
6 7u83 376
	unsigned char n = name(son(e));
377
	if (n == name_tag) {
378
		return;
379
	}
2 7u83 380
 
6 7u83 381
	if (n == cont_tag) {
382
		exp s = son(son(e));
383
		if (name(s) == name_tag &&
384
		    (isvar(son(s)) || isglob(son(s)) || isusereg(son(s)))) {
385
			return;
386
		}
2 7u83 387
 
6 7u83 388
		if (name(s) == reff_tag && name(son(s)) == name_tag &&
389
		    (isvar(son(son(s))) || isglob(son(son(s))) ||
390
		     isusereg(son(son(s))))) {
391
			return;
392
		}
2 7u83 393
 
6 7u83 394
		ccp(sto, to, 1, e);
395
		return;
396
	}
2 7u83 397
 
6 7u83 398
	if (n == reff_tag) {
399
		exp s = son(e);
400
		if (name(son(s)) == name_tag && isusereg(son(son(s)))) {
401
			return;
402
		}
2 7u83 403
 
6 7u83 404
		if (name(son(s)) == addptr_tag) {
405
			ap_argsc(sto, to, 1, s, shape_size(sa), 1);
406
			return;
407
		}
408
 
409
		ccp(sto, to, 1, s);
410
		return;
2 7u83 411
	}
412
 
6 7u83 413
	if (n == addptr_tag) {
414
		ap_argsc(sto, to, 1, e, shape_size(sa), 0);
415
		return;
416
	}
2 7u83 417
 
6 7u83 418
	ccp(sto, to, 1, e);
419
	return;
2 7u83 420
}
421
 
422
 
423
/*
424
    DOIT ROUTINE, IS t NOT AN OPERAND?
425
*/
426
 
6 7u83 427
static bool
428
notopnd(exp t, int i)
2 7u83 429
{
6 7u83 430
	return (i >= 0 && !is_opnd(t));
2 7u83 431
}
432
 
433
#ifndef tdf3
6 7u83 434
static int scan_for_alloca(exp);
2 7u83 435
 
6 7u83 436
static int
437
scan_alloc_args(exp s)
2 7u83 438
{
6 7u83 439
	if (scan_for_alloca(s)) {
440
		return 1;
441
	}
442
	if (last(s)) {
443
		return 0;
444
	}
445
	return scan_alloc_args(bro(s));
2 7u83 446
}
447
 
6 7u83 448
static int
449
scan_for_alloca(exp t)
2 7u83 450
{
6 7u83 451
	switch (name(t)) {
452
	case local_free_all_tag:
453
	case local_free_tag:
454
	case last_local_tag:
455
	case alloca_tag:
456
	case make_lv_tag:
457
		return 1;
458
	case case_tag:
459
		return scan_for_alloca(son(t));
460
	case labst_tag:
461
		return scan_for_alloca(bro(son(t)));
462
	case env_offset_tag:
463
	case string_tag:
464
	case name_tag:
465
		return 0;
466
	case apply_general_tag:
467
		if call_is_untidy(t) {
468
			return 1;
469
		}
470
		return scan_alloc_args(son(t));
471
	default:
472
		if (son(t) == nilexp) {
473
			return 0;
474
		}
475
		return scan_alloc_args(son(t));
476
	}
2 7u83 477
}
478
 
6 7u83 479
static bool
480
no_alloca(exp t, int i)
2 7u83 481
{
6 7u83 482
	UNUSED(i);
483
	return (scan_for_alloca(t));
2 7u83 484
}
485
 
486
#endif
487
 
488
/*
489
    APPLY cc, DOING IT WITH OPERANDS
490
*/
491
 
6 7u83 492
static void
493
all_opnd(bool sto, exp to, exp e)
2 7u83 494
{
495
#if 0
6 7u83 496
	if (!last(bro(son(e)))) {
2 7u83 497
 
6 7u83 498
		/* Operation has more than two parameters.  Make it diadic */
499
		exp opn = getexp(sh(e), e, 0, bro(son(e)), nilexp, 0, 0,
500
				 name(e));
501
		exp nd = getexp(sh(e), bro(e), last(e), opn, nilexp, 0, 1,
502
				ident_tag);
503
		exp id = getexp(sh(e), e, 1, nd, nilexp, 0, 0, name_tag);
504
		pt(nd) = id;
505
		bro(son(e)) = id;
506
		setlast(e);
507
		bro(e) = nd;
508
		while (!last(bro(son(e)))) {
509
			bro(son(e)) = bro(bro(son(e)));
510
		}
511
		bro(bro(son(e))) = opn;
512
		e = nd;
513
		scan2(sto, e, e);
514
	}
2 7u83 515
#endif
6 7u83 516
	cc(sto, to, 1, e, notopnd, 1);
517
	return;
2 7u83 518
}
519
 
520
 
521
/*
522
    IS e ASSIGNABLE?
523
*/
524
 
6 7u83 525
static bool
526
is_assable(exp e)
2 7u83 527
{
6 7u83 528
	long sz;
529
	unsigned char n = name(e);
530
	if (is_a(n)) {
531
		return (1);
532
	}
533
	if (n != apply_tag && n != apply_general_tag) {
534
		return (0);
535
	}
536
	n = name(sh(e));
537
	sz = shape_size(sh(e));
538
	return (n <= ulonghd || (n == ptrhd && sz == 32));
2 7u83 539
}
540
 
541
 
542
/*
543
    DOIT ROUTINE, IS t NOT ASSIGNABLE?
544
*/
545
 
6 7u83 546
static bool
547
notass(exp t, int i)
2 7u83 548
{
6 7u83 549
	return (i >= 0 && !is_assable(t));
2 7u83 550
}
551
 
552
 
553
/*
554
    APPLY cc, DOING IT WITH ASSIGNABLES
555
*/
556
 
6 7u83 557
static void
558
all_assable(bool sto, exp to, exp e)
2 7u83 559
{
6 7u83 560
	cc(sto, to, 1, e, notass, 1);
561
	return;
2 7u83 562
}
563
 
564
 
565
/*
566
    IS e DIRECTLY ADDRESSABLE?
567
*/
568
 
6 7u83 569
static bool
570
is_direct(exp e)
2 7u83 571
{
6 7u83 572
    unsigned char s = name(e);
573
    return ((s == name_tag && !isglob(son(e)) && !isvar(son(e))) ||
574
	    (s == cont_tag && name(son(e)) == name_tag &&
575
	     !isglob(son(son(e))) && isvar(son(son(e)))));
2 7u83 576
}
577
 
578
 
579
/*
580
    IS e INDIRECTLY ADDRESSABLE?
581
*/
582
 
6 7u83 583
static bool
584
is_indable(exp e)
2 7u83 585
{
6 7u83 586
	unsigned char s = name(e);
587
	if (s == name_tag) {
588
		return (1);
589
	}
2 7u83 590
 
6 7u83 591
	if (s == cont_tag) {
592
		unsigned char t = name(son(e));
593
		return ((t == name_tag && isvar(son(son(e)))) ||
594
			(t == cont_tag && name(son(son(e))) == name_tag &&
595
			 isvar(son(son(son(e))))) ||
596
			(t == reff_tag && is_direct(son(son(e)))));
597
	}
2 7u83 598
 
6 7u83 599
	return ((s == reff_tag && is_direct(son(e))) || s == addptr_tag);
2 7u83 600
}
601
 
602
#ifndef tdf3
603
/*
604
    MAKES son ( e ) INDIRECTLY ADDRESSABLE
605
*/
6 7u83 606
static void
607
indable_son(bool sto, exp to, exp e)
2 7u83 608
{
6 7u83 609
	if (!is_indable(son(e))) {
610
		exp ec;
611
		cca(sto, to, 1, e);
612
		ec = contexp(sto, to);
613
		scan2(1, ec, son(ec));
614
	} else {
615
		scan2(sto, to, son(e));
616
	}
617
	return;
2 7u83 618
}
619
 
620
#endif
621
 
622
/*
623
    APPLY scan2 TO A BRO LIST
624
*/
625
 
6 7u83 626
static void
627
scanargs(bool st, exp e)
2 7u83 628
{
6 7u83 629
	exp t = e;
630
	exp temp;
2 7u83 631
 
6 7u83 632
	while (temp = contexp(st, t), scan2(st, t, temp),
633
	       temp = contexp(st, t), !last(temp)) {
634
		t = contexp(st, t);
635
		st = 0;
636
	}
637
	return;
2 7u83 638
}
639
 
640
 
641
/*
642
    DOIT ROUTINE FOR APPLY
643
*/
644
 
645
#if 0
6 7u83 646
static bool
647
apdo(exp t, int i)
2 7u83 648
{
6 7u83 649
	/* The first argument needs special treatment */
650
	if (i == 1) {
651
		return (!is_indable(t));
652
	}
653
	return (0);
2 7u83 654
}
655
#endif
656
 
657
 
658
/*
659
    DOIT ROUTINE FOR PLUS
660
*/
661
 
6 7u83 662
static bool
663
plusdo(exp t, int i)
2 7u83 664
{
6 7u83 665
	/* Can't negate first argument */
666
	if (i == 1) {
667
		return (!is_opnd(t));
668
	}
669
	/* But can negate the rest */
670
	if (name(t) == neg_tag) {
671
		return (0);
672
	}
673
	return (!is_opnd(t));
2 7u83 674
}
675
 
676
 
677
/*
678
    DOIT ROUTINE FOR MULT
679
*/
680
 
6 7u83 681
static bool
682
multdo(exp t, int i)
2 7u83 683
{
6 7u83 684
	return (i >= 0 && !is_o(name(t)));
2 7u83 685
}
686
 
687
 
688
/*
689
    DOIT ROUTINE FOR AND
690
*/
691
 
6 7u83 692
static bool
693
anddo(exp t, int i)
2 7u83 694
{
695
#if 0
6 7u83 696
	/* Can't negate first argument */
697
	if (i == 1) {
698
		return (!is_o(name(t)));
699
	}
700
	/* But can negate the rest */
701
	if (name(t) == not_tag) {
702
		return (0);
703
	}
2 7u83 704
#endif
6 7u83 705
	return (!is_o(name(t)));
2 7u83 706
}
707
 
708
 
709
/*
710
    DOIT ROUTINE FOR XOR
711
*/
712
 
6 7u83 713
static bool
714
notado(exp t, int i)
2 7u83 715
{
6 7u83 716
	return (i >= 0 && !is_o(name(t)));
2 7u83 717
}
718
 
719
 
720
/*
721
    MAIN SCAN ROUTINE
722
*/
723
 
6 7u83 724
void
725
scan2(bool sto, exp to, exp e)
2 7u83 726
{
6 7u83 727
	switch (name(e)) {
728
	case cond_tag:
729
	case rep_tag:
730
	case compound_tag:
2 7u83 731
#ifdef rscope_tag
6 7u83 732
	case rscope_tag:
2 7u83 733
#endif
6 7u83 734
	case solve_tag:
735
	case concatnof_tag:
736
	case nof_tag:
737
	case diagnose_tag:
2 7u83 738
#ifndef tdf3
6 7u83 739
	case caller_tag:
740
		if (son(e) == nilexp) {
741
			/* empty make_nof */
742
			return;
743
		}
744
		scanargs(1, e);
745
		return;
2 7u83 746
#else
6 7u83 747
		scanargs(1, e);
748
		return;
2 7u83 749
#endif
6 7u83 750
	case labst_tag:
751
		scan2(0, son(e), bro(son(e)));
752
		return;
753
	case ident_tag:
754
		scan2(0, son(e), bro(son(e)));
755
		scan2(1, e, son(e));
756
		return;
757
	case seq_tag:
758
		scanargs(1, son(e));
759
		scan2(0, son(e), bro(son(e)));
760
		return;
2 7u83 761
#if 0
6 7u83 762
	case diag_tag:
763
	case cscope_tag:
764
	case fscope_tag:
765
		scanargs(1, e);
766
		return;
767
#endif
768
	case local_free_tag:
769
	case long_jump_tag:
770
	case ncopies_tag:
771
		all_assable(sto, to, e);
772
		return;
773
	case alloca_tag:
774
		all_opnd(sto, to, e);
775
		return;
776
#ifndef tdf3
777
	case set_stack_limit_tag: {
778
		exp lim = get_stack_limit();
779
		setbro(lim, son(e));
780
		setson(e, lim);
781
		setname(e, ass_tag);
782
		scan2(sto, to, e);
783
		return;
2 7u83 784
	}
785
#endif
6 7u83 786
	case offset_add_tag:
787
	case offset_subtract_tag:
788
		if ((al2(sh(son(e))) == 1) && (al2(sh(bro(son(e)))) != 1)) {
789
			make_bitfield_offset(bro(son(e)), son(e), 0, sh(e));
790
		}
791
		if ((al2(sh(son(e))) != 1) && (al2(sh(bro(son(e)))) == 1)) {
792
			make_bitfield_offset(son(e), e, 1, sh(e));
793
		}
794
	case test_tag:
795
	case absbool_tag:
796
	case testbit_tag:
797
	case make_stack_limit_tag:
798
	case minus_tag:
799
	case subptr_tag:
800
	case div0_tag:
801
	case div1_tag:
802
	case div2_tag:
803
	case shl_tag:
804
	case shr_tag:
805
	case rem0_tag:
806
	case mod_tag:
807
	case rem2_tag:
808
	case round_tag:
809
	case max_tag:
810
	case offset_max_tag:
811
	case min_tag:
812
	case offset_div_by_int_tag:
813
	case offset_negate_tag:
814
	case offset_pad_tag:
815
	case minptr_tag:
816
	case fplus_tag:
817
	case fminus_tag:
818
	case fmult_tag:
819
	case fdiv_tag:
820
	case fneg_tag:
821
	case fabs_tag:
822
	case chfl_tag:
823
	case float_tag:
824
	case offset_mult_tag:
825
	case offset_div_tag:
826
	case movecont_tag:
827
		all_opnd(sto, to, e);
828
		return;
829
	case not_tag:
830
	case neg_tag:
831
	case abs_tag:
832
	case chvar_tag:
833
		all_opnd(sto, to, e);
834
		return;
835
	case bitf_to_int_tag:
836
	case int_to_bitf_tag:
837
		all_opnd(sto, to, e);
838
		return;
839
	case ass_tag:
840
	case assvol_tag: {
841
		exp toc;
842
		/* Change assvol into ass */
843
		if (name(e) == assvol_tag) {
844
			setname(e, ass_tag);
845
		}
846
		if (!is_assable(bro(son(e)))) {
847
			cca(sto, to, 0, son(e));
848
			toc = contexp(sto, to);
849
			scan2(1, toc, son(toc));
850
		} else {
851
			scan2(sto, to, bro(son(e)));
852
		}
853
		cont_arg(sto, to, e, sh(bro(son(e))));
854
		return;
2 7u83 855
	}
856
#ifndef tdf3
6 7u83 857
	case tail_call_tag: {
858
		exp cees = bro(son(e));
859
		cur_proc_has_tail_call = 1;
860
		cur_proc_use_same_callees = (name(cees) == same_callees_tag);
2 7u83 861
 
6 7u83 862
		if (son(cees) != nilexp) {
863
			cc(sto, to, 1, cees, no_alloca, 1);
864
		}
2 7u83 865
 
6 7u83 866
		indable_son(sto, to, e);
2 7u83 867
 
6 7u83 868
		return;
2 7u83 869
	}
6 7u83 870
	case apply_general_tag: {
871
		exp cees = bro(bro(son(e)));
872
		exp p_post = cees;	/* bro(p_post) is postlude */
2 7u83 873
 
6 7u83 874
		cur_proc_use_same_callees = (name(cees) == same_callees_tag);
2 7u83 875
 
6 7u83 876
		while (name(bro(p_post)) == ident_tag &&
877
		       name(son(bro(p_post))) == caller_name_tag) {
878
			p_post = son(bro(p_post));
879
		}
880
		scan2(0, p_post, bro(p_post));
881
		if (son(cees) != nilexp) {
882
			scanargs(1, cees);
883
		}
884
		if (no(bro(son(e))) != 0) {
885
			scanargs(1, bro(son(e)));
886
		}
2 7u83 887
 
6 7u83 888
		if (!is_indable(son(e))) {
889
			exp ec;
890
			cca(sto, to, 1, e);
891
			ec = contexp(sto, to);
892
			scan2(1, ec, son(ec));
893
		} else {
894
			scan2(sto, to, son(e));
895
		}
896
		return;
897
	}
2 7u83 898
#endif
6 7u83 899
	case apply_tag:
900
		scanargs(1, e);
901
		/* Fall through */
902
	case goto_lv_tag:
903
		if (!is_indable(son(e))) {
904
			exp ec;
905
			cca(sto, to, 1, e);
906
			ec = contexp(sto, to);
907
			scan2(1, ec, son(ec));
908
		} else {
909
			scan2(sto, to, son(e));
910
		}
911
		return;
2 7u83 912
#ifndef tdf3
6 7u83 913
	case untidy_return_tag:
2 7u83 914
#endif
6 7u83 915
	case res_tag: {
916
		long sz;
2 7u83 917
 
6 7u83 918
		if (name(son(e)) == apply_tag ||
919
		    name(son(e)) == apply_general_tag)
920
		{
921
			scan2(sto, to, son(e));
922
			return;
923
		}
2 7u83 924
 
6 7u83 925
		sz = shape_size(sh(son(e)));
2 7u83 926
 
6 7u83 927
		if (sz <= 64) {
928
			all_assable(sto, to, e);
929
			return;
930
		}
931
		all_opnd(sto, to, e);
932
		return;
2 7u83 933
	}
6 7u83 934
	case case_tag: {
935
		exp toc;
936
		if (!is_opnd(son(e))) {
937
			cca(sto, to, 1, e);
938
			toc = contexp(sto, to);
939
			scan2(1, toc, son(toc));
940
		} else {
941
			scan2(sto, to, son(e));
942
		}
943
		return;
2 7u83 944
	}
6 7u83 945
	case plus_tag:
946
		if (name(son(e)) == neg_tag &&
947
		    name(bro(son(e))) == val_tag) {
948
			scan2(sto, to, son(e));
949
			return;
950
		}
951
		cc(sto, to, 1, e, plusdo, 1);
952
		return;
953
	case addptr_tag: {
954
		exp a = bro(son(e));
2 7u83 955
 
6 7u83 956
		if (name(a) == offset_mult_tag &&
957
		    name(bro(son(a))) == val_tag) {
958
			long k = no(bro(son(a))) / 8;
959
			if (k == 1 || k == 2 || k == 4 || k == 8) {
960
				ccp(sto, to, 1, a);
961
				ap_arg1(sto, to, 1, e, 0);
962
				return;
963
			}
2 7u83 964
		}
965
 
6 7u83 966
		ccp(sto, to, 0, son(e));
967
		ap_arg1(sto, to, 1, e, 0);
968
		return;
2 7u83 969
	}
6 7u83 970
	case mult_tag:
971
		cc(sto, to, 1, e, multdo, 1);
972
		return;
973
	case and_tag:
974
		cc(sto, to, 1, e, anddo, 1);
975
		return;
976
	case or_tag:
977
	case xor_tag:
978
		cc(sto, to, 1, e, notado, 1);
979
		return;
980
	case cont_tag:
981
	case contvol_tag:
982
		/* Change contvol into cont */
983
		if (name(e) == contvol_tag) {
984
			setname(e, cont_tag);
985
		}
986
		cont_arg(sto, to, e, sh(e));
987
		return;
988
	case field_tag:
989
		if (!is_o(name(son(e))) || name(e) == cont_tag) {
990
			exp temp;
991
			cca(sto, to, 1, e);
992
			temp = contexp(sto, to);
993
			scan2(1, temp, son(temp));
994
		} else {
995
			scan2(sto, to, son(e));
996
		}
997
		return;
998
	case reff_tag: {
999
		exp s = son(e);
1000
		if (name(s) == name_tag || (name(s) == cont_tag &&
1001
		     name(son(s)) == name_tag)) {
1002
			return;
1003
		}
1004
		ccp(sto, to, 1, e);
1005
		return;
2 7u83 1006
	}
1007
	case general_proc_tag:
6 7u83 1008
	case proc_tag:
1009
		scan2(1, e, son(e));
1010
		return;
2 7u83 1011
#if 0
6 7u83 1012
	case val_tag:
1013
		if (name(sh(e)) == offsethd && al2(sh(e)) >= 8) {
1014
			no(e) = no(e) >> 3;
1015
		}
1016
		return;
1017
#endif
1018
	default:
1019
		return;
2 7u83 1020
	}
1021
}