Mike Crowe said:
> 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.

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

unsubscribe: body of `unsubscribe linux-arm' to [EMAIL PROTECTED]

Reply via email to