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?


> Ok guys, I'm trying to work up some fixed-point multiplication routines 
> optimized in assembly for arm7.  Here are two different functions.

Alright, I was hesitant to take a whack because I don't currently have an
ARM toolchain or assembly spec in front of me, and I'd be working purely
from memory.  Plus I'm not familiar with the "M" constraint, but in the
absence of any other suggestions, I'll make a wild-ass guess...

> The other function was supposed to take a const argument for the "n" 
> part of the Qm.n fixed-point format.
> 
> [code]
> inline int fixp_mul_32s_nX( int a, int b, char n ) {
> 	int res, tmp;
> 	__asm__ __volatile__ (
> 		"smull	%0, %1, %2, %3			\n\t"
> 		"movs	%0, %0, lsr #%4			\n\t"
> 		"adc	%1, %0, %1, lsl #(32-%4)	\n\t"
> 		: "=&r" (res), "=&r" (tmp)
> 		: "r" (a), "r" (b), "M" (n)
> 	);
> 	return res;
> }
> [/code]

I may be wrong, but I seem to remember (way back from my ARM assembly
hacking days) that the argument to an lsl/lsr operand could either be
a register or an immediate 0..31, but not an expression.  I don't think
there's a way to represent lsl #(32-%4) in the actual instruction, given
that %4 must be a register.  (If it came into the function as a parameter,
then it certainly can't be an immediate constant, or there would have to
be a separate copy of the function for every possible value of that
parameter.)  I think you may be forced to throw an extra instruction in
there to calculate the second shift value, e.g.:

[code]
inline int fixp_mul_32s_nX( int a, int b, char n ) {
	int res, tmp;
	__asm__ __volatile__ (
		"smull	%0, %1, %2, %3			\n\t"
		"movs	%0, %0, lsr %4			\n\t"
		"sub	%4, %5, %4			\n\t"
		"adc	%1, %0, %1, lsl %4		\n\t"
		: "=&r" (res), "=&r" (tmp)
		: "r" (a), "r" (b), "r" (n), "r" (32)
	);
	return res;
}
[/code]

...which doesn't answer your direct question about the "M" constraint,
but (assuming my memory is still sharp for ARM assembly stuff) may answer
your indirect question of how do you get that function working the way
you intended.  Good luck!


                       ------Carl

------
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]