This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: i386 setjmp, asm volatile ("") and -fno-defer-pop


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]