This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Q for inline arm assembly: 'M' constraint?


> Richard Earnshaw wrote:
> 
> > inline int fixp_mul_32s_nX( int a, int b, char n ) {
> > 	int res, tmp;
> > 	int p = 32-n;
> > 	__asm__ __volatile__ (
> > 		"smull	%0, %1, %2, %3			\n\t"
> > 		"movs	%0, %0, lsr %4			\n\t"
> > 		"adc	%1, %0, %1, lsl %5		\n\t"
> > 		: "=&r" (res), "=&r" (tmp)
> > 		: "r" (a), "r" (b), "rM" (n), "rM" (p)
> > 	);
> > 	return res;
> > }
> > 
> > This allows the compiler to use a register or a constant in the range 
> > 0-31.  But it's quite possible that you will always get a register passed 
> > in this case.
> 
> Ok, I've tried this, and you're right, I always get a register, but why? 

Not entirely sure.  Which compiler release and what optimization level are 
you using?  With a simple testcase I tried I got:

static inline int fixp_mul_32s_nX( int a, int b, char n ) {
        int res, tmp;
        int p = 32-n;
        __asm__ __volatile__ (
                "smull  %0, %1, %2, %3                  \n\t"
                "movs   %0, %0, lsr %4                  \n\t"
                "adc    %1, %0, %1, lsl %5              \n\t"
                : "=&r" (res), "=&r" (tmp)
                : "r" (a), "r" (b), "rM" (n), "rM" (p)
        );
        return res;
}
int
foo (int a, int b) {
 return fixp_mul_32s_nX(a, b, 15);}

foo:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        @ lr needed for prologue
        smull   r2, r3, r0, r1
        movs    r2, r2, lsr #15
        adc     r3, r2, r3, lsl #17

        mov     r0, r2
        mov     pc, lr

with -O1 on the current development version of the compiler.

>  Is it just me, or does the "M" constraint seem useless?  Am I expecting too 
> much?  Is there some other way to do what I'm trying to?
> 

The M constraint was added primarily for internal use by the compiler 
(internal patterns work in a similar way to ASM, but with more flexibility 
and control).  Use of it in ASM statements is supported only to the extent 
that it works for you...

I suspect that the reason you aren't getting what you want is that you 
have not turned on optimization, but there may be something else that 
isn't apparent.

R.



------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com


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