Mail Archives: cygwin/1998/07/28/11:56:57
GNU C version 2.7-b19 on gnu-win32 version b19.1 (intel x86)
generates bad assembler for the following program. The program
(cut down from C code automatically generated by the Mercury compiler)
is not strictly conforming, but even so, the generated assembler
is pretty nonsensical. This worked fine in b18.
To reproduce the problem, compile the following program with `gcc -O2 -S'.
/*--- cut here --------------------------------------------------------------*/
void abort(void);
typedef unsigned int Word;
typedef int Integer;
typedef void Code;
register Word mr0 __asm__("esi");
register Word mr1 __asm__("edi");
register Word mr2 __asm__("ebx");
typedef struct MR_mercury_engine_struct {
Word fake_reg[1024];
} MercuryEngine;
extern MercuryEngine MR_engine_base;
extern void mercury__compare_3_3 (void) __asm__("_entry_" "mercury__compare_3_3" ) ;
static void foo_module (void);
static void foo_module (void) { __asm__ __volatile__("" : : "g"( foo_module )) ; __asm__ __volatile__("" : : "g"( && foo_module_dummy_label )) ; foo_module_dummy_label : {
__asm__ __volatile__("" : : "g"( && foo_entry )) ; ;
;
} return; {
_entry_foo_entry : __asm__ __volatile__( " .globl _entry_" "foo_entry" "\n" "_entry_" "foo_entry" ":\n" ); skip_foo_entry : ; } foo_entry : __asm__ __volatile__("" : : "g"( && _entry_foo_entry )) ; { ;
( ((void)0) , ((void)0) , (( Word * )( ( mr0 ) )) = (( Word * )( ( mr0 ) )) + ( 11 ), ((void)0) , (void)0 ) ;
((( Word * )( ( mr0 ) )) [- 11 ]) = (Word) (( Code * )( ( mr1 ) )) ;
( ((MR_engine_base. fake_reg ) ) [7] ) = ((const Word *) (( ( ( ((MR_engine_base. fake_reg ) ) [3] ) ) ) - ( ( ( 1 ) ) )) )[ (Integer) 3 ] ;
( ((MR_engine_base. fake_reg ) ) [12] ) = ((const Word *) (( ( ( ((MR_engine_base. fake_reg ) ) [3] ) ) ) - ( ( ( 1 ) ) )) )[ (Integer) 0 ] ;
if (((Integer) ( ((MR_engine_base. fake_reg ) ) [7] ) != (Integer) (const Word *) ((const Word *)((const char *)( (( (Integer) 0 ) << 2 ) ) + ( ( 0 ) ))) ))
do { ((void)0) ; goto foo_label ; } while(0) ;
do { ((void)0) ; do { ((void)0) ; (( Code * )( ( mr1 ) )) = ( (&& _entry_foo_label ) ); ((void)0) ; do { ((void)0) ; { register int stack_pointer __asm__("esp"); __asm__("" : : "g"(stack_pointer)); } goto *( ( (& mercury__compare_3_3 ) ) ) ; } while(0) ; } while (0) ; } while (0) ;
abort();
_entry_foo_label : skip_foo_label : ; } foo_label : { ;
abort();
} }
/*--- cut here --------------------------------------------------------------*/
The generated code for the `goto' above is the assembler statement
jmp *%ecx
but this is the *only* occurrence of %ecx in the generated code.
%ecx is never initialized, and the reference to `mercury__compare_3_3'
somehow gets optimized away entirely.
[Incidentally, the obvious alternative of using an inline asm jmp instead
of `goto *(...)' didn't work either, because that resulted in a gcc internal
error -- on a different test case, however. I will report that one
separately if I can cut it down to a reasonable size).]
--
Fergus Henderson <fjh AT cs DOT mu DOT oz DOT au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh AT 128 DOT 250 DOT 37 DOT 3 | -- the last words of T. S. Garp.
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".
- Raw text -