This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Unsaved register?
- To: <gcc-bugs at gcc dot gnu dot org>
- Subject: Unsaved register?
- From: Erik Walthinsen <omega at temple-baptist dot com>
- Date: Tue, 29 May 2001 15:39:48 -0700 (PDT)
I'm working on a bitstream implementation using mmx, with extensive
inlining support, etc. I've run across what I think is a bug in the
register-stomping code. The routine in question is:
extern inline
uint32_t bitstream_get_mmx(bitstream_t *bs,uint32_t num_bits) {
uint32_t bits,result;
//fprintf(stderr,"num_bits is %d\n",num_bits);
asm volatile (
"movq %4, %%mm7\n\t" // put current bits into mm7
"movl %5, %3\n\t" // put remaining bits into reg3
"subl %6, %3\n\t" // subtract num_bits from reg3
"jnl 1f\n\t" // skip if we have enough bits
"pushl %6\n\t" // push num_bits
"pushl %7\n\t" // push bs
"call bitstream_get_bh_mmx\n\t" // call the bottom half
"movl %%eax, %0\n\t" // save the result
"jmp 2f\n\t"
"1:\n\t"
"movd %8, %%mm5\n\t" // put the shift count into mm5
// we know we have enough bits, they're at the top of mm7
"movq %%mm7, %%mm6\n\t" // working copy in mm6
"movd %6, %%mm4\n\t" // get the bit count again
"psrlq %%mm5, %%mm6\n\t" // shift mm6 right by 64 - numbits
// mm6 now has the right data
"movl %3, %2\n\t" // save back the modified curbits
"movd %%mm6, %0\n\t" // write the resulting bits out
"psllq %%mm4, %%mm7\n\t" // strip those bits off mm7
"movq %%mm7, %1\n\t" // save the remaining bits back
"2:\n\t"
:
"=r"(result), "=m"(bs->current.u64), "=m"(bs->current_bits), "=r"(bits) :
"1"(bs->current.u64), "2"(bs->current_bits), "r"(num_bits), "r"(bs),
"rm"(_bitstream_mmx_64_minus[num_bits]) :
"memory"
);
return result;
}
This is compiling down to the following:
movl $5, %ecx // constant arg num_bits = 5
. . .
movq (%edi), %mm7
movl 8(%edi), %eax
subl %ecx, %eax
jnl 1f
pushl %ecx
pushl %edi
call bitstream_get_bh_mmx
movl %eax, %edx
jmp 2f
1:
movd _bitstream_mmx_64_minus+20, %mm5
movq %mm7, %mm6
movd %ecx, %mm4
psrlq %mm5, %mm6
movl %eax, 8(%edi)
movd %mm6, %edx
psllq %mm4, %mm7
movq %mm7, (%edi)
2:
Now, bitstream_get_bh_mmx calls bitstream_next_word_mmx at the end, which
seems to be the culprit:
. . .
.stabn 68,0,36,.LM173-bitstream_next_word_mmx
.LM173:
movl 44(%esi), %ecx
movzbl (%ebx,%ecx), %edx
movzbl 1(%ebx,%ecx), %eax
. . .
Now, in looking through all the generated code for this function (which is
a mix of C and libmmx code), I see *no* previous references to %ecx.
AFAICT, gcc should either be saving the contents of %ecx at the top of
next_word, or should not be assigning %ecx to the num_bits argument.
It feels like a bug to me, but I only last night finally conquered the
inline asm syntax, and maybe only partially at that. Am I doing something
wrong in the inline asm routine that's allowing this? If it is a bug, is
there a way around it?
TIA,
Omega
P.S. I'm not on the gcc-bugs list, so please cc: me, thanx.
Erik Walthinsen <omega@temple-baptist.com> - System Administrator
__
/ \ GStreamer - The only way to stream!
| | M E G A ***** http://gstreamer.net/ *****
_\ /_