/* Call Wallaby library function
 * 
 * This function is called by using the _WALLABYLIB* macros as defined
 * in wallabylib.h. The index of the actual library function must first
 * be stored in wallabylib_func. The _WALLABYLIB_FUNC macro takes care
 * of this. The _WALLABYLIB_CALL macro then calls the function below.
 *
 * The wallabylib_call function looks up the correct jumpaddress for the
 * requested function and the correct Wallaby version. Then it calls
 * that function with exactly the same arguments as the ones this
 * function was called with.
 */

#include "version.h"

#define EXTERN(name) .globl name;
#define ENTRY(name) .globl name; \
                    name:

EXTERN(wallaby_version)
EXTERN(wallabylib_func)
EXTERN(v514_jumptable)
EXTERN(v515_jumptable)
EXTERN(v517_jumptable)
EXTERN(v622_jumptable)
EXTERN(v515b_jumptable)

ENTRY(wallabylib_call)
    sub     sp, sp, #4              /* Reserve space for function call */
    stmfd   sp!, {r0-r3,lr}
    ldr     r0, ptr_wallaby_version
    ldr     r1, [r0]                /* r1 now holds the wallaby version */
    cmp     r1, #WALLABY_UNIDENT
    beq     skipcall                /* Skip on no version detected */
    sub     r1, r1, #1
    adr     r0, ptr_jumptables
    add     r0, r0, r1, lsl #2
    ldr     r2, [r0]                /* r2 holds the jumptable pointer for the correct version */
    ldr     r0, ptr_wallabylib_func
    ldr     r3, [r0]                /* r3 holds the function index */
    add     r1, r2, r3, lsl #2      /* r3 holds the function pointer */
    ldr     r3, [r1]
    str     r3, [sp, #0x14]
    ldmfd   sp!, {r0-r3,lr,pc}
skipcall:                           /* skip library call when no correct */
    ldmfd   sp!, {r0-r3,lr}         /*   version has been detected */
    add     sp, sp, #4
    mov     pc, lr

ptr_wallaby_version:
    .word   wallaby_version
ptr_wallabylib_func:
    .word   wallabylib_func
ptr_jumptables:
    .word   v514_jumptable
    .word   v515_jumptable
    .word   v517_jumptable
    .word   v622_jumptable
    .word   v515b_jumptable

