First Try At Inline Asm


sparr

Member
Joined
Jun 3, 2006
Messages
292
Code:
int mulff(int a, int b)
{
  int c;
  asm volatile
  (
	"smull r7,r8,%1,%2\n" // {r2,r3} = r0*r1
	"mov %0, r7\n"	  // return the high 32 bits, hopefully
	: "=r"(c)   // %0 = output value from the function
	: "r"(a), "r"(b)  // inputs: %1, %2
	: "r7", "r8"	// registers we clobber
  );
  return c;
}

This mostly returns zero, even when it should return other stuff. If I return r8 instead of r7 then for some reason I only get values between -65536 and +65535, with the upper 16 bits all 0 or all 1.

PS: yes, this is a very much stripped down version of what I started with.
 
Sparr posted on Jul 28 2006 at 06:20 AM said:
Code:
int mulff(int a, int b)
{
  int c;
  asm volatile
  (
	"smull r7,r8,%1,%2\n" // {r2,r3} = r0*r1
	"mov %0, r7\n"	  // return the high 32 bits, hopefully
	: "=r"(c)   // %0 = output value from the function
	: "r"(a), "r"(b)  // inputs: %1, %2
	: "r7", "r8"	// registers we clobber
  );
  return c;
}
This mostly returns zero, even when it should return other stuff. If I return r8 instead of r7 then for some reason I only get values between -65536 and +65535, with the upper 16 bits all 0 or all 1.

PS: yes, this is a very much stripped down version of what I started with.

Well, GCC is "doing the right thing", even with maximum optimisation:

.global _Z5mulffii
.type _Z5mulffii, %function
_Z5mulffii:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
stmfd sp!, {r7, r8}
@ lr needed for prologue
#APP
smull r7,r8,r0,r1
mov r0, r7

ldmfd sp!, {r7, r8}
bx lr
Are you passing in fixed point values? If you are you should shift the result accordingly (result = r7>>16 | r8<<16, for example). If not, what values are you trying? (I've not got time to run some test cases on it myself right now).
 
Last edited by a moderator:
i was doing the shift/or/shift originally, and getting garbage. i stripped it down to just returning one of the result registers directly for testing purposes, even though it gives the wrong answer it gives a more predictable wrong answer.

the problem ended up being a mistake somewhere in my handling of the variables in the inline asm syntax. i copied the smull function from libogg (hello optimized ARM code, *GRAB*) and it is working fine now.
 
Back
Top