This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PPro patch #2
- To: law at cygnus dot com
- Subject: Re: PPro patch #2
- From: hjl at lucon dot org (H.J. Lu)
- Date: Fri, 5 Jun 1998 08:27:32 -0700 (PDT)
- Cc: egcs-patches at cygnus dot com
>
>
> Note, you did not send this to egcs-patches. Please do not
> send patches directly to me. Send them to egcs-patches so that
> everyone can comment on them.
>
> In message <m0yhbhR-000268C@ocean.lucon.org>you write:
> > Here is the second PPro patch.
> Do you have a testcase for this bug?
I am enclosing a few testcases here. You have to enable all PPro
features to see all bugs.
>
> > /* This insn requires the top of stack to be the destination. */
> >
> > + /* If the comparison operator is an FP comparison operator,
> > + it is handled correctly by compare_for_stack_reg () who
> > + will move the destination to the top of stack. But if the
> > + comparison operator is not an FP comparison operator, we
> > + have to handle it here. */
> > + if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
> > + && REGNO (*dest) != regstack->reg[regstack->top])
> > + emit_swap_insn (insn, regstack, *dest);
> > +
> I don't understand how this comment applies.
>
> Don't we get to this code for any conditional move, regardless of
> whether or not this is an FP comparison operator?
>
> The format of a conditional move is the same regardless of
> the mode of the comparison operator:
>
> (set (dest) (if_then_else (comparison_operator
> (comparison_arg1)
> (comparison_arg2))
> (result1)
> (result2)))
>
>
> So, when we call subst_stack_regs with such a pattern, we will always
> to into the IF_THEN_ELSE case, regardless of what the comparison
> operator is?!? What am I missing?
>
> How can we get into compare_for_stack_reg for a conditional move?
> I don't see how that can happen anymore.
subst_stack_regs_pat handles the register stack in the comparison
insn, which is the one before the conditional move insn.
>
> At the least the comment needs updating, this may point to a need
> for you to look more closely at the problem you're trying to solve.
>
> If we decide it's no longer possible to get into compare_for_stack_reg
> for conditional moves, then we should remove the cmove support
> from that function.
>
Please check out subst_stack_regs_pat () and how it is called. It has
switch (GET_CODE (SET_SRC (pat)))
{
case COMPARE:
compare_for_stack_reg (insn, regstack, pat);
break;
......
case IF_THEN_ELSE:
.....
break;
}
But COMPARE is for comparison only. If it is an interger insn setting
CC, it will never get there. We have to handle it in IF_THEN_ELSE.
--
H.J. Lu (hjl@gnu.org)
---
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1998-06-05 08:14 PDT by <hjl@ocean>.
# Source directory was `/home/hjl/bugs/gcc/ppro/glibc'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 869 -rw-r--r-- Makefile
# 1588 -rw-r--r-- ccos.c
# 1932 -rw-r--r-- hypot.c
# 154 -rw-r--r-- loop.c
# 285 -rw-r--r-- nan.c
# 167 -rw-r--r-- mp4.c
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh20434; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
CC=gcc-glibc2 -mcpu=i686 -march=i686 -B/home/work/build/bin/egcs/gcc/
CC=gcc-glibc2 -mcpu=i686 -march=i686 -B/home/work/gnu/bin/egcs/gcc/
CC=gcc-glibc2 -mcpu=i686 -march=i686 -B/home/work/gnu/bin/egcs-ppro/gcc/
CC=gcc-glibc2 -mcpu=i686 -march=i686 -B/home/work/build/bin/egcs-ppro/gcc/
CFLAGS=-O6 -fexpensive-optimizations # -dra
CFLAGS=-O2
LD=gcc-glibc2
#LDLIBS=-lm
X
PROGS=ccos hypot loop nan
SRCS=$(PROGS:=.c) mp4.c
X
all: $(PROGS) mp4.s
X for f in $(PROGS); do echo "Running: $$f"; $$f; done
X
X.c.s:
X $(CC) -S $(CFLAGS) $<
X
ccos: ccos.s
X $(LD) $(CFLAGS) -o $@ $^ $(LDLIBS)
X
hypot: hypot.s
X $(LD) $(CFLAGS) -o $@ $^ $(LDLIBS)
X
loop: loop.s
X $(LD) $(CFLAGS) -o $@ $^ $(LDLIBS)
X
nan: nan.s
X $(LD) $(CFLAGS) -o $@ $^ $(LDLIBS)
X
ll: ll.s
X $(LD) $(CFLAGS) -o $@ $^ $(LDLIBS)
X
clean:
X $(RM) -f *.s *.cc.* *.c.* $(PROGS) *.o core a.out
X
shar:
X shar Makefile $(SRCS) > shar.out
SHAR_EOF
$shar_touch -am 0605081498 'Makefile' &&
chmod 0644 'Makefile' ||
$echo 'restore of' 'Makefile' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'Makefile:' 'MD5 check failed'
84e2cecd424e97d709eb652b3aa5d746 Makefile
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
test 869 -eq "$shar_count" ||
$echo 'Makefile:' 'original size' '869,' 'current size' "$shar_count!"
fi
fi
# ============= ccos.c ==============
if test -f 'ccos.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'ccos.c' '(file already exists)'
else
$echo 'x -' extracting 'ccos.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'ccos.c' &&
static double plus_zero;
static double nan_value;
static double minus_infty;
static double plus_infty;
X
typedef unsigned int u_int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef int int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef union
{
X double value;
X struct
X {
X u_int32_t lsw;
X u_int32_t msw;
X } parts;
} ieee_double_shape_type;
X
int __isinf (double x)
{
X int32_t hx,lx;
X ieee_double_shape_type gl_u;
X gl_u.value = x;
X lx = gl_u.parts.lsw;
X hx = gl_u.parts.msw;
X lx |= (hx & 0x7fffffff) ^ 0x7ff00000;
X lx |= -lx;
X return ~(lx >> 31) & (hx >> 30);
}
X
__complex__ double
__ccos (__complex__ double x)
{
X __complex__ double res;
X
X if (__real__ x == 0.0 || __imag__ x == 0.0)
X {
X __real__ res = 1;
X __imag__ res = 0.0;
X }
X else if (__isinf (__imag__ x))
X {
X __real__ res = 2;
X __imag__ res = 0.0;
X }
X else
X {
X __real__ res = 3;
X __imag__ res = 0.0;
X }
X
X return res;
}
X
int
bar (__complex__ double x)
{
X printf ("%lf\n", x);
X return __real__ x == 2.0;
}
X
main ()
{
X plus_zero = 0.0;
X nan_value = plus_zero / plus_zero;
X plus_infty = (__extension__
X ((union { unsigned char __c[8]; double __d; })
X {__c: { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }}).__d);
X minus_infty = - (__extension__
X ((union { unsigned char __c[8]; double __d; })
X {__c: { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }}).__d);
X
X (void) &nan_value;
X (void) &minus_infty;
X (void) &plus_infty;
X
X if (bar (__ccos ((
X { __complex__ double __retval;
X __real__ __retval = nan_value;
X __imag__ __retval = plus_infty;
X __retval;
X }))) == 0)
X abort ();
X
X return 0;
}
SHAR_EOF
$shar_touch -am 0514065398 'ccos.c' &&
chmod 0644 'ccos.c' ||
$echo 'restore of' 'ccos.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'ccos.c:' 'MD5 check failed'
ac09eeb9acfd3bc19a358fef6d461e60 ccos.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'ccos.c'`"
test 1588 -eq "$shar_count" ||
$echo 'ccos.c:' 'original size' '1588,' 'current size' "$shar_count!"
fi
fi
# ============= hypot.c ==============
if test -f 'hypot.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'hypot.c' '(file already exists)'
else
$echo 'x -' extracting 'hypot.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'hypot.c' &&
static double plus_zero;
static double nan_value;
static double minus_infty;
static double plus_infty;
X
typedef unsigned int u_int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef int int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef union
{
X double value;
X struct
X {
X u_int32_t lsw;
X u_int32_t msw;
X } parts;
} ieee_double_shape_type;
double __ieee754_hypot(double x, double y)
{
X double a,b,w = -1;
X int32_t j,ha,hb;
X ieee_double_shape_type gh_u;
X ieee_double_shape_type sh_u;
X gh_u.value = x;
X ha = gh_u.parts.msw;
X ha &= 0x7fffffff;
X gh_u.value = y;
X hb = gh_u.parts.msw;
X hb &= 0x7fffffff;
X a=x;b=y;
X sh_u.value = a;
X sh_u.parts.msw = ha;
X a = sh_u.value;
X sh_u.value = b;
X sh_u.parts.msw = hb;
X b = sh_u.value;
X if(ha > 0x5f300000) {
X if(ha >= 0x7ff00000) {
X u_int32_t low;
X ieee_double_shape_type gl_u;
X w = a+b;
X gl_u.value = a;
X low = gl_u.parts.lsw;
X if(((ha&0xfffff)|low)==0) w = a;
X gl_u.value = b;
X low = gl_u.parts.lsw;
X if(((hb^0x7ff00000)|low)==0) w = b;
X return w;
X }
X }
X return w;
}
X
int __isinf (double x)
{
X int32_t hx,lx;
X ieee_double_shape_type gl_u;
X gl_u.value = x;
X lx = gl_u.parts.lsw;
X hx = gl_u.parts.msw;
X lx |= (hx & 0x7fffffff) ^ 0x7ff00000;
X lx |= -lx;
X return ~(lx >> 31) & (hx >> 30);
}
X
int
bar (double x)
{
X printf ("%lf\n", x);
X return __isinf (x);
}
X
main ()
{
X plus_zero = 0.0;
X nan_value = plus_zero / plus_zero;
X plus_infty = (__extension__
X ((union { unsigned char __c[8]; double __d; })
X {__c: { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }}).__d);
X minus_infty = - (__extension__
X ((union { unsigned char __c[8]; double __d; })
X {__c: { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }}).__d);
X
X (void) &nan_value;
X (void) &minus_infty;
X (void) &plus_infty;
X
X printf ("%lf\n", __ieee754_hypot (-1, -1));
X
X if (bar (__ieee754_hypot (minus_infty, nan_value)) != 1)
X abort ();
X
X return 0;
}
SHAR_EOF
$shar_touch -am 0512204498 'hypot.c' &&
chmod 0644 'hypot.c' ||
$echo 'restore of' 'hypot.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'hypot.c:' 'MD5 check failed'
3e17d64d7fb90091a0cc80680c816e43 hypot.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hypot.c'`"
test 1932 -eq "$shar_count" ||
$echo 'hypot.c:' 'original size' '1932,' 'current size' "$shar_count!"
fi
fi
# ============= loop.c ==============
if test -f 'loop.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'loop.c' '(file already exists)'
else
$echo 'x -' extracting 'loop.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'loop.c' &&
int
foo (int x, int y)
{
X x = x - y;
X
X if (x >= 0)
X y = 0;
X
X return y == 0 ? 1 : 0;
}
X
main ()
{
X if (foo (-0x7fffffff, 300) == 0)
X abort ();
}
SHAR_EOF
$shar_touch -am 0513185098 'loop.c' &&
chmod 0644 'loop.c' ||
$echo 'restore of' 'loop.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'loop.c:' 'MD5 check failed'
f311f83bdb625149d231918ce358255e loop.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'loop.c'`"
test 154 -eq "$shar_count" ||
$echo 'loop.c:' 'original size' '154,' 'current size' "$shar_count!"
fi
fi
# ============= nan.c ==============
if test -f 'nan.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'nan.c' '(file already exists)'
else
$echo 'x -' extracting 'nan.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'nan.c' &&
static double plus_zero;
static double nan_value;
X
int
foo ()
{
X volatile double NaN_var;
X
X NaN_var = nan_value;
X
X return NaN_var != NaN_var;
}
X
main ()
{
X plus_zero = 0.0;
X nan_value = plus_zero / plus_zero;
X
X (void) &nan_value;
X
X if (foo () != 1)
X abort ();
X
X return 0;
}
SHAR_EOF
$shar_touch -am 0511171898 'nan.c' &&
chmod 0644 'nan.c' ||
$echo 'restore of' 'nan.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'nan.c:' 'MD5 check failed'
24534ddbf6fa67ed1ce03eb075acbad6 nan.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'nan.c'`"
test 285 -eq "$shar_count" ||
$echo 'nan.c:' 'original size' '285,' 'current size' "$shar_count!"
fi
fi
# ============= mp4.c ==============
if test -f 'mp4.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'mp4.c' '(file already exists)'
else
$echo 'x -' extracting 'mp4.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'mp4.c' &&
extern double log (double);
X
void test (float *fa)
{
X int i;
X
X for (i = 0; i < 10; i++)
X fa[i] = log( (( fa[i] ) > ( 1. ) ? ( fa[i] ) : ( 1. )) ) / log(2.);
}
SHAR_EOF
$shar_touch -am 0517221998 'mp4.c' &&
chmod 0644 'mp4.c' ||
$echo 'restore of' 'mp4.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'mp4.c:' 'MD5 check failed'
3f6df45cb6d77935e65b3c7acbdf2dde mp4.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'mp4.c'`"
test 167 -eq "$shar_count" ||
$echo 'mp4.c:' 'original size' '167,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh20434
exit 0