On Tue, 18 Jan 2000, Pavel Machek wrote:
> Hi!
>
> > > If the intention is to clear bit 31, `&= 0x7fffffff' is the thing which
> > > works and is probably more efficient.
> >
> > Not true on all RISC machines I am familiar with. It's 2 instructions
> > either way. On x86 you'll end up using a larger opcode and one of
> > x86's most notable performance advantages is it's code density.
>
> Leave that to the gcc. If it is faster to clear high bit with two
> shifts, _gcc_ is the one to decide that. And yes gcc is clever enough
> to se things like that. [replacing and 0x7fffffff with shl 1 shr 1
> is really no problem].
>
Well it's a problem if it doesn't work.
Script started on Tue Jan 18 10:18:50 2000
# cat xxx.c
int foo0 (int bar)
{
return bar & 0x7fffffff;
}
int foo1 (int bar)
{
return ((bar << 1) >> 1);
}
int main()
{
int xxx = 0xffffffff;
printf("%d\n", foo0(xxx));
printf("%d\n", foo1(xxx));
return 0;
}
# gcc -O2 -o xxx xxx.c
# xxx
2147483647
-1
# exit
exit
Script done on Tue Jan 18 10:19:19 2000
If you want to AND off a bit, AND off a bit. Don't try to fool the
tools. Tools are often broken if you try "tricks".
The intermediate code show all:
.file "xxx.c"
.version "01.01"
gcc2_compiled.:
.text
.align 4
.globl foo0
.type foo0,@function
foo0:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%eax
andl $2147483647,%eax ! Just AND if off, fine.
leave
ret
.Lfe1:
.size foo0,.Lfe1-foo0
.align 4
.globl foo1
.type foo1,@function
foo1:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%edx
leal 0(,%edx,2),%eax ! Good grief
sarl $1,%eax ! Arithmetic shift extends sign
leave
ret
.Lfe2:
.size foo1,.Lfe2-foo1
.section .rodata
.LC0:
.string "%d\n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
pushl $-1
call foo0
pushl %eax
pushl $.LC0
call printf
pushl $-1
call foo1
pushl %eax
pushl $.LC0
call printf
xorl %eax,%eax
leave
ret
.Lfe3:
.size main,.Lfe3-main
.ident "GCC: (GNU) 2.7.2.3"
So, the double-shift is truly broken. Just AND it and be done with it.
Cheers,
Dick Johnson
Penguin : Linux version 2.3.39 on an i686 machine (800.63 BogoMips).
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:18 EST