;->s.Interface



r0      RN      0
r1      RN      1
r2      RN      2
r3      RN      3
r4      RN      4
r5      RN      5
r6      RN      6
r7      RN      7
r8      RN      8
r9      RN      9
r10     RN     10
r11     RN     11
r12     RN     12
r13     RN     13
r14     RN     14
r15     RN     15

a1      RN      0
a2      RN      1
a3      RN      2
a4      RN      3

v1      RN      4
v2      RN      5
v3      RN      6
v4      RN      7
v5      RN      8
v6      RN      9

sl      RN     10
fp      RN     11
ip      RN     12
sp      RN     13
lr      RN     14
pc      RN     15

C_bit   *       1 :SHL: 29
V_bit   *       1 :SHL: 28

        IMPORT  |Image$$RO$$Base|
        IMPORT  |_Lib$Reloc$Off$DP|

        IMPORT  dumper_entry

        EXPORT  veneer_dumper_entry


        AREA    FSEntry_Interfaces,REL,CODE,READONLY

        LTORG

veneer_dumper_entry
        STMFD   sp!, {r8}

        ; Store the input registers onto the stack
        STMFD   sp!,{r0-r9, sl, fp, ip, lr}

        MOV     r8, #fsentry_branchtable - %F10 + 4*0


        MOV     sl, sp, LSR #20
        MOV     sl, sl, LSL #20         ; SP_LWM
        LDMIA   sl, {v1, v2}            ; save old reloc modifiers over fn call
        LDR     r12, [r12]              ; private word pointer
        LDMIB   r12, {fp, r12}          ; new relocation modifiers
        STMIA   sl,  {fp, r12}          ; set by module init
        MOV     fp, #0                  ; halt C backtrace here!

        ; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|
        DCD     |_Lib$Reloc$Off$DP| + &E28AA000

        ; Pass a pointer to the structure on the stack
        MOV     a1, sp

        ; BL    fsentry_branchtable[r8]
        MOV     lr, pc
        ADD     pc, pc, r8

        ; This is equivalent of 'SUB r10, r10, #0' + |_Lib$Reloc$Off$DP|
        DCD     |_Lib$Reloc$Off$DP| + &E24AA000

10      ; This label must be the 2nd instructions past the above ADD pc, pc, r8

        STMIA   sl, {v1, v2}            ; restore old reloc modifiers

        TEQ     pc,pc
        BNE     mode26

     ; Save the returned value in r8

        CMP     r0,#0
        STRNE   r0,[sp,#0]

        ; Get the stuff off the stack
        LDMFD   sp!, {r0-r9, sl, fp, ip, lr}
        ; If returned value indicates an error, then set the overflow and put it back in r0

        ; Mess about with the flag bits in r8
        MRS     r8, CPSR
        BIC     r8, r8, #C_bit + V_bit
        ORRNE   r8, r8, #V_bit          ; V = err != 0
        TST     r1, r1                  ; C = r1 == 0
        ORREQ   r8, r8, #C_bit

        ; Move the flag bits into psr
        MSR    CPSR_f, R8

        LDMFD   sp!, {r8}

        MOV     pc, lr



mode26
        ; Save the returned value in r8

        CMP     r0,#0
        STRNE   r0,[sp,#0]

        ; Get the stuff off the stack
        LDMFD   sp!, {r0-r9, sl, fp, ip, lr}

        ; If returned value indicates an error, then set the overflow and put it back in r0

        ; Mess about with the flag bits in r8
        MOV     r8, pc
        BIC     r8, r8, #C_bit + V_bit
        ORRNE   r8, r8, #V_bit          ; V = err != 0
        TST     r1, r1                  ; C = r1 == 0
        ORREQ   r8, r8, #C_bit

        ; Move the flag bits into psr
        TEQP    r8, #0

        LDMFD   sp!, {r8}

        MOV     pc, lr

fsentry_branchtable
        B       dumper_entry

        END



