Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /branches/tendra5/src/installers/amd64/common/codec.c – Rev 6 and 118

Subversion Repositories tendra.SVN

Rev

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

Rev 6 Rev 118
Line 190... Line 190...
190
 
190
 
191
 
191
 
192
/* PROCEDURES */
192
/* PROCEDURES */
193
 
193
 
194
/* returns true if is_o(e) but not a possible 80386 operand */
194
/* returns true if is_o(e) but not a possible 80386 operand */
195
int
195
int is_crc
196
is_crc(exp e)
196
(exp e)
197
{
197
{
319
 
482
 
320
/* process the binary logical operation exp. op is the compiling procedure for
-
 
321
   the operation. It is commutative and associative, the operation takes a
483
/* if a is a negation form b-son(a)
322
   variable number of arguments. It is therefore necessary to avoid the mistake
-
 
323
   of assigning to the destination (dest) inappropriately if its value is used
-
 
324
   in the expression. At most one of the arguments will not be a possible 80386
-
 
325
   operand. If there is such an argument, logop precomputes it, putting the
-
 
326
   value into reg0. */
484
   otherwise b+a in dest */
327
static void
485
static void addsub
328
logop(void(*op)(shape, where, where, where), exp e, where dest, ash stack)
486
(shape sha, where a, where b, where dest, exp e)
329
{
487
{
330
	exp arg1 = son(e);
488
  UNUSED(e);
331
	exp arg2 = bro(arg1);
489
  if (name(a.where_exp) == neg_tag)
332
	shape sha = sh(e);
490
    sub(sha, mw(son(a.where_exp), 0), b, dest);
333
	exp t, u;
491
  else
334
	where qw;
-
 
335
 
-
 
336
	if (last(arg1)) {
-
 
337
		coder(dest, stack, arg1);
492
    add(sha, a, b, dest);
338
		return;
493
  return;
339
	}
494
}
340
 
495
 
341
	/* just two arguments. */
-
 
342
	if (last (arg2)) {
-
 
343
		bop(op, sha, arg1, arg2, dest, stack);
-
 
344
		return;
-
 
345
	}
-
 
346
	/* need to take care about overlap between dest and args or to avoid
-
 
347
	   extra push. So use reg0. */
-
 
348
	qw.where_exp = copyexp(reg0.where_exp);
-
 
349
	sh(qw.where_exp) = sha;
-
 
350
	qw.where_off = 0;
-
 
351
	t = arg1;
-
 
352
	/* now look for an argument which is not a possible 80386 operand */
-
 
353
	while (1) {
-
 
354
		if (!is_o(name(t)) || is_crc(t)) {
-
 
355
			break;
-
 
356
		}
-
 
357
		if (last(t)) {
-
 
358
			t = nilexp;
-
 
359
			break;
-
 
360
		}
-
 
361
		t = bro(t);
-
 
362
	}
-
 
363
 
496
 
364
	/* all arguments are possible 80386 operands */
-
 
365
	if (t == nilexp) {
-
 
366
		(*op)(sha, mw(arg1, 0), mw(arg2, 0), qw);
-
 
367
		t = bro(arg2);
-
 
368
		while (!last(t)) {
-
 
369
			/* encode operations in turn */
-
 
370
			(*op) (sha, mw (t, 0), qw, qw);
-
 
371
			t = bro(t);
-
 
372
		}
-
 
373
		/* encode final operation */
-
 
374
		(*op) (sha, mw (t, 0), qw, dest);
-
 
375
		retcell(qw.where_exp);
-
 
376
		cond1_set = 0;
-
 
377
		return;
-
 
378
	}
-
 
379
 
497
 
380
	/* encode the single argument which is not a possible 80386 operend */
498
/***********************************************************************
381
	coder (qw, stack, t);
-
 
382
	u = arg1;
-
 
383
	/* now encode the remaining operations */
499
   codec outputs the code which evaulates e and puts the result into
384
	while (1) {
500
   dest.
385
		if (t != u) {
-
 
386
			if (last(u) || (bro(u) == t && last(bro(u)))) {
501
 ***********************************************************************/
387
				(*op)(sha, mw(u, 0), qw, dest);
-
 
388
			} else {
-
 
389
				(*op)(sha, mw(u, 0), qw, qw);
-
 
390
			}
-
 
391
		}
-
 
392
		if (last(u)) {
-
 
393
			break;
-
 
394
		}
-
 
395
		u = bro(u);
-
 
396
	}
-
 
397
	retcell(qw.where_exp);
-
 
398
	cond1_set = 0;
-
 
399
	return;
-
 
400
}
-
 
401
 
502
 
402
 
503
 
403
/* process the multiply operation exp. op is the compiling procedure for
504
/* encode e, putting the result into dest.
404
   the operation. It is commutative and associative, the operation takes a
-
 
405
   variable number of arguments. It is therefore necessary to avoid the mistake
-
 
406
   of assigning to the destination (dest) inappropriately if its value is used
-
 
407
   in the expression. At most one of the arguments will not be a possible 80386
-
 
408
   operand. If there is such an argument, it is precomputed, putting the value
-
 
409
   into reg0. */
505
   stack is the current stack level */
410
static void
506
void codec
411
multop(void(*op)(shape, where, where, where), exp e, where dest, ash stack)
507
(where dest, ash stack, exp e)
412
{
508
{
-
 
509
  switch (name(e)) {
-
 
510
    case plus_tag:
-
 
511
      {				/* at most one of the arguments will not
-
 
512
				   be a possible 80386 operand */
413
	exp arg1 = son(e);
513
	exp arg1 = son(e);
414
	exp arg2 = bro(arg1);
514
	exp arg2 = bro(arg1);
415
	exp t, u;
515
	exp t, u, v;
416
	where qw;
516
	where qw;
-
 
517
	exp old_overflow_e = overflow_e;
417
 
518
 
418
	if (last(arg1)) {
519
	if (last (arg1)) {	/* there is only one argument */
419
		coder(dest, stack, arg1);
520
	  coder(dest, stack, arg1);
420
		return;
521
	  return;
421
	}
522
	};
-
 
523
 
-
 
524
	if (!optop(e))
-
 
525
          overflow_e = e;
422
 
526
 
-
 
527
	if (last(arg2) && is_o(name(arg1)) && !is_crc(arg1) &&
-
 
528
	   ((is_o(name(arg2)) && !is_crc(arg2)) ||
-
 
529
	     (name(arg2) == neg_tag &&
-
 
530
	       !is_crc(son(arg2)) &&
-
 
531
	       is_o(name(son(arg2)))))) {
423
	/* just two arguments. */
532
	  /* just two arguments. */
424
	if (last (arg2)) {
533
	  addsub(sh(e), mw(arg2, 0), mw(arg1, 0), dest, e);
425
		bop(op, sh(e), arg1, arg2, dest, stack);
534
          overflow_e = old_overflow_e;
426
		return;
535
	  return;
427
	}
536
	};
428
	/* need to take care about overlap between dest and args or to avoid
537
	/* need to take care about overlap between dest and args or to
429
	   extra push. So use reg0. */
538
	   avoid extra push. So use reg0. */
-
 
539
	t = arg1;
430
	qw.where_exp = copyexp(reg0.where_exp);
540
	qw.where_exp = copyexp(reg0.where_exp);
431
	sh(qw.where_exp) = sh(e);
541
	sh(qw.where_exp) = sh(e);
432
	qw.where_off = 0;
542
	qw.where_off = 0;
433
	t = arg1;
543
 
434
	/* now look for an argument which is not a possible 80386 operand */
544
	/* now look for argument which is not a possible 80386 operand */
435
	while (1) {
545
	while (1) {
436
		if (!is_o(name(t)) || is_crc(t)) {
546
	  if ((!is_o(name(t)) || is_crc(t)) &&
-
 
547
	     (name(t)!= neg_tag || !is_o(name(son(t))) ||
-
 
548
	       is_crc(son(t))))
437
			break;
549
	    break;
438
		}
-
 
439
		if (last(t)) {
550
	  if (last(t)) {
440
			t = nilexp;
551
	    t = nilexp;
441
			break;
552
	    break;
442
		}
553
	  };
443
		t = bro(t);
554
	  t = bro(t);
444
	}
555
	};
445
 
556
 
-
 
557
	if (t == nilexp && name(arg1) == neg_tag &&
-
 
558
	    name(arg2) == neg_tag)
-
 
559
	  t = arg1;
-
 
560
 
446
	/* all arguments are possible 80386 operands */
561
	if (t == nilexp) {	/* all arguments are possible 80386
-
 
562
				   operands */
447
	if (t == nilexp) {
563
	  t = bro(arg2);
-
 
564
	  if (name(arg1) == neg_tag)
448
		(*op)(sh(e), mw(arg1, 0), mw(arg2, 0), qw);
565
	    addsub(sh(e), mw(arg1, 0), mw(arg2, 0),
-
 
566
		(t == e)? dest : qw, e);
-
 
567
	  else
-
 
568
	    addsub(sh(e), mw(arg2, 0), mw(arg1, 0),
-
 
569
		(t == e)? dest : qw, e);
-
 
570
	  if (t == e)
-
 
571
           {
-
 
572
             overflow_e = old_overflow_e;
449
		t = bro(arg2);
573
	     return;
-
 
574
           };
450
		while (!last(t)) {
575
	  while (!last(t)) {
451
			/* encode operations in turn */
576
	    u = bro(t);
452
			(*op) (sh (e), mw (t, 0), qw, qw);
577
	    addsub(sh(e), mw(t, 0), qw, qw, e);
453
			t = bro(t);
578
	    t = u;
454
		}
579
	  };
455
		/* encode final operation */
-
 
456
		(*op) (sh (e), mw (t, 0), qw, dest);
580
	  addsub(sh(e), mw(t, 0), qw, dest, e);
457
		retcell(qw.where_exp);
581
          overflow_e = old_overflow_e;
458
		cond1_set = 0;
-
 
459
		return;
582
	  return;
460
	}
583
	};
461
 
584
 
462
	/* encode the single argument which is not a possible 80386 operend */
585
	coder (qw, stack, t);	/* encode the argument which is not a
463
	coder (qw, stack, t);
586
				   possible 80386 operand */
464
	u = arg1;
587
	u = arg1;
465
	/* now encode the remaining operations */
588
	/* now encode the remaining operations */
466
	while (1) {
589
	while (1) {
-
 
590
	  v = bro(u);
467
		if (t != u) {
591
	  if (t != u) {
468
			if (last(u) || (bro(u) == t && last(bro(u)))) {
592
	    if (last(u) || (v == t && last(v)))
469
				(*op)(sh(e), mw(u, 0), qw, dest);
593
	      addsub(sh(e), mw(u, 0), qw, dest, e);
470
			} else {
594
	    else
471
				(*op)(sh(e), mw(u, 0), qw, qw);
595
	      addsub(sh(e), mw(u, 0), qw, qw, e);
472
			}
596
	  };
473
		}
-
 
474
		if (last(u)) {
597
	  if (last(u))
475
			break;
598
	    break;
476
		}
-
 
477
		u = bro(u);
599
	  u = v;
478
	}
600
	};
479
	retcell(qw.where_exp);
601
	retcell(qw.where_exp);
480
	cond1_set = 0;
602
        cond1_set = 0;
-
 
603
        overflow_e = old_overflow_e;
-
 
604
	return;
-
 
605
      };
-
 
606
    case addptr_tag: {		/* use index operation */
-
 
607
	mova(mw(e, 0), dest);
-
 
608
	return;
-
 
609
      };
-
 
610
    case chvar_tag: {
-
 
611
	exp a = son(e);
-
 
612
	exp old_overflow_e = overflow_e;
-
 
613
        if (!optop(e))
-
 
614
          overflow_e = e;
-
 
615
	if (!is_o(name(a)) || is_crc(a)) {
-
 
616
				/* argument is not a possible 80386
-
 
617
				   operand, so evaluate it in reg0 */
-
 
618
	  if (inmem(dest) ||
-
 
619
		(shape_size(sh(a)) == 8 && bad_from_reg(dest)) ||
-
 
620
		shape_size(sh(a)) == 64) {
-
 
621
	    where qw;
-
 
622
	    qw.where_exp = copyexp(reg0.where_exp);
-
 
623
	    sh(qw.where_exp) = sh(a);
-
 
624
	    qw.where_off = 0;
-
 
625
	    coder(qw, stack, a);
-
 
626
	    change_var_check(sh(e), qw, dest);
-
 
627
	    overflow_e = old_overflow_e;
-
 
628
	    retcell(qw.where_exp);
-
 
629
            cond1_set = 0;
-
 
630
	    return;
-
 
631
	  };
-
 
632
	  coder(dest, stack, a);
-
 
633
	  if (name(sh(e)) > name(sh(a)))
-
 
634
	    change_var_sh(sh(e), sh(a), dest, dest);
-
 
635
	  overflow_e = old_overflow_e;
-
 
636
	  return;
-
 
637
	};
-
 
638
	change_var_check(sh(e), mw(a, 0), dest);
-
 
639
	overflow_e = old_overflow_e;
-
 
640
	return;
-
 
641
      };
-
 
642
    case minus_tag:
-
 
643
      {
-
 
644
	exp old_overflow_e = overflow_e;
-
 
645
        if (!optop(e))
-
 
646
          overflow_e = e;
-
 
647
	bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
-
 
648
	overflow_e = old_overflow_e;
-
 
649
	return;
-
 
650
      };
-
 
651
    case subptr_tag:
-
 
652
    case minptr_tag:
-
 
653
    case make_stack_limit_tag:
-
 
654
      {
-
 
655
	bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
-
 
656
	return;
-
 
657
      };
-
 
658
    case mult_tag:
-
 
659
      {
-
 
660
        if (!optop(e))
-
 
661
          {
-
 
662
	    exp old_overflow_e = overflow_e;
-
 
663
            overflow_e = e;
-
 
664
	    multop(multiply, e, dest, stack);
-
 
665
            overflow_e = old_overflow_e;
-
 
666
          }
-
 
667
        else
-
 
668
	  multop(mult, e, dest, stack);
-
 
669
	return;
-
 
670
      };
-
 
671
    case div2_tag:
-
 
672
      {
-
 
673
	exp old_overflow_e = overflow_e;
-
 
674
        if (errhandle(e))
-
 
675
          overflow_e = e;
-
 
676
	bop(div2, sh(e), bro(son(e)), son(e), dest, stack);
-
 
677
	overflow_e = old_overflow_e;
-
 
678
	return;
-
 
679
      };
-
 
680
    case div1_tag:
-
 
681
      {
-
 
682
	exp old_overflow_e = overflow_e;
-
 
683
        if (errhandle(e))
-
 
684
          overflow_e = e;
-
 
685
	bop(div1, sh(e), bro(son(e)), son(e), dest, stack);
-
 
686
	overflow_e = old_overflow_e;
-
 
687
	return;
-
 
688
      };
-
 
689
    case div0_tag:
-
 
690
      {
-
 
691
	exp old_overflow_e = overflow_e;
-
 
692
        if (errhandle(e))
-
 
693
          overflow_e = e;
-
 
694
	bop(div0, sh(e), bro(son(e)), son(e), dest, stack);
-
 
695
	overflow_e = old_overflow_e;
-
 
696
	return;
-
 
697
      };
-
 
698
    case neg_tag:
-
 
699
      {
-
 
700
	exp old_overflow_e = overflow_e;
-
 
701
        if (!optop(e))
-
 
702
          overflow_e = e;
-
 
703
	uop(negate, sh(e), son(e), dest, stack);
-
 
704
	overflow_e = old_overflow_e;
-
 
705
	return;
-
 
706
      };
-
 
707
    case shl_tag:
-
 
708
      {
-
 
709
	exp old_overflow_e = overflow_e;
-
 
710
	overflow_e = e;
-
 
711
        if (!optop(e))
-
 
712
          overflow_e = e;
-
 
713
	bop(shiftl, sh(e), bro(son(e)), son(e), dest, stack);
-
 
714
	overflow_e = old_overflow_e;
-
 
715
	return;
-
 
716
      };
-
 
717
    case shr_tag:
-
 
718
      {
-
 
719
	bop(shiftr, sh(e), bro(son(e)), son(e), dest, stack);
-
 
720
	return;
-
 
721
      };
-
 
722
    case rotl_tag:
-
 
723
      {
-
 
724
	bop(rotatel, sh(e), bro(son(e)), son(e), dest, stack);
481
	return;
725
	return;
482
}
726
      };
483
 
-
 
484
 
-
 
485
/* if a is a negation form b-son(a) otherwise b+a in dest */
727
    case rotr_tag:
486
static void
728
      {
487
addsub(shape sha, where a, where b, where dest, exp e)
729
	bop(rotater, sh(e), bro(son(e)), son(e), dest, stack);
488
{
730
	return;
489
	UNUSED(e);
731
      };
-
 
732
    case mod_tag:
-
 
733
      {
490
	if (name(a.where_exp) == neg_tag) {
734
	exp old_overflow_e = overflow_e;
491
		sub(sha, mw(son(a.where_exp), 0), b, dest);
735
        if (errhandle(e))
492
	} else {
736
          overflow_e = e;
-
 
737
	bop(mod, sh(e), bro(son(e)), son(e), dest, stack);
493
		add(sha, a, b, dest);
738
	overflow_e = old_overflow_e;
494
	}
-
 
495
	return;
739
	return;
496
}
-
 
497
 
-
 
498
 
-
 
499
/***********************************************************************
-
 
500
   codec outputs the code which evaulates e and puts the result into
-
 
501
   dest.
740
      };
502
 ***********************************************************************/
-
 
503
 
-
 
504
/* encode e, putting the result into dest.  stack is the current stack level */
-
 
505
void
-
 
506
codec(where dest, ash stack, exp e)
-
 
507
{
-
 
508
	switch (name(e)) {
-
 
509
	case plus_tag: {
-
 
510
		/* at most one of the arguments will not be a possible 80386
-
 
511
		 * operand */
-
 
512
		exp arg1 = son(e);
-
 
513
		exp arg2 = bro(arg1);
-
 
514
		exp t, u, v;
-
 
515
		where qw;
-
 
516
		exp old_overflow_e = overflow_e;
-
 
517
 
-
 
518
		if (last (arg1)) {
-
 
519
			/* there is only one argument */
-
 
520
			coder(dest, stack, arg1);
-
 
521
			return;
-
 
522
		}
-
 
523
 
-
 
524
		if (!optop(e)) {
-
 
525
			overflow_e = e;
-
 
526
		}
-
 
527
 
-
 
528
		if (last(arg2) && is_o(name(arg1)) && !is_crc(arg1) &&
-
 
529
		    ((is_o(name(arg2)) && !is_crc(arg2)) ||
-
 
530
		     (name(arg2) == neg_tag && !is_crc(son(arg2)) &&
-
 
531
		      is_o(name(son(arg2)))))) {
-
 
532
			/* just two arguments. */
-
 
533
			addsub(sh(e), mw(arg2, 0), mw(arg1, 0), dest, e);
-
 
534
			overflow_e = old_overflow_e;
-
 
535
			return;
-
 
536
		}
-
 
537
		/* need to take care about overlap between dest and
-
 
538
		 * args or to avoid extra push. So use reg0. */
-
 
539
		t = arg1;
-
 
540
		qw.where_exp = copyexp(reg0.where_exp);
-
 
541
		sh(qw.where_exp) = sh(e);
-
 
542
		qw.where_off = 0;
-
 
543
 
-
 
544
		/* now look for argument which is not a possible 80386
-
 
545
		 * operand */
-
 
546
		while (1) {
-
 
547
			if ((!is_o(name(t)) || is_crc(t)) &&
-
 
548
			    (name(t) != neg_tag || !is_o(name(son(t))) ||
-
 
549
			     is_crc(son(t)))) {
-
 
550
				break;
-
 
551
			}
-
 
552
			if (last(t)) {
-
 
553
				t = nilexp;
-
 
554
				break;
-
 
555
			}
-
 
556
			t = bro(t);
-
 
557
		}
-
 
558
 
-
 
559
		if (t == nilexp && name(arg1) == neg_tag &&
-
 
560
		    name(arg2) == neg_tag) {
-
 
561
			t = arg1;
-
 
562
		}
-
 
563
 
-
 
564
		/* all arguments are possible 80386 operands */
-
 
565
		if (t == nilexp) {
-
 
566
			t = bro(arg2);
-
 
567
			if (name(arg1) == neg_tag) {
-
 
568
				addsub(sh(e), mw(arg1, 0), mw(arg2, 0),
-
 
569
				       (t == e) ? dest : qw, e);
-
 
570
			} else {
-
 
571
				addsub(sh(e), mw(arg2, 0), mw(arg1, 0),
-
 
572
				       (t == e) ? dest : qw, e);
-
 
573
			}
-
 
574
			if (t == e) {
-
 
575
				overflow_e = old_overflow_e;
-
 
576
				return;
-
 
577
			}
-
 
578
			while (!last(t)) {
-
 
579
				u = bro(t);
-
 
580
				addsub(sh(e), mw(t, 0), qw, qw, e);
-
 
581
				t = u;
-
 
582
			}
-
 
583
			addsub(sh(e), mw(t, 0), qw, dest, e);
-
 
584
			overflow_e = old_overflow_e;
-
 
585
			return;
-
 
586
		}
-
 
587
 
-
 
588
		/* encode the argument which is not a possible 80386
-
 
589
		 * operand */
-
 
590
		coder (qw, stack, t);
-
 
591
		u = arg1;
-
 
592
		/* now encode the remaining operations */
-
 
593
		while (1) {
-
 
594
			v = bro(u);
-
 
595
			if (t != u) {
-
 
596
				if (last(u) || (v == t && last(v))) {
-
 
597
					addsub(sh(e), mw(u, 0), qw, dest, e);
-
 
598
				} else {
-
 
599
					addsub(sh(e), mw(u, 0), qw, qw, e);
-
 
600
				}
-
 
601
			}
-
 
602
			if (last(u)) {
-
 
603
				break;
-
 
604
			}
-
 
605
			u = v;
-
 
606
		}
-
 
607
		retcell(qw.where_exp);
-
 
608
		cond1_set = 0;
-
 
609
		overflow_e = old_overflow_e;
-
 
610
		return;
-
 
611
	}
-
 
612
	case addptr_tag:
741
    case rem2_tag:
613
		/* use index operation */
-
 
614
		mova(mw(e, 0), dest);
-
 
615
		return;
-
 
616
	case chvar_tag: {
-
 
617
		exp a = son(e);
-
 
618
		exp old_overflow_e = overflow_e;
-
 
619
		if (!optop(e)) {
-
 
620
			overflow_e = e;
-
 
621
		}
-
 
622
		if (!is_o(name(a)) || is_crc(a)) {
-
 
623
			/* argument is not a possible 80386 operand, so
-
 
624
			 * evaluate it in reg0 */
-
 
625
			if (inmem(dest) ||
-
 
626
			    (shape_size(sh(a)) == 8 && bad_from_reg(dest)) ||
-
 
627
			    shape_size(sh(a)) == 64) {
-
 
628
				where qw;
-
 
629
				qw.where_exp = copyexp(reg0.where_exp);
-
 
630
				sh(qw.where_exp) = sh(a);
-
 
631
				qw.where_off = 0;
-
 
632
				coder(qw, stack, a);
-
 
633
				change_var_check(sh(e), qw, dest);
-
 
634
				overflow_e = old_overflow_e;
-
 
635
				retcell(qw.where_exp);
-
 
636
				cond1_set = 0;
-
 
637
				return;
-
 
638
			}
-
 
639
			coder(dest, stack, a);
-
 
640
			if (name(sh(e)) > name(sh(a)))
-
 
641
				change_var_sh(sh(e), sh(a), dest, dest);
-
 
642
			overflow_e = old_overflow_e;
-
 
643
			return;
-
 
644
		}
-
 
645
		change_var_check(sh(e), mw(a, 0), dest);
-
 
646
		overflow_e = old_overflow_e;
-
 
647
		return;
-
 
648
	}
-
 
649
	case minus_tag: {
-
 
650
		exp old_overflow_e = overflow_e;
-
 
651
		if (!optop(e)) {
-
 
652
			overflow_e = e;
-
 
653
		}
-
 
654
		bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
-
 
655
		overflow_e = old_overflow_e;
-
 
656
		return;
-
 
657
	}
-
 
658
	case subptr_tag:
-
 
659
	case minptr_tag:
-
 
660
	case make_stack_limit_tag:
-
 
661
		bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
-
 
662
		return;
-
 
663
	case mult_tag: {
-
 
664
		if (!optop(e)) {
-
 
665
			exp old_overflow_e = overflow_e;
-
 
666
			overflow_e = e;
-
 
667
			multop(multiply, e, dest, stack);
-
 
668
			overflow_e = old_overflow_e;
-
 
669
		} else {
742
      {
670
			multop(mult, e, dest, stack);
-
 
671
		}
-
 
672
		return;
-
 
673
	}
-
 
674
	case div2_tag: {
-
 
675
		exp old_overflow_e = overflow_e;
743
	exp old_overflow_e = overflow_e;
676
		if (errhandle(e)) {
744
        if (errhandle(e))
677
			overflow_e = e;
745
          overflow_e = e;
678
		}
-
 
679
		bop(div2, sh(e), bro(son(e)), son(e), dest, stack);
746
	bop(rem2, sh(e), bro(son(e)), son(e), dest, stack);
680
		overflow_e = old_overflow_e;
-
 
681
		return;
-
 
682
	}
-
 
683
	case div1_tag: {
-
 
684
		exp old_overflow_e = overflow_e;
-
 
685
		if (errhandle(e)) {
-
 
686
			overflow_e = e;
-
 
687
		}
-
 
688
		bop(div1, sh(e), bro(son(e)), son(e), dest, stack);
-
 
689
		overflow_e = old_overflow_e;
-
 
690
		return;
-
 
691
	}
-
 
692
	case div0_tag: {
-
 
693
		exp old_overflow_e = overflow_e;
-
 
694
		if (errhandle(e)) {
-
 
695
			overflow_e = e;
-
 
696
		}
-
 
697
		bop(div0, sh(e), bro(son(e)), son(e), dest, stack);
-
 
698
		overflow_e = old_overflow_e;
-
 
699
		return;
-
 
700
	}
-
 
701
	case neg_tag: {
-
 
702
		exp old_overflow_e = overflow_e;
-
 
703
		if (!optop(e)) {
-
 
704
			overflow_e = e;
-
 
705
		}
-
 
706
		uop(negate, sh(e), son(e), dest, stack);
-
 
707
		overflow_e = old_overflow_e;
-
 
708
		return;
-
 
709
	}
-
 
710
	case shl_tag: {
-
 
711
		exp old_overflow_e = overflow_e;
-
 
712
		overflow_e = e;
-
 
713
		if (!optop(e)) {
-
 
714
			overflow_e = e;
-
 
715
		}
-
 
716
		bop(shiftl, sh(e), bro(son(e)), son(e), dest, stack);
-
 
717
		overflow_e = old_overflow_e;
747
	overflow_e = old_overflow_e;
718
		return;
-
 
719
	}
-
 
720
	case shr_tag:
-
 
721
		bop(shiftr, sh(e), bro(son(e)), son(e), dest, stack);
-
 
722
		return;
748
	return;
723
	case rotl_tag:
-
 
724
		bop(rotatel, sh(e), bro(son(e)), son(e), dest, stack);
-
 
725
		return;
749
      };
726
	case rotr_tag:
750
    case rem0_tag:
727
		bop(rotater, sh(e), bro(son(e)), son(e), dest, stack);
-
 
728
		return;
751
      {
729
	case mod_tag: {
-
 
730
		exp old_overflow_e = overflow_e;
752
	exp old_overflow_e = overflow_e;
731
		if (errhandle(e)) {
753
        if (errhandle(e))
732
			overflow_e = e;
754
          overflow_e = e;
733
		}
-
 
734
		bop(mod, sh(e), bro(son(e)), son(e), dest, stack);
755
	bop(rem0, sh(e), bro(son(e)), son(e), dest, stack);
735
		overflow_e = old_overflow_e;
756
	overflow_e = old_overflow_e;
736
		return;
757
	return;
737
	}
-
 
738
	case rem2_tag: {
-
 
739
		exp old_overflow_e = overflow_e;
-
 
740
		if (errhandle(e)) {
-
 
741
			overflow_e = e;
-
 
742
		}
-
 
743
		bop(rem2, sh(e), bro(son(e)), son(e), dest, stack);
-
 
744
		overflow_e = old_overflow_e;
-
 
745
		return;
758
      };
746
	}
-
 
747
	case rem0_tag: {
759
    case round_tag:
748
		exp old_overflow_e = overflow_e;
-
 
749
		if (errhandle(e)) {
-
 
750
			overflow_e = e;
-
 
751
		}
-
 
752
		bop(rem0, sh(e), bro(son(e)), son(e), dest, stack);
-
 
753
		overflow_e = old_overflow_e;
-
 
754
		return;
760
      {
755
	}
-
 
756
	case round_tag: {
-
 
757
		shape s = sh(e);
761
	shape s = sh(e);
758
		where d;
762
	where d;
759
		d = dest;
763
	d = dest;
760
		if (shape_size(s) < 32) {
764
	if (shape_size(s) < 32) {
761
			s = slongsh;
765
	  s = slongsh;
762
			if (inmem(dest)) {
766
	  if (inmem(dest))
763
				d = reg0;
767
	    d = reg0;
764
			}
-
 
765
		}
-
 
766
		setup_fl_ovfl(e);
-
 
767
		switch (round_number(e)) {
-
 
768
		case 0:
-
 
769
			uop(frnd0, s, son(e), d, stack);
-
 
770
			break;
-
 
771
		case 1:
-
 
772
			uop(frnd1, s, son(e), d, stack);
-
 
773
			break;
-
 
774
		case 2:
-
 
775
			uop(frnd2, s, son(e), d, stack);
-
 
776
			break;
-
 
777
		case 3:
-
 
778
			uop(frnd3, s, son(e), d, stack);
-
 
779
			break;
-
 
780
		case 4:
-
 
781
			uop(frnd4, s, son(e), d, stack);
-
 
782
			break;
-
 
783
		}
-
 
784
		test_fl_ovfl(e, d);
-
 
785
		if (name(s) != name(sh(e))) {
-
 
786
			exp old_overflow_e = overflow_e;
-
 
787
			if (!optop(e)) {
-
 
788
				overflow_e = e;
-
 
789
			}
-
 
790
			change_var_sh(sh(e), s, d, dest);
-
 
791
			overflow_e = old_overflow_e;
-
 
792
		}
-
 
793
		return;
-
 
794
	}
768
	}
795
	case fplus_tag:
-
 
796
		setup_fl_ovfl(e);
769
        setup_fl_ovfl(e);
797
		fl_multop(fplus_tag, sh(e), son(e), dest);
-
 
798
		test_fl_ovfl(e, dest);
-
 
799
		return;
-
 
800
	case fmult_tag:
-
 
801
		setup_fl_ovfl(e);
-
 
802
		fl_multop(fmult_tag, sh(e), son(e), dest);
-
 
803
		test_fl_ovfl(e, dest);
-
 
804
		return;
-
 
805
	case fminus_tag:
-
 
806
		setup_fl_ovfl(e);
-
 
807
		fl_binop(fminus_tag, sh(e), mw(bro(son(e)), 0), mw(son(e), 0),
-
 
808
			 dest, bro(son(e)));
-
 
809
		test_fl_ovfl(e, dest);
-
 
810
		return;
-
 
811
	case fdiv_tag:
-
 
812
		setup_fl_ovfl(e);
-
 
813
		fl_binop(fdiv_tag, sh(e), mw(bro(son(e)), 0), mw(son(e), 0),
-
 
814
			 dest, bro(son(e)));
770
	switch (round_number(e)) {
815
		test_fl_ovfl(e, dest);
-
 
816
		return;
-
 
817
	case fneg_tag:
-
 
818
		setup_fl_ovfl(e);
-
 
819
		fl_neg(sh(e), mw(son(e), 0), dest);
-
 
820
		test_fl_ovfl(e, dest);
-
 
821
		return;
-
 
822
	case fabs_tag:
771
	  case 0:
823
		setup_fl_ovfl(e);
-
 
824
		fl_abs(sh(e), mw(son(e), 0), dest);
-
 
825
		test_fl_ovfl(e, dest);
-
 
826
		return;
-
 
827
	case float_tag:
-
 
828
		setup_fl_ovfl(e);
-
 
829
		floater(sh(e), mw(son(e), 0), dest);
772
		uop(frnd0, s, son(e), d, stack);
830
		test_fl_ovfl(e, dest);
-
 
831
		return;
-
 
832
	case chfl_tag:
-
 
833
		if (name(sh(e)) < name(sh(son(e)))) {
-
 
834
			setup_fl_ovfl(e);
-
 
835
		}
-
 
836
		changefl(sh(e), mw(son(e), 0), dest);
-
 
837
		if (name(sh(e)) < name(sh(son(e)))) {
-
 
838
			test_fl_ovfl(e, dest);
-
 
839
		}
-
 
840
		return;
773
		break;
841
	case and_tag:
774
	  case 1:
842
		logop(and, e, dest, stack);
775
		uop(frnd1, s, son(e), d, stack);
843
		return;
776
		break;
844
	case or_tag:
777
	  case 2:
845
		logop(or, e, dest, stack);
778
		uop(frnd2, s, son(e), d, stack);
846
		return;
779
		break;
847
	case xor_tag:
780
	  case 3:
848
		logop(xor, e, dest, stack);
781
		uop(frnd3, s, son(e), d, stack);
849
		return;
782
		break;
850
	case not_tag:
783
	  case 4:
851
		uop(not, sh(e), son(e), dest, stack);
784
		uop(frnd4, s, son(e), d, stack);
852
		return;
785
		break;
853
	case offset_pad_tag:
-
 
854
		if (al2(sh(son(e))) >= al2(sh(e))) {
-
 
855
			if (al2(sh(e)) != 1 || al2(sh(son(e))) == 1) {
-
 
856
				coder(dest, stack, son(e));
-
 
857
			} else {
-
 
858
				coder(reg0, stack, son(e));
-
 
859
				shiftl(slongsh, mw(zeroe, 3), reg0, dest);
-
 
860
			}
786
	};
861
		} else {
-
 
862
			int al = al2(sh(e)) /8;
787
        test_fl_ovfl(e, d);
863
			coder(reg0, stack, son(e));
-
 
864
			if (al2(sh(son(e))) == 1) {
788
	if (name(s)!= name(sh(e))) {
865
				add(slongsh, mw(zeroe, al*8 -1), reg0, reg0);
-
 
866
				shiftr(slongsh, mw(zeroe, 3), reg0, reg0);
-
 
867
			} else {
-
 
868
				add(slongsh, mw(zeroe, al-1), reg0, reg0);
-
 
869
			}
-
 
870
			and(slongsh, mw(zeroe, -al), reg0, dest);
-
 
871
		}
-
 
872
		return;
-
 
873
	case offset_add_tag:
-
 
874
		bop(add, sh(e), son(e), bro(son(e)), dest, stack);
-
 
875
		return;
-
 
876
	case abs_tag: {
-
 
877
		exp old_overflow_e = overflow_e;
789
	  exp old_overflow_e = overflow_e;
878
		if (!optop(e)) {
790
          if (!optop(e))
879
			overflow_e = e;
791
            overflow_e = e;
880
		}
-
 
881
		uop(absop, sh(e), son(e), dest, stack);
792
	  change_var_sh(sh(e), s, d, dest);
882
		overflow_e = old_overflow_e;
793
	  overflow_e = old_overflow_e;
883
		return;
-
 
884
	}
794
	}
1016
 
1052
 
-
 
1053
	/* other values */
1017
 
1054
 
1018
		/* other values */
-
 
1019
 
-
 
1020
		if (name(e) != top_tag && name(e) != prof_tag) {
1055
	if (name(e)!= top_tag && name(e)!= prof_tag)
1021
			move(sh(e), mw(e, 0), dest);
1056
	  move(sh(e), mw(e, 0), dest);
1022
		} else {
1057
	else
1023
			top_regsinuse = regsinuse;
1058
	  top_regsinuse = regsinuse;
1024
		}
1059
	return;
1025
		return;
1060
      };
1026
	}
1061
  };
1027
}
1062
}