Optimization and inline assembly in GCC 4.0/MIPS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello!

I have a problem which I don't know if it's a bug or simply an error
on my part (admittedly I'm stretching some expectations). This code
was working in GCC 3.4, but broke after I switched to 4.0. I think I
have managed to fix it, but am not sure my fix holds.


The problem is that GCC optimizes away more code to setup an
argument. The code I'm working on is part of the Cibyl project [1],
which recompiles MIPS binaries -> Java bytecode. The problematic code
is the following:

   int vStreamOpen(const char *filename, int mode)
   {
     char m[4];

     memset(m, 0, sizeof(m));
     if (mode & (1<<2))
       m[0] = 'r';

     return (int)fopen(filename, m);
   }

the if-statement in this case does not generate any code (GCC assumes
that m is ignored by fopen). fopen is in my case a Java-function,
which is called through a "system call", to which I pass arguments
through a special instruction encoding.

The relevant defintions in this case is

   #define __NR_fopen 16
   static inline _syscall2(FILE*,fopen, const char*, path, const char*, mode);

   ...

   #define _syscall2(type,name,atype,a,btype,b) \
   type name(atype a, btype b) \
   { \
	   register unsigned long __v0 asm("$2"); \
	   \
	   __asm__ volatile ( \
	   ".set  push\n.set  noreorder\n" \
	   ".short 0xfffe\n" \
	   ".short %1\n" \
	   ".short 0xfffe\n" \
	   ".short %2\n" \
	   ".short 0xffff\t#" #name "\n\t" \
	   ".short %3\n" \
	   ".set\tpop\n" \
	   : "=r" (__v0) \
	   : "r"(a), "r"(b), \
	     "i" (__NR_##name) \
	   ); \
	   \
	   return (type) __v0; \
   }

and GCC 4.0 generates

   00000000 <vStreamOpen>:
      0:	27bdfff8 	addiu	sp,sp,-8
      4:	afa00000 	sw	zero,0(sp)
      8:	fffe0004 	0xfffe0004
      c:	fffe0005 	0xfffe001d
     10:	ffff0010 	0xffff0010
     14:	03e00008 	jr	ra
     18:	27bd0008 	addiu	sp,sp,8
     1c:	00000000 	nop

from this (i.e., the if-statement above does not generate any
code). The effect is the same as if I would call a function where GCC
can prove that the passed parameter is unused.


Is there any way to specify that GCC should refrain from optimizing
this code away? I've looked a bit in the _syscall-definitions in the
Linux sources (include/asm-mips/unistd.h) and the GCC info-pages, and
adding a "memory" to clobber-list seems to fix my issue. The question
is then: is the memory clobber enough or does it just work by chance
here?

// Simon

[1] http://spel.bth.se/index.php/Cibyl

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux