Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    Copyright (c) 1993 Open Software Foundation, Inc.
32
    Copyright (c) 1993 Open Software Foundation, Inc.
3
 
33
 
4
 
34
 
5
    All Rights Reserved
35
    All Rights Reserved
6
 
36
 
7
 
37
 
8
    Permission to use, copy, modify, and distribute this software
38
    Permission to use, copy, modify, and distribute this software
9
    and its documentation for any purpose and without fee is hereby
39
    and its documentation for any purpose and without fee is hereby
10
    granted, provided that the above copyright notice appears in all
40
    granted, provided that the above copyright notice appears in all
11
    copies and that both the copyright notice and this permission
41
    copies and that both the copyright notice and this permission
12
    notice appear in supporting documentation.
42
    notice appear in supporting documentation.
Line 14... Line 44...
14
 
44
 
15
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
45
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
16
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
46
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17
    PARTICULAR PURPOSE.
47
    PARTICULAR PURPOSE.
18
 
48
 
19
 
49
 
20
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
50
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
21
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
51
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
52
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
23
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
53
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
54
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
*/
55
*/
26
 
56
 
27
/*
57
/*
28
    		 Crown Copyright (c) 1997
58
    		 Crown Copyright (c) 1997
29
    
59
 
30
    This TenDRA(r) Computer Program is subject to Copyright
60
    This TenDRA(r) Computer Program is subject to Copyright
31
    owned by the United Kingdom Secretary of State for Defence
61
    owned by the United Kingdom Secretary of State for Defence
32
    acting through the Defence Evaluation and Research Agency
62
    acting through the Defence Evaluation and Research Agency
33
    (DERA).  It is made available to Recipients with a
63
    (DERA).  It is made available to Recipients with a
34
    royalty-free licence for its use, reproduction, transfer
64
    royalty-free licence for its use, reproduction, transfer
35
    to other parties and amendment for any purpose not excluding
65
    to other parties and amendment for any purpose not excluding
36
    product development provided that any such use et cetera
66
    product development provided that any such use et cetera
37
    shall be deemed to be acceptance of the following conditions:-
67
    shall be deemed to be acceptance of the following conditions:-
38
    
68
 
39
        (1) Its Recipients shall ensure that this Notice is
69
        (1) Its Recipients shall ensure that this Notice is
40
        reproduced upon any copies or amended versions of it;
70
        reproduced upon any copies or amended versions of it;
41
    
71
 
42
        (2) Any amended version of it shall be clearly marked to
72
        (2) Any amended version of it shall be clearly marked to
43
        show both the nature of and the organisation responsible
73
        show both the nature of and the organisation responsible
44
        for the relevant amendment or amendments;
74
        for the relevant amendment or amendments;
45
    
75
 
46
        (3) Its onward transfer from a recipient to another
76
        (3) Its onward transfer from a recipient to another
47
        party shall be deemed to be that party's acceptance of
77
        party shall be deemed to be that party's acceptance of
48
        these conditions;
78
        these conditions;
49
    
79
 
50
        (4) DERA gives no warranty or assurance as to its
80
        (4) DERA gives no warranty or assurance as to its
51
        quality or suitability for any purpose and DERA accepts
81
        quality or suitability for any purpose and DERA accepts
52
        no liability whatsoever in relation to any use to which
82
        no liability whatsoever in relation to any use to which
53
        it may be put.
83
        it may be put.
54
*/
84
*/
Line 135... Line 165...
135
 * Will evaluating exp 'e' cause last instruction to be a load from store?
165
 * Will evaluating exp 'e' cause last instruction to be a load from store?
136
 * Always false if generating diagnostics, we dont want to rearrange in
166
 * Always false if generating diagnostics, we dont want to rearrange in
137
 * this case as it makes debugging less obvious.
167
 * this case as it makes debugging less obvious.
138
 * This is not exact, register contents tracking may find a copy in reg.
168
 * This is not exact, register contents tracking may find a copy in reg.
139
 */
169
 */
140
#define LOADFROMSTORE(e) \
170
#define LOADFROMSTORE(e)\
141
	( \
171
	(\
142
	!diagnose \
172
	!diagnose \
143
	&& \
173
	&& \
144
	( \
174
	(\
145
	  (name(e) == cont_tag && (name(son(e)) != name_tag || INMEMIDENT(son(son(e))))) \
175
	 (name(e) == cont_tag && (name(son(e))!= name_tag || INMEMIDENT(son(son(e)))))\
146
	  || \
176
	  || \
147
	  (name(e) == name_tag && isglob(son(e))) /* load of TOC entry */ \
177
	  (name(e) == name_tag && isglob(son(e))) /* load of TOC entry */ \
148
	) \
178
	)\
149
	)
179
	)
150
int maxfix, maxfloat;		/* the maximum number of t-regs */
180
int maxfix, maxfloat;		/* the maximum number of t-regs */
151
bool tail_call;
181
bool tail_call;
152
bool gen_call;
182
bool gen_call;
153
long callee_size;
183
long callee_size;
Line 166... Line 196...
166
extern bool do_tlrecursion;
196
extern bool do_tlrecursion;
167
 
197
 
168
static bool nonevis = 1;
198
static bool nonevis = 1;
169
static bool rep_tag_scanned;
199
static bool rep_tag_scanned;
170
 
200
 
171
int scan_cond PROTO_S ((exp *,exp));
201
int scan_cond(exp *,exp);
172
needs scan PROTO_S ((exp *, exp ** ));
202
needs scan(exp *, exp **);
173
static void number_caller_parameter PROTO_S ((exp));
203
static void number_caller_parameter(exp);
174
static void number_callee_parameter PROTO_S ((exp));
204
static void number_callee_parameter(exp);
175
 
205
 
176
/* declaration of scan.
206
/* declaration of scan.
177
   needs is defined in procrectypes.h.
207
   needs is defined in procrectypes.h.
178
   This is a structure which has two integers giving
208
   This is a structure which has two integers giving
179
   the number of fixed and floating point registers required to contain live values
209
   the number of fixed and floating point registers required to contain live values
Line 191... Line 221...
191
This procedure effectively inserts a new declaration into an exp. This
221
This procedure effectively inserts a new declaration into an exp. This
192
is used to stop a procedure requiring more than the available number of
222
is used to stop a procedure requiring more than the available number of
193
registers.
223
registers.
194
****************************************************************/
224
****************************************************************/
195
 
225
 
196
static void cca PROTO_N ((to,x)) PROTO_T (exp * *to X exp * x)
226
static void cca(exp * *to, exp * x)
197
{
227
{
198
  if (name((**to))==diagnose_tag)
228
  if (name((**to)) ==diagnose_tag)
199
  {
229
  {
200
    *to = &son((**to));
230
    *to = &son((**to));
201
  }
231
  }
202
  if (x == (*to))
232
  if (x == (*to))
203
  {
233
  {
Line 242... Line 272...
242
static needs twofix = { 2, 0, 0, 0 };			/* needs 2 fix pt regs */
272
static needs twofix = { 2, 0, 0, 0 };			/* needs 2 fix pt regs */
243
static needs onefloat = { 0, 1, 0, 0 };			/* needs 1 flt pt regs */
273
static needs onefloat = { 0, 1, 0, 0 };			/* needs 1 flt pt regs */
244
static needs zeroneeds = { 0, 0, 0, 0 };		/* has no needs */
274
static needs zeroneeds = { 0, 0, 0, 0 };		/* has no needs */
245
 
275
 
246
 
276
 
247
static needs shapeneeds PROTO_N ((s)) PROTO_T (shape s)
277
static needs shapeneeds(shape s)
248
{				/* this gives the needs for manipulating a
278
{				/* this gives the needs for manipulating a
249
				 * value of shape s */
279
				 * value of shape s */
250
  if (is_floating(name(s)))
280
  if (is_floating(name(s)))
251
  {
281
  {
252
    return onefloat;
282
    return onefloat;
Line 264... Line 294...
264
    }
294
    }
265
  }
295
  }
266
}
296
}
267
 
297
 
268
 
298
 
269
static bool complex PROTO_N ((e)) PROTO_T (exp e)
299
static bool complex(exp e)
270
{				/* these are basically the expressions which
300
{				/* these are basically the expressions which
271
				 * cannot be accessed by a simple load or
301
				 * cannot be accessed by a simple load or
272
				 * store instruction */
302
				 * store instruction */
273
  if (name(e) == name_tag ||
303
  if (name(e) == name_tag ||
274
      (
304
     (
275
       name(e) == cont_tag && 
305
       name(e) == cont_tag &&
276
       name(son(e)) == name_tag 
306
       name(son(e)) == name_tag
277
       && isvar(son(son(e)))
307
       && isvar(son(son(e)))
278
       ) || 
308
      ) ||
279
      name(e) == val_tag || 
309
      name(e) == val_tag ||
280
      name(e) == real_tag
310
      name(e) == real_tag
281
      )
311
     )
282
  {
312
  {
283
    return 0;
313
    return 0;
284
  }
314
  }
285
  else
315
  else
286
  {
316
  {
287
    return 1;
317
    return 1;
288
  }
318
  }
289
}
319
}
290
 
320
 
291
 
321
 
292
needs commutative_scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
322
needs commutative_scan(exp * e, exp * *at)
293
{
323
{
294
  /*
324
  /*
295
   * does the scan on commutative and associative operations and may perform
325
   * does the scan on commutative and associative operations and may perform
296
   * various transformations allowed by these properties
326
   * various transformations allowed by these properties
297
   */
327
   */
Line 305... Line 335...
305
  ASSERT(father(son(*e)) == *e);
335
  ASSERT(father(son(*e)) == *e);
306
 
336
 
307
  /* scan the first operand - won't be a val_tag */
337
  /* scan the first operand - won't be a val_tag */
308
  a1 = scan(br, at);
338
  a1 = scan(br, at);
309
 
339
 
310
  /* 
340
  /*
311
   * if first operand is a proc, or ends with a load instruction,
341
   * if first operand is a proc, or ends with a load instruction,
312
   * it is not worth doing a commute to a later position
342
   * it is not worth doing a commute to a later position
313
   */
343
   */
314
  dont_commute = (a1.fixneeds >= maxfix || (a1.propsneeds & hasproccall))
344
  dont_commute = (a1.fixneeds >= maxfix || (a1.propsneeds & hasproccall))
315
		 || LOADFROMSTORE(*br);
345
		 || LOADFROMSTORE(*br);
316
 
346
 
317
  do
347
  do
318
  {
348
  {
319
    exp *prevbr;
349
    exp *prevbr;
320
 
350
 
321
    prevbr = br;
351
    prevbr = br;
322
    prev = *(br);
352
    prev = *(br);
323
    br = &bro(prev);
353
    br = &bro(prev);
324
    a2 = scan(br, at);
354
    a2 = scan(br, at);
325
    /* scan the next operand ... */
355
    /* scan the next operand ... */
326
    if (name(*(br)) != val_tag)
356
    if (name(*(br))!= val_tag)
327
    {
357
    {
328
      prop pc;
358
      prop pc;
329
      bool all_treg_needs;
359
      bool all_treg_needs;
330
 
360
 
331
      a1.floatneeds = max(a1.floatneeds, a2.floatneeds);
361
      a1.floatneeds = max(a1.floatneeds, a2.floatneeds);
332
      pc = a2.propsneeds & hasproccall;
362
      pc = a2.propsneeds & hasproccall;
333
      all_treg_needs = (a2.fixneeds >= maxfix || pc != 0);
363
      all_treg_needs = (a2.fixneeds >= maxfix || pc != 0);
334
 
364
 
335
      if ( !dont_commute
365
      if (!dont_commute
336
	   &&
366
	   &&
337
	   (all_treg_needs || LOADFROMSTORE(*br))
367
	  (all_treg_needs || LOADFROMSTORE(*br))
338
	   &&
368
	   &&
339
	   (a1.fixneeds < maxfix && (a1.propsneeds & hasproccall) == 0)
369
	  (a1.fixneeds < maxfix && (a1.propsneeds & hasproccall) == 0)
340
	 )
370
	)
341
      {
371
      {
342
	/*
372
	/*
343
	 * ...its evaluation will call a proc, or ends with a load instruction,
373
	 * ...its evaluation will call a proc, or ends with a load instruction,
344
	 * so put it first
374
	 * so put it first
345
	 */
375
	 */
Line 352... Line 382...
352
	if (lcop)
382
	if (lcop)
353
	  setlast(prev);
383
	  setlast(prev);
354
	bro(cop) = op1;
384
	bro(cop) = op1;
355
	clearlast(cop);
385
	clearlast(cop);
356
	son(dad) = cop;
386
	son(dad) = cop;
357
	br = (prev == op1) ? &bro(cop) : prevbr;
387
	br = (prev == op1)? &bro(cop): prevbr;
358
	dont_commute = 1;
388
	dont_commute = 1;
359
	a1.fixneeds = max(a2.fixneeds, a1.fixneeds + 1);
389
	a1.fixneeds = max(a2.fixneeds, a1.fixneeds + 1);
360
	a1.propsneeds |= a2.propsneeds;
390
	a1.propsneeds |= a2.propsneeds;
361
	a1.maxargs = max(a1.maxargs, a2.maxargs);
391
	a1.maxargs = max(a1.maxargs, a2.maxargs);
362
      }
392
      }
Line 382... Line 412...
382
 
412
 
383
  return a1;
413
  return a1;
384
}
414
}
385
 
415
 
386
 
416
 
387
needs non_commutative_scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
417
needs non_commutative_scan(exp * e, exp * *at)
388
{
418
{
389
  /*
419
  /*
390
   * scan non-commutative fix pt operation
420
   * scan non-commutative fix pt operation
391
   */
421
   */
392
  needs l;
422
  needs l;
Line 415... Line 445...
415
    l.maxargs = max(l.maxargs, r.maxargs);
445
    l.maxargs = max(l.maxargs, r.maxargs);
416
  }
446
  }
417
  return l;
447
  return l;
418
}
448
}
419
 
449
 
420
static needs fpop PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
450
static needs fpop(exp * e, exp * *at)
421
{
451
{
422
  /* scans diadic floating point operation  */
452
  /* scans diadic floating point operation  */
423
  needs l;
453
  needs l;
424
  needs r;
454
  needs r;
425
  exp op = *(e);
455
  exp op = *(e);
Line 466... Line 496...
466
 
496
 
467
Calculates a needs value. Each element of which is the maximum of the
497
Calculates a needs value. Each element of which is the maximum of the
468
corresponding elements in the two parameter needs
498
corresponding elements in the two parameter needs
469
**********************************************************************/
499
**********************************************************************/
470
 
500
 
471
static needs maxneeds PROTO_N ((a,b)) PROTO_T (needs a X needs b)
501
static needs maxneeds(needs a, needs b)
472
{
502
{
473
  needs an;
503
  needs an;
474
 
504
 
475
  an.fixneeds = max(a.fixneeds, b.fixneeds);
505
  an.fixneeds = max(a.fixneeds, b.fixneeds);
476
  an.floatneeds = max(a.floatneeds, b.floatneeds);
506
  an.floatneeds = max(a.floatneeds, b.floatneeds);
Line 483... Line 513...
483
/**********************************************************************
513
/**********************************************************************
484
	maxsequence
514
	maxsequence
485
 
515
 
486
**********************************************************************/
516
**********************************************************************/
487
 
517
 
488
static needs maxtup PROTO_N ((e,at)) PROTO_T (exp e X exp ** at)
518
static needs maxtup(exp e, exp ** at)
489
{				/* calculates the needs of a tuple of
519
{				/* calculates the needs of a tuple of
490
				 * expressions; any new declarations required
520
				 * expressions; any new declarations required
491
				 * by a component expression will replace the
521
				 * by a component expression will replace the
492
				 * component expression */
522
				 * component expression */
493
  exp *stat = &son(e);
523
  exp *stat = &son(e);
494
  needs an;
524
  needs an;
495
 
525
 
496
  an = zeroneeds;
526
  an = zeroneeds;
497
  if(*stat==nilexp )
527
  if (*stat==nilexp)
498
  {
528
  {
499
    return an;
529
    return an;
500
  }
530
  }
501
  while (an = maxneeds(an, scan(stat, at)), !last(*stat))
531
  while (an = maxneeds(an, scan(stat, at)), !last(*stat))
502
  {
532
  {
Line 504... Line 534...
504
  }
534
  }
505
  return an;
535
  return an;
506
}
536
}
507
 
537
 
508
 
538
 
509
static bool unchanged PROTO_N ((usedname,ident)) PROTO_T (exp usedname X exp ident)
539
static bool unchanged(exp usedname, exp ident)
510
{
540
{
511
  /*
541
  /*
512
   * finds if usedname is only used in cont operation or as result of ident
542
   * finds if usedname is only used in cont operation or as result of ident
513
   * i.e. value of name is unchanged over its scope
543
   * i.e. value of name is unchanged over its scope
514
   */
544
   */
Line 516... Line 546...
516
 
546
 
517
  while (uses != nilexp)
547
  while (uses != nilexp)
518
  {
548
  {
519
    if (intnl_to(ident, uses))
549
    if (intnl_to(ident, uses))
520
    {
550
    {
521
      if (!last(uses) || name(bro(uses)) != cont_tag)
551
      if (!last(uses) || name(bro(uses))!= cont_tag)
522
      {
552
      {
523
	exp z = uses;
553
	exp z = uses;
524
 
554
 
525
	while (z != ident)
555
	while (z != ident)
526
	{
556
	{
527
	  if (!last(z) ||
557
	  if (!last(z) ||
528
	      (name(bro(z)) != seq_tag && name(bro(z)) != ident_tag))
558
	     (name(bro(z))!= seq_tag && name(bro(z))!= ident_tag))
529
	  {
559
	  {
530
	    return 0;
560
	    return 0;
531
	  }
561
	  }
532
	  z = bro(z);
562
	  z = bro(z);
533
	}
563
	}
Line 537... Line 567...
537
  }
567
  }
538
  return 1;
568
  return 1;
539
}
569
}
540
 
570
 
541
 
571
 
542
static exp *ptr_position PROTO_N ((e)) PROTO_T (exp e)
572
static exp *ptr_position(exp e)
543
{
573
{
544
  exp *a;
574
  exp *a;
545
  exp dad = father(e);
575
  exp dad = father(e);
546
 
576
 
547
  if (son(dad) == e)
577
  if (son(dad) == e)
Line 550... Line 580...
550
  }
580
  }
551
  else
581
  else
552
  {
582
  {
553
    exp sib = son(dad);
583
    exp sib = son(dad);
554
 
584
 
555
    while (bro(sib) != e)
585
    while (bro(sib)!= e)
556
    {
586
    {
557
      sib = bro(sib);
587
      sib = bro(sib);
558
    }
588
    }
559
    a = &bro(sib);
589
    a = &bro(sib);
560
  }
590
  }
Line 569... Line 599...
569
 * space in the calling work-space for the result struct whether or not the
599
 * space in the calling work-space for the result struct whether or not the
570
 * value is used e.g. as in f(x); or f(x).a etc. This proc is part of the
600
 * value is used e.g. as in f(x); or f(x).a etc. This proc is part of the
571
 * mechanism to determine whether it is necessary to insert a dummy
601
 * mechanism to determine whether it is necessary to insert a dummy
572
 * declaration to ensure that this space exists.
602
 * declaration to ensure that this space exists.
573
 */
603
 */
574
static bool chase PROTO_N ((sel,e)) PROTO_T (exp sel X exp * e)
604
static bool chase(exp sel, exp * e)
575
{
605
{
576
  /* distribute selection throughout compound expressions */
606
  /* distribute selection throughout compound expressions */
577
  bool b = 0;
607
  bool b = 0;
578
  exp *one;
608
  exp *one;
579
 
609
 
Line 616... Line 646...
616
	return chase(sel, e);
646
	return chase(sel, e);
617
      }				/* ... continue to default */
647
      }				/* ... continue to default */
618
    }
648
    }
619
  default:
649
  default:
620
    {
650
    {
621
      if (son(sel) != *e)
651
      if (son(sel)!= *e)
622
      {				/* only change if not outer */
652
      {				/* only change if not outer */
623
	exp stare = *e;
653
	exp stare = *e;
624
	exp newsel = getexp(sh(sel), bro(stare), last(stare), stare, nilexp,
654
	exp newsel = getexp(sh(sel), bro(stare), last(stare), stare, nilexp,
625
			    props(sel), no(sel), name(sel));
655
			    props(sel), no(sel), name(sel));
626
 
656
 
Line 661... Line 691...
661
of the exp in each case.
691
of the exp in each case.
662
 
692
 
663
********************************************************************/
693
********************************************************************/
664
 
694
 
665
 
695
 
666
needs scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
696
needs scan(exp * e, exp * *at)
667
{
697
{
668
  /*
698
  /*
669
   * e is the expression to be scanned, at is the place to put any new decs .
699
   * e is the expression to be scanned, at is the place to put any new decs .
670
   * NB order of recursive calls with same at is critical
700
   * NB order of recursive calls with same at is critical
671
   */
701
   */
Line 673... Line 703...
673
  int nstare = name(ste);
703
  int nstare = name(ste);
674
  static long exp_num = 0;		/* count of exps we evaluate */
704
  static long exp_num = 0;		/* count of exps we evaluate */
675
 
705
 
676
  exp_num++;
706
  exp_num++;
677
  ASSERT(*e != nilexp);
707
  ASSERT(*e != nilexp);
678
  
708
 
679
 
709
 
680
  switch (nstare)
710
  switch (nstare)
681
  {
711
  {
682
   case 0:
712
   case 0:
683
    {/* zero_tag */
713
    {/* zero_tag */
Line 690... Line 720...
690
   case ncopies_tag:
720
   case ncopies_tag:
691
    {
721
    {
692
      needs nl;
722
      needs nl;
693
      bool cantdo;
723
      bool cantdo;
694
      exp dad;
724
      exp dad;
695
      
725
 
696
      if(nstare==nof_tag && son(ste)==nilexp)
726
      if (nstare==nof_tag && son(ste) ==nilexp)
697
	return zeroneeds;
727
	return zeroneeds;
698
      
728
 
699
      if (name(ste) == ncopies_tag && name(son(ste)) != name_tag
729
      if (name(ste) == ncopies_tag && name(son(ste))!= name_tag
700
	  && name(son(ste)) != val_tag)
730
	  && name(son(ste))!= val_tag)
701
      {
731
      {
702
	nl = scan(&son(*e), at);
732
	nl = scan(&son(*e), at);
703
	cca(at, &son(*e));
733
	cca(at, &son(*e));
704
      }
734
      }
705
      else
735
      else
706
      {
736
      {
707
	nl = maxtup(*(e), at);
737
	nl = maxtup(*(e), at);
708
      }
738
      }
709
      ste = *e;
739
      ste = *e;
710
      dad = father(ste);
740
      dad = father(ste);
711
      if (name(dad) == compound_tag || 
741
      if (name(dad) == compound_tag ||
712
	  name(dad) == nof_tag || 
742
	  name(dad) == nof_tag ||
713
	  name(dad) == concatnof_tag)
743
	  name(dad) == concatnof_tag)
714
      {
744
      {
715
	cantdo = 0;
745
	cantdo = 0;
716
      }
746
      }
717
      else if (last(ste))
747
      else if (last(ste))
718
      {
748
      {
719
	if (name(bro(ste)) == ass_tag)
749
	if (name(bro(ste)) == ass_tag)
720
	{
750
	{
721
	  exp a = son(bro(ste));
751
	  exp a = son(bro(ste));
722
 
752
 
723
	  cantdo = (name(a) != name_tag || !isvar(son(a)));
753
	  cantdo = (name(a)!= name_tag || !isvar(son(a)));
724
	}
754
	}
725
	else
755
	else
726
	{
756
	{
727
	  cantdo = 1;
757
	  cantdo = 1;
728
	}
758
	}
729
      }
759
      }
730
      else if (last(bro(ste)))
760
      else if (last(bro(ste)))
731
      {
761
      {
732
	cantdo = (name(bro(bro(ste))) != ident_tag);
762
	cantdo = (name(bro(bro(ste)))!= ident_tag);
733
      }
763
      }
734
      else
764
      else
735
      {
765
      {
736
	cantdo = 1;
766
	cantdo = 1;
737
      }
767
      }
738
      
768
 
739
 
769
 
740
      if (cantdo)
770
      if (cantdo)
741
      {
771
      {
742
	/* can only deal with tuples in simple assignment or identity */
772
	/* can only deal with tuples in simple assignment or identity */
743
	int prps = (nl.propsneeds & hasproccall) << 1;
773
	int prps = (nl.propsneeds & hasproccall) << 1;
744
 
774
 
745
	cca(at, ptr_position(ste));
775
	cca(at, ptr_position(ste));
746
	nl = shapeneeds(sh(*(e)));
776
	nl = shapeneeds(sh(*(e)));
747
	nl.propsneeds |= morefix;
777
	nl.propsneeds |= morefix;
748
	nl.propsneeds |= prps;
778
	nl.propsneeds |= prps;
749
      }
779
      }
750
 
780
 
751
      nl.fixneeds = max(nl.fixneeds,2);
781
      nl.fixneeds = max(nl.fixneeds,2);
752
      
782
 
753
      return nl;
783
      return nl;
754
    };
784
    };
755
 
785
 
756
  case cond_tag:
786
  case cond_tag:
757
    {
787
    {
758
      if (scan_cond(e, nilexp) !=0) 
788
      if (scan_cond(e, nilexp)!=0)
759
      {
789
      {
760
	return scan(e, at);
790
	return scan(e, at);
761
      }                   /* Else goto next case */
791
      }                   /* Else goto next case */
762
    }
792
    }
763
    /*FALLTHROUGH*/
793
    /*FALLTHROUGH*/
764
   case rep_tag:
794
   case rep_tag:
765
   case solve_tag:
795
   case solve_tag:
766
    {
796
    {
767
      exp *stat;
797
      exp *stat;
768
      exp *statat;
798
      exp *statat;
769
      needs an;
799
      needs an;
770
 
800
 
771
      stat = &son(*e);
801
      stat = &son(*e);
772
      statat = stat;
802
      statat = stat;
773
      an = zeroneeds;
803
      an = zeroneeds;
774
      rep_tag_scanned=0;
804
      rep_tag_scanned=0;
775
      /* 
805
      /*
776
       * Simply scan each argument
806
       * Simply scan each argument
777
       * The arguments are effectively independent pieces
807
       * The arguments are effectively independent pieces
778
       * of code for these constructions 
808
       * of code for these constructions
779
       */
809
       */
780
      /***********************************************************/
810
      /***********************************************************/
781
      /*    _        _________                                   */
811
      /*    _        _________                                   */
782
      /*   |_|----->|        _|                                  */
812
      /*   |_|----->|        _|                                  */
783
      /*  /         |    _  |_|                                  */
813
      /*  /         |    _  |_|                                  */
784
      /* e          |___|_|___|                                  */
814
      /* e          |___|_|___|                                  */
785
      /*               / |                                       */
815
      /*               / |                                       */
786
      /*              /  |                                       */
816
      /*              /  |                                       */
787
      /*          stat(1)|       stat(2)       stat(3)           */
817
      /*          stat(1)|       stat(2)       stat(3)           */
788
      /*             ____v____  /  _________  /  _________       */ 
818
      /*             ____v____  /  _________  /  _________       */
789
      /*            |        _|/  |        _|/  |        _|      */
819
      /*            |        _|/  |        _|/  |        _|      */
790
      /*            |    _  |_|-->|    _  |_|-->|    _  |_|-->   */
820
      /*            |    _  |_|-->|    _  |_|-->|    _  |_|-->   */
791
      /*            |___|_|___|   |___|_|___|   |___|_|___|      */
821
      /*            |___|_|___|   |___|_|___|   |___|_|___|      */
792
      /*                                                         */
822
      /*                                                         */
793
      /***********************************************************/
823
      /***********************************************************/
794
      while (an = maxneeds(an, scan(stat, &statat)), !last(*(stat)))
824
      while (an = maxneeds(an, scan(stat, &statat)), !last(*(stat)))
795
      {
825
      {
796
	stat = &bro(*stat);
826
	stat = &bro(*stat);
797
	statat = stat;
827
	statat = stat;
798
      }
828
      }
799
      if(name(*e)==rep_tag)
829
      if (name(*e) ==rep_tag)
800
      {
830
      {
801
	if (rep_tag_scanned==0)
831
	if (rep_tag_scanned==0)
802
	{
832
	{
803
	  setinnermost(*e);
833
	  setinnermost(*e);
804
	}
834
	}
Line 806... Line 836...
806
	{
836
	{
807
	  clearinnermost(*e);
837
	  clearinnermost(*e);
808
	}
838
	}
809
      }
839
      }
810
      rep_tag_scanned=1;
840
      rep_tag_scanned=1;
811
      if ((an.propsneeds & usesproccall) != 0)
841
      if ((an.propsneeds & usesproccall)!= 0)
812
      {
842
      {
813
	an.propsneeds |= hasproccall;
843
	an.propsneeds |= hasproccall;
814
      }
844
      }
815
      return an;
845
      return an;
816
    }
846
    }
Line 822... Line 852...
822
      needs an;
852
      needs an;
823
      int expn = exp_num;
853
      int expn = exp_num;
824
 
854
 
825
      ASSERT(!last(son(*e)));
855
      ASSERT(!last(son(*e)));
826
      ASSERT(last(bro(son(*e))));
856
      ASSERT(last(bro(son(*e))));
827
 
857
 
828
      /****************************************/
858
      /****************************************/
829
      /*    _     _________                   */
859
      /*    _     _________                   */
830
      /*   |_|-->| labst   |                  */
860
      /*   |_|-->| labst   |                  */
831
      /*  /      |    _    |                  */
861
      /*  /      |    _    |                  */
832
      /* e       |___|_|___|   stat           */
862
      /* e       |___|_|___|   stat           */
Line 839... Line 869...
839
      /****************************************/
869
      /****************************************/
840
      stat = &bro(son(*e));
870
      stat = &bro(son(*e));
841
      statat = stat;
871
      statat = stat;
842
      an = scan(stat, &statat);
872
      an = scan(stat, &statat);
843
 
873
 
844
      if ((an.propsneeds & usesproccall) != 0)
874
      if ((an.propsneeds & usesproccall)!= 0)
845
      {
875
      {
846
	an.propsneeds |= hasproccall;
876
	an.propsneeds |= hasproccall;
847
      }
877
      }
848
      
878
 
849
      /*
879
      /*
850
       * ptno(son()) is set to exp number so that make_code can estimate
880
       * ptno(son()) is set to exp number so that make_code can estimate
851
       * distances of conditional branches, which is limited on POWER.
881
       * distances of conditional branches, which is limited on POWER.
852
       */
882
       */
853
      ptno(son(*e)) = expn;
883
      ptno(son(*e)) = expn;
Line 876... Line 906...
876
      bool uses_R_RESULT;
906
      bool uses_R_RESULT;
877
      bool uses_FR_RESULT;
907
      bool uses_FR_RESULT;
878
#if 0
908
#if 0
879
      /* We can't do this because of env_offset not appearing in the list of uses */
909
      /* We can't do this because of env_offset not appearing in the list of uses */
880
      if (pt(stare) == nilexp)
910
      if (pt(stare) == nilexp)
881
      {
911
      {
882
	/* no uses, should have caonly flag set (not already set for params) */
912
	/* no uses, should have caonly flag set (not already set for params) */
883
	setcaonly(stare);
913
	setcaonly(stare);
884
      }
914
      }
885
#endif 
915
#endif
886
      if (isvar(stare) && (!iscaonly(stare) || all_variables_visible))
916
      if (isvar(stare) && (!iscaonly(stare) || all_variables_visible))
887
      {
917
      {
888
	setvis(stare);
918
	setvis(stare);
889
      }
919
      }
890
      
920
 
891
      if (isparam(stare))
921
      if (isparam(stare))
892
      {
922
      {
893
	if (name(son(stare))!=formal_callee_tag)
923
	if (name(son(stare))!=formal_callee_tag)
894
	{
924
	{
895
	  number_caller_parameter(stare);
925
	  number_caller_parameter(stare);
896
	}
926
	}
897
	else
927
	else
898
	{
928
	{
899
	  number_callee_parameter(stare);
929
	  number_callee_parameter(stare);
900
	}
930
	}
901
      }
931
      }
902
            	
932
 
903
      nonevis &= !isvis(stare);
933
      nonevis &= !isvis(stare);
904
      
934
 
905
      /* Scan the body of the ident */
935
      /* Scan the body of the ident */
906
      arg = &bro(son(stare));
936
      arg = &bro(son(stare));
907
      bdy = scan(arg, &arg);
937
      bdy = scan(arg, &arg);
908
      /* Scan the def of the ident */
938
      /* Scan the def of the ident */
909
      arg = &son(stare);
939
      arg = &son(stare);
910
      defneeds = scan(arg, &arg);
940
      defneeds = scan(arg, &arg);
911
      ASSERT(stare == *e);
941
      ASSERT(stare == *e);
912
      
942
 
913
      nonevis = old_nonevis;
943
      nonevis = old_nonevis;
914
      t = son(stare);
944
      t = son(stare);
915
      s = bro(t);
945
      s = bro(t);
916
      fxregble = fixregable(stare);
946
      fxregble = fixregable(stare);
917
      flregble = floatregable(stare);
947
      flregble = floatregable(stare);
918
      uses_R_RESULT = (bdy.propsneeds & uses_R_RESULT_bit)!=0;
948
      uses_R_RESULT = (bdy.propsneeds & uses_R_RESULT_bit)!=0;
919
      uses_FR_RESULT = (bdy.propsneeds & uses_FR_RESULT_bit)!=0;
949
      uses_FR_RESULT = (bdy.propsneeds & uses_FR_RESULT_bit)!=0;
920
/*****************************************************************************/
950
/*****************************************************************************/
921
      if (name(son(stare))==caller_name_tag)
951
      if (name(son(stare)) ==caller_name_tag)
922
      {
952
      {
923
	/*
953
	/*
924
	 * IDENT is a caller in postlude 
954
	 * IDENT is a caller in postlude
925
	 */
955
	 */
926
	no(stare) = R_NO_REG;
956
	no(stare) = R_NO_REG;
927
	/* At present all callers in postludes are only allowed on the stack*/
957
	/* At present all callers in postludes are only allowed on the stack*/
928
	/* This is because of the problems created by nested postludes */
958
	/* This is because of the problems created by nested postludes */
929
      }
959
      }
930
/*****************************************************************************/
960
/*****************************************************************************/
931
      else if (isparam(stare) && name(son(stare))==formal_callee_tag)
961
      else if (isparam(stare) && name(son(stare)) ==formal_callee_tag)
932
      {
962
      {
933
	/*
963
	/*
934
	 * IDENT is a callee parameter
964
	 * IDENT is a callee parameter
935
	 */
965
	 */
936
	no(stare) = R_NO_REG;
966
	no(stare) = R_NO_REG;
Line 943... Line 973...
943
	 */
973
	 */
944
	if (do_profile)
974
	if (do_profile)
945
	{
975
	{
946
	  /* mcount is called after the last param is dealt with */
976
	  /* mcount is called after the last param is dealt with */
947
	  /* So we must put all params on the stack or in s-regs */
977
	  /* So we must put all params on the stack or in s-regs */
948
	  bdy.propsneeds |= hasproccall;  
978
	  bdy.propsneeds |= hasproccall;
949
	}
979
	}
950
	no(stare)=R_NO_REG;
980
	no(stare) =R_NO_REG;
951
      }
981
      }
952
/*****************************************************************************/
982
/*****************************************************************************/
953
      else
983
      else
954
      {
984
      {
955
	/*
985
	/*
956
	 * IDENT is a normal ident
986
	 * IDENT is a normal ident
957
	 */
987
	 */
958
	ASSERT(!isparam(*e));
988
	ASSERT(!isparam(*e));
959
 
989
 
960
	
990
 
961
	if (!isvis(*e) && 
991
	if (!isvis(*e) &&
962
	    (bdy.propsneeds & anyproccall)==0 &&
992
	   (bdy.propsneeds & anyproccall) ==0 &&
963
	    (
993
	   (
964
	     (uses_R_RESULT==0 && fxregble) || 
994
	    (uses_R_RESULT==0 && fxregble) ||
965
	     (uses_FR_RESULT==0 && flregble)
995
	    (uses_FR_RESULT==0 && flregble)
966
	     ) &&
996
	    ) &&
967
	    (
997
	   (
968
	     name(t) == apply_tag || /* Let a := f()*/
998
	     name(t) == apply_tag || /* Let a := f()*/
969
	     (name(s) == seq_tag && name(bro(son(s))) == res_tag &&
999
	    (name(s) == seq_tag && name(bro(son(s))) == res_tag &&
970
	      name(son(bro(son(s)))) == cont_tag && isvar(stare) &&
1000
	      name(son(bro(son(s)))) == cont_tag && isvar(stare) &&
971
	      name(son(son(bro(son(s))))) == name_tag &&
1001
	      name(son(son(bro(son(s))))) == name_tag &&
972
	      son(son(son(bro(son(s))))) == stare
1002
	      son(son(son(bro(son(s))))) == stare
973
	      )			/* Let a := ..; return cont a */
1003
	      )			/* Let a := ..; return cont a */
974
	     )
-
 
975
	    )
1004
	    )
-
 
1005
	   )
976
	{	
1006
	{
977
	  /* Ident suitable for res reg */
1007
	  /* Ident suitable for res reg */
978
	  if (fxregble)
1008
	  if (fxregble)
979
	  {
1009
	  {
980
	    props(stare) |= inreg_bits;
1010
	    props(stare) |= inreg_bits;
981
	    no(stare) = R_RESULT;
1011
	    no(stare) = R_RESULT;
Line 989... Line 1019...
989
	  }
1019
	  }
990
	}
1020
	}
991
 
1021
 
992
#if 1
1022
#if 1
993
	else if (!isvar(*e) && !isparam(*e) &&
1023
	else if (!isvar(*e) && !isparam(*e) &&
994
		 ((name(t) == reff_tag && name(son(t)) == cont_tag &&
1024
		((name(t) == reff_tag && name(son(t)) == cont_tag &&
995
		   name(son(son(t))) == name_tag && isvar(son(son(son(t))))
1025
		   name(son(son(t))) == name_tag && isvar(son(son(son(t))))
996
		   && !isvis(son(son(son(t)))) && !isglob(son(son(son(t))))
1026
		   && !isvis(son(son(son(t)))) && !isglob(son(son(son(t))))
997
		   && unchanged(son(son(son(t))), stare)
1027
		   && unchanged(son(son(son(t))), stare)
998
	  /*
1028
	  /*
999
	   * reff cont variable-not assigned to in scope
1029
	   * reff cont variable-not assigned to in scope
1000
	   */
1030
	   */
1001
		   ) ||
1031
		  ) ||
1002
		  (name(t) == cont_tag && name(son(t)) == name_tag &&
1032
		 (name(t) == cont_tag && name(son(t)) == name_tag &&
1003
		   isvar(son(son(t))) && !isvis(son(son(t))) && !isglob(son(son(t)))
1033
		   isvar(son(son(t))) && !isvis(son(son(t))) && !isglob(son(son(t)))
1004
		   && unchanged(son(son(t)), stare)
1034
		   && unchanged(son(son(t)), stare)
1005
	  /*
1035
	  /*
1006
	   * cont variable - not assigned to in scope
1036
	   * cont variable - not assigned to in scope
1007
	   */
1037
	   */
1008
		   )
-
 
1009
		  )
1038
		  )
1010
	  )
1039
		 )
-
 
1040
	 )
1011
	{
1041
	{
1012
	  props(stare) |= defer_bit;
1042
	  props(stare) |= defer_bit;
1013
	  /* dont take space for this dec */
1043
	  /* dont take space for this dec */
1014
	}
1044
	}
1015
#endif
1045
#endif
1016
#if 0	/* dont undo large const in loop optimisation */
1046
#if 0	/* dont undo large const in loop optimisation */
1017
	else if (!isvar(stare) &&
1047
	else if (!isvar(stare) &&
1018
		 (isusereg(stare) == 0)
1048
		(isusereg(stare) == 0)
1019
		 && (name(t) == name_tag || name(t) == val_tag))
1049
		 && (name(t) == name_tag || name(t) == val_tag))
1020
	{
1050
	{
1021
	  props(stare) |= defer_bit;
1051
	  props(stare) |= defer_bit;
1022
	  /* dont take space for this dec */
1052
	  /* dont take space for this dec */
1023
	}
1053
	}
Line 1039... Line 1069...
1039
	}
1069
	}
1040
#endif
1070
#endif
1041
	/* All the parameters have been scanned at this point so
1071
	/* All the parameters have been scanned at this point so
1042
	   maxfix gives the total no of free t-regs */
1072
	   maxfix gives the total no of free t-regs */
1043
	else if (fxregble &&
1073
	else if (fxregble &&
1044
		 bdy.fixneeds < maxfix && 
1074
		 bdy.fixneeds < maxfix &&
1045
		 (bdy.propsneeds & morefix) == 0 && 
1075
		(bdy.propsneeds & morefix) == 0 &&
1046
		 ((bdy.propsneeds & anyproccall)==0
1076
		((bdy.propsneeds & anyproccall) ==0
1047
#if 0
1077
#if 0
1048
		  ||
1078
		  ||
1049
		  tempdec(stare, ((bdy.propsneeds & morefix)==0) && bdy.fixneeds<2)
1079
		  tempdec(stare,((bdy.propsneeds & morefix) ==0) && bdy.fixneeds<2)
1050
#endif
1080
#endif
1051
		  )
-
 
1052
		 )
1081
		 )
-
 
1082
		)
1053
	{
1083
	{
1054
	  if ( (props(stare) & notparreg) ==0)
1084
	  if ((props(stare) & notparreg) ==0)
1055
	  {
1085
	  {
1056
	    no(stare) = R_NO_REG;
1086
	    no(stare) = R_NO_REG;
1057
	    props(stare) |= inreg_bits;
1087
	    props(stare) |= inreg_bits;
1058
	    if (uses_R_RESULT==1)
1088
	    if (uses_R_RESULT==1)
1059
	    {
1089
	    {
Line 1061... Line 1091...
1061
	    }
1091
	    }
1062
	    bdy.fixneeds += 1;
1092
	    bdy.fixneeds += 1;
1063
	  }
1093
	  }
1064
	}
1094
	}
1065
	else if (flregble &&
1095
	else if (flregble &&
1066
		 bdy.floatneeds < maxfloat && 
1096
		 bdy.floatneeds < maxfloat &&
1067
		 (bdy.propsneeds & morefloat) == 0 && 
1097
		(bdy.propsneeds & morefloat) == 0 &&
1068
		 ((bdy.propsneeds & anyproccall)==0
1098
		((bdy.propsneeds & anyproccall) ==0
1069
#if 0
1099
#if 0
1070
		  ||
1100
		  ||
1071
		  tempdec(stare, ((bdy.propsneeds & morefloat) == 0 &&
1101
		  tempdec(stare,((bdy.propsneeds & morefloat) == 0 &&
1072
				     bdy.floatneeds < 1))
1102
				     bdy.floatneeds < 1))
1073
#endif
1103
#endif
1074
		  )
-
 
1075
		 )
1104
		 )
-
 
1105
		)
1076
	{
1106
	{
1077
	  if ( (props(stare) & notparreg) == 0)
1107
	  if ((props(stare) & notparreg) == 0)
1078
	  {
1108
	  {
1079
	    /* Ident suitable for float t-reg */
1109
	    /* Ident suitable for float t-reg */
1080
	    no(stare) = FR_NO_REG;
1110
	    no(stare) = FR_NO_REG;
1081
	    props(stare) |= infreg_bits;
1111
	    props(stare) |= infreg_bits;
1082
	    if (uses_FR_RESULT==1)
1112
	    if (uses_FR_RESULT==1)
Line 1094... Line 1124...
1094
	   */
1124
	   */
1095
	  no(stare) = R_NO_REG;
1125
	  no(stare) = R_NO_REG;
1096
	}
1126
	}
1097
      }
1127
      }
1098
      bdy = maxneeds(bdy, defneeds);
1128
      bdy = maxneeds(bdy, defneeds);
1099
      if ((bdy.propsneeds & usesproccall) != 0)
1129
      if ((bdy.propsneeds & usesproccall)!= 0)
1100
      {
1130
      {
1101
	bdy.propsneeds |= hasproccall;
1131
	bdy.propsneeds |= hasproccall;
1102
      }
1132
      }
1103
      return bdy;
1133
      return bdy;
1104
    }
1134
    }
Line 1114... Line 1144...
1114
    {
1144
    {
1115
      exp *arg = &bro(son(*e));
1145
      exp *arg = &bro(son(*e));
1116
      needs an;
1146
      needs an;
1117
      exp *stat;
1147
      exp *stat;
1118
      exp * atsc = &son(son(*e));
1148
      exp * atsc = &son(son(*e));
1119
      for(;;) 
1149
      for (;;)
1120
      {
1150
      {
1121
	exp sc = *atsc;
1151
	exp sc = *atsc;
1122
	if (name(sc) == cond_tag && name(sh(son(sc)))==bothd
1152
	if (name(sc) == cond_tag && name(sh(son(sc))) ==bothd
1123
	    && name(bro(son(bro(son(sc))))) == top_tag) 
1153
	    && name(bro(son(bro(son(sc))))) == top_tag)
1124
	{
1154
	{
1125
	  /* sc is cond(... goto | make_top); can replace
1155
	  /* sc is cond(... goto | make_top); can replace
1126
	     make_top by next exp in sequence */
1156
	     make_top by next exp in sequence */
1127
	  exp lbst = bro(son(sc));
1157
	  exp lbst = bro(son(sc));
1128
	  exp mkt = bro(son(lbst));
1158
	  exp mkt = bro(son(lbst));
1129
	  exp ne = (last(sc))? bro(son(*e)): bro(sc);
1159
	  exp ne = (last(sc))? bro(son(*e)): bro(sc);
1130
	  exp bne = bro(ne);
1160
	  exp bne = bro(ne);
1131
	  bool lne = last(ne);
1161
	  bool lne = last(ne);
1132
	  if (name(ne) != cond_tag) 
1162
	  if (name(ne)!= cond_tag)
1133
	  { 
1163
	  {
1134
	    /* only worthwhile eliding if ne is a cond */
1164
	    /* only worthwhile eliding if ne is a cond */
1135
	    if (last(sc)) break;
1165
	    if (last(sc))break;
1136
	    atsc = &bro(sc);
1166
	    atsc = &bro(sc);
1137
	    continue;
1167
	    continue;
1138
	  }
1168
	  }
1139
	  sh(sc) = sh(ne);
1169
	  sh(sc) = sh(ne);
1140
	  bro(ne) = lbst; setlast(ne);
1170
	  bro(ne) = lbst; setlast(ne);
1141
	  bro(son(lbst)) = ne;
1171
	  bro(son(lbst)) = ne;
1142
	  /* sc is now cond( ... goto | next cond exp) */
1172
	  /* sc is now cond( ... goto | next cond exp) */
1143
	  if (!last(sc)) 
1173
	  if (!last(sc))
1144
	  { /* not last in seq - swallow next*/
1174
	  { /* not last in seq - swallow next*/
1145
	    bro(sc) = bne; 
1175
	    bro(sc) = bne;
1146
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1176
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1147
	    no(son(*e))--; /* one less statement */
1177
	    no(son(*e))--; /* one less statement */
1148
	  }
1178
	  }
1149
	  else if (no(son(*e)) != 1) 
1179
	  else if (no(son(*e))!= 1)
1150
	  { /* last but not only - replace by
1180
	  { /* last but not only - replace by
1151
	       make_top and put cond in res posn */
1181
	       make_top and put cond in res posn */
1152
	    bro(mkt) = bro(sc); setlast(mkt);
1182
	    bro(mkt) = bro(sc); setlast(mkt);
1153
	    *atsc = mkt;
1183
	    *atsc = mkt;
1154
	    bro(sc) = bne; 
1184
	    bro(sc) = bne;
1155
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1185
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1156
	    *arg = sc;
1186
	    *arg = sc;
1157
	    sc = mkt;
1187
	    sc = mkt;
1158
	  }
1188
	  }
1159
	  else 
1189
	  else
1160
	  { /* whole sequence can be replace by cond */
1190
	  { /* whole sequence can be replace by cond */
1161
	    bro(sc) = bro(*e);
1191
	    bro(sc) = bro(*e);
1162
	    if (last(*e)) { setlast(sc); } else {clearlast(sc); }
1192
	    if (last(*e)) { setlast(sc); } else {clearlast(sc); }
1163
	    *e = sc;
1193
	    *e = sc;
1164
	    return scan(e, at);
1194
	    return scan(e, at);
1165
	  }
1195
	  }
1166
	  
1196
 
1167
	}
1197
	}
1168
	if (last(sc)) break;
1198
	if (last(sc))break;
1169
	atsc = &bro(sc);
1199
	atsc = &bro(sc);
1170
      }
1200
      }
1171
      an = scan(arg, &arg);
1201
      an = scan(arg, &arg);
1172
      stat = &son(son(*e));
1202
      stat = &son(son(*e));
1173
 
1203
 
Line 1179... Line 1209...
1179
	stneeds = scan(stat, &arg);
1209
	stneeds = scan(stat, &arg);
1180
	/* initial statements voided */
1210
	/* initial statements voided */
1181
	an = maxneeds(an, stneeds);
1211
	an = maxneeds(an, stneeds);
1182
	if (last(*(stat)))
1212
	if (last(*(stat)))
1183
	{
1213
	{
1184
	  if ((an.propsneeds & usesproccall) != 0)
1214
	  if ((an.propsneeds & usesproccall)!= 0)
1185
	  {
1215
	  {
1186
	    an.propsneeds |= hasproccall;
1216
	    an.propsneeds |= hasproccall;
1187
	  }
1217
	  }
1188
	  return an;
1218
	  return an;
1189
	}
1219
	}
Line 1225... Line 1255...
1225
	if (!(a.ashsize <= 32 && a.ashsize == a.ashalign))
1255
	if (!(a.ashsize <= 32 && a.ashsize == a.ashalign))
1226
	  nr.fixneeds += 2;	/* memory block copy */
1256
	  nr.fixneeds += 2;	/* memory block copy */
1227
      }
1257
      }
1228
 
1258
 
1229
      if (name(*(lhs)) == name_tag &&
1259
      if (name(*(lhs)) == name_tag &&
1230
	  ((isvar(son(*(lhs))) && !isglob(son(*(lhs)))) ||
1260
	 ((isvar(son(*(lhs))) && !isglob(son(*(lhs)))) ||
1231
	   ((nr.propsneeds & (hasproccall | morefix)) == 0
1261
	  ((nr.propsneeds & (hasproccall | morefix)) == 0
1232
	    && nr.fixneeds+1 < maxfix
1262
	    && nr.fixneeds+1 < maxfix
1233
	    )
-
 
1234
	   )
1263
	   )
-
 
1264
	  )
1235
	)
1265
	)
1236
      {	
1266
      {
1237
	/* simple destination */
1267
	/* simple destination */
1238
	if (isvar(son(*(lhs))) && isglob(son(*(lhs))))
1268
	if (isvar(son(*(lhs))) && isglob(son(*(lhs))))
1239
	  nr.fixneeds += 1;		/* for TOC access */
1269
	  nr.fixneeds += 1;		/* for TOC access */
1240
	return nr;
1270
	return nr;
1241
      }
1271
      }
Line 1244... Line 1274...
1244
	needs nl;
1274
	needs nl;
1245
	prop prps = (nr.propsneeds & hasproccall) << 1;
1275
	prop prps = (nr.propsneeds & hasproccall) << 1;
1246
 
1276
 
1247
	nl = scan(lhs, at);
1277
	nl = scan(lhs, at);
1248
	/* scan destination */
1278
	/* scan destination */
1249
	if (APPLYLIKE(*(rhs)) && 
1279
	if (APPLYLIKE(*(rhs)) &&
1250
	    nstare == ass_tag &&
1280
	    nstare == ass_tag &&
1251
	    (nl.propsneeds & (anyproccall|uses_R_RESULT_bit|uses_FR_RESULT_bit))==0
1281
	   (nl.propsneeds & (anyproccall|uses_R_RESULT_bit|uses_FR_RESULT_bit)) ==0
1252
	    )
1282
	   )
1253
	{
1283
	{
1254
	  /*
1284
	  /*
1255
	   * source is proc call, so assign result reg directly
1285
	   * source is proc call, so assign result reg directly
1256
	   */
1286
	   */
1257
	  ;
1287
	 ;
1258
	}
1288
	}
1259
	else if (nr.fixneeds >= maxfix || prps != 0)
1289
	else if (nr.fixneeds >= maxfix || prps != 0)
1260
	{
1290
	{
1261
	  /*
1291
	  /*
1262
	   * source and destination regs overlap, so identify source
1292
	   * source and destination regs overlap, so identify source
Line 1281... Line 1311...
1281
      props(*e) = 0;		/* clear possibility of tlrecirsion; may be
1311
      props(*e) = 0;		/* clear possibility of tlrecirsion; may be
1282
				 * set later */
1312
				 * set later */
1283
      no_of_returns++;
1313
      no_of_returns++;
1284
      x = scan(arg, at);	/* scan result exp ... */
1314
      x = scan(arg, at);	/* scan result exp ... */
1285
 
1315
 
1286
      if (shape_size(s) != 0)
1316
      if (shape_size(s)!= 0)
1287
      {			
1317
      {
1288
	/* ...not a void result */
1318
	/* ...not a void result */
1289
	x.propsneeds |= has_result_bit;
1319
	x.propsneeds |= has_result_bit;
1290
 
1320
 
1291
	if (is_floating(name(s)))
1321
	if (is_floating(name(s)))
1292
	{		
1322
	{
1293
	  /* ... floating pt result */
1323
	  /* ... floating pt result */
1294
	  x.propsneeds |= realresult_bit;
1324
	  x.propsneeds |= realresult_bit;
1295
	  if (name(s) != shrealhd)
1325
	  if (name(s)!= shrealhd)
1296
	  {
1326
	  {
1297
	    x.propsneeds |= longrealresult_bit;
1327
	    x.propsneeds |= longrealresult_bit;
1298
	  }
1328
	  }
1299
	}
1329
	}
1300
	else
1330
	else
1301
	{
1331
	{
1302
	  if (!valregable(s))
1332
	  if (!valregable(s))
1303
	  {	
1333
	  {
1304
	    ASSERT(redo_structfns==0);
1334
	    ASSERT(redo_structfns==0);
1305
	    x.propsneeds |= long_result_bit;
1335
	    x.propsneeds |= long_result_bit;
1306
	  }
1336
	  }
1307
	}
1337
	}
1308
      }
1338
      }
Line 1318... Line 1348...
1318
	{
1348
	{
1319
 
1349
 
1320
	  /*
1350
	  /*
1321
	   * result is tag allocated into result reg - see ident_tag:
1351
	   * result is tag allocated into result reg - see ident_tag:
1322
	   */
1352
	   */
1323
	  if ((props(r) & inreg_bits) != 0)
1353
	  if ((props(r) & inreg_bits)!= 0)
1324
	  {
1354
	  {
1325
	    x.fixneeds--;
1355
	    x.fixneeds--;
1326
	  }
1356
	  }
1327
	  else if ((props(r) & infreg_bits) != 0)
1357
	  else if ((props(r) & infreg_bits)!= 0)
1328
	  {
1358
	  {
1329
	    x.floatneeds--;
1359
	    x.floatneeds--;
1330
	  }
1360
	  }
1331
	  else
1361
	  else
1332
	  {
1362
	  {
1333
	    props(r) |= (is_floating(name(s))) ? infreg_bits : inreg_bits;
1363
	    props(r) |= (is_floating(name(s)))? infreg_bits : inreg_bits;
1334
	  }
1364
	  }
1335
	  x.propsneeds |= uses_res_reg_bit;
1365
	  x.propsneeds |= uses_res_reg_bit;
1336
	  no(r) = R_USE_RES_REG;/* identification  uses result reg in body */
1366
	  no(r) = R_USE_RES_REG;/* identification  uses result reg in body */
1337
	}
1367
	}
1338
      }
1368
      }
Line 1353... Line 1383...
1353
 
1383
 
1354
 
1384
 
1355
 
1385
 
1356
      nds = scan(fnexp, at);
1386
      nds = scan(fnexp, at);
1357
      /* scan the function exp ... */
1387
      /* scan the function exp ... */
1358
      if ((nds.propsneeds & hasproccall) != 0)
1388
      if ((nds.propsneeds & hasproccall)!= 0)
1359
      {
1389
      {
1360
	/* .... it must be identified */
1390
	/* .... it must be identified */
1361
	cca(at, fnexp);
1391
	cca(at, fnexp);
1362
	nds.propsneeds &= ~hasproccall;
1392
	nds.propsneeds &= ~hasproccall;
1363
	nds.propsneeds |= usesproccall;
1393
	nds.propsneeds |= usesproccall;
1364
	fn = son(application);
1394
	fn = son(application);
1365
	par = &bro(fn);
1395
	par = &bro(fn);
1366
      }
1396
      }
1367
 
1397
 
1368
 
1398
 
1369
      for (i = 1; !last(fn); ++i)
1399
      for (i = 1; !last(fn); ++i)
1370
      {				/* scan parameters in turn ... */
1400
      {				/* scan parameters in turn ... */
1371
	needs onepar;
1401
	needs onepar;
Line 1388... Line 1418...
1388
	onepar = scan(par, at);
1418
	onepar = scan(par, at);
1389
 
1419
 
1390
	FULLCOMMENT4("scan: apply_tag: i=%d parn=%d pars=%d mover=%d",
1420
	FULLCOMMENT4("scan: apply_tag: i=%d parn=%d pars=%d mover=%d",
1391
		i, onepar.fixneeds, par_regs_used, move_to_stack_regs);
1421
		i, onepar.fixneeds, par_regs_used, move_to_stack_regs);
1392
 
1422
 
1393
	if (((i != 1 || regresult) && (onepar.propsneeds & hasproccall) != 0))
1423
	if (((i != 1 || regresult) && (onepar.propsneeds & hasproccall)!= 0))
1394
	{
1424
	{
1395
	  /* if it isn't the first parameter, and it calls a proc, identify it */
1425
	  /* if it isn't the first parameter, and it calls a proc, identify it */
1396
	  FULLCOMMENT("scan apply_tag: cca bring forward apply");
1426
	  FULLCOMMENT("scan apply_tag: cca bring forward apply");
1397
	  cca(at, par);
1427
	  cca(at, par);
1398
	  nds.propsneeds |= usesproccall;
1428
	  nds.propsneeds |= usesproccall;
1399
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
1429
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
1400
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
1430
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
1401
	}
1431
	}
1402
	else if ((i != 1 && (onepar.propsneeds & hasproccall) != 0) ||
1432
	else if ((i != 1 && (onepar.propsneeds & hasproccall)!= 0) ||
1403
		 onepar.fixneeds >= 6 /* +++ remove safety net */ ||
1433
		 onepar.fixneeds >= 6 /* +++ remove safety net */ ||
1404
		 onepar.fixneeds + move_to_stack_regs + par_regs_used > maxfix)
1434
		 onepar.fixneeds + move_to_stack_regs + par_regs_used > maxfix)
1405
	{
1435
	{
1406
	  /* requires to many regs to evaluate, identify it */
1436
	  /* requires to many regs to evaluate, identify it */
1407
	  FULLCOMMENT("scan apply_tag: cca, param has too large fixneeds");
1437
	  FULLCOMMENT("scan apply_tag: cca, param has too large fixneeds");
Line 1422... Line 1452...
1422
	  break;
1452
	  break;
1423
	};
1453
	};
1424
	par = &bro(*par);
1454
	par = &bro(*par);
1425
      }
1455
      }
1426
 
1456
 
1427
      if (!regresult && name(father(application)) != ass_tag)
1457
      if (!regresult && name(father(application))!= ass_tag)
1428
      {
1458
      {
1429
	/* find space for non reg result */
1459
	/* find space for non reg result */
1430
	FULLCOMMENT("scan apply_tag: cca space for non reg result");
1460
	FULLCOMMENT("scan apply_tag: cca space for non reg result");
1431
	cca(at, ptr_position(application));
1461
	cca(at, ptr_position(application));
1432
	nds.propsneeds |= usesproccall;
1462
	nds.propsneeds |= usesproccall;
Line 1434... Line 1464...
1434
      else
1464
      else
1435
      {
1465
      {
1436
	nds.propsneeds |= hasproccall;
1466
	nds.propsneeds |= hasproccall;
1437
      }
1467
      }
1438
      nds.maxargs = max(nds.maxargs, parsize);
1468
      nds.maxargs = max(nds.maxargs, parsize);
1439
      return nds;
1469
      return nds;
1440
    };
1470
    };
1441
 
1471
 
1442
  case null_tag:
1472
  case null_tag:
1443
    {
1473
    {
1444
      /* many int optimisations keyed off val_tag so represent null as val_tag */
1474
      /* many int optimisations keyed off val_tag so represent null as val_tag */
Line 1481... Line 1511...
1481
   case neg_tag:
1511
   case neg_tag:
1482
   case case_tag:
1512
   case case_tag:
1483
   case not_tag:
1513
   case not_tag:
1484
   case offset_negate_tag:
1514
   case offset_negate_tag:
1485
   case diagnose_tag:
1515
   case diagnose_tag:
1486
   case goto_lv_tag:  
1516
   case goto_lv_tag:
1487
   case alloca_tag:
1517
   case alloca_tag:
1488
    {
1518
    {
1489
      return scan(&son(*e), at);
1519
      return scan(&son(*e), at);
1490
    }
1520
    }
1491
   case abs_tag:
1521
   case abs_tag:
Line 1503... Line 1533...
1503
      exp NEG__TAG;
1533
      exp NEG__TAG;
1504
      exp COND__TAG;
1534
      exp COND__TAG;
1505
      exp ZERO__TAG;
1535
      exp ZERO__TAG;
1506
      exp ABS__TAG;
1536
      exp ABS__TAG;
1507
      ABS__TAG = *e;
1537
      ABS__TAG = *e;
1508
      
1538
 
1509
      CLEAR__TAG = getexp (f_top, nilexp, 0, nilexp, nilexp,0, 0, clear_tag);
1539
      CLEAR__TAG = getexp(f_top, nilexp, 0, nilexp, nilexp,0, 0, clear_tag);
1510
      LABST__TAG = me_b3(int_shpe,CLEAR__TAG,me_obtain(id),labst_tag);
1540
      LABST__TAG = me_b3(int_shpe,CLEAR__TAG,me_obtain(id),labst_tag);
1511
 
1541
 
1512
      VAL__TAG = me_shint(int_shpe,0);
1542
      VAL__TAG = me_shint(int_shpe,0);
1513
      TEST__TAG = me_q1(no_nat_option,f_less_than,&LABST__TAG,
1543
      TEST__TAG = me_q1(no_nat_option,f_less_than,&LABST__TAG,
1514
			me_obtain(id),VAL__TAG,test_tag);
1544
			me_obtain(id),VAL__TAG,test_tag);
1515
      NEG__TAG = me_u3(int_shpe,me_obtain(id),neg_tag);
1545
      NEG__TAG = me_u3(int_shpe,me_obtain(id),neg_tag);
1516
      pt(NEG__TAG) = pt(ABS__TAG);
1546
      pt(NEG__TAG) = pt(ABS__TAG);
1517
      props(NEG__TAG)=props(ABS__TAG);
1547
      props(NEG__TAG) =props(ABS__TAG);
1518
      
1548
 
1519
      ZERO__TAG = me_u3(f_top,TEST__TAG,0);
1549
      ZERO__TAG = me_u3(f_top,TEST__TAG,0);
1520
      SEQ__TAG = me_b3(int_shpe,ZERO__TAG,NEG__TAG,seq_tag);
1550
      SEQ__TAG = me_b3(int_shpe,ZERO__TAG,NEG__TAG,seq_tag);
1521
      COND__TAG = me_b3(int_shpe,SEQ__TAG,LABST__TAG,cond_tag);
1551
      COND__TAG = me_b3(int_shpe,SEQ__TAG,LABST__TAG,cond_tag);
1522
      id = me_complete_id(id,COND__TAG);
1552
      id = me_complete_id(id,COND__TAG);
1523
      if (last(*e))
1553
      if (last(*e))
1524
      {
1554
      {
1525
	setlast(id);
1555
	setlast(id);
1526
      }
1556
      }
1527
      else
1557
      else
1528
      {
1558
      {
1529
	clearlast(id);
1559
	clearlast(id);
1530
      }
1560
      }
1531
      bro(id) = bro(*e);
1561
      bro(id) = bro(*e);
1532
      *e = id;
1562
      *e = id;
1533
      return scan(e,at);
1563
      return scan(e,at);
1534
    }
1564
    }
1535
    
1565
 
1536
 
1566
 
1537
 
1567
 
1538
   case fneg_tag:
1568
   case fneg_tag:
1539
   case fabs_tag:
1569
   case fabs_tag:
1540
   case chfl_tag:
1570
   case chfl_tag:
Line 1544... Line 1574...
1544
      nds = scan(&son(*e), at);
1574
      nds = scan(&son(*e), at);
1545
      return nds;
1575
      return nds;
1546
    }
1576
    }
1547
   case bitf_to_int_tag:
1577
   case bitf_to_int_tag:
1548
   case int_to_bitf_tag:
1578
   case int_to_bitf_tag:
1549
    {
1579
    {
1550
      exp *arg = &son(*e);
1580
      exp *arg = &son(*e);
1551
 
1581
 
1552
      return scan(arg, at);
1582
      return scan(arg, at);
1553
    }
1583
    }
1554
 
1584
 
1555
  case round_tag:
1585
  case round_tag:
1556
    {
1586
    {
1557
      needs s;
1587
      needs s;
1558
      exp *arg = &son(*e);
1588
      exp *arg = &son(*e);
1559
      shape sres = sh(*e);
1589
      shape sres = sh(*e);
1560
      if(shape_size(sres) !=32)
1590
      if (shape_size(sres)!=32)
1561
      {
1591
      {
1562
	exp ch = getexp(sres,bro(*e),last(*e),*e,pt(*e),props(*e),0,chvar_tag);
1592
	exp ch = getexp(sres,bro(*e),last(*e),*e,pt(*e),props(*e),0,chvar_tag);
1563
	bro(*e)=ch;setlast(*e);
1593
	bro(*e) =ch;setlast(*e);
1564
	sh(*e)=slongsh;
1594
	sh(*e) =slongsh;
1565
	*e=ch;
1595
	*e=ch;
1566
	return scan(e,at);
1596
	return scan(e,at);
1567
      }
1597
      }
1568
      s = scan(arg,at);
1598
      s = scan(arg,at);
1569
      s.fixneeds = max(s.fixneeds,1);
1599
      s.fixneeds = max(s.fixneeds,1);
Line 1640... Line 1670...
1640
       * a) lhs a const (to support convention of const on rhs); or
1670
       * a) lhs a const (to support convention of const on rhs); or
1641
       * b) rhs is a load from mem, move to lhs in hope of reducing
1671
       * b) rhs is a load from mem, move to lhs in hope of reducing
1642
       *    load-use delays
1672
       *    load-use delays
1643
       */
1673
       */
1644
      if (
1674
      if (
1645
	   (
1675
	  (
1646
	    test_number(stare)==TEST_NE||test_number(stare)==TEST_EQ||
1676
	    test_number(stare) ==TEST_NE||test_number(stare) ==TEST_EQ||
1647
	    !is_floating(name(sh(l)))
1677
	    !is_floating(name(sh(l)))
1648
	    )
1678
	   )
1649
	   &&
1679
	   &&
1650
	   (
1680
	  (
1651
	     (name(l) == val_tag)
1681
	    (name(l) == val_tag)
1652
	     ||
1682
	     ||
1653
	     (LOADFROMSTORE(r) && !LOADFROMSTORE(l))
1683
	    (LOADFROMSTORE(r) && !LOADFROMSTORE(l))
1654
	   )
1684
	  )
1655
	 )
1685
	)
1656
      {
1686
      {
1657
	/* commute */
1687
	/* commute */
1658
	bro(l) = stare;
1688
	bro(l) = stare;
1659
	setlast(l);
1689
	setlast(l);
1660
	bro(r) = l;
1690
	bro(r) = l;
Line 1662... Line 1692...
1662
	son(stare) = r;
1692
	son(stare) = r;
1663
	r = l;
1693
	r = l;
1664
	l = son(stare);
1694
	l = son(stare);
1665
	settest_number(stare,cbranch(test_number(stare)));
1695
	settest_number(stare,cbranch(test_number(stare)));
1666
      }
1696
      }
1667
      
1697
 
1668
      if (is_floating(name(sh(l))))
1698
      if (is_floating(name(sh(l))))
1669
      {
1699
      {
1670
	return fpop(e, at);
1700
	return fpop(e, at);
1671
      }
1701
      }
1672
      else if (name(r) == val_tag && no(r) == 1 
1702
      else if (name(r) == val_tag && no(r) == 1
1673
	       && (test_number(stare) == TEST_GE || 
1703
	       && (test_number(stare) == TEST_GE ||
1674
		   test_number(stare) == TEST_LT)
1704
		   test_number(stare) == TEST_LT)
1675
	       )
1705
	      )
1676
      {
1706
      {
1677
	/* The only reason for this optimisation is that it increases
1707
	/* The only reason for this optimisation is that it increases
1678
	   the chance of using the Record bit */
1708
	   the chance of using the Record bit */
1679
	no(r) = 0;
1709
	no(r) = 0;
1680
	if (test_number(stare) == TEST_GE)
1710
	if (test_number(stare) == TEST_GE)
Line 1696... Line 1726...
1696
     exp * s  = &bro(*d);
1726
     exp * s  = &bro(*d);
1697
     exp * sz = &bro(*s);
1727
     exp * sz = &bro(*s);
1698
     needs nd;
1728
     needs nd;
1699
     needs ns;
1729
     needs ns;
1700
     needs nsz;
1730
     needs nsz;
1701
     prop prps ;
1731
     prop prps;
1702
     nd  = scan(d, at);
1732
     nd  = scan(d, at);
1703
     ns  = scan (s, at);
1733
     ns  = scan(s, at);
1704
     nsz = scan(sz, at);
1734
     nsz = scan(sz, at);
1705
     prps = (ns.propsneeds & hasproccall) << 1;
1735
     prps = (ns.propsneeds & hasproccall) << 1;
1706
     if (ns.fixneeds >= maxfix || prps != 0) {
1736
     if (ns.fixneeds >= maxfix || prps != 0) {
1707
       /* if reg requirements overlap, identify
1737
       /* if reg requirements overlap, identify
1708
	  second operand */
1738
	  second operand */
1709
       cca (at, s);
1739
       cca(at, s);
1710
       ns = shapeneeds (sh (* (s)));
1740
       ns = shapeneeds(sh(*(s)));
1711
       ns.propsneeds |= morefix;
1741
       ns.propsneeds |= morefix;
1712
       ns.propsneeds &= ~(prps >> 1);
1742
       ns.propsneeds &= ~(prps >> 1);
1713
       ns.propsneeds |= prps;
1743
       ns.propsneeds |= prps;
1714
     }
1744
     }
1715
     nd.fixneeds += 1;
1745
     nd.fixneeds += 1;
1716
     nd = maxneeds (nd, ns);
1746
     nd = maxneeds(nd, ns);
1717
     prps= (nsz.propsneeds & hasproccall) << 1;
1747
     prps= (nsz.propsneeds & hasproccall) << 1;
1718
     if (nd.fixneeds +nsz.fixneeds >= maxfix || prps != 0) {
1748
     if (nd.fixneeds +nsz.fixneeds >= maxfix || prps != 0) {
1719
       /* if reg requirements overlap, identify
1749
       /* if reg requirements overlap, identify
1720
	  last operand */
1750
	  last operand */
1721
       cca (at, sz);
1751
       cca(at, sz);
1722
       nsz = shapeneeds (sh (* (sz)));
1752
       nsz = shapeneeds(sh(*(sz)));
1723
       nsz.propsneeds |= morefix;
1753
       nsz.propsneeds |= morefix;
1724
       nsz.propsneeds &= ~(prps >> 1);
1754
       nsz.propsneeds &= ~(prps >> 1);
1725
       nsz.propsneeds |= prps;
1755
       nsz.propsneeds |= prps;
1726
     }                
1756
     }
1727
     nd.fixneeds+=1;
1757
     nd.fixneeds+=1;
1728
     nd = maxneeds(nd,nsz);
1758
     nd = maxneeds(nd,nsz);
1729
     if (nd.fixneeds < 4) nd.fixneeds = 3;
1759
     if (nd.fixneeds < 4)nd.fixneeds = 3;
1730
     return nd;
1760
     return nd;
1731
   }
1761
   }
1732
    
1762
 
1733
    
1763
 
1734
    
1764
 
1735
   case plus_tag:
1765
   case plus_tag:
1736
    {				/* replace any operands which are neg(..) by -
1766
    {				/* replace any operands which are neg(..) by -
1737
				 * if poss */
1767
				 * if poss */
1738
      exp sum = *(e);
1768
      exp sum = *(e);
1739
      exp list = son(sum);
1769
      exp list = son(sum);
1740
      bool someneg = 0;
1770
      bool someneg = 0;
1741
      bool allneg = 1;
1771
      bool allneg = 1;
1742
 
1772
 
1743
      /* check BUGP13 [corruption by extract_consts()] is fixed */
1773
      /* check BUGP13 [corruption by extract_consts()] is fixed */
1744
      /* check father set correctly */
1774
      /* check father set correctly */
1745
      ASSERT(father(son(sum))==sum);
1775
      ASSERT(father(son(sum)) ==sum);
1746
 
1776
 
1747
      for (; optop(sum);)
1777
      for (; optop(sum);)
1748
      {
1778
      {
1749
	if (name(list) == neg_tag)
1779
	if (name(list) == neg_tag)
1750
	  someneg = 1;
1780
	  someneg = 1;
Line 1806... Line 1836...
1806
 
1836
 
1807
	  /* set father of sum, new neg_tag exp */
1837
	  /* set father of sum, new neg_tag exp */
1808
	  bro(sum) = x;
1838
	  bro(sum) = x;
1809
 
1839
 
1810
	  /* check father of sum is correct */
1840
	  /* check father of sum is correct */
1811
	  ASSERT(father(son(sum))==sum);
1841
	  ASSERT(father(son(sum)) ==sum);
1812
 
1842
 
1813
	  *(e) = x;
1843
	  *(e) = x;
1814
	}			/* end allneg */
1844
	}			/* end allneg */
1815
	else
1845
	else
1816
	{
1846
	{
Line 1876... Line 1906...
1876
	  }
1906
	  }
1877
	  *(e) = newsum;
1907
	  *(e) = newsum;
1878
	}			/* end else allneg */
1908
	}			/* end else allneg */
1879
 
1909
 
1880
	/* check father set correctly */
1910
	/* check father set correctly */
1881
	ASSERT(father(son(*e))==*e);
1911
	ASSERT(father(son(*e)) ==*e);
1882
 
1912
 
1883
	return scan(e, at);
1913
	return scan(e, at);
1884
 
1914
 
1885
      }				/* end someneg - else continue to next case */
1915
      }				/* end someneg - else continue to next case */
1886
    }
1916
    }
1887
   case addptr_tag:
1917
   case addptr_tag:
1888
    {
1918
    {
1889
      exp p = son(*e);
1919
      exp p = son(*e);
1890
      exp d = bro(p);
1920
      exp d = bro(p);
1891
      int fal = frame_al_of_ptr(sh(p));    	
1921
      int fal = frame_al_of_ptr(sh(p));
1892
      if (fal!=0 && i_reckon_its_a_general_proc(fal)) 
1922
      if (fal!=0 && i_reckon_its_a_general_proc(fal))
1893
      {	
1923
      {
1894
	int oal = frame_al1_of_offset(sh(d));
1924
	int oal = frame_al1_of_offset(sh(d));
1895
/*	if( ((oal-1)&oal) != 0) 
1925
/*	if( ((oal-1)&oal) != 0)
1896
	{
1926
	{
1897
	  fail("can't cope with mixed frame offsets yet");
1927
	  fail("can't cope with mixed frame offsets yet");
1898
	}*/
1928
	}*/
1899
	if ( !l_or_cees(oal)) 
1929
	if (!l_or_cees(oal))
1900
	{
1930
	{
1901
	  /* callers are referenced through R_TP */
1931
	  /* callers are referenced through R_TP */
1902
	  /* to get this we use locptr to access through R_FP(current_env)*/
1932
	  /* to get this we use locptr to access through R_FP(current_env)*/
1903
	  exp ne = getexp(sh(p), d, 0, p, nilexp, 0, 0,locptr_tag);
1933
	  exp ne = getexp(sh(p), d, 0, p, nilexp, 0, 0,locptr_tag);
1904
	  bro(p) = ne; setlast(p);
1934
	  bro(p) = ne; setlast(p);
1905
	  son(*e) = ne;
1935
	  son(*e) = ne;
1906
	}
1936
	}
1907
      }
1937
      }
1908
      /* ... and continue */  	  
1938
      /* ... and continue */
1909
    }
1939
    }
1910
    
1940
 
1911
    
1941
 
1912
   case local_free_tag:
1942
   case local_free_tag:
1913
   case mult_tag:
1943
   case mult_tag:
1914
   case and_tag:
1944
   case and_tag:
1915
   case or_tag:
1945
   case or_tag:
1916
   case xor_tag:
1946
   case xor_tag:
Line 1919... Line 1949...
1919
    };
1949
    };
1920
   case reff_tag:
1950
   case reff_tag:
1921
   case offset_pad_tag:
1951
   case offset_pad_tag:
1922
   case chvar_tag:
1952
   case chvar_tag:
1923
   case locptr_tag:
1953
   case locptr_tag:
1924
    {
1954
    {
1925
      exp *arg = &son(*e);
1955
      exp *arg = &son(*e);
1926
 
1956
 
1927
      return maxneeds(scan(arg, at),
1957
      return maxneeds(scan(arg, at),
1928
		      shapeneeds(sh(*(e))));
1958
		      shapeneeds(sh(*(e))));
1929
    };
1959
    };
1930
    
1960
 
1931
  case float_tag:
1961
  case float_tag:
1932
    {
1962
    {
1933
      needs nds;
1963
      needs nds;
1934
      exp *arg = &son(*e);
1964
      exp *arg = &son(*e);
1935
 
1965
 
Line 1953... Line 1983...
1953
    };
1983
    };
1954
   case offset_mult_tag: case offset_div_tag: {
1984
   case offset_mult_tag: case offset_div_tag: {
1955
     exp op1 = son(*e);
1985
     exp op1 = son(*e);
1956
     exp op2 = bro(op1);
1986
     exp op2 = bro(op1);
1957
     shape s = sh(op2);
1987
     shape s = sh(op2);
1958
     if (name(op2)==val_tag  && name(s)==offsethd 
1988
     if (name(op2) ==val_tag  && name(s) ==offsethd
1959
	 && al2(s) >= 8) {
1989
	 && al2(s) >= 8) {
1960
       int n = no(op2)/8;
1990
       int n = no(op2) /8;
1961
       if (n == 1) {
1991
       if (n == 1) {
1962
	 /* offset is one  byte */
1992
	 /* offset is one  byte */
1963
	 bro(op1) = bro(*e);
1993
	 bro(op1) = bro(*e);
1964
	 if (last(*e)) { setlast(op1); } else {clearlast(op1); }
1994
	 if (last(*e)) { setlast(op1); } else {clearlast(op1); }
1965
	 *e = op1;
1995
	 *e = op1;
1966
	 return( scan(e, at));
1996
	 return(scan(e, at));
1967
       }
1997
       }
1968
       else 
1998
       else
1969
	 if ( name(*e) == offset_mult_tag && n > 1 && (n&(n-1))== 0)
1999
	 if (name(*e) == offset_mult_tag && n > 1 && (n& (n-1)) == 0)
1970
	   if( name(op1) == and_tag 
2000
	   if (name(op1) == and_tag
1971
	      && name(son(op1))== shr_tag &&
2001
	      && name(son(op1)) == shr_tag &&
1972
	      name(bro(son(op1)))==val_tag ) {
2002
	      name(bro(son(op1))) ==val_tag) {
1973
	     exp shexp = son(op1);
2003
	     exp shexp = son(op1);
1974
	     exp ac = bro(shexp);
2004
	     exp ac = bro(shexp);
1975
	     exp shop1 = son(shexp);
2005
	     exp shop1 = son(shexp);
1976
	     exp shop2 = bro(shop1);
2006
	     exp shop2 = bro(shop1);
1977
	     int na = no(ac);
2007
	     int na = no(ac);
1978
	     if ((na&(na+1))==0 && name(shop2)==val_tag) {
2008
	     if ((na& (na+1)) ==0 && name(shop2) ==val_tag) {
1979
	       int pn = 0;
2009
	       int pn = 0;
1980
	       int ns = no(shop2);
2010
	       int ns = no(shop2);
1981
	       int i = n;
2011
	       int i = n;
1982
	       while (i>1) { i >>= 1; pn++; }
2012
	       while (i>1) { i >>= 1; pn++; }
1983
	       
2013
 
1984
	       if (ns > pn) 
2014
	       if (ns > pn)
1985
	       {
2015
	       {
1986
		 /* can do transform:
2016
		 /* can do transform:
1987
		    (((shop1>>ns) & na) * n) =>
2017
		    (((shop1>>ns) & na) * n) =>
1988
		    shop1>>(ns-pn) & (na*n)
2018
		    shop1>>(ns-pn) & (na*n)
1989
		      */
2019
		      */
1990
		 no(shop2) = ns-pn;
2020
		 no(shop2) = ns-pn;
1991
		 no(ac) = na*n;
2021
		 no(ac) = na*n;
1992
		 bro(op1) = bro(*e);
2022
		 bro(op1) = bro(*e);
1993
		 if (last(*e)) 
2023
		 if (last(*e))
1994
		 {
2024
		 {
1995
		   setlast(op1); 
2025
		   setlast(op1);
1996
		 } 
2026
		 }
1997
		 else 
2027
		 else
1998
		 {
2028
		 {
1999
		   clearlast(op1);
2029
		   clearlast(op1);
2000
		 }   
2030
		 }
2001
		 *e = op1;
2031
		 *e = op1;
2002
		 return( scan(e, at));
2032
		 return(scan(e, at));
2003
	       }
2033
	       }
2004
	     }
2034
	     }
2005
	   }
2035
	   }
2006
	   else 
2036
	   else
2007
	   { 
2037
	   {
2008
	     /* will do this by literal shift */
2038
	     /* will do this by literal shift */
2009
	     no(op2) = n;
2039
	     no(op2) = n;
2010
	     return scan(&son(*e), at);
2040
	     return scan(&son(*e), at);
2011
	   } 
2041
	   }
2012
     }
2042
     }
2013
     return non_commutative_scan (e, at);
2043
     return non_commutative_scan(e, at);
2014
     
2044
 
2015
   }
2045
   }
2016
    
2046
 
2017
 
2047
 
2018
   case div0_tag:
2048
   case div0_tag:
2019
   case div1_tag:
2049
   case div1_tag:
2020
   case div2_tag:
2050
   case div2_tag:
2021
   case rem0_tag:
2051
   case rem0_tag:
Line 2028... Line 2058...
2028
   case max_tag:
2058
   case max_tag:
2029
   case min_tag:
2059
   case min_tag:
2030
   case offset_max_tag:
2060
   case offset_max_tag:
2031
   case component_tag:
2061
   case component_tag:
2032
   case make_stack_limit_tag:
2062
   case make_stack_limit_tag:
2033
    {
2063
    {
2034
      return non_commutative_scan(e, at);
2064
      return non_commutative_scan(e, at);
2035
    };
2065
    };
2036
   case offset_add_tag:
2066
   case offset_add_tag:
2037
    {
2067
    {
2038
      exp l = son(*e);
2068
      exp l = son(*e);
2039
      exp r = bro(l);
2069
      exp r = bro(l);
2040
      if (name(l) == val_tag) 
2070
      if (name(l) == val_tag)
2041
      {
2071
      {
2042
	sh(l) = sh(r);   /* both offsets will be treated the same */
2072
	sh(l) = sh(r);   /* both offsets will be treated the same */
2043
	son(*e) = r; clearlast(r);
2073
	son(*e) = r; clearlast(r);
2044
	bro(r) = l; setlast(l); bro(l) = *e;
2074
	bro(r) = l; setlast(l); bro(l) = *e;
2045
	/* ... and put val last */
2075
	/* ... and put val last */
2046
      }
2076
      }
2047
      else
2077
      else
2048
      {	
2078
      {
2049
	if (al2(sh(l))>=8 && al2(sh(r)) <8) 
2079
	if (al2(sh(l)) >=8 && al2(sh(r)) <8)
2050
	{
2080
	{
2051
	  return non_commutative_scan(e, at);
2081
	  return non_commutative_scan(e, at);
2052
	}
2082
	}
2053
      }
2083
      }
2054
      
2084
 
2055
      setname(*e, plus_tag);
2085
      setname(*e, plus_tag);
2056
      
2086
 
2057
      return commutative_scan(e,at);
2087
      return commutative_scan(e,at);
2058
    }
2088
    }
2059
   case offset_subtract_tag: {
2089
   case offset_subtract_tag: {
2060
	exp l = son(*e);
2090
	exp l = son(*e);
2061
	exp r = bro(l);
2091
	exp r = bro(l);
2062
	if (name(r)==val_tag) {
2092
	if (name(r) ==val_tag) {
2063
		sh(r) = sh(l);   /* both offsets will be treated the same */
2093
		sh(r) = sh(l);   /* both offsets will be treated the same */
2064
	}
2094
	}
2065
	else		
2095
	else
2066
	if ( al2(sh(r))>=8 && al2(sh(l)) <8) {
2096
	if (al2(sh(r)) >=8 && al2(sh(l)) <8) {
2067
	        return non_commutative_scan (e, at);
2097
	        return non_commutative_scan(e, at);
2068
	}
2098
	}
2069
 
2099
 
2070
	setname(*e, minus_tag);
2100
	setname(*e, minus_tag);
2071
	return non_commutative_scan (e, at);
2101
	return non_commutative_scan(e, at);
2072
    }
2102
    }
2073
    
2103
 
2074
  case fdiv_tag:
2104
  case fdiv_tag:
2075
  case fplus_tag:
2105
  case fplus_tag:
2076
  case fminus_tag:
2106
  case fminus_tag:
2077
  case fmult_tag:
2107
  case fmult_tag:
2078
    {
2108
    {
Line 2115... Line 2145...
2115
	if (!last(stare))
2145
	if (!last(stare))
2116
	  clearlast(ss);
2146
	  clearlast(ss);
2117
	bro(ss) = bro(stare);
2147
	bro(ss) = bro(stare);
2118
	sh(ss) = sh(stare);
2148
	sh(ss) = sh(stare);
2119
	*e = ss;
2149
	*e = ss;
2120
	return (scan(e, at));
2150
	return(scan(e, at));
2121
      }
2151
      }
2122
      str = scan(arg, at);
2152
      str = scan(arg, at);
2123
      return maxneeds(str, shapeneeds(sh(*(e))));
2153
      return maxneeds(str, shapeneeds(sh(*(e))));
2124
    };
2154
    };
2125
 
2155
 
2126
/*********************************************************************
2156
/*********************************************************************
2127
	load_proc
2157
	load_proc
2128
 
2158
 
2129
 
2159
 
2130
number is number of proc (useful for indexing)
2160
number is number of proc (useful for indexing)
2131
*********************************************************************/
2161
*********************************************************************/
2132
   case proc_tag:
2162
   case proc_tag:
2133
   case general_proc_tag:
2163
   case general_proc_tag:
2134
    {
2164
    {
2135
      exp *bexp;
2165
      exp *bexp;
2136
      exp *bat;
2166
      exp *bat;
2137
      needs body;
2167
      needs body;
2138
      
2168
 
2139
      exp_num = 0;
2169
      exp_num = 0;
2140
      callee_size = 0;
2170
      callee_size = 0;
2141
      max_callees = -1;
2171
      max_callees = -1;
2142
      no_of_returns = 0;
2172
      no_of_returns = 0;
2143
      maxfix = maxfix_tregs;
2173
      maxfix = maxfix_tregs;
2144
      maxfloat = MAXFLT_TREGS;
2174
      maxfloat = MAXFLT_TREGS;
2145
      stparam = 0;
2175
      stparam = 0;
2146
      fixparam = R_FIRST_PARAM;
2176
      fixparam = R_FIRST_PARAM;
2147
      floatparam = FR_FIRST_PARAM;
2177
      floatparam = FR_FIRST_PARAM;
2148
      
2178
 
2149
      /* Parameter allocation t-regs */
2179
      /* Parameter allocation t-regs */
2150
      freefixed = PROC_TREGS;
2180
      freefixed = PROC_TREGS;
2151
      freefloat = PROC_FLT_TREGS;
2181
      freefloat = PROC_FLT_TREGS;
2152
      
2182
 
2153
      if (name(*e)==general_proc_tag)
2183
      if (name(*e) ==general_proc_tag)
2154
      {
2184
      {
2155
	end_param = GENERAL_PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2185
	end_param = GENERAL_PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2156
      }
2186
      }
2157
      else
2187
      else
2158
      {
2188
      {
2159
	end_param = PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2189
	end_param = PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2160
      }
2190
      }
2161
      
2191
 
2162
      nonevis = 1;
2192
      nonevis = 1;
2163
      gen_call = 0;
2193
      gen_call = 0;
2164
      tail_call = 0;
2194
      tail_call = 0;
2165
      bexp = &son(*e);
2195
      bexp = &son(*e);
2166
      bat = bexp;
2196
      bat = bexp;
Line 2190... Line 2220...
2190
 general_env_offset
2220
 general_env_offset
2191
 caller_name
2221
 caller_name
2192
 formal_callee
2222
 formal_callee
2193
 caller
2223
 caller
2194
********************************************************************/
2224
********************************************************************/
2195
   case apply_general_tag: 
2225
   case apply_general_tag:
2196
    {
2226
    {
2197
      exp application = *(e);
2227
      exp application = *(e);
2198
      exp *fn = &son (application);
2228
      exp *fn = &son(application);
2199
      exp cers = bro(*fn);
2229
      exp cers = bro(*fn);
2200
      exp *cerl = &son(cers);
2230
      exp *cerl = &son(cers);
2201
      long stpar = 0;
2231
      long stpar = 0;
2202
      needs nds;
2232
      needs nds;
2203
      needs plnds;
2233
      needs plnds;
2204
      int i;
2234
      int i;
2205
      
2235
 
2206
      gen_call = 1;
2236
      gen_call = 1;
2207
      
2237
 
2208
      /* scan the function */
2238
      /* scan the function */
2209
      nds = scan(fn, at);
2239
      nds = scan(fn, at);
2210
      
2240
 
2211
      if ((nds.propsneeds & hasproccall) != 0) 
2241
      if ((nds.propsneeds & hasproccall)!= 0)
2212
      {
2242
      {
2213
	/* .... it must be identified */
2243
	/* .... it must be identified */
2214
	cca (at, fn);
2244
	cca(at, fn);
2215
	nds.propsneeds &= ~hasproccall;
2245
	nds.propsneeds &= ~hasproccall;
2216
	nds.propsneeds |= usesproccall;
2246
	nds.propsneeds |= usesproccall;
2217
	fn = &son(application);
2247
	fn = &son(application);
2218
      }
2248
      }
2219
      /* scan the callers */
2249
      /* scan the callers */
2220
      for(i=0; i<no(cers); i++) 
2250
      for (i=0; i<no(cers); i++)
2221
      {
2251
      {
2222
	needs onepar;
2252
	needs onepar;
2223
	shape shonepar = sh(*cerl);
2253
	shape shonepar = sh(*cerl);
2224
	exp * par = (name(*cerl)==caller_tag)?&son(*cerl):cerl;
2254
	exp * par = (name(*cerl) ==caller_tag)?&son(*cerl):cerl;
2225
	int n = ALIGNNEXT(stpar, shape_align(shonepar));  
2255
	int n = ALIGNNEXT(stpar, shape_align(shonepar));
2226
	onepar = scan(par,at);
2256
	onepar = scan(par,at);
2227
	if ((i != 0 && (onepar.propsneeds & hasproccall) != 0) ||
2257
	if ((i != 0 && (onepar.propsneeds & hasproccall)!= 0) ||
2228
	    onepar.fixneeds+(stpar>>5) > maxfix) 
2258
	    onepar.fixneeds+ (stpar>>5) > maxfix)
2229
	{
2259
	{
2230
	  /* +++ if we go over a certain number of param regs
2260
	  /* +++ if we go over a certain number of param regs
2231
	     they are forced to be on the stack so stpar>>5 
2261
	     they are forced to be on the stack so stpar>>5
2232
	     is not the best estimate ,but sufficient*/
2262
	     is not the best estimate ,but sufficient*/
2233
	  /* stpar>>5 is the no of param regs used so far */
2263
	  /* stpar>>5 is the no of param regs used so far */
2234
	  /* if it isn't the first parameter, and it
2264
	  /* if it isn't the first parameter, and it
2235
	     calls a proc, identify it */
2265
	     calls a proc, identify it */
2236
	  /* it is ok for first param to have a proccall since we have
2266
	  /* it is ok for first param to have a proccall since we have
2237
	     no loaded parameters to corrupt */
2267
	     no loaded parameters to corrupt */
2238
	  cca (at, par);
2268
	  cca(at, par);
2239
	  nds.propsneeds |= usesproccall;
2269
	  nds.propsneeds |= usesproccall;
2240
	  nds = maxneeds (shapeneeds (sh (* (par))), nds);
2270
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
2241
	  nds.maxargs = max (nds.maxargs, onepar.maxargs);
2271
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
2242
	}
2272
	}
2243
	else 
2273
	else
2244
	{
2274
	{
2245
	  nds = maxneeds (onepar, nds);
2275
	  nds = maxneeds(onepar, nds);
2246
	}
2276
	}
2247
	if (name(*cerl)==caller_tag) 
2277
	if (name(*cerl) ==caller_tag)
2248
	{
2278
	{
2249
	  /* for caller_tag's we record where it will live */
2279
	  /* for caller_tag's we record where it will live */
2250
	  no(*cerl) = n; 
2280
	  no(*cerl) = n;
2251
	  clear_coded_caller(*cerl);
2281
	  clear_coded_caller(*cerl);
2252
	}
2282
	}
2253
	n = n + shape_size(shonepar);
2283
	n = n + shape_size(shonepar);
2254
	stpar = ALIGNNEXT(n,32);
2284
	stpar = ALIGNNEXT(n,32);
2255
	cerl = &bro(*cerl);
2285
	cerl = &bro(*cerl);
2256
      }
2286
      }
2257
      nds.maxargs = max (nds.maxargs, stpar);
2287
      nds.maxargs = max(nds.maxargs, stpar);
2258
      /* scan the callees */
2288
      /* scan the callees */
2259
      nds = maxneeds(scan(&bro(bro(son(application))), at), nds);
2289
      nds = maxneeds(scan(&bro(bro(son(application))), at), nds);
2260
      /* scan the postlude */
2290
      /* scan the postlude */
2261
      plnds = scan(&bro(bro(bro(son(application)))), at);
2291
      plnds = scan(&bro(bro(bro(son(application)))), at);
2262
      if(plnds.propsneeds & anyproccall)
2292
      if (plnds.propsneeds & anyproccall)
2263
      {
2293
      {
2264
	props(application)=1;
2294
	props(application) =1;
2265
	if (is_floating(name(sh(application))) || valregable(sh(application))) 
2295
	if (is_floating(name(sh(application))) || valregable(sh(application)))
2266
	{
2296
	{
2267
	  cca(at, ptr_position(application));
2297
	  cca(at, ptr_position(application));
2268
	  plnds.propsneeds |= usesproccall;
2298
	  plnds.propsneeds |= usesproccall;
2269
	}
2299
	}
2270
      }
2300
      }
2271
      else
2301
      else
2272
      {
2302
      {
2273
	props(application)=0;
2303
	props(application) =0;
2274
	if (is_floating(name(sh(application))) || valregable(sh(application))) 
2304
	if (is_floating(name(sh(application))) || valregable(sh(application)))
2275
	{
2305
	{
2276
	  cca(at, ptr_position(application));
2306
	  cca(at, ptr_position(application));
2277
	}
2307
	}
2278
      }
2308
      }
2279
      nds = maxneeds(nds, plnds);
2309
      nds = maxneeds(nds, plnds);
2280
      nds.propsneeds |= hasproccall;
2310
      nds.propsneeds |= hasproccall;
2281
      return nds;
2311
      return nds;
2282
    }
2312
    }
2283
/********************************************************************/ 
2313
/********************************************************************/
2284
   case make_callee_list_tag:
2314
   case make_callee_list_tag:
2285
    {
2315
    {
2286
      exp cees = *e;
2316
      exp cees = *e;
2287
      exp *par = &son(cees);
2317
      exp *par = &son(cees);
2288
      needs nds;
2318
      needs nds;
2289
      long stpar = 0;
2319
      long stpar = 0;
2290
      int i;
2320
      int i;
2291
      nds = zeroneeds;
2321
      nds = zeroneeds;
2292
      for ( i=0;i<no(cees);i++)
2322
      for (i=0;i<no(cees);i++)
2293
      {
2323
      {
2294
	/* scan each callee and identify if necessary */
2324
	/* scan each callee and identify if necessary */
2295
	needs onepar;
2325
	needs onepar;
2296
	shape shonepar = sh(*par);
2326
	shape shonepar = sh(*par);
2297
	int n = ALIGNNEXT(stpar,shape_align(shonepar));
2327
	int n = ALIGNNEXT(stpar,shape_align(shonepar));
2298
	onepar = scan(par,at);
2328
	onepar = scan(par,at);
2299
	if((onepar.propsneeds & hasproccall)!=0 || onepar.fixneeds+1>maxfix)
2329
	if ((onepar.propsneeds & hasproccall)!=0 || onepar.fixneeds+1>maxfix)
2300
	{
2330
	{
2301
	  /* if it calls a proc identify it */
2331
	  /* if it calls a proc identify it */
2302
	  cca(at,par);
2332
	  cca(at,par);
2303
	  nds.propsneeds |=usesproccall;
2333
	  nds.propsneeds |=usesproccall;
2304
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
2334
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
Line 2311... Line 2341...
2311
	n += shape_size(shonepar);
2341
	n += shape_size(shonepar);
2312
	stpar = ALIGNNEXT(n,32);
2342
	stpar = ALIGNNEXT(n,32);
2313
	par = &bro(*par);
2343
	par = &bro(*par);
2314
      }
2344
      }
2315
      no(cees)=stpar; /* The total no of bits needed for callees */
2345
      no(cees)=stpar; /* The total no of bits needed for callees */
2316
      max_callees = max (max_callees, stpar);
2346
      max_callees = max(max_callees, stpar);
2317
      return nds;
2347
      return nds;
2318
    }
2348
    }
2319
    
2349
 
2320
/********************************************************************/ 
2350
/********************************************************************/
2321
   case make_dynamic_callee_tag:
2351
   case make_dynamic_callee_tag:
2322
    {
2352
    {
2323
      exp cees = *e;
2353
      exp cees = *e;
2324
      exp *ptr = &son(cees);
2354
      exp *ptr = &son(cees);
2325
      needs ndsp;
2355
      needs ndsp;
2326
      needs nds;
2356
      needs nds;
2327
      nds = zeroneeds;
2357
      nds = zeroneeds;
2328
      ndsp = scan(ptr, at);
2358
      ndsp = scan(ptr, at);
2329
      if (((ndsp.propsneeds & hasproccall) != 0) ||
2359
      if (((ndsp.propsneeds & hasproccall)!= 0) ||
2330
	  ndsp.fixneeds+1 > maxfix) 
2360
	  ndsp.fixneeds+1 > maxfix)
2331
      {
2361
      {
2332
	cca (at, ptr);
2362
	cca(at, ptr);
2333
	nds.propsneeds |= usesproccall;
2363
	nds.propsneeds |= usesproccall;
2334
	nds = maxneeds (shapeneeds (sh (* (ptr))), nds);
2364
	nds = maxneeds(shapeneeds(sh(*(ptr))), nds);
2335
	nds.maxargs =  max(nds.maxargs, ndsp.maxargs);
2365
	nds.maxargs =  max(nds.maxargs, ndsp.maxargs);
2336
      }
2366
      }
2337
      else 
2367
      else
2338
      {
2368
      {
2339
	nds = ndsp;
2369
	nds = ndsp;
2340
      }
2370
      }
2341
      ndsp = scan(&bro(son(*e)), at);
2371
      ndsp = scan(&bro(son(*e)), at);
2342
      if (((ndsp.propsneeds & hasproccall) != 0) ||
2372
      if (((ndsp.propsneeds & hasproccall)!= 0) ||
2343
	  ndsp.fixneeds+2 > maxfix) 
2373
	  ndsp.fixneeds+2 > maxfix)
2344
      {
2374
      {
2345
	cca (at, &bro(son(cees)));
2375
	cca(at, &bro(son(cees)));
2346
	nds.propsneeds |= usesproccall;
2376
	nds.propsneeds |= usesproccall;
2347
	nds = maxneeds (shapeneeds (sh (bro(son(*e)))), nds);
2377
	nds = maxneeds(shapeneeds(sh(bro(son(*e)))), nds);
2348
	nds.maxargs = max (nds.maxargs, ndsp.maxargs);
2378
	nds.maxargs = max(nds.maxargs, ndsp.maxargs);
2349
      }
2379
      }
2350
      else 
2380
      else
2351
      {
2381
      {
2352
	nds = maxneeds (ndsp, nds);
2382
	nds = maxneeds(ndsp, nds);
2353
      }
2383
      }
2354
      if (nds.fixneeds<5) nds.fixneeds = 5;
2384
      if (nds.fixneeds<5)nds.fixneeds = 5;
2355
      return nds;
2385
      return nds;
2356
    }
2386
    }
2357
/********************************************************************/
2387
/********************************************************************/
2358
   case tail_call_tag:
2388
   case tail_call_tag:
2359
    {
2389
    {
2360
      needs ndsp;
2390
      needs ndsp;
2361
      needs nds;
2391
      needs nds;
2362
      exp *fn = &son(*e);
2392
      exp *fn = &son(*e);
2363
      ndsp = scan(fn,at);
2393
      ndsp = scan(fn,at);
2364
      tail_call = 1;
2394
      tail_call = 1;
2365
      if(((ndsp.propsneeds & hasproccall)!=0)|| ndsp.fixneeds+1>maxfix)
2395
      if (((ndsp.propsneeds & hasproccall)!=0) || ndsp.fixneeds+1>maxfix)
2366
      {
2396
      {
2367
	cca(at,fn);
2397
	cca(at,fn);
2368
	nds.propsneeds |= usesproccall;
2398
	nds.propsneeds |= usesproccall;
2369
	nds = maxneeds ( shapeneeds(sh(*fn)),nds);
2399
	nds = maxneeds(shapeneeds(sh(*fn)),nds);
2370
	nds.maxargs = max (nds.maxargs,ndsp.maxargs);
2400
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
2371
      }
2401
      }
2372
      else
2402
      else
2373
      {
2403
      {
2374
	nds = ndsp;
2404
	nds = ndsp;
2375
      }
2405
      }
Line 2382... Line 2412...
2382
   case same_callees_tag:
2412
   case same_callees_tag:
2383
    {
2413
    {
2384
      needs nds;
2414
      needs nds;
2385
      nds = zeroneeds;
2415
      nds = zeroneeds;
2386
      nds.fixneeds = 4;
2416
      nds.fixneeds = 4;
2387
      max_callees = max (max_callees, callee_size);
2417
      max_callees = max(max_callees, callee_size);
2388
      return nds;
2418
      return nds;
2389
    }
2419
    }
2390
/********************************************************************/
2420
/********************************************************************/
2391
   case env_size_tag:
2421
   case env_size_tag:
2392
   case set_stack_limit_tag:
2422
   case set_stack_limit_tag:
Line 2419... Line 2449...
2419
      fail("case not covered in needs scan");
2449
      fail("case not covered in needs scan");
2420
      return zeroneeds;
2450
      return zeroneeds;
2421
    }
2451
    }
2422
  }
2452
  }
2423
}
2453
}
2424
int scan_cond PROTO_N ((e, outer_id)) PROTO_T (exp * e X exp outer_id)
2454
int scan_cond(exp * e, exp outer_id)
2425
{
2455
{
2426
  exp ste = *e;
2456
  exp ste = *e;
2427
  exp first = son (ste);
2457
  exp first = son(ste);
2428
  exp labst = bro (first);
2458
  exp labst = bro(first);
2429
  exp second = bro (son (labst));
2459
  exp second = bro(son(labst));
2430
  
-
 
2431
  ASSERT(name(ste)==cond_tag);
-
 
2432
 
2460
 
-
 
2461
  ASSERT(name(ste) ==cond_tag);
-
 
2462
 
2433
  if (name(second)==top_tag && name(sh(first))==bothd && no(son(labst))==1
2463
  if (name(second) ==top_tag && name(sh(first)) ==bothd && no(son(labst)) ==1
2434
      && name(first)==seq_tag && name(bro(son(first))) == goto_tag){
2464
      && name(first) ==seq_tag && name(bro(son(first))) == goto_tag) {
2435
    /* cond is { ... test(L); ? ; goto X | L:make_top}
2465
    /* cond is { ... test(L); ? ; goto X | L:make_top}
2436
       if ? empty can replace by seq { ... not-test(X); make_top }
2466
       if ? empty can replace by seq { ... not-test(X); make_top }
2437
       */
2467
       */
2438
    exp l = son(son(first));
2468
    exp l = son(son(first));
2439
    while(!last(l)) { l = bro(l); }
2469
    while (!last(l)) { l = bro(l); }
2440
    while(name(l)==seq_tag) { l = bro(son(l)); }
2470
    while (name(l) ==seq_tag) { l = bro(son(l)); }
2441
    if (name(l)==test_tag && pt(l)==labst) {
2471
    if (name(l) ==test_tag && pt(l) ==labst) {
2442
      settest_number(l, notbranch[test_number(l)]);
2472
      settest_number(l, notbranch[test_number(l)]);
2443
      pt(l) = pt(bro(son(first)));
2473
      pt(l) = pt(bro(son(first)));
2444
      bro(son(first)) = second;
2474
      bro(son(first)) = second;
2445
      bro(second) = first; setlast(second);
2475
      bro(second) = first; setlast(second);
2446
      bro(first) = bro(ste); 
2476
      bro(first) = bro(ste);
2447
      if(last(ste)) { setlast(first);} else { clearlast(first); }
2477
      if (last(ste)) { setlast(first);} else { clearlast(first); }
2448
      *e = first;
2478
      *e = first;
2449
      return 1;
2479
      return 1;
2450
    }
2480
    }
2451
    else return 0;
2481
    else return 0;
2452
  }
2482
  }
2453
  
2483
 
2454
  
2484
 
2455
  if (name (first) == seq_tag && name (second) == cond_tag 
2485
  if (name(first) == seq_tag && name(second) == cond_tag
2456
      && no(son(labst)) == 1 
2486
      && no(son(labst)) == 1
2457
      && name (son (son (first))) == test_tag 
2487
      && name(son(son(first))) == test_tag
2458
      && pt (son (son (first))) == labst
2488
      && pt(son(son(first))) == labst
2459
      && name (son (second)) == seq_tag
2489
      && name(son(second)) == seq_tag
2460
      && name (son (son (son (second)))) == test_tag) {
2490
      && name(son(son(son(second)))) == test_tag) {
2461
    /* cond is ( seq (test to L;....| 
2491
    /* cond is ( seq (test to L;....|
2462
       L:cond(seq(test;...),...) ) ..... */
2492
       L:cond(seq(test;...),...) ) ..... */
2463
    exp test1 = son (son (first));
2493
    exp test1 = son(son(first));
2464
    exp test2 = son (son (son (second)));
2494
    exp test2 = son(son(son(second)));
2465
    exp op11 = son(test1);
2495
    exp op11 = son(test1);
2466
    exp op21 = bro(op11);
2496
    exp op21 = bro(op11);
2467
    exp op12 = son(test2);
2497
    exp op12 = son(test2);
2468
    exp op22 = bro(op12);
2498
    exp op22 = bro(op12);
2469
    bool c1 = complex (op11);
2499
    bool c1 = complex(op11);
2470
    bool c2 = complex (op21);
2500
    bool c2 = complex(op21);
2471
    
2501
 
2472
    if (c1 && eq_exp (op11, op12)) {
2502
    if (c1 && eq_exp(op11, op12)) {
2473
      /* ....if first operands of tests are
2503
      /* ....if first operands of tests are
2474
	 same, identify them */
2504
	 same, identify them */
2475
      exp newid = getexp (sh (ste), bro (ste), last (ste), op11, nilexp,
2505
      exp newid = getexp(sh(ste), bro(ste), last(ste), op11, nilexp,
2476
			  0, 2, ident_tag);
2506
			  0, 2, ident_tag);
2477
      exp tg1 = getexp (sh (op11), op21, 0, newid, nilexp, 0, 0, name_tag);
2507
      exp tg1 = getexp(sh(op11), op21, 0, newid, nilexp, 0, 0, name_tag);
2478
      exp tg2 = getexp (sh (op12), op22, 0, newid, nilexp, 0, 0, name_tag);
2508
      exp tg2 = getexp(sh(op12), op22, 0, newid, nilexp, 0, 0, name_tag);
2479
      
2509
 
2480
      pt (newid) = tg1;
2510
      pt(newid) = tg1;
2481
      pt (tg1) = tg2;	/* uses of newid */
2511
      pt (tg1) = tg2;	/* uses of newid */
2482
      bro (op11) = ste; clearlast (op11);/* body of newid */
2512
      bro (op11) = ste; clearlast (op11);/* body of newid */
2483
      /* forget son test2 = son test1 */
2513
      /* forget son test2 = son test1 */
2484
      bro (ste) = newid;
2514
      bro(ste) = newid;
2485
      setlast (ste);	/* father body = newid */
2515
      setlast (ste);	/* father body = newid */
2486
      son (test1) = tg1;
2516
      son(test1) = tg1;
2487
      son (test2) = tg2;	/* relace 1st operands of test */
2517
      son (test2) = tg2;	/* relace 1st operands of test */
2488
      if (!complex(op21) ) { 
2518
      if (!complex(op21)) {
2489
	/* if the second operand of 1st test is simple, then identification
2519
	/* if the second operand of 1st test is simple, then identification
2490
	   could go in a t-teg (!!!NB overloading of inlined flag!!!).... */
2520
	   could go in a t-teg (!!!NB overloading of inlined flag!!!).... */
2491
	setinlined(newid); 
2521
	setinlined(newid);
2492
      }
2522
      }
2493
      kill_exp(op12, op12);
2523
      kill_exp(op12, op12);
2494
      * (e) = newid;
2524
      *(e) = newid;
2495
      if( scan_cond (&bro(son(labst)), newid) == 2 && complex(op22)) {
2525
      if (scan_cond(&bro(son(labst)), newid) == 2 && complex(op22)) {
2496
	/* ... however a further use of identification means that 
2526
	/* ... however a further use of identification means that
2497
	   the second operand of the second test must also be simple */
2527
	   the second operand of the second test must also be simple */
2498
	clearinlined(newid);
2528
	clearinlined(newid);
2499
      }
2529
      }
2500
      return 1;
2530
      return 1;
2501
    }
2531
    }
2502
    else
2532
    else
2503
      if (c2 && eq_exp (op21, op22)) {
2533
      if (c2 && eq_exp(op21, op22)) {
2504
	/* ....if second operands of tests are
2534
	/* ....if second operands of tests are
2505
	   same, identify them */
2535
	   same, identify them */
2506
	
2536
 
2507
	exp newid = getexp (sh (ste), bro (ste), last (ste), op21,
2537
	exp newid = getexp(sh(ste), bro(ste), last(ste), op21,
2508
			    nilexp, 0, 2, ident_tag);
2538
			    nilexp, 0, 2, ident_tag);
2509
	exp tg1 = getexp (sh (op21), test1, 1,
2539
	exp tg1 = getexp(sh(op21), test1, 1,
2510
			  newid, nilexp, 0, 0, name_tag);
2540
			  newid, nilexp, 0, 0, name_tag);
2511
	exp tg2 = getexp (sh (op22), test2, 1, newid, nilexp,
2541
	exp tg2 = getexp(sh(op22), test2, 1, newid, nilexp,
2512
			  0, 0, name_tag);
2542
			  0, 0, name_tag);
2513
	
2543
 
2514
	pt (newid) = tg1;
2544
	pt(newid) = tg1;
2515
	pt (tg1) = tg2;	/* uses of newid */
2545
	pt (tg1) = tg2;	/* uses of newid */
2516
	bro (op21) = ste; clearlast (op21);
2546
	bro(op21) = ste; clearlast(op21);
2517
	/* body of newid */
2547
	/* body of newid */
2518
	/* forget bro son test2 = bro son test1 */
2548
	/* forget bro son test2 = bro son test1 */
2519
	bro (ste) = newid;
2549
	bro(ste) = newid;
2520
	setlast (ste);	/* father body = newid */
2550
	setlast (ste);	/* father body = newid */
2521
	bro (op11) = tg1;
2551
	bro(op11) = tg1;
2522
	bro (op12) = tg2;
2552
	bro(op12) = tg2;
2523
	if (!complex(op11) ) { setinlined(newid); }
2553
	if (!complex(op11)) { setinlined(newid); }
2524
	kill_exp(op22, op22);
2554
	kill_exp(op22, op22);
2525
	/* relace 2nd operands of test */
2555
	/* relace 2nd operands of test */
2526
	* (e) = newid;
2556
	*(e) = newid;
2527
	if (scan_cond (&bro(son(labst)), newid) == 2 && complex(op12) ) { 
2557
	if (scan_cond(&bro(son(labst)), newid) == 2 && complex(op12)) {
2528
	  clearinlined(newid); 
2558
	  clearinlined(newid);
2529
	}
2559
	}
2530
	return 1;
2560
	return 1;
2531
      }
2561
      }
2532
      else
2562
      else
2533
	if (name (op12) != name_tag
2563
	if (name(op12)!= name_tag
2534
	    && name (op11) == name_tag 
2564
	    && name(op11) == name_tag
2535
	    && son (op11) == outer_id
2565
	    && son(op11) == outer_id
2536
	    && eq_exp (son (outer_id), op12)
2566
	    && eq_exp(son(outer_id), op12)
2537
	    ) {		/* 1st param of test1 is already identified with
2567
	    ) {		/* 1st param of test1 is already identified with
2538
			   1st param of  test2 */
2568
			   1st param of  test2 */
2539
	  exp tg = getexp (sh (op12), op22, 0, outer_id,
2569
	  exp tg = getexp(sh(op12), op22, 0, outer_id,
2540
			   pt (outer_id), 0, 0, name_tag);
2570
			   pt(outer_id), 0, 0, name_tag);
2541
	  pt (outer_id) = tg;
2571
	  pt(outer_id) = tg;
2542
	  no (outer_id) += 1;
2572
	  no(outer_id) += 1;
2543
	  if (complex(op21) ){ clearinlined(outer_id); }
2573
	  if (complex(op21)) { clearinlined(outer_id); }
2544
	  /* update usage of ident */
2574
	  /* update usage of ident */
2545
	  son (test2) = tg;
2575
	  son(test2) = tg;
2546
	  kill_exp(op12, op12);
2576
	  kill_exp(op12, op12);
2547
	  if (scan_cond (&bro(son(labst)), outer_id) == 2 && complex(op22)) {
2577
	  if (scan_cond(&bro(son(labst)), outer_id) == 2 && complex(op22)) {
2548
	    clearinlined(outer_id);
2578
	    clearinlined(outer_id);
2549
	  }
2579
	  }
2550
	  return 2;
2580
	  return 2;
2551
	}
2581
	}
2552
  }			
2582
  }
2553
  return 0;
2583
  return 0;
2554
}
2584
}
2555
static void number_caller_parameter PROTO_N ((param_id)) PROTO_T (exp param_id)
2585
static void number_caller_parameter(exp param_id)
2556
{
2586
{
2557
  exp init_exp = son(param_id);
2587
  exp init_exp = son(param_id);
2558
  shape param_shape = sh(init_exp);
2588
  shape param_shape = sh(init_exp);
2559
  long par_size = shape_size(param_shape);
2589
  long par_size = shape_size(param_shape);
2560
  long par_stack_location = ALIGNNEXT(stparam,32);
2590
  long par_stack_location = ALIGNNEXT(stparam,32);
2561
  
2591
 
2562
  ASSERT(name(init_exp)==clear_tag);
2592
  ASSERT(name(init_exp) ==clear_tag);
2563
  
2593
 
2564
  if(is_floating(name(param_shape)))
2594
  if (is_floating(name(param_shape)))
2565
  {
2595
  {
2566
    if(floatparam <= FR_LAST_PARAM )
2596
    if (floatparam <= FR_LAST_PARAM)
2567
    {
2597
    {
2568
      props(init_exp) = floatparam;
2598
      props(init_exp) = floatparam;
2569
      floatparam++;
2599
      floatparam++;
2570
    }
2600
    }
2571
    else
2601
    else
2572
    {
2602
    {
2573
      props(init_exp) = 0;/*passed by stack */
2603
      props(init_exp) = 0;/*passed by stack */
2574
    }
2604
    }
2575
  }
2605
  }
2576
  else
2606
  else
2577
  {
2607
  {
2578
    if (fixparam <= end_param)
2608
    if (fixparam <= end_param)
2579
    {
2609
    {
2580
      props(init_exp) = fixparam;
2610
      props(init_exp) = fixparam;
2581
    }
2611
    }
2582
    else
2612
    else
2583
    {
2613
    {
2584
      props(init_exp) = 0;/*passed by stack*/
2614
      props(init_exp) = 0;/*passed by stack*/
Line 2588... Line 2618...
2588
  stparam = ALIGNNEXT(par_stack_location + par_size, 32);
2618
  stparam = ALIGNNEXT(par_stack_location + par_size, 32);
2589
  fixparam = R_FIRST_PARAM + (stparam / 32);
2619
  fixparam = R_FIRST_PARAM + (stparam / 32);
2590
  return;
2620
  return;
2591
}
2621
}
2592
 
2622
 
2593
  
2623
 
2594
static void number_callee_parameter PROTO_N ((callee_id)) PROTO_T (exp callee_id)
2624
static void number_callee_parameter(exp callee_id)
2595
{
2625
{
2596
  exp def = son(callee_id);
2626
  exp def = son(callee_id);
2597
  shape callee_shape = sh(def);
2627
  shape callee_shape = sh(def);
2598
  long size_of_callee = shape_size(callee_shape);
2628
  long size_of_callee = shape_size(callee_shape);
2599
  long alignment_of_callee = shape_align(callee_shape);
2629
  long alignment_of_callee = shape_align(callee_shape);
2600
  long n = ALIGNNEXT( callee_size , alignment_of_callee);
2630
  long n = ALIGNNEXT(callee_size , alignment_of_callee);
2601
 
2631
 
2602
  no(def) = n;
2632
  no(def) = n;
2603
  callee_size = ALIGNNEXT ( n + size_of_callee , 32 );
2633
  callee_size = ALIGNNEXT(n + size_of_callee , 32);
2604
  return;
2634
  return;
2605
}
2635
}