Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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