Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

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