__builtin_constant_p and inline assembly constraints

Simon Kagstrom simon.kagstrom@bth.se
Tue Aug 22 12:31:00 GMT 2006


I'm trying to dyanmically generate different bitpatterns using inline
assembly depeding on a value is constant or not. I'm using it to issue
system calls (see http://spel.bth.se/index.php/Cibyl) and avoid
clobbering registers with constant values. What I'm trying to achieve
is this:

	move    a0,v0	# Normal MIPS instruction
	0000fffd 	# Argument, is a constant
	00000020 	# Constant 32
	ffff0001 	# System call number 1

I use the first word as encoding of the "argument" type and the second
as the constant or register number. My problem is: How can I generate
this reliably from inline assembly? It seems to me that
__builtin_constant_p doesn't work as I would expect it to.

My syscall macros are defined as:

#define _syscall1(type,name,atype,a) \
type name(atype a) \
{ \
	register unsigned long __v0 asm("$2"); \
	__asm__ volatile ( \
        ".set  push" \
	".set  noreorder  " \
	".long %1" \
        ".long %2" \
	".short 0xffff  #" #name "  " \
        ".short %3" \
        ".set  pop" \
	: "=&r" (__v0) \
	:"r?i" (__builtin_constant_p(a) ? 0xfffd : 0xfffe), "r?i" (a), \
         "i" (__NR_##name) \
	); \
	return (type) __v0; \

When I compile code which uses the above call (puts("Hello, cruel world!\n");,
const char* argument), I get the following:

	move    a0,v0	# Normal MIPS instruction
	0000fffe 	# Argument, is a _register_
	00000020 	# Constant 32
	ffff0001 	# System call number 1

so the funny thing here is that GCC seems to realize that the "r?i"
constraint to the right can emit the constant directly (without a
register), whereas __builtin_constant_p() returns false and my
thought-out evil optimization fails.

I realize that GCC cannot detect all constant values with
__builtin_constant_p(), but in this case it seems internally
inconsistent - it apparently emits a constant for the string
address. Any takes? Would this qualify as a bug?

My GCC is

   mips-linux-gcc (GCC) 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)

// Simon

More information about the Gcc-help mailing list