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
*/
Line 243... Line 273...
243
 * removed rscope related fns.
273
 * removed rscope related fns.
244
 * added RET_IN_CODE, not set -> return at end of leaf, not in middle...
274
 * added RET_IN_CODE, not set -> return at end of leaf, not in middle...
245
 *
275
 *
246
 * Revision 1.1  94/05/03  14:49:48  djch
276
 * Revision 1.1  94/05/03  14:49:48  djch
247
 * Initial revision
277
 * Initial revision
248
 * 
278
 *
249
 * Revision 1.8  94/02/21  16:12:49  16:12:49  ra (Robert Andrews)
279
 * Revision 1.8  94/02/21  16:12:49  16:12:49  ra (Robert Andrews)
250
 * reg_result now returns int, not bool.
280
 * reg_result now returns int, not bool.
251
 * 
281
 *
252
 * Revision 1.7  93/09/27  14:53:49  14:53:49  ra (Robert Andrews)
282
 * Revision 1.7  93/09/27  14:53:49  14:53:49  ra (Robert Andrews)
253
 * In System V the __GLOBAL_OFFSET_TABLE_ starts with only one _.
283
 * In System V the __GLOBAL_OFFSET_TABLE_ starts with only one _.
254
 * 
284
 *
255
 * Revision 1.6  93/08/27  11:35:12  11:35:12  ra (Robert Andrews)
285
 * Revision 1.6  93/08/27  11:35:12  11:35:12  ra (Robert Andrews)
256
 * A number of lint-like changes.
286
 * A number of lint-like changes.
257
 * 
287
 *
258
 * Revision 1.5  93/08/13  14:44:13  14:44:13  ra (Robert Andrews)
288
 * Revision 1.5  93/08/13  14:44:13  14:44:13  ra (Robert Andrews)
259
 * Reformatted.
289
 * Reformatted.
260
 * 
290
 *
261
 * Revision 1.4  93/07/14  11:21:26  11:21:26  ra (Robert Andrews)
291
 * Revision 1.4  93/07/14  11:21:26  11:21:26  ra (Robert Andrews)
262
 * Misprint when reformatting : .reserved should be .reserve.
292
 * Misprint when reformatting : .reserved should be .reserve.
263
 * 
293
 *
264
 * Revision 1.3  93/07/05  18:23:46  18:23:46  ra (Robert Andrews)
294
 * Revision 1.3  93/07/05  18:23:46  18:23:46  ra (Robert Andrews)
265
 * Made distinction between the System V assembler and the System V ABI.
295
 * Made distinction between the System V assembler and the System V ABI.
266
 * Added support for PIC (procedure prologue).
296
 * Added support for PIC (procedure prologue).
267
 * 
297
 *
268
 * Revision 1.2  93/06/29  14:30:40  14:30:40  ra (Robert Andrews)
298
 * Revision 1.2  93/06/29  14:30:40  14:30:40  ra (Robert Andrews)
269
 * Changed an error message.
299
 * Changed an error message.
270
 * 
300
 *
271
 * Revision 1.1  93/06/24  14:59:01  14:59:01  ra (Robert Andrews)
301
 * Revision 1.1  93/06/24  14:59:01  14:59:01  ra (Robert Andrews)
272
 * Initial revision
302
 * Initial revision
273
 * 
303
 *
274
--------------------------------------------------------------------------
304
--------------------------------------------------------------------------
275
*/
305
*/
276
 
306
 
277
/*
307
/*
278
  This file contains functions which handle the various aspects
308
  This file contains functions which handle the various aspects
279
  of procedure definition and invocation.
309
  of procedure definition and invocation.
280
*/
310
*/
281
 
311
 
Line 331... Line 361...
331
 
361
 
332
/*
362
/*
333
  CODE GENERATION STATE FOR THE CURRENT PROCEDURE
363
  CODE GENERATION STATE FOR THE CURRENT PROCEDURE
334
*/
364
*/
335
 
365
 
336
static void alloc_space PROTO_S((int,int));
366
static void alloc_space(int,int);
337
static void alloc_reg_space PROTO_S((int,int));
367
static void alloc_reg_space(int,int);
338
 
368
 
339
extern int call_base_reg;
369
extern int call_base_reg;
340
 
370
 
341
 
371
 
342
struct proc_state proc_state ;
372
struct proc_state proc_state;
343
static exp current_proc;
373
static exp current_proc;
344
 
374
 
345
bool Has_vcallees = 0;
375
bool Has_vcallees = 0;
346
bool Has_no_vcallers = 0;
376
bool Has_no_vcallers = 0;
347
bool in_general_proc = 0;
377
bool in_general_proc = 0;
Line 369... Line 399...
369
int aritherr_lab = 0;
399
int aritherr_lab = 0;
370
 
400
 
371
int stackerr_lab = 0;
401
int stackerr_lab = 0;
372
int local_stackerr_lab = 0;
402
int local_stackerr_lab = 0;
373
 
403
 
374
#define is64(X) ((name(X)==u64hd)||(name(X)==s64hd))
404
#define is64(X)((name(X) ==u64hd) || (name(X) ==s64hd))
375
 
405
 
376
 
406
 
377
void call_tdf_main 
407
void call_tdf_main
378
    PROTO_Z () {
408
(void) {
379
  outs("\tcall\t___TDF_main\n");
409
  outs("\tcall\t___TDF_main\n");
380
  outs("\tnop\n");
410
  outs("\tnop\n");
381
  return;
411
  return;
382
}
412
}
383
 
413
 
384
  
414
 
385
 
415
 
386
 
416
 
387
/*
417
/*
388
  FIND TEMPORARY MEMORY
418
  FIND TEMPORARY MEMORY
389
  This is a temporary location in the stack frame callee parameter 
419
  This is a temporary location in the stack frame callee parameter
390
  save area that can be used in short instruction sequences, such 
420
  save area that can be used in short instruction sequences, such
391
  as moving between float and fixed registers.  It is initialised 
421
  as moving between float and fixed registers.  It is initialised
392
  in the procedure prelude.
422
  in the procedure prelude.
393
*/
423
*/
394
 
424
 
395
baseoff mem_temp 
425
baseoff mem_temp
396
    PROTO_N ( ( byte_offset ) )
-
 
397
    PROTO_T ( int byte_offset ){
426
(int byte_offset) {
398
  baseoff b ;
427
  baseoff b;
399
  b = proc_state.mem_temp0 ;
428
  b = proc_state.mem_temp0;
400
  /* only 2 words of temp allocated */
429
  /* only 2 words of temp allocated */
401
  assert ( byte_offset >= 0 && byte_offset < 8 ) ;
430
  assert(byte_offset >= 0 && byte_offset < 8);
402
  b.offset += byte_offset ;
431
  b.offset += byte_offset;
403
  return ( b ) ;
432
  return(b);
404
}
433
}
405
 
434
 
406
 
435
 
407
 
436
 
408
/*
437
/*
409
  Postlude chaining function 
438
  Postlude chaining function
410
*/
439
*/
411
static postlude_chain * old_postludes;
440
static postlude_chain * old_postludes;
412
 
441
 
413
void update_plc 
442
void update_plc
414
    PROTO_N ( ( chain, maxargs ) )
-
 
415
    PROTO_T ( postlude_chain* chain X int maxargs ) {
443
(postlude_chain* chain, int maxargs) {
416
 
444
 
417
  while(chain) {
445
  while (chain) {
418
    exp pl = chain->postlude;
446
    exp pl = chain->postlude;
419
    while(name(pl) == ident_tag) {
447
    while (name(pl) == ident_tag) {
420
      if (name(son(pl)) == caller_name_tag)
448
      if (name(son(pl)) == caller_name_tag)
421
	no(pl) += (maxargs<<1);
449
	no(pl) += (maxargs<<1);
422
      pl = bro(son(pl));
450
      pl = bro(son(pl));
423
    }
451
    }
424
    chain = chain->outer;
452
    chain = chain->outer;
425
  }
453
  }
426
  return;
454
  return;
427
}
455
}
428
 
456
 
429
 
457
 
430
/*
458
/*
431
  ENCODE A PROCEDURE DEFINITION
459
  ENCODE A PROCEDURE DEFINITION
432
*/
460
*/
433
 
461
 
434
makeans make_proc_tag_code 
462
makeans make_proc_tag_code
435
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
436
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
463
(exp e, space sp, where dest, int exitlab) {
437
  procrec *pr = &procrecs [ no ( e ) ] ;
464
  procrec *pr = &procrecs[no(e)];
438
  needs *ndpr = &pr->needsproc ;
465
  needs *ndpr = &pr->needsproc;
439
  spacereq *sppr = &pr->spacereqproc ;
466
  spacereq *sppr = &pr->spacereqproc;
440
  long pprops = ( long ) ( ndpr->prps ) ;
467
  long pprops = (long)(ndpr->prps);
441
  bool leaf = ( bool ) ( ( pprops & anyproccall ) == 0 ) ;	/* LINT */
468
  bool leaf = ( bool ) ( ( pprops & anyproccall ) == 0 ) ;	/* LINT */
442
  long maxargs = ndpr->maxargs ;/* maxargs of proc body in bits */
469
  long maxargs = ndpr->maxargs ;/* maxargs of proc body in bits */
443
  long st = sppr->stack ;		/* space for locals in bits */
470
  long st = sppr->stack ;		/* space for locals in bits */
444
  struct proc_state old_proc_state ;
471
  struct proc_state old_proc_state;
445
  makeans mka ;
472
  makeans mka;
446
  exp par ;
473
  exp par;
447
  old_postludes = (postlude_chain*)NULL;
474
  old_postludes = (postlude_chain*)NULL;
448
  current_proc = e;
475
  current_proc = e;
449
  Has_vcallees = (name(e) == general_proc_tag) && (proc_has_vcallees(e));
476
  Has_vcallees = (name(e) == general_proc_tag) && (proc_has_vcallees(e));
450
  Has_no_vcallers = (name(e) == proc_tag) || (!proc_has_vcallers(e));
477
  Has_no_vcallers = (name(e) == proc_tag) || (!proc_has_vcallers(e));
451
  in_general_proc = (name(e) == general_proc_tag);
478
  in_general_proc = (name(e) == general_proc_tag);
452
#ifdef GENCOMPAT
479
#ifdef GENCOMPAT
453
  May_have_callees = proc_may_have_callees(e);
480
  May_have_callees = proc_may_have_callees(e);
454
#endif
481
#endif
455
  /* save & reinstate proc_state for nested procs */
482
  /* save & reinstate proc_state for nested procs */
456
  old_proc_state = proc_state ;
483
  old_proc_state = proc_state;
457
  mka.lab = exitlab ;
484
  mka.lab = exitlab;
458
  mka.regmove = NOREG ;
485
  mka.regmove = NOREG;
459
#ifdef GENCOMPAT
486
#ifdef GENCOMPAT
460
  if (May_have_callees) {
487
  if (May_have_callees) {
461
#else
488
#else
462
  if(in_general_proc) {
489
  if (in_general_proc) {
463
#endif
490
#endif
464
    sp = guardreg(callee_start_reg,sp);
491
    sp = guardreg(callee_start_reg,sp);
465
  }
492
  }
466
  
493
 
467
  if(Has_vcallees) {
494
  if (Has_vcallees) {
468
    sp = guardreg(callee_end_reg,sp);
495
    sp = guardreg(callee_end_reg,sp);
469
    outs("\t.optim\t\"-O0\"\n"); /* as -O2 optimises out some moves 
496
    outs("\t.optim\t\"-O0\"\n"); /* as -O2 optimises out some moves
470
				    from %sp to other registers */
497
				    from %sp to other registers */
471
  }
498
  }
472
  
499
 
473
  /* this is a procedure definition */
500
  /* this is a procedure definition */
474
  assert ( name ( e ) == proc_tag || name(e) == general_proc_tag) ;
501
  assert(name(e) == proc_tag || name(e) == general_proc_tag);
475
  
502
 
476
  /* set global flag for res_tag */
503
  /* set global flag for res_tag */
477
  proc_state.leaf_proc = leaf ;
504
  proc_state.leaf_proc = leaf;
478
 
505
 
479
  /* maxargs is the maxargs in bits of any proc called, not this proc */
506
  /* maxargs is the maxargs in bits of any proc called, not this proc */
480
 
507
 
481
  /* SPARC reserved stack area */
508
  /* SPARC reserved stack area */
482
  if ( leaf ) {
509
  if (leaf) {
483
    /* reg window dump area */
510
    /* reg window dump area */
484
    assert ( maxargs == 0 ) ;
511
    assert(maxargs == 0);
485
    maxargs = ( 16 ) * 32 ;
512
    maxargs = (16)* 32;
486
  } 
513
  }
487
  else {
514
  else {
488
    assert ( maxargs >= 0 ) ;
515
    assert(maxargs >= 0);
489
    /* at least reg param dump for calls */
516
    /* at least reg param dump for calls */
490
    if ( maxargs < ( 6 ) * 32 ) maxargs = ( 6 ) * 32 ;
517
    if (maxargs < (6)* 32)maxargs = (6)* 32;
491
    /* plus reg window dump area + hidden struct return param */
518
    /* plus reg window dump area + hidden struct return param */
492
    maxargs += ( 16 + 1 ) * 32 ;
519
    maxargs += (16 + 1)* 32;
493
  }
520
  }
494
  
521
 
495
  /* use space we are allowing for called procs */
522
  /* use space we are allowing for called procs */
496
  proc_state.mem_temp0.base = R_SP ;
523
  proc_state.mem_temp0.base = R_SP;
497
  proc_state.mem_temp0.offset = ( 16 + 1 + 1 ) * 4 ;
524
  proc_state.mem_temp0.offset = (16 + 1 + 1)* 4;
498
 
525
 
499
  /* double word aligned */
526
  /* double word aligned */
500
  assert ( ( proc_state.mem_temp0.offset & 7 ) == 0 ) ;
527
  assert((proc_state.mem_temp0.offset & 7) == 0);
501
  
528
 
502
  /* make sure mem_temp () is allowed for */
529
  /* make sure mem_temp () is allowed for */
503
  if ( proc_state.mem_temp0.base == R_SP &&
530
  if (proc_state.mem_temp0.base == R_SP &&
504
       maxargs < ( ( proc_state.mem_temp0.offset + 8 ) << 3 ) ) {
531
       maxargs < ((proc_state.mem_temp0.offset + 8) << 3)) {
505
    /* ie, a leaf proc */
532
    /* ie, a leaf proc */
506
    assert ( leaf ) ;
533
    assert(leaf);
507
    maxargs = ( proc_state.mem_temp0.offset + 8 ) << 3 ;
534
    maxargs = (proc_state.mem_temp0.offset + 8) << 3;
508
    }
535
    }
509
  
536
 
510
  /* align to 64 bit boundaries */
537
  /* align to 64 bit boundaries */
511
  maxargs = ( maxargs + 63 ) & ~63 ;
538
  maxargs = (maxargs + 63) & ~63;
512
  st = ( st + 63 ) & ~63 ;
539
  st = (st + 63) & ~63;
513
  /* -----------------------WARNING--------------------------- */
540
  /* -----------------------WARNING--------------------------- */
514
  /* if you alter these then please check boff_env_offset, 'cos 
541
  /* if you alter these then please check boff_env_offset, 'cos
515
     they're effectively reproduced there..... */
542
     they're effectively reproduced there..... */
516
  proc_state.locals_space = st ;
543
  proc_state.locals_space = st;
517
  proc_state.locals_offset = 0 ;
544
  proc_state.locals_offset = 0;
518
  /*proc_state.params_offset = ( 16 + 1 ) * 32 ;*/
545
  /*proc_state.params_offset = ( 16 + 1 ) * 32 ;*/
519
  proc_state.params_offset = PARAMS_OFFSET;
546
  proc_state.params_offset = PARAMS_OFFSET;
520
  proc_state.callee_size = ndpr->callee_size;
547
  proc_state.callee_size = ndpr->callee_size;
521
  /* beyond register window save area and hidden param of 
548
  /* beyond register window save area and hidden param of
522
     caller's frame */
549
     caller's frame */
523
  
550
 
524
  proc_state.frame_size = maxargs + st ;
551
  proc_state.frame_size = maxargs + st;
525
  proc_state.maxargs = maxargs ;
552
  proc_state.maxargs = maxargs;
526
  
553
 
527
  st = proc_state.frame_size >> 3 ;
554
  st = proc_state.frame_size >> 3;
528
 
555
 
529
#ifdef NEWDWARF
556
#ifdef NEWDWARF
530
  if (dwarf2) {
557
  if (dwarf2) {
531
    START_BB ();
558
    START_BB();
532
    dw2_start_fde(current_proc);
559
    dw2_start_fde(current_proc);
533
  }
560
  }
534
#endif
561
#endif
535
 
562
 
536
  if(name(e) == general_proc_tag){
563
  if (name(e) == general_proc_tag) {
537
    if(proc_has_checkstack(e) && (st > 64)) {
564
    if (proc_has_checkstack(e) && (st > 64)) {
538
      rir_ins(i_save,R_SP,-64,R_SP);
565
      rir_ins(i_save,R_SP,-64,R_SP);
539
    }
566
    }
540
    else {
567
    else {
541
      rir_ins(i_save,R_SP,-st,R_SP);
568
      rir_ins(i_save,R_SP,-st,R_SP);
542
    }
569
    }
543
#ifdef NEWDWARF
570
#ifdef NEWDWARF
544
    if (dwarf2)
571
    if (dwarf2)
545
      dw2_fde_save();
572
      dw2_fde_save();
546
#endif
573
#endif
547
#ifdef GENCOMPAT
574
#ifdef GENCOMPAT
548
    if (May_have_callees)
575
    if (May_have_callees)
549
#endif
576
#endif
550
    {
577
    {
551
      int entry_lab = new_label();
578
      int entry_lab = new_label();
552
      uncond_ins(i_b,entry_lab);
579
      uncond_ins(i_b,entry_lab);
553
      /*rir_ins(i_save,R_SP,0,R_SP);*/
580
      /*rir_ins(i_save,R_SP,0,R_SP);*/
554
 
581
 
555
      if(st>64) {
582
      if (st>64) {
556
	rir_ins(i_sub,R_SP, st - 64,R_SP);
583
	rir_ins(i_sub,R_SP, st - 64,R_SP);
557
      }
584
      }
558
      set_label(entry_lab);
585
      set_label(entry_lab);
559
    }
586
    }
560
  }
587
  }
561
  else{
588
  else{
562
    rir_ins ( i_save, R_SP, -st, R_SP ) ;
589
    rir_ins(i_save, R_SP, -st, R_SP);
563
#ifdef NEWDWARF
590
#ifdef NEWDWARF
564
    if (dwarf2)
591
    if (dwarf2)
565
      dw2_fde_save();
592
      dw2_fde_save();
566
#endif
593
#endif
567
    /* more here about fp */
594
    /* more here about fp */
568
  }
595
  }
569
  
596
 
570
  /* position independent code */
597
  /* position independent code */
571
  if ( PIC_code && proc_uses_external ( e ) ) {
598
  if (PIC_code && proc_uses_external(e)) {
572
    char *g = "__GLOBAL_OFFSET_TABLE_" ;
599
    char *g = "__GLOBAL_OFFSET_TABLE_";
573
    if ( sysV_assembler ) g++ ;
600
    if (sysV_assembler)g++;
574
    outs ( "1:\n" ) ;
601
    outs("1:\n");
575
    outs ( "\tcall\t2f\n" ) ;
602
    outs("\tcall\t2f\n");
576
    outf ( "\tsethi\t%%hi(%s+(.-1b)),%%l7\n", g ) ;
603
    outf("\tsethi\t%%hi(%s+ (.-1b)),%%l7\n", g);
577
    outs ( "2:\n" ) ;
604
    outs("2:\n");
578
    outf ( "\tor\t%%l7,%%lo(%s+(.-1b)),%%l7\n", g ) ;
605
    outf("\tor\t%%l7,%%lo(%s+ (.-1b)),%%l7\n", g);
579
    outs ( "\tadd\t%l7,%o7,%l7\n" ) ;
606
    outs("\tadd\t%l7,%o7,%l7\n");
580
#ifdef NEWDWARF
607
#ifdef NEWDWARF
581
    if (dwarf2)
608
    if (dwarf2)
582
      lost_count_ins();
609
      lost_count_ins();
583
#endif
610
#endif
584
  }
611
  }
585
 
612
 
586
  local_stackerr_lab = 0;
613
  local_stackerr_lab = 0;
587
  stackerr_lab = 0;
614
  stackerr_lab = 0;
588
  if(name(e) == general_proc_tag){
615
  if (name(e) == general_proc_tag) {
589
    if(proc_has_checkstack(e)){
616
    if (proc_has_checkstack(e)) {
590
      baseoff b;
617
      baseoff b;
591
      int rtmp;
618
      int rtmp;
592
      int rt;
619
      int rt;
593
      if (st > 64) {
620
      if (st > 64) {
594
	rt = getreg(sp.fixed);
621
	rt = getreg(sp.fixed);
595
	rir_ins(i_sub,R_SP,(st - 64),rt);
622
	rir_ins(i_sub,R_SP,(st - 64),rt);
Line 600... Line 627...
600
      b = find_tag(TDF_STACKLIM);
627
      b = find_tag(TDF_STACKLIM);
601
      stackerr_lab = new_label();
628
      stackerr_lab = new_label();
602
      rtmp = getreg(guardreg(rt,sp).fixed);
629
      rtmp = getreg(guardreg(rt,sp).fixed);
603
      ld_ins(i_ld,b,rtmp);
630
      ld_ins(i_ld,b,rtmp);
604
      condrr_ins(i_bgtu,rtmp,R_SP,stackerr_lab);
631
      condrr_ins(i_bgtu,rtmp,R_SP,stackerr_lab);
605
      if(rt != R_SP) {
632
      if (rt != R_SP) {
606
	rr_ins(i_mov,rt,R_SP);
633
	rr_ins(i_mov,rt,R_SP);
607
      }
634
      }
608
    }
635
    }
609
 
636
 
610
    /* Here we make a local copy of the callees */
637
    /* Here we make a local copy of the callees */
611
    if(Has_vcallees) {
638
    if (Has_vcallees) {
612
      baseoff b;
639
      baseoff b;
613
      int copy_lab = new_label();
640
      int copy_lab = new_label();
614
      int end_copy_lab = new_label();
641
      int end_copy_lab = new_label();
615
      /* copy callees to new space (pointed to by reg rdest) */
642
      /* copy callees to new space (pointed to by reg rdest) */
616
      int rsize = getreg(sp.fixed);
643
      int rsize = getreg(sp.fixed);
Line 644... Line 671...
644
      int rdest = getreg(sp.fixed);
671
      int rdest = getreg(sp.fixed);
645
      int el;
672
      int el;
646
      int rt = getreg(guardreg(rdest,sp).fixed);
673
      int rt = getreg(guardreg(rdest,sp).fixed);
647
      alloc_space(size,rdest);
674
      alloc_space(size,rdest);
648
      b.offset = 0;
675
      b.offset = 0;
649
      for(el = proc_state.callee_size/8;el>0;el -= (PTR_SZ>>3)) {
676
      for (el = proc_state.callee_size/8;el>0;el -= (PTR_SZ>>3)) {
650
	b.base = callee_start_reg;
677
	b.base = callee_start_reg;
651
	b.offset = el - (PTR_SZ>>3);
678
	b.offset = el - (PTR_SZ>>3);
652
	ld_ro_ins(i_ld,b,rt);
679
	ld_ro_ins(i_ld,b,rt);
653
	b.base = rdest;
680
	b.base = rdest;
654
	st_ro_ins(i_st,rt,b);
681
	st_ro_ins(i_st,rt,b);
655
      }
682
      }
656
      /* now deallocate old storage.  This is needs for outpars to be 
683
      /* now deallocate old storage.  This is needs for outpars to be
657
	 accessed properly from postludes. */
684
	 accessed properly from postludes. */
658
#if 0
685
#if 0
659
      rir_ins(i_add,callee_start_reg,((proc_state.callee_size>>3)+7)&~7,callee_start_reg);
686
      rir_ins(i_add,callee_start_reg,((proc_state.callee_size>>3) +7) &~7,callee_start_reg);
660
      rir_ins(i_sub,callee_start_reg,96,R_FP);
687
      rir_ins(i_sub,callee_start_reg,96,R_FP);
661
#endif
688
#endif
662
      rr_ins(i_mov,rdest,callee_start_reg);
689
      rr_ins(i_mov,rdest,callee_start_reg);
663
 
690
 
664
    }
691
    }
665
  }
692
  }
666
  if ( do_profile ) {
693
  if (do_profile) {
667
      /* implement -p option, call mcount */
694
      /* implement -p option, call mcount */
668
    static int p_lab = 0 ;
695
    static int p_lab = 0;
669
    p_lab++ ;
696
    p_lab++;
670
    if ( sysV_assembler ) {
697
    if (sysV_assembler) {
671
      outs ( "\t.reserve\tLP." ) ;
698
      outs("\t.reserve\tLP.");
672
      outn ( p_lab ) ;
699
      outn(p_lab);
673
      outs ( ",4,\".bss\",4\n" ) ;
700
      outs(",4,\".bss\",4\n");
674
      } 
701
      }
675
    else {
702
    else {
676
      outs ( "\t.reserve\tLP." ) ;
703
      outs("\t.reserve\tLP.");
677
      outn ( p_lab ) ;
704
      outn(p_lab);
678
      outs ( ",4,\"bss\",4\n" ) ;
705
      outs(",4,\"bss\",4\n");
679
    }
706
    }
680
    insection ( text_section ) ;
707
    insection(text_section);
681
    outs ( "\tset\tLP." ) ;
708
    outs("\tset\tLP.");
682
    outn ( p_lab ) ;
709
    outn(p_lab);
683
    outs ( ",%o0\n" ) ;
710
    outs(",%o0\n");
684
#ifdef NEWDWARF
711
#ifdef NEWDWARF
685
    if (dwarf2)
712
    if (dwarf2)
686
      lost_count_ins();
713
      lost_count_ins();
687
#endif
714
#endif
688
    extj_special_ins ( i_call, "mcount", 1 ) ;
715
    extj_special_ins(i_call, "mcount", 1);
689
  }
716
  }
690
 
717
 
691
    /* Move params if necessary */
718
    /* Move params if necessary */
692
  par = son ( e ) ;
719
  par = son(e);
693
  while ( name ( par ) == ident_tag ) {
720
  while (name(par) == ident_tag) {
694
    if ( isparam ( par ) ) {
721
    if (isparam(par)) {
695
      /* Got a parameter ident */
722
      /* Got a parameter ident */
696
      int r = ( int ) props ( son ( par ) ) ;
723
      int r = (int)props(son(par));
697
      /* ( r == 0 ) ? ( on stack ) : ( input reg no ) */
724
      /* ( r == 0 ) ? ( on stack ) : ( input reg no ) */
698
/*	assert ( name ( son ( par ) ) == clear_tag ) ;*/
725
/*	assert ( name ( son ( par ) ) == clear_tag ) ;*/
699
 
726
 
700
      if ( r != 0 ) {
727
      if (r != 0) {
701
	/* Parameter in register */
728
	/* Parameter in register */
702
	assert ( R_I0 <= r && r <= R_I5 ) ;
729
	assert(R_I0 <= r && r <= R_I5);
703
	
730
 
704
	if ( no ( par ) != 0 ) {
731
	if (no(par)!= 0) {
705
	  if ( no ( par ) == R_NO_REG ) {
732
	  if (no(par) == R_NO_REG) {
706
	    /* struct/union parameter, on stack aleady,
733
	    /* struct/union parameter, on stack aleady,
707
	       nothing useful in reg */
734
	       nothing useful in reg */
708
	    assert ( !fixregable ( par ) &&
735
	    assert(!fixregable(par) &&
709
		     !floatregable ( par ) ) ;
736
		     !floatregable(par));
710
	  } 
737
	  }
711
	  else if ( no ( par ) == r ) {
738
	  else if (no(par) == r) {
712
	    if ( name ( sh ( son ( par ) ) ) == ucharhd ) {
739
	    if (name(sh(son(par))) == ucharhd) {
713
	      rir_ins ( i_and, r, 255, no ( par ) ) ;
740
	      rir_ins(i_and, r, 255, no(par));
714
	    } 
741
	    }
715
	    else if ( name ( sh ( son ( par ) ) ) == uwordhd ) {
742
	    else if (name(sh(son(par))) == uwordhd) {
716
	      rir_ins ( i_and, r, 65535, no ( par ) ) ;
743
	      rir_ins(i_and, r, 65535, no(par));
717
	    }	
744
	    }
718
	  } 
745
	  }
719
	  else {
746
	  else {
720
	    if ( name ( sh ( son ( par ) ) ) == ucharhd ) {
747
	    if (name(sh(son(par))) == ucharhd) {
721
	      rir_ins ( i_and, r, 255, no ( par ) ) ;
748
	      rir_ins(i_and, r, 255, no(par));
722
	    } 
749
	    }
723
	    else if ( name ( sh ( son ( par ) ) ) == uwordhd ) {
750
	    else if (name(sh(son(par))) == uwordhd) {
724
	      rir_ins ( i_and, r, 65535, no ( par ) ) ;
751
	      rir_ins(i_and, r, 65535, no(par));
725
	    } 
752
	    }
726
	    else {
753
	    else {
727
	      rr_ins ( i_mov, r, no ( par ) ) ;
754
	      rr_ins(i_mov, r, no(par));
728
	    }
755
	    }
729
	  }
756
	  }
730
	} 
757
	}
731
	else {
758
	else {
732
	  /* Parameter in reg move to stack */
759
	  /* Parameter in reg move to stack */
733
	  baseoff stackpos ;
760
	  baseoff stackpos;
734
	  long size = shape_size ( sh ( son ( par ) ) ) ;
761
	  long size = shape_size(sh(son(par)));
735
	  int offs = ( int ) ( ( no ( son ( par ) ) +
762
	  int offs = (int)((no(son(par)) +
736
				 proc_state.params_offset ) >> 3 ) ;
763
				 proc_state.params_offset) >> 3);
737
	  stackpos.base = R_FP ;
764
	  stackpos.base = R_FP;
738
	  stackpos.offset =offs ;
765
	  stackpos.offset =offs;
739
 
766
 
740
	  switch ( size ) {
767
	  switch (size) {
741
	    case 8 : {
768
	    case 8: {
742
	      st_ro_ins ( i_stb, r, stackpos ) ;
769
	      st_ro_ins(i_stb, r, stackpos);
743
	      break ;
770
	      break;
744
	    }
771
	    }
745
	    case 16 : {
772
	    case 16: {
746
	      st_ro_ins ( i_sth, r, stackpos ) ;
773
	      st_ro_ins(i_sth, r, stackpos);
747
	      break ;
774
	      break;
748
	    }
775
	    }
749
	    case 32 : {
776
	    case 32: {
750
	      st_ro_ins ( i_st, r, stackpos ) ;
777
	      st_ro_ins(i_st, r, stackpos);
751
	      break ;
778
	      break;
752
	    }
779
	    }
753
	    case 64 : {
780
	    case 64: {
754
	      /* A double can be passed first word in reg
781
	      /* A double can be passed first word in reg
755
		 (R_I5) and second word on stack. Must only
782
		 (R_I5) and second word on stack. Must only
756
		 store out first word in this case  */
783
		 store out first word in this case  */
757
	      st_ro_ins ( i_st, r, stackpos ) ;
784
	      st_ro_ins(i_st, r, stackpos);
758
	      if ( r != R_I5 ) {
785
	      if (r != R_I5) {
759
		/* float point double passed in fixed
786
		/* float point double passed in fixed
760
		   point reg pair */
787
		   point reg pair */
761
		stackpos.offset += 4 ;
788
		stackpos.offset += 4;
762
		st_ro_ins ( i_st, r + 1, stackpos ) ;
789
		st_ro_ins(i_st, r + 1, stackpos);
763
	      }
790
	      }
764
	      break ;
791
	      break;
765
	    }
792
	    }
766
	    default : {
793
	    default : {
767
	      fail ( "bad size in make_proc_tag_code" ) ;
794
	      fail("bad size in make_proc_tag_code");
768
	      break ;
795
	      break;
769
	    }
796
	    }
770
	  }
797
	  }
771
	}
798
	}
772
      } 
799
      }
773
      else {
800
      else {
774
	/* Param on stack, no change */
801
	/* Param on stack, no change */
775
      }
802
      }
776
    }
803
    }
777
    par = bro ( son ( par ) ) ;
804
    par = bro(son(par));
778
  }
805
  }
779
 
806
 
780
  clear_all () ;
807
  clear_all();
781
  
808
 
782
    
809
 
783
    if ( ( pprops & long_result_bit ) != 0 ) {
810
    if ((pprops & long_result_bit)!= 0) {
784
      /* structure or union result, address of space to [ %fp+64 ] */
811
      /* structure or union result, address of space to [ %fp+64 ] */
785
      instore is ;
812
      instore is;
786
      /* [%fp+64] as per call convention */
813
      /* [%fp+64] as per call convention */
787
      is.adval = 0 ;
814
      is.adval = 0;
788
      is.b.base = R_FP ;
815
      is.b.base = R_FP;
789
      is.b.offset = ( 16 * 4 ) ;
816
      is.b.offset = (16 * 4);
790
      setinsalt ( proc_state.procans, is ) ;
817
      setinsalt(proc_state.procans, is);
791
    } 
818
    }
792
    else if ( ( pprops & realresult_bit ) != 0 ) {
819
    else if ((pprops & realresult_bit)!= 0) {
793
      /* proc has real result */
820
      /* proc has real result */
794
      freg frg ;
821
      freg frg;
795
      frg.fr = 0 ;
822
      frg.fr = 0;
796
      frg.dble = ( bool ) ( ( pprops & longrealresult_bit ) ? 1 : 0 ) ;
823
      frg.dble = (bool)((pprops & longrealresult_bit)? 1 : 0);
797
      setfregalt ( proc_state.procans, frg ) ;
824
      setfregalt(proc_state.procans, frg);
798
    } 
825
    }
799
    else if ( ( pprops & has_result_bit ) != 0 ) {
826
    else if ((pprops & has_result_bit)!= 0) {
800
      setregalt ( proc_state.procans, R_I0 ) ;
827
      setregalt(proc_state.procans, R_I0);
801
    } 
828
    }
802
    else {
829
    else {
803
      /* no result */
830
      /* no result */
804
      setregalt ( proc_state.procans, R_G0 ) ;
831
      setregalt(proc_state.procans, R_G0);
805
    }
832
    }
806
 
833
 
807
    proc_state.rscope_level = 0 ;
834
    proc_state.rscope_level = 0;
808
    proc_state.result_label = 0 ;
835
    proc_state.result_label = 0;
809
 
836
 
810
    /* code for body of proc */
837
    /* code for body of proc */
811
#if 1
838
#if 1
812
    if(!sysV_abi && do_dynamic_init && !strcmp(proc_name,"_main")) {
839
    if (!sysV_abi && do_dynamic_init && !strcmp(proc_name,"_main")) {
813
      call_tdf_main();
840
      call_tdf_main();
814
    }
841
    }
815
#endif    
842
#endif
816
    (void) code_here ( son ( e ), sp, nowhere ) ;
843
   (void)code_here(son(e), sp, nowhere);
817
    clear_all () ;
844
    clear_all();
818
    if (stackerr_lab){
845
    if (stackerr_lab) {
819
      set_label(stackerr_lab);
846
      set_label(stackerr_lab);
820
      fprintf ( as_file, "\t%s\n", i_restore ) ;     
847
      fprintf(as_file, "\t%s\n", i_restore);
821
      if(local_stackerr_lab) {
848
      if (local_stackerr_lab) {
822
	set_label(local_stackerr_lab);
849
	set_label(local_stackerr_lab);
823
      }
850
      }
824
      
851
 
825
      /*rir_ins(i_add,R_SP,proc_state.frame_size>>3,R_SP);*/
852
      /*rir_ins(i_add,R_SP,proc_state.frame_size>>3,R_SP);*/
826
      do_exception(f_stack_overflow);
853
      do_exception(f_stack_overflow);
827
    }
854
    }
828
    if (aritherr_lab != 0){
855
    if (aritherr_lab != 0) {
829
      set_label(aritherr_lab);
856
      set_label(aritherr_lab);
830
      do_exception(f_overflow);
857
      do_exception(f_overflow);
831
    }
858
    }
832
    
859
 
833
#ifndef RET_IN_CODE
860
#ifndef RET_IN_CODE
834
    if (proc_state.result_label !=0){
861
    if (proc_state.result_label !=0) {
835
      set_label ( proc_state.result_label ) ;
862
      set_label(proc_state.result_label);
836
#ifdef NEWDWARF
863
#ifdef NEWDWARF
837
      if (dwarf2)
864
      if (dwarf2)
838
        dw2_return_pos (0);
865
        dw2_return_pos(0);
839
#endif
866
#endif
840
      ret_restore_ins () ;
867
      ret_restore_ins();
841
    }
868
    }
842
#endif	
869
#endif
843
#ifdef NEWDWARF
870
#ifdef NEWDWARF
844
    if (dwarf2)
871
    if (dwarf2)
845
      dw2_complete_fde ();
872
      dw2_complete_fde();
846
#endif    
873
#endif
847
    proc_state = old_proc_state ;
874
    proc_state = old_proc_state;
848
    return ( mka ) ;
875
    return(mka);
849
}
876
}
850
 
877
 
851
 
878
 
852
 
879
 
853
/*
880
/*
854
  ENCODE A PROCEDURE RESULT
881
  ENCODE A PROCEDURE RESULT
855
*/
882
*/
856
 
883
 
857
makeans make_res_tag_code 
884
makeans make_res_tag_code
858
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
859
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
885
(exp e, space sp, where dest, int exitlab) {
860
  where w ;
886
  where w;
861
  makeans mka ;
887
  makeans mka;
862
  mka.lab = exitlab ;
888
  mka.lab = exitlab;
863
  mka.regmove = NOREG ;
889
  mka.regmove = NOREG;
864
  assert ( name ( e ) == res_tag || name(e) == untidy_return_tag) ;
890
  assert(name(e) == res_tag || name(e) == untidy_return_tag);
865
  w.answhere = proc_state.procans ;
891
  w.answhere = proc_state.procans;
866
  w.ashwhere = ashof ( sh ( son ( e ) ) ) ;
892
  w.ashwhere = ashof(sh(son(e)));
867
  ( void ) code_here ( son ( e ), sp, w ) ;
893
 (void)code_here(son(e), sp, w);
868
  assert(proc_state.rscope_level == 0);
894
  assert(proc_state.rscope_level == 0);
869
				/* procedure return */
895
				/* procedure return */
870
  switch ( discrim ( w.answhere ) ){
896
  switch (discrim(w.answhere)) {
871
    case notinreg : {
897
    case notinreg: {
872
      instore isw ;
898
      instore isw;
873
      isw = insalt ( w.answhere ) ;
899
      isw = insalt(w.answhere);
874
      /* [%fp+64] as per call convention */
900
      /* [%fp+64] as per call convention */
875
      if ( isw.adval == 0 && isw.b.base == R_FP &&
901
      if (isw.adval == 0 && isw.b.base == R_FP &&
876
	   isw.b.offset == ( 16 * 4 ) ) {
902
	   isw.b.offset == (16 * 4)) {
877
	/* struct or union result */
903
	/* struct or union result */
878
#ifdef NEWDWARF
904
#ifdef NEWDWARF
879
	if (dwarf2)
905
	if (dwarf2)
880
	  dw2_return_pos (0);
906
	  dw2_return_pos(0);
881
#endif
907
#endif
882
	stret_restore_ins () ;
908
	stret_restore_ins();
883
	break ;
909
	break;
884
      }	
910
      }
885
	   /* FALL THROUGH */
911
	   /* FALL THROUGH */
886
    }
912
    }
887
    default : 
913
    default :
888
    {
914
    {
889
      /* not struct or union result */
915
      /* not struct or union result */
890
      if ( proc_state.leaf_proc && name(e) == res_tag && !sysV_assembler
916
      if (proc_state.leaf_proc && name(e) == res_tag && !sysV_assembler
891
#ifdef NEWDIAGS
917
#ifdef NEWDIAGS
892
		&& !diag_visible) {
918
		&& !diag_visible) {
893
#else
919
#else
894
		&& !diagnose) {
920
		&& !diagnose) {
895
#endif
921
#endif
Line 897... Line 923...
897
	   for the peep-hole assembler 'as -O' to recognise
923
	   for the peep-hole assembler 'as -O' to recognise
898
	   leaf procs (not applicable in SunOS
924
	   leaf procs (not applicable in SunOS
899
	   5 assembler).  Empirical tests show that using last
925
	   5 assembler).  Empirical tests show that using last
900
	   return is very slightly faster for SPECint tests
926
	   return is very slightly faster for SPECint tests
901
		- but beware of confusing diagnostic info */
927
		- but beware of confusing diagnostic info */
902
	if ( proc_state.result_label == 0 ) {
928
	if (proc_state.result_label == 0) {
903
	  /* first return in proc, generate return */
929
	  /* first return in proc, generate return */
904
	  proc_state.result_label = new_label () ;
930
	  proc_state.result_label = new_label();
905
	  /* first return in a leaf proc is ret_restore,
931
	  /* first return in a leaf proc is ret_restore,
906
	     others branch here */
932
	     others branch here */
907
#if RET_IN_CODE
933
#if RET_IN_CODE
908
	  set_label ( proc_state.result_label ) ;
934
	  set_label(proc_state.result_label);
909
	  {
935
	  {
910
	    baseoff b;
936
	    baseoff b;
911
	    b.base = R_FP;
937
	    b.base = R_FP;
912
#if 0
938
#if 0
913
	    if(Has_vcallees){
939
	    if (Has_vcallees) {
914
	      baseoff b;
940
	      baseoff b;
915
	      b.base = R_FP;
941
	      b.base = R_FP;
916
	      b.offset = -4 * PTR_SZ>>3;
942
	      b.offset = -4 * PTR_SZ>>3;
917
	      ld_ro_ins(i_ld,b,local_reg);
943
	      ld_ro_ins(i_ld,b,local_reg);
918
	    }
944
	    }
919
#endif
945
#endif
920
	  }
946
	  }
921
#ifdef NEWDWARF
947
#ifdef NEWDWARF
922
	  if (dwarf2)
948
	  if (dwarf2)
923
	    dw2_return_pos (0);
949
	    dw2_return_pos(0);
924
#endif
950
#endif
925
	  if(name(e) == res_tag) {
951
	  if (name(e) == res_tag) {
926
	    ret_restore_ins () ;
952
	    ret_restore_ins();
927
	  }
953
	  }
928
	  else {
954
	  else {
929
	    fprintf ( as_file, "\t%s\n", i_ret );
955
	    fprintf(as_file, "\t%s\n", i_ret);
930
#ifdef NEWDWARF
956
#ifdef NEWDWARF
931
	    if (dwarf2)
957
	    if (dwarf2)
932
	      count_ins(1);
958
	      count_ins(1);
933
#endif
959
#endif
934
	    rir_ins(i_restore,R_SP,-proc_state.maxargs>>3,R_SP);
960
	    rir_ins(i_restore,R_SP,-proc_state.maxargs>>3,R_SP);
935
	  }
961
	  }
936
	
962
 
937
#else
963
#else
938
	  uncond_ins ( i_b, proc_state.result_label ) ;
964
	  uncond_ins(i_b, proc_state.result_label);
939
#endif
965
#endif
940
	} 
966
	}
941
	else {
967
	else {
942
	  /* jump to the return for this proc */
968
	  /* jump to the return for this proc */
943
	  uncond_ins ( i_b, proc_state.result_label ) ;
969
	  uncond_ins(i_b, proc_state.result_label);
944
	}
970
	}
945
      } 
971
      }
946
      else {
972
      else {
947
	baseoff b;
973
	baseoff b;
948
	b.base = R_FP;
974
	b.base = R_FP;
949
#if 0
975
#if 0
950
	if(Has_vcallees){
976
	if (Has_vcallees) {
951
	  baseoff b;
977
	  baseoff b;
952
	  b.base = R_FP;
978
	  b.base = R_FP;
953
	  b.offset = -4 * PTR_SZ>>3;
979
	  b.offset = -4 * PTR_SZ>>3;
954
	  ld_ro_ins(i_ld,b,local_reg);
980
	  ld_ro_ins(i_ld,b,local_reg);
955
	}
981
	}
956
#endif
982
#endif
957
	/* return here, avoiding cost of branch to return */
983
	/* return here, avoiding cost of branch to return */
958
#ifdef NEWDWARF
984
#ifdef NEWDWARF
959
	if (dwarf2)
985
	if (dwarf2)
960
	  dw2_return_pos (0);
986
	  dw2_return_pos(0);
961
#endif
987
#endif
962
	if(name(e) == res_tag) {
988
	if (name(e) == res_tag) {
963
	  ret_restore_ins () ;
989
	  ret_restore_ins();
964
	}
990
	}
965
	else {
991
	else {
966
	  fprintf ( as_file, "\t%s\n", i_ret );
992
	  fprintf(as_file, "\t%s\n", i_ret);
967
#ifdef NEWDWARF
993
#ifdef NEWDWARF
968
	  if (dwarf2)
994
	  if (dwarf2)
969
	    count_ins(1);
995
	    count_ins(1);
970
#endif
996
#endif
971
	  rir_ins(i_restore,R_SP,-proc_state.maxargs>>3,R_SP);
997
	  rir_ins(i_restore,R_SP,-proc_state.maxargs>>3,R_SP);
972
	  /*fprintf ( as_file, "\t%s,\%sp,0,\%sp\n", i_restore ) ;*/
998
	  /*fprintf ( as_file, "\t%s,\%sp,0,\%sp\n", i_restore ) ;*/
973
	}
999
	}
974
	/*      ret_restore_ins () ;*/
1000
	/*      ret_restore_ins () ;*/
975
      }
1001
      }
976
    }
1002
    }
977
  }
1003
  }
978
  /* regs invalid after return (what about inlining?) */
1004
  /* regs invalid after return (what about inlining?) */
979
  clear_all () ;	
1005
  clear_all();
980
  return ( mka ) ;
1006
  return(mka);
981
}
1007
}
982
 
1008
 
983
 
1009
 
984
/*
1010
/*
985
  ENCODE A PROCEDURE CALL
1011
  ENCODE A PROCEDURE CALL
986
*/
1012
*/
987
extern int reg_result PROTO_S ( ( shape ) ) ;
1013
extern int reg_result(shape);
988
 
1014
 
989
makeans make_apply_tag_code 
1015
makeans make_apply_tag_code
990
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
991
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
1016
(exp e, space sp, where dest, int exitlab) {
992
  exp fn = son ( e ) ;
1017
  exp fn = son(e);
993
  exp par = bro ( fn ) ;
1018
  exp par = bro(fn);
994
  exp list = par ;
1019
  exp list = par;
995
  int hda = ( int ) name ( sh ( e ) ) ;
1020
  int hda = (int)name(sh(e));
996
  int special ;
1021
  int special;
997
  int param_reg = R_O0 ;	 /* next param reg to use */
1022
  int param_reg = R_O0 ;	 /* next param reg to use */
998
  int param_regs_used ;	 /* how many were used */
1023
  int param_regs_used ;	 /* how many were used */
999
  ash ansash ;
1024
  ash ansash;
1000
  space nsp ;
1025
  space nsp;
1001
  int void_result = (( name ( sh ( e ) ) == tophd ) ||
1026
  int void_result = ((name(sh(e)) == tophd) ||
1002
		     ( name ( sh ( e ) ) == bothd));
1027
		    (name(sh(e)) == bothd));
1003
    
-
 
1004
  int reg_res = reg_result ( sh ( e ) ) ;
-
 
1005
  int guarded_dest_reg = R_NO_REG ;/* reg used to address tuple result */
-
 
1006
  makeans mka ;
-
 
1007
 
1028
 
1008
  exp dad = father ( e ) ;
1029
  int reg_res = reg_result(sh(e));
1009
  bool tlrecurse = ( bool ) ( proc_state.rscope_level == 0 &&
1030
  int guarded_dest_reg = R_NO_REG ;/* reg used to address tuple result */
1010
			      name ( dad ) == res_tag && props ( dad ) ) ;
1031
  makeans mka;
1011
 
1032
 
1012
  nsp = sp ;
1033
  exp dad = father(e);
-
 
1034
  bool tlrecurse = (bool)(proc_state.rscope_level == 0 &&
-
 
1035
			      name(dad) == res_tag && props(dad));
1013
 
1036
 
-
 
1037
  nsp = sp;
-
 
1038
 
1014
  mka.lab = exitlab ;
1039
  mka.lab = exitlab;
1015
  mka.regmove = NOREG ;
1040
  mka.regmove = NOREG;
1016
  assert ( name ( e ) == apply_tag ) ;
1041
  assert(name(e) == apply_tag);
1017
 
1042
 
1018
  /* first see if it is a special to be handled inline */
1043
  /* first see if it is a special to be handled inline */
1019
  if ( ( special = specialfn ( fn ) ) > 0 ) {
1044
  if ((special = specialfn(fn)) > 0) {
1020
    /* eg function is strlen */
1045
    /* eg function is strlen */
1021
    mka.lab = specialmake ( special, list, sp, dest, exitlab ) ;
1046
    mka.lab = specialmake(special, list, sp, dest, exitlab);
1022
    return ( mka ) ;
1047
    return(mka);
1023
  }
1048
  }
1024
 
1049
 
1025
  ansash = ashof ( sh ( e ) ) ;
1050
  ansash = ashof(sh(e));
1026
 
-
 
1027
  if ( !reg_res && !void_result ) {
-
 
1028
    /* structure or union result, address of space to [%sp+64] 
-
 
1029
     must do this before evaluating args as dest may use param reg */
-
 
1030
    instore is ;
-
 
1031
    baseoff stack_struct_ret_addr ;
-
 
1032
 
1051
 
-
 
1052
  if (!reg_res && !void_result) {
-
 
1053
    /* structure or union result, address of space to [%sp+64]
-
 
1054
     must do this before evaluating args as dest may use param reg */
-
 
1055
    instore is;
-
 
1056
    baseoff stack_struct_ret_addr;
-
 
1057
 
1033
    /* [%sp+64] as per call convention */
1058
    /* [%sp+64] as per call convention */
1034
    stack_struct_ret_addr.base = R_SP ;
1059
    stack_struct_ret_addr.base = R_SP;
1035
    stack_struct_ret_addr.offset = ( 16 * 4 ) ;
1060
    stack_struct_ret_addr.offset = (16 * 4);
1036
 
1061
 
1037
    assert ( discrim ( dest.answhere ) == notinreg ) ;
1062
    assert(discrim(dest.answhere) == notinreg);
1038
    if(discrim(dest.answhere) != notinreg){	/* should be redundant */
1063
    if(discrim(dest.answhere) != notinreg){	/* should be redundant */
1039
      is.b = mem_temp(0);
1064
      is.b = mem_temp(0);
1040
      is.adval = 1;
1065
      is.adval = 1;
1041
    }
1066
    }
1042
    else{
1067
    else{
1043
      is = insalt ( dest.answhere ) ;
1068
      is = insalt(dest.answhere);
1044
    }
1069
    }
1045
    if ( is.adval ) {
1070
    if (is.adval) {
1046
      /* generate address of dest */
1071
      /* generate address of dest */
1047
      if ( IS_FIXREG ( is.b.base ) ) {
1072
      if (IS_FIXREG(is.b.base)) {
1048
	if ( is.b.offset == 0 ) {
1073
	if (is.b.offset == 0) {
1049
	  st_ro_ins ( i_st, is.b.base, stack_struct_ret_addr ) ;
1074
	  st_ro_ins(i_st, is.b.base, stack_struct_ret_addr);
1050
	} 
1075
	}
1051
	else {
1076
	else {
1052
	  rir_ins ( i_add, is.b.base, is.b.offset, R_TMP ) ;
1077
	  rir_ins(i_add, is.b.base, is.b.offset, R_TMP);
1053
	  st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1078
	  st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1054
	}
1079
	}
1055
	guarded_dest_reg = is.b.base ;	/* can be guarded */
1080
	guarded_dest_reg = is.b.base ;	/* can be guarded */
1056
      } 
1081
      }
1057
      else {
1082
      else {
1058
	set_ins ( is.b, R_TMP ) ;
1083
	set_ins(is.b, R_TMP);
1059
	st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1084
	st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1060
      }
1085
      }
1061
    } 
1086
    }
1062
    else {
1087
    else {
1063
      /* load dest */
1088
      /* load dest */
1064
      ld_ins ( i_ld, is.b, R_TMP ) ;
1089
      ld_ins(i_ld, is.b, R_TMP);
1065
      st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1090
      st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1066
    }
1091
    }
1067
  }
1092
  }
1068
 
1093
 
1069
 
1094
 
1070
  /* evaluate params to param reg or stack */
1095
  /* evaluate params to param reg or stack */
1071
  if ( !last ( fn ) ) {
1096
  if (!last(fn)) {
1072
    int param_offset = ( 16 + 1 ) * 32 ;
1097
    int param_offset = (16 + 1)* 32;
1073
    /* beyond reg window save area and hidden param of caller's frame */
1098
    /* beyond reg window save area and hidden param of caller's frame */
1074
 
1099
 
1075
    /* evaluate parameters in turn */
1100
    /* evaluate parameters in turn */
1076
    for ( ; ; ) {
1101
    for (; ;) {
1077
      ash ap ;
1102
      ash ap;
1078
      where w ;
1103
      where w;
1079
      shape a = sh ( list ) ;
1104
      shape a = sh(list);
1080
      int hd = ( int ) name ( a ) ;
1105
      int hd = (int)name(a);
1081
      ap = ashof ( a ) ;
1106
      ap = ashof(a);
1082
      w.ashwhere = ap ;
1107
      w.ashwhere = ap;
1083
 
1108
 
1084
      if ( 0 /*struct_par*/ ) {
1109
      if ( 0 /*struct_par*/ ) {
1085
	/* non-ABI construct being used - give stronger warning */
1110
	/* non-ABI construct being used - give stronger warning */
1086
	if ( sysV_abi ) fail ( "Structure parameter passed by value" ) ;
1111
	if (sysV_abi)fail("Structure parameter passed by value");
1087
      }
1112
      }
1088
 
1113
 
1089
      if ( is_floating ( hd ) && param_reg <= R_O5 ) {
1114
      if (is_floating(hd) && param_reg <= R_O5) {
1090
	/* Float point. Copy to stack as if stack parameter,
1115
	/* Float point. Copy to stack as if stack parameter,
1091
	   then recover words as needed into fixed point regs */
1116
	   then recover words as needed into fixed point regs */
1092
	instore is ;
1117
	instore is;
1093
	/* Locations we offer may not be aligned for doubles.  We
1118
	/* Locations we offer may not be aligned for doubles.  We
1094
	   assume 'move' can cope with this */
1119
	   assume 'move' can cope with this */
1095
	is.b.base = R_SP ;
1120
	is.b.base = R_SP;
1096
	is.b.offset = param_offset >> 3 ;
1121
	is.b.offset = param_offset >> 3;
1097
	is.adval = 1 ;
1122
	is.adval = 1;
1098
 
1123
 
1099
	setinsalt ( w.answhere, is ) ;
1124
	setinsalt(w.answhere, is);
1100
	( void ) code_here ( list, nsp, w ) ;
1125
	(void)code_here(list, nsp, w);
1101
	ld_ro_ins ( i_ld, is.b, param_reg ) ;
1126
	ld_ro_ins(i_ld, is.b, param_reg);
1102
	nsp = guardreg ( param_reg, nsp ) ;
1127
	nsp = guardreg(param_reg, nsp);
1103
	param_reg++ ;     
1128
	param_reg++;
1104
	param_offset += 32 ;
1129
	param_offset += 32;
1105
 
1130
 
1106
	if ( hd != shrealhd ) {
1131
	if (hd != shrealhd) {
1107
	  /* double */
1132
	  /* double */
1108
	  if ( param_reg <= R_O5 ) {
1133
	  if (param_reg <= R_O5) {
1109
	    /* double whose second word can go in reg */
1134
	    /* double whose second word can go in reg */
1110
	    is.b.offset += 4 ;
1135
	    is.b.offset += 4;
1111
	    ld_ro_ins ( i_ld, is.b, param_reg ) ;
1136
	    ld_ro_ins(i_ld, is.b, param_reg);
1112
	    nsp = guardreg ( param_reg, nsp ) ;
1137
	    nsp = guardreg(param_reg, nsp);
1113
	    param_reg++ ;
1138
	    param_reg++;
1114
	  }
1139
	  }
1115
	  param_offset += 32 ;
1140
	  param_offset += 32;
1116
	}
1141
	}
1117
      } 
1142
      }
1118
      else if ( valregable ( sh ( list ) ) && param_reg <= R_O5 ) {
1143
      else if (valregable(sh(list)) && param_reg <= R_O5) {
1119
	/* fixed point parameter in a single reg */
1144
	/* fixed point parameter in a single reg */
1120
	nsp = guardreg ( param_reg, nsp ) ;
1145
	nsp = guardreg(param_reg, nsp);
1121
	reg_operand_here ( list, nsp, param_reg ) ;
1146
	reg_operand_here(list, nsp, param_reg);
1122
	param_reg++ ;     
1147
	param_reg++;
1123
	param_offset += 32 ;
1148
	param_offset += 32;
1124
      } 
1149
      }
1125
      else {
1150
      else {
1126
	/* stack parameter */
1151
	/* stack parameter */
1127
	instore is ;
1152
	instore is;
1128
	/* Locations we offer may not be aligned for doubles.
1153
	/* Locations we offer may not be aligned for doubles.
1129
	   We assume 'move' can cope with this  */
1154
	   We assume 'move' can cope with this  */
1130
	is.b.base = R_SP ;
1155
	is.b.base = R_SP;
1131
	is.b.offset = param_offset >> 3 ;
1156
	is.b.offset = param_offset >> 3;
1132
	is.adval = 1 ;
1157
	is.adval = 1;
1133
	if ( valregable ( sh ( list ) ) &&
1158
	if (valregable(sh(list)) &&
1134
	     ( ap.ashsize == 8 || ap.ashsize == 16 ) ) {
1159
	    (ap.ashsize == 8 || ap.ashsize == 16)) {
1135
	  /* Byte or 16bit scalar parameter - convert to integer.
1160
	  /* Byte or 16bit scalar parameter - convert to integer.
1136
	     We must pass a full word to conform with SPARC ABI,
1161
	     We must pass a full word to conform with SPARC ABI,
1137
	     so have to expand source to full word.  We do this
1162
	     so have to expand source to full word.  We do this
1138
	     by loading into a reg */
1163
	     by loading into a reg */
1139
	  int r = reg_operand ( list, nsp ) ;
1164
	  int r = reg_operand(list, nsp);
1140
	  ans op ;
1165
	  ans op;
1141
	  setregalt ( op, r ) ;
1166
	  setregalt(op, r);
1142
	  /* round down to word boundary */
1167
	  /* round down to word boundary */
1143
	  is.b.offset &= ~0x3 ;
1168
	  is.b.offset &= ~0x3;
1144
	  ap.ashsize = ap.ashalign = 32 ;
1169
	  ap.ashsize = ap.ashalign = 32;
1145
	  w.ashwhere = ap ;
1170
	  w.ashwhere = ap;
1146
	  setinsalt ( w.answhere, is ) ;
1171
	  setinsalt(w.answhere, is);
1147
	  ( void ) move ( op, w, guardreg ( r, nsp ).fixed, 1 ) ;
1172
	 (void)move(op, w, guardreg(r, nsp).fixed, 1);
1148
	} 
-
 
1149
	else {
-
 
1150
	  setinsalt ( w.answhere, is ) ;
-
 
1151
	  ( void ) code_here ( list, nsp, w ) ;
-
 
1152
	}
1173
	}
-
 
1174
	else {
-
 
1175
	  setinsalt(w.answhere, is);
-
 
1176
	 (void)code_here(list, nsp, w);
-
 
1177
	}
1153
	param_offset = ( int ) ( param_offset + ap.ashsize ) ;
1178
	param_offset = (int)(param_offset + ap.ashsize);
1154
      }
1179
      }
1155
 
1180
 
1156
      if ( last ( list ) ) break ;
1181
      if (last(list))break;
1157
      list = bro ( list ) ;
1182
      list = bro(list);
1158
    }
1183
    }
1159
  }
1184
  }
1160
 
1185
 
1161
  assert ( param_reg >= R_O0 && param_reg <= R_O5 + 1 ) ;
1186
  assert(param_reg >= R_O0 && param_reg <= R_O5 + 1);
1162
  param_regs_used = param_reg - R_O0 ;
1187
  param_regs_used = param_reg - R_O0;
1163
 
1188
 
1164
  if ( special != 0 ) {
1189
  if (special != 0) {
1165
    extj_special_ins ( i_call, special_call_name ( special ),
1190
    extj_special_ins(i_call, special_call_name(special),
1166
		       param_regs_used ) ;
1191
		       param_regs_used);
1167
  } 
1192
  }
1168
  else if ( name ( fn ) == name_tag &&
1193
  else if (name(fn) == name_tag &&
1169
	      name ( son ( fn ) ) == ident_tag &&
1194
	      name(son(fn)) == ident_tag &&
1170
	      ( son ( son ( fn ) ) == nilexp ||
1195
	     (son(son(fn)) == nilexp ||
1171
		(name ( son ( son ( fn ) ) ) == proc_tag || 
1196
		(name(son(son(fn))) == proc_tag ||
1172
		 name(son(son(fn))) == general_proc_tag)) ) {
1197
		 name(son(son(fn))) == general_proc_tag))) {
1173
    baseoff b ;
1198
    baseoff b;
1174
    b = boff ( son ( fn ) ) ;
1199
    b = boff(son(fn));
1175
    if ( !tlrecurse ) {
1200
    if (!tlrecurse) {
1176
#ifdef NEWDWARF
1201
#ifdef NEWDWARF
1177
      if (current_dg_info) {
1202
      if (current_dg_info) {
1178
	current_dg_info->data.i_call.brk = set_dw_text_label ();
1203
	current_dg_info->data.i_call.brk = set_dw_text_label();
1179
	current_dg_info->data.i_call.p.k = WH_CODELAB;
1204
	current_dg_info->data.i_call.p.k = WH_CODELAB;
1180
	current_dg_info->data.i_call.p.u.l = b.base;
1205
	current_dg_info->data.i_call.p.u.l = b.base;
1181
	current_dg_info->data.i_call.p.o = b.offset;
1206
	current_dg_info->data.i_call.p.o = b.offset;
1182
      }
1207
      }
1183
#endif
1208
#endif
1184
      extj_ins ( i_call, b, param_regs_used ) ;
1209
      extj_ins(i_call, b, param_regs_used);
1185
    } 
1210
    }
1186
    else {
1211
    else {
1187
      assert ( !tlrecurse ) ;
1212
      assert(!tlrecurse);
1188
    }
1213
    }
1189
  } 
1214
  }
1190
  else {
1215
  else {
1191
    int r = reg_operand ( fn, nsp ) ;
1216
    int r = reg_operand(fn, nsp);
1192
#ifdef NEWDWARF
1217
#ifdef NEWDWARF
1193
    if (current_dg_info) {
1218
    if (current_dg_info) {
1194
      current_dg_info->data.i_call.brk = set_dw_text_label ();
1219
      current_dg_info->data.i_call.brk = set_dw_text_label();
1195
      current_dg_info->data.i_call.p.k = WH_REG;
1220
      current_dg_info->data.i_call.p.k = WH_REG;
1196
      current_dg_info->data.i_call.p.u.l = r;
1221
      current_dg_info->data.i_call.p.u.l = r;
1197
    }
1222
    }
1198
#endif
1223
#endif
1199
    extj_reg_ins ( i_call, r, param_regs_used ) ;
1224
    extj_reg_ins(i_call, r, param_regs_used);
1200
  }
1225
  }
1201
 
1226
 
1202
  if ( !reg_res && !void_result ) {
1227
  if (!reg_res && !void_result) {
1203
    /* Generate unimp instruction, as per structure result call
1228
    /* Generate unimp instruction, as per structure result call
1204
       convention.  Argument is low-order 12 bits of structure size,
1229
       convention.  Argument is low-order 12 bits of structure size,
1205
       see section D.4 of * SPARC architecture manual */
1230
       see section D.4 of * SPARC architecture manual */
1206
    unimp_ins ( ( long ) ( ( ansash.ashsize / 8 ) & 0xfff ) ) ;
1231
    unimp_ins((long)((ansash.ashsize / 8) & 0xfff));
1207
  }
1232
  }
1208
 
1233
 
1209
#ifdef NEWDWARF
1234
#ifdef NEWDWARF
1210
  if (dwarf2)
1235
  if (dwarf2)
1211
    START_BB ();
1236
    START_BB();
1212
#endif
1237
#endif
1213
 
1238
 
1214
  /* grab clobbered %g and %o regs, as safety test for bad code */
1239
  /* grab clobbered %g and %o regs, as safety test for bad code */
1215
  {
1240
  {
1216
    int r ;
1241
    int r;
1217
    space gsp ;
1242
    space gsp;
1218
    gsp = sp ;
1243
    gsp = sp;
1219
 
1244
 
1220
    /* %g1..%g_reg_max, %o0..%o7 */
1245
    /* %g1..%g_reg_max, %o0..%o7 */
1221
    for ( r = R_G1 ; r < R_O7 + 1 ;
1246
    for (r = R_G1; r < R_O7 + 1;
1222
		     r = ( ( r == R_G0 + g_reg_max ) ? R_O0 : r + 1 ) ) {
1247
		     r = ((r == R_G0 + g_reg_max)? R_O0 : r + 1)) {
1223
      /* skip R_O0 as often used in result-reg optimisation */
1248
      /* skip R_O0 as often used in result-reg optimisation */
1224
      if ( !( r == R_TMP || r == R_O0 || r == R_SP ||
1249
      if (!(r == R_TMP || r == R_O0 || r == R_SP ||
1225
	      r == guarded_dest_reg ) ) {
1250
	      r == guarded_dest_reg)) {
1226
	/* not special regs */
1251
	/* not special regs */
1227
	gsp = needreg ( r, gsp ) ;
1252
	gsp = needreg(r, gsp);
1228
      }
1253
      }
1229
    }
1254
    }
1230
  }
1255
  }
1231
  clear_all () ;	/* ??? not %i0..%l7 that may be t-regs */
1256
  clear_all () ;	/* ??? not %i0..%l7 that may be t-regs */
1232
 
1257
 
1233
  if ( reg_res ) {
1258
  if (reg_res) {
1234
    ans aa ;
1259
    ans aa;
1235
    if ( is_floating ( hda ) ) {
1260
    if (is_floating(hda)) {
1236
      freg frg ;
1261
      freg frg;
1237
      frg.fr = 0 ;
1262
      frg.fr = 0;
1238
      frg.dble = ( bool ) ( hda != shrealhd ) ;
1263
      frg.dble = (bool)(hda != shrealhd);
1239
      setfregalt ( aa, frg ) ;
1264
      setfregalt(aa, frg);
1240
      /* move floating point result of application to destination */
1265
      /* move floating point result of application to destination */
1241
      ( void ) move ( aa, dest, sp.fixed, 1 ) ;
1266
     (void)move(aa, dest, sp.fixed, 1);
1242
    } 
1267
    }
1243
    else {
1268
    else {
1244
      setregalt ( aa, R_O0 ) ;
1269
      setregalt(aa, R_O0);
1245
      if ( discrim ( dest.answhere ) == inreg ) {
1270
      if (discrim(dest.answhere) == inreg) {
1246
	int r = regalt ( dest.answhere ) ;
1271
	int r = regalt(dest.answhere);
1247
	if ( r == R_G0 ) {
1272
	if (r == R_G0) {
1248
	  /* void result */
1273
	  /* void result */
1249
	}
1274
	}
1250
	else if ( r != R_O0 ) {
1275
	else if (r != R_O0) {
1251
	  /* move result from %o0 */
1276
	  /* move result from %o0 */
1252
	  ( void ) move ( aa, dest, sp.fixed, 1 ) ;
1277
	 (void)move(aa, dest, sp.fixed, 1);
1253
	} 
1278
	}
1254
	else {
1279
	else {
1255
	  /* no move required */
1280
	  /* no move required */
1256
	}
1281
	}
1257
	mka.regmove = R_O0 ;
1282
	mka.regmove = R_O0;
1258
      } 
1283
      }
1259
      else {
1284
      else {
1260
	( void ) move ( aa, dest, sp.fixed, 1 ) ;
1285
	(void)move(aa, dest, sp.fixed, 1);
1261
      }
1286
      }
1262
    }
1287
    }
1263
  } 
1288
  }
1264
  else {
1289
  else {
1265
    /* not register result */
1290
    /* not register result */
1266
  }
1291
  }
1267
  return ( mka ) ;
1292
  return(mka);
1268
}
1293
}
1269
 
1294
 
1270
 
1295
 
1271
static space do_callers 
1296
static space do_callers
1272
    PROTO_N ( ( list, sp, param_reg, trad_call ) )
-
 
1273
    PROTO_T ( exp list X space sp X int* param_reg X bool trad_call ){
1297
(exp list, space sp, int* param_reg, bool trad_call) {
1274
  int param_offset = (16+1)*32; /* beyond reg window save area & 
1298
  int param_offset = (16+1)*32; /* beyond reg window save area &
1275
				 hidden param of callers frame */
1299
				 hidden param of callers frame */
1276
  int last_reg;
1300
  int last_reg;
1277
#ifdef GENCOMPAT
1301
#ifdef GENCOMPAT
1278
  if (!trad_call) {
1302
  if (!trad_call) {
1279
#else
1303
#else
1280
  if(in_general_proc) {
1304
  if (in_general_proc) {
1281
#endif
1305
#endif
1282
    if(vc_call) {
1306
    if (vc_call) {
1283
      last_reg = R_O3;
1307
      last_reg = R_O3;
1284
    }
1308
    }
1285
    else {
1309
    else {
1286
      last_reg = R_O4;
1310
      last_reg = R_O4;
1287
    }
1311
    }
1288
  }
1312
  }
1289
  else {
1313
  else {
1290
    last_reg = R_O5;
1314
    last_reg = R_O5;
1291
  }
1315
  }
1292
  
1316
 
1293
  for(;;){
1317
  for (;;) {
1294
    ash ap;
1318
    ash ap;
1295
    where w;
1319
    where w;
1296
    shape a = sh(list);
1320
    shape a = sh(list);
1297
    int hd = (int)name(a);
1321
    int hd = (int)name(a);
1298
    exp par = (name(list) == caller_tag)?son(list) : list;
1322
    exp par = (name(list) == caller_tag)?son(list): list;
1299
    ap = ashof(a);
1323
    ap = ashof(a);
1300
    w.ashwhere = ap;
1324
    w.ashwhere = ap;
1301
    if(is_floating(hd) && *param_reg <= last_reg){
1325
    if (is_floating(hd) && *param_reg <= last_reg) {
1302
      /* floating pt.  Copy to stack as if stack param then recover
1326
      /* floating pt.  Copy to stack as if stack param then recover
1303
	 into fixed point reg */
1327
	 into fixed point reg */
1304
      instore is;
1328
      instore is;
1305
      is.b.base = R_SP;
1329
      is.b.base = R_SP;
1306
      is.b.offset = param_offset>>3;
1330
      is.b.offset = param_offset>>3;
1307
      is.adval = 1;
1331
      is.adval = 1;
1308
      setinsalt(w.answhere,is);
1332
      setinsalt(w.answhere,is);
1309
      (void)code_here ( par, sp, w ) ;
1333
     (void)code_here(par, sp, w);
1310
      if(hd == doublehd){
1334
      if (hd == doublehd) {
1311
	rir_ins(i_add,is.b.base,is.b.offset,*param_reg);
1335
	rir_ins(i_add,is.b.base,is.b.offset,*param_reg);
1312
      }
1336
      }
1313
      else {
1337
      else {
1314
	ld_ro_ins ( i_ld, is.b, *param_reg ) ;
1338
	ld_ro_ins(i_ld, is.b, *param_reg);
1315
      }
1339
      }
1316
      sp = guardreg ( *param_reg, sp ) ;
1340
      sp = guardreg(*param_reg, sp);
1317
      (*param_reg)++ ;     
1341
     (*param_reg) ++;
1318
      param_offset += 32 ;
1342
      param_offset += 32;
1319
      if ( hd == realhd ) {
1343
      if (hd == realhd) {
1320
	/* double */
1344
	/* double */
1321
	if ( *param_reg <= last_reg ) {
1345
	if (*param_reg <= last_reg) {
1322
	  /* double whose second word can go in reg */
1346
	  /* double whose second word can go in reg */
1323
	  is.b.offset += 4 ;
1347
	  is.b.offset += 4;
1324
	  ld_ro_ins ( i_ld, is.b, *param_reg ) ;
1348
	  ld_ro_ins(i_ld, is.b, *param_reg);
1325
	  sp = guardreg (* param_reg, sp ) ;
1349
	  sp = guardreg(* param_reg, sp);
1326
	  (*param_reg)++ ;
1350
	 (*param_reg) ++;
1327
	}
1351
	}
1328
	param_offset += 32 ;
1352
	param_offset += 32;
1329
      }
1353
      }
1330
    } 
1354
    }
1331
    else if ( valregable ( sh ( list ) ) && *param_reg <= last_reg ) {
1355
    else if (valregable(sh(list)) && *param_reg <= last_reg) {
1332
      /* fixed point parameter in a single reg */
1356
      /* fixed point parameter in a single reg */
1333
      sp = guardreg ( *param_reg, sp ) ;
1357
      sp = guardreg(*param_reg, sp);
1334
      reg_operand_here ( list, sp, *param_reg ) ;
1358
      reg_operand_here(list, sp, *param_reg);
1335
      (*param_reg)++ ;     
1359
     (*param_reg) ++;
1336
      param_offset += 32 ;
1360
      param_offset += 32;
1337
    } 
1361
    }
1338
    else {
1362
    else {
1339
      /* stack parameter */
1363
      /* stack parameter */
1340
      instore is ;
1364
      instore is;
1341
      /* Locations we offer may not be aligned for doubles.
1365
      /* Locations we offer may not be aligned for doubles.
1342
	 We assume 'move' can cope with this  */
1366
	 We assume 'move' can cope with this  */
1343
      is.b.base = R_SP ;
1367
      is.b.base = R_SP;
1344
      is.b.offset = param_offset >> 3 ;
1368
      is.b.offset = param_offset >> 3;
1345
      is.adval = 1 ;
1369
      is.adval = 1;
1346
      if ( valregable ( sh ( list ) ) &&
1370
      if (valregable(sh(list)) &&
1347
	   ( ap.ashsize == 8 || ap.ashsize == 16 ) ) {
1371
	  (ap.ashsize == 8 || ap.ashsize == 16)) {
1348
	/* Byte or 16bit scalar parameter - convert to integer.
1372
	/* Byte or 16bit scalar parameter - convert to integer.
1349
	   We must pass a full word to conform with SPARC ABI,
1373
	   We must pass a full word to conform with SPARC ABI,
1350
	   so have to expand source to full word.  We do this
1374
	   so have to expand source to full word.  We do this
1351
	   by loading into a reg */
1375
	   by loading into a reg */
1352
	int r = reg_operand ( list, sp ) ;
1376
	int r = reg_operand(list, sp);
1353
	ans op ;
1377
	ans op;
1354
	setregalt ( op, r ) ;
1378
	setregalt(op, r);
1355
	/* round down to word boundary */
1379
	/* round down to word boundary */
1356
	is.b.offset &= ~0x3 ;
1380
	is.b.offset &= ~0x3;
1357
	ap.ashsize = ap.ashalign = 32 ;
1381
	ap.ashsize = ap.ashalign = 32;
1358
	w.ashwhere = ap ;
1382
	w.ashwhere = ap;
1359
	setinsalt ( w.answhere, is ) ;
1383
	setinsalt(w.answhere, is);
1360
	(void)move ( op, w, guardreg ( r, sp ).fixed, 1 ) ;
1384
	(void)move(op, w, guardreg(r, sp).fixed, 1);
1361
      } 
1385
      }
1362
      else{
1386
      else{
1363
	setinsalt ( w.answhere, is ) ;
1387
	setinsalt(w.answhere, is);
1364
	(void)code_here ( par, sp, w ) ;
1388
	(void)code_here(par, sp, w);
1365
      }
1389
      }
1366
      if ( *param_reg <= last_reg ) {
1390
      if (*param_reg <= last_reg) {
1367
	/* Copy back into the correct param regs */
1391
	/* Copy back into the correct param regs */
1368
	int start_offset = is.b.offset;
1392
	int start_offset = is.b.offset;
1369
	int block_size = w.ashwhere.ashsize;
1393
	int block_size = w.ashwhere.ashsize;
1370
	baseoff curr_pos;
1394
	baseoff curr_pos;
1371
	curr_pos.base = R_SP;
1395
	curr_pos.base = R_SP;
1372
	curr_pos.offset = start_offset;
1396
	curr_pos.offset = start_offset;
1373
	if(is64(sh(list)) || (name(sh(list)) == cpdhd) || 
1397
	if (is64(sh(list)) || (name(sh(list)) == cpdhd) ||
1374
	   (name(sh(list)) == nofhd)){
1398
	  (name(sh(list)) == nofhd)) {
1375
	  rir_ins(i_add,curr_pos.base,curr_pos.offset,*param_reg);
1399
	  rir_ins(i_add,curr_pos.base,curr_pos.offset,*param_reg);
1376
	  (*param_reg)++;
1400
	 (*param_reg) ++;
1377
	  block_size -=32;
1401
	  block_size -=32;
1378
        }
1402
        }
1379
	else {
1403
	else {
1380
	  while (*param_reg <= last_reg && block_size>0) {
1404
	  while (*param_reg <= last_reg && block_size>0) {
1381
	    ld_ro_ins(i_ld,curr_pos,*param_reg);
1405
	    ld_ro_ins(i_ld,curr_pos,*param_reg);
1382
	    ++(*param_reg);
1406
	    ++ (*param_reg);
1383
	    curr_pos.offset += 4;
1407
	    curr_pos.offset += 4;
1384
	    block_size -= 32;
1408
	    block_size -= 32;
1385
	  }
1409
	  }
1386
	}
1410
	}
1387
      }
1411
      }
1388
      param_offset = ( int ) ( param_offset + ap.ashsize ) ;
1412
      param_offset = (int)(param_offset + ap.ashsize);
1389
    }
1413
    }
1390
    if ( last ( list ) ) return sp;
1414
    if (last(list)) return sp;
1391
    list = bro ( list ) ;
1415
    list = bro(list);
1392
  }
1416
  }
1393
 
1417
 
1394
  return sp;
1418
  return sp;
1395
}
1419
}
1396
 
1420
 
1397
/*
1421
/*
1398
  Give the first parameter par_base, find parameter 'num'
1422
  Give the first parameter par_base, find parameter 'num'
1399
*/
1423
*/
1400
exp get_param 
1424
exp get_param
1401
    PROTO_N ( ( par_base, num ) )
-
 
1402
    PROTO_T ( exp par_base X int num ) {
1425
(exp par_base, int num) {
1403
  exp res_exp = par_base;
1426
  exp res_exp = par_base;
1404
  int current_par;
1427
  int current_par;
1405
  if(num == 1) return par_base;
1428
  if (num == 1) return par_base;
1406
  for(current_par = 2;current_par<=num;++current_par) {
1429
  for (current_par = 2;current_par<=num;++current_par) {
1407
    res_exp = bro(res_exp);
1430
    res_exp = bro(res_exp);
1408
  }
1431
  }
1409
  return res_exp;
1432
  return res_exp;
1410
}
1433
}
1411
 
1434
 
1412
  
1435
 
1413
  
1436
 
1414
 
1437
 
1415
/*
1438
/*
1416
  Move the caller parameters up the stack from their current position
1439
  Move the caller parameters up the stack from their current position
1417
  by %size_reg bytes.  The function assumes that there will always be at 
1440
  by %size_reg bytes.  The function assumes that there will always be at
1418
  least one parameter.
1441
  least one parameter.
1419
*/
1442
*/
1420
static void move_parameters 
1443
static void move_parameters
1421
    PROTO_N ( ( callers, size_reg, sp ) )
-
 
1422
    PROTO_T ( exp callers X int size_reg X space sp ) {
1444
(exp callers, int size_reg, space sp) {
1423
  int param_offset;   /* offset of first parameter */
1445
  int param_offset;   /* offset of first parameter */
1424
  int newbase;
1446
  int newbase;
1425
  baseoff b;
1447
  baseoff b;
1426
  int last_caller = 0;
1448
  int last_caller = 0;
1427
  int has_callers = 0;
1449
  int has_callers = 0;
1428
  exp current_caller = son(callers);
1450
  exp current_caller = son(callers);
1429
  int rtmp = getreg(sp.fixed);
1451
  int rtmp = getreg(sp.fixed);
1430
  int rtop = getreg(guardreg(rtmp,sp).fixed);
1452
  int rtop = getreg(guardreg(rtmp,sp).fixed);
1431
  int i;
1453
  int i;
1432
  
1454
 
1433
  param_offset = 64;
1455
  param_offset = 64;
1434
  for(i=0;i<no(callers);++i){
1456
  for (i=0;i<no(callers);++i) {
1435
    if (shape_size(sh(current_caller)) > 32)
1457
    if (shape_size(sh(current_caller)) > 32)
1436
      param_offset += 8;
1458
      param_offset += 8;
1437
    else
1459
    else
1438
      param_offset += 4;
1460
      param_offset += 4;
1439
    current_caller = bro(current_caller);
1461
    current_caller = bro(current_caller);
1440
  }
1462
  }
1441
  current_caller = son(callers);
1463
  current_caller = son(callers);
1442
  
1464
 
1443
 
1465
 
1444
  /* top is sp + param_offset + callers * num */
1466
  /* top is sp + param_offset + callers * num */
1445
  while(!last_caller) {
1467
  while (!last_caller) {
1446
    last_caller = last(current_caller);
1468
    last_caller = last(current_caller);
1447
    if(name(current_caller) == caller_tag) {
1469
    if (name(current_caller) == caller_tag) {
1448
      has_callers = 1;
1470
      has_callers = 1;
1449
    }
1471
    }
1450
    current_caller = bro(current_caller);
1472
    current_caller = bro(current_caller);
1451
  }
1473
  }
1452
  current_caller = son(callers);
1474
  current_caller = son(callers);
1453
  last_caller = 0;
1475
  last_caller = 0;
1454
 
1476
 
1455
  if(!has_callers) return;
1477
  if (!has_callers) return;
1456
  rir_ins(i_add,R_SP,param_offset /*+ (no(callers))*/,rtop);
1478
  rir_ins(i_add,R_SP,param_offset /*+ (no(callers))*/,rtop);
1457
  
1479
 
1458
  
1480
 
1459
  b.offset = param_offset;
1481
  b.offset = param_offset;
1460
  b.offset = 0;
1482
  b.offset = 0;
1461
  if (size_reg == R_NO_REG)
1483
  if (size_reg == R_NO_REG)
1462
    newbase = rtop;
1484
    newbase = rtop;
1463
  else {
1485
  else {
1464
    newbase = getreg(guardreg(rtop,sp).fixed);
1486
    newbase = getreg(guardreg(rtop,sp).fixed);
1465
    rrr_ins(i_add,rtop,size_reg,newbase);
1487
    rrr_ins(i_add,rtop,size_reg,newbase);
1466
  }
1488
  }
1467
  assert(current_caller != (exp)NULL);
1489
  assert(current_caller != (exp)NULL);
1468
 
1490
 
1469
  for(i=no(callers);i>0;--i) {
1491
  for (i=no(callers);i>0;--i) {
1470
    exp par = get_param(son(callers),i);
1492
    exp par = get_param(son(callers),i);
1471
    if(name( par ) == caller_tag) {
1493
    if (name(par) == caller_tag) {
1472
      /* move it up the stack */
1494
      /* move it up the stack */
1473
      b.base = rtop;
1495
      b.base = rtop;
1474
      ld_ro_ins(i_ld,b,rtmp);
1496
      ld_ro_ins(i_ld,b,rtmp);
1475
      b.base = newbase;
1497
      b.base = newbase;
1476
      st_ro_ins(i_st,rtmp,b);
1498
      st_ro_ins(i_st,rtmp,b);
1477
      if(shape_size(sh(par)) > 32) {
1499
      if (shape_size(sh(par)) > 32) {
1478
	b.base = rtop;
1500
	b.base = rtop;
1479
	b.offset = -4;
1501
	b.offset = -4;
1480
	ld_ro_ins(i_ld,b,rtmp);
1502
	ld_ro_ins(i_ld,b,rtmp);
1481
	b.base = newbase;
1503
	b.base = newbase;
1482
	st_ro_ins(i_st,rtmp,b);
1504
	st_ro_ins(i_st,rtmp,b);
Line 1487... Line 1509...
1487
      b.offset -= (shape_size(sh(par)) > 32 ? 8 : 4);
1509
      b.offset -= (shape_size(sh(par)) > 32 ? 8 : 4);
1488
  }
1510
  }
1489
  return;
1511
  return;
1490
}
1512
}
1491
 
1513
 
1492
      
-
 
1493
 
1514
 
-
 
1515
 
1494
makeans make_apply_general_tag_code 
1516
makeans make_apply_general_tag_code
1495
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
1496
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
1517
(exp e, space sp, where dest, int exitlab) {
1497
  exp fn = son(e);
1518
  exp fn = son(e);
1498
  exp callers = bro(fn);
1519
  exp callers = bro(fn);
1499
  exp cllees = bro(callers);
1520
  exp cllees = bro(callers);
1500
  exp postlude = bro(cllees);
1521
  exp postlude = bro(cllees);
1501
  int hda = (int)name(sh(e));
1522
  int hda = (int)name(sh(e));
1502
  int param_reg = R_O0;
1523
  int param_reg = R_O0;
1503
  int param_regs_used;
1524
  int param_regs_used;
1504
  ash ansash;
1525
  ash ansash;
1505
  space nsp;
1526
  space nsp;
1506
  int void_result = (( name ( sh ( e ) ) == tophd ) ||
1527
  int void_result = ((name(sh(e)) == tophd) ||
1507
		     ( name ( sh ( e ) ) == bothd));
1528
		    (name(sh(e)) == bothd));
1508
    
1529
 
1509
  int reg_res = reg_result ( sh ( e ) ) ;
1530
  int reg_res = reg_result(sh(e));
1510
  int guarded_dest_reg = R_NO_REG; /* reg used to address tuple result */
1531
  int guarded_dest_reg = R_NO_REG; /* reg used to address tuple result */
1511
  makeans mka ;
1532
  makeans mka;
1512
  exp dad = father ( e ) ;
1533
  exp dad = father(e);
1513
  bool tlrecurse = ( bool ) ( proc_state.rscope_level == 0 &&
1534
  bool tlrecurse = (bool)(proc_state.rscope_level == 0 &&
1514
			      name ( dad ) == res_tag && props ( dad ) ) ;
1535
			      name(dad) == res_tag && props(dad));
1515
  bool trad_call = 0;
1536
  bool trad_call = 0;
1516
  ansash = ashof(sh(e));
1537
  ansash = ashof(sh(e));
1517
  nsp = sp;
1538
  nsp = sp;
1518
  mka.lab = exitlab ;
1539
  mka.lab = exitlab;
1519
  mka.regmove = NOREG ;
1540
  mka.regmove = NOREG;
1520
  if((call_has_vcallees(cllees)!= 0)) {
1541
  if ((call_has_vcallees(cllees)!= 0)) {
1521
    outs("\t.optim\t\"-O0\"\n"); 
1542
    outs("\t.optim\t\"-O0\"\n");
1522
  }
1543
  }
1523
 
1544
 
1524
  param_regs_used = param_reg - R_O0;
1545
  param_regs_used = param_reg - R_O0;
1525
 
1546
 
1526
#ifdef GENCOMPAT
1547
#ifdef GENCOMPAT
1527
  if ((call_has_vcallees(cllees)== 0)) {
1548
  if ((call_has_vcallees(cllees) == 0)) {
1528
    if (name(cllees) == make_callee_list_tag) {
1549
    if (name(cllees) == make_callee_list_tag) {
1529
      if (no(cllees) == 0)
1550
      if (no(cllees) == 0)
1530
	trad_call = 1;
1551
	trad_call = 1;
1531
    }
1552
    }
1532
    else if (name(cllees) == make_dynamic_callee_tag) {
1553
    else if (name(cllees) == make_dynamic_callee_tag) {
Line 1538... Line 1559...
1538
	trad_call = 1;
1559
	trad_call = 1;
1539
    }
1560
    }
1540
  }
1561
  }
1541
#endif
1562
#endif
1542
  if (!trad_call)
1563
  if (!trad_call)
1543
    (void)make_code(cllees,nsp,nowhere,0);
1564
   (void)make_code(cllees,nsp,nowhere,0);
1544
 
1565
 
1545
  if(!reg_res && !void_result){
1566
  if (!reg_res && !void_result) {
1546
    /* structure result */
1567
    /* structure result */
1547
        instore is ;
1568
        instore is;
1548
    baseoff stack_struct_ret_addr ;
1569
    baseoff stack_struct_ret_addr;
1549
 
1570
 
1550
    /* [%sp+64] as per call convention */
1571
    /* [%sp+64] as per call convention */
1551
    stack_struct_ret_addr.base = R_SP ;
1572
    stack_struct_ret_addr.base = R_SP;
1552
    stack_struct_ret_addr.offset = ( 16 * 4 ) ;
1573
    stack_struct_ret_addr.offset = (16 * 4);
1553
 
1574
 
1554
    assert ( discrim ( dest.answhere ) == notinreg ) ;
1575
    assert(discrim(dest.answhere) == notinreg);
1555
    if(discrim(dest.answhere) != notinreg){	/* should be redundant */
1576
    if(discrim(dest.answhere) != notinreg){	/* should be redundant */
1556
      discrim(dest.answhere) = notinreg;
1577
      discrim(dest.answhere) = notinreg;
1557
      is.b.base = R_SP;
1578
      is.b.base = R_SP;
1558
      is.b.offset = (4*16);
1579
      is.b.offset = (4*16);
1559
      /* is.b = mem_temp(0);   not compatible with out_pars */
1580
      /* is.b = mem_temp(0);   not compatible with out_pars */
1560
      is.adval = 1;
1581
      is.adval = 1;
1561
      dest.answhere.val.instoreans = is;
1582
      dest.answhere.val.instoreans = is;
1562
    }
1583
    }
1563
    else{
1584
    else{
1564
      is = insalt ( dest.answhere ) ;
1585
      is = insalt(dest.answhere);
1565
    }
1586
    }
1566
    if ( is.adval ) {
1587
    if (is.adval) {
1567
      /* generate address of dest */
1588
      /* generate address of dest */
1568
      if ( IS_FIXREG ( is.b.base ) ) {
1589
      if (IS_FIXREG(is.b.base)) {
1569
	if ( is.b.offset == 0 ) {
1590
	if (is.b.offset == 0) {
1570
	  st_ro_ins ( i_st, is.b.base, stack_struct_ret_addr ) ;
1591
	  st_ro_ins(i_st, is.b.base, stack_struct_ret_addr);
1571
	} 
1592
	}
1572
	else {
1593
	else {
1573
	  rir_ins ( i_add, is.b.base, is.b.offset, R_TMP ) ;
1594
	  rir_ins(i_add, is.b.base, is.b.offset, R_TMP);
1574
	  st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1595
	  st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1575
	}
1596
	}
1576
	guarded_dest_reg = is.b.base ;	/* can be guarded */
1597
	guarded_dest_reg = is.b.base ;	/* can be guarded */
1577
      } 
1598
      }
1578
      else {
1599
      else {
1579
	set_ins ( is.b, R_TMP ) ;
1600
	set_ins(is.b, R_TMP);
1580
	st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1601
	st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1581
      }
1602
      }
1582
    } 
1603
    }
1583
    else {
1604
    else {
1584
      /* load dest */
1605
      /* load dest */
1585
      ld_ins ( i_ld, is.b, R_TMP ) ;
1606
      ld_ins(i_ld, is.b, R_TMP);
1586
      st_ro_ins ( i_st, R_TMP, stack_struct_ret_addr ) ;
1607
      st_ro_ins(i_st, R_TMP, stack_struct_ret_addr);
1587
    }
1608
    }
1588
  }
1609
  }
1589
 
1610
 
1590
 
1611
 
1591
#ifdef GENCOMPAT
1612
#ifdef GENCOMPAT
1592
  if (!trad_call)
1613
  if (!trad_call)
1593
#endif
1614
#endif
1594
  {
1615
  {
1595
    /*rr_ins(i_mov,callee_start_reg,R_O5);*/ 
1616
    /*rr_ins(i_mov,callee_start_reg,R_O5);*/
1596
    nsp = guardreg(R_O5,nsp);
1617
    nsp = guardreg(R_O5,nsp);
1597
    if(call_has_vcallees(cllees)) {
1618
    if (call_has_vcallees(cllees)) {
1598
      /*rr_ins(i_mov,callee_end_reg,R_O4);*/
1619
      /*rr_ins(i_mov,callee_end_reg,R_O4);*/
1599
      nsp = guardreg(R_O4,nsp);
1620
      nsp = guardreg(R_O4,nsp);
1600
    }
1621
    }
1601
  }
1622
  }
1602
 
1623
 
1603
  if(no(callers) != 0){
1624
  if (no(callers)!= 0) {
1604
    int tmp = in_general_proc;
1625
    int tmp = in_general_proc;
1605
    in_general_proc = 1;
1626
    in_general_proc = 1;
1606
    vc_call = (call_has_vcallees(cllees)!=0);
1627
    vc_call = (call_has_vcallees(cllees)!=0);
1607
    nsp = do_callers(son(callers),nsp,&param_reg, trad_call);
1628
    nsp = do_callers(son(callers),nsp,&param_reg, trad_call);
1608
    vc_call = 0;
1629
    vc_call = 0;
1609
    in_general_proc = tmp;
1630
    in_general_proc = tmp;
1610
  }
1631
  }
1611
  call_base_reg = R_SP;
1632
  call_base_reg = R_SP;
1612
  
1633
 
1613
  if ( name ( fn ) == name_tag && name ( son ( fn ) ) == ident_tag &&
1634
  if (name(fn) == name_tag && name(son(fn)) == ident_tag &&
1614
       ( son ( son ( fn ) ) == nilexp ||
1635
      (son(son(fn)) == nilexp ||
1615
	 (name ( son ( son ( fn ) ) ) == proc_tag ||
1636
	(name(son(son(fn))) == proc_tag ||
1616
	  name(son(son(fn))) == general_proc_tag)) ) {
1637
	  name(son(son(fn))) == general_proc_tag))) {
1617
    baseoff b;
1638
    baseoff b;
1618
    b = boff(son(fn));
1639
    b = boff(son(fn));
1619
    if(!tlrecurse){
1640
    if (!tlrecurse) {
1620
      /* don't tell the assembler how many parameters are being used, as
1641
      /* don't tell the assembler how many parameters are being used, as
1621
	 it optimises away changes to "unused" parameter registers which,
1642
	 it optimises away changes to "unused" parameter registers which,
1622
	 in general procs, are needed to pass callees.
1643
	 in general procs, are needed to pass callees.
1623
	 */
1644
	 */
1624
#ifdef NEWDWARF
1645
#ifdef NEWDWARF
1625
      if (current_dg_info) {
1646
      if (current_dg_info) {
1626
	current_dg_info->data.i_call.brk = set_dw_text_label ();
1647
	current_dg_info->data.i_call.brk = set_dw_text_label();
1627
	current_dg_info->data.i_call.p.k = WH_CODELAB;
1648
	current_dg_info->data.i_call.p.k = WH_CODELAB;
1628
	current_dg_info->data.i_call.p.u.l = b.base;
1649
	current_dg_info->data.i_call.p.u.l = b.base;
1629
	current_dg_info->data.i_call.p.o = b.offset;
1650
	current_dg_info->data.i_call.p.o = b.offset;
1630
      }
1651
      }
1631
#endif
1652
#endif
Line 1637... Line 1658...
1637
  }
1658
  }
1638
  else{
1659
  else{
1639
    int r = reg_operand(fn,nsp);
1660
    int r = reg_operand(fn,nsp);
1640
#ifdef NEWDWARF
1661
#ifdef NEWDWARF
1641
    if (current_dg_info) {
1662
    if (current_dg_info) {
1642
      current_dg_info->data.i_call.brk = set_dw_text_label ();
1663
      current_dg_info->data.i_call.brk = set_dw_text_label();
1643
      current_dg_info->data.i_call.p.k = WH_REG;
1664
      current_dg_info->data.i_call.p.k = WH_REG;
1644
      current_dg_info->data.i_call.p.u.l = r;
1665
      current_dg_info->data.i_call.p.u.l = r;
1645
    }
1666
    }
1646
#endif
1667
#endif
1647
    extj_reg_ins(i_call,r,-1 /*param_regs_used*/);
1668
    extj_reg_ins(i_call,r,-1 /*param_regs_used*/);
1648
  }
1669
  }
1649
  if(!reg_res && !void_result){
1670
  if (!reg_res && !void_result) {
1650
    /* Generate unimp instruction, as per structure result call
1671
    /* Generate unimp instruction, as per structure result call
1651
	   convention.  Argument is low-order 12 bits of structure size,
1672
	   convention.  Argument is low-order 12 bits of structure size,
1652
	   see section D.4 of * SPARC architecture manual */
1673
	   see section D.4 of * SPARC architecture manual */
1653
    unimp_ins ( ( long ) ( ( ansash.ashsize / 8 ) & 0xfff ) ) ;
1674
    unimp_ins((long)((ansash.ashsize / 8) & 0xfff));
1654
  }
1675
  }
1655
 
1676
 
1656
#ifdef NEWDWARF
1677
#ifdef NEWDWARF
1657
  if (dwarf2)
1678
  if (dwarf2)
1658
    START_BB ();
1679
    START_BB();
1659
#endif
1680
#endif
1660
 
1681
 
1661
  /* free the space used to generate the callee parameters and, if in
1682
  /* free the space used to generate the callee parameters and, if in
1662
     a postlude, move the caller outpars up the stack to a correct parameter 
1683
     a postlude, move the caller outpars up the stack to a correct parameter
1663
     offset from the new stack pointer */
1684
     offset from the new stack pointer */
1664
 
1685
 
1665
  clear_all();
1686
  clear_all();
1666
  {
1687
  {
1667
    int size_reg;
1688
    int size_reg;
Line 1671... Line 1692...
1671
    if (trad_call)
1692
    if (trad_call)
1672
      size_reg = R_NO_REG;
1693
      size_reg = R_NO_REG;
1673
    else
1694
    else
1674
#endif
1695
#endif
1675
    {
1696
    {
1676
      if(name(cllees) == make_callee_list_tag) {
1697
      if (name(cllees) == make_callee_list_tag) {
1677
	size_reg = getreg(nsp.fixed);
1698
	size_reg = getreg(nsp.fixed);
1678
	ir_ins(i_mov,((no(cllees)>>3)+23)&~7,size_reg);
1699
	ir_ins(i_mov,((no(cllees) >>3) +23) &~7,size_reg);
1679
      }
1700
      }
1680
      else if(name(cllees) == make_dynamic_callee_tag) {
1701
      else if (name(cllees) == make_dynamic_callee_tag) {
1681
	size_reg = reg_operand(bro(son(cllees)),nsp);
1702
	size_reg = reg_operand(bro(son(cllees)),nsp);
1682
	rir_ins(i_add,size_reg,4*(PTR_SZ>>3)+7,size_reg);
1703
	rir_ins(i_add,size_reg,4*(PTR_SZ>>3) +7,size_reg);
1683
	rir_ins(i_and,size_reg,~7,size_reg);
1704
	rir_ins(i_and,size_reg,~7,size_reg);
1684
      }
1705
      }
1685
      else {	/* same callees */
1706
      else {	/* same callees */
1686
	size_reg = getreg(nsp.fixed);
1707
	size_reg = getreg(nsp.fixed);
1687
	if(Has_vcallees) {
1708
	if (Has_vcallees) {
1688
	  rrr_ins(i_sub,callee_end_reg,callee_start_reg,size_reg);
1709
	  rrr_ins(i_sub,callee_end_reg,callee_start_reg,size_reg);
1689
	}
1710
	}
1690
	else {
1711
	else {
1691
	  ir_ins(i_mov,proc_state.callee_size/8,size_reg);
1712
	  ir_ins(i_mov,proc_state.callee_size/8,size_reg);
1692
	}
1713
	}
1693
      }
1714
      }
1694
      nsp = guardreg(size_reg,nsp);
1715
      nsp = guardreg(size_reg,nsp);
1695
    }
1716
    }
1696
    if(no(callers)/* && (in_postlude || postlude_has_call(e))*/) {
1717
    if(no(callers)/* && (in_postlude || postlude_has_call(e))*/) {
1697
      move_parameters(callers,size_reg,nsp); /* move all outpars into 
1718
      move_parameters(callers,size_reg,nsp); /* move all outpars into
1698
						    correct positions */
1719
						    correct positions */
1699
    }
1720
    }
1700
    if(!call_is_untidy(cllees) && size_reg != R_NO_REG) {
1721
    if (!call_is_untidy(cllees) && size_reg != R_NO_REG) {
1701
      if(!sysV_assembler) {
1722
      if (!sysV_assembler) {
1702
	/* with -O2 SunOS removes [add %sp,X,%sp] statements. */
1723
	/* with -O2 SunOS removes [add %sp,X,%sp] statements. */
1703
	outs("\t.optim\t\"-O0\"\n"); 
1724
	outs("\t.optim\t\"-O0\"\n");
1704
      }
1725
      }
1705
      rrr_ins(i_add,R_SP,size_reg,R_SP);
1726
      rrr_ins(i_add,R_SP,size_reg,R_SP);
1706
    }
1727
    }
1707
  }
1728
  }
1708
  
1729
 
1709
  
1730
 
1710
 
1731
 
1711
  /* grab clobbered %g and %o regs, as safety test for bad code */
1732
  /* grab clobbered %g and %o regs, as safety test for bad code */
1712
  {
1733
  {
1713
    int r ;
1734
    int r;
1714
    space gsp ;
1735
    space gsp;
1715
    gsp = sp ;
1736
    gsp = sp;
1716
 
1737
 
1717
    /* %g1..%g_reg_max, %o0..%o7 */
1738
    /* %g1..%g_reg_max, %o0..%o7 */
1718
    for ( r = R_G1 ; r < R_O7 + 1 ;
1739
    for (r = R_G1; r < R_O7 + 1;
1719
		     r = ( ( r == R_G0 + g_reg_max ) ? R_O0 : r + 1 ) ) {
1740
		     r = ((r == R_G0 + g_reg_max)? R_O0 : r + 1)) {
1720
      /* skip R_O0 as often used in result-reg optimisation */
1741
      /* skip R_O0 as often used in result-reg optimisation */
1721
      if ( !( r == R_TMP || r == R_O0 || r == R_SP ||
1742
      if (!(r == R_TMP || r == R_O0 || r == R_SP ||
1722
	      r == guarded_dest_reg ) ) {
1743
	      r == guarded_dest_reg)) {
1723
	/* not special regs */
1744
	/* not special regs */
1724
	gsp = needreg ( r, gsp ) ;
1745
	gsp = needreg(r, gsp);
1725
      }
1746
      }
1726
    }
1747
    }
1727
  }
1748
  }
1728
  clear_all () ;	/* ??? not %i0..%l7 that may be t-regs */
1749
  clear_all () ;	/* ??? not %i0..%l7 that may be t-regs */
1729
 
1750
 
1730
  if ( reg_res ) {
1751
  if (reg_res) {
1731
    ans aa ;
1752
    ans aa;
1732
    if ( is_floating ( hda ) ) {
1753
    if (is_floating(hda)) {
1733
      freg frg ;
1754
      freg frg;
1734
      frg.fr = 0 ;
1755
      frg.fr = 0;
1735
      frg.dble = ( bool ) ( hda != shrealhd ) ;
1756
      frg.dble = (bool)(hda != shrealhd);
1736
      setfregalt ( aa, frg ) ;
1757
      setfregalt(aa, frg);
1737
      /* move floating point result of application to destination */
1758
      /* move floating point result of application to destination */
1738
      ( void ) move ( aa, dest, sp.fixed, 1 ) ;
1759
     (void)move(aa, dest, sp.fixed, 1);
1739
    } else {
1760
    } else {
1740
      setregalt ( aa, R_O0 ) ;
1761
      setregalt(aa, R_O0);
1741
      if ( discrim ( dest.answhere ) == inreg ) {
1762
      if (discrim(dest.answhere) == inreg) {
1742
	int r = regalt ( dest.answhere ) ;
1763
	int r = regalt(dest.answhere);
1743
	if ( r == R_G0 ) {
1764
	if (r == R_G0) {
1744
	  /* void result */
1765
	  /* void result */
1745
	} 
1766
	}
1746
	else if ( r != R_O0 ) {
1767
	else if (r != R_O0) {
1747
	  /* move result from %o0 */
1768
	  /* move result from %o0 */
1748
	  ( void ) move ( aa, dest, sp.fixed, 1 ) ;
1769
	 (void)move(aa, dest, sp.fixed, 1);
1749
	} 
1770
	}
1750
	else {
1771
	else {
1751
	  /* no move required */
1772
	  /* no move required */
1752
	  assert (name(postlude) == top_tag);
1773
	  assert(name(postlude) == top_tag);
1753
	}
1774
	}
1754
	mka.regmove = R_O0 ;
1775
	mka.regmove = R_O0;
1755
      } 
1776
      }
1756
      else {
1777
      else {
1757
	( void ) move ( aa, dest, sp.fixed, 1 ) ;
1778
	(void)move(aa, dest, sp.fixed, 1);
1758
      }
1779
      }
1759
    }
1780
    }
1760
  } 
1781
  }
1761
  else {
1782
  else {
1762
    /* not register result */
1783
    /* not register result */
1763
  }
1784
  }
1764
#if 0
1785
#if 0
1765
  if(Has_vcallees){
1786
  if (Has_vcallees) {
1766
    baseoff b;
1787
    baseoff b;
1767
    b.base = R_FP;
1788
    b.base = R_FP;
1768
    b.offset = -3 * (PTR_SZ>>3);
1789
    b.offset = -3 *(PTR_SZ>>3);
1769
    ld_ro_ins(i_ld,b,local_reg);
1790
    ld_ro_ins(i_ld,b,local_reg);
1770
  }
1791
  }
1771
#endif
1792
#endif
1772
  		
1793
 
1773
  if(call_is_untidy(cllees)) {
1794
  if (call_is_untidy(cllees)) {
1774
    /*    rir_ins(i_sub,R_SP,proc_state.maxargs>>3,R_SP);*/
1795
    /*    rir_ins(i_sub,R_SP,proc_state.maxargs>>3,R_SP);*/
1775
    /*assert(name(bro(cllees)) == top_tag);*/
1796
    /*assert(name(bro(cllees)) == top_tag);*/
1776
  }
1797
  }
1777
  else if(postlude_has_call(e)){
1798
  else if (postlude_has_call(e)) {
1778
    exp x = son(callers);
1799
    exp x = son(callers);
1779
    postlude_chain p;
1800
    postlude_chain p;
1780
    
1801
 
1781
    if (x != nilexp) {
1802
    if (x != nilexp) {
1782
      for(;;) {
1803
      for (;;) {
1783
	if(name(x) == caller_tag) {
1804
	if (name(x) == caller_tag) {
1784
	  no(x) += proc_state.maxargs;
1805
	  no(x) += proc_state.maxargs;
1785
#if 0
1806
#if 0
1786
	  if(name(sh(x)) == realhd){
1807
	  if (name(sh(x)) == realhd) {
1787
	    no(x) -=32;
1808
	    no(x) -=32;
1788
	  }
1809
	  }
1789
#endif
1810
#endif
1790
	}
1811
	}
1791
	if(last(x))break;
1812
	if (last(x))break;
1792
	x = bro(x);
1813
	x = bro(x);
1793
      }
1814
      }
1794
    }
1815
    }
1795
    mka.regmove = NOREG;
1816
    mka.regmove = NOREG;
1796
    update_plc(old_postludes,proc_state.maxargs);
1817
    update_plc(old_postludes,proc_state.maxargs);
Line 1798... Line 1819...
1798
    p.outer = old_postludes;
1819
    p.outer = old_postludes;
1799
    old_postludes = &p;
1820
    old_postludes = &p;
1800
    rir_ins(i_sub,R_SP,proc_state.maxargs>>3,R_SP);
1821
    rir_ins(i_sub,R_SP,proc_state.maxargs>>3,R_SP);
1801
 
1822
 
1802
    in_postlude = 1;
1823
    in_postlude = 1;
1803
    (void)make_code(postlude,sp,nowhere,0);
1824
   (void)make_code(postlude,sp,nowhere,0);
1804
    in_postlude = 0;
1825
    in_postlude = 0;
1805
    rir_ins(i_add,R_SP,proc_state.maxargs>>3,R_SP);
1826
    rir_ins(i_add,R_SP,proc_state.maxargs>>3,R_SP);
1806
    old_postludes = p.outer;
1827
    old_postludes = p.outer;
1807
    update_plc(old_postludes,-proc_state.maxargs);
1828
    update_plc(old_postludes,-proc_state.maxargs);
1808
  }
1829
  }
1809
  else {
1830
  else {
1810
    (void)make_code(postlude,sp,nowhere,0);
1831
   (void)make_code(postlude,sp,nowhere,0);
1811
  }
1832
  }
1812
 
1833
 
1813
  return mka;
1834
  return mka;
1814
}
1835
}
1815
 
1836
 
1816
 
1837
 
1817
/*
1838
/*
1818
  Allocate an amount of space on the stack corresponding to the value
1839
  Allocate an amount of space on the stack corresponding to the value
1819
  held in register size_reg, and store a pointer to the resulting area
1840
  held in register size_reg, and store a pointer to the resulting area
1820
  in register ptr_reg.
1841
  in register ptr_reg.
1821
*/
1842
*/
1822
static void alloc_reg_space 
1843
static void alloc_reg_space
1823
    PROTO_N ( ( size_reg, ptr_reg ) )
-
 
1824
    PROTO_T ( int size_reg X int ptr_reg ) {
1844
(int size_reg, int ptr_reg) {
1825
  
1845
 
1826
  int maxargbytes = (int)proc_state.maxargs/8;
1846
  int maxargbytes = (int)proc_state.maxargs/8;
1827
  rir_ins(i_add,size_reg,7,R_TMP);   
1847
  rir_ins(i_add,size_reg,7,R_TMP);
1828
  rir_ins(i_and,R_TMP,~7,R_TMP);      /* make the size a multiple of 8 */
1848
  rir_ins(i_and,R_TMP,~7,R_TMP);      /* make the size a multiple of 8 */
1829
  rrr_ins(i_sub,R_SP,R_TMP,R_SP);
1849
  rrr_ins(i_sub,R_SP,R_TMP,R_SP);
1830
  rir_ins(i_add,R_SP,maxargbytes,ptr_reg);
1850
  rir_ins(i_add,R_SP,maxargbytes,ptr_reg);
1831
  return;
1851
  return;
1832
}
1852
}
1833
 
1853
 
1834
  
1854
 
1835
/* 
1855
/*
1836
   As alloc_reg_space, but with a constant size.
1856
   As alloc_reg_space, but with a constant size.
1837
*/
1857
*/
1838
static void alloc_space 
1858
static void alloc_space
1839
    PROTO_N ( ( size, ptr_reg ) )
-
 
1840
    PROTO_T ( int size X int ptr_reg ) {
1859
(int size, int ptr_reg) {
1841
  int maxargbytes = (int)proc_state.maxargs/8;
1860
  int maxargbytes = (int)proc_state.maxargs/8;
1842
  size = (size+7)&~7;
1861
  size = (size+7) &~7;
1843
  rir_ins(i_sub,R_SP,size,R_SP);
1862
  rir_ins(i_sub,R_SP,size,R_SP);
1844
  rir_ins(i_add,R_SP,maxargbytes,ptr_reg);
1863
  rir_ins(i_add,R_SP,maxargbytes,ptr_reg);
1845
  return;
1864
  return;
1846
}
1865
}
1847
 
1866
 
1848
 
1867
 
1849
makeans make_make_callee_list_tag 
1868
makeans make_make_callee_list_tag
1850
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
1851
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
1869
(exp e, space sp, where dest, int exitlab) {
1852
  int size = ((no(e)>>3) + 23)&~7;
1870
  int size = ((no(e) >>3) + 23) &~7;
1853
  makeans mka;
1871
  makeans mka;
1854
  bool vc = call_has_vcallees(e);
1872
  bool vc = call_has_vcallees(e);
1855
  exp list = son(e);
1873
  exp list = son(e);
1856
  where w;
1874
  where w;
1857
  instore is;
1875
  instore is;
1858
  baseoff b;
1876
  baseoff b;
1859
  int disp = 0;
1877
  int disp = 0;
1860
  ash ap;
1878
  ash ap;
1861
  space nsp;
1879
  space nsp;
1862
  int rdest;
1880
  int rdest;
1863
  
1881
 
1864
  nsp = guardreg(R_O5,sp);
1882
  nsp = guardreg(R_O5,sp);
1865
  nsp = guardreg(R_O4,nsp);
1883
  nsp = guardreg(R_O4,nsp);
1866
  mka.regmove = R_G0;
1884
  mka.regmove = R_G0;
1867
  mka.lab = 0;
1885
  mka.lab = 0;
1868
  /* perform an alloca */
1886
  /* perform an alloca */
Line 1870... Line 1888...
1870
  nsp = guardreg(call_base_reg,nsp);
1888
  nsp = guardreg(call_base_reg,nsp);
1871
  rr_ins(i_mov,R_SP,call_base_reg);
1889
  rr_ins(i_mov,R_SP,call_base_reg);
1872
  rdest  = getreg(nsp.fixed);
1890
  rdest  = getreg(nsp.fixed);
1873
  nsp = guardreg(rdest,nsp);
1891
  nsp = guardreg(rdest,nsp);
1874
  alloc_space(size,rdest); /* */
1892
  alloc_space(size,rdest); /* */
1875
    
1893
 
1876
  b.base = rdest;
1894
  b.base = rdest;
1877
  b.offset = size - (PTR_SZ>>3);
1895
  b.offset = size - (PTR_SZ>>3);
1878
  st_ro_ins(i_st,R_FP,b);
1896
  st_ro_ins(i_st,R_FP,b);
1879
  if(no(e)){
1897
  if (no(e)) {
1880
    int lastpar = 0;
1898
    int lastpar = 0;
1881
    for(;!lastpar;list = bro(list)){
1899
    for (;!lastpar;list = bro(list)) {
1882
      ap = ashof(sh(list));
1900
      ap = ashof(sh(list));
1883
      disp = rounder(disp,ap.ashalign);
1901
      disp = rounder(disp,ap.ashalign);
1884
      is.b.offset = disp>>3;
1902
      is.b.offset = disp>>3;
1885
      is.b.base = rdest;
1903
      is.b.base = rdest;
1886
      is.adval = 1;
1904
      is.adval = 1;
Line 1889... Line 1907...
1889
      code_here(list,guard(w,nsp),w);
1907
      code_here(list,guard(w,nsp),w);
1890
      disp = rounder(disp+ap.ashsize,PTR_SZ);
1908
      disp = rounder(disp+ap.ashsize,PTR_SZ);
1891
      lastpar = last(list);
1909
      lastpar = last(list);
1892
    }
1910
    }
1893
  }
1911
  }
1894
  rr_ins(i_mov,rdest,callee_start_reg_out);/* Not before, as the construction 
1912
  rr_ins(i_mov,rdest,callee_start_reg_out);/* Not before, as the construction
1895
					      of the callees may require that 
1913
					      of the callees may require that
1896
					      we access some of the old 
1914
					      we access some of the old
1897
					      callees */
1915
					      callees */
1898
  if(vc){
1916
  if (vc) {
1899
    rir_ins(i_add,callee_start_reg_out,size,callee_end_reg_out);
1917
    rir_ins(i_add,callee_start_reg_out,size,callee_end_reg_out);
1900
    /*rir_ins(i_add,R_FP,size,R_FP);*/
1918
    /*rir_ins(i_add,R_FP,size,R_FP);*/
1901
  }
1919
  }
1902
  return mka;
1920
  return mka;
1903
}
1921
}
-
 
1922
 
1904
 
1923
 
1905
 
1924
 
1906
  
-
 
1907
/*
1925
/*
1908
  Construct a copy of the current callees for use in a new procedure
1926
  Construct a copy of the current callees for use in a new procedure
1909
  call.  This writes the callee pointer(s) to the output registers o4 and 
1927
  call.  This writes the callee pointer(s) to the output registers o4 and
1910
  o5, so a tail call will have to copy back to i4,i5.
1928
  o5, so a tail call will have to copy back to i4,i5.
1911
*/
1929
*/
1912
makeans make_same_callees_tag 
1930
makeans make_same_callees_tag
1913
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
1914
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
1931
(exp e, space sp, where dest, int exitlab) {
1915
  baseoff b;
1932
  baseoff b;
1916
  bool vc = call_has_vcallees(e);
1933
  bool vc = call_has_vcallees(e);
1917
  makeans mka;
1934
  makeans mka;
1918
  space nsp;
1935
  space nsp;
1919
  mka.regmove = R_G0;
1936
  mka.regmove = R_G0;
1920
  if(Has_vcallees) {
1937
  if (Has_vcallees) {
1921
    /* copy from [callee_start_reg ... callee_end_reg] into newly allocated
1938
    /* copy from [callee_start_reg ... callee_end_reg] into newly allocated
1922
       area, then set callee_start reg to start of area and, if the call
1939
       area, then set callee_start reg to start of area and, if the call
1923
       also has vcallees, set callee_end_reg to the end of the area.
1940
       also has vcallees, set callee_end_reg to the end of the area.
1924
       */
1941
       */
1925
    int rsize; /* register to contain the size of the 
1942
    int rsize; /* register to contain the size of the
1926
				     callee parameters area */
1943
				     callee parameters area */
1927
    int rsrc,rdest;               /* registers containing pointers to where 
1944
    int rsrc,rdest;               /* registers containing pointers to where
1928
				     to copy from and to */
1945
				     to copy from and to */
1929
    int rtmp;                     /* temporary register used in copying */
1946
    int rtmp;                     /* temporary register used in copying */
1930
    
1947
 
1931
    int end_copy_lab = new_label();   /* marks end of copy loop */
1948
    int end_copy_lab = new_label();   /* marks end of copy loop */
1932
    int start_copy_lab = new_label(); /* marks start of copy loop */
1949
    int start_copy_lab = new_label(); /* marks start of copy loop */
1933
    nsp = guardreg(R_O4,sp);
1950
    nsp = guardreg(R_O4,sp);
1934
    nsp = guardreg(R_O5,nsp);
1951
    nsp = guardreg(R_O5,nsp);
1935
    call_base_reg = getreg((nsp.fixed|PARAM_TREGS));
1952
    call_base_reg = getreg((nsp.fixed|PARAM_TREGS));
1936
    nsp = guardreg(call_base_reg,sp);
1953
    nsp = guardreg(call_base_reg,sp);
1937
    rsize = getreg(nsp.fixed);
1954
    rsize = getreg(nsp.fixed);
1938
    nsp = guardreg(rsize,sp);
1955
    nsp = guardreg(rsize,sp);
1939
    rsrc = getreg(nsp.fixed);
1956
    rsrc = getreg(nsp.fixed);
1940
    nsp = guardreg(rsrc,nsp);
1957
    nsp = guardreg(rsrc,nsp);
Line 1942... Line 1959...
1942
    nsp = guardreg(rdest,nsp);
1959
    nsp = guardreg(rdest,nsp);
1943
    rrr_ins(i_sub,callee_end_reg,callee_start_reg,rsize);
1960
    rrr_ins(i_sub,callee_end_reg,callee_start_reg,rsize);
1944
    rr_ins(i_mov,R_SP,call_base_reg);
1961
    rr_ins(i_mov,R_SP,call_base_reg);
1945
    alloc_reg_space(rsize,rdest); /* */
1962
    alloc_reg_space(rsize,rdest); /* */
1946
    rrr_ins(i_add,rdest,rsize,rdest);
1963
    rrr_ins(i_add,rdest,rsize,rdest);
1947
        
1964
 
1948
    /* now do top-down copy of parameters */
1965
    /* now do top-down copy of parameters */
1949
    rir_ins(i_sub,callee_end_reg, 4*(PTR_SZ>>3), rsrc);
1966
    rir_ins(i_sub,callee_end_reg, 4*(PTR_SZ>>3), rsrc);
1950
    rir_ins(i_sub,rdest, 4*(PTR_SZ>>3), rdest);
1967
    rir_ins(i_sub,rdest, 4*(PTR_SZ>>3), rdest);
1951
    /*condrr_ins(i_be,rdest,rsrc,end_copy_lab);*/
1968
    /*condrr_ins(i_be,rdest,rsrc,end_copy_lab);*/
1952
    set_label(start_copy_lab);
1969
    set_label(start_copy_lab);
1953
    b.base = rsrc;
1970
    b.base = rsrc;
1954
    b.offset = -(PTR_SZ>>3);
1971
    b.offset = - (PTR_SZ>>3);
1955
    rtmp = getreg(nsp.fixed);
1972
    rtmp = getreg(nsp.fixed);
1956
    ld_ro_ins(i_ld,b,rtmp);
1973
    ld_ro_ins(i_ld,b,rtmp);
1957
    b.base = rdest;
1974
    b.base = rdest;
1958
    st_ro_ins(i_st,rtmp,b);
1975
    st_ro_ins(i_st,rtmp,b);
1959
    rir_ins(i_sub,rsrc,PTR_SZ>>3,rsrc);
1976
    rir_ins(i_sub,rsrc,PTR_SZ>>3,rsrc);
1960
    rir_ins(i_sub,rdest,PTR_SZ>>3,rdest);
1977
    rir_ins(i_sub,rdest,PTR_SZ>>3,rdest);
1961
    condrr_ins(i_bne,rsrc,callee_start_reg,start_copy_lab);
1978
    condrr_ins(i_bne,rsrc,callee_start_reg,start_copy_lab);
1962
    set_label(end_copy_lab);
1979
    set_label(end_copy_lab);
1963
    /* callee_start_reg will now be rdest */
1980
    /* callee_start_reg will now be rdest */
1964
    rr_ins(i_mov,rdest,callee_start_reg_out);
1981
    rr_ins(i_mov,rdest,callee_start_reg_out);
1965
    
1982
 
1966
    if(vc) {
1983
    if (vc) {
1967
      rrr_ins(i_add,callee_start_reg_out,rsize,callee_end_reg_out);
1984
      rrr_ins(i_add,callee_start_reg_out,rsize,callee_end_reg_out);
1968
    }
1985
    }
1969
  }
1986
  }
1970
  else {
1987
  else {
1971
    int size_of_callees = proc_state.callee_size/8;
1988
    int size_of_callees = proc_state.callee_size/8;
1972
    int rdest;
1989
    int rdest;
1973
    int el;
1990
    int el;
1974
    int rsrc;
1991
    int rsrc;
1975
    space nsp;
1992
    space nsp;
1976
    int tmpreg ;
1993
    int tmpreg;
1977
    nsp = guardreg(R_O4,sp);
1994
    nsp = guardreg(R_O4,sp);
1978
    nsp = guardreg(R_O5,nsp);
1995
    nsp = guardreg(R_O5,nsp);
1979
    call_base_reg = getreg((nsp.fixed|PARAM_TREGS));
1996
    call_base_reg = getreg((nsp.fixed|PARAM_TREGS));
1980
    nsp = guardreg(call_base_reg,sp);
1997
    nsp = guardreg(call_base_reg,sp);
1981
    rdest = getreg(nsp.fixed);
1998
    rdest = getreg(nsp.fixed);
Line 1988... Line 2005...
1988
    b.offset = size_of_callees - (PTR_SZ>>3);
2005
    b.offset = size_of_callees - (PTR_SZ>>3);
1989
    st_ro_ins(i_st,R_FP,b);
2006
    st_ro_ins(i_st,R_FP,b);
1990
    rsrc = getreg(nsp.fixed);
2007
    rsrc = getreg(nsp.fixed);
1991
    rir_ins(i_add,callee_start_reg,size_of_callees,rsrc);
2008
    rir_ins(i_add,callee_start_reg,size_of_callees,rsrc);
1992
    /*rir_ins(i_add,rdest,size_of_callees,rdest);*/
2009
    /*rir_ins(i_add,rdest,size_of_callees,rdest);*/
1993
    for(el=(size_of_callees-4*(PTR_SZ>>3));el>0;el-=(PTR_SZ>>3)){
2010
    for (el= (size_of_callees-4*(PTR_SZ>>3));el>0;el-= (PTR_SZ>>3)) {
1994
      b.base = rsrc;
2011
      b.base = rsrc;
1995
      b.offset = el - size_of_callees - (PTR_SZ>>3);
2012
      b.offset = el - size_of_callees - (PTR_SZ>>3);
1996
      ld_ro_ins(i_ld,b,tmpreg);
2013
      ld_ro_ins(i_ld,b,tmpreg);
1997
      b.base = rdest;
2014
      b.base = rdest;
1998
      b.offset = el - (PTR_SZ>>3);
2015
      b.offset = el - (PTR_SZ>>3);
1999
      st_ro_ins(i_st,tmpreg,b);
2016
      st_ro_ins(i_st,tmpreg,b);
2000
    }
2017
    }
2001
    /* callee_start_reg will no be rdest */
2018
    /* callee_start_reg will no be rdest */
2002
    if(vc) {
2019
    if (vc) {
2003
      rir_ins(i_add,rdest,size_of_callees,callee_end_reg_out);
2020
      rir_ins(i_add,rdest,size_of_callees,callee_end_reg_out);
2004
      /*rr_ins(i_mov,rdest,callee_end_reg_out);*/
2021
      /*rr_ins(i_mov,rdest,callee_end_reg_out);*/
2005
    }
2022
    }
2006
    rr_ins(i_mov,rdest,callee_start_reg_out);
2023
    rr_ins(i_mov,rdest,callee_start_reg_out);
2007
    /*rir_ins(i_sub,rdest,size_of_callees,callee_start_reg_out);*/
2024
    /*rir_ins(i_sub,rdest,size_of_callees,callee_start_reg_out);*/
2008
  }
2025
  }
2009
  return mka;
2026
  return mka;
2010
}
2027
}
2011
 
2028
 
2012
 
2029
 
2013
/* 
2030
/*
2014
   Produce code to dynamically construct a new set of callee params.  The
2031
   Produce code to dynamically construct a new set of callee params.  The
2015
   parameters are placed in a specially allocated piece of the current stack, 
2032
   parameters are placed in a specially allocated piece of the current stack,
2016
   and pointed to by callee_start_reg and callee_end_reg.
2033
   and pointed to by callee_start_reg and callee_end_reg.
2017
*/
2034
*/
2018
makeans make_make_dynamic_callee_tag 
2035
makeans make_make_dynamic_callee_tag
2019
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
2020
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
2036
(exp e, space sp, where dest, int exitlab) {
2021
  /* bool vc = call_has_vcallees(e); */
2037
  /* bool vc = call_has_vcallees(e); */
2022
  int rptr,rsize,rdest,r_true_size;
2038
  int rptr,rsize,rdest,r_true_size;
2023
  int copy_start_lab = new_label();
2039
  int copy_start_lab = new_label();
2024
  int copy_end_lab = new_label();
2040
  int copy_end_lab = new_label();
2025
  space nsp;
2041
  space nsp;
Line 2035... Line 2051...
2035
  nsp = guardreg(rptr,nsp);
2051
  nsp = guardreg(rptr,nsp);
2036
  load_reg(son(e),rptr,nsp);    /* rptr now contains a pointer to the start of
2052
  load_reg(son(e),rptr,nsp);    /* rptr now contains a pointer to the start of
2037
			       the callees */
2053
			       the callees */
2038
  rsize = getreg(nsp.fixed);
2054
  rsize = getreg(nsp.fixed);
2039
  nsp = guardreg(rsize,nsp);
2055
  nsp = guardreg(rsize,nsp);
2040
  load_reg(bro(son(e)),rsize,nsp); /* rsize now contains the size of the 
2056
  load_reg(bro(son(e)),rsize,nsp); /* rsize now contains the size of the
2041
				      callees */
2057
				      callees */
2042
  rdest = getreg(nsp.fixed);
2058
  rdest = getreg(nsp.fixed);
2043
  nsp = guardreg(rdest,nsp);
2059
  nsp = guardreg(rdest,nsp);
2044
  r_true_size = getreg(nsp.fixed);
2060
  r_true_size = getreg(nsp.fixed);
2045
  nsp = guardreg(r_true_size,nsp);
2061
  nsp = guardreg(r_true_size,nsp);
2046
  /*rdest = callee_start_reg_out;*/ /*getreg(nsp.fixed);*/
2062
  /*rdest = callee_start_reg_out;*/ /*getreg(nsp.fixed);*/
2047
  rir_ins(i_add,rsize,4*(PTR_SZ>>3)+7,r_true_size);
2063
  rir_ins(i_add,rsize,4*(PTR_SZ>>3) +7,r_true_size);
2048
  rir_ins(i_and,r_true_size,~7,r_true_size);
2064
  rir_ins(i_and,r_true_size,~7,r_true_size);
2049
  rr_ins(i_mov,R_SP,call_base_reg);
2065
  rr_ins(i_mov,R_SP,call_base_reg);
2050
  
2066
 
2051
  alloc_reg_space(r_true_size,rdest); /* */
2067
  alloc_reg_space(r_true_size,rdest); /* */
2052
  rrr_ins(i_add,rdest,r_true_size /*rsize*/,R_TMP);
2068
  rrr_ins(i_add,rdest,r_true_size /*rsize*/,R_TMP);
2053
  /*rrr_ins(i_sub,rdest,r_true_size,rdest);*/
2069
  /*rrr_ins(i_sub,rdest,r_true_size,rdest);*/
2054
  b.base = R_TMP;
2070
  b.base = R_TMP;
2055
  b.offset = -(PTR_SZ>>3);
2071
  b.offset = - (PTR_SZ>>3);
2056
  st_ro_ins(i_st,R_FP,b);
2072
  st_ro_ins(i_st,R_FP,b);
2057
  rr_ins(i_mov,rdest,callee_start_reg_out);
2073
  rr_ins(i_mov,rdest,callee_start_reg_out);
2058
  /*if(vc)*/ rr_ins(i_mov,R_TMP,callee_end_reg_out);
2074
  /*if(vc)*/ rr_ins(i_mov,R_TMP,callee_end_reg_out);
2059
  
2075
 
2060
  /* Now copy from rptr to rdest */
2076
  /* Now copy from rptr to rdest */
2061
  condrr_ins(i_ble,rsize,R_G0,copy_end_lab);  /* make shure size > 0 */
2077
  condrr_ins(i_ble,rsize,R_G0,copy_end_lab);  /* make shure size > 0 */
2062
  b.offset = 0;
2078
  b.offset = 0;
2063
  set_label(copy_start_lab);
2079
  set_label(copy_start_lab);
2064
  b.base = rptr;
2080
  b.base = rptr;
Line 2068... Line 2084...
2068
  rir_ins(i_add,rptr,PTR_SZ>>3,rptr);
2084
  rir_ins(i_add,rptr,PTR_SZ>>3,rptr);
2069
  rir_ins(i_add,rdest,PTR_SZ>>3,rdest);
2085
  rir_ins(i_add,rdest,PTR_SZ>>3,rdest);
2070
  rir_ins(i_sub,rsize,PTR_SZ>>3,rsize);
2086
  rir_ins(i_sub,rsize,PTR_SZ>>3,rsize);
2071
  condrr_ins(i_bgt,rsize,R_G0,copy_start_lab);
2087
  condrr_ins(i_bgt,rsize,R_G0,copy_start_lab);
2072
  set_label(copy_end_lab);
2088
  set_label(copy_end_lab);
2073
  return mka;
2089
  return mka;
2074
}
2090
}
-
 
2091
 
-
 
2092
 
-
 
2093
 
2075
 
2094
 
2076
  
-
 
2077
  
-
 
2078
  
-
 
2079
/*
2095
/*
2080
  This generates code for a tail_call tag.  The target of the call MUST be 
2096
  This generates code for a tail_call tag.  The target of the call MUST be
2081
  a general proc.
2097
  a general proc.
2082
*/
2098
*/
2083
makeans make_tail_call_tag 
2099
makeans make_tail_call_tag
2084
    PROTO_N ( ( e, sp, dest, exitlab ) )
-
 
2085
    PROTO_T ( exp e X space sp X where dest X int exitlab ){
2100
(exp e, space sp, where dest, int exitlab) {
2086
  exp fn = son(e);
2101
  exp fn = son(e);
2087
  exp cllees = bro(fn);
2102
  exp cllees = bro(fn);
2088
  exp bdy = son(current_proc);
2103
  exp bdy = son(current_proc);
2089
  space nsp;
2104
  space nsp;
2090
  bool vc = call_has_vcallees(cllees);
2105
  bool vc = call_has_vcallees(cllees);
2091
  int callee_size = proc_state.callee_size;
2106
  int callee_size = proc_state.callee_size;
2092
  makeans mka;
2107
  makeans mka;
2093
  baseoff bproc;
2108
  baseoff bproc;
2094
  bool glob = ((name(fn) == name_tag) && (name(son(fn)) == ident_tag) &&
2109
  bool glob = ((name(fn) == name_tag) && (name(son(fn)) == ident_tag) &&
2095
	       ((son(son(fn)) == nilexp) || (name(son(son(fn))) == proc_tag)
2110
	      ((son(son(fn)) == nilexp) || (name(son(son(fn))) == proc_tag)
2096
		|| (name(son(son(fn))) == general_proc_tag)));
2111
		|| (name(son(son(fn))) == general_proc_tag)));
2097
  bool trad_proc = 0;
2112
  bool trad_proc = 0;
2098
#ifdef GENCOMPAT
2113
#ifdef GENCOMPAT
2099
  if (!vc) {
2114
  if (!vc) {
2100
    if (name(cllees) == make_callee_list_tag) {
2115
    if (name(cllees) == make_callee_list_tag) {
Line 2114... Line 2129...
2114
 
2129
 
2115
  mka.lab = exitlab;
2130
  mka.lab = exitlab;
2116
  mka.regmove = R_G0;
2131
  mka.regmove = R_G0;
2117
  nsp = sp;
2132
  nsp = sp;
2118
  nsp.fixed |= PARAM_TREGS;
2133
  nsp.fixed |= PARAM_TREGS;
2119
  if(name(cllees) != same_callees_tag){
2134
  if (name(cllees)!= same_callees_tag) {
2120
    code_here(cllees,sp,nowhere);
2135
    code_here(cllees,sp,nowhere);
2121
  }
2136
  }
2122
#ifndef NEWDIAGS
2137
#ifndef NEWDIAGS
2123
  for(;name(bdy) == diagnose_tag;bdy=son(bdy));
2138
  for (;name(bdy) == diagnose_tag;bdy=son(bdy));
2124
#endif
2139
#endif
2125
 
2140
 
2126
  while(name(bdy) == ident_tag && isparam(bdy)){
2141
  while (name(bdy) == ident_tag && isparam(bdy)) {
2127
    exp sbdy = son(bdy);
2142
    exp sbdy = son(bdy);
2128
    baseoff b;
2143
    baseoff b;
2129
    b.base = R_FP;
2144
    b.base = R_FP;
2130
    b.offset = (no(sbdy)>>3) + (proc_state.params_offset>>3);
2145
    b.offset = (no(sbdy) >>3) + (proc_state.params_offset>>3);
2131
 
2146
 
2132
    if (name(sbdy) == formal_callee_tag) {
2147
    if (name(sbdy) == formal_callee_tag) {
2133
      if((props(bdy) & inanyreg)!=0) {
2148
      if ((props(bdy) & inanyreg)!=0) {
2134
	b.offset -= (proc_state.callee_size>>3);
2149
	b.offset -= (proc_state.callee_size>>3);
2135
	if(isvar(bdy)) {
2150
	if (isvar(bdy)) {
2136
	  if(is_floating(name(sh(bdy)))) {
2151
	  if (is_floating(name(sh(bdy)))) {
2137
	    stf_ins(i_st,no(bdy)<<1,b); 	/* add case for long double */
2152
	    stf_ins(i_st,no(bdy)<<1,b); 	/* add case for long double */
2138
	  }
2153
	  }
2139
	  else {
2154
	  else {
2140
	    st_ro_ins(i_st,no(bdy),b);
2155
	    st_ro_ins(i_st,no(bdy),b);
2141
	  }
2156
	  }
2142
	}
2157
	}
2143
      }
2158
      }
2144
    }
2159
    }
2145
    else if(props(sbdy)== 0 && ((props(bdy) & inanyreg)!=0)){
2160
    else if (props(sbdy) == 0 && ((props(bdy) & inanyreg)!=0)) {
2146
      /* move from reg to store */
2161
      /* move from reg to store */
2147
      if(isvar(bdy)){
2162
      if (isvar(bdy)) {
2148
	if(is_floating(name(sh(sbdy)))){
2163
	if (is_floating(name(sh(sbdy)))) {
2149
	  stf_ins(i_stf,no(bdy)<<1,b);
2164
	  stf_ins(i_stf,no(bdy) <<1,b);
2150
	}
2165
	}
2151
	else{
2166
	else{
2152
	  assert( IS_IN_REG(props(sbdy)));
2167
	  assert(IS_IN_REG(props(sbdy)));
2153
/*	  props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2168
/*	  props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2154
	  st_ro_ins(i_st,no(bdy),b);
2169
	  st_ro_ins(i_st,no(bdy),b);
2155
	}
2170
	}
2156
      }
2171
      }
2157
    }
2172
    }
2158
    else if(props(sbdy)!=0 && ((props(bdy)&inanyreg) == 0)){
2173
    else if (props(sbdy)!=0 && ((props(bdy) &inanyreg) == 0)) {
2159
      /* move from store to reg */
2174
      /* move from store to reg */
2160
      int par_reg = props(sbdy);
2175
      int par_reg = props(sbdy);
2161
      int last_reg = (shape_size(sh(sbdy)) > 32 ? par_reg+1 : par_reg);
2176
      int last_reg = (shape_size(sh(sbdy)) > 32 ? par_reg+1 : par_reg);
2162
      int past_reg = ((trad_proc) ? R_I5+1 : (vc)?R_I4:R_I5);
2177
      int past_reg = ((trad_proc)? R_I5+1 :(vc)?R_I4:R_I5);
2163
					  /* registers i4 & i5 are reserved
2178
					  /* registers i4 & i5 are reserved
2164
					       in general procs for handling
2179
					       in general procs for handling
2165
					       of callee parameters */
2180
					       of callee parameters */
2166
      assert( IS_IN_REG(par_reg));
2181
      assert(IS_IN_REG(par_reg));
2167
/*    props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2182
/*    props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2168
      if ((last_param(bdy) && isvis(bdy) && !Has_no_vcallers)
2183
      if ((last_param(bdy) && isvis(bdy) && !Has_no_vcallers)
2169
		|| last_reg >= past_reg)
2184
		|| last_reg >= past_reg)
2170
	last_reg = past_reg - 1;
2185
	last_reg = past_reg - 1;
2171
      while(par_reg <= last_reg) {
2186
      while (par_reg <= last_reg) {
2172
	ld_ro_ins(i_ld,b,par_reg);
2187
	ld_ro_ins(i_ld,b,par_reg);
2173
	++par_reg;
2188
	++par_reg;
2174
	b.offset += 4;
2189
	b.offset += 4;
2175
      }
2190
      }
2176
    }
2191
    }
2177
    else if(props(sbdy) != 0 && (props(sbdy) != no(bdy))){
2192
    else if (props(sbdy)!= 0 && (props(sbdy)!= no(bdy))) {
2178
      if(is_floating(name(sh(sbdy)))){
2193
      if (is_floating(name(sh(sbdy)))) {
2179
	freg fr;
2194
	freg fr;
2180
	fr.fr = no(bdy);
2195
	fr.fr = no(bdy);
2181
	fr.dble = (name(sh(sbdy)) == realhd);
2196
	fr.dble = (name(sh(sbdy)) == realhd);
2182
	stf_ins ( i_st, fr.fr<<1, mem_temp ( 0 ) ) ;
2197
	stf_ins(i_st, fr.fr<<1, mem_temp(0));
2183
	ld_ro_ins ( i_ld, mem_temp ( 0 ), props(sbdy) ) ;
2198
	ld_ro_ins(i_ld, mem_temp(0), props(sbdy));
2184
	if ( fr.dble ) {
2199
	if (fr.dble) {
2185
	  stf_ins ( i_st, ( fr.fr << 1 ) + 1,
2200
	  stf_ins(i_st,(fr.fr << 1) + 1,
2186
		    mem_temp ( 4 ) ) ;
2201
		    mem_temp(4));
2187
	  ld_ro_ins ( i_ld, mem_temp ( 4 ), props(sbdy)+ 1 ) ;
2202
	  ld_ro_ins(i_ld, mem_temp(4), props(sbdy) + 1);
2188
	}
2203
	}
2189
      }
2204
      }
2190
      else{
2205
      else{
2191
	assert( IS_IN_REG(props(sbdy)));
2206
	assert(IS_IN_REG(props(sbdy)));
2192
/*	props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2207
/*	props(sbdy) = (props(sbdy)-R_I0)+R_O0;*/
2193
	rr_ins(i_mov,no(bdy),props(sbdy));
2208
	rr_ins(i_mov,no(bdy),props(sbdy));
2194
      }
2209
      }
2195
    }
2210
    }
2196
    bdy = bro(sbdy);
2211
    bdy = bro(sbdy);
2197
  }
2212
  }
2198
 
2213
 
2199
  bproc = boff(son(fn));
2214
  bproc = boff(son(fn));
Line 2205... Line 2220...
2205
      set_ins(bproc,r);
2220
      set_ins(bproc,r);
2206
    }
2221
    }
2207
    else{
2222
    else{
2208
      load_reg(fn,r,nsp);
2223
      load_reg(fn,r,nsp);
2209
    }
2224
    }
2210
    if(!sysV_assembler) {
2225
    if (!sysV_assembler) {
2211
	/* with -O2 SunOS corrupts unusual jmp/restore combination. */
2226
	/* with -O2 SunOS corrupts unusual jmp/restore combination. */
2212
      outs("\t.optim\t\"-O0\"\n"); 
2227
      outs("\t.optim\t\"-O0\"\n");
2213
    }
2228
    }
2214
#ifdef NEWDWARF
2229
#ifdef NEWDWARF
2215
    if (current_dg_info) {
2230
    if (current_dg_info) {
2216
	current_dg_info->data.i_lj.brk = set_dw_text_label ();
2231
	current_dg_info->data.i_lj.brk = set_dw_text_label();
2217
	current_dg_info->data.i_lj.j.k = WH_REG;
2232
	current_dg_info->data.i_lj.j.k = WH_REG;
2218
	current_dg_info->data.i_lj.j.u.l = r;
2233
	current_dg_info->data.i_lj.j.u.l = r;
2219
    }
2234
    }
2220
#endif
2235
#endif
2221
    extj_reg_ins_no_delay(i_jmp,r,-1);
2236
    extj_reg_ins_no_delay(i_jmp,r,-1);
Line 2227... Line 2242...
2227
  }
2242
  }
2228
  else
2243
  else
2229
#endif
2244
#endif
2230
  {
2245
  {
2231
    bproc.offset = 12;
2246
    bproc.offset = 12;
2232
    if(name(cllees)!= same_callees_tag) {
2247
    if (name(cllees)!= same_callees_tag) {
2233
      rr_ins(i_mov,callee_start_reg_out,callee_start_reg);
2248
      rr_ins(i_mov,callee_start_reg_out,callee_start_reg);
2234
      if(vc) rr_ins(i_mov,callee_end_reg_out,callee_end_reg);
2249
      if (vc)rr_ins(i_mov,callee_end_reg_out,callee_end_reg);
2235
    }
2250
    }
2236
    if(name(cllees) == same_callees_tag && (vc && !Has_vcallees)) {
2251
    if (name(cllees) == same_callees_tag && (vc && !Has_vcallees)) {
2237
      rir_ins(i_add,callee_start_reg,callee_size>>3,callee_end_reg);
2252
      rir_ins(i_add,callee_start_reg,callee_size>>3,callee_end_reg);
2238
    }
2253
    }
2239
  
2254
 
2240
    {
2255
    {
2241
      int r = getreg(nsp.fixed);
2256
      int r = getreg(nsp.fixed);
2242
      if(glob){
2257
      if (glob) {
2243
	set_ins(bproc,r);
2258
	set_ins(bproc,r);
2244
#ifdef NEWDWARF
2259
#ifdef NEWDWARF
2245
	if (current_dg_info) {
2260
	if (current_dg_info) {
2246
	  current_dg_info->data.i_lj.brk = set_dw_text_label ();
2261
	  current_dg_info->data.i_lj.brk = set_dw_text_label();
2247
	  current_dg_info->data.i_lj.j.k = WH_REG;
2262
	  current_dg_info->data.i_lj.j.k = WH_REG;
2248
	  current_dg_info->data.i_lj.j.u.l = r;
2263
	  current_dg_info->data.i_lj.j.u.l = r;
2249
	}
2264
	}
2250
#endif
2265
#endif
2251
	extj_reg_ins(i_jmp,r,-1);
2266
	extj_reg_ins(i_jmp,r,-1);
2252
      }
2267
      }
2253
      else{
2268
      else{
2254
	load_reg(fn,r,nsp);
2269
	load_reg(fn,r,nsp);
2255
	rir_ins(i_add,r,12,r);
2270
	rir_ins(i_add,r,12,r);
2256
#ifdef NEWDWARF
2271
#ifdef NEWDWARF
2257
	if (current_dg_info) {
2272
	if (current_dg_info) {
2258
	  current_dg_info->data.i_lj.brk = set_dw_text_label ();
2273
	  current_dg_info->data.i_lj.brk = set_dw_text_label();
2259
	  current_dg_info->data.i_lj.j.k = WH_REG;
2274
	  current_dg_info->data.i_lj.j.k = WH_REG;
2260
	  current_dg_info->data.i_lj.j.u.l = r;
2275
	  current_dg_info->data.i_lj.j.u.l = r;
2261
	}
2276
	}
2262
#endif
2277
#endif
2263
	extj_reg_ins(i_jmp,r,-1);
2278
	extj_reg_ins(i_jmp,r,-1);
2264
      }
2279
      }
2265
    }
2280
    }
2266
  }
2281
  }
2267
  clear_all();
2282
  clear_all();
2268
  return mka;
2283
  return mka;
2269
}	
2284
}
2270
 
2285
 
2271
 
2286
 
2272
 
2287
 
2273
 
2288