Patchwork RFA: partially hookize basic types *_TYPE_SIZE

login
register
mail settings
Submitter Joern Rennecke
Date Dec. 11, 2010, 5:14 p.m.
Message ID <20101211121425.qi5vylikws8w4wo4-nzlynne@webmail.spamcop.net>
Download mbox | patch
Permalink /patch/75202/
State New
Headers show

Comments

Joern Rennecke - Dec. 11, 2010, 5:14 p.m.
This patch hookizes BOOL_TYPE_SIZE, and the consumer side of the *_TYPE_SIZE
macros for the c-family integer and floating point sizes.

As discussed before, WCHAR_TYPE_SIZE, ADA_LONG_TYPE_SIZE, and the
stdint *_TYPE_SIZE macros can be handled differently, by translating to
a standard basic integer / floating point type first - that will need
hooks to be provided by a separate patch - and then looking up the size of
this type, by making use of the infrastructure provided by this patch.

Bootstrapped & regresion tested on x86_64-pc-linux-gnu .

cross-tested on x86_64-pc-linux-gnu for:
alpha-linux-gnu hppa-linux-gnu mips-elf sh-elf arc-elf ia64-elf  
mmix-knuth-mmixware sparc-elf arm-eabi iq2000-elf mn10300-elf spu-elf  
avr-elf lm32-elf moxie-elf v850-elf bfin-elf m32c-elf pdp11-aout  
vax-linux-gnu cris-elf m32r-elf picochip-elf xstormy16-elf crx-elf  
m68hc11-elf ppc-elf xtensa-elf fr30-elf m68k-elf rx-elf frv-elf  
mcore-elf s390-linux-gnu h8300-elf mep-elf score-elf

microblaze-elf is currently affected by PR target/46738
2010-12-11  Joern Rennecke  <amylaar@spamcop.net>

	PR other/46677
gcc:
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (BOOL_TYPE_SIZE): Delete.
	(TARGET_BOOL_TYPE_SIZE): New hook.
	* targhooks.c (legacy_integer_type_size): New function.
	(default_bool_type_size, legacy_float_type_size): Likewise.
	* targhooks.h (legacy_integer_type_size): Declare.
	(default_bool_type_size, legacy_float_type_size): Likewise.
	* target.def (bool_type_size): New hook.
	(integer_type_size, float_type_size): Likewise.
	* defaults.h (BOOL_TYPE_SIZE): Delete.
	* tree.c (free_lang_data): Use targetm.bool_type_size.
	(build_common_tree_nodes): Likewise.
	* tree.h (enum integer_type_kind): Move from here...
	* coretypes.h ... to here.
	* target.h (enum th_float_type): New enum.
	* tree-ssa-loop-ivopts.c (add_standard_iv_candidates):
	Use targetm.integer_type_size.
	* tree-data-ref.c: Include target.h
	(estimated_loop_iterations_tree): Use targetm.integer_type_size.
	* system.h (BOOL_TYPE_SIZE): Poison.
	* Makefile.in (tree-data-ref.o): Depend on $(TARGET_H) .
	* config/rs6000/darwin.h (BOOL_TYPE_SIZE): Delete.
	(darwin_bool_type_size): Declare.
	(TARGET_BOOL_TYPE_SIZE): Define.
	* config/darwin.c (darwin_bool_type_size): New function.
gcc/c-family.c:
	* c-common.c (c_common_to_target_charset):
	Use TYPE_PRECISION (char_type_node).
gcc/java:
	* decl.c (java_init_decl_processing): Use targetm.integer_type_size.
	* expr.c (expand_java_return): Likewise.
gcc/ada:
	* gcc-interface/decl.c (gnat_to_gnu_entity):
	Use targetm.float_type_size and targetm.integer_type_size.
	(make_type_from_size): Use targetm.integer_type_size.
	* gcc-interface/targtyps.c: Include target.h .
	[!ADA_LONG_TYPE_SIZE] (ADA_LONG_TYPE_SIZE):
	Use targetm.integer_type_size.
	[!WIDEST_HARDWARE_FP_SIZE] (LONG_DOUBLE_TYPE_SIZE): Don't define.
	(get_target_char_size): Use targetm.integer_type_size.
	(get_target_wchar_t_size, get_target_short_size): Likewise.
	(get_target_int_size, get_target_long_long_size): Likewise.
	(get_target_float_size): Use targetm.float_type_size.
	(get_target_double_size, get_target_long_double_size): Likewise.
	(MALLOC_OBSERVABLE_ALIGNMENT): Use targetm.integer_type_size.
	* gcc-interface/trans.c: Include target.h .
	(gigi): Use targetm.float_type_size.
	(build_binary_op_trapv): Use targetm.integer_type_size.
	* gcc-interface/Make-lang.in (ada/targtyps.o): Depend on $(TARGET_H).
	(ada/trans.o): Likewise.
gcc/fortran:
	* trans-types.c (gfc_init_kinds): Use targetm.integer_type_size.
	(gfc_build_int_type): Likewise.
	(gfc_build_uint_type): Use TYPE_PRECISION on the type nodes checked.
	(gfc_build_real_type): Use targetm.float_type_size.
	(gfc_build_logical_type): Use targetm.bool_type_size.
	[0] (c_size_t_size): Delete.
	* f95-lang.c [!CHAR_TYPE_SIZE] (CHAR_TYPE_SIZE): Don't define.
	[!INT_TYPE_SIZE] (INT_TYPE_SIZE): Likewise.
	* iso-c-binding.def (c_bool): Use targetm.bool_type_size.
	* types.def (BT_BOOL): Likewise.
	* trans-intrinsic.c (build_round_expr): Use TYPE_PRECISION
	on *_integer_type_node to find out these type's sizes.
	(gfc_conv_intrinsic_leadz, gfc_conv_intrinsic_trailz): Likewise.
	(gfc_conv_intrinsic_popcnt_poppar): Likewise.

Patch

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 167678)
+++ doc/tm.texi	(working copy)
@@ -1489,11 +1489,9 @@  @defmac CHAR_TYPE_SIZE
 @code{BITS_PER_UNIT}.
 @end defmac
 
-@defmac BOOL_TYPE_SIZE
-A C expression for the size in bits of the C++ type @code{bool} and
-C99 type @code{_Bool} on the target machine.  If you don't define
-this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
-@end defmac
+@deftypefn {Target Hook} int TARGET_BOOL_TYPE_SIZE (void)
+The size, in bits, of the boolean type used by most front ends that have such  a type.  (Java is an exception, because the language defines the type size.)   The default is @code{CHAR_TYPE_SIZE}.
+@end deftypefn
 
 @defmac FLOAT_TYPE_SIZE
 A C expression for the size in bits of the type @code{float} on the
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 167678)
+++ doc/tm.texi.in	(working copy)
@@ -1479,11 +1479,7 @@  @defmac CHAR_TYPE_SIZE
 @code{BITS_PER_UNIT}.
 @end defmac
 
-@defmac BOOL_TYPE_SIZE
-A C expression for the size in bits of the C++ type @code{bool} and
-C99 type @code{_Bool} on the target machine.  If you don't define
-this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
-@end defmac
+@hook TARGET_BOOL_TYPE_SIZE
 
 @defmac FLOAT_TYPE_SIZE
 A C expression for the size in bits of the type @code{float} on the
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 167678)
+++ targhooks.c	(working copy)
@@ -439,6 +439,56 @@  targhook_float_words_big_endian (void)
   return !!FLOAT_WORDS_BIG_ENDIAN;
 }
 
+int
+legacy_integer_type_size (enum integer_type_kind type)
+{
+  switch (type)
+    {
+    case itk_char:
+      return CHAR_TYPE_SIZE;
+    case itk_short:
+      return SHORT_TYPE_SIZE;
+    case itk_int:
+      return INT_TYPE_SIZE;
+    case itk_long:
+      return LONG_TYPE_SIZE;
+    case itk_long_long:
+      return LONG_LONG_TYPE_SIZE;
+    case itk_int128:
+      return 128;
+    default:
+      gcc_unreachable ();
+    }
+}
+
+/* `bool' has size and alignment `1', on almost all platforms.  */
+int
+default_bool_type_size (void)
+{
+  return CHAR_TYPE_SIZE;
+}
+
+int
+legacy_float_type_size (enum th_float_type type)
+{
+  switch (type)
+    {
+    case th_ft_float:
+      return FLOAT_TYPE_SIZE;
+    case th_ft_double:
+      return DOUBLE_TYPE_SIZE;
+    case th_ft_widest_hard_fp:
+#ifdef WIDEST_HARDWARE_FP_SIZE
+      return WIDEST_HARDWARE_FP_SIZE;
+#endif /* WIDEST_HARDWARE_FP_SIZE */
+      /* Fall through.  */
+    case th_ft_long_double:
+      return LONG_DOUBLE_TYPE_SIZE;
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* True if the target supports decimal floating point.  */
 
 bool
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 167678)
+++ targhooks.h	(working copy)
@@ -70,6 +70,9 @@  extern bool default_asm_output_addr_cons
 extern bool default_scalar_mode_supported_p (enum machine_mode);
 extern bool targhook_words_big_endian (void);
 extern bool targhook_float_words_big_endian (void);
+extern int legacy_integer_type_size (enum integer_type_kind);
+extern int default_bool_type_size (void);
+extern int legacy_float_type_size (enum th_float_type);
 extern bool default_decimal_float_supported_p (void);
 extern bool default_fixed_point_supported_p (void);
 
Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 167678)
+++ c-family/c-common.c	(working copy)
@@ -8408,8 +8408,11 @@  c_common_to_target_charset (HOST_WIDE_IN
   uc = cpp_host_to_exec_charset (parse_in, uc);
 
   if (flag_signed_char)
-    return ((HOST_WIDE_INT)uc) << (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE)
-			       >> (HOST_BITS_PER_WIDE_INT - CHAR_TYPE_SIZE);
+    {
+      unsigned shift = HOST_BITS_PER_WIDE_INT - TYPE_PRECISION (char_type_node);
+
+      return ((HOST_WIDE_INT)uc) << shift >> shift;
+    }
   else
     return uc;
 }
Index: java/decl.c
===================================================================
--- java/decl.c	(revision 167678)
+++ java/decl.c	(working copy)
@@ -610,7 +610,8 @@  java_init_decl_processing (void)
   set_sizetype (size_type_node);
 
   /* Define these next since types below may used them.  */
-  integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
+  integer_type_node
+    = java_type_for_size (targetm.integer_type_size (itk_int), 0);
   integer_zero_node = build_int_cst (NULL_TREE, 0);
   integer_one_node = build_int_cst (NULL_TREE, 1);
   integer_two_node = build_int_cst (NULL_TREE, 2);
Index: java/expr.c
===================================================================
--- java/expr.c	(revision 167678)
+++ java/expr.c	(working copy)
@@ -1275,9 +1275,9 @@  expand_java_return (tree type)
 
       /* Handle the situation where the native integer type is smaller
 	 than the JVM integer. It can happen for many cross compilers.
-	 The whole if expression just goes away if INT_TYPE_SIZE < 32
-	 is false. */
-      if (INT_TYPE_SIZE < 32
+	 The whole if expression just goes away if
+	 targetm.integer_type_size (itk_int) < 32 is false.  */
+      if (targetm.integer_type_size (itk_int) < 32
 	  && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
 	      < GET_MODE_SIZE (TYPE_MODE (type))))
 	retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
Index: target.def
===================================================================
--- target.def	(revision 167678)
+++ target.def	(working copy)
@@ -1178,6 +1178,26 @@  HOOK_VECTOR_END (vectorize)
  bool, (void),
  targhook_float_words_big_endian)
 
+DEFHOOK_UNDOC
+(integer_type_size,
+ "",
+ int, (enum integer_type_kind type),
+ legacy_integer_type_size)
+
+DEFHOOK
+(bool_type_size,
+ "The size, in bits, of the boolean type used by most front ends that have such\
+  a type.  (Java is an exception, because the language defines the type size.) \
+  The default is @code{CHAR_TYPE_SIZE}.",
+ int, (void),
+ default_bool_type_size)
+
+DEFHOOK_UNDOC
+(float_type_size,
+ "",
+ int, (enum th_float_type type),
+ legacy_float_type_size)
+
 /* True if the target supports decimal floating point.  */
 DEFHOOK
 (decimal_float_supported_p,
Index: defaults.h
===================================================================
--- defaults.h	(revision 167678)
+++ defaults.h	(working copy)
@@ -431,11 +431,6 @@  #define ASM_OUTPUT_MEASURED_SIZE(STREAM,
 #define CHAR_TYPE_SIZE BITS_PER_UNIT
 #endif
 
-#ifndef BOOL_TYPE_SIZE
-/* `bool' has size and alignment `1', on almost all platforms.  */
-#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE
-#endif
-
 #ifndef SHORT_TYPE_SIZE
 #define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
 #endif
Index: tree.c
===================================================================
--- tree.c	(revision 167678)
+++ tree.c	(working copy)
@@ -5087,11 +5087,11 @@  free_lang_data (void)
   fileptr_type_node = ptr_type_node;
   if (TREE_CODE (boolean_type_node) != BOOLEAN_TYPE
       || (TYPE_MODE (boolean_type_node)
-	  != mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0))
+	  != mode_for_size (targetm.bool_type_size (), MODE_INT, 0))
       || TYPE_PRECISION (boolean_type_node) != 1
       || !TYPE_UNSIGNED (boolean_type_node))
     {
-      boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
+      boolean_type_node = make_unsigned_type (targetm.bool_type_size ());
       TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
       TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
       TYPE_PRECISION (boolean_type_node) = 1;
@@ -9015,10 +9015,11 @@  build_common_tree_nodes (bool signed_cha
       }
 #endif
   /* Define a boolean type.  This type only represents boolean values but
-     may be larger than char depending on the value of BOOL_TYPE_SIZE.
+     may be larger than char depending on the value of
+     targetm.bool_type_size ().
      Front ends which want to override this size (i.e. Java) can redefine
      boolean_type_node before calling build_common_tree_nodes_2.  */
-  boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
+  boolean_type_node = make_unsigned_type (targetm.bool_type_size ());
   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
   TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
   TYPE_PRECISION (boolean_type_node) = 1;
Index: tree.h
===================================================================
--- tree.h	(revision 167678)
+++ tree.h	(working copy)
@@ -3876,30 +3876,6 @@  #define MAIN_NAME_P(NODE) \
 #define current_target_pragma		global_trees[TI_CURRENT_TARGET_PRAGMA]
 #define current_optimize_pragma		global_trees[TI_CURRENT_OPTIMIZE_PRAGMA]
 
-/* An enumeration of the standard C integer types.  These must be
-   ordered so that shorter types appear before longer ones, and so
-   that signed types appear before unsigned ones, for the correct
-   functioning of interpret_integer() in c-lex.c.  */
-enum integer_type_kind
-{
-  itk_char,
-  itk_signed_char,
-  itk_unsigned_char,
-  itk_short,
-  itk_unsigned_short,
-  itk_int,
-  itk_unsigned_int,
-  itk_long,
-  itk_unsigned_long,
-  itk_long_long,
-  itk_unsigned_long_long,
-  itk_int128,
-  itk_unsigned_int128,
-  itk_none
-};
-
-typedef enum integer_type_kind integer_type_kind;
-
 /* The standard C integer types.  Use integer_type_kind to index into
    this array.  */
 extern GTY(()) tree integer_types[itk_none];
Index: target.h
===================================================================
--- target.h	(revision 167678)
+++ target.h	(working copy)
@@ -163,6 +163,13 @@  struct default_options
   int value;
 };
 
+/* enums to describe types in target hooks.
+   integer_type_kind is defined in coretypes.h  */
+enum th_float_type
+{
+  th_ft_float, th_ft_double, th_ft_widest_hard_fp, th_ft_long_double
+};
+
 /* The target structure.  This holds all the backend hooks.  */
 #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
 #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c	(revision 167678)
+++ tree-ssa-loop-ivopts.c	(working copy)
@@ -2403,11 +2403,16 @@  add_standard_iv_candidates_for_size (str
 static void
 add_standard_iv_candidates (struct ivopts_data *data)
 {
-  add_standard_iv_candidates_for_size (data, INT_TYPE_SIZE);
+  /* FIXME: we shouldn't use type sizes here, but look at what sizes suit
+     the target.  */
+  add_standard_iv_candidates_for_size
+    (data, targetm.integer_type_size (itk_int));
 
   /* The same for a double-integer type if it is still fast enough.  */
-  if (BITS_PER_WORD >= INT_TYPE_SIZE * 2)
-    add_standard_iv_candidates_for_size (data, INT_TYPE_SIZE * 2);
+  if (BITS_PER_WORD >= targetm.integer_type_size (itk_int) * 2)
+    add_standard_iv_candidates_for_size (data,
+					 targetm.integer_type_size (itk_int)
+					 * 2);
 }
 
 
Index: ada/gcc-interface/decl.c
===================================================================
--- ada/gcc-interface/decl.c	(revision 167678)
+++ ada/gcc-interface/decl.c	(working copy)
@@ -394,17 +394,18 @@  gnat_to_gnu_entity (Entity_Id gnat_entit
 	  esize = UI_To_Int (Esize (gnat_entity));
 
 	  if (IN (kind, Float_Kind))
-	    max_esize = fp_prec_to_size (LONG_DOUBLE_TYPE_SIZE);
+	    max_esize
+	      = fp_prec_to_size (targetm.float_type_size (th_ft_long_double));
 	  else if (IN (kind, Access_Kind))
 	    max_esize = POINTER_SIZE * 2;
 	  else
-	    max_esize = LONG_LONG_TYPE_SIZE;
+	    max_esize = targetm.integer_type_size (itk_long_long);
 
 	  if (esize > max_esize)
 	   esize = max_esize;
 	}
       else
-	esize = LONG_LONG_TYPE_SIZE;
+	esize = targetm.integer_type_size (itk_long_long);
     }
 
   switch (kind)
@@ -7905,7 +7906,7 @@  set_rm_size (Uint uint_size, tree gnu_ty
 static tree
 make_type_from_size (tree type, tree size_tree, bool for_biased)
 {
-  unsigned HOST_WIDE_INT size;
+  unsigned HOST_WIDE_INT size, max;
   bool biased_p;
   tree new_type;
 
@@ -7935,8 +7936,9 @@  make_type_from_size (tree type, tree siz
 	break;
 
       biased_p |= for_biased;
-      if (size > LONG_LONG_TYPE_SIZE)
-	size = LONG_LONG_TYPE_SIZE;
+      max = targetm.integer_type_size (itk_long_long);
+      if (size > max)
+	size = max;
 
       if (TYPE_UNSIGNED (type) || biased_p)
 	new_type = make_unsigned_type (size);
Index: ada/gcc-interface/targtyps.c
===================================================================
--- ada/gcc-interface/targtyps.c	(revision 167678)
+++ ada/gcc-interface/targtyps.c	(working copy)
@@ -31,6 +31,7 @@ 
 #include "tree.h"
 #include "tm.h"
 #include "tm_p.h"
+#include "target.h"
 
 #include "ada.h"
 #include "types.h"
@@ -51,11 +52,7 @@ 
 /* If we don't have a specific size for Ada's equivalent of `long', use that
    of C.  */
 #ifndef ADA_LONG_TYPE_SIZE
-#define ADA_LONG_TYPE_SIZE LONG_TYPE_SIZE
-#endif
-
-#ifndef WIDEST_HARDWARE_FP_SIZE
-#define WIDEST_HARDWARE_FP_SIZE LONG_DOUBLE_TYPE_SIZE
+#define ADA_LONG_TYPE_SIZE (targetm.integer_type_size (itk_long))
 #endif
 
 /* The following provide a functional interface for the front end Ada code
@@ -76,26 +73,26 @@  get_target_bits_per_word (void)
 Pos
 get_target_char_size (void)
 {
-  return CHAR_TYPE_SIZE;
+  return targetm.integer_type_size (itk_char);
 }
 
 Pos
 get_target_wchar_t_size (void)
 {
   /* We never want wide characters less than "short" in Ada.  */
-  return MAX (SHORT_TYPE_SIZE, WCHAR_TYPE_SIZE);
+  return MAX (targetm.integer_type_size (itk_short), WCHAR_TYPE_SIZE);
 }
 
 Pos
 get_target_short_size (void)
 {
-  return SHORT_TYPE_SIZE;
+  return targetm.integer_type_size (itk_short);
 }
 
 Pos
 get_target_int_size (void)
 {
-  return INT_TYPE_SIZE;
+  return targetm.integer_type_size (itk_int);
 }
 
 Pos
@@ -107,25 +104,25 @@  get_target_long_size (void)
 Pos
 get_target_long_long_size (void)
 {
-  return LONG_LONG_TYPE_SIZE;
+  return targetm.integer_type_size (itk_long_long);
 }
 
 Pos
 get_target_float_size (void)
 {
-  return fp_prec_to_size (FLOAT_TYPE_SIZE);
+  return fp_prec_to_size (targetm.float_type_size (th_ft_float));
 }
 
 Pos
 get_target_double_size (void)
 {
-  return fp_prec_to_size (DOUBLE_TYPE_SIZE);
+  return fp_prec_to_size (targetm.float_type_size (th_ft_double));
 }
 
 Pos
 get_target_long_double_size (void)
 {
-  return fp_prec_to_size (WIDEST_HARDWARE_FP_SIZE);
+  return fp_prec_to_size (targetm.float_type_size (th_ft_widest_hard_fp));
 }
 
 Pos
@@ -166,7 +163,7 @@  get_target_maximum_default_alignment (vo
 #ifdef MALLOC_OBSERVABLE_ALIGNMENT
 #define MALLOC_ALIGNMENT MALLOC_OBSERVABLE_ALIGNMENT
 #else
-#define MALLOC_OBSERVABLE_ALIGNMENT (2 * LONG_TYPE_SIZE)
+#define MALLOC_OBSERVABLE_ALIGNMENT (2 * targetm.integer_type_size (itk_long))
 #define MALLOC_ALIGNMENT \
   MAX (MALLOC_ABI_ALIGNMENT, MALLOC_OBSERVABLE_ALIGNMENT)
 #endif
Index: ada/gcc-interface/Make-lang.in
===================================================================
--- ada/gcc-interface/Make-lang.in	(revision 167678)
+++ ada/gcc-interface/Make-lang.in	(working copy)
@@ -1242,11 +1242,11 @@  ada/targtyps.o : ada/gcc-interface/targt
    coretypes.h $(TM_H) $(TM_P_H) $(TREE_H) ada/gcc-interface/ada.h \
    ada/types.h ada/atree.h ada/elists.h ada/namet.h ada/nlists.h \
    ada/snames.h ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h \
-   ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
+   ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h $(TARGET_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
 
 ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h  \
+   $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h $(TARGET_H) \
    $(GIMPLE_H) ada/gcc-interface/ada.h ada/adadecode.h ada/types.h \
    ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \
    ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \
Index: ada/gcc-interface/trans.c
===================================================================
--- ada/gcc-interface/trans.c	(revision 167678)
+++ ada/gcc-interface/trans.c	(working copy)
@@ -34,6 +34,7 @@ 
 #include "libfuncs.h"	/* For set_stack_check_libfunc.  */
 #include "tree-iterator.h"
 #include "gimple.h"
+#include "target.h"
 
 #include "ada.h"
 #include "adadecode.h"
@@ -557,7 +558,8 @@  gigi (Node_Id gnat_root, int max_gnat_no
       /* In this case, the builtin floating point types are VAX float,
 	 so make up a type for use.  */
       longest_float_type_node = make_node (REAL_TYPE);
-      TYPE_PRECISION (longest_float_type_node) = LONG_DOUBLE_TYPE_SIZE;
+      TYPE_PRECISION (longest_float_type_node)
+	= targetm.float_type_size (th_ft_long_double);
       layout_type (longest_float_type_node);
       record_builtin_type ("longest float type", longest_float_type_node);
     }
@@ -6789,7 +6791,8 @@  build_binary_op_trapv (enum tree_code co
 
       else if (needed_precision <= BITS_PER_WORD
 	       || (code == MULT_EXPR
-		   && needed_precision <= LONG_LONG_TYPE_SIZE))
+		   && (needed_precision
+		       <= targetm.integer_type_size (itk_long_long))))
 	{
 	  tree wide_type = gnat_type_for_size (needed_precision, 0);
 
Index: fortran/iso-c-binding.def
===================================================================
--- fortran/iso-c-binding.def	(revision 167678)
+++ fortran/iso-c-binding.def	(working copy)
@@ -116,7 +116,7 @@  NAMED_CMPXCST (ISOCBINDING_LONG_DOUBLE_C
                get_real_kind_from_node (long_double_type_node))
 
 NAMED_LOGCST (ISOCBINDING_BOOL, "c_bool", \
-              get_int_kind_from_width (BOOL_TYPE_SIZE))
+              get_int_kind_from_width (targetm.bool_type_size ()))
 
 NAMED_CHARKNDCST (ISOCBINDING_CHAR, "c_char", gfc_default_character_kind)
 
Index: fortran/trans-types.c
===================================================================
--- fortran/trans-types.c	(revision 167678)
+++ fortran/trans-types.c	(working copy)
@@ -568,7 +568,7 @@  gfc_init_kinds (void)
   /* Choose the integer kind the same size as "void*" for our index kind.  */
   gfc_index_integer_kind = POINTER_SIZE / 8;
   /* Pick a kind the same size as the C "int" type.  */
-  gfc_c_int_kind = INT_TYPE_SIZE / 8;
+  gfc_c_int_kind = targetm.integer_type_size (itk_int) / 8;
 
   /* initialize the C interoperable kinds  */
   init_c_interop_kinds();
@@ -671,15 +671,15 @@  gfc_build_int_type (gfc_integer_info *in
 {
   int mode_precision = info->bit_size;
 
-  if (mode_precision == CHAR_TYPE_SIZE)
+  if (mode_precision == targetm.integer_type_size (itk_char))
     info->c_char = 1;
-  if (mode_precision == SHORT_TYPE_SIZE)
+  if (mode_precision == targetm.integer_type_size (itk_short))
     info->c_short = 1;
-  if (mode_precision == INT_TYPE_SIZE)
+  if (mode_precision == targetm.integer_type_size (itk_int))
     info->c_int = 1;
-  if (mode_precision == LONG_TYPE_SIZE)
+  if (mode_precision == targetm.integer_type_size (itk_long))
     info->c_long = 1;
-  if (mode_precision == LONG_LONG_TYPE_SIZE)
+  if (mode_precision == targetm.integer_type_size (itk_long_long))
     info->c_long_long = 1;
 
   if (TYPE_PRECISION (intQI_type_node) == mode_precision)
@@ -699,15 +699,15 @@  gfc_build_int_type (gfc_integer_info *in
 tree
 gfc_build_uint_type (int size)
 {
-  if (size == CHAR_TYPE_SIZE)
+  if (size == TYPE_PRECISION (unsigned_char_type_node))
     return unsigned_char_type_node;
-  if (size == SHORT_TYPE_SIZE)
+  if (size == TYPE_PRECISION (short_unsigned_type_node))
     return short_unsigned_type_node;
-  if (size == INT_TYPE_SIZE)
+  if (size == TYPE_PRECISION (unsigned_type_node))
     return unsigned_type_node;
-  if (size == LONG_TYPE_SIZE)
+  if (size == TYPE_PRECISION (long_unsigned_type_node))
     return long_unsigned_type_node;
-  if (size == LONG_LONG_TYPE_SIZE)
+  if (size == TYPE_PRECISION (long_long_unsigned_type_node))
     return long_long_unsigned_type_node;
 
   return make_unsigned_type (size);
@@ -720,13 +720,14 @@  gfc_build_real_type (gfc_real_info *info
   int mode_precision = info->mode_precision;
   tree new_type;
 
-  if (mode_precision == FLOAT_TYPE_SIZE)
+  if (mode_precision == targetm.float_type_size (th_ft_float))
     info->c_float = 1;
-  if (mode_precision == DOUBLE_TYPE_SIZE)
+  if (mode_precision == targetm.float_type_size (th_ft_double))
     info->c_double = 1;
-  if (mode_precision == LONG_DOUBLE_TYPE_SIZE)
+  if (mode_precision == targetm.float_type_size (th_ft_long_double))
     info->c_long_double = 1;
-  if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
+  if (mode_precision != targetm.float_type_size (th_ft_long_double)
+      && mode_precision == 128)
     {
       info->c_float128 = 1;
       gfc_real16_is_float128 = true;
@@ -771,7 +772,7 @@  gfc_build_logical_type (gfc_logical_info
   int bit_size = info->bit_size;
   tree new_type;
 
-  if (bit_size == BOOL_TYPE_SIZE)
+  if (bit_size == targetm.bool_type_size ())
     {
       info->c_bool = 1;
       return boolean_type_node;
@@ -785,27 +786,6 @@  gfc_build_logical_type (gfc_logical_info
   return new_type;
 }
 
-
-#if 0
-/* Return the bit size of the C "size_t".  */
-
-static unsigned int
-c_size_t_size (void)
-{
-#ifdef SIZE_TYPE  
-  if (strcmp (SIZE_TYPE, "unsigned int") == 0)
-    return INT_TYPE_SIZE;
-  if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
-    return LONG_TYPE_SIZE;
-  if (strcmp (SIZE_TYPE, "short unsigned int") == 0)
-    return SHORT_TYPE_SIZE;
-  gcc_unreachable ();
-#else
-  return LONG_TYPE_SIZE;
-#endif
-}
-#endif
-
 /* Create the backend type nodes. We map them to their
    equivalent C type, at least for now.  We also give
    names to the types here, and we push them in the
Index: fortran/f95-lang.c
===================================================================
--- fortran/f95-lang.c	(revision 167678)
+++ fortran/f95-lang.c	(working copy)
@@ -551,14 +551,6 @@  clear_binding_stack (void)
 }
 
 
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
-
-#ifndef INT_TYPE_SIZE
-#define INT_TYPE_SIZE BITS_PER_WORD
-#endif
-
 #undef SIZE_TYPE
 #define SIZE_TYPE "long unsigned int"
 
Index: fortran/types.def
===================================================================
--- fortran/types.def	(revision 167678)
+++ fortran/types.def	(working copy)
@@ -51,7 +51,8 @@  Software Foundation; either version 3, o
 
 DEF_PRIMITIVE_TYPE (BT_VOID, void_type_node)
 DEF_PRIMITIVE_TYPE (BT_BOOL,
-		    (*lang_hooks.types.type_for_size) (BOOL_TYPE_SIZE, 1))
+		    (*lang_hooks.types.type_for_size)
+		     (targetm.bool_type_size (), 1))
 DEF_PRIMITIVE_TYPE (BT_INT, integer_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT, unsigned_type_node)
 DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node)
Index: fortran/trans-intrinsic.c
===================================================================
--- fortran/trans-intrinsic.c	(revision 167678)
+++ fortran/trans-intrinsic.c	(working copy)
@@ -385,9 +385,9 @@  build_round_expr (tree arg, tree restype
   /* Depending on the type of the result, choose the long int intrinsic
      (lround family) or long long intrinsic (llround).  We might also
      need to convert the result afterwards.  */
-  if (resprec <= LONG_TYPE_SIZE)
+  if (resprec <= TYPE_PRECISION (long_integer_type_node))
     longlong = false;
-  else if (resprec <= LONG_LONG_TYPE_SIZE)
+  else if (resprec <= TYPE_PRECISION (long_long_integer_type_node))
     longlong = true;
   else
     gcc_unreachable ();
@@ -3555,24 +3555,24 @@  gfc_conv_intrinsic_leadz (gfc_se * se, g
   argsize = TYPE_PRECISION (TREE_TYPE (arg));
 
   /* Which variant of __builtin_clz* should we call?  */
-  if (argsize <= INT_TYPE_SIZE)
+  if (argsize <= TYPE_PRECISION (unsigned_type_node))
     {
       arg_type = unsigned_type_node;
       func = built_in_decls[BUILT_IN_CLZ];
     }
-  else if (argsize <= LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_unsigned_type_node))
     {
       arg_type = long_unsigned_type_node;
       func = built_in_decls[BUILT_IN_CLZL];
     }
-  else if (argsize <= LONG_LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_long_unsigned_type_node))
     {
       arg_type = long_long_unsigned_type_node;
       func = built_in_decls[BUILT_IN_CLZLL];
     }
   else
     {
-      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
+      gcc_assert (argsize == 2 * TYPE_PRECISION (long_long_unsigned_type_node));
       arg_type = gfc_build_uint_type (argsize);
       func = NULL_TREE;
     }
@@ -3609,7 +3609,8 @@  gfc_conv_intrinsic_leadz (gfc_se * se, g
 	 is the bit-size of the long long type (64 in this example).  */
       tree ullsize, ullmax, tmp1, tmp2;
 
-      ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
+      ullsize = build_int_cst (result_type,
+			       TYPE_PRECISION (long_long_unsigned_type_node));
       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
 				long_long_unsigned_type_node,
 				build_int_cst (long_long_unsigned_type_node,
@@ -3674,24 +3675,24 @@  gfc_conv_intrinsic_trailz (gfc_se * se, 
   argsize = TYPE_PRECISION (TREE_TYPE (arg));
 
   /* Which variant of __builtin_ctz* should we call?  */
-  if (argsize <= INT_TYPE_SIZE)
+  if (argsize <= TYPE_PRECISION (unsigned_type_node))
     {
       arg_type = unsigned_type_node;
       func = built_in_decls[BUILT_IN_CTZ];
     }
-  else if (argsize <= LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_unsigned_type_node))
     {
       arg_type = long_unsigned_type_node;
       func = built_in_decls[BUILT_IN_CTZL];
     }
-  else if (argsize <= LONG_LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_long_unsigned_type_node))
     {
       arg_type = long_long_unsigned_type_node;
       func = built_in_decls[BUILT_IN_CTZLL];
     }
   else
     {
-      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
+      gcc_assert (argsize == 2 * TYPE_PRECISION (long_long_unsigned_type_node));
       arg_type = gfc_build_uint_type (argsize);
       func = NULL_TREE;
     }
@@ -3723,7 +3724,8 @@  gfc_conv_intrinsic_trailz (gfc_se * se, 
 	 is the bit-size of the long long type (64 in this example).  */
       tree ullsize, ullmax, tmp1, tmp2;
 
-      ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
+      ullsize = build_int_cst (result_type,
+			       TYPE_PRECISION (long_long_unsigned_type_node));
       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
 				long_long_unsigned_type_node,
 				build_int_cst (long_long_unsigned_type_node, 0));
@@ -3780,17 +3782,17 @@  gfc_conv_intrinsic_popcnt_poppar (gfc_se
   result_type = gfc_get_int_type (gfc_default_integer_kind);
 
   /* Which variant of the builtin should we call?  */
-  if (argsize <= INT_TYPE_SIZE)
+  if (argsize <= TYPE_PRECISION (unsigned_type_node))
     {
       arg_type = unsigned_type_node;
       func = built_in_decls[parity ? BUILT_IN_PARITY : BUILT_IN_POPCOUNT];
     }
-  else if (argsize <= LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_unsigned_type_node))
     {
       arg_type = long_unsigned_type_node;
       func = built_in_decls[parity ? BUILT_IN_PARITYL : BUILT_IN_POPCOUNTL];
     }
-  else if (argsize <= LONG_LONG_TYPE_SIZE)
+  else if (argsize <= TYPE_PRECISION (long_long_unsigned_type_node))
     {
       arg_type = long_long_unsigned_type_node;
       func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
@@ -3804,7 +3806,7 @@  gfc_conv_intrinsic_popcnt_poppar (gfc_se
 
       /* For now, we only cover the case where argsize is twice as large
 	 as 'long long'.  */
-      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
+      gcc_assert (argsize == 2 * TYPE_PRECISION (long_long_unsigned_type_node));
 
       func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
 
@@ -3818,8 +3820,10 @@  gfc_conv_intrinsic_popcnt_poppar (gfc_se
 				   fold_convert (long_long_unsigned_type_node,
 						 arg));
 
-      arg2 = fold_build2_loc (input_location, RSHIFT_EXPR, utype, arg,
-			      build_int_cst (utype, LONG_LONG_TYPE_SIZE));
+      arg2 = (fold_build2_loc
+	       (input_location, RSHIFT_EXPR, utype, arg,
+		build_int_cst (utype,
+			       TYPE_PRECISION (long_long_unsigned_type_node))));
       call2 = build_call_expr_loc (input_location, func, 1,
 				   fold_convert (long_long_unsigned_type_node,
 						 arg2));
Index: tree-data-ref.c
===================================================================
--- tree-data-ref.c	(revision 167678)
+++ tree-data-ref.c	(working copy)
@@ -92,6 +92,7 @@  Software Foundation; either version 3, o
 #include "tree-scalar-evolution.h"
 #include "tree-pass.h"
 #include "langhooks.h"
+#include "target.h"
 
 static struct datadep_stats
 {
@@ -1635,7 +1636,12 @@  estimated_loop_iterations_tree (struct l
   if (!estimated_loop_iterations (loop, conservative, &nit))
     return chrec_dont_know;
 
-  type = lang_hooks.types.type_for_size (INT_TYPE_SIZE, true);
+  /* FIXME: this seems rather iffy; better choices might be
+     TYPE_PRECISION (int_type_mode) or BITS_PER_WORD.  However, that would
+     not be bug-compatible, and for targets that have multiple fast integer
+     modes, all should be handled; likewise for signedness.  */
+  type = lang_hooks.types.type_for_size (targetm.integer_type_size (itk_int),
+					 true);
   if (!double_int_fits_to_tree_p (type, nit))
     return chrec_dont_know;
 
Index: coretypes.h
===================================================================
--- coretypes.h	(revision 167678)
+++ coretypes.h	(working copy)
@@ -157,6 +157,30 @@  #define gcc_obstack_init(OBSTACK)			\
    in target.h.  */
 typedef int reg_class_t;
 
+/* An enumeration of the standard C integer types.  These must be
+   ordered so that shorter types appear before longer ones, and so
+   that signed types appear before unsigned ones, for the correct
+   functioning of interpret_integer() in c-lex.c.  */
+enum integer_type_kind
+{
+  itk_char,
+  itk_signed_char,
+  itk_unsigned_char,
+  itk_short,
+  itk_unsigned_short,
+  itk_int,
+  itk_unsigned_int,
+  itk_long,
+  itk_unsigned_long,
+  itk_long_long,
+  itk_unsigned_long_long,
+  itk_int128,
+  itk_unsigned_int128,
+  itk_none
+};
+
+typedef enum integer_type_kind integer_type_kind;
+
 #else
 
 struct _dont_use_rtx_here_;
Index: system.h
===================================================================
--- system.h	(revision 167678)
+++ system.h	(working copy)
@@ -759,7 +759,7 @@  #define gcc_assert(EXPR) 						\
 	LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP			\
 	LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP 		\
 	CAN_DEBUG_WITHOUT_FP UNLIKELY_EXECUTED_TEXT_SECTION_NAME	\
-	HOT_TEXT_SECTION_NAME
+	HOT_TEXT_SECTION_NAME BOOL_TYPE_SIZE
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 167678)
+++ Makefile.in	(working copy)
@@ -2670,7 +2670,7 @@  tree-scalar-evolution.o: tree-scalar-evo
    gt-tree-scalar-evolution.h tree-pretty-print.h gimple-pretty-print.h
 tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(GGC_H) $(FLAGS_H) $(TREE_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
-   $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
+   $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) $(TARGET_H) \
    $(TREE_DATA_REF_H) $(TREE_PASS_H) langhooks.h tree-pretty-print.h \
    gimple-pretty-print.h
 sese.o: sese.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
Index: config/rs6000/darwin.h
===================================================================
--- config/rs6000/darwin.h	(revision 167678)
+++ config/rs6000/darwin.h	(working copy)
@@ -369,7 +369,8 @@  #define BLOCK_REG_PADDING(MODE, TYPE, FI
 /* For binary compatibility with 2.95; Darwin C APIs use bool from
    stdbool.h, which was an int-sized enum in 2.95.  Users can explicitly
    choose to have sizeof(bool)==1 with the -mone-byte-bool switch. */
-#define BOOL_TYPE_SIZE (darwin_one_byte_bool ? CHAR_TYPE_SIZE : INT_TYPE_SIZE)
+extern int darwin_bool_type_size (void);
+#define TARGET_BOOL_TYPE_SIZE darwin_bool_type_size
 
 #undef REGISTER_TARGET_PRAGMAS
 #define REGISTER_TARGET_PRAGMAS() \
Index: config/darwin.c
===================================================================
--- config/darwin.c	(revision 167678)
+++ config/darwin.c	(working copy)
@@ -2998,4 +2998,10 @@  darwin_function_section (tree decl, enum
     }
 }
 
+int
+darwin_bool_type_size (void)
+{
+  return darwin_one_byte_bool ? CHAR_TYPE_SIZE : INT_TYPE_SIZE;
+}
+
 #include "gt-darwin.h"