mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-05 01:34:12 +08:00
re PR other/18665 (-ftrapv borks up simple integer arithmetic)
PR other/18665 * libgcc-std.ver (GCC_3.4.4): Inherit from GCC_3.4.2. Export __absvti2, __addvti3, __mulvti3, __negvti2 and __subvti3. * libgcc2.c (__addvsi3): Rename to __addvSI3. New version if COMPAT_SIMODE_TRAPPING_ARITHMETIC. (__addvdi3): Rename to __addvDI3. (__subvsi3): Rename to __subvSI3. Use word type for the result. New version if COMPAT_SIMODE_TRAPPING_ARITHMETIC. (__subvdi3): Rename to __subvDI3. (_mulvsi3): Rename to _mulvSI3. New version if COMPAT_SIMODE_TRAPPING_ARITHMETIC. (_mulvdi3): Rename to _mulvDI3. (__negvsi2): Rename to __negvSI2. New version if COMPAT_SIMODE_TRAPPING_ARITHMETIC. (__negvdi2): Rename to __negvDI2. (__absvsi2): Rename to __absvSI2. New version if COMPAT_SIMODE_TRAPPING_ARITHMETIC. (__absvdi2): Rename to __absvDI2. * libgcc2.h (64-bit targets): Define COMPAT_SIMODE_TRAPPING_ARITHMETIC. (__absvSI2, __addvSI3, __subvSI3, __mulvSI3, __negvSI2, __absvDI2, __addvDI3, __subvDI3, __mulvDI3, __negvDI2): Define to the appropriate symbol and declare. (__absvsi2, __addvsi3, __subvsi3, __mulvsi3, __negvsi2): Declare if COMPAT_SIMODE_TRAPPING_ARITHMETIC. From-SVN: r92187
This commit is contained in:
parent
c331bf0802
commit
0aec601466
@ -223,3 +223,13 @@ GCC_3.4.2 {
|
||||
__enable_execute_stack
|
||||
__trampoline_setup
|
||||
}
|
||||
|
||||
%inherit GCC_3.4.4 GCC_3.4.2
|
||||
GCC_3.4.4 {
|
||||
# libgcc2 TImode arithmetic (for 64-bit targets).
|
||||
__absvti2
|
||||
__addvti3
|
||||
__mulvti3
|
||||
__negvti2
|
||||
__subvti3
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ __negdi2 (DWtype u)
|
||||
|
||||
#ifdef L_addvsi3
|
||||
Wtype
|
||||
__addvsi3 (Wtype a, Wtype b)
|
||||
__addvSI3 (Wtype a, Wtype b)
|
||||
{
|
||||
const Wtype w = a + b;
|
||||
|
||||
@ -82,11 +82,23 @@ __addvsi3 (Wtype a, Wtype b)
|
||||
|
||||
return w;
|
||||
}
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
SItype
|
||||
__addvsi3 (SItype a, SItype b)
|
||||
{
|
||||
const SItype w = a + b;
|
||||
|
||||
if (b >= 0 ? w < a : w > a)
|
||||
abort ();
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
#endif
|
||||
|
||||
#ifdef L_addvdi3
|
||||
DWtype
|
||||
__addvdi3 (DWtype a, DWtype b)
|
||||
__addvDI3 (DWtype a, DWtype b)
|
||||
{
|
||||
const DWtype w = a + b;
|
||||
|
||||
@ -99,20 +111,32 @@ __addvdi3 (DWtype a, DWtype b)
|
||||
|
||||
#ifdef L_subvsi3
|
||||
Wtype
|
||||
__subvsi3 (Wtype a, Wtype b)
|
||||
__subvSI3 (Wtype a, Wtype b)
|
||||
{
|
||||
const DWtype w = a - b;
|
||||
const Wtype w = a - b;
|
||||
|
||||
if (b >= 0 ? w > a : w < a)
|
||||
abort ();
|
||||
|
||||
return w;
|
||||
}
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
SItype
|
||||
__subvsi3 (SItype a, SItype b)
|
||||
{
|
||||
const SItype w = a - b;
|
||||
|
||||
if (b >= 0 ? w > a : w < a)
|
||||
abort ();
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
#endif
|
||||
|
||||
#ifdef L_subvdi3
|
||||
DWtype
|
||||
__subvdi3 (DWtype a, DWtype b)
|
||||
__subvDI3 (DWtype a, DWtype b)
|
||||
{
|
||||
const DWtype w = a - b;
|
||||
|
||||
@ -126,7 +150,7 @@ __subvdi3 (DWtype a, DWtype b)
|
||||
#ifdef L_mulvsi3
|
||||
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||
Wtype
|
||||
__mulvsi3 (Wtype a, Wtype b)
|
||||
__mulvSI3 (Wtype a, Wtype b)
|
||||
{
|
||||
const DWtype w = (DWtype) a * (DWtype) b;
|
||||
|
||||
@ -135,11 +159,25 @@ __mulvsi3 (Wtype a, Wtype b)
|
||||
|
||||
return w;
|
||||
}
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
#undef WORD_SIZE
|
||||
#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
|
||||
SItype
|
||||
__mulvsi3 (SItype a, SItype b)
|
||||
{
|
||||
const DItype w = (DItype) a * (DItype) b;
|
||||
|
||||
if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
|
||||
abort ();
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
#endif
|
||||
|
||||
#ifdef L_negvsi2
|
||||
Wtype
|
||||
__negvsi2 (Wtype a)
|
||||
__negvSI2 (Wtype a)
|
||||
{
|
||||
const Wtype w = -a;
|
||||
|
||||
@ -148,11 +186,23 @@ __negvsi2 (Wtype a)
|
||||
|
||||
return w;
|
||||
}
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
SItype
|
||||
__negvsi2 (SItype a)
|
||||
{
|
||||
const SItype w = -a;
|
||||
|
||||
if (a >= 0 ? w > 0 : w < 0)
|
||||
abort ();
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
#endif
|
||||
|
||||
#ifdef L_negvdi2
|
||||
DWtype
|
||||
__negvdi2 (DWtype a)
|
||||
__negvDI2 (DWtype a)
|
||||
{
|
||||
const DWtype w = -a;
|
||||
|
||||
@ -165,10 +215,28 @@ __negvdi2 (DWtype a)
|
||||
|
||||
#ifdef L_absvsi2
|
||||
Wtype
|
||||
__absvsi2 (Wtype a)
|
||||
__absvSI2 (Wtype a)
|
||||
{
|
||||
Wtype w = a;
|
||||
|
||||
if (a < 0)
|
||||
#ifdef L_negvsi2
|
||||
w = __negvSI2 (a);
|
||||
#else
|
||||
w = -a;
|
||||
|
||||
if (w < 0)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
return w;
|
||||
}
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
SItype
|
||||
__absvsi2 (SItype a)
|
||||
{
|
||||
SItype w = a;
|
||||
|
||||
if (a < 0)
|
||||
#ifdef L_negvsi2
|
||||
w = __negvsi2 (a);
|
||||
@ -181,17 +249,18 @@ __absvsi2 (Wtype a)
|
||||
|
||||
return w;
|
||||
}
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
#endif
|
||||
|
||||
#ifdef L_absvdi2
|
||||
DWtype
|
||||
__absvdi2 (DWtype a)
|
||||
__absvDI2 (DWtype a)
|
||||
{
|
||||
DWtype w = a;
|
||||
|
||||
if (a < 0)
|
||||
#ifdef L_negvdi2
|
||||
w = __negvdi2 (a);
|
||||
w = __negvDI2 (a);
|
||||
#else
|
||||
w = -a;
|
||||
|
||||
@ -206,7 +275,7 @@ __absvdi2 (DWtype a)
|
||||
#ifdef L_mulvdi3
|
||||
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||
DWtype
|
||||
__mulvdi3 (DWtype u, DWtype v)
|
||||
__mulvDI3 (DWtype u, DWtype v)
|
||||
{
|
||||
/* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
|
||||
but the checked multiplication needs only two. */
|
||||
|
@ -139,6 +139,16 @@ typedef int word_type __attribute__ ((mode (__word__)));
|
||||
#define float bogus_type
|
||||
#define double bogus_type
|
||||
|
||||
/* Versions prior to 3.4.4 were not taking into account the word size for
|
||||
the 5 trapping arithmetic functions absv, addv, subv, mulv and negv. As
|
||||
a consequence, the si and di variants were always and the only ones emitted.
|
||||
To maintain backward compatibility, COMPAT_SIMODE_TRAPPING_ARITHMETIC is
|
||||
defined on platforms where it makes sense to still have the si variants
|
||||
emitted. As a bonus, their implementation is now correct. Note that the
|
||||
same mechanism should have been implemented for the di variants, but it
|
||||
turns out that no platform would define COMPAT_DIMODE_TRAPPING_ARITHMETIC
|
||||
if it existed. */
|
||||
|
||||
#if MIN_UNITS_PER_WORD > 4
|
||||
#define W_TYPE_SIZE (8 * BITS_PER_UNIT)
|
||||
#define Wtype DItype
|
||||
@ -149,6 +159,7 @@ typedef int word_type __attribute__ ((mode (__word__)));
|
||||
#define UDWtype UTItype
|
||||
#define __NW(a,b) __ ## a ## di ## b
|
||||
#define __NDW(a,b) __ ## a ## ti ## b
|
||||
#define COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
#elif MIN_UNITS_PER_WORD > 2 \
|
||||
|| (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)
|
||||
#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
|
||||
@ -214,6 +225,17 @@ typedef int word_type __attribute__ ((mode (__word__)));
|
||||
#define __fixunsdfSI __NW(fixunsdf,)
|
||||
#define __fixunssfSI __NW(fixunssf,)
|
||||
|
||||
#define __absvSI2 __NW(absv,2)
|
||||
#define __addvSI3 __NW(addv,3)
|
||||
#define __subvSI3 __NW(subv,3)
|
||||
#define __mulvSI3 __NW(mulv,3)
|
||||
#define __negvSI2 __NW(negv,2)
|
||||
#define __absvDI2 __NDW(absv,2)
|
||||
#define __addvDI3 __NDW(addv,3)
|
||||
#define __subvDI3 __NDW(subv,3)
|
||||
#define __mulvDI3 __NDW(mulv,3)
|
||||
#define __negvDI2 __NDW(negv,2)
|
||||
|
||||
#define __ffsSI2 __NW(ffs,2)
|
||||
#define __clzSI2 __NW(clz,2)
|
||||
#define __ctzSI2 __NW(ctz,2)
|
||||
@ -255,16 +277,24 @@ extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
|
||||
extern word_type __cmpdi2 (DWtype, DWtype);
|
||||
extern word_type __ucmpdi2 (DWtype, DWtype);
|
||||
|
||||
extern Wtype __absvsi2 (Wtype);
|
||||
extern DWtype __absvdi2 (DWtype);
|
||||
extern Wtype __addvsi3 (Wtype, Wtype);
|
||||
extern DWtype __addvdi3 (DWtype, DWtype);
|
||||
extern Wtype __subvsi3 (Wtype, Wtype);
|
||||
extern DWtype __subvdi3 (DWtype, DWtype);
|
||||
extern Wtype __mulvsi3 (Wtype, Wtype);
|
||||
extern DWtype __mulvdi3 (DWtype, DWtype);
|
||||
extern Wtype __negvsi2 (Wtype);
|
||||
extern DWtype __negvdi2 (DWtype);
|
||||
extern Wtype __absvSI2 (Wtype);
|
||||
extern Wtype __addvSI3 (Wtype, Wtype);
|
||||
extern Wtype __subvSI3 (Wtype, Wtype);
|
||||
extern Wtype __mulvSI3 (Wtype, Wtype);
|
||||
extern Wtype __negvSI2 (Wtype);
|
||||
extern DWtype __absvDI2 (DWtype);
|
||||
extern DWtype __addvDI3 (DWtype, DWtype);
|
||||
extern DWtype __subvDI3 (DWtype, DWtype);
|
||||
extern DWtype __mulvDI3 (DWtype, DWtype);
|
||||
extern DWtype __negvDI2 (DWtype);
|
||||
|
||||
#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
|
||||
extern SItype __absvsi2 (SItype);
|
||||
extern SItype __addvsi3 (SItype, SItype);
|
||||
extern SItype __subvsi3 (SItype, SItype);
|
||||
extern SItype __mulvsi3 (SItype, SItype);
|
||||
extern SItype __negvsi2 (SItype);
|
||||
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
||||
|
||||
#if BITS_PER_UNIT == 8
|
||||
extern DWtype __fixdfdi (DFtype);
|
||||
|
@ -1,3 +1,7 @@
|
||||
2004-12-15 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* gcc.dg/ftrapv-2.c: New test.
|
||||
|
||||
2004-12-15 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR 18981
|
||||
|
107
gcc/testsuite/gcc.dg/ftrapv-2.c
Normal file
107
gcc/testsuite/gcc.dg/ftrapv-2.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* Copyright (C) 2004 Free Software Foundation.
|
||||
|
||||
PR other/18665
|
||||
Verify that -ftrapv doesn't produce bogus results
|
||||
on 64-bit platforms.
|
||||
|
||||
Written by Eric Botcazou */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-ftrapv" } */
|
||||
|
||||
extern void abort(void);
|
||||
|
||||
int __attribute__((noinline))
|
||||
iabsv(int a)
|
||||
{
|
||||
return abs(a);
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
iaddv(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
isubv(int a, int b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
imulv(int a, int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
inegv(int a)
|
||||
{
|
||||
return -a;
|
||||
}
|
||||
|
||||
long __attribute__((noinline))
|
||||
labsv(long a)
|
||||
{
|
||||
return abs(a);
|
||||
}
|
||||
|
||||
long __attribute__((noinline))
|
||||
laddv(long a, long b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
long __attribute__((noinline))
|
||||
lsubv(long a, long b)
|
||||
{
|
||||
return a - b;
|
||||
}
|
||||
|
||||
long __attribute__((noinline))
|
||||
lmulv(long a, long b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
long __attribute__((noinline))
|
||||
lnegv(long a)
|
||||
{
|
||||
return -a;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (iabsv (-1) != 1)
|
||||
abort ();
|
||||
|
||||
if (iaddv (2,-3) != -1)
|
||||
abort ();
|
||||
|
||||
if (isubv (2,3) != -1)
|
||||
abort ();
|
||||
|
||||
if (imulv (-2,3) != -6)
|
||||
abort ();
|
||||
|
||||
if (inegv (-1) != 1)
|
||||
abort ();
|
||||
|
||||
if (labsv (-1L) != 1L)
|
||||
abort ();
|
||||
|
||||
if (laddv (2L,-3L) != -1L)
|
||||
abort ();
|
||||
|
||||
if (lsubv (2L,3L) != -1L)
|
||||
abort ();
|
||||
|
||||
if (lmulv (-2L,3L) != -6L)
|
||||
abort ();
|
||||
|
||||
if (lnegv (-1L) != 1L)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user