This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Introduce abi_word_mode


Hi,

I'm currently working on a s390 patch which needs gcc to 
use internally a different word mode than the ABI-visible one.
More precisely I want 32bit applications to 
make use of 64bit registers without breaking the 32bit ABI. 
I think the only target providing something like that is power
currently.

The problem with this is that gcc is not aware that there
might be two different word modes one representing the actual
register width and one to be used whenever the ABI comes into
play. Ulrichs idea was to introduce an abi_word_mode to address
this. As the name suggests this would be the mode to be used
whenever a register or a register-size value is externally
visible. For everything else word_mode is used as before.

Unfortunately simply introducing abi_word_mode is the by far
easiest part of this. The difficult part is to decide for
every occurence of word_mode in the middle-end whether this
maybe ABI relevant. I've tried this and the result ist the 
attached patch.


Doing this I found two mechanisms which I guess were introduced to help
the power back end to deal with these issues. The attached patch removes
both since the same can be achieved more easily now using the abi_word_mode:

1.) STACK_SIZE_MODE although I'm not sure whether word_mode
is a good choice at all (see below) it can be replaced by 
abi_word_mode which makes the rs6000 bits defining it obsolete.

2.) TARGET_EH_RETURN_FILTER_MODE is used to special case
word_mode in get_exception_filter.


While grepping for word_mode I've found several uses of
word_mode which don't seem to be correct:

1.) The errno variable should be a signed int right?! So the use 
of word_mode in expand_errno_check looks odd to me. 
The patch leaves this as is.

2.) expand_builtin_extend_pointer currently converts a ptr_mode
address to word_mode. Shouldn't this be Pmode?
Thats the reason why there is a BT_WORD primitive type defined in
builtin-types.def. The only usage of this seems to be to define
the function type of builtin_extend_pointer. The patch replaces
word_mode with abi_word_mode to have 32bit pointers when building
a 32bit application even if word_mode is defined to be 64bit.

3.) STACK_SIZE_MODE is used when performing an add or sub on the
stack pointer. It currently defaults to word_mode. Since the
stack pointer is a Pmode value I would expect this to be Pmode
as well. The patch uses abi_word_mode here to mimic what the
rs6000 back end wants to see by defining STACK_SIZE_MODE.


The patch is a non-functional change for all targets except rs6000. 
So its not suprising that everything bootstraps as usual and no 
testsuite regression occurs on i686, s390 and s390x.

It can only be tested on targets defining UNITS_PER_ABI_WORD
different from UNITS_PER_WORD. The patch already does this for 
rs6000 (although untested yet) and I've an experimental patch 
doing this for s390. With the s390 patch on top I've successfully 
boostrapped an 31bit gcc with --with-mode=zarch without getting 
any testsuite regressions.
(Btw. in order to make this work properly in conjunction with signal 
handling also a kernel patch is needed.)

Originally I planned to use the abi_word_mode also in the middle end code
handling function arguments and return values. That would have simplified the 
back end code a bit since it wouldn't be necessary to emit PARALLELs to tell
the middle end that values bigger than abi_word_mode are distributed over
several registers. But unfortunately it turned out to add a lot of extra
complexity to the middle-end. When the middle-end splits input or return
values wider than word_mode into several argument registers it relies on the
fact that it is always possible to access word_mode parts of the value 
(using operand_subword). When the abi_word_mode is smaller than word_mode it is
necessary to have a more general mechanism splitting function arguments and
return values - operand_subword can't be used anymore. So it seems to be much
easier to let the back end handle this.


Ok for gcc 4.3?

Bye,

-Andreas-


Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/c-common.c	2006-09-26 08:54:36.000000000 +0200
*************** handle_mode_attribute (tree *node, tree 
*** 4489,4495 ****
        if (!strcmp (p, "byte"))
  	mode = byte_mode;
        else if (!strcmp (p, "word"))
! 	mode = word_mode;
        else if (!strcmp (p, "pointer"))
  	mode = ptr_mode;
        else
--- 4489,4495 ----
        if (!strcmp (p, "byte"))
  	mode = byte_mode;
        else if (!strcmp (p, "word"))
! 	mode = abi_word_mode;
        else if (!strcmp (p, "pointer"))
  	mode = ptr_mode;
        else
Index: gcc/except.c
===================================================================
*** gcc/except.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/except.c	2006-09-26 08:54:36.000000000 +0200
*************** init_eh (void)
*** 368,374 ****
        DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
  
        tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
!       tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1),
  			      tmp);
        f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
        DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
--- 368,374 ----
        DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
  
        tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
!       tmp = build_array_type (lang_hooks.types.type_for_mode (abi_word_mode, 1),
  			      tmp);
        f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
        DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
*************** get_exception_filter (struct function *f
*** 618,624 ****
    rtx filter = fun->eh->filter;
    if (fun == cfun && ! filter)
      {
!       filter = gen_reg_rtx (targetm.eh_return_filter_mode ());
        fun->eh->filter = filter;
      }
    return filter;
--- 618,624 ----
    rtx filter = fun->eh->filter;
    if (fun == cfun && ! filter)
      {
!       filter = gen_reg_rtx (abi_word_mode);
        fun->eh->filter = filter;
      }
    return filter;
*************** build_post_landing_pads (void)
*** 1452,1459 ****
  			emit_cmp_and_jump_insns
  			  (cfun->eh->filter,
  			   GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
! 			   EQ, NULL_RTX,
! 			   targetm.eh_return_filter_mode (), 0, c->label);
  
  			tp_node = TREE_CHAIN (tp_node);
  			flt_node = TREE_CHAIN (flt_node);
--- 1452,1458 ----
  			emit_cmp_and_jump_insns
  			  (cfun->eh->filter,
  			   GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
! 			   EQ, NULL_RTX, abi_word_mode, 0, c->label);
  
  			tp_node = TREE_CHAIN (tp_node);
  			flt_node = TREE_CHAIN (flt_node);
*************** build_post_landing_pads (void)
*** 1486,1492 ****
  	  emit_cmp_and_jump_insns (cfun->eh->filter,
  				   GEN_INT (region->u.allowed.filter),
  				   EQ, NULL_RTX,
! 				   targetm.eh_return_filter_mode (), 0, region->label);
  
  	  /* We delay the generation of the _Unwind_Resume until we generate
  	     landing pads.  We emit a marker here so as to get good control
--- 1485,1491 ----
  	  emit_cmp_and_jump_insns (cfun->eh->filter,
  				   GEN_INT (region->u.allowed.filter),
  				   EQ, NULL_RTX,
! 				   abi_word_mode, 0, region->label);
  
  	  /* We delay the generation of the _Unwind_Resume until we generate
  	     landing pads.  We emit a marker here so as to get good control
*************** dw2_build_landing_pads (void)
*** 1639,1645 ****
        emit_move_insn (cfun->eh->exc_ptr,
  		      gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
        emit_move_insn (cfun->eh->filter,
! 		      gen_rtx_REG (targetm.eh_return_filter_mode (),
  				   EH_RETURN_DATA_REGNO (1)));
  
        seq = get_insns ();
--- 1638,1644 ----
        emit_move_insn (cfun->eh->exc_ptr,
  		      gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
        emit_move_insn (cfun->eh->filter,
! 		      gen_rtx_REG (abi_word_mode,
  				   EH_RETURN_DATA_REGNO (1)));
  
        seq = get_insns ();
*************** sjlj_emit_dispatch_table (rtx dispatch_l
*** 1992,1999 ****
  			sjlj_fc_call_site_ofs);
    dispatch = copy_to_reg (mem);
  
!   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
!   if (word_mode != ptr_mode)
      {
  #ifdef POINTERS_EXTEND_UNSIGNED
        mem = convert_memory_address (ptr_mode, mem);
--- 1991,1998 ----
  			sjlj_fc_call_site_ofs);
    dispatch = copy_to_reg (mem);
  
!   mem = adjust_address (fc, abi_word_mode, sjlj_fc_data_ofs);
!   if (abi_word_mode != ptr_mode)
      {
  #ifdef POINTERS_EXTEND_UNSIGNED
        mem = convert_memory_address (ptr_mode, mem);
*************** sjlj_emit_dispatch_table (rtx dispatch_l
*** 2003,2009 ****
      }
    emit_move_insn (cfun->eh->exc_ptr, mem);
  
!   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
    emit_move_insn (cfun->eh->filter, mem);
  
    /* Jump to one of the directly reachable regions.  */
--- 2002,2008 ----
      }
    emit_move_insn (cfun->eh->exc_ptr, mem);
  
!   mem = adjust_address (fc, abi_word_mode, sjlj_fc_data_ofs + UNITS_PER_ABI_WORD);
    emit_move_insn (cfun->eh->filter, mem);
  
    /* Jump to one of the directly reachable regions.  */
*************** expand_builtin_extend_pointer (tree addr
*** 3025,3031 ****
    extend = 1;
  #endif
  
!   return convert_modes (word_mode, ptr_mode, addr, extend);
  }
  
  /* In the following functions, we represent entries in the action table
--- 3024,3030 ----
    extend = 1;
  #endif
  
!   return convert_modes (abi_word_mode, ptr_mode, addr, extend);
  }
  
  /* In the following functions, we represent entries in the action table
Index: gcc/defaults.h
===================================================================
*** gcc/defaults.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/defaults.h	2006-09-26 08:54:36.000000000 +0200
*************** Software Foundation, 51 Franklin Street,
*** 394,399 ****
--- 394,403 ----
     your target, you should override these values by defining the
     appropriate symbols in your tm.h file.  */
  
+ #ifndef UNITS_PER_ABI_WORD
+ #define UNITS_PER_ABI_WORD UNITS_PER_WORD
+ #endif
+ 
  #ifndef BITS_PER_UNIT
  #define BITS_PER_UNIT 8
  #endif
*************** Software Foundation, 51 Franklin Street,
*** 402,407 ****
--- 406,415 ----
  #define BITS_PER_WORD (BITS_PER_UNIT * UNITS_PER_WORD)
  #endif
  
+ #ifndef BITS_PER_ABI_WORD
+ #define BITS_PER_ABI_WORD (BITS_PER_UNIT * UNITS_PER_ABI_WORD)
+ #endif
+ 
  #ifndef CHAR_TYPE_SIZE
  #define CHAR_TYPE_SIZE BITS_PER_UNIT
  #endif
Index: gcc/builtin-types.def
===================================================================
*** gcc/builtin-types.def.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/builtin-types.def	2006-09-26 08:54:36.000000000 +0200
*************** DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_lo
*** 74,80 ****
  DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node)
  DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
  DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
! DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 0))
  DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
  DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
  DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
--- 74,80 ----
  DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node)
  DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
  DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
! DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (abi_word_mode, 0))
  DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
  DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
  DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
Index: gcc/java/constants.c
===================================================================
*** gcc/java/constants.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/java/constants.c	2006-09-26 08:54:36.000000000 +0200
*************** build_constants_constructor (void)
*** 508,515 ****
  	     FIXME: This is a kludge.  The field we're initializing is
  	     not a scalar but a union, and that's how we should
  	     represent it in the compiler.  We should fix this.  */
! 	  if (BYTES_BIG_ENDIAN && BITS_PER_WORD > 32)
! 	    temp <<= BITS_PER_WORD - 32;
  
  	  tags_list
  	    = tree_cons (NULL_TREE, 
--- 508,515 ----
  	     FIXME: This is a kludge.  The field we're initializing is
  	     not a scalar but a union, and that's how we should
  	     represent it in the compiler.  We should fix this.  */
! 	  if (BYTES_BIG_ENDIAN && BITS_PER_ABI_WORD > 32)
! 	    temp <<= BITS_PER_ABI_WORD - 32;
  
  	  tags_list
  	    = tree_cons (NULL_TREE, 
Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/emit-rtl.c	2006-09-26 08:54:36.000000000 +0200
*************** Software Foundation, 51 Franklin Street,
*** 62,67 ****
--- 62,68 ----
  
  enum machine_mode byte_mode;	/* Mode whose width is BITS_PER_UNIT.  */
  enum machine_mode word_mode;	/* Mode whose width is BITS_PER_WORD.  */
+ enum machine_mode abi_word_mode;/* Mode whose width is BITS_PER_ABI_WORD.  */
  enum machine_mode double_mode;	/* Mode whose width is DOUBLE_TYPE_SIZE.  */
  enum machine_mode ptr_mode;	/* Mode whose width is POINTER_SIZE.  */
  
*************** init_emit_once (int line_numbers)
*** 5114,5119 ****
--- 5115,5121 ----
  
    byte_mode = VOIDmode;
    word_mode = VOIDmode;
+   abi_word_mode = VOIDmode;
    double_mode = VOIDmode;
  
    for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
*************** init_emit_once (int line_numbers)
*** 5127,5132 ****
--- 5129,5138 ----
        if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
  	  && word_mode == VOIDmode)
  	word_mode = mode;
+ 
+       if (GET_MODE_BITSIZE (mode) == BITS_PER_ABI_WORD
+ 	  && abi_word_mode == VOIDmode)
+ 	abi_word_mode = mode;
      }
  
    for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
Index: gcc/machmode.h
===================================================================
*** gcc/machmode.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/machmode.h	2006-09-26 08:54:36.000000000 +0200
*************** extern const unsigned char class_narrowe
*** 171,176 ****
--- 171,177 ----
  
  extern enum machine_mode byte_mode;
  extern enum machine_mode word_mode;
+ extern enum machine_mode abi_word_mode;
  extern enum machine_mode ptr_mode;
  
  /* Target-dependent machine mode initialization - in insn-modes.c.  */
Index: gcc/target.h
===================================================================
*** gcc/target.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/target.h	2006-09-26 08:54:36.000000000 +0200
*************** struct gcc_target
*** 381,389 ****
       form was.  Return true if the switch was valid.  */
    bool (* handle_option) (size_t code, const char *arg, int value);
  
-   /* Return machine mode for filter value.  */
-   enum machine_mode (* eh_return_filter_mode) (void);
- 
    /* Given two decls, merge their attributes and return the result.  */
    tree (* merge_decl_attributes) (tree, tree);
  
--- 381,386 ----
Index: gcc/target-def.h
===================================================================
*** gcc/target-def.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/target-def.h	2006-09-26 08:54:36.000000000 +0200
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 340,348 ****
  
  #define TARGET_HANDLE_OPTION hook_bool_size_t_constcharptr_int_true
  
- /* In except.c */
- #define TARGET_EH_RETURN_FILTER_MODE  default_eh_return_filter_mode
- 
  /* In tree.c.  */
  #define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
  #define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
--- 340,345 ----
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 610,616 ****
    TARGET_VECTORIZE,				\
    TARGET_DEFAULT_TARGET_FLAGS,			\
    TARGET_HANDLE_OPTION,				\
-   TARGET_EH_RETURN_FILTER_MODE,			\
    TARGET_MERGE_DECL_ATTRIBUTES,			\
    TARGET_MERGE_TYPE_ATTRIBUTES,			\
    TARGET_ATTRIBUTE_TABLE,			\
--- 607,612 ----
Index: gcc/config/rs6000/rs6000.h
===================================================================
*** gcc/config/rs6000/rs6000.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/config/rs6000/rs6000.h	2006-09-26 08:54:36.000000000 +0200
*************** extern enum rs6000_nop_insertion rs6000_
*** 412,417 ****
--- 412,418 ----
  
  /* Width of a word, in units (bytes).  */
  #define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
+ #define UNITS_PER_ABI_WORD (TARGET_32BIT ? 4 : UNITS_PER_WORD)
  #ifdef IN_LIBGCC2
  #define MIN_UNITS_PER_WORD UNITS_PER_WORD
  #else
*************** do {								\
*** 1814,1822 ****
     between pointers and any other objects of this machine mode.  */
  #define Pmode (TARGET_32BIT ? SImode : DImode)
  
- /* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space.  */
- #define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
- 
  /* Mode of a function address in a call instruction (for indexing purposes).
     Doesn't matter on RS/6000.  */
  #define FUNCTION_MODE SImode
--- 1815,1820 ----
Index: gcc/config/rs6000/rs6000.c
===================================================================
*** gcc/config/rs6000/rs6000.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/config/rs6000/rs6000.c	2006-09-26 08:54:36.000000000 +0200
*************** static void rs6000_emit_vector_select (r
*** 764,770 ****
  static tree rs6000_stack_protect_fail (void);
  
  const int INSN_NOT_AVAILABLE = -1;
- static enum machine_mode rs6000_eh_return_filter_mode (void);
  
  /* Hash table stuff for keeping track of TOC entries.  */
  
--- 764,769 ----
*************** static const char alt_reg_names[][8] =
*** 993,1001 ****
  #undef TARGET_GIMPLIFY_VA_ARG_EXPR
  #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
  
- #undef TARGET_EH_RETURN_FILTER_MODE
- #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
- 
  #undef TARGET_SCALAR_MODE_SUPPORTED_P
  #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
  
--- 992,997 ----
*************** rs6000_dbx_register_number (unsigned int
*** 19419,19431 ****
    return regno;
  }
  
- /* target hook eh_return_filter_mode */
- static enum machine_mode
- rs6000_eh_return_filter_mode (void)
- {
-   return TARGET_32BIT ? SImode : word_mode;
- }
- 
  /* Target hook for scalar_mode_supported_p.  */
  static bool
  rs6000_scalar_mode_supported_p (enum machine_mode mode)
--- 19415,19420 ----
Index: gcc/function.c
===================================================================
*** gcc/function.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/function.c	2006-09-26 08:54:36.000000000 +0200
*************** frame_offset_overflow (HOST_WIDE_INT off
*** 371,377 ****
  
    if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1))
  	       /* Leave room for the fixed part of the frame.  */
! 	       - 64 * UNITS_PER_WORD)
      {
        error ("%Jtotal size of local objects too large", func);
        return TRUE;
--- 371,377 ----
  
    if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1))
  	       /* Leave room for the fixed part of the frame.  */
! 	       - 64 * UNITS_PER_ABI_WORD)
      {
        error ("%Jtotal size of local objects too large", func);
        return TRUE;
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/optabs.c	2006-09-26 08:54:36.000000000 +0200
*************** prepare_cmp_insn (rtx *px, rtx *py, enum
*** 3710,3716 ****
  	libfunc = ucmp_optab->handlers[(int) mode].libfunc;
  
        result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
! 					word_mode, 2, x, mode, y, mode);
  
        /* There are two kinds of comparison routines. Biased routines
  	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
--- 3710,3716 ----
  	libfunc = ucmp_optab->handlers[(int) mode].libfunc;
  
        result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
! 					abi_word_mode, 2, x, mode, y, mode);
  
        /* There are two kinds of comparison routines. Biased routines
  	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
*************** prepare_cmp_insn (rtx *px, rtx *py, enum
*** 3721,3727 ****
  	 biasing the unbiased result by adding 1. This gives us a way to
  	 represent LTU. */
        *px = result;
!       *pmode = word_mode;
        *py = const1_rtx;
  
        if (!TARGET_LIB_INT_CMP_BIASED)
--- 3721,3727 ----
  	 biasing the unbiased result by adding 1. This gives us a way to
  	 represent LTU. */
        *px = result;
!       *pmode = abi_word_mode;
        *py = const1_rtx;
  
        if (!TARGET_LIB_INT_CMP_BIASED)
*************** prepare_float_lib_cmp (rtx *px, rtx *py,
*** 3996,4005 ****
    start_sequence ();
    value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
  				   word_mode, 2, x, mode, y, mode);
    insns = get_insns ();
    end_sequence ();
  
!   target = gen_reg_rtx (word_mode);
    emit_libcall_block (insns, target, value, equiv);
  
    if (comparison == UNORDERED
--- 3996,4009 ----
    start_sequence ();
    value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
  				   word_mode, 2, x, mode, y, mode);
+ 
+   if (GET_MODE (value) != abi_word_mode)
+     value = convert_modes (abi_word_mode, GET_MODE (value), value, 0);
+ 
    insns = get_insns ();
    end_sequence ();
  
!   target = gen_reg_rtx (abi_word_mode);
    emit_libcall_block (insns, target, value, equiv);
  
    if (comparison == UNORDERED
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/doc/tm.texi	2006-09-26 08:54:36.000000000 +0200
*************** would most commonly define this macro if
*** 1275,1290 ****
  64-bit mode.
  @end defmac
  
- @defmac STACK_SIZE_MODE
- If defined, an expression of type @code{enum machine_mode} that
- specifies the mode of the size increment operand of an
- @code{allocate_stack} named pattern (@pxref{Standard Names}).
- 
- You need not define this macro if it always returns @code{word_mode}.
- You would most commonly define this macro if the @code{allocate_stack}
- pattern needs to support both a 32- and a 64-bit mode.
- @end defmac
- 
  @defmac TARGET_FLOAT_FORMAT
  A code distinguishing the floating point format of the target machine.
  There are four defined values:
--- 1275,1280 ----
Index: gcc/expr.h
===================================================================
*** gcc/expr.h.orig	2006-09-26 08:54:21.000000000 +0200
--- gcc/expr.h	2006-09-26 08:54:36.000000000 +0200
*************** do {								\
*** 193,205 ****
  #define STACK_SAVEAREA_MODE(LEVEL) Pmode
  #endif
  
- /* Supply a default definition of STACK_SIZE_MODE for
-    allocate_dynamic_stack_space.  Normally PLUS/MINUS, so word_mode.  */
- 
- #ifndef STACK_SIZE_MODE
- #define STACK_SIZE_MODE word_mode
- #endif
- 
  /* Provide default values for the macros controlling stack checking.  */
  
  #ifndef STACK_CHECK_BUILTIN
--- 193,198 ----
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig	2006-09-26 08:54:32.000000000 +0200
--- gcc/targhooks.c	2006-09-26 08:54:52.000000000 +0200
*************** default_pretend_outgoing_varargs_named (
*** 134,145 ****
  	  != default_setup_incoming_varargs);
  }
  
- enum machine_mode
- default_eh_return_filter_mode (void)
- {
-   return word_mode;
- }
- 
  /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK.  */
  
  unsigned HOST_WIDE_INT
--- 134,139 ----
Index: gcc/explow.c
===================================================================
*** gcc/explow.c.orig	2006-09-26 08:54:32.000000000 +0200
--- gcc/explow.c	2006-09-26 08:54:52.000000000 +0200
*************** allocate_dynamic_stack_space (rtx size, 
*** 1223,1229 ****
  #ifdef HAVE_allocate_stack
    if (HAVE_allocate_stack)
      {
!       enum machine_mode mode = STACK_SIZE_MODE;
        insn_operand_predicate_fn pred;
  
        /* We don't have to check against the predicate for operand 0 since
--- 1223,1229 ----
  #ifdef HAVE_allocate_stack
    if (HAVE_allocate_stack)
      {
!       enum machine_mode mode = abi_word_mode;
        insn_operand_predicate_fn pred;
  
        /* We don't have to check against the predicate for operand 0 since
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig	2006-09-26 08:54:32.000000000 +0200
--- gcc/targhooks.h	2006-09-26 08:54:52.000000000 +0200
*************** extern void default_setup_incoming_varar
*** 30,36 ****
  extern rtx default_builtin_setjmp_frame_value (void);
  extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
  
- extern enum machine_mode default_eh_return_filter_mode (void);
  extern unsigned HOST_WIDE_INT default_shift_truncation_mask
    (enum machine_mode);
  extern unsigned int default_min_divisions_for_recip_mul (enum machine_mode);
--- 30,35 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]