GCC inline asm with aapcs

CDevel

I'm trying to optimize a mathematical function writing inline assembly with GCC and ARM Cortex-A7. My code is this:

__inline int __attribute__((pcs("aapcs"))) optAbsVal(int x)
{
  asm("CMP R0, #0\n"
      "IT LT\n"
      "RSBLT R0, R0, #0");
  return(x);
}

I did not specify any input/output parameters nor the clobbers inside the inline asm block because, according to the calling convention, x should be in R0, as well as the return value. The problem is this function returns the value of x without modifying it, which makes me think either x is not in R0 or the compiler modifies in some way the function. I resolved this by adding the parameters "=r"(x) : "0"(x), but still I'm not satisfied with this code as it seems I'm doing unnecessary operations. The reason I'm doing pcs("aapcs") is to avoid load/store ops to get better performances, but this is getting worse instead.

Ross Ridge

Since x isn't the return value it doesn't need to be in R0. The return value is the result of the evaluating the expression given in the return statement. So with return x the return value isn't x, the return value is the value of x. This is important distinction because that this means x doesn't need to live in R0, only that the value in x in needs to be copied into R0 before the function returns.

So since the last statement to be executed in your function is return (x); then that means the last thing your function does is copy x to R0, which clobbers the value you stored in R0 in your inline assembly statement.

This is why you must always fully describe the effect on the machine state your inline assembly statements. The compiler has no idea you want the value in R0 preserved. It has no idea you expect the value passed in the x paramater to be in R0 on entry to the asm statement. That might be true because of the calling convention, but the rules of the calling convention only apply at entry and exit to a function, not in the middle of a function where your asm statement is. If your function is inlined into another function then the calling convention doesn't apply at all since there's no actual function call.

So what you want is something like this:

__inline int optAbsVal(int x)
{
  asm("CMP %0, #0\n"
      "IT LT\n"
      "RSBLT %0, %0, #0"
      : "+r" (x) : : "cc");
  return(x);
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related