This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [RFC,PATCH] 2 new mode attributes to replace mode(word) uses in libgcc
Hi,
> Let's just make the variable 'c' in __divdi3 and __moddi3 have type
> int, rather than fuss with word_type or Wtype. I can't see any
> disadvantage to that.
Standard C data types are not allowed in libgcc. Although it would be
ok for this flag variable the standard data types are disabled by
overriding them using macros.
> When I look at your patch, there seems to be something missing: you
> haven't changed optabs.c. It seems to me that you need to change
> optabs.c to use cmp_return_mode and shift_count_mode. You should use
> cmp_return_mode rather than word_mode in prepare_cmp_insn. And you
> should use shift_count_mode in expand_binop if shift_op.
Yes, this was missing. I've added those bits in the attached patch.
I was wondering about prepare_float_lib_cmp. There is also used word_mode
as return mode which looks wrong to me since the eq<float mode> functions
in soft-fp are all defined with int as return type. So I've changed this
to TYPE_MODE (integer_type_node).
Bootstrapping on i686, s390 and s390x.
OK for mainline - given no testsuite regressions occur?
Bye,
-Andreas-
2007-05-31 Andreas Krebbel <krebbel1@de.ibm.com>
* libgcc2.h (word_type): Type definition removed.
(cmp_return_type, shift_count_type): Type definitions added.
(__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter
replaced with shift_count_type.
(__cmpdi2, __ucmpdi2): word_type of return type replaced with
cmp_return_type.
* libgcc2.c (__udivmoddi4, __moddi3): Type of local variable c
changed from word_type to Wtype.
(__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter
replaced with shift_count_type.
(__cmpdi2, __ucmpdi2): word_type of return type replaced with
cmp_return_type.
* c-common.c (handle_mode_attribute): Handling for libgcc_cmp_return and
libgcc_shift_count attribute added.
* target-def.h (TARGET_LIBGCC_CMP_RETURN_MODE,
TARGET_LIBGCC_SHIFT_COUNT_MODE): New target hooks defined.
(TARGET_INITIALIZER): New target hooks added.
* targhooks.c (default_libgcc_cmp_return_mode,
default_libgcc_shift_count_mode): Default implementations for the new
target hooks added.
* targhooks.h (default_libgcc_cmp_return_mode,
default_libgcc_shift_count_mode): Function prototypes added.
* target.h (struct gcc_target): Fields for the new target hooks added.
* optabs.c (expand_binop): Use shift_count_mode when expanding shift
as library call.
(prepare_cmp_insn): Use cmp_return_mode when expanding comparison as
library call.
(prepare_float_lib_cmp): Use integer type as return type.
* doc/tm.texi (TARGET_LIBGCC_CMP_RETURN_MODE,
TARGET_LIBGCC_SHIFT_COUNT_MODE): Documentation added.
* config/s390/s390.c (s390_libgcc_cmp_return_mode,
s390_libgcc_shift_count_mode): Functions added.
(TARGET_LIBGCC_CMP_RETURN_MODE, TARGET_LIBGCC_SHIFT_COUNT_MODE): Target
hooks defined.
Index: gcc/libgcc2.h
===================================================================
*** gcc/libgcc2.h.orig 2007-05-29 08:59:17.000000000 +0200
--- gcc/libgcc2.h 2007-05-30 16:47:54.000000000 +0200
*************** typedef float TFtype __attribute__ ((mo
*** 173,179 ****
typedef _Complex float TCtype __attribute__ ((mode (TC)));
#endif
! typedef int word_type __attribute__ ((mode (__word__)));
/* Make sure that we don't accidentally use any normal C language built-in
type names in the first part of this file. Instead we want to use *only*
--- 173,180 ----
typedef _Complex float TCtype __attribute__ ((mode (TC)));
#endif
! typedef int cmp_return_type __attribute__((mode (__libgcc_cmp_return__)));
! typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__)));
/* Make sure that we don't accidentally use any normal C language built-in
type names in the first part of this file. Instead we want to use *only*
*************** extern UDWtype __udivmoddi4 (UDWtype, UD
*** 329,337 ****
extern DWtype __negdi2 (DWtype);
#endif
! extern DWtype __lshrdi3 (DWtype, word_type);
! extern DWtype __ashldi3 (DWtype, word_type);
! extern DWtype __ashrdi3 (DWtype, word_type);
/* __udiv_w_sdiv is static inline when building other libgcc2 portions. */
#if (!defined(L_udivdi3) && !defined(L_divdi3) && \
--- 330,338 ----
extern DWtype __negdi2 (DWtype);
#endif
! extern DWtype __lshrdi3 (DWtype, shift_count_type);
! extern DWtype __ashldi3 (DWtype, shift_count_type);
! extern DWtype __ashrdi3 (DWtype, shift_count_type);
/* __udiv_w_sdiv is static inline when building other libgcc2 portions. */
#if (!defined(L_udivdi3) && !defined(L_divdi3) && \
*************** extern DWtype __ashrdi3 (DWtype, word_ty
*** 339,346 ****
extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
#endif
! extern word_type __cmpdi2 (DWtype, DWtype);
! extern word_type __ucmpdi2 (DWtype, DWtype);
extern Wtype __absvSI2 (Wtype);
extern Wtype __addvSI3 (Wtype, Wtype);
--- 340,347 ----
extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
#endif
! extern cmp_return_type __cmpdi2 (DWtype, DWtype);
! extern cmp_return_type __ucmpdi2 (DWtype, DWtype);
extern Wtype __absvSI2 (Wtype);
extern Wtype __addvSI3 (Wtype, Wtype);
Index: gcc/libgcc2.c
===================================================================
*** gcc/libgcc2.c.orig 2007-05-29 08:59:17.000000000 +0200
--- gcc/libgcc2.c 2007-05-30 16:47:54.000000000 +0200
*************** __mulvDI3 (DWtype u, DWtype v)
*** 406,421 ****
/* Unless shift functions are defined with full ANSI prototypes,
! parameter b will be promoted to int if word_type is smaller than an int. */
#ifdef L_lshrdi3
DWtype
! __lshrdi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
--- 406,421 ----
/* Unless shift functions are defined with full ANSI prototypes,
! parameter b will be promoted to int if shift_count_type is smaller than an int. */
#ifdef L_lshrdi3
DWtype
! __lshrdi3 (DWtype u, shift_count_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
*************** __lshrdi3 (DWtype u, word_type b)
*** 437,449 ****
#ifdef L_ashldi3
DWtype
! __ashldi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
--- 437,449 ----
#ifdef L_ashldi3
DWtype
! __ashldi3 (DWtype u, shift_count_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
*************** __ashldi3 (DWtype u, word_type b)
*** 465,477 ****
#ifdef L_ashrdi3
DWtype
! __ashrdi3 (DWtype u, word_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
--- 465,477 ----
#ifdef L_ashrdi3
DWtype
! __ashrdi3 (DWtype u, shift_count_type b)
{
if (b == 0)
return u;
const DWunion uu = {.ll = u};
! const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
DWunion w;
if (bm <= 0)
*************** __udivmoddi4 (UDWtype n, UDWtype d, UDWt
*** 1082,1088 ****
DWtype
__divdi3 (DWtype u, DWtype v)
{
! word_type c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
--- 1082,1088 ----
DWtype
__divdi3 (DWtype u, DWtype v)
{
! Wtype c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
*************** __divdi3 (DWtype u, DWtype v)
*** 1106,1112 ****
DWtype
__moddi3 (DWtype u, DWtype v)
{
! word_type c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
--- 1106,1112 ----
DWtype
__moddi3 (DWtype u, DWtype v)
{
! Wtype c = 0;
DWunion uu = {.ll = u};
DWunion vv = {.ll = v};
DWtype w;
*************** __udivdi3 (UDWtype n, UDWtype d)
*** 1146,1152 ****
#endif
#ifdef L_cmpdi2
! word_type
__cmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
--- 1146,1152 ----
#endif
#ifdef L_cmpdi2
! cmp_return_type
__cmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
*************** __cmpdi2 (DWtype a, DWtype b)
*** 1165,1171 ****
#endif
#ifdef L_ucmpdi2
! word_type
__ucmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
--- 1165,1171 ----
#endif
#ifdef L_ucmpdi2
! cmp_return_type
__ucmpdi2 (DWtype a, DWtype b)
{
const DWunion au = {.ll = a};
Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig 2007-05-30 16:06:18.000000000 +0200
--- gcc/c-common.c 2007-05-30 16:47:54.000000000 +0200
*************** handle_mode_attribute (tree *node, tree
*** 4996,5001 ****
--- 4996,5005 ----
mode = word_mode;
else if (!strcmp (p, "pointer"))
mode = ptr_mode;
+ else if (!strcmp (p, "libgcc_cmp_return"))
+ mode = targetm.libgcc_cmp_return_mode ();
+ else if (!strcmp (p, "libgcc_shift_count"))
+ mode = targetm.libgcc_shift_count_mode ();
else
for (j = 0; j < NUM_MACHINE_MODES; j++)
if (!strcmp (p, GET_MODE_NAME (j)))
Index: gcc/target-def.h
===================================================================
*** gcc/target-def.h.orig 2007-05-30 16:06:18.000000000 +0200
--- gcc/target-def.h 2007-05-30 16:47:54.000000000 +0200
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 371,376 ****
--- 371,380 ----
/* In except.c */
#define TARGET_EH_RETURN_FILTER_MODE default_eh_return_filter_mode
+ /* In libgcc2.c */
+ #define TARGET_LIBGCC_CMP_RETURN_MODE default_libgcc_cmp_return_mode
+ #define TARGET_LIBGCC_SHIFT_COUNT_MODE default_libgcc_shift_count_mode
+
/* In tree.c. */
#define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
#define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 653,658 ****
--- 657,664 ----
TARGET_DEFAULT_TARGET_FLAGS, \
TARGET_HANDLE_OPTION, \
TARGET_EH_RETURN_FILTER_MODE, \
+ TARGET_LIBGCC_CMP_RETURN_MODE, \
+ TARGET_LIBGCC_SHIFT_COUNT_MODE, \
TARGET_MERGE_DECL_ATTRIBUTES, \
TARGET_MERGE_TYPE_ATTRIBUTES, \
TARGET_ATTRIBUTE_TABLE, \
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig 2007-05-30 16:06:18.000000000 +0200
--- gcc/targhooks.c 2007-05-30 16:47:54.000000000 +0200
*************** default_eh_return_filter_mode (void)
*** 140,145 ****
--- 140,157 ----
return word_mode;
}
+ enum machine_mode
+ default_libgcc_cmp_return_mode (void)
+ {
+ return word_mode;
+ }
+
+ enum machine_mode
+ default_libgcc_shift_count_mode (void)
+ {
+ return word_mode;
+ }
+
/* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */
unsigned HOST_WIDE_INT
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig 2007-05-30 16:06:18.000000000 +0200
--- gcc/targhooks.h 2007-05-30 16:47:54.000000000 +0200
*************** extern rtx default_builtin_setjmp_frame_
*** 31,36 ****
--- 31,38 ----
extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
extern enum machine_mode default_eh_return_filter_mode (void);
+ extern enum machine_mode default_libgcc_cmp_return_mode (void);
+ extern enum machine_mode default_libgcc_shift_count_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);
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig 2007-05-30 16:06:12.000000000 +0200
--- gcc/doc/tm.texi 2007-05-30 16:47:54.000000000 +0200
*************** You would most commonly define this macr
*** 1327,1332 ****
--- 1327,1346 ----
pattern needs to support both a 32- and a 64-bit mode.
@end defmac
+ @deftypefn {Target Hook} {enum machine_mode} TARGET_LIBGCC_CMP_RETURN_MODE ()
+ This target hook should return the mode to be used for the return value
+ of compare instructions expanded to libgcc calls. If not defined
+ @code{word_mode} is returned which is the right choice for a majority of
+ targets.
+ @end deftypefn
+
+ @deftypefn {Target Hook} {enum machine_mode} TARGET_LIBGCC_SHIFT_COUNT_MODE ()
+ This target hook should return the mode to be used for the shift count operand
+ of shift instructions expanded to libgcc calls. If not defined
+ @code{word_mode} is returned which is the right choice for a majority of
+ targets.
+ @end deftypefn
+
@defmac TARGET_FLOAT_FORMAT
A code distinguishing the floating point format of the target machine.
There are four defined values:
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig 2007-05-29 08:59:17.000000000 +0200
--- gcc/config/s390/s390.c 2007-05-30 16:47:54.000000000 +0200
*************** struct machine_function GTY(())
*** 322,327 ****
--- 322,339 ----
#define REGNO_PAIR_OK(REGNO, MODE) \
(HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1))
+ static enum machine_mode
+ s390_libgcc_cmp_return_mode (void)
+ {
+ return TARGET_64BIT ? DImode : SImode;
+ }
+
+ static enum machine_mode
+ s390_libgcc_shift_count_mode (void)
+ {
+ return TARGET_64BIT ? DImode : SImode;
+ }
+
/* Return true if the back end supports mode MODE. */
static bool
s390_scalar_mode_supported_p (enum machine_mode mode)
*************** s390_reorg (void)
*** 9339,9344 ****
--- 9351,9362 ----
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD s390_secondary_reload
+ #undef TARGET_LIBGCC_CMP_RETURN_MODE
+ #define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode
+
+ #undef TARGET_LIBGCC_SHIFT_COUNT_MODE
+ #define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
Index: gcc/target.h
===================================================================
*** gcc/target.h.orig 2007-05-30 16:06:18.000000000 +0200
--- gcc/target.h 2007-05-30 16:47:54.000000000 +0200
*************** struct gcc_target
*** 428,433 ****
--- 428,439 ----
/* Return machine mode for filter value. */
enum machine_mode (* eh_return_filter_mode) (void);
+ /* Return machine mode for libgcc expanded cmp instructions. */
+ enum machine_mode (* libgcc_cmp_return_mode) (void);
+
+ /* Return machine mode for libgcc expanded shift instructions. */
+ enum machine_mode (* libgcc_shift_count_mode) (void);
+
/* Given two decls, merge their attributes and return the result. */
tree (* merge_decl_attributes) (tree, tree);
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c.orig 2007-05-29 08:59:17.000000000 +0200
--- gcc/optabs.c 2007-05-31 10:31:36.000000000 +0200
*************** expand_binop (enum machine_mode mode, op
*** 1948,1957 ****
if (shift_op)
{
! op1_mode = word_mode;
/* Specify unsigned here,
since negative shift counts are meaningless. */
! op1x = convert_to_mode (word_mode, op1, 1);
}
if (GET_MODE (op0) != VOIDmode
--- 1948,1957 ----
if (shift_op)
{
! op1_mode = targetm.libgcc_shift_count_mode ();
/* Specify unsigned here,
since negative shift counts are meaningless. */
! op1x = convert_to_mode (op1_mode, op1, 1);
}
if (GET_MODE (op0) != VOIDmode
*************** prepare_cmp_insn (rtx *px, rtx *py, enum
*** 3868,3874 ****
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
--- 3868,3875 ----
libfunc = ucmp_optab->handlers[(int) mode].libfunc;
result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
! targetm.libgcc_cmp_return_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_float_lib_cmp (rtx *px, rtx *py,
*** 4153,4159 ****
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! word_mode, 2, x, mode, y, mode);
insns = get_insns ();
end_sequence ();
--- 4154,4161 ----
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! TYPE_MODE (integer_type_node),
! 2, x, mode, y, mode);
insns = get_insns ();
end_sequence ();