Subject: Function calling conventions

From: Mike Crowe <[email-masked]>
Date: Thu, 4 Mar 1999 14:21:17 +0000

I'm searching for documentation of the calling conventions used by
egcs-1.1.1 on ARM. I've looked at the egcs and binutils source but
haven't found anything useful.

I'm particularly interested in the registers that need and need not be
preserved by functions.

TIA

-- 
Mike Crowe <[email-masked]>
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Russell King <[email-masked]>
Date: Thu, 4 Mar 1999 17:53:50 +0000 (GMT)

> I'm particularly interested in the registers that need and need not be

Briefly (or not so breifly):

  r0 = first argument
  r1 = second argument
  r2 = third argument
  r3 = fourth argument

  r4 - r9 need to be preserved
  r10 = stack limit (APCS) or PIC register
  r11 = frame pointer
  r12 = temporary register (need not preserved, but is
        destroyed over a function call)
  r13 = stack pointer
  r14 = link register (PC for function return)
  r15 = program counter

  fifth and so on arguments can be found on the stack at the point
  when the function is called.

Minimal function entry and exit is:
  ( fp = r11, ip = r12, sp = r13, lr = r14, pc = r15 )

  mov ip, sp
  stmfd sp!, {fp, ip, lr, pc}
  sub fp, ip, #4

  @ r0 = arg1, r1 = arg2, r2 = arg3, r3 = arg4
  @ ldr rd, [fp, #4] will load rd with arg5

  ldmea fp, {fp, sp, pc}

Maximal function entry and exit is:
  ( fp = r11, ip = r12, sp = r13, lr = r14, pc = r15 )

  mov ip, sp
  stmfd sp!, {r4, r5, r6, r7, r8, r9, fp, ip, lr, pc}
  sub fp, ip, #4

  @ r0 = arg1, r1 = arg2, r2 = arg3, r3 = arg4
  @ ldr rd, [fp, #4] will load rd with arg5

  ldmea fp, {r4, r5, r6, r7, r8, r9, fp, sp, pc}

If you wish to do varargs type stuff, then it changes to:

  mov ip, sp
  stmfd sp!, {r0, r1, r2, r3}
  stmfd sp!, {..., fp, ip, lr, pc}
  sub fp, ip, #4 + 4 * 4		@ 4 + sizeof(reg) * number of extra regs

  @ argn is at [fp, #4 + 4 * n]

  ldmea fp, {..., fp, sp, pc}

If you don't require the frame pointer, you can just use
the stack conventionally, but so long as you follow the
register preservation rules.

Also note that the frame pointer is either supposed to
contain either a valid frame pointer or zero at all times.

There are other optimisations that you can do to all of these
such as function epilog optimisation, eg:

  ldmea fp, {..., fp, sp, lr}
  b  function

instead of:

  bl function
  ldmea fp, {..., fp, sp, pc}

Hmm, this has come up before - maybe someone ought to put
this into an FAQ on the subject?

--
Russell King ([email-masked])

---

From: Philip Blundell <[email-masked]>
Date: Thu, 04 Mar 1999 19:00:33 +0000

>I'm particularly interested in the registers that need and need not be

I think you can get ABI documentation from ARM's web site; look for APCS or 
ATPCS documents.  At the moment the code GCC produces is pretty much compliant 
with APCS.

Briefly a function can clobber R12 and as many of R0-R3 as are not needed for 
return values.

p.