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
Line 166... Line 196...
166
#include "scan2.h"
196
#include "scan2.h"
167
#include "basicread.h"
197
#include "basicread.h"
168
 
198
 
169
/* MACROS */
199
/* MACROS */
170
 
200
 
171
#define assexp(isson, p, v) if (isson) setson(p, v); else setbro(p, v)
201
#define assexp(isson, p, v) if (isson)setson(p, v); else setbro(p, v)
172
#define contexp(isson, p) ((isson) ? son(p) : bro(p))
202
#define contexp(isson, p)((isson)? son(p): bro(p))
173
 
203
 
174
/* PROCEDURES */
204
/* PROCEDURES */
175
 
205
 
176
/* inserts an identity declaration of x at
206
/* inserts an identity declaration of x at
177
   to, and replaces x by a use of the
207
   to, and replaces x by a use of the
178
   identifier */
208
   identifier */
179
static void cca
209
static void cca
180
    PROTO_N ( (sto, to, sx, x) )
-
 
181
    PROTO_T ( int sto X exp to X int sx X exp x )
210
(int sto, exp to, int sx, exp x)
182
{
211
{
183
  exp def, ato, id, tg;
212
  exp def, ato, id, tg;
184
  def = contexp (sx, x);
213
  def = contexp(sx, x);
185
  if (name(def)==caller_tag) {	/* position sensitive */
214
  if (name(def)==caller_tag) {	/* position sensitive */
186
    cca (sto, to, 1, def);
215
    cca(sto, to, 1, def);
187
    return;
216
    return;
188
  }
217
  }
189
  ato = contexp (sto, to);
218
  ato = contexp(sto, to);
190
  id = getexp (sh (ato), bro (ato), (int)(last (ato)), def, nilexp,
219
  id = getexp(sh(ato), bro(ato), (int)(last(ato)), def, nilexp,
191
      0, 1, ident_tag);
220
      0, 1, ident_tag);
192
  tg = getexp (sh (def), bro (def), (int)(last (def)), id, nilexp,
221
  tg = getexp(sh(def), bro(def), (int)(last(def)), id, nilexp,
193
      0, 0, name_tag);
222
      0, 0, name_tag);
194
  pt (id) = tg;
223
  pt(id) = tg;
195
  clearlast (def);
224
  clearlast(def);
196
  if (def != ato) {
225
  if (def != ato) {
197
    bro (def) = ato;
226
    bro(def) = ato;
198
    bro (ato) = id;
227
    bro(ato) = id;
199
    setlast (ato);
228
    setlast(ato);
200
    assexp (sto, to, id);
229
    assexp(sto, to, id);
201
    assexp (sx, x, tg);
230
    assexp(sx, x, tg);
202
  }
231
  }
203
  else {
232
  else {
204
    bro (def) = tg;
233
    bro(def) = tg;
205
    bro (tg) = id;
234
    bro(tg) = id;
206
    setlast (tg);
235
    setlast(tg);
207
    clearlast (def);
236
    clearlast(def);
208
    assexp (sto, to, id);
237
    assexp(sto, to, id);
209
  };
238
  };
210
#ifdef NEWDIAGS
239
#ifdef NEWDIAGS
211
  if (diagnose) {
240
  if (diagnose) {
212
    dgf(id) = dgf(bro(son(id)));
241
    dgf(id) = dgf(bro(son(id)));
213
    dgf(bro(son(id))) = nildiag;
242
    dgf(bro(son(id))) = nildiag;
Line 233... Line 262...
233
   precomputed in reg0 before the
262
   precomputed in reg0 before the
234
   operations. This boolean result is used
263
   operations. This boolean result is used
235
   to ensure that not more than one
264
   to ensure that not more than one
236
   operand is so treated */
265
   operand is so treated */
237
static int cc
266
static int cc
238
    PROTO_N ( (sto, to, se, e, doit, count, usereg0) )
-
 
239
    PROTO_T ( int sto X exp to X int se X exp e X
-
 
240
	      int (*doit) PROTO_S ((exp, int, int )) X
267
(int sto, exp to, int se, exp e,	      int(*doit)(exp, int, int),
241
	      int count X int usereg0 )
268
 int count, int usereg0)
242
{
269
{
243
  int unused = usereg0;	/* can still use reg0 */
270
  int unused = usereg0;	/* can still use reg0 */
244
  exp ec = contexp (se, e);
271
  exp ec = contexp(se, e);
245
  if (last (ec)) {
272
  if (last(ec)) {
246
    if (doit (ec, count, unused)) {
273
    if (doit(ec, count, unused)) {
247
      cca (sto, to, se, e);
274
      cca(sto, to, se, e);
248
      ec = contexp (sto, to);
275
      ec = contexp(sto, to);
249
      return (scan2 (1, ec, son (ec), unused));
276
      return(scan2(1, ec, son(ec), unused));
250
    }
277
    }
251
    else {
278
    else {
252
      if (unused)
279
      if (unused)
253
	return (scan2 (se, e, ec, 1));
280
	return(scan2(se, e, ec, 1));
254
      return (scan2 (sto, to, ec, unused));
281
      return(scan2(sto, to, ec, unused));
255
    }
282
    }
256
  }
283
  }
257
  else {
284
  else {
258
    unused = cc (sto, to, 0, ec, doit, count + 1, unused);
285
    unused = cc(sto, to, 0, ec, doit, count + 1, unused);
259
    /* can we still use reg0? */
286
    /* can we still use reg0? */
260
    ec = contexp (se, e);
287
    ec = contexp(se, e);
261
    if (doit (ec, count, unused)) {
288
    if (doit(ec, count, unused)) {
262
      cca (sto, to, se, e);
289
      cca(sto, to, se, e);
263
      ec = contexp (sto, to);
290
      ec = contexp(sto, to);
264
      return (scan2 (1, ec, son (ec), unused));
291
      return(scan2(1, ec, son(ec), unused));
265
    }
292
    }
266
    else {
293
    else {
267
      if (unused)
294
      if (unused)
268
	return (scan2 (sto, to, ec, 1));
295
	return(scan2(sto, to, ec, 1));
269
      return (scan2 (sto, to, ec, unused));
296
      return(scan2(sto, to, ec, unused));
270
    };
297
    };
271
  };
298
  };
272
}
299
}
273
 
300
 
274
/* keeping the same to, scans along the
301
/* keeping the same to, scans along the
Line 282... Line 309...
282
   element, still using the same to. This
309
   element, still using the same to. This
283
   keeps all operations in the same order.
310
   keeps all operations in the same order.
284
   The difference in detail from cc supports
311
   The difference in detail from cc supports
285
   the asymmetry of div etc */
312
   the asymmetry of div etc */
286
static void cc1
313
static void cc1
287
    PROTO_N ( (sto, to, se, e, doit, count, usereg0) )
-
 
288
    PROTO_T ( int sto X exp to X int se X exp e X
-
 
289
	      int (*doit) PROTO_S ((exp, int, int)) X
314
(int sto, exp to, int se, exp e,	      int(*doit)(exp, int, int),
290
	      int count X int usereg0 )
315
 int count, int usereg0)
291
{
316
{
292
  int unused = ((count == 1) ? usereg0 : 0);
317
  int unused = ((count == 1)? usereg0 : 0);
293
	/* can we still use reg0? */
318
	/* can we still use reg0? */
294
  exp ec = contexp (se, e);
319
  exp ec = contexp(se, e);
295
  if (last (ec)) {
320
  if (last(ec)) {
296
    if (doit (ec, count, unused)) {
321
    if (doit(ec, count, unused)) {
297
      cca (sto, to, se, e);
322
      cca(sto, to, se, e);
298
      ec = contexp (sto, to);
323
      ec = contexp(sto, to);
299
      IGNORE scan2 (1, ec, son (ec), unused);
324
      IGNORE scan2(1, ec, son(ec), unused);
300
      return;
325
      return;
301
    }
326
    }
302
    else {
327
    else {
303
      if (unused)  {
328
      if (unused) {
304
	IGNORE scan2 (se, e, ec, 1);
329
	IGNORE scan2(se, e, ec, 1);
305
        return;
330
        return;
306
      };
331
      };
307
      IGNORE scan2 (sto, to, ec, unused);
332
      IGNORE scan2(sto, to, ec, unused);
308
      return;
333
      return;
309
    }
334
    }
310
  }
335
  }
311
  else {
336
  else {
312
    cc1 (sto, to, 0, ec, doit, count + 1, unused);
337
    cc1(sto, to, 0, ec, doit, count + 1, unused);
313
    /* can we still use reg0? */
338
    /* can we still use reg0? */
314
    ec = contexp (se, e);
339
    ec = contexp(se, e);
315
    if (doit (ec, count, unused)) {
340
    if (doit(ec, count, unused)) {
316
      cca (sto, to, se, e);
341
      cca(sto, to, se, e);
317
      ec = contexp (sto, to);
342
      ec = contexp(sto, to);
318
      IGNORE scan2 (1, ec, son (ec), unused);
343
      IGNORE scan2(1, ec, son(ec), unused);
319
      return;
344
      return;
320
    }
345
    }
321
    else {
346
    else {
322
      if (unused)  {
347
      if (unused) {
323
	IGNORE scan2 (se, e, ec, 1);
348
	IGNORE scan2(se, e, ec, 1);
324
	return;
349
	return;
325
      };
350
      };
326
      IGNORE scan2 (sto, to, ec, unused);
351
      IGNORE scan2(sto, to, ec, unused);
327
      return;
352
      return;
328
    };
353
    };
329
  };
354
  };
330
}
355
}
331
 
356
 
332
 
357
 
333
/* does cca and forces the declaration to use a register */
358
/* does cca and forces the declaration to use a register */
334
static void ccp
359
static void ccp
335
    PROTO_N ( (sto, to, sx, x) )
-
 
336
    PROTO_T ( int sto X exp to X int sx X exp x )
360
(int sto, exp to, int sx, exp x)
337
{
361
{
338
  exp toc;
362
  exp toc;
339
  cca (sto, to, sx, x);
363
  cca(sto, to, sx, x);
340
  toc = contexp (sto, to);
364
  toc = contexp(sto, to);
341
  setusereg (toc);
365
  setusereg(toc);
342
  IGNORE scan2 (1, toc, son (toc), 0);
366
  IGNORE scan2(1, toc, son(toc), 0);
343
  return;
367
  return;
344
}
368
}
345
 
369
 
346
/* is an operand */
370
/* is an operand */
347
static int is_opnd
371
static int is_opnd
348
    PROTO_N ( (e) )
-
 
349
    PROTO_T ( exp e )
372
(exp e)
350
{
373
{
351
				/* make sure (is_o && is_crc -> !is_opnd) */
374
				/* make sure (is_o && is_crc -> !is_opnd) */
352
  unsigned char  n = name (e);
375
  unsigned char  n = name(e);
353
  if (n == name_tag) {
376
  if (n == name_tag) {
354
    if (isvar(son(e)))
377
    if (isvar(son(e)))
355
	return (isglob(son(e)) && !PIC_code);
378
	return(isglob(son(e)) && !PIC_code);
356
    return (son(son(e)) != nilexp &&
379
    return(son(son(e))!= nilexp &&
357
	(!isglob(son(e)) || !PIC_code || name(sh(son(e))) != prokhd ||
380
	(!isglob(son(e)) || !PIC_code || name(sh(son(e)))!= prokhd ||
358
				(brog(son(e)) -> dec_u.dec_val.extnamed)) &&
381
				(brog(son(e)) -> dec_u.dec_val.extnamed)) &&
359
	(name(son(son(e))) != ident_tag || !isparam(son(son(e))) ));
382
	(name(son(son(e)))!= ident_tag || !isparam(son(son(e)))));
360
  }
383
  }
361
  return (
384
  return(
362
      n == val_tag || n == real_tag || n == env_size_tag ||
385
      n == val_tag || n == real_tag || n == env_size_tag ||
363
      n == cont_tag ||
386
      n == cont_tag ||
364
      n == string_tag ||
387
      n == string_tag ||
365
      n == null_tag ||
388
      n == null_tag ||
366
      n == proc_tag || n == general_proc_tag);
389
      n == proc_tag || n == general_proc_tag);
Line 378... Line 401...
378
   This guarantees that we only load the
401
   This guarantees that we only load the
379
   registers as close to the actual
402
   registers as close to the actual
380
   instruction as possible, since we are
403
   instruction as possible, since we are
381
   short of registers on the 80386 */
404
   short of registers on the 80386 */
382
static void ap_argsc
405
static void ap_argsc
383
    PROTO_N ( (sto, to, e) )
-
 
384
    PROTO_T ( int sto X exp to X exp e )
406
(int sto, exp to, exp e)
385
{
407
{
386
  exp p, a, q;
408
  exp p, a, q;
387
  int  k;
409
  int  k;
388
  int do1 = 1;
410
  int do1 = 1;
389
 
411
 
390
  if (name (son (e)) == reff_tag)
412
  if (name(son(e)) == reff_tag)
391
    q = son (son (e));
413
    q = son(son(e));
392
  else
414
  else
393
    q = son (e);		/* q must be addptr - all addptrs processed here */
415
    q = son (e);		/* q must be addptr - all addptrs processed here */
394
 
416
 
395
  if ((frame_al_of_ptr(sh(son(q))) & al_includes_vcallees) &&
417
  if ((frame_al_of_ptr(sh(son(q))) & al_includes_vcallees) &&
396
	(frame_al1_of_offset(sh(bro(son(q)))) & al_includes_caller_args)) {
418
	(frame_al1_of_offset(sh(bro(son(q)))) & al_includes_caller_args)) {
397
				/* env_offset to arg requires indirection from
419
				/* env_offset to arg requires indirection from
398
				   frame pointer */
420
				   frame pointer */
399
    shape pc_sh = f_pointer(f_callers_alignment(0));
421
    shape pc_sh = f_pointer(f_callers_alignment(0));
400
    exp c = getexp (pc_sh, bro(son(q)), 0, nilexp, nilexp, 0, 0, cont_tag);
422
    exp c = getexp(pc_sh, bro(son(q)), 0, nilexp, nilexp, 0, 0, cont_tag);
401
    exp r = getexp (pc_sh, c, 1, son(q), nilexp, 0, 64, reff_tag);
423
    exp r = getexp(pc_sh, c, 1, son(q), nilexp, 0, 64, reff_tag);
402
    setfather (r, son(q));
424
    setfather(r, son(q));
403
    son(c) = r;
425
    son(c) = r;
404
    son(q) = c;
426
    son(q) = c;
405
  }
427
  }
406
 
428
 
407
  p = son (q);
429
  p = son(q);
408
  a = bro (p);
430
  a = bro(p);
409
 
431
 
410
  if (name (p) == name_tag && isvar (son (p)) && isglob (son (p)))
432
  if (name(p) == name_tag && isvar(son(p)) && isglob(son(p)))
411
    do1 = 0;
433
    do1 = 0;
412
 
434
 
413
  if (do1)
435
  if (do1)
414
    ccp (1, e, 1, q);
436
    ccp(1, e, 1, q);
415
 
437
 
416
  if (name (a) == offset_mult_tag && name (bro (son (a))) == val_tag &&
438
  if (name(a) == offset_mult_tag && name(bro(son(a))) == val_tag &&
417
      (k = no (bro (son (a))), k == 8 || k == 16 || k == 32 || k == 64))
439
  (k = no(bro(son(a))), k == 8 || k == 16 || k == 32 || k == 64))
418
    ccp (1, e, 1, bro (son (q)));
440
    ccp(1, e, 1, bro(son(q)));
419
  else
441
  else
420
    ccp (1, e, 0, son (q));
442
    ccp(1, e, 0, son(q));
421
 
443
 
422
  if (do1) {
444
  if (do1) {
423
    cca (sto, to, 1, son (e));
445
    cca(sto, to, 1, son(e));
424
    cca (sto, to, 1, bro (son (son (e))));
446
    cca(sto, to, 1, bro(son(son(e))));
425
  }
447
  }
426
  else
448
  else
427
    cca (sto, to, 1, son (e));
449
    cca(sto, to, 1, son(e));
428
 
450
 
429
  return;
451
  return;
430
 
452
 
431
}
453
}
432
 
454
 
Line 443... Line 465...
443
   instructions that use them, since we
465
   instructions that use them, since we
444
   are short of registers in the 80386.
466
   are short of registers in the 80386.
445
   This is done by contop in instr386, during
467
   This is done by contop in instr386, during
446
   the code production. */
468
   the code production. */
447
static int cont_arg
469
static int cont_arg
448
    PROTO_N ( (sto, to, e, usereg0) )
-
 
449
    PROTO_T ( int sto X exp to X exp e X int usereg0 )
470
(int sto, exp to, exp e, int usereg0)
450
{
471
{
451
  unsigned char  n = name (son (e));
472
  unsigned char  n = name(son(e));
452
 
473
 
453
 
474
 
454
    if (n == name_tag && isvar (son (son (e))))
475
    if (n == name_tag && isvar(son(son(e))))
455
      return usereg0;
476
      return usereg0;
456
 
477
 
457
    if (n == cont_tag && usereg0 && shape_size(sh(e)) <= 32) {
478
    if (n == cont_tag && usereg0 && shape_size(sh(e)) <= 32) {
458
      cont_arg(sto, to, son(e), 1);
479
      cont_arg(sto, to, son(e), 1);
459
      return 0;
480
      return 0;
460
    }
481
    }
461
 
482
 
462
    if (n == reff_tag) {
483
    if (n == reff_tag) {
463
      exp s = son (son (e));
484
      exp s = son(son(e));
464
      if (name (s) == name_tag)  {
485
      if (name(s) == name_tag) {
465
	if (isusereg (son (s)))
486
	if (isusereg(son(s)))
466
          return 0;
487
          return 0;
467
        if (!PIC_code && isglob(son(s)) && isvar(son(s)))
488
        if (!PIC_code && isglob(son(s)) && isvar(son(s)))
468
          return 0;
489
          return 0;
469
      };
490
      };
470
 
491
 
471
      if (name(s) == cont_tag && usereg0 && shape_size(sh(e)) <= 32) {
492
      if (name(s) == cont_tag && usereg0 && shape_size(sh(e)) <= 32) {
472
	cont_arg(sto, to, s, 1);
493
	cont_arg(sto, to, s, 1);
473
	return 0;
494
	return 0;
474
      }
495
      }
475
 
496
 
476
      if (name (s) == addptr_tag) {
497
      if (name(s) == addptr_tag) {
477
	ap_argsc (sto, to, e);
498
	ap_argsc(sto, to, e);
478
	return 0;
499
	return 0;
479
      }
500
      }
480
    };
501
    };
481
 
502
 
482
 
503
 
483
    if (n == addptr_tag) {
504
    if (n == addptr_tag) {
484
      ap_argsc (sto, to, e);
505
      ap_argsc(sto, to, e);
485
      return 0;
506
      return 0;
486
    };
507
    };
487
 
508
 
488
  if (n == reff_tag)
509
  if (n == reff_tag)
489
    ccp (1, e, 1, son (e));
510
    ccp(1, e, 1, son(e));
490
  else
511
  else
491
    ccp (1, e, 1, e);
512
    ccp(1, e, 1, e);
492
 
513
 
493
  cca (sto, to, 1, son (e));
514
  cca(sto, to, 1, son(e));
494
 
515
 
495
  return 0;
516
  return 0;
496
}
517
}
497
 
518
 
498
 
519
 
499
/* is assignable */
520
/* is assignable */
500
static int is_assable
521
static int is_assable
501
    PROTO_N ( (e) )
-
 
502
    PROTO_T ( exp e )
522
(exp e)
503
{
523
{
504
  return (is_a (name (e)) || name(e) == alloca_tag ||
524
  return(is_a(name(e)) || name(e) == alloca_tag ||
505
	 ((name (e) == apply_tag || name (e) == apply_general_tag) &&
525
	((name(e) == apply_tag || name(e) == apply_general_tag) &&
506
	(name (sh (e)) <= ulonghd || name (sh (e)) == ptrhd)));
526
	(name(sh(e)) <= ulonghd || name(sh(e)) == ptrhd)));
507
}
527
}
508
 
528
 
509
/* doit routine, is not an operand */
529
/* doit routine, is not an operand */
510
static int notopnd
530
static int notopnd
511
    PROTO_N ( (t, c, usereg0) )
-
 
512
    PROTO_T ( exp t X int c X int usereg0 )
531
(exp t, int c, int usereg0)
513
{
532
{
514
  UNUSED(c);
533
  UNUSED(c);
515
  if (usereg0) {
534
  if (usereg0) {
516
    if (is_opnd (t))
535
    if (is_opnd(t))
517
      return (0);
536
      return(0);
518
    return (!is_assable (t));
537
    return(!is_assable(t));
519
  };
538
  };
520
  return (!is_opnd (t));
539
  return(!is_opnd(t));
521
}
540
}
522
 
541
 
523
static int scan_for_alloca PROTO_S ((exp));
542
static int scan_for_alloca(exp);
524
 
543
 
525
static int scan_alloc_args
544
static int scan_alloc_args
526
    PROTO_N ( (s) )
-
 
527
    PROTO_T ( exp s )
545
(exp s)
528
{
546
{
529
  if (scan_for_alloca(s))
547
  if (scan_for_alloca(s))
530
    return 1;
548
    return 1;
531
  if (last(s))
549
  if (last(s))
532
    return 0;
550
    return 0;
533
  return scan_alloc_args(bro(s));
551
  return scan_alloc_args(bro(s));
534
}
552
}
535
 
553
 
536
static int scan_for_alloca
554
static int scan_for_alloca
537
    PROTO_N ( (t) )
-
 
538
    PROTO_T ( exp t )
555
(exp t)
539
{
556
{
540
  switch (name(t)) {
557
  switch (name(t)) {
541
    case local_free_all_tag:
558
    case local_free_all_tag:
542
    case local_free_tag:
559
    case local_free_tag:
543
    case last_local_tag:
560
    case last_local_tag:
Line 562... Line 579...
562
      return scan_alloc_args(son(t));
579
      return scan_alloc_args(son(t));
563
  };
580
  };
564
}
581
}
565
 
582
 
566
static int no_alloca
583
static int no_alloca
567
    PROTO_N ( (t, c, usereg0) )
-
 
568
    PROTO_T ( exp t X int c X int usereg0 )
584
(exp t, int c, int usereg0)
569
{
585
{
570
  UNUSED(c); UNUSED(usereg0);
586
  UNUSED(c); UNUSED(usereg0);
571
  return scan_for_alloca(t);
587
  return scan_for_alloca(t);
572
}
588
}
573
 
589
 
574
/* uses cc, requiring all to be operands */
590
/* uses cc, requiring all to be operands */
575
static void all_opnd
591
static void all_opnd
576
    PROTO_N ( (sto, to, e, usereg0) )
-
 
577
    PROTO_T ( int sto X exp to X exp e X int usereg0 )
592
(int sto, exp to, exp e, int usereg0)
578
{
593
{
579
  IGNORE cc (sto, to, 1, e, notopnd, 1, usereg0);
594
  IGNORE cc(sto, to, 1, e, notopnd, 1, usereg0);
580
  return;
595
  return;
581
}
596
}
582
 
597
 
583
/* doit routine, not assignable */
598
/* doit routine, not assignable */
584
static int notass
599
static int notass
585
    PROTO_N ( (t, i, usereg0) )
-
 
586
    PROTO_T ( exp t X int i X int usereg0 )
600
(exp t, int i, int usereg0)
587
{
601
{
588
  UNUSED(i); UNUSED(usereg0);
602
  UNUSED(i); UNUSED(usereg0);
589
  return (!is_assable (t));
603
  return(!is_assable(t));
590
}
604
}
591
 
605
 
592
/* uses cc, requiring all to be assignable */
606
/* uses cc, requiring all to be assignable */
593
static void all_assable
607
static void all_assable
594
    PROTO_N ( (sto, to, e) )
-
 
595
    PROTO_T ( int sto X exp to X exp e )
608
(int sto, exp to, exp e)
596
{
609
{
597
  IGNORE cc (sto, to, 1, e, notass, 1, 1);
610
  IGNORE cc(sto, to, 1, e, notass, 1, 1);
598
  return;
611
  return;
599
}
612
}
600
 
613
 
601
/* just used in the next routine */
614
/* just used in the next routine */
602
static int is_direct
615
static int is_direct
603
    PROTO_N ( (e) )
-
 
604
    PROTO_T ( exp e )
616
(exp e)
605
{
617
{
606
  unsigned char  s = name (e);
618
  unsigned char  s = name(e);
607
  return ((s == name_tag && !isglob (son (e)) && !isvar (son (e))) ||
619
  return((s == name_tag && !isglob(son(e)) && !isvar(son(e))) ||
608
      (s == cont_tag && name (son (e)) == name_tag &&
620
  (s == cont_tag && name(son(e)) == name_tag &&
609
	!isglob (son (son (e))) && isvar (son (son (e)))));
621
	!isglob(son(son(e))) && isvar(son(son(e)))));
610
}
622
}
611
 
623
 
612
/* is indirectly addressable */
624
/* is indirectly addressable */
613
static int is_indable
625
static int is_indable
614
    PROTO_N ( (e) )
-
 
615
    PROTO_T ( exp e )
626
(exp e)
616
{
627
{
617
  unsigned char  s = name (e);
628
  unsigned char  s = name(e);
618
  if (s == name_tag)
629
  if (s == name_tag)
619
    return (1);
630
    return(1);
620
 
631
 
621
  if (s == cont_tag) {
632
  if (s == cont_tag) {
622
    unsigned char  t = name (son (e));
633
    unsigned char  t = name(son(e));
623
    return ((t == name_tag && isvar (son (son (e)))) ||
634
    return((t == name_tag && isvar(son(son(e)))) ||
624
	(t == cont_tag && name (son (son (e))) == name_tag &&
635
	(t == cont_tag && name(son(son(e))) == name_tag &&
625
	  isvar (son (son (son (e))))) ||
636
	  isvar(son(son(son(e))))) ||
626
	(t == reff_tag && is_direct (son (son (e)))));
637
	(t == reff_tag && is_direct(son(son(e)))));
627
  };
638
  };
628
 
639
 
629
  return ((s == reff_tag && is_direct (son (e))) ||
640
  return((s == reff_tag && is_direct(son(e))) ||
630
 
641
 
631
      s == addptr_tag);
642
      s == addptr_tag);
632
}
643
}
633
 
644
 
634
 
645
 
635
/* son must be indirectly addressable */
646
/* son must be indirectly addressable */
636
static void indable_son
647
static void indable_son
637
    PROTO_N ( (sto, to, e) )
-
 
638
    PROTO_T ( int sto X exp to X exp e )
648
(int sto, exp to, exp e)
639
{
649
{
640
  if (!is_indable (son (e))) {
650
  if (!is_indable(son(e))) {
641
    exp ec;
651
    exp ec;
642
    cca (sto, to, 1, e);
652
    cca(sto, to, 1, e);
643
    ec = contexp (sto, to);
653
    ec = contexp(sto, to);
644
    IGNORE scan2 (1, ec, son (ec), 0);
654
    IGNORE scan2(1, ec, son(ec), 0);
645
  }
655
  }
646
  else
656
  else
647
    IGNORE scan2 (sto, to, son (e), 0);
657
    IGNORE scan2(sto, to, son(e), 0);
648
  return;
658
  return;
649
}
659
}
650
 
660
 
651
 
661
 
652
 
662
 
653
/* apply scan2 to this bro list, moving "to" along it */
663
/* apply scan2 to this bro list, moving "to" along it */
654
static void scanargs
664
static void scanargs
655
    PROTO_N ( (st, e, usereg0) )
-
 
656
    PROTO_T ( int st X exp e X int usereg0 )
665
(int st, exp e, int usereg0)
657
{
666
{
658
  exp t = e;
667
  exp t = e;
659
  exp temp;
668
  exp temp;
660
 
669
 
661
  while (temp = contexp (st, t), IGNORE scan2 (st, t, temp, usereg0),
670
  while (temp = contexp(st, t), IGNORE scan2(st, t, temp, usereg0),
662
      temp = contexp (st, t), !last (temp)) {
671
      temp = contexp(st, t), !last(temp)) {
663
    t = contexp (st, t);
672
    t = contexp(st, t);
664
    st = 0;
673
    st = 0;
665
  };
674
  };
666
  return;
675
  return;
667
}
676
}
668
 
677
 
669
 
678
 
670
 
679
 
671
/* doit routine for plus first arg cant be negate, others can */
680
/* doit routine for plus first arg cant be negate, others can */
672
static int plusdo
681
static int plusdo
673
    PROTO_N ( (t, i, usereg0) )
-
 
674
    PROTO_T ( exp t X int i X int usereg0 )
682
(exp t, int i, int usereg0)
675
{
683
{
676
  UNUSED(i);
684
  UNUSED(i);
677
  if (usereg0)
685
  if (usereg0)
678
    return (0);
686
    return(0);
679
  if (name (t) == neg_tag)
687
  if (name(t) == neg_tag)
680
    return (0);
688
    return(0);
681
  return (!is_opnd (t));
689
  return(!is_opnd(t));
682
}
690
}
683
 
691
 
684
/* doit routine for mult */
692
/* doit routine for mult */
685
static int multdo
693
static int multdo
686
    PROTO_N ( (t, i, usereg0) )
-
 
687
    PROTO_T ( exp t X int i X int usereg0 )
694
(exp t, int i, int usereg0)
688
{
695
{
689
  UNUSED(i);
696
  UNUSED(i);
690
  return ((usereg0) ? 0 : !is_opnd (t));
697
  return((usereg0)? 0 : !is_opnd(t));
691
}
698
}
692
 
699
 
693
/* doit routine for and */
700
/* doit routine for and */
694
static int anddo
701
static int anddo
695
    PROTO_N ( (t, i, usereg0) )
-
 
696
    PROTO_T ( exp t X int i X int usereg0 )
702
(exp t, int i, int usereg0)
697
{
703
{
698
  UNUSED(i);
704
  UNUSED(i);
699
  return ((usereg0) ? 0 : !is_opnd (t));
705
  return((usereg0)? 0 : !is_opnd(t));
700
}
706
}
701
 
707
 
702
/* doit routine for xor */
708
/* doit routine for xor */
703
static int notado
709
static int notado
704
    PROTO_N ( (t, i, usereg0) )
-
 
705
    PROTO_T ( exp t X int i X int usereg0 )
710
(exp t, int i, int usereg0)
706
{
711
{
707
  UNUSED(i);
712
  UNUSED(i);
708
  return ((usereg0) ? 0 : !is_opnd (t));
713
  return((usereg0)? 0 : !is_opnd(t));
709
}
714
}
710
 
715
 
711
/* change offset representation bytes to bits */
716
/* change offset representation bytes to bits */
712
static void make_bitfield_offset
717
static void make_bitfield_offset
713
    PROTO_N ( (e, pe, spe, sha) )
-
 
714
    PROTO_T ( exp e X exp pe X int spe X shape sha )
718
(exp e, exp pe, int spe, shape sha)
715
{
719
{
716
  exp omul;
720
  exp omul;
717
  exp val8;
721
  exp val8;
718
  if (name(e) == val_tag)
722
  if (name(e) == val_tag)
719
    return;
723
    return;
720
  omul = getexp (sha, bro(e), (int)(last (e)), e, nilexp, 0, 0, offset_mult_tag);
724
  omul = getexp(sha, bro(e), (int)(last(e)), e, nilexp, 0, 0, offset_mult_tag);
721
  val8 = getexp (slongsh, omul, 1, nilexp, nilexp, 0, 8, val_tag);
725
  val8 = getexp(slongsh, omul, 1, nilexp, nilexp, 0, 8, val_tag);
722
  clearlast(e);
726
  clearlast(e);
723
  setbro(e, val8);
727
  setbro(e, val8);
724
  assexp(spe, pe, omul);
728
  assexp(spe, pe, omul);
725
}
729
}
726
 
730
 
727
static void scan_apply_args
731
static void scan_apply_args
728
    PROTO_N ( (spto, pto, sato, ato) )
-
 
729
    PROTO_T ( int spto X exp pto X int sato X exp ato )
732
(int spto, exp pto, int sato, exp ato)
730
{
733
{
731
  if (scan_alloc_args (contexp (sato, ato)))
734
  if (scan_alloc_args(contexp(sato, ato)))
732
    IGNORE cc (spto, pto, sato, ato, no_alloca, 1, 0);
735
    IGNORE cc(spto, pto, sato, ato, no_alloca, 1, 0);
733
  else
736
  else
734
    IGNORE scanargs(sato, ato, 1);
737
    IGNORE scanargs(sato, ato, 1);
735
}
738
}
736
 
739
 
737
/* avoid registers corrupted by dynamic callees */
740
/* avoid registers corrupted by dynamic callees */
738
static void cca_for_cees
741
static void cca_for_cees
739
    PROTO_N ( (sto, to, e) )
-
 
740
    PROTO_T ( int sto X exp to X exp e )
742
(int sto, exp to, exp e)
741
{
743
{
742
  if (name(son(e)) == name_tag) {
744
  if (name(son(e)) == name_tag) {
743
    if (!isglob (son(son(e))))
745
    if (!isglob(son(son(e))))
744
      set_intnl_call (son(son(e)));
746
      set_intnl_call(son(son(e)));
745
    return;
747
    return;
746
  }
748
  }
747
  if (name(son(e)) == cont_tag && name(son(son(e))) == name_tag) {
749
  if (name(son(e)) == cont_tag && name(son(son(e))) == name_tag) {
748
    if (!isglob (son(son(son(e)))))
750
    if (!isglob(son(son(son(e)))))
749
      set_intnl_call (son(son(son(e))));
751
      set_intnl_call(son(son(son(e))));
750
    return;
752
    return;
751
  }
753
  }
752
  cca (sto, to, 1, e);
754
  cca(sto, to, 1, e);
753
  set_intnl_call (contexp (sto, to));
755
  set_intnl_call(contexp(sto, to));
754
}
756
}
755
 
757
 
756
 
758
 
757
static int is_asm_opnd
759
static int is_asm_opnd
758
    PROTO_N ( (e, ext) )
-
 
759
    PROTO_T ( exp e X int ext )
760
(exp e, int ext)
760
{
761
{
761
  unsigned char n = name (e);
762
  unsigned char n = name(e);
762
  if (n == name_tag) {
763
  if (n == name_tag) {
763
    setvis (son(e));
764
    setvis(son(e));
764
    return 1;
765
    return 1;
765
  }
766
  }
766
  if (n == cont_tag && name(son(e)) == name_tag && isvar(son(son(e)))) {
767
  if (n == cont_tag && name(son(e)) == name_tag && isvar(son(son(e)))) {
767
    setvis (son(son(e)));
768
    setvis(son(son(e)));
768
    return 1;
769
    return 1;
769
  }
770
  }
770
  return (n == val_tag || n == real_tag || n == null_tag ||
771
  return(n == val_tag || n == real_tag || n == null_tag ||
771
	(n == reff_tag && name(son(e)) == name_tag));
772
	(n == reff_tag && name(son(e)) == name_tag));
772
}
773
}
773
 
774
 
774
static int is_asm_var
775
static int is_asm_var
775
    PROTO_N ( (e, ext) )
-
 
776
    PROTO_T ( exp e X int ext )
776
(exp e, int ext)
777
{
777
{
778
  unsigned char n = name (e);
778
  unsigned char n = name(e);
779
  if (n == name_tag && isvar(son(e))) {
779
  if (n == name_tag && isvar(son(e))) {
780
    setvis (son(e));
780
    setvis(son(e));
781
    return 1;
781
    return 1;
782
  }
782
  }
783
  return 0;
783
  return 0;
784
}
784
}
785
 
785
 
786
void check_asm_seq
786
void check_asm_seq
787
    PROTO_N ( (e, ext) )
-
 
788
    PROTO_T ( exp e X int ext )
787
(exp e, int ext)
789
{
788
{
790
  if (name(e) == asm_tag) {
789
  if (name(e) == asm_tag) {
791
    if ((asm_string(e) && name(son(e)) == string_tag) ||
790
    if ((asm_string(e) && name(son(e)) == string_tag) ||
792
	(asm_in(e) && is_asm_opnd(son(e), ext)) ||
791
	(asm_in(e) && is_asm_opnd(son(e), ext)) ||
793
	(asm_var(e) && is_asm_var(son(e), ext)) )
792
	(asm_var(e) && is_asm_var(son(e), ext)))
794
      return;
793
      return;
795
  }
794
  }
796
  if (name(e) == seq_tag) {
795
  if (name(e) == seq_tag) {
797
    exp t = son(son(e));
796
    exp t = son(son(e));
798
    for (;;) {
797
    for (;;) {
799
      check_asm_seq (t, ext);
798
      check_asm_seq(t, ext);
800
      if (last(t))
799
      if (last(t))
801
	break;
800
	break;
802
      t = bro(t);
801
      t = bro(t);
803
    }
802
    }
804
    check_asm_seq (bro(son(e)), ext);
803
    check_asm_seq(bro(son(e)), ext);
805
  }
804
  }
806
  else
805
  else
807
  if (name(e) != top_tag)
806
  if (name(e)!= top_tag)
808
    failer ("illegal ~asm");
807
    failer("illegal ~asm");
809
  return;
808
  return;
810
}
809
}
811
 
810
 
812
 
811
 
813
 
812
 
814
/* main scan routine */
813
/* main scan routine */
815
int scan2
814
int scan2
816
    PROTO_N ( (sto, to, e, usereg0) )
-
 
817
    PROTO_T ( int sto X exp to X exp e X int usereg0 )
815
(int sto, exp to, exp e, int usereg0)
818
{
816
{
819
  switch (name (e)) {
817
  switch (name(e)) {
820
    case prof_tag:
818
    case prof_tag:
821
	return 0;
819
	return 0;
822
    case cond_tag:
820
    case cond_tag:
823
    case rep_tag:
821
    case rep_tag:
824
    case compound_tag:
822
    case compound_tag:
Line 830... Line 828...
830
    case diagnose_tag:
828
    case diagnose_tag:
831
#endif
829
#endif
832
    case caller_tag:
830
    case caller_tag:
833
      {
831
      {
834
	if (son(e) == nilexp) /* empty make_nof */
832
	if (son(e) == nilexp) /* empty make_nof */
835
	  return (0);
833
	  return(0);
836
	scanargs (1, e, 1);
834
	scanargs(1, e, 1);
837
	return (0);
835
	return(0);
838
      };
836
      };
839
 
837
 
840
    case labst_tag:
838
    case labst_tag:
841
      {
839
      {
842
	IGNORE scan2 (0, son (e), bro (son (e)), 1);
840
	IGNORE scan2(0, son(e), bro(son(e)), 1);
843
	return (0);
841
	return(0);
844
      };
842
      };
845
    case ident_tag:
843
    case ident_tag:
846
      {
844
      {
847
	IGNORE scan2 (0, son (e), bro (son (e)), 0);
845
	IGNORE scan2(0, son(e), bro(son(e)), 0);
848
	IGNORE scan2 (1, e, son (e), 0);
846
	IGNORE scan2(1, e, son(e), 0);
849
	return (0);
847
	return(0);
850
      };
848
      };
851
    case seq_tag:
849
    case seq_tag:
852
      {
850
      {
853
	scanargs (1, son (e), 1);
851
	scanargs(1, son(e), 1);
854
	IGNORE scan2 (0, son (e), bro (son (e)), 1);
852
	IGNORE scan2(0, son(e), bro(son(e)), 1);
855
	return (0);
853
	return(0);
856
      };
854
      };
857
 
855
 
858
    case local_free_tag:
856
    case local_free_tag:
859
    case long_jump_tag:
857
    case long_jump_tag:
860
    case return_to_label_tag:
858
    case return_to_label_tag:
861
      {
859
      {
862
	all_assable (sto, to, e);
860
	all_assable(sto, to, e);
863
	return (0);
861
	return(0);
864
      };
862
      };
865
 
863
 
866
    case offset_add_tag:
864
    case offset_add_tag:
867
    case offset_subtract_tag:
865
    case offset_subtract_tag:
868
      {
866
      {
869
	if (al2(sh(son(e))) == 1 && al2(sh(bro(son(e)))) != 1)
867
	if (al2(sh(son(e))) == 1 && al2(sh(bro(son(e))))!= 1)
870
	  make_bitfield_offset (bro(son(e)), son(e), 0, sh(e));
868
	  make_bitfield_offset(bro(son(e)), son(e), 0, sh(e));
871
	if (al2(sh(son(e))) != 1 && al2(sh(bro(son(e)))) == 1)
869
	if (al2(sh(son(e)))!= 1 && al2(sh(bro(son(e)))) == 1)
872
	  make_bitfield_offset (son(e), e, 1, sh(e));
870
	  make_bitfield_offset(son(e), e, 1, sh(e));
873
	IGNORE all_opnd (sto, to, e, usereg0);
871
	IGNORE all_opnd(sto, to, e, usereg0);
874
	return 0;
872
	return 0;
875
	/* all arguments except possibly one must be operands */
873
	/* all arguments except possibly one must be operands */
876
      };
874
      };
877
 
875
 
878
    case offset_mult_tag:
876
    case offset_mult_tag:
Line 888... Line 886...
888
    case bitf_to_int_tag:
886
    case bitf_to_int_tag:
889
    case max_tag:
887
    case max_tag:
890
    case min_tag:
888
    case min_tag:
891
    case abs_tag:
889
    case abs_tag:
892
      {
890
      {
893
	IGNORE all_opnd (sto, to, e, usereg0);
891
	IGNORE all_opnd(sto, to, e, usereg0);
894
	return 0;
892
	return 0;
895
	/* all arguments except possibly one must be operands */
893
	/* all arguments except possibly one must be operands */
896
      };
894
      };
897
    case subptr_tag:
895
    case subptr_tag:
898
    case minptr_tag:
896
    case minptr_tag:
899
    case make_stack_limit_tag:
897
    case make_stack_limit_tag:
900
      {
898
      {
901
	IGNORE all_opnd (sto, to, e, 0);
899
	IGNORE all_opnd(sto, to, e, 0);
902
	return 0;
900
	return 0;
903
      };
901
      };
904
    case set_stack_limit_tag:
902
    case set_stack_limit_tag:
905
      {
903
      {
906
	exp lim = find_stlim_var();
904
	exp lim = find_stlim_var();
907
	setbro (lim, son(e));
905
	setbro(lim, son(e));
908
	setson (e, lim);
906
	setson(e, lim);
909
	setname (e, ass_tag);
907
	setname(e, ass_tag);
910
	return scan2 (sto, to, e, usereg0);
908
	return scan2(sto, to, e, usereg0);
911
      };
909
      };
912
    case chvar_tag:
910
    case chvar_tag:
913
      {
911
      {
914
	int ur = usereg0 && name(son(e)) != cont_tag;
912
	int ur = usereg0 && name(son(e))!= cont_tag;
915
	IGNORE all_opnd (sto, to, e, ur);
913
	IGNORE all_opnd(sto, to, e, ur);
916
	return 0;
914
	return 0;
917
      };
915
      };
918
 
916
 
919
    case test_tag:
917
    case test_tag:
920
    case absbool_tag:
918
    case absbool_tag:
921
      {
919
      {
922
	if ((name (sh (son (e))) >= shrealhd &&
920
	if ((name(sh(son(e))) >= shrealhd &&
923
	      name (sh (son (e))) <= doublehd))
921
	      name(sh(son(e))) <= doublehd))
924
	  IGNORE all_opnd (sto, to, e, 0);/* all arguments must be operands */
922
	  IGNORE all_opnd (sto, to, e, 0);/* all arguments must be operands */
925
	else
923
	else
926
	  IGNORE all_opnd (sto, to, e, usereg0);
924
	  IGNORE all_opnd(sto, to, e, usereg0);
927
	/* all arguments except possibly one must be operands */
925
	/* all arguments except possibly one must be operands */
928
	return 0;
926
	return 0;
929
      };
927
      };
930
 
928
 
931
    case mod_tag:
929
    case mod_tag:
Line 933... Line 931...
933
    case rem0_tag:
931
    case rem0_tag:
934
    case div1_tag:
932
    case div1_tag:
935
    case div2_tag:
933
    case div2_tag:
936
    case div0_tag:
934
    case div0_tag:
937
      {
935
      {
938
	if (name (sh (e)) == u64hd) {
936
	if (name(sh(e)) == u64hd) {
939
	  exp * bottom = &bro(son(e));
937
	  exp * bottom = &bro(son(e));
940
	  if (name(*bottom) == chvar_tag && shape_size (sh (son(*bottom))) <= 32 &&
938
	  if (name(*bottom) == chvar_tag && shape_size(sh(son(*bottom))) <= 32 &&
941
		name (son(*bottom)) != val_tag && !is_signed (sh (son(*bottom))) ) {
939
		name(son(*bottom))!= val_tag && !is_signed(sh(son(*bottom)))) {
942
	    if (shape_size (sh (son(*bottom))) == 32) {
940
	    if (shape_size(sh(son(*bottom))) == 32) {
943
	      setbro (son(*bottom), bro(*bottom));
941
	      setbro(son(*bottom), bro(*bottom));
944
	      *bottom = son(*bottom);
942
	      *bottom = son(*bottom);
945
	    }
943
	    }
946
	    else
944
	    else
947
	      setsh (son(*bottom), ulongsh);
945
	      setsh(son(*bottom), ulongsh);
948
	  }
946
	  }
949
	}
947
	}
950
	cc1 (sto, to, 1, e, notopnd, 1, usereg0);
948
	cc1(sto, to, 1, e, notopnd, 1, usereg0);
951
	return 0;
949
	return 0;
952
	/* all arguments except possibly the first must be operands */
950
	/* all arguments except possibly the first must be operands */
953
      };
951
      };
954
 
952
 
955
    case shl_tag:
953
    case shl_tag:
956
    case shr_tag:
954
    case shr_tag:
957
    case rotl_tag:
955
    case rotl_tag:
958
    case rotr_tag:
956
    case rotr_tag:
959
    case offset_div_tag:
957
    case offset_div_tag:
960
      {
958
      {
961
	cc1 (sto, to, 1, e, notopnd, 1, usereg0);
959
	cc1(sto, to, 1, e, notopnd, 1, usereg0);
962
	return 0;
960
	return 0;
963
	/* all arguments except possibly the first must be operands */
961
	/* all arguments except possibly the first must be operands */
964
      };
962
      };
965
 
963
 
966
    case offset_div_by_int_tag:
964
    case offset_div_by_int_tag:
967
      {
965
      {
968
	if (name(sh(bro(son(e)))) != slonghd &&  name(sh(bro(son(e)))) != ulonghd) {
966
	if (name(sh(bro(son(e))))!= slonghd &&  name(sh(bro(son(e))))!= ulonghd) {
969
	  exp ch = getexp ((name(sh(bro(son(e))))&1 ? slongsh : ulongsh),
967
	  exp ch = getexp((name(sh(bro(son(e)))) &1 ? slongsh : ulongsh),
970
		e, 1, bro(son(e)), nilexp, 0, 0, chvar_tag);
968
		e, 1, bro(son(e)), nilexp, 0, 0, chvar_tag);
971
	  setbro(bro(son(e)), ch);
969
	  setbro(bro(son(e)), ch);
972
	  setbro(son(e), ch);
970
	  setbro(son(e), ch);
973
	};
971
	};
974
	cc1 (sto, to, 1, e, notopnd, 1, usereg0);
972
	cc1(sto, to, 1, e, notopnd, 1, usereg0);
975
	return 0;
973
	return 0;
976
	/* all arguments except possibly the first must be operands */
974
	/* all arguments except possibly the first must be operands */
977
      };
975
      };
978
 
976
 
979
    case fplus_tag:
977
    case fplus_tag:
Line 993... Line 991...
993
    case ass_tag:
991
    case ass_tag:
994
    case assvol_tag:
992
    case assvol_tag:
995
      {
993
      {
996
	exp toc;
994
	exp toc;
997
	if (name (e) == assvol_tag)/* change assvol to assign */
995
	if (name (e) == assvol_tag)/* change assvol to assign */
998
	  setname (e, ass_tag);
996
	  setname(e, ass_tag);
999
	IGNORE cont_arg (sto, to, e, 0);
997
	IGNORE cont_arg(sto, to, e, 0);
1000
	/* special check for references */
998
	/* special check for references */
1001
	if (!is_assable (bro (son (e)))) {
999
	if (!is_assable(bro(son(e)))) {
1002
	  /* second argument must be assignable */
1000
	  /* second argument must be assignable */
1003
	  cca (sto, to, 0, son (e));
1001
	  cca(sto, to, 0, son(e));
1004
	  toc = contexp (sto, to);
1002
	  toc = contexp(sto, to);
1005
	  IGNORE scan2 (1, toc, son (toc), 1);
1003
	  IGNORE scan2(1, toc, son(toc), 1);
1006
	}
1004
	}
1007
	else
1005
	else
1008
	  IGNORE scan2 (sto, to, bro (son (e)), 1);
1006
	  IGNORE scan2(sto, to, bro(son(e)), 1);
1009
	return (0);
1007
	return(0);
1010
      };
1008
      };
1011
    case apply_tag:
1009
    case apply_tag:
1012
      {
1010
      {
1013
	if (builtinproc(e)) {	/* son must be named global */
1011
	if (builtinproc(e)) {	/* son must be named global */
1014
	  if (!last(son(e)))
1012
	  if (!last(son(e)))
1015
	    IGNORE cc (sto, to, 0, son(e), notopnd, 1, 0);
1013
	    IGNORE cc(sto, to, 0, son(e), notopnd, 1, 0);
1016
	  return 0;
1014
	  return 0;
1017
	}
1015
	}
1018
        if (!last(son(e)))
1016
        if (!last(son(e)))
1019
	  scan_apply_args (sto, to, 0, son(e));
1017
	  scan_apply_args(sto, to, 0, son(e));
1020
	indable_son (sto, to, e);
1018
	indable_son(sto, to, e);
1021
	return (0);
1019
	return(0);
1022
      };
1020
      };
1023
    case apply_general_tag:
1021
    case apply_general_tag:
1024
      {
1022
      {
1025
	exp cees = bro(bro(son(e)));
1023
	exp cees = bro(bro(son(e)));
1026
	exp p_post = cees;	/* bro(p_post) is postlude */
1024
	exp p_post = cees;	/* bro(p_post) is postlude */
1027
	while (name(bro(p_post)) == ident_tag && name(son(bro(p_post))) == caller_name_tag)
1025
	while (name(bro(p_post)) == ident_tag && name(son(bro(p_post))) == caller_name_tag)
1028
	  p_post = son(bro(p_post));
1026
	  p_post = son(bro(p_post));
1029
	scan2 (0, p_post, bro(p_post), 1);
1027
	scan2(0, p_post, bro(p_post), 1);
1030
	if (son(cees) != nilexp)
1028
	if (son(cees)!= nilexp)
1031
	  scan_apply_args (sto, to, 1, cees);
1029
	  scan_apply_args(sto, to, 1, cees);
1032
	if (no(bro(son(e))) != 0)
1030
	if (no(bro(son(e)))!= 0)
1033
	  scan_apply_args (sto, to, 1, bro(son(e)));
1031
	  scan_apply_args(sto, to, 1, bro(son(e)));
1034
	indable_son (sto, to, e);
1032
	indable_son(sto, to, e);
1035
	if ((name(cees) == make_dynamic_callee_tag && name(bro(son(cees))) != val_tag)
1033
	if ((name(cees) == make_dynamic_callee_tag && name(bro(son(cees)))!= val_tag)
1036
		|| (name(cees) == same_callees_tag && callee_size < 0))
1034
		|| (name(cees) == same_callees_tag && callee_size < 0))
1037
	  has_dy_callees = 1;
1035
	  has_dy_callees = 1;
1038
	if (name(cees) == same_callees_tag)
1036
	if (name(cees) == same_callees_tag)
1039
	  has_same_callees = 1;
1037
	  has_same_callees = 1;
1040
	if (name(cees) == make_dynamic_callee_tag || name(cees) == same_callees_tag)
1038
	if (name(cees) == make_dynamic_callee_tag || name(cees) == same_callees_tag)
1041
	  cca_for_cees (sto, to, e);
1039
	  cca_for_cees(sto, to, e);
1042
	return (0);
1040
	return(0);
1043
      };
1041
      };
1044
    case tail_call_tag:
1042
    case tail_call_tag:
1045
      {
1043
      {
1046
	exp cees = bro(son(e));
1044
	exp cees = bro(son(e));
1047
	has_tail_call = 1;
1045
	has_tail_call = 1;
1048
	if (son(cees) != nilexp)
1046
	if (son(cees)!= nilexp)
1049
	  IGNORE cc (sto, to, 1, cees, no_alloca, 1, 0);
1047
	  IGNORE cc(sto, to, 1, cees, no_alloca, 1, 0);
1050
	indable_son (sto, to, e);
1048
	indable_son(sto, to, e);
1051
	if (name(cees) == make_dynamic_callee_tag && name(bro(son(cees))) != val_tag)
1049
	if (name(cees) == make_dynamic_callee_tag && name(bro(son(cees)))!= val_tag)
1052
	  has_dy_callees = 1;
1050
	  has_dy_callees = 1;
1053
	if (name(cees) == same_callees_tag)
1051
	if (name(cees) == same_callees_tag)
1054
	  has_same_callees = 1;
1052
	  has_same_callees = 1;
1055
	if (name(cees) == make_dynamic_callee_tag)
1053
	if (name(cees) == make_dynamic_callee_tag)
1056
	  cca_for_cees (sto, to, e);
1054
	  cca_for_cees(sto, to, e);
1057
	return (0);
1055
	return(0);
1058
      };
1056
      };
1059
    case goto_lv_tag:
1057
    case goto_lv_tag:
1060
      {
1058
      {
1061
	indable_son (sto, to, e);
1059
	indable_son(sto, to, e);
1062
	return (0);
1060
	return(0);
1063
      };
1061
      };
1064
    case res_tag:
1062
    case res_tag:
1065
    case untidy_return_tag:
1063
    case untidy_return_tag:
1066
      {
1064
      {
1067
	if ((name(sh(son(e))) == cpdhd) &&
1065
	if ((name(sh(son(e))) == cpdhd) &&
1068
	     (name(son(e)) != cont_tag ||
1066
	 (name(son(e))!= cont_tag ||
1069
	      name(son(son(e))) != name_tag ||
1067
	      name(son(son(e)))!= name_tag ||
1070
	      !isvar(son(son(son(e)))))) { /* gcc compatibility */
1068
	      !isvar(son(son(son(e)))))) { /* gcc compatibility */
1071
	  exp ec;
1069
	  exp ec;
1072
	  cca (sto, to, 1, e);
1070
	  cca(sto, to, 1, e);
1073
	  ec = contexp (sto, to);
1071
	  ec = contexp(sto, to);
1074
	  IGNORE scan2 (1, ec, son (ec), 0);
1072
	  IGNORE scan2(1, ec, son(ec), 0);
1075
	  return 0;
1073
	  return 0;
1076
	}
1074
	}
1077
	else  {
1075
	else  {
1078
	  IGNORE (scan2 (sto, to, son (e), 1));
1076
	  IGNORE(scan2(sto, to, son(e), 1));
1079
	  return 0;
1077
	  return 0;
1080
	};
1078
	};
1081
      };
1079
      };
1082
    case case_tag:
1080
    case case_tag:
1083
      {
1081
      {
1084
	exp toc;
1082
	exp toc;
1085
	if (name (son (e)) != name_tag &&
1083
	if (name(son(e))!= name_tag &&
1086
	    (name (son (e)) != cont_tag ||
1084
	(name(son(e))!= cont_tag ||
1087
	      name (son (son (e))) != name_tag)) {
1085
	      name(son(son(e)))!= name_tag)) {
1088
	  cca (sto, to, 1, e);
1086
	  cca(sto, to, 1, e);
1089
	  toc = contexp (sto, to);
1087
	  toc = contexp(sto, to);
1090
	  IGNORE scan2 (1, toc, son (toc), 0);
1088
	  IGNORE scan2(1, toc, son(toc), 0);
1091
	}
1089
	}
1092
	else
1090
	else
1093
	  IGNORE scan2 (sto, to, son (e), 0);
1091
	  IGNORE scan2(sto, to, son(e), 0);
1094
	return (0);
1092
	return(0);
1095
      };
1093
      };
1096
    case plus_tag:
1094
    case plus_tag:
1097
      {
1095
      {
1098
	IGNORE cc (sto, to, 1, e, plusdo, 1, usereg0);
1096
	IGNORE cc(sto, to, 1, e, plusdo, 1, usereg0);
1099
	return 0;
1097
	return 0;
1100
      };
1098
      };
1101
    case addptr_tag:
1099
    case addptr_tag:
1102
      {
1100
      {
1103
	exp f = father (e);
1101
	exp f = father(e);
1104
	exp new_r = getexp (sh (e), bro (e), (int)(last (e)),
1102
	exp new_r = getexp(sh(e), bro(e), (int)(last(e)),
1105
                             e, nilexp, 0,
1103
                             e, nilexp, 0,
1106
	    0, reff_tag);
1104
	    0, reff_tag);
1107
	exp * ref = refto (f, e);
1105
	exp * ref = refto(f, e);
1108
	setlast (e);
1106
	setlast(e);
1109
	bro (e) = new_r;
1107
	bro(e) = new_r;
1110
	*ref = new_r;
1108
	*ref = new_r;
1111
	ap_argsc (sto, to, new_r);
1109
	ap_argsc(sto, to, new_r);
1112
	return (0);
1110
	return(0);
1113
      };
1111
      };
1114
    case mult_tag:
1112
    case mult_tag:
1115
      {
1113
      {
1116
	if (shape_size (sh (e)) == 64 && optop(e)) {
1114
	if (shape_size(sh(e)) == 64 && optop(e)) {
1117
	  exp * arglist = &son(e);
1115
	  exp * arglist = &son(e);
1118
	  for (;;) {
1116
	  for (;;) {
1119
	    if (name(*arglist) == chvar_tag && shape_size (sh (son(*arglist))) <= 32 &&
1117
	    if (name(*arglist) == chvar_tag && shape_size(sh(son(*arglist))) <= 32 &&
1120
		(is_signed (sh (e)) || !is_signed (sh (son(*arglist)))) ) {
1118
		(is_signed(sh(e)) || !is_signed(sh(son(*arglist))))) {
1121
	      if (shape_size (sh (son(*arglist))) == 32) {
1119
	      if (shape_size(sh(son(*arglist))) == 32) {
1122
		setbro (son(*arglist), bro(*arglist));
1120
		setbro(son(*arglist), bro(*arglist));
1123
		if (last(*arglist))
1121
		if (last(*arglist))
1124
		  setlast (son(*arglist));
1122
		  setlast(son(*arglist));
1125
		else
1123
		else
1126
		  clearlast (son(*arglist));
1124
		  clearlast(son(*arglist));
1127
		*arglist = son(*arglist);
1125
		*arglist = son(*arglist);
1128
	      }
1126
	      }
1129
	      else
1127
	      else
1130
		setsh (son(*arglist), (is_signed (sh (e)) ? slongsh : ulongsh));
1128
		setsh(son(*arglist), (is_signed(sh(e))? slongsh : ulongsh));
1131
	    }
1129
	    }
1132
	    if (last(*arglist))
1130
	    if (last(*arglist))
1133
	      break;
1131
	      break;
1134
	    arglist = &bro(*arglist);
1132
	    arglist = &bro(*arglist);
1135
	  }
1133
	  }
1136
	}
1134
	}
1137
	IGNORE cc (sto, to, 1, e, multdo, 1, usereg0);
1135
	IGNORE cc(sto, to, 1, e, multdo, 1, usereg0);
1138
	return 0;
1136
	return 0;
1139
      };
1137
      };
1140
    case and_tag:
1138
    case and_tag:
1141
      {
1139
      {
1142
	IGNORE cc (sto, to, 1, e, anddo, 1, usereg0);
1140
	IGNORE cc(sto, to, 1, e, anddo, 1, usereg0);
1143
	return 0;
1141
	return 0;
1144
      };
1142
      };
1145
    case or_tag:
1143
    case or_tag:
1146
    case xor_tag:
1144
    case xor_tag:
1147
      {
1145
      {
1148
	IGNORE cc (sto, to, 1, e, notado, 1, usereg0);
1146
	IGNORE cc(sto, to, 1, e, notado, 1, usereg0);
1149
	return 0;
1147
	return 0;
1150
      };
1148
      };
1151
    case cont_tag:
1149
    case cont_tag:
1152
    case contvol_tag:
1150
    case contvol_tag:
1153
      {
1151
      {
1154
	if (name (e) == contvol_tag)
1152
	if (name(e) == contvol_tag)
1155
	  setname (e, cont_tag);
1153
	  setname(e, cont_tag);
1156
	return cont_arg (sto, to, e, usereg0);
1154
	return cont_arg(sto, to, e, usereg0);
1157
      };
1155
      };
1158
    case field_tag:
1156
    case field_tag:
1159
      {
1157
      {
1160
	if (!is_o (name (son (e))) || name (e) == cont_tag) {
1158
	if (!is_o(name(son(e))) || name(e) == cont_tag) {
1161
	  exp temp;
1159
	  exp temp;
1162
	  cca (sto, to, 1, e);
1160
	  cca(sto, to, 1, e);
1163
	  temp = contexp (sto, to);
1161
	  temp = contexp(sto, to);
1164
	  return (scan2 (1, temp, son (temp), usereg0));
1162
	  return(scan2(1, temp, son(temp), usereg0));
1165
	}
1163
	}
1166
	else
1164
	else
1167
	  return (scan2 (sto, to, son (e), usereg0));
1165
	  return(scan2(sto, to, son(e), usereg0));
1168
      };
1166
      };
1169
    case reff_tag:
1167
    case reff_tag:
1170
      {
1168
      {
1171
	if (name (son (e)) == addptr_tag) {
1169
	if (name(son(e)) == addptr_tag) {
1172
	  ap_argsc (sto, to, e);
1170
	  ap_argsc(sto, to, e);
1173
	  return (0);
1171
	  return(0);
1174
	};
1172
	};
1175
 
1173
 
1176
	ccp (sto, to, 1, e);
1174
	ccp(sto, to, 1, e);
1177
	return (0);
1175
	return(0);
1178
      };
1176
      };
1179
    case proc_tag:
1177
    case proc_tag:
1180
    case general_proc_tag:
1178
    case general_proc_tag:
1181
      {
1179
      {
1182
	IGNORE scan2 (1, e, son (e), 1);
1180
	IGNORE scan2(1, e, son(e), 1);
1183
	return (0);
1181
	return(0);
1184
      };
1182
      };
1185
    case asm_tag:
1183
    case asm_tag:
1186
      {
1184
      {
1187
	if (props(e) != 0)
1185
	if (props(e)!= 0)
1188
	  failer ("~asm not in ~asm_sequence");
1186
	  failer("~asm not in ~asm_sequence");
1189
	check_asm_seq (son(e), 0);
1187
	check_asm_seq(son(e), 0);
1190
	proc_has_asm = 1;
1188
	proc_has_asm = 1;
1191
	return (0);
1189
	return(0);
1192
      };
1190
      };
1193
 
1191
 
1194
    case name_tag:
1192
    case name_tag:
1195
      if (!is_opnd (e)) {
1193
      if (!is_opnd(e)) {
1196
	return 0;
1194
	return 0;
1197
      }
1195
      }
1198
 
1196
 
1199
	/* DELIBERATE FALL THROUGH */
1197
	/* DELIBERATE FALL THROUGH */
1200
    default:
1198
    default:
1201
      return (usereg0);
1199
      return(usereg0);
1202
  };
1200
  };
1203
}
1201
}