Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 395... Line 425...
395
  0x1ff, 0x3ff, 0x7ff, 0xfff,
425
  0x1ff, 0x3ff, 0x7ff, 0xfff,
396
  0x1fff, 0x3fff, 0x7fff, 0xffff,
426
  0x1fff, 0x3fff, 0x7fff, 0xffff,
397
  0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
427
  0x1ffff, 0x3ffff, 0x7ffff, 0xfffff,
398
  0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
428
  0x1fffff, 0x3fffff, 0x7fffff, 0xffffff,
399
  0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
429
  0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
400
  0x1fffffff, 0x3fffffff, 0x7fffffff, (int)0xffffffff
430
  0x1fffffff, 0x3fffffff, 0x7fffffff,(int)0xffffffff
401
};
431
};
402
 
432
 
403
int  msmask[33] = {
433
int  msmask[33] = {
404
  0,
434
  0,
405
  (int)0x80000000, (int)0xc0000000, (int)0xe0000000, (int)0xf0000000,
435
 (int)0x80000000,(int)0xc0000000,(int)0xe0000000,(int)0xf0000000,
406
  (int)0xf8000000, (int)0xfc000000, (int)0xfe000000, (int)0xff000000,
436
 (int)0xf8000000,(int)0xfc000000,(int)0xfe000000,(int)0xff000000,
407
  (int)0xff800000, (int)0xffc00000, (int)0xffe00000, (int)0xfff00000,
437
 (int)0xff800000,(int)0xffc00000,(int)0xffe00000,(int)0xfff00000,
408
  (int)0xfff80000, (int)0xfffc0000, (int)0xfffe0000, (int)0xffff0000,
438
 (int)0xfff80000,(int)0xfffc0000,(int)0xfffe0000,(int)0xffff0000,
409
  (int)0xffff8000, (int)0xffffc000, (int)0xffffe000, (int)0xfffff000,
439
 (int)0xffff8000,(int)0xffffc000,(int)0xffffe000,(int)0xfffff000,
410
  (int)0xfffff800, (int)0xfffffc00, (int)0xfffffe00, (int)0xffffff00,
440
 (int)0xfffff800,(int)0xfffffc00,(int)0xfffffe00,(int)0xffffff00,
411
  (int)0xffffff80, (int)0xffffffc0, (int)0xffffffe0, (int)0xfffffff0,
441
 (int)0xffffff80,(int)0xffffffc0,(int)0xffffffe0,(int)0xfffffff0,
412
  (int)0xfffffff8, (int)0xfffffffc, (int)0xfffffffe, (int)0xffffffff
442
 (int)0xfffffff8,(int)0xfffffffc,(int)0xfffffffe,(int)0xffffffff
413
};
443
};
414
 
444
 
415
static int flpt_test_no[] = {0, 0x45, 0x5, 0x5, 0x41, 0x44, 0x44,
445
static int flpt_test_no[] = {0, 0x45, 0x5, 0x5, 0x41, 0x44, 0x44,
416
			     0x41, 0x5, 0x5, 0x45, 0x40, 0x40, 0x4, 0x4};
446
			     0x41, 0x5, 0x5, 0x45, 0x40, 0x40, 0x4, 0x4};
417
 
447
 
418
 
448
 
419
/* PROCEDURES */
449
/* PROCEDURES */
420
 
450
 
421
static void try_overflow
451
static void try_overflow
422
    PROTO_N ( (sha, inv) )
-
 
423
    PROTO_T ( shape sha X int inv )
452
(shape sha, int inv)
424
{
453
{
425
  if (overflow_e != nilexp) {
454
  if (overflow_e != nilexp) {
426
    exp oe = overflow_e;
455
    exp oe = overflow_e;
427
    if (isov(overflow_e)) {
456
    if (isov(overflow_e)) {
428
      exp jd = pt(son(pt(overflow_e)));
457
      exp jd = pt(son(pt(overflow_e)));
429
      overflow_e = nilexp;
458
      overflow_e = nilexp;
430
      jmp_overflow (jd, is_signed(sha), inv);
459
      jmp_overflow(jd, is_signed(sha), inv);
431
    }
460
    }
432
    else
461
    else
433
    if (istrap(overflow_e)) {
462
    if (istrap(overflow_e)) {
434
      overflow_e = nilexp;
463
      overflow_e = nilexp;
435
      trap_overflow (is_signed(sha), inv);
464
      trap_overflow(is_signed(sha), inv);
436
    }
465
    }
437
    overflow_e = oe;
466
    overflow_e = oe;
438
  }
467
  }
439
  return;
468
  return;
440
}
469
}
441
 
470
 
442
static void test_exception
471
static void test_exception
443
    PROTO_N ( (test_no, sha) )
-
 
444
    PROTO_T ( int test_no X shape sha )
472
(int test_no, shape sha)
445
{
473
{
446
  if (overflow_e != nilexp) {
474
  if (overflow_e != nilexp) {
447
    exp oe = overflow_e;
475
    exp oe = overflow_e;
448
    if (isov(overflow_e)) {
476
    if (isov(overflow_e)) {
449
      exp jd = pt(son(pt(overflow_e)));
477
      exp jd = pt(son(pt(overflow_e)));
450
      overflow_e = nilexp;
478
      overflow_e = nilexp;
451
      branch (test_no, jd, is_signed(sha), name(sha));
479
      branch(test_no, jd, is_signed(sha), name(sha));
452
    }
480
    }
453
    else
481
    else
454
    if (istrap(overflow_e)) {
482
    if (istrap(overflow_e)) {
455
      overflow_e = nilexp;
483
      overflow_e = nilexp;
456
      test_trap (test_no, is_signed(sha), name(sha));
484
      test_trap(test_no, is_signed(sha), name(sha));
457
    }
485
    }
458
    overflow_e = oe;
486
    overflow_e = oe;
459
  }
487
  }
460
  return;
488
  return;
461
}
489
}
462
 
490
 
463
static void do_exception
491
static void do_exception
464
    PROTO_Z ()
492
(void)
465
{
493
{
466
  if (overflow_e != nilexp) {
494
  if (overflow_e != nilexp) {
467
    exp oe = overflow_e;
495
    exp oe = overflow_e;
468
    if (isov(overflow_e)) {
496
    if (isov(overflow_e)) {
469
      exp jd = pt(son(pt(overflow_e)));
497
      exp jd = pt(son(pt(overflow_e)));
470
      overflow_e = nilexp;
498
      overflow_e = nilexp;
471
      jump (jd, 0);
499
      jump(jd, 0);
472
    }
500
    }
473
    else
501
    else
474
    if (istrap(overflow_e)) {
502
    if (istrap(overflow_e)) {
475
      overflow_e = nilexp;
503
      overflow_e = nilexp;
476
      trap_ins(f_overflow);
504
      trap_ins(f_overflow);
Line 481... Line 509...
481
}
509
}
482
 
510
 
483
 
511
 
484
 
512
 
485
static int use_pop_ass
513
static int use_pop_ass
486
    PROTO_N ( (n, ln) )
-
 
487
    PROTO_T ( exp n X exp ln )
514
(exp n, exp ln)
488
{
515
{
489
  exp id;
516
  exp id;
490
  if (name (ln) == cont_tag)
517
  if (name(ln) == cont_tag)
491
    ln = son (ln);
518
    ln = son(ln);
492
  if (name (ln) != name_tag)
519
  if (name(ln)!= name_tag)
493
    return (0);
520
    return(0);
494
  id = son (ln);
521
  id = son(ln);
495
  while (n != id && last (n) &&
522
  while (n != id && last(n) &&
496
	 (is_a(name(n)) || name(n) == ident_tag ||
523
	(is_a(name(n)) || name(n) == ident_tag ||
497
		name(n) == ass_tag))
524
		name(n) == ass_tag))
498
    n = bro (n);
525
    n = bro(n);
499
  if (n == id)
526
  if (n == id)
500
    return (get_reg_no (no (id)) - fstack_pos + 2);
527
    return(get_reg_no(no(id)) - fstack_pos + 2);
501
  return (0);
528
  return(0);
502
}
529
}
503
 
530
 
504
 
531
 
505
static int   use_pop
532
static int   use_pop
506
    PROTO_N ( (n, ln) )
-
 
507
    PROTO_T ( exp n X exp ln )
533
(exp n, exp ln)
508
{
534
{
509
  exp id;
535
  exp id;
510
  if (name (ln) == cont_tag)
536
  if (name(ln) == cont_tag)
511
    ln = son (ln);
537
    ln = son(ln);
512
  if (name (ln) != name_tag)
538
  if (name(ln)!= name_tag)
513
    return (0);
539
    return(0);
514
  id = son (ln);
540
  id = son(ln);
515
  while (n != id && last (n))
541
  while (n != id && last(n))
516
    n = bro (n);
542
    n = bro(n);
517
  if (n == id)
543
  if (n == id)
518
    return (get_reg_no (no (id)) - fstack_pos + 2);
544
    return(get_reg_no(no(id)) - fstack_pos + 2);
519
  return (0);
545
  return(0);
520
}
546
}
521
 
547
 
522
int  count_regs
548
int  count_regs
523
    PROTO_N ( (mask) )
-
 
524
    PROTO_T ( int mask )
549
(int mask)
525
{
550
{
526
  return (bits_in[mask & 0xf] + bits_in[(mask >> 4) & 0x3]);
551
  return(bits_in[mask & 0xf] + bits_in[(mask >> 4) & 0x3]);
527
}
552
}
528
 
553
 
529
static void cmp64_contop
554
static void cmp64_contop
530
    PROTO_N ( (d) )
-
 
531
    PROTO_T ( int d )
555
(int d)
532
{
556
{
533
  if (d && contop_dopop) {
557
  if (d && contop_dopop) {
534
    int lolab = next_lab();
558
    int lolab = next_lab();
535
    simple_branch (je, lolab);
559
    simple_branch(je, lolab);
536
    if (contop_dopop == 1)
560
    if (contop_dopop == 1)
537
     {
561
     {
538
      ins1 (popl, size32, SPILLREG);
562
      ins1(popl, size32, SPILLREG);
539
#ifdef NEWDWARF
563
#ifdef NEWDWARF
540
      if (diagnose && dwarf2 && no_frame)
564
      if (diagnose && dwarf2 && no_frame)
541
	dw2_track_pop();
565
	dw2_track_pop();
542
#endif
566
#endif
543
     }
567
     }
544
    else
568
    else
545
     {
569
     {
546
	exp ap = getexp (f_bottom, nilexp, 0, sp.where_exp,
570
	exp ap = getexp(f_bottom, nilexp, 0, sp.where_exp,
547
                          nilexp, 0, 4, reff_tag);
571
                          nilexp, 0, 4, reff_tag);
548
        ins2 (leal, size32, size32, mw (ap, 0), sp);
572
        ins2(leal, size32, size32, mw(ap, 0), sp);
549
     };
573
     };
550
    simple_branch (jmp, cmp_64hilab);
574
    simple_branch(jmp, cmp_64hilab);
551
    simplest_set_lab (lolab);
575
    simplest_set_lab(lolab);
552
  }
576
  }
553
  else
577
  else
554
    simple_branch (jne, cmp_64hilab);
578
    simple_branch(jne, cmp_64hilab);
555
  return;
579
  return;
556
}
580
}
557
 
581
 
558
 
582
 
559
void end_contop
583
void end_contop
560
    PROTO_Z ()
584
(void)
561
{
585
{
562
  if (contop_level == 0)
586
  if (contop_level == 0)
563
    reg0_in_use = 0;
587
    reg0_in_use = 0;
564
  if (contop_dopop) {
588
  if (contop_dopop) {
565
    if (contop_dopop == 1)
589
    if (contop_dopop == 1)
566
     {
590
     {
567
      ins1 (popl, size32, SPILLREG);
591
      ins1(popl, size32, SPILLREG);
568
#ifdef NEWDWARF
592
#ifdef NEWDWARF
569
      if (diagnose && dwarf2 && no_frame)
593
      if (diagnose && dwarf2 && no_frame)
570
	dw2_track_pop();
594
	dw2_track_pop();
571
#endif
595
#endif
572
     }
596
     }
573
    else
597
    else
574
     {
598
     {
575
	exp ap = getexp (f_bottom, nilexp, 0, sp.where_exp,
599
	exp ap = getexp(f_bottom, nilexp, 0, sp.where_exp,
576
                          nilexp, 0, 4, reff_tag);
600
                          nilexp, 0, 4, reff_tag);
577
        ins2 (leal, size32, size32, mw (ap, 0), sp);
601
        ins2(leal, size32, size32, mw(ap, 0), sp);
578
     };
602
     };
579
    invalidate_dest (SPILLREG);
603
    invalidate_dest(SPILLREG);
580
    contop_dopop = 0;
604
    contop_dopop = 0;
581
    extra_stack -= 32;
605
    extra_stack -= 32;
582
    min_rfree |= SPILLMASK;
606
    min_rfree |= SPILLMASK;
583
  };
607
  };
584
  return;
608
  return;
585
}
609
}
586
 
610
 
587
 
611
 
588
/* if a in cont or ass of an identified object, load the address */
612
/* if a in cont or ass of an identified object, load the address */
589
void contop
613
void contop
590
    PROTO_N ( (a, r0inuse, dest) )
-
 
591
    PROTO_T ( exp a X int r0inuse X where dest )
614
(exp a, int r0inuse, where dest)
592
{
615
{
593
  unsigned char  n = name (a);
616
  unsigned char  n = name(a);
594
  int  offset = 0;
617
  int  offset = 0;
595
 
618
 
596
  contop_level++;
619
  contop_level++;
597
 
620
 
598
  if (PIC_code) {
621
  if (PIC_code) {
Line 603... Line 626...
603
    SPILLREG = reg3;
626
    SPILLREG = reg3;
604
    SPILLMASK = 0x8;
627
    SPILLMASK = 0x8;
605
  };
628
  };
606
 
629
 
607
  if ((n == cont_tag || n == ass_tag || n == reff_tag)
630
  if ((n == cont_tag || n == ass_tag || n == reff_tag)
608
      && name (son (a)) == ident_tag) {
631
      && name(son(a)) == ident_tag) {
609
		/* IF 1 */
632
		/* IF 1 */
610
    ash st;				/* dummy stack for use by coder */
633
    ash st;				/* dummy stack for use by coder */
611
    exp fin = bro (son (son (a)));	/* fin holds body of final
634
    exp fin = bro (son (son (a)));	/* fin holds body of final
612
					   identity */
635
					   identity */
613
    unsigned char  oldn = name (fin);		/* oldn hold name of final
636
    unsigned char  oldn = name (fin);		/* oldn hold name of final
614
					   identity */
637
					   identity */
615
    exp id1 = son (a);			/* outer identity */
638
    exp id1 = son (a);			/* outer identity */
616
    int  inreg1 = ptno (son (son (id1))) == reg_pl;
639
    int  inreg1 = ptno(son(son(id1))) == reg_pl;
617
					/* true if def of outer identity
640
					/* true if def of outer identity
618
					   is already in a register */
641
					   is already in a register */
619
    int  reg_mask = (~regsinuse) & 0x3e;
642
    int  reg_mask = (~regsinuse) & 0x3e;
620
    int  regs_free = count_regs (reg_mask);
643
    int  regs_free = count_regs(reg_mask);
621
					/* number of free integer
644
					/* number of free integer
622
					   registers */
645
					   registers */
623
    exp old_overflow_e;
646
    exp old_overflow_e;
624
    st.ashsize = 0;
647
    st.ashsize = 0;
625
    st.ashalign = 0;
648
    st.ashalign = 0;
Line 630... Line 653...
630
    if (oldn == ident_tag) {
653
    if (oldn == ident_tag) {
631
		/* IF 2 */
654
		/* IF 2 */
632
	/* body of id1 is an identity, so TWO identities, so
655
	/* body of id1 is an identity, so TWO identities, so
633
	   addptr ivolved */
656
	   addptr ivolved */
634
      exp id2 = bro (son (id1));	/* inner identity */
657
      exp id2 = bro (son (id1));	/* inner identity */
635
      int  inreg2 = ptno (son (son (id2))) == reg_pl;
658
      int  inreg2 = ptno(son(son(id2))) == reg_pl;
636
					/* true if def of inner identity
659
					/* true if def of inner identity
637
					   is already in a register */
660
					   is already in a register */
638
      int  regs_good = regs_free + inreg1 + inreg2;
661
      int  regs_good = regs_free + inreg1 + inreg2;
639
					/* we want two registers but the
662
					/* we want two registers but the
640
					   definitions of id1 and id2 will
663
					   definitions of id1 and id2 will
641
					   do */
664
					   do */
642
      fin = bro (son (fin));
665
      fin = bro(son(fin));
643
      oldn = name (fin);		/* correct fin and oldn */
666
      oldn = name (fin);		/* correct fin and oldn */
644
 
667
 
645
      if (regs_good < 2) {
668
      if (regs_good < 2) {
646
		/* IF 3 */
669
		/* IF 3 */
647
	/* we have two declarations and need some registers */
670
	/* we have two declarations and need some registers */
648
 
671
 
649
	if ((inreg1 + inreg2) == 1 && !reg0_in_use) {
672
	if ((inreg1 + inreg2) == 1 && !reg0_in_use) {
650
		/* with reg0 we have enough registers */
673
		/* with reg0 we have enough registers */
651
	  if (inreg2) {
674
	  if (inreg2) {
652
	    ptno (id1) = reg_pl;
675
	    ptno(id1) = reg_pl;
653
	    no (id1) = 1;		/* id1 uses reg0 */
676
	    no (id1) = 1;		/* id1 uses reg0 */
654
	    ptno (id2) = reg_pl;
677
	    ptno(id2) = reg_pl;
655
	    no (id2) = no (son (son (id2)));
678
	    no(id2) = no(son(son(id2)));
656
	  }
679
	  }
657
	  else {
680
	  else {
658
	    ptno (id2) = reg_pl;
681
	    ptno(id2) = reg_pl;
659
	    no (id2) = 1;		/* id2 uses reg0 */
682
	    no (id2) = 1;		/* id2 uses reg0 */
660
	    ptno (id1) = reg_pl;
683
	    ptno(id1) = reg_pl;
661
	    no (id1) = no (son (son (id1)));
684
	    no(id1) = no(son(son(id1)));
662
	  };
685
	  };
663
 
686
 
664
	  coder (mw (id1, 0), st, son (id1));
687
	  coder(mw(id1, 0), st, son(id1));
665
	  coder (mw (id2, 0), st, son (id2)); /* work out defs */
688
	  coder (mw (id2, 0), st, son (id2)); /* work out defs */
666
	  contop_level--;
689
	  contop_level--;
667
	  son (a) = fin;		/* code body in caller */
690
	  son (a) = fin;		/* code body in caller */
668
	  return;
691
	  return;
669
	};
692
	};
Line 674... Line 697...
674
					   no need to spill */
697
					   no need to spill */
675
	  where use_reg;		/* holds free register */
698
	  where use_reg;		/* holds free register */
676
 
699
 
677
	  if (regs_free == 1) {
700
	  if (regs_free == 1) {
678
	    frr f;
701
	    frr f;
679
	    f = first_reg (reg_mask);
702
	    f = first_reg(reg_mask);
680
	    use_reg = reg_wheres[f.fr_no];	/* free register from
703
	    use_reg = reg_wheres[f.fr_no];	/* free register from
681
						   mask */
704
						   mask */
682
	    min_rfree |= reg_mask;	/* mark as used */
705
	    min_rfree |= reg_mask;	/* mark as used */
683
	  }
706
	  }
684
	  else
707
	  else
685
	    use_reg = reg0;		/* reg0 is free */
708
	    use_reg = reg0;		/* reg0 is free */
686
 
709
 
687
	  if (name (fin) == reff_tag) {	/* remove reff */
710
	  if (name (fin) == reff_tag) {	/* remove reff */
688
	    offset = no (fin);
711
	    offset = no(fin);
689
	    fin = son (fin);
712
	    fin = son(fin);
690
	  };
713
	  };
691
          old_overflow_e = overflow_e;
714
          old_overflow_e = overflow_e;
692
          overflow_e = nilexp;
715
          overflow_e = nilexp;
693
			/* this must be an addptr, note that the
716
			/* this must be an addptr, note that the
694
			   calculations cannot involve the free reg */
717
			   calculations cannot involve the free reg */
695
	  if (name (bro (son (fin))) == name_tag) {
718
	  if (name(bro(son(fin))) == name_tag) {
696
			/* the offset is named, so add the pointer to the
719
			/* the offset is named, so add the pointer to the
697
			   offset and put in the free register */
720
			   offset and put in the free register */
698
	    add (slongsh, mw (son (id2), 0), mw (son (id1), 0), use_reg);
721
	    add(slongsh, mw(son(id2), 0), mw(son(id1), 0), use_reg);
699
	  }
722
	  }
700
	  else {
723
	  else {
701
			/* this is an offset_mult so do the arithmetic of
724
			/* this is an offset_mult so do the arithmetic of
702
			   address calculation and put the address in
725
			   address calculation and put the address in
703
			   the free register */
726
			   the free register */
704
	    exp m = bro (son (fin));
727
	    exp m = bro(son(fin));
705
            move(slongsh, mw (son (id1), 0), use_reg);
728
            move(slongsh, mw(son(id1), 0), use_reg);
706
            mult (slongsh, use_reg, mw (bro (son (m)), 0),
729
            mult(slongsh, use_reg, mw(bro(son(m)), 0),
707
		use_reg);
730
		use_reg);
708
	    add (slongsh, mw (son (id2), 0), use_reg, use_reg);
731
	    add(slongsh, mw(son(id2), 0), use_reg, use_reg);
709
	  };
732
	  };
710
          overflow_e = old_overflow_e;
733
          overflow_e = old_overflow_e;
711
 
734
 
712
	  if (offset != 0) {
735
	  if (offset != 0) {
713
			/* put back the reff if there was one */
736
			/* put back the reff if there was one */
714
	    exp r = getexp (sh (son (a)), nilexp, 0, use_reg.where_exp,
737
	    exp r = getexp(sh(son(a)), nilexp, 0, use_reg.where_exp,
715
		nilexp, 0, offset, reff_tag);
738
		nilexp, 0, offset, reff_tag);
716
	    son (a) = r;
739
	    son(a) = r;
717
	  }
740
	  }
718
	  else
741
	  else
719
	    son (a) = use_reg.where_exp;
742
	    son(a) = use_reg.where_exp;
720
		/* the address is in the free register, code the rest
743
		/* the address is in the free register, code the rest
721
		   in caller */
744
		   in caller */
722
	  contop_level--;
745
	  contop_level--;
723
	  return;
746
	  return;
724
	};
747
	};
725
 
748
 
726
		/* we are a register short so spill SPILLREG */
749
		/* we are a register short so spill SPILLREG */
727
	ins1 (pushl, size32, SPILLREG);
750
	ins1(pushl, size32, SPILLREG);
728
#ifdef NEWDWARF
751
#ifdef NEWDWARF
729
	if (diagnose && dwarf2 && no_frame)
752
	if (diagnose && dwarf2 && no_frame)
730
	  dw2_track_push();
753
	  dw2_track_push();
731
#endif
754
#endif
732
	extra_stack += 32;
755
	extra_stack += 32;
733
	check_stack_max;
756
	check_stack_max;
734
 
757
 
735
	if (name (fin) == reff_tag) {	/* remove reff */
758
	if (name (fin) == reff_tag) {	/* remove reff */
736
	  offset = no (fin);
759
	  offset = no(fin);
737
	  fin = son (fin);
760
	  fin = son(fin);
738
	};
761
	};
739
 
762
 
740
        old_overflow_e = overflow_e;
763
        old_overflow_e = overflow_e;
741
        overflow_e = nilexp;
764
        overflow_e = nilexp;
742
		/* it must be an addptr */
765
		/* it must be an addptr */
743
	if (name (bro (son (fin))) == name_tag) {
766
	if (name(bro(son(fin))) == name_tag) {
744
		/* the offset is named */
767
		/* the offset is named */
745
	  move (slongsh, mw (son (id1), 0), SPILLREG);
768
	  move(slongsh, mw(son(id1), 0), SPILLREG);
746
			/* put the offset in SPILLREG */
769
			/* put the offset in SPILLREG */
747
 
770
 
748
	  if (eq_where (SPILLREG, mw (son (id2), 0)))
771
	  if (eq_where(SPILLREG, mw(son(id2), 0)))
749
			/* id2 is the SPILLREG, so add the pushed value */
772
			/* id2 is the SPILLREG, so add the pushed value */
750
	    add (slongsh, stack0, SPILLREG, SPILLREG);
773
	    add(slongsh, stack0, SPILLREG, SPILLREG);
751
	  else
774
	  else
752
			/* otherwise add def of id2 to SPILLREG */
775
			/* otherwise add def of id2 to SPILLREG */
753
	    add (slongsh, mw (son (id2), 0), SPILLREG, SPILLREG);
776
	    add(slongsh, mw(son(id2), 0), SPILLREG, SPILLREG);
754
	}
777
	}
755
	else {
778
	else {
756
		/* the offset is an offset_mult */
779
		/* the offset is an offset_mult */
757
	  exp m = bro (son (fin));
780
	  exp m = bro(son(fin));
758
	  move (slongsh, mw (son (id1), 0), SPILLREG);
781
	  move(slongsh, mw(son(id1), 0), SPILLREG);
759
			/* number to SPILLREG */
782
			/* number to SPILLREG */
760
	  mult (slongsh, SPILLREG, mw (bro (son (m)), 0), SPILLREG);
783
	  mult(slongsh, SPILLREG, mw(bro(son(m)), 0), SPILLREG);
761
			/* multiply by size */
784
			/* multiply by size */
762
	  if (eq_where (SPILLREG, mw (son (id2), 0)))
785
	  if (eq_where(SPILLREG, mw(son(id2), 0)))
763
			/* id2 is the SPILLREG, so add the pushed value */
786
			/* id2 is the SPILLREG, so add the pushed value */
764
	    add (slongsh, stack0, SPILLREG, SPILLREG);
787
	    add(slongsh, stack0, SPILLREG, SPILLREG);
765
	  else
788
	  else
766
			/* otherwise add def of id2 to SPILLREG */
789
			/* otherwise add def of id2 to SPILLREG */
767
	    add (slongsh, mw (son (id2), 0), SPILLREG, SPILLREG);
790
	    add(slongsh, mw(son(id2), 0), SPILLREG, SPILLREG);
768
	};
791
	};
769
        overflow_e = old_overflow_e;
792
        overflow_e = old_overflow_e;
770
 
793
 
771
	if (offset != 0) {	/* put back the reff if needed */
794
	if (offset != 0) {	/* put back the reff if needed */
772
	  exp r = getexp (sh (son (a)), nilexp, 0, SPILLREG.where_exp,
795
	  exp r = getexp(sh(son(a)), nilexp, 0, SPILLREG.where_exp,
773
	      nilexp, 0, offset, reff_tag);
796
	      nilexp, 0, offset, reff_tag);
774
	  son (a) = r;
797
	  son(a) = r;
775
	}
798
	}
776
	else
799
	else
777
	  son (a) = SPILLREG.where_exp;
800
	  son(a) = SPILLREG.where_exp;
778
			/* code the rest in the caller */
801
			/* code the rest in the caller */
779
 
802
 
780
	contop_level--;
803
	contop_level--;
781
 
804
 
782
	if (!eq_where (dest, SPILLREG))
805
	if (!eq_where(dest, SPILLREG))
783
	  contop_dopop = 1;	/* arrange to pop SPILLREG if not equal
806
	  contop_dopop = 1;	/* arrange to pop SPILLREG if not equal
784
				   to dest */
807
				   to dest */
785
	else
808
	else
786
	  contop_dopop = 2;	/* do not pop SPILREG */
809
	  contop_dopop = 2;	/* do not pop SPILREG */
787
	return;
810
	return;
Line 809... Line 832...
809
	  dw2_track_push();
832
	  dw2_track_push();
810
#endif
833
#endif
811
	extra_stack += 32;
834
	extra_stack += 32;
812
	check_stack_max;
835
	check_stack_max;
813
 
836
 
814
	move (slongsh, mw (son (id1), 0), SPILLREG);
837
	move(slongsh, mw(son(id1), 0), SPILLREG);
815
		/* put the pointer into SPILLREG */
838
		/* put the pointer into SPILLREG */
816
 
839
 
817
        ptno(id1) = reg_pl;
840
        ptno(id1) = reg_pl;
818
        no(id1) = SPILLMASK;	/* set place for identity to SPILLREG */
841
        no(id1) = SPILLMASK;	/* set place for identity to SPILLREG */
819
 
842
 
820
        son(a) = fin;	/* code the rest in caller */
843
        son(a) = fin;	/* code the rest in caller */
821
	contop_level--;
844
	contop_level--;
822
	if (!eq_where (dest, SPILLREG))
845
	if (!eq_where(dest, SPILLREG))
823
	  contop_dopop = 1;	/* arrange to pop SPILLREG */
846
	  contop_dopop = 1;	/* arrange to pop SPILLREG */
824
	else
847
	else
825
	  contop_dopop = 2;	/* do not pop SPILLREG */
848
	  contop_dopop = 2;	/* do not pop SPILLREG */
826
	return;
849
	return;
827
      };
850
      };
828
 
851
 
829
		/* reg0 is available */
852
		/* reg0 is available */
830
      move (slongsh, mw (son (id1), 0), reg0);
853
      move(slongsh, mw(son(id1), 0), reg0);
831
		/* put the pointer into reg0 */
854
		/* put the pointer into reg0 */
832
 
855
 
833
      ptno(id1) = reg_pl;
856
      ptno(id1) = reg_pl;
834
      no(id1) = 1;	/* set place for identity to reg0 */
857
      no(id1) = 1;	/* set place for identity to reg0 */
835
 
858
 
Line 854... Line 877...
854
 
877
 
855
 
878
 
856
 
879
 
857
 
880
 
858
void initzeros
881
void initzeros
859
    PROTO_Z ()
882
(void)
860
{
883
{
861
				/* set up the constants */
884
				/* set up the constants */
862
  int  flongmax = new_flpt ();
885
  int  flongmax = new_flpt();
863
  int  fllmax = new_flpt ();
886
  int  fllmax = new_flpt();
864
  int  fslongmax = new_flpt ();
887
  int  fslongmax = new_flpt();
865
  int  fsllmax = new_flpt ();
888
  int  fsllmax = new_flpt();
866
  int  i;
889
  int  i;
867
  flt * flongmaxr = &flptnos[flongmax];
890
  flt * flongmaxr = &flptnos[flongmax];
868
  flt * fllmaxr = &flptnos[fllmax];
891
  flt * fllmaxr = &flptnos[fllmax];
869
  flt * fslongmaxr = &flptnos[fslongmax];
892
  flt * fslongmaxr = &flptnos[fslongmax];
870
  flt * fsllmaxr = &flptnos[fsllmax];
893
  flt * fsllmaxr = &flptnos[fsllmax];
Line 876... Line 899...
876
  fslongmaxr -> sign = 1;
899
  fslongmaxr -> sign = 1;
877
  fslongmaxr -> exp = 1;
900
  fslongmaxr -> exp = 1;
878
  fsllmaxr -> sign = 1;
901
  fsllmaxr -> sign = 1;
879
  fsllmaxr -> exp = 3;
902
  fsllmaxr -> exp = 3;
880
  for (i = 0; i < MANT_SIZE; i++) {
903
  for (i = 0; i < MANT_SIZE; i++) {
881
    (flongmaxr -> mant)[i] = (unsigned short)((i == 0) ? 1 : 0);
904
   (flongmaxr -> mant)[i] = (unsigned short)((i == 0)? 1 : 0);
882
    (fllmaxr -> mant)[i] = (unsigned short)((i == 0) ? 1 : 0);
905
   (fllmaxr -> mant)[i] = (unsigned short)((i == 0)? 1 : 0);
883
    (fslongmaxr -> mant)[i] = (unsigned short)((i == 0) ? 32768 : 0);
906
   (fslongmaxr -> mant)[i] = (unsigned short)((i == 0)? 32768 : 0);
884
    (fsllmaxr -> mant)[i] = (unsigned short)((i == 0) ? 32768 : 0);
907
   (fsllmaxr -> mant)[i] = (unsigned short)((i == 0)? 32768 : 0);
885
  };
908
  };
886
 
909
 
887
  zeroe = getexp (f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
910
  zeroe = getexp(f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
888
  fzeroe = getexp (shrealsh, nilexp, 0, nilexp, nilexp, 0, fzero_no, real_tag);
911
  fzeroe = getexp(shrealsh, nilexp, 0, nilexp, nilexp, 0, fzero_no, real_tag);
889
  fonee = getexp (shrealsh, nilexp, 0, nilexp, nilexp, 0, fone_no, real_tag);
912
  fonee = getexp(shrealsh, nilexp, 0, nilexp, nilexp, 0, fone_no, real_tag);
890
  flongmaxe = getexp (shrealsh, nilexp, 0, nilexp, nilexp, 0,
913
  flongmaxe = getexp(shrealsh, nilexp, 0, nilexp, nilexp, 0,
891
      flongmax, real_tag);
914
      flongmax, real_tag);
892
  smaxe = getexp (realsh, nilexp, 0, nilexp, nilexp, 0,
915
  smaxe = getexp(realsh, nilexp, 0, nilexp, nilexp, 0,
893
      fslongmax, real_tag);
916
      fslongmax, real_tag);
894
  sllmaxe = getexp (doublesh, nilexp, 0, nilexp, nilexp, 0,
917
  sllmaxe = getexp(doublesh, nilexp, 0, nilexp, nilexp, 0,
895
      fsllmax, real_tag);
918
      fsllmax, real_tag);
896
  dzeroe = getexp (realsh, nilexp, 0, nilexp, nilexp, 0, fzero_no, real_tag);
919
  dzeroe = getexp(realsh, nilexp, 0, nilexp, nilexp, 0, fzero_no, real_tag);
897
  donee = getexp (realsh, nilexp, 0, nilexp, nilexp, 0, fone_no, real_tag);
920
  donee = getexp(realsh, nilexp, 0, nilexp, nilexp, 0, fone_no, real_tag);
898
  dlongmaxe = getexp (realsh, nilexp, 0, nilexp, nilexp, 0,
921
  dlongmaxe = getexp(realsh, nilexp, 0, nilexp, nilexp, 0,
899
      flongmax, real_tag);
922
      flongmax, real_tag);
900
  dllmaxe = getexp (doublesh, nilexp, 0, nilexp, nilexp, 0,
923
  dllmaxe = getexp(doublesh, nilexp, 0, nilexp, nilexp, 0,
901
      fllmax, real_tag);
924
      fllmax, real_tag);
902
  pushid = getexp (f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, apply_tag);
925
  pushid = getexp(f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, apply_tag);
903
  pushdest.where_exp = pushid;
926
  pushdest.where_exp = pushid;
904
  pushdest.where_off = 0;
927
  pushdest.where_off = 0;
905
  zero.where_exp = zeroe;
928
  zero.where_exp = zeroe;
906
  fzero.where_exp = fzeroe;
929
  fzero.where_exp = fzeroe;
907
  fone.where_exp = fonee;
930
  fone.where_exp = fonee;
Line 911... Line 934...
911
  fzero.where_off = 0;
934
  fzero.where_off = 0;
912
  fone.where_off = 0;
935
  fone.where_off = 0;
913
  dzero.where_off = 0;
936
  dzero.where_off = 0;
914
  done.where_off = 0;
937
  done.where_off = 0;
915
 
938
 
916
  dummys = getexp (slongsh, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
939
  dummys = getexp(slongsh, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
917
  dummyu = getexp (ulongsh, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
940
  dummyu = getexp(ulongsh, nilexp, 0, nilexp, nilexp, 0, 0, val_tag);
918
 
941
 
919
  reg0id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
942
  reg0id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
920
      0x1, ident_tag);
943
      0x1, ident_tag);
921
  ptno(reg0id) = reg_pl;
944
  ptno(reg0id) = reg_pl;
922
  reg0 = mw (getexp (slongsh, nilexp, 0, reg0id, nilexp, 0, 0, name_tag),
945
  reg0 = mw(getexp(slongsh, nilexp, 0, reg0id, nilexp, 0, 0, name_tag),
923
      0);
946
      0);
924
 
947
 
925
  reg0charid = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
948
  reg0charid = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
926
      0x1, ident_tag);
949
      0x1, ident_tag);
927
  ptno(reg0charid) = reg_pl;
950
  ptno(reg0charid) = reg_pl;
928
  reg0char = mw (getexp (scharsh, nilexp, 0, reg0id,
951
  reg0char = mw(getexp(scharsh, nilexp, 0, reg0id,
929
	nilexp, 0, 0, name_tag),
952
	nilexp, 0, 0, name_tag),
930
      0);
953
      0);
931
 
954
 
932
  reg1id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
955
  reg1id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
933
      0x2, ident_tag);
956
      0x2, ident_tag);
934
  ptno(reg1id) = reg_pl;
957
  ptno(reg1id) = reg_pl;
935
  reg1 = mw (getexp (slongsh, nilexp, 0, reg1id, nilexp, 0, 0, name_tag),
958
  reg1 = mw(getexp(slongsh, nilexp, 0, reg1id, nilexp, 0, 0, name_tag),
936
      0);
959
      0);
937
 
960
 
938
  reg2id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
961
  reg2id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
939
      0x4, ident_tag);
962
      0x4, ident_tag);
940
  ptno(reg2id) = reg_pl;
963
  ptno(reg2id) = reg_pl;
941
  reg2 = mw (getexp (slongsh, nilexp, 0, reg2id, nilexp, 0, 0, name_tag),
964
  reg2 = mw(getexp(slongsh, nilexp, 0, reg2id, nilexp, 0, 0, name_tag),
942
      0);
965
      0);
943
 
966
 
944
  reg3id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
967
  reg3id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
945
      0x8, ident_tag);
968
      0x8, ident_tag);
946
  ptno(reg3id) = reg_pl;
969
  ptno(reg3id) = reg_pl;
947
  reg3 = mw (getexp (slongsh, nilexp, 0, reg3id, nilexp, 0, 0, name_tag),
970
  reg3 = mw(getexp(slongsh, nilexp, 0, reg3id, nilexp, 0, 0, name_tag),
948
      0);
971
      0);
949
 
972
 
950
 
973
 
951
  reg4id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
974
  reg4id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
952
      0x10, ident_tag);
975
      0x10, ident_tag);
953
  ptno(reg4id) = reg_pl;
976
  ptno(reg4id) = reg_pl;
954
  reg4 = mw (getexp (slongsh, nilexp, 0, reg4id, nilexp, 0, 0, name_tag),
977
  reg4 = mw(getexp(slongsh, nilexp, 0, reg4id, nilexp, 0, 0, name_tag),
955
      0);
978
      0);
956
 
979
 
957
  reg5id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
980
  reg5id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
958
      0x20, ident_tag);
981
      0x20, ident_tag);
959
  ptno(reg5id) = reg_pl;
982
  ptno(reg5id) = reg_pl;
960
  reg5 = mw (getexp (slongsh, nilexp, 0, reg5id, nilexp, 0, 0, name_tag),
983
  reg5 = mw(getexp(slongsh, nilexp, 0, reg5id, nilexp, 0, 0, name_tag),
961
      0);
984
      0);
962
 
985
 
963
  reg6id = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
986
  reg6id = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
964
      0x40, ident_tag);
987
      0x40, ident_tag);
965
  ptno(reg6id) = reg_pl;
988
  ptno(reg6id) = reg_pl;
966
  reg6 = mw (getexp (slongsh, nilexp, 0, reg6id, nilexp, 0, 0, name_tag),
989
  reg6 = mw(getexp(slongsh, nilexp, 0, reg6id, nilexp, 0, 0, name_tag),
967
      0);
990
      0);
968
 
991
 
969
  flstackid = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
992
  flstackid = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
970
      0x10000, ident_tag);
993
      0x10000, ident_tag);
971
  ptno(flstackid) = reg_pl;
994
  ptno(flstackid) = reg_pl;
972
  flstack = mw (getexp (realsh, nilexp, 0, flstackid, nilexp,
995
  flstack = mw(getexp(realsh, nilexp, 0, flstackid, nilexp,
973
	0, 0, name_tag),
996
	0, 0, name_tag),
974
      0);
997
      0);
975
 
998
 
976
  reg0uid = getexp (f_bottom, nilexp, 0, dummyu, nilexp, 0,
999
  reg0uid = getexp(f_bottom, nilexp, 0, dummyu, nilexp, 0,
977
      0x1, ident_tag);
1000
      0x1, ident_tag);
978
  ptno(reg0uid) = reg_pl;
1001
  ptno(reg0uid) = reg_pl;
979
  reg0u = mw (getexp (ulongsh, nilexp, 0, reg0uid, nilexp, 0, 0, name_tag),
1002
  reg0u = mw(getexp(ulongsh, nilexp, 0, reg0uid, nilexp, 0, 0, name_tag),
980
      0);
1003
      0);
981
 
1004
 
982
  spid = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
1005
  spid = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
983
      128, ident_tag);
1006
      128, ident_tag);
984
  ptno(spid) = reg_pl;
1007
  ptno(spid) = reg_pl;
985
  sp = mw (getexp (slongsh, nilexp, 0, spid, nilexp, 0, 0, name_tag), 0);
1008
  sp = mw(getexp(slongsh, nilexp, 0, spid, nilexp, 0, 0, name_tag), 0);
986
 
1009
 
987
  bpid = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0,
1010
  bpid = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0,
988
      64, ident_tag);
1011
      64, ident_tag);
989
  ptno(bpid) = reg_pl;
1012
  ptno(bpid) = reg_pl;
990
  bp = mw (getexp (slongsh, nilexp, 0, bpid, nilexp, 0, 0, name_tag), 0);
1013
  bp = mw(getexp(slongsh, nilexp, 0, bpid, nilexp, 0, 0, name_tag), 0);
991
 
1014
 
992
 
1015
 
993
  stack0ref = getexp (f_top, nilexp, 0, sp.where_exp, nilexp, 0, -32,
1016
  stack0ref = getexp(f_top, nilexp, 0, sp.where_exp, nilexp, 0, -32,
994
      reff_tag);
1017
      reff_tag);
995
  stack0 = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0,
1018
  stack0 = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0,
996
	stack0ref, nilexp, 0, 0, cont_tag), 0);
1019
	stack0ref, nilexp, 0, 0, cont_tag), 0);
997
 
1020
 
998
  ind_reg0 = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0,
1021
  ind_reg0 = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0,
999
	reg0.where_exp, nilexp, 0, 0, cont_tag), 0);
1022
	reg0.where_exp, nilexp, 0, 0, cont_tag), 0);
1000
  ind_reg1 = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0,
1023
  ind_reg1 = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0,
1001
	reg1.where_exp, nilexp, 0, 0, cont_tag), 0);
1024
	reg1.where_exp, nilexp, 0, 0, cont_tag), 0);
1002
  ind_reg2 = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0,
1025
  ind_reg2 = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0,
1003
	reg2.where_exp, nilexp, 0, 0, cont_tag), 0);
1026
	reg2.where_exp, nilexp, 0, 0, cont_tag), 0);
1004
  ind_reg4 = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0,
1027
  ind_reg4 = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0,
1005
	reg4.where_exp, nilexp, 0, 0, cont_tag), 0);
1028
	reg4.where_exp, nilexp, 0, 0, cont_tag), 0);
1006
  ind_sp = mw (getexp (f_pointer (f_alignment(slongsh)), nilexp, 0, sp.where_exp,
1029
  ind_sp = mw(getexp(f_pointer(f_alignment(slongsh)), nilexp, 0, sp.where_exp,
1007
	nilexp, 0, 0, cont_tag), 0);
1030
	nilexp, 0, 0, cont_tag), 0);
1008
 
1031
 
1009
  firstlocalid = getexp (f_bottom, nilexp, 0, dummys, nilexp, 0, 0, ident_tag);
1032
  firstlocalid = getexp(f_bottom, nilexp, 0, dummys, nilexp, 0, 0, ident_tag);
1010
  ptno(firstlocalid) = local_pl;
1033
  ptno(firstlocalid) = local_pl;
1011
  firstlocal = mw (getexp (slongsh, nilexp, 0, firstlocalid, nilexp, 0, 0, name_tag), 0);
1034
  firstlocal = mw(getexp(slongsh, nilexp, 0, firstlocalid, nilexp, 0, 0, name_tag), 0);
1012
 
1035
 
1013
  reg_wheres[0] = reg0;
1036
  reg_wheres[0] = reg0;
1014
  reg_wheres[1] = reg1;
1037
  reg_wheres[1] = reg1;
1015
  reg_wheres[2] = reg2;
1038
  reg_wheres[2] = reg2;
1016
  reg_wheres[3] = reg3;
1039
  reg_wheres[3] = reg3;
1017
  reg_wheres[4] = reg4;
1040
  reg_wheres[4] = reg4;
1018
  reg_wheres[5] = reg5;
1041
  reg_wheres[5] = reg5;
1019
  reg_wheres[6] = bp;
1042
  reg_wheres[6] = bp;
1020
 
1043
 
1021
  ferrmemid = getexp (f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, ident_tag);
1044
  ferrmemid = getexp(f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, ident_tag);
1022
  ptno(ferrmemid) = ferr_pl;
1045
  ptno(ferrmemid) = ferr_pl;
1023
  ferrmem = getexp (realsh, nilexp, 0, ferrmemid, nilexp, 0, 0, name_tag);
1046
  ferrmem = getexp(realsh, nilexp, 0, ferrmemid, nilexp, 0, 0, name_tag);
1024
 
1047
 
1025
}
1048
}
1026
 
1049
 
1027
 
1050
 
1028
 
1051
 
1029
 /* 80386 output routines */
1052
 /* 80386 output routines */
1030
 
1053
 
1031
 
1054
 
1032
/* is w in memory and not a constant */
1055
/* is w in memory and not a constant */
1033
int flinmem
1056
int flinmem
1034
    PROTO_N ( (w) )
-
 
1035
    PROTO_T ( where w )
1057
(where w)
1036
{
1058
{
1037
  exp e = w.where_exp;
1059
  exp e = w.where_exp;
1038
  unsigned char  n = name (e);
1060
  unsigned char  n = name(e);
1039
  exp id;
1061
  exp id;
1040
  int recog = 0;
1062
  int recog = 0;
1041
 
1063
 
1042
  if (n == ident_tag || n == labst_tag) {
1064
  if (n == ident_tag || n == labst_tag) {
1043
    id = e;
1065
    id = e;
1044
    recog = 1;
1066
    recog = 1;
1045
  }
1067
  }
1046
  else {
1068
  else {
1047
    if (n == name_tag) {
1069
    if (n == name_tag) {
1048
      id = son (e);
1070
      id = son(e);
1049
      recog = 1;
1071
      recog = 1;
1050
    }
1072
    }
1051
    else {
1073
    else {
1052
      if ((n == cont_tag || n == ass_tag) &&
1074
      if ((n == cont_tag || n == ass_tag) &&
1053
	  name (son (e)) == name_tag && isvar (son (son (e)))) {
1075
	  name(son(e)) == name_tag && isvar(son(son(e)))) {
1054
	id = son (son (e));
1076
	id = son(son(e));
1055
	recog = 1;
1077
	recog = 1;
1056
      }
1078
      }
1057
    };
1079
    };
1058
  };
1080
  };
1059
 
1081
 
Line 1061... Line 1083...
1061
  if (n == diagnose_tag)
1083
  if (n == diagnose_tag)
1062
    return flinmem(mw(son(e), w.where_off));
1084
    return flinmem(mw(son(e), w.where_off));
1063
#endif
1085
#endif
1064
 
1086
 
1065
  if (!recog)
1087
  if (!recog)
1066
    return (1);
1088
    return(1);
1067
  else {
1089
  else {
1068
    SET(id);
1090
    SET(id);
1069
  };
1091
  };
1070
 
1092
 
1071
  if (ptno (id) == reg_pl &&
1093
  if (ptno(id) == reg_pl &&
1072
      (name (sh (son (id))) > ucharhd || no (id) < 0x10))/* 0x10 is edi */
1094
      (name (sh (son (id))) > ucharhd || no (id) < 0x10))/* 0x10 is edi */
1073
    return (0);  /* there are no char versions of edi, esi */
1095
    return (0);  /* there are no char versions of edi, esi */
1074
 
1096
 
1075
  return (1);
1097
  return(1);
1076
}
1098
}
1077
 
1099
 
1078
 
1100
 
1079
/* is w in memory or an integer or null
1101
/* is w in memory or an integer or null
1080
   pointer constant */
1102
   pointer constant */
1081
int inmem
1103
int inmem
1082
    PROTO_N ( (w) )
-
 
1083
    PROTO_T ( where w )
1104
(where w)
1084
{
1105
{
1085
  unsigned char  n = name (w.where_exp);
1106
  unsigned char  n = name(w.where_exp);
1086
  if (n == val_tag ||
1107
  if (n == val_tag ||
1087
	n == null_tag || n == current_env_tag)
1108
	n == null_tag || n == current_env_tag)
1088
    return (0);
1109
    return(0);
1089
  return (flinmem (w));
1110
  return(flinmem(w));
1090
}
1111
}
1091
 
1112
 
1092
int w_islastuse
1113
int w_islastuse
1093
    PROTO_N ( (w) )
-
 
1094
    PROTO_T ( where w )
1114
(where w)
1095
{
1115
{
1096
  exp e = w.where_exp;
1116
  exp e = w.where_exp;
1097
  if (name(e) == name_tag && !isvar(son(e)))
1117
  if (name(e) == name_tag && !isvar(son(e)))
1098
    return islastuse(e);
1118
    return islastuse(e);
1099
  if (name(e) == cont_tag && name(son(e)) == name_tag &&
1119
  if (name(e) == cont_tag && name(son(e)) == name_tag &&
Line 1103... Line 1123...
1103
}
1123
}
1104
 
1124
 
1105
/* abs value a1 of shape sha and put
1125
/* abs value a1 of shape sha and put
1106
   it in dest */
1126
   it in dest */
1107
void absop
1127
void absop
1108
    PROTO_N ( (sha, a1, dest) )
-
 
1109
    PROTO_T ( shape sha X where a1 X where dest )
1128
(shape sha, where a1, where dest)
1110
{
1129
{
1111
  int labno = next_lab();
1130
  int labno = next_lab();
1112
  where q;
1131
  where q;
1113
  int sz = shape_size(sha);
1132
  int sz = shape_size(sha);
1114
  char * op, * ng;
1133
  char * op, * ng;
Line 1145... Line 1164...
1145
 
1164
 
1146
  if (sz == 64) {
1165
  if (sz == 64) {
1147
	/* must be in reg0/reg1 */
1166
	/* must be in reg0/reg1 */
1148
    ins2(testl, 32, 32, reg1, reg1);
1167
    ins2(testl, 32, 32, reg1, reg1);
1149
    simple_branch(jge, labno);
1168
    simple_branch(jge, labno);
1150
    move (slongsh, reg1, reg2);
1169
    move(slongsh, reg1, reg2);
1151
    move (slongsh, zero, reg1);
1170
    move(slongsh, zero, reg1);
1152
    ins1(negl, 32, reg0);
1171
    ins1(negl, 32, reg0);
1153
    ins2(sbbl, 32, 32, reg2, reg1);
1172
    ins2(sbbl, 32, 32, reg2, reg1);
1154
    try_overflow (sha, 0);
1173
    try_overflow(sha, 0);
1155
    invalidate_dest(reg1);
1174
    invalidate_dest(reg1);
1156
    invalidate_dest(reg2);
1175
    invalidate_dest(reg2);
1157
  }
1176
  }
1158
  else {
1177
  else {
1159
    ins2(op, sz, sz, q, q);
1178
    ins2(op, sz, sz, q, q);
1160
    simple_branch(jg, labno);
1179
    simple_branch(jg, labno);
1161
    ins1(ng, sz, q);
1180
    ins1(ng, sz, q);
1162
    try_overflow (sha, 0);
1181
    try_overflow(sha, 0);
1163
  }
1182
  }
1164
  invalidate_dest(q);
1183
  invalidate_dest(q);
1165
  simple_set_label(labno);
1184
  simple_set_label(labno);
1166
  move(sha, q, dest);
1185
  move(sha, q, dest);
1167
  return;
1186
  return;
1168
}
1187
}
1169
 
1188
 
1170
 
1189
 
1171
static void maxmin
1190
static void maxmin
1172
    PROTO_N ( (sha, a1, a2, dest, ismax) )
-
 
1173
    PROTO_T ( shape sha X where a1 X where a2 X where dest X int ismax )
1191
(shape sha, where a1, where a2, where dest, int ismax)
1174
{
1192
{
1175
  where tempw;
1193
  where tempw;
1176
  int labno = next_lab();
1194
  int labno = next_lab();
1177
  int lab64;
1195
  int lab64;
1178
  int mem1;
1196
  int mem1;
Line 1182... Line 1200...
1182
  char * op12;
1200
  char * op12;
1183
  char * op21;
1201
  char * op21;
1184
  int late_contop = 0;
1202
  int late_contop = 0;
1185
 
1203
 
1186
  if (is_signed(sha)) {
1204
  if (is_signed(sha)) {
1187
    op12 = (ismax)  ? jl : jg;
1205
    op12 = (ismax) ? jl : jg;
1188
    op21 = (ismax) ? jg : jl;
1206
    op21 = (ismax)? jg : jl;
1189
  }
1207
  }
1190
  else {
1208
  else {
1191
    op12 = (ismax)  ? jb : ja;
1209
    op12 = (ismax) ? jb : ja;
1192
    op21 = (ismax) ? ja : jb;
1210
    op21 = (ismax)? ja : jb;
1193
  };
1211
  };
1194
 
1212
 
1195
  cond1_set = 0;
1213
  cond1_set = 0;
1196
  cond2_set = 0;
1214
  cond2_set = 0;
1197
 
1215
 
Line 1220... Line 1238...
1220
 
1238
 
1221
  mem1 = inmem(a1);
1239
  mem1 = inmem(a1);
1222
  mem2 = inmem(a2);
1240
  mem2 = inmem(a2);
1223
 
1241
 
1224
  if (eq_where(a1, a2)) {
1242
  if (eq_where(a1, a2)) {
1225
    move (sha, a1, dest);
1243
    move(sha, a1, dest);
1226
    return;
1244
    return;
1227
  }
1245
  }
1228
  if (eq_where(a1, dest)) {
1246
  if (eq_where(a1, dest)) {
1229
    exp hold1 = son(a1.where_exp);
1247
    exp hold1 = son(a1.where_exp);
1230
    exp hold2 = son(a2.where_exp);
1248
    exp hold2 = son(a2.where_exp);
Line 1232... Line 1250...
1232
    if (mem1 && mem2) {
1250
    if (mem1 && mem2) {
1233
      move(sha, a2, reg0);
1251
      move(sha, a2, reg0);
1234
      maxmin(sha, a1, reg0, dest, ismax);
1252
      maxmin(sha, a1, reg0, dest, ismax);
1235
      return;
1253
      return;
1236
    };
1254
    };
1237
    if (name(a2.where_exp) != val_tag) {
1255
    if (name(a2.where_exp)!= val_tag) {
1238
      if (mem1) {
1256
      if (mem1) {
1239
	if (sz == 64) {
1257
	if (sz == 64) {
1240
		/* a2 must be reg0/1 */
1258
		/* a2 must be reg0/1 */
1241
	  regsinuse |= 0x2;
1259
	  regsinuse |= 0x2;
1242
	  contop (a1.where_exp, 1, dest);
1260
	  contop(a1.where_exp, 1, dest);
1243
	  ins2 (cmpl, 32, 32, mw(a1.where_exp, a1.where_off + 32), reg1);
1261
	  ins2(cmpl, 32, 32, mw(a1.where_exp, a1.where_off + 32), reg1);
1244
	  simple_branch (op12, labno);
1262
	  simple_branch(op12, labno);
1245
	  simple_branch (jne, lab64);
1263
	  simple_branch(jne, lab64);
1246
	  ins2 (cmpl, 32, 32, a1, reg0);
1264
	  ins2(cmpl, 32, 32, a1, reg0);
1247
	  simple_branch ((ismax ? jb : ja), labno);
1265
	  simple_branch((ismax ? jb : ja), labno);
1248
	  late_contop = contop_dopop;
1266
	  late_contop = contop_dopop;
1249
	  contop_dopop = 0;
1267
	  contop_dopop = 0;
1250
	}
1268
	}
1251
	else {
1269
	else {
1252
	  contop(a1.where_exp, eq_where(a2, reg0), dest);
1270
	  contop(a1.where_exp, eq_where(a2, reg0), dest);
1253
          ins2(in, sz, sz, a1, a2);
1271
          ins2(in, sz, sz, a1, a2);
1254
	  end_contop();
1272
	  end_contop();
1255
          simple_branch(op12, labno);
1273
          simple_branch(op12, labno);
1256
	};
1274
	};
Line 1259... Line 1277...
1259
	if (mem2) {
1277
	if (mem2) {
1260
	  if (sz == 64) {
1278
	  if (sz == 64) {
1261
		/* a1 and dest must be reg0/1 */
1279
		/* a1 and dest must be reg0/1 */
1262
	    regsinuse |= 0x2;
1280
	    regsinuse |= 0x2;
1263
	    contop(a2.where_exp, 1, dest);
1281
	    contop(a2.where_exp, 1, dest);
1264
	    ins2 (cmpl, 32, 32, reg1, mw(a2.where_exp, a2.where_off + 32));
1282
	    ins2(cmpl, 32, 32, reg1, mw(a2.where_exp, a2.where_off + 32));
1265
	    simple_branch (op12, labno);
1283
	    simple_branch(op12, labno);
1266
	    simple_branch (jne, lab64);
1284
	    simple_branch(jne, lab64);
1267
	    ins2 (cmpl, 32, 32, reg0, a2);
1285
	    ins2(cmpl, 32, 32, reg0, a2);
1268
	    simple_branch ((ismax ? jb : ja), labno);
1286
	    simple_branch((ismax ? jb : ja), labno);
1269
	  }
1287
	  }
1270
	  else {
1288
	  else {
1271
	    contop(a2.where_exp, eq_where(a1, reg0), dest);
1289
	    contop(a2.where_exp, eq_where(a1, reg0), dest);
1272
            ins2(in, sz, sz, a1, a2);
1290
            ins2(in, sz, sz, a1, a2);
1273
            simple_branch(op12, labno);
1291
            simple_branch(op12, labno);
1274
	  };
1292
	  };
1275
	  late_contop = contop_dopop;
1293
	  late_contop = contop_dopop;
1276
	  contop_dopop = 0;
1294
	  contop_dopop = 0;
1277
	}
1295
	}
1278
	else  {		/* cannot be (sz == 64) */
1296
	else  {		/* cannot be (sz == 64) */
1279
	  ins2(in, sz, sz, a1, a2);
1297
	  ins2(in, sz, sz, a1, a2);
1280
          simple_branch(op12, labno);
1298
          simple_branch(op12, labno);
1281
        };
1299
        };
1282
      };
1300
      };
1283
    }
1301
    }
1284
    else {
1302
    else {
1285
      if (sz == 64) {
1303
      if (sz == 64) {
1286
	int c, c1;
1304
	int c, c1;
1287
	if (!isbigval(a2.where_exp)) {
1305
	if (!isbigval(a2.where_exp)) {
1288
	  c = no (a2.where_exp) + a2.where_off;
1306
	  c = no(a2.where_exp) + a2.where_off;
1289
	  c1 = (is_signed(sha) && c < 0) ? -1 : 0;
1307
	  c1 = (is_signed(sha) && c < 0)? -1 : 0;
1290
	}
1308
	}
1291
	else {
1309
	else {
1292
	  flt64 x;
1310
	  flt64 x;
1293
	  int ov;
1311
	  int ov;
1294
	  x = flt_to_f64(no(a2.where_exp), is_signed(sha), &ov);
1312
	  x = flt_to_f64(no(a2.where_exp), is_signed(sha), &ov);
1295
	  c = x.small;
1313
	  c = x.small;
1296
	  c1 = x.big;
1314
	  c1 = x.big;
1297
	};
1315
	};
1298
	if (mem1) {
1316
	if (mem1) {
1299
	  contop (a1.where_exp, 0, dest);
1317
	  contop(a1.where_exp, 0, dest);
1300
	  ins2 (cmpl, 32, 32, mw(zeroe, c1), mw(a1.where_exp, a1.where_off + 32));
1318
	  ins2(cmpl, 32, 32, mw(zeroe, c1), mw(a1.where_exp, a1.where_off + 32));
1301
	  simple_branch (op21, labno);
1319
	  simple_branch(op21, labno);
1302
	  simple_branch (jne, lab64);
1320
	  simple_branch(jne, lab64);
1303
	  ins2 (cmpl, 32, 32, mw(zeroe, c), a1);
1321
	  ins2(cmpl, 32, 32, mw(zeroe, c), a1);
1304
	  simple_branch ((ismax ? ja : jb), labno);
1322
	  simple_branch((ismax ? ja : jb), labno);
1305
	  late_contop = contop_dopop;
1323
	  late_contop = contop_dopop;
1306
	  contop_dopop = 0;
1324
	  contop_dopop = 0;
1307
	}
1325
	}
1308
	else {
1326
	else {
1309
		/* a1 and dest must be reg0/1 */
1327
		/* a1 and dest must be reg0/1 */
1310
	  ins2 (cmpl, 32, 32, mw(zeroe, c1), reg1);
1328
	  ins2(cmpl, 32, 32, mw(zeroe, c1), reg1);
1311
	  simple_branch (op21, labno);
1329
	  simple_branch(op21, labno);
1312
	  simple_branch (jne, lab64);
1330
	  simple_branch(jne, lab64);
1313
	  ins2 (cmpl, 32, 32, mw(zeroe, c), reg0);
1331
	  ins2(cmpl, 32, 32, mw(zeroe, c), reg0);
1314
	  simple_branch ((ismax ? ja : jb), labno);
1332
	  simple_branch((ismax ? ja : jb), labno);
1315
	};
1333
	};
1316
      }
1334
      }
1317
      else {
1335
      else {
1318
	if (mem1) {
1336
	if (mem1) {
1319
	  contop(a1.where_exp, 0, dest);
1337
	  contop(a1.where_exp, 0, dest);
Line 1324... Line 1342...
1324
          ins2(in, sz, sz, a2, a1);
1342
          ins2(in, sz, sz, a2, a1);
1325
	simple_branch(op21, labno);
1343
	simple_branch(op21, labno);
1326
      };
1344
      };
1327
    };
1345
    };
1328
    if (sz == 64)
1346
    if (sz == 64)
1329
      simplest_set_lab (lab64);
1347
      simplest_set_lab(lab64);
1330
    move(sha, a2, dest);
1348
    move(sha, a2, dest);
1331
    simple_set_label(labno);
1349
    simple_set_label(labno);
1332
    if (late_contop) {
1350
    if (late_contop) {
1333
      contop_dopop = late_contop;
1351
      contop_dopop = late_contop;
1334
      end_contop();
1352
      end_contop();
Line 1343... Line 1361...
1343
  };
1361
  };
1344
 
1362
 
1345
  if (eq_where(a1, reg0)) {
1363
  if (eq_where(a1, reg0)) {
1346
    reg0_in_use = 1;
1364
    reg0_in_use = 1;
1347
    maxmin(sha, reg0, a2, reg0, ismax);
1365
    maxmin(sha, reg0, a2, reg0, ismax);
1348
    move(sha, reg0, dest);
1366
    move(sha, reg0, dest);
1349
    return;
1367
    return;
1350
  };
1368
  };
1351
 
1369
 
1352
  if (eq_where(a2, reg0)) {
1370
  if (eq_where(a2, reg0)) {
1353
    reg0_in_use = 1;
1371
    reg0_in_use = 1;
1354
    maxmin(sha, a1, reg0, reg0, ismax);
1372
    maxmin(sha, a1, reg0, reg0, ismax);
Line 1359... Line 1377...
1359
  move(sha, a1, reg0);
1377
  move(sha, a1, reg0);
1360
  maxmin(sha, reg0, a2, dest, ismax);
1378
  maxmin(sha, reg0, a2, dest, ismax);
1361
  return;
1379
  return;
1362
}
1380
}
1363
 
1381
 
1364
 
1382
 
1365
/* max values a1, a2 of shape sha and put them in dest */
1383
/* max values a1, a2 of shape sha and put them in dest */
1366
void maxop
1384
void maxop
1367
    PROTO_N ( (sha, a1, a2, dest) )
-
 
1368
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
1385
(shape sha, where a1, where a2, where dest)
1369
{
1386
{
1370
  maxmin(sha, a1, a2, dest, 1);
1387
  maxmin(sha, a1, a2, dest, 1);
1371
  return;
1388
  return;
1372
}
1389
}
1373
 
1390
 
1374
/* min values a1, a2 of shape sha and put them in dest */
1391
/* min values a1, a2 of shape sha and put them in dest */
1375
void minop
1392
void minop
1376
    PROTO_N ( (sha, a1, a2, dest) )
-
 
1377
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
1393
(shape sha, where a1, where a2, where dest)
1378
{
1394
{
1379
  maxmin(sha, a1, a2, dest, 0);
1395
  maxmin(sha, a1, a2, dest, 0);
1380
  return;
1396
  return;
1381
}
1397
}
1382
 
1398
 
1383
/* add values a1, a2 of shape sha and put them in dest  */
1399
/* add values a1, a2 of shape sha and put them in dest  */
1384
void add_plus
1400
void add_plus
1385
    PROTO_N ( (sha, a1, a2, dest, plus1) )
-
 
1386
    PROTO_T ( shape sha X where a1 X where a2 X where dest X int plus1 )
1401
(shape sha, where a1, where a2, where dest, int plus1)
1387
{
1402
{
1388
  int  sz;
1403
  int  sz;
1389
  exp a = a1.where_exp;
1404
  exp a = a1.where_exp;
1390
  int  aoff = a1.where_off;
1405
  int  aoff = a1.where_off;
1391
  exp b = a2.where_exp;
1406
  exp b = a2.where_exp;
1392
  int  boff = a2.where_off;
1407
  int  boff = a2.where_off;
1393
  sz = shape_size(sha);
1408
  sz = shape_size(sha);
1394
 
1409
 
1395
  if (name(a) == val_tag && name(sh(a)) == offsethd && al2(sh(a)) != 1) {
1410
  if (name(a) == val_tag && name(sh(a)) == offsethd && al2(sh(a))!= 1) {
1396
    if (name(sha) == offsethd && al2(sha) != 1)
1411
    if (name(sha) == offsethd && al2(sha)!= 1)
1397
      no(a) = no(a) / 8;
1412
      no(a) = no(a) / 8;
1398
    sh(a) = slongsh;
1413
    sh(a) = slongsh;
1399
  };
1414
  };
1400
  if (name(b) == val_tag && name(sh(b)) == offsethd && al2(sh(b)) != 1) {
1415
  if (name(b) == val_tag && name(sh(b)) == offsethd && al2(sh(b))!= 1) {
1401
    if (name(sha) == offsethd && al2(sha) != 1)
1416
    if (name(sha) == offsethd && al2(sha)!= 1)
1402
      no(b) = no(b) / 8;
1417
      no(b) = no(b) / 8;
1403
    sh(b) = slongsh;
1418
    sh(b) = slongsh;
1404
  };
1419
  };
1405
 
1420
 
1406
  cond1_set = 1;
1421
  cond1_set = 1;
1407
  cond2_set = 0;
1422
  cond2_set = 0;
1408
  cond1 = dest;			/* we know the conditions are set
1423
  cond1 = dest;			/* we know the conditions are set
1409
				   according to the which will be in dest
1424
				   according to the which will be in dest
1410
				*/
1425
				*/
1411
 
1426
 
1412
  if (eq_where (a1, dest) &&
1427
  if (eq_where(a1, dest) &&
1413
	(!keep_short || !flinmem(dest))) {	/* altering dest */
1428
	(!keep_short || !flinmem(dest))) {	/* altering dest */
1414
    if (name (b) == val_tag && !plus1 && !isbigval(b) && (no (b) + boff == 0 ||
1429
    if (name(b) == val_tag && !plus1 && !isbigval(b) && (no(b) + boff == 0 ||
1415
	  ((no (b) + boff == 1 || no (b) + boff == -1) && sz <= 32 &&
1430
	 ((no(b) + boff == 1 || no(b) + boff == -1) && sz <= 32 &&
1416
	    (overflow_e == nilexp || is_signed(sha) )))) {
1431
	   (overflow_e == nilexp || is_signed(sha))))) {
1417
      exp hold = son(a);
1432
      exp hold = son(a);
1418
      if (no (b) + boff == 0) {	/* adding zero */
1433
      if (no (b) + boff == 0) {	/* adding zero */
1419
	cond1_set = 0;		/* we didn't know conditions after all */
1434
	cond1_set = 0;		/* we didn't know conditions after all */
1420
	return;
1435
	return;
1421
      };
1436
      };
1422
      contop (a, 0, a1);	/* get the address of a if necessary */
1437
      contop (a, 0, a1);	/* get the address of a if necessary */
1423
      if (no (b) + boff == 1) {	/* use inc */
1438
      if (no (b) + boff == 1) {	/* use inc */
1424
	if (sz == 8) {
1439
	if (sz == 8) {
1425
	  ins1 (incb, sz, a1);
1440
	  ins1(incb, sz, a1);
1426
	};
1441
	};
1427
	if (sz == 16) {
1442
	if (sz == 16) {
1428
	  ins1 (incw, sz, a1);
1443
	  ins1(incw, sz, a1);
1429
	};
1444
	};
1430
	if (sz == 32) {
1445
	if (sz == 32) {
1431
	  ins1 (incl, sz, a1);
1446
	  ins1(incl, sz, a1);
1432
	};
1447
	};
1433
      }
1448
      }
1434
      else {			/* use dec */
1449
      else {			/* use dec */
1435
	if (sz == 8) {
1450
	if (sz == 8) {
1436
	  ins1 (decb, sz, a1);
1451
	  ins1(decb, sz, a1);
1437
	};
1452
	};
1438
	if (sz == 16) {
1453
	if (sz == 16) {
1439
	  ins1 (decw, sz, a1);
1454
	  ins1(decw, sz, a1);
1440
	};
1455
	};
1441
	if (sz == 32) {
1456
	if (sz == 32) {
1442
	  ins1 (decl, sz, a1);
1457
	  ins1(decl, sz, a1);
1443
	};
1458
	};
1444
      };
1459
      };
1445
      invalidate_dest (dest);
1460
      invalidate_dest(dest);
1446
      end_contop ();
1461
      end_contop();
1447
      try_overflow (sha, plus1);
1462
      try_overflow(sha, plus1);
1448
      son(a) = hold;
1463
      son(a) = hold;
1449
      return;
1464
      return;
1450
    };
1465
    };
1451
 
1466
 
1452
    if (!inmem (a1) || !inmem (a2)) {
1467
    if (!inmem(a1) || !inmem(a2)) {
1453
      /* either a1 or a2 is not in memory */
1468
      /* either a1 or a2 is not in memory */
1454
      int riu = regsinuse;
1469
      int riu = regsinuse;
1455
      exp holda = son(a);
1470
      exp holda = son(a);
1456
      exp holdb = son(b);
1471
      exp holdb = son(b);
1457
      if (sz == 64)
1472
      if (sz == 64)
1458
	regsinuse |= 0x2;
1473
	regsinuse |= 0x2;
1459
      if (inmem (a1))
1474
      if (inmem(a1))
1460
	contop (a, eq_where (reg0, a2), a1);
1475
	contop(a, eq_where(reg0, a2), a1);
1461
      else
1476
      else
1462
	contop (b,
1477
	contop(b,
1463
	     (eq_where (reg0, a2) || eq_where (reg0, a1)), a1);
1478
	    (eq_where(reg0, a2) || eq_where(reg0, a1)), a1);
1464
      if (plus1)
1479
      if (plus1)
1465
	ins0 (stc);
1480
	ins0(stc);
1466
      if (sz == 8) {
1481
      if (sz == 8) {
1467
	ins2 ((plus1 ? adcb : addb), sz, sz, a2, a1);
1482
	ins2((plus1 ? adcb : addb), sz, sz, a2, a1);
1468
      };
1483
      };
1469
      if (sz == 16) {
1484
      if (sz == 16) {
1470
	ins2 ((plus1 ? adcw : addw), sz, sz, a2, a1);
1485
	ins2((plus1 ? adcw : addw), sz, sz, a2, a1);
1471
      };
1486
      };
1472
      if (sz == 32) {
1487
      if (sz == 32) {
1473
	ins2 ((plus1 ? adcl : addl), sz, sz, a2, a1);
1488
	ins2((plus1 ? adcl : addl), sz, sz, a2, a1);
1474
      };
1489
      };
1475
      if (sz == 64) {
1490
      if (sz == 64) {
1476
	where hi1, lo1, hi2, lo2;
1491
	where hi1, lo1, hi2, lo2;
1477
	lo1 = a1;
1492
	lo1 = a1;
1478
	hi1 = (inmem(a1) ? mw (a, aoff + 32) : reg1);
1493
	hi1 = (inmem(a1)? mw(a, aoff + 32): reg1);
1479
	if (name (b) == val_tag) {
1494
	if (name(b) == val_tag) {
1480
	  int c, c1;
1495
	  int c, c1;
1481
	  if (!isbigval(b)) {
1496
	  if (!isbigval(b)) {
1482
	    c = no (b) + boff;
1497
	    c = no(b) + boff;
1483
	    c1 = (is_signed(sha) && c < 0) ? -1 : 0;
1498
	    c1 = (is_signed(sha) && c < 0)? -1 : 0;
1484
	  }
1499
	  }
1485
	  else {
1500
	  else {
1486
	    flt64 x;
1501
	    flt64 x;
1487
	    int ov;
1502
	    int ov;
1488
	    x = flt_to_f64(no(b), is_signed(sha), &ov);
1503
	    x = flt_to_f64(no(b), is_signed(sha), &ov);
1489
	    c = x.small;
1504
	    c = x.small;
1490
	    c1 = x.big;
1505
	    c1 = x.big;
1491
	  };
1506
	  };
1492
	  lo2 = mw (zeroe, c);
1507
	  lo2 = mw(zeroe, c);
1493
	  hi2 = mw (zeroe, c1);
1508
	  hi2 = mw(zeroe, c1);
1494
	}
1509
	}
1495
	else {
1510
	else {
1496
	  lo2 = a2;
1511
	  lo2 = a2;
1497
	  hi2 = (inmem(a2) ? mw (b, boff + 32) : reg1);
1512
	  hi2 = (inmem(a2)? mw(b, boff + 32): reg1);
1498
	}
1513
	}
1499
	ins2 ((plus1 ? adcl : addl), 32, 32, lo2, lo1);
1514
	ins2((plus1 ? adcl : addl), 32, 32, lo2, lo1);
1500
	ins2 (adcl, 32, 32, hi2, hi1);
1515
	ins2(adcl, 32, 32, hi2, hi1);
1501
      };
1516
      };
1502
      invalidate_dest (dest);
1517
      invalidate_dest(dest);
1503
      end_contop ();
1518
      end_contop();
1504
      regsinuse = riu;
1519
      regsinuse = riu;
1505
      try_overflow (sha, plus1);
1520
      try_overflow(sha, plus1);
1506
      son(a) = holda;
1521
      son(a) = holda;
1507
      son(b) = holdb;
1522
      son(b) = holdb;
1508
      return;
1523
      return;
1509
    };
1524
    };
1510
 
1525
 
1511
    move (sha, a2, reg0);
1526
    move(sha, a2, reg0);
1512
    add_plus (sha, reg0, a1, a1, plus1);
1527
    add_plus(sha, reg0, a1, a1, plus1);
1513
    invalidate_dest (dest);
1528
    invalidate_dest(dest);
1514
    return;
1529
    return;
1515
  };
1530
  };
1516
 
1531
 
1517
  if (eq_where (a2, dest) &&
1532
  if (eq_where(a2, dest) &&
1518
	(!keep_short || !flinmem(dest))) {	/* altering dest */
1533
	(!keep_short || !flinmem(dest))) {	/* altering dest */
1519
    if (name (a) == val_tag && !plus1 && !isbigval(a) && (no (a) + aoff == 0 ||
1534
    if (name(a) == val_tag && !plus1 && !isbigval(a) && (no(a) + aoff == 0 ||
1520
	  ((no (a) + aoff == 1 || no (a) + aoff == -1) && sz <= 32 &&
1535
	 ((no(a) + aoff == 1 || no(a) + aoff == -1) && sz <= 32 &&
1521
	    (overflow_e == nilexp || is_signed(sha) )))) {
1536
	   (overflow_e == nilexp || is_signed(sha))))) {
1522
      exp hold = son(a);
1537
      exp hold = son(a);
1523
      if (no (a) + aoff == 0) {	/* adding zero */
1538
      if (no (a) + aoff == 0) {	/* adding zero */
1524
	cond1_set = 0;		/* we didn't know conditions after all */
1539
	cond1_set = 0;		/* we didn't know conditions after all */
1525
	return;
1540
	return;
1526
      };
1541
      };
1527
      contop (b, 0, a2);
1542
      contop(b, 0, a2);
1528
      if (no (a) + aoff == 1) {	/* use inc */
1543
      if (no (a) + aoff == 1) {	/* use inc */
1529
	if (sz == 8) {
1544
	if (sz == 8) {
1530
	  ins1 (incb, sz, a2);
1545
	  ins1(incb, sz, a2);
1531
	};
1546
	};
1532
	if (sz == 16) {
1547
	if (sz == 16) {
1533
	  ins1 (incw, sz, a2);
1548
	  ins1(incw, sz, a2);
1534
	};
1549
	};
1535
	if (sz == 32) {
1550
	if (sz == 32) {
1536
	  ins1 (incl, sz, a2);
1551
	  ins1(incl, sz, a2);
1537
	};
1552
	};
1538
      }
1553
      }
1539
      else {			/* use dec */
1554
      else {			/* use dec */
1540
	if (sz == 8) {
1555
	if (sz == 8) {
1541
	  ins1 (decb, sz, a2);
1556
	  ins1(decb, sz, a2);
1542
	};
1557
	};
1543
	if (sz == 16) {
1558
	if (sz == 16) {
1544
	  ins1 (decw, sz, a2);
1559
	  ins1(decw, sz, a2);
1545
	};
1560
	};
1546
	if (sz == 32) {
1561
	if (sz == 32) {
1547
	  ins1 (decl, sz, a2);
1562
	  ins1(decl, sz, a2);
1548
	};
1563
	};
1549
      };
1564
      };
1550
      invalidate_dest (dest);
1565
      invalidate_dest(dest);
1551
      end_contop ();
1566
      end_contop();
1552
      try_overflow (sha, plus1);
1567
      try_overflow(sha, plus1);
1553
      son(a) = hold;
1568
      son(a) = hold;
1554
      return;
1569
      return;
1555
    };
1570
    };
1556
 
1571
 
1557
    if (!inmem (a1) || !inmem (a2)) {
1572
    if (!inmem(a1) || !inmem(a2)) {
1558
      /* either a1 or a2 is not in memory */
1573
      /* either a1 or a2 is not in memory */
1559
      int riu = regsinuse;
1574
      int riu = regsinuse;
1560
      exp holda = son(a);
1575
      exp holda = son(a);
1561
      exp holdb = son(b);
1576
      exp holdb = son(b);
1562
      if (sz == 64)
1577
      if (sz == 64)
1563
	regsinuse |= 0x2;
1578
	regsinuse |= 0x2;
1564
      if (inmem (a1))
1579
      if (inmem(a1))
1565
	contop (a, eq_where (reg0, a2), a2);
1580
	contop(a, eq_where(reg0, a2), a2);
1566
      else
1581
      else
1567
	contop (b,
1582
	contop(b,
1568
	     (eq_where (reg0, a2) || eq_where (reg0, a1)), a2);
1583
	    (eq_where(reg0, a2) || eq_where(reg0, a1)), a2);
1569
      if (plus1)
1584
      if (plus1)
1570
	ins0 (stc);
1585
	ins0(stc);
1571
      if (sz == 8) {
1586
      if (sz == 8) {
1572
	ins2 ((plus1 ? adcb : addb), sz, sz, a1, a2);
1587
	ins2((plus1 ? adcb : addb), sz, sz, a1, a2);
1573
      };
1588
      };
1574
      if (sz == 16) {
1589
      if (sz == 16) {
1575
	ins2 ((plus1 ? adcw : addw), sz, sz, a1, a2);
1590
	ins2((plus1 ? adcw : addw), sz, sz, a1, a2);
1576
      };
1591
      };
1577
      if (sz == 32) {
1592
      if (sz == 32) {
1578
	ins2 ((plus1 ? adcl : addl), sz, sz, a1, a2);
1593
	ins2((plus1 ? adcl : addl), sz, sz, a1, a2);
1579
      };
1594
      };
1580
      if (sz == 64) {
1595
      if (sz == 64) {
1581
	where hi1, lo1, hi2, lo2;
1596
	where hi1, lo1, hi2, lo2;
1582
	lo2 = a2;
1597
	lo2 = a2;
1583
	hi2 = (inmem(a2) ? mw (b, a2.where_off + 32) : reg1);
1598
	hi2 = (inmem(a2)? mw(b, a2.where_off + 32): reg1);
1584
	if (name (a) == val_tag) {
1599
	if (name(a) == val_tag) {
1585
	  int c, c1;
1600
	  int c, c1;
1586
	  if (!isbigval(a)) {
1601
	  if (!isbigval(a)) {
1587
	    c = no (a) + aoff;
1602
	    c = no(a) + aoff;
1588
	    c1 = (is_signed(sha) && c < 0) ? -1 : 0;
1603
	    c1 = (is_signed(sha) && c < 0)? -1 : 0;
1589
	  }
1604
	  }
1590
	  else {
1605
	  else {
1591
	    flt64 x;
1606
	    flt64 x;
1592
	    int ov;
1607
	    int ov;
1593
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
1608
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
1594
	    c = x.small;
1609
	    c = x.small;
1595
	    c1 = x.big;
1610
	    c1 = x.big;
1596
	  };
1611
	  };
1597
	  lo1 = mw (zeroe, c);
1612
	  lo1 = mw(zeroe, c);
1598
	  hi1 = mw (zeroe, c1);
1613
	  hi1 = mw(zeroe, c1);
1599
	}
1614
	}
1600
	else {
1615
	else {
1601
	  lo1 = a1;
1616
	  lo1 = a1;
1602
	  hi1 = (inmem(a1) ? mw (a, aoff + 32) : reg1);
1617
	  hi1 = (inmem(a1)? mw(a, aoff + 32): reg1);
1603
	}
1618
	}
1604
	ins2 ((plus1 ? adcl : addl), 32, 32, lo1, lo2);
1619
	ins2((plus1 ? adcl : addl), 32, 32, lo1, lo2);
1605
 	ins2 (adcl, 32, 32, hi1, hi2);
1620
 	ins2(adcl, 32, 32, hi1, hi2);
1606
      };
1621
      };
1607
      invalidate_dest (dest);
1622
      invalidate_dest(dest);
1608
      try_overflow (sha, plus1);
1623
      try_overflow(sha, plus1);
1609
      end_contop ();
1624
      end_contop();
1610
      regsinuse = riu;
1625
      regsinuse = riu;
1611
      son(a) = holda;
1626
      son(a) = holda;
1612
      son(b) = holdb;
1627
      son(b) = holdb;
1613
      return;
1628
      return;
1614
    };
1629
    };
1615
 
1630
 
1616
    move (sha, a1, reg0);
1631
    move(sha, a1, reg0);
1617
    add_plus (sha, reg0, a2, a2, plus1);
1632
    add_plus(sha, reg0, a2, a2, plus1);
1618
    invalidate_dest (dest);
1633
    invalidate_dest(dest);
-
 
1634
    return;
-
 
1635
  };
-
 
1636
 
-
 
1637
  if (name(a) == val_tag && !plus1 && !isbigval(a) && no(a) + aoff == 0) {
-
 
1638
    /* adding zero and moving */
-
 
1639
    cond1_set = 0;
-
 
1640
    move(sha, a2, dest);
1619
    return;
1641
    return;
1620
  };
1642
  };
1621
 
1643
 
1622
  if (name (a) == val_tag && !plus1 && !isbigval(a) && no (a) + aoff == 0) {
1644
  if (name(b) == val_tag && !plus1 && !isbigval(b) && no(b) + boff == 0) {
1623
    /* adding zero and moving */
1645
    /* adding zero and moving */
1624
    cond1_set = 0;
1646
    cond1_set = 0;
1625
    move (sha, a2, dest);
-
 
1626
    return;
-
 
1627
  };
-
 
1628
 
-
 
1629
  if (name (b) == val_tag && !plus1 && !isbigval(b) && no (b) + boff == 0) {
-
 
1630
    /* adding zero and moving */
-
 
1631
    cond1_set = 0;
-
 
1632
    move (sha, a1, dest);
1647
    move(sha, a1, dest);
1633
    return;
1648
    return;
1634
  };
1649
  };
1635
 
1650
 
1636
  /* switch on memory position of a1, a2, dest */
1651
  /* switch on memory position of a1, a2, dest */
1637
  switch ((inmem (a1) << 2) + (inmem (a2) << 1) + inmem (dest)) {
1652
  switch ((inmem(a1) << 2) + (inmem(a2) << 1) + inmem(dest)) {
1638
    case 0:
1653
    case 0:
1639
      {				/* none in memory */
1654
      {				/* none in memory */
1640
	exp ap;
1655
	exp ap;
1641
        int n;
1656
        int n;
1642
        if (overflow_e != nilexp || sz > 32)
1657
        if (overflow_e != nilexp || sz > 32)
1643
          {
1658
          {
1644
            move (sha, a2, dest);
1659
            move(sha, a2, dest);
1645
            add_plus (sha, a1, dest, dest, plus1);
1660
            add_plus(sha, a1, dest, dest, plus1);
1646
            return;
1661
            return;
1647
          };
1662
          };
1648
	/* otherwise cannot be plus1 */
1663
	/* otherwise cannot be plus1 */
1649
	if (name (a) == val_tag) {
1664
	if (name(a) == val_tag) {
1650
	  if (name (b) == val_tag) {/* we know the answer */
1665
	  if (name (b) == val_tag) {/* we know the answer */
1651
	    cond1_set = 0;
1666
	    cond1_set = 0;
1652
	    move (sha, mw (zeroe,
1667
	    move(sha, mw(zeroe,
1653
		    no (a) + no (b) + a1.where_off + a2.where_off),
1668
		    no(a) + no(b) + a1.where_off + a2.where_off),
1654
		    dest);
1669
		    dest);
1655
	    return;
1670
	    return;
1656
	  };
1671
	  };
1657
          if (name(sh(a)) == offsethd)
1672
          if (name(sh(a)) == offsethd)
1658
            n = 1;
1673
            n = 1;
1659
          else
1674
          else
1660
            n = 8;
1675
            n = 8;
1661
          if (n == 8 && (no(a) & (int)0xf0000000) == 0)  {
1676
          if (n == 8 && (no(a) & (int)0xf0000000) == 0) {
1662
	    ap = getexp (f_bottom, nilexp, 0, b, nilexp, 0,
1677
	    ap = getexp(f_bottom, nilexp, 0, b, nilexp, 0,
1663
	        (no (a) + a1.where_off) * n,
1678
	       (no(a) + a1.where_off)* n,
1664
	        reff_tag);
1679
	        reff_tag);
1665
	    cond1_set = 0;
1680
	    cond1_set = 0;
1666
	    ins2 (leal, 32, 32, mw (ap, 0), dest);
1681
	    ins2(leal, 32, 32, mw(ap, 0), dest);
1667
	    retcell (ap);
1682
	    retcell(ap);
1668
	    invalidate_dest (dest);
1683
	    invalidate_dest(dest);
1669
	    return;
1684
	    return;
1670
          }
1685
          }
1671
          else  {
1686
          else  {
1672
            move(sha, a2, dest);
1687
            move(sha, a2, dest);
1673
            add(sha, a1, dest, dest);
1688
            add(sha, a1, dest, dest);
1674
            return;
1689
            return;
1675
          };
1690
          };
1676
	};
1691
	};
1677
	if (name (b) == val_tag) {
1692
	if (name(b) == val_tag) {
1678
          if (name(sh(b)) == offsethd)
1693
          if (name(sh(b)) == offsethd)
1679
            n = 1;
1694
            n = 1;
1680
          else
1695
          else
1681
            n = 8;
1696
            n = 8;
1682
          if (n == 8 && (no(b) & (int)0xf0000000) == 0)  {
1697
          if (n == 8 && (no(b) & (int)0xf0000000) == 0) {
1683
	    ap = getexp (f_bottom, nilexp, 0, a, nilexp, 0,
1698
	    ap = getexp(f_bottom, nilexp, 0, a, nilexp, 0,
1684
	        (no (b) + a2.where_off) * n,
1699
	       (no(b) + a2.where_off)* n,
1685
	        reff_tag);
1700
	        reff_tag);
1686
	    cond1_set = 0;
1701
	    cond1_set = 0;
1687
	    ins2 (leal, 32, 32, mw (ap, 0), dest);
1702
	    ins2(leal, 32, 32, mw(ap, 0), dest);
1688
	    retcell (ap);
1703
	    retcell(ap);
1689
	    invalidate_dest (dest);
1704
	    invalidate_dest(dest);
1690
	    return;
1705
	    return;
1691
          }
1706
          }
1692
          else  {
1707
          else  {
1693
            move(sha, a1, dest);
1708
            move(sha, a1, dest);
1694
            add(sha, a2, dest, dest);
1709
            add(sha, a2, dest, dest);
1695
            return;
1710
            return;
1696
          };
1711
          };
1697
	};
1712
	};
1698
	ap = getexp (f_bottom, nilexp, 0, a, nilexp, 0, 0,
1713
	ap = getexp(f_bottom, nilexp, 0, a, nilexp, 0, 0,
1699
	      addptr_tag);
1714
	      addptr_tag);
1700
	{
1715
	{
1701
	  exp temp = bro(a);
1716
	  exp temp = bro(a);
1702
	  bro (a) = b;
1717
	  bro(a) = b;
1703
	  cond1_set = 0;
1718
	  cond1_set = 0;
1704
	  ins2 (leal, 32, 32, mw (ap, 0), dest);
1719
	  ins2(leal, 32, 32, mw(ap, 0), dest);
1705
	  retcell (ap);
1720
	  retcell(ap);
1706
          invalidate_dest (dest);
1721
          invalidate_dest(dest);
1707
	  bro(a) = temp;
1722
	  bro(a) = temp;
1708
          return;
1723
          return;
1709
	}
1724
	}
1710
      };
1725
      };
1711
    case 1:
1726
    case 1:
1712
    case 3:
1727
    case 3:
1713
    case 5:
1728
    case 5:
1714
    case 7:
1729
    case 7:
1715
      /* dest is in memory */
1730
      /* dest is in memory */
1716
      add_plus (sha, a1, a2, reg0, plus1);
1731
      add_plus(sha, a1, a2, reg0, plus1);
1717
      move (sha, reg0, dest);
1732
      move(sha, reg0, dest);
1718
      return;
1733
      return;
1719
    case 2: 			/* a2 in memory others not */
1734
    case 2: 			/* a2 in memory others not */
1720
      if (eq_where (a1, reg0))
1735
      if (eq_where(a1, reg0))
1721
	reg0_in_use = 1;
1736
	reg0_in_use = 1;
1722
      move (sha, a2, dest);
1737
      move(sha, a2, dest);
1723
      add_plus (sha, a1, dest, dest, plus1);
1738
      add_plus(sha, a1, dest, dest, plus1);
1724
      invalidate_dest (dest);
1739
      invalidate_dest(dest);
1725
      return;
1740
      return;
1726
    case 4: 			/* a1 in memory others not */
1741
    case 4: 			/* a1 in memory others not */
1727
      if (eq_where (a2, reg0))
1742
      if (eq_where(a2, reg0))
1728
	reg0_in_use = 1;
1743
	reg0_in_use = 1;
1729
      move (sha, a1, dest);
1744
      move(sha, a1, dest);
1730
      add_plus (sha, a2, dest, dest, plus1);
1745
      add_plus(sha, a2, dest, dest, plus1);
1731
      invalidate_dest (dest);
1746
      invalidate_dest(dest);
1732
      return;
1747
      return;
1733
    default: 			/* case 6 a1 and a2 in memory, dest not */
1748
    default: 			/* case 6 a1 and a2 in memory, dest not */
1734
      move (sha, a2, reg0);
1749
      move(sha, a2, reg0);
1735
      add_plus (sha, a1, reg0, reg0, plus1);
1750
      add_plus(sha, a1, reg0, reg0, plus1);
1736
      move (sha, reg0, dest);
1751
      move(sha, reg0, dest);
1737
      return;
1752
      return;
1738
  };
1753
  };
1739
}
1754
}
1740
 
1755
 
1741
 
1756
 
1742
/* add values a1, a2 of shape sha and put them in dest */
1757
/* add values a1, a2 of shape sha and put them in dest */
1743
void add
1758
void add
1744
    PROTO_N ( (sha, a1, a2, dest) )
-
 
1745
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
1759
(shape sha, where a1, where a2, where dest)
1746
{
1760
{
1747
  add_plus (sha, a1, a2, dest, 0);
1761
  add_plus(sha, a1, a2, dest, 0);
1748
  return;
1762
  return;
1749
}
1763
}
1750
 
1764
 
1751
 
1765
 
1752
/* negate a1 in sup_dest then add a2 and put in dest */
1766
/* negate a1 in sup_dest then add a2 and put in dest */
1753
void inverted_sub
1767
void inverted_sub
1754
    PROTO_N ( (sha, a1, a2, sup_dest, dest) )
-
 
1755
    PROTO_T ( shape sha X where a1 X where a2 X where sup_dest X where dest )
1768
(shape sha, where a1, where a2, where sup_dest, where dest)
1756
{
1769
{
1757
  if (overflow_e == nilexp) {
1770
  if (overflow_e == nilexp) {
1758
    negate (sha, a1, sup_dest);
1771
    negate(sha, a1, sup_dest);
1759
    add_plus (sha, a2, sup_dest, dest, 0);
1772
    add_plus(sha, a2, sup_dest, dest, 0);
1760
  }
1773
  }
1761
  else {
1774
  else {
1762
    exp old_overflow_e = overflow_e;
1775
    exp old_overflow_e = overflow_e;
1763
    overflow_e = nilexp;
1776
    overflow_e = nilexp;
1764
    not (sha, a1, sup_dest);
1777
    not(sha, a1, sup_dest);
1765
    overflow_e = old_overflow_e;
1778
    overflow_e = old_overflow_e;
1766
    add_plus (sha, a2, sup_dest, dest, 1);
1779
    add_plus(sha, a2, sup_dest, dest, 1);
1767
  }
1780
  }
1768
  return;
1781
  return;
1769
}
1782
}
1770
 
1783
 
1771
 
1784
 
1772
/* subtract a1 from a2 and put in dest,
1785
/* subtract a1 from a2 and put in dest,
1773
   shape sha, structure similar to add qv.
1786
   shape sha, structure similar to add qv.
1774
   for comments */
1787
   for comments */
1775
void sub
1788
void sub
1776
    PROTO_N ( (sha, a1, a2, dest) )
-
 
1777
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
1789
(shape sha, where a1, where a2, where dest)
1778
{
1790
{
1779
  int  sz;
1791
  int  sz;
1780
  exp a = a1.where_exp;
1792
  exp a = a1.where_exp;
1781
  int  aoff = a1.where_off;
1793
  int  aoff = a1.where_off;
1782
  exp b = a2.where_exp;
1794
  exp b = a2.where_exp;
1783
  sz = shape_size(sha);
1795
  sz = shape_size(sha);
1784
 
1796
 
1785
  if (name(a) == val_tag && name(sh(a)) == offsethd && al2(sh(a)) != 1) {
1797
  if (name(a) == val_tag && name(sh(a)) == offsethd && al2(sh(a))!= 1) {
1786
    if (name(sha) == offsethd && al2(sha) != 1)
1798
    if (name(sha) == offsethd && al2(sha)!= 1)
1787
      no(a) = no(a) / 8;
1799
      no(a) = no(a) / 8;
1788
    sh(a) = slongsh;
1800
    sh(a) = slongsh;
1789
  };
1801
  };
1790
  if (name(b) == val_tag && name(sh(b)) == offsethd && al2(sh(b)) != 1) {
1802
  if (name(b) == val_tag && name(sh(b)) == offsethd && al2(sh(b))!= 1) {
1791
    if (name(sha) == offsethd && al2(sha) != 1)
1803
    if (name(sha) == offsethd && al2(sha)!= 1)
1792
      no(b) = no(b) / 8;
1804
      no(b) = no(b) / 8;
1793
    sh(b) = slongsh;
1805
    sh(b) = slongsh;
1794
  };
1806
  };
1795
 
1807
 
1796
  if (name (sha) & 1) {
1808
  if (name(sha) & 1) {
1797
    cond1_set = 1;
1809
    cond1_set = 1;
1798
    cond2_set = 0;
1810
    cond2_set = 0;
1799
    cond1 = dest;
1811
    cond1 = dest;
1800
  }
1812
  }
1801
  else {			/* the conditions are not set correctly if
1813
  else {			/* the conditions are not set correctly if
Line 1803... Line 1815...
1803
    cond1_set = 0;
1815
    cond1_set = 0;
1804
    cond2_set = 0;
1816
    cond2_set = 0;
1805
  };
1817
  };
1806
 
1818
 
1807
 
1819
 
1808
  if (eq_where (a2, dest) &&
1820
  if (eq_where(a2, dest) &&
1809
	(!keep_short || !flinmem(dest))) {
1821
	(!keep_short || !flinmem(dest))) {
1810
    if (name (a) == val_tag && !isbigval(a) && (no (a) + aoff == 0 ||
1822
    if (name(a) == val_tag && !isbigval(a) && (no(a) + aoff == 0 ||
1811
	  ((no (a) + aoff == 1 || no (a) + aoff == -1) && sz <= 32 &&
1823
	 ((no(a) + aoff == 1 || no(a) + aoff == -1) && sz <= 32 &&
1812
	    (overflow_e == nilexp || is_signed(sha) )))) {
1824
	   (overflow_e == nilexp || is_signed(sha))))) {
1813
      exp hold = son(b);
1825
      exp hold = son(b);
1814
      if (no (a) + aoff == 0) {	/* we didn't know the conditions */
1826
      if (no (a) + aoff == 0) {	/* we didn't know the conditions */
1815
	cond1_set = 0;
1827
	cond1_set = 0;
1816
	return;
1828
	return;
1817
      };
1829
      };
1818
      contop (b, 0, a2);
1830
      contop(b, 0, a2);
1819
      if (no (a) + aoff == 1) {	/* use dec */
1831
      if (no (a) + aoff == 1) {	/* use dec */
1820
	if (sz == 8) {
1832
	if (sz == 8) {
1821
	  ins1 (decb, sz, a2);
1833
	  ins1(decb, sz, a2);
1822
	};
1834
	};
1823
	if (sz == 16) {
1835
	if (sz == 16) {
1824
	  ins1 (decw, sz, a2);
1836
	  ins1(decw, sz, a2);
1825
	};
1837
	};
1826
	if (sz == 32) {
1838
	if (sz == 32) {
1827
	  ins1 (decl, sz, a2);
1839
	  ins1(decl, sz, a2);
1828
	};
1840
	};
1829
      }
1841
      }
1830
      else {			/* use inc */
1842
      else {			/* use inc */
1831
	if (sz == 8) {
1843
	if (sz == 8) {
1832
	  ins1 (incb, sz, a2);
1844
	  ins1(incb, sz, a2);
1833
	};
1845
	};
1834
	if (sz == 16) {
1846
	if (sz == 16) {
1835
	  ins1 (incw, sz, a2);
1847
	  ins1(incw, sz, a2);
1836
	};
1848
	};
1837
	if (sz == 32) {
1849
	if (sz == 32) {
1838
	  ins1 (incl, sz, a2);
1850
	  ins1(incl, sz, a2);
1839
	};
1851
	};
1840
      };
1852
      };
1841
      invalidate_dest (dest);
1853
      invalidate_dest(dest);
1842
      end_contop ();
1854
      end_contop();
1843
      try_overflow (sha, 0);
1855
      try_overflow(sha, 0);
1844
      son(b) = hold;
1856
      son(b) = hold;
1845
      return;
1857
      return;
1846
    };
1858
    };
1847
 
1859
 
1848
    if (!inmem (a1) || !inmem (a2)) {
1860
    if (!inmem(a1) || !inmem(a2)) {
1849
      int riu = regsinuse;
1861
      int riu = regsinuse;
1850
      exp holda = son(a);
1862
      exp holda = son(a);
1851
      exp holdb = son(b);
1863
      exp holdb = son(b);
1852
      if (sz == 64)
1864
      if (sz == 64)
1853
	regsinuse |= 0x2;
1865
	regsinuse |= 0x2;
1854
      if (inmem (a1))
1866
      if (inmem(a1))
1855
	contop (a, eq_where (reg0, a2), a2);
1867
	contop(a, eq_where(reg0, a2), a2);
1856
      else
1868
      else
1857
	contop (b,
1869
	contop(b,
1858
	     (eq_where (reg0, a2) || eq_where (reg0, a1)), a2);
1870
	    (eq_where(reg0, a2) || eq_where(reg0, a1)), a2);
1859
      if (sz == 8) {
1871
      if (sz == 8) {
1860
	ins2 (subb, sz, sz, a1, a2);
1872
	ins2(subb, sz, sz, a1, a2);
1861
      };
1873
      };
1862
      if (sz == 16) {
1874
      if (sz == 16) {
1863
	ins2 (subw, sz, sz, a1, a2);
1875
	ins2(subw, sz, sz, a1, a2);
1864
      };
1876
      };
1865
      if (sz == 32) {
1877
      if (sz == 32) {
1866
	ins2 (subl, sz, sz, a1, a2);
1878
	ins2(subl, sz, sz, a1, a2);
1867
      };
1879
      };
1868
      if (sz == 64) {
1880
      if (sz == 64) {
1869
	where hi1, lo1, hi2, lo2;
1881
	where hi1, lo1, hi2, lo2;
1870
	lo2 = a2;
1882
	lo2 = a2;
1871
	hi2 = (inmem(a2) ? mw (b, a2.where_off + 32) : reg1);
1883
	hi2 = (inmem(a2)? mw(b, a2.where_off + 32): reg1);
1872
	if (name (a) == val_tag) {
1884
	if (name(a) == val_tag) {
1873
	  int c, c1;
1885
	  int c, c1;
1874
	  if (!isbigval(a)) {
1886
	  if (!isbigval(a)) {
1875
	    c = no (a) + aoff;
1887
	    c = no(a) + aoff;
1876
	    c1 = (is_signed(sha) && c < 0) ? -1 : 0;
1888
	    c1 = (is_signed(sha) && c < 0)? -1 : 0;
1877
	  }
1889
	  }
1878
	  else {
1890
	  else {
1879
	    flt64 x;
1891
	    flt64 x;
1880
	    int ov;
1892
	    int ov;
1881
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
1893
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
1882
	    c = x.small;
1894
	    c = x.small;
1883
	    c1 = x.big;
1895
	    c1 = x.big;
1884
	  };
1896
	  };
1885
	  lo1 = mw (zeroe, c);
1897
	  lo1 = mw(zeroe, c);
1886
	  hi1 = mw (zeroe, c1);
1898
	  hi1 = mw(zeroe, c1);
1887
	}
1899
	}
1888
	else {
1900
	else {
1889
	  lo1 = a1;
1901
	  lo1 = a1;
1890
	  hi1 = (inmem(a1) ? mw (a, aoff + 32) : reg1);
1902
	  hi1 = (inmem(a1)? mw(a, aoff + 32): reg1);
1891
	}
1903
	}
1892
 	ins2 (subl, 32, 32, lo1, lo2);
1904
 	ins2(subl, 32, 32, lo1, lo2);
1893
 	ins2 (sbbl, 32, 32, hi1, hi2);
1905
 	ins2(sbbl, 32, 32, hi1, hi2);
1894
      };
1906
      };
1895
      invalidate_dest (dest);
1907
      invalidate_dest(dest);
1896
      end_contop ();
1908
      end_contop();
1897
      regsinuse = riu;
1909
      regsinuse = riu;
1898
      try_overflow (sha, 0);
1910
      try_overflow(sha, 0);
1899
      son(a) = holda;
1911
      son(a) = holda;
1900
      son(b) = holdb;
1912
      son(b) = holdb;
1901
      return;
1913
      return;
1902
    };
1914
    };
1903
 
1915
 
1904
    move (sha, a1, reg0);
1916
    move(sha, a1, reg0);
1905
    sub (sha, reg0, dest, dest);
1917
    sub(sha, reg0, dest, dest);
1906
    invalidate_dest (dest);
1918
    invalidate_dest(dest);
1907
    return;
1919
    return;
1908
  };
1920
  };
1909
 
1921
 
1910
  if (name (a) == val_tag && !isbigval(a) && no (a) + aoff == 0) {
1922
  if (name(a) == val_tag && !isbigval(a) && no(a) + aoff == 0) {
1911
    cond1_set = 0;
1923
    cond1_set = 0;
1912
    move (sha, a2, dest);
1924
    move(sha, a2, dest);
1913
    return;
1925
    return;
1914
  };
1926
  };
1915
 
1927
 
1916
  switch ((inmem (a1) << 2) + (inmem (a2) << 1) + inmem (dest)) {
1928
  switch ((inmem(a1) << 2) + (inmem(a2) << 1) + inmem(dest)) {
1917
    case 0:
1929
    case 0:
1918
    case 2: 			/* a2 may be in mem, others not */
1930
    case 2: 			/* a2 may be in mem, others not */
1919
      if (!eq_where (a1, dest)) {
1931
      if (!eq_where(a1, dest)) {
1920
	if (eq_where (a1, reg0))
1932
	if (eq_where(a1, reg0))
1921
	  reg0_in_use = 1;
1933
	  reg0_in_use = 1;
1922
	move (sha, a2, dest);
1934
	move(sha, a2, dest);
1923
	sub (sha, a1, dest, dest);
1935
	sub(sha, a1, dest, dest);
1924
	invalidate_dest (dest);
1936
	invalidate_dest(dest);
1925
	return;
1937
	return;
1926
      };
1938
      };
1927
      if (eq_where (a1, reg0) || eq_where (a2, reg0)) {
1939
      if (eq_where(a1, reg0) || eq_where(a2, reg0)) {
1928
	if (eq_where (a2, reg0))
1940
	if (eq_where(a2, reg0))
1929
	  reg0_in_use = 1;
1941
	  reg0_in_use = 1;
1930
	inverted_sub (sha, a1, a2, dest, dest);
1942
	inverted_sub(sha, a1, a2, dest, dest);
1931
	return;
1943
	return;
1932
      };
1944
      };
1933
      inverted_sub (sha, a1, a2, reg0, dest);
1945
      inverted_sub(sha, a1, a2, reg0, dest);
1934
      return;
1946
      return;
1935
    case 4:  			/* a1 in memory others not */
1947
    case 4:  			/* a1 in memory others not */
1936
      if (eq_where (dest, reg0)) {
1948
      if (eq_where(dest, reg0)) {
1937
	move (sha, a2, reg0);
1949
	move(sha, a2, reg0);
1938
	sub (sha, a1, reg0, reg0);
1950
	sub(sha, a1, reg0, reg0);
1939
	invalidate_dest (dest);
1951
	invalidate_dest(dest);
1940
	return;
1952
	return;
1941
      };		/* else drop through */
1953
      };		/* else drop through */
1942
    case 1:
1954
    case 1:
1943
    case 3:
1955
    case 3:
1944
    case 5:
1956
    case 5:
1945
    case 7: 			/* dest is in memory */
1957
    case 7: 			/* dest is in memory */
1946
      sub (sha, a1, a2, reg0);
1958
      sub(sha, a1, a2, reg0);
1947
      move (sha, reg0, dest);
1959
      move(sha, reg0, dest);
1948
      return;
1960
      return;
1949
    default: 			/* case 6 a1 and a2 in memory, dest not */
1961
    default: 			/* case 6 a1 and a2 in memory, dest not */
1950
      /* we ought to look to see if dest affects the addressing of a1 or
1962
      /* we ought to look to see if dest affects the addressing of a1 or
1951
         a2, and use it if not */
1963
         a2, and use it if not */
1952
      inverted_sub (sha, a1, a2, reg0, dest);
1964
      inverted_sub(sha, a1, a2, reg0, dest);
1953
      return;
1965
      return;
1954
  };
1966
  };
1955
}
1967
}
1956
 
1968
 
1957
 
1969
 
1958
/* put a negated into dest, shape sha */
1970
/* put a negated into dest, shape sha */
1959
void negate
1971
void negate
1960
    PROTO_N ( (sha, a, dest) )
-
 
1961
    PROTO_T ( shape sha X where a X where dest )
1972
(shape sha, where a, where dest)
1962
{
1973
{
1963
  int  sz;
1974
  int  sz;
1964
  sz = shape_size(sha);
1975
  sz = shape_size(sha);
1965
 
1976
 
1966
  cond1_set = 1;
1977
  cond1_set = 1;
1967
  cond2_set = 0;
1978
  cond2_set = 0;
1968
  cond1 = dest;
1979
  cond1 = dest;
1969
 
1980
 
1970
  if (!inmem (a) && eq_where (a, dest)) {/* negating in situ */
1981
  if (!inmem (a) && eq_where (a, dest)) {/* negating in situ */
1971
    if (sz == 8) {
1982
    if (sz == 8) {
1972
      ins1 (negb, sz, dest);
1983
      ins1(negb, sz, dest);
1973
      invalidate_dest (dest);
1984
      invalidate_dest(dest);
1974
    };
1985
    };
1975
    if (sz == 16) {
1986
    if (sz == 16) {
1976
      ins1 (negw, sz, dest);
1987
      ins1(negw, sz, dest);
1977
      invalidate_dest (dest);
1988
      invalidate_dest(dest);
1978
    };
1989
    };
1979
    if (sz == 32) {
1990
    if (sz == 32) {
1980
      ins1 (negl, sz, dest);
1991
      ins1(negl, sz, dest);
1981
      invalidate_dest (dest);
1992
      invalidate_dest(dest);
1982
    };
1993
    };
1983
    if (sz == 64) {	/* must be reg0/1 */
1994
    if (sz == 64) {	/* must be reg0/1 */
1984
      move (slongsh, reg1, reg2);
1995
      move(slongsh, reg1, reg2);
1985
      move (slongsh, zero, reg1);
1996
      move(slongsh, zero, reg1);
1986
      ins1(negl, 32, reg0);
1997
      ins1(negl, 32, reg0);
1987
      ins2(sbbl, 32, 32, reg2, reg1);
1998
      ins2(sbbl, 32, 32, reg2, reg1);
1988
      try_overflow (sha, 0);
1999
      try_overflow(sha, 0);
1989
      invalidate_dest (reg0);
2000
      invalidate_dest(reg0);
1990
      invalidate_dest (reg1);
2001
      invalidate_dest(reg1);
1991
      invalidate_dest (reg2);
2002
      invalidate_dest(reg2);
1992
      return;
2003
      return;
1993
    };
2004
    };
1994
    try_overflow (sha, 0);
2005
    try_overflow(sha, 0);
1995
    return;
2006
    return;
1996
  };
2007
  };
1997
 
2008
 
1998
  if (!inmem (a) && name (a.where_exp) != val_tag &&
2009
  if (!inmem(a) && name(a.where_exp)!= val_tag &&
1999
      (w_islastuse (a) || eq_where (a, reg0))) {
2010
     (w_islastuse(a) || eq_where(a, reg0))) {
2000
    /* a is a register and no longer needed */
2011
    /* a is a register and no longer needed */
2001
    negate (sha, a, a);
2012
    negate(sha, a, a);
2002
    move (sha, a, dest);
2013
    move(sha, a, dest);
2003
    return;
2014
    return;
2004
  };
2015
  };
2005
 
2016
 
2006
  if (!inmem (dest)) {		/* dest is a register */
2017
  if (!inmem (dest)) {		/* dest is a register */
2007
    move (sha, a, dest);
2018
    move(sha, a, dest);
2008
    negate (sha, dest, dest);
2019
    negate(sha, dest, dest);
2009
    invalidate_dest (dest);
2020
    invalidate_dest(dest);
2010
    return;
2021
    return;
2011
  };
2022
  };
2012
 
2023
 
2013
  /* dest is in memory, a is either in memory or needed, it won't be reg0
2024
  /* dest is in memory, a is either in memory or needed, it won't be reg0
2014
  */
2025
  */
2015
  move (sha, a, reg0);
2026
  move(sha, a, reg0);
2016
  negate (sha, reg0, reg0);
2027
  negate(sha, reg0, reg0);
2017
  move (sha, reg0, dest);
2028
  move(sha, reg0, dest);
2018
  return;
2029
  return;
2019
}
2030
}
2020
 
2031
 
2021
/* put not(a) into dest, shape sha */
2032
/* put not(a) into dest, shape sha */
2022
void not
2033
void not
2023
    PROTO_N ( (sha, a, dest) )
-
 
2024
    PROTO_T ( shape sha X where a X where dest )
2034
(shape sha, where a, where dest)
2025
{
2035
{
2026
  int  sz;
2036
  int  sz;
2027
  sz = shape_size(sha);
2037
  sz = shape_size(sha);
2028
 
2038
 
2029
  cond1_set = 0;
2039
  cond1_set = 0;
2030
  cond2_set = 0;
2040
  cond2_set = 0;
2031
 
2041
 
2032
  if (!inmem (a) && eq_where (a, dest)) {/* inverting in situ */
2042
  if (!inmem (a) && eq_where (a, dest)) {/* inverting in situ */
2033
    if (sz == 8) {
2043
    if (sz == 8) {
2034
      ins1 (notb, sz, dest);
2044
      ins1(notb, sz, dest);
2035
      invalidate_dest (dest);
2045
      invalidate_dest(dest);
2036
      return;
2046
      return;
2037
    };
2047
    };
2038
    if (sz == 16) {
2048
    if (sz == 16) {
2039
      ins1 (notw, sz, dest);
2049
      ins1(notw, sz, dest);
2040
      invalidate_dest (dest);
2050
      invalidate_dest(dest);
2041
      return;
2051
      return;
2042
    };
2052
    };
2043
    if (sz == 32) {
2053
    if (sz == 32) {
2044
      ins1 (notl, sz, dest);
2054
      ins1(notl, sz, dest);
2045
      invalidate_dest (dest);
2055
      invalidate_dest(dest);
2046
      return;
2056
      return;
2047
    };
2057
    };
2048
    if (sz == 64) {	/* must be reg0/1 */
2058
    if (sz == 64) {	/* must be reg0/1 */
2049
      ins1 (notl, 32, reg0);
2059
      ins1(notl, 32, reg0);
2050
      ins1 (notl, 32, reg1);
2060
      ins1(notl, 32, reg1);
2051
      invalidate_dest (reg0);
2061
      invalidate_dest(reg0);
2052
      invalidate_dest (reg1);
2062
      invalidate_dest(reg1);
2053
      return;
2063
      return;
2054
    };
2064
    };
2055
  };
2065
  };
2056
 
2066
 
2057
  if (!inmem (a) && name (a.where_exp) != val_tag &&
2067
  if (!inmem(a) && name(a.where_exp)!= val_tag &&
2058
      (w_islastuse (a) || eq_where (a, reg0))) {
2068
     (w_islastuse(a) || eq_where(a, reg0))) {
2059
    not (sha, a, a);
2069
    not(sha, a, a);
2060
    move (sha, a, dest);
2070
    move(sha, a, dest);
2061
    return;
2071
    return;
2062
  };
2072
  };
2063
 
2073
 
2064
  if (!inmem (dest)) {		/* dest is a register */
2074
  if (!inmem (dest)) {		/* dest is a register */
2065
    move (sha, a, dest);
2075
    move(sha, a, dest);
2066
    not (sha, dest, dest);
2076
    not(sha, dest, dest);
2067
    invalidate_dest (dest);
2077
    invalidate_dest(dest);
2068
    return;
2078
    return;
2069
  };
2079
  };
2070
 
2080
 
2071
  /* dest is in memory, a is either in memory or needed, it won't be reg0
2081
  /* dest is in memory, a is either in memory or needed, it won't be reg0
2072
  */
2082
  */
2073
  move (sha, a, reg0);
2083
  move(sha, a, reg0);
2074
  not (sha, reg0, reg0);
2084
  not(sha, reg0, reg0);
2075
  move (sha, reg0, dest);
2085
  move(sha, reg0, dest);
2076
  return;
2086
  return;
2077
}
2087
}
2078
 
2088
 
2079
 
2089
 
2080
 
2090
 
2081
 
2091
 
2082
/* floating register for e */
2092
/* floating register for e */
2083
int  in_fl_reg
2093
int  in_fl_reg
2084
    PROTO_N ( (e) )
-
 
2085
    PROTO_T ( exp e )
2094
(exp e)
2086
{
2095
{
2087
  unsigned char  ne = name (e);
2096
  unsigned char  ne = name(e);
2088
  if (ne == name_tag && ptno (son (e)) == reg_pl) {
2097
  if (ne == name_tag && ptno(son(e)) == reg_pl) {
2089
    int  n = no (son (e));
2098
    int  n = no(son(e));
2090
    return ((n > 0x80) ? n : 0);
2099
    return((n > 0x80)? n : 0);
2091
  };
2100
  };
2092
  if (ne == cont_tag && name (son (e)) == name_tag &&
2101
  if (ne == cont_tag && name(son(e)) == name_tag &&
2093
      isvar (son (son (e))) &&
2102
      isvar(son(son(e))) &&
2094
      ptno (son (son (e))) == reg_pl) {
2103
      ptno(son(son(e))) == reg_pl) {
2095
    int  n = no (son (son (e)));
2104
    int  n = no(son(son(e)));
2096
    return ((n > 0x80) ? n : 0);
2105
    return((n > 0x80)? n : 0);
2097
  };
2106
  };
2098
  if (ne == ass_tag && name (son (e)) == name_tag &&
2107
  if (ne == ass_tag && name(son(e)) == name_tag &&
2099
      isvar (son (son (e))) &&
2108
      isvar(son(son(e))) &&
2100
      ptno (son (son (e))) == reg_pl) {
2109
      ptno(son(son(e))) == reg_pl) {
2101
    int  n = no (son (son (e)));
2110
    int  n = no(son(son(e)));
2102
    return ((n > 0x80) ? n : 0);
2111
    return((n > 0x80)? n : 0);
2103
  };
2112
  };
2104
  if (ne == ident_tag && ptno (e) == reg_pl) {
2113
  if (ne == ident_tag && ptno(e) == reg_pl) {
2105
    int  n = no (e);
2114
    int  n = no(e);
2106
    return ((n > 0x80) ? n : 0);
2115
    return((n > 0x80)? n : 0);
2107
  };
2116
  };
2108
  return (0);
2117
  return(0);
2109
}
2118
}
2110
 
2119
 
2111
 
2120
 
2112
/* is e in the floating point stack top ? */
2121
/* is e in the floating point stack top ? */
2113
int in_fstack
2122
int in_fstack
2114
    PROTO_N ( (e) )
-
 
2115
    PROTO_T ( exp e )
2123
(exp e)
2116
{
2124
{
2117
  int  f = in_fl_reg (e);
2125
  int  f = in_fl_reg(e);
2118
  int  fpos = (f) ? get_reg_no (f) : 0;
2126
  int  fpos = (f)? get_reg_no(f): 0;
2119
  return (fpos == fstack_pos);
2127
  return(fpos == fstack_pos);
2120
}
2128
}
2121
 
2129
 
2122
 
2130
 
2123
 
2131
 
2124
/* is e in a register */
2132
/* is e in a register */
2125
int  in_reg
2133
int  in_reg
2126
    PROTO_N ( (e) )
-
 
2127
    PROTO_T ( exp e )
2134
(exp e)
2128
{
2135
{
2129
  unsigned char  ne = name (e);
2136
  unsigned char  ne = name(e);
2130
  if (ne == name_tag && ptno (son (e)) == reg_pl) {
2137
  if (ne == name_tag && ptno(son(e)) == reg_pl) {
2131
    int  n = no (son (e));
2138
    int  n = no(son(e));
2132
    if (!iscaonly (son (e)) && isvar (son (e)))
2139
    if (!iscaonly(son(e)) && isvar(son(e)))
2133
      n = (n | (int)0x80000000);
2140
      n = (n | (int)0x80000000);
2134
    return (n);
2141
    return(n);
2135
  };
2142
  };
2136
  if (ne == cont_tag && name (son (e)) == name_tag &&
2143
  if (ne == cont_tag && name(son(e)) == name_tag &&
2137
      isvar (son (son (e))) &&
2144
      isvar(son(son(e))) &&
2138
      ptno (son (son (e))) == reg_pl) {
2145
      ptno(son(son(e))) == reg_pl) {
2139
    int  n = no (son (son (e)));
2146
    int  n = no(son(son(e)));
2140
    if (!iscaonly (son (son (e))) && isvar (son (son (e))))
2147
    if (!iscaonly(son(son(e))) && isvar(son(son(e))))
2141
      n = (n | (int)0x80000000);
2148
      n = (n | (int)0x80000000);
2142
    return (n);
2149
    return(n);
2143
  };
2150
  };
2144
  if (ne == ass_tag && name (son (e)) == name_tag &&
2151
  if (ne == ass_tag && name(son(e)) == name_tag &&
2145
      isvar (son (son (e))) &&
2152
      isvar(son(son(e))) &&
2146
      ptno (son (son (e))) == reg_pl) {
2153
      ptno(son(son(e))) == reg_pl) {
2147
    int  n = no (son (son (e)));
2154
    int  n = no(son(son(e)));
2148
    if (!iscaonly (son (son (e))) && isvar (son (son (e))))
2155
    if (!iscaonly(son(son(e))) && isvar(son(son(e))))
2149
      n = (n | (int)0x80000000);
2156
      n = (n | (int)0x80000000);
2150
    return (n);
2157
    return(n);
2151
  };
2158
  };
2152
  if (ne == ident_tag && ptno (e) == reg_pl) {
2159
  if (ne == ident_tag && ptno(e) == reg_pl) {
2153
    int  n = no (e);
2160
    int  n = no(e);
2154
    if (!iscaonly (e) && isvar (e))
2161
    if (!iscaonly(e) && isvar(e))
2155
      n = (n | (int)0x80000000);
2162
      n = (n | (int)0x80000000);
2156
    return (n);
2163
    return(n);
2157
  };
2164
  };
2158
  if (ne == current_env_tag)
2165
  if (ne == current_env_tag)
2159
    return (0x40);
2166
    return(0x40);
2160
  return (0);
2167
  return(0);
2161
}
2168
}
2162
 
2169
 
2163
static int all_in_regs
2170
static int all_in_regs
2164
    PROTO_N ( (e) )
-
 
2165
    PROTO_T ( exp e )
2171
(exp e)
2166
{
2172
{
2167
  exp id1, id2;
2173
  exp id1, id2;
2168
  unsigned char  n = name (e);
2174
  unsigned char  n = name(e);
2169
 
2175
 
2170
  if ((n == cont_tag || n == ass_tag || n == reff_tag)
2176
  if ((n == cont_tag || n == ass_tag || n == reff_tag)
2171
      && name (son (e)) == ident_tag) {
2177
      && name(son(e)) == ident_tag) {
2172
    id1 = son (e);
2178
    id1 = son(e);
2173
    if (ptno (son (son (id1))) != reg_pl)
2179
    if (ptno(son(son(id1)))!= reg_pl)
2174
      return (0);
2180
      return(0);
2175
    id2 = bro (son (id1));
2181
    id2 = bro(son(id1));
2176
    if (name (id2) != ident_tag)
2182
    if (name(id2)!= ident_tag)
2177
      return (1);
2183
      return(1);
2178
    return (ptno (son (son (id2))) == reg_pl);
2184
    return(ptno(son(son(id2))) == reg_pl);
2179
  };
2185
  };
2180
 
2186
 
2181
  return (1);
2187
  return(1);
2182
}
2188
}
2183
 
2189
 
2184
int two_contops
2190
int two_contops
2185
    PROTO_N ( (fe, te) )
-
 
2186
    PROTO_T ( exp fe X exp te )
2191
(exp fe, exp te)
2187
{
2192
{
2188
  int   nr = count_regs ((~regsinuse) & 0x3e);
2193
  int   nr = count_regs((~regsinuse) & 0x3e);
2189
  if (nr >= 2)
2194
  if (nr >= 2)
2190
    return (1);
2195
    return(1);
2191
  if (nr == 1)
2196
  if (nr == 1)
2192
    return (all_in_regs (fe) || all_in_regs (te));
2197
    return(all_in_regs(fe) || all_in_regs(te));
2193
  return (all_in_regs (fe) && all_in_regs (te));
2198
  return(all_in_regs(fe) && all_in_regs(te));
2194
}
2199
}
2195
 
2200
 
2196
 
2201
 
2197
/* move value of shape sha from "from" to "to" */
2202
/* move value of shape sha from "from" to "to" */
2198
void move
2203
void move
2199
    PROTO_N ( (sha, from, to) )
-
 
2200
    PROTO_T ( shape sha X where from X where to )
2204
(shape sha, where from, where to)
2201
{
2205
{
2202
  int  sz;
2206
  int  sz;
2203
  int  c, c1;
2207
  int  c, c1;
2204
  int isco = 0;
2208
  int isco = 0;
2205
  exp fe = from.where_exp;
2209
  exp fe = from.where_exp;
2206
  exp te = to.where_exp;
2210
  exp te = to.where_exp;
2207
  exp holdfe = son(fe);
2211
  exp holdfe = son(fe);
2208
  exp holdte = son(te);
2212
  exp holdte = son(te);
2209
  where reg_w;
2213
  where reg_w;
2210
  sz = rounder (shape_size(sha), 8);
2214
  sz = rounder(shape_size(sha), 8);
2211
 
-
 
2212
 
2215
 
2213
 
2216
 
-
 
2217
 
2214
  if (sz == 0 || eq_where (from, to))
2218
  if (sz == 0 || eq_where(from, to))
2215
    return;
2219
    return;
2216
 
2220
 
2217
  /* move does not set conditions. Only clear if to spoils cond record */
2221
  /* move does not set conditions. Only clear if to spoils cond record */
2218
 
2222
 
2219
  if ((cond1_set && (eq_where (to, cond1) ||
2223
  if ((cond1_set && (eq_where(to, cond1) ||
2220
	  invalidates (to.where_exp, cond1.where_exp))) ||
2224
	  invalidates(to.where_exp, cond1.where_exp))) ||
2221
      (cond2_set &&
2225
     (cond2_set &&
2222
	(eq_where (to, cond2a) || eq_where (to, cond2b) ||
2226
	(eq_where(to, cond2a) || eq_where(to, cond2b) ||
2223
	  invalidates (to.where_exp, cond2a.where_exp) ||
2227
	  invalidates(to.where_exp, cond2a.where_exp) ||
2224
	  invalidates (to.where_exp, cond2b.where_exp)))) {
2228
	  invalidates(to.where_exp, cond2b.where_exp)))) {
2225
    cond1_set = 0;
2229
    cond1_set = 0;
2226
    cond2_set = 0;
2230
    cond2_set = 0;
2227
  };
2231
  };
2228
 
2232
 
2229
  if (name(fe) == reff_tag ||
2233
  if (name(fe) == reff_tag ||
2230
	(PIC_code && name(fe) == name_tag &&
2234
	(PIC_code && name(fe) == name_tag &&
2231
	  isglob(son (fe)) &&
2235
	  isglob(son(fe)) &&
2232
	  (name (sha) == offsethd) &&
2236
	 (name(sha) == offsethd) &&
2233
	  !brog(son(fe)) ->  dec_u.dec_val.extnamed))
2237
	  !brog(son(fe)) ->  dec_u.dec_val.extnamed))
2234
    {
2238
    {
2235
      mova(from, to);
2239
      mova(from, to);
2236
      return;
2240
      return;
2237
    };
2241
    };
2238
 
2242
 
2239
  if (name (sha) >= shrealhd && name (sha) <= doublehd) {
2243
  if (name(sha) >= shrealhd && name(sha) <= doublehd) {
2240
    /* moving a float or double */
2244
    /* moving a float or double */
2241
    int  f1 = in_fl_reg (from.where_exp);
2245
    int  f1 = in_fl_reg(from.where_exp);
2242
    int  f2 = in_fl_reg (to.where_exp);
2246
    int  f2 = in_fl_reg(to.where_exp);
2243
    int  f1pos = (f1) ? get_reg_no (f1) : 0;
2247
    int  f1pos = (f1)? get_reg_no(f1): 0;
2244
    int  f2pos = (f2) ? get_reg_no (f2) : 0;
2248
    int  f2pos = (f2)? get_reg_no(f2): 0;
2245
    if (f1pos && f1pos == f2pos && f2 != 0x10000)
2249
    if (f1pos && f1pos == f2pos && f2 != 0x10000)
2246
      return;			/* from and to are the same */
2250
      return;			/* from and to are the same */
2247
    if (f1pos && f1pos > f2pos && f2 != 0x10000) {
2251
    if (f1pos && f1pos > f2pos && f2 != 0x10000) {
2248
      if (f1pos == fstack_pos &&
2252
      if (f1pos == fstack_pos &&
2249
	  from.where_exp != flstack.where_exp &&
2253
	  from.where_exp != flstack.where_exp &&
2250
	/*  name (sha) != doublehd && */
2254
	/*  name (sha) != doublehd && */
2251
	  use_pop_ass (to.where_exp, from.where_exp) != 2) {
2255
	  use_pop_ass(to.where_exp, from.where_exp)!= 2) {
2252
	if (flinmem (to)) {	/* are going to pop the floating point
2256
	if (flinmem (to)) {	/* are going to pop the floating point
2253
				   stack */
2257
				   stack */
2254
	  contop (te, 0, reg0);	/* compute address of to if necessary */
2258
	  contop (te, 0, reg0);	/* compute address of to if necessary */
2255
	  if (name (sha) == shrealhd)
2259
	  if (name(sha) == shrealhd)
2256
	    ins1 (fsts, 32, to);
2260
	    ins1(fsts, 32, to);
2257
	  else
2261
	  else
2258
	  if (name (sha) == realhd)
2262
	  if (name(sha) == realhd)
2259
	    ins1 (fstl, 64, to);
2263
	    ins1(fstl, 64, to);
2260
	  else {
2264
	  else {
2261
	    ins1 (fstpt, 96, to);
2265
	    ins1(fstpt, 96, to);
2262
	    ins1 (fldt, 96, to);
2266
	    ins1(fldt, 96, to);
2263
	  };
2267
	  };
2264
	  end_contop ();
2268
	  end_contop();
2265
	  son(fe) = holdfe;
2269
	  son(fe) = holdfe;
2266
	  son(te) = holdte;
2270
	  son(te) = holdte;
2267
	  return;
2271
	  return;
2268
	};
2272
	};
2269
	ins1 (fst, 0, to);	/* store fstack0 into to (a reg) */
2273
	ins1 (fst, 0, to);	/* store fstack0 into to (a reg) */
2270
	son(fe) = holdfe;
2274
	son(fe) = holdfe;
2271
	son(te) = holdte;
2275
	son(te) = holdte;
2272
	return;
2276
	return;
2273
      };
2277
      };
2274
      if (f1pos != fstack_pos)
2278
      if (f1pos != fstack_pos)
2275
	move (sha, from, flstack);
2279
	move(sha, from, flstack);
2276
      /* push from into floating point stack */
2280
      /* push from into floating point stack */
2277
      if (flinmem (to)) {	/* store from fstack0 into memory and pop
2281
      if (flinmem (to)) {	/* store from fstack0 into memory and pop
2278
				*/
2282
				*/
2279
	contop (te, 0, reg0);
2283
	contop(te, 0, reg0);
2280
	if (name (sha) == shrealhd)
2284
	if (name(sha) == shrealhd)
2281
	  ins1 (fstps, 32, to);
2285
	  ins1(fstps, 32, to);
2282
	else
2286
	else
2283
	if (name (sha) == realhd)
2287
	if (name(sha) == realhd)
2284
	  ins1 (fstpl, 64, to);
2288
	  ins1(fstpl, 64, to);
2285
	else
2289
	else
2286
	  ins1 (fstpt, 96, to);
2290
	  ins1(fstpt, 96, to);
2287
	pop_fl;
2291
	pop_fl;
2288
	end_contop ();
2292
	end_contop();
2289
	son(fe) = holdfe;
2293
	son(fe) = holdfe;
2290
	son(te) = holdte;
2294
	son(te) = holdte;
2291
	return;
2295
	return;
2292
      };
2296
      };
2293
      ins1 (fstp, 0, to);	/* pop from fstack0 into floating point
2297
      ins1 (fstp, 0, to);	/* pop from fstack0 into floating point
2294
				   register */
2298
				   register */
2295
      pop_fl;
2299
      pop_fl;
2296
      son(fe) = holdfe;
2300
      son(fe) = holdfe;
2297
      son(te) = holdte;
2301
      son(te) = holdte;
2298
      return;
2302
      return;
2299
    };
2303
    };
2300
    if (in_fl_reg (to.where_exp)) {
2304
    if (in_fl_reg(to.where_exp)) {
2301
      int fz;
2305
      int fz;
2302
      if (name (from.where_exp) == real_tag &&
2306
      if (name(from.where_exp) == real_tag &&
2303
	  ((fz = cmpflpt (no (from.where_exp),
2307
	 ((fz = cmpflpt(no(from.where_exp),
2304
                           no (fzeroe), 5), fz) ||
2308
                           no(fzeroe), 5), fz) ||
2305
	    cmpflpt (no (from.where_exp), no (fonee), 5))) {
2309
	    cmpflpt(no(from.where_exp), no(fonee), 5))) {
2306
	if (fz)
2310
	if (fz)
2307
	  ins0 (fldz);		/* push zero into fstack0 */
2311
	  ins0 (fldz);		/* push zero into fstack0 */
2308
	else
2312
	else
2309
	  ins0 (fld1);		/* push one into fstack0 */
2313
	  ins0 (fld1);		/* push one into fstack0 */
2310
      }
2314
      }
2311
      else {
2315
      else {
2312
	if (flinmem (from)) {	/* push from into fstack0 from memory */
2316
	if (flinmem (from)) {	/* push from into fstack0 from memory */
2313
	  contop (fe, 0, reg0);	/* put address of from into reg0 if
2317
	  contop (fe, 0, reg0);	/* put address of from into reg0 if
2314
				   necessary */
2318
				   necessary */
2315
	  if (name (sha) == shrealhd)
2319
	  if (name(sha) == shrealhd)
2316
	    ins1 (flds, 32, from);
2320
	    ins1(flds, 32, from);
2317
	  else
-
 
2318
	  if (name (sha) == realhd)
-
 
2319
	    ins1 (fldl, 64, from);
-
 
2320
	  else
2321
	  else
-
 
2322
	  if (name(sha) == realhd)
-
 
2323
	    ins1(fldl, 64, from);
-
 
2324
	  else
2321
	    ins1 (fldt, 96, from);
2325
	    ins1(fldt, 96, from);
2322
	  end_contop ();
2326
	  end_contop();
2323
	}
2327
	}
2324
	else {
2328
	else {
2325
	  if (f1pos == fstack_pos) {/* push fstack0 */
2329
	  if (f1pos == fstack_pos) {/* push fstack0 */
2326
	    load_stack0 ();
2330
	    load_stack0();
2327
	  }
2331
	  }
2328
	  else
2332
	  else
2329
	    ins1 (fld, 0, from);/* push floating point register */
2333
	    ins1 (fld, 0, from);/* push floating point register */
2330
	};
2334
	};
2331
      };
2335
      };
2332
      push_fl;			/* we necessarily did a push */
2336
      push_fl;			/* we necessarily did a push */
2333
      if (flinmem (to)) {	/* pop fstack0 to to (in memory ) */
2337
      if (flinmem (to)) {	/* pop fstack0 to to (in memory ) */
2334
	contop (te, 0, reg0);
2338
	contop(te, 0, reg0);
2335
	if (name (sha) == shrealhd)
2339
	if (name(sha) == shrealhd)
2336
	  ins1 (fstps, 32, to);
2340
	  ins1(fstps, 32, to);
2337
	else
2341
	else
2338
	if (name (sha) == realhd)
2342
	if (name(sha) == realhd)
2339
	  ins1 (fstpl, 64, to);
2343
	  ins1(fstpl, 64, to);
2340
	else
2344
	else
2341
	  ins1 (fstpt, 96, to);
2345
	  ins1(fstpt, 96, to);
2342
	pop_fl;
2346
	pop_fl;
2343
	end_contop ();
2347
	end_contop();
2344
	son(fe) = holdfe;
2348
	son(fe) = holdfe;
2345
	son(te) = holdte;
2349
	son(te) = holdte;
2346
	return;
2350
	return;
2347
      };
2351
      };
2348
 
2352
 
2349
      f2 = in_fl_reg (to.where_exp);
2353
      f2 = in_fl_reg(to.where_exp);
2350
      f2pos = get_reg_no (f2);
2354
      f2pos = get_reg_no(f2);
2351
      if (f2pos == fstack_pos) {
2355
      if (f2pos == fstack_pos) {
2352
	son(fe) = holdfe;
2356
	son(fe) = holdfe;
2353
	son(te) = holdte;
2357
	son(te) = holdte;
2354
	return;
2358
	return;
2355
      }
2359
      }
Line 2380... Line 2384...
2380
      son(te) = holdte;
2384
      son(te) = holdte;
2381
      return;
2385
      return;
2382
    };
2386
    };
2383
    /* we are pushing on parameter stack */
2387
    /* we are pushing on parameter stack */
2384
    if (sz == 32) {
2388
    if (sz == 32) {
2385
      reg_w = equiv_reg (from, sz);
2389
      reg_w = equiv_reg(from, sz);
2386
      if (reg_w.where_exp != nilexp) {
2390
      if (reg_w.where_exp != nilexp) {
2387
	ins1(pushl, 32, reg_w);
2391
	ins1(pushl, 32, reg_w);
2388
#ifdef NEWDWARF
2392
#ifdef NEWDWARF
2389
	if (diagnose && dwarf2 && no_frame)
2393
	if (diagnose && dwarf2 && no_frame)
2390
	  dw2_track_push();
2394
	  dw2_track_push();
2391
#endif
2395
#endif
2392
	son(fe) = holdfe;
2396
	son(fe) = holdfe;
2393
	son(te) = holdte;
2397
	son(te) = holdte;
2394
	return;
2398
	return;
2395
      };
2399
      };
2396
    };
2400
    };
2397
    if (sz == 64) {	/* must be s64 or u64 */
2401
    if (sz == 64) {	/* must be s64 or u64 */
2398
      if (name (fe) == val_tag) {	/* moving a constant integer */
2402
      if (name (fe) == val_tag) {	/* moving a constant integer */
2399
	if (!isbigval(fe)) {
2403
	if (!isbigval(fe)) {
2400
	  c = no (fe) + from.where_off;
2404
	  c = no(fe) + from.where_off;
2401
	  c1 = (name(sha) == s64hd && c < 0) ? -1 : 0;
2405
	  c1 = (name(sha) == s64hd && c < 0)? -1 : 0;
2402
	}
2406
	}
2403
	else {
2407
	else {
2404
	  flt64 x;
2408
	  flt64 x;
2405
	  int ov;
2409
	  int ov;
2406
	  x = flt_to_f64(no(fe), is_signed(sh(fe)), &ov);
2410
	  x = flt_to_f64(no(fe), is_signed(sh(fe)), &ov);
2407
	  c = x.small;
2411
	  c = x.small;
2408
	  c1 = x.big;
2412
	  c1 = x.big;
2409
	}
2413
	}
2410
	ins1 (pushl, 32, mw(zeroe, c1));
2414
	ins1(pushl, 32, mw(zeroe, c1));
2411
#ifdef NEWDWARF
2415
#ifdef NEWDWARF
2412
	if (diagnose && dwarf2 && no_frame)
2416
	if (diagnose && dwarf2 && no_frame)
2413
	  dw2_track_push();
2417
	  dw2_track_push();
2414
#endif
2418
#endif
2415
 
2419
 
2416
	ins1 (pushl, 32, mw(zeroe, c));
2420
	ins1(pushl, 32, mw(zeroe, c));
2417
#ifdef NEWDWARF
2421
#ifdef NEWDWARF
2418
	if (diagnose && dwarf2 && no_frame)
2422
	if (diagnose && dwarf2 && no_frame)
2419
	  dw2_track_push();
2423
	  dw2_track_push();
2420
#endif
2424
#endif
2421
 
2425
 
2422
	son(fe) = holdfe;
2426
	son(fe) = holdfe;
2423
	son(te) = holdte;
2427
	son(te) = holdte;
2424
	return;
2428
	return;
2425
      }
2429
      }
2426
      move (sha, from, reg0);
2430
      move(sha, from, reg0);
2427
      ins0 (pushedx);
2431
      ins0(pushedx);
2428
#ifdef NEWDWARF
2432
#ifdef NEWDWARF
2429
      if (diagnose && dwarf2 && no_frame)
2433
      if (diagnose && dwarf2 && no_frame)
2430
	dw2_track_push();
2434
	dw2_track_push();
2431
#endif
2435
#endif
2432
 
2436
 
2433
      ins0 (pusheax);
2437
      ins0(pusheax);
2434
#ifdef NEWDWARF
2438
#ifdef NEWDWARF
2435
      if (diagnose && dwarf2 && no_frame)
2439
      if (diagnose && dwarf2 && no_frame)
2436
	dw2_track_push();
2440
	dw2_track_push();
2437
#endif
2441
#endif
2438
 
2442
 
2439
      son(fe) = holdfe;
2443
      son(fe) = holdfe;
2440
      son(te) = holdte;
2444
      son(te) = holdte;
2441
      return;
2445
      return;
2442
    };
2446
    };
2443
    if (sz < 32 ||
2447
    if (sz < 32 ||
2444
         (is80486 && inmem(from))) {
2448
        (is80486 && inmem(from))) {
2445
      move (sha, from, reg0);
2449
      move(sha, from, reg0);
2446
      ins1 (pushl, 32, reg0);
2450
      ins1(pushl, 32, reg0);
2447
#ifdef NEWDWARF
2451
#ifdef NEWDWARF
2448
      if (diagnose && dwarf2 && no_frame)
2452
      if (diagnose && dwarf2 && no_frame)
2449
	dw2_track_push();
2453
	dw2_track_push();
2450
#endif
2454
#endif
2451
 
2455
 
2452
      son(fe) = holdfe;
2456
      son(fe) = holdfe;
2453
      son(te) = holdte;
2457
      son(te) = holdte;
2454
      return;
2458
      return;
2455
    };
2459
    };
2456
    contop (from.where_exp, 0, reg0);
2460
    contop(from.where_exp, 0, reg0);
2457
    ins1 (pushl, sz, from);
2461
    ins1(pushl, sz, from);
2458
#ifdef NEWDWARF
2462
#ifdef NEWDWARF
2459
    if (diagnose && dwarf2 && no_frame)
2463
    if (diagnose && dwarf2 && no_frame)
2460
      dw2_track_push();
2464
      dw2_track_push();
2461
#endif
2465
#endif
2462
 
2466
 
2463
    end_contop ();
2467
    end_contop();
2464
    son(fe) = holdfe;
2468
    son(fe) = holdfe;
2465
    son(te) = holdte;
2469
    son(te) = holdte;
2466
    return;
2470
    return;
2467
  };
2471
  };
2468
 
2472
 
2469
 
2473
 
2470
  if (inmem (from) && inmem (to) && ((sz <= 32 && sz != 24)
2474
  if (inmem(from) && inmem(to) && ((sz <= 32 && sz != 24)
2471
				|| name(sha) == u64hd || name(sha) == s64hd)) {
2475
				|| name(sha) == u64hd || name(sha) == s64hd)) {
2472
    /* from and to are both in memory */
2476
    /* from and to are both in memory */
2473
    move (sha, from, reg0);
2477
    move(sha, from, reg0);
2474
    move (sha, reg0, to);
2478
    move(sha, reg0, to);
2475
    son(fe) = holdfe;
2479
    son(fe) = holdfe;
2476
    son(te) = holdte;
2480
    son(te) = holdte;
2477
    return;
2481
    return;
2478
  };
2482
  };
2479
 
2483
 
Line 2492... Line 2496...
2492
  };
2496
  };
2493
 
2497
 
2494
  if (name (fe) == val_tag) {	/* moving a constant integer */
2498
  if (name (fe) == val_tag) {	/* moving a constant integer */
2495
    isco = 1;
2499
    isco = 1;
2496
    if (!isbigval(fe)) {
2500
    if (!isbigval(fe)) {
2497
      c = no (fe) + from.where_off;
2501
      c = no(fe) + from.where_off;
2498
      if (sz == 64)
2502
      if (sz == 64)
2499
	c1 = (name(sha) == s64hd && c < 0) ? -1 : 0;
2503
	c1 = (name(sha) == s64hd && c < 0)? -1 : 0;
2500
    }
2504
    }
2501
    else {
2505
    else {
2502
      flt64 x;
2506
      flt64 x;
2503
      int ov;
2507
      int ov;
2504
      x = flt_to_f64(no(fe), is_signed(sh(fe)), &ov);
2508
      x = flt_to_f64(no(fe), is_signed(sh(fe)), &ov);
Line 2512... Line 2516...
2512
  };
2516
  };
2513
 
2517
 
2514
 
2518
 
2515
  if (isco) {			/* moving a constant */
2519
  if (isco) {			/* moving a constant */
2516
 
2520
 
2517
    contop (te, 0, to);
2521
    contop(te, 0, to);
2518
    SET(c);
2522
    SET(c);
2519
 
2523
 
2520
    if (c == 0 && !inmem (to) && sz <= 32) {/* constant is zero, so clear */
2524
    if (c == 0 && !inmem (to) && sz <= 32) {/* constant is zero, so clear */
2521
      cond1_set = 0;
2525
      cond1_set = 0;
2522
      cond2_set = 0;
2526
      cond2_set = 0;
2523
      ins2 (xorl, 32, 32, to, to);
2527
      ins2(xorl, 32, 32, to, to);
2524
      invalidate_dest (to);
2528
      invalidate_dest(to);
2525
      end_contop ();
2529
      end_contop();
2526
      son(fe) = holdfe;
2530
      son(fe) = holdfe;
2527
      son(te) = holdte;
2531
      son(te) = holdte;
2528
      return;
2532
      return;
2529
    };
2533
    };
2530
 
2534
 
2531
    /* use fastest operation for each size of constant */
2535
    /* use fastest operation for each size of constant */
2532
 
2536
 
2533
    if (sz == 8 && !eq_where (to, reg5) && !eq_where (to, reg4)) {
2537
    if (sz == 8 && !eq_where(to, reg5) && !eq_where(to, reg4)) {
2534
      ins2 (movb, sz, sz, mw (zeroe, (c & 0xff)), to);
2538
      ins2(movb, sz, sz, mw(zeroe,(c & 0xff)), to);
2535
      invalidate_dest (to);
2539
      invalidate_dest(to);
2536
      end_contop ();
2540
      end_contop();
2537
      son(fe) = holdfe;
2541
      son(fe) = holdfe;
2538
      son(te) = holdte;
2542
      son(te) = holdte;
2539
      return;
2543
      return;
2540
    };
2544
    };
2541
 
2545
 
2542
    if (sz == 16) {
2546
    if (sz == 16) {
2543
      ins2 (movw, sz, sz, mw (zeroe, (c & 0xffff)), to);
2547
      ins2(movw, sz, sz, mw(zeroe,(c & 0xffff)), to);
2544
      invalidate_dest (to);
2548
      invalidate_dest(to);
2545
      end_contop ();
2549
      end_contop();
2546
      son(fe) = holdfe;
2550
      son(fe) = holdfe;
2547
      son(te) = holdte;
2551
      son(te) = holdte;
2548
      return;
2552
      return;
2549
    };
2553
    };
2550
 
2554
 
2551
    if (sz == 64) {
2555
    if (sz == 64) {
2552
      if (eq_where (to, reg0)) {
2556
      if (eq_where(to, reg0)) {
2553
	if (c == 0)
2557
	if (c == 0)
2554
	  ins2 (xorl, 32, 32, reg0, reg0);
2558
	  ins2(xorl, 32, 32, reg0, reg0);
2555
	else
2559
	else
2556
	  ins2 (movl, 32, 32, mw (zeroe, c), reg0);
2560
	  ins2(movl, 32, 32, mw(zeroe, c), reg0);
2557
	if (c1 == 0)
2561
	if (c1 == 0)
2558
	  ins2 (xorl, 32, 32, reg1, reg1);
2562
	  ins2(xorl, 32, 32, reg1, reg1);
2559
	else
2563
	else
2560
	  ins2 (movl, 32, 32, mw (zeroe, c1), reg1);
2564
	  ins2(movl, 32, 32, mw(zeroe, c1), reg1);
2561
	invalidate_dest (reg0);
2565
	invalidate_dest(reg0);
2562
	invalidate_dest (reg1);
2566
	invalidate_dest(reg1);
2563
      }
2567
      }
2564
      else {
2568
      else {
2565
        ins2 (movl, 32, 32, mw (zeroe, c), to);
2569
        ins2(movl, 32, 32, mw(zeroe, c), to);
2566
        ins2 (movl, 32, 32, mw (zeroe, c1), mw (te, to.where_off + 32));
2570
        ins2(movl, 32, 32, mw(zeroe, c1), mw(te, to.where_off + 32));
2567
	invalidate_dest (to);
2571
	invalidate_dest(to);
2568
      }
2572
      }
2569
      end_contop ();
2573
      end_contop();
2570
      son(fe) = holdfe;
2574
      son(fe) = holdfe;
2571
      son(te) = holdte;
2575
      son(te) = holdte;
2572
      return;
2576
      return;
2573
    }
2577
    }
2574
 
2578
 
2575
    if (inmem(to) && (c == 0 &&
2579
    if (inmem(to) && (c == 0 &&
2576
	 ((name(te) == ass_tag && name(son(te)) == name_tag &&
2580
	((name(te) == ass_tag && name(son(te)) == name_tag &&
2577
		isvar(son(son(te)))) ||
2581
		isvar(son(son(te)))) ||
2578
		(name(te) == ident_tag)))) {
2582
		(name(te) == ident_tag)))) {
2579
      reg_w = equiv_reg (from, sz);
2583
      reg_w = equiv_reg(from, sz);
2580
      if (reg_w.where_exp != nilexp)
2584
      if (reg_w.where_exp != nilexp)
2581
	move (sha, reg_w, to);
2585
	move(sha, reg_w, to);
2582
      else {
2586
      else {
2583
        move(slongsh, from, reg0);
2587
        move(slongsh, from, reg0);
2584
        move(slongsh, reg0, to);
2588
        move(slongsh, reg0, to);
2585
        move_reg(from, reg0, sha);
2589
        move_reg(from, reg0, sha);
2586
      };
2590
      };
2587
    }
2591
    }
2588
    else {
2592
    else {
2589
      ins2 (movl, 32, 32, from, to);
2593
      ins2(movl, 32, 32, from, to);
2590
    }
2594
    }
2591
 
2595
 
2592
    invalidate_dest (to);
2596
    invalidate_dest(to);
2593
    end_contop ();
2597
    end_contop();
2594
    son(fe) = holdfe;
2598
    son(fe) = holdfe;
2595
    son(te) = holdte;
2599
    son(te) = holdte;
2596
    return;
2600
    return;
2597
  };
2601
  };
2598
 
2602
 
2599
  /* moving a non-constant value */
2603
  /* moving a non-constant value */
2600
 
2604
 
2601
 
2605
 
2602
 
2606
 
2603
  if (sz == 8) {		/* moving a byte */
2607
  if (sz == 8) {		/* moving a byte */
2604
    if (!inmem (from) &&
2608
    if (!inmem(from) &&
2605
	(in_reg (from.where_exp) & 0x70)) {
2609
	(in_reg(from.where_exp) & 0x70)) {
2606
      if (!inmem (to)) {
2610
      if (!inmem(to)) {
-
 
2611
	move(slongsh, from, to);
-
 
2612
	son(fe) = holdfe;
-
 
2613
	son(te) = holdte;
-
 
2614
	return;
-
 
2615
      };
-
 
2616
      move(slongsh, from, reg0);
-
 
2617
      move(sha, reg0, to);
-
 
2618
      son(fe) = holdfe;
-
 
2619
      son(te) = holdte;
-
 
2620
      return;
-
 
2621
    };
-
 
2622
 
-
 
2623
    if (!inmem(to) && name(to.where_exp)!= val_tag &&
-
 
2624
	(in_reg(to.where_exp) & 0x70)) {
-
 
2625
      if (!inmem(from)) {
2607
	move (slongsh, from, to);
2626
	move(slongsh, from, to);
2608
	son(fe) = holdfe;
2627
	son(fe) = holdfe;
2609
	son(te) = holdte;
2628
	son(te) = holdte;
2610
	return;
2629
	return;
2611
      };
2630
      };
2612
      move (slongsh, from, reg0);
2631
      move(sha, from, reg0);
2613
      move (sha, reg0, to);
2632
      move(slongsh, reg0, to);
2614
      son(fe) = holdfe;
2633
      son(fe) = holdfe;
2615
      son(te) = holdte;
2634
      son(te) = holdte;
2616
      return;
2635
      return;
2617
    };
2636
    };
2618
 
-
 
2619
    if (!inmem (to) && name (to.where_exp) != val_tag &&
-
 
2620
	(in_reg (to.where_exp) & 0x70)) {
-
 
2621
      if (!inmem (from)) {
-
 
2622
	move (slongsh, from, to);
-
 
2623
	son(fe) = holdfe;
-
 
2624
	son(te) = holdte;
-
 
2625
	return;
-
 
2626
      };
-
 
2627
      move (sha, from, reg0);
-
 
2628
      move (slongsh, reg0, to);
-
 
2629
      son(fe) = holdfe;
-
 
2630
      son(te) = holdte;
-
 
2631
      return;
-
 
2632
    };
-
 
2633
 
2637
 
2634
    if (in_reg (from.where_exp)) {
2638
    if (in_reg(from.where_exp)) {
2635
      contop (te, eq_where (reg0, from), to);
2639
      contop(te, eq_where(reg0, from), to);
2636
      ins2 (movb, sz, sz, from, to);
2640
      ins2(movb, sz, sz, from, to);
2637
      invalidate_dest (to);
-
 
2638
      move_reg (from, to, sha);
-
 
2639
      end_contop ();
-
 
2640
    }
-
 
2641
    else {
-
 
2642
      reg_w = equiv_reg (from, sz);
-
 
2643
      if (reg_w.where_exp != nilexp) {
-
 
2644
	move (sha, reg_w, to);
-
 
2645
	move_reg (from, to, sha);
-
 
2646
      }
-
 
2647
      else {
-
 
2648
	contop (fe, 0, to);
-
 
2649
	ins2 (movb, sz, sz, from, to);
-
 
2650
	invalidate_dest (to);
-
 
2651
	move_reg (from, to, sha);
-
 
2652
	end_contop ();
-
 
2653
      };
-
 
2654
    };
-
 
2655
    son(fe) = holdfe;
-
 
2656
    son(te) = holdte;
-
 
2657
    return;
-
 
2658
  };
-
 
2659
  if (sz == 16) {		/* moving 16 bits */
-
 
2660
    if (in_reg (from.where_exp)) {
-
 
2661
      contop (te, eq_where (reg0, from), to);
-
 
2662
      ins2 (movw, sz, sz, from, to);
-
 
2663
      invalidate_dest (to);
2641
      invalidate_dest(to);
2664
      move_reg (from, to, sha);
2642
      move_reg(from, to, sha);
2665
      end_contop ();
2643
      end_contop();
2666
    }
2644
    }
2667
    else {
2645
    else {
2668
      reg_w = equiv_reg (from, sz);
2646
      reg_w = equiv_reg(from, sz);
2669
      if (reg_w.where_exp != nilexp) {
2647
      if (reg_w.where_exp != nilexp) {
2670
	move (sha, reg_w, to);
2648
	move(sha, reg_w, to);
2671
	move_reg (from, to, sha);
2649
	move_reg(from, to, sha);
2672
      }
2650
      }
2673
      else {
2651
      else {
2674
	contop (fe, 0, to);
2652
	contop(fe, 0, to);
-
 
2653
	ins2(movb, sz, sz, from, to);
-
 
2654
	invalidate_dest(to);
-
 
2655
	move_reg(from, to, sha);
-
 
2656
	end_contop();
-
 
2657
      };
-
 
2658
    };
-
 
2659
    son(fe) = holdfe;
-
 
2660
    son(te) = holdte;
-
 
2661
    return;
-
 
2662
  };
-
 
2663
  if (sz == 16) {		/* moving 16 bits */
-
 
2664
    if (in_reg(from.where_exp)) {
-
 
2665
      contop(te, eq_where(reg0, from), to);
-
 
2666
      ins2(movw, sz, sz, from, to);
-
 
2667
      invalidate_dest(to);
-
 
2668
      move_reg(from, to, sha);
-
 
2669
      end_contop();
-
 
2670
    }
-
 
2671
    else {
-
 
2672
      reg_w = equiv_reg(from, sz);
-
 
2673
      if (reg_w.where_exp != nilexp) {
-
 
2674
	move(sha, reg_w, to);
-
 
2675
	move_reg(from, to, sha);
-
 
2676
      }
-
 
2677
      else {
-
 
2678
	contop(fe, 0, to);
2675
	ins2 (movw, sz, sz, from, to);
2679
	ins2(movw, sz, sz, from, to);
2676
	invalidate_dest (to);
2680
	invalidate_dest(to);
2677
	move_reg (from, to, sha);
2681
	move_reg(from, to, sha);
2678
	end_contop ();
2682
	end_contop();
2679
      };
2683
      };
2680
    };
2684
    };
2681
    son(fe) = holdfe;
2685
    son(fe) = holdfe;
2682
    son(te) = holdte;
2686
    son(te) = holdte;
2683
    return;
2687
    return;
2684
  };
2688
  };
2685
  if (sz == 32) {		/* moving 32 bits */
2689
  if (sz == 32) {		/* moving 32 bits */
2686
 
2690
 
2687
    if (in_reg (from.where_exp)) {
2691
    if (in_reg(from.where_exp)) {
2688
      contop (te, eq_where (reg0, from), to);
2692
      contop(te, eq_where(reg0, from), to);
2689
      ins2 (movl, sz, sz, from, to);
2693
      ins2(movl, sz, sz, from, to);
2690
      invalidate_dest (to);
2694
      invalidate_dest(to);
2691
      move_reg (from, to, sha);
2695
      move_reg(from, to, sha);
2692
      end_contop ();
2696
      end_contop();
2693
    }
2697
    }
2694
    else {
2698
    else {
2695
      reg_w = equiv_reg (from, sz);
2699
      reg_w = equiv_reg(from, sz);
2696
      if (reg_w.where_exp != nilexp) {
2700
      if (reg_w.where_exp != nilexp) {
2697
	move (sha, reg_w, to);
2701
	move(sha, reg_w, to);
2698
	move_reg (from, to, sha);
2702
	move_reg(from, to, sha);
2699
      }
2703
      }
2700
      else {
2704
      else {
2701
	contop (fe, 0, to);
2705
	contop(fe, 0, to);
2702
	ins2 (movl, sz, sz, from, to);
2706
	ins2(movl, sz, sz, from, to);
2703
	invalidate_dest (to);
2707
	invalidate_dest(to);
2704
	move_reg (from, to, sha);
2708
	move_reg(from, to, sha);
2705
	end_contop ();
2709
	end_contop();
2706
      };
2710
      };
2707
    };
2711
    };
2708
    son(fe) = holdfe;
2712
    son(fe) = holdfe;
2709
    son(te) = holdte;
2713
    son(te) = holdte;
2710
    return;
2714
    return;
2711
  };
2715
  };
2712
 
2716
 
2713
  if (sz == 64 && (eq_where (to, reg0) || eq_where (from, reg0))) {
2717
  if (sz == 64 && (eq_where(to, reg0) || eq_where(from, reg0))) {
2714
				/* moving reg0 & reg1 to or from memory */
2718
				/* moving reg0 & reg1 to or from memory */
2715
    where w1;
2719
    where w1;
2716
    int riu = regsinuse;
2720
    int riu = regsinuse;
2717
    if (!eq_where (from, reg0)) {
2721
    if (!eq_where(from, reg0)) {
2718
      regsinuse |= 0x2;
2722
      regsinuse |= 0x2;
2719
      contop (fe, 0, reg0);
2723
      contop(fe, 0, reg0);
2720
      w1 = mw (fe, from.where_off + 32);
2724
      w1 = mw(fe, from.where_off + 32);
2721
      ins2 (movl, sz, sz, w1, reg1);
2725
      ins2(movl, sz, sz, w1, reg1);
2722
      ins2 (movl, sz, sz, from, reg0);
2726
      ins2(movl, sz, sz, from, reg0);
2723
      invalidate_dest (reg0);
2727
      invalidate_dest(reg0);
2724
      invalidate_dest (reg1);
2728
      invalidate_dest(reg1);
2725
      end_contop ();
2729
      end_contop();
2726
    }
2730
    }
2727
    else
2731
    else
2728
    if (!eq_where (to, reg0)) {
2732
    if (!eq_where(to, reg0)) {
2729
      regsinuse |= 0x2;
2733
      regsinuse |= 0x2;
2730
      contop (te, 1, to);
2734
      contop(te, 1, to);
2731
      w1 = mw (te, to.where_off + 32);
2735
      w1 = mw(te, to.where_off + 32);
2732
      ins2 (movl, sz, sz, reg0, to);
2736
      ins2(movl, sz, sz, reg0, to);
2733
      ins2 (movl, sz, sz, reg1, w1);
2737
      ins2(movl, sz, sz, reg1, w1);
2734
      invalidate_dest (to);
2738
      invalidate_dest(to);
2735
      end_contop ();
2739
      end_contop();
2736
    };
2740
    };
2737
    regsinuse = riu;
2741
    regsinuse = riu;
2738
    son(fe) = holdfe;
2742
    son(fe) = holdfe;
2739
    son(te) = holdte;
2743
    son(te) = holdte;
2740
    return;
2744
    return;
2741
  }
2745
  }
2742
 
2746
 
2743
  if (name(sha) == realhd && might_overlap(sha, from, to)) {
2747
  if (name(sha) == realhd && might_overlap(sha, from, to)) {
2744
     if ((regsinuse & 0x7e) != 0x7e) {
2748
     if ((regsinuse & 0x7e)!= 0x7e) {
2745
        int  foff = from.where_off;
2749
        int  foff = from.where_off;
2746
        int  toff = to.where_off;
2750
        int  toff = to.where_off;
2747
        int  old_regsinuse = regsinuse;
2751
        int  old_regsinuse = regsinuse;
2748
        where extra_reg;
2752
        where extra_reg;
2749
 
2753
 
2750
        contop (fe, 1, to);
2754
        contop(fe, 1, to);
2751
        regsinuse = top_regsinuse;
2755
        regsinuse = top_regsinuse;
2752
        contop_level++;
2756
        contop_level++;
2753
        reg0_in_use = 1;
2757
        reg0_in_use = 1;
2754
        contop (te, 1, to);
2758
        contop(te, 1, to);
2755
        regsinuse = old_regsinuse;
2759
        regsinuse = old_regsinuse;
2756
 
2760
 
2757
        if ((regsinuse & 0x2) == 0)
2761
        if ((regsinuse & 0x2) == 0)
2758
	  extra_reg = reg1;
2762
	  extra_reg = reg1;
2759
	else
2763
	else
Line 2780... Line 2784...
2780
	  min_rfree |= 0x40;
2784
	  min_rfree |= 0x40;
2781
        }
2785
        }
2782
	else {
2786
	else {
2783
	  SET(extra_reg);
2787
	  SET(extra_reg);
2784
	};
2788
	};
2785
        ins2 (movl, size32, size32, mw (fe, foff), reg0);
2789
        ins2(movl, size32, size32, mw(fe, foff), reg0);
2786
        ins2 (movl, size32, size32, mw (fe, foff + 32), extra_reg);
2790
        ins2(movl, size32, size32, mw(fe, foff + 32), extra_reg);
2787
        ins2 (movl, size32, size32, reg0, mw (te, toff));
2791
        ins2(movl, size32, size32, reg0, mw(te, toff));
2788
        ins2 (movl, size32, size32, extra_reg, mw (te, toff + 32));
2792
        ins2(movl, size32, size32, extra_reg, mw(te, toff + 32));
2789
	invalidate_dest(reg0);
2793
	invalidate_dest(reg0);
2790
	invalidate_dest(extra_reg);
2794
	invalidate_dest(extra_reg);
2791
	invalidate_dest(to);
2795
	invalidate_dest(to);
2792
        end_contop ();
2796
        end_contop();
2793
        contop_level--;
2797
        contop_level--;
2794
        end_contop ();
2798
        end_contop();
2795
	son(fe) = holdfe;
2799
	son(fe) = holdfe;
2796
	son(te) = holdte;
2800
	son(te) = holdte;
2797
	return;
2801
	return;
2798
      };
2802
      };
2799
    move(sha, from, flstack);
2803
    move(sha, from, flstack);
Line 2801... Line 2805...
2801
    son(fe) = holdfe;
2805
    son(fe) = holdfe;
2802
    son(te) = holdte;
2806
    son(te) = holdte;
2803
    return;
2807
    return;
2804
  };
2808
  };
2805
 
2809
 
2806
  if (sz <= (40 * 8) && two_contops (fe, te)) {
2810
  if (sz <= (40 * 8) && two_contops(fe, te)) {
2807
    int  i;
2811
    int  i;
2808
    int  foff = from.where_off;
2812
    int  foff = from.where_off;
2809
    int  toff = to.where_off;
2813
    int  toff = to.where_off;
2810
    int  old_regsinuse = regsinuse;
2814
    int  old_regsinuse = regsinuse;
2811
 
2815
 
2812
 
2816
 
2813
    contop (fe, 1, to);
2817
    contop(fe, 1, to);
2814
    regsinuse = top_regsinuse;
2818
    regsinuse = top_regsinuse;
2815
    contop_level++;
2819
    contop_level++;
2816
    reg0_in_use = 1;
2820
    reg0_in_use = 1;
2817
    contop (te, 1, to);
2821
    contop(te, 1, to);
2818
    regsinuse = old_regsinuse;
2822
    regsinuse = old_regsinuse;
2819
 
2823
 
2820
    /* use movl as far as possible */
2824
    /* use movl as far as possible */
2821
    for (i = 0; i <= (sz - 32); i = i + 32) {
2825
    for (i = 0; i <= (sz - 32); i = i + 32) {
2822
      ins2 (movl, size32, size32, mw (fe, foff + i), reg0);
2826
      ins2(movl, size32, size32, mw(fe, foff + i), reg0);
2823
      ins2 (movl, size32, size32, reg0, mw (te, toff + i));
2827
      ins2(movl, size32, size32, reg0, mw(te, toff + i));
2824
      invalidate_dest (mw (te, toff + i));
2828
      invalidate_dest(mw(te, toff + i));
2825
    };
2829
    };
2826
    if (i == sz) {
2830
    if (i == sz) {
2827
      invalidate_dest (reg0);
2831
      invalidate_dest(reg0);
2828
      end_contop ();
2832
      end_contop();
2829
      contop_level--;
2833
      contop_level--;
2830
      end_contop ();
2834
      end_contop();
2831
      son(fe) = holdfe;
2835
      son(fe) = holdfe;
2832
      son(te) = holdte;
2836
      son(te) = holdte;
2833
      return;
2837
      return;
2834
    };
2838
    };
2835
    /* move final word and byte if necessary */
2839
    /* move final word and byte if necessary */
2836
    if ((sz - i) >= 16) {
2840
    if ((sz - i) >= 16) {
2837
      ins2 (movw, size16, size16, mw (fe, foff + i), reg0);
2841
      ins2(movw, size16, size16, mw(fe, foff + i), reg0);
2838
      ins2 (movw, size16, size16, reg0, mw (te, toff + i));
2842
      ins2(movw, size16, size16, reg0, mw(te, toff + i));
2839
      invalidate_dest (mw (te, toff + i));
2843
      invalidate_dest(mw(te, toff + i));
2840
      i += 16;
2844
      i += 16;
2841
    };
2845
    };
2842
    if ((sz - i) >= 8) {
2846
    if ((sz - i) >= 8) {
2843
      ins2 (movb, size8, size8, mw (fe, foff + i), reg0);
2847
      ins2(movb, size8, size8, mw(fe, foff + i), reg0);
2844
      ins2 (movb, size8, size8, reg0, mw (te, toff + i));
2848
      ins2(movb, size8, size8, reg0, mw(te, toff + i));
2845
      invalidate_dest (mw (te, toff + i));
2849
      invalidate_dest(mw(te, toff + i));
2846
    };
2850
    };
2847
    invalidate_dest (reg0);
2851
    invalidate_dest(reg0);
2848
    end_contop ();
2852
    end_contop();
2849
    contop_level--;
2853
    contop_level--;
2850
    end_contop ();
2854
    end_contop();
2851
    son(fe) = holdfe;
2855
    son(fe) = holdfe;
2852
    son(te) = holdte;
2856
    son(te) = holdte;
2853
    return;
2857
    return;
2854
  };
2858
  };
2855
 
2859
 
Line 2862... Line 2866...
2862
  };
2866
  };
2863
 
2867
 
2864
  {				/* use rep movsl to do the move */
2868
  {				/* use rep movsl to do the move */
2865
    int  old_extra_stack = extra_stack;
2869
    int  old_extra_stack = extra_stack;
2866
    int  old_regsinuse;
2870
    int  old_regsinuse;
2867
    if (regsinuse & 0x20) {
2871
    if (regsinuse & 0x20) {
2868
      extra_stack += 32;
2872
      extra_stack += 32;
2869
      ins0 (pushesi);
2873
      ins0(pushesi);
2870
#ifdef NEWDWARF
2874
#ifdef NEWDWARF
2871
      if (diagnose && dwarf2 && no_frame)
2875
      if (diagnose && dwarf2 && no_frame)
2872
	dw2_track_push();
2876
	dw2_track_push();
2873
#endif
2877
#endif
2874
    };
2878
    };
2875
    if (regsinuse & 0x10) {
2879
    if (regsinuse & 0x10) {
2876
      extra_stack += 32;
2880
      extra_stack += 32;
2877
      ins0 (pushedi);
2881
      ins0(pushedi);
2878
#ifdef NEWDWARF
2882
#ifdef NEWDWARF
2879
      if (diagnose && dwarf2 && no_frame)
2883
      if (diagnose && dwarf2 && no_frame)
2880
	dw2_track_push();
2884
	dw2_track_push();
2881
#endif
2885
#endif
2882
    };
2886
    };
2883
    if (regsinuse & 0x4) {
2887
    if (regsinuse & 0x4) {
2884
      extra_stack += 32;
2888
      extra_stack += 32;
2885
      ins0 (pushecx);
2889
      ins0(pushecx);
2886
#ifdef NEWDWARF
2890
#ifdef NEWDWARF
2887
      if (diagnose && dwarf2 && no_frame)
2891
      if (diagnose && dwarf2 && no_frame)
2888
	dw2_track_push();
2892
	dw2_track_push();
2889
#endif
2893
#endif
2890
    };
2894
    };
2891
    old_regsinuse = regsinuse;
2895
    old_regsinuse = regsinuse;
2892
    if (regsinuse & 0x20) {
2896
    if (regsinuse & 0x20) {
2893
      mova (from, pushdest);
2897
      mova(from, pushdest);
2894
      extra_stack += 32;
2898
      extra_stack += 32;
2895
    }
2899
    }
2896
    else {
2900
    else {
2897
      mova (from, reg5);
2901
      mova(from, reg5);
2898
      regsinuse |= 0x20;
2902
      regsinuse |= 0x20;
2899
    };
2903
    };
2900
 
2904
 
2901
    mova (to, reg4);
2905
    mova(to, reg4);
2902
    regsinuse = old_regsinuse;
2906
    regsinuse = old_regsinuse;
2903
 
2907
 
2904
    move (slongsh, mw (zeroe, (sz / 32)), reg2);
2908
    move(slongsh, mw(zeroe,(sz / 32)), reg2);
2905
 
2909
 
2906
    if (regsinuse & 0x20) {
2910
    if (regsinuse & 0x20) {
2907
      ins0 (popesi);
2911
      ins0(popesi);
2908
#ifdef NEWDWARF
2912
#ifdef NEWDWARF
2909
      if (diagnose && dwarf2 && no_frame)
2913
      if (diagnose && dwarf2 && no_frame)
2910
	dw2_track_pop();
2914
	dw2_track_pop();
2911
#endif
2915
#endif
2912
    }
2916
    }
2913
    ins0 (rep);
2917
    ins0(rep);
2914
    ins0 (movsl);
2918
    ins0(movsl);
2915
 
2919
 
2916
    /* and move the last word and byte if necessary */
2920
    /* and move the last word and byte if necessary */
2917
    sz = sz % 32;
2921
    sz = sz % 32;
2918
    if (sz >= 16) {
2922
    if (sz >= 16) {
2919
      ins0 (movsw);
2923
      ins0(movsw);
2920
      sz -= 16;
2924
      sz -= 16;
2921
    };
2925
    };
2922
    if (sz == 8)
2926
    if (sz == 8)
2923
      ins0 (movsb);
2927
      ins0(movsb);
2924
 
2928
 
2925
 
2929
 
2926
    invalidate_dest (reg2);
2930
    invalidate_dest(reg2);
2927
    invalidate_dest (reg4);
2931
    invalidate_dest(reg4);
2928
    invalidate_dest (reg5);
2932
    invalidate_dest(reg5);
2929
    if (regsinuse & 0x4) {
2933
    if (regsinuse & 0x4) {
2930
      ins0 (popecx);
2934
      ins0(popecx);
2931
#ifdef NEWDWARF
2935
#ifdef NEWDWARF
2932
      if (diagnose && dwarf2 && no_frame)
2936
      if (diagnose && dwarf2 && no_frame)
2933
	dw2_track_pop();
2937
	dw2_track_pop();
2934
#endif
2938
#endif
2935
    };
2939
    };
2936
    if (regsinuse & 0x10) {
2940
    if (regsinuse & 0x10) {
2937
      ins0 (popedi);
2941
      ins0(popedi);
2938
#ifdef NEWDWARF
2942
#ifdef NEWDWARF
2939
      if (diagnose && dwarf2 && no_frame)
2943
      if (diagnose && dwarf2 && no_frame)
2940
	dw2_track_pop();
2944
	dw2_track_pop();
2941
#endif
2945
#endif
2942
    };
2946
    };
2943
    if (regsinuse & 0x20) {
2947
    if (regsinuse & 0x20) {
2944
      ins0 (popesi);
2948
      ins0(popesi);
2945
#ifdef NEWDWARF
2949
#ifdef NEWDWARF
2946
      if (diagnose && dwarf2 && no_frame)
2950
      if (diagnose && dwarf2 && no_frame)
2947
	dw2_track_pop();
2951
	dw2_track_pop();
2948
#endif
2952
#endif
2949
    };
2953
    };
2950
    check_stack_max;
2954
    check_stack_max;
2951
    extra_stack = old_extra_stack;
2955
    extra_stack = old_extra_stack;
2952
    min_rfree |= 0x30;
2956
    min_rfree |= 0x30;
2953
    invalidate_dest (to);
2957
    invalidate_dest(to);
2954
    son(fe) = holdfe;
2958
    son(fe) = holdfe;
2955
    son(te) = holdte;
2959
    son(te) = holdte;
2956
    return;
2960
    return;
2957
  };
2961
  };
2958
}
2962
}
2959
 
2963
 
2960
/* use rep movsb */
2964
/* use rep movsb */
2961
void movecont
2965
void movecont
2962
    PROTO_N ( (from, to, length, nooverlap) )
-
 
2963
    PROTO_T ( where from X where to X where length X int nooverlap )
2966
(where from, where to, where length, int nooverlap)
2964
{
2967
{
2965
  if (nooverlap) {
2968
  if (nooverlap) {
2966
    int  old_extra_stack = extra_stack;
2969
    int  old_extra_stack = extra_stack;
2967
    if (regsinuse & 0x20) {
2970
    if (regsinuse & 0x20) {
2968
      extra_stack += 32;
2971
      extra_stack += 32;
2969
      ins0 (pushesi);
2972
      ins0(pushesi);
2970
#ifdef NEWDWARF
2973
#ifdef NEWDWARF
2971
      if (diagnose && dwarf2 && no_frame)
2974
      if (diagnose && dwarf2 && no_frame)
2972
	dw2_track_push();
2975
	dw2_track_push();
2973
#endif
2976
#endif
2974
    }
2977
    }
2975
    if (regsinuse & 0x10) {
2978
    if (regsinuse & 0x10) {
2976
      extra_stack += 32;
2979
      extra_stack += 32;
2977
      ins0 (pushedi);
2980
      ins0(pushedi);
2978
#ifdef NEWDWARF
2981
#ifdef NEWDWARF
2979
      if (diagnose && dwarf2 && no_frame)
2982
      if (diagnose && dwarf2 && no_frame)
2980
	dw2_track_push();
2983
	dw2_track_push();
2981
#endif
2984
#endif
2982
    }
2985
    }
2983
    ins0 (pushecx);
2986
    ins0(pushecx);
2984
#ifdef NEWDWARF
2987
#ifdef NEWDWARF
2985
    if (diagnose && dwarf2 && no_frame)
2988
    if (diagnose && dwarf2 && no_frame)
2986
      dw2_track_push();
2989
      dw2_track_push();
2987
#endif
2990
#endif
2988
    extra_stack += 32;
2991
    extra_stack += 32;
2989
    move (sh(from.where_exp), from, pushdest);
2992
    move(sh(from.where_exp), from, pushdest);
2990
    extra_stack += 32;
-
 
2991
    move (sh(to.where_exp), to, pushdest);
-
 
2992
    extra_stack += 32;
2993
    extra_stack += 32;
-
 
2994
    move(sh(to.where_exp), to, pushdest);
-
 
2995
    extra_stack += 32;
2993
    move (sh(length.where_exp), length, pushdest);
2996
    move(sh(length.where_exp), length, pushdest);
2994
    ins0 (popecx);
2997
    ins0(popecx);
2995
#ifdef NEWDWARF
2998
#ifdef NEWDWARF
2996
    if (diagnose && dwarf2 && no_frame)
2999
    if (diagnose && dwarf2 && no_frame)
2997
      dw2_track_pop();
3000
      dw2_track_pop();
2998
#endif
3001
#endif
2999
    ins0 (popedi);
3002
    ins0(popedi);
3000
#ifdef NEWDWARF
3003
#ifdef NEWDWARF
3001
    if (diagnose && dwarf2 && no_frame)
3004
    if (diagnose && dwarf2 && no_frame)
3002
      dw2_track_pop();
3005
      dw2_track_pop();
3003
#endif
3006
#endif
3004
    ins0 (popesi);
3007
    ins0(popesi);
3005
#ifdef NEWDWARF
3008
#ifdef NEWDWARF
3006
    if (diagnose && dwarf2 && no_frame)
3009
    if (diagnose && dwarf2 && no_frame)
3007
      dw2_track_pop();
3010
      dw2_track_pop();
3008
#endif
3011
#endif
3009
    move (slongsh, reg2, reg0);
3012
    move(slongsh, reg2, reg0);
3010
    ins2 (sarl, size8, size32, mw (zeroe, 2), reg2);
3013
    ins2(sarl, size8, size32, mw(zeroe, 2), reg2);
3011
    ins0 (rep);
3014
    ins0(rep);
3012
    ins0 (movsl);
3015
    ins0(movsl);
3013
    move (slongsh, reg0, reg2);
3016
    move(slongsh, reg0, reg2);
3014
    ins2 (andl, size32, size32, mw (zeroe, 3), reg2);
3017
    ins2(andl, size32, size32, mw(zeroe, 3), reg2);
3015
    ins0 (rep);
3018
    ins0(rep);
3016
    ins0 (movsb);
3019
    ins0(movsb);
3017
    ins0 (popecx);
3020
    ins0(popecx);
3018
#ifdef NEWDWARF
3021
#ifdef NEWDWARF
3019
    if (diagnose && dwarf2 && no_frame)
3022
    if (diagnose && dwarf2 && no_frame)
3020
      dw2_track_pop();
3023
      dw2_track_pop();
3021
#endif
3024
#endif
3022
    if (regsinuse & 0x10) {
3025
    if (regsinuse & 0x10) {
3023
      ins0 (popedi);
3026
      ins0(popedi);
3024
#ifdef NEWDWARF
3027
#ifdef NEWDWARF
3025
      if (diagnose && dwarf2 && no_frame)
3028
      if (diagnose && dwarf2 && no_frame)
3026
	dw2_track_pop();
3029
	dw2_track_pop();
3027
#endif
3030
#endif
3028
    }
3031
    }
3029
    if (regsinuse & 0x20) {
3032
    if (regsinuse & 0x20) {
3030
      ins0 (popesi);
3033
      ins0(popesi);
3031
#ifdef NEWDWARF
3034
#ifdef NEWDWARF
3032
      if (diagnose && dwarf2 && no_frame)
3035
      if (diagnose && dwarf2 && no_frame)
3033
	dw2_track_pop();
3036
	dw2_track_pop();
3034
#endif
3037
#endif
3035
    }
3038
    }
3036
    check_stack_max;
3039
    check_stack_max;
3037
    extra_stack = old_extra_stack;
3040
    extra_stack = old_extra_stack;
3038
    min_rfree |= 0x30;
3041
    min_rfree |= 0x30;
3039
    invalidate_dest (reg0);
3042
    invalidate_dest(reg0);
3040
    invalidate_dest (reg2);
3043
    invalidate_dest(reg2);
3041
    invalidate_dest (to);
3044
    invalidate_dest(to);
3042
  }
3045
  }
3043
  else {
3046
  else {
3044
    move(sh(length.where_exp), length, pushdest);
3047
    move(sh(length.where_exp), length, pushdest);
3045
    extra_stack += 32;
3048
    extra_stack += 32;
3046
    move(sh(from.where_exp), from, pushdest);
3049
    move(sh(from.where_exp), from, pushdest);
3047
    extra_stack += 32;
3050
    extra_stack += 32;
3048
    move(sh(to.where_exp), to, pushdest);
3051
    move(sh(to.where_exp), to, pushdest);
3049
    if (name_memmove == nilexp)
3052
    if (name_memmove == nilexp)
3050
      name_memmove = make_extn ("memmove", f_proc, 0);
3053
      name_memmove = make_extn("memmove", f_proc, 0);
3051
    callins (0, name_memmove, stack_dec);	/* call_libfn("memmove"); */
3054
    callins (0, name_memmove, stack_dec);	/* call_libfn("memmove"); */
3052
    extra_stack -= 64;
3055
    extra_stack -= 64;
3053
    add(slongsh, mw(zeroe, 12), sp, sp);
3056
    add(slongsh, mw(zeroe, 12), sp, sp);
3054
    invalidate_dest(reg0);
3057
    invalidate_dest(reg0);
3055
    invalidate_dest(reg1);
3058
    invalidate_dest(reg1);
3056
    invalidate_dest(reg2);
3059
    invalidate_dest(reg2);
3057
  };
3060
  };
3058
 
3061
 
3059
  return;
3062
  return;
3060
}
3063
}
3061
 
3064
 
3062
 
3065
 
3063
 
3066
 
3064
 
3067
 
3065
void retins
3068
void retins
3066
    PROTO_Z ()
3069
(void)
3067
{
3070
{
3068
		/* leave proc, discarding any callee parameters */
3071
		/* leave proc, discarding any callee parameters */
3069
		/* can overwrite %ecx */
3072
		/* can overwrite %ecx */
3070
  int n = (remove_struct_ref && has_struct_res(crt_proc_exp)) ? 32 : 0;
3073
  int n = (remove_struct_ref && has_struct_res(crt_proc_exp))? 32 : 0;
3071
  if (callee_size >= 0) {
3074
  if (callee_size >= 0) {
3072
    if ((n += callee_size) == 0)
3075
    if ((n += callee_size) == 0)
3073
      ins0 (ret);
3076
      ins0(ret);
3074
    else
3077
    else
3075
      ins1(ret, 32, mw(zeroe, n/8));
3078
      ins1(ret, 32, mw(zeroe, n/8));
3076
  }
3079
  }
3077
  else {	/* variable sized callees to be discarded */
3080
  else {	/* variable sized callees to be discarded */
3078
    ins0 (popecx);	/* return address */
3081
    ins0 (popecx);	/* return address */
3079
    ins0 ("pop %esp");	/* discard callees */
3082
    ins0 ("pop %esp");	/* discard callees */
3080
    if (n != 0)
3083
    if (n != 0)
3081
      add (slongsh, mw (zeroe, n/8), sp, sp);
3084
      add(slongsh, mw(zeroe, n/8), sp, sp);
3082
    ins0 ("jmp *%ecx");
3085
    ins0("jmp *%ecx");
3083
  }
3086
  }
3084
  return;
3087
  return;
3085
}
3088
}
3086
 
3089
 
3087
void stack_return
3090
void stack_return
3088
    PROTO_N ( (longs) )
-
 
3089
    PROTO_T ( int longs )
3091
(int longs)
3090
{
3092
{
3091
  if (longs == 32 && (regsinuse & 0x2) == 0)
3093
  if (longs == 32 && (regsinuse & 0x2) == 0)
3092
   {
3094
   {
3093
     ins0(popedx);
3095
     ins0(popedx);
3094
#ifdef NEWDWARF
3096
#ifdef NEWDWARF
3095
      if (diagnose && dwarf2 && no_frame)
3097
      if (diagnose && dwarf2 && no_frame)
3096
	dw2_track_pop();
3098
	dw2_track_pop();
3097
#endif
3099
#endif
3098
     invalidate_dest(reg1);
3100
     invalidate_dest(reg1);
3099
     stack_dec += longs;
3101
     stack_dec += longs;
3100
     return;
3102
     return;
3101
   };
3103
   };
3102
  if (longs == 32 && (regsinuse & 0x4) == 0)
3104
  if (longs == 32 && (regsinuse & 0x4) == 0)
3103
   {
3105
   {
3104
     ins0(popecx);
3106
     ins0(popecx);
3105
#ifdef NEWDWARF
3107
#ifdef NEWDWARF
Line 3111... Line 3113...
3111
     return;
3113
     return;
3112
   };
3114
   };
3113
  if (is80586 && longs == 64 && (regsinuse & 0x2) == 0)
3115
  if (is80586 && longs == 64 && (regsinuse & 0x2) == 0)
3114
   {
3116
   {
3115
     ins0(popedx);
3117
     ins0(popedx);
3116
#ifdef NEWDWARF
3118
#ifdef NEWDWARF
3117
      if (diagnose && dwarf2 && no_frame)
3119
      if (diagnose && dwarf2 && no_frame)
3118
	dw2_track_pop();
3120
	dw2_track_pop();
3119
#endif
3121
#endif
3120
     ins0(popedx);
3122
     ins0(popedx);
3121
#ifdef NEWDWARF
3123
#ifdef NEWDWARF
3122
      if (diagnose && dwarf2 && no_frame)
3124
      if (diagnose && dwarf2 && no_frame)
3123
	dw2_track_pop();
3125
	dw2_track_pop();
3124
#endif
3126
#endif
3125
     invalidate_dest(reg1);
3127
     invalidate_dest(reg1);
3126
     stack_dec += longs;
3128
     stack_dec += longs;
3127
     return;
3129
     return;
3128
   };
3130
   };
3129
  if (is80586 && longs == 64 && (regsinuse & 0x4) == 0)
3131
  if (is80586 && longs == 64 && (regsinuse & 0x4) == 0)
3130
   {
3132
   {
3131
     ins0(popecx);
3133
     ins0(popecx);
3132
#ifdef NEWDWARF
3134
#ifdef NEWDWARF
3133
      if (diagnose && dwarf2 && no_frame)
3135
      if (diagnose && dwarf2 && no_frame)
3134
	dw2_track_pop();
3136
	dw2_track_pop();
3135
#endif
3137
#endif
3136
     ins0(popecx);
3138
     ins0(popecx);
3137
#ifdef NEWDWARF
3139
#ifdef NEWDWARF
3138
      if (diagnose && dwarf2 && no_frame)
3140
      if (diagnose && dwarf2 && no_frame)
3139
	dw2_track_pop();
3141
	dw2_track_pop();
3140
#endif
3142
#endif
3141
     invalidate_dest(reg2);
3143
     invalidate_dest(reg2);
3142
     stack_dec += longs;
3144
     stack_dec += longs;
3143
     return;
3145
     return;
3144
   };
3146
   };
3145
  add (slongsh, mw (zeroe, (longs / 8)), sp, sp);
3147
  add(slongsh, mw(zeroe,(longs / 8)), sp, sp);
3146
  stack_dec += longs;
3148
  stack_dec += longs;
3147
#ifdef NEWDWARF
3149
#ifdef NEWDWARF
3148
  if (diagnose && dwarf2 && no_frame)
3150
  if (diagnose && dwarf2 && no_frame)
3149
    dw2_track_sp();
3151
    dw2_track_sp();
3150
#endif
3152
#endif
3151
  return;
3153
  return;
3152
}
3154
}
3153
 
3155
 
3154
/* call instruction */
3156
/* call instruction */
3155
void callins
3157
void callins
3156
    PROTO_N ( (longs, fn, ret_stack_dec) )
-
 
3157
    PROTO_T ( int longs X exp fn X int ret_stack_dec )
3158
(int longs, exp fn, int ret_stack_dec)
3158
{
3159
{
3159
  cond1_set = 0;
3160
  cond1_set = 0;
3160
  cond2_set = 0;
3161
  cond2_set = 0;
3161
  if (name (fn) == name_tag && !isvar (son (fn)) && isglob (son (fn))) {
3162
  if (name(fn) == name_tag && !isvar(son(fn)) && isglob(son(fn))) {
3162
    exp ind = getexp (f_proc, nilexp, 0, fn, nilexp, 0,
3163
    exp ind = getexp(f_proc, nilexp, 0, fn, nilexp, 0,
3163
	0, cont_tag);
3164
	0, cont_tag);
3164
#ifdef NEWDWARF
3165
#ifdef NEWDWARF
3165
    if (current_dg_info) {
3166
    if (current_dg_info) {
3166
      current_dg_info->data.i_call.brk = set_dw_text_label ();
3167
      current_dg_info->data.i_call.brk = set_dw_text_label();
3167
      current_dg_info->data.i_call.p.k = WH_STR;
3168
      current_dg_info->data.i_call.p.k = WH_STR;
3168
      current_dg_info->data.i_call.p.u.s = (brog(son(fn)))->dec_u.dec_val.dec_id;
3169
      current_dg_info->data.i_call.p.u.s = (brog(son(fn))) ->dec_u.dec_val.dec_id;
3169
      current_dg_info->data.i_call.p.o = no(fn)/8;
3170
      current_dg_info->data.i_call.p.o = no(fn) /8;
3170
    }
3171
    }
3171
#endif
3172
#endif
3172
    ins1 (call, 32, mw (ind, 0));
3173
    ins1(call, 32, mw(ind, 0));
3173
    retcell (ind);
3174
    retcell(ind);
3174
  }
3175
  }
3175
  else {
3176
  else {
3176
    if (inmem (mw (fn, 0))) {
3177
    if (inmem(mw(fn, 0))) {
3177
      move (slongsh, mw (fn, 0), reg0);
3178
      move(slongsh, mw(fn, 0), reg0);
3178
      fn = reg0.where_exp;
3179
      fn = reg0.where_exp;
3179
    };
3180
    };
3180
#ifdef NEWDWARF
3181
#ifdef NEWDWARF
3181
    if (current_dg_info) {
3182
    if (current_dg_info) {
3182
      int rn;
3183
      int rn;
3183
      if (name(fn)==name_tag && !isvar(son(fn)))
3184
      if (name(fn) ==name_tag && !isvar(son(fn)))
3184
	rn = no(son(fn));
3185
	rn = no(son(fn));
3185
      else
3186
      else
3186
      if (name(fn)==cont_tag && name(son(fn))==name_tag && 
3187
      if (name(fn) ==cont_tag && name(son(fn)) ==name_tag &&
3187
		isvar(son(son(fn))))
3188
		isvar(son(son(fn))))
3188
	rn = no(son(son(fn)));
3189
	rn = no(son(son(fn)));
3189
      else {
3190
      else {
3190
	failer ("where?");
3191
	failer("where?");
3191
	rn = 1;
3192
	rn = 1;
3192
      }
3193
      }
3193
      current_dg_info->data.i_call.brk = set_dw_text_label ();
3194
      current_dg_info->data.i_call.brk = set_dw_text_label();
3194
      current_dg_info->data.i_call.p.k = WH_REG;
3195
      current_dg_info->data.i_call.p.k = WH_REG;
3195
      current_dg_info->data.i_call.p.u.l = get_reg_no (rn);
3196
      current_dg_info->data.i_call.p.u.l = get_reg_no(rn);
3196
    }
3197
    }
3197
#endif
3198
#endif
3198
    ins1ind (call, 32, mw (fn, 0));
3199
    ins1ind(call, 32, mw(fn, 0));
3199
  };
3200
  };
3200
  stack_dec = ret_stack_dec;
3201
  stack_dec = ret_stack_dec;
3201
#ifdef NEWDWARF
3202
#ifdef NEWDWARF
3202
  START_BB ();
3203
  START_BB();
3203
#endif
3204
#endif
3204
  if (longs == 32 || (longs == 64 && is80586) ||
3205
  if (longs == 32 || (longs == 64 && is80586) ||
3205
	!no_frame || !not_in_params || !not_in_postlude)
3206
	!no_frame || !not_in_params || !not_in_postlude)
3206
    stack_return(longs);
3207
    stack_return(longs);
3207
  else
3208
  else
3208
    keep_short = 1;
3209
    keep_short = 1;
3209
  return;
3210
  return;
3210
}
3211
}
3211
 
3212
 
3212
void jumpins
3213
void jumpins
3213
    PROTO_N ( (lab) )
-
 
3214
    PROTO_T ( exp lab )
3214
(exp lab)
3215
{
3215
{
3216
    if (inmem (mw (lab, 0))) {
3216
    if (inmem(mw(lab, 0))) {
3217
      move (slongsh, mw (lab, 0), reg0);
3217
      move(slongsh, mw(lab, 0), reg0);
3218
      lab = reg0.where_exp;
3218
      lab = reg0.where_exp;
3219
    };
3219
    };
3220
    ins1ind (jmp, 32, mw (lab, 0));
3220
    ins1ind(jmp, 32, mw(lab, 0));
3221
    return;
3221
    return;
3222
}
3222
}
3223
 
3223
 
3224
 
3224
 
3225
 
3225
 
3226
/* compare from with min (from - min)
3226
/* compare from with min (from - min)
3227
   values have shape sha. The testno for
3227
   values have shape sha. The testno for
3228
   which it is being used is supplied so
3228
   which it is being used is supplied so
3229
   that we can optimise cmp(0,x)
3229
   that we can optimise cmp(0,x)
3230
 
3230
 
3231
   Result true (1) if optimised compare with 0
3231
   Result true (1) if optimised compare with 0
3232
   in which case we need to ignore overflow */
3232
   in which case we need to ignore overflow */
3233
int cmp
3233
int cmp
3234
    PROTO_N ( (sha, from, min, nt, e) )
-
 
3235
    PROTO_T ( shape sha X where from X where min X int nt X exp e )
3234
(shape sha, where from, where min, int nt, exp e)
3236
{
3235
{
3237
  int  sz;
3236
  int  sz;
3238
  exp cc = cond1.where_exp;
3237
  exp cc = cond1.where_exp;
3239
  exp cc2a = cond2a.where_exp;
3238
  exp cc2a = cond2a.where_exp;
3240
  exp me;
3239
  exp me;
Line 3244... Line 3243...
3244
  exp hold_from = son(from.where_exp);
3243
  exp hold_from = son(from.where_exp);
3245
  exp hold_min = son(min.where_exp);
3244
  exp hold_min = son(min.where_exp);
3246
  sz = shape_size(sha);
3245
  sz = shape_size(sha);
3247
 
3246
 
3248
  if (cond1_set &&
3247
  if (cond1_set &&
3249
      (eq_where (min, zero) || (name(min.where_exp) == null_tag && no(min.where_exp) == 0)) &&
3248
     (eq_where(min, zero) || (name(min.where_exp) == null_tag && no(min.where_exp) == 0)) &&
3250
      (is_signed (sha) || nt >= 5) &&
3249
     (is_signed(sha) || nt >= 5) &&
3251
      ((name (cc) == ident_tag && eq_shape (sh (son (cc)), sha)) ||
3250
     ((name(cc) == ident_tag && eq_shape(sh(son(cc)), sha)) ||
3252
	(name (cc) == ass_tag && eq_shape (sh (bro (son (cc))), sha)) ||
3251
	(name(cc) == ass_tag && eq_shape(sh(bro(son(cc))), sha)) ||
3253
	eq_shape (sh (cc), sha)) &&
3252
	eq_shape(sh(cc), sha)) &&
3254
      eq_where (cond1, from) && sz <= 32)
3253
      eq_where(cond1, from) && sz <= 32)
3255
    return 1;			/* we are comparing the value from which
3254
    return 1;			/* we are comparing the value from which
3256
				   the conditions are set with zero */
3255
				   the conditions are set with zero */
3257
 
3256
 
3258
  if (cond2_set &&
3257
  if (cond2_set &&
3259
	((name (cc2a) == ident_tag && eq_shape (sh (son (cc2a)), sha)) ||
3258
	((name(cc2a) == ident_tag && eq_shape(sh(son(cc2a)), sha)) ||
3260
	  eq_shape (sh (cc2a), sha)) &&
3259
	  eq_shape(sh(cc2a), sha)) &&
3261
	eq_where (cond2a, from) &&
3260
	eq_where(cond2a, from) &&
3262
	eq_where (cond2b, min))
3261
	eq_where(cond2b, min))
3263
    return 0;			/* we are repeating the previous
3262
    return 0;			/* we are repeating the previous
3264
				   comparison */
3263
				   comparison */
3265
 
3264
 
3266
 
3265
 
3267
  if (!is_floating (name (sha))) {
3266
  if (!is_floating(name(sha))) {
3268
    where orig_min;
3267
    where orig_min;
3269
    orig_min = min;
3268
    orig_min = min;
3270
    has_equiv_from = equiv_reg (from, sz);
3269
    has_equiv_from = equiv_reg(from, sz);
3271
    if (has_equiv_from.where_exp != nilexp) {
3270
    if (has_equiv_from.where_exp != nilexp) {
3272
      from = has_equiv_from;
3271
      from = has_equiv_from;
3273
      hold_from = son(from.where_exp);
3272
      hold_from = son(from.where_exp);
3274
    }
3273
    }
3275
    has_equiv_min = equiv_reg(min, sz);
3274
    has_equiv_min = equiv_reg(min, sz);
Line 3277... Line 3276...
3277
      min = has_equiv_min;
3276
      min = has_equiv_min;
3278
      hold_min = son(min.where_exp);
3277
      hold_min = son(min.where_exp);
3279
    }
3278
    }
3280
 
3279
 
3281
    if (cond1_set &&
3280
    if (cond1_set &&
3282
        (eq_where (min, zero) || (name(min.where_exp) == null_tag && no(min.where_exp) == 0)) &&
3281
       (eq_where(min, zero) || (name(min.where_exp) == null_tag && no(min.where_exp) == 0)) &&
3283
        (is_signed (sha) || nt >= 5) &&
3282
       (is_signed(sha) || nt >= 5) &&
3284
        ((name (cc) == ident_tag && eq_shape (sh (son (cc)), sha)) ||
3283
       ((name(cc) == ident_tag && eq_shape(sh(son(cc)), sha)) ||
3285
	  (name (cc) == ass_tag && eq_shape (sh (bro (son (cc))), sha)) ||
3284
	 (name(cc) == ass_tag && eq_shape(sh(bro(son(cc))), sha)) ||
3286
	  eq_shape (sh (cc), sha)) &&
3285
	  eq_shape(sh(cc), sha)) &&
3287
        eq_where (cond1, from) && sz <= 32)
3286
        eq_where(cond1, from) && sz <= 32)
3288
      return 1;			/* we are comparing the value from which
3287
      return 1;			/* we are comparing the value from which
3289
				   the conditions are set with zero */
3288
				   the conditions are set with zero */
3290
 
3289
 
3291
    if (cond2_set &&
3290
    if (cond2_set &&
3292
	  ((name (cc2a) == ident_tag && eq_shape (sh (son (cc2a)), sha)) ||
3291
	 ((name(cc2a) == ident_tag && eq_shape(sh(son(cc2a)), sha)) ||
3293
	    eq_shape (sh (cc2a), sha)) &&
3292
	    eq_shape(sh(cc2a), sha)) &&
3294
	  eq_where (cond2a, from) &&
3293
	  eq_where(cond2a, from) &&
3295
	  eq_where (cond2b, min))
3294
	  eq_where(cond2b, min))
3296
      return 0;			/* we are repeating the previous
3295
      return 0;			/* we are repeating the previous
3297
				   comparison */
3296
				   comparison */
3298
 
3297
 
3299
    if (((name(min.where_exp) == null_tag && no(min.where_exp) == 0)
3298
    if (((name(min.where_exp) == null_tag && no(min.where_exp) == 0)
3300
	 || eq_where (min, zero)) &&
3299
	 || eq_where(min, zero)) &&
3301
	!inmem (from)) {
3300
	!inmem(from)) {
3302
				/* min is zero */
3301
				/* min is zero */
3303
 
3302
 
3304
      cond1_set = 1;
3303
      cond1_set = 1;
3305
      cond2_set = 0;
3304
      cond2_set = 0;
3306
      cond1 = from;
3305
      cond1 = from;
3307
 
3306
 
3308
 
3307
 
3309
      if (sz == 8) {
3308
      if (sz == 8) {
3310
	ins2 (testb, sz, sz, from, from);
3309
	ins2(testb, sz, sz, from, from);
3311
	return 0;
3310
	return 0;
3312
      };
3311
      };
3313
      if (sz == 16) {
3312
      if (sz == 16) {
3314
	ins2 (testw, sz, sz, from, from);
3313
	ins2(testw, sz, sz, from, from);
3315
	return 0;
3314
	return 0;
3316
      };
3315
      };
3317
      if (sz == 32) {
3316
      if (sz == 32) {
3318
	ins2 (testl, sz, sz, from, from);
3317
	ins2(testl, sz, sz, from, from);
3319
	return 0;
3318
	return 0;
3320
      };
3319
      };
3321
      if (sz == 64) {	/* !inmem, so from must be reg0/reg1 */
3320
      if (sz == 64) {	/* !inmem, so from must be reg0/reg1 */
3322
	if (nt >= 5) {
3321
	if (nt >= 5) {
3323
	  ins2 (orl, 32, 32, reg1, reg0);
3322
	  ins2(orl, 32, 32, reg1, reg0);
3324
	  invalidate_dest (reg0);
3323
	  invalidate_dest(reg0);
3325
	  cond1_set = 0;
3324
	  cond1_set = 0;
3326
	  return 0;
3325
	  return 0;
3327
	}
3326
	}
3328
	else
3327
	else
3329
	if (nt == f_less_than || nt == f_greater_than_or_equal) {
3328
	if (nt == f_less_than || nt == f_greater_than_or_equal) {
3330
	  ins2 (testl, 32, 32, reg1, reg1);
3329
	  ins2(testl, 32, 32, reg1, reg1);
3331
	  cond1_set = 0;
3330
	  cond1_set = 0;
3332
	  return 0;
3331
	  return 0;
3333
	}
3332
	}
3334
      }
3333
      }
3335
    };
3334
    };
Line 3338... Line 3337...
3338
    cond1_set = 0;
3337
    cond1_set = 0;
3339
    cond2_set = 1;
3338
    cond2_set = 1;
3340
    cond2a = from;
3339
    cond2a = from;
3341
    cond2b = min;
3340
    cond2b = min;
3342
 
3341
 
3343
 
3342
 
3344
    if (nt >= 5 &&
3343
    if (nt >= 5 &&
3345
        ((name(from.where_exp) == null_tag && no(from.where_exp) == 0) ||
3344
       ((name(from.where_exp) == null_tag && no(from.where_exp) == 0) ||
3346
		 eq_where (from, zero)) &&
3345
		 eq_where(from, zero)) &&
3347
        !inmem (min)) {
3346
        !inmem(min)) {
3348
      /* from is zero and the test is == or != so we don't have to reverse
3347
      /* from is zero and the test is == or != so we don't have to reverse
3349
         its sense */
3348
         its sense */
3350
 
3349
 
3351
      if (sz == 8) {
3350
      if (sz == 8) {
3352
	ins2 (testb, sz, sz, min, min);
3351
	ins2(testb, sz, sz, min, min);
3353
	return 0;
3352
	return 0;
3354
      };
3353
      };
3355
      if (sz == 16) {
3354
      if (sz == 16) {
3356
	ins2 (testw, sz, sz, min, min);
3355
	ins2(testw, sz, sz, min, min);
3357
	return 0;
3356
	return 0;
3358
      };
3357
      };
3359
      if (sz == 32) {
3358
      if (sz == 32) {
3360
	ins2 (testl, sz, sz, min, min);
3359
	ins2(testl, sz, sz, min, min);
3361
	return 0;
3360
	return 0;
3362
      };
3361
      };
3363
      if (sz == 64) {	/* !inmem, so min must be reg0/reg1 */
3362
      if (sz == 64) {	/* !inmem, so min must be reg0/reg1 */
3364
	ins2 (orl, 32, 32, reg1, reg0);
3363
	ins2(orl, 32, 32, reg1, reg0);
3365
	invalidate_dest (reg0);
3364
	invalidate_dest(reg0);
3366
	cond2_set = 0;
3365
	cond2_set = 0;
3367
	return 0;
3366
	return 0;
3368
      }
3367
      }
3369
    };
3368
    };
3370
 
3369
 
3371
    if (sz != 16 && sz <= 32 && ((name(min.where_exp) == null_tag ||
3370
    if (sz != 16 && sz <= 32 && ((name(min.where_exp) == null_tag ||
3372
		 name(min.where_exp) == val_tag) &&
3371
		 name(min.where_exp) == val_tag) &&
3373
			 no(min.where_exp) == 0) &&
3372
			 no(min.where_exp) == 0) &&
3374
        inmem (from) && has_equiv_from.where_exp == nilexp) {
3373
        inmem(from) && has_equiv_from.where_exp == nilexp) {
3375
      {
3374
      {
3376
        move(sha, from, reg0);
3375
        move(sha, from, reg0);
3377
	cond1_set = 0;
3376
	cond1_set = 0;
3378
	cond2_set = 0;
3377
	cond2_set = 0;
3379
        IGNORE cmp(sha, reg0, min, nt, e);
3378
        IGNORE cmp(sha, reg0, min, nt, e);
Line 3397... Line 3396...
3397
	  break;
3396
	  break;
3398
	default:
3397
	default:
3399
	  failer("unexpected size");
3398
	  failer("unexpected size");
3400
      };
3399
      };
3401
 
3400
 
3402
      if ((inmem (from) && inmem (min)) ||
3401
      if ((inmem(from) && inmem(min)) ||
3403
	  (name (sha) == prokhd && !PIC_code && !eq_where(min, reg0)) ||
3402
	 (name(sha) == prokhd && !PIC_code && !eq_where(min, reg0)) ||
3404
	  (name (from.where_exp) == name_tag &&
3403
	 (name(from.where_exp) == name_tag &&
3405
	    isvar (son (from.where_exp))) ||
3404
	    isvar(son(from.where_exp))) ||
3406
	   (name(from.where_exp) == reff_tag &&
3405
	  (name(from.where_exp) == reff_tag &&
3407
	    name(son(from.where_exp)) == name_tag &&
3406
	    name(son(from.where_exp)) == name_tag &&
3408
	    !isvar(son(son(from.where_exp))))) {
3407
	    !isvar(son(son(from.where_exp))))) {
3409
	if ((name (from.where_exp) == name_tag &&
3408
	if ((name(from.where_exp) == name_tag &&
3410
	    ((isvar (son (from.where_exp)) &&
3409
	   ((isvar(son(from.where_exp)) &&
3411
	      ptno (son (from.where_exp)) <= par_pl) ||
3410
	      ptno(son(from.where_exp)) <= par_pl) ||
3412
            ( PIC_code &&
3411
           (PIC_code &&
3413
              isglob(son (from.where_exp)) &&
3412
              isglob(son(from.where_exp)) &&
3414
	      (name (sha) == prokhd || name(sha) == ptrhd) &&
3413
	     (name(sha) == prokhd || name(sha) == ptrhd) &&
3415
              !brog(son(from.where_exp)) ->  dec_u.dec_val.extnamed))) ||
3414
              !brog(son(from.where_exp)) ->  dec_u.dec_val.extnamed))) ||
3416
	      name(from.where_exp) == reff_tag)
3415
	      name(from.where_exp) == reff_tag)
3417
	  mova (from, reg0);
3416
	  mova(from, reg0);
3418
	else
3417
	else
3419
	  move (sha, from, reg0);
3418
	  move(sha, from, reg0);
3420
	son(from.where_exp) = hold_from;
3419
	son(from.where_exp) = hold_from;
3421
	from = reg0;
3420
	from = reg0;
3422
	hold_from = son(from.where_exp);
3421
	hold_from = son(from.where_exp);
3423
      }
3422
      }
3424
      else {
3423
      else {
3425
	if (inmem (from)) {
3424
	if (inmem(from)) {
3426
	  if (sz == 64)
3425
	  if (sz == 64)
3427
	    regsinuse |= 0x2;
3426
	    regsinuse |= 0x2;
3428
	  contop (from.where_exp, eq_where (reg0, min), reg0);
3427
	  contop(from.where_exp, eq_where(reg0, min), reg0);
3429
	  contop_done = 1;
3428
	  contop_done = 1;
3430
	};
3429
	};
3431
      };
3430
      };
3432
 
3431
 
3433
      if ((name(min.where_exp) == val_tag || name(min.where_exp) == env_offset_tag) &&
3432
      if ((name(min.where_exp) == val_tag || name(min.where_exp) == env_offset_tag) &&
3434
            ((name(from.where_exp) == val_tag || name(from.where_exp) == env_offset_tag) ||
3433
           ((name(from.where_exp) == val_tag || name(from.where_exp) == env_offset_tag) ||
3435
		(keep_short && inmem(from))))  {
3434
		(keep_short && inmem(from)))) {
3436
        move (sha, from, reg0);
3435
        move(sha, from, reg0);
3437
	son(from.where_exp) = hold_from;
3436
	son(from.where_exp) = hold_from;
3438
        from = reg0;
3437
        from = reg0;
3439
	hold_from = son(from.where_exp);
3438
	hold_from = son(from.where_exp);
3440
      };
3439
      };
3441
 
3440
 
3442
      if (eq_where (from, reg0) && eq_where (min, reg0)
3441
      if (eq_where(from, reg0) && eq_where(min, reg0)
3443
				&& !eq_where (orig_min, reg0)) {
3442
				&& !eq_where(orig_min, reg0)) {
3444
	son(min.where_exp) = hold_min;
3443
	son(min.where_exp) = hold_min;
3445
	min = orig_min;		/* equiv_reg lost due to evaluation of from */
3444
	min = orig_min;		/* equiv_reg lost due to evaluation of from */
3446
	hold_min = son(min.where_exp);
3445
	hold_min = son(min.where_exp);
3447
      }
3446
      }
3448
 
3447
 
3449
      me = min.where_exp;
3448
      me = min.where_exp;
3450
      if ((name (me) == name_tag && isvar (son (me)) &&
3449
      if ((name(me) == name_tag && isvar(son(me)) &&
3451
	     ptno (son (me)) <= par_pl) ||
3450
	     ptno(son(me)) <= par_pl) ||
3452
          (PIC_code && name (me) == name_tag && isglob(son(me)) &&
3451
         (PIC_code && name(me) == name_tag && isglob(son(me)) &&
3453
            (name(sha) == prokhd || name(sha) == ptrhd) &&
3452
           (name(sha) == prokhd || name(sha) == ptrhd) &&
3454
             !brog(son(me)) ->  dec_u.dec_val.extnamed) ||
3453
             !brog(son(me)) ->  dec_u.dec_val.extnamed) ||
3455
	   (name(me) == reff_tag && name(son(me)) == name_tag &&
3454
	  (name(me) == reff_tag && name(son(me)) == name_tag &&
3456
	    !isvar(son(son(me))))){
3455
	    !isvar(son(son(me))))) {
3457
	if (eq_where (from, reg0)) {
3456
	if (eq_where(from, reg0)) {
3458
          ins0(pusheax);
3457
          ins0(pusheax);
3459
#ifdef NEWDWARF
3458
#ifdef NEWDWARF
3460
	  if (diagnose && dwarf2 && no_frame)
3459
	  if (diagnose && dwarf2 && no_frame)
3461
	    dw2_track_push();
3460
	    dw2_track_push();
3462
#endif
3461
#endif
3463
          extra_stack += 32;
3462
          extra_stack += 32;
3464
	  check_stack_max;
3463
	  check_stack_max;
3465
	  mova (min, reg0);
3464
	  mova(min, reg0);
3466
	  ins2 (in, sz, sz, reg0, mw(ind_sp.where_exp, -32));
3465
	  ins2(in, sz, sz, reg0, mw(ind_sp.where_exp, -32));
3467
	  invalidate_dest (ind_sp);
3466
	  invalidate_dest(ind_sp);
3468
	  invalidate_dest (reg0);
3467
	  invalidate_dest(reg0);
3469
          ins0(popeax);
3468
          ins0(popeax);
3470
#ifdef NEWDWARF
3469
#ifdef NEWDWARF
3471
	  if (diagnose && dwarf2 && no_frame)
3470
	  if (diagnose && dwarf2 && no_frame)
3472
	    dw2_track_pop();
3471
	    dw2_track_pop();
3473
#endif
3472
#endif
3474
          extra_stack -= 32;
3473
          extra_stack -= 32;
3475
	  son(from.where_exp) = hold_from;
3474
	  son(from.where_exp) = hold_from;
3476
	  son(min.where_exp) = hold_min;
3475
	  son(min.where_exp) = hold_min;
3477
          return 0;
3476
          return 0;
3478
	};
3477
	};
3479
	mova (min, reg0);
3478
	mova(min, reg0);
3480
	son(min.where_exp) = hold_min;
3479
	son(min.where_exp) = hold_min;
3481
	min = reg0;
3480
	min = reg0;
3482
	hold_min = son(min.where_exp);
3481
	hold_min = son(min.where_exp);
3483
     }
3482
     }
3484
      else {
3483
      else {
3485
	if (inmem (min)) {
3484
	if (inmem(min)) {
3486
	  if (sz == 64)
3485
	  if (sz == 64)
3487
	    regsinuse |= 0x2;
3486
	    regsinuse |= 0x2;
3488
	  contop (min.where_exp, eq_where (reg0, from), reg0);
3487
	  contop(min.where_exp, eq_where(reg0, from), reg0);
3489
	  contop_done = 1;
3488
	  contop_done = 1;
3490
	};
3489
	};
3491
      };
3490
      };
3492
 
3491
 
3493
      if (sz == 8 && (eq_where (min, reg4) || eq_where (min, reg5))) {
3492
      if (sz == 8 && (eq_where(min, reg4) || eq_where(min, reg5))) {
3494
	if (!eq_where (from, reg0)) {
3493
	if (!eq_where(from, reg0)) {
3495
	  move (sha, min, reg0);
3494
	  move(sha, min, reg0);
3496
	  son(min.where_exp) = hold_min;
3495
	  son(min.where_exp) = hold_min;
3497
	  min = reg0;
3496
	  min = reg0;
3498
	  hold_min = son(min.where_exp);
3497
	  hold_min = son(min.where_exp);
3499
	}
3498
	}
3500
	else {
3499
	else {
3501
	  sub (sha, min, reg0, reg0);
3500
	  sub(sha, min, reg0, reg0);
3502
	  if (contop_done)
3501
	  if (contop_done)
3503
	    end_contop ();
3502
	    end_contop();
3504
	  son(from.where_exp) = hold_from;
3503
	  son(from.where_exp) = hold_from;
3505
	  son(min.where_exp) = hold_min;
3504
	  son(min.where_exp) = hold_min;
3506
	  return 0;
3505
	  return 0;
3507
	}
3506
	}
3508
      };
3507
      };
3509
 
3508
 
3510
      if (sz != 64) {
3509
      if (sz != 64) {
3511
	ins2 (in, sz, sz, min, from);/* do the comparison */
3510
	ins2 (in, sz, sz, min, from);/* do the comparison */
3512
	if (contop_done)
3511
	if (contop_done)
3513
	  end_contop ();
3512
	  end_contop();
3514
	son(from.where_exp) = hold_from;
3513
	son(from.where_exp) = hold_from;
3515
	son(min.where_exp) = hold_min;
3514
	son(min.where_exp) = hold_min;
3516
	return 0;
3515
	return 0;
3517
      }
3516
      }
3518
      {		/* compare 64bit */
3517
      {		/* compare 64bit */
3519
	where fromlo, fromhi, minlo, minhi;
3518
	where fromlo, fromhi, minlo, minhi;
3520
	cond2_set = 0;
3519
	cond2_set = 0;
3521
	if (eq_where (from, reg0)) {
3520
	if (eq_where(from, reg0)) {
3522
	  fromlo = reg0;
3521
	  fromlo = reg0;
3523
	  fromhi = reg1;
3522
	  fromhi = reg1;
3524
	}
3523
	}
3525
	else {
3524
	else {
3526
	  fromlo = from;
3525
	  fromlo = from;
3527
	  fromhi = mw (from.where_exp, from.where_off + 32);
3526
	  fromhi = mw(from.where_exp, from.where_off + 32);
3528
	}
3527
	}
3529
	if (eq_where (min, reg0)) {
3528
	if (eq_where(min, reg0)) {
3530
	  minlo = reg0;
3529
	  minlo = reg0;
3531
	  minhi = reg1;
3530
	  minhi = reg1;
3532
	}
3531
	}
3533
	else
3532
	else
3534
	if (name(min.where_exp) == val_tag) {
3533
	if (name(min.where_exp) == val_tag) {
3535
	  int c, c1;
3534
	  int c, c1;
3536
	  if (!isbigval(min.where_exp)) {
3535
	  if (!isbigval(min.where_exp)) {
3537
	    c = no(min.where_exp);
3536
	    c = no(min.where_exp);
3538
	    c1 = (is_signed(sha) && c < 0) ? -1 : 0;
3537
	    c1 = (is_signed(sha) && c < 0)? -1 : 0;
3539
	    if (c == 0 && (nt == f_greater_than_or_equal || nt == f_less_than)) {
3538
	    if (c == 0 && (nt == f_greater_than_or_equal || nt == f_less_than)) {
3540
				/* sign bit says it all, so ignore fromlo */
3539
				/* sign bit says it all, so ignore fromlo */
3541
	      ins2 (cmpl, 32, 32, zero, fromhi);
3540
	      ins2(cmpl, 32, 32, zero, fromhi);
3542
	      if (contop_done)
3541
	      if (contop_done)
3543
		end_contop ();
3542
		end_contop();
3544
	      regsinuse = riu;
3543
	      regsinuse = riu;
3545
	      son(from.where_exp) = hold_from;
3544
	      son(from.where_exp) = hold_from;
3546
	      son(min.where_exp) = hold_min;
3545
	      son(min.where_exp) = hold_min;
3547
	      return 0;
3546
	      return 0;
3548
	    }
3547
	    }
Line 3552... Line 3551...
3552
	    int ov;
3551
	    int ov;
3553
	    x = flt_to_f64(no(min.where_exp), is_signed(sha), &ov);
3552
	    x = flt_to_f64(no(min.where_exp), is_signed(sha), &ov);
3554
	    c = x.small;
3553
	    c = x.small;
3555
	    c1 = x.big;
3554
	    c1 = x.big;
3556
	  }
3555
	  }
3557
	  minlo = mw (zeroe, c);
3556
	  minlo = mw(zeroe, c);
3558
	  minhi = mw (zeroe, c1);
3557
	  minhi = mw(zeroe, c1);
3559
	}
3558
	}
3560
	else {
3559
	else {
3561
	  minlo = min;
3560
	  minlo = min;
3562
	  minhi = mw (min.where_exp, min.where_off + 32);
3561
	  minhi = mw(min.where_exp, min.where_off + 32);
3563
	}
3562
	}
3564
	if (nt >= 5 || !is_signed(sha)) {
3563
	if (nt >= 5 || !is_signed(sha)) {
3565
	  int flags_set_lab = next_lab ();
3564
	  int flags_set_lab = next_lab();
3566
	  ins2 (cmpl, 32, 32, minhi, fromhi);
3565
	  ins2(cmpl, 32, 32, minhi, fromhi);
3567
	  simple_branch (jne, flags_set_lab);
3566
	  simple_branch(jne, flags_set_lab);
3568
	  ins2 (cmpl, 32, 32, minlo, fromlo);
3567
	  ins2(cmpl, 32, 32, minlo, fromlo);
3569
	  simplest_set_lab (flags_set_lab);
3568
	  simplest_set_lab(flags_set_lab);
3570
	  if (contop_done)
3569
	  if (contop_done)
3571
	    end_contop ();
3570
	    end_contop();
3572
	  regsinuse = riu;
3571
	  regsinuse = riu;
3573
	  son(from.where_exp) = hold_from;
3572
	  son(from.where_exp) = hold_from;
3574
	  son(min.where_exp) = hold_min;
3573
	  son(min.where_exp) = hold_min;
3575
	  return 0;
3574
	  return 0;
3576
	}
3575
	}
3577
	cmp_64hilab = next_lab ();
3576
	cmp_64hilab = next_lab();
3578
	ins2 (cmpl, 32, 32, minhi, fromhi);
3577
	ins2(cmpl, 32, 32, minhi, fromhi);
3579
	cmp64_contop (contop_done);	/* if hi unequal, undo contop and jump to cmp_64hilab */
3578
	cmp64_contop (contop_done);	/* if hi unequal, undo contop and jump to cmp_64hilab */
3580
	ins2 (cmpl, 32, 32, minlo, fromlo);
3579
	ins2(cmpl, 32, 32, minlo, fromlo);
3581
        if (contop_done)
3580
        if (contop_done)
3582
	  end_contop ();
3581
	  end_contop();
3583
	regsinuse = riu;
3582
	regsinuse = riu;
3584
	son(from.where_exp) = hold_from;
3583
	son(from.where_exp) = hold_from;
3585
	son(min.where_exp) = hold_min;
3584
	son(min.where_exp) = hold_min;
3586
        return 0;
3585
        return 0;
3587
      }
3586
      }
Line 3599... Line 3598...
3599
    return 0;
3598
    return 0;
3600
  }
3599
  }
3601
}
3600
}
3602
 
3601
 
3603
int bad_from_reg
3602
int bad_from_reg
3604
    PROTO_N ( (from) )
-
 
3605
    PROTO_T ( where from )
3603
(where from)
3606
{
3604
{
3607
    return (!inmem (from) && name (from.where_exp) != val_tag &&
3605
    return(!inmem(from) && name(from.where_exp)!= val_tag &&
3608
	(in_reg (from.where_exp) & 0x70));
3606
	(in_reg(from.where_exp) & 0x70));
3609
}
3607
}
3610
 
3608
 
3611
/* change variety from (which has shape
3609
/* change variety from (which has shape
3612
   fsh) to sha, and put in to */
3610
   fsh) to sha, and put in to */
3613
void change_var_sh
3611
void change_var_sh
3614
    PROTO_N ( (sha, fsh, from, to) )
-
 
3615
    PROTO_T ( shape sha X shape fsh X where from X where to )
3612
(shape sha, shape fsh, where from, where to)
3616
{
3613
{
3617
  exp fe = from.where_exp;
3614
  exp fe = from.where_exp;
3618
  exp holdfe = son(fe);
3615
  exp holdfe = son(fe);
3619
  int  szf,			/* size of from */
3616
  int  szf,			/* size of from */
3620
        szt;			/* size of to */
3617
        szt;			/* size of to */
Line 3626... Line 3623...
3626
 
3623
 
3627
  szf = shape_size(fsh);
3624
  szf = shape_size(fsh);
3628
  sgf = is_signed(fsh);
3625
  sgf = is_signed(fsh);
3629
 
3626
 
3630
  /* set szt and sgt */
3627
  /* set szt and sgt */
3631
  switch (name (sha)) {
3628
  switch (name(sha)) {
3632
    case scharhd:
3629
    case scharhd:
3633
      szt = 8;
3630
      szt = 8;
3634
      sgt = 1;
3631
      sgt = 1;
3635
      break;
3632
      break;
3636
    case ucharhd:
3633
    case ucharhd:
Line 3658... Line 3655...
3658
      sgt = 0;
3655
      sgt = 0;
3659
      break;
3656
      break;
3660
    case bitfhd:
3657
    case bitfhd:
3661
      szt = 32;
3658
      szt = 32;
3662
      sgt = is_signed(sha);
3659
      sgt = is_signed(sha);
3663
      sha = (sgt) ? slongsh: ulongsh;
3660
      sha = (sgt)? slongsh: ulongsh;
3664
      break;
3661
      break;
3665
    default:
3662
    default:
3666
      szt = 32;
3663
      szt = 32;
3667
      sgt = 0;
3664
      sgt = 0;
3668
      break;
3665
      break;
3669
  };
3666
  };
3670
 
3667
 
3671
  if (name (fe) == val_tag) {	/* we know the value */
3668
  if (name (fe) == val_tag) {	/* we know the value */
3672
    int val;
3669
    int val;
3673
    if (!isbigval(fe)) {
3670
    if (!isbigval(fe)) {
3674
      val = dochvar (no (fe), sha);
3671
      val = dochvar(no(fe), sha);
3675
      if (overflow_e != nilexp && (dochvar (no (fe), fsh) != val || (val < 0 &&
3672
      if (overflow_e != nilexp && (dochvar(no(fe), fsh)!= val || (val < 0 &&
3676
		((szt == 32 && (sgt != sgf)) || (szt == 64 && !sgt && sgf)))))
3673
		((szt == 32 && (sgt != sgf)) || (szt == 64 && !sgt && sgf)))))
3677
	do_exception ();
3674
	do_exception();
3678
      no (fe) = val;
3675
      no(fe) = val;
3679
    }
3676
    }
3680
    else {
3677
    else {
3681
      flt64 x;
3678
      flt64 x;
3682
      int ov;
3679
      int ov;
3683
      x = flt_to_f64(no(fe), sgf, &ov);
3680
      x = flt_to_f64(no(fe), sgf, &ov);
3684
      val = dochvar ((int)(x.small), sha);
3681
      val = dochvar((int)(x.small), sha);
3685
      if (overflow_e != nilexp && (
3682
      if (overflow_e != nilexp && (
3686
		(szt == 64 && x.big < 0 && (sgt != sgf)) ||
3683
		(szt == 64 && x.big < 0 && (sgt != sgf)) ||
3687
		(szt == 32 && ((!(x.small & (1<<31)) && x.big != 0) ||
3684
		(szt == 32 && ((!(x.small & (1<<31)) && x.big != 0) ||
3688
			((x.small & (1<<31)) && x.big != -sgt))) ||
3685
			((x.small & (1<<31)) && x.big != -sgt))) ||
3689
		(szt < 32)))
3686
		(szt < 32)))
3690
	do_exception ();
3687
	do_exception();
3691
      if (szt != 64) {
3688
      if (szt != 64) {
3692
	no (fe) = val;
3689
	no(fe) = val;
3693
	clearbigval (fe);
3690
	clearbigval(fe);
3694
      }
3691
      }
3695
    };
3692
    };
3696
    sh (fe) = sha;
3693
    sh(fe) = sha;
3697
    move (sha, from, to);
3694
    move(sha, from, to);
3698
    return;
3695
    return;
3699
  };
3696
  };
3700
 
3697
 
3701
 
3698
 
3702
  if (name(fsh) == bitfhd) {
3699
  if (name(fsh) == bitfhd) {
3703
    if (szf < 8) {
3700
    if (szf < 8) {
3704
      if (sgf && !sgt) {
3701
      if (sgf && !sgt) {
3705
	and (scharsh, from, mw (zeroe, (1 << szf) - 1), reg0);
3702
	and(scharsh, from, mw(zeroe,(1 << szf) - 1), reg0);
3706
	from = reg0;
3703
	from = reg0;
3707
      }
3704
      }
3708
      szf = 8;
3705
      szf = 8;
3709
      fsh = (sgf) ? scharsh : ucharsh;
3706
      fsh = (sgf)? scharsh : ucharsh;
3710
    }
3707
    }
3711
    else
3708
    else
3712
    if (szf < 16) {
3709
    if (szf < 16) {
3713
      if (sgf && !sgt) {
3710
      if (sgf && !sgt) {
3714
	and (swordsh, from, mw (zeroe, (1 << szf) - 1), reg0);
3711
	and(swordsh, from, mw(zeroe,(1 << szf) - 1), reg0);
3715
	from = reg0;
3712
	from = reg0;
3716
      }
3713
      }
3717
      szf = 16;
3714
      szf = 16;
3718
      fsh = (sgf) ? swordsh : uwordsh;
3715
      fsh = (sgf)? swordsh : uwordsh;
3719
    }
3716
    }
3720
    else
3717
    else
3721
    if (szf < 32) {
3718
    if (szf < 32) {
3722
      if (sgf && !sgt) {
3719
      if (sgf && !sgt) {
3723
	and (slongsh, from, mw (zeroe, (1 << szf) - 1), reg0);
3720
	and(slongsh, from, mw(zeroe,(1 << szf) - 1), reg0);
3724
	from = reg0;
3721
	from = reg0;
3725
      }
3722
      }
3726
      szf = 32;
3723
      szf = 32;
3727
      fsh = (sgf) ? slongsh : ulongsh;
3724
      fsh = (sgf)? slongsh : ulongsh;
3728
    }
3725
    }
3729
  }
3726
  }
3730
 
3727
 
3731
  if (overflow_e != nilexp && (sgt < sgf || (szt - sgt) < (szf - sgf))) {
3728
  if (overflow_e != nilexp && (sgt < sgf || (szt - sgt) < (szf - sgf))) {
3732
    int smax = (szt == 64) ? 0x7fffffff : (1 << (szt-1)) - 1;
3729
    int smax = (szt == 64)? 0x7fffffff :(1 << (szt-1)) - 1;
3733
    int min = (sgt) ? (-smax)-1 : 0;
3730
    int min = (sgt)?(-smax) -1 : 0;
3734
    int max = (sgt) ? smax : smax+smax+1;
3731
    int max = (sgt)? smax : smax+smax+1;
3735
    if (inmem(from)) {
3732
    if (inmem(from)) {
3736
      move (fsh, from, reg0);
3733
      move(fsh, from, reg0);
3737
      from = reg0;
3734
      from = reg0;
3738
    };
3735
    };
3739
    if (szf == 64) {
3736
    if (szf == 64) {
3740
      if (szt == 64) {
3737
      if (szt == 64) {
3741
	IGNORE cmp (slongsh, reg1, zero, f_greater_than_or_equal, nilexp);
3738
	IGNORE cmp(slongsh, reg1, zero, f_greater_than_or_equal, nilexp);
3742
	test_exception (f_greater_than_or_equal, slongsh);
3739
	test_exception(f_greater_than_or_equal, slongsh);
3743
      }
3740
      }
3744
      else {
3741
      else {
3745
	int lab1;
3742
	int lab1;
3746
	IGNORE cmp (slongsh, reg1, zero, f_equal, nilexp);
3743
	IGNORE cmp(slongsh, reg1, zero, f_equal, nilexp);
3747
	if (sgf && sgt) {
3744
	if (sgf && sgt) {
3748
	  int lab2 = next_lab ();
3745
	  int lab2 = next_lab();
3749
	  lab1 = next_lab ();
3746
	  lab1 = next_lab();
3750
	  simple_branch (je, lab2);
3747
	  simple_branch(je, lab2);
3751
	  IGNORE cmp (slongsh, reg1, mw(zeroe,-1), f_equal, nilexp);
3748
	  IGNORE cmp(slongsh, reg1, mw(zeroe,-1), f_equal, nilexp);
3752
	  test_exception (f_equal, slongsh);
3749
	  test_exception(f_equal, slongsh);
3753
	  IGNORE cmp (ulongsh, from, mw(zeroe,min), f_greater_than_or_equal, nilexp);
3750
	  IGNORE cmp(ulongsh, from, mw(zeroe,min), f_greater_than_or_equal, nilexp);
3754
	  test_exception (f_greater_than_or_equal, ulongsh);
3751
	  test_exception(f_greater_than_or_equal, ulongsh);
3755
	  simple_branch (jmp, lab1);
3752
	  simple_branch(jmp, lab1);
3756
	  simplest_set_lab (lab2);
3753
	  simplest_set_lab(lab2);
3757
	}
3754
	}
3758
	else
3755
	else
3759
	  test_exception (f_equal, slongsh);
3756
	  test_exception(f_equal, slongsh);
3760
	if (szt != 32 || sgt) {
3757
	if (szt != 32 || sgt) {
3761
	  IGNORE cmp (ulongsh, reg0, mw(zeroe,max), f_less_than_or_equal, nilexp);
3758
	  IGNORE cmp(ulongsh, reg0, mw(zeroe,max), f_less_than_or_equal, nilexp);
3762
	  test_exception (f_less_than_or_equal, ulongsh);
3759
	  test_exception(f_less_than_or_equal, ulongsh);
3763
	};
3760
	};
3764
	if (sgf && sgt)
3761
	if (sgf && sgt)
3765
	  simplest_set_lab (lab1);
3762
	  simplest_set_lab(lab1);
3766
      };
3763
      };
3767
    }
3764
    }
3768
    else {
3765
    else {
3769
      if (sgf && (!sgt || szt < szf)) {
3766
      if (sgf && (!sgt || szt < szf)) {
3770
	IGNORE cmp (fsh, from, mw(zeroe,min), f_greater_than_or_equal, nilexp);
3767
	IGNORE cmp(fsh, from, mw(zeroe,min), f_greater_than_or_equal, nilexp);
3771
	test_exception (f_greater_than_or_equal, fsh);
3768
	test_exception(f_greater_than_or_equal, fsh);
3772
      };
3769
      };
3773
      if ((szt - sgt) < (szf - sgf)) {
3770
      if ((szt - sgt) < (szf - sgf)) {
3774
	IGNORE cmp (fsh, from, mw(zeroe,max), f_less_than_or_equal, nilexp);
3771
	IGNORE cmp(fsh, from, mw(zeroe,max), f_less_than_or_equal, nilexp);
3775
	test_exception (f_less_than_or_equal, fsh);
3772
	test_exception(f_less_than_or_equal, fsh);
3776
      };
3773
      };
3777
    };
3774
    };
3778
  }
3775
  }
3779
 
3776
 
3780
  if (szf == 8) {
3777
  if (szf == 8) {
3781
    if (bad_from_reg(from)) {
3778
    if (bad_from_reg(from)) {
3782
      move (slongsh, from, reg0);
3779
      move(slongsh, from, reg0);
3783
      from = reg0;
3780
      from = reg0;
3784
    };
3781
    };
3785
 
3782
 
3786
    if (szt == 8) {
3783
    if (szt == 8) {
3787
      move (sha, from, to);
3784
      move(sha, from, to);
3788
      return;
3785
      return;
3789
    };
3786
    };
3790
 
3787
 
3791
    if (szt == 16) {
3788
    if (szt == 16) {
3792
      if (sgf) {
3789
      if (sgf) {
3793
	if (inmem (to)) {
3790
	if (inmem(to)) {
3794
	  contop (fe, eq_where (reg0, from), reg0);
3791
	  contop(fe, eq_where(reg0, from), reg0);
3795
	  ins2 (movsbw, szf, szt, from, reg0);
3792
	  ins2(movsbw, szf, szt, from, reg0);
3796
	  invalidate_dest (reg0);
3793
	  invalidate_dest(reg0);
3797
	  end_contop ();
3794
	  end_contop();
3798
	  move (sha, reg0, to);
3795
	  move(sha, reg0, to);
3799
	}
3796
	}
3800
	else {
3797
	else {
3801
	  contop (fe, eq_where (reg0, from), to);
3798
	  contop(fe, eq_where(reg0, from), to);
3802
	  ins2 (movsbw, szf, szt, from, to);
3799
	  ins2(movsbw, szf, szt, from, to);
3803
	  invalidate_dest (to);
3800
	  invalidate_dest(to);
3804
	  end_contop ();
3801
	  end_contop();
3805
	};
3802
	};
3806
	son(fe) = holdfe;
3803
	son(fe) = holdfe;
3807
	return;
3804
	return;
3808
      }
3805
      }
3809
      else {
3806
      else {
3810
	if (inmem (to)) {
3807
	if (inmem(to)) {
3811
	  contop (fe, eq_where (reg0, from), reg0);
3808
	  contop(fe, eq_where(reg0, from), reg0);
3812
	  ins2 (movzbw, szf, szt, from, reg0);
3809
	  ins2(movzbw, szf, szt, from, reg0);
3813
	  invalidate_dest (reg0);
3810
	  invalidate_dest(reg0);
3814
	  end_contop ();
3811
	  end_contop();
3815
	  move (sha, reg0, to);
3812
	  move(sha, reg0, to);
3816
	}
3813
	}
3817
	else {
3814
	else {
3818
	  contop (fe, eq_where (reg0, from), to);
3815
	  contop(fe, eq_where(reg0, from), to);
3819
	  ins2 (movzbw, szf, szt, from, to);
3816
	  ins2(movzbw, szf, szt, from, to);
3820
	  invalidate_dest (to);
3817
	  invalidate_dest(to);
3821
	  end_contop ();
3818
	  end_contop();
3822
	};
3819
	};
3823
	son(fe) = holdfe;
3820
	son(fe) = holdfe;
3824
	return;
3821
	return;
3825
      };
3822
      };
3826
    };
3823
    };
3827
    if (szt >= 32) {
3824
    if (szt >= 32) {
3828
      if (sgf) {
3825
      if (sgf) {
3829
	if (inmem (to) || szt == 64) {
3826
	if (inmem(to) || szt == 64) {
3830
	  contop (fe, eq_where (reg0, from), reg0);
3827
	  contop(fe, eq_where(reg0, from), reg0);
3831
	  ins2 (movsbl, szf, 32, from, reg0);
3828
	  ins2(movsbl, szf, 32, from, reg0);
3832
	  invalidate_dest (reg0);
3829
	  invalidate_dest(reg0);
3833
	  end_contop ();
3830
	  end_contop();
3834
	  if (szt == 64) {
3831
	  if (szt == 64) {
3835
	    if (sgt) {
3832
	    if (sgt) {
3836
	      move (slongsh, reg0, reg1);
3833
	      move(slongsh, reg0, reg1);
3837
	      ins2 (sarl, 8, 32, mw(zeroe,31), reg1);
3834
	      ins2(sarl, 8, 32, mw(zeroe,31), reg1);
3838
	    }
3835
	    }
3839
	    else
3836
	    else
3840
	      move (ulongsh, zero, reg1);
3837
	      move(ulongsh, zero, reg1);
3841
	  };
3838
	  };
3842
	  move (sha, reg0, to);
3839
	  move(sha, reg0, to);
3843
	}
3840
	}
3844
	else {
3841
	else {
3845
	  contop (fe, eq_where (reg0, from), to);
3842
	  contop(fe, eq_where(reg0, from), to);
3846
	  ins2 (movsbl, szf, szt, from, to);
3843
	  ins2(movsbl, szf, szt, from, to);
3847
	  invalidate_dest (to);
3844
	  invalidate_dest(to);
3848
	  end_contop ();
3845
	  end_contop();
3849
	};
3846
	};
3850
	son(fe) = holdfe;
3847
	son(fe) = holdfe;
3851
	return;
3848
	return;
3852
      };
3849
      };
3853
      if (inmem (to) || szt == 64) {
3850
      if (inmem(to) || szt == 64) {
3854
	move(scharsh, from, reg0);
3851
	move(scharsh, from, reg0);
3855
	and(slongsh, reg0, mw(zeroe, 0xff), reg0);
3852
	and(slongsh, reg0, mw(zeroe, 0xff), reg0);
3856
	if (szt == 64)
3853
	if (szt == 64)
3857
	  move (ulongsh, zero, reg1);
3854
	  move(ulongsh, zero, reg1);
3858
	move (sha, reg0, to);
3855
	move(sha, reg0, to);
3859
	}
3856
	}
3860
      else {
3857
      else {
3861
	if (eq_where(to, reg4)|| eq_where(to, reg5)||
3858
	if (eq_where(to, reg4) || eq_where(to, reg5) ||
3862
		 eq_where(to, reg6)) {
3859
		 eq_where(to, reg6)) {
3863
	  contop (fe, eq_where (reg0, from), to);
3860
	  contop(fe, eq_where(reg0, from), to);
3864
	  ins2 (movzbl, szf, szt, from, to);
3861
	  ins2(movzbl, szf, szt, from, to);
3865
	  invalidate_dest (to);
3862
	  invalidate_dest(to);
3866
	  end_contop ();
3863
	  end_contop();
3867
	}
3864
	}
3868
	else {
3865
	else {
3869
	  move(scharsh, from, to);
3866
	  move(scharsh, from, to);
3870
	  and(slongsh, to, mw(zeroe, 0xff), to);
3867
	  and(slongsh, to, mw(zeroe, 0xff), to);
3871
	};
3868
	};
3872
      };
3869
      };
3873
      son(fe) = holdfe;
3870
      son(fe) = holdfe;
3874
      return;
3871
      return;
3875
    };
3872
    };
3876
  };
3873
  };
3877
 
3874
 
3878
  if (szf == 16) {
3875
  if (szf == 16) {
3879
    if (szt == 8) {
3876
    if (szt == 8) {
3880
      if (bad_from_reg(from)) {
3877
      if (bad_from_reg(from)) {
3881
        move (slongsh, from, reg0);
3878
        move(slongsh, from, reg0);
3882
        from = reg0;
3879
        from = reg0;
3883
      };
3880
      };
3884
 
3881
 
3885
      if (sgt) {
3882
      if (sgt) {
3886
	if (inmem (to)) {
3883
	if (inmem(to)) {
3887
	  move (sh (fe), from, reg0);
3884
	  move(sh(fe), from, reg0);
3888
	  move (sha, reg0, to);
3885
	  move(sha, reg0, to);
3889
	}
3886
	}
3890
	else
3887
	else
3891
	  move (sha, from, to);
3888
	  move(sha, from, to);
3892
	son(fe) = holdfe;
3889
	son(fe) = holdfe;
3893
	return;
3890
	return;
3894
      };
3891
      };
3895
      move (sha, from, to);
3892
      move(sha, from, to);
3896
      son(fe) = holdfe;
3893
      son(fe) = holdfe;
3897
      return;
3894
      return;
3898
    };
3895
    };
3899
    if (szt == 16) {
3896
    if (szt == 16) {
3900
      move (sha, from, to);
3897
      move(sha, from, to);
3901
      son(fe) = holdfe;
3898
      son(fe) = holdfe;
3902
      return;
3899
      return;
3903
    };
3900
    };
3904
    if (sgf) {
3901
    if (sgf) {
3905
      if (inmem (to) || szt == 64) {
3902
      if (inmem(to) || szt == 64) {
3906
	contop (fe, eq_where (reg0, from), reg0);
3903
	contop(fe, eq_where(reg0, from), reg0);
3907
	ins2 (movswl, szf, 32, from, reg0);
3904
	ins2(movswl, szf, 32, from, reg0);
3908
	invalidate_dest (reg0);
3905
	invalidate_dest(reg0);
3909
	end_contop ();
3906
	end_contop();
3910
	if (szt == 64) {
3907
	if (szt == 64) {
3911
	  if (sgt) {
3908
	  if (sgt) {
3912
	    move (slongsh, reg0, reg1);
3909
	    move(slongsh, reg0, reg1);
3913
	    ins2 (sarl, 8, 32, mw(zeroe,31), reg1);
3910
	    ins2(sarl, 8, 32, mw(zeroe,31), reg1);
3914
	  }
3911
	  }
3915
	  else
3912
	  else
3916
	    move (ulongsh, zero, reg1);
3913
	    move(ulongsh, zero, reg1);
3917
	};
3914
	};
3918
	move (sha, reg0, to);
3915
	move(sha, reg0, to);
3919
      }
3916
      }
3920
      else {
3917
      else {
3921
	contop (fe, eq_where (reg0, from), to);
3918
	contop(fe, eq_where(reg0, from), to);
3922
	ins2 (movswl, szf, szt, from, to);
3919
	ins2(movswl, szf, szt, from, to);
3923
	invalidate_dest (to);
3920
	invalidate_dest(to);
3924
	end_contop ();
3921
	end_contop();
3925
      };
3922
      };
3926
      son(fe) = holdfe;
3923
      son(fe) = holdfe;
3927
      return;
3924
      return;
3928
    };
3925
    };
3929
    if (inmem (to) || szt == 64) {
3926
    if (inmem(to) || szt == 64) {
3930
      move(swordsh, from, reg0);
3927
      move(swordsh, from, reg0);
3931
      and(slongsh, reg0, mw(zeroe, 0xffff), reg0);
3928
      and(slongsh, reg0, mw(zeroe, 0xffff), reg0);
3932
      if (szt == 64)
3929
      if (szt == 64)
3933
	move (ulongsh, zero, reg1);
3930
	move(ulongsh, zero, reg1);
3934
      move (sha, reg0, to);
3931
      move(sha, reg0, to);
3935
    }
3932
    }
3936
    else {
3933
    else {
3937
      move(swordsh, from, to);
3934
      move(swordsh, from, to);
3938
      and(slongsh, to, mw(zeroe, 0xffff), to);
3935
      and(slongsh, to, mw(zeroe, 0xffff), to);
3939
    };
3936
    };
Line 3942... Line 3939...
3942
  };
3939
  };
3943
 
3940
 
3944
  if (szf >= 32) {
3941
  if (szf >= 32) {
3945
    if (szt == 8) {
3942
    if (szt == 8) {
3946
      if (bad_from_reg(from)) {
3943
      if (bad_from_reg(from)) {
3947
        move (slongsh, from, reg0);
3944
        move(slongsh, from, reg0);
3948
        from = reg0;
3945
        from = reg0;
3949
      };
3946
      };
3950
      if (sgt) {
3947
      if (sgt) {
3951
        if (inmem (from) && inmem (to)) {
3948
        if (inmem(from) && inmem(to)) {
3952
	  move (sh (fe), from, reg0);
3949
	  move(sh(fe), from, reg0);
3953
	  move (sha, reg0, to);
3950
	  move(sha, reg0, to);
3954
        }
3951
        }
3955
        else
3952
        else
3956
	  move (sha, from, to);
3953
	  move(sha, from, to);
3957
	son(fe) = holdfe;
3954
	son(fe) = holdfe;
3958
        return;
3955
        return;
3959
      };
3956
      };
3960
      move (sha, from, to);
3957
      move(sha, from, to);
3961
      son(fe) = holdfe;
3958
      son(fe) = holdfe;
3962
      return;
3959
      return;
3963
    };
3960
    };
3964
 
3961
 
3965
    if (szt == 16) {
3962
    if (szt == 16) {
3966
      if (sgt) {
3963
      if (sgt) {
3967
        if (inmem (to)) {
3964
        if (inmem(to)) {
3968
	  move (sha, from, reg0);
3965
	  move(sha, from, reg0);
3969
  	  move (sha, reg0, to);
3966
  	  move(sha, reg0, to);
3970
        }
3967
        }
3971
        else
3968
        else
3972
  	  move (sha, from, to);
3969
  	  move(sha, from, to);
3973
	son(fe) = holdfe;
3970
	son(fe) = holdfe;
3974
        return;
3971
        return;
3975
      };
3972
      };
3976
      move (sha, from, to);
3973
      move(sha, from, to);
3977
      son(fe) = holdfe;
3974
      son(fe) = holdfe;
3978
      return;
3975
      return;
3979
    };
3976
    };
3980
    if (szt > szf) {
3977
    if (szt > szf) {
3981
      move (slongsh, from, reg0);
3978
      move(slongsh, from, reg0);
3982
      if (sgf && sgt) {
3979
      if (sgf && sgt) {
3983
	move (slongsh, reg0, reg1);
3980
	move(slongsh, reg0, reg1);
3984
	ins2 (sarl, 8, 32, mw(zeroe,31), reg1);
3981
	ins2(sarl, 8, 32, mw(zeroe,31), reg1);
3985
      }
3982
      }
3986
      else
3983
      else
3987
	move (ulongsh, zero, reg1);
3984
	move(ulongsh, zero, reg1);
3988
      invalidate_dest (reg0);
3985
      invalidate_dest(reg0);
3989
      from = reg0;
3986
      from = reg0;
3990
    }
3987
    }
3991
    move (sha, from, to);
3988
    move(sha, from, to);
3992
    son(fe) = holdfe;
3989
    son(fe) = holdfe;
3993
    return;
3990
    return;
3994
  };
3991
  };
3995
 
3992
 
3996
  if (!sgf)  {
3993
  if (!sgf) {
3997
    move (sha, from, to);
3994
    move(sha, from, to);
3998
    son(fe) = holdfe;
3995
    son(fe) = holdfe;
3999
    return;
3996
    return;
4000
  };
3997
  };
4001
 
3998
 
4002
  move(sha, from, to);
3999
  move(sha, from, to);
4003
  son(fe) = holdfe;
4000
  son(fe) = holdfe;
4004
  return;
4001
  return;
4005
}
4002
}
4006
 
4003
 
4007
/* change variety from to sha, and put in to */
4004
/* change variety from to sha, and put in to */
4008
void change_var
4005
void change_var
4009
    PROTO_N ( (sha, from, to) )
-
 
4010
    PROTO_T ( shape sha X where from X where to )
4006
(shape sha, where from, where to)
4011
{
4007
{
4012
  exp fe = from.where_exp;
4008
  exp fe = from.where_exp;
4013
  shape fsh = sh (fe);
4009
  shape fsh = sh(fe);
4014
  exp old_overflow_e = overflow_e;
4010
  exp old_overflow_e = overflow_e;
4015
  overflow_e = nilexp;
4011
  overflow_e = nilexp;
4016
  change_var_sh (sha, fsh, from, to);
4012
  change_var_sh(sha, fsh, from, to);
4017
  overflow_e = old_overflow_e;
4013
  overflow_e = old_overflow_e;
4018
  return;
4014
  return;
4019
}
4015
}
4020
 
4016
 
4021
/* change variety from to sha, and put in to */
4017
/* change variety from to sha, and put in to */
4022
void change_var_check
4018
void change_var_check
4023
    PROTO_N ( (sha, from, to) )
-
 
4024
    PROTO_T ( shape sha X where from X where to )
4019
(shape sha, where from, where to)
4025
{
4020
{
4026
  exp fe = from.where_exp;
4021
  exp fe = from.where_exp;
4027
  shape fsh = sh (fe);
4022
  shape fsh = sh(fe);
4028
  change_var_sh (sha, fsh, from, to);
4023
  change_var_sh(sha, fsh, from, to);
4029
  return;
4024
  return;
4030
}
4025
}
4031
 
4026
 
4032
/* op values a1, a2 of shape sha and put
4027
/* op values a1, a2 of shape sha and put
4033
   them in dest. opb, opw and opl are the
4028
   them in dest. opb, opw and opl are the
4034
   byte, short and long versions of the
4029
   byte, short and long versions of the
4035
   operator. one is the unit for the
4030
   operator. one is the unit for the
4036
   operator. Similar to plus qv. for
4031
   operator. Similar to plus qv. for
4037
   comments.  */
4032
   comments.  */
4038
void andetc
4033
void andetc
4039
    PROTO_N ( (opb, opw, opl, one, sha, a1, a2, dest) )
-
 
4040
    PROTO_T ( char *opb X char *opw X char *opl X int one X shape sha X where a1 X where a2 X where dest )
4034
(char *opb, char *opw, char *opl, int one, shape sha, where a1, where a2, where dest)
4041
{
4035
{
4042
  int  sz;
4036
  int  sz;
4043
  exp a = a1.where_exp;
4037
  exp a = a1.where_exp;
4044
  int  aoff = a1.where_off;
4038
  int  aoff = a1.where_off;
4045
  exp b = a2.where_exp;
4039
  exp b = a2.where_exp;
4046
  int  boff = a2.where_off;
4040
  int  boff = a2.where_off;
4047
  exp holda = son(a);
4041
  exp holda = son(a);
4048
  exp holdb = son(b);
4042
  exp holdb = son(b);
4049
  sz = shape_size(sha);
4043
  sz = shape_size(sha);
4050
 
4044
 
4051
  if (name (a) == val_tag && !isbigval(a) && no (a) + aoff == one) {
4045
  if (name(a) == val_tag && !isbigval(a) && no(a) + aoff == one) {
4052
    move (sha, a2, dest);
4046
    move(sha, a2, dest);
4053
    return;
4047
    return;
4054
  };
4048
  };
4055
 
4049
 
4056
  if (name (b) == val_tag && !isbigval(b) && no (b) + boff == one) {
4050
  if (name(b) == val_tag && !isbigval(b) && no(b) + boff == one) {
4057
    move (sha, a1, dest);
4051
    move(sha, a1, dest);
4058
    return;
4052
    return;
4059
  };
4053
  };
4060
 
4054
 
4061
  cond1_set = 1;
4055
  cond1_set = 1;
4062
  cond2_set = 0;
4056
  cond2_set = 0;
4063
  cond1 = dest;			/* conditions will be set from dest */
4057
  cond1 = dest;			/* conditions will be set from dest */
4064
 
4058
 
4065
  if (eq_where (a1, dest) &&
4059
  if (eq_where(a1, dest) &&
4066
	(!keep_short || !flinmem(dest))) {
4060
	(!keep_short || !flinmem(dest))) {
4067
    if (!inmem (a1) || !inmem (a2)) {
4061
    if (!inmem(a1) || !inmem(a2)) {
4068
      /* use 2 address */
4062
      /* use 2 address */
4069
      int riu = regsinuse;
4063
      int riu = regsinuse;
4070
      if (sz == 64)
4064
      if (sz == 64)
4071
	regsinuse |= 0x2;
4065
	regsinuse |= 0x2;
4072
      if (inmem (a1))
4066
      if (inmem(a1))
4073
	contop (a, eq_where (reg0, a2), a1);
4067
	contop(a, eq_where(reg0, a2), a1);
4074
      else
4068
      else
4075
	contop (b,
4069
	contop(b,
4076
	     (eq_where (reg0, a2) || eq_where (reg0, a1)), a1);
4070
	    (eq_where(reg0, a2) || eq_where(reg0, a1)), a1);
4077
      if (sz == 8) {
4071
      if (sz == 8) {
4078
	ins2 (opb, sz, sz, a2, a1);
4072
	ins2(opb, sz, sz, a2, a1);
4079
      }
4073
      }
4080
      else
4074
      else
4081
      if (sz == 16) {
4075
      if (sz == 16) {
4082
	ins2 (opw, sz, sz, a2, a1);
4076
	ins2(opw, sz, sz, a2, a1);
4083
      }
4077
      }
4084
      else
4078
      else
4085
      if (sz == 32) {
4079
      if (sz == 32) {
4086
	ins2 (opl, sz, sz, a2, a1);
4080
	ins2(opl, sz, sz, a2, a1);
4087
      }
4081
      }
4088
      else
4082
      else
4089
      if (sz == 64) {
4083
      if (sz == 64) {
4090
	where dhi, dlo, shi, slo;
4084
	where dhi, dlo, shi, slo;
4091
	if (inmem(a1)) {
4085
	if (inmem(a1)) {
4092
	  dlo = a1;
4086
	  dlo = a1;
4093
	  dhi = mw (a, aoff+32);
4087
	  dhi = mw(a, aoff+32);
4094
	}
4088
	}
4095
	else {
4089
	else {
4096
	  dlo = reg0;
4090
	  dlo = reg0;
4097
	  dhi = reg1;
4091
	  dhi = reg1;
4098
	};
4092
	};
4099
	if (name(b) == val_tag) {
4093
	if (name(b) == val_tag) {
4100
	  int c, c1;
4094
	  int c, c1;
4101
	  if (!isbigval(b)) {
4095
	  if (!isbigval(b)) {
4102
	    c = no(b) + boff;
4096
	    c = no(b) + boff;
4103
	    c1 = (name(sha) == s64hd && c < 0) ? -1 : 0;
4097
	    c1 = (name(sha) == s64hd && c < 0)? -1 : 0;
4104
	  }
4098
	  }
4105
	  else {
4099
	  else {
4106
	    flt64 x;
4100
	    flt64 x;
4107
	    int ov;
4101
	    int ov;
4108
	    x = flt_to_f64(no(b), is_signed(sha), &ov);
4102
	    x = flt_to_f64(no(b), is_signed(sha), &ov);
4109
	    c = x.small;
4103
	    c = x.small;
4110
	    c1 = x.big;
4104
	    c1 = x.big;
4111
	  }
4105
	  }
4112
	  if (c != one)
4106
	  if (c != one)
4113
	    ins2 (opl, 32, 32, mw(zeroe, c), dlo);
4107
	    ins2(opl, 32, 32, mw(zeroe, c), dlo);
4114
	  if (c1 != one)
4108
	  if (c1 != one)
4115
	    ins2 (opl, 32, 32, mw(zeroe, c1), dhi);
4109
	    ins2(opl, 32, 32, mw(zeroe, c1), dhi);
4116
	}
4110
	}
4117
	else {
4111
	else {
4118
	  if (inmem(a2)) {
4112
	  if (inmem(a2)) {
4119
	    slo = a2;
4113
	    slo = a2;
4120
	    shi = mw (b, boff+32);
4114
	    shi = mw(b, boff+32);
4121
	  }
4115
	  }
4122
	  else {
4116
	  else {
4123
	    slo = reg0;
4117
	    slo = reg0;
4124
	    shi = reg1;
4118
	    shi = reg1;
4125
	  };
4119
	  };
4126
	  ins2 (opl, 32, 32, slo, dlo);
4120
	  ins2(opl, 32, 32, slo, dlo);
4127
	  ins2 (opl, 32, 32, shi, dhi);
4121
	  ins2(opl, 32, 32, shi, dhi);
4128
	};
4122
	};
4129
      };
4123
      };
4130
      invalidate_dest (dest);
4124
      invalidate_dest(dest);
4131
      end_contop ();
4125
      end_contop();
4132
      regsinuse = riu;
4126
      regsinuse = riu;
4133
      son(a) = holda;
4127
      son(a) = holda;
4134
      son(b) = holdb;
4128
      son(b) = holdb;
4135
      return;
4129
      return;
4136
    };
4130
    };
4137
 
4131
 
4138
    move (sha, a2, reg0);
4132
    move(sha, a2, reg0);
4139
    andetc (opb, opw, opl, one, sha, reg0, dest, dest);
4133
    andetc(opb, opw, opl, one, sha, reg0, dest, dest);
4140
    return;
4134
    return;
4141
  };
4135
  };
4142
 
4136
 
4143
  if (eq_where (a2, dest) &&
4137
  if (eq_where(a2, dest) &&
4144
	(!keep_short || !flinmem(dest))) {	/* use 2 address */
4138
	(!keep_short || !flinmem(dest))) {	/* use 2 address */
4145
    if (!inmem (a1) || !inmem (a2)) {
4139
    if (!inmem(a1) || !inmem(a2)) {
4146
      int riu = regsinuse;
4140
      int riu = regsinuse;
4147
      if (sz == 64)
4141
      if (sz == 64)
4148
	regsinuse |= 0x2;
4142
	regsinuse |= 0x2;
4149
      if (inmem (a1))
4143
      if (inmem(a1))
4150
	contop (a, eq_where (reg0, a2), a2);
4144
	contop(a, eq_where(reg0, a2), a2);
4151
      else
4145
      else
4152
	contop (b,
4146
	contop(b,
4153
	     (eq_where (reg0, a1) || eq_where (reg0, a2)), a2);
4147
	    (eq_where(reg0, a1) || eq_where(reg0, a2)), a2);
4154
      if (sz == 8) {
4148
      if (sz == 8) {
4155
	ins2 (opb, sz, sz, a1, a2);
4149
	ins2(opb, sz, sz, a1, a2);
4156
      }
4150
      }
4157
      else
4151
      else
4158
      if (sz == 16) {
4152
      if (sz == 16) {
4159
	ins2 (opw, sz, sz, a1, a2);
4153
	ins2(opw, sz, sz, a1, a2);
4160
      }
4154
      }
4161
      if (sz == 32) {
4155
      if (sz == 32) {
4162
	ins2 (opl, sz, sz, a1, a2);
4156
	ins2(opl, sz, sz, a1, a2);
4163
      }
4157
      }
4164
      else
4158
      else
4165
      if (sz == 64) {
4159
      if (sz == 64) {
4166
	where dhi, dlo, shi, slo;
4160
	where dhi, dlo, shi, slo;
4167
	if (inmem(a2)) {
4161
	if (inmem(a2)) {
4168
	  dlo = a2;
4162
	  dlo = a2;
4169
	  dhi = mw (b, boff+32);
4163
	  dhi = mw(b, boff+32);
4170
	}
4164
	}
4171
	else {
4165
	else {
4172
	  dlo = reg0;
4166
	  dlo = reg0;
4173
	  dhi = reg1;
4167
	  dhi = reg1;
4174
	};
4168
	};
4175
	if (name(a) == val_tag) {
4169
	if (name(a) == val_tag) {
4176
	  int c, c1;
4170
	  int c, c1;
4177
	  if (!isbigval(a)) {
4171
	  if (!isbigval(a)) {
4178
	    c = no(a) + aoff;
4172
	    c = no(a) + aoff;
4179
	    c1 = (name(sha) == s64hd && c < 0) ? -1 : 0;
4173
	    c1 = (name(sha) == s64hd && c < 0)? -1 : 0;
4180
	  }
4174
	  }
4181
	  else {
4175
	  else {
4182
	    flt64 x;
4176
	    flt64 x;
4183
	    int ov;
4177
	    int ov;
4184
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
4178
	    x = flt_to_f64(no(a), is_signed(sha), &ov);
4185
	    c = x.small;
4179
	    c = x.small;
4186
	    c1 = x.big;
4180
	    c1 = x.big;
4187
	  }
4181
	  }
4188
	  if (c != one)
4182
	  if (c != one)
4189
	    ins2 (opl, 32, 32, mw(zeroe, c), dlo);
4183
	    ins2(opl, 32, 32, mw(zeroe, c), dlo);
4190
	  if (c1 != one)
4184
	  if (c1 != one)
4191
	    ins2 (opl, 32, 32, mw(zeroe, c1), dhi);
4185
	    ins2(opl, 32, 32, mw(zeroe, c1), dhi);
4192
	}
4186
	}
4193
	else {
4187
	else {
4194
	  if (inmem(a1)) {
4188
	  if (inmem(a1)) {
4195
	    slo = a1;
4189
	    slo = a1;
4196
	    shi = mw (a, aoff+32);
4190
	    shi = mw(a, aoff+32);
4197
	  }
4191
	  }
4198
	  else {
4192
	  else {
4199
	    slo = reg0;
4193
	    slo = reg0;
4200
	    shi = reg1;
4194
	    shi = reg1;
4201
	  };
4195
	  };
4202
	  ins2 (opl, 32, 32, slo, dlo);
4196
	  ins2(opl, 32, 32, slo, dlo);
4203
	  ins2 (opl, 32, 32, shi, dhi);
4197
	  ins2(opl, 32, 32, shi, dhi);
4204
	};
4198
	};
4205
      };
4199
      };
4206
      invalidate_dest (dest);
4200
      invalidate_dest(dest);
4207
      end_contop ();
4201
      end_contop();
4208
      regsinuse = riu;
4202
      regsinuse = riu;
4209
      son(a) = holda;
4203
      son(a) = holda;
4210
      son(b) = holdb;
4204
      son(b) = holdb;
4211
      return;
4205
      return;
4212
    };
4206
    };
4213
 
4207
 
4214
    move (sha, a1, reg0);
4208
    move(sha, a1, reg0);
4215
    andetc (opb, opw, opl, one, sha, reg0, dest, dest);
4209
    andetc(opb, opw, opl, one, sha, reg0, dest, dest);
4216
    return;
4210
    return;
4217
  };
4211
  };
4218
 
4212
 
4219
  switch ((inmem (a1) << 2) + (inmem (a2) << 1) + inmem (dest)) {
4213
  switch ((inmem(a1) << 2) + (inmem(a2) << 1) + inmem(dest)) {
4220
    case 0:
4214
    case 0:
4221
      move (sha, a2, dest);
4215
      move(sha, a2, dest);
4222
      andetc (opb, opw, opl, one, sha, a1, dest, dest);
4216
      andetc(opb, opw, opl, one, sha, a1, dest, dest);
4223
      return;
4217
      return;
4224
    case 1:
4218
    case 1:
4225
    case 3:
4219
    case 3:
4226
    case 5:
4220
    case 5:
4227
    case 7:
4221
    case 7:
4228
      andetc (opb, opw, opl, one, sha, a1, a2, reg0);
4222
      andetc(opb, opw, opl, one, sha, a1, a2, reg0);
4229
      move (sha, reg0, dest);
4223
      move(sha, reg0, dest);
4230
      return;
4224
      return;
4231
    case 2:
4225
    case 2:
4232
      if (eq_where (a1, reg0))
4226
      if (eq_where(a1, reg0))
4233
	reg0_in_use = 1;
4227
	reg0_in_use = 1;
4234
      move (sha, a2, dest);
4228
      move(sha, a2, dest);
4235
      andetc (opb, opw, opl, one, sha, a1, dest, dest);
4229
      andetc(opb, opw, opl, one, sha, a1, dest, dest);
4236
      return;
4230
      return;
4237
    case 4:
4231
    case 4:
4238
      if (eq_where (a2, reg0))
4232
      if (eq_where(a2, reg0))
4239
	reg0_in_use = 1;
4233
	reg0_in_use = 1;
4240
      move (sha, a1, dest);
4234
      move(sha, a1, dest);
4241
      andetc (opb, opw, opl, one, sha, a2, dest, dest);
4235
      andetc(opb, opw, opl, one, sha, a2, dest, dest);
4242
      return;
4236
      return;
4243
    default: 			/* case 6 */
4237
    default: 			/* case 6 */
4244
      move (sha, a2, reg0);
4238
      move(sha, a2, reg0);
4245
      andetc (opb, opw, opl, one, sha, a1, reg0, reg0);
4239
      andetc(opb, opw, opl, one, sha, a1, reg0, reg0);
4246
      move (sha, reg0, dest);
4240
      move(sha, reg0, dest);
4247
      return;
4241
      return;
4248
  };
4242
  };
4249
 
4243
 
4250
}
4244
}
4251
 
4245
 
4252
void and
4246
void and
4253
    PROTO_N ( (sha, a1, a2, dest) )
-
 
4254
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
4247
(shape sha, where a1, where a2, where dest)
4255
{
4248
{
4256
  andetc (andb, andw, andl, -1, sha, a1, a2, dest);
4249
  andetc(andb, andw, andl, -1, sha, a1, a2, dest);
4257
  return;
4250
  return;
4258
}
4251
}
4259
 
4252
 
4260
void or
4253
void or
4261
    PROTO_N ( (sha, a1, a2, dest) )
-
 
4262
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
4254
(shape sha, where a1, where a2, where dest)
4263
{
4255
{
4264
  andetc (orb, orw, orl, 0, sha, a1, a2, dest);
4256
  andetc(orb, orw, orl, 0, sha, a1, a2, dest);
4265
  return;
-
 
4266
}
-
 
4267
 
-
 
4268
void xor
-
 
4269
    PROTO_N ( (sha, a1, a2, dest) )
-
 
4270
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
-
 
4271
{
-
 
4272
  andetc (xorb, xorw, xorl, 0, sha, a1, a2, dest);
-
 
4273
  return;
4257
  return;
4274
}
4258
}
4275
 
4259
 
-
 
4260
void xor
-
 
4261
(shape sha, where a1, where a2, where dest)
-
 
4262
{
-
 
4263
  andetc(xorb, xorw, xorl, 0, sha, a1, a2, dest);
-
 
4264
  return;
-
 
4265
}
-
 
4266
 
4276
 
4267
 
4277
static void needs_lib64
4268
static void needs_lib64
4278
    PROTO_Z ()
4269
(void)
4279
{
4270
{
4280
  if (!lib64_set) {
4271
  if (!lib64_set) {
4281
    lib64_s_mult = make_extn ("__TDFUs_mult", f_proc, 0);
4272
    lib64_s_mult = make_extn("__TDFUs_mult", f_proc, 0);
4282
    lib64_u_mult = make_extn ("__TDFUu_mult", f_proc, 0);
4273
    lib64_u_mult = make_extn("__TDFUu_mult", f_proc, 0);
4283
    lib64_div[0] = make_extn ("__TDFUu_div2", f_proc, 0);
4274
    lib64_div[0] = make_extn("__TDFUu_div2", f_proc, 0);
4284
    lib64_div[1] = make_extn ("__TDFUs_div2", f_proc, 0);
4275
    lib64_div[1] = make_extn("__TDFUs_div2", f_proc, 0);
4285
    lib64_div[2] = make_extn ("__TDFUu_div1", f_proc, 0);
4276
    lib64_div[2] = make_extn("__TDFUu_div1", f_proc, 0);
4286
    lib64_div[3] = make_extn ("__TDFUs_div1", f_proc, 0);
4277
    lib64_div[3] = make_extn("__TDFUs_div1", f_proc, 0);
4287
    lib64_rem[0] = make_extn ("__TDFUu_rem2", f_proc, 0);
4278
    lib64_rem[0] = make_extn("__TDFUu_rem2", f_proc, 0);
4288
    lib64_rem[1] = make_extn ("__TDFUs_rem2", f_proc, 0);
4279
    lib64_rem[1] = make_extn("__TDFUs_rem2", f_proc, 0);
4289
    lib64_rem[2] = make_extn ("__TDFUu_rem1", f_proc, 0);
4280
    lib64_rem[2] = make_extn("__TDFUu_rem1", f_proc, 0);
4290
    lib64_rem[3] = make_extn ("__TDFUs_rem1", f_proc, 0);
4281
    lib64_rem[3] = make_extn("__TDFUs_rem1", f_proc, 0);
4291
    lib64_error = make_extn ("__TDFerror", slongsh, 1);
4282
    lib64_error = make_extn("__TDFerror", slongsh, 1);
4292
    if (!PIC_code)
4283
    if (!PIC_code)
4293
      lib64_error = getexp (slongsh, nilexp, 1, lib64_error, nilexp, 0, 0, cont_tag);
4284
      lib64_error = getexp(slongsh, nilexp, 1, lib64_error, nilexp, 0, 0, cont_tag);
4294
    lib64_set = 1;
4285
    lib64_set = 1;
4295
  };
4286
  };
4296
  return;
4287
  return;
4297
}
4288
}
4298
 
4289
 
4299
 
4290
 
4300
/* 64-bit multiply a1 by a2, result to reg0/1
4291
/* 64-bit multiply a1 by a2, result to reg0/1
4301
   arg shapes sh1, sh2 may be 32 or 64-bit
4292
   arg shapes sh1, sh2 may be 32 or 64-bit
4302
   proper subset varieties for sha */
4293
   proper subset varieties for sha */
4303
static void mult64
4294
static void mult64
4304
    PROTO_N ( (sha, sh1, sh2, a1, a2) )
-
 
4305
    PROTO_T ( shape sha X shape sh1 X shape sh2 X where a1 X where a2 )
4295
(shape sha, shape sh1, shape sh2, where a1, where a2)
4306
{
4296
{
4307
  int riu = regsinuse;	/* we know reg2 not in use */
4297
  int riu = regsinuse;	/* we know reg2 not in use */
4308
  exp holda2 = son(a2.where_exp);
4298
  exp holda2 = son(a2.where_exp);
4309
 
4299
 
4310
  if (shape_size(sh1) == 32) {
4300
  if (shape_size(sh1) == 32) {
4311
    if (shape_size(sh2) != 32 || (eq_where (a2, reg0) && !eq_where (a1, reg0))) {
4301
    if (shape_size(sh2)!= 32 || (eq_where(a2, reg0) && !eq_where(a1, reg0))) {
4312
      mult64 (sha, sh2, sh1, a2, a1);
4302
      mult64(sha, sh2, sh1, a2, a1);
4313
      return;
4303
      return;
4314
    };
4304
    };
4315
    if (eq_where (a1, reg0)) {
4305
    if (eq_where(a1, reg0)) {
4316
      int difsg = (is_signed(sh1) != is_signed(sh2));
4306
      int difsg = (is_signed(sh1)!= is_signed(sh2));
4317
      int lab1, lab2;
4307
      int lab1, lab2;
4318
      regsinuse |= 0x2;
4308
      regsinuse |= 0x2;
4319
      contop (a2.where_exp, 1, a2);
4309
      contop(a2.where_exp, 1, a2);
4320
      if (name(a2.where_exp) == val_tag) {
4310
      if (name(a2.where_exp) == val_tag) {
4321
	if ((no(a2.where_exp) = a2.where_off) >= 0) {
4311
	if ((no(a2.where_exp) = a2.where_off) >= 0) {
4322
	  sh2 = sh1;
4312
	  sh2 = sh1;
4323
	  difsg = 0;
4313
	  difsg = 0;
4324
	};
4314
	};
4325
	reg0_in_use = 1;
4315
	reg0_in_use = 1;
4326
	move (sh2, a2, reg2);
4316
	move(sh2, a2, reg2);
4327
	a2 = reg2;
4317
	a2 = reg2;
4328
      };
4318
      };
4329
      if (difsg && is_signed(sh2)) {
4319
      if (difsg && is_signed(sh2)) {
4330
	if (inmem (a2)) {
4320
	if (inmem(a2)) {
4331
	  ins2 (movl, 32, 32, a2, reg2);
4321
	  ins2(movl, 32, 32, a2, reg2);
4332
	  a2 = reg2;
4322
	  a2 = reg2;
4333
	};
4323
	};
4334
	ins2 (xchg, 32, 32, reg0, reg2);
4324
	ins2(xchg, 32, 32, reg0, reg2);
4335
      };
4325
      };
4336
      if (difsg) {
4326
      if (difsg) {
4337
	lab1 = next_lab();
4327
	lab1 = next_lab();
4338
	lab2 = next_lab();
4328
	lab2 = next_lab();
4339
	ins2 (testl, 32, 32, reg0, reg0);
4329
	ins2(testl, 32, 32, reg0, reg0);
4340
	simple_branch (jns, lab1);
4330
	simple_branch(jns, lab1);
4341
	ins1 (mull, 32, a2);
4331
	ins1(mull, 32, a2);
4342
	ins2 (decl, 32, 32, a2, reg1);
4332
	ins2(decl, 32, 32, a2, reg1);
4343
	simple_branch (jmp, lab2);
4333
	simple_branch(jmp, lab2);
4344
	simplest_set_lab (lab1);
4334
	simplest_set_lab(lab1);
4345
	ins1 (mull, 32, a2);
4335
	ins1(mull, 32, a2);
4346
	simplest_set_lab (lab2);
4336
	simplest_set_lab(lab2);
4347
      }
4337
      }
4348
      else
4338
      else
4349
        ins1 ((is_signed(sh1) ? imull : mull), 32, a2);
4339
        ins1((is_signed(sh1)? imull : mull), 32, a2);
4350
      end_contop ();
4340
      end_contop();
4351
      regsinuse = riu;
4341
      regsinuse = riu;
4352
      son(a2.where_exp) = holda2;
4342
      son(a2.where_exp) = holda2;
4353
      return;
4343
      return;
4354
    };
4344
    };
4355
	/* neither is in reg0 */
4345
	/* neither is in reg0 */
4356
    if (is_signed(sh2) && !is_signed(sh1)) {
4346
    if (is_signed(sh2) && !is_signed(sh1)) {
4357
      mult64 (sha, sh2, sh1, a2, a1);
4347
      mult64(sha, sh2, sh1, a2, a1);
4358
      return;
4348
      return;
4359
    };
4349
    };
4360
    if (is_signed(sh1)) {
4350
    if (is_signed(sh1)) {
4361
      if (name(a1.where_exp) != val_tag) {
4351
      if (name(a1.where_exp)!= val_tag) {
4362
	move (sh1, a1, reg0);
4352
	move(sh1, a1, reg0);
4363
	mult64 (sha, sh1, sh2, reg0, a2);
4353
	mult64(sha, sh1, sh2, reg0, a2);
4364
	return;
4354
	return;
4365
      };
4355
      };
4366
      if ((no(a1.where_exp) + a1.where_off) >= 0 || is_signed(sh2)) {
4356
      if ((no(a1.where_exp) + a1.where_off) >= 0 || is_signed(sh2)) {
4367
	move (sh2, a2, reg0);
4357
	move(sh2, a2, reg0);
4368
	mult64 (sha, sh2, sh2, reg0, a1);
4358
	mult64(sha, sh2, sh2, reg0, a1);
4369
	return;
4359
	return;
4370
      };
4360
      };
4371
	/* otherwise, we are multiplying negative constant by unsigned */
4361
	/* otherwise, we are multiplying negative constant by unsigned */
4372
      move (sh1, a1, reg0);
4362
      move(sh1, a1, reg0);
4373
      contop (a2.where_exp, 1, a2);
4363
      contop(a2.where_exp, 1, a2);
4374
      if (name(a2.where_exp) == val_tag) {
4364
      if (name(a2.where_exp) == val_tag) {
4375
	reg0_in_use = 1;
4365
	reg0_in_use = 1;
4376
	move (sh2, a2, reg2);
4366
	move(sh2, a2, reg2);
4377
	a2 = reg2;
4367
	a2 = reg2;
4378
      };
4368
      };
4379
      ins1 (mull, 32, a2);
4369
      ins1(mull, 32, a2);
4380
      ins2 (subl, 32, 32, a2, reg1);
4370
      ins2(subl, 32, 32, a2, reg1);
4381
      end_contop ();
4371
      end_contop();
4382
      son(a2.where_exp) = holda2;
4372
      son(a2.where_exp) = holda2;
4383
      return;
4373
      return;
4384
    };
4374
    };
4385
	/* both are unsigned */
4375
	/* both are unsigned */
4386
    if (name(a1.where_exp) == val_tag) {
4376
    if (name(a1.where_exp) == val_tag) {
4387
      move (sh1, a1, reg0);
4377
      move(sh1, a1, reg0);
4388
      mult64 (sha, sh1, sh2, reg0, a2);
4378
      mult64(sha, sh1, sh2, reg0, a2);
4389
      return;
4379
      return;
4390
    };
4380
    };
4391
    {
4381
    {
4392
      move (sh2, a2, reg0);
4382
      move(sh2, a2, reg0);
4393
      mult64 (sha, sh2, sh1, reg0, a1);
4383
      mult64(sha, sh2, sh1, reg0, a1);
4394
      return;
4384
      return;
4395
    };
4385
    };
4396
  };
4386
  };
4397
 
4387
 
4398
  if (overflow_e != nilexp && !optop(overflow_e)) {
4388
  if (overflow_e != nilexp && !optop(overflow_e)) {
4399
				/* need library proc to check for overflow */
4389
				/* need library proc to check for overflow */
4400
    needs_lib64();
4390
    needs_lib64();
4401
    if (eq_where (a1, reg0)) {
4391
    if (eq_where(a1, reg0)) {
4402
      a1 = a2;
4392
      a1 = a2;
4403
      a2 = reg0;
4393
      a2 = reg0;
4404
    };
4394
    };
4405
    move (sha, a2, pushdest);
4395
    move(sha, a2, pushdest);
4406
    extra_stack += 64;
4396
    extra_stack += 64;
4407
    move (sha, a1, pushdest);
4397
    move(sha, a1, pushdest);
4408
    extra_stack -= 64;
4398
    extra_stack -= 64;
4409
    callins (0, (is_signed(sha) ? lib64_s_mult : lib64_u_mult), stack_dec);
4399
    callins(0,(is_signed(sha)? lib64_s_mult : lib64_u_mult), stack_dec);
4410
    add(slongsh, mw(zeroe, 16), sp, sp);
4400
    add(slongsh, mw(zeroe, 16), sp, sp);
4411
    ins2 (movl, 32, 32, mw(lib64_error, 0), reg2);
4401
    ins2(movl, 32, 32, mw(lib64_error, 0), reg2);
4412
    if (PIC_code)
4402
    if (PIC_code)
4413
      ins2 (movl, 32, 32, ind_reg2, reg2);
4403
      ins2(movl, 32, 32, ind_reg2, reg2);
4414
    ins2 (testl, 32, 32, reg2, reg2);
4404
    ins2(testl, 32, 32, reg2, reg2);
4415
    test_exception (f_greater_than_or_equal, slongsh);
4405
    test_exception(f_greater_than_or_equal, slongsh);
4416
    return;
4406
    return;
4417
  };
4407
  };
4418
 
4408
 
4419
  if (shape_size(sh2) == 32 || (name(a2.where_exp) == val_tag && !isbigval(a2.where_exp))) {
4409
  if (shape_size(sh2) == 32 || (name(a2.where_exp) == val_tag && !isbigval(a2.where_exp))) {
4420
    if (eq_where (a1, reg0)) {
4410
    if (eq_where(a1, reg0)) {
4421
      reg0_in_use = 1;
4411
      reg0_in_use = 1;
4422
      regsinuse |= 0x2;
4412
      regsinuse |= 0x2;
4423
      move (slongsh, a2, reg2);
4413
      move(slongsh, a2, reg2);
4424
    }
4414
    }
4425
    else {
4415
    else {
4426
      move (slongsh, a2, reg2);
4416
      move(slongsh, a2, reg2);
4427
      regsinuse |= 0x4;
4417
      regsinuse |= 0x4;
4428
      move (sha, a1, reg0);
4418
      move(sha, a1, reg0);
4429
    }
4419
    }
4430
    ins0 (pushedx);
4420
    ins0(pushedx);
4431
#ifdef NEWDWARF
4421
#ifdef NEWDWARF
4432
    if (diagnose && dwarf2 && no_frame)
4422
    if (diagnose && dwarf2 && no_frame)
4433
      dw2_track_push();
4423
      dw2_track_push();
4434
#endif
4424
#endif
4435
    if (is_signed(sha) && is_signed(sh2) &&
4425
    if (is_signed(sha) && is_signed(sh2) &&
4436
	  (name(a2.where_exp) != val_tag || (no(a2.where_exp) + a2.where_off) < 0)) {
4426
	 (name(a2.where_exp)!= val_tag || (no(a2.where_exp) + a2.where_off) < 0)) {
4437
      ins0 (pusheax);
4427
      ins0(pusheax);
4438
#ifdef NEWDWARF
4428
#ifdef NEWDWARF
4439
      if (diagnose && dwarf2 && no_frame)
4429
      if (diagnose && dwarf2 && no_frame)
4440
	dw2_track_push();
4430
	dw2_track_push();
4441
#endif
4431
#endif
4442
      ins1 (mull, 32, reg2);
4432
      ins1(mull, 32, reg2);
4443
      if (name(a2.where_exp) != val_tag) {
4433
      if (name(a2.where_exp)!= val_tag) {
4444
	int lab1 = next_lab();
4434
	int lab1 = next_lab();
4445
	ins2 (testl, 32, 32, reg2, reg2);
4435
	ins2(testl, 32, 32, reg2, reg2);
4446
	simple_branch (jns, lab1);
4436
	simple_branch(jns, lab1);
4447
	ins2 (subl, 32, 32, ind_sp, reg1);
4437
	ins2(subl, 32, 32, ind_sp, reg1);
4448
	simplest_set_lab (lab1);
4438
	simplest_set_lab(lab1);
4449
      }
4439
      }
4450
      else
4440
      else
4451
	ins2 (subl, 32, 32, ind_sp, reg1);
4441
	ins2(subl, 32, 32, ind_sp, reg1);
4452
      ins2 (addl, 32, 32, mw(zeroe,4), sp);
4442
      ins2(addl, 32, 32, mw(zeroe,4), sp);
4453
    }
4443
    }
4454
    else
4444
    else
4455
      ins1 (mull, 32, reg2);
4445
      ins1(mull, 32, reg2);
4456
    ins2 (imull, 32, 32, ind_sp, reg2);
4446
    ins2(imull, 32, 32, ind_sp, reg2);
4457
    ins2 (addl, 32, 32, reg2, reg1);
4447
    ins2(addl, 32, 32, reg2, reg1);
4458
    ins0 (popecx);
4448
    ins0(popecx);
4459
#ifdef NEWDWARF
4449
#ifdef NEWDWARF
4460
    if (diagnose && dwarf2 && no_frame)
4450
    if (diagnose && dwarf2 && no_frame)
4461
      dw2_track_pop();
4451
      dw2_track_pop();
4462
#endif
4452
#endif
4463
    regsinuse = riu;
4453
    regsinuse = riu;
4464
    return;
4454
    return;
4465
  };
4455
  };
4466
 
4456
 
4467
  if (eq_where (a1, a2)) {
4457
  if (eq_where(a1, a2)) {
4468
    move (sha, a1, reg0);
4458
    move(sha, a1, reg0);
4469
    ins0 (pushedx);
4459
    ins0(pushedx);
4470
#ifdef NEWDWARF
4460
#ifdef NEWDWARF
4471
    if (diagnose && dwarf2 && no_frame)
4461
    if (diagnose && dwarf2 && no_frame)
4472
      dw2_track_push();
4462
      dw2_track_push();
4473
#endif
4463
#endif
4474
    ins2 (movl, 32, 32, reg0, reg2);
4464
    ins2(movl, 32, 32, reg0, reg2);
4475
    ins1 (mull, 32, reg0);
4465
    ins1(mull, 32, reg0);
4476
    ins2 (imull, 32, 32, ind_sp, reg2);
4466
    ins2(imull, 32, 32, ind_sp, reg2);
4477
    ins2 (addl, 32, 32, reg2, reg1);
4467
    ins2(addl, 32, 32, reg2, reg1);
4478
    ins2 (addl, 32, 32, reg2, reg1);
4468
    ins2(addl, 32, 32, reg2, reg1);
4479
    ins0 (popecx);
4469
    ins0(popecx);
4480
#ifdef NEWDWARF
4470
#ifdef NEWDWARF
4481
    if (diagnose && dwarf2 && no_frame)
4471
    if (diagnose && dwarf2 && no_frame)
4482
      dw2_track_pop();
4472
      dw2_track_pop();
4483
#endif
4473
#endif
4484
    return;
4474
    return;
4485
  };
4475
  };
4486
 
4476
 
4487
  if (eq_where (a2, reg0)) {
4477
  if (eq_where(a2, reg0)) {
4488
    son(a2.where_exp) = holda2;
4478
    son(a2.where_exp) = holda2;
4489
    a2 = a1;
4479
    a2 = a1;
4490
    holda2 = son(a2.where_exp);
4480
    holda2 = son(a2.where_exp);
4491
    a1 = reg0;
4481
    a1 = reg0;
4492
  };
4482
  };
4493
  move (sha, a1, reg0);
4483
  move(sha, a1, reg0);
4494
  reg0_in_use = 1;
4484
  reg0_in_use = 1;
4495
  regsinuse |= 0x6;
4485
  regsinuse |= 0x6;
4496
  contop (a2.where_exp, 1, a2);
4486
  contop(a2.where_exp, 1, a2);
4497
  ins0 (pushedx);
4487
  ins0(pushedx);
4498
#ifdef NEWDWARF
4488
#ifdef NEWDWARF
4499
  if (diagnose && dwarf2 && no_frame)
4489
  if (diagnose && dwarf2 && no_frame)
4500
    dw2_track_push();
4490
    dw2_track_push();
4501
#endif
4491
#endif
4502
  extra_stack += 32;
4492
  extra_stack += 32;
4503
  ins2 (movl, 32, 32, reg0, reg2);
4493
  ins2(movl, 32, 32, reg0, reg2);
4504
  ins1 (mull, 32, a2);
4494
  ins1(mull, 32, a2);
4505
  ins2 (imull, 32, 32, mw(a2.where_exp, a2.where_off+32), reg2);
4495
  ins2(imull, 32, 32, mw(a2.where_exp, a2.where_off+32), reg2);
4506
  ins2 (addl, 32, 32, reg2, reg1);
4496
  ins2(addl, 32, 32, reg2, reg1);
4507
  ins0 (popecx);
4497
  ins0(popecx);
4508
#ifdef NEWDWARF
4498
#ifdef NEWDWARF
4509
  if (diagnose && dwarf2 && no_frame)
4499
  if (diagnose && dwarf2 && no_frame)
4510
    dw2_track_pop();
4500
    dw2_track_pop();
4511
#endif
4501
#endif
4512
  extra_stack -= 32;
4502
  extra_stack -= 32;
4513
  ins2 (imull, 32, 32, a2, reg2);
4503
  ins2(imull, 32, 32, a2, reg2);
4514
  ins2 (addl, 32, 32, reg2, reg1);
4504
  ins2(addl, 32, 32, reg2, reg1);
4515
  end_contop ();
4505
  end_contop();
4516
  regsinuse = riu;
4506
  regsinuse = riu;
4517
  son(a2.where_exp) = holda2;
4507
  son(a2.where_exp) = holda2;
4518
  return;
4508
  return;
4519
}
4509
}
4520
 
4510
 
4521
 
4511
 
4522
static void clean_multiply
4512
static void clean_multiply
4523
    PROTO_N ( (stored) )
-
 
4524
    PROTO_T ( int stored )
4513
(int stored)
4525
{
4514
{
4526
  if (stored)
4515
  if (stored)
4527
   {
4516
   {
4528
      ins0(popedx);
4517
      ins0(popedx);
4529
#ifdef NEWDWARF
4518
#ifdef NEWDWARF
Line 4538... Line 4527...
4538
 
4527
 
4539
/* multiply a1 by a2 add inc and put into
4528
/* multiply a1 by a2 add inc and put into
4540
   dest. optimisation have already been
4529
   dest. optimisation have already been
4541
   done. */
4530
   done. */
4542
void multiply
4531
void multiply
4543
    PROTO_N ( (sha, a1, a2, dest) )
-
 
4544
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
4532
(shape sha, where a1, where a2, where dest)
4545
{
4533
{
4546
  int  sz;
4534
  int  sz;
4547
  char *in;
4535
  char *in;
4548
  int stored = 0;
4536
  int stored = 0;
4549
  exp hold_a1 = son(a1.where_exp);
4537
  exp hold_a1 = son(a1.where_exp);
Line 4552... Line 4540...
4552
 
4540
 
4553
  cond1_set = 0;
4541
  cond1_set = 0;
4554
  cond2_set = 0;
4542
  cond2_set = 0;
4555
 
4543
 
4556
  if (sz == 64) {
4544
  if (sz == 64) {
4557
    mult64 (sha, sh(a1.where_exp), sh(a2.where_exp), a1, a2);
4545
    mult64(sha, sh(a1.where_exp), sh(a2.where_exp), a1, a2);
4558
    move (sha, reg0, dest);
4546
    move(sha, reg0, dest);
4559
    invalidate_dest (reg0);
4547
    invalidate_dest(reg0);
4560
    invalidate_dest (reg2);
4548
    invalidate_dest(reg2);
4561
    return;
4549
    return;
4562
  };
4550
  };
4563
 
4551
 
4564
  if (sz == 8)
4552
  if (sz == 8)
4565
    in = imulb;
4553
    in = imulb;
4566
  else {
4554
  else {
4567
    if (sz == 16)
4555
    if (sz == 16)
4568
      in = imulw;
4556
      in = imulw;
4569
    else
4557
    else
4570
      in = imull;
4558
      in = imull;
4571
  };
4559
  };
4572
  invalidate_dest (reg0);
4560
  invalidate_dest(reg0);
4573
  if (name (a2.where_exp) == val_tag && sz != 8 &&
4561
  if (name(a2.where_exp) == val_tag && sz != 8 &&
4574
	(is_signed (sha) || overflow_e == nilexp || optop(overflow_e))) {
4562
	(is_signed(sha) || overflow_e == nilexp || optop(overflow_e))) {
4575
    	    /* x * const -> y */
4563
    	    /* x * const -> y */
4576
    contop (a1.where_exp, eq_where (reg0, a1), dest);
4564
    contop(a1.where_exp, eq_where(reg0, a1), dest);
4577
    if (!inmem (dest)) {
4565
    if (!inmem(dest)) {
4578
        /* x * const -> reg */
4566
        /* x * const -> reg */
4579
      if (name (a1.where_exp) == val_tag) {
4567
      if (name(a1.where_exp) == val_tag) {
4580
	move (sha, a1, dest);
4568
	move(sha, a1, dest);
4581
	son(a1.where_exp) = hold_a1;
4569
	son(a1.where_exp) = hold_a1;
4582
	a1 = dest;
4570
	a1 = dest;
4583
	hold_a1 = son(a1.where_exp);
4571
	hold_a1 = son(a1.where_exp);
4584
      };
4572
      };
4585
      ins3 (in, sz, sz, sz, a2, a1, dest);
4573
      ins3(in, sz, sz, sz, a2, a1, dest);
4586
      invalidate_dest (dest);
4574
      invalidate_dest(dest);
4587
      end_contop ();
4575
      end_contop();
4588
      try_overflow (sha, 0);
4576
      try_overflow(sha, 0);
4589
      son(a1.where_exp) = hold_a1;
4577
      son(a1.where_exp) = hold_a1;
4590
      return;
4578
      return;
4591
    };
4579
    };
4592
       /* x * const -> notreg   : use reg0 */
4580
       /* x * const -> notreg   : use reg0 */
4593
    if (name (a1.where_exp) == val_tag) {
4581
    if (name(a1.where_exp) == val_tag) {
4594
      move (sha, a1, reg0);
4582
      move(sha, a1, reg0);
4595
      son(a1.where_exp) = hold_a1;
4583
      son(a1.where_exp) = hold_a1;
4596
      a1 = reg0;
4584
      a1 = reg0;
4597
      hold_a1 =  son(a1.where_exp);
4585
      hold_a1 =  son(a1.where_exp);
4598
    };
4586
    };
4599
    ins3 (in, sz, sz, sz, a2, a1, reg0);
4587
    ins3(in, sz, sz, sz, a2, a1, reg0);
4600
    invalidate_dest (reg0);
4588
    invalidate_dest(reg0);
4601
    end_contop ();
4589
    end_contop();
4602
    try_overflow (sha, 0);
4590
    try_overflow(sha, 0);
4603
    move (sha, reg0, dest);
4591
    move(sha, reg0, dest);
4604
    son(a1.where_exp) = hold_a1;
4592
    son(a1.where_exp) = hold_a1;
4605
    return;
4593
    return;
4606
  };
4594
  };
4607
 
4595
 
4608
  if (is_signed (sha) && sz != 8) {
4596
  if (is_signed(sha) && sz != 8) {
4609
      /* signed : we don't have to disturb eax/edx */
4597
      /* signed : we don't have to disturb eax/edx */
4610
    if (!inmem (dest)) {
4598
    if (!inmem(dest)) {
4611
      if (eq_where (a2, dest)) {
4599
      if (eq_where(a2, dest)) {
4612
	contop (a1.where_exp,
4600
	contop(a1.where_exp,
4613
	     (eq_where (reg0, a1) || eq_where (reg0, a2)),
4601
	    (eq_where(reg0, a1) || eq_where(reg0, a2)),
4614
	    dest);
4602
	    dest);
4615
	ins2 (in, sz, sz, a1, dest);
4603
	ins2(in, sz, sz, a1, dest);
4616
	invalidate_dest (dest);
4604
	invalidate_dest(dest);
4617
	end_contop ();
4605
	end_contop();
4618
        try_overflow (sha, 0);
4606
        try_overflow(sha, 0);
4619
	son(a1.where_exp) = hold_a1;
4607
	son(a1.where_exp) = hold_a1;
4620
	return;
4608
	return;
4621
      };
4609
      };
4622
      if (eq_where (a1, dest)) {
4610
      if (eq_where(a1, dest)) {
4623
	contop (a2.where_exp,
4611
	contop(a2.where_exp,
4624
	     (eq_where (reg0, a1) || eq_where (reg0, a2)),
4612
	    (eq_where(reg0, a1) || eq_where(reg0, a2)),
4625
	    dest);
4613
	    dest);
4626
	ins2 (in, sz, sz, a2, dest);
4614
	ins2(in, sz, sz, a2, dest);
4627
	invalidate_dest (dest);
4615
	invalidate_dest(dest);
4628
	end_contop ();
4616
	end_contop();
4629
        try_overflow (sha, 0);
4617
        try_overflow(sha, 0);
4630
	son(a2.where_exp) = hold_a2;
4618
	son(a2.where_exp) = hold_a2;
4631
	return;
4619
	return;
4632
      };
4620
      };
4633
    };
4621
    };
4634
    if (eq_where (reg0, a2)) {
4622
    if (eq_where(reg0, a2)) {
4635
      contop (a1.where_exp, 1, reg0);
4623
      contop(a1.where_exp, 1, reg0);
4636
      ins2 (in, sz, sz, a1, reg0);
4624
      ins2(in, sz, sz, a1, reg0);
4637
      invalidate_dest (reg0);
4625
      invalidate_dest(reg0);
4638
      end_contop ();
4626
      end_contop();
4639
      try_overflow (sha, 0);
4627
      try_overflow(sha, 0);
4640
      move (sha, reg0, dest);
4628
      move(sha, reg0, dest);
4641
      son(a1.where_exp) = hold_a1;
4629
      son(a1.where_exp) = hold_a1;
4642
      return;
4630
      return;
4643
    };
4631
    };
4644
    move (sha, a1, reg0);
4632
    move(sha, a1, reg0);
4645
    contop (a2.where_exp, 1, reg0);
4633
    contop(a2.where_exp, 1, reg0);
4646
    ins2 (in, sz, sz, a2, reg0);
4634
    ins2(in, sz, sz, a2, reg0);
4647
    invalidate_dest (reg0);
4635
    invalidate_dest(reg0);
4648
    end_contop ();
4636
    end_contop();
4649
    try_overflow (sha, 0);
4637
    try_overflow(sha, 0);
4650
    move (sha, reg0, dest);
4638
    move(sha, reg0, dest);
4651
    son(a2.where_exp) = hold_a2;
4639
    son(a2.where_exp) = hold_a2;
4652
    return;
4640
    return;
4653
  }
4641
  }
4654
  else {
4642
  else {
4655
       /* unsigned : use mul which only allows eax edx result */
4643
       /* unsigned : use mul which only allows eax edx result */
4656
	/* or signed imulb with same constraint */
4644
	/* or signed imulb with same constraint */
4657
    if (!is_signed (sha))
4645
    if (!is_signed(sha))
4658
      in = &in[1];
4646
      in = &in[1];
4659
    if ((regsinuse & 0x2) && !eq_where (dest, reg1)) {
4647
    if ((regsinuse & 0x2) && !eq_where(dest, reg1)) {
4660
      stored = 1;
4648
      stored = 1;
4661
      ins0(pushedx);
4649
      ins0(pushedx);
4662
#ifdef NEWDWARF
4650
#ifdef NEWDWARF
4663
      if (diagnose && dwarf2 && no_frame)
4651
      if (diagnose && dwarf2 && no_frame)
4664
	dw2_track_push();
4652
	dw2_track_push();
4665
#endif
4653
#endif
4666
      extra_stack += 32;
4654
      extra_stack += 32;
4667
      check_stack_max;
4655
      check_stack_max;
4668
      invalidate_dest (reg1);
4656
      invalidate_dest(reg1);
4669
    };
4657
    };
4670
    if (eq_where (reg0, dest)) {
4658
    if (eq_where(reg0, dest)) {
4671
      if (eq_where (a2, reg0)) {
4659
      if (eq_where(a2, reg0)) {
4672
	contop (a1.where_exp, 1, a1);
4660
	contop(a1.where_exp, 1, a1);
4673
	if (name (a1.where_exp) == val_tag) {
4661
	if (name(a1.where_exp) == val_tag) {
4674
	  move (sha, a1, reg1);
4662
	  move(sha, a1, reg1);
4675
	  ins1 (in, sz, reg1);
4663
	  ins1(in, sz, reg1);
4676
	}
4664
	}
4677
	else {
4665
	else {
4678
	  ins1 (in, sz, a1);
4666
	  ins1(in, sz, a1);
4679
	};
4667
	};
4680
        invalidate_dest (reg0);
4668
        invalidate_dest(reg0);
4681
        invalidate_dest(reg1);
4669
        invalidate_dest(reg1);
4682
	invalidate_dest (a1);
4670
	invalidate_dest(a1);
4683
	end_contop ();
4671
	end_contop();
4684
	clean_multiply (stored);
4672
	clean_multiply(stored);
4685
        try_overflow (sha, 0);
4673
        try_overflow(sha, 0);
4686
	son(a1.where_exp) = hold_a1;
4674
	son(a1.where_exp) = hold_a1;
4687
	return;
4675
	return;
4688
      };
4676
      };
4689
      if (eq_where (a1, reg0)) {
4677
      if (eq_where(a1, reg0)) {
4690
	contop (a2.where_exp, 1, a2);
4678
	contop(a2.where_exp, 1, a2);
4691
	if (name (a2.where_exp) == val_tag) {
4679
	if (name(a2.where_exp) == val_tag) {
4692
	  move (sha, a2, reg1);
4680
	  move(sha, a2, reg1);
4693
	  ins1 (in, sz, reg1);
4681
	  ins1(in, sz, reg1);
4694
	}
4682
	}
4695
	else {
4683
	else {
4696
	  ins1 (in, sz, a2);
4684
	  ins1(in, sz, a2);
4697
	};
4685
	};
4698
        invalidate_dest (reg0);
4686
        invalidate_dest(reg0);
4699
        invalidate_dest(reg1);
4687
        invalidate_dest(reg1);
4700
	invalidate_dest (a2);
4688
	invalidate_dest(a2);
4701
	end_contop ();
4689
	end_contop();
4702
	clean_multiply (stored);
4690
	clean_multiply(stored);
4703
        try_overflow (sha, 0);
4691
        try_overflow(sha, 0);
4704
	son(a2.where_exp) = hold_a2;
4692
	son(a2.where_exp) = hold_a2;
4705
	return;
4693
	return;
4706
      };
4694
      };
4707
    };
4695
    };
4708
    if (eq_where (reg0, a2)) {
4696
    if (eq_where(reg0, a2)) {
4709
      contop (a1.where_exp, 1, a1);
4697
      contop(a1.where_exp, 1, a1);
4710
      if (name (a1.where_exp) == val_tag) {
4698
      if (name(a1.where_exp) == val_tag) {
4711
	move (sha, a1, reg1);
4699
	move(sha, a1, reg1);
4712
	ins1 (in, sz, reg1);
4700
	ins1(in, sz, reg1);
4713
      }
4701
      }
4714
      else {
4702
      else {
4715
	ins1 (in, sz, a1);
4703
	ins1(in, sz, a1);
4716
      };
4704
      };
4717
      invalidate_dest (a1);
4705
      invalidate_dest(a1);
4718
      invalidate_dest (reg0);
4706
      invalidate_dest(reg0);
4719
      invalidate_dest(reg1);
4707
      invalidate_dest(reg1);
4720
      end_contop ();
4708
      end_contop();
4721
      clean_multiply (stored);
4709
      clean_multiply(stored);
4722
      try_overflow (sha, 0);
4710
      try_overflow(sha, 0);
4723
      move (sha, reg0, dest);
4711
      move(sha, reg0, dest);
4724
      son(a1.where_exp) = hold_a1;
4712
      son(a1.where_exp) = hold_a1;
4725
      return;
4713
      return;
4726
    };
4714
    };
4727
    move (sha, a1, reg0);
4715
    move(sha, a1, reg0);
4728
    contop (a2.where_exp, 1, a2);
4716
    contop(a2.where_exp, 1, a2);
4729
    if (name (a2.where_exp) == val_tag) {
4717
    if (name(a2.where_exp) == val_tag) {
4730
      move (sha, a2, reg1);
4718
      move(sha, a2, reg1);
4731
      ins1 (in, sz, reg1);
4719
      ins1(in, sz, reg1);
4732
    }
4720
    }
4733
    else {
4721
    else {
4734
      ins1 (in, sz, a2);
4722
      ins1(in, sz, a2);
4735
    };
4723
    };
4736
    invalidate_dest (a2);
4724
    invalidate_dest(a2);
4737
    invalidate_dest (a1);
4725
    invalidate_dest(a1);
4738
    invalidate_dest (reg0);
4726
    invalidate_dest(reg0);
4739
    invalidate_dest (reg1);
4727
    invalidate_dest(reg1);
4740
    end_contop ();
4728
    end_contop();
4741
    clean_multiply (stored);
4729
    clean_multiply(stored);
4742
    try_overflow (sha, 0);
4730
    try_overflow(sha, 0);
4743
    move (sha, reg0, dest);
4731
    move(sha, reg0, dest);
4744
    son(a2.where_exp) = hold_a2;
4732
    son(a2.where_exp) = hold_a2;
4745
    return;
4733
    return;
4746
  };
4734
  };
4747
}
4735
}
4748
 
4736
 
Line 4751... Line 4739...
4751
  25, 15, 9, 7, 5, 3
4739
  25, 15, 9, 7, 5, 3
4752
};
4740
};
4753
 
4741
 
4754
/* do multiplications by small integer constants */
4742
/* do multiplications by small integer constants */
4755
void longc_mult
4743
void longc_mult
4756
    PROTO_N ( (a1, a2, dest, inc) )
-
 
4757
    PROTO_T ( where a1 X where a2 X where dest X int inc )
4744
(where a1, where a2, where dest, int inc)
4758
{
4745
{
4759
  int  i,
4746
  int  i,
4760
        j;
4747
        j;
4761
  int  n = no (a2.where_exp) + a2.where_off;
4748
  int  n = no(a2.where_exp) + a2.where_off;
4762
  shape sha = slongsh;
4749
  shape sha = slongsh;
4763
  exp holdd = son(dest.where_exp);
4750
  exp holdd = son(dest.where_exp);
4764
 
4751
 
4765
  if (name(sh(a2.where_exp)) == offsethd && al2(sh(a2.where_exp)) != 1)
4752
  if (name(sh(a2.where_exp)) == offsethd && al2(sh(a2.where_exp))!= 1)
4766
     n = n / 8;
4753
     n = n / 8;
4767
 
4754
 
4768
  cond1_set = 0;
4755
  cond1_set = 0;
4769
  cond2_set = 0;
4756
  cond2_set = 0;
4770
 
4757
 
4771
  if (n == 0) {
4758
  if (n == 0) {
4772
    move (sha, zero, dest);
4759
    move(sha, zero, dest);
4773
    return;
4760
    return;
4774
  };
4761
  };
4775
 
4762
 
4776
  if (n == 1) {
4763
  if (n == 1) {
4777
    move (sha, a1, dest);
4764
    move(sha, a1, dest);
4778
    return;
4765
    return;
4779
  };
4766
  };
4780
 
4767
 
4781
 
4768
 
4782
  switch (n) {
4769
  switch (n) {
4783
    case 2:
4770
    case 2:
4784
      if (inmem (a1)) {
4771
      if (inmem(a1)) {
4785
	where newdest;
4772
	where newdest;
4786
	newdest = (inmem (dest)) ? reg0 : dest;
4773
	newdest = (inmem(dest))? reg0 : dest;
4787
	move (sha, a1, newdest);
4774
	move(sha, a1, newdest);
4788
	add (sha, newdest, newdest, dest);
4775
	add(sha, newdest, newdest, dest);
4789
	return;
4776
	return;
4790
      }
4777
      }
4791
      add(sha, a1, a1, dest);
4778
      add(sha, a1, a1, dest);
4792
      return;
4779
      return;
4793
    case 3:
4780
    case 3:
4794
      if (inmem (a1)) {
4781
      if (inmem(a1)) {
4795
	move (sha, a1, reg0);
4782
	move(sha, a1, reg0);
4796
	contop (dest.where_exp, 1, dest);
4783
	contop(dest.where_exp, 1, dest);
4797
	mult_op (inc, reg0, reg0, 2, dest);
4784
	mult_op(inc, reg0, reg0, 2, dest);
4798
	invalidate_dest (dest);
-
 
4799
	son(dest.where_exp) = holdd;
-
 
4800
	return;
-
 
4801
      };
-
 
4802
      contop (dest.where_exp, eq_where (reg0, a1), dest);
-
 
4803
      mult_op (inc, a1, a1, 2, dest);
-
 
4804
      invalidate_dest (dest);
-
 
4805
      son(dest.where_exp) = holdd;
-
 
4806
      return;
-
 
4807
    case 5:
-
 
4808
      if (inmem (a1)) {
-
 
4809
	move (sha, a1, reg0);
-
 
4810
	contop (dest.where_exp, 1, dest);
-
 
4811
	mult_op (inc, reg0, reg0, 4, dest);
-
 
4812
	invalidate_dest (dest);
4785
	invalidate_dest(dest);
4813
	son(dest.where_exp) = holdd;
4786
	son(dest.where_exp) = holdd;
4814
	return;
4787
	return;
4815
      };
4788
      };
4816
      contop (dest.where_exp, eq_where (reg0, a1), dest);
4789
      contop(dest.where_exp, eq_where(reg0, a1), dest);
-
 
4790
      mult_op(inc, a1, a1, 2, dest);
-
 
4791
      invalidate_dest(dest);
-
 
4792
      son(dest.where_exp) = holdd;
-
 
4793
      return;
-
 
4794
    case 5:
-
 
4795
      if (inmem(a1)) {
-
 
4796
	move(sha, a1, reg0);
-
 
4797
	contop(dest.where_exp, 1, dest);
-
 
4798
	mult_op(inc, reg0, reg0, 4, dest);
-
 
4799
	invalidate_dest(dest);
-
 
4800
	son(dest.where_exp) = holdd;
-
 
4801
	return;
-
 
4802
      };
-
 
4803
      contop(dest.where_exp, eq_where(reg0, a1), dest);
4817
      mult_op (inc, a1, a1, 4, dest);
4804
      mult_op(inc, a1, a1, 4, dest);
4818
      invalidate_dest (dest);
4805
      invalidate_dest(dest);
4819
      son(dest.where_exp) = holdd;
4806
      son(dest.where_exp) = holdd;
4820
      return;
4807
      return;
4821
    case 7:
4808
    case 7:
4822
      if (!inmem(a1) && !inmem(dest) && !eq_where(a1, dest)) {
4809
      if (!inmem(a1) && !inmem(dest) && !eq_where(a1, dest)) {
4823
	longc_mult (a1, mw(zeroe, 8), dest, inc);
4810
	longc_mult(a1, mw(zeroe, 8), dest, inc);
4824
	sub(sha, a1, dest, dest);
4811
	sub(sha, a1, dest, dest);
4825
	return;
4812
	return;
4826
      };
4813
      };
4827
      if (!inmem(a1) && !inmem(dest)) {
4814
      if (!inmem(a1) && !inmem(dest)) {
4828
	if (!eq_where(a1, reg0)) {
4815
	if (!eq_where(a1, reg0)) {
4829
	  contop (dest.where_exp, 1, dest);
4816
	  contop(dest.where_exp, 1, dest);
4830
	  mult_op (inc, a1, a1, 2, reg0);
4817
	  mult_op(inc, a1, a1, 2, reg0);
4831
	  mult_op (inc, reg0, a1, 4, dest);
4818
	  mult_op(inc, reg0, a1, 4, dest);
4832
	  invalidate_dest (reg0);
4819
	  invalidate_dest(reg0);
4833
	  invalidate_dest (dest);
4820
	  invalidate_dest(dest);
4834
	  son(dest.where_exp) = holdd;
4821
	  son(dest.where_exp) = holdd;
4835
	  return;
4822
	  return;
4836
	}
4823
	}
4837
	else  {
4824
	else  {
4838
	  ins0(pushedx);
4825
	  ins0(pushedx);
4839
#ifdef NEWDWARF
4826
#ifdef NEWDWARF
4840
	  if (diagnose && dwarf2 && no_frame)
4827
	  if (diagnose && dwarf2 && no_frame)
4841
	    dw2_track_push();
4828
	    dw2_track_push();
4842
#endif
4829
#endif
4843
	  mult_op (inc, a1, a1, 2, reg1);
4830
	  mult_op(inc, a1, a1, 2, reg1);
4844
	  mult_op (inc, reg1, reg0, 4, dest);
4831
	  mult_op(inc, reg1, reg0, 4, dest);
4845
	  invalidate_dest (dest);
4832
	  invalidate_dest(dest);
4846
	  ins0(popedx);
4833
	  ins0(popedx);
4847
#ifdef NEWDWARF
4834
#ifdef NEWDWARF
4848
	  if (diagnose && dwarf2 && no_frame)
4835
	  if (diagnose && dwarf2 && no_frame)
4849
	    dw2_track_pop();
4836
	    dw2_track_pop();
4850
#endif
4837
#endif
Line 4852... Line 4839...
4852
	};
4839
	};
4853
      };
4840
      };
4854
      if (inmem(a1) && !inmem(dest)) {
4841
      if (inmem(a1) && !inmem(dest)) {
4855
	move(sha, a1, reg0);
4842
	move(sha, a1, reg0);
4856
	longc_mult(reg0, a2, dest, inc);
4843
	longc_mult(reg0, a2, dest, inc);
4857
	return;
4844
	return;
4858
      };
4845
      };
4859
      multiply (sha, a1, a2, dest);
4846
      multiply(sha, a1, a2, dest);
4860
      return;
4847
      return;
4861
    case 9:
4848
    case 9:
4862
      if (inmem (a1)) {
4849
      if (inmem(a1)) {
4863
	move (sha, a1, reg0);
4850
	move(sha, a1, reg0);
4864
	contop (dest.where_exp, 1, dest);
4851
	contop(dest.where_exp, 1, dest);
4865
	mult_op (inc, reg0, reg0, 8, dest);
4852
	mult_op(inc, reg0, reg0, 8, dest);
4866
	invalidate_dest (dest);
4853
	invalidate_dest(dest);
4867
	son(dest.where_exp) = holdd;
4854
	son(dest.where_exp) = holdd;
4868
	return;
4855
	return;
4869
      };
4856
      };
4870
      contop (dest.where_exp, eq_where (reg0, a1), dest);
4857
      contop(dest.where_exp, eq_where(reg0, a1), dest);
4871
      mult_op (inc, a1, a1, 8, dest);
4858
      mult_op(inc, a1, a1, 8, dest);
4872
      invalidate_dest (dest);
4859
      invalidate_dest(dest);
4873
      son(dest.where_exp) = holdd;
4860
      son(dest.where_exp) = holdd;
4874
      return;
4861
      return;
4875
    case 15: {
4862
    case 15: {
4876
        if (!inmem(a1)) {
4863
        if (!inmem(a1)) {
4877
	  mult_op (inc, a1, a1, 2, reg0);
4864
	  mult_op(inc, a1, a1, 2, reg0);
4878
	}
4865
	}
4879
	else  {
4866
	else  {
4880
	  move (sha, a1, reg0);
4867
	  move(sha, a1, reg0);
4881
	  mult_op (inc, reg0, reg0, 2, reg0);
4868
	  mult_op(inc, reg0, reg0, 2, reg0);
4882
	};
4869
	};
4883
	contop (dest.where_exp, 1, dest);
4870
	contop(dest.where_exp, 1, dest);
4884
	mult_op (inc, reg0, reg0, 4, dest);
4871
	mult_op(inc, reg0, reg0, 4, dest);
4885
	invalidate_dest (reg0);
4872
	invalidate_dest(reg0);
4886
	invalidate_dest (dest);
4873
	invalidate_dest(dest);
4887
	son(dest.where_exp) = holdd;
4874
	son(dest.where_exp) = holdd;
4888
	return;
4875
	return;
4889
      };
4876
      };
4890
    case 25: {
4877
    case 25: {
4891
        if (!inmem(a1)) {
4878
        if (!inmem(a1)) {
4892
	  mult_op (inc, a1, a1, 4, reg0);
4879
	  mult_op(inc, a1, a1, 4, reg0);
4893
	}
4880
	}
4894
	else  {
4881
	else  {
4895
	  move (sha, a1, reg0);
4882
	  move(sha, a1, reg0);
4896
	  mult_op (inc, reg0, reg0, 4, reg0);
4883
	  mult_op(inc, reg0, reg0, 4, reg0);
4897
	};
4884
	};
4898
	contop (dest.where_exp, 1, dest);
4885
	contop(dest.where_exp, 1, dest);
4899
	mult_op (inc, reg0, reg0, 4, dest);
4886
	mult_op(inc, reg0, reg0, 4, dest);
4900
	invalidate_dest (reg0);
4887
	invalidate_dest(reg0);
4901
	invalidate_dest (dest);
4888
	invalidate_dest(dest);
4902
	son(dest.where_exp) = holdd;
4889
	son(dest.where_exp) = holdd;
4903
	return;
4890
	return;
4904
      };
4891
      };
4905
    default:
4892
    default:
4906
      if ((n & (n - 1)) == 0) {
4893
      if ((n & (n - 1)) == 0) {
4907
	int  mask = 1;
4894
	int  mask = 1;
4908
	int  c;
4895
	int  c;
4909
	for (c = 0; (mask & n) == 0; ++c)
4896
	for (c = 0;(mask & n) == 0; ++c)
4910
	  mask += mask;
4897
	  mask += mask;
4911
	shiftl (sha, mw (zeroe, c), a1, dest);
4898
	shiftl(sha, mw(zeroe, c), a1, dest);
4912
	return;
4899
	return;
4913
      };
4900
      };
4914
      if ((-n & (-n - 1)) == 0) {
4901
      if ((-n & (-n - 1)) == 0) {
4915
	int  mask = 1;
4902
	int  mask = 1;
4916
	int  c;
4903
	int  c;
4917
	for (c = 0; (mask & -n) == 0; ++c)
4904
	for (c = 0;(mask & -n) == 0; ++c)
4918
	  mask += mask;
4905
	  mask += mask;
4919
	shiftl (sha, mw (zeroe, c), a1, dest);
4906
	shiftl(sha, mw(zeroe, c), a1, dest);
4920
        negate (sha, dest, dest);
4907
        negate(sha, dest, dest);
4921
	return;
4908
	return;
4922
      };
4909
      };
4923
      for (i = 0; i < short_mults; ++i) {
4910
      for (i = 0; i < short_mults; ++i) {
4924
	if ((n % mtab[i]) == 0) {
4911
	if ((n % mtab[i]) == 0) {
4925
	  int  x = n / mtab[i];
4912
	  int  x = n / mtab[i];
4926
	  if ((x & (x - 1)) == 0) {
4913
	  if ((x & (x - 1)) == 0) {
4927
	    where w;
4914
	    where w;
4928
	    if (inmem (dest))
4915
	    if (inmem(dest))
4929
	      w = reg0;
4916
	      w = reg0;
4930
	    else
4917
	    else
4931
	      w = dest;
4918
	      w = dest;
4932
	    longc_mult (a1, mw (zeroe, mtab[i]), w, 0);
4919
	    longc_mult(a1, mw(zeroe, mtab[i]), w, 0);
4933
	    longc_mult (w, mw (zeroe, x), dest, inc);
4920
	    longc_mult(w, mw(zeroe, x), dest, inc);
4934
	    return;
4921
	    return;
4935
	  };
4922
	  };
4936
	  for (j = 0; j < short_mults; ++j) {
4923
	  for (j = 0; j < short_mults; ++j) {
4937
	    if (x == mtab[j]) {
4924
	    if (x == mtab[j]) {
4938
	      where w;
4925
	      where w;
4939
	      if (inmem (dest))
4926
	      if (inmem(dest))
4940
		w = reg0;
4927
		w = reg0;
4941
	      else
4928
	      else
4942
		w = dest;
4929
		w = dest;
4943
	      longc_mult (a1, mw (zeroe, mtab[i]), w, 0);
4930
	      longc_mult(a1, mw(zeroe, mtab[i]), w, 0);
4944
	      longc_mult (w, mw (zeroe, x), dest, inc);
4931
	      longc_mult(w, mw(zeroe, x), dest, inc);
4945
	      return;
4932
	      return;
4946
	    };
4933
	    };
4947
	  };
4934
	  };
4948
	};
4935
	};
4949
      };
4936
      };
4950
      multiply (sha, a1, a2, dest);
4937
      multiply(sha, a1, a2, dest);
4951
      return;
4938
      return;
4952
  };
4939
  };
4953
}
4940
}
4954
 
4941
 
4955
/* multiply a1 by a2 and put into dest.
4942
/* multiply a1 by a2 and put into dest.
4956
   look out for special cases by calling
4943
   look out for special cases by calling
4957
   longc_mult */
4944
   longc_mult */
4958
void mult
4945
void mult
4959
    PROTO_N ( (sha, a1, a2, dest) )
-
 
4960
    PROTO_T ( shape sha X where a1 X where a2 X where dest )
4946
(shape sha, where a1, where a2, where dest)
4961
{
4947
{
4962
  int  inc = 0;
4948
  int  inc = 0;
4963
  int sha_size = shape_size(sha);
4949
  int sha_size = shape_size(sha);
4964
  cond1_set = 0;
4950
  cond1_set = 0;
4965
  cond2_set = 0;
4951
  cond2_set = 0;
4966
 
4952
 
4967
  if (name (a1.where_exp) == val_tag && sha_size == 32) {
4953
  if (name(a1.where_exp) == val_tag && sha_size == 32) {
4968
    longc_mult (a2, a1, dest, inc);
4954
    longc_mult(a2, a1, dest, inc);
4969
    return;
4955
    return;
4970
  };
4956
  };
4971
 
4957
 
4972
  if (name (a2.where_exp) == val_tag && sha_size == 32) {
4958
  if (name(a2.where_exp) == val_tag && sha_size == 32) {
4973
    longc_mult (a1, a2, dest, inc);
4959
    longc_mult(a1, a2, dest, inc);
4974
    return;
4960
    return;
4975
  };
4961
  };
4976
 
4962
 
4977
  multiply (sha, a1, a2, dest);
4963
  multiply(sha, a1, a2, dest);
4978
  return;
4964
  return;
4979
}
4965
}
4980
 
4966
 
4981
 
4967
 
4982
 
4968
 
4983
/* shift from wshift places to to. */
4969
/* shift from wshift places to to. */
4984
void shiftl
4970
void shiftl
4985
    PROTO_N ( (sha, wshift, from, to) )
-
 
4986
    PROTO_T ( shape sha X where wshift X where from X where to )
4971
(shape sha, where wshift, where from, where to)
4987
{
4972
{
4988
  exp p = wshift.where_exp;
4973
  exp p = wshift.where_exp;
4989
  int  places = no (p) + wshift.where_off;
4974
  int  places = no(p) + wshift.where_off;
4990
  char *shifter;
4975
  char *shifter;
4991
  int  sz;
4976
  int  sz;
4992
  int sig = is_signed (sha);
4977
  int sig = is_signed(sha);
4993
  exp holdto = son(to.where_exp);
4978
  exp holdto = son(to.where_exp);
4994
  sz = shape_size(sha);
4979
  sz = shape_size(sha);
4995
 
4980
 
4996
  cond1_set = 0;
4981
  cond1_set = 0;
4997
  cond2_set = 0;
4982
  cond2_set = 0;
4998
 
4983
 
4999
  if (sz == 64) {
4984
  if (sz == 64) {
5000
    int riu = regsinuse;
4985
    int riu = regsinuse;
5001
    move (sha, from, reg0);
4986
    move(sha, from, reg0);
5002
    if (name(wshift.where_exp) == val_tag)
4987
    if (name(wshift.where_exp) == val_tag)
5003
      rotshift64 (0, sig, wshift);
4988
      rotshift64(0, sig, wshift);
5004
    else {	/* need count in reg2 */
4989
    else {	/* need count in reg2 */
5005
      if (regsinuse & 0x4) {
4990
      if (regsinuse & 0x4) {
5006
        ins0(pushecx);
4991
        ins0(pushecx);
5007
#ifdef NEWDWARF
4992
#ifdef NEWDWARF
5008
	if (diagnose && dwarf2 && no_frame)
4993
	if (diagnose && dwarf2 && no_frame)
5009
	  dw2_track_push();
4994
	  dw2_track_push();
5010
#endif
4995
#endif
5011
        extra_stack += 32;
4996
        extra_stack += 32;
5012
        check_stack_max;
4997
        check_stack_max;
5013
      };
4998
      };
5014
      reg0_in_use = 1;
4999
      reg0_in_use = 1;
5015
      regsinuse |= 0x2;
5000
      regsinuse |= 0x2;
5016
      move (slongsh, wshift, reg2);
5001
      move(slongsh, wshift, reg2);
5017
      rotshift64 (0, sig, wshift);
5002
      rotshift64(0, sig, wshift);
5018
      invalidate_dest (reg2);
5003
      invalidate_dest(reg2);
5019
      if (regsinuse & 0x4) {
5004
      if (regsinuse & 0x4) {
5020
         ins0(popecx);
5005
         ins0(popecx);
5021
#ifdef NEWDWARF
5006
#ifdef NEWDWARF
5022
	if (diagnose && dwarf2 && no_frame)
5007
	if (diagnose && dwarf2 && no_frame)
5023
	  dw2_track_pop();
5008
	  dw2_track_pop();
5024
#endif
5009
#endif
5025
         extra_stack -= 32;
5010
         extra_stack -= 32;
5026
      }
5011
      }
5027
    };
5012
    };
5028
    invalidate_dest (reg0);
5013
    invalidate_dest(reg0);
5029
    invalidate_dest (reg1);
5014
    invalidate_dest(reg1);
5030
    move (sha, reg0, to);
5015
    move(sha, reg0, to);
5031
    regsinuse = riu;
5016
    regsinuse = riu;
5032
    return;
5017
    return;
5033
  }
5018
  }
5034
 
5019
 
5035
  switch (sz) {			/* choose shift operation from signedness
5020
  switch (sz) {			/* choose shift operation from signedness
5036
				   and length */
5021
				   and length */
5037
    case 8:
5022
    case 8:
5038
      shifter = (sig) ? salb : shlb;
5023
      shifter = (sig)? salb : shlb;
5039
      break;
5024
      break;
5040
    case 16:
5025
    case 16:
5041
      shifter = (sig) ? salw : shlw;
5026
      shifter = (sig)? salw : shlw;
5042
      break;
5027
      break;
5043
    default:
5028
    default:
5044
      shifter = (sig) ? sall : shll;
5029
      shifter = (sig)? sall : shll;
5045
  };
5030
  };
5046
 
5031
 
5047
  if (name (p) == val_tag) {	/* no of places is constant */
5032
  if (name (p) == val_tag) {	/* no of places is constant */
5048
    if (places >= 32) {
5033
    if (places >= 32) {
5049
      move (sha, zero, to);
5034
      move(sha, zero, to);
5050
      return;
5035
      return;
5051
    };
5036
    };
5052
    if (places == 0)
5037
    if (places == 0)
5053
      {
5038
      {
5054
        move(sha, from, to);
5039
        move(sha, from, to);
5055
        return;
5040
        return;
5056
      };
5041
      };
5057
 
5042
 
5058
    if (places >=1 && places <= 1)	/* correspond to longc_mult */
5043
    if (places >=1 && places <= 1)	/* correspond to longc_mult */
5059
     {
5044
     {
5060
       int k = 8;
5045
       int k = 8;
5061
       if (places == 1)
5046
       if (places == 1)
5062
         k = 2;
5047
         k = 2;
Line 5065... Line 5050...
5065
       longc_mult(from, mw(zeroe, k), to, 0);
5050
       longc_mult(from, mw(zeroe, k), to, 0);
5066
       return;
5051
       return;
5067
     };
5052
     };
5068
 
5053
 
5069
    if (eq_where (from, to)) {	/* shift in situ */
5054
    if (eq_where (from, to)) {	/* shift in situ */
5070
      contop (to.where_exp, 0, to);
5055
      contop(to.where_exp, 0, to);
5071
      ins2 (shifter, 8, sz, wshift, to);
5056
      ins2(shifter, 8, sz, wshift, to);
5072
      invalidate_dest (to);
5057
      invalidate_dest(to);
5073
      end_contop ();
5058
      end_contop();
5074
      son(to.where_exp) = holdto;
5059
      son(to.where_exp) = holdto;
5075
      return;
5060
      return;
5076
    };
5061
    };
5077
    if (!inmem (to)) {		/* to is a register */
5062
    if (!inmem (to)) {		/* to is a register */
5078
      move (sha, from, to);
5063
      move(sha, from, to);
5079
      contop (to.where_exp, 0, to);
5064
      contop(to.where_exp, 0, to);
5080
      ins2 (shifter, 8, sz, wshift, to);
5065
      ins2(shifter, 8, sz, wshift, to);
5081
      invalidate_dest (to);
5066
      invalidate_dest(to);
5082
      end_contop ();
5067
      end_contop();
5083
      son(to.where_exp) = holdto;
5068
      son(to.where_exp) = holdto;
5084
      return;
5069
      return;
5085
    };
5070
    };
5086
    /* use reg0 to shift in */
5071
    /* use reg0 to shift in */
5087
    move (sha, from, reg0);
5072
    move(sha, from, reg0);
5088
    ins2 (shifter, 8, sz, wshift, reg0);
5073
    ins2(shifter, 8, sz, wshift, reg0);
5089
    invalidate_dest (reg0);
5074
    invalidate_dest(reg0);
5090
    move (sha, reg0, to);
5075
    move(sha, reg0, to);
5091
    invalidate_dest (to);
5076
    invalidate_dest(to);
5092
    return;
5077
    return;
5093
  };
5078
  };
5094
  {				/* we don't know the number of places */
5079
  {				/* we don't know the number of places */
5095
    int   to_reg2,
5080
    int   to_reg2,
5096
          wshift_reg2;
5081
          wshift_reg2;
5097
    to_reg2 = eq_where (to, reg2);
5082
    to_reg2 = eq_where(to, reg2);
5098
    wshift_reg2 = eq_where (wshift, reg2);
5083
    wshift_reg2 = eq_where(wshift, reg2);
5099
 
5084
 
5100
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2) {
5085
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2) {
5101
      ins0(pushecx);
5086
      ins0(pushecx);
5102
#ifdef NEWDWARF
5087
#ifdef NEWDWARF
5103
      if (diagnose && dwarf2 && no_frame)
5088
      if (diagnose && dwarf2 && no_frame)
5104
	dw2_track_push();
5089
	dw2_track_push();
5105
#endif
5090
#endif
5106
      extra_stack += 32;
5091
      extra_stack += 32;
5107
      check_stack_max;
5092
      check_stack_max;
5108
    };
5093
    };
5109
 
5094
 
5110
    /* scan2 has guaranteed that wshift is not in reg0 */
5095
    /* scan2 has guaranteed that wshift is not in reg0 */
5111
 
5096
 
5112
    change_var (slongsh, from, reg0);
5097
    change_var(slongsh, from, reg0);
5113
    reg0_in_use = 1;
5098
    reg0_in_use = 1;
5114
    move (slongsh, wshift, reg2);
5099
    move(slongsh, wshift, reg2);
5115
 
5100
 
5116
    ins2 (shifter, 8, sz, reg2, reg0);
5101
    ins2(shifter, 8, sz, reg2, reg0);
5117
    invalidate_dest (reg0);
5102
    invalidate_dest(reg0);
5118
    invalidate_dest (reg2);
5103
    invalidate_dest(reg2);
5119
 
5104
 
5120
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2)
5105
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2)
5121
     {
5106
     {
5122
       ins0(popecx);
5107
       ins0(popecx);
5123
#ifdef NEWDWARF
5108
#ifdef NEWDWARF
5124
      if (diagnose && dwarf2 && no_frame)
5109
      if (diagnose && dwarf2 && no_frame)
5125
	dw2_track_pop();
5110
	dw2_track_pop();
5126
#endif
5111
#endif
5127
       extra_stack -= 32;
5112
       extra_stack -= 32;
5128
     }
5113
     }
5129
 
5114
 
5130
    /* reg2 might be used in the address of to */
5115
    /* reg2 might be used in the address of to */
5131
    move (sha, reg0, to);
5116
    move(sha, reg0, to);
5132
  };
5117
  };
5133
  return;
5118
  return;
5134
 
5119
 
5135
}
5120
}
5136
 
5121
 
5137
/* shift from wshift places to to. */
5122
/* shift from wshift places to to. */
5138
static void rotshiftr
5123
static void rotshiftr
5139
    PROTO_N ( (shft, sha, wshift, from, to) )
-
 
5140
    PROTO_T ( int shft X shape sha X where wshift X where from X where to )
5124
(int shft, shape sha, where wshift, where from, where to)
5141
{
5125
{
5142
  exp p = wshift.where_exp;
5126
  exp p = wshift.where_exp;
5143
  int  places = no (p) + wshift.where_off;
5127
  int  places = no(p) + wshift.where_off;
5144
  char *shifter;
5128
  char *shifter;
5145
  int  sz;
5129
  int  sz;
5146
  int sig = is_signed (sha);
5130
  int sig = is_signed(sha);
5147
  exp holdto = son(to.where_exp);
5131
  exp holdto = son(to.where_exp);
5148
  sz = shape_size(sha);
5132
  sz = shape_size(sha);
5149
 
5133
 
5150
  cond1_set = 0;
5134
  cond1_set = 0;
5151
  cond2_set = 0;
5135
  cond2_set = 0;
5152
 
5136
 
5153
  if (sz == 64) {
5137
  if (sz == 64) {
5154
    int riu = regsinuse;
5138
    int riu = regsinuse;
5155
    move (sha, from, reg0);
5139
    move(sha, from, reg0);
5156
    if (name(wshift.where_exp) == val_tag)
5140
    if (name(wshift.where_exp) == val_tag)
5157
      rotshift64 (shft+1, sig, wshift);
5141
      rotshift64(shft+1, sig, wshift);
5158
    else {	/* need count in reg2 */
5142
    else {	/* need count in reg2 */
5159
      if (regsinuse & 0x4) {
5143
      if (regsinuse & 0x4) {
5160
        ins0(pushecx);
5144
        ins0(pushecx);
5161
#ifdef NEWDWARF
5145
#ifdef NEWDWARF
5162
	if (diagnose && dwarf2 && no_frame)
5146
	if (diagnose && dwarf2 && no_frame)
5163
	  dw2_track_push();
5147
	  dw2_track_push();
5164
#endif
5148
#endif
5165
        extra_stack += 32;
5149
        extra_stack += 32;
5166
        check_stack_max;
5150
        check_stack_max;
5167
      };
5151
      };
5168
      reg0_in_use = 1;
5152
      reg0_in_use = 1;
5169
      regsinuse |= 0x2;
5153
      regsinuse |= 0x2;
5170
      move (slongsh, wshift, reg2);
5154
      move(slongsh, wshift, reg2);
5171
      rotshift64 (shft+1, sig, wshift);
5155
      rotshift64(shft+1, sig, wshift);
5172
      invalidate_dest (reg2);
5156
      invalidate_dest(reg2);
5173
      if (regsinuse & 0x4) {
5157
      if (regsinuse & 0x4) {
5174
         ins0(popecx);
5158
         ins0(popecx);
5175
#ifdef NEWDWARF
5159
#ifdef NEWDWARF
5176
	if (diagnose && dwarf2 && no_frame)
5160
	if (diagnose && dwarf2 && no_frame)
5177
	  dw2_track_pop();
5161
	  dw2_track_pop();
5178
#endif
5162
#endif
5179
         extra_stack -= 32;
5163
         extra_stack -= 32;
5180
      }
5164
      }
5181
    };
5165
    };
5182
    invalidate_dest (reg0);
5166
    invalidate_dest(reg0);
5183
    invalidate_dest (reg1);
5167
    invalidate_dest(reg1);
5184
    move (sha, reg0, to);
5168
    move(sha, reg0, to);
5185
    regsinuse = riu;
5169
    regsinuse = riu;
5186
    return;
5170
    return;
5187
  }
5171
  }
5188
 
5172
 
5189
  if (shft == 0) {
5173
  if (shft == 0) {
5190
    switch (sz) {
5174
    switch (sz) {
5191
      case 8:
5175
      case 8:
5192
        shifter = (sig) ? sarb : shrb;
5176
        shifter = (sig)? sarb : shrb;
5193
        break;
5177
        break;
5194
      case 16:
5178
      case 16:
5195
        shifter = (sig) ? sarw : shrw;
5179
        shifter = (sig)? sarw : shrw;
5196
        break;
5180
        break;
5197
      default:
5181
      default:
5198
        shifter = (sig) ? sarl : shrl;
5182
        shifter = (sig)? sarl : shrl;
5199
    }
5183
    }
5200
  }
5184
  }
5201
  else {
5185
  else {
5202
    switch (sz) {
5186
    switch (sz) {
5203
      case 8:
5187
      case 8:
5204
        shifter = (shft == 1) ? rorb : rolb;
5188
        shifter = (shft == 1)? rorb : rolb;
5205
        break;
5189
        break;
5206
      case 16:
5190
      case 16:
5207
        shifter = (shft == 1) ? rorw : rolw;
5191
        shifter = (shft == 1)? rorw : rolw;
5208
        break;
5192
        break;
5209
      default:
5193
      default:
5210
        shifter = (shft == 1) ? rorl : roll;
5194
        shifter = (shft == 1)? rorl : roll;
5211
    }
5195
    }
5212
  };
5196
  };
5213
 
5197
 
5214
  if (name (p) == val_tag) {
5198
  if (name(p) == val_tag) {
5215
    if (places >= 32) {
5199
    if (places >= 32) {
5216
      if (sig)
5200
      if (sig)
5217
	no (p) = 31;
5201
	no(p) = 31;
5218
      else {
5202
      else {
5219
	move (sha, zero, to);
5203
	move(sha, zero, to);
5220
	return;
5204
	return;
5221
      };
5205
      };
5222
    };
5206
    };
5223
    if (eq_where (from, to)) {
5207
    if (eq_where(from, to)) {
-
 
5208
      contop(to.where_exp, 0, to);
-
 
5209
      ins2(shifter, 8, sz, wshift, to);
-
 
5210
      invalidate_dest(to);
-
 
5211
      end_contop();
-
 
5212
      son(to.where_exp) = holdto;
-
 
5213
      return;
-
 
5214
    };
-
 
5215
    if (!inmem(to)) {
-
 
5216
      move(sha, from, to);
5224
      contop (to.where_exp, 0, to);
5217
      contop(to.where_exp, 0, to);
5225
      ins2 (shifter, 8, sz, wshift, to);
5218
      ins2(shifter, 8, sz, wshift, to);
5226
      invalidate_dest (to);
5219
      invalidate_dest(to);
5227
      end_contop ();
5220
      end_contop();
5228
      son(to.where_exp) = holdto;
5221
      son(to.where_exp) = holdto;
5229
      return;
5222
      return;
5230
    };
5223
    };
5231
    if (!inmem (to)) {
-
 
5232
      move (sha, from, to);
-
 
5233
      contop (to.where_exp, 0, to);
-
 
5234
      ins2 (shifter, 8, sz, wshift, to);
-
 
5235
      invalidate_dest (to);
-
 
5236
      end_contop ();
-
 
5237
      son(to.where_exp) = holdto;
-
 
5238
      return;
-
 
5239
    };
-
 
5240
    move (sha, from, reg0);
5224
    move(sha, from, reg0);
5241
    ins2 (shifter, 8, sz, wshift, reg0);
5225
    ins2(shifter, 8, sz, wshift, reg0);
5242
    invalidate_dest (reg0);
5226
    invalidate_dest(reg0);
5243
    move (sha, reg0, to);
5227
    move(sha, reg0, to);
5244
    return;
5228
    return;
5245
  };
5229
  };
5246
  {
5230
  {
5247
    int   to_reg2,
5231
    int   to_reg2,
5248
          wshift_reg2;
5232
          wshift_reg2;
5249
    int selfed = 0;
5233
    int selfed = 0;
5250
    to_reg2 = eq_where (to, reg2);
5234
    to_reg2 = eq_where(to, reg2);
5251
    wshift_reg2 = eq_where (wshift, reg2);
5235
    wshift_reg2 = eq_where(wshift, reg2);
5252
 
5236
 
5253
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2) {
5237
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2) {
5254
      ins0(pushecx);
5238
      ins0(pushecx);
5255
#ifdef NEWDWARF
5239
#ifdef NEWDWARF
5256
      if (diagnose && dwarf2 && no_frame)
5240
      if (diagnose && dwarf2 && no_frame)
Line 5262... Line 5246...
5262
 
5246
 
5263
    /* scan2 has guaranteed that wshift is not in reg0 */
5247
    /* scan2 has guaranteed that wshift is not in reg0 */
5264
 
5248
 
5265
    if (eq_where(from, to) &&
5249
    if (eq_where(from, to) &&
5266
	 !eq_where(from, reg2) &&
5250
	 !eq_where(from, reg2) &&
5267
	 ((regsinuse & 0x4) == 0 || wshift_reg2) &&
5251
	((regsinuse & 0x4) == 0 || wshift_reg2) &&
5268
	 sz == 32) {
5252
	 sz == 32) {
5269
      move (slongsh, wshift, reg2);
5253
      move(slongsh, wshift, reg2);
5270
      ins2 (shifter, 8, sz, reg2, to);
5254
      ins2(shifter, 8, sz, reg2, to);
5271
      invalidate_dest (to);
5255
      invalidate_dest(to);
5272
      invalidate_dest (reg2);
5256
      invalidate_dest(reg2);
5273
      selfed = 1;
5257
      selfed = 1;
5274
    }
5258
    }
5275
    else {
5259
    else {
5276
      change_var (slongsh, from, reg0);
5260
      change_var(slongsh, from, reg0);
5277
      reg0_in_use = 1;
5261
      reg0_in_use = 1;
5278
      move (slongsh, wshift, reg2);
5262
      move(slongsh, wshift, reg2);
5279
 
5263
 
5280
      ins2 (shifter, 8, sz, reg2, reg0);
5264
      ins2(shifter, 8, sz, reg2, reg0);
5281
      invalidate_dest (reg0);
5265
      invalidate_dest(reg0);
5282
      invalidate_dest (reg2);
5266
      invalidate_dest(reg2);
5283
    };
5267
    };
5284
 
5268
 
5285
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2)
5269
    if (!to_reg2 && (regsinuse & 0x4) && !wshift_reg2)
5286
     {
5270
     {
5287
       ins0(popecx);
5271
       ins0(popecx);
Line 5292... Line 5276...
5292
       extra_stack -= 32;
5276
       extra_stack -= 32;
5293
     }
5277
     }
5294
 
5278
 
5295
    /* reg2 might be used in the address of to */
5279
    /* reg2 might be used in the address of to */
5296
    if (!selfed)
5280
    if (!selfed)
5297
      move (sha, reg0, to);
5281
      move(sha, reg0, to);
5298
  };
5282
  };
5299
  return;
5283
  return;
5300
 
5284
 
5301
}
5285
}
5302
 
5286
 
5303
/* shift from wshift places to to. */
5287
/* shift from wshift places to to. */
5304
void shiftr
5288
void shiftr
5305
    PROTO_N ( (sha, wshift, from, to) )
-
 
5306
    PROTO_T ( shape sha X where wshift X where from X where to )
5289
(shape sha, where wshift, where from, where to)
5307
{
5290
{
5308
  rotshiftr (0, sha, wshift, from, to);
5291
  rotshiftr(0, sha, wshift, from, to);
5309
  return;
5292
  return;
5310
}
5293
}
5311
 
5294
 
5312
/* shift from wshift places to to. */
5295
/* shift from wshift places to to. */
5313
void rotater
5296
void rotater
5314
    PROTO_N ( (sha, wshift, from, to) )
-
 
5315
    PROTO_T ( shape sha X where wshift X where from X where to )
5297
(shape sha, where wshift, where from, where to)
5316
{
5298
{
5317
  rotshiftr (1, sha, wshift, from, to);
5299
  rotshiftr(1, sha, wshift, from, to);
5318
  return;
5300
  return;
5319
}
5301
}
5320
 
5302
 
5321
/* shift from wshift places to to. */
5303
/* shift from wshift places to to. */
5322
void rotatel
5304
void rotatel
5323
    PROTO_N ( (sha, wshift, from, to) )
-
 
5324
    PROTO_T ( shape sha X where wshift X where from X where to )
5305
(shape sha, where wshift, where from, where to)
5325
{
5306
{
5326
  rotshiftr (2, sha, wshift, from, to);
5307
  rotshiftr(2, sha, wshift, from, to);
5327
  return;
5308
  return;
5328
}
5309
}
5329
 
5310
 
5330
/* divide top by bottom and put in dest */
5311
/* divide top by bottom and put in dest */
5331
static void divit
5312
static void divit
5332
    PROTO_N ( (sha, bottom, top, dest, whichdiv, use_shift) )
-
 
5333
    PROTO_T ( shape sha X where bottom X where top X where dest X int whichdiv X int use_shift )
5313
(shape sha, where bottom, where top, where dest, int whichdiv, int use_shift)
5334
{
5314
{
5335
  int sz;
5315
  int sz;
5336
  int v;
5316
  int v;
5337
  where d;
5317
  where d;
5338
  int sg = is_signed (sha);
5318
  int sg = is_signed(sha);
5339
  int r1flag = 0, r2flag = 0;
5319
  int r1flag = 0, r2flag = 0;
5340
  int reslab = 0, test_zero = 0, test_ov = 0;
5320
  int reslab = 0, test_zero = 0, test_ov = 0;
5341
  shape shb = sh(bottom.where_exp);
5321
  shape shb = sh(bottom.where_exp);
5342
  d = bottom;
5322
  d = bottom;
5343
 
5323
 
Line 5345... Line 5325...
5345
    sg = 1;  /* fudge because some systems have ptrdiff_t as unsigned
5325
    sg = 1;  /* fudge because some systems have ptrdiff_t as unsigned
5346
                though ANSI C says it must be signed
5326
                though ANSI C says it must be signed
5347
             */
5327
             */
5348
 
5328
 
5349
  if (overflow_e != nilexp && !istrap(overflow_e)) {
5329
  if (overflow_e != nilexp && !istrap(overflow_e)) {
5350
    if (name (bottom.where_exp) != val_tag || no(bottom.where_exp) == 0)
5330
    if (name(bottom.where_exp)!= val_tag || no(bottom.where_exp) == 0)
5351
      test_zero = 1;
5331
      test_zero = 1;
5352
    if (sg && (name (bottom.where_exp) != val_tag || no(bottom.where_exp) == -1))
5332
    if (sg && (name(bottom.where_exp)!= val_tag || no(bottom.where_exp) == -1))
5353
      test_ov = 1;
5333
      test_ov = 1;
5354
  }
5334
  }
5355
 
5335
 
5356
  sz = shape_size(sha);
5336
  sz = shape_size(sha);
5357
 
5337
 
5358
  cond1_set = 0;
5338
  cond1_set = 0;
5359
  cond2_set = 0;
5339
  cond2_set = 0;
5360
 
5340
 
5361
  if ((use_shift || !sg) &&
5341
  if ((use_shift || !sg) &&
5362
      name (bottom.where_exp) == val_tag && !isbigval(bottom.where_exp) &&
5342
      name(bottom.where_exp) == val_tag && !isbigval(bottom.where_exp) &&
5363
      (v = no (bottom.where_exp), v > 0 && (v & (v - 1)) == 0) ) {
5343
     (v = no(bottom.where_exp), v > 0 && (v & (v - 1)) == 0)) {
5364
    int  c = 0;
5344
    int  c = 0;
5365
    int  m = 1;
5345
    int  m = 1;
5366
    where rw;
5346
    where rw;
5367
    if (name(shb) == offsethd &&
5347
    if (name(shb) == offsethd &&
5368
          al2(shb) != 1)
5348
          al2(shb)!= 1)
5369
      v = v / 8;
5349
      v = v / 8;
5370
    while (m != v) {
5350
    while (m != v) {
5371
      ++c;
5351
      ++c;
5372
      m = m << 1;
5352
      m = m << 1;
5373
    };
5353
    };
5374
 
5354
 
5375
    if (c == 0)  {
5355
    if (c == 0) {
5376
      move (sha, top, dest);
5356
      move(sha, top, dest);
5377
      return;
5357
      return;
5378
    };
5358
    };
5379
 
5359
 
5380
    if (inmem (dest))
5360
    if (inmem(dest))
5381
      rw = reg0;
5361
      rw = reg0;
5382
    else
5362
    else
5383
      rw = dest;
5363
      rw = dest;
5384
    move (sha, top, rw);
5364
    move(sha, top, rw);
5385
    switch (sz) {
5365
    switch (sz) {
5386
      case 8:
5366
      case 8:
5387
	ins2 ((sg) ? sarb : shrb, 8, 8, mw (zeroe, c), rw);
5367
	ins2((sg)? sarb : shrb, 8, 8, mw(zeroe, c), rw);
5388
	break;
5368
	break;
5389
      case 16:
5369
      case 16:
5390
	ins2 ((sg) ? sarw : shrw, 8, 16, mw (zeroe, c), rw);
5370
	ins2((sg)? sarw : shrw, 8, 16, mw(zeroe, c), rw);
5391
	break;
5371
	break;
5392
      case 64:
5372
      case 64:
5393
	rotshift64 (1, sg, mw (zeroe, c));	/* shift within reg0/reg1 */
5373
	rotshift64 (1, sg, mw (zeroe, c));	/* shift within reg0/reg1 */
5394
	break;
5374
	break;
5395
      default: /* case 32 */
5375
      default: /* case 32 */
5396
	ins2 ((sg) ? sarl : shrl, 8, 32, mw (zeroe, c), rw);
5376
	ins2((sg)? sarl : shrl, 8, 32, mw(zeroe, c), rw);
5397
    }
5377
    }
5398
    invalidate_dest (rw);
5378
    invalidate_dest(rw);
5399
    if (inmem (dest))
5379
    if (inmem(dest))
5400
      move (sha, rw, dest);
5380
      move(sha, rw, dest);
5401
    return;
5381
    return;
5402
  };
5382
  };
5403
 
5383
 
5404
  if (sz == 64 && shape_size (shb) == 64 && (
5384
  if (sz == 64 && shape_size(shb) == 64 && (
5405
	name (bottom.where_exp) != val_tag || isbigval(bottom.where_exp) ||
5385
	name(bottom.where_exp)!= val_tag || isbigval(bottom.where_exp) ||
5406
 	no (bottom.where_exp) < 0 || sg)) {
5386
 	no(bottom.where_exp) < 0 || sg)) {
5407
    needs_lib64();
5387
    needs_lib64();
5408
    if (eq_where (top, reg0)) {
5388
    if (eq_where(top, reg0)) {
5409
      ins2 (subl, 32, 32, mw(zeroe, 16), sp);
5389
      ins2(subl, 32, 32, mw(zeroe, 16), sp);
5410
      extra_stack += 128;
5390
      extra_stack += 128;
5411
      move (sha, top, mw(ind_sp.where_exp, -128));
5391
      move(sha, top, mw(ind_sp.where_exp, -128));
5412
      move (sha, bottom, mw(ind_sp.where_exp, -64));
5392
      move(sha, bottom, mw(ind_sp.where_exp, -64));
5413
      invalidate_dest (ind_sp);
5393
      invalidate_dest(ind_sp);
5414
      extra_stack -= 128;
5394
      extra_stack -= 128;
5415
    }
5395
    }
5416
    else {
5396
    else {
5417
      move (sha, bottom, pushdest);
5397
      move(sha, bottom, pushdest);
5418
      extra_stack += 64;
5398
      extra_stack += 64;
5419
      move (sha, top, pushdest);
5399
      move(sha, top, pushdest);
5420
      extra_stack -= 64;
5400
      extra_stack -= 64;
5421
    }
5401
    }
5422
    callins (0, lib64_div [sg + 2*(whichdiv==1)], stack_dec);
5402
    callins(0, lib64_div[sg + 2*(whichdiv==1)], stack_dec);
5423
    ins2 (addl, 32, 32, mw(zeroe, 16), sp);
5403
    ins2(addl, 32, 32, mw(zeroe, 16), sp);
5424
    if (overflow_e != nilexp && !optop(overflow_e)) {
5404
    if (overflow_e != nilexp && !optop(overflow_e)) {
5425
      ins2 (movl, 32, 32, mw(lib64_error, 0), reg2);
5405
      ins2(movl, 32, 32, mw(lib64_error, 0), reg2);
5426
      if (PIC_code)
5406
      if (PIC_code)
5427
        ins2 (movl, 32, 32, ind_reg2, reg2);
5407
        ins2(movl, 32, 32, ind_reg2, reg2);
5428
      ins2 (testl, 32, 32, reg2, reg2);
5408
      ins2(testl, 32, 32, reg2, reg2);
5429
      test_exception (f_greater_than_or_equal, slongsh);
5409
      test_exception(f_greater_than_or_equal, slongsh);
5430
    }
5410
    }
5431
    move (sha, reg0, dest);
5411
    move(sha, reg0, dest);
5432
    return;
5412
    return;
5433
  };
5413
  };
5434
 
5414
 
5435
  if (sz == 8) {
5415
  if (sz == 8) {
5436
    if (sg)
5416
    if (sg)
5437
      change_var (swordsh, top, reg0);
5417
      change_var(swordsh, top, reg0);
5438
    else
5418
    else
5439
      change_var (uwordsh, top, reg0);
5419
      change_var(uwordsh, top, reg0);
5440
  }
5420
  }
5441
  else
5421
  else
5442
    move (sha, top, reg0);
5422
    move(sha, top, reg0);
5443
 
5423
 
5444
 
5424
 
5445
  if (flinmem (bottom) || (eq_where (bottom, reg1) && sz > 8) || (whichdiv==1 && sg) ) {
5425
  if (flinmem(bottom) || (eq_where(bottom, reg1) && sz > 8) || (whichdiv==1 && sg)) {
5446
    d = reg2;
5426
    d = reg2;
5447
    if (regsinuse & 0x4 && !eq_where (dest, reg2)) {
5427
    if (regsinuse & 0x4 && !eq_where(dest, reg2)) {
5448
      /* preserve ecx if necessary */
5428
      /* preserve ecx if necessary */
5449
      r2flag = 1;
5429
      r2flag = 1;
5450
      ins0(pushecx);
5430
      ins0(pushecx);
5451
#ifdef NEWDWARF
5431
#ifdef NEWDWARF
5452
      if (diagnose && dwarf2 && no_frame)
5432
      if (diagnose && dwarf2 && no_frame)
5453
	dw2_track_push();
5433
	dw2_track_push();
5454
#endif
5434
#endif
Line 5457... Line 5437...
5457
    };
5437
    };
5458
    reg0_in_use = 1;
5438
    reg0_in_use = 1;
5459
    if (sz == 64) {
5439
    if (sz == 64) {
5460
      int riu = regsinuse;
5440
      int riu = regsinuse;
5461
      regsinuse |= 0x2;
5441
      regsinuse |= 0x2;
5462
      move (shb, bottom, reg2);
5442
      move(shb, bottom, reg2);
5463
      regsinuse = riu;
5443
      regsinuse = riu;
5464
    }
5444
    }
5465
    else
5445
    else
5466
      move (shb, bottom, reg2);
5446
      move(shb, bottom, reg2);
5467
  };
5447
  };
5468
 
5448
 
5469
  if (test_zero) {		/* avoid divide by zero trap */
5449
  if (test_zero) {		/* avoid divide by zero trap */
5470
    IGNORE cmp (shb, d, zero, f_not_equal, nilexp);
5450
    IGNORE cmp(shb, d, zero, f_not_equal, nilexp);
5471
    if (isov(overflow_e))
5451
    if (isov(overflow_e))
5472
      test_exception (f_not_equal, shb);
5452
      test_exception(f_not_equal, shb);
5473
    else {
5453
    else {
5474
      reslab = next_lab();
5454
      reslab = next_lab();
5475
      simple_branch (je, reslab);
5455
      simple_branch(je, reslab);
5476
    }
5456
    }
5477
  }
5457
  }
5478
 
5458
 
5479
  if (test_ov) {		/* avoid most_neg divide by -1 trap */
5459
  if (test_ov) {		/* avoid most_neg divide by -1 trap */
5480
    int divlab = next_lab ();
5460
    int divlab = next_lab();
5481
    if (reslab == 0)
5461
    if (reslab == 0)
5482
      reslab = next_lab();
5462
      reslab = next_lab();
5483
    IGNORE cmp (shb, d, mw(zeroe,-1), f_equal, nilexp);
5463
    IGNORE cmp(shb, d, mw(zeroe,-1), f_equal, nilexp);
5484
    simple_branch (jne, divlab);
5464
    simple_branch(jne, divlab);
5485
    negate (sha, reg0, reg0);
5465
    negate(sha, reg0, reg0);
5486
    simple_branch (jmp, reslab);
5466
    simple_branch(jmp, reslab);
5487
    simple_set_label(divlab);
5467
    simple_set_label(divlab);
5488
  }
5468
  }
5489
 
5469
 
5490
  if (!eq_where (dest, reg1) && regsinuse & 0x2 && sz > 8) {
5470
  if (!eq_where(dest, reg1) && regsinuse & 0x2 && sz > 8) {
5491
    r1flag = 1;
5471
    r1flag = 1;
5492
    ins0(pushedx);
5472
    ins0(pushedx);
5493
#ifdef NEWDWARF
5473
#ifdef NEWDWARF
5494
    if (diagnose && dwarf2 && no_frame)
5474
    if (diagnose && dwarf2 && no_frame)
5495
      dw2_track_push();
5475
      dw2_track_push();
5496
#endif
5476
#endif
5497
    stack_dec -= 32;
5477
    stack_dec -= 32;
5498
    check_stack_max;
5478
    check_stack_max;
5499
    invalidate_dest (reg1);
5479
    invalidate_dest(reg1);
5500
  };
5480
  };
5501
 
5481
 
5502
  if (sg) {			/* signed */
5482
  if (sg) {			/* signed */
5503
    switch (sz) {
5483
    switch (sz) {
5504
      case 8:
5484
      case 8:
5505
	ins1 (idivb, 8, d);
5485
	ins1(idivb, 8, d);
5506
	break;
5486
	break;
5507
      case 16:
5487
      case 16:
5508
	move(swordsh, reg0, reg1);
5488
	move(swordsh, reg0, reg1);
5509
	ins2(sarw, 16, 16, mw(zeroe, 15), reg1);
5489
	ins2(sarw, 16, 16, mw(zeroe, 15), reg1);
5510
	ins1 (idivw, 16, d);
5490
	ins1(idivw, 16, d);
5511
	break;
5491
	break;
5512
      case 64:
5492
      case 64:
5513
	failer(BADOP);
5493
	failer(BADOP);
5514
      default:
5494
      default:
5515
	move(slongsh, reg0, reg1);
5495
	move(slongsh, reg0, reg1);
5516
	ins2(sarl, 32, 32, mw(zeroe, 31), reg1);
5496
	ins2(sarl, 32, 32, mw(zeroe, 31), reg1);
5517
	ins1 (idivl, 32, d);
5497
	ins1(idivl, 32, d);
5518
    }
5498
    }
5519
    if (whichdiv == 1) {
5499
    if (whichdiv == 1) {
5520
      int end = next_lab();
5500
      int end = next_lab();
5521
      switch (sz) {
5501
      switch (sz) {
5522
	case 8:
5502
	case 8:
Line 5530... Line 5510...
5530
	  ins2(testw, 16, 16, reg1, reg1);
5510
	  ins2(testw, 16, 16, reg1, reg1);
5531
	  simple_branch(je, end);
5511
	  simple_branch(je, end);
5532
	  ins2(xorw, 16, 16, reg1, reg2);
5512
	  ins2(xorw, 16, 16, reg1, reg2);
5533
	  simple_branch(jge, end);
5513
	  simple_branch(jge, end);
5534
	  ins1(decw, 16, reg0);
5514
	  ins1(decw, 16, reg0);
5535
	  break;
5515
	  break;
5536
	default:
5516
	default:
5537
	  ins2(testl, 32, 32, reg1, reg1);
5517
	  ins2(testl, 32, 32, reg1, reg1);
5538
	  simple_branch(je, end);
5518
	  simple_branch(je, end);
5539
	  ins2(xorl, 32, 32, reg1, reg2);
5519
	  ins2(xorl, 32, 32, reg1, reg2);
5540
	  simple_branch(jge, end);
5520
	  simple_branch(jge, end);
5541
	  ins1(decl, 32, reg0);
5521
	  ins1(decl, 32, reg0);
5542
      }
5522
      }
5543
      simplest_set_lab(end);
5523
      simplest_set_lab(end);
5544
    };
5524
    };
5545
  }
5525
  }
5546
  else {			/* unsigned */
5526
  else {			/* unsigned */
5547
    switch (sz) {
5527
    switch (sz) {
5548
      case 8:
5528
      case 8:
5549
	ins1 (divb, 8, d);
5529
	ins1(divb, 8, d);
5550
	break;
5530
	break;
5551
      case 16:
5531
      case 16:
5552
	ins2 (xorw, 16, 16, reg1, reg1);
5532
	ins2(xorw, 16, 16, reg1, reg1);
5553
	ins1 (divw, 16, d);
5533
	ins1(divw, 16, d);
5554
	break;
5534
	break;
5555
      case 64:
5535
      case 64:
5556
	ins0 (pusheax);
5536
	ins0(pusheax);
5557
#ifdef NEWDWARF
5537
#ifdef NEWDWARF
5558
	if (diagnose && dwarf2 && no_frame)
5538
	if (diagnose && dwarf2 && no_frame)
5559
	  dw2_track_push();
5539
	  dw2_track_push();
5560
#endif
5540
#endif
5561
	move(slongsh, reg1, reg0);
5541
	move(slongsh, reg1, reg0);
5562
	ins2 (xorl, 32, 32, reg1, reg1);
5542
	ins2(xorl, 32, 32, reg1, reg1);
5563
	ins1 (divl, 32, d);
5543
	ins1(divl, 32, d);
5564
	ins2 (xchg, 32, 32, ind_sp, reg0);
5544
	ins2(xchg, 32, 32, ind_sp, reg0);
5565
	ins1 (divl, 32, d);
5545
	ins1(divl, 32, d);
5566
	ins0 (popedx);
5546
	ins0(popedx);
5567
#ifdef NEWDWARF
5547
#ifdef NEWDWARF
5568
	if (diagnose && dwarf2 && no_frame)
5548
	if (diagnose && dwarf2 && no_frame)
5569
	  dw2_track_pop();
5549
	  dw2_track_pop();
5570
#endif
5550
#endif
5571
	break;
5551
	break;
5572
      default:
5552
      default:
5573
	ins2 (xorl, 32, 32, reg1, reg1);
5553
	ins2(xorl, 32, 32, reg1, reg1);
5574
	ins1 (divl, 32, d);
5554
	ins1(divl, 32, d);
5575
    }
5555
    }
5576
  };
5556
  };
5577
  invalidate_dest (reg0);
5557
  invalidate_dest(reg0);
5578
  invalidate_dest (reg1);
5558
  invalidate_dest(reg1);
5579
  invalidate_dest (reg2);
5559
  invalidate_dest(reg2);
5580
 
5560
 
5581
  if (r1flag)
5561
  if (r1flag)
5582
   {
5562
   {
5583
     ins0(popedx);
5563
     ins0(popedx);
5584
#ifdef NEWDWARF
5564
#ifdef NEWDWARF
Line 5587... Line 5567...
5587
#endif
5567
#endif
5588
     stack_dec += 32;
5568
     stack_dec += 32;
5589
   };
5569
   };
5590
 
5570
 
5591
  if (reslab != 0)
5571
  if (reslab != 0)
5592
    simple_set_label (reslab);
5572
    simple_set_label(reslab);
5593
 
5573
 
5594
  if (r2flag)
5574
  if (r2flag)
5595
   {
5575
   {
5596
     ins0(popecx);
5576
     ins0(popecx);
5597
#ifdef NEWDWARF
5577
#ifdef NEWDWARF
Line 5599... Line 5579...
5599
	dw2_track_pop();
5579
	dw2_track_pop();
5600
#endif
5580
#endif
5601
     stack_dec += 32;
5581
     stack_dec += 32;
5602
   };
5582
   };
5603
 
5583
 
5604
  move (sha, reg0, dest);
5584
  move(sha, reg0, dest);
5605
  return;
5585
  return;
5606
}
5586
}
5607
 
5587
 
5608
 
5588
 
5609
void div2
5589
void div2
5610
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5611
    PROTO_T ( shape sha X where bottom X where top X where dest )
5590
(shape sha, where bottom, where top, where dest)
5612
{
5591
{
5613
  divit (sha, bottom, top, dest, 2, 0);
5592
  divit(sha, bottom, top, dest, 2, 0);
5614
  return;
5593
  return;
5615
}
5594
}
5616
 
5595
 
5617
void div1
5596
void div1
5618
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5619
    PROTO_T ( shape sha X where bottom X where top X where dest )
5597
(shape sha, where bottom, where top, where dest)
5620
{
5598
{
5621
  divit (sha, bottom, top, dest, 1, 1);
5599
  divit(sha, bottom, top, dest, 1, 1);
5622
  return;
5600
  return;
5623
}
5601
}
5624
 
5602
 
5625
void div0
5603
void div0
5626
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5627
    PROTO_T ( shape sha X where bottom X where top X where dest )
5604
(shape sha, where bottom, where top, where dest)
5628
{
5605
{
5629
  divit (sha, bottom, top, dest, 0, 1);
5606
  divit(sha, bottom, top, dest, 0, 1);
5630
  return;
5607
  return;
5631
}
5608
}
5632
 
5609
 
5633
/* remainder after dividing top by bottom to dest */
5610
/* remainder after dividing top by bottom to dest */
5634
static void remit
5611
static void remit
5635
    PROTO_N ( (sha, bottom, top, dest, whichrem, use_mask) )
-
 
5636
    PROTO_T ( shape sha X where bottom X where top X where dest X int whichrem X int use_mask )
5612
(shape sha, where bottom, where top, where dest, int whichrem, int use_mask)
5637
{
5613
{
5638
  int  sz;
5614
  int  sz;
5639
  where d;
5615
  where d;
5640
  int sg = is_signed (sha);
5616
  int sg = is_signed(sha);
5641
  int r1flag = 0, r2flag = 0;
5617
  int r1flag = 0, r2flag = 0;
5642
  int  v;
5618
  int  v;
5643
  int reslab = 0, test_zero = 0, test_ov = 0;
5619
  int reslab = 0, test_zero = 0, test_ov = 0;
5644
  shape shb = sh(bottom.where_exp);
5620
  shape shb = sh(bottom.where_exp);
5645
  d = bottom;
5621
  d = bottom;
5646
  sz = shape_size(sha);
5622
  sz = shape_size(sha);
5647
 
5623
 
5648
  if (overflow_e != nilexp && !istrap(overflow_e)) {
5624
  if (overflow_e != nilexp && !istrap(overflow_e)) {
5649
    if (name (bottom.where_exp) != val_tag || no(bottom.where_exp) == 0)
5625
    if (name(bottom.where_exp)!= val_tag || no(bottom.where_exp) == 0)
5650
      test_zero = 1;
5626
      test_zero = 1;
5651
    if (sg && (name (bottom.where_exp) != val_tag || no(bottom.where_exp) == -1))
5627
    if (sg && (name(bottom.where_exp)!= val_tag || no(bottom.where_exp) == -1))
5652
      test_ov = 1;
5628
      test_ov = 1;
5653
  }
5629
  }
5654
 
5630
 
5655
  cond1_set = 0;
5631
  cond1_set = 0;
5656
  cond2_set = 0;
5632
  cond2_set = 0;
5657
 
5633
 
5658
  if ((use_mask || !sg) &&
5634
  if ((use_mask || !sg) &&
5659
      name (bottom.where_exp) == val_tag && !isbigval(bottom.where_exp) &&
5635
      name(bottom.where_exp) == val_tag && !isbigval(bottom.where_exp) &&
5660
      (v = no (bottom.where_exp), v > 0 && (v & (v - 1)) == 0)) {
5636
     (v = no(bottom.where_exp), v > 0 && (v & (v - 1)) == 0)) {
5661
    /* use and if possible (Note this is compatible with ANSI C, but not
5637
    /* use and if possible (Note this is compatible with ANSI C, but not
5662
       with Ada) */
5638
       with Ada) */
5663
    int  c = 0;
5639
    int  c = 0;
5664
    int  m = 1;
5640
    int  m = 1;
5665
    while (m != v) {
5641
    while (m != v) {
5666
      ++c;
5642
      ++c;
5667
      m = m << 1;
5643
      m = m << 1;
5668
    };
5644
    };
5669
    and (sha, top, mw (zeroe, lsmask[c]), dest);
5645
    and(sha, top, mw(zeroe, lsmask[c]), dest);
5670
    return;
5646
    return;
5671
  };
5647
  };
5672
 
5648
 
5673
  if (sz == 64 && shape_size (shb) == 64 && (
5649
  if (sz == 64 && shape_size(shb) == 64 && (
5674
	name (bottom.where_exp) != val_tag || isbigval(bottom.where_exp) ||
5650
	name(bottom.where_exp)!= val_tag || isbigval(bottom.where_exp) ||
5675
 	no (bottom.where_exp) < 0 || sg)) {
5651
 	no(bottom.where_exp) < 0 || sg)) {
5676
    needs_lib64();
5652
    needs_lib64();
5677
    if (eq_where (top, reg0)) {
5653
    if (eq_where(top, reg0)) {
5678
      ins2 (subl, 32, 32, mw(zeroe, 16), sp);
5654
      ins2(subl, 32, 32, mw(zeroe, 16), sp);
5679
      extra_stack += 128;
5655
      extra_stack += 128;
5680
      move (sha, top, mw(ind_sp.where_exp, -128));
5656
      move(sha, top, mw(ind_sp.where_exp, -128));
5681
      move (sha, bottom, mw(ind_sp.where_exp, -64));
5657
      move(sha, bottom, mw(ind_sp.where_exp, -64));
5682
      extra_stack -= 128;
5658
      extra_stack -= 128;
5683
    }
5659
    }
5684
    else {
5660
    else {
5685
      move (sha, bottom, pushdest);
5661
      move(sha, bottom, pushdest);
5686
      extra_stack += 64;
5662
      extra_stack += 64;
5687
      move (sha, top, pushdest);
5663
      move(sha, top, pushdest);
5688
      extra_stack -= 64;
5664
      extra_stack -= 64;
5689
    }
5665
    }
5690
    callins (0, lib64_rem [sg + 2*(whichrem==1)], stack_dec);
5666
    callins(0, lib64_rem[sg + 2*(whichrem==1)], stack_dec);
5691
    ins2 (addl, 32, 32, mw(zeroe, 16), sp);
5667
    ins2(addl, 32, 32, mw(zeroe, 16), sp);
5692
    if (overflow_e != nilexp && !optop(overflow_e)) {
5668
    if (overflow_e != nilexp && !optop(overflow_e)) {
5693
      ins2 (movl, 32, 32, mw(lib64_error, 0), reg2);
5669
      ins2(movl, 32, 32, mw(lib64_error, 0), reg2);
5694
      if (PIC_code)
5670
      if (PIC_code)
5695
        ins2 (movl, 32, 32, ind_reg2, reg2);
5671
        ins2(movl, 32, 32, ind_reg2, reg2);
5696
      ins2 (testl, 32, 32, reg2, reg2);
5672
      ins2(testl, 32, 32, reg2, reg2);
5697
      test_exception (f_greater_than_or_equal, slongsh);
5673
      test_exception(f_greater_than_or_equal, slongsh);
5698
    }
5674
    }
5699
    move (sha, reg0, dest);
5675
    move(sha, reg0, dest);
5700
    return;
5676
    return;
5701
  };
5677
  };
5702
 
5678
 
5703
  if (sz == 8) {
5679
  if (sz == 8) {
5704
    if (sg)
5680
    if (sg)
5705
      change_var (swordsh, top, reg0);
5681
      change_var(swordsh, top, reg0);
5706
    else
5682
    else
5707
      change_var (uwordsh, top, reg0);
5683
      change_var(uwordsh, top, reg0);
5708
  }
5684
  }
5709
  else
5685
  else
5710
    move (sha, top, reg0);
5686
    move(sha, top, reg0);
5711
 
5687
 
5712
 
5688
 
5713
  if (flinmem (bottom) || (eq_where (bottom, reg1) && sz > 8) || (whichrem==1 && sg) ) {
5689
  if (flinmem(bottom) || (eq_where(bottom, reg1) && sz > 8) || (whichrem==1 && sg)) {
5714
    d = reg2;
5690
    d = reg2;
5715
    if (regsinuse & 0x4 && !eq_where (dest, reg2)) {
5691
    if (regsinuse & 0x4 && !eq_where(dest, reg2)) {
5716
      /* preserve ecx if necessary */
5692
      /* preserve ecx if necessary */
5717
      r2flag = 1;
5693
      r2flag = 1;
5718
      ins0(pushecx);
5694
      ins0(pushecx);
5719
#ifdef NEWDWARF
5695
#ifdef NEWDWARF
5720
      if (diagnose && dwarf2 && no_frame)
5696
      if (diagnose && dwarf2 && no_frame)
Line 5725... Line 5701...
5725
    };
5701
    };
5726
    reg0_in_use = 1;
5702
    reg0_in_use = 1;
5727
    if (sz == 64) {
5703
    if (sz == 64) {
5728
      int riu = regsinuse;
5704
      int riu = regsinuse;
5729
      regsinuse |= 0x2;
5705
      regsinuse |= 0x2;
5730
      move (shb, bottom, reg2);
5706
      move(shb, bottom, reg2);
5731
      regsinuse = riu;
5707
      regsinuse = riu;
5732
    }
5708
    }
5733
    else
5709
    else
5734
      move (shb, bottom, reg2);
5710
      move(shb, bottom, reg2);
5735
  };
5711
  };
5736
 
5712
 
5737
  if (test_zero) {		/* avoid divide by zero trap */
5713
  if (test_zero) {		/* avoid divide by zero trap */
5738
    IGNORE cmp (shb, d, zero, f_not_equal, nilexp);
5714
    IGNORE cmp(shb, d, zero, f_not_equal, nilexp);
5739
    if (isov(overflow_e))
5715
    if (isov(overflow_e))
5740
      test_exception (f_not_equal, shb);
5716
      test_exception(f_not_equal, shb);
5741
    else {
5717
    else {
5742
      reslab = next_lab();
5718
      reslab = next_lab();
5743
      simple_branch (je, reslab);
5719
      simple_branch(je, reslab);
5744
    }
5720
    }
5745
  }
5721
  }
5746
 
5722
 
5747
  if (test_ov) {		/* avoid most_neg divide by -1 trap */
5723
  if (test_ov) {		/* avoid most_neg divide by -1 trap */
5748
    int divlab = next_lab ();
5724
    int divlab = next_lab();
5749
    if (reslab == 0)
5725
    if (reslab == 0)
5750
      reslab = next_lab();
5726
      reslab = next_lab();
5751
    IGNORE cmp (shb, d, mw(zeroe,-1), f_equal, nilexp);
5727
    IGNORE cmp(shb, d, mw(zeroe,-1), f_equal, nilexp);
5752
    simple_branch (jne, divlab);
5728
    simple_branch(jne, divlab);
5753
    move (sha, zero, reg0);
5729
    move(sha, zero, reg0);
5754
    simple_branch (jmp, reslab);
5730
    simple_branch(jmp, reslab);
5755
    simple_set_label(divlab);
5731
    simple_set_label(divlab);
5756
  }
5732
  }
5757
 
5733
 
5758
  if (!eq_where (dest, reg1) && regsinuse & 0x2 && sz > 8) {
5734
  if (!eq_where(dest, reg1) && regsinuse & 0x2 && sz > 8) {
5759
    r1flag = 1;
5735
    r1flag = 1;
5760
    ins0(pushedx);
5736
    ins0(pushedx);
5761
#ifdef NEWDWARF
5737
#ifdef NEWDWARF
5762
    if (diagnose && dwarf2 && no_frame)
5738
    if (diagnose && dwarf2 && no_frame)
5763
      dw2_track_push();
5739
      dw2_track_push();
5764
#endif
5740
#endif
5765
    stack_dec -= 32;
5741
    stack_dec -= 32;
5766
    check_stack_max;
5742
    check_stack_max;
5767
    invalidate_dest (reg1);
5743
    invalidate_dest(reg1);
5768
  };
5744
  };
5769
 
5745
 
5770
  if (sg) {			/* signed */
5746
  if (sg) {			/* signed */
5771
    switch (sz) {
5747
    switch (sz) {
5772
      case 8:
5748
      case 8:
5773
	ins1 (idivb, 8, d);
5749
	ins1(idivb, 8, d);
5774
	break;
5750
	break;
5775
      case 16:
5751
      case 16:
5776
	move(swordsh, reg0, reg1);
5752
	move(swordsh, reg0, reg1);
5777
	ins2(sarw, 16, 16, mw(zeroe, 15), reg1);
5753
	ins2(sarw, 16, 16, mw(zeroe, 15), reg1);
5778
	ins1 (idivw, 16, d);
5754
	ins1(idivw, 16, d);
5779
	break;
5755
	break;
5780
      case 64:
5756
      case 64:
5781
	failer(BADOP);
5757
	failer(BADOP);
5782
      default:
5758
      default:
5783
	move(slongsh, reg0, reg1);
5759
	move(slongsh, reg0, reg1);
5784
	ins2(sarl, 32, 32, mw(zeroe, 31), reg1);
5760
	ins2(sarl, 32, 32, mw(zeroe, 31), reg1);
5785
	ins1 (idivl, 32, d);
5761
	ins1(idivl, 32, d);
5786
    }
5762
    }
5787
    if (whichrem==1) {
5763
    if (whichrem==1) {
5788
      int end = next_lab();
5764
      int end = next_lab();
5789
      switch (sz) {
5765
      switch (sz) {
5790
	case 8:
5766
	case 8:
Line 5815... Line 5791...
5815
     };
5791
     };
5816
  }
5792
  }
5817
  else {			/* unsigned */
5793
  else {			/* unsigned */
5818
    switch (sz) {
5794
    switch (sz) {
5819
      case 8:
5795
      case 8:
5820
	ins1 (divb, 8, d);
5796
	ins1(divb, 8, d);
5821
	break;
5797
	break;
5822
      case 16:
5798
      case 16:
5823
	ins2 (xorw, 16, 16, reg1, reg1);
5799
	ins2(xorw, 16, 16, reg1, reg1);
5824
	ins1 (divw, 16, d);
5800
	ins1(divw, 16, d);
5825
	break;
5801
	break;
5826
      case 64:
5802
      case 64:
5827
	ins0 (pusheax);
5803
	ins0(pusheax);
5828
#ifdef NEWDWARF
5804
#ifdef NEWDWARF
5829
	if (diagnose && dwarf2 && no_frame)
5805
	if (diagnose && dwarf2 && no_frame)
5830
	  dw2_track_push();
5806
	  dw2_track_push();
5831
#endif
5807
#endif
5832
	move(slongsh, reg1, reg0);
5808
	move(slongsh, reg1, reg0);
5833
	ins2 (xorl, 32, 32, reg1, reg1);
5809
	ins2(xorl, 32, 32, reg1, reg1);
5834
	ins1 (divl, 32, d);
5810
	ins1(divl, 32, d);
5835
	ins0 (popeax);
5811
	ins0(popeax);
5836
#ifdef NEWDWARF
5812
#ifdef NEWDWARF
5837
        if (diagnose && dwarf2 && no_frame)
5813
        if (diagnose && dwarf2 && no_frame)
5838
	  dw2_track_pop();
5814
	  dw2_track_pop();
5839
#endif
5815
#endif
5840
	ins1 (divl, 32, d);
5816
	ins1(divl, 32, d);
5841
	break;
5817
	break;
5842
      default:
5818
      default:
5843
	ins2 (xorl, 32, 32, reg1, reg1);
5819
	ins2(xorl, 32, 32, reg1, reg1);
5844
	ins1 (divl, 32, d);
5820
	ins1(divl, 32, d);
5845
    }
5821
    }
5846
  };
5822
  };
5847
  if (sz == 8)
5823
  if (sz == 8)
5848
    ins0 ("movb %ah,%al");
5824
    ins0("movb %ah,%al");
5849
  else
5825
  else
5850
  if (sz == 64) {
5826
  if (sz == 64) {
5851
    move(slongsh, reg1, reg0);
5827
    move(slongsh, reg1, reg0);
5852
    ins2 (xorl, 32, 32, reg1, reg1);
5828
    ins2(xorl, 32, 32, reg1, reg1);
5853
  }
5829
  }
5854
  else
5830
  else
5855
    move(sha, reg1, reg0);
5831
    move(sha, reg1, reg0);
5856
  invalidate_dest (reg0);
5832
  invalidate_dest(reg0);
5857
  invalidate_dest (reg1);
5833
  invalidate_dest(reg1);
5858
  invalidate_dest (reg2);
5834
  invalidate_dest(reg2);
5859
 
5835
 
5860
 
5836
 
5861
  if (r1flag)
5837
  if (r1flag)
5862
   {
5838
   {
5863
     ins0(popedx);
5839
     ins0(popedx);
5864
#ifdef NEWDWARF
5840
#ifdef NEWDWARF
5865
      if (diagnose && dwarf2 && no_frame)
5841
      if (diagnose && dwarf2 && no_frame)
5866
	dw2_track_pop();
5842
	dw2_track_pop();
5867
#endif
5843
#endif
5868
     stack_dec += 32;
5844
     stack_dec += 32;
5869
   };
5845
   };
5870
 
5846
 
5871
  if (reslab != 0)
5847
  if (reslab != 0)
5872
    simple_set_label (reslab);
5848
    simple_set_label(reslab);
5873
 
5849
 
5874
  if (r2flag)
5850
  if (r2flag)
5875
   {
5851
   {
5876
     ins0(popecx);
5852
     ins0(popecx);
5877
#ifdef NEWDWARF
5853
#ifdef NEWDWARF
5878
      if (diagnose && dwarf2 && no_frame)
5854
      if (diagnose && dwarf2 && no_frame)
5879
	dw2_track_pop();
5855
	dw2_track_pop();
5880
#endif
5856
#endif
5881
     stack_dec += 32;
5857
     stack_dec += 32;
5882
   };
5858
   };
5883
 
5859
 
5884
  move (sha, reg0, dest);
5860
  move(sha, reg0, dest);
5885
 
5861
 
5886
  return;
5862
  return;
5887
}
5863
}
5888
 
5864
 
5889
/* remainder after dividing top by bottom to dest */
5865
/* remainder after dividing top by bottom to dest */
5890
void rem2
5866
void rem2
5891
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5892
    PROTO_T ( shape sha X where bottom X where top X where dest )
5867
(shape sha, where bottom, where top, where dest)
5893
{
5868
{
5894
  remit(sha, bottom, top, dest, 2, 0);
5869
  remit(sha, bottom, top, dest, 2, 0);
5895
  return;
5870
  return;
5896
}
5871
}
5897
 
5872
 
5898
/* remainder after dividing top by bottom to dest */
5873
/* remainder after dividing top by bottom to dest */
5899
void rem0
5874
void rem0
5900
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5901
    PROTO_T ( shape sha X where bottom X where top X where dest )
5875
(shape sha, where bottom, where top, where dest)
5902
{
5876
{
5903
  remit(sha, bottom, top, dest, 0, 1);
5877
  remit(sha, bottom, top, dest, 0, 1);
5904
  return;
5878
  return;
5905
}
5879
}
5906
 
5880
 
5907
/* remainder after dividing top by bottom to dest */
5881
/* remainder after dividing top by bottom to dest */
5908
void mod
5882
void mod
5909
    PROTO_N ( (sha, bottom, top, dest) )
-
 
5910
    PROTO_T ( shape sha X where bottom X where top X where dest )
5883
(shape sha, where bottom, where top, where dest)
5911
{
5884
{
5912
  remit(sha, bottom, top, dest, 1, 1);
5885
  remit(sha, bottom, top, dest, 1, 1);
5913
  return;
5886
  return;
5914
}
5887
}
5915
 
5888
 
5916
 
5889
 
5917
/* move address of from to to */
5890
/* move address of from to to */
5918
void mova
5891
void mova
5919
    PROTO_N ( (from, to) )
-
 
5920
    PROTO_T ( where from X where to )
5892
(where from, where to)
5921
{
5893
{
5922
  exp fe = from.where_exp;
5894
  exp fe = from.where_exp;
5923
  exp holdfe = son(fe);
5895
  exp holdfe = son(fe);
5924
 
5896
 
5925
  cond1_set = 0;
5897
  cond1_set = 0;
5926
  cond2_set = 0;
5898
  cond2_set = 0;
5927
 
5899
 
5928
  if (name (fe) == reff_tag &&
5900
  if (name(fe) == reff_tag &&
5929
      name (son (fe)) != ident_tag) {/* add on offset from reff */
5901
      name (son (fe)) != ident_tag) {/* add on offset from reff */
5930
    mova (mw (son (fe), from.where_off + no (fe)), to);
5902
    mova(mw(son(fe), from.where_off + no(fe)), to);
5931
    return;
5903
    return;
5932
  };
5904
  };
5933
 
5905
 
5934
  if (name (to.where_exp) == apply_tag) {	/* pushing */
5906
  if (name (to.where_exp) == apply_tag) {	/* pushing */
5935
    if (!PIC_code && name (fe) == cont_tag &&
5907
    if (!PIC_code && name(fe) == cont_tag &&
5936
         name (son (fe)) != ident_tag &&
5908
         name(son(fe))!= ident_tag &&
5937
	(name (son (fe)) != name_tag || !isvar (son (son (fe)))) &&
5909
	(name(son(fe))!= name_tag || !isvar(son(son(fe)))) &&
5938
	((extra_stack == 0 && from.where_off == 0) ||
5910
	((extra_stack == 0 && from.where_off == 0) ||
5939
	  !eq_where (mw (son (fe), 0), sp))) {
5911
	  !eq_where(mw(son(fe), 0), sp))) {
5940
      contop (fe, 0, to);
5912
      contop(fe, 0, to);
5941
      ins1lit (pushl,  32, mw (son (fe), from.where_off));
5913
      ins1lit(pushl,  32, mw(son(fe), from.where_off));
-
 
5914
#ifdef NEWDWARF
-
 
5915
      if (diagnose && dwarf2 && no_frame)
-
 
5916
	dw2_track_push();
-
 
5917
#endif
-
 
5918
      end_contop();
-
 
5919
      son(fe) = holdfe;
-
 
5920
      return;
-
 
5921
    };
-
 
5922
    if (!PIC_code &&name(fe) == name_tag &&
-
 
5923
        isglob(son(fe)) && isvar(son(fe))) {
-
 
5924
      contop(fe, 0, to);
-
 
5925
      ins1lit(pushl,  32, from);
5942
#ifdef NEWDWARF
5926
#ifdef NEWDWARF
5943
      if (diagnose && dwarf2 && no_frame)
5927
      if (diagnose && dwarf2 && no_frame)
5944
	dw2_track_push();
5928
	dw2_track_push();
5945
#endif
5929
#endif
5946
      end_contop ();
5930
      end_contop();
5947
      son(fe) = holdfe;
-
 
5948
      return;
-
 
5949
    };
-
 
5950
    if (!PIC_code &&name (fe) == name_tag &&
-
 
5951
        isglob (son (fe)) && isvar (son (fe))) {
-
 
5952
      contop (fe, 0, to);
-
 
5953
      ins1lit (pushl,  32, from);
-
 
5954
#ifdef NEWDWARF
-
 
5955
      if (diagnose && dwarf2 && no_frame)
-
 
5956
	dw2_track_push();
-
 
5957
#endif
-
 
5958
      end_contop ();
-
 
5959
      son(fe) = holdfe;
5931
      son(fe) = holdfe;
5960
      return;
5932
      return;
5961
    };
5933
    };
5962
    mova (from, reg0);
5934
    mova(from, reg0);
5963
    ins1 (pushl,  32, reg0);
5935
    ins1(pushl,  32, reg0);
5964
#ifdef NEWDWARF
5936
#ifdef NEWDWARF
5965
    if (diagnose && dwarf2 && no_frame)
5937
    if (diagnose && dwarf2 && no_frame)
5966
      dw2_track_push();
5938
      dw2_track_push();
5967
#endif
5939
#endif
5968
    return;
5940
    return;
5969
  };
5941
  };
5970
 
5942
 
5971
 
5943
 
5972
  if (inmem (to)) {
5944
  if (inmem(to)) {
5973
    mova (from, reg0);
5945
    mova(from, reg0);
5974
    move (slongsh, reg0, to);
5946
    move(slongsh, reg0, to);
5975
    return;
5947
    return;
5976
  };
5948
  };
5977
 
5949
 
5978
  if (!PIC_code && name (fe) == name_tag && isvar (son (fe)) &&
5950
  if (!PIC_code && name(fe) == name_tag && isvar(son(fe)) &&
5979
      isglob (son (fe))) {
5951
      isglob(son(fe))) {
5980
    move (slongsh, from, to);
5952
    move(slongsh, from, to);
5981
    return;
5953
    return;
5982
  };
5954
  };
5983
 
-
 
5984
  contop (from.where_exp, 0, to);
-
 
5985
 
5955
 
-
 
5956
  contop(from.where_exp, 0, to);
-
 
5957
 
5986
  if (name (fe) == name_tag && !isvar(son(fe)) && ptno(son(fe)) == reg_pl)
5958
  if (name(fe) == name_tag && !isvar(son(fe)) && ptno(son(fe)) == reg_pl)
5987
    add(slongsh, mw(fe, 0), mw(zeroe, from.where_off/8), to);
5959
    add(slongsh, mw(fe, 0), mw(zeroe, from.where_off/8), to);
5988
  else
5960
  else
5989
    ins2 (leal,  32,  32, from, to);
5961
    ins2(leal,  32,  32, from, to);
5990
 
5962
 
5991
  invalidate_dest (to);
5963
  invalidate_dest(to);
5992
  end_contop ();
5964
  end_contop();
5993
  son(fe) = holdfe;
5965
  son(fe) = holdfe;
5994
  return;
5966
  return;
5995
}
5967
}
5996
 
5968
 
5997
int   adjust_pos
5969
int   adjust_pos
5998
    PROTO_N ( (e, nbits) )
-
 
5999
    PROTO_T ( exp e X int nbits )
5970
(exp e, int nbits)
6000
{
5971
{
6001
  int   pos;
5972
  int   pos;
6002
  UNUSED(nbits);
5973
  UNUSED(nbits);
6003
  pos = no (e) % 8;
5974
  pos = no(e)% 8;
6004
  no (e) -= pos;
5975
  no(e) -= pos;
6005
  return (pos);
5976
  return(pos);
6006
}
5977
}
6007
 
5978
 
6008
/* find bit position of bitfield defined
5979
/* find bit position of bitfield defined
6009
   by e, and alter e to address the start
5980
   by e, and alter e to address the start
6010
   of the byte */
5981
   of the byte */
6011
int   bit_pos_cont
5982
int   bit_pos_cont
6012
    PROTO_N ( (e, nbits) )
-
 
6013
    PROTO_T ( exp e X int nbits )
5983
(exp e, int nbits)
6014
{
5984
{
6015
  if (name (e) == reff_tag ||
5985
  if (name(e) == reff_tag ||
6016
      name (e) == name_tag)
5986
      name(e) == name_tag)
6017
    return (adjust_pos (e, nbits));
5987
    return(adjust_pos(e, nbits));
6018
 
5988
 
6019
  if (name (e) == ident_tag) {
5989
  if (name(e) == ident_tag) {
6020
    if (name (bro (son (e))) == reff_tag)
5990
    if (name(bro(son(e))) == reff_tag)
6021
      return (adjust_pos (bro (son (e)), nbits));
5991
      return(adjust_pos(bro(son(e)), nbits));
6022
 
5992
 
6023
    if (name (bro (son (e))) == ident_tag)
5993
    if (name(bro(son(e))) == ident_tag)
6024
      return bit_pos_cont (bro (son (e)), nbits);
5994
      return bit_pos_cont(bro(son(e)), nbits);
6025
 
5995
 
6026
    if (name (bro (son (e))) == name_tag &&
5996
    if (name(bro(son(e))) == name_tag &&
6027
	son (bro (son (e))) == e &&
5997
	son(bro(son(e))) == e &&
6028
	name (son (e)) == name_tag)
5998
	name(son(e)) == name_tag)
6029
      return (bit_pos_cont (son (son (e)), nbits));
5999
      return(bit_pos_cont(son(son(e)), nbits));
6030
 
6000
 
6031
    if (name (son (e)) == name_tag)
6001
    if (name(son(e)) == name_tag)
6032
      return (adjust_pos (son (e), nbits));
6002
      return(adjust_pos(son(e), nbits));
6033
 
6003
 
6034
    return (0);
6004
    return(0);
6035
  };
6005
  };
6036
 
6006
 
6037
  failer (BAD_BIT_OPND);
6007
  failer(BAD_BIT_OPND);
6038
  return (0);
6008
  return(0);
6039
 
6009
 
6040
}
6010
}
6041
 
6011
 
6042
/* find bit position of bitfield defined
6012
/* find bit position of bitfield defined
6043
   by e, and alter e to address the start
6013
   by e, and alter e to address the start
6044
   of the byte. Looks at top level and
6014
   of the byte. Looks at top level and
6045
   calls bit_pos_cont to it is a cont or
6015
   calls bit_pos_cont to it is a cont or
6046
   ass (which needs recursive calling) */
6016
   ass (which needs recursive calling) */
6047
int   bit_pos
6017
int   bit_pos
6048
    PROTO_N ( (e, nbits) )
-
 
6049
    PROTO_T ( exp e X int nbits )
6018
(exp e, int nbits)
6050
{
6019
{
6051
  if (name (e) == name_tag)
6020
  if (name(e) == name_tag)
6052
    return (adjust_pos (e, nbits));
6021
    return(adjust_pos(e, nbits));
6053
 
6022
 
6054
  if (name (e) == cont_tag || name (e) == ass_tag)
6023
  if (name(e) == cont_tag || name(e) == ass_tag)
6055
    return (bit_pos_cont (son (e), nbits));
6024
    return(bit_pos_cont(son(e), nbits));
6056
 
6025
 
6057
  if (name (e) == ident_tag)
6026
  if (name(e) == ident_tag)
6058
    return (0);
6027
    return(0);
6059
 
6028
 
6060
  failer (BAD_BIT_OPND);
6029
  failer(BAD_BIT_OPND);
6061
  return (0);
6030
  return(0);
6062
}
6031
}
6063
 
6032
 
6064
void mem_to_bits
6033
void mem_to_bits
6065
    PROTO_N ( (e, sha, dest, stack) )
-
 
6066
    PROTO_T ( exp e X shape sha X where dest X ash stack )
6034
(exp e, shape sha, where dest, ash stack)
6067
{
6035
{
6068
  int pos, lsn;
6036
  int pos, lsn;
6069
  int nbits = shape_size(sha);
6037
  int nbits = shape_size(sha);
6070
  shape dsh;
6038
  shape dsh;
6071
  char *rs;
6039
  char *rs;
6072
  shape move_sh;
6040
  shape move_sh;
6073
 
6041
 
6074
  cond1_set = 0;
6042
  cond1_set = 0;
6075
  cond2_set = 0;
6043
  cond2_set = 0;
6076
 
6044
 
6077
 
6045
 
6078
  dsh = (is_signed(sha)) ? slongsh : ulongsh;
6046
  dsh = (is_signed(sha))? slongsh : ulongsh;
6079
 
6047
 
6080
  pos = bit_pos(e, nbits);
6048
  pos = bit_pos(e, nbits);
6081
 
6049
 
6082
  lsn = 32 - nbits - pos;
6050
  lsn = 32 - nbits - pos;
6083
  rs = (is_signed(sha)) ? sarl : shrl;
6051
  rs = (is_signed(sha))? sarl : shrl;
6084
	/* right shift with sign extension or not
6052
	/* right shift with sign extension or not
6085
				*/
6053
				*/
6086
 
6054
 
6087
  if (pos == 0 && (nbits == 8 || nbits == 16)) {
6055
  if (pos == 0 && (nbits == 8 || nbits == 16)) {
6088
    /* can use byte or word instructions. */
6056
    /* can use byte or word instructions. */
6089
    shape osh;
6057
    shape osh;
6090
    exp temp;
6058
    exp temp;
6091
 
6059
 
6092
    if (nbits == 8) {
6060
    if (nbits == 8) {
6093
      if (is_signed(sha))
6061
      if (is_signed(sha))
6094
	osh = scharsh;
6062
	osh = scharsh;
6095
      else
6063
      else
6096
	osh = ucharsh;
6064
	osh = ucharsh;
6097
    }
6065
    }
6098
    else {
6066
    else {
Line 6106... Line 6074...
6106
    temp = getexp(dsh, nilexp, 0, e, nilexp, 0, 0, chvar_tag);
6074
    temp = getexp(dsh, nilexp, 0, e, nilexp, 0, 0, chvar_tag);
6107
    coder(dest, stack, temp);
6075
    coder(dest, stack, temp);
6108
    retcell(temp);
6076
    retcell(temp);
6109
    return;
6077
    return;
6110
  };
6078
  };
6111
 
6079
 
6112
  if ((pos + nbits) <= 8)
6080
  if ((pos + nbits) <= 8)
6113
    move_sh = scharsh;
6081
    move_sh = scharsh;
6114
  else
6082
  else
6115
    move_sh = slongsh;
6083
    move_sh = slongsh;
6116
 
6084
 
6117
  if (!inmem (dest)) {		/* dest is register */
6085
  if (!inmem (dest)) {		/* dest is register */
6118
    move (move_sh, mw (e, 0), dest);/* move e to dest */
6086
    move (move_sh, mw (e, 0), dest);/* move e to dest */
6119
    if (lsn != 0)
6087
    if (lsn != 0)
6120
      ins2 (shll,  32,  32, mw (zeroe, lsn), dest);
6088
      ins2(shll,  32,  32, mw(zeroe, lsn), dest);
6121
    invalidate_dest (dest);
6089
    invalidate_dest(dest);
6122
    /* shift it left to remove unwanted bits */
6090
    /* shift it left to remove unwanted bits */
6123
    if (nbits != 32)
6091
    if (nbits != 32)
6124
      ins2 (rs,  32,  32, mw (zeroe, 32 - nbits), dest);
6092
      ins2(rs,  32,  32, mw(zeroe, 32 - nbits), dest);
6125
    /* shift it right to remove unwanted bits and propagate sign if
6093
    /* shift it right to remove unwanted bits and propagate sign if
6126
       necessary */
6094
       necessary */
6127
    invalidate_dest (dest);
6095
    invalidate_dest(dest);
6128
    return;
6096
    return;
6129
  };
6097
  };
6130
 
6098
 
6131
  move (move_sh, mw (e, 0), reg0);/* move e to reg0 */
6099
  move (move_sh, mw (e, 0), reg0);/* move e to reg0 */
6132
  if (lsn != 0)
6100
  if (lsn != 0)
6133
    ins2 (shll,  32,  32, mw (zeroe, lsn), reg0);
6101
    ins2(shll,  32,  32, mw(zeroe, lsn), reg0);
6134
  invalidate_dest (reg0);
6102
  invalidate_dest(reg0);
6135
  /* shift it left to remove unwanted bits */
6103
  /* shift it left to remove unwanted bits */
6136
  if (nbits != 32)
6104
  if (nbits != 32)
6137
    ins2 (rs,  32,  32, mw (zeroe, 32 - nbits), reg0);
6105
    ins2(rs,  32,  32, mw(zeroe, 32 - nbits), reg0);
6138
  /* shift it right to remove unwanted bits and propagate sign if
6106
  /* shift it right to remove unwanted bits and propagate sign if
6139
     necessary */
6107
     necessary */
6140
  move (dsh, reg0, dest);/* move to dest */
6108
  move (dsh, reg0, dest);/* move to dest */
6141
  return;
6109
  return;
6142
}
6110
}
6143
 
6111
 
6144
void bits_to_mem
6112
void bits_to_mem
6145
    PROTO_N ( (e, d, stack) )
-
 
6146
    PROTO_T ( exp e X exp d X ash stack )
6113
(exp e, exp d, ash stack)
6147
{
6114
{
6148
  int pos;
6115
  int pos;
6149
  int nbits = shape_size(sh(e));
6116
  int nbits = shape_size(sh(e));
6150
  int mask, lsn, k;
6117
  int mask, lsn, k;
6151
  where dest;
6118
  where dest;
Line 6153... Line 6120...
6153
  dest = mw(d, 0);
6120
  dest = mw(d, 0);
6154
 
6121
 
6155
  cond1_set = 0;
6122
  cond1_set = 0;
6156
  cond2_set = 0;
6123
  cond2_set = 0;
6157
 
6124
 
6158
  pos = bit_pos (d, nbits);
6125
  pos = bit_pos(d, nbits);
6159
 
6126
 
6160
  lsn = 32 - nbits - pos;
6127
  lsn = 32 - nbits - pos;
6161
  mask = msmask[lsn] + lsmask[pos];
6128
  mask = msmask[lsn] + lsmask[pos];
6162
 
6129
 
6163
  k = lsmask[nbits] << pos;
6130
  k = lsmask[nbits] << pos;
Line 6169... Line 6136...
6169
    k &= 0xff;
6136
    k &= 0xff;
6170
   }
6137
   }
6171
  else
6138
  else
6172
    move_sh = slongsh;
6139
    move_sh = slongsh;
6173
 
6140
 
6174
  if (name(e) == int_to_bitf_tag && name (son(e)) == val_tag) {
6141
  if (name(e) == int_to_bitf_tag && name(son(e)) == val_tag) {
6175
    if (no (son(e)) == lsmask[nbits]) {
6142
    if (no(son(e)) == lsmask[nbits]) {
6176
      /* if we are assigning all ones, just or them in */
6143
      /* if we are assigning all ones, just or them in */
6177
      or (move_sh, mw (zeroe, k), dest, dest);
6144
      or(move_sh, mw(zeroe, k), dest, dest);
6178
      return;
6145
      return;
6179
    };
6146
    };
6180
    if (no (son(e)) == 0) {
6147
    if (no(son(e)) == 0) {
6181
      /* if we are assigning all ones, just or them in */
6148
      /* if we are assigning all ones, just or them in */
6182
      k = ~k;
6149
      k = ~k;
6183
      if ((pos+nbits) <= 8)
6150
      if ((pos+nbits) <= 8)
6184
        k &= 0xff;
6151
        k &= 0xff;
6185
      and (move_sh, mw (zeroe, k), dest, dest);
6152
      and(move_sh, mw(zeroe, k), dest, dest);
6186
      return;
6153
      return;
6187
    };
6154
    };
6188
  };
6155
  };
6189
 
6156
 
6190
  if (pos == 0 && (nbits == 8 || nbits == 16)) {
6157
  if (pos == 0 && (nbits == 8 || nbits == 16)) {
Line 6199... Line 6166...
6199
	if (name(son(e)) == val_tag) {
6166
	if (name(son(e)) == val_tag) {
6200
	  move(osh, mw(son(e), 0), dest);
6167
	  move(osh, mw(son(e), 0), dest);
6201
	}
6168
	}
6202
	else {
6169
	else {
6203
         coder(reg0, stack, son(e));
6170
         coder(reg0, stack, son(e));
6204
         move (osh, reg0, dest);
6171
         move(osh, reg0, dest);
6205
	};
6172
	};
6206
     }
6173
     }
6207
    else
6174
    else
6208
       move(osh, mw(e, 0), dest);
6175
       move(osh, mw(e, 0), dest);
6209
    return;
6176
    return;
Line 6213... Line 6180...
6213
  if (name (e) != val_tag) {	/* this needs improvement */
6180
  if (name (e) != val_tag) {	/* this needs improvement */
6214
    if (name(e) == int_to_bitf_tag)
6181
    if (name(e) == int_to_bitf_tag)
6215
       coder(reg0, stack, son(e));
6182
       coder(reg0, stack, son(e));
6216
    else
6183
    else
6217
       move(sh(e), mw(e, 0), reg0);
6184
       move(sh(e), mw(e, 0), reg0);
6218
    and (slongsh, mw (zeroe, lsmask[nbits]), reg0, reg0);
6185
    and(slongsh, mw(zeroe, lsmask[nbits]), reg0, reg0);
6219
    /* mask it to the right size */
6186
    /* mask it to the right size */
6220
    if (pos != 0)
6187
    if (pos != 0)
6221
      ins2 (shll,  32,  32, mw (zeroe, pos), reg0);
6188
      ins2(shll,  32,  32, mw(zeroe, pos), reg0);
6222
    invalidate_dest (reg0);
6189
    invalidate_dest(reg0);
6223
    /* shift it into position */
6190
    /* shift it into position */
6224
    keep_short = 0;	/* stop use of reg0 by and */
6191
    keep_short = 0;	/* stop use of reg0 by and */
6225
    and (move_sh, mw (zeroe, mask), dest, dest);
6192
    and(move_sh, mw(zeroe, mask), dest, dest);
6226
    add (move_sh, reg0, dest, dest);/* and add it into the dest */
6193
    add (move_sh, reg0, dest, dest);/* and add it into the dest */
6227
    return;
6194
    return;
6228
  }
6195
  }
6229
  else {
6196
  else {
6230
    k = (no (e) & lsmask[nbits]) << pos;
6197
    k = (no(e) & lsmask[nbits]) << pos;
6231
    /* constant bits we are assigning */
6198
    /* constant bits we are assigning */
6232
    if (k == 0)
6199
    if (k == 0)
6233
      return;			/* if we are assigning zero we don't need
6200
      return;			/* if we are assigning zero we don't need
6234
				   anything more */
6201
				   anything more */
6235
    move (slongsh, mw (zeroe, k), reg0);
6202
    move(slongsh, mw(zeroe, k), reg0);
6236
    /* we don't need this move to reg0 since add looks after this better
6203
    /* we don't need this move to reg0 since add looks after this better
6237
    */
6204
    */
6238
    keep_short = 0;
6205
    keep_short = 0;
6239
    and (move_sh, mw (zeroe, mask), dest, dest);
6206
    and(move_sh, mw(zeroe, mask), dest, dest);
6240
    add (move_sh, reg0, dest, dest);/* add into dest */
6207
    add (move_sh, reg0, dest, dest);/* add into dest */
6241
    return;
6208
    return;
6242
  };
6209
  };
6243
}
6210
}
6244
 
6211
 
6245
 
6212
 
6246
 
6213
 
6247
 
6214
 
6248
/* apply floating point operation op
6215
/* apply floating point operation op
6249
   between fstack0 and memory. reverse
6216
   between fstack0 and memory. reverse
6250
   arguments of operation if rev. */
6217
   arguments of operation if rev. */
6251
void fopm
6218
void fopm
6252
    PROTO_N ( (sha, op, rev, wh) )
-
 
6253
    PROTO_T ( shape sha X unsigned char op X int rev X where wh )
6219
(shape sha, unsigned char op, int rev, where wh)
6254
{
6220
{
6255
  exp hold = son(wh.where_exp);
6221
  exp hold = son(wh.where_exp);
6256
  contop (wh.where_exp, 0, reg0);
6222
  contop(wh.where_exp, 0, reg0);
6257
  if (name (sha) == shrealhd) {	/* floats */
6223
  if (name (sha) == shrealhd) {	/* floats */
6258
    switch (op) {
6224
    switch (op) {
6259
      case fplus_tag:
6225
      case fplus_tag:
6260
	ins1 (fadds,  32, wh);
6226
	ins1(fadds,  32, wh);
6261
	end_contop ();
6227
	end_contop();
6262
	son(wh.where_exp) = hold;
6228
	son(wh.where_exp) = hold;
6263
	return;
6229
	return;
6264
      case fminus_tag:
6230
      case fminus_tag:
6265
	if (rev)
6231
	if (rev)
6266
	  ins1 (fsubrs,  32, wh);
6232
	  ins1(fsubrs,  32, wh);
6267
	else
6233
	else
6268
	  ins1 (fsubs,  32, wh);
6234
	  ins1(fsubs,  32, wh);
6269
	end_contop ();
6235
	end_contop();
6270
	son(wh.where_exp) = hold;
6236
	son(wh.where_exp) = hold;
6271
	return;
6237
	return;
6272
      case fmult_tag:
6238
      case fmult_tag:
6273
	ins1 (fmuls,  32, wh);
6239
	ins1(fmuls,  32, wh);
6274
	end_contop ();
6240
	end_contop();
6275
	son(wh.where_exp) = hold;
6241
	son(wh.where_exp) = hold;
6276
	return;
6242
	return;
6277
      case fdiv_tag:
6243
      case fdiv_tag:
6278
	if (rev)
6244
	if (rev)
6279
	  ins1 (fdivrs,  32, wh);
6245
	  ins1(fdivrs,  32, wh);
6280
	else
6246
	else
6281
	  ins1 (fdivs,  32, wh);
6247
	  ins1(fdivs,  32, wh);
6282
	end_contop ();
6248
	end_contop();
6283
	son(wh.where_exp) = hold;
6249
	son(wh.where_exp) = hold;
6284
	return;
6250
	return;
6285
      default:
6251
      default:
6286
	failer (BAD_FLOP);
6252
	failer(BAD_FLOP);
6287
	end_contop ();
6253
	end_contop();
6288
	son(wh.where_exp) = hold;
6254
	son(wh.where_exp) = hold;
6289
	return;
6255
	return;
6290
    };
6256
    };
6291
  };
6257
  };
6292
 
6258
 
6293
  switch (op) {			/* doubles */
6259
  switch (op) {			/* doubles */
6294
    case fplus_tag:
6260
    case fplus_tag:
6295
      ins1 (faddl,  64, wh);
6261
      ins1(faddl,  64, wh);
6296
      end_contop ();
6262
      end_contop();
6297
      son(wh.where_exp) = hold;
6263
      son(wh.where_exp) = hold;
6298
      return;
6264
      return;
6299
    case fminus_tag:
6265
    case fminus_tag:
6300
      if (rev)
6266
      if (rev)
6301
	ins1 (fsubrl,  64, wh);
6267
	ins1(fsubrl,  64, wh);
6302
      else
6268
      else
6303
	ins1 (fsubl,  64, wh);
6269
	ins1(fsubl,  64, wh);
6304
      end_contop ();
6270
      end_contop();
6305
      son(wh.where_exp) = hold;
6271
      son(wh.where_exp) = hold;
6306
      return;
6272
      return;
6307
    case fmult_tag:
6273
    case fmult_tag:
6308
      ins1 (fmull,  64, wh);
6274
      ins1(fmull,  64, wh);
6309
      end_contop ();
6275
      end_contop();
6310
      son(wh.where_exp) = hold;
6276
      son(wh.where_exp) = hold;
6311
      return;
6277
      return;
6312
    case fdiv_tag:
6278
    case fdiv_tag:
6313
      if (rev)
6279
      if (rev)
6314
	ins1 (fdivrl,  64, wh);
6280
	ins1(fdivrl,  64, wh);
6315
      else
6281
      else
6316
	ins1 (fdivl,  64, wh);
6282
	ins1(fdivl,  64, wh);
6317
      end_contop ();
6283
      end_contop();
6318
      son(wh.where_exp) = hold;
6284
      son(wh.where_exp) = hold;
6319
      return;
6285
      return;
6320
    default:
6286
    default:
6321
      failer (BAD_FLOP);
6287
      failer(BAD_FLOP);
6322
      end_contop ();
6288
      end_contop();
6323
      son(wh.where_exp) = hold;
6289
      son(wh.where_exp) = hold;
6324
      return;
6290
      return;
6325
  };
6291
  };
6326
}
6292
}
6327
 
6293
 
Line 6329... Line 6295...
6329
 
6295
 
6330
/* apply floating point operation op
6296
/* apply floating point operation op
6331
   between fstack0 and fstackn. Reverse
6297
   between fstack0 and fstackn. Reverse
6332
   arguments of operation if rev. */
6298
   arguments of operation if rev. */
6333
void fopr
6299
void fopr
6334
    PROTO_N ( (op, rev, wh, d, and_pop) )
-
 
6335
    PROTO_T ( unsigned char op X int rev X where wh X where d X int and_pop )
6300
(unsigned char op, int rev, where wh, where d, int and_pop)
6336
{
6301
{
6337
  switch (op) {
6302
  switch (op) {
6338
    case fplus_tag:
6303
    case fplus_tag:
6339
      if (and_pop) {
6304
      if (and_pop) {
6340
	ins2 (faddp, 0, 0, wh, d);
6305
	ins2(faddp, 0, 0, wh, d);
6341
	pop_fl;
6306
	pop_fl;
6342
      }
6307
      }
6343
      else
6308
      else
6344
	ins2 (fadd, 0, 0, wh, d);
6309
	ins2(fadd, 0, 0, wh, d);
6345
      break;
6310
      break;
6346
    case fminus_tag:
6311
    case fminus_tag:
6347
      if (rev) {
6312
      if (rev) {
6348
	if (and_pop) {
6313
	if (and_pop) {
6349
	  ins2 (fsubrp, 0, 0, wh, d);
6314
	  ins2(fsubrp, 0, 0, wh, d);
6350
	  pop_fl;
6315
	  pop_fl;
6351
	}
6316
	}
6352
	else
6317
	else
6353
	  ins2 (fsubr, 0, 0, wh, d);
6318
	  ins2(fsubr, 0, 0, wh, d);
6354
      }
6319
      }
6355
      else {
6320
      else {
6356
	if (and_pop) {
6321
	if (and_pop) {
6357
	  ins2 (fsubp, 0, 0, wh, d);
6322
	  ins2(fsubp, 0, 0, wh, d);
6358
	  pop_fl;
6323
	  pop_fl;
6359
	}
6324
	}
6360
	else
6325
	else
6361
	  ins2 (fsub, 0, 0, wh, d);
6326
	  ins2(fsub, 0, 0, wh, d);
6362
      };
6327
      };
6363
      break;
6328
      break;
6364
    case fmult_tag:
6329
    case fmult_tag:
6365
      if (and_pop) {
6330
      if (and_pop) {
6366
	ins2 (fmulp, 0, 0, wh, d);
6331
	ins2(fmulp, 0, 0, wh, d);
6367
	pop_fl;
6332
	pop_fl;
6368
      }
6333
      }
6369
      else
6334
      else
6370
	ins2 (fmul, 0, 0, wh, d);
6335
	ins2(fmul, 0, 0, wh, d);
6371
      break;
6336
      break;
6372
    case fdiv_tag:
6337
    case fdiv_tag:
6373
      if (rev) {
6338
      if (rev) {
6374
	if (and_pop) {
6339
	if (and_pop) {
6375
	  ins2 (fdivrp, 0, 0, wh, d);/* (1,arg1-in-st0,arg2,1) -> arg2 */
6340
	  ins2 (fdivrp, 0, 0, wh, d);/* (1,arg1-in-st0,arg2,1) -> arg2 */
Line 6383... Line 6348...
6383
	  ins2 (fdivp, 0, 0, wh, d); /* (0,arg2-in-st0,arg1,1) -> arg1 */
6348
	  ins2 (fdivp, 0, 0, wh, d); /* (0,arg2-in-st0,arg1,1) -> arg1 */
6384
	  pop_fl;
6349
	  pop_fl;
6385
	}
6350
	}
6386
	else
6351
	else
6387
	  ins2 (fdiv, 0, 0, wh, d);  /* (0,arg1,arg2-in-st0,0) -> st0 */
6352
	  ins2 (fdiv, 0, 0, wh, d);  /* (0,arg1,arg2-in-st0,0) -> st0 */
6388
      };
6353
      };
6389
      break;
6354
      break;
6390
    default:
6355
    default:
6391
      failer (BAD_FLOP);
6356
      failer(BAD_FLOP);
6392
      break;
6357
      break;
6393
  };
6358
  };
6394
 
6359
 
6395
  return;
6360
  return;
6396
}
6361
}
Line 6398... Line 6363...
6398
 
6363
 
6399
/* apply binary floating point operation
6364
/* apply binary floating point operation
6400
   to arg1 and arg2 and put result into
6365
   to arg1 and arg2 and put result into
6401
   dest */
6366
   dest */
6402
void fl_binop
6367
void fl_binop
6403
    PROTO_N ( (op, sha, arg1, arg2, dest, last_arg) )
-
 
6404
    PROTO_T ( unsigned char op X shape sha X where arg1 X where arg2 X where dest X exp last_arg )
6368
(unsigned char op, shape sha, where arg1, where arg2, where dest, exp last_arg)
6405
{
6369
{
6406
  int   m1 = flinmem (arg1);
6370
  int   m1 = flinmem(arg1);
6407
  int   m2 = flinmem (arg2);
6371
  int   m2 = flinmem(arg2);
6408
  int   m3 = flinmem (dest);
6372
  int   m3 = flinmem(dest);
6409
  int tst = (m1 << 2) + (m2 << 1) + m3;
6373
  int tst = (m1 << 2) + (m2 << 1) + m3;
6410
 
6374
 
6411
  if (name(sha) == doublehd && tst > 1)
6375
  if (name(sha) == doublehd && tst > 1)
6412
   {
6376
   {
6413
     move(sha, arg1, flstack);
6377
     move(sha, arg1, flstack);
Line 6429... Line 6393...
6429
   };
6393
   };
6430
 
6394
 
6431
  switch (tst) {
6395
  switch (tst) {
6432
    case 6:
6396
    case 6:
6433
    case 7:
6397
    case 7:
6434
      move (sha, arg2, flstack);
6398
      move(sha, arg2, flstack);
6435
      fopm (sha, op, 0, arg1);
6399
      fopm(sha, op, 0, arg1);
6436
 
6400
 
6437
      move (sha, flstack, dest);
6401
      move(sha, flstack, dest);
6438
      return;
6402
      return;
6439
    case 4:
6403
    case 4:
6440
      if (eq_where (arg2, dest)) {
6404
      if (eq_where(arg2, dest)) {
6441
	int  fd = in_fl_reg (dest.where_exp);
6405
	int  fd = in_fl_reg(dest.where_exp);
6442
	if (fd && get_reg_no (fd) == fstack_pos) {
6406
	if (fd && get_reg_no(fd) == fstack_pos) {
6443
	  fopm (sha, op, 0, arg1);
6407
	  fopm(sha, op, 0, arg1);
6444
 
6408
 
6445
	  return;
6409
	  return;
6446
	};
6410
	};
6447
	move (sha, arg1, flstack);
6411
	move(sha, arg1, flstack);
6448
	fopr (op, 1, flstack, dest, 1); /* 1: fdivrp st,st(2) */
6412
	fopr (op, 1, flstack, dest, 1); /* 1: fdivrp st,st(2) */
6449
 
6413
 
6450
	return;
6414
	return;
6451
      };
6415
      };
6452
      /* fall through to case 5 */
6416
      /* fall through to case 5 */
6453
    case 5:
6417
    case 5:
6454
 
6418
 
6455
      if (use_pop (last_arg, arg2.where_exp) == 2) {
6419
      if (use_pop(last_arg, arg2.where_exp) == 2) {
6456
	fopm (sha, op, 0, arg1);
6420
	fopm(sha, op, 0, arg1);
6457
 
6421
 
6458
	move (sha, flstack, dest);
6422
	move(sha, flstack, dest);
6459
	return;
6423
	return;
6460
      };
6424
      };
6461
 
6425
 
6462
      move (sha, arg1, flstack);
6426
      move(sha, arg1, flstack);
6463
      fopr (op, 1, arg2, flstack, 0); /* 2: fdivr st(2),st */
6427
      fopr (op, 1, arg2, flstack, 0); /* 2: fdivr st(2),st */
6464
 
6428
 
6465
      move (sha, flstack, dest);
6429
      move(sha, flstack, dest);
6466
      return;
6430
      return;
6467
    case 2:
6431
    case 2:
6468
      if (eq_where (arg1, dest)) {
6432
      if (eq_where(arg1, dest)) {
6469
	int  fd = in_fl_reg (dest.where_exp);
6433
	int  fd = in_fl_reg(dest.where_exp);
6470
	if (fd && get_reg_no (fd) == fstack_pos) {
6434
	if (fd && get_reg_no(fd) == fstack_pos) {
6471
	  fopm (sha, op, 1, arg2);
6435
	  fopm(sha, op, 1, arg2);
6472
 
6436
 
6473
	  return;
6437
	  return;
6474
	};
6438
	};
6475
	move (sha, arg2, flstack);
6439
	move(sha, arg2, flstack);
6476
	fopr (op, 0, flstack, dest, 1);/* 3: fdivp st,st(2) */
6440
	fopr (op, 0, flstack, dest, 1);/* 3: fdivp st,st(2) */
6477
 
6441
 
6478
	return;
6442
	return;
6479
      };
6443
      };
6480
      /* fall through to case 3 */
6444
      /* fall through to case 3 */
6481
    case 3:
6445
    case 3:
6482
      if (use_pop (last_arg, arg1.where_exp) == 2) {
6446
      if (use_pop(last_arg, arg1.where_exp) == 2) {
6483
	fopm (sha, op, 1, arg2);
6447
	fopm(sha, op, 1, arg2);
6484
 
6448
 
6485
	move (sha, flstack, dest);
6449
	move(sha, flstack, dest);
6486
	return;
6450
	return;
6487
      };
6451
      };
6488
 
6452
 
6489
      move (sha, arg2, flstack);
6453
      move(sha, arg2, flstack);
6490
      fopr (op, 0, arg1, flstack, 0); /* 4: fdiv st(2),st */
6454
      fopr (op, 0, arg1, flstack, 0); /* 4: fdiv st(2),st */
6491
 
6455
 
6492
      move (sha, flstack, dest);
6456
      move(sha, flstack, dest);
6493
      return;
6457
      return;
6494
    case 0:
6458
    case 0:
6495
    case 1:
6459
    case 1:
6496
      {
6460
      {
6497
	int   up1;
6461
	int   up1;
6498
	int   up2;
6462
	int   up2;
6499
	up1 = use_pop_ass (last_arg, arg1.where_exp);
6463
	up1 = use_pop_ass(last_arg, arg1.where_exp);
6500
	up2 = use_pop_ass (last_arg, arg2.where_exp);
6464
	up2 = use_pop_ass(last_arg, arg2.where_exp);
6501
 
6465
 
6502
	if (tst == 0) {
6466
	if (tst == 0) {
6503
	  int  fd1 = get_reg_no(in_fl_reg (arg1.where_exp));
6467
	  int  fd1 = get_reg_no(in_fl_reg(arg1.where_exp));
6504
	  int  fd2 = get_reg_no(in_fl_reg (arg2.where_exp));
6468
	  int  fd2 = get_reg_no(in_fl_reg(arg2.where_exp));
6505
 
6469
 
6506
	  if (up1 == 2 && fd2 != fstack_pos && eq_where(arg2, dest)) {
6470
	  if (up1 == 2 && fd2 != fstack_pos && eq_where(arg2, dest)) {
6507
	    fopr(op, 1, flstack, arg2, 1); /* 8: fdivrp st,st(3) */
6471
	    fopr(op, 1, flstack, arg2, 1); /* 8: fdivrp st,st(3) */
6508
	    return;
6472
	    return;
6509
	  };
6473
	  };
Line 6514... Line 6478...
6514
	};
6478
	};
6515
 
6479
 
6516
	{
6480
	{
6517
	  if (up1 == 2) {
6481
	  if (up1 == 2) {
6518
	    int  fd2;
6482
	    int  fd2;
6519
	    fd2 = in_fl_reg (arg2.where_exp);
6483
	    fd2 = in_fl_reg(arg2.where_exp);
6520
	    if (get_reg_no (fd2) != fstack_pos) {
6484
	    if (get_reg_no(fd2)!= fstack_pos) {
6521
	      if (tst == 0) {
6485
	      if (tst == 0) {
6522
	        fopr (op, 1, arg2, flstack, 0); /* 9: fdivr st(1),st */
6486
	        fopr (op, 1, arg2, flstack, 0); /* 9: fdivr st(1),st */
6523
	        move (sha, flstack, dest);
6487
	        move(sha, flstack, dest);
6524
	        return;
6488
	        return;
6525
	      }
6489
	      }
6526
	      else
6490
	      else
6527
	      if (up2 == 1) {
6491
	      if (up2 == 1) {
6528
	        fopr (op, 1, flstack, arg2, 1); /* 7: divrp st,st(1) */
6492
	        fopr (op, 1, flstack, arg2, 1); /* 7: divrp st,st(1) */
6529
	        move (sha, flstack, dest);
6493
	        move(sha, flstack, dest);
6530
	        return;
6494
	        return;
6531
	      };
6495
	      };
6532
	    };
6496
	    };
6533
	  };
6497
	  };
6534
 
6498
 
6535
	  if (up2 == 2) {
6499
	  if (up2 == 2) {
6536
	    int  fd1;
6500
	    int  fd1;
6537
	    fd1 = in_fl_reg (arg1.where_exp);
6501
	    fd1 = in_fl_reg(arg1.where_exp);
6538
	    if (get_reg_no (fd1) != fstack_pos) {
6502
	    if (get_reg_no(fd1)!= fstack_pos) {
6539
	      if (tst == 0) {
6503
	      if (tst == 0) {
6540
	        fopr (op, 0, arg1, flstack, 0); /* 10: fdiv st(2), st */
6504
	        fopr (op, 0, arg1, flstack, 0); /* 10: fdiv st(2), st */
6541
	        move (sha, flstack, dest);
6505
	        move(sha, flstack, dest);
6542
	        return;
6506
	        return;
6543
	      }
6507
	      }
6544
	      else
6508
	      else
6545
	      if (up1 == 1) {
6509
	      if (up1 == 1) {
6546
	        fopr (op, 0, flstack, arg1, 1); /* untested */
6510
	        fopr (op, 0, flstack, arg1, 1); /* untested */
6547
	        move (sha, flstack, dest);
6511
	        move(sha, flstack, dest);
6548
	        return;
6512
	        return;
6549
	      }
6513
	      }
6550
	      else {
6514
	      else {
6551
		fopr(op, 0, arg1, flstack, 0); /* 6: fdiv st(2),st */
6515
		fopr(op, 0, arg1, flstack, 0); /* 6: fdiv st(2),st */
6552
		move (sha, flstack, dest);
6516
		move(sha, flstack, dest);
6553
		return;
6517
		return;
6554
	      };
6518
	      };
6555
	    };
6519
	    };
6556
	  };
6520
	  };
6557
	};
6521
	};
6558
 
6522
 
6559
 
6523
 
6560
	move (sha, arg2, flstack);
6524
	move(sha, arg2, flstack);
6561
	fopr (op, 0, arg1, flstack, 0); /* 5: fdiv st(2),st */
6525
	fopr (op, 0, arg1, flstack, 0); /* 5: fdiv st(2),st */
6562
 
6526
 
6563
	move (sha, flstack, dest);
6527
	move(sha, flstack, dest);
6564
	return;
6528
	return;
6565
	};
6529
	};
6566
 
6530
 
6567
 
6531
 
6568
  };
6532
  };
Line 6571... Line 6535...
6571
 
6535
 
6572
/* apply binary floating point operation
6536
/* apply binary floating point operation
6573
   to list of arguments arglist and put result
6537
   to list of arguments arglist and put result
6574
   into dest */
6538
   into dest */
6575
void fl_multop
6539
void fl_multop
6576
    PROTO_N ( (op, sha, arglist, dest) )
-
 
6577
    PROTO_T ( unsigned char op X shape sha X exp arglist X where dest )
6540
(unsigned char op, shape sha, exp arglist, where dest)
6578
{
6541
{
6579
  exp arg1 = arglist;
6542
  exp arg1 = arglist;
6580
  exp arg2 = bro(arg1);
6543
  exp arg2 = bro(arg1);
6581
  if (last (arg1)) {	/* only one arg, so just move to dest */
6544
  if (last (arg1)) {	/* only one arg, so just move to dest */
6582
    move (sha, mw (arg1, 0), dest);
6545
    move(sha, mw(arg1, 0), dest);
6583
    return;
6546
    return;
6584
  }
6547
  }
6585
  if (last (arg2)) {	/* two args */
6548
  if (last (arg2)) {	/* two args */
6586
    fl_binop (op, sha, mw (arg1, 0), mw (arg2, 0), dest, arg2);
6549
    fl_binop(op, sha, mw(arg1, 0), mw(arg2, 0), dest, arg2);
6587
    return;
6550
    return;
6588
  }
6551
  }
6589
  move(sha, mw (arg1, 0), flstack);
6552
  move(sha, mw(arg1, 0), flstack);
6590
  for (;;) {
6553
  for (;;) {
6591
    move(sha, mw (arg2, 0), flstack);
6554
    move(sha, mw(arg2, 0), flstack);
6592
    switch (op)
6555
    switch (op)
6593
     {
6556
     {
6594
	case fplus_tag:
6557
	case fplus_tag:
6595
	   ins0("faddp %st,%st(1)"); break;
6558
	   ins0("faddp %st,%st(1)"); break;
6596
	case fmult_tag:
6559
	case fmult_tag:
6597
	   ins0("fmulp %st,%st(1)"); break;
6560
	   ins0("fmulp %st,%st(1)"); break;
6598
	default:
6561
	default:
6599
	   failer (BAD_FLOP); break;
6562
	   failer(BAD_FLOP); break;
6600
      };
6563
      };
6601
    pop_fl;
6564
    pop_fl;
6602
    if (last(arg2)) break;
6565
    if (last(arg2))break;
6603
    arg2 = bro(arg2);
6566
    arg2 = bro(arg2);
6604
  }
6567
  }
6605
  move(sha, flstack, dest);
6568
  move(sha, flstack, dest);
6606
  return;
6569
  return;
6607
}
6570
}
Line 6616... Line 6579...
6616
      3 round toward 0
6579
      3 round toward 0
6617
      4 is round as state
6580
      4 is round as state
6618
   ul is true iff dest is unsigned >= 32
6581
   ul is true iff dest is unsigned >= 32
6619
   sz is 32 unless dest is 64-bit */
6582
   sz is 32 unless dest is 64-bit */
6620
static  void round_code
6583
static  void round_code
6621
    PROTO_N ( (mode, ul, sz) )
-
 
6622
    PROTO_T ( int mode X int ul X int sz )
6584
(int mode, int ul, int sz)
6623
{
6585
{
6624
  if (mode == 0 || mode == 4) {
6586
  if (mode == 0 || mode == 4) {
6625
    sub (slongsh, mw (zeroe, sz/8), sp, sp);
6587
    sub(slongsh, mw(zeroe, sz/8), sp, sp);
6626
    extra_stack += sz;
6588
    extra_stack += sz;
6627
    check_stack_max;
6589
    check_stack_max;
6628
  }
6590
  }
6629
  else {
6591
  else {
6630
    sub (slongsh, mw (zeroe, (sz+32)/8), sp, sp);
6592
    sub(slongsh, mw(zeroe,(sz+32) /8), sp, sp);
6631
    extra_stack += (sz+32);
6593
    extra_stack += (sz+32);
6632
    check_stack_max;
6594
    check_stack_max;
6633
    ins1 (fstcw, size16, mw (ind_sp.where_exp, (-(sz+32))));
6595
    ins1(fstcw, size16, mw(ind_sp.where_exp,(- (sz+32))));
6634
    if (ul && mode ==3) {	/* round toward zero unsigned */
6596
    if (ul && mode ==3) {	/* round toward zero unsigned */
6635
      int labpos = next_lab();
6597
      int labpos = next_lab();
6636
      int labend = next_lab();
6598
      int labend = next_lab();
6637
      ins0 (ftst);
6599
      ins0(ftst);
6638
      ins1 (fnstsw, 16, reg0);
6600
      ins1(fnstsw, 16, reg0);
6639
      testah(flpt_test_no[f_less_than]);
6601
      testah(flpt_test_no[f_less_than]);
6640
      move (swordsh, mw (ind_sp.where_exp, (-(sz+32))), reg0);
6602
      move(swordsh, mw(ind_sp.where_exp,(- (sz+32))), reg0);
6641
      simple_branch (jpe, labpos);
6603
      simple_branch(jpe, labpos);
6642
      or (swordsh, mw (zeroe, (mode << 10)), reg0, reg0);  /* neg, round toward zero */
6604
      or (swordsh, mw (zeroe, (mode << 10)), reg0, reg0);  /* neg, round toward zero */
6643
      simple_branch (jmp, labend);
6605
      simple_branch(jmp, labend);
6644
      simplest_set_lab (labpos);
6606
      simplest_set_lab(labpos);
6645
      or (swordsh, mw (zeroe, (1 << 10)), reg0, reg0);  /* pos, round down */
6607
      or (swordsh, mw (zeroe, (1 << 10)), reg0, reg0);  /* pos, round down */
6646
      simplest_set_lab (labend);
6608
      simplest_set_lab(labend);
6647
    }
6609
    }
6648
    else {
6610
    else {
6649
      move (swordsh, mw (ind_sp.where_exp, (-(sz+32))), reg0);
6611
      move(swordsh, mw(ind_sp.where_exp,(- (sz+32))), reg0);
6650
      or (swordsh, mw (zeroe, (mode << 10)), reg0, reg0);
6612
      or(swordsh, mw(zeroe,(mode << 10)), reg0, reg0);
6651
    };
6613
    };
6652
    move (swordsh, reg0, mw (ind_sp.where_exp, (-(sz+16))));
6614
    move(swordsh, reg0, mw(ind_sp.where_exp,(- (sz+16))));
6653
    invalidate_dest (reg0);
6615
    invalidate_dest(reg0);
6654
    ins1 (fldcw, size16, mw (ind_sp.where_exp, (-(sz+16))));
6616
    ins1(fldcw, size16, mw(ind_sp.where_exp,(- (sz+16))));
6655
  };
6617
  };
6656
  if (ul) {
6618
  if (ul) {
6657
    if (sz == 64) {
6619
    if (sz == 64) {
6658
      move (doublesh, mw (sllmaxe, 0), flstack);
6620
      move(doublesh, mw(sllmaxe, 0), flstack);
6659
      ins0("fsubrp %st,%st(1)");
6621
      ins0("fsubrp %st,%st(1)");
6660
      pop_fl;
6622
      pop_fl;
6661
    }
6623
    }
6662
    else
6624
    else
6663
      ins1 (fsubl, size64, mw (smaxe, 0));
6625
      ins1(fsubl, size64, mw(smaxe, 0));
6664
  };
6626
  };
6665
  ins0 (frndint);
6627
  ins0(frndint);
6666
  ins1 ((sz == 64 ? fistpll : fistpl), sz, mw (ind_sp.where_exp, (-sz)));
6628
  ins1((sz == 64 ? fistpll : fistpl), sz, mw(ind_sp.where_exp,(-sz)));
6667
  if (mode != 0 && mode != 4) {
6629
  if (mode != 0 && mode != 4) {
6668
    ins1 (fldcw, size16, mw (ind_sp.where_exp, (-(sz+32))));
6630
    ins1(fldcw, size16, mw(ind_sp.where_exp,(- (sz+32))));
6669
    add (slongsh, mw (zeroe, 4), sp, sp);
6631
    add(slongsh, mw(zeroe, 4), sp, sp);
6670
    extra_stack -= 32;
6632
    extra_stack -= 32;
6671
  };
6633
  };
6672
  invalidate_dest(ind_sp);
6634
  invalidate_dest(ind_sp);
6673
  return;
6635
  return;
6674
}
6636
}
6675
 
6637
 
6676
 
6638
 
6677
static  void roundit
6639
static  void roundit
6678
    PROTO_N ( (sha, from, to, mode) )
-
 
6679
    PROTO_T ( shape sha X where from X where to X int mode )
6640
(shape sha, where from, where to, int mode)
6680
{
6641
{
6681
  shape shfrom = sh (from.where_exp);
6642
  shape shfrom = sh(from.where_exp);
6682
  int ul = (name (sha) == ulonghd || name (sha) == u64hd);
6643
  int ul = (name(sha) == ulonghd || name(sha) == u64hd);
6683
  int sz = (shape_size (sha) == 64) ? 64 : 32;
6644
  int sz = (shape_size(sha) == 64)? 64 : 32;
6684
 
6645
 
6685
  cond1_set = 0;
6646
  cond1_set = 0;
6686
  cond2_set = 0;
6647
  cond2_set = 0;
6687
 
6648
 
6688
  move (shfrom, from, flstack);
6649
  move(shfrom, from, flstack);
6689
 
6650
 
6690
  round_code (mode, ul, sz);
6651
  round_code(mode, ul, sz);
6691
  if (ul) {
6652
  if (ul) {
6692
    xor (ulongsh, mw(ind_sp.where_exp, -32), mw(zeroe, (int)((unsigned int)1<<31)),
6653
    xor(ulongsh, mw(ind_sp.where_exp, -32), mw(zeroe,(int)((unsigned int)1<<31)),
6693
	mw(ind_sp.where_exp, -32));
6654
	mw(ind_sp.where_exp, -32));
6694
  }
6655
  }
6695
  pop_fl;
6656
  pop_fl;
6696
  if (flinmem (to)) {
6657
  if (flinmem(to)) {
6697
    move (sha, mw(ind_sp.where_exp, -sz), reg0);
6658
    move(sha, mw(ind_sp.where_exp, -sz), reg0);
6698
    invalidate_dest(reg0);
6659
    invalidate_dest(reg0);
6699
    add (slongsh, mw (zeroe, sz/8), sp, sp);
6660
    add(slongsh, mw(zeroe, sz/8), sp, sp);
6700
    extra_stack -= sz;
6661
    extra_stack -= sz;
6701
    move (sha, reg0, to);
6662
    move(sha, reg0, to);
6702
  }
6663
  }
6703
  else
6664
  else
6704
   {
6665
   {
6705
    move (sha, mw(ind_sp.where_exp, -sz), to);
6666
    move(sha, mw(ind_sp.where_exp, -sz), to);
6706
    add (slongsh, mw (zeroe, sz/8), sp, sp);
6667
    add(slongsh, mw(zeroe, sz/8), sp, sp);
6707
    extra_stack -= sz;
6668
    extra_stack -= sz;
6708
   };
6669
   };
6709
  return;
6670
  return;
6710
}
6671
}
6711
 
6672
 
6712
 
6673
 
6713
/* floating point round */
6674
/* floating point round */
6714
void frnd0
6675
void frnd0
6715
    PROTO_N ( (sha, from, to) )
-
 
6716
    PROTO_T ( shape sha X where from X where to )
6676
(shape sha, where from, where to)
6717
{
6677
{
6718
  roundit (sha, from, to, 0);
6678
  roundit(sha, from, to, 0);
6719
  return;
6679
  return;
6720
}
6680
}
6721
 
6681
 
6722
/* floating point round */
6682
/* floating point round */
6723
void frnd1
6683
void frnd1
6724
    PROTO_N ( (sha, from, to) )
-
 
6725
    PROTO_T ( shape sha X where from X where to )
6684
(shape sha, where from, where to)
6726
{
6685
{
6727
  roundit (sha, from, to, 1);
6686
  roundit(sha, from, to, 1);
6728
  return;
6687
  return;
6729
}
6688
}
6730
 
6689
 
6731
/* floating point round */
6690
/* floating point round */
6732
void frnd2
6691
void frnd2
6733
    PROTO_N ( (sha, from, to) )
-
 
6734
    PROTO_T ( shape sha X where from X where to )
6692
(shape sha, where from, where to)
6735
{
6693
{
6736
  roundit (sha, from, to, 2);
6694
  roundit(sha, from, to, 2);
6737
  return;
6695
  return;
6738
}
6696
}
6739
 
6697
 
6740
/* floating point round */
6698
/* floating point round */
6741
void frnd3
6699
void frnd3
6742
    PROTO_N ( (sha, from, to) )
-
 
6743
    PROTO_T ( shape sha X where from X where to )
6700
(shape sha, where from, where to)
6744
{
6701
{
6745
  roundit (sha, from, to, 3);
6702
  roundit(sha, from, to, 3);
6746
  return;
6703
  return;
6747
}
6704
}
6748
 
6705
 
6749
/* floating point round */
6706
/* floating point round */
6750
void frnd4
6707
void frnd4
6751
    PROTO_N ( (sha, from, to) )
-
 
6752
    PROTO_T ( shape sha X where from X where to )
6708
(shape sha, where from, where to)
6753
{
6709
{
6754
  roundit (sha, from, to, 4);
6710
  roundit(sha, from, to, 4);
6755
  return;
6711
  return;
6756
}
6712
}
6757
 
6713
 
6758
/* float the integer from, result to */
6714
/* float the integer from, result to */
6759
void floater
6715
void floater
6760
    PROTO_N ( (sha, from, to) )
-
 
6761
    PROTO_T ( shape sha X where from X where to )
6716
(shape sha, where from, where to)
6762
{
6717
{
6763
  shape shfrom = sh (from.where_exp);
6718
  shape shfrom = sh(from.where_exp);
6764
  int  szf;
6719
  int  szf;
6765
  int im;
6720
  int im;
6766
  exp holdfe;
6721
  exp holdfe;
6767
  szf = shape_size(shfrom);
6722
  szf = shape_size(shfrom);
6768
  im = inmem (from);
6723
  im = inmem(from);
6769
 
6724
 
6770
 
6725
 
6771
  if (!im || szf < 32) {
6726
  if (!im || szf < 32) {
6772
    if (szf < 32) {
6727
    if (szf < 32) {
6773
      change_var (slongsh, from, reg0);
6728
      change_var(slongsh, from, reg0);
6774
      ins1 (pushl,  32, reg0);
6729
      ins1(pushl,  32, reg0);
6775
#ifdef NEWDWARF
6730
#ifdef NEWDWARF
6776
      if (diagnose && dwarf2 && no_frame)
6731
      if (diagnose && dwarf2 && no_frame)
6777
	dw2_track_push();
6732
	dw2_track_push();
6778
#endif
6733
#endif
6779
      from = ind_sp;
6734
      from = ind_sp;
6780
    }
6735
    }
6781
    else {
6736
    else {
6782
      if (szf == 64) {
6737
      if (szf == 64) {
6783
	ins0 (pushedx);
6738
	ins0(pushedx);
6784
#ifdef NEWDWARF
6739
#ifdef NEWDWARF
6785
	if (diagnose && dwarf2 && no_frame)
6740
	if (diagnose && dwarf2 && no_frame)
6786
	  dw2_track_push();
6741
	  dw2_track_push();
6787
#endif
6742
#endif
6788
	ins0 (pusheax);
6743
	ins0(pusheax);
6789
#ifdef NEWDWARF
6744
#ifdef NEWDWARF
6790
	if (diagnose && dwarf2 && no_frame)
6745
	if (diagnose && dwarf2 && no_frame)
6791
	  dw2_track_push();
6746
	  dw2_track_push();
6792
#endif
6747
#endif
6793
      }
6748
      }
6794
      else {
6749
      else {
6795
	ins1 (pushl, szf, from);
6750
	ins1(pushl, szf, from);
6796
#ifdef NEWDWARF
6751
#ifdef NEWDWARF
6797
	if (diagnose && dwarf2 && no_frame)
6752
	if (diagnose && dwarf2 && no_frame)
6798
	  dw2_track_push();
6753
	  dw2_track_push();
6799
#endif
6754
#endif
6800
      }
6755
      }
6801
      from = ind_sp;
6756
      from = ind_sp;
6802
    };
6757
    };
6803
  };
6758
  };
6804
 
6759
 
6805
  holdfe = son(from.where_exp);
6760
  holdfe = son(from.where_exp);
6806
  contop (from.where_exp, 0, reg0);
6761
  contop(from.where_exp, 0, reg0);
6807
  ins1 ((szf == 64 ? fildll : fildl), szf, from);
6762
  ins1((szf == 64 ? fildll : fildl), szf, from);
6808
  if (name (shfrom) == ulonghd || name (shfrom) == u64hd) {
6763
  if (name(shfrom) == ulonghd || name(shfrom) == u64hd) {
6809
    int  lab = next_lab ();
6764
    int  lab = next_lab();
6810
    ins2 (cmpl, szf, szf, zero, from);
6765
    ins2(cmpl, szf, szf, zero, from);
6811
    simple_branch (jge, lab);
6766
    simple_branch(jge, lab);
6812
    if (szf == 64) {
6767
    if (szf == 64) {
6813
      move (doublesh, mw (sllmaxe, 0), flstack);
6768
      move(doublesh, mw(sllmaxe, 0), flstack);
6814
      ins0("faddp %st,%st(1)");
6769
      ins0("faddp %st,%st(1)");
6815
    }
6770
    }
6816
    else
6771
    else
6817
      ins1 (faddl, size64, mw (dlongmaxe, 0));
6772
      ins1(faddl, size64, mw(dlongmaxe, 0));
6818
    simple_set_label (lab);
6773
    simple_set_label(lab);
6819
  };
6774
  };
6820
  end_contop ();
6775
  end_contop();
6821
 
6776
 
6822
  if (!im || szf < 32) {
6777
  if (!im || szf < 32) {
6823
    ins2 (addl,  32,  32, mw (zeroe, (szf == 64 ? 8 : 4)), sp);
6778
    ins2(addl,  32,  32, mw(zeroe,(szf == 64 ? 8 : 4)), sp);
6824
  };
6779
  };
6825
  push_fl;
6780
  push_fl;
6826
  move (sha, flstack, to);
6781
  move(sha, flstack, to);
6827
  son(from.where_exp) = holdfe;
6782
  son(from.where_exp) = holdfe;
6828
  return;
6783
  return;
6829
}
6784
}
6830
 
6785
 
6831
/* change floating variety of from to sha,
6786
/* change floating variety of from to sha,
6832
   put in to. Shortening change now dealt
6787
   put in to. Shortening change now dealt
6833
   with by test_fl_ovfl */
6788
   with by test_fl_ovfl */
6834
void changefl
6789
void changefl
6835
    PROTO_N ( (sha, from, to) )
-
 
6836
    PROTO_T ( shape sha X where from X where to )
6790
(shape sha, where from, where to)
6837
{
6791
{
6838
  shape shfrom = sh (from.where_exp);
6792
  shape shfrom = sh(from.where_exp);
6839
  if (in_fl_reg (from.where_exp)) {/* from is in a fl reg */
6793
  if (in_fl_reg (from.where_exp)) {/* from is in a fl reg */
6840
	/* change in case of shortening now dealt with by test_fl_ovfl */
6794
	/* change in case of shortening now dealt with by test_fl_ovfl */
6841
    move (sha, from, to);	/* just move to destination */
6795
    move (sha, from, to);	/* just move to destination */
6842
    return;
6796
    return;
6843
  };
6797
  };
6844
 
6798
 
6845
  /* from is not in fl reg */
6799
  /* from is not in fl reg */
6846
  move (shfrom, from, flstack);
6800
  move(shfrom, from, flstack);
6847
  move (sha, flstack, to);
6801
  move(sha, flstack, to);
6848
  return;
6802
  return;
6849
}
6803
}
6850
 
6804
 
6851
/* floating point negate */
6805
/* floating point negate */
6852
void fl_neg
6806
void fl_neg
6853
    PROTO_N ( (sha, from, to) )
-
 
6854
    PROTO_T ( shape sha X where from X where to )
6807
(shape sha, where from, where to)
6855
{
6808
{
6856
  int  f1 = in_fl_reg (from.where_exp);
6809
  int  f1 = in_fl_reg(from.where_exp);
6857
  int  f2 = in_fl_reg (to.where_exp);
6810
  int  f2 = in_fl_reg(to.where_exp);
6858
 
6811
 
6859
 
6812
 
6860
  if (f1 != 0 && f2 != 0 &&
6813
  if (f1 != 0 && f2 != 0 &&
6861
      get_reg_no (f1) == fstack_pos &&
6814
      get_reg_no(f1) == fstack_pos &&
6862
      get_reg_no (f2) == fstack_pos) {
6815
      get_reg_no(f2) == fstack_pos) {
6863
    ins0 (fchs);
6816
    ins0(fchs);
6864
    return;
6817
    return;
6865
  };
6818
  };
6866
  move (sha, from, flstack);
6819
  move(sha, from, flstack);
6867
  ins0 (fchs);
6820
  ins0(fchs);
6868
  move (sha, flstack, to);
6821
  move(sha, flstack, to);
6869
  return;
6822
  return;
6870
}
6823
}
6871
 
6824
 
6872
/* floating point abs */
6825
/* floating point abs */
6873
void fl_abs
6826
void fl_abs
6874
    PROTO_N ( (sha, from, to) )
-
 
6875
    PROTO_T ( shape sha X where from X where to )
6827
(shape sha, where from, where to)
6876
{
6828
{
6877
  int  f1 = in_fl_reg (from.where_exp);
6829
  int  f1 = in_fl_reg(from.where_exp);
6878
  int  f2 = in_fl_reg (to.where_exp);
6830
  int  f2 = in_fl_reg(to.where_exp);
6879
 
6831
 
6880
 
6832
 
6881
  if (f1 != 0 && f2 != 0 &&
6833
  if (f1 != 0 && f2 != 0 &&
6882
      get_reg_no (f1) == fstack_pos &&
6834
      get_reg_no(f1) == fstack_pos &&
6883
      get_reg_no (f2) == fstack_pos) {
6835
      get_reg_no(f2) == fstack_pos) {
6884
    ins0 (fabs);
6836
    ins0(fabs);
6885
    return;
6837
    return;
6886
  };
6838
  };
6887
  move (sha, from, flstack);
6839
  move(sha, from, flstack);
6888
  ins0 (fabs);
6840
  ins0(fabs);
6889
  move (sha, flstack, to);
6841
  move(sha, flstack, to);
6890
  return;
6842
  return;
6891
}
6843
}
6892
 
6844
 
6893
/*
6845
/*
6894
    For each of 14 possible comparison operators replace the sahf, j??
6846
    For each of 14 possible comparison operators replace the sahf, j??
Line 6904... Line 6856...
6904
*/
6856
*/
6905
 
6857
 
6906
 
6858
 
6907
/* floating point compare */
6859
/* floating point compare */
6908
void fl_comp
6860
void fl_comp
6909
    PROTO_N ( (sha, pos, neg, e) )
-
 
6910
    PROTO_T ( shape sha X where pos X where neg X exp e )
6861
(shape sha, where pos, where neg, exp e)
6911
{
6862
{
6912
				/* can improve this to use other
6863
				/* can improve this to use other
6913
				   comparison instructions */
6864
				   comparison instructions */
6914
  cond1_set = 0;
6865
  cond1_set = 0;
6915
  cond2_set = 0;
6866
  cond2_set = 0;
6916
  move (sha, neg, flstack);
6867
  move(sha, neg, flstack);
6917
  move (sha, pos, flstack);
6868
  move(sha, pos, flstack);
6918
  ins0 (fcompp);
6869
  ins0(fcompp);
6919
 
6870
 
6920
  ins1 (fnstsw,  16, reg0);
6871
  ins1(fnstsw,  16, reg0);
6921
 
6872
 
6922
  testah(flpt_test_no[test_number(e)]);
6873
  testah(flpt_test_no[test_number(e)]);
6923
 
6874
 
6924
  invalidate_dest (reg0);
6875
  invalidate_dest(reg0);
6925
  pop_fl;
6876
  pop_fl;
6926
  pop_fl;
6877
  pop_fl;
6927
  return;
6878
  return;
6928
}
6879
}
6929
 
6880
 
6930
/* use test instruction */
6881
/* use test instruction */
6931
void test
6882
void test
6932
    PROTO_N ( (sha, a, b) )
-
 
6933
    PROTO_T ( shape sha X where a X where b )
6883
(shape sha, where a, where b)
6934
{
6884
{
6935
  char *t;
6885
  char *t;
6936
  int  sz;
6886
  int  sz;
6937
  exp hold;
6887
  exp hold;
6938
 
6888
 
Line 6950... Line 6900...
6950
  };
6900
  };
6951
 
6901
 
6952
  cond1_set = 0;
6902
  cond1_set = 0;
6953
  cond2_set = 0;
6903
  cond2_set = 0;
6954
 
6904
 
6955
  if (inmem (a) && inmem (b)) {
6905
  if (inmem(a) && inmem(b)) {
6956
    hold = son(b.where_exp);
6906
    hold = son(b.where_exp);
6957
    move (sha, a, reg0);
6907
    move(sha, a, reg0);
6958
    contop (b.where_exp, 1, reg0);
6908
    contop(b.where_exp, 1, reg0);
6959
    ins2 (t, sz, sz, reg0, b);
6909
    ins2(t, sz, sz, reg0, b);
6960
    end_contop ();
6910
    end_contop();
6961
    son(b.where_exp) = hold;
6911
    son(b.where_exp) = hold;
6962
    return;
6912
    return;
6963
  };
6913
  };
6964
  if (!inmem (b) && name (a.where_exp) != val_tag) {
6914
  if (!inmem(b) && name(a.where_exp)!= val_tag) {
6965
    hold = son(a.where_exp);
6915
    hold = son(a.where_exp);
6966
    contop (a.where_exp,  (eq_where (reg0, a) || eq_where (reg0, b)),
6916
    contop(a.where_exp, (eq_where(reg0, a) || eq_where(reg0, b)),
6967
	reg0);
6917
	reg0);
6968
    ins2 (t, sz, sz, b, a);
6918
    ins2(t, sz, sz, b, a);
6969
    end_contop ();
6919
    end_contop();
6970
    son(a.where_exp) = hold;
6920
    son(a.where_exp) = hold;
6971
    return;
6921
    return;
6972
  };
6922
  };
6973
  hold = son(b.where_exp);
6923
  hold = son(b.where_exp);
6974
  contop (b.where_exp,  (eq_where (reg0, a) || eq_where (reg0, b)),
6924
  contop(b.where_exp, (eq_where(reg0, a) || eq_where(reg0, b)),
6975
      reg0);
6925
      reg0);
6976
  ins2 (t, sz, sz, a, b);
6926
  ins2(t, sz, sz, a, b);
6977
  end_contop ();
6927
  end_contop();
6978
  son(b.where_exp) = hold;
6928
  son(b.where_exp) = hold;
6979
  return;
6929
  return;
6980
}
6930
}
6981
 
6931
 
6982
 
6932
 
6983
/* decrease the stack */
6933
/* decrease the stack */
6984
void decstack
6934
void decstack
6985
    PROTO_N ( (longs) )
-
 
6986
    PROTO_T ( int longs )
6935
(int longs)
6987
{
6936
{
6988
 
6937
 
6989
  ins2 (subl,  32,  32, mw (zeroe, (longs / 8)), sp);
6938
  ins2(subl,  32,  32, mw(zeroe,(longs / 8)), sp);
6990
  return;
6939
  return;
6991
}
6940
}
6992
 
6941
 
6993
void long_jump
6942
void long_jump
6994
    PROTO_N ( (e) )
-
 
6995
    PROTO_T ( exp e )
6943
(exp e)
6996
{
6944
{
6997
  ins0(popebp);
6945
  ins0(popebp);
6998
  ins0(ret);
6946
  ins0(ret);
6999
  return;
6947
  return;
7000
}
6948
}
Line 7002... Line 6950...
7002
 
6950
 
7003
 
6951
 
7004
static int fp_clear = 0;
6952
static int fp_clear = 0;
7005
 
6953
 
7006
void reset_fpucon
6954
void reset_fpucon
7007
    PROTO_Z ()
6955
(void)
7008
{
6956
{
7009
  fp_clear = 0;
6957
  fp_clear = 0;
7010
  if (fpucon == normal_fpucon)
6958
  if (fpucon == normal_fpucon)
7011
    return;
6959
    return;
7012
  if (fpucon & ~normal_fpucon & (int)0xd) {
6960
  if (fpucon & ~normal_fpucon & (int)0xd) {
7013
    ins0(fclex);
6961
    ins0(fclex);
7014
    fp_clear = 1;
6962
    fp_clear = 1;
7015
  }
6963
  }
7016
  if (ferrsize < 32)
6964
  if (ferrsize < 32)
7017
    ferrsize = 32;
6965
    ferrsize = 32;
7018
  ins1 (fldcw, 16, mw(ferrmem,0));
6966
  ins1(fldcw, 16, mw(ferrmem,0));
7019
  fpucon = normal_fpucon;
6967
  fpucon = normal_fpucon;
7020
}
6968
}
7021
 
6969
 
7022
static void set_fpucon
6970
static void set_fpucon
7023
    PROTO_N ( (mask, val) )
-
 
7024
    PROTO_T ( int mask X int val )
6971
(int mask, int val)
7025
{
6972
{
7026
  if ((fpucon & mask) == val)
6973
  if ((fpucon & mask) == val)
7027
    return;
6974
    return;
7028
  fpucon = ((~mask & fpucon) | val);
6975
  fpucon = ((~mask & fpucon) | val);
7029
  if (ferrsize < 32)
6976
  if (ferrsize < 32)
7030
    ferrsize = 32;
6977
    ferrsize = 32;
7031
  move (uwordsh, mw(zeroe, fpucon), mw(ferrmem, 16));
6978
  move(uwordsh, mw(zeroe, fpucon), mw(ferrmem, 16));
7032
  ins1 (fldcw, 16, mw(ferrmem,16));
6979
  ins1(fldcw, 16, mw(ferrmem,16));
7033
}
6980
}
7034
 
6981
 
7035
void setup_fl_ovfl
6982
void setup_fl_ovfl
7036
    PROTO_N ( (e) )
-
 
7037
    PROTO_T ( exp e )
6983
(exp e)
7038
{
6984
{
7039
  int traps = 0xd;
6985
  int traps = 0xd;
7040
  int ival;
6986
  int ival;
7041
  int eprmask = 0x300;
6987
  int eprmask = 0x300;
7042
  if (errhandle(e) == 0) {
6988
  if (errhandle(e) == 0) {
7043
    if (name(sh(e)) == doublehd)
6989
    if (name(sh(e)) == doublehd)
7044
      set_fpucon (eprmask, eprmask);
6990
      set_fpucon(eprmask, eprmask);
7045
    return;
6991
    return;
7046
  }
6992
  }
7047
  if (!fp_clear && !optop(e)) {
6993
  if (!fp_clear && !optop(e)) {
7048
    ins0(fclex);
6994
    ins0(fclex);
7049
    fp_clear = 1;
6995
    fp_clear = 1;
7050
  }
6996
  }
7051
  ival = (istrap(e) ? 0 : traps);
6997
  ival = (istrap(e)? 0 : traps);
7052
  if (name(sh(e)) == doublehd || name(sh(e)) == s64hd || name(sh(e)) == u64hd)
6998
  if (name(sh(e)) == doublehd || name(sh(e)) == s64hd || name(sh(e)) == u64hd)
7053
    set_fpucon ((eprmask | traps), (eprmask | ival));
6999
    set_fpucon((eprmask | traps), (eprmask | ival));
7054
  else
7000
  else
7055
    set_fpucon (traps, ival);
7001
    set_fpucon(traps, ival);
7056
  return;
7002
  return;
7057
}
7003
}
7058
 
7004
 
7059
void test_fl_ovfl
7005
void test_fl_ovfl
7060
    PROTO_N ( (e, dest) )
-
 
7061
    PROTO_T ( exp e X where dest )
7006
(exp e, where dest)
7062
{
7007
{
7063
  int r;
7008
  int r;
7064
  if (errhandle(e) == 0)
7009
  if (errhandle(e) == 0)
7065
    return;
7010
    return;
7066
  r = in_fl_reg(dest.where_exp);
7011
  r = in_fl_reg(dest.where_exp);
Line 7072... Line 7017...
7072
      ferrsize = reqsize;
7017
      ferrsize = reqsize;
7073
    m = mw(ferrmem,32);
7018
    m = mw(ferrmem,32);
7074
    if (get_reg_no(r) == fstack_pos && !optop(e)) {
7019
    if (get_reg_no(r) == fstack_pos && !optop(e)) {
7075
	/* avoid move, which pops the stack */
7020
	/* avoid move, which pops the stack */
7076
      if (name(sh(e)) == realhd)
7021
      if (name(sh(e)) == realhd)
7077
	ins1 (fstl, 64, m);
7022
	ins1(fstl, 64, m);
7078
      else
7023
      else
7079
	ins1 (fsts, 32, m);
7024
	ins1(fsts, 32, m);
7080
    }
7025
    }
7081
    else {
7026
    else {
7082
      move (sh(e), dest, m);
7027
      move(sh(e), dest, m);
7083
      if (optop(e))		/* replace by suitable value */
7028
      if (optop(e))		/* replace by suitable value */
7084
	move (sh(e), m, dest);
7029
	move(sh(e), m, dest);
7085
    }
7030
    }
7086
  }
7031
  }
7087
  if (optop(e)) {
7032
  if (optop(e)) {
7088
    fp_clear = 0;
7033
    fp_clear = 0;
7089
    return;
7034
    return;
7090
  }
7035
  }
7091
  if (isov(e))  {
7036
  if (isov(e)) {
7092
    if (eq_where (dest, reg0)) {
7037
    if (eq_where(dest, reg0)) {
7093
      ins0(pusheax);
7038
      ins0(pusheax);
7094
#ifdef NEWDWARF
7039
#ifdef NEWDWARF
7095
      if (diagnose && dwarf2 && no_frame)
7040
      if (diagnose && dwarf2 && no_frame)
7096
	dw2_track_push();
7041
	dw2_track_push();
7097
#endif
7042
#endif
7098
    }
7043
    }
7099
    ins1 (fstsw,  16, reg0);
7044
    ins1(fstsw,  16, reg0);
7100
    ins2(testb, 8, 8, mw(zeroe, 13), reg0);
7045
    ins2(testb, 8, 8, mw(zeroe, 13), reg0);
7101
		/* Overflow, Zero divide or Invalid  */
7046
		/* Overflow, Zero divide or Invalid  */
7102
    if (eq_where (dest, reg0)) {
7047
    if (eq_where(dest, reg0)) {
7103
      ins0(popeax);
7048
      ins0(popeax);
7104
#ifdef NEWDWARF
7049
#ifdef NEWDWARF
7105
      if (diagnose && dwarf2 && no_frame)
7050
      if (diagnose && dwarf2 && no_frame)
7106
	dw2_track_pop();
7051
	dw2_track_pop();
7107
#endif
7052
#endif
Line 7111... Line 7056...
7111
  };
7056
  };
7112
  return;
7057
  return;
7113
}
7058
}
7114
 
7059
 
7115
exp find_stlim_var
7060
exp find_stlim_var
7116
    PROTO_Z ()
7061
(void)
7117
{
7062
{
7118
  return (make_extn ("__trans386_stack_limit", ulongsh, 1));
7063
  return(make_extn("__trans386_stack_limit", ulongsh, 1));
7119
}
7064
}
7120
 
7065
 
7121
void checkalloc_stack
7066
void checkalloc_stack
7122
    PROTO_N ( (sz, b) )
-
 
7123
    PROTO_T ( where sz X int b )
7067
(where sz, int b)
7124
{
7068
{
7125
  /* uses reg1 */
7069
  /* uses reg1 */
7126
  int erlab = next_lab ();
7070
  int erlab = next_lab();
7127
  int cnlab = next_lab ();
7071
  int cnlab = next_lab();
7128
  if (cont_stacklimit == nilexp) {
7072
  if (cont_stacklimit == nilexp) {
7129
    cont_stacklimit = make_extn ("__trans386_stack_limit", ulongsh, 1);
7073
    cont_stacklimit = make_extn("__trans386_stack_limit", ulongsh, 1);
7130
    if (!PIC_code)
7074
    if (!PIC_code)
7131
      cont_stacklimit = getexp (ulongsh, nilexp, 1, cont_stacklimit, nilexp, 0, 0, cont_tag);
7075
      cont_stacklimit = getexp(ulongsh, nilexp, 1, cont_stacklimit, nilexp, 0, 0, cont_tag);
7132
  }
7076
  }
7133
  ins2 (movl, 32, 32, sp, reg1);
7077
  ins2(movl, 32, 32, sp, reg1);
7134
  ins2 (subl, 32, 32, sz, reg1);
7078
  ins2(subl, 32, 32, sz, reg1);
7135
  simple_branch (jb, erlab);
7079
  simple_branch(jb, erlab);
7136
  if (PIC_code) {
7080
  if (PIC_code) {
7137
    ins2 (movl, 32, 32, mw(cont_stacklimit, 0), reg0);
7081
    ins2(movl, 32, 32, mw(cont_stacklimit, 0), reg0);
7138
    ins2 (cmpl, 32, 32, ind_reg0, reg1);
7082
    ins2(cmpl, 32, 32, ind_reg0, reg1);
7139
    simple_branch (ja, cnlab);
7083
    simple_branch(ja, cnlab);
7140
  }
7084
  }
7141
  else {
7085
  else {
7142
    ins2 (cmpl, 32, 32, mw(cont_stacklimit, 0), reg1);
7086
    ins2(cmpl, 32, 32, mw(cont_stacklimit, 0), reg1);
7143
    simple_branch (ja, cnlab);
7087
    simple_branch(ja, cnlab);
7144
  }
7088
  }
7145
  simple_set_label (erlab);
7089
  simple_set_label(erlab);
7146
  trap_ins (f_stack_overflow);
7090
  trap_ins(f_stack_overflow);
7147
  simple_set_label (cnlab);
7091
  simple_set_label(cnlab);
7148
  if (b)
7092
  if (b)
7149
    ins2 (movl, 32, 32, reg1, sp);
7093
    ins2(movl, 32, 32, reg1, sp);
7150
}
7094
}
7151
 
7095
 
7152
/* Builtin functions. All args are operands */
7096
/* Builtin functions. All args are operands */
7153
void special_ins
7097
void special_ins
7154
    PROTO_N ( (id, arg, dest) )
-
 
7155
    PROTO_T ( char * id X exp arg X where dest )
7098
(char * id, exp arg, where dest)
7156
{
7099
{
7157
  if (!strcmp (id, "__trans386_special") && name(arg) == val_tag) {
7100
  if (!strcmp(id, "__trans386_special") && name(arg) == val_tag) {
7158
    switch (no(arg)) {
7101
    switch (no(arg)) {
7159
      case 0:
7102
      case 0:
7160
	ins0(fwait);
7103
	ins0(fwait);
7161
	return;
7104
	return;
7162
      case 1:
7105
      case 1:
Line 7167... Line 7110...
7167
      case 2:
7110
      case 2:
7168
	ins0(fclex);
7111
	ins0(fclex);
7169
	return;
7112
	return;
7170
    };
7113
    };
7171
  }
7114
  }
7172
  failer (BADOP);
7115
  failer(BADOP);
7173
}
7116
}
7174
 
7117
 
7175
void save_stack
7118
void save_stack
7176
    PROTO_Z ()
7119
(void)
7177
{
7120
{
7178
  if (extra_stack || stack_dec)
7121
  if (extra_stack || stack_dec)
7179
    failer ("unclean stack");
7122
    failer("unclean stack");
7180
  ins2 (movl, 32, 32, sp, firstlocal);
7123
  ins2(movl, 32, 32, sp, firstlocal);
7181
}
7124
}
7182
 
7125
 
7183
void restore_stack
7126
void restore_stack
7184
    PROTO_Z ()
7127
(void)
7185
{
7128
{
7186
  if (extra_stack || stack_dec)
7129
  if (extra_stack || stack_dec)
7187
    failer ("unclean stack");
7130
    failer("unclean stack");
7188
  ins2 (movl, 32, 32, firstlocal, sp);
7131
  ins2(movl, 32, 32, firstlocal, sp);
7189
}
7132
}
7190
 
7133
 
7191
void start_asm
7134
void start_asm
7192
    PROTO_Z ()
7135
(void)
7193
{
7136
{
7194
  outnl ();
7137
  outnl();
7195
#ifdef as_comment_symbol
7138
#ifdef as_comment_symbol
7196
  outc ('\t'); outc (as_comment_symbol);
7139
  outc('\t'); outc(as_comment_symbol);
7197
  outs (" ASM sequence start");
7140
  outs(" ASM sequence start");
7198
  outnl ();
7141
  outnl();
7199
#endif
7142
#endif
7200
  return;
7143
  return;
7201
}
7144
}
7202
 
7145
 
7203
void end_asm
7146
void end_asm
7204
    PROTO_Z ()
7147
(void)
7205
{
7148
{
7206
#ifdef as_comment_symbol
7149
#ifdef as_comment_symbol
7207
  outc ('\t'); outc (as_comment_symbol);
7150
  outc('\t'); outc(as_comment_symbol);
7208
  outs (" ASM sequence ends");
7151
  outs(" ASM sequence ends");
7209
  outnl ();
7152
  outnl();
7210
#endif
7153
#endif
7211
  outnl ();
7154
  outnl();
7212
  return;
7155
  return;
7213
}
7156
}
7214
 
7157
 
7215
void asm_ins
7158
void asm_ins
7216
    PROTO_N ( (e) )
-
 
7217
    PROTO_T ( exp e )
7159
(exp e)
7218
{
7160
{
7219
  if (name(son(e)) == string_tag)
7161
  if (name(son(e)) == string_tag)
7220
    outs (nostr(son(e)));
7162
    outs(nostr(son(e)));
7221
  else {
7163
  else {
7222
    int prev_use_bp = must_use_bp;
7164
    int prev_use_bp = must_use_bp;
7223
    must_use_bp = 1;	/* scan2 must ensure !no_frame */
7165
    must_use_bp = 1;	/* scan2 must ensure !no_frame */
7224
    operand (shape_size(son(e)), mw (son(e), 0), 1, 0);
7166
    operand(shape_size(son(e)), mw(son(e), 0), 1, 0);
7225
    must_use_bp = prev_use_bp;
7167
    must_use_bp = prev_use_bp;
7226
  }
7168
  }
7227
  return;
7169
  return;
7228
}
7170
}