Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 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
*/
29
 
59
 
30
 
60
 
31
/* 	$Id: scan.c,v 1.1.1.1 1998/01/17 15:56:01 release Exp $	 */
61
/* 	$Id$	 */
32
 
62
 
33
#ifndef lint
63
#ifndef lint
34
static char vcid[] = "$Id: scan.c,v 1.1.1.1 1998/01/17 15:56:01 release Exp $";
64
static char vcid[] = "$Id$";
35
#endif /* lint */
65
#endif /* lint */
36
 
66
 
37
/*
67
/*
38
$Log: scan.c,v $
68
$Log: scan.c,v $
39
 * Revision 1.1.1.1  1998/01/17  15:56:01  release
69
 * Revision 1.1.1.1  1998/01/17  15:56:01  release
Line 118... Line 148...
118
 * Revision 1.5  1995/05/16  10:55:24  john
148
 * Revision 1.5  1995/05/16  10:55:24  john
119
 * Changes for spec 3.1
149
 * Changes for spec 3.1
120
 *
150
 *
121
 * Revision 1.4  1995/04/10  14:14:05  john
151
 * Revision 1.4  1995/04/10  14:14:05  john
122
 * Fix to likeplus
152
 * Fix to likeplus
123
 *
153
 *
124
 * Revision 1.3  1995/04/07  11:05:49  john
154
 * Revision 1.3  1995/04/07  11:05:49  john
125
 * Fix to scan_cond, and removed subvar_use
155
 * Fix to scan_cond, and removed subvar_use
126
 *
156
 *
127
 * Revision 1.2  1995/03/29  14:05:28  john
157
 * Revision 1.2  1995/03/29  14:05:28  john
128
 * Changes to keep tcheck happy
158
 * Changes to keep tcheck happy
Line 140... Line 170...
140
 * Removed unused code
170
 * Removed unused code
141
 *
171
 *
142
 * Revision 1.19  1995/01/10  09:44:53  john
172
 * Revision 1.19  1995/01/10  09:44:53  john
143
 * Modified register requirements.
173
 * Modified register requirements.
144
 *
174
 *
145
*/
175
*/
146
 
176
 
147
/*
177
/*
148
  scan.c
178
  scan.c
149
  Defines the scan through a program which reorganises it so 
179
  Defines the scan through a program which reorganises it so
150
  that all arguments of operations are suitable for later 
180
  that all arguments of operations are suitable for later
151
  code-production. The procedure scan evaluates the register 
181
  code-production. The procedure scan evaluates the register
152
  requirements of an exp. The exps are produced from the decoding 
182
  requirements of an exp. The exps are produced from the decoding
153
  process and the various exp -> exp transformations in the proc 
183
  process and the various exp -> exp transformations in the proc
154
  independent (common to other  translators)
184
  independent (common to other  translators)
155
*/
185
*/
156
 
186
 
157
#include "config.h"
187
#include "config.h"
158
#include "common_types.h"
188
#include "common_types.h"
159
#include "exptypes.h"
189
#include "exptypes.h"
160
#include "exp.h"
190
#include "exp.h"
161
#include "expmacs.h"
191
#include "expmacs.h"
Line 186... Line 216...
186
int maxfix, maxfloat;		/* the maximum number of t-regs */
216
int maxfix, maxfloat;		/* the maximum number of t-regs */
187
static int stparam, fixparam, floatparam;
217
static int stparam, fixparam, floatparam;
188
       /* used by scan to set initial parameter	positions */
218
       /* used by scan to set initial parameter	positions */
189
static int numparams=0;
219
static int numparams=0;
190
 
220
 
191
extern alignment long_to_al PROTO_S ((int)); 
221
extern alignment long_to_al(int);
192
	
222
 
193
extern long notbranch[6];
223
extern long notbranch[6];
194
extern bool do_tlrecursion;
224
extern bool do_tlrecursion;
195
 
225
 
196
static bool rscope_level = 0;
226
static bool rscope_level = 0;
197
static bool nonevis = 1;
227
static bool nonevis = 1;
198
static int callerfortr;
228
static int callerfortr;
199
 
229
 
200
needs scan PROTO_S ((exp *,exp **));
230
needs scan(exp *,exp **);
201
 
231
 
202
/*
232
/*
203
  identifies integer varieties which require more work to manipulate
233
  identifies integer varieties which require more work to manipulate
204
  (because of a lack of appropriate instructions)
234
  (because of a lack of appropriate instructions)
205
*/
235
*/
206
#define is_awkward_variety(vname) ((vname == scharhd || vname == ucharhd \
236
#define is_awkward_variety(vname)((vname == scharhd || vname == ucharhd \
207
				  || vname == swordhd || vname == uwordhd))
237
				  || vname == swordhd || vname == uwordhd))
208
 
238
 
209
 
239
 
210
 
240
 
211
/* 
241
/*
212
   declaration of scan.  
242
   declaration of scan.
213
   needs is defined in procrectypes.h.
243
   needs is defined in procrectypes.h.
214
   This is a structure which has two integers giving
244
   This is a structure which has two integers giving
215
   the number of fixed and floating point registers required 
245
   the number of fixed and floating point registers required
216
   to contain live values in the expression parameters. A 
246
   to contain live values in the expression parameters. A
217
   further field prop is used for various flags about certain 
247
   further field prop is used for various flags about certain
218
   forms of exp (mainly idents and procs). The maxargs field 
248
   forms of exp (mainly idents and procs). The maxargs field
219
   gives the maximum size in bits for the parameters of all the 
249
   gives the maximum size in bits for the parameters of all the
220
   procs called in the exp. The needs of a proc body are preserved 
250
   procs called in the exp. The needs of a proc body are preserved
221
   in the needs field of the procrec (see procrectypes.h).
251
   in the needs field of the procrec (see procrectypes.h).
222
*/
252
*/
223
 
253
 
224
 
254
 
225
#if DO_NEW_DIVISION 
255
#if DO_NEW_DIVISION
226
#define is_machine_divide(e) (name(bro(son(e))) != val_tag)
256
#define is_machine_divide(e)(name(bro(son(e)))!= val_tag)
227
#else
257
#else
228
#define is_machine_divide(e) 1
258
#define is_machine_divide(e)1
229
#endif
259
#endif
230
 
260
 
231
 
261
 
232
/*
262
/*
233
  cca
263
  cca
234
  
264
 
235
  This procedure effectively inserts a new declaration into an 
265
  This procedure effectively inserts a new declaration into an
236
  exp. This is used to stop a procedure requiring more than the 
266
  exp. This is used to stop a procedure requiring more than the
237
  available number of registers.
267
  available number of registers.
238
*/
268
*/
239
void cca
269
void cca
240
    PROTO_N ( ( to, x ) )
-
 
241
    PROTO_T ( exp **to X exp *x )
270
(exp **to, exp *x)
242
{
271
{
243
 
272
 
244
  if (name((**to))==diagnose_tag){
273
  if (name((**to)) ==diagnose_tag) {
245
    *to = &(son((**to)));  
274
    *to = & (son((**to)));
246
  }
275
  }
247
  if (x == (*to)) {
276
  if (x == (*to)) {
248
    exp def = * (x);
277
    exp def = *(x);
249
    /* replace by  Let tg = def In tg Ni */
278
    /* replace by  Let tg = def In tg Ni */
250
    exp id = getexp (sh (def), bro (def), last (def), def, nilexp,
279
    exp id = getexp(sh(def), bro(def), last(def), def, nilexp,
251
		     0, 1, ident_tag);
280
		     0, 1, ident_tag);
252
    exp tg = getexp (sh (def), id, 1, id, nilexp,
281
    exp tg = getexp(sh(def), id, 1, id, nilexp,
253
		     0, 0, name_tag);
282
		     0, 0, name_tag);
254
    pt (id) = tg;		/* use of tag */
283
    pt (id) = tg;		/* use of tag */
255
    bro (def) = tg;		/* bro(def) is body of Let = tg */
284
    bro (def) = tg;		/* bro(def) is body of Let = tg */
256
    clearlast (def);
285
    clearlast(def);
257
    * (x) = id;		/* replace pointer to x by Let */
286
    * (x) = id;		/* replace pointer to x by Let */
258
    return;
287
    return;
259
  }
288
  }
260
  else {		/* replace by Let tg = def In ato/def = tg
289
  else {		/* replace by Let tg = def In ato/def = tg
261
			   Ni */
290
			   Ni */
262
    exp def = * (x);
291
    exp def = *(x);
263
    exp ato = * (*to);
292
    exp ato = *(*to);
264
    exp id = getexp (sh (ato), bro (ato), last (ato), def, nilexp,
293
    exp id = getexp(sh(ato), bro(ato), last(ato), def, nilexp,
265
		     0, 1, ident_tag);
294
		     0, 1, ident_tag);
266
    exp tg = getexp (sh (def), bro (def), last (def), id, nilexp,
295
    exp tg = getexp(sh(def), bro(def), last(def), id, nilexp,
267
		     0, 0, name_tag);
296
		     0, 0, name_tag);
268
    pt (id) = tg;		/* use of tg */
297
    pt (id) = tg;		/* use of tg */
269
    bro (def) = ato;		/* ato is body of Let */
298
    bro (def) = ato;		/* ato is body of Let */
270
    clearlast (def);
299
    clearlast(def);
271
    bro (ato) = id;		/* its father is Let */
300
    bro (ato) = id;		/* its father is Let */
272
    setlast (ato);
301
    setlast(ato);
273
    * (*to) = id;		/* replace pointer to 'to' by Let */
302
    * (*to) = id;		/* replace pointer to 'to' by Let */
274
    * (x) = tg;		/* replace use of x by tg */
303
    * (x) = tg;		/* replace use of x by tg */
275
    *to = & bro(def);		/* later replacement to same 'to' will be
304
    *to = & bro(def);		/* later replacement to same 'to' will be
276
				   at body of Let */
305
				   at body of Let */
277
    return;
306
    return;
Line 303... Line 332...
303
  0, 1, 0, 0
332
  0, 1, 0, 0
304
};				/* needs 1 flt pt regs */
333
};				/* needs 1 flt pt regs */
305
needs zeroneeds = {
334
needs zeroneeds = {
306
  0, 0, 0, 0
335
  0, 0, 0, 0
307
};				/* has no needs */
336
};				/* has no needs */
308
	     
337
 
309
 
338
 
310
 
339
 
311
/*
340
/*
312
  Calculate the number of registers required to move a data item of 
341
  Calculate the number of registers required to move a data item of
313
  shape s to/from memory.  Worst case values.
342
  shape s to/from memory.  Worst case values.
314
*/
343
*/
315
needs shapeneeds
344
needs shapeneeds
316
    PROTO_N ( ( s ) )
-
 
317
    PROTO_T ( shape s )
345
(shape s)
318
{
346
{
319
  if(is_floating(name(s))){
347
  if (is_floating(name(s))) {
320
    return onefloat;
348
    return onefloat;
321
  }
349
  }
322
  else{
350
  else{
323
    ash as;
351
    ash as;
324
    as = ashof(s);
352
    as = ashof(s);
325
    if((as.ashalign==8) /*&& (name(s)==ptrhd)*/){
353
    if((as.ashalign==8) /*&& (name(s)==ptrhd)*/){
326
      return fourfix;
354
      return fourfix;
327
    }
355
    }
328
    if((as.ashalign==16)) {
356
    if ((as.ashalign==16)) {
329
      return fivefix;		/* If not aligned on 4 byte boundary */
357
      return fivefix;		/* If not aligned on 4 byte boundary */
330
    }
358
    }
331
    if(valregable(s)){
359
    if (valregable(s)) {
332
      return onefix;
360
      return onefix;
333
    }
361
    }
334
    else{
362
    else{
335
      return twofix;
363
      return twofix;
336
    }
364
    }
337
  }
365
  }
338
}
366
}
339
 
367
 
340
static void make_bitfield_offset
368
static void make_bitfield_offset
341
    PROTO_N ( ( e,pe,spe,sha ) )
-
 
342
    PROTO_T ( exp e X exp pe X int spe X shape sha )
369
(exp e, exp pe, int spe, shape sha)
343
{
370
{
344
  exp omul;
371
  exp omul;
345
  exp val8;
372
  exp val8;
346
  if (name(e) == val_tag){
373
  if (name(e) == val_tag) {
347
    no(e) *= 8;
374
    no(e)*= 8;
348
    return;
375
    return;
349
  }
376
  }
350
  omul = getexp(sha,bro(e),(int)(last (e)),e,nilexp,0,0,offset_mult_tag);
377
  omul = getexp(sha,bro(e), (int)(last(e)),e,nilexp,0,0,offset_mult_tag);
351
  val8 = getexp(slongsh,omul,1,nilexp,nilexp,0,8,val_tag);
378
  val8 = getexp(slongsh,omul,1,nilexp,nilexp,0,8,val_tag);
352
  clearlast(e);
379
  clearlast(e);
353
  setbro(e, val8);
380
  setbro(e, val8);
354
  if(spe) {
381
  if (spe) {
355
    son(pe) = omul;
382
    son(pe) = omul;
356
  }
383
  }
357
  else{
384
  else{
358
    bro(pe) = omul;
385
    bro(pe) = omul;
359
  }
386
  }
360
  return;
387
  return;
361
}
388
}
362
 
389
 
363
bool complex
390
bool complex
364
    PROTO_N ( ( e ) )
-
 
365
    PROTO_T ( exp e )
391
(exp e)
366
{
392
{
367
  /* these are basically the expressions
393
  /* these are basically the expressions
368
     which cannot be accessed by a simple
394
     which cannot be accessed by a simple
369
     load or store instruction */
395
     load or store instruction */
370
  if(name (e) == name_tag || 
396
  if (name(e) == name_tag ||
371
     (name (e) == cont_tag && name (son (e)) == name_tag &&
397
    (name(e) == cont_tag && name(son(e)) == name_tag &&
372
      isvar (son (son (e))))
398
      isvar(son(son(e))))
373
     || name (e) == val_tag || name (e) == real_tag || name(e)==null_tag ) {
399
     || name(e) == val_tag || name(e) == real_tag || name(e) ==null_tag) {
374
    return 0;
400
    return 0;
375
  }
401
  }
376
  else {
402
  else {
377
    return 1;
403
    return 1;
378
  }
404
  }
379
}
405
}
380
 
406
 
381
int scan_cond
407
int scan_cond
382
    PROTO_N ( ( e,outer_id ) )
-
 
383
    PROTO_T ( exp *e X exp outer_id )
408
(exp *e, exp outer_id)
384
{
409
{
385
  exp ste = *e;
410
  exp ste = *e;
386
  exp first = son (ste);
411
  exp first = son(ste);
387
  exp labst = bro (first);
412
  exp labst = bro(first);
388
  exp second = bro (son (labst));
413
  exp second = bro(son(labst));
389
  
414
 
390
  Assert(name(ste)==cond_tag);
415
  Assert(name(ste) ==cond_tag);
391
  
416
 
392
  if (name(second)==top_tag && name(sh(first))==bothd && no(son(labst))==1
417
  if (name(second) ==top_tag && name(sh(first)) ==bothd && no(son(labst)) ==1
393
      && name(first)==seq_tag && name(bro(son(first))) == goto_tag){
418
      && name(first) ==seq_tag && name(bro(son(first))) == goto_tag) {
394
    /* cond is { ... test(L); ? ; goto X | L:make_top}
419
    /* cond is { ... test(L); ? ; goto X | L:make_top}
395
       if ? empty can replace by seq { ... not-test(X); make_top }
420
       if ? empty can replace by seq { ... not-test(X); make_top }
396
       */
421
       */
397
    exp l = son(son(first));
422
    exp l = son(son(first));
398
    while(!last(l)) { l = bro(l); }
423
    while (!last(l)) { l = bro(l); }
399
    while(name(l)==seq_tag) { l = bro(son(l)); }
424
    while (name(l) ==seq_tag) { l = bro(son(l)); }
400
    if (name(l)==test_tag && pt(l)==labst) {
425
    if (name(l) ==test_tag && pt(l) ==labst) {
401
      settest_number(l, notbranch[test_number(l)-1]);
426
      settest_number(l, notbranch[test_number(l) -1]);
402
      pt(l) = pt(bro(son(first)));
427
      pt(l) = pt(bro(son(first)));
403
      bro(son(first)) = second;
428
      bro(son(first)) = second;
404
      bro(second) = first; setlast(second);
429
      bro(second) = first; setlast(second);
405
      bro(first) = bro(ste); 
430
      bro(first) = bro(ste);
406
      if(last(ste)) { setlast(first);} else { clearlast(first); }
431
      if (last(ste)) { setlast(first);} else { clearlast(first); }
407
      *e = first;
432
      *e = first;
408
      return 1;
433
      return 1;
409
    }
434
    }
410
    else return 0;
435
    else return 0;
411
  }
436
  }
412
 
437
 
413
 
438
 
414
  if (name (first) == seq_tag && name (second) == cond_tag 
439
  if (name(first) == seq_tag && name(second) == cond_tag
415
      && no(son(labst)) == 1 
440
      && no(son(labst)) == 1
416
      && name (son (son (first))) == test_tag 
441
      && name(son(son(first))) == test_tag
417
      && pt (son (son (first))) == labst
442
      && pt(son(son(first))) == labst
418
      && name (son (second)) == seq_tag
443
      && name(son(second)) == seq_tag
419
      && name (son (son (son (second)))) == test_tag) {
444
      && name(son(son(son(second)))) == test_tag) {
420
    /* cond is ( seq (test to L;....| L:cond(seq(test;...),...) ) 
445
    /* cond is ( seq (test to L;....| L:cond(seq(test;...),...) )
421
       ..... */
446
       ..... */
422
    exp test1 = son (son (first));
447
    exp test1 = son(son(first));
423
    exp test2 = son (son (son (second)));
448
    exp test2 = son(son(son(second)));
424
    exp op11 = son(test1);
449
    exp op11 = son(test1);
425
    exp op21 = bro(op11);
450
    exp op21 = bro(op11);
426
    exp op12 = son(test2);
451
    exp op12 = son(test2);
427
    exp op22 = bro(op12);
452
    exp op22 = bro(op12);
428
    bool c1 = complex (op11);
453
    bool c1 = complex(op11);
429
    bool c2 = complex (op21);
454
    bool c2 = complex(op21);
430
 
455
 
431
    if (c1 && eq_exp (op11, op12)) {
456
    if (c1 && eq_exp(op11, op12)) {
432
				/* ....if first operands of tests are
457
				/* ....if first operands of tests are
433
				   same, identify them */
458
				   same, identify them */
434
      exp newid = getexp (sh (ste), bro (ste), last (ste), op11, nilexp,
459
      exp newid = getexp(sh(ste), bro(ste), last(ste), op11, nilexp,
435
			  0, 2, ident_tag);
460
			  0, 2, ident_tag);
436
      exp tg1 = getexp (sh (op11), op21, 0, newid, nilexp, 0, 0, name_tag);
461
      exp tg1 = getexp(sh(op11), op21, 0, newid, nilexp, 0, 0, name_tag);
437
      exp tg2 = getexp (sh (op12), op22, 0, newid, nilexp, 0, 0, name_tag);
462
      exp tg2 = getexp(sh(op12), op22, 0, newid, nilexp, 0, 0, name_tag);
438
      
463
 
439
      pt (newid) = tg1;
464
      pt(newid) = tg1;
440
      pt (tg1) = tg2;	/* uses of newid */
465
      pt (tg1) = tg2;	/* uses of newid */
441
      bro (op11) = ste; clearlast (op11);/* body of newid */
466
      bro (op11) = ste; clearlast (op11);/* body of newid */
442
      /* forget son test2 = son test1 */
467
      /* forget son test2 = son test1 */
443
      bro (ste) = newid;
468
      bro(ste) = newid;
444
      setlast (ste);	/* father body = newid */
469
      setlast (ste);	/* father body = newid */
445
      son (test1) = tg1;
470
      son(test1) = tg1;
446
      son (test2) = tg2;	/* relace 1st operands of test */
471
      son (test2) = tg2;	/* relace 1st operands of test */
447
      if (!complex(op21) ) { 
472
      if (!complex(op21)) {
448
	/* if the second operand of 1st test is 
473
	/* if the second operand of 1st test is
449
	   simple, then identification could go 
474
	   simple, then identification could go
450
	   in a t-teg (!!!NB overloading of inlined flag!!!).... */
475
	   in a t-teg (!!!NB overloading of inlined flag!!!).... */
451
	setinlined(newid); 
476
	setinlined(newid);
452
      }
477
      }
453
      kill_exp(op12, op12);
478
      kill_exp(op12, op12);
454
      * (e) = newid;
479
      *(e) = newid;
455
      if( scan_cond (&bro(son(labst)), newid) == 2 && complex(op22)) {
480
      if (scan_cond(&bro(son(labst)), newid) == 2 && complex(op22)) {
456
	/* ... however a further use of identification means that 
481
	/* ... however a further use of identification means that
457
	   the second operand of the second test must also be simple */
482
	   the second operand of the second test must also be simple */
458
	clearinlined(newid);
483
	clearinlined(newid);
459
      }
484
      }
460
      return 1;
485
      return 1;
461
    }
486
    }
462
    else if (c2 && eq_exp (op21, op22)) {
487
    else if (c2 && eq_exp(op21, op22)) {
463
				/* ....if second operands of tests are
488
				/* ....if second operands of tests are
464
				   same, identify them */
489
				   same, identify them */
465
 
490
 
466
      exp newid = getexp (sh (ste), bro (ste), last (ste), op21,
491
      exp newid = getexp(sh(ste), bro(ste), last(ste), op21,
467
			  nilexp, 0, 2, ident_tag);
492
			  nilexp, 0, 2, ident_tag);
468
      exp tg1 = getexp (sh (op21), test1, 1,
493
      exp tg1 = getexp(sh(op21), test1, 1,
469
			newid, nilexp, 0, 0, name_tag);
494
			newid, nilexp, 0, 0, name_tag);
470
      exp tg2 = getexp (sh (op22), test2, 1, newid, nilexp,
495
      exp tg2 = getexp(sh(op22), test2, 1, newid, nilexp,
471
			0, 0, name_tag);
496
			0, 0, name_tag);
472
 
497
 
473
      pt (newid) = tg1;
498
      pt(newid) = tg1;
474
      pt (tg1) = tg2;	/* uses of newid */
499
      pt (tg1) = tg2;	/* uses of newid */
475
      bro (op21) = ste; clearlast (op21);
500
      bro(op21) = ste; clearlast(op21);
476
      /* body of newid */
501
      /* body of newid */
477
      /* forget bro son test2 = bro son test1 */
502
      /* forget bro son test2 = bro son test1 */
478
      bro (ste) = newid;
503
      bro(ste) = newid;
479
      setlast (ste);	/* father body = newid */
504
      setlast (ste);	/* father body = newid */
480
      bro (op11) = tg1;
505
      bro(op11) = tg1;
481
      bro (op12) = tg2;
506
      bro(op12) = tg2;
482
      if (!complex(op11) ) { setinlined(newid); }
507
      if (!complex(op11)) { setinlined(newid); }
483
      kill_exp(op22, op22);
508
      kill_exp(op22, op22);
484
      /* relace 2nd operands of test */
509
      /* relace 2nd operands of test */
485
      * (e) = newid;
510
      *(e) = newid;
486
      if (scan_cond (&bro(son(labst)), newid) == 2 && complex(op12) ) { 
511
      if (scan_cond(&bro(son(labst)), newid) == 2 && complex(op12)) {
487
	clearinlined(newid); 
512
	clearinlined(newid);
488
      }
513
      }
489
      return 1;
514
      return 1;
490
    }
515
    }
491
    else if (name (op12) != name_tag
516
    else if (name(op12)!= name_tag
492
	     && name (op11) == name_tag 
517
	     && name(op11) == name_tag
493
	     && son (op11) == outer_id
518
	     && son(op11) == outer_id
494
	     && eq_exp (son (outer_id), op12)
519
	     && eq_exp(son(outer_id), op12)
495
	     ) {		
520
	    ) {
496
      /* 1st param of test1 is already identified with 
521
      /* 1st param of test1 is already identified with
497
	 1st param of  test2 */
522
	 1st param of  test2 */
498
      exp tg = getexp (sh (op12), op22, 0, outer_id,
523
      exp tg = getexp(sh(op12), op22, 0, outer_id,
499
		       pt (outer_id), 0, 0, name_tag);
524
		       pt(outer_id), 0, 0, name_tag);
500
      pt (outer_id) = tg;
525
      pt(outer_id) = tg;
501
      no (outer_id) += 1;
526
      no(outer_id) += 1;
502
      if (complex(op21) ){ clearinlined(outer_id); }
527
      if (complex(op21)) { clearinlined(outer_id); }
503
      /* update usage of ident */
528
      /* update usage of ident */
504
      son (test2) = tg;
529
      son(test2) = tg;
505
      kill_exp(op12, op12);
530
      kill_exp(op12, op12);
506
      if (scan_cond (&bro(son(labst)), outer_id) == 2 && complex(op22)) {
531
      if (scan_cond(&bro(son(labst)), outer_id) == 2 && complex(op22)) {
507
	clearinlined(outer_id);
532
	clearinlined(outer_id);
508
      }
533
      }
509
      return 2;
534
      return 2;
510
    }
535
    }
511
  }			
536
  }
512
  return 0;
537
  return 0;
513
}
538
}
514
 
539
 
515
/* 
540
/*
516
   does the scan on commutative and associative operations and 
541
   does the scan on commutative and associative operations and
517
   may perform various transformations allowed by these properties 
542
   may perform various transformations allowed by these properties
518
*/
543
*/
519
needs likeplus
544
needs likeplus
520
    PROTO_N ( ( e, at ) )
-
 
521
    PROTO_T ( exp *e X exp **at )
545
(exp *e, exp **at)
522
{
546
{
523
  needs a1;
547
  needs a1;
524
  needs a2;
548
  needs a2;
525
  prop pc;
549
  prop pc;
526
  exp * br  = &son(*e);
550
  exp * br  = &son(*e);
527
  exp dad = * (e);
551
  exp dad = *(e);
528
  exp prev;
552
  exp prev;
529
  bool commuted = 0;
553
  bool commuted = 0;
530
 
554
 
531
#if 0
555
#if 0
532
  if(optop(*e)){
556
  if (optop(*e)) {
533
    Assert(name(*br) != val_tag);
557
    Assert(name(*br)!= val_tag);
534
  }
558
  }
535
#endif
559
#endif
536
  a1 = scan (br, at);
560
  a1 = scan(br, at);
537
  /* scan the first operand - won't be a val_tag */
561
  /* scan the first operand - won't be a val_tag */
538
  do {
562
  do {
539
    exp * prevbr;
563
    exp * prevbr;
540
    prevbr = br;
564
    prevbr = br;
541
    prev = * (br);
565
    prev = *(br);
542
    br = &bro(prev);
566
    br = &bro(prev);
543
    a2 = scan (br, at);
567
    a2 = scan(br, at);
544
    /* scan the next operand ... */    
568
    /* scan the next operand ... */
545
    if (name (* (br)) != val_tag) {      
569
    if (name(*(br))!= val_tag) {
546
      a1.floatneeds = max (a1.floatneeds, a2.floatneeds);
570
      a1.floatneeds = max(a1.floatneeds, a2.floatneeds);
547
      pc = a2.propsneeds & hasproccall;
571
      pc = a2.propsneeds & hasproccall;
548
      if (a2.fixneeds < maxfix && pc == 0) {
572
      if (a2.fixneeds < maxfix && pc == 0) {
549
	/* ..its evaluation  will not disturb the accumulated result */
573
	/* ..its evaluation  will not disturb the accumulated result */
550
	a1.fixneeds = max (a1.fixneeds, a2.fixneeds + 1);
574
	a1.fixneeds = max(a1.fixneeds, a2.fixneeds + 1);
551
	a1.propsneeds = a1.propsneeds | a2.propsneeds;
575
	a1.propsneeds = a1.propsneeds | a2.propsneeds;
552
      }
576
      }
553
      else if (a1.fixneeds < maxfix &&
577
      else if (a1.fixneeds < maxfix &&
554
	       (a1.propsneeds & hasproccall) == 0 && !commuted) {
578
	      (a1.propsneeds & hasproccall) == 0 && !commuted) {
555
	/* ..its evaluation will call a proc, so put it first */
579
	/* ..its evaluation will call a proc, so put it first */
556
	exp op1 = son (dad);
580
	exp op1 = son(dad);
557
	exp cop = * (br);
581
	exp cop = *(br);
558
	bool lcop = last (cop);
582
	bool lcop = last(cop);
559
	bro (prev) = bro (cop);
583
	bro(prev) = bro(cop);
560
	if (lcop)
584
	if (lcop)
561
	  setlast (prev);
585
	  setlast(prev);
562
	bro (cop) = op1;
586
	bro(cop) = op1;
563
	clearlast (cop);
587
	clearlast(cop);
564
	son (dad) = cop;
588
	son(dad) = cop;
565
	br = (prev==op1) ? &bro(cop):prevbr;
589
	br = (prev==op1)? &bro(cop):prevbr;
566
	commuted = 1;
590
	commuted = 1;
567
	a1.fixneeds = max (a2.fixneeds, a1.fixneeds + 1);
591
	a1.fixneeds = max(a2.fixneeds, a1.fixneeds + 1);
568
	a1.propsneeds |= a2.propsneeds;
592
	a1.propsneeds |= a2.propsneeds;
569
	a1.maxargs = max (a1.maxargs, a2.maxargs);
593
	a1.maxargs = max(a1.maxargs, a2.maxargs);
570
      }
594
      }
571
      else {	/* ... its evaluation would disturb
595
      else {	/* ... its evaluation would disturb
572
		   accumulated result, so replace it by a
596
		   accumulated result, so replace it by a
573
		   newly declared tag */
597
		   newly declared tag */
574
	cca (at, br);
598
	cca(at, br);
575
	a1.fixneeds = max (a1.fixneeds, 2);
599
	a1.fixneeds = max(a1.fixneeds, 2);
576
	a1.propsneeds = a1.propsneeds | morefix | (pc << 1);
600
	a1.propsneeds = a1.propsneeds | morefix | (pc << 1);
577
	a1.maxargs = max (a1.maxargs, a2.maxargs);
601
	a1.maxargs = max(a1.maxargs, a2.maxargs);
578
      }
602
      }
579
    }	
603
    }
580
  } while (!last (* (br)));
604
  } while (!last(*(br)));
581
  return a1;
605
  return a1;
582
}
606
}
583
 
607
 
584
 
608
 
585
needs likediv
609
needs likediv
586
    PROTO_N ( ( e, at ) )
-
 
587
    PROTO_T ( exp *e X exp **at )
610
(exp *e, exp **at)
588
{
611
{
589
  /* scan non-commutative fix pt operation 
612
  /* scan non-commutative fix pt operation
590
   */
613
   */
591
  needs l;
614
  needs l;
592
  needs r;
615
  needs r;
593
  prop pc;
616
  prop pc;
594
  exp * arg = &son(*e);
617
  exp * arg = &son(*e);
595
  l = scan (arg, at);
618
  l = scan(arg, at);
596
  /* scan 1st operand */
619
  /* scan 1st operand */
597
  arg = &bro(*arg);
620
  arg = &bro(*arg);
598
  r = scan (arg, at);
621
  r = scan(arg, at);
599
  /* scan second operand ... */
622
  /* scan second operand ... */
600
  l.floatneeds = max (l.floatneeds, r.floatneeds);
623
  l.floatneeds = max(l.floatneeds, r.floatneeds);
601
  pc = r.propsneeds & hasproccall;
624
  pc = r.propsneeds & hasproccall;
602
  if (r.fixneeds < maxfix && pc == 0) {/* ...it fits into registers */
625
  if (r.fixneeds < maxfix && pc == 0) {/* ...it fits into registers */
603
    l.fixneeds = max (l.fixneeds, r.fixneeds + 1);
626
    l.fixneeds = max(l.fixneeds, r.fixneeds + 1);
604
    l.propsneeds = l.propsneeds | r.propsneeds;
627
    l.propsneeds = l.propsneeds | r.propsneeds;
605
  }
628
  }
606
  else {			/* ...it requires new declaration of
629
  else {			/* ...it requires new declaration of
607
				   second operand */
630
				   second operand */
608
    cca (at, arg);
631
    cca(at, arg);
609
    l.fixneeds = max (l.fixneeds, 1);
632
    l.fixneeds = max(l.fixneeds, 1);
610
    l.propsneeds = l.propsneeds | morefix | (pc << 1);
633
    l.propsneeds = l.propsneeds | morefix | (pc << 1);
611
    l.maxargs = max (l.maxargs, r.maxargs);
634
    l.maxargs = max(l.maxargs, r.maxargs);
612
  }
635
  }
613
  return l;
636
  return l;
614
}
637
}
615
 
638
 
616
needs fpop
639
needs fpop
617
    PROTO_N ( ( e, at ) )
-
 
618
    PROTO_T ( exp *e X exp **at )
640
(exp *e, exp **at)
619
{
641
{
620
  /* scans diadic floating point operation  */
642
  /* scans diadic floating point operation  */
621
  needs l;
643
  needs l;
622
  needs r;
644
  needs r;
623
  exp op = *(e);
645
  exp op = *(e);
624
  prop pcr, pcl;
646
  prop pcr, pcl;
625
  exp * arg = &son(op);
647
  exp * arg = &son(op);
626
  bool withert = !(optop(*e));
648
  bool withert = !(optop(*e));
627
 
649
 
628
  l = scan (arg, at);
650
  l = scan(arg, at);
629
  arg = &bro(*arg);
651
  arg = &bro(*arg);
630
  r = scan (arg, at);
652
  r = scan(arg, at);
631
  l.fixneeds = max (l.fixneeds, r.fixneeds);
653
  l.fixneeds = max(l.fixneeds, r.fixneeds);
632
  pcr = r.propsneeds & hasproccall;
654
  pcr = r.propsneeds & hasproccall;
633
  pcl = l.propsneeds & hasproccall;
655
  pcl = l.propsneeds & hasproccall;
634
 
656
 
635
  if (r.floatneeds <= l.floatneeds && r.floatneeds < maxfloat && pcr==0) {
657
  if (r.floatneeds <= l.floatneeds && r.floatneeds < maxfloat && pcr==0) {
636
    l.floatneeds = max (2, max (l.floatneeds, r.floatneeds + 1));
658
    l.floatneeds = max(2, max(l.floatneeds, r.floatneeds + 1));
637
    l.propsneeds = l.propsneeds | r.propsneeds;
659
    l.propsneeds = l.propsneeds | r.propsneeds;
638
    ClearRev(op);
660
    ClearRev(op);
639
  }
661
  }
640
  else if (pcl == 0 && l.floatneeds<=r.floatneeds && l.floatneeds<maxfloat ) {
662
  else if (pcl == 0 && l.floatneeds<=r.floatneeds && l.floatneeds<maxfloat) {
641
    l.floatneeds = max (2, max (r.floatneeds, l.floatneeds + 1));
663
    l.floatneeds = max(2, max(r.floatneeds, l.floatneeds + 1));
642
    l.propsneeds = l.propsneeds | r.propsneeds;
664
    l.propsneeds = l.propsneeds | r.propsneeds;
643
    SetRev(op);
665
    SetRev(op);
644
  } 	   
666
  }
645
  else if (r.floatneeds < maxfloat && pcr == 0) {
667
  else if (r.floatneeds < maxfloat && pcr == 0) {
646
    l.floatneeds = max (2, max (l.floatneeds, r.floatneeds + 1));
668
    l.floatneeds = max(2, max(l.floatneeds, r.floatneeds + 1));
647
    l.propsneeds = l.propsneeds | r.propsneeds;
669
    l.propsneeds = l.propsneeds | r.propsneeds;
648
    ClearRev(op);
670
    ClearRev(op);
649
  }
671
  }
650
  else {
672
  else {
651
    cca (at, arg);
673
    cca(at, arg);
652
    ClearRev(op);
674
    ClearRev(op);
653
    l.floatneeds = max (l.floatneeds, 2);
675
    l.floatneeds = max(l.floatneeds, 2);
654
    l.propsneeds = l.propsneeds | morefloat | (pcr << 1);
676
    l.propsneeds = l.propsneeds | morefloat | (pcr << 1);
655
    l.maxargs = max (l.maxargs, r.maxargs);
677
    l.maxargs = max(l.maxargs, r.maxargs);
656
  }
678
  }
657
  if (withert && l.fixneeds < 2) l.fixneeds = 2;
679
  if (withert && l.fixneeds < 2)l.fixneeds = 2;
658
  return l;
680
  return l;
659
}
681
}
660
 
682
 
661
/*
683
/*
662
  maxneeds
684
  maxneeds
663
  Calculates a needs value. Each element of which is the 
685
  Calculates a needs value. Each element of which is the
664
  maximum of the corresponding elements in the two parameter needs
686
  maximum of the corresponding elements in the two parameter needs
665
*/
687
*/
666
needs maxneeds
688
needs maxneeds
667
    PROTO_N ( ( a, b ) )
-
 
668
    PROTO_T ( needs a X needs b )
689
(needs a, needs b)
669
{
690
{
670
  needs an;
691
  needs an;
671
  an.fixneeds = max (a.fixneeds, b.fixneeds);
692
  an.fixneeds = max(a.fixneeds, b.fixneeds);
672
  an.floatneeds = max (a.floatneeds, b.floatneeds);
693
  an.floatneeds = max(a.floatneeds, b.floatneeds);
673
  an.maxargs = max (a.maxargs, b.maxargs);
694
  an.maxargs = max(a.maxargs, b.maxargs);
674
  an.numparams=max(a.numparams,b.numparams);
695
  an.numparams=max(a.numparams,b.numparams);
675
  an.propsneeds = a.propsneeds | b.propsneeds;
696
  an.propsneeds = a.propsneeds | b.propsneeds;
676
  return an;
697
  return an;
677
}
698
}
678
 
699
 
679
/* 
700
/*
680
   calculates the needs of a tuple of expressions; any new 
701
   calculates the needs of a tuple of expressions; any new
681
   declarations required by a component expression will
702
   declarations required by a component expression will
682
   replace the component expression 
703
   replace the component expression
683
*/
704
*/
684
needs maxtup
705
needs maxtup
685
    PROTO_N ( ( e, at ) )
-
 
686
    PROTO_T ( exp e X exp **at )
706
(exp e, exp **at)
687
{
707
{
688
  exp * stat = &son(e);
708
  exp * stat = &son(e);
689
  needs an;
709
  needs an;
690
  
710
 
691
  an = zeroneeds;
711
  an = zeroneeds;
692
  if(son(e) == nilexp) return zeroneeds;
712
  if (son(e) == nilexp) return zeroneeds;
693
  while (an = maxneeds (an, scan (stat, at)), !last(*stat) ) {
713
  while (an = maxneeds(an, scan(stat, at)), !last(*stat)) {
694
    stat = &bro(*stat);
714
    stat = &bro(*stat);
695
  }
715
  }
696
  return an;
716
  return an;
697
}
717
}
698
 
718
 
699
/* 
719
/*
700
   finds if usedname is only used in cont operation or as result 
720
   finds if usedname is only used in cont operation or as result
701
   of ident i.e. value of name is unchanged over its scope 
721
   of ident i.e. value of name is unchanged over its scope
702
*/
722
*/
703
bool unchanged
723
bool unchanged
704
    PROTO_N ( ( usedname, ident ) )
-
 
705
    PROTO_T ( exp usedname X exp ident )
724
(exp usedname, exp ident)
706
{
725
{
707
  exp uses = pt (usedname);
726
  exp uses = pt(usedname);
708
  while (uses != nilexp) {
727
  while (uses != nilexp) {
709
    if (intnl_to (ident, uses)) {
728
    if (intnl_to(ident, uses)) {
710
      if (!last (uses) || name (bro (uses)) != cont_tag) {
729
      if (!last(uses) || name(bro(uses))!= cont_tag) {
711
	exp z = uses;
730
	exp z = uses;
712
	while (z != ident) {
731
	while (z != ident) {
713
	  if (!last (z) ||
732
	  if (!last(z) ||
714
	      (name (bro (z)) != seq_tag && name (bro (z)) != ident_tag)) {
733
	     (name(bro(z))!= seq_tag && name(bro(z))!= ident_tag)) {
715
	    return 0;
734
	    return 0;
716
	  }
735
	  }
717
	  z = bro (z);
736
	  z = bro(z);
718
	}
737
	}
719
      }
738
      }
720
    }
739
    }
721
    uses = pt (uses);
740
    uses = pt(uses);
722
  }
741
  }
723
  return 1;
742
  return 1;
724
}
743
}
725
 
744
 
726
 
745
 
727
/* check if e  is (let a = 0 in cond(inttest(L)=result; a=1 | L:top);
746
/* check if e  is (let a = 0 in cond(inttest(L)=result; a=1 | L:top);
728
   a ni ) This will be compiled later using set instructions instead
747
   a ni ) This will be compiled later using set instructions instead
729
   of branches 
748
   of branches
730
*/
749
*/
731
exp absbool
750
exp absbool
732
    PROTO_N ( ( id ) )
-
 
733
    PROTO_T ( exp id )
751
(exp id)
734
{
752
{
735
  if (isvar (id) && name (son (id)) == val_tag && no (son (id)) == 0
753
  if (isvar(id) && name(son(id)) == val_tag && no(son(id)) == 0
736
      && no (id) == 2 /* name initially 0 only used twice */ ) {
754
      && no (id) == 2 /* name initially 0 only used twice */ ) {
737
    exp bdy = bro (son (id));
755
    exp bdy = bro(son(id));
738
    if (name (bdy) == seq_tag && name (bro (son (bdy))) == cont_tag &&
756
    if (name(bdy) == seq_tag && name(bro(son(bdy))) == cont_tag &&
739
	name (son (bro (son (bdy)))) == name_tag &&
757
	name(son(bro(son(bdy)))) == name_tag &&
740
	son (son (bro (son (bdy)))) == id
758
	son(son(bro(son(bdy)))) == id
741
	/* one use is result  of sequence body */ ) {
759
	/* one use is result  of sequence body */ ) {
742
      exp c = son (son (bdy));
760
      exp c = son(son(bdy));
743
      if (last (c) && name (c) == cond_tag /* seq is cond=c; id */ ) {
761
      if (last (c) && name (c) == cond_tag /* seq is cond=c; id */ ) {
744
	exp first = son (c);
762
	exp first = son(c);
745
	exp second = bro (son (c));
763
	exp second = bro(son(c));
746
	if (no (son (second)) == 1 /* only one jump to else */ &&
764
	if (no (son (second)) == 1 /* only one jump to else */ &&
747
	    name (bro (son (second))) == top_tag
765
	    name(bro(son(second))) == top_tag
748
	    && name (first) == seq_tag /* cond is (seq= first | L: top) */ ) {
766
	    && name (first) == seq_tag /* cond is (seq= first | L: top) */ ) {
749
	  exp s = son (son (first));
767
	  exp s = son(son(first));
750
	  exp r = bro (son (first));
768
	  exp r = bro(son(first));
751
	  if (name (r) == ass_tag && name (son (r)) == name_tag &&
769
	  if (name(r) == ass_tag && name(son(r)) == name_tag &&
752
	      son (son (r)) == id && name (bro (son (r))) == val_tag &&
770
	      son(son(r)) == id && name(bro(son(r))) == val_tag &&
753
	      no (bro (son (r))) == 1 /* last of seq is id = 1 */ &&
771
	      no (bro (son (r))) == 1 /* last of seq is id = 1 */ &&
754
	      last (s) && name (s) == test_tag && pt (s) == second
772
	      last(s) && name(s) == test_tag && pt(s) == second
755
	      && !is_floating (name (sh (son (s))))
773
	      && !is_floating(name(sh(son(s))))
756
	      /* *t of seq is int test jumping to
774
	      /* *t of seq is int test jumping to
757
		 second */
775
		 second */
758
	      ) {
776
	     ) {
759
	    return s;
777
	    return s;
760
	  }
778
	  }
761
	}
779
	}
762
      }
780
      }
763
    }
781
    }
764
  }
782
  }
765
  return 0;
783
  return 0;
766
}
784
}
767
 
785
 
768
 
786
 
769
exp * ptr_position
787
exp * ptr_position
770
    PROTO_N ( ( e ) )
-
 
771
    PROTO_T ( exp e )
788
(exp e)
772
{
789
{
773
  exp * a;
790
  exp * a;
774
  exp dad = father(e);
791
  exp dad = father(e);
775
  if (son(dad)==e) { 
792
  if (son(dad) ==e) {
776
    a = &son(dad);
793
    a = &son(dad);
777
  }
794
  }
778
  else {
795
  else {
779
    exp sib = son(dad);
796
    exp sib = son(dad);
780
    while (bro(sib)!=e) { sib = bro(sib); }
797
    while (bro(sib)!=e) { sib = bro(sib); }
781
    a = &bro(sib);
798
    a = &bro(sib);
782
  }
799
  }
783
  return a;
800
  return a;
784
}
801
}
785
 
802
 
786
bool chase
803
bool chase
787
    PROTO_N ( ( sel, e ) )
-
 
788
    PROTO_T ( exp sel X exp *e )
804
(exp sel, exp *e)
789
{
805
{
790
  /* distribute selection throughout compound expressions */
806
  /* distribute selection throughout compound expressions */
791
  bool b = 0;
807
  bool b = 0;
792
  exp * one;
808
  exp * one;
793
  switch(name(*e)) {
809
  switch (name(*e)) {
794
    case ident_tag : 
810
    case ident_tag:
795
    case seq_tag : 
811
    case seq_tag:
796
    case rep_tag : 
812
    case rep_tag:
797
    case labst_tag : {
813
    case labst_tag: {
798
      b = chase(sel, &bro(son(*e)));
814
      b = chase(sel, &bro(son(*e)));
799
      break;
815
      break;
800
    }
816
    }
801
    case solve_tag :
817
    case solve_tag:
802
    case cond_tag : {
818
    case cond_tag: {
803
      one = &son(*e);
819
      one = &son(*e);
804
      for(;;)  {
820
      for (;;) {
805
	b |= chase(sel, one);
821
	b |= chase(sel, one);
806
	if (last(*one)) break;
822
	if (last(*one))break;
807
	one = &bro(*one);
823
	one = &bro(*one);
808
      }
824
      }
809
      break;
825
      break;
810
    }
826
    }
811
    case field_tag : {
827
    case field_tag: {
812
      if (chase(*e, &son(*e))) {
828
      if (chase(*e, &son(*e))) {
813
	/* inner field has been distributed */
829
	/* inner field has been distributed */
814
	exp stare = *e;
830
	exp stare = *e;
815
	exp ss = son(stare);
831
	exp ss = son(stare);
816
	if (!last (stare)) clearlast (ss);
832
	if (!last(stare))clearlast(ss);
817
	bro (ss) = bro (stare);
833
	bro(ss) = bro(stare);
818
	sh (ss) = sh (stare);
834
	sh(ss) = sh(stare);
819
	*e = ss;
835
	*e = ss;
820
	return chase(sel, e);
836
	return chase(sel, e);
821
      } /* ... continue to default */
837
      } /* ... continue to default */
822
    }
838
    }
823
      FALL_THROUGH;
839
      FALL_THROUGH;
824
    default: {
840
    default: {
825
      if ((son(sel)!= *e) &&(name(sh(*e))!=bothd)){
841
      if ((son(sel)!= *e) && (name(sh(*e))!=bothd)) {
826
	/* only change if not outer */
842
	/* only change if not outer */
827
	exp stare = *e;
843
	exp stare = *e;
828
	exp newsel = getexp (sh (sel), bro (stare), last (stare), stare, 
844
	exp newsel = getexp(sh(sel), bro(stare), last(stare), stare,
829
			     nilexp,props (sel), no (sel), name (sel));
845
			     nilexp,props(sel), no(sel), name(sel));
830
	*e =  newsel;	
846
	*e =  newsel;
831
	bro(stare)=newsel;setlast(stare);
847
	bro(stare) =newsel;setlast(stare);
832
	b = 1;
848
	b = 1;
833
      }
849
      }
834
    }
850
    }
835
  }
851
  }
836
  if (b) sh(*e) = sh(sel);
852
  if (b)sh(*e) = sh(sel);
837
  return b;
853
  return b;
838
}	
854
}
839
 
855
 
840
 
856
 
841
/* check for C style varargs */
857
/* check for C style varargs */
842
bool vascan
858
bool vascan
843
    PROTO_N ( ( e ) )
-
 
844
    PROTO_T ( exp *e )
859
(exp *e)
845
{
860
{
846
  bool result = FALSE;
861
  bool result = FALSE;
847
  exp tr;
862
  exp tr;
848
  int s2;
863
  int s2;
849
  for(tr=son(*e); (name(tr)==ident_tag)&&(isparam(tr))&&(!result); 
864
  for (tr=son(*e);(name(tr) ==ident_tag) && (isparam(tr)) && (!result);
850
		  tr = bro(son(tr))){
865
		  tr = bro(son(tr))) {
851
    s2 = shape_size(sh(son(tr)));
866
    s2 = shape_size(sh(son(tr)));
852
    result = (name(sh(son(tr)))==cpdhd)&&last_param(tr)&&(s2==0);
867
    result = (name(sh(son(tr))) ==cpdhd) &&last_param(tr) && (s2==0);
853
  }
868
  }
854
  return result;
869
  return result;
855
}	
870
}
-
 
871
 
856
 
872
 
857
    
-
 
858
bool gen_call;
873
bool gen_call;
859
bool in_vcallers_proc;
874
bool in_vcallers_proc;
860
 
875
 
861
 
876
 
862
/*
877
/*
863
  scan
878
  scan
864
 
879
 
865
  This procedure works out register requirements of an exp. At each
880
  This procedure works out register requirements of an exp. At each
866
  call the fix field of the needs is the number of fixpnt registers
881
  call the fix field of the needs is the number of fixpnt registers
867
  required to contain live values to evaluate this expression. 
882
  required to contain live values to evaluate this expression.
868
  This never exceeds maxfix because if it would have, a new 
883
  This never exceeds maxfix because if it would have, a new
869
  declaration is introduced in the exp tree (similarly for 
884
  declaration is introduced in the exp tree (similarly for
870
  floating regs and maxfloat). In these cases the prop field will
885
  floating regs and maxfloat). In these cases the prop field will
871
  contain the bits morefix (or morefloat).
886
  contain the bits morefix (or morefloat).
872
 
887
 
873
  As well as working out the register requirements scan performs 
888
  As well as working out the register requirements scan performs
874
  some transformations on the procedure.  It also determines whether
889
  some transformations on the procedure.  It also determines whether
875
  or not the procedure uses varargs, if it contains a division by a
890
  or not the procedure uses varargs, if it contains a division by a
876
  non-constant, and if it may need to move values between float and
891
  non-constant, and if it may need to move values between float and
877
  fixed point registers.
892
  fixed point registers.
878
 
893
 
879
  If the procedure does contain a division by a non constant then
894
  If the procedure does contain a division by a non constant then
880
  those registers which are corrupted by the division instruction 
895
  those registers which are corrupted by the division instruction
881
  are not made available to the register allocator for the duration
896
  are not made available to the register allocator for the duration
882
  of that procedure (see settempregs()).  A better, though more
897
  of that procedure (see settempregs()).  A better, though more
883
  complicated, solution would be to disallow the use of these
898
  complicated, solution would be to disallow the use of these
884
  registers in evaluating the LHS of operations in which the RHS
899
  registers in evaluating the LHS of operations in which the RHS
885
  contains a division.
900
  contains a division.
886
*/
901
*/
887
needs scan
902
needs scan
888
    PROTO_N ( ( e, at ) )
-
 
889
    PROTO_T ( exp *e X exp **at )
903
(exp *e, exp **at)
890
{
904
{
891
  /*  e is the expression to be scanned, at
905
  /*  e is the expression to be scanned, at
892
      is the place to put any new decs . NB order of recursive
906
      is the place to put any new decs . NB order of recursive
893
      calls with same at is critical */
907
      calls with same at is critical */
894
  static int has_old_varargs;
908
  static int has_old_varargs;
895
  static int has_div;
909
  static int has_div;
896
  static int has_float;
910
  static int has_float;
897
  exp   ste = * (e);
911
  exp   ste = *(e);
898
  int   nstare = name (ste);
912
  int   nstare = name(ste);
899
  
913
 
900
  switch (nstare) {
914
  switch (nstare) {
901
    case 0 : {
915
    case 0: {
902
      return zeroneeds;
916
      return zeroneeds;
903
    }
917
    }
904
    
918
 
905
    case compound_tag : 
919
    case compound_tag:
906
    case nof_tag :  
920
    case nof_tag:
907
    case concatnof_tag : 
921
    case concatnof_tag:
908
    case ncopies_tag :{
922
    case ncopies_tag:{
909
      needs nl;
923
      needs nl;
910
      bool cantdo;
924
      bool cantdo;
911
      exp dad;
925
      exp dad;
912
      if (name(ste)==ncopies_tag && name(son(ste)) !=name_tag 
926
      if (name(ste) ==ncopies_tag && name(son(ste))!=name_tag
913
	  && name(son(ste)) != val_tag ) {
927
	  && name(son(ste))!= val_tag) {
914
	nl = scan(&son(*e), at);
928
	nl = scan(&son(*e), at);
915
	cca(at, &son(*e));
929
	cca(at, &son(*e));
916
      }    
930
      }
917
      else nl = maxtup(*(e), at);
931
      else nl = maxtup(*(e), at);
918
      dad = father(ste);
932
      dad = father(ste);
919
      if (name(dad)==compound_tag || name(dad) == nof_tag 
933
      if (name(dad) ==compound_tag || name(dad) == nof_tag
920
	  || name(dad) == concatnof_tag) {
934
	  || name(dad) == concatnof_tag) {
921
	cantdo=0;
935
	cantdo=0;
922
      }
936
      }
923
      else if (last(ste) ){ 
937
      else if (last(ste)) {
924
	if (name(bro(ste)) == ass_tag ) {
938
	if (name(bro(ste)) == ass_tag) {
925
	  exp a = son(bro(ste));
939
	  exp a = son(bro(ste));
926
	  cantdo = (name(a) != name_tag || !isvar(son(a)) );
940
	  cantdo = (name(a)!= name_tag || !isvar(son(a)));
927
	}
941
	}
928
	else cantdo = 1;
942
	else cantdo = 1;
929
      }
943
      }
930
      else if (last(bro(ste)) ) { cantdo = (name(bro(bro(ste))) != ident_tag) ;}
944
      else if (last(bro(ste))) { cantdo = (name(bro(bro(ste)))!= ident_tag);}
931
      else cantdo = 1;
945
      else cantdo = 1;
932
          
946
 
933
      if (cantdo)  {
947
      if (cantdo) {
934
	/*can only deal with tuples in simple assignment or identity*/
948
	/*can only deal with tuples in simple assignment or identity*/
935
	int prps = (nl.propsneeds & hasproccall) << 1;
949
	int prps = (nl.propsneeds & hasproccall) << 1;
936
	cca(at, ptr_position(ste));
950
	cca(at, ptr_position(ste));
937
	nl = shapeneeds(sh(*(e)));
951
	nl = shapeneeds(sh(*(e)));
938
	nl.propsneeds |= morefix;
952
	nl.propsneeds |= morefix;
939
	nl.propsneeds |= prps;				
953
	nl.propsneeds |= prps;
940
      }
954
      }
941
      
955
 
942
      if (nl.fixneeds <2) nl.fixneeds = 2;
956
      if (nl.fixneeds <2)nl.fixneeds = 2;
943
      return nl;
957
      return nl;
944
    }
958
    }
945
    
959
 
946
    case cond_tag : {
960
    case cond_tag: {
947
      exp t, f, v;
961
      exp t, f, v;
948
      if (oddtest(ste, & t, &f, &v) ) {
962
      if (oddtest(ste, & t, &f, &v)) {
949
	/* transform to f((absbool(t) <<1)-1)  */
963
	/* transform to f((absbool(t) <<1)-1)  */
950
	exp bc = bro(ste);
964
	exp bc = bro(ste);
951
	bool lc = last(ste);
965
	bool lc = last(ste);
952
	exp ab = getexp(sh(v),nilexp,0,t, nilexp, 0, 0, absbool_tag);
966
	exp ab = getexp(sh(v),nilexp,0,t, nilexp, 0, 0, absbool_tag);
953
	exp shl = getexp(sh(v), nilexp, 0, ab, nilexp, 0, 0, shl_tag);
967
	exp shl = getexp(sh(v), nilexp, 0, ab, nilexp, 0, 0, shl_tag);
Line 955... Line 969...
955
	exp p = getexp(sh(v), nilexp, 1, shl, nilexp, 0, 0, plus_tag);
969
	exp p = getexp(sh(v), nilexp, 1, shl, nilexp, 0, 0, plus_tag);
956
	exp vm1 = getexp(sh(v), p, 1, nilexp,nilexp, 0, -1, val_tag);
970
	exp vm1 = getexp(sh(v), p, 1, nilexp,nilexp, 0, -1, val_tag);
957
	bro(ab) = v1;
971
	bro(ab) = v1;
958
	bro(shl) = vm1;
972
	bro(shl) = vm1;
959
	bro(t) = ab; setlast(t);
973
	bro(t) = ab; setlast(t);
960
	if (no(v)==-1){settest_number(t, notbranch[test_number(t)-1]);}
974
	if (no(v) ==-1) {settest_number(t, notbranch[test_number(t) -1]);}
961
	if (f==v) {
975
	if (f==v) {
962
	  *e = p;
976
	  *e = p;
963
	}
977
	}
964
	else {
978
	else {
965
	  son(bro(v)) = p;
979
	  son(bro(v)) = p;
966
	  bro(p) = bro(v);
980
	  bro(p) = bro(v);
967
	  *e = f;
981
	  *e = f;
968
	}
982
	}
969
	bro(*e) = bc; if (lc) { setlast(*e); } else {clearlast(*e); }
983
	bro(*e) = bc; if (lc) { setlast(*e); } else {clearlast(*e); }
970
	return scan(e, at);
984
	return scan(e, at);
971
      }
985
      }
972
/* 	
986
/*
973
	if (is_maxlike(ste, &t) ) {
987
	if (is_maxlike(ste, &t) ) {
974
	son(ste) = t;
988
	son(ste) = t;
975
	bro(t) = ste; setlast(t);
989
	bro(t) = ste; setlast(t);
976
	setname(ste, maxlike_tag);
990
	setname(ste, maxlike_tag);
977
	return scan(&son(ste), at);
991
	return scan(&son(ste), at);
Line 981... Line 995...
981
	bro(t) = ste; setlast(t);
995
	bro(t) = ste; setlast(t);
982
	setname(ste, minlike_tag);
996
	setname(ste, minlike_tag);
983
	return scan(&son(ste), at);
997
	return scan(&son(ste), at);
984
	}
998
	}
985
	*/
999
	*/
986
      if (is_abslike(ste, &t) ) {
1000
      if (is_abslike(ste, &t)) {
987
	son(ste) = t;
1001
	son(ste) = t;
988
	bro(t) = ste; setlast(t);
1002
	bro(t) = ste; setlast(t);
989
	setname(ste, abslike_tag);
1003
	setname(ste, abslike_tag);
990
	return scan(&son(ste), at);
1004
	return scan(&son(ste), at);
991
      }
1005
      }
992
      if (is_fabs(ste, &t) ) {
1006
      if (is_fabs(ste, &t)) {
993
	son(ste) = son(t);
1007
	son(ste) = son(t);
994
	bro(son(t)) = ste; setlast(son(t));
1008
	bro(son(t)) = ste; setlast(son(t));
995
	setname(ste, fabs_tag);
1009
	setname(ste, fabs_tag);
996
	return scan(&son(ste), at);
1010
	return scan(&son(ste), at);
997
      }
1011
      }
998
 
1012
 
999
      if (scan_cond(e, nilexp) !=0) {
1013
      if (scan_cond(e, nilexp)!=0) {
1000
	return scan(e, at);
1014
	return scan(e, at);
1001
      }			/* else goto next case */
1015
      }			/* else goto next case */
1002
    }
1016
    }
1003
    FALL_THROUGH;
1017
    FALL_THROUGH;
1004
    case labst_tag : 
1018
    case labst_tag:
1005
    case rep_tag : 
1019
    case rep_tag:
1006
    case solve_tag : {
1020
    case solve_tag: {
1007
      exp * stat;
1021
      exp * stat;
1008
      exp * statat;
1022
      exp * statat;
1009
      needs an;
1023
      needs an;
1010
      stat = &son(*e);
1024
      stat = &son(*e);
1011
      statat = stat;
1025
      statat = stat;
1012
      an = zeroneeds;
1026
      an = zeroneeds;
1013
      while (an = maxneeds (an, scan (stat, &statat)),
1027
      while (an = maxneeds(an, scan(stat, &statat)),
1014
	     
1028
 
1015
	     !last (* (stat))) {
1029
	     !last(*(stat))) {
1016
	stat = &bro(*stat);
1030
	stat = &bro(*stat);
1017
	statat = stat;
1031
	statat = stat;
1018
      }
1032
      }
1019
      if ((an.propsneeds & usesproccall) != 0) {
1033
      if ((an.propsneeds & usesproccall)!= 0) {
1020
	an.propsneeds |= hasproccall;
1034
	an.propsneeds |= hasproccall;
1021
      }
1035
      }
1022
      return an;
1036
      return an;
1023
    }
1037
    }
1024
    
1038
 
1025
      /*
1039
      /*
1026
	ident
1040
	ident
1027
      
1041
 
1028
	shape of exp is body,
1042
	shape of exp is body,
1029
	son is def, brother of son is body,
1043
	son is def, brother of son is body,
1030
	ptr of ident exp is chain of uses 
1044
	ptr of ident exp is chain of uses
1031
	*/
1045
	*/
1032
    case ident_tag :   {
1046
    case ident_tag:   {
1033
      needs bdy;
1047
      needs bdy;
1034
      needs def;
1048
      needs def;
1035
      exp stare = * (e);
1049
      exp stare = *(e);
1036
      exp * arg = &bro(son(stare));  /* ptr to body */
1050
      exp * arg = &bro(son(stare));  /* ptr to body */
1037
      exp t = pt (stare);
1051
      exp t = pt(stare);
1038
      exp s;
1052
      exp s;
1039
      bool fxregble;
1053
      bool fxregble;
1040
      bool flregble;
1054
      bool flregble;
1041
      bool old_nonevis = nonevis;
1055
      bool old_nonevis = nonevis;
1042
      exp ab;
1056
      exp ab;
1043
      /*	  bdy.numparams=0;*/
1057
      /*	  bdy.numparams=0;*/
1044
#if 1
1058
#if 1
1045
      if (!iscaonly(stare)) setvis(stare);
1059
      if (!iscaonly(stare))setvis(stare);
1046
      if(name(son(stare)) == formal_callee_tag) {
1060
      if (name(son(stare)) == formal_callee_tag) {
1047
	setvis(stare);
1061
	setvis(stare);
1048
      }
1062
      }
1049
#endif      
1063
#endif
1050
      
1064
 
1051
      if (isparam(stare) && name(son(stare)) != formal_callee_tag) {
1065
      if (isparam(stare) && name(son(stare))!= formal_callee_tag) {
1052
	exp def = son(stare);
1066
	exp def = son(stare);
1053
	shape shdef = sh(def);
1067
	shape shdef = sh(def);
1054
	long n = rounder(stparam, shape_align(shdef));
1068
	long n = rounder(stparam, shape_align(shdef));
1055
	long sizep = shape_size(shdef);
1069
	long sizep = shape_size(shdef);
1056
	numparams = min( numparams+rounder(sizep,REG_SIZE),6*REG_SIZE );
1070
	numparams = min(numparams+rounder(sizep,REG_SIZE),6*REG_SIZE);
1057
	/*numparams=min(numparams+max(REG_SIZE,sizep),6*REG_SIZE);*/
1071
	/*numparams=min(numparams+max(REG_SIZE,sizep),6*REG_SIZE);*/
1058
	/*Assert(name(def)==clear_tag); */
1072
	/*Assert(name(def)==clear_tag); */
1059
	if (is_floating(name(shdef)) ) {
1073
	if (is_floating(name(shdef))) {
1060
	  if (sizep<=64 && stparam <= 320 ) {
1074
	  if (sizep<=64 && stparam <= 320) {
1061
	    props(def) = floatparam;
1075
	    props(def) = floatparam;
1062
	    maxfloat--;
1076
	    maxfloat--;
1063
	  }					
1077
	  }
1064
	}
1078
	}
1065
	else if (sizep<=64  && stparam<=320  ) { /*change for 64 bit regs*/
1079
	else if (sizep<=64  && stparam<=320  ) { /*change for 64 bit regs*/
1066
	    props(def) = fixparam;
1080
	    props(def) = fixparam;
1067
	    maxfix--;
1081
	    maxfix--;
1068
	  }
1082
	  }
1069
	  else if(stparam<=320){
1083
	  else if (stparam<=320) {
1070
	    props(def) = fixparam;
1084
	    props(def) = fixparam;
1071
	  }
1085
	  }
1072
	  else props(def)=0;
1086
	  else props(def) =0;
1073
	stparam = rounder(n+sizep, 64 );	/* calculate the offset */
1087
	stparam = rounder(n+sizep, 64 );	/* calculate the offset */
1074
	fixparam = 16+(stparam>>6);	/* >> 6, was >>5 */
1088
	fixparam = 16+(stparam>>6);	/* >> 6, was >>5 */
1075
	floatparam=16+(stparam>>6);
1089
	floatparam=16+ (stparam>>6);
1076
	if(((isvis(stare) && props(son(stare))!=0 && (name(sh(son(stare)))==cpdhd)) || in_vcallers_proc) && last_param(stare)){
1090
	if (((isvis(stare) && props(son(stare))!=0 && (name(sh(son(stare))) ==cpdhd)) || in_vcallers_proc) && last_param(stare)) {
1077
	  numparams=12*REG_SIZE;	/* must allow space for all
1091
	  numparams=12*REG_SIZE;	/* must allow space for all
1078
					   parameter registers for 
1092
					   parameter registers for
1079
					   varargs function */
1093
					   varargs function */
1080
	}
1094
	}
1081
	no(def)=n;
1095
	no(def) =n;
1082
	/* if varargs then save all param regs to stack */
1096
	/* if varargs then save all param regs to stack */
1083
	
1097
 
1084
	if (!is_floating(name(shdef)) && !valregable(shdef))
1098
	if (!is_floating(name(shdef)) && !valregable(shdef))
1085
	  setvis(stare);
1099
	  setvis(stare);
1086
	/* now props(def) = pos parreg and no(def) = par stack address		   
1100
	/* now props(def) = pos parreg and no(def) = par stack address
1087
	 */  
1101
	 */
1088
      }
1102
      }
1089
      else if(isparam(stare) && name(son(stare)) == formal_callee_tag){
1103
      else if (isparam(stare) && name(son(stare)) == formal_callee_tag) {
1090
	exp def = son(stare);
1104
	exp def = son(stare);
1091
	shape shdef = sh(def);
1105
	shape shdef = sh(def);
1092
	long sizep = shape_size(shdef);
1106
	long sizep = shape_size(shdef);
1093
	long alp = shape_align(shdef);
1107
	long alp = shape_align(shdef);
1094
	long n = rounder(callee_size, alp);
1108
	long n = rounder(callee_size, alp);
1095
	no(def) = n;
1109
	no(def) = n;
1096
	callee_size = rounder(n+sizep, REG_SIZE);
1110
	callee_size = rounder(n+sizep, REG_SIZE);
1097
      }
1111
      }
1098
      if(gen_call) {
1112
      if (gen_call) {
1099
	numparams = max(6*REG_SIZE,numparams);
1113
	numparams = max(6*REG_SIZE,numparams);
1100
      }
1114
      }
1101
            
1115
 
1102
      nonevis &= !isvis(stare);
1116
      nonevis &= !isvis(stare);
1103
      bdy = scan (arg, &arg);
1117
      bdy = scan(arg, &arg);
1104
      /* scan the body-scope */
1118
      /* scan the body-scope */
1105
      arg = &son(stare);
1119
      arg = &son(stare);
1106
      def = scan (arg, &arg);
1120
      def = scan(arg, &arg);
1107
      bdy.numparams = numparams;
1121
      bdy.numparams = numparams;
1108
      /* scan the initialisation of tag */
1122
      /* scan the initialisation of tag */
1109
      
1123
 
1110
      nonevis = old_nonevis;
1124
      nonevis = old_nonevis;
1111
      t = son (stare);
1125
      t = son(stare);
1112
      s = bro (t);
1126
      s = bro(t);
1113
      fxregble = fixregable (stare);
1127
      fxregble = fixregable(stare);
1114
      flregble = floatregable (stare);
1128
      flregble = floatregable(stare);
1115
      
1129
 
1116
      if (isparam(stare) ) {
1130
      if (isparam(stare)) {
1117
	if (name(son(stare))!=formal_callee_tag && !isvis(stare) && 
1131
	if (name(son(stare))!=formal_callee_tag && !isvis(stare) &&
1118
	    !isoutpar(stare) && (bdy.propsneeds & anyproccall)==0   ) {
1132
	    !isoutpar(stare) && (bdy.propsneeds & anyproccall) ==0  ) {
1119
	  /* leave pars in par regs or put in t-regs 
1133
	  /* leave pars in par regs or put in t-regs
1120
	     !! WHAT ABOUT TEMP DECS !!
1134
	     !! WHAT ABOUT TEMP DECS !!
1121
	     */
1135
	     */
1122
	  int x = props(son(stare));
1136
	  int x = props(son(stare));
1123
	  if (x != 0) {
1137
	  if (x != 0) {
1124
	    no(stare)= x;
1138
	    no(stare) = x;
1125
	    if (flregble) { 
1139
	    if (flregble) {
1126
	      props(stare)|= infreg_bits; 
1140
	      props(stare) |= infreg_bits;
1127
	    }
1141
	    }
1128
	    else { props(stare) |= inreg_bits; }
1142
	    else { props(stare) |= inreg_bits; }
1129
	  }
1143
	  }
1130
	  else if (fxregble && bdy.fixneeds < maxfix && 
1144
	  else if (fxregble && bdy.fixneeds < maxfix &&
1131
		   (bdy.propsneeds & morefix) == 0 ){
1145
		  (bdy.propsneeds & morefix) == 0) {
1132
	    no(stare) = NO_REG;	
1146
	    no(stare) = NO_REG;
1133
	    props(stare) |= inreg_bits;
1147
	    props(stare) |= inreg_bits;
1134
	    bdy.fixneeds+=1;
1148
	    bdy.fixneeds+=1;
1135
	  }
1149
	  }
1136
	  else if (flregble && 
1150
	  else if (flregble &&
1137
		   bdy.floatneeds < maxfloat && 
1151
		   bdy.floatneeds < maxfloat &&
1138
		   (bdy.propsneeds & morefloat) == 0 ) {
1152
		  (bdy.propsneeds & morefloat) == 0) {
1139
	    no(stare) = NO_REG;
1153
	    no(stare) = NO_REG;
1140
	    props(stare) |= infreg_bits;
1154
	    props(stare) |= infreg_bits;
1141
	    bdy.floatneeds +=1;
1155
	    bdy.floatneeds +=1;
1142
	  }
1156
	  }
1143
	  else no(stare) = 100;
1157
	  else no(stare) = 100;
1144
	}
1158
	}
1145
	else no(stare) = 100;
1159
	else no(stare) = 100;
1146
	
1160
 
1147
      }
1161
      }
1148
      else {   	    	 
1162
      else {
1149
	if ((ab = absbool (stare)) != nilexp) {
1163
	if ((ab = absbool(stare))!= nilexp) {
1150
	  /* form is (let a = 0 in cond(test(L)=ab;
1164
	  /* form is (let a = 0 in cond(test(L)=ab;
1151
	     a=1 | L:top) ni replace declaration by
1165
	     a=1 | L:top) ni replace declaration by
1152
	     ABS */
1166
	     ABS */
1153
	  bro (ab) = stare;
1167
	  bro(ab) = stare;
1154
	  setlast (ab);       /* father => *e */
1168
	  setlast (ab);       /* father => *e */
1155
	  son (stare) = ab;
1169
	  son(stare) = ab;
1156
	  pt (stare) = nilexp;
1170
	  pt(stare) = nilexp;
1157
	  pt (ab) = nilexp;
1171
	  pt(ab) = nilexp;
1158
	  setname (stare, absbool_tag);
1172
	  setname(stare, absbool_tag);
1159
	  return maxneeds (bdy, def);
1173
	  return maxneeds(bdy, def);
1160
	}
1174
	}
1161
	
1175
 
1162
	if (!isvis (*e) && !isparam(*e) &&
1176
	if (!isvis(*e) && !isparam(*e) &&
1163
	    (bdy.propsneeds & (anyproccall | uses2_bit)) == 0
1177
	   (bdy.propsneeds & (anyproccall | uses2_bit)) == 0
1164
	    && (fxregble || flregble) &&
1178
	    && (fxregble || flregble) &&
1165
	    (name (t) == apply_tag || name(t) == apply_general_tag ||
1179
	   (name(t) == apply_tag || name(t) == apply_general_tag ||
1166
	     (name (s) == seq_tag && name (bro (son (s))) == res_tag &&
1180
	    (name(s) == seq_tag && name(bro(son(s))) == res_tag &&
1167
	      name (son (bro (son (s)))) == cont_tag && isvar (stare) &&
1181
	      name(son(bro(son(s)))) == cont_tag && isvar(stare) &&
1168
	      name (son (son (bro (son (s))))) == name_tag &&
1182
	      name(son(son(bro(son(s))))) == name_tag &&
1169
	      son (son (son (bro (son (s))))) == stare
1183
	      son(son(son(bro(son(s))))) == stare
1170
	      )               /* Let a := ..; return cont a */
1184
	      )               /* Let a := ..; return cont a */
1171
	     )
1185
	    )
1172
	    ) {    	/* put tag in result reg if definition is
1186
	    ) {    	/* put tag in result reg if definition is
1173
			   call of proc, or body ends with return
1187
			   call of proc, or body ends with return
1174
			   tag, provided result is not used other
1188
			   tag, provided result is not used other
1175
			   wise */
1189
			   wise */
1176
	  props (stare) |= (fxregble) ? inreg_bits : infreg_bits;
1190
	  props(stare) |= (fxregble)? inreg_bits : infreg_bits;
1177
	  bdy.propsneeds |= uses2_bit;
1191
	  bdy.propsneeds |= uses2_bit;
1178
	  no (stare) = 101;   /* identification  uses result reg in body 
1192
	  no (stare) = 101;   /* identification  uses result reg in body
1179
			       */
1193
			       */
1180
	}
1194
	}
1181
	else if (!isvar (*e) && !isparam(*e) &&
1195
	else if (!isvar(*e) && !isparam(*e) &&
1182
		 ((name (t) == reff_tag && name (son (t)) == cont_tag &&
1196
		((name(t) == reff_tag && name(son(t)) == cont_tag &&
1183
		   name (son (son (t))) == name_tag && isvar (son (son (son (t))))
1197
		   name(son(son(t))) == name_tag && isvar(son(son(son(t))))
1184
		   && !isvis (son (son (son (t)))) && 
1198
		   && !isvis(son(son(son(t)))) &&
1185
		   !isglob (son (son (son (t))))
1199
		   !isglob(son(son(son(t))))
1186
		   && unchanged (son (son (son (t))), stare)
1200
		   && unchanged(son(son(son(t))), stare)
1187
		   /* reff cont variable-not assigned to in
1201
		   /* reff cont variable-not assigned to in
1188
		      scope */
1202
		      scope */
1189
		   ) ||
1203
		  ) ||
1190
		  (name (t) == cont_tag && name (son (t)) == name_tag &&
1204
		 (name(t) == cont_tag && name(son(t)) == name_tag &&
1191
		   isvar (son (son (t))) && !isvis (son (son (t))) && 
1205
		   isvar(son(son(t))) && !isvis(son(son(t))) &&
1192
		   !isglob (son (son (t))) && unchanged (son (son (t)), stare)
1206
		   !isglob(son(son(t))) && unchanged(son(son(t)), stare)
1193
		   /* cont variable - not assigned to in
1207
		   /* cont variable - not assigned to in
1194
		      scope */
1208
		      scope */
1195
		   )
-
 
1196
		  )
1209
		  )
-
 
1210
		 )
1197
		 ) {
1211
		) {
1198
	  props (stare) |= defer_bit;
1212
	  props(stare) |= defer_bit;
1199
	  /* dont take space for this dec */
1213
	  /* dont take space for this dec */
1200
	}
1214
	}
1201
	else if (!isvar (stare)  && !isvis(stare) &&
1215
	else if (!isvar(stare) && !isvis(stare) &&
1202
		 ((props (stare) & 0x10 /* forced in const */ ) == 0)
1216
		 ((props (stare) & 0x10 /* forced in const */ ) == 0)
1203
		 && (name (t) == name_tag || name (t) == val_tag )) {
1217
		 && (name(t) == name_tag || name(t) == val_tag)) {
1204
	  props (stare) |= defer_bit;
1218
	  props(stare) |= defer_bit;
1205
	  /* dont take space for this dec */
1219
	  /* dont take space for this dec */
1206
	}
1220
	}
1207
	else if (fxregble && (/*isinlined(stare)||*/
1221
	else if (fxregble && (/*isinlined(stare)||*/
1208
			      (bdy.fixneeds < maxfix && 
1222
			     (bdy.fixneeds < maxfix &&
1209
			       (bdy.propsneeds & morefix) == 0 && 
1223
			      (bdy.propsneeds & morefix) == 0 &&
1210
			       ((bdy.propsneeds & anyproccall) == 0 || 
1224
			      ((bdy.propsneeds & anyproccall) == 0 ||
1211
				tempdec (stare,((bdy.propsneeds&morefix)==0 &&
1225
				tempdec(stare,((bdy.propsneeds&morefix) ==0 &&
1212
					      bdy.fixneeds < maxfix-2 )))))) {
1226
					      bdy.fixneeds < maxfix-2)))))) {
1213
	  /* put this tag in some  fixpt t-reg -
1227
	  /* put this tag in some  fixpt t-reg -
1214
	     which will be decided  in make_code */
1228
	     which will be decided  in make_code */
1215
	  props (stare) |= inreg_bits;
1229
	  props(stare) |= inreg_bits;
1216
	  no (stare) = NO_REG;	/* aha! */
1230
	  no (stare) = NO_REG;	/* aha! */
1217
	  bdy.fixneeds += 1;
1231
	  bdy.fixneeds += 1;
1218
	}
1232
	}
1219
	else if (bdy.floatneeds < maxfloat && 
1233
	else if (bdy.floatneeds < maxfloat &&
1220
		 (bdy.propsneeds & morefloat) == 0 && flregble &&
1234
		(bdy.propsneeds & morefloat) == 0 && flregble &&
1221
		 ((bdy.propsneeds & anyproccall) == 0
1235
		((bdy.propsneeds & anyproccall) == 0
1222
		  || tempdec (stare, ((bdy.propsneeds & morefloat) == 0 &&
1236
		  || tempdec(stare,((bdy.propsneeds & morefloat) == 0 &&
1223
				      bdy.floatneeds < maxfloat-2/*6*/)))) {
1237
				      bdy.floatneeds < maxfloat-2/*6*/)))) {
1224
	  /* put this tag in some  float t-reg -
1238
	  /* put this tag in some  float t-reg -
1225
	     which will be decided  in make_code */
1239
	     which will be decided  in make_code */
1226
	  props (stare) |= infreg_bits;
1240
	  props(stare) |= infreg_bits;
1227
	  no (stare) = NO_REG;
1241
	  no(stare) = NO_REG;
1228
	  bdy.floatneeds += 1;
1242
	  bdy.floatneeds += 1;
1229
	}
1243
	}
1230
	else {
1244
	else {
1231
#if 1
1245
#if 1
1232
	  if (fxregble && ((bdy.propsneeds & anyproccall) == 0) && 
1246
	  if (fxregble && ((bdy.propsneeds & anyproccall) == 0) &&
1233
	      (bdy.fixneeds < maxfix)){
1247
	     (bdy.fixneeds < maxfix)) {
1234
	    SetPossParReg(stare);	/* +1 to fixneeds ? */
1248
	    SetPossParReg(stare);	/* +1 to fixneeds ? */
1235
	    bdy.fixneeds += 1;
1249
	    bdy.fixneeds += 1;
1236
	  }
1250
	  }
1237
#endif
1251
#endif
1238
	  no (stare) = 100;
1252
	  no(stare) = 100;
1239
	  /* allocate either on stack or saved reg */
1253
	  /* allocate either on stack or saved reg */
1240
	}
1254
	}
1241
      }
1255
      }
1242
      bdy = maxneeds (bdy, def);
1256
      bdy = maxneeds(bdy, def);
1243
      if ((bdy.propsneeds & usesproccall) != 0) {
1257
      if ((bdy.propsneeds & usesproccall)!= 0) {
1244
	bdy.propsneeds |= hasproccall;
1258
	bdy.propsneeds |= hasproccall;
1245
      }
1259
      }
1246
      return bdy;
1260
      return bdy;
1247
    }
1261
    }
1248
    
1262
 
1249
      /*
1263
      /*
1250
	sequence
1264
	sequence
1251
      
1265
 
1252
	shape of exp is shape of end of sequence, son is sequence 
1266
	shape of exp is shape of end of sequence, son is sequence
1253
	holder, son of this is list of voided statements.
1267
	holder, son of this is list of voided statements.
1254
	*/
1268
	*/
1255
    
1269
 
1256
    case seq_tag : {
1270
    case seq_tag: {
1257
      exp * arg = &bro(son(*e));
1271
      exp * arg = &bro(son(*e));
1258
      needs an;
1272
      needs an;
1259
      exp * stat;
1273
      exp * stat;
1260
      
1274
 
1261
      an = scan (arg, &arg);
1275
      an = scan(arg, &arg);
1262
      stat = &son(son(*e));		
1276
      stat = &son(son(*e));
1263
      
1277
 
1264
      arg = stat;
1278
      arg = stat;
1265
      for (;;) {
1279
      for (;;) {
1266
	needs stneeds;
1280
	needs stneeds;
1267
	stneeds = scan (stat, &arg);
1281
	stneeds = scan(stat, &arg);
1268
	/* initial statements voided */
1282
	/* initial statements voided */
1269
	an = maxneeds (an, stneeds);
1283
	an = maxneeds(an, stneeds);
1270
	if (last (* (stat))) {
1284
	if (last(*(stat))) {
1271
	  if ((an.propsneeds & usesproccall) != 0) {
1285
	  if ((an.propsneeds & usesproccall)!= 0) {
1272
	    an.propsneeds |= hasproccall;
1286
	    an.propsneeds |= hasproccall;
1273
	  }
1287
	  }
1274
	  return an;
1288
	  return an;
1275
	}
1289
	}
1276
	stat = &bro(*stat);
1290
	stat = &bro(*stat);
1277
	arg = stat;
1291
	arg = stat;
1278
      }
1292
      }
1279
      
1293
 
1280
    }
1294
    }
1281
    
1295
 
1282
    /*
1296
    /*
1283
      goto
1297
      goto
1284
      
1298
 
1285
      shape is bottom
1299
      shape is bottom
1286
      son is exp for value jumped with
1300
      son is exp for value jumped with
1287
      ptr is labelled exp
1301
      ptr is labelled exp
1288
      */
1302
      */
1289
    case goto_tag : {
1303
    case goto_tag: {
1290
      return zeroneeds;
1304
      return zeroneeds;
1291
    }
1305
    }
1292
    
1306
 
1293
    case ass_tag : 
1307
    case ass_tag:
1294
    case assvol_tag : {
1308
    case assvol_tag: {
1295
      exp * lhs = &son(*e);
1309
      exp * lhs = &son(*e);
1296
      exp * rhs = &bro(*lhs);
1310
      exp * rhs = &bro(*lhs);
1297
      needs nr;
1311
      needs nr;
1298
      ash a;
1312
      ash a;
1299
      
1313
 
1300
      nr = scan (rhs, at);
1314
      nr = scan(rhs, at);
1301
      /* scan source */
1315
      /* scan source */
1302
      
1316
 
1303
      a = ashof (sh (* (rhs)));
1317
      a = ashof(sh(*(rhs)));
1304
      if (nstare != ass_tag || a.ashsize != a.ashalign || a.ashalign == 1) {
1318
      if (nstare != ass_tag || a.ashsize != a.ashalign || a.ashalign == 1) {
1305
	/* complicated move */
1319
	/* complicated move */
1306
	nr.propsneeds |= uses2_bit;
1320
	nr.propsneeds |= uses2_bit;
1307
      }
1321
      }
1308
      if (name (* (lhs)) == name_tag &&
1322
      if (name(*(lhs)) == name_tag &&
1309
	  (isvar (son (* (lhs))) ||
1323
	 (isvar(son(*(lhs))) ||
1310
	   ((nr.propsneeds & (hasproccall | morefix)) == 0
1324
	  ((nr.propsneeds & (hasproccall | morefix)) == 0
1311
	    && nr.fixneeds < maxfix
1325
	    && nr.fixneeds < maxfix
1312
	    )
-
 
1313
	   )
1326
	   )
-
 
1327
	  )
1314
	  ) {			/* simple destination */
1328
	  ) {			/* simple destination */
1315
	return nr;
1329
	return nr;
1316
      }
1330
      }
1317
      else {
1331
      else {
1318
	needs nl;
1332
	needs nl;
1319
	prop prps = (nr.propsneeds & hasproccall) << 1;
1333
	prop prps = (nr.propsneeds & hasproccall) << 1;
1320
	nl = scan (lhs, at);
1334
	nl = scan(lhs, at);
1321
	/* scan destination */
1335
	/* scan destination */
1322
	nr.fixneeds += 1;
1336
	nr.fixneeds += 1;
1323
	if (name (* (rhs)) == apply_tag && name(*(rhs))==apply_general_tag && 
1337
	if (name(*(rhs)) == apply_tag && name(*(rhs)) ==apply_general_tag &&
1324
	    nstare == ass_tag && (nl.propsneeds & 
1338
	    nstare == ass_tag && (nl.propsneeds &
1325
				  (uses2_bit | anyproccall)) == 0) {
1339
				 (uses2_bit | anyproccall)) == 0) {
1326
	  /* source is proc call, so assign result
1340
	  /* source is proc call, so assign result
1327
	     reg directly */
1341
	     reg directly */
1328
	  ;
1342
	 ;
1329
	}
1343
	}
1330
	else if (nr.fixneeds >= maxfix || prps != 0) {
1344
	else if (nr.fixneeds >= maxfix || prps != 0) {
1331
	  /* source and destination regs overlap, so identify source */
1345
	  /* source and destination regs overlap, so identify source */
1332
	  cca (at, rhs);
1346
	  cca(at, rhs);
1333
	  nl = shapeneeds (sh (* (rhs)));
1347
	  nl = shapeneeds(sh(*(rhs)));
1334
	  nl.propsneeds |= morefix;
1348
	  nl.propsneeds |= morefix;
1335
	  nl.propsneeds &= ~(prps >> 1);
1349
	  nl.propsneeds &= ~(prps >> 1);
1336
	  nl.propsneeds |= prps;
1350
	  nl.propsneeds |= prps;
1337
	}
1351
	}
1338
	return maxneeds (nl, nr);
1352
	return maxneeds(nl, nr);
1339
      }
1353
      }
1340
    }
1354
    }
1341
    case untidy_return_tag :
1355
    case untidy_return_tag:
1342
    case res_tag : {
1356
    case res_tag: {
1343
      ash a;
1357
      ash a;
1344
      needs x;
1358
      needs x;
1345
      shape s;
1359
      shape s;
1346
      exp * arg = &son(*e);
1360
      exp * arg = &son(*e);
1347
      exp r, ss, t;
1361
      exp r, ss, t;
1348
      s = sh (* (arg));
1362
      s = sh(*(arg));
1349
      a = ashof (s);
1363
      a = ashof(s);
1350
      props(*e) = 0; /* clear possibility of tlrecirsion; may be set later */
1364
      props(*e) = 0; /* clear possibility of tlrecirsion; may be set later */
1351
      x = scan (arg, at);
1365
      x = scan(arg, at);
1352
      /* scan result exp ... */
1366
      /* scan result exp ... */
1353
      if (is_floating (name (s))) {/* ... floating pt result */
1367
      if (is_floating (name (s))) {/* ... floating pt result */
1354
	x.propsneeds |= realresult_bit;
1368
	x.propsneeds |= realresult_bit;
1355
	if (name (s) != shrealhd) {
1369
	if (name(s)!= shrealhd) {
1356
	  x.propsneeds |= longrealresult_bit;
1370
	  x.propsneeds |= longrealresult_bit;
1357
	}
1371
	}
1358
      }
1372
      }
1359
      else {
1373
      else {
1360
	if (!valregable (s)) {/* .... result does not fit into reg */
1374
	if (!valregable (s)) {/* .... result does not fit into reg */
1361
	  x.propsneeds |= long_result_bit;
1375
	  x.propsneeds |= long_result_bit;
1362
	}
1376
	}
1363
      }
1377
      }
1364
      if (a.ashsize != 0) {	/* ...not a void result */
1378
      if (a.ashsize != 0) {	/* ...not a void result */
1365
	x.propsneeds |= has_result_bit;
1379
	x.propsneeds |= has_result_bit;
1366
      }
1380
      }
1367
      
1381
 
1368
      if ((name (*e) == res_tag) && 
1382
      if ((name(*e) == res_tag) &&
1369
	  (x.propsneeds & (long_result_bit | anyproccall | uses2_bit)) == 0) {
1383
	 (x.propsneeds & (long_result_bit | anyproccall | uses2_bit)) == 0) {
1370
	r = son (* (e));
1384
	r = son(*(e));
1371
	if (name (r) == ident_tag && isvar (r) &&
1385
	if (name(r) == ident_tag && isvar(r) &&
1372
	    name (ss = bro (son (r))) == seq_tag &&
1386
	    name(ss = bro(son(r))) == seq_tag &&
1373
	    name (t = bro (son (ss))) == cont_tag &&
1387
	    name(t = bro(son(ss))) == cont_tag &&
1374
	    name (son (t)) == name_tag && son (son (t)) == r) {
1388
	    name(son(t)) == name_tag && son(son(t)) == r) {
1375
	  /* result is tag allocated into result reg
1389
	  /* result is tag allocated into result reg
1376
	     - see ident_tag: */
1390
	     - see ident_tag: */
1377
	  if ((props (r) & inreg_bits) != 0) {
1391
	  if ((props(r) & inreg_bits)!= 0) {
1378
	    x.fixneeds--;
1392
	    x.fixneeds--;
1379
	  }
1393
	  }
1380
	  else if ((props (r) & infreg_bits) != 0) {
1394
	  else if ((props(r) & infreg_bits)!= 0) {
1381
	    x.floatneeds--;
1395
	    x.floatneeds--;
1382
	  }
1396
	  }
1383
	  else {
1397
	  else {
1384
	    props (r) |= (is_floating (name (s))) ? infreg_bits : inreg_bits;
1398
	    props(r) |= (is_floating(name(s)))? infreg_bits : inreg_bits;
1385
	  }
1399
	  }
1386
	  x.propsneeds |= uses2_bit;
1400
	  x.propsneeds |= uses2_bit;
1387
	  no (r) = 101;	/* identification  uses result reg in body 
1401
	  no (r) = 101;	/* identification  uses result reg in body
1388
			 */
1402
			 */
1389
	}
1403
	}
1390
      }
1404
      }
1391
      return x;
1405
      return x;
1392
    }
1406
    }
1393
    case apply_general_tag : {
1407
    case apply_general_tag: {
1394
      exp application = *(e);
1408
      exp application = *(e);
1395
      exp *fn = &son(application);
1409
      exp *fn = &son(application);
1396
      exp callers = bro(*fn);
1410
      exp callers = bro(*fn);
1397
      exp *cerl = &son(callers);
1411
      exp *cerl = &son(callers);
1398
      int stpar = 0;
1412
      int stpar = 0;
1399
      needs nds,pstldnds;
1413
      needs nds,pstldnds;
1400
      int i;
1414
      int i;
1401
      gen_call = 1;
1415
      gen_call = 1;
1402
      nds = scan(fn,at);
1416
      nds = scan(fn,at);
1403
      if(nds.propsneeds & hasproccall){	/* Identify it */
1417
      if(nds.propsneeds & hasproccall){	/* Identify it */
1404
	cca(at,fn);
1418
	cca(at,fn);
1405
	nds.propsneeds &= ~hasproccall;
1419
	nds.propsneeds &= ~hasproccall;
1406
	nds.propsneeds |= usesproccall;
1420
	nds.propsneeds |= usesproccall;
1407
	fn = &son(application);
1421
	fn = &son(application);
1408
      }
1422
      }
1409
      for(i=0;i<no(callers);++i){
1423
      for (i=0;i<no(callers);++i) {
1410
	needs onepar;
1424
	needs onepar;
1411
	shape shonepar = sh(*cerl);
1425
	shape shonepar = sh(*cerl);
1412
	exp * par = (name(*cerl)==caller_tag)?&son(*cerl):cerl;
1426
	exp * par = (name(*cerl) ==caller_tag)?&son(*cerl):cerl;
1413
	int n = rounder(stpar,shape_align(shonepar));
1427
	int n = rounder(stpar,shape_align(shonepar));
1414
	onepar = scan(par,at);
1428
	onepar = scan(par,at);
1415
	if(((i != 0) && (onepar.propsneeds & hasproccall)) || 
1429
	if (((i != 0) && (onepar.propsneeds & hasproccall)) ||
1416
	   (onepar.fixneeds+(stpar>>6) > maxfix)){
1430
	  (onepar.fixneeds+ (stpar>>6) > maxfix)) {
1417
	  /* not the first parameter, and calls a proc */
1431
	  /* not the first parameter, and calls a proc */
1418
	  cca(at,par);
1432
	  cca(at,par);
1419
	  nds.propsneeds |= usesproccall;
1433
	  nds.propsneeds |= usesproccall;
1420
	  nds = maxneeds(shapeneeds(sh(*(par))),nds);
1434
	  nds = maxneeds(shapeneeds(sh(*(par))),nds);
1421
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
1435
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
1422
	}
1436
	}
1423
	else{
1437
	else{
1424
	  nds = maxneeds(onepar,nds);
1438
	  nds = maxneeds(onepar,nds);
1425
	}
1439
	}
1426
	if(name(*cerl) == caller_tag){
1440
	if (name(*cerl) == caller_tag) {
1427
	  no(*cerl) = n;
1441
	  no(*cerl) = n;
1428
	}
1442
	}
1429
	n += shape_size(shonepar);
1443
	n += shape_size(shonepar);
1430
	stpar = rounder(n,REG_SIZE);
1444
	stpar = rounder(n,REG_SIZE);
1431
	cerl = &bro(*cerl);
1445
	cerl = &bro(*cerl);
1432
      }
1446
      }
1433
      nds.maxargs = max(nds.maxargs,stpar);
1447
      nds.maxargs = max(nds.maxargs,stpar);
1434
      nds = maxneeds(scan(&bro(bro(son(application))),at),nds);
1448
      nds = maxneeds(scan(&bro(bro(son(application))),at),nds);
1435
      pstldnds = scan(&bro(bro(bro(son(application)))),at);
1449
      pstldnds = scan(&bro(bro(bro(son(application)))),at);
1436
      if(pstldnds.propsneeds & (anyproccall | uses2_bit)){
1450
      if (pstldnds.propsneeds & (anyproccall | uses2_bit)) {
1437
	props(*e) = 1;
1451
	props(*e) = 1;
1438
	if(valregable(sh(application)) || floatregable(sh(application))) {
1452
	if (valregable(sh(application)) || floatregable(sh(application))) {
1439
	  cca(at,ptr_position(application));
1453
	  cca(at,ptr_position(application));
1440
	  pstldnds.propsneeds |= usesproccall;
1454
	  pstldnds.propsneeds |= usesproccall;
1441
	}
1455
	}
1442
      }
1456
      }
1443
      else{
1457
      else{
Line 1445... Line 1459...
1445
      }
1459
      }
1446
      nds = maxneeds(nds,pstldnds);
1460
      nds = maxneeds(nds,pstldnds);
1447
      nds.propsneeds |= hasproccall;
1461
      nds.propsneeds |= hasproccall;
1448
      return nds;
1462
      return nds;
1449
    }
1463
    }
1450
    case make_callee_list_tag : {
1464
    case make_callee_list_tag: {
1451
      exp cllees = *e;
1465
      exp cllees = *e;
1452
      exp *par = &son(cllees);
1466
      exp *par = &son(cllees);
1453
      needs nds;
1467
      needs nds;
1454
      int stpar = 0,i;
1468
      int stpar = 0,i;
1455
      nds = zeroneeds;
1469
      nds = zeroneeds;
1456
      for(i=0;i<no(cllees);++i){
1470
      for (i=0;i<no(cllees);++i) {
1457
	needs onepar;
1471
	needs onepar;
1458
	shape shonepar = sh(*par);
1472
	shape shonepar = sh(*par);
1459
	int n = rounder(stpar,shape_align(shonepar));
1473
	int n = rounder(stpar,shape_align(shonepar));
1460
	onepar = scan(par,at);
1474
	onepar = scan(par,at);
1461
	if((onepar.propsneeds & hasproccall) || (onepar.fixneeds+1>maxfix)){
1475
	if ((onepar.propsneeds & hasproccall) || (onepar.fixneeds+1>maxfix)) {
1462
	  /* identify it */
1476
	  /* identify it */
1463
	  cca(at,par);
1477
	  cca(at,par);
1464
	  nds.propsneeds |= usesproccall;
1478
	  nds.propsneeds |= usesproccall;
1465
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
1479
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
1466
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
1480
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
Line 1469... Line 1483...
1469
	  nds = maxneeds(onepar,nds);
1483
	  nds = maxneeds(onepar,nds);
1470
	}
1484
	}
1471
	n += shape_size(shonepar);
1485
	n += shape_size(shonepar);
1472
	stpar = rounder(n,REG_SIZE);
1486
	stpar = rounder(n,REG_SIZE);
1473
	par = &bro(*par);
1487
	par = &bro(*par);
1474
      }
1488
      }
1475
      no(cllees) = stpar;
1489
      no(cllees) = stpar;
1476
      return nds;
1490
      return nds;
1477
    }
1491
    }
1478
  
1492
 
1479
    case make_dynamic_callee_tag : {
1493
    case make_dynamic_callee_tag: {
1480
      exp callees = *e;
1494
      exp callees = *e;
1481
      exp *ptr = &son(callees);
1495
      exp *ptr = &son(callees);
1482
      needs ndsp,nds;
1496
      needs ndsp,nds;
1483
      nds = zeroneeds;
1497
      nds = zeroneeds;
1484
      ndsp = scan(ptr,at);
1498
      ndsp = scan(ptr,at);
1485
      if((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+1 > maxfix)){
1499
      if ((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+1 > maxfix)) {
1486
	cca(at,ptr);
1500
	cca(at,ptr);
1487
	nds.propsneeds |= usesproccall;
1501
	nds.propsneeds |= usesproccall;
1488
	nds = maxneeds(shapeneeds(sh(*ptr)),nds);
1502
	nds = maxneeds(shapeneeds(sh(*ptr)),nds);
1489
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1503
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1490
      }
1504
      }
1491
      else{
1505
      else{
1492
	nds = ndsp;
1506
	nds = ndsp;
1493
      }
1507
      }
1494
      ndsp = scan(&bro(son(*e)),at);
1508
      ndsp = scan(&bro(son(*e)),at);
1495
      if((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+2 > maxfix)){
1509
      if ((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+2 > maxfix)) {
1496
	cca(at,&bro(son(callees)));
1510
	cca(at,&bro(son(callees)));
1497
	nds.propsneeds |= usesproccall;
1511
	nds.propsneeds |= usesproccall;
1498
	nds = maxneeds(shapeneeds(sh(bro(son(*e)))),nds);
1512
	nds = maxneeds(shapeneeds(sh(bro(son(*e)))),nds);
1499
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1513
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1500
      }
1514
      }
1501
      else{
1515
      else{
1502
	nds = maxneeds(ndsp,nds);
1516
	nds = maxneeds(ndsp,nds);
1503
      }
1517
      }
1504
      if(nds.fixneeds<5) nds.fixneeds = 5;	/* ?? */
1518
      if(nds.fixneeds<5) nds.fixneeds = 5;	/* ?? */
1505
      return nds;
1519
      return nds;
1506
    }
1520
    }
1507
  
1521
 
1508
    case same_callees_tag : {
1522
    case same_callees_tag: {
1509
      needs nds;
1523
      needs nds;
1510
      nds = zeroneeds;
1524
      nds = zeroneeds;
1511
      nds.fixneeds = 4;		/* ?? */
1525
      nds.fixneeds = 4;		/* ?? */
1512
      return nds;
1526
      return nds;
1513
    }
1527
    }
1514
 
1528
 
1515
    case tail_call_tag : {
1529
    case tail_call_tag: {
1516
      needs ndsp,nds;
1530
      needs ndsp,nds;
1517
      exp *fn = &son(*e);
1531
      exp *fn = &son(*e);
1518
      ndsp = scan(fn,at);
1532
      ndsp = scan(fn,at);
1519
      if((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+1 > maxfix)){
1533
      if ((ndsp.propsneeds & hasproccall) || (ndsp.fixneeds+1 > maxfix)) {
1520
	cca(at,fn);
1534
	cca(at,fn);
1521
	nds.propsneeds |= usesproccall;
1535
	nds.propsneeds |= usesproccall;
1522
	nds = maxneeds(shapeneeds(sh(*fn)),nds);
1536
	nds = maxneeds(shapeneeds(sh(*fn)),nds);
1523
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1537
	nds.maxargs = max(nds.maxargs,ndsp.maxargs);
1524
      }
1538
      }
1525
      else{
1539
      else{
1526
	nds = ndsp;
1540
	nds = ndsp;
1527
      }
1541
      }
1528
      gen_call = 1;
1542
      gen_call = 1;
1529
      ndsp = scan(&bro(son(*e)),at);
1543
      ndsp = scan(&bro(son(*e)),at);
1530
      nds = maxneeds(nds,ndsp);
1544
      nds = maxneeds(nds,ndsp);
1531
      return nds;
1545
      return nds;
1532
    }
1546
    }
1533
 
1547
 
1534
    case apply_tag : {
1548
    case apply_tag: {
1535
      exp application = *(e);
1549
      exp application = *(e);
1536
      exp fn = son (application);
1550
      exp fn = son(application);
1537
      exp * par = &bro(fn);
1551
      exp * par = &bro(fn);
1538
      exp * fnexp = &son(*e);
1552
      exp * fnexp = &son(*e);
1539
      int   parsize =0;
1553
      int   parsize =0;
1540
      needs nds;
1554
      needs nds;
1541
      bool tlrecpos = nonevis && callerfortr && (rscope_level == 0);
1555
      bool tlrecpos = nonevis && callerfortr && (rscope_level == 0);
1542
      int   i;
1556
      int   i;
1543
      
1557
 
1544
      nds = scan (fnexp, at);
1558
      nds = scan(fnexp, at);
1545
      /* scan the function exp ... */
1559
      /* scan the function exp ... */
1546
      if ((nds.propsneeds & hasproccall) != 0) {
1560
      if ((nds.propsneeds & hasproccall)!= 0) {
1547
	/* .... it must be identified */
1561
	/* .... it must be identified */
1548
	cca (at, fnexp);
1562
	cca(at, fnexp);
1549
	nds.propsneeds &= ~hasproccall;
1563
	nds.propsneeds &= ~hasproccall;
1550
	nds.propsneeds |= usesproccall;
1564
	nds.propsneeds |= usesproccall;
1551
	fn = son(application);
1565
	fn = son(application);
1552
	par = &bro(fn);
1566
	par = &bro(fn);
1553
      }
1567
      }
1554
 
1568
 
1555
      if (name(fn) != name_tag ||
1569
      if (name(fn)!= name_tag ||
1556
	  (son(son(fn)) != nilexp && name(son(son(fn))) != proc_tag) ) {
1570
	 (son(son(fn))!= nilexp && name(son(son(fn)))!= proc_tag)) {
1557
	tlrecpos = 0;
1571
	tlrecpos = 0;
1558
      }
1572
      }
1559
 
1573
 
1560
      for (i = 1;!last(fn); ++i) {	/* scan parameters in turn ... */
1574
      for (i = 1;!last(fn); ++i) {	/* scan parameters in turn ... */
1561
	needs onepar;
1575
	needs onepar;
1562
	shape shpar = sh(*par);
1576
	shape shpar = sh(*par);
1563
	onepar = scan (par, at);
1577
	onepar = scan(par, at);
1564
	
1578
 
1565
	if ((i != 1 && (onepar.propsneeds & hasproccall) != 0) ||
1579
	if ((i != 1 && (onepar.propsneeds & hasproccall)!= 0) ||
1566
	    onepar.fixneeds+(parsize>>6) > maxfix) {
1580
	    onepar.fixneeds+ (parsize>>6) > maxfix) {
1567
	  /* if it isn't the first parameter, and it
1581
	  /* if it isn't the first parameter, and it
1568
	     calls a proc, identify it */
1582
	     calls a proc, identify it */
1569
	  cca (at, par);
1583
	  cca(at, par);
1570
	  nds.propsneeds |= usesproccall;
1584
	  nds.propsneeds |= usesproccall;
1571
	  nds = maxneeds (shapeneeds (sh (* (par))), nds);
1585
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
1572
	  nds.maxargs = max (nds.maxargs, onepar.maxargs);
1586
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
1573
	}
1587
	}
1574
	else {
1588
	else {
1575
	  nds = maxneeds (onepar, nds);
1589
	  nds = maxneeds(onepar, nds);
1576
	}
1590
	}
1577
	parsize = rounder(parsize, shape_align(shpar));
1591
	parsize = rounder(parsize, shape_align(shpar));
1578
	parsize = rounder(parsize+shape_size(shpar), REG_SIZE);
1592
	parsize = rounder(parsize+shape_size(shpar), REG_SIZE);
1579
	/* ? */
1593
	/* ? */
1580
	if ((!valregable(shpar) && !is_floating(name(shpar))) || parsize > 384) {
1594
	if ((!valregable(shpar) && !is_floating(name(shpar))) || parsize > 384) {
1581
	  tlrecpos = 0;
1595
	  tlrecpos = 0;
1582
	}	  
1596
	}
1583
	if (last (* (par))) {
1597
	if (last(*(par))) {
1584
	  break;
1598
	  break;
1585
	}        
1599
	}
1586
	par = &bro(*par);
1600
	par = &bro(*par);
1587
      }
1601
      }
1588
#if DO_SPECIAL
1602
#if DO_SPECIAL
1589
      if ((i = specialfn (fn)) > 0) {/* eg strlen */
1603
      if ((i = specialfn (fn)) > 0) {/* eg strlen */
1590
	nds = maxneeds (specialneeds (i), nds);
1604
	nds = maxneeds(specialneeds(i), nds);
1591
	return nds;
1605
	return nds;
1592
      }
1606
      }
1593
      else 
1607
      else
1594
	if (i == -1) {	/* call of strcpy .... */
1608
	if (i == -1) {	/* call of strcpy .... */
1595
	  exp par2 = * (par);
1609
	  exp par2 = *(par);
1596
	  /* TEST for constant string????????????????? 
1610
	  /* TEST for constant string?????????????????
1597
	     if (name (par2) == eval_tag && name (son (par2)) == pack_tag
1611
	     if (name (par2) == eval_tag && name (son (par2)) == pack_tag
1598
	     && name (son (son (par2))) == string_tag) {
1612
	     && name (son (son (par2))) == string_tag) {
1599
	     setname (* (e), ass_tag);
1613
	     setname (* (e), ass_tag);
1600
	     son (* (e)) = * (parlist);
1614
	     son (* (e)) = * (parlist);
1601
	     son (par2) = son (son (par2));
1615
	     son (par2) = son (son (par2));
1602
	     sh (par2) = sh (son (par2));
1616
	     sh (par2) = sh (son (par2));
1603
	     bro (par2) = * (e) ;
1617
	     bro (par2) = * (e) ;
1604
	     bro(son(par2)) = par2;	
1618
	     bro(son(par2)) = par2;
1605
	     return maxneeds (nds, twofix);
1619
	     return maxneeds (nds, twofix);
1606
	     }
1620
	     }
1607
	     */
1621
	     */
1608
	}
1622
	}
1609
#endif	
1623
#endif
1610
      if (tlrecpos) {
1624
      if (tlrecpos) {
1611
	exp dad = father(application);
1625
	exp dad = father(application);
1612
	if (name(dad)==res_tag) { 
1626
	if (name(dad) ==res_tag) {
1613
	  props(dad) = 1; /* do a tl recursion*/
1627
	  props(dad) = 1; /* do a tl recursion*/
1614
	}
1628
	}
1615
      }
1629
      }
1616
      nds.propsneeds |= hasproccall;
1630
      nds.propsneeds |= hasproccall;
1617
      nds.maxargs = max (nds.maxargs, parsize);
1631
      nds.maxargs = max(nds.maxargs, parsize);
1618
      return nds;
1632
      return nds;
1619
      
1633
 
1620
    }
1634
    }
1621
 
1635
 
1622
    case name_tag : {
1636
    case name_tag: {
1623
      if(is_vararg(*e)){
1637
      if (is_vararg(*e)) {
1624
	/* if the tag represents va_list (set in spec_toks.c) */
1638
	/* if the tag represents va_list (set in spec_toks.c) */
1625
	has_old_varargs = 1;
1639
	has_old_varargs = 1;
1626
      }
1640
      }
1627
      return shapeneeds (sh(*(e)));
1641
      return shapeneeds(sh(*(e)));
1628
    }
1642
    }
1629
 
1643
 
1630
    case val_tag : {
1644
    case val_tag: {
1631
      exp s = sh(*e);
1645
      exp s = sh(*e);
1632
      if (name(s)==offsethd && al2(s) >= 8) {
1646
      if (name(s) ==offsethd && al2(s) >= 8) {
1633
	/* express disps in bytes */
1647
	/* express disps in bytes */
1634
	no(*e) = no(*e) >>3;
1648
	no(*e) = no(*e) >>3;
1635
      }
1649
      }
1636
      /*... and continue */
1650
      /*... and continue */
1637
    }
1651
    }
1638
    FALL_THROUGH;
1652
    FALL_THROUGH;
1639
    case env_size_tag :
1653
    case env_size_tag:
1640
    case give_stack_limit_tag :
1654
    case give_stack_limit_tag:
1641
    case null_tag : 
1655
    case null_tag:
1642
    case real_tag :  
1656
    case real_tag:
1643
    case string_tag :
1657
    case string_tag:
1644
    case env_offset_tag : 
1658
    case env_offset_tag:
1645
    case general_env_offset_tag :
1659
    case general_env_offset_tag:
1646
    case caller_name_tag :
1660
    case caller_name_tag:
1647
    /*    case next_frame_tag :*/
1661
    /*    case next_frame_tag :*/
1648
    case current_env_tag : 
1662
    case current_env_tag:
1649
    case make_lv_tag :
1663
    case make_lv_tag:
1650
    case last_local_tag :{
1664
    case last_local_tag:{
1651
      return shapeneeds (sh (* (e)));
1665
      return shapeneeds(sh(*(e)));
1652
    }
1666
    }
1653
    
1667
 
1654
    case clear_tag : 
1668
    case clear_tag:
1655
    case formal_callee_tag :
1669
    case formal_callee_tag:
1656
    case top_tag :
1670
    case top_tag:
1657
    case prof_tag :
1671
    case prof_tag:
1658
    case local_free_all_tag :{
1672
    case local_free_all_tag:{
1659
      return zeroneeds;
1673
      return zeroneeds;
1660
    }
1674
    }
1661
    case set_stack_limit_tag :
1675
    case set_stack_limit_tag:
1662
#ifdef return_to_label_tag
1676
#ifdef return_to_label_tag
1663
    case return_to_label_tag :
1677
    case return_to_label_tag:
1664
#endif
1678
#endif
1665
    case diagnose_tag :
1679
    case diagnose_tag:
1666
    case neg_tag : 
1680
    case neg_tag:
1667
    case case_tag : 
1681
    case case_tag:
1668
    case not_tag :       
1682
    case not_tag:
1669
    case offset_negate_tag : 
1683
    case offset_negate_tag:
1670
    case absbool_tag : 
1684
    case absbool_tag:
1671
    case goto_lv_tag :	
1685
    case goto_lv_tag:
1672
    case abs_tag :
1686
    case abs_tag:
1673
    case local_free_tag :{
1687
    case local_free_tag:{
1674
      exp * arg = &son(*e);
1688
      exp * arg = &son(*e);
1675
      return scan (arg, at);
1689
      return scan(arg, at);
1676
    }
1690
    }
1677
    case fneg_tag : 
1691
    case fneg_tag:
1678
    case fabs_tag : 
1692
    case fabs_tag:
1679
    case chfl_tag : {
1693
    case chfl_tag: {
-
 
1694
      needs nds;
-
 
1695
      nds = scan(&son(*e), at);
-
 
1696
      if (!optop(*e) && nds.fixneeds <2)nds.fixneeds = 2;
-
 
1697
      return nds;
-
 
1698
    }
-
 
1699
 
-
 
1700
    case alloca_tag: {
1680
      needs nds;
1701
      needs nds;
1681
      nds = scan(&son(*e), at);
1702
      nds = scan(&son(*e), at);
1682
      if (!optop(*e) && nds.fixneeds <2) nds.fixneeds = 2;
1703
      if (nds.fixneeds <2)nds.fixneeds = 2;
1683
      return nds;
1704
      return nds;
1684
    }
1705
    }
1685
    
-
 
1686
    case alloca_tag : {
-
 
1687
      needs nds;
-
 
1688
      nds = scan(&son(*e), at);
-
 
1689
      if (nds.fixneeds <2) nds.fixneeds = 2;
-
 
1690
      return nds;
-
 
1691
    }    
-
 
1692
    case bitf_to_int_tag : {
1706
    case bitf_to_int_tag: {
1693
      /* is bitfield signed or unsigned ?? */
1707
      /* is bitfield signed or unsigned ?? */
1694
      exp * arg = &son(*e);
1708
      exp * arg = &son(*e);
1695
      needs nds;
1709
      needs nds;
1696
      exp stararg;
1710
      exp stararg;
1697
      exp stare;
1711
      exp stare;
1698
      int sizeb;
1712
      int sizeb;
1699
     
1713
 
1700
      nds = scan (arg, at);
1714
      nds = scan(arg, at);
1701
      stararg = *(arg);
1715
      stararg = *(arg);
1702
      stare = * (e);
1716
      stare = *(e);
1703
      sizeb = ashof (sh (stararg)).ashsize;
1717
      sizeb = ashof(sh(stararg)).ashsize;
1704
      if ((name(stararg)==name_tag && 
1718
      if ((name(stararg) ==name_tag &&
1705
	   ((sizeb == 8 && (no (stararg) & 7) == 0)
1719
	  ((sizeb == 8 && (no(stararg) & 7) == 0)
1706
	    || (sizeb == 16 && (no (stararg) & 15) == 0)
1720
	    || (sizeb == 16 && (no(stararg) & 15) == 0)
1707
	    || (sizeb == 32 && (no(stararg) & 31)== 0)
1721
	    || (sizeb == 32 && (no(stararg) & 31) == 0)
1708
	    || (sizeb == 64 && (no(stararg) & 63) ==0)
1722
	    || (sizeb == 64 && (no(stararg) & 63) ==0)
1709
	    )
1723
	   )
1710
	   ) || (name(stararg)==cont_tag && 
1724
	  ) || (name(stararg) ==cont_tag &&
1711
		 ((name(son(stararg)) != name_tag && 
1725
		((name(son(stararg))!= name_tag &&
1712
		   name(son(stararg))!=reff_tag)
1726
		   name(son(stararg))!=reff_tag)
1713
		  || (sizeb == 8 && (no (son(stararg)) & 7) == 0)
1727
		  || (sizeb == 8 && (no(son(stararg)) & 7) == 0)
1714
		  || (sizeb == 16 && (no (son(stararg)) & 15) == 0)
1728
		  || (sizeb == 16 && (no(son(stararg)) & 15) == 0)
1715
		  || (sizeb == 32 && (no(son(stararg)) & 31)== 0)
1729
		  || (sizeb == 32 && (no(son(stararg)) & 31) == 0)
1716
		  || (sizeb == 64 && (no(son(stararg)) & 63)== 0)
1730
		  || (sizeb == 64 && (no(son(stararg)) & 63) == 0)
1717
		  )
1731
		 )
1718
		 )	
1732
		)
1719
	  ) {	
1733
	 ) {
1720
	bool sgned = name(sh(stare)) & 1;
1734
	bool sgned = name(sh(stare)) & 1;
1721
	shape ns = (sizeb==8)? ( (sgned)?scharsh:ucharsh)
1735
	shape ns = (sizeb==8)?((sgned)?scharsh:ucharsh)
1722
	  : (sizeb==16) ?((sgned)?swordsh:uwordsh)
1736
	  :(sizeb==16)?((sgned)?swordsh:uwordsh)
1723
	  : sh(stare);
1737
	  : sh(stare);
1724
	/*  can use short loads instead of bits extractions*/
1738
	/*  can use short loads instead of bits extractions*/
1725
	if (name(stararg)==cont_tag) { 
1739
	if (name(stararg) ==cont_tag) {
1726
	  /* make the ptr shape consistent */
1740
	  /* make the ptr shape consistent */
1727
	  sh(son(stararg)) = f_pointer(long_to_al(shape_align(ns)));
1741
	  sh(son(stararg)) = f_pointer(long_to_al(shape_align(ns)));
1728
	}
1742
	}
1729
	sh(stararg) = ns;
1743
	sh(stararg) = ns;
1730
	setname(stare, chvar_tag);
1744
	setname(stare, chvar_tag);
1731
      }	
1745
      }
1732
      return nds;
1746
      return nds;
1733
    }
1747
    }
1734
    
1748
 
1735
    case int_to_bitf_tag : {
1749
    case int_to_bitf_tag: {
1736
      exp * arg = &son(*e);
1750
      exp * arg = &son(*e);
1737
      return scan (arg, at);
1751
      return scan(arg, at);
1738
    }
1752
    }
1739
    
1753
 
1740
    case round_tag : {
1754
    case round_tag: {
1741
      needs s;
1755
      needs s;
1742
      exp * arg = &son(*e);
1756
      exp * arg = &son(*e);
1743
      s = scan (arg, at);
1757
      s = scan(arg, at);
1744
      s.fixneeds = max (s.fixneeds, 2);
1758
      s.fixneeds = max(s.fixneeds, 2);
1745
      s.floatneeds = max (s.floatneeds, 2);
1759
      s.floatneeds = max(s.floatneeds, 2);
1746
      has_float = 1;
1760
      has_float = 1;
1747
      return s;
1761
      return s;
1748
    }
1762
    }
1749
    
1763
 
1750
    case shl_tag : 
1764
    case shl_tag:
1751
    case shr_tag : 
1765
    case shr_tag:
1752
    case long_jump_tag : {
1766
    case long_jump_tag: {
1753
      exp * lhs = &son(*e);
1767
      exp * lhs = &son(*e);
1754
      exp * rhs  = & bro(*lhs);
1768
      exp * rhs  = & bro(*lhs);
1755
      needs nr;
1769
      needs nr;
1756
      needs nl;
1770
      needs nl;
1757
      prop prps ;
1771
      prop prps;
1758
      nr = scan(rhs, at);
1772
      nr = scan(rhs, at);
1759
      nl = scan (lhs, at);
1773
      nl = scan(lhs, at);
1760
      rhs = &bro(*lhs);
1774
      rhs = &bro(*lhs);
1761
      prps = (nr.propsneeds & hasproccall) << 1;
1775
      prps = (nr.propsneeds & hasproccall) << 1;
1762
      if (nr.fixneeds >= maxfix || prps != 0) {
1776
      if (nr.fixneeds >= maxfix || prps != 0) {
1763
	/* if reg requirements overlap, identify
1777
	/* if reg requirements overlap, identify
1764
	   second operand */
1778
	   second operand */
1765
	cca (at, rhs);
1779
	cca(at, rhs);
1766
	nl = shapeneeds (sh (* (rhs)));
1780
	nl = shapeneeds(sh(*(rhs)));
1767
	nl.propsneeds |= morefix;
1781
	nl.propsneeds |= morefix;
1768
	nl.propsneeds &= ~(prps >> 1);
1782
	nl.propsneeds &= ~(prps >> 1);
1769
	nl.propsneeds |= prps;
1783
	nl.propsneeds |= prps;
1770
      }
1784
      }
1771
      nr.fixneeds += 1;
1785
      nr.fixneeds += 1;
1772
      return maxneeds (nl, nr);
1786
      return maxneeds(nl, nr);
1773
      
1787
 
1774
    }
1788
    }
1775
    
1789
 
1776
    case test_tag : {
1790
    case test_tag: {
1777
      exp stare = *(e);
1791
      exp stare = *(e);
1778
      exp l = son (stare);
1792
      exp l = son(stare);
1779
      exp r = bro (l);
1793
      exp r = bro(l);
1780
      exp dad = father(stare);
1794
      exp dad = father(stare);
1781
      bool xlike = (name(dad)==maxlike_tag || name(dad)==minlike_tag || name(dad)==abslike_tag);
1795
      bool xlike = (name(dad) ==maxlike_tag || name(dad) ==minlike_tag || name(dad) ==abslike_tag);
1782
      /* don't do various optimisations if xlike */
1796
      /* don't do various optimisations if xlike */
1783
      
1797
 
1784
      if (!last (stare) && name (bro (stare)) == test_tag &&
1798
      if (!last(stare) && name(bro(stare)) == test_tag &&
1785
	  no (stare) == no (bro (stare)) &&
1799
	  no(stare) == no(bro(stare)) &&
1786
	  props(stare)==props(bro(stare)) &&
1800
	  props(stare) ==props(bro(stare)) &&
1787
	  eq_exp (l, son (bro (stare))) && eq_exp (r, bro (son (bro (stare))))
1801
	  eq_exp(l, son(bro(stare))) && eq_exp(r, bro(son(bro(stare))))
1788
	  ) {			/* same test following in seq list -
1802
	  ) {			/* same test following in seq list -
1789
				   remove second test */
1803
				   remove second test */
1790
	if (last (bro (stare)))
1804
	if (last(bro(stare)))
1791
	  setlast (stare);
1805
	  setlast(stare);
1792
	bro (stare) = bro (bro (stare));
1806
	bro(stare) = bro(bro(stare));
1793
      }
1807
      }
1794
      
1808
 
1795
      if (last (stare) && name (bro (stare)) == 0/* seq holder */
1809
      if (last (stare) && name (bro (stare)) == 0/* seq holder */
1796
	  && name (bro (bro (stare))) == test_tag &&
1810
	  && name(bro(bro(stare))) == test_tag &&
1797
	  name (bro (bro (bro (stare)))) == seq_tag &&
1811
	  name(bro(bro(bro(stare)))) == seq_tag &&
1798
	  no (stare) == no (bro (bro (stare))) &&
1812
	  no(stare) == no(bro(bro(stare))) &&
1799
	  props(stare)==props(bro(bro(stare))) &&
1813
	  props(stare) ==props(bro(bro(stare))) &&
1800
	  eq_exp (l, son (bro (bro (stare))))
1814
	  eq_exp(l, son(bro(bro(stare))))
1801
	  && eq_exp (r, bro (son (bro (bro (stare)))))
1815
	  && eq_exp(r, bro(son(bro(bro(stare)))))
1802
	  ) {			/* same test following in seq res - void
1816
	  ) {			/* same test following in seq res - void
1803
				   second test */
1817
				   second test */
1804
	setname (bro (bro (stare)), top_tag);
1818
	setname(bro(bro(stare)), top_tag);
1805
	son (bro (bro (stare))) = nilexp;
1819
	son(bro(bro(stare))) = nilexp;
1806
	pt (bro (bro (stare))) = nilexp;
1820
	pt(bro(bro(stare))) = nilexp;
1807
      }
1821
      }
1808
      
1822
 
1809
      if (!xlike && name (l) == val_tag && (props (stare) == 5 || props (stare) == 6)) {
1823
      if (!xlike && name(l) == val_tag && (props(stare) == 5 || props(stare) == 6)) {
1810
	/* commute  const = x */
1824
	/* commute  const = x */
1811
	bro (l) = stare;
1825
	bro(l) = stare;
1812
	setlast (l);
1826
	setlast(l);
1813
	bro (r) = l;
1827
	bro(r) = l;
1814
	clearlast (r);
1828
	clearlast(r);
1815
	son (stare) = r;
1829
	son(stare) = r;
1816
	r = l;
1830
	r = l;
1817
	l = son (stare);
1831
	l = son(stare);
1818
      }
1832
      }
1819
      
1833
 
1820
      if (!xlike && name (r) == val_tag && (props (stare) == 5 
1834
      if (!xlike && name(r) == val_tag && (props(stare) == 5
1821
					    || props (stare) == 6) && no (r) == 0 &&
1835
					    || props(stare) == 6) && no(r) == 0 &&
1822
	  name (l) == and_tag && name (bro (son (l))) == val_tag &&
1836
	  name(l) == and_tag && name(bro(son(l))) == val_tag &&
1823
	  (no (bro (son (l))) & (no (bro (son (l))) - 1)) == 0 
1837
	 (no(bro(son(l))) & (no(bro(son(l))) - 1)) == 0
1824
	  ) {			
1838
	 ) {
1825
	/* zero test  x & 2^n   -> neg test (x shl
1839
	/* zero test  x & 2^n   -> neg test (x shl
1826
	   (31-n)) */
1840
	   (31-n)) */
1827
	exp copy;
1841
	exp copy;
1828
	INT64  n = isbigval(bro(son(l)))?exp_to_INT64((bro(son(l)))):
1842
	INT64  n = isbigval(bro(son(l)))?exp_to_INT64((bro(son(l)))):
1829
	  make_INT64(0,no (bro (son (l))));
1843
	  make_INT64(0,no(bro(son(l))));
1830
	int   x;
1844
	int   x;
1831
	for(x = 0; INT64_lt(zero_int64,n);++x) {
1845
	for (x = 0; INT64_lt(zero_int64,n);++x) {
1832
/*      for (x = 0; n > 0; x++) {*/
1846
/*      for (x = 0; n > 0; x++) {*/
1833
	  n = INT64_shift_left(n,1,1);
1847
	  n = INT64_shift_left(n,1,1);
1834
	  /*n = n << 1;*/
1848
	  /*n = n << 1;*/
1835
	}
1849
	}
1836
	if (x == 0) {		/* no shift required */
1850
	if (x == 0) {		/* no shift required */
1837
	  bro (son (l)) = r;	/* zero there */
1851
	  bro (son (l)) = r;	/* zero there */
1838
	  son (stare) = son (l);/* x */
1852
	  son (stare) = son (l);/* x */
1839
	}
1853
	}
1840
	else {
1854
	else {
1841
	  setname (l, shl_tag);
1855
	  setname(l, shl_tag);
1842
	  no (bro (son (l))) = x;
1856
	  no(bro(son(l))) = x;
1843
	}
1857
	}
1844
	props (stare) -= 3;	/* test for neg */
1858
	props (stare) -= 3;	/* test for neg */
1845
	if(!is64(sh(son(stare))) && name(l)!=shl_tag ){
1859
	if (!is64(sh(son(stare))) && name(l)!=shl_tag) {
1846
	  sh(son(stare)) = slongsh;
1860
	  sh(son(stare)) = slongsh;
1847
	  copy = getexp(s64sh,bro(son(stare)),0,son(stare),nilexp,0,0,
1861
	  copy = getexp(s64sh,bro(son(stare)),0,son(stare),nilexp,0,0,
1848
			chvar_tag);
1862
			chvar_tag);
1849
	  son(stare) = copy;
1863
	  son(stare) = copy;
1850
	}
1864
	}
1851
	else{
1865
	else{
1852
	  sh(son(stare)) = s64sh;
1866
	  sh(son(stare)) = s64sh;
1853
	}
1867
	}
1854
	  
1868
 
1855
      }
1869
      }
1856
      if (name (l) == bitf_to_int_tag && name (r) == val_tag &&
1870
      if (name(l) == bitf_to_int_tag && name(r) == val_tag &&
1857
	  (props (stare) == 5 || props (stare) == 6) &&
1871
	 (props(stare) == 5 || props(stare) == 6) &&
1858
	  (name (son (l)) == cont_tag || name (son (l)) == name_tag)) {
1872
	 (name(son(l)) == cont_tag || name(son(l)) == name_tag)) {
1859
	/* equality of bits against +ve consts
1873
	/* equality of bits against +ve consts
1860
	   doesnt need sign adjustment */
1874
	   doesnt need sign adjustment */
1861
	long  n = no (r);
1875
	long  n = no(r);
1862
	switch (name (sh (l))) {
1876
	switch (name(sh(l))) {
1863
	  case scharhd : {
1877
	  case scharhd: {
1864
	    if (n >= 0 && n <= 127) {
1878
	    if (n >= 0 && n <= 127) {
1865
	      sh (l) = ucharsh;
1879
	      sh(l) = ucharsh;
1866
	    } break;
1880
	    } break;
1867
	  }
1881
	  }
1868
	  case swordhd : {
1882
	  case swordhd: {
1869
	    if (n >= 0 && n <= 0xffff) {
1883
	    if (n >= 0 && n <= 0xffff) {
1870
	      sh (l) = uwordsh;
1884
	      sh(l) = uwordsh;
1871
	    } break;
1885
	    } break;
1872
	  }
1886
	  }
1873
	  default: ;
1887
	  default:;
1874
	}
1888
	}
1875
      }	
1889
      }
1876
      else if (is_floating (name (sh (l)))) {
1890
      else if (is_floating(name(sh(l)))) {
1877
	return fpop (e, at);
1891
	return fpop(e, at);
1878
      }	
1892
      }
1879
      else if (!xlike && name (r) == val_tag && no (r) == 1 && !isbigval(r)
1893
      else if (!xlike && name(r) == val_tag && no(r) == 1 && !isbigval(r)
1880
	       && (props (stare) == 3 || props (stare) == 2)) {
1894
	       && (props(stare) == 3 || props(stare) == 2)) {
1881
	no (r) = 0;
1895
	no(r) = 0;
1882
	if (props (stare) == 3) {
1896
	if (props(stare) == 3) {
1883
	  props (stare) = 4;/* branch >=1 -> branch > 0 */
1897
	  props (stare) = 4;/* branch >=1 -> branch > 0 */
1884
	}	
1898
	}
1885
	else	 {
1899
	else	 {
1886
	  props (stare) = 1;/* branch <1 -> branch <= 0 */
1900
	  props (stare) = 1;/* branch <1 -> branch <= 0 */
1887
	}	
1901
	}
1888
      }
1902
      }
1889
      return likediv (e, at);
1903
      return likediv(e, at);
1890
    }
1904
    }
1891
    case plus_tag :{
1905
    case plus_tag:{
1892
      /* replace any operands which are neg(..)
1906
      /* replace any operands which are neg(..)
1893
	 by - ,if poss */
1907
	 by - ,if poss */
1894
      exp sum = * (e);
1908
      exp sum = *(e);
1895
      exp list = son (sum);
1909
      exp list = son(sum);
1896
      bool someneg = 0;
1910
      bool someneg = 0;
1897
      bool allneg = 1;
1911
      bool allneg = 1;
1898
      for (;optop(sum);) {
1912
      for (;optop(sum);) {
1899
	if (name (list) == neg_tag)
1913
	if (name(list) == neg_tag)
1900
	  someneg = 1;
1914
	  someneg = 1;
1901
	else
1915
	else
1902
	  allneg = 0;
1916
	  allneg = 0;
1903
	if (last (list))
1917
	if (last(list))
1904
	  break;
1918
	  break;
1905
	list = bro (list);
1919
	list = bro(list);
1906
      }
1920
      }
1907
      
1921
 
1908
      if (someneg) {		/* there are some neg() operands */
1922
      if (someneg) {		/* there are some neg() operands */
1909
	if (allneg) {
1923
	if (allneg) {
1910
	  /* transform -..-... to -(..+.. +...) */
1924
	  /* transform -..-... to -(..+.. +...) */
1911
	  exp x = son (sum);
1925
	  exp x = son(sum);
1912
	  list = son (x);
1926
	  list = son(x);
1913
	  /* ALTERATION #1 here to fix minor structural bug */
1927
	  /* ALTERATION #1 here to fix minor structural bug */
1914
	  for (;;) {
1928
	  for (;;) {
1915
	    if (!last (x)) {
1929
	    if (!last(x)) {
1916
	      bro (list) = son (bro (x));
1930
	      bro(list) = son(bro(x));
1917
	      clearlast (list);
1931
	      clearlast(list);
1918
	      list = bro (list);
1932
	      list = bro(list);
1919
	      x = bro (x);
1933
	      x = bro(x);
1920
	    }
1934
	    }
1921
	    else {
1935
	    else {
1922
	      bro(list) = sum;
1936
	      bro(list) = sum;
1923
	      setlast (list);
1937
	      setlast(list);
1924
	      son (sum) = son (son (sum));
1938
	      son(sum) = son(son(sum));
1925
	      /* use existing exp */
1939
	      /* use existing exp */
1926
	      break;
1940
	      break;
1927
	    }
1941
	    }
1928
	  }
1942
	  }
1929
	  x = getexp (sh (sum), bro (sum), last (sum), sum, nilexp,
1943
	  x = getexp(sh(sum), bro(sum), last(sum), sum, nilexp,
1930
		      0, 0, neg_tag);
1944
		      0, 0, neg_tag);
1931
	  setlast(sum); bro(sum)=x; /* set father of sum to be negate */
1945
	  setlast(sum); bro(sum)=x; /* set father of sum to be negate */
1932
	  * (e) = x;
1946
	  *(e) = x;
1933
	  
1947
 
1934
	}			/* end allneg */
1948
	}			/* end allneg */
1935
	else {
1949
	else {
1936
	  /* transform to  ((..(..+..) - ..) -..) */
1950
	  /* transform to  ((..(..+..) - ..) -..) */
1937
	  int   n = 0;
1951
	  int   n = 0;
1938
	  exp brosum = bro (sum);
1952
	  exp brosum = bro(sum);
1939
	  bool lastsum = last (sum);
1953
	  bool lastsum = last(sum);
1940
	  exp x = son (sum);
1954
	  exp x = son(sum);
1941
	  exp newsum = sum;
1955
	  exp newsum = sum;
1942
	  list = nilexp;
1956
	  list = nilexp;
1943
	  for (;;) {
1957
	  for (;;) {
1944
	    exp nxt = bro (x);
1958
	    exp nxt = bro(x);
1945
	    bool final = last (x);
1959
	    bool final = last(x);
1946
	    if (name (x) == neg_tag) {
1960
	    if (name(x) == neg_tag) {
1947
	      bro (son (x)) = list;
1961
	      bro(son(x)) = list;
1948
	      list = son (x);
1962
	      list = son(x);
1949
	    }
1963
	    }
1950
	    else {
1964
	    else {
1951
	      bro (x) = newsum;
1965
	      bro(x) = newsum;
1952
	      newsum = x;
1966
	      newsum = x;
1953
	      if ((n++) == 0)
1967
	      if ((n++) == 0)
1954
		setlast (newsum);
1968
		setlast(newsum);
1955
	      else
1969
	      else
1956
		clearlast (newsum);
1970
		clearlast(newsum);
1957
	    }
1971
	    }
1958
	    if (final)
1972
	    if (final)
1959
	      break;
1973
	      break;
1960
	    x = nxt;
1974
	    x = nxt;
1961
	  }
1975
	  }
1962
	  
1976
 
1963
	  if (n > 1) {
1977
	  if (n > 1) {
1964
	    son (sum) = newsum;
1978
	    son(sum) = newsum;
1965
	    newsum = sum;	/* use existing exp for add operations */
1979
	    newsum = sum;	/* use existing exp for add operations */
1966
	  }
1980
	  }
1967
	  for (;;) {		/* introduce - operations */
1981
	  for (;;) {		/* introduce - operations */
1968
	    exp nxt = bro (list);
1982
	    exp nxt = bro(list);
1969
	    bro (newsum) = list;
1983
	    bro(newsum) = list;
1970
	    clearlast (newsum);
1984
	    clearlast(newsum);
1971
	    x = getexp (sh (sum), nilexp, 0, newsum, nilexp, 0, 0, minus_tag);
1985
	    x = getexp(sh(sum), nilexp, 0, newsum, nilexp, 0, 0, minus_tag);
1972
	    
1986
 
1973
	    bro (list) = x;
1987
	    bro(list) = x;
1974
	    setlast (list);
1988
	    setlast(list);
1975
	    newsum = x;
1989
	    newsum = x;
1976
	    if ((list = nxt) == nilexp)
1990
	    if ((list = nxt) == nilexp)
1977
	      break;
1991
	      break;
1978
	  }
1992
	  }
1979
	  bro (newsum) = brosum;
1993
	  bro(newsum) = brosum;
1980
	  if (lastsum) {
1994
	  if (lastsum) {
1981
	    setlast (newsum);
1995
	    setlast(newsum);
1982
	  }
1996
	  }
1983
	  else {
1997
	  else {
1984
	    clearlast (newsum);
1998
	    clearlast(newsum);
1985
	  }
1999
	  }
1986
	  * (e) = newsum;
2000
	  *(e) = newsum;
1987
	  
2001
 
1988
	}			/* end else allneg */
2002
	}			/* end else allneg */
1989
	
2003
 
1990
	return scan (e, at);
2004
	return scan(e, at);
1991
	
2005
 
1992
      }			/* end someneg - else continue to next
2006
      }			/* end someneg - else continue to next
1993
			   case */
2007
			   case */
1994
    }
2008
    }
1995
      FALL_THROUGH
2009
      FALL_THROUGH
1996
    case and_tag :
2010
    case and_tag:
1997
    case mult_tag :  
2011
    case mult_tag:
1998
    case or_tag : 
2012
    case or_tag:
1999
    case xor_tag : {
2013
    case xor_tag: {
2000
	return likeplus (e, at);
2014
	return likeplus(e, at);
2001
      }
2015
      }
2002
    case addptr_tag : {
2016
    case addptr_tag: {
2003
      exp ptr_arg = son(*e);
2017
      exp ptr_arg = son(*e);
2004
      exp offset_arg = bro(ptr_arg);
2018
      exp offset_arg = bro(ptr_arg);
2005
      int fralign = frame_al_of_ptr(sh(ptr_arg));
2019
      int fralign = frame_al_of_ptr(sh(ptr_arg));
2006
      if (fralign){
2020
      if (fralign) {
2007
	int offalign = frame_al1_of_offset(sh(offset_arg));
2021
	int offalign = frame_al1_of_offset(sh(offset_arg));
2008
#if 0
2022
#if 0
2009
	if( ((offalign-1)&offalign) != 0){
2023
	if (((offalign-1) &offalign)!= 0) {
2010
	  failer("Mixed frame offsets not supported");
2024
	  failer("Mixed frame offsets not supported");
2011
	}
2025
	}
2012
#endif
2026
#endif
2013
	if(includes_vcallees(fralign) && l_or_cees(offalign)){
2027
	if (includes_vcallees(fralign) && l_or_cees(offalign)) {
2014
	  exp newexp = getexp(sh(ptr_arg),offset_arg,0,ptr_arg,nilexp,0,0,
2028
	  exp newexp = getexp(sh(ptr_arg),offset_arg,0,ptr_arg,nilexp,0,0,
2015
			      locptr_tag);
2029
			      locptr_tag);
2016
	  bro(ptr_arg) = newexp;
2030
	  bro(ptr_arg) = newexp;
2017
	  setlast(ptr_arg);
2031
	  setlast(ptr_arg);
2018
	  son(*e) = newexp;
2032
	  son(*e) = newexp;
2019
	}
2033
	}
2020
      }
2034
      }
2021
      return likediv(e,at);
2035
      return likediv(e,at);
2022
    }
-
 
2023
    case locptr_tag :
-
 
2024
    case reff_tag :
-
 
2025
    case offset_pad_tag :
-
 
2026
    case chvar_tag : {
-
 
2027
      exp * arg = &son(*e);
-
 
2028
      needs nds;
-
 
2029
      nds = maxneeds (scan (arg, at),shapeneeds (sh (* (e))));
-
 
2030
      /*      nds.fixneeds += 1;*/
-
 
2031
      return nds;
-
 
2032
    }
2036
    }
-
 
2037
    case locptr_tag:
-
 
2038
    case reff_tag:
-
 
2039
    case offset_pad_tag:
-
 
2040
    case chvar_tag: {
-
 
2041
      exp * arg = &son(*e);
-
 
2042
      needs nds;
-
 
2043
      nds = maxneeds(scan(arg, at),shapeneeds(sh(*(e))));
-
 
2044
      /*      nds.fixneeds += 1;*/
-
 
2045
      return nds;
2033
    
2046
    }
-
 
2047
 
2034
    case float_tag :  {
2048
    case float_tag:  {
2035
      needs nds;	
2049
      needs nds;
2036
      exp * arg = &son(*e);
2050
      exp * arg = &son(*e);
2037
      nds = maxneeds (scan (arg, at), shapeneeds (sh (* (e))));
2051
      nds = maxneeds(scan(arg, at), shapeneeds(sh(*(e))));
2038
      if ((name(sh(son(*(e)))) == ulonghd)||(name(sh(son(*(e))))==u64hd)) {
2052
      if ((name(sh(son(*(e)))) == ulonghd) || (name(sh(son(*(e)))) ==u64hd)) {
2039
	if (nds.floatneeds <2) nds.floatneeds =2;	/* remove */
2053
	if (nds.floatneeds <2) nds.floatneeds =2;	/* remove */
2040
      }
2054
      }
2041
      has_float = 1;
2055
      has_float = 1;
2042
      return nds;
2056
      return nds;
2043
    }	
2057
    }
2044
    case cont_tag : 
2058
    case cont_tag:
2045
    case contvol_tag : {
2059
    case contvol_tag: {
2046
      exp * arg = &son(*e);
2060
      exp * arg = &son(*e);
2047
      needs nds;
2061
      needs nds;
2048
     
2062
 
2049
      nds = maxneeds (scan (arg, at), shapeneeds (sh (* (e))));
2063
      nds = maxneeds(scan(arg, at), shapeneeds(sh(*(e))));
2050
      if(is_awkward_variety(name(sh(*e)))){
2064
      if (is_awkward_variety(name(sh(*e)))) {
2051
	nds.fixneeds = max(nds.fixneeds,4);
2065
	nds.fixneeds = max(nds.fixneeds,4);
2052
      }
2066
      }
2053
      else{
2067
      else{
2054
	nds.fixneeds = max (nds.fixneeds, 2);
2068
	nds.fixneeds = max(nds.fixneeds, 2);
2055
      }
2069
      }
2056
      if (nstare != cont_tag) {
2070
      if (nstare != cont_tag) {
2057
	nds.propsneeds |= uses2_bit;
2071
	nds.propsneeds |= uses2_bit;
2058
      }
2072
      }
2059
      return nds;
2073
      return nds;
2060
    }	
2074
    }
2061
    
2075
 
2062
    case offset_mult_tag : 
2076
    case offset_mult_tag:
2063
    case offset_div_tag : {
2077
    case offset_div_tag: {
2064
      exp op2 = bro(son(*e));
2078
      exp op2 = bro(son(*e));
2065
      shape s = sh(op2);
2079
      shape s = sh(op2);
2066
      if (name(op2)==val_tag && no(op2) == 8 && name(s)==offsethd && al2(s) >= 8) {
2080
      if (name(op2) ==val_tag && no(op2) == 8 && name(s) ==offsethd && al2(s) >= 8) {
2067
	/* offset is one  byte */
2081
	/* offset is one  byte */
2068
	exp op1 = son(*e);
2082
	exp op1 = son(*e);
2069
	bro(op1) = bro(*e);
2083
	bro(op1) = bro(*e);
2070
	if (last(*e)) { setlast(op1); } else {clearlast(op1); }
2084
	if (last(*e)) { setlast(op1); } else {clearlast(op1); }
2071
	*e = op1;
2085
	*e = op1;
2072
	return( scan(e, at));
2086
	return(scan(e, at));
2073
      }
2087
      }
2074
      /*... else continue */
2088
      /*... else continue */
2075
    }
2089
    }
2076
      FALL_THROUGH;
2090
      FALL_THROUGH;
2077
    case div2_tag : 
2091
    case div2_tag:
2078
    case rem2_tag : 
2092
    case rem2_tag:
2079
    case rem0_tag :
2093
    case rem0_tag:
2080
    case div0_tag :
2094
    case div0_tag:
2081
    case offset_div_by_int_tag :{
2095
    case offset_div_by_int_tag:{
2082
	if(is_machine_divide(*e)){
2096
	if (is_machine_divide(*e)) {
2083
	  has_div = 1;
2097
	  has_div = 1;
2084
	}
2098
	}
2085
	return likediv(e,at);
2099
	return likediv(e,at);
2086
      }
2100
      }
2087
    case offset_add_tag :  
2101
    case offset_add_tag:
2088
    case offset_subtract_tag : {
2102
    case offset_subtract_tag: {
2089
      if((al2(sh(son(*e))) == 1) && (al2(sh(bro(son(*e)))) != 1)){
2103
      if ((al2(sh(son(*e))) == 1) && (al2(sh(bro(son(*e))))!= 1)) {
2090
	make_bitfield_offset(bro(son(*e)),son(*e),0,sh(*e));
2104
	make_bitfield_offset(bro(son(*e)),son(*e),0,sh(*e));
2091
      }
2105
      }
2092
      if((al2(sh(son(*e))) != 1) && (al2(sh(bro(son(*e)))) == 1)){
2106
      if ((al2(sh(son(*e)))!= 1) && (al2(sh(bro(son(*e)))) == 1)) {
2093
	make_bitfield_offset(son(*e),*e,1,sh(*e));
2107
	make_bitfield_offset(son(*e),*e,1,sh(*e));
2094
      }
2108
      }
2095
    }
2109
    }
2096
    FALL_THROUGH;
2110
    FALL_THROUGH;
2097
#ifdef make_stack_limit_tag
2111
#ifdef make_stack_limit_tag
2098
    case make_stack_limit_tag :
2112
    case make_stack_limit_tag:
2099
#endif
2113
#endif
2100
    case min_tag :
2114
    case min_tag:
2101
    case max_tag :
2115
    case max_tag:
2102
    case minus_tag : 
2116
    case minus_tag:
2103
    case subptr_tag : 
2117
    case subptr_tag:
2104
    case minptr_tag : 
2118
    case minptr_tag:
2105
    case offset_max_tag : 
2119
    case offset_max_tag:
2106
    case component_tag :{
2120
    case component_tag:{
2107
      return likediv (e, at);
2121
      return likediv(e, at);
2108
    }
-
 
2109
    case div1_tag : {
-
 
2110
      if(is_machine_divide(*e)){
-
 
2111
	has_div = 1;
-
 
2112
      }
-
 
2113
      if ((name(sh(*e)) & 1)==0) { setname(*e, div2_tag); }
-
 
2114
      return likediv(e,at);
-
 
2115
    }
2122
    }
2116
    case mod_tag : {
2123
    case div1_tag: {
2117
      if(is_machine_divide(*e)){
2124
      if (is_machine_divide(*e)) {
2118
	has_div = 1;
2125
	has_div = 1;
2119
      }
2126
      }
2120
      if ((name(sh(*e)) & 1)==0) { setname(*e, rem2_tag); }
2127
      if ((name(sh(*e)) & 1) ==0) { setname(*e, div2_tag); }
2121
      return likediv(e,at);
2128
      return likediv(e,at);
2122
    }
2129
    }
-
 
2130
    case mod_tag: {
-
 
2131
      if (is_machine_divide(*e)) {
-
 
2132
	has_div = 1;
-
 
2133
      }
-
 
2134
      if ((name(sh(*e)) & 1) ==0) { setname(*e, rem2_tag); }
-
 
2135
      return likediv(e,at);
-
 
2136
    }
2123
    case fdiv_tag : 
2137
    case fdiv_tag:
2124
#if (FBASE==10)		/* (FBASE==10) is now defunct */
2138
#if (FBASE==10)		/* (FBASE==10) is now defunct */
2125
    {
2139
    {
2126
      /* replace X/const by X*const^-1 */
2140
      /* replace X/const by X*const^-1 */
2127
      exp z = * (e);
2141
      exp z = *(e);
2128
      exp a2 = bro (son (z));
2142
      exp a2 = bro(son(z));
2129
      if (name (a2) == real_tag) {
2143
      if (name(a2) == real_tag) {
2130
	flt inverse;
2144
	flt inverse;
2131
	flt unitflt;
2145
	flt unitflt;
2132
	str2flt ("1.0", &unitflt, (char **) 0);
2146
	str2flt("1.0", &unitflt,(char **)0);
2133
	if (flt_div (unitflt, flptnos[no (a2)], &inverse) == OKAY) {
2147
	if (flt_div(unitflt, flptnos[no(a2)], &inverse) == OKAY) {
2134
	  
2148
 
2135
	  int   f = new_flpt ();
2149
	  int   f = new_flpt();
2136
	  flptnos[f] = inverse;
2150
	  flptnos[f] = inverse;
2137
	  no (a2) = f;
2151
	  no(a2) = f;
2138
	  setname (z, fmult_tag);
2152
	  setname(z, fmult_tag);
2139
	}
2153
	}
2140
      }
2154
      }
2141
    }
2155
    }
2142
#endif
2156
#endif
2143
    case fplus_tag : 
2157
    case fplus_tag:
2144
    case fminus_tag : 
2158
    case fminus_tag:
2145
    case fmult_tag : {
2159
    case fmult_tag: {
2146
      exp op = *(e);
2160
      exp op = *(e);
2147
      exp a2 = bro(son(op));
2161
      exp a2 = bro(son(op));
2148
      has_float = 1;
2162
      has_float = 1;
2149
      if (!last(a2) ) { 
2163
      if (!last(a2)) {
2150
	/* + and * can have >2 parameters 
2164
	/* + and * can have >2 parameters
2151
	   - make them diadic - can do better
2165
	   - make them diadic - can do better
2152
	   a+exp => let x = exp in a+x */
2166
	   a+exp => let x = exp in a+x */
2153
	exp opn = getexp(sh(op), op, 0, a2, nilexp, 0, 0, name(op));
2167
	exp opn = getexp(sh(op), op, 0, a2, nilexp, 0, 0, name(op));
2154
	/* dont need to transfer error treatment - nans */
2168
	/* dont need to transfer error treatment - nans */
2155
	exp nd = getexp(sh(op), bro(op), last(op), opn, nilexp, 0, 1,
2169
	exp nd = getexp(sh(op), bro(op), last(op), opn, nilexp, 0, 1,
2156
			ident_tag);
2170
			ident_tag);
2157
	exp id = getexp(sh(op), op, 1, nd, nilexp, 0, 0, name_tag);
2171
	exp id = getexp(sh(op), op, 1, nd, nilexp, 0, 0, name_tag);
2158
	pt(nd) = id;
2172
	pt(nd) = id;
2159
	bro(son(op)) = id;
2173
	bro(son(op)) = id;
2160
	setlast(op); bro(op) = nd;
2174
	setlast(op); bro(op) = nd;
2161
	while (!last(a2)) a2 = bro(a2);
2175
	while (!last(a2))a2 = bro(a2);
2162
	bro(a2) = opn;
2176
	bro(a2) = opn;
2163
	*(e) = nd;
2177
	*(e) = nd;
2164
	return scan(e, at);
2178
	return scan(e, at);
2165
      }    	
2179
      }
2166
      
2180
 
2167
      return fpop (e, at);
2181
      return fpop(e, at);
2168
    }
2182
    }
2169
 
2183
 
2170
    case fmax_tag : {
2184
    case fmax_tag: {
2171
      has_float = 1;
2185
      has_float = 1;
2172
      return fpop(e,at);
2186
      return fpop(e,at);
2173
    }
2187
    }
2174
    
2188
 
2175
    case field_tag : {
2189
    case field_tag: {
2176
      needs str;
2190
      needs str;
2177
      exp * arg = &son(*e);
2191
      exp * arg = &son(*e);
2178
      if (chase(*e, arg)) { /* field has been distributed */
2192
      if (chase(*e, arg)) { /* field has been distributed */
2179
	exp stare = *e;
2193
	exp stare = *e;
2180
	exp ss = son (stare);
2194
	exp ss = son(stare);
2181
	if (!last (stare))
2195
	if (!last(stare))
2182
	  clearlast (ss);
2196
	  clearlast(ss);
2183
	bro (ss) = bro (stare);
2197
	bro(ss) = bro(stare);
2184
	sh (ss) = sh (stare);
2198
	sh(ss) = sh(stare);
2185
	*e = ss;
2199
	*e = ss;
2186
	return (scan (e, at));
2200
	return(scan(e, at));
2187
      }	  
2201
      }
2188
      str = scan (arg, at);
2202
      str = scan(arg, at);
2189
      return maxneeds (str, shapeneeds (sh (* (e))));
2203
      return maxneeds(str, shapeneeds(sh(*(e))));
2190
    }
2204
    }
2191
    case general_proc_tag :
2205
    case general_proc_tag:
2192
    case proc_tag :{
2206
    case proc_tag:{
2193
      exp * bexp;	
2207
      exp * bexp;
2194
      exp * bat;
2208
      exp * bat;
2195
      needs body;
2209
      needs body;
2196
      exp stare = *(e);
2210
      exp stare = *(e);
2197
      callerfortr = do_tlrecursion && !proc_has_setjmp(stare) 
2211
      callerfortr = do_tlrecursion && !proc_has_setjmp(stare)
2198
	&& !proc_has_alloca(stare) && !proc_has_lv(stare) && 
2212
	&& !proc_has_alloca(stare) && !proc_has_lv(stare) &&
2199
	!proc_uses_crt_env(stare);		
2213
	!proc_uses_crt_env(stare);
2200
      callerfortr=0;
2214
      callerfortr=0;
2201
      maxfix = 12;  /* excluding regs corrupted by div */
2215
      maxfix = 12;  /* excluding regs corrupted by div */
2202
      maxfloat = 12; /* jm - 21? */
2216
      maxfloat = 12; /* jm - 21? */
2203
      stparam = 0;
2217
      stparam = 0;
2204
      fixparam = 16;
2218
      fixparam = 16;
2205
      floatparam = 16;
2219
      floatparam = 16;
2206
      nonevis = 1;
2220
      nonevis = 1;
2207
      rscope_level = 0;		
2221
      rscope_level = 0;
2208
      numparams=0;
2222
      numparams=0;
2209
      callee_size = 0;
2223
      callee_size = 0;
2210
      gen_call = (name(stare) == general_proc_tag);
2224
      gen_call = (name(stare) == general_proc_tag);
2211
      in_vcallers_proc = (gen_call && proc_has_vcallers(stare));
2225
      in_vcallers_proc = (gen_call && proc_has_vcallers(stare));
2212
      bexp = & son(*e); 
2226
      bexp = & son(*e);
2213
      bat = bexp;
2227
      bat = bexp;
2214
      body = scan (bexp, &bat);
2228
      body = scan(bexp, &bat);
2215
      /* scan the body of the proc */
2229
      /* scan the body of the proc */
2216
      if(gen_call || Has_fp){
2230
      if (gen_call || Has_fp) {
2217
	/* reserve space for the link area */
2231
	/* reserve space for the link area */
2218
	callee_size += 4*PTR_SZ;
2232
	callee_size += 4*PTR_SZ;
2219
      }
2233
      }
2220
#if 0
2234
#if 0
2221
      if(name(stare) == proc_tag && gen_call) {
2235
      if (name(stare) == proc_tag && gen_call) {
2222
	set_proc_has_gen_call(*e);
2236
	set_proc_has_gen_call(*e);
2223
      }
2237
      }
2224
 
2238
 
2225
#endif      
2239
#endif
2226
      if(has_old_varargs){
2240
      if (has_old_varargs) {
2227
	set_has_c_vararg(*e);
2241
	set_has_c_vararg(*e);
2228
	has_old_varargs = 0;
2242
	has_old_varargs = 0;
2229
      }
2243
      }
2230
      if(has_div){
2244
      if (has_div) {
2231
	set_has_machine_division(*e);
2245
	set_has_machine_division(*e);
2232
	has_div = 0;
2246
	has_div = 0;
2233
      }
2247
      }
2234
      if(has_float){
2248
      if (has_float) {
2235
	set_has_float(*e);	/* need to allocate space on stack for 
2249
	set_has_float(*e);	/* need to allocate space on stack for
2236
				   a float <-> int register move */
2250
				   a float <-> int register move */
2237
      }
2251
      }
2238
      return body;	 /*  should never require this in reg in C */
2252
      return body;	 /*  should never require this in reg in C */
2239
    }
2253
    }
2240
    case movecont_tag : {
2254
    case movecont_tag: {
2241
      exp * d = &son(*e);
2255
      exp * d = &son(*e);
2242
      exp * s = & bro(*d);
2256
      exp * s = & bro(*d);
2243
      exp * sz = &bro(*s);
2257
      exp * sz = &bro(*s);
2244
      needs nd;
2258
      needs nd;
2245
      needs ns;
2259
      needs ns;
2246
      needs nsz;
2260
      needs nsz;
2247
      prop prps ;
2261
      prop prps;
2248
      nd = scan(d, at);
2262
      nd = scan(d, at);
2249
      ns = scan (s, at);
2263
      ns = scan(s, at);
2250
      nsz = scan(sz, at);
2264
      nsz = scan(sz, at);
2251
      prps = (ns.propsneeds & hasproccall) << 1;
2265
      prps = (ns.propsneeds & hasproccall) << 1;
2252
      if (ns.fixneeds >= maxfix || prps != 0) {
2266
      if (ns.fixneeds >= maxfix || prps != 0) {
2253
	/* if reg requirements overlap, identify
2267
	/* if reg requirements overlap, identify
2254
	   second operand */
2268
	   second operand */
2255
	cca (at, s); 
2269
	cca(at, s);
2256
	ns = shapeneeds (sh (* (s)));
2270
	ns = shapeneeds(sh(*(s)));
2257
	ns.propsneeds |= morefix;
2271
	ns.propsneeds |= morefix;
2258
	ns.propsneeds &= ~(prps >> 1);
2272
	ns.propsneeds &= ~(prps >> 1);
2259
	ns.propsneeds |= prps;
2273
	ns.propsneeds |= prps;
2260
      }
2274
      }
2261
      nd.fixneeds += 1;
2275
      nd.fixneeds += 1;
2262
      nd = maxneeds (nd, ns); /* ns? */
2276
      nd = maxneeds (nd, ns); /* ns? */
2263
      prps= (nsz.propsneeds & hasproccall) << 1;
2277
      prps= (nsz.propsneeds & hasproccall) << 1;
2264
      if (nd.fixneeds+nsz.fixneeds >= maxfix || prps != 0) {
2278
      if (nd.fixneeds+nsz.fixneeds >= maxfix || prps != 0) {
2265
	/* if reg requirements overlap, identify last operand */
2279
	/* if reg requirements overlap, identify last operand */
2266
	cca (at, sz); 
2280
	cca(at, sz);
2267
	nsz = shapeneeds (sh (* (sz)));
2281
	nsz = shapeneeds(sh(*(sz)));
2268
	nsz.propsneeds |= morefix;
2282
	nsz.propsneeds |= morefix;
2269
	nsz.propsneeds &= ~(prps >> 1);
2283
	nsz.propsneeds &= ~(prps >> 1);
2270
	nsz.propsneeds |= prps;
2284
	nsz.propsneeds |= prps;
2271
      }                
2285
      }
2272
      nd.fixneeds+=1;
2286
      nd.fixneeds+=1;
2273
      nd = maxneeds(nd,nsz);
2287
      nd = maxneeds(nd,nsz);
2274
      if (nd.fixneeds < 4) nd.fixneeds = 3;
2288
      if (nd.fixneeds < 4)nd.fixneeds = 3;
2275
      return nd;
2289
      return nd;
2276
    }
2290
    }
2277
    case trap_tag :
2291
    case trap_tag:
2278
    case special_tag :{
2292
    case special_tag:{
2279
      return zeroneeds;
2293
      return zeroneeds;
2280
    }
2294
    }
2281
    
2295
 
2282
    default: {
2296
    default: {
2283
      printf ("case %d not covered in needs scan\n", name (* e));
2297
      printf("case %d not covered in needs scan\n", name(* e));
2284
      /* NB should call failer */
2298
      /* NB should call failer */
2285
      return zeroneeds;
2299
      return zeroneeds;
2286
    }
2300
    }
2287
  }
2301
  }
2288
}
2302
}