This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Introduce abi_word_mode - take 2
Hello,
> Thanks for the clarification! Andreas is going to prepare a
> patch along those lines ...
Here it is. I did several changes:
- Added the documentation for UNITS_PER_ABI_WORD and BITS_PER_ABI_WORD.
- Removed the STACK_SIZE_MODE parts. So the macro stays as is.
- Reworked the prepare_cmp_insn and prepare_float_lib_cmp changes.
The patch still removes the target hook eh_return_filter mode and changes
the rs6000 back-end to make use of abi_word_mode.
I've bootstrapped gcc with this patch on s390 and i686.
Bootstrapped on s390x together with a patch defining UNITS_PER_ABI_WORD
using the -mzarch and -m31 options.
No testsuite regressions.
Bye,
-Andreas-
Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/c-common.c 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/except.c 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/defaults.h 2006-10-09 09:35:29.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/java/constants.c
===================================================================
*** gcc/java/constants.c.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/java/constants.c 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/emit-rtl.c 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/machmode.h 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/target.h 2006-10-09 09:35:29.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-10-06 14:54:43.000000000 +0200
--- gcc/target-def.h 2006-10-09 09:35:29.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-10-06 14:55:14.000000000 +0200
--- gcc/config/rs6000/rs6000.h 2006-10-09 09:35:29.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
Index: gcc/config/rs6000/rs6000.c
===================================================================
*** gcc/config/rs6000/rs6000.c.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/config/rs6000/rs6000.c 2006-10-09 09:35:29.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/optabs.c
===================================================================
*** gcc/optabs.c.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/optabs.c 2006-10-09 11:06:52.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
*** 3720,3726 ****
case. For unsigned comparisons always compare against 1 after
biasing the unbiased result by adding 1. This gives us a way to
represent LTU. */
! *px = result;
*pmode = word_mode;
*py = const1_rtx;
--- 3720,3729 ----
case. For unsigned comparisons always compare against 1 after
biasing the unbiased result by adding 1. This gives us a way to
represent LTU. */
! if (word_mode != GET_MODE (result))
! *px = convert_modes (word_mode, GET_MODE (result), result, 0);
! else
! *px = result;
*pmode = word_mode;
*py = const1_rtx;
*************** prepare_float_lib_cmp (rtx *px, rtx *py,
*** 3995,4001 ****
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! word_mode, 2, x, mode, y, mode);
insns = get_insns ();
end_sequence ();
--- 3998,4008 ----
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! abi_word_mode, 2, x, mode, y, mode);
!
! if (word_mode != GET_MODE (value))
! value = convert_modes (word_mode, GET_MODE (value), value, 0);
!
insns = get_insns ();
end_sequence ();
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig 2006-10-06 14:55:12.000000000 +0200
--- gcc/doc/tm.texi 2006-10-09 09:35:29.000000000 +0200
*************** Number of bits in a word. If you do not
*** 931,936 ****
--- 931,943 ----
is @code{BITS_PER_UNIT * UNITS_PER_WORD}.
@end defmac
+ @defmac BITS_PER_ABI_WORD
+ Number of bits in an integral data type when defined with the type
+ attribute @code{mode(word)} (e.g. with
+ @code{__attribute__((__mode__(__word__))))}. If you do not
+ define this macro, the default is @code{BITS_PER_UNIT * UNITS_PER_ABI_WORD}.
+ @end defmac
+
@defmac MAX_BITS_PER_WORD
Maximum number of bits in a word. If this is undefined, the default is
@code{BITS_PER_WORD}. Otherwise, it is the constant value that is the
*************** Number of storage units in a word; norma
*** 942,947 ****
--- 949,965 ----
register, a power of two from 1 or 8.
@end defmac
+ @defmac UNITS_PER_ABI_WORD
+ Number of storage units in an integral data type when defined with the type
+ attribute @code{mode(word)} (e.g. with
+ @code{__attribute__((__mode__(__word__))))}. The value has to be a power of
+ two. If it is undefined, the default is @code{UNITS_PER_WORD}.
+
+ A gcc backend needs to define this macro when it provides configurations
+ using different values for @code{UNITS_PER_WORD} that need to support the
+ same ABI.
+ @end defmac
+
@defmac MIN_UNITS_PER_WORD
Minimum number of units in a word. If this is undefined, the default is
@code{UNITS_PER_WORD}. Otherwise, it is the constant value that is the
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/targhooks.c 2006-10-09 09:35:29.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/targhooks.h
===================================================================
*** gcc/targhooks.h.orig 2006-10-06 14:54:43.000000000 +0200
--- gcc/targhooks.h 2006-10-09 09:35:29.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: gcc/builtin-types.def
===================================================================
*** gcc/builtin-types.def.orig 2006-10-06 14:55:14.000000000 +0200
--- gcc/builtin-types.def 2006-10-09 09:35:59.000000000 +0200
*************** DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_lo
*** 75,81 ****
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, 1))
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)
--- 75,81 ----
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, 1))
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)