Subversion Repositories tendra.SVN

Rev

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

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