OSDN Git Service

* config/alpha/vms.h (INCLUDE_DEFAULTS): Add /gnu/lib/gcc-lib/include.
[pf3gnuchains/gcc-fork.git] / gcc / ch / typeck.c
index 45bf8df..84ee56e 100644 (file)
@@ -1,5 +1,6 @@
 /* Build expressions with type checking for CHILL compiler.
-   Copyright (C) 1992, 93, 1994 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000
+   Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -15,7 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 /* This file is part of the CHILL front end.
@@ -36,23 +38,20 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "expr.h"
 #include "lex.h"
 #include "toplev.h"
-
-extern tree intQI_type_node;
-extern tree intHI_type_node;
-extern tree intSI_type_node;
-extern tree intDI_type_node;
-extern tree intTI_type_node;
-
-extern tree unsigned_intQI_type_node;
-extern tree unsigned_intHI_type_node;
-extern tree unsigned_intSI_type_node;
-extern tree unsigned_intDI_type_node;
-extern tree unsigned_intTI_type_node;
+#include "output.h"
 
 /* forward declarations */
-static int chill_l_equivalent PROTO((tree, tree, struct mode_chain*));
-static tree extract_constant_from_buffer PROTO((tree, unsigned char *, int));
-static int expand_constant_to_buffer PROTO((tree, unsigned char *, int));
+static int chill_l_equivalent PARAMS ((tree, tree, struct mode_chain*));
+static tree extract_constant_from_buffer PARAMS ((tree, const unsigned char *, int));
+static int expand_constant_to_buffer PARAMS ((tree, unsigned char *, int));
+static tree build_empty_string PARAMS ((tree));
+static tree make_chill_pointer_type PARAMS ((tree, enum tree_code));
+static unsigned int min_precision PARAMS ((tree, int));
+static tree make_chill_range_type PARAMS ((tree, tree, tree));
+static void apply_chill_array_layout PARAMS ((tree));
+static int field_decl_cmp PARAMS ((tree *, tree*));
+static tree make_chill_struct_type PARAMS ((tree));
+static int apply_chill_field_layout PARAMS ((tree, int *));
 \f
 /*
  * This function checks an array access.
@@ -67,7 +66,7 @@ static int expand_constant_to_buffer PROTO((tree, unsigned char *, int));
 tree
 valid_array_index_p (array, idx, error_message, is_varying_lhs)
      tree array, idx;
-     char *error_message;
+     const char *error_message;
      int is_varying_lhs;
 {
   tree cond, low_limit, high_cond, atype, domain;
@@ -158,7 +157,7 @@ valid_array_index_p (array, idx, error_message, is_varying_lhs)
     {
       if (tree_int_cst_equal (cond, boolean_false_node))
        return idx;       /* condition met at compile time */
-      error (error_message); /* condition failed at compile time */
+      error ("%s", error_message); /* condition failed at compile time */
       return error_mark_node;
     }
   else if (range_checking)
@@ -218,17 +217,17 @@ build_chill_slice (array, min_value, length)
      
      The static allocation info is passed by using the parent array's
      limits to compute a temp_size, which is passed in the lang_specific
-     field of the slice_type.
-   */
+     field of the slice_type. */
      
   if (TREE_CODE (array_type) == ARRAY_TYPE)
     {
       tree domain_type = TYPE_DOMAIN (array_type);
       tree domain_min = TYPE_MIN_VALUE (domain_type);
-      tree domain_max = fold (build (PLUS_EXPR, domain_type,
-                                    domain_min,
-                                    size_binop (MINUS_EXPR,
-                                                length, integer_one_node)));
+      tree domain_max
+       = fold (build (PLUS_EXPR, domain_type,
+                      domain_min,
+                      fold (build (MINUS_EXPR, integer_type_node,
+                                   length, integer_one_node))));
       tree index_type = build_chill_range_type (TYPE_DOMAIN (array_type),
                                                domain_min,
                                                domain_max);
@@ -245,14 +244,16 @@ build_chill_slice (array, min_value, length)
 
       SET_CH_NOVELTY (slice_type, CH_NOVELTY (array_type));
 
-      if (TREE_CONSTANT (array) && TREE_CODE (min_value) == INTEGER_CST
-         && TREE_CODE (length) == INTEGER_CST)
+      if (TREE_CONSTANT (array) && host_integerp (min_value, 0)
+         && host_integerp (length, 0))
        {
-         int type_size = int_size_in_bytes (array_type);
-         unsigned char *buffer = (unsigned char*) alloca (type_size);
-         int delta = int_size_in_bytes (element_type)
-           * (TREE_INT_CST_LOW (min_value) - TREE_INT_CST_LOW (domain_min));
-         bzero (buffer, type_size);
+         unsigned HOST_WIDE_INT type_size = int_size_in_bytes (array_type);
+         unsigned char *buffer = (unsigned char *) alloca (type_size);
+         int delta = (int_size_in_bytes (element_type)
+                      * (tree_low_cst (min_value, 0)
+                         - tree_low_cst (domain_min, 0)));
+
+         memset (buffer, 0, type_size);
          if (expand_constant_to_buffer (array, buffer, type_size))
            {
              result = extract_constant_from_buffer (slice_type,
@@ -411,13 +412,15 @@ build_chill_slice_with_range (array, min_value, max_value)
       && tree_int_cst_lt (max_value, min_value))
     return build_empty_string (TREE_TYPE (TREE_TYPE (array)));
 
-  return build_chill_slice (array, min_value,
-            save_expr (size_binop (PLUS_EXPR,
-              size_binop (MINUS_EXPR, max_value, min_value),
-                                   integer_one_node)));
+  return
+    build_chill_slice
+      (array, min_value,
+       save_expr (fold (build (PLUS_EXPR, integer_type_node,
+                              fold (build (MINUS_EXPR, integer_type_node,
+                                           max_value, min_value)),
+                              integer_one_node))));
 }
 
-
 tree
 build_chill_slice_with_length (array, min_value, length)
      tree array, min_value, length;
@@ -453,9 +456,10 @@ build_chill_slice_with_length (array, min_value, length)
       length = integer_one_node;
     }
 
-  max_index = size_binop (MINUS_EXPR, 
-               size_binop (PLUS_EXPR, length, min_value),
-                         integer_one_node);
+  max_index = fold (build (MINUS_EXPR, integer_type_node,
+                          fold (build (PLUS_EXPR, integer_type_node,
+                                       length, min_value)),
+                          integer_one_node));
   max_index = convert_to_class (chill_expr_class (min_value), max_index);
 
   min_value = valid_array_index_p (array, min_value,
@@ -566,7 +570,7 @@ build_chill_array_ref_1 (array, idx)
   if (! integer_zerop (TYPE_MIN_VALUE (domain)))
     {
       /* The C part of the compiler doesn't understand how to do
-        arithmetic with dissimilar enum types.  So we check compatability
+        arithmetic with dissimilar enum types.  So we check compatibility
         here, and perform the math in INTEGER_TYPE.  */
       if (TREE_CODE (TREE_TYPE (idx)) == ENUMERAL_TYPE
          && chill_comptypes (TREE_TYPE (idx), domain, 0))
@@ -625,13 +629,14 @@ build_chill_array_ref_1 (array, idx)
       else if (TREE_CODE (array) == STRING_CST
               && CH_CHARS_TYPE_P (TREE_TYPE (array)))
        {
-         HOST_WIDE_INT i = TREE_INT_CST_LOW (idx);
+         HOST_WIDE_INT i = tree_low_cst (idx, 0);
+
          if (i >= 0 && i < TREE_STRING_LENGTH (array))
-           {
-             char ch = TREE_STRING_POINTER (array) [i];
-             return convert_to_class (class,
-                                      build_int_2 ((unsigned char)ch, 0));
-           }
+           return
+             convert_to_class
+               (class,
+                build_int_2
+                ((unsigned char) TREE_STRING_POINTER (array) [i], 0));
        }
     }
 
@@ -730,16 +735,18 @@ expand_constant_to_buffer (value, buffer, buf_size)
     {
     case INTEGER_CST:
       {
-       HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
+       unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
        HOST_WIDE_INT hi = TREE_INT_CST_HIGH (value);
        for (i = 0; i < size; i++)
          {
            /* Doesn't work if host and target BITS_PER_UNIT differ. */
            unsigned char byte = lo & ((1 << BITS_PER_UNIT) - 1);
+
            if (BYTES_BIG_ENDIAN)
              buffer[size - i - 1] = byte;
            else
              buffer[i] = byte;
+
            rshift_double (lo, hi, BITS_PER_UNIT, BITS_PER_UNIT * size,
                           &lo, &hi, 0);
          }
@@ -769,10 +776,10 @@ expand_constant_to_buffer (value, buffer, buf_size)
              tree min_val = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
              if (min_val)
                {
-                 if (TREE_CODE (min_val) != INTEGER_CST)
+                 if (! host_integerp (min_val, 0))
                    return 0;
                  else
-                   min_index = TREE_INT_CST_LOW (min_val);
+                   min_index = tree_low_cst (min_val, 0);
                }
            }
 
@@ -783,14 +790,15 @@ expand_constant_to_buffer (value, buffer, buf_size)
              HOST_WIDE_INT offset;
              HOST_WIDE_INT last_index;
              tree purpose = TREE_PURPOSE (list);
+
              if (purpose)
                {
-                 if (TREE_CODE (purpose) == INTEGER_CST)
-                   last_index = next_index = TREE_INT_CST_LOW (purpose);
+                 if (host_integerp (purpose, 0))
+                   last_index = next_index = tree_low_cst (purpose, 0);
                  else if (TREE_CODE (purpose) == RANGE_EXPR)
                    {
-                     next_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 0));
-                     last_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 1));
+                     next_index = tree_low_cst (TREE_OPERAND (purpose, 0), 0);
+                     last_index = tree_low_cst (TREE_OPERAND (purpose, 1), 0);
                    }
                  else
                    return 0;
@@ -815,12 +823,14 @@ expand_constant_to_buffer (value, buffer, buf_size)
            {
              tree field = TREE_PURPOSE (list);
              HOST_WIDE_INT offset;
+
              if (field == NULL_TREE || TREE_CODE (field) != FIELD_DECL)
                return 0;
+
              if (DECL_BIT_FIELD (field))
                return 0;
-             offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
-               / BITS_PER_UNIT;
+
+             offset = int_byte_position (field);
              if (!expand_constant_to_buffer (TREE_VALUE (list),
                                              buffer + offset,
                                              buf_size - offset))
@@ -849,14 +859,16 @@ expand_constant_to_buffer (value, buffer, buf_size)
 static tree
 extract_constant_from_buffer (type, buffer, buf_size)
      tree type;
-     unsigned char *buffer;
+     const unsigned char *buffer;
      int buf_size;
 {
   tree value;
-  int size = int_size_in_bytes (type);
-  int i;
+  HOST_WIDE_INT size = int_size_in_bytes (type);
+  HOST_WIDE_INT i;
+
   if (size < 0 || size > buf_size)
     return 0;
+
   switch (TREE_CODE (type))
     {
     case INTEGER_TYPE:
@@ -901,16 +913,18 @@ extract_constant_from_buffer (type, buffer, buf_size)
        value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
        if (value)
          {
-           if (TREE_CODE (value) != INTEGER_CST)
+           if (! host_integerp (value, 0))
              return 0;
            else
-             min_index = TREE_INT_CST_LOW (value);
+             min_index = tree_low_cst (value, 0);
          }
+
        value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
-       if (value == NULL_TREE || TREE_CODE (value) != INTEGER_CST)
+       if (value == NULL_TREE || ! host_integerp (value, 0))
          return 0;
        else
-         max_index = TREE_INT_CST_LOW (value);
+         max_index = tree_low_cst (value, 0);
+
        for (cur_index = max_index; cur_index >= min_index; cur_index--)
          {
            HOST_WIDE_INT offset = (cur_index - min_index) * element_size;
@@ -932,8 +946,8 @@ extract_constant_from_buffer (type, buffer, buf_size)
        tree field = TYPE_FIELDS (type);
        for (; field != NULL_TREE; field = TREE_CHAIN (field))
          {
-           HOST_WIDE_INT offset
-             = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) / BITS_PER_UNIT;
+           HOST_WIDE_INT offset = int_byte_position (field);
+
            if (DECL_BIT_FIELD (field))
              return 0;
            value = extract_constant_from_buffer (TREE_TYPE (field),
@@ -952,7 +966,7 @@ extract_constant_from_buffer (type, buffer, buf_size)
     case UNION_TYPE:
       {
        tree longest_variant = NULL_TREE;
-       int longest_size = 0;
+       unsigned HOST_WIDE_INT longest_size = 0;
        tree field = TYPE_FIELDS (type);
        
        /* This is a kludge.  We assume that converting the data to te
@@ -965,7 +979,8 @@ extract_constant_from_buffer (type, buffer, buf_size)
 
        for (; field != NULL_TREE; field = TREE_CHAIN (field))
          {
-           int size = TREE_INT_CST_LOW (size_in_bytes (TREE_TYPE (field)));
+           unsigned HOST_WIDE_INT size
+             = int_size_in_bytes (TREE_TYPE (field));
            
            if (size > longest_size)
              {
@@ -973,9 +988,13 @@ extract_constant_from_buffer (type, buffer, buf_size)
                longest_variant = field;
              }
          }
+
        if (longest_variant == NULL_TREE)
          return NULL_TREE;
-       return extract_constant_from_buffer (TREE_TYPE (longest_variant), buffer, buf_size);
+
+       return
+         extract_constant_from_buffer (TREE_TYPE (longest_variant),
+                                       buffer, buf_size);
       }
 
     case SET_TYPE:
@@ -983,26 +1002,32 @@ extract_constant_from_buffer (type, buffer, buf_size)
        tree list = NULL_TREE;
        int i;
        HOST_WIDE_INT min_index, max_index;
+
        if (TYPE_DOMAIN (type) == 0)
          return 0;
+
        value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
        if (value == NULL_TREE)
          min_index = 0;
-       else if (TREE_CODE (value) != INTEGER_CST)
+
+       else if (! host_integerp (value, 0))
          return 0;
        else
-         min_index = TREE_INT_CST_LOW (value);
+         min_index = tree_low_cst (value, 0);
+
        value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
        if (value == NULL_TREE)
          max_index = 0;
-       else if (TREE_CODE (value) != INTEGER_CST)
+       else if (! host_integerp (value, 0))
          return 0;
        else
-         max_index = TREE_INT_CST_LOW (value);
+         max_index = tree_low_cst (value, 0);
+
        for (i = max_index + 1 - min_index; --i >= 0; )
          {
-           unsigned char byte = (unsigned char)buffer[i / BITS_PER_UNIT];
-           unsigned bit_pos = (unsigned)i % (unsigned)BITS_PER_UNIT;
+           unsigned char byte = (unsigned char) buffer[i / BITS_PER_UNIT];
+           unsigned bit_pos = (unsigned) i % (unsigned) BITS_PER_UNIT;
+
            if (BYTES_BIG_ENDIAN
                ? (byte & (1 << (BITS_PER_UNIT - 1 - bit_pos)))
                : (byte & (1 << bit_pos)))
@@ -1089,7 +1114,7 @@ build_chill_cast (type, expr)
   if (expr_type_is_discrete && type_is_discrete)
     {
       /* do an overflow check
-        FIXME: is this always neccessary ??? */
+        FIXME: is this always necessary ??? */
       /* FIXME: don't do range chacking when target type is PTR.
         PTR doesn't have MIN and MAXVALUE. result is sigsegv. */
       if (range_checking && type != ptr_type_node)
@@ -1168,7 +1193,7 @@ build_chill_cast (type, expr)
     {
       unsigned char *buffer = (unsigned char*) alloca (type_size);
       tree value;
-      bzero (buffer, type_size);
+      memset (buffer, 0, type_size);
       if (!expand_constant_to_buffer (expr, buffer, type_size))
        {
          error ("not implemented: constant conversion from that kind of expression");
@@ -1207,26 +1232,26 @@ build_chill_cast (type, expr)
                 build1 (NOP_EXPR, build_pointer_type (type),
                         build1 (ADDR_EXPR, build_pointer_type (expr_type),
                                 expr)));
-  TREE_READONLY (expr) == TYPE_READONLY (type);
+  TREE_READONLY (expr) = TYPE_READONLY (type);
   return expr;
 }
 \f
-/*
- * given a set_type, build an integer array from it that C will grok.
- */
+/* Given a set_type, build an integer array from it that C will grok. */
+
 tree
 build_array_from_set (type)
      tree type;
 {
   tree bytespint, bit_array_size, int_array_count;
  
-  if (type == NULL_TREE || type == error_mark_node || TREE_CODE (type) != SET_TYPE)
+  if (type == NULL_TREE || type == error_mark_node
+      || TREE_CODE (type) != SET_TYPE)
     return error_mark_node;
 
-  bytespint = build_int_2 (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR, 0);
+  /* ??? Should this really be *HOST*??  */
+  bytespint = size_int (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR);
   bit_array_size = size_in_bytes (type);
-  int_array_count = fold (size_binop (TRUNC_DIV_EXPR, bit_array_size,
-                                                bytespint));
+  int_array_count = size_binop (TRUNC_DIV_EXPR, bit_array_size, bytespint);
   if (integer_zerop (int_array_count))
     int_array_count = size_one_node;
   type = build_array_type (integer_type_node, 
@@ -1240,14 +1265,16 @@ build_chill_bin_type (size)
      tree size;
 {
 #if 0
-  int isize;
+  HOST_WIDE_INT isize;
 
-  if (TREE_CODE (size) != INTEGER_CST
-      || (isize = TREE_INT_CST_LOW (size), isize <= 0))
+  if (! host_integerp (size, 1))
     {
       error ("operand to bin must be a non-negative integer literal");
       return error_mark_node;
     }
+
+  isize = tree_low_cst (size, 1);
+
   if (isize <= TYPE_PRECISION (unsigned_char_type_node))
     return unsigned_char_type_node;
   if (isize <= TYPE_PRECISION (short_unsigned_type_node))
@@ -1282,7 +1309,7 @@ tree
 chill_expand_tuple (type, constructor)
      tree type, constructor;
 {
-  char *name;
+  const char *name;
   tree nonreft = type;
 
   if (TYPE_NAME (type) != NULL_TREE)
@@ -1695,12 +1722,10 @@ chill_similar (mode1, mode2, chain)
 
     default:
       ;
-#if 0
       /* Need to handle row modes, instance modes,
         association modes, access modes, text modes,
         duration modes, absolute time modes, structure modes,
         parameterized structure modes */
-#endif
     }
   return 1;
 }
@@ -1782,9 +1807,9 @@ chill_l_equivalent (mode1, mode2, chain)
     return 0;
   if (TYPE_READONLY (mode1) != TYPE_READONLY (mode2))
     return 0;
-#if 0
+/*
   ... other conditions ...;
-#endif
+ */
   return 1;
 }
 
@@ -1810,9 +1835,9 @@ chill_read_compatible (modeM, modeN)
        {
          return chill_l_equivalent (TREE_TYPE (modeM), TREE_TYPE (modeN), 0);
        }
-#if 0
+/*
       ...;
-#endif
+*/
     }
   return 1;
 }
@@ -1862,13 +1887,12 @@ chill_compatible (expr, mode)
     case CH_REFERENCE_CLASS:
       if (!CH_IS_REFERENCE_MODE (mode))
        return 0;
-#if 0
-      /* FIXME! */
+/* FIXME!
       if (class.mode is a row mode)
        ...;
       else if (class.mode is not a static mode)
-       return 0; /* is this possible? FIXME */
-#endif
+       return 0; is this possible?
+*/
       return !CH_IS_BOUND_REFERENCE_MODE(mode)
        || CH_READ_COMPATIBLE (TREE_TYPE (mode), class.mode);
     }
@@ -2171,8 +2195,7 @@ build_init_struct ()
   /* We temporarily reset the maximum_field_alignment to zero so the
      compiler's init data structures can be compatible with the
      run-time system, even when we're compiling with -fpack. */
-  extern int maximum_field_alignment;
-  int save_maximum_field_alignment = maximum_field_alignment;
+  unsigned int save_maximum_field_alignment = maximum_field_alignment;
   maximum_field_alignment = 0;
 
   decl1 = build_decl (FIELD_DECL, get_identifier ("__INIT_ENTRY"),
@@ -2402,7 +2425,7 @@ build_chill_modify_expr (lhs, rhs)
 /* Construct, lay out and return the type of pointers to TO_TYPE.
    If such a type has already been constructed, reuse it.  */
 
-tree
+static tree
 make_chill_pointer_type (to_type, code)
      tree to_type;
      enum tree_code code;  /* POINTER_TYPE or REFERENCE_TYPE */
@@ -2489,7 +2512,7 @@ build_chill_reference_type (to_type)
   return t;
 }
 \f
-tree
+static tree
 make_chill_range_type (type, lowval, highval)
      tree type, lowval, highval;
 {
@@ -2500,6 +2523,36 @@ make_chill_range_type (type, lowval, highval)
   return itype;
 }
 
+\f
+/* Return the minimum number of bits needed to represent VALUE in a
+   signed or unsigned type, UNSIGNEDP says which.  */
+
+static unsigned int
+min_precision (value, unsignedp)
+     tree value;
+     int unsignedp;
+{
+  int log;
+
+  /* If the value is negative, compute its negative minus 1.  The latter
+     adjustment is because the absolute value of the largest negative value
+     is one larger than the largest positive value.  This is equivalent to
+     a bit-wise negation, so use that operation instead.  */
+
+  if (tree_int_cst_sgn (value) < 0)
+    value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
+
+  /* Return the number of bits needed, taking into account the fact
+     that we need one more bit for a signed than unsigned type.  */
+
+  if (integer_zerop (value))
+    log = 0;
+  else
+    log = tree_floor_log2 (value);
+
+  return log + 1 + ! unsignedp;
+}
+
 tree
 layout_chill_range_type (rangetype, must_be_const)
      tree rangetype;
@@ -2518,30 +2571,31 @@ layout_chill_range_type (rangetype, must_be_const)
     {
       int binsize;
       
-      /* make a range out of it */
+      /* Make a range out of it */
       if (TREE_CODE (highval) != INTEGER_CST)
        {
          error ("non-constant expression for BIN");
          return error_mark_node;
        }
-      binsize = TREE_INT_CST_LOW (highval);
-      if (binsize < 0)
+      else if (tree_int_cst_sgn (highval) < 0)
        {
          error ("expression for BIN must not be negative");
          return error_mark_node;
        }
-      if (binsize > 32)
+      else if (compare_tree_int (highval, 32) > 0)
        {
          error ("cannot process BIN (>32)");
          return error_mark_node;
        }
+
+      binsize = tree_low_cst (highval, 1);
       type = ridpointers [(int) RID_RANGE];
       lowval = integer_zero_node;
       highval = build_int_2 ((1 << binsize) - 1, 0);
     }
  
-  if (TREE_CODE (lowval) == ERROR_MARK ||
-      TREE_CODE (highval) == ERROR_MARK)
+  if (TREE_CODE (lowval) == ERROR_MARK
+      || TREE_CODE (highval) == ERROR_MARK)
     return error_mark_node;
 
   if (!CH_COMPATIBLE_CLASSES (lowval, highval))
@@ -2578,37 +2632,14 @@ layout_chill_range_type (rangetype, must_be_const)
          && TREE_CODE (lowval) == INTEGER_CST
          && TREE_CODE (highval) == INTEGER_CST)
        {
-         /* The logic of this code has been copied from finish_enum
-            in c-decl.c.  FIXME duplication! */
-         int precision = 0;
-         HOST_WIDE_INT maxvalue = TREE_INT_CST_LOW (highval);
-         HOST_WIDE_INT minvalue = TREE_INT_CST_LOW (lowval);
-         if (TREE_INT_CST_HIGH (lowval) >= 0
-             ? tree_int_cst_lt (TYPE_MAX_VALUE (unsigned_type_node), highval)
-             : (tree_int_cst_lt (lowval, TYPE_MIN_VALUE (integer_type_node))
-                || tree_int_cst_lt (TYPE_MAX_VALUE (integer_type_node), highval)))
-           precision = TYPE_PRECISION (long_long_integer_type_node);
-         else
-           {
-             if (maxvalue > 0)
-               precision = floor_log2 (maxvalue) + 1;
-             if (minvalue < 0)
-               {
-                 /* Compute number of bits to represent magnitude of a
-                    negative value.  Add one to MINVALUE since range of
-                    negative numbers includes the power of two.  */
-                 unsigned negprecision = floor_log2 (-minvalue - 1) + 1;
-                 if (negprecision > precision)
-                   precision = negprecision;
-                 precision += 1;       /* room for sign bit */
-               }
+         int unsignedp = tree_int_cst_sgn (lowval) >= 0;
+         unsigned int precision = MAX (min_precision (highval, unsignedp),
+                                       min_precision (lowval, unsignedp));
 
-             if (!precision)
-               precision = 1;
-           }
-         type = type_for_size (precision, minvalue >= 0);
+         type = type_for_size (precision, unsignedp);
 
        }
+
       TREE_TYPE (rangetype) = type;
     }
   else
@@ -2691,6 +2722,7 @@ layout_chill_range_type (rangetype, must_be_const)
   TYPE_SIZE (rangetype) = TYPE_SIZE (type);
   TYPE_SIZE_UNIT (rangetype) = TYPE_SIZE_UNIT (type);
   TYPE_ALIGN (rangetype) = TYPE_ALIGN (type);
+  TYPE_USER_ALIGN (rangetype) = TYPE_USER_ALIGN (type);
   TREE_UNSIGNED (rangetype) = TREE_UNSIGNED (type);
   CH_NOVELTY (rangetype) = CH_NOVELTY (type);
   return rangetype;
@@ -2736,7 +2768,9 @@ apply_chill_array_layout (array_type)
      tree array_type;
 {
   tree layout, temp, what, element_type;
-  int stepsize, word, start_bit, length, natural_length;
+  HOST_WIDE_INT stepsize = 0;
+  HOST_WIDE_INT word, start_bit = 0, length;
+  HOST_WIDE_INT natural_length;
   int stepsize_specified;
   int start_bit_error = 0;
   int length_error = 0;
@@ -2757,8 +2791,10 @@ apply_chill_array_layout (array_type)
       && get_type_precision (TYPE_MIN_VALUE (element_type),
                             TYPE_MAX_VALUE (element_type)) == 1)
     natural_length = 1;
+  else if (host_integerp (TYPE_SIZE (element_type), 1))
+    natural_length = tree_low_cst (TYPE_SIZE (element_type), 1);
   else
-    natural_length = TREE_INT_CST_LOW (TYPE_SIZE (element_type));
+    natural_length = -1;
 
   if (layout == integer_one_node) /* PACK */
     {
@@ -2774,32 +2810,32 @@ apply_chill_array_layout (array_type)
   temp = TREE_VALUE (layout);
   if (TREE_VALUE (temp) != NULL_TREE)
     {
-      if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
-       error ("Stepsize in STEP must be an integer constant");
+      if (! host_integerp (TREE_VALUE (temp), 0))
+       error ("stepsize in STEP must be an integer constant");
       else
        {
-         stepsize = TREE_INT_CST_LOW (TREE_VALUE (temp));
-         if (stepsize <= 0)
-           error ("Stepsize in STEP must be > 0");
+         if (tree_int_cst_sgn (TREE_VALUE (temp)) <= 0)
+           error ("stepsize in STEP must be > 0");
          else
            stepsize_specified = 1;
 
+         stepsize = tree_low_cst (TREE_VALUE (temp), 1);
          if (stepsize != natural_length)
-           sorry ("Stepsize in STEP must be the natural width of "
-                  "the array element mode");
+           sorry ("stepsize in STEP must be the natural width of the array element mode");
        }
     }
 
   temp = TREE_PURPOSE (temp);
-  if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
-    error ("Starting word in POS must be an integer constant");
+  if (! host_integerp (TREE_PURPOSE (temp), 0))
+    error ("starting word in POS must be an integer constant");
   else
     {
-      word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-      if (word < 0)
-       error ("Starting word in POS must be >= 0");
-      if (word != 0)
-       sorry ("Starting word in POS within STEP must be 0");
+      if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
+       error ("starting word in POS must be >= 0");
+      if (! integer_zerop (TREE_PURPOSE (temp)))
+       sorry ("starting word in POS within STEP must be 0");
+
+      word = tree_low_cst (TREE_PURPOSE (temp), 0);
     }
 
   length = natural_length;
@@ -2807,25 +2843,27 @@ apply_chill_array_layout (array_type)
   if (temp != NULL_TREE)
     {
       int wordsize = TYPE_PRECISION (chill_integer_type_node);
-      if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+      if (! host_integerp (TREE_PURPOSE (temp), 0))
        {
-         error ("Starting bit in POS must be an integer constant");
+         error ("starting bit in POS must be an integer constant");
          start_bit_error = 1;
        }
       else
        {
-         start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-         if (start_bit != 0)
-           sorry ("Starting bit in POS within STEP must be 0");
-         if (start_bit < 0)
+         if (! integer_zerop (TREE_PURPOSE (temp)))
+           sorry ("starting bit in POS within STEP must be 0");
+
+         if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
            {
-             error ("Starting bit in POS must be >= 0");
+             error ("starting bit in POS must be >= 0");
              start_bit = 0;
              start_bit_error = 1;
            }
-         else if (start_bit >= wordsize)
+         
+         start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+         if (start_bit >= wordsize)
            {
-             error ("Starting bit in POS must be < the width of a word");
+             error ("starting bit in POS must be < the width of a word");
              start_bit = 0;
              start_bit_error = 1;
            }
@@ -2837,37 +2875,38 @@ apply_chill_array_layout (array_type)
          what = TREE_PURPOSE (temp);
          if (what == integer_zero_node)
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("Length in POS must be an integer constant");
+                 error ("length in POS must be an integer constant");
                  length_error = 1;
                }
              else
                {
-                 length = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 length = tree_low_cst (TREE_VALUE (temp), 0);
                  if (length <= 0)
-                   error ("Length in POS must be > 0");
+                   error ("length in POS must be > 0");
                }
            }
          else
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("End bit in POS must be an integer constant");
+                 error ("end bit in POS must be an integer constant");
                  length_error = 1;
                }
              else
                {
-                 int end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
+
                  if (end_bit < start_bit)
                    {
-                     error ("End bit in POS must be >= the start bit");
+                     error ("end bit in POS must be >= the start bit");
                      end_bit = wordsize - 1;
                      length_error = 1;
                    }
                  else if (end_bit >= wordsize)
                    {
-                     error ("End bit in POS must be < the width of a word");
+                     error ("end bit in POS must be < the width of a word");
                      end_bit = wordsize - 1;
                      length_error = 1;
                    }
@@ -2877,16 +2916,14 @@ apply_chill_array_layout (array_type)
                    length = end_bit - start_bit + 1;
                }
            }
+
          if (! length_error && length != natural_length)
-           {
-             sorry ("The length specified on POS within STEP must be "
-                    "the natural length of the array element type");
-           }
+           sorry ("the length specified on POS within STEP must be the natural length of the array element type");
        }
     }
 
   if (! length_error && stepsize_specified && stepsize < length)
-    error ("Step size in STEP must be >= the length in POS");
+    error ("step size in STEP must be >= the length in POS");
 
   if (length == 1)
     TYPE_PACKED (array_type) = 1;
@@ -2989,21 +3026,17 @@ field_decl_cmp (x, y)
   return (long)DECL_NAME (*x) - (long)DECL_NAME (*y);
 }
 
-tree
+static tree
 make_chill_struct_type (fieldlist)
      tree fieldlist;
 {
   tree t, x;
-  if (TREE_UNION_ELEM (fieldlist))
-    t = make_node (UNION_TYPE);
-  else
-    t = make_node (RECORD_TYPE);
+
+  t = make_node (TREE_UNION_ELEM (fieldlist) ? UNION_TYPE : RECORD_TYPE);
+
   /* Install struct as DECL_CONTEXT of each field decl. */
   for (x = fieldlist; x; x = TREE_CHAIN (x))
-    {
-      DECL_CONTEXT (x) = t;
-      DECL_FIELD_SIZE (x) = 0;
-    }
+    DECL_CONTEXT (x) = t;
 
   /* Delete all duplicate fields from the fieldlist */
   for (x = fieldlist; x && TREE_CHAIN (x);)
@@ -3035,31 +3068,37 @@ make_chill_struct_type (fieldlist)
   return t;
 }
 
-/* decl is a FIELD_DECL.
-   DECL_INIT (decl) is (NULL_TREE, integer_one_node, integer_zero_node, tree_list),
-   meaning (default, pack, nopack, POS (...) ).
+/* DECL is a FIELD_DECL.
+   DECL_INIT (decl) is
+       (NULL_TREE, integer_one_node, integer_zero_node, tree_list)
+    meaning
+        (default, pack, nopack, POS (...) ).
+
    The return value is a boolean: 1 if POS specified, 0 if not */
+
 static int
 apply_chill_field_layout (decl, next_struct_offset)
      tree decl;
-     intnext_struct_offset;
+     int *next_struct_offset;
 {
-  tree layout, type, temp, what;
-  int word, wordsize, start_bit, offset, length, natural_length;
+  tree layout = DECL_INITIAL (decl);
+  tree type = TREE_TYPE (decl);
+  tree temp, what;
+  HOST_WIDE_INT word = 0;
+  HOST_WIDE_INT wordsize, start_bit, offset, length, natural_length;
   int pos_error = 0;
-  int is_discrete;
+  int is_discrete = discrete_type_p (type);
 
-  type = TREE_TYPE (decl);
-  is_discrete = discrete_type_p (type);
   if (is_discrete)
-    natural_length = get_type_precision (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+    natural_length
+      = get_type_precision (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+  else if (host_integerp (TYPE_SIZE (type), 1))
+    natural_length = tree_low_cst (TYPE_SIZE (type), 1);
   else
-    natural_length = TREE_INT_CST_LOW (TYPE_SIZE (type));
+    natural_length = -1;
 
-  layout = DECL_INITIAL (decl);
   if (layout == integer_zero_node) /* NOPACK */
     {
-      DECL_PACKED (decl) = 0;
       *next_struct_offset += natural_length;
       return 0; /* not POS */
     }
@@ -3067,14 +3106,17 @@ apply_chill_field_layout (decl, next_struct_offset)
   if (layout == integer_one_node) /* PACK */
     {
       if (is_discrete)
-       DECL_BIT_FIELD (decl) = 1;
+       {
+         DECL_BIT_FIELD (decl) = 1;
+         DECL_SIZE (decl) = bitsize_int (natural_length);
+       }
       else
        {
-         DECL_BIT_FIELD (decl) = 0;
          DECL_ALIGN (decl) = BITS_PER_UNIT;
+         DECL_USER_ALIGN (decl) = 0;
        }
+
       DECL_PACKED (decl) = 1;
-      DECL_FIELD_SIZE (decl) = natural_length;
       *next_struct_offset += natural_length;
       return 0; /* not POS */
     }
@@ -3084,20 +3126,21 @@ apply_chill_field_layout (decl, next_struct_offset)
      natural width of the underlying type. */
   temp = TREE_PURPOSE (layout);
 
-  if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+  if (! host_integerp (TREE_PURPOSE (temp), 0))
     {
-      error ("Starting word in POS must be an integer constant");
+      error ("starting word in POS must be an integer constant");
       pos_error = 1;
     }
   else
     {
-      word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-      if (word < 0)
+      if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
        {
-         error ("Starting word in POS must be >= 0");
+         error ("starting word in POS must be >= 0");
          word = 0;
          pos_error = 1;
        }
+      else
+       word = tree_low_cst (TREE_PURPOSE (temp), 0);
     }
 
   wordsize = TYPE_PRECISION (chill_integer_type_node);
@@ -3107,24 +3150,25 @@ apply_chill_field_layout (decl, next_struct_offset)
   temp = TREE_VALUE (temp);
   if (temp != NULL_TREE)
     {
-      if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+      if (! host_integerp (TREE_PURPOSE (temp), 0))
        {
-         error ("Starting bit in POS must be an integer constant");
+         error ("starting bit in POS must be an integer constant");
          start_bit = *next_struct_offset - offset;
          pos_error = 1;
        }
       else
        {
-         start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
-         if (start_bit < 0)
+         if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
            {
-             error ("Starting bit in POS must be >= 0");
+             error ("starting bit in POS must be >= 0");
              start_bit = *next_struct_offset - offset;
              pos_error = 1;
            }
-         else if (start_bit >= wordsize)
+
+         start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+         if (start_bit >= wordsize)
            {
-             error ("Starting bit in POS must be < the width of a word");
+             error ("starting bit in POS must be < the width of a word");
              start_bit = *next_struct_offset - offset;
              pos_error = 1;
            }
@@ -3136,50 +3180,53 @@ apply_chill_field_layout (decl, next_struct_offset)
          what = TREE_PURPOSE (temp);
          if (what == integer_zero_node)
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("Length in POS must be an integer constant");
+                 error ("length in POS must be an integer constant");
                  pos_error = 1;
                }
              else
                {
-                 length = TREE_INT_CST_LOW (TREE_VALUE (temp));
-                 if (length <= 0)
+                 if (tree_int_cst_sgn (TREE_VALUE (temp)) < 0)
                    {
-                     error ("Length in POS must be > 0");
+                     error ("length in POS must be > 0");
                      length = natural_length;
                      pos_error = 1;
                    }
+                 else
+                   length = tree_low_cst (TREE_VALUE (temp), 0);
+
                }
            }
          else
            {
-             if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+             if (! host_integerp (TREE_VALUE (temp), 0))
                {
-                 error ("End bit in POS must be an integer constant");
+                 error ("end bit in POS must be an integer constant");
                  pos_error = 1;
                }
              else
                {
-                 int end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+                 HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
+
                  if (end_bit < start_bit)
                    {
-                     error ("End bit in POS must be >= the start bit");
+                     error ("end bit in POS must be >= the start bit");
                      pos_error = 1;
                    }
                  else if (end_bit >= wordsize)
                    {
-                     error ("End bit in POS must be < the width of a word");
+                     error ("end bit in POS must be < the width of a word");
                      pos_error = 1;
                    }
                  else
                    length = end_bit - start_bit + 1;
                }
            }
+
          if (length != natural_length && ! pos_error)
            {
-             sorry ("The length specified on POS must be the natural length "
-                    "of the field type");
+             sorry ("the length specified on POS must be the natural length of the field type");
              length = natural_length;
            }
        }
@@ -3192,7 +3239,10 @@ apply_chill_field_layout (decl, next_struct_offset)
 
   DECL_PACKED (decl) = 1;
   DECL_BIT_FIELD (decl) = is_discrete;
-  DECL_FIELD_SIZE (decl) = length;
+
+  if (is_discrete)
+    DECL_SIZE (decl) = bitsize_int (length);
+
   *next_struct_offset += natural_length;
 
   return 1; /* was POS */
@@ -3212,12 +3262,7 @@ layout_chill_struct_type (t)
 
   old_momentary = suspend_momentary ();
 
-  /* Process specified field sizes.
-     Set DECL_FIELD_SIZE to the specified size, or 0 if none specified.
-     The specified size is found in the DECL_INITIAL.
-     Store 0 there, except for ": 0" fields (so we can find them
-     and delete them, below).  */
-
+  /* Process specified field sizes.  */
   next_struct_offset = 0;
   for (x = fieldlist; x; x = TREE_CHAIN (x))
     {
@@ -3243,7 +3288,7 @@ layout_chill_struct_type (t)
        }
       else
        {
-         int min_align = TYPE_ALIGN (TREE_TYPE (x));
+         unsigned int min_align = TYPE_ALIGN (TREE_TYPE (x));
          DECL_ALIGN (x) = MAX (DECL_ALIGN (x), min_align);
          was_pos = 0;
        }
@@ -3253,7 +3298,7 @@ layout_chill_struct_type (t)
     }
 
   if (pos_error)
-    error ("If one field has a POS layout, then all fields must have a POS layout");
+    error ("if one field has a POS layout, then all fields must have a POS layout");
 
   /* Now DECL_INITIAL is null on all fields.  */
 
@@ -3297,7 +3342,8 @@ layout_chill_struct_type (t)
        for (x = fieldlist; x; x = TREE_CHAIN (x))
          field_array[len++] = x;
 
-       qsort (field_array, len, sizeof (tree), field_decl_cmp);
+       qsort (field_array, len, sizeof (tree),
+              (int (*) PARAMS ((const void *, const void *))) field_decl_cmp);
       }
   }
 
@@ -3306,6 +3352,7 @@ layout_chill_struct_type (t)
       TYPE_FIELDS (x) = TYPE_FIELDS (t);
       TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
       TYPE_ALIGN (x) = TYPE_ALIGN (t);
+      TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
     }
 
   resume_momentary (old_momentary);
@@ -3346,7 +3393,7 @@ smash_dummy_type (type)
 {
   /* Save fields that we don't want to copy from ORIGIN. */ 
   tree origin = TREE_TYPE (type);
-  tree main = TYPE_MAIN_VARIANT (origin);
+  tree main_tree = TYPE_MAIN_VARIANT (origin);
   int  save_uid = TYPE_UID (type);
   struct obstack *save_obstack = TYPE_OBSTACK (type);
   tree save_name = TYPE_NAME (type);
@@ -3377,9 +3424,9 @@ smash_dummy_type (type)
            {
              tree oldindex = TYPE_DOMAIN (origin);
              new_max = check_range (new_max, new_max, NULL_TREE,
-                                    size_binop (PLUS_EXPR,
-                                                TYPE_MAX_VALUE (oldindex),
-                                                integer_one_node));
+                                    fold (build (PLUS_EXPR, integer_type_node,
+                                                 TYPE_MAX_VALUE (oldindex),
+                                                 integer_one_node)));
              origin = build_string_type (TREE_TYPE (origin), new_max);
            }
          else if (TREE_CODE (origin) == ARRAY_TYPE)
@@ -3394,12 +3441,12 @@ smash_dummy_type (type)
            }
          else if (TREE_CODE (origin) == RECORD_TYPE)
            {
-             error ("parameterised structures not implemented");
+             error ("parameterized structures not implemented");
              return error_mark_node;
            }
          else
            {
-             error ("invalid parameterised type");
+             error ("invalid parameterized type");
              return error_mark_node;
            }
            
@@ -3439,8 +3486,8 @@ smash_dummy_type (type)
   if (save_readonly)
     { /* TYPE is READ ORIGIN.
         Add this type to the chain of variants of TYPE.  */
-      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (main);
-      TYPE_NEXT_VARIANT (main) = type;
+      TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (main_tree);
+      TYPE_NEXT_VARIANT (main_tree) = type;
       TYPE_READONLY (type) = save_readonly;
     }
   else
@@ -3671,137 +3718,6 @@ mark_addressable (exp)
     }
 }
 \f
-/* Return nonzero if VALUE is a valid constant-valued expression
-   for use in initializing a static variable; one that can be an
-   element of a "constant" initializer.
-
-   Return null_pointer_node if the value is absolute;
-   if it is relocatable, return the variable that determines the relocation.
-   We assume that VALUE has been folded as much as possible;
-   therefore, we do not need to check for such things as
-   arithmetic-combinations of integers.  */
-
-tree
-initializer_constant_valid_p (value, endtype)
-     tree value;
-     tree endtype;
-{
-  switch (TREE_CODE (value))
-    {
-    case CONSTRUCTOR:
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
-         && TREE_CONSTANT (value))
-       return
-         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-                                       endtype);
-       
-      return TREE_STATIC (value) ? null_pointer_node : 0;
-
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-      return null_pointer_node;
-
-    case ADDR_EXPR:
-      return TREE_OPERAND (value, 0);
-
-    case NON_LVALUE_EXPR:
-      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-    case CONVERT_EXPR:
-    case NOP_EXPR:
-      /* Allow conversions between pointer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between real types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow length-preserving conversions between integer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between other integer types only if
-        explicit value.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                    endtype);
-         if (inner == null_pointer_node)
-           return null_pointer_node;
-         return 0;
-       }
-
-      /* Allow (int) &foo provided int is as wide as a pointer.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Likewise conversions from int to pointers.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Allow conversions to union types if the value inside is okay.  */
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-      return 0;
-
-    case PLUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* If either term is absolute, use the other terms relocation.  */
-       if (valid0 == null_pointer_node)
-         return valid1;
-       if (valid1 == null_pointer_node)
-         return valid0;
-       return 0;
-      }
-
-    case MINUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* Win if second argument is absolute.  */
-       if (valid1 == null_pointer_node)
-         return valid0;
-       /* Win if both arguments have the same relocation.
-          Then the value is absolute.  */
-       if (valid0 == valid1)
-         return null_pointer_node;
-       return 0;
-      }
-    default:
-      return 0;
-    }
-}
-\f
 /* Return an integer type with BITS bits of precision,
    that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */
 
@@ -3838,8 +3754,10 @@ type_for_size (bits, unsignedp)
   if (bits <= TYPE_PRECISION (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
+#if HOST_BITS_PER_WIDE_INT >= 64
   if (bits <= TYPE_PRECISION (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
 
   return 0;
 }
@@ -3853,49 +3771,51 @@ type_for_mode (mode, unsignedp)
      enum machine_mode mode;
      int unsignedp;
 {
-  if (mode == TYPE_MODE (integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (integer_type_node))
     return unsignedp ? unsigned_type_node : integer_type_node;
 
-  if (mode == TYPE_MODE (signed_char_type_node))
+  if ((int)mode == (int)TYPE_MODE (signed_char_type_node))
     return unsignedp ? unsigned_char_type_node : signed_char_type_node;
 
-  if (mode == TYPE_MODE (short_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (short_integer_type_node))
     return unsignedp ? short_unsigned_type_node : short_integer_type_node;
 
-  if (mode == TYPE_MODE (long_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_integer_type_node))
     return unsignedp ? long_unsigned_type_node : long_integer_type_node;
 
-  if (mode == TYPE_MODE (long_long_integer_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_long_integer_type_node))
     return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node;
 
-  if (mode == TYPE_MODE (intQI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intQI_type_node))
     return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
 
-  if (mode == TYPE_MODE (intHI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intHI_type_node))
     return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
 
-  if (mode == TYPE_MODE (intSI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intSI_type_node))
     return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
 
-  if (mode == TYPE_MODE (intDI_type_node))
+  if ((int)mode == (int)TYPE_MODE (intDI_type_node))
     return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
 
-  if (mode == TYPE_MODE (intTI_type_node))
+#if HOST_BITS_PER_WIDE_INT >= 64
+  if ((int)mode == (int)TYPE_MODE (intTI_type_node))
     return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
 
-  if (mode == TYPE_MODE (float_type_node))
+  if ((int)mode == (int)TYPE_MODE (float_type_node))
     return float_type_node;
 
-  if (mode == TYPE_MODE (double_type_node))
+  if ((int)mode == (int)TYPE_MODE (double_type_node))
     return double_type_node;
 
-  if (mode == TYPE_MODE (long_double_type_node))
+  if ((int)mode == (int)TYPE_MODE (long_double_type_node))
     return long_double_type_node;
 
-  if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
+  if ((int)mode == (int)TYPE_MODE (build_pointer_type (char_type_node)))
     return build_pointer_type (char_type_node);
 
-  if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
+  if ((int)mode == (int)TYPE_MODE (build_pointer_type (integer_type_node)))
     return build_pointer_type (integer_type_node);
 
   return 0;