__builtin_constant_p and inline assembly constraints

Andrew Haley aph@gcc.gnu.org
Wed Aug 23 12:15:00 GMT 2006


Simon Kagstrom writes:
 > At Wed, 23 Aug 2006 11:02:24 +0100,
 > Andrew Haley wrote:
 > > 
 > > Weird.  There's not really enough information here.  Can you provide
 > > the .s file from the compiler?  That would give us more of a clue.
 > 
 > I've attached it below.
 > 
 > At Wed, 23 Aug 2006 11:14:45 +0100,
 > Andrew Haley wrote:
 > > 
 > > Simon Kagstrom writes:
 > >  > 
 > >  > #define _syscall1(type,name,atype,a) \
 > >  > type name(atype a) { \
 > >  > 	register unsigned long __v0 asm("$2"); \
 > >  > 	__asm__ volatile (".set  push\n.set  noreorder\n"); \
 > >  >         __emit_parameter(a); \
 > >  > 	__asm__ volatile ( \
 > >  > 	".short 0xffff\t#" #name "\n\t" \
 > >  >         ".short %1\n" \
 > >  > 	: "=&r" (__v0) \
 > >  > 	: "i" (__NR_##name) ); \
 > >  >         __asm__ volatile(".set\tpop\n"); \
 > >  > 	return (type) __v0; \
 > >  > }
 > > 
 > > I'm still trying to get my head around what the assembler will do when
 > > gcc moves these asms around.
 > > 
 > > Put the ".set  push\n.set  noreorder\n" stuff *inside* the asms.  Please.  :-)
 > 
 > I tried placing the .set push / .set noreorder stuff in the
 > __emit_parameter and the main asm statement, and the generated code
 > looks better:
 > 
 >  1002314:               addiu   sp,sp,72
 >  1002318:               0xfffe0009
 >  100231c:               j       100229c <test_malloc+0x144>
 >  1002320:               nop
 > 
 > 01002324 <main>:
 >  1002324:               addiu   sp,sp,-24
 > 
 > But I cannot quite understand where the difference comes from. What I
 > would like the original macro to generate is:
 > 
 > .set push
 > .set noreorder
 > 	.long	0xfffe0009
 > 	.short	0xffff
 > 	.short	9
 > .set pop

So why not do that, then?  In a single asm.  

GCC is entitled to put anything it likes between volatile asms, or
move them around, as long as they get executed in the order you've
asked for.

If you do anything in an asm statement that changes the global assmber
state, you must undo it *before the end of that asm statement*.

 > Is the problem perhaps that GCC outputs assembly directives "between"
 > the __emit_parameter and the main asm statement without pushing the
 > current settings?

Yes.  Have a look.  Here it is:


$L83:
#APP
	.set  push
.set  noreorder

	.short  0xfffe
.short  $9

#NO_APP
	j	$L79
	.end	test_malloc
	.section	.rodata.str1.4


Andrew.




More information about the Gcc-help mailing list