diff -c c68III/intexpr.c c68III.1/intexpr.c
*** c68III/intexpr.c	Mon Feb  4 19:58:36 1991
--- c68III.1/intexpr.c	Fri Mar  1 10:50:00 1991
***************
*** 29,54 ****
  
  double
  floatexpr()
! /* simple floating point number */
  {
! #ifndef NOFLOAT
!     double          temp;
!     int             sign = 0;
!     if (lastst == minus) {
! 	sign = 1;
! 	getsym();
!     }
!     if (lastst != rconst && lastst != iconst)
  	error(ERR_FPCON);
!     if (lastst == iconst)
! 	temp = (double) ival;
!     else
! 	temp = rval;
!     getsym();
!     if (sign)
! 	temp = -temp;
!     return temp;
! #endif
  }
  
  long
--- 29,55 ----
  
  double
  floatexpr()
! /* floating point expression */
  {
!     struct enode   *ep;
!     struct typ     *tp;
! 
!     tp = exprnc(&ep);
!     if (tp == 0) {
  	error(ERR_FPCON);
! 	return (double) 0;
!     }
! 
!     opt4(&ep);
! 
!     if (ep->nodetype == en_icon)
!         return (double) ep->v.i;
! 
!     if (ep->nodetype == en_fcon)
!         return ep->v.f;
! 
!     error (ERR_SYNTAX);
!     return (double) 0;
  }
  
  long
***************
*** 62,68 ****
  	error(ERR_INTEXPR);
  	return 0;
      }
!     opt0(&ep);
  
      if (ep->nodetype != en_icon) {
  	error(ERR_SYNTAX);
--- 63,69 ----
  	error(ERR_INTEXPR);
  	return 0;
      }
!     opt4(&ep);
  
      if (ep->nodetype != en_icon) {
  	error(ERR_SYNTAX);
diff -c c68III/optimize.c c68III.1/optimize.c
*** c68III/optimize.c	Mon Feb  4 19:58:39 1991
--- c68III.1/optimize.c	Fri Mar  1 10:50:03 1991
***************
*** 39,109 ****
      struct enode   *ep = *node;
      enum e_node     type = ep->nodetype;
  
!     ep->nodetype = en_icon;
!     switch (type) {
!       case en_add:
! 	ep->v.i = ep->v.p[0]->v.i + ep->v.p[1]->v.i;
! 	break;
!       case en_sub:
! 	ep->v.i = ep->v.p[0]->v.i - ep->v.p[1]->v.i;
! 	break;
!       case en_mul:
! 	ep->v.i = ep->v.p[0]->v.i * ep->v.p[1]->v.i;
! 	break;
!       case en_div:
! 	if (ep->v.p[1]->v.i == 0) {
! 	    fprintf(stderr, "division by zero in constant node\n");
! 	    ep->nodetype = en_div;
! 	} else {
! 	    ep->v.i = ep->v.p[0]->v.i / ep->v.p[1]->v.i;
! 	}
! 	break;
!       case en_mod:
! 	if (ep->v.p[1]->v.i == 0) {
! 	    fprintf(stderr, "mod by zero in constant node\n");
! 	    ep->nodetype = en_mod;
! 	} else {
! 	    ep->v.i = ep->v.p[0]->v.i % ep->v.p[1]->v.i;
! 	}
! 	break;
!       case en_lsh:
! 	ep->v.i = ep->v.p[0]->v.i << ep->v.p[1]->v.i;
! 	break;
!       case en_rsh:
! 	ep->v.i = ep->v.p[0]->v.i >> ep->v.p[1]->v.i;
! 	break;
!       case en_and:
! 	ep->v.i = ep->v.p[0]->v.i & ep->v.p[1]->v.i;
! 	break;
!       case en_or:
! 	ep->v.i = ep->v.p[0]->v.i | ep->v.p[1]->v.i;
! 	break;
!       case en_xor:
! 	ep->v.i = ep->v.p[0]->v.i ^ ep->v.p[1]->v.i;
! 	break;
!       case en_eq:
! 	ep->v.i = ep->v.p[0]->v.i == ep->v.p[1]->v.i;
! 	break;
!       case en_ne:
! 	ep->v.i = ep->v.p[0]->v.i != ep->v.p[1]->v.i;
! 	break;
!       case en_uminus:
! 	ep->v.i = -ep->v.p[0]->v.i;
! 	break;
!       case en_compl:
! 	ep->v.i = ~ep->v.p[0]->v.i;
! /*
!  * This prevents, e.g. ~0x8000 to be 0xFFFF7FFF in 16-bit mode
!  * (it should be 0x7FFF in this case
!  */
!         ep->v.i = strip_icon(ep->v.i, ep->etype);
! 	break;
!       case en_not:
! 	ep->v.i = !ep->v.p[0]->v.i;
! 	break;
!       default:
! 	fatal("DOOPER");
      }
  }
  
  int
--- 39,291 ----
      struct enode   *ep = *node;
      enum e_node     type = ep->nodetype;
  
! #define ep0 ep->v.p[0]
! #define ep1 ep->v.p[1]
! #define epi ep->v.i
! #define epf ep->v.f
! #define ulong unsigned long
! 
!     ep->nodetype = ep0->nodetype;
!     if (ep0->nodetype == en_fcon) {
!         switch (type) {
!           case en_uminus:
!             epf = - ep0->v.f;
!             break;
!           case en_not:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f) ? 0 : 1;
!             break;
!           case en_add:
!             epf = ep0->v.f + ep1->v.f;
!             break;
!           case en_sub:
!             epf = ep0->v.f - ep1->v.f;
!             break;
!           case en_mul:
!             epf = ep0->v.f * ep1->v.f;
!             break;
!           case en_div:
! 	    if (ep1->v.f == 0.0) {
! 	        fprintf(stderr, "division by zero in constant node\n");
! 	        ep->nodetype = en_div;
! 	    } else {
! 	        epf = ep0->v.f / ep1->v.f;
! 	    }
!             break;
!           case en_eq:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f == ep1->v.f) ? 1 : 0;
!             break;
!           case en_ne:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f != ep1->v.f) ? 1 : 0;
!             break;
!           case en_land:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f && ep1->v.f) ? 1 : 0;
!             break;
!           case en_lor:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f || ep1->v.f) ? 1 : 0;
!             break;
!           case en_lt:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f < ep1->v.f) ? 1 : 0;
!             break;
!           case en_le:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f <= ep1->v.f) ? 1 : 0;
!             break;
!           case en_gt:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f > ep1->v.f) ? 1 : 0;
!             break;
!           case en_ge:
!             ep->nodetype = en_icon;
!             epi = (ep0->v.f >= ep1->v.f) ? 1 : 0;
!             break;
!           default:
!             ep->nodetype == type;
!             fprintf(stderr,"Illegal operation in dooper FLOAT\n");
!             break;
!         }
!         return;
      }
+     /*
+      * Thus, ep0->nodetype is en_icon
+      * We have to distinguisch unsigned long from the other cases
+      *
+      * Since we always store in ep->v.i, it is
+      * ASSUMED THAT (long) (ulong) ep->v.i == ep->v.i always
+      */
+     if (ep0->etype == bt_ulong || ep0->etype == bt_pointer) {
+         switch (type) {
+           case en_uminus:
+             epi = - (ulong) ep0->v.i;
+             break;
+           case en_not:
+             epi = ((ulong) ep0->v.i) ? 0 : 1;
+             break;
+           case en_compl:
+             epi = ~ (ulong) ep0->v.i;
+             epi = strip_icon(epi, ep->etype);
+             break;
+           case en_add:
+             epi = (ulong) ep0->v.i + (ulong) ep1->v.i;
+             break;
+           case en_sub:
+             epi = (ulong) ep0->v.i - (ulong) ep1->v.i;
+             break;
+           case en_mul:
+             epi = (ulong) ep0->v.i * (ulong) ep1->v.i;
+             break;
+           case en_div:
+ 	    if ((ulong) ep1->v.i == 0) {
+ 	        fprintf(stderr, "division by zero in constant node\n");
+ 	        ep->nodetype = en_div;
+ 	    } else {
+ 	        epi = (ulong) ep0->v.i / (ulong) ep1->v.i;
+ 	    }
+             break;
+           case en_mod:
+ 	    if ((ulong) ep1->v.i == 0) {
+ 	        fprintf(stderr, "division by zero in constant node\n");
+ 	        ep->nodetype = en_mod;
+ 	    } else {
+ 	        epi = (ulong) ep0->v.i % (ulong) ep1->v.i;
+ 	    }
+             break;
+           case en_and:
+             epi = (ulong) ep0->v.i & (ulong) ep1->v.i;
+             break;
+           case en_or:
+             epi = (ulong) ep0->v.i | (ulong) ep1->v.i;
+             break;
+           case en_xor:
+             epi = (ulong) ep0->v.i ^ (ulong) ep1->v.i;
+             break;
+           case en_eq:
+             epi = ((ulong) ep0->v.i == (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_ne:
+             epi = ((ulong) ep0->v.i != (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_land:
+             epi = ((ulong) ep0->v.i && (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_lor:
+             epi = ((ulong) ep0->v.i || (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_lt:
+             epi = ((ulong) ep0->v.i < (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_le:
+             epi = ((ulong) ep0->v.i <= (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_gt:
+             epi = ((ulong) ep0->v.i > (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_ge:
+             epi = ((ulong) ep0->v.i >= (ulong) ep1->v.i) ? 1 : 0;
+             break;
+           case en_lsh:
+             epi = (ulong) ep0->v.i << (ulong) ep1->v.i;
+             break;
+           case en_rsh:
+             epi = (ulong) ep0->v.i >> (ulong) ep1->v.i;
+             break;
+           default:
+             ep->nodetype == type;
+             fprintf(stderr,"Illegal operation in dooper ULONG\n");
+             break;
+         }
+     } else {
+         switch (type) {
+           case en_uminus:
+             epi = - ep0->v.i;
+             break;
+           case en_not:
+             epi = (ep0->v.i) ? 0 : 1;
+             break;
+           case en_compl:
+             epi = ~ ep0->v.i;
+             epi = strip_icon(epi, ep->nodetype);
+             break;
+           case en_add:
+             epi = ep0->v.i + ep1->v.i;
+             break;
+           case en_sub:
+             epi = ep0->v.i - ep1->v.i;
+             break;
+           case en_mul:
+             epi = ep0->v.i * ep1->v.i;
+             break;
+           case en_div:
+ 	    if (ep1->v.i == 0) {
+ 	        fprintf(stderr, "division by zero in constant node\n");
+ 	        ep->nodetype = en_div;
+ 	    } else {
+ 	        epi = ep0->v.i / ep1->v.i;
+ 	    }
+             break;
+           case en_mod:
+ 	    if (ep1->v.i == 0) {
+ 	        fprintf(stderr, "division by zero in constant node\n");
+ 	        ep->nodetype = en_mod;
+ 	    } else {
+ 	        epi = ep0->v.i % ep1->v.i;
+ 	    }
+             break;
+           case en_and:
+             epi = ep0->v.i & ep1->v.i;
+             break;
+           case en_or:
+             epi = ep0->v.i | ep1->v.i;
+             break;
+           case en_xor:
+             epi = ep0->v.i ^ ep1->v.i;
+             break;
+           case en_eq:
+             epi = (ep0->v.i == ep1->v.i) ? 1 : 0;
+             break;
+           case en_ne:
+             epi = (ep0->v.i != ep1->v.i) ? 1 : 0;
+             break;
+           case en_land:
+             epi = (ep0->v.i && ep1->v.i) ? 1 : 0;
+             break;
+           case en_lor:
+             epi = (ep0->v.i || ep1->v.i) ? 1 : 0;
+             break;
+           case en_lt:
+             epi = (ep0->v.i < ep1->v.i) ? 1 : 0;
+             break;
+           case en_le:
+             epi = (ep0->v.i <= ep1->v.i) ? 1 : 0;
+             break;
+           case en_gt:
+             epi = (ep0->v.i > ep1->v.i) ? 1 : 0;
+             break;
+           case en_ge:
+             epi = (ep0->v.i >= ep1->v.i) ? 1 : 0;
+             break;
+           case en_lsh:
+             epi = ep0->v.i << ep1->v.i;
+             break;
+           case en_rsh:
+             epi = ep0->v.i >> ep1->v.i;
+             break;
+           default:
+             ep->nodetype == type;
+             fprintf(stderr,"Illegal operation in dooper LONG\n");
+             break;
+         }
+     }
+ #undef ep0
+ #undef ep1
+ #undef epi
+ #undef epf
+ #undef ulong
  }
  
  int
***************
*** 144,151 ****
  /*
   * opt0 - delete useless expressions and combine constants.
   *
!  * opt0 will delete expressions such as x + 0, x - 0, x * 0, x * 1, 0 / x, x /
!  * 1, x mod 0, etc from the tree pointed to by node and combine obvious
   * constant operations. It cannot combine name and label constants but will
   * combine icon type nodes.
   */
--- 326,339 ----
  /*
   * opt0 - delete useless expressions and combine constants.
   *
!  * opt0 will delete expressions such as x + 0,
!  *  x - 0,
!  *  x * 0,
!  *  x * 1,
!  *  0 / x,
!  *  x / 1,
!  *  x mod 0,
!  *  etc from the tree pointed to by node and combine obvious
   * constant operations. It cannot combine name and label constants but will
   * combine icon type nodes.
   */
***************
*** 152,157 ****
--- 340,349 ----
      struct enode  **node;
  {
      struct enode   *ep;
+ 
+ #define ep0 ep->v.p[0]
+ #define ep1 ep->v.p[1]
+ 
      long            val, sc;
      enum e_node     typ;
      ep = *node;
***************
*** 164,300 ****
        case en_ainc:
        case en_adec:
        case en_deref:
! 	opt0(&(ep->v.p[0]));
  	break;
        case en_uminus:
        case en_not:
        case en_compl:
! 	opt0(&(ep->v.p[0]));
!         if (ep->v.p[0]->nodetype == typ) {
!             *node = ep->v.p[0]->v.p[0];
              break;
          }
! 	if (ep->v.p[0]->nodetype == en_icon)
  	    dooper(node);
  	break;
        case en_add:
        case en_sub:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
!         if (ep->v.p[1]->nodetype == en_uminus) {
!             ep->v.p[1] = ep->v.p[1]->v.p[0];
              ep->nodetype = typ = (typ == en_add) ? en_sub : en_add;
          }
!         if (ep->v.p[0]->nodetype == en_uminus && typ == en_add) {
!             ep->v.p[0] = ep->v.p[0]->v.p[0];
              swap_nodes(ep);
              ep->nodetype = typ = en_sub;
          }
  	if (typ == en_add) {
! 	    if (ep->v.p[1]->nodetype == en_autocon)
  		swap_nodes(ep);
  	}
! 	if (ep->v.p[0]->nodetype == en_icon) {
! 	    if (ep->v.p[1]->nodetype == en_icon) {
! 		dooper(node);
! 		break;
! 	    }
! 	    if (ep->v.p[0]->v.i == 0) {
  		if (typ == en_sub) {
! 		    ep->v.p[0] = ep->v.p[1];
  		    ep->nodetype = typ = en_uminus;
  		} else
! 		    *node = ep->v.p[1];
  		break;
  	    }
! 	} else if (ep->v.p[1]->nodetype == en_icon) {
! 	    if (ep->v.p[0]->nodetype == en_autocon && typ == en_add) {
! 		ep->v.p[0]->v.i += ep->v.p[1]->v.i;
! 		*node = ep->v.p[0];
  		break;
  	    }
! 	    if (ep->v.p[1]->v.i == 0) {
! 		*node = ep->v.p[0];
  		break;
  	    }
  	}
  	break;
        case en_mul:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
! 	if (ep->v.p[0]->nodetype == en_icon) {
! 	    if (ep->v.p[1]->nodetype == en_icon) {
! 		dooper(node);
! 		break;
! 	    }
! 	    val = ep->v.p[0]->v.i;
  	    if (val == 0) {
! 		*node = ep->v.p[0];
  		break;
  	    }
  	    if (val == 1) {
! 		*node = ep->v.p[1];
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
  		swap_nodes(ep);
! 		ep->v.p[1]->v.i = sc;
  		ep->nodetype = en_lsh;
  	    }
! 	} else if (ep->v.p[1]->nodetype == en_icon) {
! 	    val = ep->v.p[1]->v.i;
  	    if (val == 0) {
! 		*node = ep->v.p[1];
  		break;
  	    }
  	    if (val == 1) {
! 		*node = ep->v.p[0];
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
! 		ep->v.p[1]->v.i = sc;
  		ep->nodetype = en_lsh;
  	    }
  	}
  	break;
        case en_div:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
! 	if (ep->v.p[0]->nodetype == en_icon) {
! 	    if (ep->v.p[1]->nodetype == en_icon) {
! 		dooper(node);
  		break;
  	    }
! 	    if (ep->v.p[0]->v.i == 0) {	/* 0/x */
! 		*node = ep->v.p[0];
! 		break;
! 	    }
! 	} else if (ep->v.p[1]->nodetype == en_icon) {
! 	    val = ep->v.p[1]->v.i;
  	    if (val == 1) {	/* x/1 */
! 		*node = ep->v.p[0];
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
! 		ep->v.p[1]->v.i = sc;
  		ep->nodetype = en_rsh;
  	    }
  	}
  	break;
        case en_mod:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
! 	if (ep->v.p[1]->nodetype == en_icon) {
! 	    if (ep->v.p[0]->nodetype == en_icon) {
! 		dooper(node);
! 		break;
! 	    }
! 	    sc = pwrof2(ep->v.p[1]->v.i);
  	    if (sc != -1) {
! 		ep->v.p[1]->v.i = mod_mask(sc);
  		ep->nodetype = en_and;
  	    }
  	}
--- 356,516 ----
        case en_ainc:
        case en_adec:
        case en_deref:
! 	opt0(&ep0);
  	break;
        case en_uminus:
        case en_not:
        case en_compl:
! 	opt0(&ep0);
!         /*
!          * This operation applied twice is a no-op
!          */
!         if (ep0->nodetype == typ) {
!             *node = ep0->v.p[0];
              break;
          }
! 	if (ep0->nodetype == en_icon || ep0->nodetype == en_fcon)
  	    dooper(node);
  	break;
        case en_add:
        case en_sub:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         /*
!          *  a + (-b)  =  a - b
!          *  a - (-b)  =  a + b
!          *  (-a) + b  =  b - a
!          */
!         if (ep1->nodetype == en_uminus) {
!             ep1 = ep1->v.p[0];
              ep->nodetype = typ = (typ == en_add) ? en_sub : en_add;
          }
!         if (ep0->nodetype == en_uminus && typ == en_add) {
!             ep0 = ep0->v.p[0];
              swap_nodes(ep);
              ep->nodetype = typ = en_sub;
          }
+         /*
+          * constant expressions
+          */
+         if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) ||
+             (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon))   {
+             dooper(node);
+             break;
+         }
  	if (typ == en_add) {
! 	    if (ep1->nodetype == en_autocon)
  		swap_nodes(ep);
  	}
! 	if (ep0->nodetype == en_icon) {
! 	    if (ep0->v.i == 0) {
  		if (typ == en_sub) {
! 		    ep0 = ep1;
  		    ep->nodetype = typ = en_uminus;
  		} else
! 		    *node = ep1;
  		break;
  	    }
! 	} else if (ep1->nodetype == en_icon) {
! 	    if (ep0->nodetype == en_autocon && typ == en_add) {
! 		ep0->v.i += ep1->v.i;
! 		*node = ep0;
  		break;
  	    }
! 	    if (ep1->v.i == 0) {
! 		*node = ep0;
  		break;
  	    }
  	}
  	break;
        case en_mul:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         /*
!          * constant expressions
!          */
!         if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) ||
!             (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon))  {
!             dooper(node);
!             break;
!         }
! 	if (ep0->nodetype == en_icon) {
! 	    val = ep0->v.i;
  	    if (val == 0) {
! 		*node = ep0;
  		break;
  	    }
  	    if (val == 1) {
! 		*node = ep1;
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
  		swap_nodes(ep);
! 		ep1->v.i = sc;
  		ep->nodetype = en_lsh;
  	    }
! 	} else if (ep1->nodetype == en_icon) {
! 	    val = ep1->v.i;
  	    if (val == 0) {
! 		*node = ep1;
  		break;
  	    }
  	    if (val == 1) {
! 		*node = ep0;
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
! 		ep1->v.i = sc;
  		ep->nodetype = en_lsh;
  	    }
  	}
  	break;
        case en_div:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         /*
!          * constant expressions
!          */
!         if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) ||
!             (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon))  {
!             dooper(node);
!             break;
!         }
! 	if (ep0->nodetype == en_icon) {
! 	    if (ep0->v.i == 0) {	/* 0/x */
! 		*node = ep0;
  		break;
  	    }
! 	} else if (ep1->nodetype == en_icon) {
! 	    val = ep1->v.i;
  	    if (val == 1) {	/* x/1 */
! 		*node = ep0;
  		break;
  	    }
  	    sc = pwrof2(val);
  	    if (sc != -1) {
! 		ep1->v.i = sc;
  		ep->nodetype = en_rsh;
  	    }
  	}
  	break;
        case en_mod:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         /*
!          * constant expressions
!          */
!         if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) ||
!             (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon))  {
!             dooper(node);
!             break;
!         }
! 	if (ep1->nodetype == en_icon) {
! 	    sc = pwrof2(ep1->v.i);
  	    if (sc != -1) {
! 		ep1->v.i = mod_mask(sc);
  		ep->nodetype = en_and;
  	    }
  	}
***************
*** 304,341 ****
        case en_xor:
        case en_eq:
        case en_ne:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
! 	if (ep->v.p[0]->nodetype == en_icon &&
! 	    ep->v.p[1]->nodetype == en_icon)
! 	    dooper(node);
  	break;
        case en_lsh:
        case en_rsh:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
! 	if (ep->v.p[0]->nodetype == en_icon && ep->v.p[1]->nodetype == en_icon)
  	    dooper(node);
! 	/* CVW: shift with zero shift count */
! 	else if (ep->v.p[1]->nodetype == en_icon && ep->v.p[1]->v.i == 0)
! 	    *node = ep->v.p[0];
  	break;
        case en_cond:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
!         if (ep->v.p[0]->nodetype == en_icon) {
! 	    if (ep->v.p[0]->v.i)
! 		*node=ep->v.p[1]->v.p[0];
  	    else
! 		*node=ep->v.p[1]->v.p[1];
  	}
  	break;
-       case en_land:
-       case en_lor:
-       case en_lt:
-       case en_le:
-       case en_gt:
-       case en_ge:
        case en_asand:
        case en_asor:
        case en_asxor:
--- 520,564 ----
        case en_xor:
        case en_eq:
        case en_ne:
!       case en_land:
!       case en_lor:
!       case en_lt:
!       case en_le:
!       case en_gt:
!       case en_ge:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         /*
!          * constant expressions
!          */
!         if ((ep0->nodetype == en_icon && ep1->nodetype == en_icon) ||
!             (ep0->nodetype == en_fcon && ep1->nodetype == en_fcon))
!             dooper(node);
  	break;
        case en_lsh:
        case en_rsh:
! 	opt0(&ep0);
! 	opt0(&ep1);
! 	if (ep0->nodetype == en_icon && ep1->nodetype == en_icon) {
  	    dooper(node);
!             break;
!         }
!         /*
!          * optimize a << 0   and a >> 0
!          */
! 	if (ep1->nodetype == en_icon && ep1->v.i == 0)
! 	    *node = ep0;
  	break;
        case en_cond:
! 	opt0(&ep0);
! 	opt0(&ep1);
!         if (ep0->nodetype == en_icon) {
! 	    if (ep0->v.i)
! 		*node=ep1->v.p[0];
  	    else
! 		*node=ep1->v.p[1];
  	}
  	break;
        case en_asand:
        case en_asor:
        case en_asxor:
***************
*** 349,369 ****
        case en_fcall:
        case en_void:
        case en_assign:
! 	opt0(&(ep->v.p[0]));
! 	opt0(&(ep->v.p[1]));
  	break;
  	/* now handled in expr.c */
        case en_cast:
! 	opt0(&(ep->v.p[0]));
! 	if (ep->v.p[0]->nodetype == en_icon &&
  	    ep->etype != bt_float &&
  	    ep->etype != bt_double) {
  	    ep->nodetype = en_icon;
! 	    ep->v.i = ep->v.p[0]->v.i;
  	}
  	break;
- 
      }
  }
  
  static long
--- 572,595 ----
        case en_fcall:
        case en_void:
        case en_assign:
! 	opt0(&ep0);
! 	opt0(&ep1);
  	break;
  	/* now handled in expr.c */
        case en_cast:
! 	opt0(&ep0);
! 	if (ep0->nodetype == en_icon &&
  	    ep->etype != bt_float &&
  	    ep->etype != bt_double) {
+ fatal("SHOULD NOT OCCUR");
  	    ep->nodetype = en_icon;
! 	    ep->v.i = ep0->v.i;
  	}
  	break;
      }
+ 
+ #undef ep0
+ #undef ep1
  }
  
  static long
diff -c c68III/out386_gas.c c68III.1/out386_gas.c
*** c68III/out386_gas.c	Mon Feb  4 19:58:55 1991
--- c68III.1/out386_gas.c	Fri Mar  1 10:50:18 1991
***************
*** 98,115 ****
--- 98,123 ----
  "leave",  op_leave,
  "ret",    op_ret,
  "rep",    op_rep,
+ #ifdef SUN_ASM_SYNTAX
  "smov",   op_smov,
+ #else
+ "movs",   op_smov,
+ #endif
  "test",   op_test,
  "fadd",   op_fadd,
  "fsub",   op_fsub,
+ "fsubr",  op_fsubr,
  "fmul",   op_fmul,
  "fdiv",   op_fdiv,
+ "fdivr",  op_fdivr,
  "fchs",   op_fchs,
  "fld",    op_fld,
+ "fild",   op_fild,
  "fst",    op_fst,
  "fstp",   op_fstp,
  "fstp %st(0)", op_fpop,
  "fcompp", op_fcompp,
+ "ftst",   op_ftst,
  "fnstsw", op_fnstsw,
  "sahf",   op_sahf,
  0, 0
***************
*** 170,179 ****
      struct enode   *offset;
  {
  
!     if (offset == 0) {
!         putc('0',output);
!         return;
!     }
      switch (offset->nodetype) {
        case en_autocon:
        case en_icon:
--- 178,185 ----
      struct enode   *offset;
  {
  
!     if (offset == 0)
!         fatal("PUTCONST");
      switch (offset->nodetype) {
        case en_autocon:
        case en_icon:
***************
*** 180,186 ****
--- 186,196 ----
  	fprintf(output, "%ld", offset->v.i);
  	break;
        case en_labcon:
+ #ifdef SUN_ASM_SYNTAX
  	fprintf(output, ".L%ld", offset->v.i);
+ #else
+ 	fprintf(output, "L%ld", offset->v.i);
+ #endif
  	break;
        case en_nacon:
  	fputs(outlate(offset->v.sp), output);
***************
*** 199,204 ****
--- 209,217 ----
  	putc('-', output);
  	putconst(offset->v.p[0]);
  	break;
+       case en_cast:
+         putconst(offset->v.p[0]);
+         break;
        default:
  	fatal("illegal constant node");
  	break;
***************
*** 346,352 ****
--- 359,369 ----
   */
      unsigned int    lab;
  {
+ #ifdef SUN_ASM_SYNTAX
      fprintf(output, ".L%u:\n", lab);
+ #else
+     fprintf(output, "L%u:\n", lab);
+ #endif
  }
  
  genbyte(val)
***************
*** 401,407 ****
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 46) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
--- 418,424 ----
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 56) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
***************
*** 415,436 ****
  }
  
  
- static int      align_counter = 0;
  genstorage(sp, align)
      struct sym     *sp;
      int             align;
  {
      nl();
      if (sp->storage_class == sc_static) {
!         if (lc_bss % align != 0) {
! 	    fprintf(output, ".lcomm .LA%d,%ld\n", align_counter++,
! 		    (long) align - (lc_bss % align));
! 	    lc_bss += (align - lc_bss % align);
!         }
! 	fprintf(output, ".lcomm .L%ld,%ld\n", sp->value.i, sp->tp->size);
          lc_bss += sp->tp->size;
       } else
! 	fprintf(output, ".comm %s,%ld\n", outlate(sp->name),sp->tp->size);
  }
  
  
--- 432,459 ----
  }
  
  
  genstorage(sp, align)
      struct sym     *sp;
      int             align;
  {
+     long size = sp->tp->size;
+     long remain;
      nl();
+ /*
+  * round up size so that it will fit all needs
+  */
+     remain = size % AL_DEFAULT;
+     if (remain != 0)
+         size = size + AL_DEFAULT - remain;
      if (sp->storage_class == sc_static) {
! #ifdef SUN_ASM_SYNTAX
! 	fprintf(output, ".lcomm .L%ld,%ld\n", sp->value.i, size);
! #else
! 	fprintf(output, ".lcomm L%ld,%ld\n", sp->value.i, size);
! #endif
          lc_bss += sp->tp->size;
       } else
! 	fprintf(output, ".comm %s,%ld\n", outlate(sp->name),size);
  }
  
  
***************
*** 501,508 ****
      int             align;
  /* align the following data */
  {
!     if (align == 1) return;
!     fprintf(output,"\t.align %d\n",align);
  }
  
  nl()
--- 524,553 ----
      int             align;
  /* align the following data */
  {
! /*
!  * In the default GAS setup, .align n aligns to a boundary of
!  * 2**n
!  */
!     switch (align) {
!       case 1:
!         break;
!       case 2:
! #ifdef SUN_ASM_SYNTAX
!         fputs("\t.align 2\n",output);
! #else
!         fputs("\t.align 1\n",output);
! #endif
!         break;
!       case 4:
! #ifdef SUN_ASM_SYNTAX
!         fputs("\t.align 4\n",output);
! #else
!         fputs("\t.align 2\n",output);
! #endif
!         break;
!       default:
!         fatal("PUT_ALIGN");
!     }
  }
  
  nl()
diff -c c68III/out68k_ack.c c68III.1/out68k_ack.c
*** c68III/out68k_ack.c	Mon Feb  4 19:58:57 1991
--- c68III.1/out68k_ack.c	Fri Mar  1 10:50:19 1991
***************
*** 468,474 ****
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 45) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
--- 468,474 ----
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 56) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
***************
*** 618,623 ****
--- 618,625 ----
      int             j, k;
      static char     symname[MAX_ID_LEN + 1];
  
+     if (*string == '.')
+         return string;
      symname[0] = '_';
      strcpy(symname + 1, string);
  
diff -c c68III/out68k_cpm.c c68III.1/out68k_cpm.c
*** c68III/out68k_cpm.c	Mon Feb  4 19:58:54 1991
--- c68III.1/out68k_cpm.c	Fri Mar  1 10:50:17 1991
***************
*** 463,469 ****
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 45) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
--- 463,469 ----
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 56) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
***************
*** 620,625 ****
--- 620,627 ----
      int             j, k;
      static char     symname[MAX_ID_LEN + 1];
  
+     if (*string == '.')
+         return string;
      symname[0] = '_';
      strcpy(symname + 1, string);
  
diff -c c68III/out68k_gas.c c68III.1/out68k_gas.c
*** c68III/out68k_gas.c	Mon Feb  4 19:58:52 1991
--- c68III.1/out68k_gas.c	Fri Mar  1 10:50:15 1991
***************
*** 415,421 ****
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 46) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
--- 415,421 ----
  genptr(node)
      struct enode   *node;
  {
!     if (gentype == longgen && outcol < 56) {
  	putc(',', output);
  	putconst(node);
  	outcol += 10;
***************
*** 429,454 ****
  }
  
  
- static int      align_counter = 0;
  genstorage(sp, align)
      struct sym     *sp;
      int             align;
  {
      nl();
!     if (lc_bss % align != 0) {
! 	fprintf(output, ".lcomm LA%d,%ld\n", align_counter++,
! 		(long) align - (lc_bss % align));
! 	lc_bss += (align - lc_bss % align);
!     }
!     if (sp->storage_class != sc_static)
! 	fprintf(output, ".lcomm %s,%ld\n", outlate(sp->name)
! 		,sp->tp->size);
!     else
! 	fprintf(output, ".lcomm L%ld,%ld\n", sp->value.i, sp->tp->size);
!     lc_bss += sp->tp->size;
  }
  
- 
  int
  stringlit(s, len)
  /*
--- 429,454 ----
  }
  
  
  genstorage(sp, align)
      struct sym     *sp;
      int             align;
  {
+     long size = sp->tp->size;
+     long remain;
      nl();
! /*
!  * round up size so that it will fit all needs
!  */
!     remain = size % AL_DEFAULT;
!     if (remain != 0)
!         size = size + AL_DEFAULT - remain;
!     if (sp->storage_class == sc_static) {
! 	fprintf(output, ".lcomm L%ld,%ld\n", sp->value.i, size);
!         lc_bss += sp->tp->size;
!      } else
! 	fprintf(output, ".lcomm %s,%ld\n", outlate(sp->name),size);
  }
  
  int
  stringlit(s, len)
  /*
***************
*** 556,561 ****
--- 556,563 ----
      char           *s;
  {
      static char     symbol[MAX_ID_LEN + 1];
+     if (*s == '.')
+         return s;
      symbol[0] = '_';
      strcpy(symbol + 1, s);
      return symbol;
diff -c c68III/peep68k.c c68III.1/peep68k.c
*** c68III/peep68k.c	Mon Feb  4 19:58:51 1991
--- c68III.1/peep68k.c	Fri Mar  1 10:50:14 1991
***************
*** 471,484 ****
      prev = ip->back;
      if (prev == 0)
  	return;
!     if ((((prev->opcode == op_move || prev->opcode == op_moveq
! 	   || prev->opcode == op_clr)
! 	  && equal_address(prev->oper1, ip->oper1))
! 	 && prev->oper2->mode != am_areg) ||
! 	(prev->opcode != op_label &&
! 	 equal_address(prev->oper2, ip->oper1))) {
! 	peep_delete(ip);
      }
  }
  
  static
--- 471,521 ----
      prev = ip->back;
      if (prev == 0)
  	return;
! /*
!  * All the following cases used to be checked with an obscure
!  * if-statement. There was an error in it that caused prev->oper2->mode
!  * to be referenced even if prev->opcode is op_clr. (This yields a NIL-
!  * pointer reference.
!  * I threw all this stuff away and replaced it by this case-statement.
!  * This is much more readable.
!  */
!     switch (prev->opcode) {
!         case op_label:
! /*
!  * List all pseudo-instructions here. Of course, they do not do
!  * anything.
!  */
!             return;
! 
!         case op_move:
! /*
!  * A move TO an address register does not set the flags
!  */
!             if (prev->oper2->mode == am_areg)
!                 return;
!         case op_moveq:
!         case op_clr:
! /*
!  * All other move an clr instructions set the flags according to
!  * the moved operand, which is prev->oper1
!  */
!             if (equal_address(prev->oper1, ip->oper1))
!                 break;
!         default:
! /*
!  * All instructions that have a target set the flags according to the
!  * target (prev->oper2)
!  * Note that equal_address may be called with a NIL pointer
!  */
!             if (equal_address(prev->oper2, ip->oper1))
!                 break;
!             return;
      }
+ /*
+  * We come here if the flags are already set, thus the tst
+  * instruction can be deleted.
+  */
+     peep_delete(ip);
  }
  
  static
***************
*** 578,583 ****
--- 615,622 ----
  {
      struct ocode   *ip;
      next_ip = peep_head;
+     if (! opt_option)
+         return;
      while (next_ip != 0) {
  	ip = next_ip;
  	next_ip = ip->fwd;
diff -c c68III/stmt.c c68III.1/stmt.c
*** c68III/stmt.c	Mon Feb  4 19:58:45 1991
--- c68III.1/stmt.c	Fri Mar  1 10:50:09 1991
***************
*** 282,291 ****
      struct snode   *snp;
      snp = (struct snode *) xalloc((int) sizeof(struct snode));
      snp->stype = st_expr;
!     if (expression(&(snp->exp)) == 0) {
  	error(ERR_EXPREXPECT);
- 	getsym();
-     }
      if (lastst != end)
  	needpunc(semicolon);
      return snp;
--- 282,296 ----
      struct snode   *snp;
      snp = (struct snode *) xalloc((int) sizeof(struct snode));
      snp->stype = st_expr;
! /*
!  * I have a problem here.
!  * If expression() fails on the first character and does not do a getsym(),
!  * there may be an infinite loop since we will continue coming up here.
!  * Since the compiler will stop after MAX_ERROR_COUNT calls to error(),
!  * this might not be THAT problem.
!  */
!     if (expression(&(snp->exp)) == 0)
  	error(ERR_EXPREXPECT);
      if (lastst != end)
  	needpunc(semicolon);
      return snp;
