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