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
/*
2
    		 Crown Copyright (c) 1997
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
 
31
/*
32
			    VERSION INFORMATION
33
			    ===================
34
 
35
--------------------------------------------------------------------------
36
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/needscan.c,v 1.3 1998/03/11 11:03:57 pwe Exp $
37
--------------------------------------------------------------------------
38
$Log: needscan.c,v $
39
 * Revision 1.3  1998/03/11  11:03:57  pwe
40
 * DWARF optimisation info
41
 *
42
 * Revision 1.2  1998/02/11  16:56:43  pwe
43
 * corrections
44
 *
45
 * Revision 1.1.1.1  1998/01/17  15:55:55  release
46
 * First version to be checked into rolling release.
47
 *
48
 * Revision 1.41  1997/12/04  19:54:21  pwe
49
 * ANDF-DE V1.9
50
 *
51
 * Revision 1.40  1997/11/06  09:29:06  pwe
52
 * ANDF-DE V1.8
53
 *
54
 * Revision 1.39  1997/10/23  09:33:06  pwe
55
 * prep extra_diags
56
 *
57
 * Revision 1.38  1997/10/10  18:32:44  pwe
58
 * prep ANDF-DE revision
59
 *
60
 * Revision 1.37  1997/08/23  13:54:19  pwe
61
 * initial ANDF-DE
62
 *
63
 * Revision 1.36  1997/05/05  07:51:17  pwe
64
 * correct offset_mult (val * val)
65
 *
66
 * Revision 1.35  1997/03/26  13:04:36  pwe
67
 * general proc compatibility
68
 *
69
 * Revision 1.34  1997/02/18  11:48:08  pwe
70
 * NEWDIAGS for debugging optimised code
71
 *
72
 * Revision 1.33  1996/11/04  12:55:14  pwe
73
 * protect callee regs from caller call
74
 *
75
 * Revision 1.32  1996/10/03  08:51:16  pwe
76
 * PIC global/large offset, and PIC case guardregs
77
 *
78
 * Revision 1.31  1996/09/18  12:03:52  pwe
79
 * fixed PIC_code
80
 *
81
 * Revision 1.30  1996/09/10  16:24:26  pwe
82
 * patch to prevent ass spin on tight loop
83
 *
84
 * Revision 1.29  1996/09/09  12:32:43  pwe
85
 * protect result during postlude
86
 *
87
 * Revision 1.28  1996/09/06  16:50:18  pwe
88
 * fix outpar doubles for postlude
89
 *
90
 * Revision 1.27  1996/09/04  15:47:51  pwe
91
 * name change to avoid cc confusion
92
 *
93
 * Revision 1.26  1996/08/30  17:00:17  pwe
94
 * ensure space available for struct return
95
 *
96
 * Revision 1.25  1996/08/28  11:47:45  pwe
97
 * correct postlude with calls
98
 *
99
 * Revision 1.24  1996/06/19  15:38:26  john
100
 * Changed env_offset
101
 *
102
 * Revision 1.23  1996/06/17  16:12:08  john
103
 * Fix to offset_mult optimisation
104
 *
105
 * Revision 1.22  1996/02/29  17:39:38  john
106
 * Fix to shift op
107
 *
108
 * Revision 1.21  1995/12/15  10:25:51  john
109
 * Changed current_env
110
 *
111
 * Revision 1.20  1995/11/23  12:47:32  john
112
 * Fix for general procs
113
 *
114
 * Revision 1.19  1995/11/17  16:21:03  john
115
 * Fix to general proc call
116
 *
117
 * Revision 1.18  1995/11/10  10:11:42  john
118
 * Fixed scan of prof_tag
119
 *
120
 * Revision 1.17  1995/11/09  17:24:51  john
121
 * the result of inlining a function is no longer stored in
122
 * a t reg.
123
 *
124
 * Revision 1.16  1995/11/07  09:41:34  john
125
 * Changed parameter passing for general procs
126
 *
127
 * Revision 1.15  1995/10/31  12:47:26  john
128
 * Change to needs for dynamic callees
129
 *
130
 * Revision 1.14  1995/10/27  10:50:49  john
131
 * Fix to general procs
132
 *
133
 * Revision 1.13  1995/09/25  16:35:06  john
134
 * Fix for outpar
135
 *
136
 * Revision 1.12  1995/09/19  14:32:01  john
137
 * Added trap_tag
138
 *
139
 * Revision 1.11  1995/09/13  16:36:59  john
140
 * Added special_tag to scan
141
 *
142
 * Revision 1.10  1995/08/31  15:57:14  john
143
 * Fixed diagnostic bug & added fmax_tag
144
 *
145
 * Revision 1.9  1995/08/22  15:28:54  john
146
 * Change to compound_tag
147
 *
148
 * Revision 1.8  1995/08/04  15:46:12  john
149
 * Fix to maxneeds
150
 *
151
 * Revision 1.7  1995/07/17  16:44:16  john
152
 * New case
153
 *
154
 * Revision 1.6  1995/07/14  16:32:43  john
155
 * Various changes for new spec
156
 *
157
 * Revision 1.5  1995/06/21  14:29:21  john
158
 * Reformatting
159
 *
160
 * Revision 1.4  1995/06/14  15:35:11  john
161
 * Added support for give_stack_limit and set_stack_limit constructs.
162
 *
163
 * Revision 1.3  1995/05/26  12:59:59  john
164
 * Changes for new spec
165
 *
166
 * Revision 1.2  1995/04/20  08:06:12  john
167
 * Changed function definition
168
 *
169
 * Revision 1.1.1.1  1995/03/13  10:19:03  john
170
 * Entered into CVS
171
 *
172
 * Revision 1.12  1995/01/23  08:51:03  john
173
 * Modified case for allocating ident to t-reg.
174
 *
175
 * Revision 1.11  1994/12/21  12:09:38  djch
176
 * Added max_tag and min_tag, corrected offset_max_tag
177
 *
178
 * Revision 1.10  1994/12/20  14:46:25  djch
179
 * fixes to get the new cond scanning code working.
180
 *
181
 * Revision 1.9  1994/12/05  11:28:42  djch
182
 * To fix CR94_013:DR116.plum_err, added scan_cond from Ian's MIPS.
183
 *
184
 * Revision 1.8  1994/12/01  13:12:04  djch
185
 * Force envoffset'd idents to the stack.
186
 * Consider returning bottom as returning void.
187
 * Scan movecont with simplified version of apply_tag (for now)
188
 * Added goto_lv_tag and abs_tag
189
 *
190
 * Revision 1.7  1994/07/06  13:49:25  djch
191
 * After scan *e may not be the exp it was before, so use *(ptr_position(ste))
192
 * instead of *e.
193
 *
194
 * Revision 1.6  1994/06/22  09:53:21  djch
195
 * added div0 and rem0
196
 *
197
 * Revision 1.5  1994/05/24  08:10:23  djch
198
 * Moved addptr to call likediv, since it is not commutative..
199
 *
200
 * Revision 1.4  1994/05/19  08:20:43  djch
201
 * fixed chase not to distribute into exp with shape bottom (avoid field(goto))
202
 *
203
 * Revision 1.3  1994/05/13  13:05:10  djch
204
 * Incorporates improvements from expt version
205
 * moved declaratiosn inside long_double code.
206
 * removed two wrong parts of test to optimise test_tags
207
 * added decrements to keep ways there accurate
208
 * removed swap for val on lhs, added optimization for x &2^n ==0 -> x<<k is -ve
209
 * one fix from mips in neg_tag moving
210
 *
211
 * Revision 1.2  1994/05/03  15:08:59  djch
212
 * ifdefed out rscope_tag
213
 *
214
 * Revision 1.9  93/11/19  16:30:46  16:30:46  ra (Robert Andrews)
215
 * Declare long_to_al.
216
 * 
217
 * Revision 1.8  93/09/27  14:51:19  14:51:19  ra (Robert Andrews)
218
 * A number of changes to allow for long doubles.
219
 * 
220
 * Revision 1.7  93/08/27  11:34:07  11:34:07  ra (Robert Andrews)
221
 * A number of lint-like changes.  Use of pset and pnset to set properties.
222
 * 
223
 * Revision 1.6  93/08/18  11:16:20  11:16:20  ra (Robert Andrews)
224
 * Reformatted.
225
 * 
226
 * Revision 1.5  93/08/13  14:42:02  14:42:02  ra (Robert Andrews)
227
 * Removed a couple of comments.  Fixed maxtup to deal with the case when
228
 * the compound initialiser does not consist entirely of constants (doesn't
229
 * arise from C).
230
 * 
231
 * Revision 1.4  93/07/12  15:17:15  15:17:15  ra (Robert Andrews)
232
 * Some of the needs cases were nonsense.  offset_mult is like mult, not div.
233
 * offset_add etc should use likediv, not divneeds.
234
 * 
235
 * Revision 1.3  93/07/05  18:22:38  18:22:38  ra (Robert Andrews)
236
 * The test for return top was wrong - it should be checking the shape,
237
 * not looking for a return ( make_top ).
238
 * 
239
 * Revision 1.2  93/06/29  14:29:05  14:29:05  ra (Robert Andrews)
240
 * The ( x / fp_const ) -> ( 1.0 / fp_const ) * x optimisation only applies
241
 * if FBASE is 10.
242
 * 
243
 * Revision 1.1  93/06/24  14:58:54  14:58:54  ra (Robert Andrews)
244
 * Initial revision
245
 * 
246
--------------------------------------------------------------------------
247
*/
248
 
249
 
250
#define SPARCTRANS_CODE
251
/*
252
  The functions in this file define the scan through a program which
253
  reorganises it so that all arguments of operations are suitable for
254
  later code-production.  The procedure scan evaluates the register
255
  requirements of an exp.  The exps are produced from the decoding
256
  process and the various exp->exp transformations (common to other
257
  translators).
258
*/
259
#include "config.h"
260
#include "common_types.h"
261
#include "myassert.h"
262
#include "exptypes.h"
263
#include "exp.h"
264
#include "expmacs.h"
265
#include "tags.h"
266
#include "extra_tags.h"
267
#include "new_tags.h"
268
#include "check.h"
269
#include "proctypes.h"
270
#include "bitsmacs.h"
271
#include "maxminmacs.h"
272
#include "regable.h"
273
#include "tempdecs.h"
274
#include "shapemacs.h"
275
#include "special.h"
276
#include "const.h"
277
#include "flpt.h"
278
#include "install_fns.h"
279
#include "externs.h"
280
#include "regmacs.h"
281
#include "muldvrem.h"
282
#include "translat.h"
283
#include "comment.h"
284
#include "flags.h"
285
#include "me_fns.h"
286
#include "needscan.h"
287
#include "reg_defs.h"
288
#include "szs_als.h"
289
#include "makecode.h"
290
 
291
extern bool do_tlrecursion ;
292
extern prop notbranch[];
293
 
294
/*
295
  LOCAL VARIABLES
296
*/
297
 
298
 
299
static int stparam ;		/* Size of parameter list in bits */
300
static int fixparam ;		/* Next available place for param */
301
 
302
static int rscope_level = 0 ;
303
static bool nonevis = 1 ;
304
static bool specialext ;	/* for PIC_code, special globals require proc_uses_external */
305
static int callerfortr ;
306
 
307
int maxfix, maxfloat ;		/* The maximum numbers of t-regs */
308
static bool gen_call;   /* true if the scan is within a general proc */
309
static bool v_proc;     /* true if the scan is within a general proc with vcallees */
310
 
311
#ifdef GENCOMPAT
312
static bool trad_proc;	/* true if the scan is within a proc with no callees */
313
#endif
314
 
315
/*
316
  THE TYPE DESCRIBING REGISTER NEEDS
317
 
318
  The type needs is defined in proctypes.h.  This is a structure 
319
  which has two integers giving the number of fixed and floating 
320
  point registers required to contain live values in the expression 
321
  parameters.  A further field prop is used for various flags about 
322
  certain forms of exp (mainly idents and procs).  The maxargs 
323
  field gives the maximum size in bits for the parameters of all 
324
  the procs called in the exp.  The needs of a proc body are 
325
  preserved in the needs field of the procrec (see proctypes.h).
326
*/
327
 
328
 
329
/*
330
  FIND A POINTER TO EXPRESSION POINTING TO e
331
*/
332
 
333
exp *ptr_position 
334
    PROTO_N ( ( e ) )
335
    PROTO_T ( exp e ){
336
  exp *res ;
337
  exp dad = father ( e ) ;
338
  exp sib = son ( dad ) ;
339
  if ( sib == e ) {
340
    res = &son ( dad ) ;
341
  } 
342
  else {
343
    while ( bro ( sib ) != e ) {
344
      sib = bro ( sib ) ;
345
    }	
346
    res = &bro ( sib ) ;
347
  }
348
  return ( res ) ;
349
}
350
 
351
 
352
/*
353
  INSERT A NEW DECLARATION
354
  This procedure effectively inserts a new declaration into an exp.
355
  This is used to stop a procedure requiring more than the available
356
  number of registers.
357
*/
358
 
359
void cca 
360
    PROTO_N ( ( to, x ) )
361
    PROTO_T ( exp ** to X exp * x ){
362
 
363
#ifndef NEWDIAGS
364
  if (name((**to))==diagnose_tag){
365
    *to = &(son((**to)));  
366
  }
367
#endif
368
  if ( x == ( *to ) ) {
369
    /* replace by Let tg = def In tg Ni */
370
    exp def = *x ;
371
    exp id = getexp ( sh ( def ), bro ( def ), ( int ) last ( def ),
372
		      def, nilexp, 0, 1, ident_tag ) ;
373
    exp tg = getexp ( sh ( def ), id, 1, id, nilexp, 0, 0, name_tag ) ;
374
    /* use of tag */
375
    pt ( id ) = tg ;
376
    /* bro ( def ) is body of Let = tg */
377
    bro ( def ) = tg ;
378
    clearlast ( def ) ;
379
    /* replace pointer to x by Let */
380
    *x = id ;
381
#ifdef NEWDIAGS
382
    if (diagnose) {
383
      dgf(id) = dgf(bro(son(id)));
384
      dgf(bro(son(id))) = nildiag;
385
    }
386
#endif
387
    return ;
388
  } 
389
  else {
390
    /* replace by Let tg = def In ato/def = tg Ni */
391
    exp def = *x ;
392
    exp ato = *( *to ) ;
393
    exp id = getexp ( sh ( ato ), bro ( ato ), ( int ) last ( ato ),
394
		      def, nilexp, 0, 1, ident_tag ) ;
395
    exp tg = getexp ( sh ( def ), bro ( def ), ( int ) last ( def ),
396
		      id, nilexp, 0, 0, name_tag ) ;
397
    /* use of tg */
398
    pt ( id ) = tg ;
399
    /* ato is body of Let */
400
    bro ( def ) = ato ;
401
    clearlast ( def ) ;
402
    /* its father is Let */
403
    bro ( ato ) = id ;
404
    setlast ( ato ) ;
405
    /* replace pointer to 'to' by Let */
406
    *( *to ) = id ;
407
    /* replace use of x by tg */
408
    *x = tg ;
409
    /* later replacement to same 'to' will be at body of Let */
410
    *to = &bro ( def ) ;
411
#ifdef NEWDIAGS
412
    if (diagnose) {
413
      dgf(id) = dgf(bro(son(id)));
414
      dgf(bro(son(id))) = nildiag;
415
    }
416
#endif
417
  }
418
  return ;
419
}
420
 
421
 
422
/*
423
  BASIC REGISTER NEEDS
424
 
425
  This represent the requirements, one fixed point register, 
426
  two fixed point registers, one floating point register and 
427
  no registers respectively.
428
*/
429
 
430
needs onefix = { 1, 0, 0, 0 } ;
431
needs twofix = { 2, 0, 0, 0 } ;
432
needs onefloat = { 0, 1, 0, 0 } ;
433
needs zeroneeds = { 0, 0, 0, 0 } ;
434
 
435
 
436
#if 0
437
 
438
/*
439
  CHECK IF ANY USES OF id ARE AS AN INITIALISER FOR A DECLARATION
440
*/
441
 
442
bool subvar_use 
443
    PROTO_N ( ( uses ) )
444
    PROTO_T ( exp uses )
445
{
446
  for ( ; uses != nilexp ; uses = pt ( uses ) ) {
447
    if ( last ( uses ) && name ( bro ( uses ) ) == cont_tag ) {
448
      exp c = bro ( uses ) ;
449
      if ( !last ( c ) && last ( bro ( c ) ) &&
450
	   name ( bro ( bro ( c ) ) ) == ident_tag ) {
451
	exp id = bro ( bro ( c ) ) ;
452
	if ( ( props ( id ) & subvar ) != 0 &&
453
	     ( props ( id ) & inanyreg ) != 0 ) {
454
	  return ( 1 ) ;
455
	}
456
      }
457
    }
458
  }
459
  return ( 0 ) ;
460
}
461
 
462
#endif
463
 
464
 
465
/*
466
  WORK OUT REGISTER NEEDS FOR A GIVEN SHAPE
467
*/
468
 
469
needs shapeneeds 
470
    PROTO_N ( ( s ) )
471
    PROTO_T ( shape s ){
472
  if ( is_floating ( name ( s ) ) ) {
473
    return ( onefloat ) ;
474
  } 
475
  else {
476
    if ( valregable ( s ) ) {
477
      return ( onefix ) ;
478
    } 
479
    else {
480
      /* if the shape does not fit into a reg, needs two fixed
481
	 regs for moving */
482
      return ( twofix ) ;
483
    }
484
  }
485
  /* NOT REACHED */
486
}
487
 
488
 
489
/*
490
  Transform a non-bit offset into a bit offset.
491
  (borrowed from trans386)
492
*/
493
static void make_bitfield_offset 
494
    PROTO_N ( ( e, pe, spe, sha ) )
495
    PROTO_T ( exp e X exp pe X int spe X shape sha ){
496
  exp omul;
497
  exp val8;
498
  if (name(e) == val_tag){
499
    no(e) *= 8;
500
    return;
501
  }
502
  omul = getexp (sha, bro(e), (int)(last (e)), e, nilexp, 0, 0, offset_mult_tag);
503
  val8 = getexp (slongsh, omul, 1, nilexp, nilexp, 0, 8, val_tag);
504
  clearlast(e);
505
  setbro(e, val8);
506
  if(spe) {
507
    son(pe) = omul;
508
  }
509
  else{
510
    bro(pe) = omul;
511
  }
512
  return;
513
}
514
 
515
 
516
 
517
/*
518
  IS AN EXPRESSSION COMPLEX?
519
  An expression is complex if, basically, it cannot be accessed by a
520
  simple load or store instruction.
521
*/
522
 
523
bool complex 
524
    PROTO_N ( ( e ) )
525
    PROTO_T ( exp e ){
526
  if ( name ( e ) == name_tag ||
527
       ( name ( e ) == cont_tag && name ( son ( e ) ) == name_tag &&
528
	 isvar ( son ( son ( e ) ) ) ) ||
529
       name(e) == val_tag || name(e) == real_tag || name(e) == null_tag ) {
530
    return ( 0 ) ;
531
  } 
532
  else {
533
    return ( 1 ) ;
534
  }
535
  /* NOT REACHED */
536
}
537
 
538
int scan_cond 
539
    PROTO_N ( ( e, outer_id ) )
540
    PROTO_T ( exp* e X exp outer_id ){
541
 
542
  exp ste = *e;
543
  exp first = son (ste);
544
  exp labst = bro (first);
545
  exp second = bro (son (labst));
546
 
547
  assert(name(ste)==cond_tag);
548
 
549
  if (name(second)==top_tag && name(sh(first))==bothd && no(son(labst))==1
550
      && name(first)==seq_tag && name(bro(son(first))) == goto_tag){
551
    /* cond is { ... test(L); ? ; goto X | L:make_top}
552
       if ? empty can replace by seq { ... not-test(X); make_top }
553
       */
554
    exp l = son(son(first));
555
    while(!last(l)) { l = bro(l); }
556
    while(name(l)==seq_tag) { l = bro(son(l)); }
557
    if (name(l)==test_tag && pt(l)==labst) {
558
      settest_number(l, notbranch[(int)test_number(l)]);
559
      pt(l) = pt(bro(son(first)));
560
      bro(son(first)) = second;
561
      bro(second) = first; setlast(second);
562
      bro(first) = bro(ste); 
563
      if(last(ste)) { setlast(first);} else { clearlast(first); }
564
      *e = first;
565
      return 1;
566
    }
567
    else return 0;
568
  }
569
 
570
 
571
  if (name (first) == seq_tag && name (second) == cond_tag 
572
      && no(son(labst)) == 1 
573
      && name (son (son (first))) == test_tag 
574
      && pt (son (son (first))) == labst
575
      && name (son (second)) == seq_tag
576
      && name (son (son (son (second)))) == test_tag) {
577
				/* cond is ( seq (test to L;....| 
578
			       L:cond(seq(test;...),...) ) ..... */
579
    exp test1 = son (son (first));
580
    exp test2 = son (son (son (second)));
581
    exp op11 = son(test1);
582
    exp op21 = bro(op11);
583
    exp op12 = son(test2);
584
    exp op22 = bro(op12);
585
    bool c1 = complex (op11);
586
    bool c2 = complex (op21);
587
 
588
    if (c1 && eq_exp (op11, op12)) {
589
				/* ....if first operands of tests are
590
				   same, identify them */
591
      exp newid = getexp (sh (ste), bro (ste), last (ste), op11, nilexp,
592
			  0, 2, ident_tag);
593
      exp tg1 = getexp (sh (op11), op21, 0, newid, nilexp, 0, 0, name_tag);
594
      exp tg2 = getexp (sh (op12), op22, 0, newid, nilexp, 0, 0, name_tag);
595
 
596
      pt (newid) = tg1;
597
      pt (tg1) = tg2;	/* uses of newid */
598
      bro (op11) = ste; clearlast (op11);/* body of newid */
599
      /* forget son test2 = son test1 */
600
      bro (ste) = newid;
601
      setlast (ste);	/* father body = newid */
602
      son (test1) = tg1;
603
      son (test2) = tg2;	/* relace 1st operands of test */
604
      if (!complex(op21) ) { 
605
	/* if the second operand of 1st test is simple, then 
606
	   identification could go in a t-teg (!!!NB overloading 
607
	   of inlined flag!!!).... */
608
	setinlined(newid); 
609
      }
610
      kill_exp(op12, op12);
611
      * (e) = newid;
612
      if( scan_cond (&bro(son(labst)), newid) == 2 && complex(op22)) {
613
	/* ... however a further use of identification means that 
614
	   the second operand of the second test must also be simple */
615
	clearinlined(newid);
616
      }
617
      return 1;
618
    }
619
    else if (c2 && eq_exp (op21, op22)) {
620
	 /* ....if second operands of tests are same, identify them */
621
 
622
      exp newid = getexp (sh (ste), bro (ste), last (ste), op21,
623
			  nilexp, 0, 2, ident_tag);
624
      exp tg1 = getexp (sh (op21), test1, 1,
625
			newid, nilexp, 0, 0, name_tag);
626
      exp tg2 = getexp (sh (op22), test2, 1, newid, nilexp,
627
			0, 0, name_tag);
628
 
629
      pt (newid) = tg1;
630
      pt (tg1) = tg2;	/* uses of newid */
631
      bro (op21) = ste; clearlast (op21);
632
      /* body of newid */
633
      /* forget bro son test2 = bro son test1 */
634
      bro (ste) = newid;
635
      setlast (ste);	/* father body = newid */
636
      bro (op11) = tg1;
637
      bro (op12) = tg2;
638
      if (!complex(op11) ) { setinlined(newid); }
639
      kill_exp(op22, op22);
640
      /* relace 2nd operands of test */
641
      * (e) = newid;
642
      if (scan_cond (&bro(son(labst)), newid) == 2 && complex(op12) ) { 
643
	clearinlined(newid); 
644
      }
645
      return 1;
646
    }
647
    else if (name (op12) != name_tag
648
	     && name (op11) == name_tag 
649
	     && son (op11) == outer_id
650
	     && eq_exp (son (outer_id), op12)
651
	     ) {	/* 1st param of test1 is already identified with
652
			   1st param of  test2 */
653
      exp tg = getexp (sh (op12), op22, 0, outer_id,
654
		       pt (outer_id), 0, 0, name_tag);
655
      pt (outer_id) = tg;
656
      no (outer_id) += 1;
657
      if (complex(op21) ){ clearinlined(outer_id); }
658
      /* update usage of ident */
659
      son (test2) = tg;
660
      kill_exp(op12, op12);
661
      if (scan_cond (&bro(son(labst)), outer_id) == 2 && complex(op22)) {
662
	clearinlined(outer_id);
663
      }
664
      return 2;
665
    }
666
  }			
667
  return 0;
668
}
669
 
670
 
671
/*
672
  WORK OUT REGISTER NEEDS FOR PLUS-LIKE OPERATIONS
673
  The operation will be n-ary, commutative and associative.
674
*/
675
 
676
needs likeplus 
677
    PROTO_N ( ( e, at ) )
678
    PROTO_T ( exp * e X exp ** at ){
679
  needs a1 ;
680
  needs a2 ;
681
  prop pc ;
682
  exp *br = &son ( *e ) ;
683
  exp dad = *e ;
684
  exp prev ;
685
  bool commuted = 0 ;
686
 
687
  /* scan the first operand - won't be a val_tag */
688
  a1 = scan ( br, at ) ;
689
 
690
  /* likeplus exp with 1 operand should never occur */
691
  assert ( !( last ( *br ) ) ) ;
692
 
693
  do {
694
    exp *prevbr ;
695
    prevbr = br ;
696
    prev = *br ;
697
    br = &bro ( prev ) ;
698
    a2 = scan ( br, at ) ;
699
    /* scan the next operand ... */
700
    if ( name ( *br ) != val_tag ) {
701
      a1.floatneeds = MAX_OF ( a1.floatneeds, a2.floatneeds ) ;
702
      pc = ( prop ) ( a2.prps & hasproccall ) ;
703
      if ( a2.fixneeds < maxfix && pc == 0 ) {
704
	/*... its evaluation will not disturb the accumulated result */
705
	a1.fixneeds = MAX_OF ( a1.fixneeds, a2.fixneeds + 1 ) ;
706
	a1.prps = ( prop ) ( a1.prps | a2.prps ) ;
707
      } 
708
      else if ( a1.fixneeds < maxfix &&
709
		pntst ( a1, hasproccall ) == 0 &&
710
		!commuted ) {
711
	/* ...its evaluation will call a proc, so put it first */
712
	exp op1 = son ( dad ) ;
713
	exp cop = *br ;
714
	bool lcop = ( bool ) last ( cop ) ;
715
	bro ( prev ) = bro ( cop ) ;
716
	if ( lcop ) setlast ( prev ) ;
717
	bro ( cop ) = op1 ;
718
	clearlast ( cop ) ;
719
	son ( dad ) = cop ;
720
	br = ( prev == op1 ) ? &bro ( cop ) : prevbr ;
721
	commuted = 1 ;
722
	a1.fixneeds = MAX_OF ( a2.fixneeds, a1.fixneeds + 1 ) ;
723
	pnset ( a1, a2.prps ) ;
724
	a1.maxargs = MAX_OF ( a1.maxargs, a2.maxargs ) ;
725
      } 
726
      else {
727
	/* evaluation would disturb accumulated result, so replace
728
	   it by a newly declared tag */
729
	cca ( at, br ) ;
730
	a1.fixneeds = MAX_OF ( a1.fixneeds, 2 ) ;
731
	pnset ( a1, morefix | ( pc << 1 ) ) ;
732
	a1.maxargs = MAX_OF ( a1.maxargs, a2.maxargs ) ;
733
      }
734
    } else {
735
      /* nothing */
736
    }
737
  } while ( !last ( *br ) ) ;
738
 
739
#if 1
740
  /* exception handling regs (from mips) */
741
  if ( !optop ( *e ) ) {
742
    if ( a1.fixneeds < 4 ) a1.fixneeds = 4 ;
743
  }
744
#endif
745
  return ( a1 ) ;
746
}
747
 
748
 
749
/*
750
  WORK OUT REGISTER NEEDS FOR DIVIDE-LIKE OPERATIONS
751
  The operation will be binary and non-commutative.
752
*/
753
 
754
needs likediv 
755
    PROTO_N ( ( e, at ) )
756
    PROTO_T ( exp * e X exp ** at ){
757
  needs l ;
758
  needs r ;
759
  prop pc ;
760
  exp *arg = &son ( *e ) ;
761
 
762
  l = scan ( arg, at ) ;
763
  /* scan 1st operand */
764
  arg = &bro ( *arg ) ;
765
  r = scan ( arg, at ) ;
766
  /* scan second operand ... */
767
  l.floatneeds = MAX_OF ( l.floatneeds, r.floatneeds ) ;
768
 
769
  pc = ( prop ) ( r.prps & hasproccall ) ;
770
  if ( r.fixneeds < maxfix && pc == 0 ) {
771
    /* fits into registers */
772
    l.fixneeds = MAX_OF ( l.fixneeds, r.fixneeds + 1 ) ;
773
    pnset ( l, r.prps ) ;
774
  } 
775
  else {
776
    /* requires new declaration of second operand */
777
    cca ( at, arg ) ;
778
    l.fixneeds = MAX_OF ( l.fixneeds, 1 ) ;
779
    pnset ( l, morefix | ( pc << 1 ) ) ;
780
    l.maxargs = MAX_OF ( l.maxargs, r.maxargs ) ;
781
  }
782
 
783
#if 1
784
  /* exception handling regs (from mips) */
785
  if ( !optop ( *e ) ) {
786
    if ( l.fixneeds < 4 ) l.fixneeds = 4 ;
787
  }
788
#endif
789
  return ( l ) ;
790
}
791
 
792
 
793
/*
794
  WORK OUT REGISTER NEEDS FOR FLOATING-POINT OPERATIONS
795
  The operation will be binary.
796
*/
797
 
798
needs fpop 
799
    PROTO_N ( ( e, at ) )
800
    PROTO_T ( exp * e X exp ** at ){
801
  needs l ;
802
  needs r ;
803
  exp op = *e ;
804
  prop pcr, pcl ;
805
  exp *arg = &son ( op ) ;
806
 
807
  l = scan ( arg, at ) ;
808
  arg = &bro ( *arg ) ;
809
  r = scan ( arg, at ) ;
810
  l.fixneeds = MAX_OF ( l.fixneeds, r.fixneeds ) ;
811
  pcr = ( prop ) ( r.prps & hasproccall ) ;
812
  pcl = ( prop ) ( l.prps & hasproccall ) ;
813
 
814
#if use_long_double
815
  if ( name ( sh ( son ( op ) ) ) == doublehd ) {
816
    ClearRev ( op ) ;
817
    arg = &son ( op ) ;
818
    if ( !is_o ( name ( *arg ) ) || pcl ) cca ( at, arg ) ;
819
    arg = &bro ( son ( op ) ) ;
820
    if ( !is_o ( name ( *arg ) ) || pcr ) cca ( at, arg ) ;
821
    l.floatneeds = MAX_OF ( l.floatneeds, r.floatneeds ) ;
822
    l.maxargs = MAX_OF ( l.maxargs, r.maxargs ) ;
823
    pnset ( l, hasproccall ) ;
824
    return ( l ) ;
825
  }
826
#endif
827
 
828
  if ( r.floatneeds <= l.floatneeds &&
829
       r.floatneeds < maxfloat && pcr == 0 ) {
830
    l.floatneeds = MAX_OF ( l.floatneeds, r.floatneeds + 1 ) ;
831
    l.floatneeds = MAX_OF ( 2, l.floatneeds ) ;
832
    pnset ( l, r.prps ) ;
833
    ClearRev ( op ) ;
834
  } 
835
  else if ( pcl == 0 && l.floatneeds <= r.floatneeds &&
836
	    l.floatneeds < maxfloat ) {
837
    l.floatneeds = MAX_OF ( r.floatneeds, l.floatneeds + 1 ) ;
838
    l.floatneeds = MAX_OF ( 2, l.floatneeds ) ;
839
    pnset ( l, r.prps ) ;
840
    SetRev ( op ) ;
841
  } 
842
  else if ( r.floatneeds < maxfloat && pcr == 0 ) {
843
    l.floatneeds = MAX_OF ( l.floatneeds, r.floatneeds + 1 ) ;
844
    l.floatneeds = MAX_OF ( 2, l.floatneeds ) ;
845
    pnset ( l, r.prps ) ;
846
    ClearRev ( op ) ;
847
  } 
848
  else {
849
    cca ( at, arg ) ;
850
    ClearRev ( op ) ;
851
    l.floatneeds = MAX_OF ( l.floatneeds, 2 ) ;
852
    pnset ( l, morefloat | ( pcr << 1 ) ) ;
853
    l.maxargs = MAX_OF ( l.maxargs, r.maxargs ) ;
854
  }
855
  return ( l ) ;
856
}
857
 
858
 
859
/*
860
  WORK OUT THE MAXIMUM OF TWO REGISTER NEEDS
861
*/
862
 
863
needs maxneeds 
864
    PROTO_N ( ( a, b ) )
865
    PROTO_T ( needs a X needs b ){
866
  needs an ;
867
  an.fixneeds = MAX_OF ( a.fixneeds, b.fixneeds ) ;
868
  an.floatneeds = MAX_OF ( a.floatneeds, b.floatneeds ) ;
869
  an.maxargs = MAX_OF ( a.maxargs, b.maxargs ) ;
870
  an.callee_size = MAX_OF(a.callee_size,b.callee_size);
871
  an.prps = ( prop ) ( a.prps | b.prps ) ;
872
  return ( an ) ;
873
}
874
 
875
 
876
/*
877
  WORK OUT THE REGISTER NEEDS OF A TUPLE OF EXPRESSIONS
878
*/
879
 
880
needs maxtup 
881
    PROTO_N ( ( e, at ) )
882
    PROTO_T ( exp e X exp ** at ){
883
  exp *s = &son ( e ) ;
884
  needs an ;
885
  an = zeroneeds ;
886
  if( *s == nilexp) return an;
887
  while (an = maxneeds (an, scan (s, at)), !last(*s) ) {
888
    s = &bro(*s);
889
  }
890
  return an;
891
 
892
 
893
  /* NOT REACHED */
894
}
895
 
896
 
897
/*
898
  IS A VALUE UNCHANGED OVER ITS SCOPE?
899
 
900
  This routine finds if usedname is only used in cont operation or as
901
  result of ident.
902
*/
903
 
904
bool unchanged 
905
    PROTO_N ( ( usedname, ident ) )
906
    PROTO_T ( exp usedname X exp ident ){
907
  exp uses = pt ( usedname ) ;
908
  while ( uses != nilexp ) {
909
    if ( intnl_to ( ident, uses ) ) {
910
      if ( !last ( uses ) || name ( bro ( uses ) ) != cont_tag ) {
911
	exp z = uses ;
912
	while ( z != ident ) {
913
	  if ( !last ( z ) || ( name ( bro ( z ) ) != seq_tag &&
914
				name ( bro ( z ) ) != ident_tag ) ) {
915
	    return ( 0 ) ;
916
	  }
917
	  z = bro ( z ) ;
918
	}
919
      }
920
    }
921
    uses = pt ( uses ) ;
922
  }
923
  return ( 1 ) ;
924
}
925
 
926
 
927
/*
928
  CHASE STRUCTURE PROCEDURE RESULTS
929
  The SPARC convention for delivering a struct from a procedure is
930
  to have an extra pointer parameter in the proc; this means that 
931
  there must always be space in the calling work-space for the 
932
  result struct whether or not the value is used e.g. as in 
933
  f ( x ) or f ( x ).a etc.  This procedure is part of the 
934
  mechanism to determine whether it is necessary to insert a dummy 
935
  declaration to ensure that this space exists.
936
*/
937
 
938
bool chase 
939
    PROTO_N ( ( sel, e ) )
940
    PROTO_T ( exp sel X exp * e ){
941
  exp *one ;
942
  bool b = 0 ;
943
 
944
  switch ( name ( *e ) ) {
945
 
946
    case rep_tag :
947
    case ident_tag :
948
    case seq_tag :
949
    case labst_tag : {
950
      b = chase ( sel, &bro ( son ( *e ) ) ) ;
951
      break ;
952
    }
953
 
954
    case solve_tag :
955
    case cond_tag : {
956
      one = &son ( *e ) ;
957
      for ( ; ; ) {
958
	b = ( bool ) ( b | chase ( sel, one ) ) ;
959
	if ( last ( *one ) ) break ;
960
	one = &bro ( *one ) ;
961
      }
962
      break ;
963
    }
964
 
965
    case field_tag : {
966
      if ( chase ( *e, &son ( *e ) ) ) {
967
	/* inner field has been distributed */
968
	exp stare = *e ;
969
	exp ss = son ( stare ) ;
970
	if ( !last ( stare ) ) clearlast ( ss ) ;
971
	bro ( ss ) = bro ( stare ) ;
972
	sh ( ss ) = sh ( stare ) ;
973
	*e = ss ;
974
	return ( chase ( sel, e ) ) ;
975
      }
976
      /* FALL THROUGH */
977
    }
978
 
979
    default : {
980
      if ( (son ( sel ) != *e) && (name (sh(*e)) != bothd)) {
981
	/* only change if not outer */
982
	exp stare = *e ;
983
	exp newsel = getexp ( sh ( sel ), bro ( stare ),
984
			      ( int ) last ( stare ), stare,
985
			      nilexp, props ( sel ), no ( sel ),
986
			      name ( sel ) ) ;
987
	*e = newsel ;
988
	bro ( stare ) = newsel ;
989
	setlast ( stare ) ;
990
	b = 1 ;
991
      }
992
    }
993
  }
994
  if ( b ) sh ( *e ) = sh ( sel ) ;
995
  return ( b ) ;
996
}
997
 
998
 
999
exp need_result_space 
1000
    PROTO_N ( ( e ) )
1001
    PROTO_T ( exp e ) {
1002
	/* dad if application needs to reserve space for struct result */
1003
  exp dad = father ( e );
1004
  switch (name (dad)) {
1005
    case 0:	/* void in sequence, or param of apply_gen */
1006
    case apply_tag:
1007
    case caller_tag:
1008
    case field_tag:
1009
      return dad;
1010
    case ident_tag:
1011
      if (e == son (dad))
1012
	return nilexp;
1013
      return (need_result_space (dad));
1014
    case rep_tag:
1015
      if (e == son (dad))
1016
	return dad;
1017
      /* else fall through */
1018
    case cond_tag:
1019
    case solve_tag:
1020
    case labst_tag:
1021
    case seq_tag:
1022
#ifndef NEWDIAGS
1023
    case diagnose_tag:
1024
#endif
1025
      return (need_result_space (dad));
1026
    default:
1027
      return nilexp;
1028
  }
1029
}
1030
 
1031
 
1032
bool spin_lab  
1033
    PROTO_N ( ( lab ) )
1034
    PROTO_T ( exp lab ) {
1035
	/* true if label implies a tight spin */
1036
  exp dest = lab;
1037
  exp temp, ll;
1038
  for (;;) {
1039
    assert (name(dest) == labst_tag);
1040
    temp = bro(son(dest));
1041
    if (temp == nilexp || name(temp) != goto_tag)
1042
      return 0;
1043
    ll = lab;
1044
    for (;;) {
1045
      if (pt(temp) == ll)
1046
	return 1;
1047
      if (ll == dest)
1048
	break;
1049
      ll = pt(bro(son(ll)));
1050
    }
1051
    dest = pt(temp);
1052
  };
1053
  return 0;
1054
}
1055
 
1056
/* Check for legal conditions for asm */
1057
 
1058
static void id_in_asm 
1059
    PROTO_N ( ( id ) )
1060
    PROTO_T ( exp id )
1061
{
1062
  if (!isparam(id) || !props(son(id)))
1063
    setvis (id);
1064
  return;
1065
}
1066
 
1067
static int is_asm_opnd 
1068
    PROTO_N ( ( e, ext ) )
1069
    PROTO_T ( exp e X int ext )
1070
{
1071
  unsigned char n = name (e);
1072
  if (n == name_tag) {
1073
    id_in_asm (son(e));
1074
    return 1;
1075
  }
1076
  if (n == cont_tag && name(son(e)) == name_tag && isvar(son(son(e)))) {
1077
    id_in_asm (son(son(e)));
1078
    return 1;
1079
  }
1080
  return (n == val_tag || n == real_tag || n == null_tag ||
1081
	(n == reff_tag && name(son(e)) == name_tag));
1082
}
1083
 
1084
static int is_asm_var 
1085
    PROTO_N ( ( e, ext ) )
1086
    PROTO_T ( exp e X int ext )
1087
{
1088
  unsigned char n = name (e);
1089
  if (n == name_tag && isvar(son(e))) {
1090
    id_in_asm (son(e));
1091
    return 1;
1092
  }
1093
  return 0;
1094
}
1095
 
1096
void check_asm_seq 
1097
    PROTO_N ( ( e, ext ) )
1098
    PROTO_T ( exp e X int ext )
1099
{
1100
  if (name(e) == asm_tag) {
1101
    if ((asm_string(e) && name(son(e)) == string_tag) ||
1102
	(asm_in(e) && is_asm_opnd(son(e), ext)) ||
1103
	(asm_var(e) && is_asm_var(son(e), ext)) )
1104
      return;
1105
  }
1106
  if (name(e) == seq_tag) {
1107
    exp t = son(son(e));
1108
    for (;;) {
1109
      check_asm_seq (t, ext);
1110
      if (last(t))
1111
	break;
1112
      t = bro(t);
1113
    }
1114
    check_asm_seq (bro(son(e)), ext);
1115
  }
1116
  else
1117
  if (name(e) != top_tag)
1118
    fail ("illegal ~asm");
1119
  return;
1120
}
1121
 
1122
 
1123
 
1124
 
1125
 
1126
/*
1127
  SCAN AN EXPRESSION TO CALCULATE REGISTER NEEDS
1128
 
1129
  This procedure works out register requirements of an exp.  At each
1130
  call the fix field of the needs is the number of fixed point 
1131
  registers required to contain live values to evaluate this 
1132
  expression.  This never exceeds maxfix because if it would have, 
1133
  a new declaration is introduced in the exp tree (similarly for 
1134
  floating registers and maxfloat).  In these cases the prop field 
1135
  will contain the bits morefix (or morefloat).
1136
 
1137
  Scan also works out various things concerned with proc calls.
1138
  The maxargs field contains the maximum size in bits of the space
1139
  required for the parameters of all the procedures called in the 
1140
  exp.
1141
 
1142
  An exp proc call produces a hasproccall bit in the prop field, if
1143
  this is transformed as part of the definition of a new declaration
1144
  the bit is replaced by a usesproccall. The distinction is only used
1145
  in unfolding nested proc calls; SPARC requires this to be done
1146
  statically. The condition that a proc exp is a leaf (i.e. no proc 
1147
  calls) is that its prop contains neither bit.  If an ident exp 
1148
  is suitable, scan marks the props of ident with either inreg or 
1149
  infreg bits to indicate that a t-reg may be used for this tag.
1150
 
1151
  A thorough understanding of needs along with other procedures that
1152
  do switch ( name ( exp ) ) requires a knowledge of the meaning of
1153
  the fields of the exp in each case (this is documented somewhere).
1154
*/
1155
 
1156
needs scan 
1157
    PROTO_N ( ( e, at ) )
1158
    PROTO_T ( exp * e X exp ** at ){
1159
  /* e is the expression to be scanned, at is the place to put any
1160
     new decs.  The order of recursive calls with same at is 
1161
     critical. */
1162
 
1163
  exp ste = *e ;
1164
  int nstare = ( int ) name ( ste ) ;
1165
 
1166
#if 0
1167
  /* ignore diagnostic information */
1168
  while ( nstare == diag_tag || nstare == cscope_tag ||
1169
	  nstare == fscope_tag ) {
1170
    e = &son ( ste ) ;
1171
    ste = *e ;
1172
    nstare = name ( ste ) ;
1173
  }
1174
#endif
1175
 
1176
  switch ( nstare ) {
1177
 
1178
    case 0 : {
1179
      return ( zeroneeds ) ;
1180
    }
1181
#if 0
1182
    case compound_tag : {
1183
      return ( maxtup ( ste, at ) ) ;
1184
    }
1185
#else
1186
    case compound_tag :
1187
#endif
1188
    case nof_tag :
1189
    case concatnof_tag :
1190
    case ncopies_tag : {
1191
      needs nl ;
1192
      bool cantdo ;
1193
      exp dad ;
1194
      if ( name ( ste ) == ncopies_tag &&
1195
	   name ( son ( ste ) ) != name_tag &&
1196
	   name ( son ( ste ) ) != val_tag ) {
1197
	nl = scan ( &son ( *e ), at ) ;
1198
	cca ( at, &son ( *e ) ) ;
1199
      } 
1200
      else {
1201
	nl = maxtup ( *e, at ) ;
1202
      }
1203
      dad = father ( ste ) ;
1204
 
1205
      if ( name ( dad ) == compound_tag ||
1206
	   name ( dad ) == nof_tag ||
1207
	   name ( dad ) == concatnof_tag ) {
1208
	cantdo = 0 ;
1209
      } 
1210
      else {
1211
	if ( last ( ste ) ) {
1212
	  if ( name ( bro ( ste ) ) == ass_tag ) {
1213
	    exp a = son ( bro ( ste ) ) ;
1214
	    cantdo = ( bool ) ( name ( a ) != name_tag ||
1215
				!isvar ( son ( a ) ) ) ;
1216
	  } 
1217
	  else {
1218
	    cantdo = 1 ;
1219
	  }
1220
	} 
1221
	else {
1222
	  if ( last ( bro ( ste ) ) ) {
1223
	    cantdo = ( bool ) ( name ( bro ( bro ( ste ) ) ) !=
1224
				ident_tag ) ;
1225
	  } 
1226
	  else {
1227
	    cantdo = 1 ;
1228
	  }
1229
	}
1230
      }
1231
 
1232
      if ( cantdo ) {
1233
	/* can only deal with tuples in simple assignment or id */
1234
	int prpsx = ( int ) ( pntst ( nl, hasproccall ) << 1 ) ;
1235
	cca ( at, ptr_position ( ste ) ) ;
1236
	nl = shapeneeds ( sh ( *e ) ) ;
1237
	pnset ( nl, morefix ) ;
1238
	pnset ( nl, prpsx ) ;
1239
      }
1240
 
1241
      if ( nl.fixneeds < 2 ) nl.fixneeds = 2 ;
1242
      return ( nl ) ;
1243
    }
1244
 
1245
    case cond_tag : {
1246
/*	    exp first = son ( ste ) ;
1247
	    exp labst = bro ( first ) ;
1248
	    exp second = bro ( son ( labst ) ) ; */
1249
 
1250
      if (scan_cond(e, nilexp) !=0) {
1251
	return scan(e, at);
1252
      }			/* else goto next case */
1253
    }
1254
    /* FALL THROUGH */
1255
 
1256
    case labst_tag :
1257
    case rep_tag :
1258
    case solve_tag : {
1259
      needs an ;
1260
      exp *stat ;
1261
      exp *statat ;
1262
      stat = &son ( *e ) ;
1263
      statat = stat ;
1264
      an = zeroneeds ;
1265
      while ( an = maxneeds ( an, scan ( stat, &statat ) ),
1266
	      !last ( *stat ) ) {
1267
	stat = &bro ( *stat ) ;
1268
	statat = stat ;
1269
      }
1270
      if ( pntst ( an, usesproccall ) != 0 ) {
1271
	pnset ( an, hasproccall ) ;
1272
      }
1273
      return ( an ) ;
1274
    }
1275
 
1276
    case ident_tag : {
1277
      needs bdy ;
1278
      needs def ;
1279
      exp stare = *e ;
1280
      exp *arg = &bro ( son ( stare ) ) ;
1281
      exp t, s ;
1282
      bool fxregble ;
1283
      bool flregble ;
1284
      bool old_nonevis = nonevis ;
1285
      if ( no ( stare ) == 0 ) {
1286
	/* no uses, should have caonly flag and no var flag */
1287
	setcaonly ( stare ) ;
1288
	clearvar ( stare ) ;
1289
#ifdef NEWDIAGS
1290
	t = pt (stare);
1291
	while (t) {
1292
	  assert (isdiaginfo (t));
1293
	  setdiscarded (t);
1294
	  t = pt(t);
1295
	}
1296
#endif
1297
      }
1298
 
1299
      if ( isvar ( stare ) && ( !iscaonly ( stare ) ||
1300
				all_variables_visible ) ) {
1301
	setvis ( stare ) ;
1302
      }
1303
 
1304
      if (name(son(stare)) == formal_callee_tag) {
1305
	setvis(stare);
1306
      }
1307
 
1308
 
1309
      if ( isparam ( stare ) && name(son(stare))!= formal_callee_tag) {
1310
	/* Use the input regs %i0..%i5 for first 6*32 bits of params */
1311
	exp def2 = son ( stare ) ;
1312
	shape shdef = sh ( def2 ) ;
1313
	int n = stparam ;
1314
	int sizep = ( int ) shape_size ( shdef ) ;
1315
	int last_reg;
1316
#ifdef GENCOMPAT
1317
	if (!trad_proc) {
1318
#else
1319
	if(gen_call) {
1320
#endif
1321
	  if(v_proc) {
1322
	    last_reg = 4;
1323
	  }
1324
	  else {
1325
	    last_reg = 5;
1326
	  }
1327
	}
1328
	else {
1329
	  last_reg = 6;
1330
	}
1331
	assert ( name ( def2 ) == clear_tag ) ;
1332
	if ( ( stparam >> 5 ) < ( last_reg ) /*&& !(isenvoff(stare))*/ ) {
1333
	  /* Param regs %i0..%i5 */
1334
	  /* is >= 1 param reg free for (part-of) the param */
1335
	  /* Use an available param reg */
1336
	  if(v_proc && (stparam>>5)==last_reg) {
1337
	    /* reserve R_I5 for use as local reg */
1338
	    props(def2) = 0;
1339
	    stparam += 32;
1340
	    n = stparam;
1341
	  }
1342
	  else {
1343
	    props ( def2 ) = ( prop ) fixparam ;
1344
	  }
1345
	} 
1346
	else {
1347
	  /* Pass by stack */
1348
	  /* envoffset'ed this way always */
1349
	  props ( def2 ) = 0 ;
1350
	}
1351
	/* "offset" in params */
1352
	no ( def2 ) = n ;
1353
	stparam = rounder ( n + sizep, 32 ) ;
1354
	/* ( stparam / 32 ) */
1355
	fixparam = R_I0 + ( stparam >> 5 ) ;
1356
      }
1357
      else if(isparam(stare) && name(son(stare)) == formal_callee_tag){
1358
	exp def2 = son(stare);
1359
	exp shdef = sh(def2);
1360
	int sizep = shape_size(shdef);
1361
	int alp = shape_align(shdef);
1362
	int n = rounder(callee_size,alp);
1363
	no(def2) = n;
1364
	callee_size = rounder(n+sizep,32);
1365
	props(def2) = 0;
1366
      }
1367
 
1368
      nonevis = ( bool ) ( nonevis & !isvis ( stare ) ) ;
1369
 
1370
      bdy = scan ( arg, &arg ) ;
1371
#if NO_TREG
1372
      /* force minimal t-reg usage */
1373
      bdy.fixneeds = maxfix ;
1374
#endif
1375
      /* scan the body-scope */
1376
      arg = &son ( stare ) ;
1377
      /* scan the initialisation of tag */
1378
      def = scan ( arg, &arg ) ;
1379
 
1380
      nonevis = old_nonevis ;
1381
      t = son ( stare ) ;
1382
      s = bro ( t ) ;
1383
      fxregble = fixregable ( stare ) ;
1384
      flregble = floatregable ( stare ) ;
1385
 
1386
      if ( isparam ( stare ) ) {
1387
	if(name(son(stare)) != formal_callee_tag){
1388
	  /* reg for param or else 0 */
1389
	  int x = ( int ) props ( son ( stare ) ) ;
1390
	  /* bit size of param */
1391
	  int par_size = shape_size ( sh ( son ( stare ) ) ) ;
1392
	  if ( par_size == 8 || par_size == 16 ) {
1393
	    /* on to right end of word */
1394
	    no ( son ( stare ) ) += 32 - par_size ;
1395
	  }
1396
	  if ( x != 0 && fxregble ) {
1397
	    /* leave suitable pars in par regs */
1398
	    no ( stare ) = x ;
1399
	    pset ( stare, inreg_bits ) ;
1400
	  } 
1401
	  else {
1402
	    if ( x != 0 && flregble ) {
1403
	      /* Caller has placed float param in par regs;
1404
		 callee must store it out for use in float regs */
1405
	      no ( stare ) = 0 ;
1406
	    } 
1407
	    else {
1408
	      /* Otherwise caller has placed param on stack */
1409
	      no ( stare ) = R_NO_REG ;
1410
	    }
1411
	  }
1412
	}
1413
	else
1414
	  no(stare) = R_NO_REG;
1415
      } 
1416
      else {
1417
	if ( !isvis ( *e ) && isparam ( *e ) && !isoutpar(stare) &&
1418
	     pntst ( bdy, anyproccall | uses_res_reg_bit ) == 0 &&
1419
	     ( fxregble || flregble ) &&
1420
	     ( ((name (t)==apply_tag) || (name(t)==apply_general_tag)) ||
1421
	       ( name ( s ) == seq_tag &&
1422
		 name ( bro ( son ( s ) ) ) == res_tag &&
1423
		 name ( son ( bro ( son ( s ) ) ) ) == cont_tag &&
1424
		 isvar ( stare ) &&
1425
		 name ( son ( son ( bro ( son ( s ) ) ) ) ) ==
1426
		 name_tag &&
1427
		 son ( son ( son ( bro ( son ( s ) ) ) ) ) ==
1428
		 stare ) ) ) {
1429
	  /* Let a : = .. ; return cont a */
1430
	  /* integrate this with the block above,
1431
	     otherwise NOTREACHED */
1432
	  /* put tag in result reg if definition is call of proc,
1433
	     or body ends with return tag, provided result is not
1434
	     used otherwise */
1435
	  pset ( stare, ( fxregble ? inreg_bits : infreg_bits ) ) ;
1436
	  pnset ( bdy, uses_res_reg_bit ) ;
1437
	  /* identification uses result reg in body */
1438
	  no ( stare ) = R_USE_RES_REG ;
1439
	}
1440
	else if (isenvoff(stare)) /* MUST go on stack */	  {
1441
	  no ( stare ) = R_NO_REG ;
1442
	} 
1443
	else if ( !isvar ( *e ) && !isparam ( *e ) &&
1444
		  /* reff cont variable-not assigned to in scope */
1445
		  ( ( name ( t ) == reff_tag &&
1446
		      name ( son ( t ) ) == cont_tag &&
1447
		      name ( son ( son ( t ) ) ) == name_tag &&
1448
		      isvar ( son ( son ( son ( t ) ) ) ) &&
1449
		      !isvis ( son ( son ( son ( t ) ) ) ) &&
1450
		      !isglob ( son ( son ( son ( t ) ) ) ) &&
1451
		      unchanged ( son ( son ( son ( t ) ) ),
1452
				  stare ) ) ||
1453
		    /* cont variable - not assigned to in scope */
1454
		    ( name ( t ) == cont_tag &&
1455
		      name ( son ( t ) ) == name_tag &&
1456
		      isvar ( son ( son ( t ) ) ) &&
1457
		      !isvis ( son ( son ( t ) ) ) &&
1458
		      !isglob ( son ( son ( t ) ) ) &&
1459
		      unchanged ( son ( son ( t ) ),
1460
				  stare ) ) ) ) {
1461
	  /* don't take space for this dec */
1462
	  pset ( stare, defer_bit ) ;
1463
	  } 
1464
	else if ( !isvar ( stare ) &&
1465
		  ( ( props ( stare ) & 0x10 ) == 0 ) &&
1466
		  ( name ( t ) == name_tag ||
1467
		    name ( t ) == val_tag ) ) {
1468
	  /* don't take space for this dec */
1469
	  pset ( stare, defer_bit ) ;
1470
	  } 
1471
	else if ( fxregble &&
1472
		  pntst(bdy,morefix)==0 &&
1473
		  (bdy.fixneeds < maxfix &&
1474
		   ( /*isinlined(stare) ||*/
1475
		     pntst ( bdy, morefix ) == 0 &&
1476
		     ( pntst ( bdy, anyproccall ) == 0 ||
1477
		       tempdec ( stare, ( bool )
1478
				 ( pntst ( bdy, morefix ) == 0 &&
1479
				   bdy.fixneeds < maxfix_tregs - 2 ))))))
1480
	  {
1481
	    /* put this tag in some fixpt t-reg - which will be
1482
	       decided in make_code */
1483
	    pset ( stare, inreg_bits ) ;
1484
	    no ( stare ) = 0 ;
1485
	    bdy.fixneeds += 1 ;
1486
	    } 
1487
	else if ( bdy.floatneeds < maxfloat &&
1488
		  pntst ( bdy, morefloat ) == 0 &&
1489
		  flregble &&
1490
		  ( pntst ( bdy, anyproccall ) == 0 ||
1491
		    tempdec ( stare, ( bool )
1492
			      ( pntst ( bdy, morefloat ) == 0 &&
1493
				bdy.floatneeds < MAXFLOAT_TREGS - 1 ) ) ) ) {
1494
	  /* put this tag in some float t-reg - which will be
1495
	     decided in make_code */
1496
	  pset ( stare, infreg_bits ) ;
1497
	  no ( stare ) = 0 ;
1498
	  bdy.floatneeds += 1 ;
1499
				/* add isinlined when you enable float
1500
				   reg allocation.... */
1501
	} 
1502
	else {
1503
	  /* allocate either on stack or saved reg */
1504
	  no ( stare ) = R_NO_REG ;
1505
	}
1506
      }
1507
      bdy = maxneeds ( bdy, def ) ;
1508
      if ( pntst ( bdy, usesproccall ) != 0 ) {
1509
	pnset ( bdy, hasproccall ) ;
1510
      }
1511
      return ( bdy ) ;
1512
    }
1513
 
1514
    case seq_tag : {
1515
      exp *arg = &bro ( son ( *e ) ) ;
1516
      needs an ;
1517
      exp *stat ;
1518
      an = scan ( arg, &arg ) ;
1519
      stat = &son ( son ( *e ) ) ;
1520
 
1521
      arg = stat ;
1522
      for ( ; ; ) {
1523
	needs stneeds ;
1524
	stneeds = scan ( stat, &arg ) ;
1525
	/* initial statements voided */
1526
	an = maxneeds ( an, stneeds ) ;
1527
	if ( last ( *stat ) ) {
1528
	  if ( pntst ( an, usesproccall ) != 0 ) {
1529
	    pnset ( an, hasproccall ) ;
1530
	  }
1531
	  return ( an ) ;
1532
	}
1533
	stat = &bro ( *stat ) ;
1534
	arg = stat ;
1535
      }
1536
      /* NOT REACHED */
1537
    }
1538
 
1539
    case goto_tag : {
1540
      needs nr ;
1541
      nr = zeroneeds ;
1542
      if (!sysV_assembler && spin_lab (pt(*e))) {
1543
	pnset ( nr, dont_optimise ) ;		/* otherwise the SunOS assembler spins */
1544
      }
1545
      return ( nr ) ;
1546
    }
1547
    case ass_tag :
1548
    case assvol_tag : {
1549
      exp *lhs = &son ( *e ) ;
1550
      exp *rhs = &bro ( *lhs ) ;
1551
      needs nr ;
1552
      ash a ;
1553
 
1554
      /* scan source */
1555
      nr = scan ( rhs, at ) ;
1556
 
1557
      a = ashof ( sh ( *rhs ) ) ;
1558
      if ( nstare != ass_tag || a.ashsize != a.ashalign ||
1559
	   a.ashalign == 1 ) {
1560
	/* struct/union assign */
1561
	if ( !( a.ashsize <= 32 && a.ashsize == a.ashalign ) ) {
1562
	  /* memory block copy */
1563
	  nr.fixneeds += 2 ;
1564
	}
1565
      }
1566
 
1567
      if ( name ( *lhs ) == name_tag &&
1568
	   ( isvar ( son ( *lhs ) ) ||
1569
	     ( pntst ( nr, hasproccall | morefix ) == 0 &&
1570
	       nr.fixneeds < maxfix ) ) ) {
1571
	/* simple destination */
1572
	return ( nr ) ;
1573
      } 
1574
      else {
1575
	needs nl ;
1576
	prop prpx = ( prop ) ( pntst ( nr, hasproccall ) << 1 ) ;
1577
 
1578
	nl = scan ( lhs, at ) ;
1579
	if ( (name(*rhs)==apply_tag || name(*rhs)==apply_general_tag) && 
1580
	     nstare==ass_tag && pntst(nl,uses_res_reg_bit|anyproccall)==0) {
1581
	  /* source is proc call, so assign result reg directly */
1582
	  /* SKIP */ ;
1583
	} 
1584
	else if ( nr.fixneeds >= maxfix || prpx != 0 ) {
1585
	  /* source and dest regs overlap, so identify source */
1586
	  cca ( at, rhs ) ;
1587
	  nl = shapeneeds ( sh ( *rhs ) ) ;
1588
	  pnset ( nl, morefix ) ;
1589
	  pnclr ( nl, ( prpx >> 1 ) ) ;
1590
	  pnset ( nl, prpx ) ;
1591
	}
1592
	nr.fixneeds += 1 ;
1593
	return ( maxneeds ( nl, nr ) ) ;
1594
      }
1595
    }
1596
    case untidy_return_tag :
1597
    case res_tag : {
1598
      ash a ;
1599
      needs x ;
1600
      shape s ;
1601
      exp *arg = &son ( *e ) ;
1602
 
1603
      s = sh ( *arg ) ;
1604
      a = ashof ( s ) ;
1605
      /* clear possibility of tlrecirsion ; may be set later */
1606
      props ( *e ) = 0 ;
1607
      x = scan ( arg, at ) ;
1608
      /* scan result exp ... */
1609
      if ( is_floating ( name ( s ) ) && a.ashsize <= 64 ) {
1610
	/* ... floating pt result */
1611
	pnset ( x, realresult_bit ) ;
1612
	if ( name ( s ) != shrealhd ) {
1613
	  pnset ( x, longrealresult_bit ) ;
1614
	}
1615
      } 
1616
      else {
1617
	if ( !valregable ( s ) && name ( s ) != tophd ) {
1618
	  /* ... result does not fit into reg */
1619
	  pnset ( x, long_result_bit ) ;
1620
	}
1621
      }
1622
 
1623
      if ( a.ashsize != 0 && name ( *arg ) != clear_tag ) {
1624
	/* ...not a void result */
1625
	pnset ( x, has_result_bit ) ;
1626
      }
1627
 
1628
#if 0
1629
      /* replace R_USE_RES_REG (from mips) by R_USE_R_I0 (here)
1630
	 and R_USE_RO0 (ident_tag above) */
1631
      /* for present R_USE_RES_REG means R_USE_R_O0 */
1632
      /* MIPS has single res reg, on SPARC it is windowed per-proc */
1633
      if ( pntst ( x, ( long_result_bit | anyproccall |
1634
			uses_res_reg_bit ) ) == 0 ) {
1635
	r = son ( *e ) ;
1636
	if ( name ( r ) == ident_tag && isvar ( r ) &&
1637
	     name ( ss = bro ( son ( r ) ) ) == seq_tag &&
1638
	     name ( t = bro ( son ( ss ) ) ) == cont_tag &&
1639
	     name ( son ( t ) ) == name_tag &&
1640
	     son ( son ( t ) ) == r ) {
1641
	  /* result is tag allocated into result reg - see ident */
1642
	  if ( ( props ( r ) & inreg_bits ) != 0 ) {
1643
	    x.fixneeds-- ;
1644
	  } 
1645
	  else if ( ( props ( r ) & infreg_bits ) != 0 ) {
1646
	    x.floatneeds-- ;
1647
	  } 
1648
	  else {
1649
	    props ( r ) |= ( is_floating ( name ( s ) ) ) ?
1650
	      infreg_bits : inreg_bits ;
1651
	  }
1652
	  pnset ( x, uses_res_reg_bit ) ;
1653
	  /* identification uses result reg in body */
1654
	  no ( r ) = R_USE_RES_REG ;
1655
	}
1656
      }
1657
#endif
1658
      return ( x ) ;
1659
    }
1660
    case apply_general_tag : {
1661
      exp application = *(e);
1662
      exp *fn = &son(application);
1663
      exp callers = bro(*fn);
1664
      exp *cerl = &son(callers);
1665
      int stpar = 0;
1666
      needs nds,pstldnds;
1667
      int i;
1668
      nds = scan(fn,at);
1669
      if(pntst(nds,hasproccall)!=0){	/* Identify it */
1670
	cca(at,fn);
1671
	pnclr(nds,hasproccall);
1672
	pnset(nds,usesproccall);
1673
	fn = &son(application);
1674
      }
1675
      for(i=0;i<no(callers);++i){
1676
	needs onepar;
1677
	shape shonepar = sh(*cerl);
1678
	exp * par = (name(*cerl)==caller_tag)?&son(*cerl):cerl;
1679
	int n = rounder(stpar + shape_size(shonepar), 32);
1680
	onepar = scan(par,at);
1681
 
1682
	if((/*(i != 0) && */pntst(onepar,hasproccall)!=0) || 
1683
	   (onepar.fixneeds+(stpar>>5) > maxfix)){
1684
	  /* not the first parameter, and calls a proc */
1685
	  /* or the first if we need to preserve callee_start_reg */
1686
	  cca(at,par);
1687
	  pnset(nds,usesproccall);
1688
	  nds = maxneeds(shapeneeds(sh(*(par))),nds);
1689
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
1690
	}
1691
	else{
1692
	  nds = maxneeds(onepar,nds);
1693
	}
1694
 
1695
	if(name(*cerl) == caller_tag){
1696
	  no(*cerl) = stpar;
1697
	}
1698
 
1699
	stpar = n;
1700
	cerl = &bro(*cerl);
1701
      }
1702
      nds.maxargs = max(nds.maxargs,stpar);
1703
      maxfix -= 6;
1704
      nds = maxneeds(scan(&bro(bro(son(application))),at),nds);
1705
      maxfix += 6;
1706
      pstldnds = scan(&bro(bro(bro(son(application)))),at);
1707
      if(pntst(pstldnds,anyproccall)!=0){
1708
	set_postlude_has_call(application);
1709
      }
1710
      else{
1711
	clear_postlude_has_call(application);
1712
      }
1713
      nds = maxneeds(nds,pstldnds);
1714
      if ( sparccpd (sh(application)) ) {
1715
	exp ap_context = need_result_space(application);
1716
	if (ap_context != nilexp) {
1717
	  /* find space for tuple result */
1718
	  assert ( name ( *( ptr_position ( application ) ) ) == apply_general_tag ) ;
1719
	  cca ( at, ptr_position ( application ) ) ;
1720
	  if (name(ap_context) != field_tag) {
1721
		/* if context is application parameter, treat as pointer */
1722
	    setvar (bro(bro(application)));
1723
	    sh(pt(bro(bro(application)))) = f_pointer(f_alignment(sh(application)));
1724
	  }
1725
	  pnset ( nds, usesproccall ) ;
1726
	}
1727
	else
1728
	  pnset ( nds, hasproccall ) ;
1729
      } 
1730
      else if ( name(bro(bro(bro(son(application))))) != top_tag && valregable(sh(application))
1731
		&& name(sh(application)) != tophd && name(sh(application)) != bothd ) {
1732
	cca ( at, ptr_position ( application ) ) ;
1733
	pnset ( nds, usesproccall ) ;
1734
      }
1735
      else {
1736
	pnset ( nds, hasproccall ) ;
1737
      }
1738
      return nds;
1739
    }
1740
    case make_callee_list_tag : {
1741
      exp cllees = *e;
1742
      exp *par = &son(cllees);
1743
      needs nds;
1744
      int stpar = 0,i;
1745
      nds = zeroneeds;
1746
      for(i=0;i<no(cllees);++i){
1747
	needs onepar;
1748
	shape shonepar = sh(*par);
1749
	int n = rounder(stpar,shape_align(shonepar));
1750
	onepar = scan(par,at);
1751
	if((pntst(onepar,hasproccall)!=0) || (onepar.fixneeds+1>maxfix)){
1752
	  /* identify it */
1753
	  cca(at,par);
1754
	  pnset(nds,usesproccall);
1755
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
1756
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
1757
	}
1758
	else{
1759
	  nds = maxneeds(onepar,nds);
1760
	}
1761
	n += shape_size(shonepar);
1762
	stpar = rounder(n,REG_SIZE);
1763
	par = &bro(*par);
1764
      }
1765
      no(cllees) = stpar;
1766
      return nds;
1767
    }
1768
    case make_dynamic_callee_tag : {
1769
      exp cllees = *e;
1770
      exp *ptr = &son(cllees);
1771
      needs ndsp,nds;
1772
      nds = zeroneeds;
1773
      ndsp = scan(ptr,at);
1774
      if((pntst(ndsp,hasproccall)!=0) || (ndsp.fixneeds+1>maxfix)){
1775
	cca(at,ptr);
1776
	pnset(nds,usesproccall);
1777
	nds = maxneeds(shapeneeds(sh(*ptr)),nds);
1778
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1779
      }
1780
      else{
1781
	nds = ndsp;
1782
      }
1783
      ndsp = scan(&bro(son(cllees)),at);
1784
      if((pntst(ndsp,hasproccall)!=0) || (ndsp.fixneeds+2>maxfix)){
1785
	cca(at,&bro(son(cllees)));
1786
	pnset(nds,usesproccall);
1787
	nds = maxneeds(shapeneeds(sh(bro(son(cllees)))),nds);
1788
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1789
      }
1790
      else{
1791
	nds = maxneeds(ndsp,nds);
1792
      }
1793
      if(nds.fixneeds<10) nds.fixneeds = 10;	/* ?? */
1794
      return nds;
1795
    }
1796
    case same_callees_tag: {
1797
      needs nds;
1798
      nds = zeroneeds;
1799
      nds.fixneeds = 6;
1800
      return nds;
1801
    }
1802
    case tail_call_tag: {
1803
      exp tlcl = *e;
1804
      needs ndsp,nds;
1805
      exp *fn = &son(tlcl);
1806
      ndsp = scan(fn,at);
1807
      if((pntst(ndsp,hasproccall)!=0) || (ndsp.fixneeds+1 > maxfix)){
1808
	cca(at,fn);
1809
	pnset(nds,usesproccall);
1810
	nds = maxneeds(shapeneeds(sh(*fn)),nds);
1811
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1812
      }
1813
      else{
1814
	nds = ndsp;
1815
      }
1816
      ndsp = scan(&bro(son(tlcl)),at);
1817
      nds = maxneeds(nds,ndsp);
1818
      if(nds.fixneeds < 6) nds.fixneeds = 6;
1819
      return nds;
1820
    }
1821
 
1822
    case apply_tag : {
1823
      int i ;
1824
      needs nds ;
1825
      int parsize = 0 ;
1826
      exp appl = *e ;
1827
      exp fn = son ( appl ) ;
1828
      exp *par = &bro ( fn ) ;
1829
      exp *fnexp = &son ( appl ) ;
1830
      bool tlrecpos = ( bool ) ( nonevis && callerfortr &&
1831
				 ( rscope_level == 0 ) ) ;
1832
 
1833
      nds = scan ( fnexp, at ) ;
1834
      /* scan the function exp ... */
1835
      if ( pntst ( nds, hasproccall ) != 0 ) {
1836
	/* ... it must be identified */
1837
	cca ( at, fnexp ) ;
1838
	pnclr ( nds, hasproccall ) ;
1839
	pnset ( nds, usesproccall ) ;
1840
	fn = son ( appl ) ;
1841
	par = &bro ( fn ) ;
1842
      }
1843
 
1844
      if ( name ( fn ) != name_tag ||
1845
	   ( son ( son ( fn ) ) != nilexp &&
1846
	     ((name ( son ( son ( fn ) ) ) != proc_tag ) ||
1847
	      name(son(son(fn)))==general_proc_tag))) {
1848
	tlrecpos = 0 ;
1849
      }
1850
 
1851
      for ( i = 1 ; !last ( fn ) ; ++i ) {
1852
	/* scan parameters in turn ... */
1853
	needs onepar ;
1854
	shape shpar = sh ( *par ) ;
1855
	onepar = scan ( par, at ) ;
1856
 
1857
	if ( ( i != 1 && pntst ( onepar, hasproccall ) != 0 ) ||
1858
	     onepar.fixneeds + ( parsize >> 5 ) > maxfix ) {
1859
	  /* if it isn't the first parameter, and it calls
1860
	     a proc, identify it */
1861
	  cca ( at, par ) ;
1862
	  pnset ( nds, usesproccall ) ;
1863
	  nds = maxneeds ( shapeneeds ( sh ( *par ) ), nds ) ;
1864
	  nds.maxargs = MAX_OF ( nds.maxargs, onepar.maxargs ) ;
1865
	} 
1866
	else {
1867
	  nds = maxneeds ( onepar, nds ) ;
1868
	}
1869
	parsize = ( int ) rounder ( parsize, shape_align ( shpar ) ) ;
1870
	parsize = rounder ( parsize + shape_size ( shpar ), 32 ) ;
1871
	if ( ( !valregable ( shpar ) &&
1872
	       !is_floating ( name ( shpar ) ) ) ||
1873
	     parsize > 128 ) {
1874
	  tlrecpos = 0 ;
1875
	}
1876
	if ( last ( *par ) ) {
1877
	  break ;
1878
	}
1879
	par = &bro ( *par ) ;
1880
      }
1881
 
1882
      if ( specialopt ( fn ) ) {
1883
	/* eg vfork */
1884
	pnset ( nds, dont_optimise ) ;
1885
      }
1886
 
1887
      if ( ( i = specialfn ( fn ) ) > 0 ) {
1888
	/* eg strlen */
1889
#if 0
1890
	nds = maxneeds ( specialneeds ( i ), nds ) ;
1891
#endif
1892
	return ( nds ) ;
1893
      } 
1894
      else if ( i == -1 ) {
1895
	/* call of strcpy ... (removed) */
1896
      }
1897
 
1898
      if ( tlrecpos ) {
1899
	exp dad = father ( appl ) ;
1900
	if ( name ( dad ) == res_tag ) {
1901
	  props ( dad ) = 1 ;     /* do a tl recursion */
1902
	}
1903
      }
1904
 
1905
      if ( sparccpd (sh(appl)) ) {
1906
	exp ap_context = need_result_space(appl);
1907
	if (ap_context != nilexp) {
1908
	  /* find space for tuple result */
1909
	  assert ( name ( *( ptr_position ( appl ) ) ) == apply_tag ) ;
1910
	  cca ( at, ptr_position ( appl ) ) ;
1911
	  if (name(ap_context) != field_tag) {
1912
		/* if context is application parameter, treat as pointer */
1913
	    setvar (bro(bro(appl)));
1914
	    sh(pt(bro(bro(appl)))) = f_pointer(f_alignment(sh(appl)));
1915
	  }
1916
	  pnset ( nds, usesproccall ) ;
1917
	}
1918
	else
1919
	  pnset ( nds, hasproccall ) ;
1920
      } 
1921
      else {
1922
	pnset ( nds, hasproccall ) ;
1923
      }
1924
      nds.maxargs = MAX_OF ( nds.maxargs, parsize ) ;
1925
      /* clobber %o0..%o5,%o7 */
1926
      nds.fixneeds = MAX_OF ( nds.fixneeds, 8 ) ;
1927
      return ( nds ) ;
1928
 
1929
    }
1930
    case movecont_tag : {	/* Only whilst it aways generates memmove */
1931
      int i ;
1932
      needs nds ;
1933
      int parsize = 0 ;
1934
      exp mv = *e ;
1935
      exp *par = &son ( mv ) ;
1936
      bool tlrecpos = ( bool ) ( nonevis && callerfortr &&
1937
				 ( rscope_level == 0 ) ) ;
1938
      nds = zeroneeds;
1939
 
1940
      for ( i = 1 ; i<=3 ; ++i ) {
1941
	/* scan parameters in turn ... */
1942
	needs onepar ;
1943
	shape shpar = sh ( *par ) ;
1944
	onepar = scan ( par, at ) ;
1945
 
1946
	if ( ( i != 1 && pntst ( onepar, hasproccall ) != 0 ) ||
1947
	     onepar.fixneeds + ( parsize >> 5 ) > maxfix ) {
1948
	  /* if it isn't the first parameter, and it calls
1949
	     a proc, identify it */
1950
	  cca ( at, par ) ;
1951
	  pnset ( nds, usesproccall ) ;
1952
	  nds = maxneeds ( shapeneeds ( sh ( *par ) ), nds ) ;
1953
	  nds.maxargs = MAX_OF ( nds.maxargs, onepar.maxargs ) ;
1954
	} 
1955
	else {
1956
	  nds = maxneeds ( onepar, nds ) ;
1957
	}
1958
	parsize = ( int ) rounder ( parsize, shape_align ( shpar ) ) ;
1959
	parsize = rounder ( parsize + shape_size ( shpar ), 32 ) ;
1960
	if ( ( !valregable ( shpar ) &&
1961
	       !is_floating ( name ( shpar ) ) ) ||
1962
	     parsize > 128 ) {
1963
	  tlrecpos = 0 ;
1964
	}
1965
	assert ((i != 3) || last(*par));
1966
	par = &bro ( *par ) ;
1967
      }
1968
 
1969
 
1970
      if ( tlrecpos ) {
1971
	exp dad = father ( mv ) ;
1972
	if ( name ( dad ) == res_tag ) {
1973
	  props ( dad ) = 1 ;     /* do a tl recursion */
1974
	}
1975
      }
1976
 
1977
      pnset ( nds, hasproccall ) ;
1978
 
1979
      nds.maxargs = MAX_OF ( nds.maxargs, parsize ) ;
1980
      /* clobber %o0..%o5,%o7 */
1981
      nds.fixneeds = MAX_OF ( nds.fixneeds, 7 ) ;
1982
      return ( nds ) ;
1983
    }
1984
 
1985
    case val_tag : {
1986
      exp s = sh ( *e ) ;
1987
      if ( name ( s ) == offsethd && al2 ( s ) >= 8 ) {
1988
	/* express disps in bytes */
1989
	no ( *e ) = no ( *e ) >> 3 ;
1990
      }
1991
      /* FALL THROUGH */
1992
    }
1993
    case env_size_tag :
1994
    case caller_name_tag :
1995
    case null_tag :
1996
    case real_tag :
1997
    case string_tag :
1998
    case env_offset_tag :
1999
    case current_env_tag :
2000
    case make_lv_tag : 
2001
    case last_local_tag : {
2002
      return ( shapeneeds ( sh ( *e ) ) ) ;
2003
    }
2004
    case name_tag : {
2005
      needs nds;
2006
      nds = shapeneeds ( sh ( *e ) ) ;
2007
      if (PIC_code && isglob (son(*e))) { 
2008
	long boff = no(*e) >> 3 ;
2009
	if (boff < -4096 || boff > 4095)
2010
	  nds.fixneeds += 1 ;
2011
      }
2012
      return ( nds ) ;
2013
    }
2014
    case give_stack_limit_tag : {
2015
      specialext = 1;
2016
      return ( shapeneeds ( sh ( *e ) ) ) ;
2017
    }
2018
    case formal_callee_tag :
2019
    case clear_tag :
2020
    case top_tag :
2021
    case prof_tag :
2022
    case local_free_all_tag : {
2023
      return ( zeroneeds ) ;
2024
    }
2025
    case local_free_tag: {
2026
      needs nds;
2027
      nds = scan( &son(*e),at);
2028
      if(nds.fixneeds < 2) nds.fixneeds = 2;
2029
    }
2030
 
2031
#if 0
2032
    case rscope_tag : {
2033
      needs sn ;
2034
      exp *s = &son ( *e ) ;
2035
#if 0
2036
      exp lst ;
2037
#endif
2038
      rscope_level++ ;
2039
#if 0
2040
      /* only needed when ( do_tlrecursion != 0 ) */
2041
      ( void ) last_statement ( son ( *e ), &lst ) ; /* always true */
2042
      if ( name ( lst ) == res_tag ) {
2043
	/* can remove res */
2044
	exp *pos = ptr_position ( lst ) ;
2045
	exp t ;
2046
 
2047
	bro ( son ( lst ) ) = bro ( lst ) ;
2048
	if ( last ( lst ) ) {
2049
	  setlast ( son ( lst ) ) ;
2050
	} 
2051
	else {
2052
	  clearlast ( son ( lst ) ) ;
2053
	}
2054
	*pos = son ( lst ) ;
2055
	for ( t = father ( *pos ) ; name ( sh ( t ) ) == bothd ;
2056
				    t = father ( t ) ) {
2057
	  /* adjust ancestors to correct shape */
2058
	  sh ( t ) = sh ( *pos ) ;
2059
	}
2060
      }
2061
#endif
2062
      sn = scan ( s, &s ) ;
2063
      rscope_level-- ;
2064
      return ( sn ) ;
2065
    }
2066
#endif
2067
    case set_stack_limit_tag : {
2068
      exp *arg = &son ( *e ) ;
2069
      specialext = 1;
2070
      return ( scan ( arg, at ) ) ;
2071
    }
2072
#ifdef return_to_label_tag
2073
    case return_to_label_tag :
2074
#endif
2075
#ifndef NEWDIAGS
2076
    case diagnose_tag :
2077
#endif
2078
    case goto_lv_tag :
2079
    case abs_tag :
2080
    case neg_tag :
2081
    case not_tag :
2082
    case offset_negate_tag : {
2083
      exp *arg = &son ( *e ) ;
2084
      if (error_treatment_is_trap ( *e ))
2085
	specialext = 1;
2086
      return ( scan ( arg, at ) ) ;
2087
    }
2088
    case case_tag :
2089
    { 
2090
      needs s;
2091
      exp *arg = &son ( *e ) ;
2092
 
2093
      s = scan ( arg, at ) ;
2094
      s.fixneeds = MAX_OF ( s.fixneeds, 2 ) ; /* dense case calls getreg */
2095
      return s;
2096
    }
2097
 
2098
    case fneg_tag :
2099
    case fabs_tag :
2100
    case chfl_tag : {
2101
      needs nds ;
2102
      exp *pste;
2103
      if (error_treatment_is_trap ( *e ))
2104
	specialext = 1;
2105
      nds = scan ( &son ( *e ), at ) ;
2106
      pste = ptr_position(ste);
2107
      if ( !optop ( *pste ) && nds.fixneeds < 2 ) nds.fixneeds = 2 ;
2108
#if use_long_double
2109
      {
2110
	exp op = *pste ;
2111
	if ( name ( sh ( op ) ) == doublehd ||
2112
	     name ( sh ( son ( op ) ) ) == doublehd ) {
2113
#if 0
2114
	  if(name(*e) == fabs_tag){
2115
	    replace_fabs(ste);
2116
	  }
2117
#endif
2118
	  if ( !is_o ( name ( son ( op ) ) ) ||
2119
	       pntst ( nds, hasproccall ) ) {
2120
	    cca ( at, &son ( op ) ) ;
2121
	  }
2122
	  pnset ( nds, hasproccall ) ;
2123
	}
2124
      }
2125
#endif
2126
      return ( nds ) ;
2127
    }
2128
 
2129
    case bitf_to_int_tag : {
2130
      exp *arg = &son ( *e ) ;
2131
      needs nds ;
2132
      exp stararg ;
2133
      exp stare ;
2134
      int sizeb ;
2135
 
2136
      nds = scan ( arg, at ) ;
2137
      stararg = *arg ;
2138
      stare = *e ;
2139
      sizeb = shape_size ( sh ( stararg ) ) ;
2140
      if ( ( name ( stararg ) == name_tag &&
2141
	     ( ( sizeb == 8 &&
2142
		 ( no ( stararg ) & 7 ) == 0 ) ||
2143
	       ( sizeb == 16 &&
2144
		 ( no ( stararg ) & 15 ) == 0 ) ||
2145
	       ( sizeb == 32 &&
2146
		 ( no ( stararg ) & 31 ) == 0 ) ) ) ||
2147
	   ( name ( stararg ) == cont_tag &&
2148
	     ( ( name ( son ( stararg ) ) != name_tag &&
2149
		 name ( son ( stararg ) ) != reff_tag ) ||
2150
	       ( sizeb == 8 &&
2151
		 ( no ( son ( stararg ) ) & 7 ) == 0 ) ||
2152
	       ( sizeb == 16 &&
2153
		 ( no ( son ( stararg ) ) & 15 ) == 0 ) ||
2154
	       ( sizeb == 32 &&
2155
		 ( no ( son ( stararg ) ) & 31 ) == 0 ) ) ) ) {
2156
	/* these bitsint ( trimnof ( X ) ) could be implemented by
2157
	   lb or lh instructions ... */
2158
	int sgned = name ( sh ( stare ) ) & 1 ;
2159
	shape ns = ( sizeb == 8 ) ? ( sgned ? scharsh : ucharsh ) :
2160
	  ( sizeb == 16 ) ? ( sgned ? swordsh : uwordsh ) :
2161
	  sh ( stare ) ;
2162
	/* can use short loads instead of bits extractions */
2163
	if ( name ( stararg ) == cont_tag ) {
2164
	  /* make the ptr shape consistent */
2165
	  sh ( son ( stararg ) ) = f_pointer ( long_to_al (
2166
							   ( long ) shape_align ( ns ) ) ) ;
2167
	}
2168
	sh ( stararg ) = ns ;
2169
	setname ( stare, chvar_tag ) ;
2170
      }
2171
      return ( nds ) ;
2172
    }
2173
 
2174
    case int_to_bitf_tag : {
2175
      exp *arg = &son ( *e ) ;
2176
      return ( scan ( arg, at ) ) ;
2177
    }
2178
    case round_tag : {
2179
      needs s ;
2180
      exp *arg ;
2181
      exp *pste;
2182
      int rm = ( int ) round_number ( *e ) ;
2183
      if (error_treatment_is_trap ( *e ))
2184
	specialext = 1;
2185
      arg = &son ( *e ) ;
2186
      s = scan ( arg, at ) ;
2187
      pste = ptr_position(ste);
2188
      s.fixneeds = MAX_OF ( s.fixneeds, 2 ) ;
2189
      if ( rm < 3 || name ( sh ( *pste ) ) == ulonghd ) {
2190
	s.floatneeds = MAX_OF ( s.floatneeds, 3 ) ;
2191
      } 
2192
      else {
2193
	s.floatneeds = MAX_OF ( s.floatneeds, 2 ) ;
2194
      }
2195
#if use_long_double
2196
      {
2197
	exp op = *pste ;
2198
 
2199
	if ( name ( sh ( son ( op ) ) ) == doublehd ) {
2200
	  if ( !is_o ( name ( son ( op ) ) ) ||
2201
	       pntst ( s, hasproccall ) ) {
2202
	    cca ( at, &son ( op ) ) ;
2203
	  }
2204
	  pnset ( s, hasproccall ) ;
2205
	}
2206
      }
2207
#endif
2208
      return ( s ) ;
2209
    }
2210
 
2211
    case shl_tag :
2212
    case shr_tag :
2213
    case long_jump_tag : {
2214
      int prpx ;
2215
      needs nl, nr ;
2216
      exp *lhs = &son ( *e ) ;
2217
      exp *rhs = &bro ( *lhs ) ;
2218
 
2219
      nr = scan ( rhs, at ) ;
2220
      nl = scan ( lhs, at ) ;
2221
      rhs = &bro(*lhs);
2222
      prpx = ( int ) ( pntst ( nr, hasproccall ) << 1 ) ;
2223
 
2224
      if ( nr.fixneeds >= maxfix || prpx != 0 ) {
2225
	/* if reg requirements overlap, identify second operand */
2226
	cca ( at, rhs ) ;
2227
	nl = shapeneeds ( sh ( *rhs ) ) ;
2228
	pnset ( nl, morefix ) ;
2229
	pnclr ( nl, ( prpx >> 1 ) ) ;
2230
	pnset ( nl, prpx ) ;
2231
      }
2232
      nr.fixneeds += 1 ;
2233
      nr.fixneeds += 1 ;	/* why? */
2234
      return ( maxneeds ( nl, nr ) ) ;
2235
    }
2236
 
2237
    case test_tag : {
2238
      exp stare = *e ;
2239
      exp l = son ( stare ) ;
2240
      exp r = bro ( l ) ;
2241
 
2242
      if ( !last ( stare ) && name ( bro ( stare ) ) == test_tag &&
2243
	   test_number ( stare ) == test_number ( bro ( stare ) ) &&
2244
	   eq_exp ( l, son ( bro ( stare ) ) ) &&
2245
	   eq_exp ( r, bro ( son ( bro ( stare ) ) ) ) ) {
2246
	/* same test following in seq list - remove second test */
2247
	if ( last ( bro ( stare ) ) ) setlast ( stare ) ;
2248
	bro ( stare ) = bro ( bro ( stare ) ) ;
2249
	no(son(pt(stare))) --; /* one less way there */
2250
      }
2251
 
2252
      if ( last ( stare ) && name ( bro ( stare ) ) == 0 &&
2253
	   name ( bro ( bro ( stare ) ) ) == test_tag &&
2254
	   name ( bro ( bro ( bro ( stare ) ) ) ) == seq_tag &&
2255
	   test_number ( stare ) ==
2256
	   test_number ( bro ( bro ( stare ) ) ) &&
2257
	   eq_exp ( l, son ( bro ( bro ( stare ) ) ) ) &&
2258
	   eq_exp ( r, bro ( son ( bro ( bro ( stare ) ) ) ) ) ) {
2259
	/* same test following in seq res - void second test */
2260
	setname ( bro ( bro ( stare ) ), top_tag ) ;
2261
	son ( bro ( bro ( stare ) ) ) = nilexp ;
2262
	pt ( bro ( bro ( stare ) ) ) = nilexp ;
2263
	no(son(pt(stare))) --; /* one less way there */
2264
      }
2265
 
2266
      assert ((name(l) == val_tag) ? (name(r) == val_tag) : 1);
2267
 				/* jmf claims to have put one val 
2268
				   on right,so only allow val 
2269
				   test val */
2270
 
2271
      if ( name(r) == val_tag && 
2272
	   (props(stare) == 5 || props(stare) == 6) && /* eq/neq */
2273
	   no (r) == 0 &&	/* against 0 */
2274
	   name (l) == and_tag && name (bro (son (l))) == val_tag &&
2275
	   (no (bro (son (l))) & (no (bro (son (l))) - 1)) == 0
2276
	   ) 
2277
	{			/* zero test  x & 2^n   -> neg test (x shl
2278
				   (31-n)) */
2279
	  long  n = no (bro (son (l)));
2280
	  int   x;
2281
	  for (x = 0; n > 0; x++) {
2282
	    n = n << 1;
2283
	  }
2284
	  if (x == 0) {		/* no shift required */
2285
	    bro (son (l)) = r;	/* zero there */
2286
	    son (stare) = son (l);/* x */
2287
	  }
2288
	  else {
2289
	    setname (l, shl_tag);
2290
	    no (bro (son (l))) = x;
2291
	  }
2292
	  props (stare) -= 3;	/* test for neg */
2293
	  sh (son (stare)) = slongsh;
2294
 
2295
	}
2296
 
2297
      if ( name ( l ) == bitf_to_int_tag &&
2298
	   name ( r ) == val_tag &&
2299
	   ( props ( stare ) == 5 || props ( stare ) == 6 ) &&
2300
	   ( name ( son ( l ) ) == cont_tag ||
2301
	     name ( son ( l ) ) == name_tag ) ) {
2302
	/* equality of bits against +ve consts doesnt need
2303
	   sign adjustment */
2304
	long n = no ( r ) ;
2305
	switch ( name ( sh ( l ) ) ) {
2306
	  case scharhd : {
2307
	    if ( n >= 0 && n <= 127 ) {
2308
	      sh ( l ) = ucharsh ;
2309
	    }
2310
	    break ;
2311
	  }
2312
	  case swordhd : {
2313
	    if ( n >= 0 && n <= 0xffff ) {
2314
	      sh ( l ) = uwordsh ;
2315
	    }
2316
	    break ;
2317
	  }
2318
	}
2319
      } 
2320
      else if ( is_floating ( name ( sh ( l ) ) ) ) {
2321
	return ( fpop ( e, at ) ) ;
2322
      } 
2323
      else if ( name ( r ) == val_tag && no ( r ) == 1 &&
2324
		  ( props ( stare ) == 3 || props ( stare ) == 2 ) ) {
2325
	no ( r ) = 0 ;
2326
	if ( props ( stare ) == 3 ) {
2327
	  /* branch >= 1 -> branch > 0 */
2328
	  props ( stare ) = 4 ;
2329
	} 
2330
	else {
2331
	  /* branch < 1 -> branch <= 0 */
2332
	  props ( stare ) = 1 ;
2333
	}
2334
      }
2335
      return ( likediv ( e, at ) ) ;
2336
    }
2337
 
2338
    case plus_tag : {
2339
      /* replace any operands which are neg ( .. ) by -, if poss */
2340
      exp sum = *e ;
2341
      exp list = son ( sum ) ;
2342
      bool someneg = 0 ;
2343
      bool allneg = 1 ;
2344
      if (error_treatment_is_trap ( *e ))
2345
	specialext = 1;
2346
 
2347
      for ( ; optop ( sum ) ; ) {
2348
	if ( name ( list ) == neg_tag ) {
2349
	  someneg = 1 ;
2350
	} 
2351
	else {
2352
	  allneg = 0 ;
2353
	}
2354
	if ( last ( list ) ) break ;
2355
	list = bro ( list ) ;
2356
      }
2357
 
2358
      if ( someneg ) {
2359
	/* there are some neg () operands */
2360
	if ( allneg ) {
2361
	  /* transform - .. - ... to - ( .. + .. + ... ) */
2362
	  exp x ;
2363
	  /* Build a new list form operand of neg_tags, which
2364
	     will become plus_tag operands */
2365
	  x = son ( sum ) ;
2366
	  list = son ( x ) ;
2367
	  for ( ; ; ) {
2368
	    /* 'x' moves along neg_tag's lists 'list' moves
2369
	       along sons of neg_tag's lists, building a new list
2370
	       eventually new list is made son of plus_tag */
2371
	    if ( !last ( x ) ) {
2372
	      bro ( list ) = son ( bro ( x ) ) ;
2373
	      clearlast ( list ) ;
2374
	      list = bro ( list ) ;
2375
	      x = bro ( x ) ;
2376
	    } 
2377
	    else {
2378
	      /* set father to be */
2379
	      bro ( list ) = sum ;
2380
	      setlast ( list ) ;
2381
	      /* set new sons of plus_tag */
2382
	      son ( sum ) = son ( son ( sum ) ) ;
2383
	      break ;
2384
	    }
2385
	  }
2386
 
2387
	  /* create new neg_tag to replace plus_tag, old
2388
	     plus_tag being the operand of the new neg_tag */
2389
	  x = getexp ( sh ( sum ), bro ( sum ), ( int ) last ( sum ),
2390
		       sum, nilexp, 0, 0, neg_tag ) ;
2391
	  setlast ( sum ) ;
2392
	  /* set father of sum, new neg_tag exp */
2393
	  bro ( sum ) = x ;
2394
	  *e = x ;
2395
	} 
2396
	else {
2397
	  /* transform to ( ( .. ( .. + .. ) - .. ) - .. ) */
2398
	  int n = 0 ;
2399
	  exp brosum = bro ( sum ) ;
2400
	  bool lastsum = ( bool ) last ( sum ) ;
2401
	  exp x = son ( sum ) ;
2402
	  exp newsum = sum ;
2403
 
2404
	  list = nilexp ;
2405
	  for ( ; ; ) {
2406
	    exp nxt = bro ( x ) ;
2407
	    bool final = ( bool ) last ( x ) ;
2408
 
2409
	    if ( name ( x ) == neg_tag ) {
2410
	      bro ( son ( x ) ) = list ;
2411
	      list = son ( x ) ;
2412
	    } 
2413
	    else {
2414
	      bro ( x ) = newsum ;
2415
	      newsum = x ;
2416
	      if ( ( n++ ) == 0 ) {
2417
		setlast ( newsum ) ;
2418
	      } 
2419
	      else {
2420
		clearlast ( newsum ) ;
2421
	      }
2422
	    }
2423
	    if ( final ) break ;
2424
	    x = nxt ;
2425
	  }
2426
 
2427
	  if ( n > 1 ) {
2428
	    son ( sum ) = newsum ;
2429
	    /* use existing exp for add operations */
2430
	    newsum = sum ;
2431
	  }
2432
	  for ( ; ; ) {
2433
	    /* introduce - operations */
2434
	    exp nxt = bro ( list ) ;
2435
	    bro ( newsum ) = list ;
2436
	    clearlast ( newsum ) ;
2437
	    x = getexp ( sh ( sum ), nilexp, 0, newsum, nilexp,
2438
			 0, 0, minus_tag ) ;
2439
	    bro ( list ) = x ;
2440
	    setlast ( list ) ;
2441
	    newsum = x ;
2442
	    if ( ( list = nxt ) == nilexp ) break ;
2443
	  }
2444
	  bro ( newsum ) = brosum ;
2445
	  if ( lastsum ) {
2446
	    setlast ( newsum ) ;
2447
	  } 
2448
	  else {
2449
	    clearlast ( newsum ) ;
2450
	  }
2451
	  *e = newsum ;
2452
 
2453
	}
2454
	return ( scan ( e, at ) ) ;
2455
 
2456
      }
2457
      /* FALL THROUGH */
2458
    }
2459
 
2460
    case and_tag :
2461
    case or_tag :
2462
    case xor_tag : {
2463
      return ( likeplus ( e, at ) ) ;
2464
    }
2465
#ifdef make_stack_limit_tag
2466
    case make_stack_limit_tag :
2467
#endif
2468
    case minus_tag :
2469
    case subptr_tag :
2470
    case minptr_tag : {
2471
      if (error_treatment_is_trap ( *e ))
2472
	specialext = 1;
2473
      return ( likediv ( e, at ) ) ;
2474
    }
2475
    case addptr_tag :
2476
    {
2477
      exp ptr_arg = son(*e);
2478
      exp offset_arg = bro(ptr_arg);
2479
      int fralign = frame_al_of_ptr(sh(ptr_arg));
2480
      if(fralign){
2481
	int offalign = frame_al1_of_offset(sh(offset_arg));
2482
#if 0
2483
	if(((offalign-1)&offalign)!=0){
2484
	  fail("Mixed frame offsets not supported");
2485
	}
2486
#endif
2487
	if(cees(offalign) && name(son(*e)) == current_env_tag) {
2488
	  setcallee_offset(son(*e));
2489
	}
2490
 
2491
 
2492
 
2493
#if 0
2494
	if(include_vcallees(fralign) && l_or_cees(offalign)){
2495
	  exp newexp = getexp(sh(ptr_arg),offset_arg,0,ptr_arg,nilexp,0,0,
2496
			      locptr_tag);
2497
	  bro(ptr_arg) = newexp;
2498
	  setlast(ptr_arg);
2499
	  son(*e) = newexp;
2500
	}
2501
#endif
2502
      }
2503
      return likediv(e,at);
2504
    }
2505
    case locptr_tag : 
2506
    case reff_tag :
2507
    case float_tag :
2508
    case offset_pad_tag :
2509
    case chvar_tag : {
2510
      exp *arg = &son ( *e ) ;
2511
      exp *pste;
2512
      needs nds ;
2513
      if (error_treatment_is_trap ( *e ))
2514
	specialext = 1;
2515
      nds =  shapeneeds ( sh ( *e ) );
2516
      nds = maxneeds ( scan ( arg, at ), nds ) ;
2517
      pste = ptr_position(ste);
2518
#if use_long_double
2519
      {
2520
	exp op = *pste ;
2521
 
2522
	if ( name ( sh ( op ) ) == doublehd ) {
2523
	  pnset ( nds, hasproccall ) ;
2524
	}
2525
      }
2526
#endif
2527
      return ( nds ) ;
2528
    }
2529
 
2530
    case cont_tag :
2531
    case contvol_tag : {
2532
      exp *arg = &son ( *e ) ;
2533
      needs nds ;
2534
      nds = maxneeds ( scan ( arg, at ), shapeneeds ( sh ( *e ) ) ) ;
2535
      nds.fixneeds = MAX_OF ( nds.fixneeds, 2 ) ;
2536
      return ( nds ) ;
2537
    }
2538
 
2539
    case mult_tag :
2540
    mult_tag_case : {
2541
      if (error_treatment_is_trap ( *e ))
2542
	specialext = 1;
2543
      return ( multneeds ( e, at ) ) ;
2544
    }
2545
 
2546
    case offset_mult_tag :
2547
    case offset_div_tag : {
2548
 
2549
      exp op1 = son(*e);
2550
      exp op2 = bro ( op1) ;
2551
      shape s = sh ( op2 ) ;
2552
      if ( name ( op2 ) == val_tag && no ( op2 ) == 8 &&
2553
	   name ( s ) == offsethd && al2 ( s ) >= 8 ) {
2554
	/* offset is one byte */
2555
	bro ( op1 ) = bro ( *e ) ;
2556
	if ( last ( *e ) ) {
2557
	  setlast ( op1 ) ;
2558
	} 
2559
	else {
2560
	  clearlast ( op1 ) ;
2561
	}
2562
	sh(op1) = sh(*e);
2563
	*e = op1 ;
2564
	if (name(*e) == val_tag)
2565
	  return ( shapeneeds ( sh ( *e ) ) ) ;	/* disps already in bytes */
2566
	else
2567
	  return ( scan ( e, at ) ) ;
2568
      }
2569
 
2570
      if ( nstare == offset_mult_tag ) goto mult_tag_case ;
2571
      /* FALL THROUGH */
2572
    }
2573
 
2574
    case div0_tag:
2575
    case div1_tag :
2576
    case div2_tag :
2577
    case offset_div_by_int_tag : {
2578
      if (error_treatment_is_trap ( *e ))
2579
	specialext = 1;
2580
      return ( divneeds ( e, at ) ) ;
2581
    }
2582
 
2583
    case offset_add_tag :
2584
    case offset_subtract_tag : {
2585
      if((al2(sh(son(*e))) == 1) && (al2(sh(bro(son(*e)))) != 1)){
2586
	make_bitfield_offset(bro(son(*e)),son(*e),0,sh(*e));
2587
      }
2588
      if((al2(sh(son(*e))) != 1) && (al2(sh(bro(son(*e)))) == 1)){
2589
	make_bitfield_offset(son(*e),*e,1,sh(*e));
2590
      }
2591
    }
2592
      /* FALL_THROUGH */
2593
    case component_tag : {
2594
      return ( likediv ( e, at ) ) ;
2595
    }
2596
    case offset_max_tag: case max_tag: case min_tag:
2597
    { needs nd;
2598
    nd = likediv(e, at);
2599
    nd.fixneeds = MAX_OF(nd.fixneeds, 3);
2600
    return nd;
2601
    } 
2602
 
2603
    case rem0_tag:
2604
    case mod_tag :
2605
    case rem2_tag : {
2606
      if (error_treatment_is_trap ( *e ))
2607
	specialext = 1;
2608
      return ( remneeds ( e, at ) ) ;
2609
    }
2610
 
2611
    case fdiv_tag :
2612
#if ( FBASE == 10 )
2613
    {
2614
      exp z = *e ;
2615
      exp a2 = bro ( son ( z ) ) ;
2616
 
2617
      if ( name ( a2 ) == real_tag ) {
2618
	/* replace X / const by X * ( 1.0 / const ) */
2619
	flt inverse ;
2620
	flt unitflt ;
2621
	unitflt = flptnos [ fone_no ] ;
2622
	if ( flt_div ( unitflt, flptnos [ no ( a2 ) ],
2623
		       &inverse ) == OKAY ) {
2624
	  int f = new_flpt () ;
2625
	  flptnos [f] = inverse ;
2626
	  no ( a2 ) = f ;
2627
	  setname ( z, fmult_tag ) ;
2628
	}
2629
      }
2630
    }
2631
    /* FALL THROUGH */
2632
#endif
2633
 
2634
    case fplus_tag :
2635
    case fminus_tag :
2636
    case fmult_tag : {
2637
      exp op = *e ;
2638
      exp a2 = bro ( son ( op ) ) ;
2639
      if (error_treatment_is_trap ( *e ))
2640
	specialext = 1;
2641
 
2642
      if ( !last ( a2 ) ) {
2643
	/* + and * can have > 2 parameters - make them diadic
2644
	   - can do better a + exp => let x = exp in a + x */
2645
	exp opn = getexp ( sh ( op ), op, 0, a2, nilexp,
2646
			   0, 0, name ( op ) ) ;
2647
	/* don't need to transfer error treatment - nans */
2648
	exp nd = getexp ( sh ( op ), bro ( op ), ( int ) last ( op ),
2649
			  opn, nilexp, 0, 1, ident_tag ) ;
2650
	exp id = getexp ( sh ( op ), op, 1, nd, nilexp,
2651
			  0, 0, name_tag ) ;
2652
	pt ( nd ) = id ;
2653
	bro ( son ( op ) ) = id ;
2654
	setlast ( op ) ;
2655
	bro ( op ) = nd ;
2656
	while ( !last ( a2 ) ) a2 = bro ( a2 ) ;
2657
	bro ( a2 ) = opn ;
2658
	*e = nd ;
2659
	return ( scan ( e, at ) ) ;
2660
      }
2661
      return ( fpop ( e, at ) ) ;
2662
    }
2663
 
2664
    case fmax_tag : {
2665
      return fpop(e,at);
2666
    }
2667
 
2668
    case field_tag : {
2669
      needs str ;
2670
      exp *arg = &son ( *e ) ;
2671
      if ( chase ( *e, arg ) ) {
2672
	/* field has been distributed */
2673
	exp stare = *e ;
2674
	exp ss = son ( stare ) ;
2675
	if ( !last ( stare ) ) clearlast ( ss ) ;
2676
	bro ( ss ) = bro ( stare ) ;
2677
	sh ( ss ) = sh ( stare ) ;
2678
	*e = ss ;
2679
	return ( scan ( e, at ) ) ;
2680
      }
2681
      str = scan ( arg, at ) ;
2682
      return ( maxneeds ( str, shapeneeds ( sh ( *e ) ) ) ) ;
2683
    }
2684
    case general_proc_tag :
2685
    case proc_tag : {
2686
      exp *bexp ;
2687
      exp *bat ;
2688
      needs body ;
2689
      exp stare = *e ;
2690
 
2691
      /* set number temp t-regs that can be used in proc */
2692
      maxfix = maxfix_tregs ;
2693
      maxfloat = MAXFLOAT_TREGS ;
2694
 
2695
      /* on SPARC tail recursion is harder than MIPS and less of a win
2696
	 but still worth implementing sometime */
2697
      assert ( do_tlrecursion==0 ) ;
2698
 
2699
      callerfortr = do_tlrecursion && !proc_has_setjmp ( stare ) &&
2700
	!proc_has_alloca ( stare ) &&
2701
	!proc_has_lv ( stare ) &&
2702
	!proc_uses_crt_env ( stare ) ;
2703
      stparam = 0 ;
2704
      fixparam = R_I0 ;
2705
      nonevis = 1 ;
2706
      specialext = proc_has_checkstack(*e);
2707
      rscope_level = 0 ;
2708
      gen_call = (name(stare) == general_proc_tag);
2709
      v_proc = proc_has_vcallees(*e);
2710
      callee_size = 0;
2711
#ifdef GENCOMPAT
2712
      trad_proc = !proc_may_have_callees(stare);
2713
#endif
2714
      /* scan the body of the proc */
2715
      bexp = &son ( *e ) ;
2716
      bat = bexp ;
2717
      body = scan ( bexp, &bat ) ;
2718
      if (specialext)
2719
	set_proc_uses_external ( *e ) ;
2720
#ifdef GENCOMPAT
2721
      if (!trad_proc) {
2722
#else
2723
      if(gen_call){
2724
#endif
2725
	callee_size += 4 * PTR_SZ;
2726
      }
2727
      /* should never require this in reg in C */
2728
      return ( body ) ;
2729
    }
2730
 
2731
    case alloca_tag : {
2732
      needs nds ;
2733
      if (checkalloc ( *e ))
2734
	specialext = 1;
2735
      nds = scan ( &son ( *e ), at ) ;
2736
      if ( nds.fixneeds < 2 ) nds.fixneeds = 2 ;
2737
      return ( nds ) ;
2738
    }
2739
    case trap_tag :{
2740
      specialext = 1;
2741
      return zeroneeds;
2742
    }
2743
    case special_tag :{
2744
      return zeroneeds;
2745
    }
2746
    case asm_tag:
2747
    {
2748
      needs nds;
2749
      nds = zeroneeds;
2750
      if (props(*e) != 0)
2751
	  fail ("~asm not in ~asm_sequence");
2752
      check_asm_seq (son(*e), 0);
2753
      /* clobber %o0..%o5,%o7 */
2754
      nds.fixneeds = MAX_OF ( nds.fixneeds, 8 ) ;
2755
      pnset ( nds, hasproccall ) ;
2756
      return ( nds ) ;
2757
    };
2758
    default : {
2759
      fail ( "Case not covered in needs scan" ) ;
2760
      return ( zeroneeds ) ;
2761
    }
2762
  }
2763
  /* NOT REACHED */
2764
}
2765