This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: i386 setjmp, asm volatile ("") and -fno-defer-pop
- To: Richard Henderson <rth at redhat dot com>
- Subject: Re: i386 setjmp, asm volatile ("") and -fno-defer-pop
- From: Etienne Lorrain <etienne at masroudeau dot com>
- Date: Wed, 20 Dec 2000 18:56:19 -0800 (PST)
- cc: <gcc at gcc dot gnu dot org>
On Wed, 20 Dec 2000, Richard Henderson wrote:
> On Wed, Dec 20, 2000 at 01:40:33AM -0800, Etienne Lorrain wrote:
> > Is there a trick with GCC to force the update of the stack pointer
> > before an asm()?
>
> No.
>
> But you have other problems:
>
> (1) What you are doing with your inline longjmp is highly illegal,
> since you are not allowed to jump outside of an asm.
Well, it is probably "highly illegal" but it happen to work,
and I am using it to catch "illegal instructions" in the BIOS:
It seems quite appropriate!
More seriously, it is not related to "asm()": I will have the same
problem with real setjmp/longjmp defined in assembler in a library.
Compiling without "-fno-defer-pop" means that I will get stack
adjustment after a setjmp() which are related to the functions
called before it.
Considering "the other problems besides the one you're seeing",
like strange aliasing optimisations in between setjmp/longjmp,
officially you cannot assume value of registers when coming
back from setjmp(). When I get an "illegal instruction", I
just return an error to the caller, I just need the stack
pointer.
Anyway, thanks for the info, there is no trick in asm(),
nor __attribute__ ((stop_defer_pop)) attribute to functions,
I just have to write them myself or keep -fno-defer-pop.
> (2) You are violating type aliasing rules all over the place with
> your bzero/memset/memcpy macros.
For this:
#define memcpy(dst, src, size) do { \
struct { char tmparray[size]; } *unused __attribute__((unused)); \
*(typeof(unused)) dst = *(typeof(unused)) src; \
} while (0)
I know that it breaks aliasing, that is why they are defined only
when SETUP is undefined, and it does happen only for instboot.c
which do not use memcpy. (there is another, size optimised, _memcpy()
later in the library.h file)
Note that this macro produces the best code I have ever seen for small
"size", just the right movb/w/l. It is boring to have a nice
memory copier/initialiser (because you need it when manipulating
real structures) and not be able to use it in the general case...
By the way, someone knows the real reason why, in C, you can use
"=" but not "!=" for global manipulation of structures?
I do not know the intrinsic reason why this is invalid:
#define memcmp(dst, src, size) ({ \
struct { char tmparray[size]; } *unused __attribute__((unused)); \
return *(typeof(unused)) dst != *(typeof(unused)) src; \
})
It would not break aliasing.
Sorry for being so verbose, probably holidays approching,
Etienne.