.i_SWI_SharedCLibrary_LibInitAPCS_R
 CODELET ((CLib_end - CLib_codelet) >> 2) + 1 + 16

 ADR     R5, CLib_codelet

 ADD     R0, R0, #JIT_SWI_OS_Flag << 20	;trigger our SWI handler
 LDMIA   R5!, {R1-R2}			;get replacement instructions
					;-------- 1st instruction --------
 SUB     R4, R14, R6			;correct for offset and prefetch
 SUB     R4, R4, #8 + (2 * 4)
 BIC     R4, R4, #%111111 << 26
 ORR     R1, R1, R4, LSR #2		;B <original address + 4>
 STMIA   R6!, {R0-R2}

 LDMIA   R5!, {R0-R4}			;write chuck ID block
 ADD     R0, R0, R6			;correct address
 ADD     R1, R1, R6			;correct address
 STMIA   R6!, {R0-R4}
 LDMIA   R5!, {R0-R4}
 ADD     R0, R0, R6			;correct address
 ADD     R1, R1, R6			;correct address
 STMIA   R6!, {R0-R4}

 ADD     R6, R6, #16 * 4		;space for stack
 STR     R6, [R6, #0]			;store _stack_ptr

 ADR     R2, CLib_end - 4		;copy _C_entry_codelet onwards
 ._L1
   LDR     R0, [R5, #4]!
   STR     R0, [R6, #4]!
   CMP     R5, R2
 BNE     _L1

B       i_instruction_handled

 .CLib_codelet
 ;SWI     XSharedCLibrary_LibInitAPCSxx		;R0
 B       CLib_chunk_id + 4			;R1 B <original address + 4>
 .CLib_chunk_id
 DCD     1					;R2	;library chunk id
 ._h1
 DCD     C_vector_chunk_1 - _h1 + (16*4)	;R0	;entry vector base
 DCD     C_vector_chunk_2 - _h1 + (16*4)	;R1	;entry vector limit
 DCD     0					;R2	;static data base
 DCD     0					;R3	;static data limit

 DCD     2					;R4	;library chunk id
 ._h2
 DCD     C_vector_chunk_2 - _h2 + (16*4)	;R0	;entry vector base
 DCD     C_inbound_table_2 - _h2 + (16*4)	;R1	;entry vector limit
 DCD     0					;R2	;static data base
 DCD     0					;R3	;static data limit

 DCD     -1					;R4	;terminator


 ;._stack	DBD 16
 .C_stack_ptr	DCD 0			;pointer to itself

.C_entry_chunk2
 ADD     R14, R14, #(C_vector_chunk_2 - C_vector_chunk_1) >> 2
.C_entry_chunk1
 ADR     R12, C_vector_chunk_1
 ADD     R14, R12, R14, LSL #2
 LDR     R0, [R13, #8]			;get entry R14 which contains PSR flags
 LDR     R12, C_stack_ptr
 STR     R0, [R12, #-4]!		;stack R14 onto our stack
 STR     R12, C_stack_ptr
 STR     R14, [R13, #8]			;overwrite R14 with C entry
 ADR     R14, _return
 LDMFD   R13!, {R0, R12, PC}		;call C function
 ._return
 STMFD   R13!, {R12}
 LDR     R12, C_stack_ptr
 LDR     R14, [R12], #4			;get R14
 STR     R12, C_stack_ptr
 LDMFD   R13!, {R12}			;return to user code
 MSR     CPSR_f, R14			;restore PSR flags
 BIC     R14, R14, #&FC000003		;jump back to user code
 ADD     PC, R14, #jit_code_start

 .C_inbound_table_1
 B       CLib_kernel_init		;0 _kernel_init need hypervising
 NOP
 NOP
 #set loop = 1

 #rept 4-1
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 B       CLib_kernel_unwind		;4 _kernel_unwind need hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 9-5
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 B       CLib_kernel_swi		;9 _kernel_swi need hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 15-10
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 STMFD   R13!, {R0, R12, R14}
 B       CLib_kernel_osgbpb		;15 _kernel_osgbpb needs hypervising
 NOP
 #set loop = loop + 1

 #rept 18-16
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 STMFD   R13!, {R0, R12, R14}
 B       CLib_kernel_osfile		;18 _kernel_osfile needs hypervising
 NOP
 #set loop = loop + 1

 #rept 25-19
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 STMFD   R13!, {R0, R12, R14}
 B       CLib_kernel_register_allocs	;25 _kernel_register_allocs needs
 NOP					;hypervising
 #set loop = loop + 1

 #rept 38-26
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 STMFD   R13!, {R0, R12, R14}
 B       CLib_kernel_moduleinit		;38 _kernel_moduleinit needs
 NOP					;hypervising
 #set loop = loop + 1

 #rept 42-39
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 STMFD   R13!, {R0, R12, R14}
 B       CLib_kernel_entermodule	;42 _kernel_entermodule needs
 NOP					;hypervising
 #set loop = loop + 1

 #rept 45-43
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk1
   #set loop = loop + 1
 #endr

 B       CLib_kernel_swi_c		;45 _kernel_swi_c needs hypervising
 NOP
 NOP
 #set loop = loop + 1

 B       CLib_kernel_register_slotextend ;46 _kernel_register_slotextend
 NOP					;needs hypervising
 NOP
 #set loop = loop + 1

 STMFD   R13!, {R0, R12, R14}
 MOV     R14, #loop
 B       C_entry_chunk1


 .C_vector_chunk_1	DBD 48*2
 .C_vector_chunk_2	DBD 185*2	;CLib has 183 official, 185 unofficial


 #set loop = 0
 .C_inbound_table_2
 #rept 18
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk2
   #set loop = loop + 1
 #endr

 B       CLib_main			;18 _main need hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 71 - 19
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk2
   #set loop = loop + 1
 #endr

 B       CLib_atexit			;71 atexit need hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 75 - 72
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk2
   #set loop = loop + 1
 #endr

 B       CLib_bsearch			;75 qsearch need hypervising
 NOP
 NOP
 #set loop = loop + 1

 B       CLib_qsort			;76 qsort need hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 128 - 77
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk2
   #set loop = loop + 1
 #endr

 B       CLib_signal			;128 signal needs hypervising
 NOP
 NOP
 #set loop = loop + 1

 #rept 183 - 129
   STMFD   R13!, {R0, R12, R14}
   MOV     R14, #loop
   B       C_entry_chunk2
   #set loop = loop + 1
 #endr

 B       CLib_swi			;183 _swi need hypervising
 NOP
 NOP
 #set loop = loop + 1

 B       CLib_swix			;184 _swix need hypervising
 NOP
 NOP
 #set loop = loop + 1



 #set    a1 = 0				;define APCS-R registers
 #set    a2 = 1
 #set    a3 = 2
 #set    a4 = 3
 #set    v1 = 4
 #set    v2 = 5
 #set    v3 = 6
 #set    v4 = 7
 #set    v5 = 8
 #set    v6 = 9
 #set    sl = 10			;APCS-A = 13
 #set    fp = 11			;APCS-A = 10
 #set    ip = 12			;APCS-A = 11
 #set    sp = 13			;APCS-A = 12
 #set    lr = 14

 ;Entry:
 ;[R0, #4] - pointer to start of language description block (PRM4-257)
 ;[R0, #8] - pointer to end of language description block (PRM4-257)
 ;R2 C Stack
 ;see PRM4-246 for language description structure


.CLib_kernel_init			;entry 0 in chunk 1 PRM4-278
 MOV     R13, R2
 STMFD   R13!, {R0-R6, R11, R12}
 ADR     R6, _language_block
 LDMIA   R0, {R1, R11, R12}		;load kernel init block
 ._L1
   LDMIA   R11, {R0-R5}
   TEQ     R4, #0
   ADDNE   R4, R4, #jit_code_start	;alter InitProc
   STRNE   R4, _c_init_entry
   ADRNE   R4, _c_init
   TEQ     R5, #0
   ADDNE   R5, R5, #jit_code_start	;alter FinaliseProc
   STRNE   R5, _c_finalise_entry
   ADRNE   R5, _c_finalise
   ADD     R1, R1, #jit_code_start
   MOV     R2, #jit_slotsize		;allow our handlers to be called
   STMIB   R6, {R1-R5}

   MOV     R1, #0
   CMP     R0, #24			;is TrapProc there?
   LDRHI   R1, [R11, #24]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_trapproc_entry	; |  store entry point
   ADRHI   R1, _c_trapproc		; |  point to our entry
   STR     R1, [R6, #24]

   MOV     R1, #0
   CMP     R0, #28			;is UncaughtTrapProc there?
   LDRHI   R1, [R11, #28]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_uncaughttrapproc_entry	; |  store entry point
   ADRHI   R1, _c_uncaughttrapproc	; |  point to our entry
   STR     R1, [R6, #28]

   MOV     R1, #0
   CMP     R0, #32			;is EventProc there?
   LDRHI   R1, [R11, #32]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_eventproc_entry	; |  store entry point
   ADRHI   R1, _c_eventproc		; |  point to our entry
   STR     R1, [R6, #32]

   MOV     R1, #0
   CMP     R0, #36			;is UnhandledEventProc there?
   LDRHI   R1, [R11, #36]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_unhandledeventproc_entry	; |  store entry point
   ADRHI   R1, _c_unhandledeventproc	; |  point to our entry
   STR     R1, [R6, #36]

   MOV     R1, #0
   CMP     R0, #40			;is FastEventProc there?
   LDRHI   R1, [R11, #40]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_fasteventproc_entry	; |  store entry point
   ADRHI   R1, _c_fasteventproc		; |  point to our entry
   STR     R1, [R6, #40]

   MOV     R1, #0
   CMP     R0, #44			;is UnwindProc there?
   LDRHI   R1, [R11, #44]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STR     R1, _c_unwindproc_entry	; |  store entry point
   ADR     R1, _c_unwindproc		; |  point to our entry
   STR     R1, [R6, #44]

   MOV     R1, #0
   CMP     R0, #48			;is NameProc there?
   LDRHI   R1, [R11, #48]		;YES,
   CMPHI   R1, #0			; |  is it set?
   ADDHI   R1, R1, #jit_code_start	; |  correct address
   STRHI   R1, _c_nameproc_entry	; |  store entry point
   ADRHI   R1, _c_nameproc		; |  point to our entry
   STR     R1, [R6, #48]

   ADD     R11, R11, R0			;go to next language block
 CMP     R11, R12
 BNE     _language_error

 LDR     R0, [R13], #4
 ADR     R11, _language_block
 ADD     R12, R11, #52
 STR     R11, [R0, #4]			;overwrite language description start
 STR     R12, [R0, #8]			;overwrite language description end
 LDMFD   R13!, {R1-R6, R11, R12}
 B       C_vector_chunk_1 + (0 << 2)

 ._language_error
 LDMFD   R13!, {R0-R6, R11, R12}	;clear stack
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5998 CLib multiple language description blocks not supported", 0
 ALIGN


 ._language_block
 DCD	52	;size
 DCD	0	;codestart
 DCD	0	;codeend
 DCD	0	;name
 DCD	0	;InitProc
 DCD	0	;FinaliseProc
 DCD	0	;TrapProc
 DCD	0	;UncaughtTrapProc
 DCD	0	;EventProc
 DCD	0	;UnhandledEventProc
 DCD	0	;FastEventProc
 DCD	0	;UnwindProc
 DCD	0	;NameProc


 ._c_init
 STMFD   R13!, {R14}			;store CLib's return address
 ADD     R14, PC, #0			;get it to return to us
 LDR     PC, _c_init_entry		;call c function
					;R0 now contains c_run entry point
 CMP     R0, #jit_appspace_end		;are we jumping to appspace?
 ADDLO   R0, R0, #jit_code_start	;YES, correct it
 STR     R0, _c_run_entry
 ADR     R0, _c_run			;change it to us

 ._c_managed_exit
 LDMFD   R13!, {PC}			;return to CLib
 ._c_init_entry			DCD 0

 ._c_run
 STMFD   R13!, {R14}			;store CLib's return address
 ADR     R14, _c_managed_exit		;return through us
 LDR     PC, _c_run_entry		;call c function
 ._c_run_entry			DCD 0

 ._c_finalise
 STMFD   R13!, {R14}			;store CLib's return address
 ADR     R14, _c_managed_exit		;return through us
 LDR     PC, _c_finalise_entry		;call c function
 ._c_finalise_entry		DCD 0

 ._c_trapproc
 STR     R14, _c_trapproc_return	;store CLib's return address
 LDR     R14, _c_trapproc_entry
 TEQ     R14, #0
 ADRNE   R14, _c_trapproc_r14		;return through us
 LDRNE   PC, _c_trapproc_entry		;call c function
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5998 CLib TrapProc called", 0
 ALIGN
 ._c_trapproc_entry		DCD 0
 ._c_trapproc_return		DCD 0
 ._c_trapproc_r14
 LDR     PC, _c_trapproc_return

 ._c_uncaughttrapproc
 STR     R14, _c_uncaughttrapproc_return	;store CLib's return address
 LDR     R14, _c_uncaughttrapproc_entry
 TEQ     R14, #0
 ADRNE   R14, _c_uncaughttrapproc_r14		;return through us
 LDRNE   PC, _c_uncaughttrapproc_entry		;call c function
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)		;_kernel_raise_error
 DCD     0
 DCB     "ADFF5998 CLib UncaughtTrapProc called", 0
 ALIGN
 ._c_uncaughttrapproc_entry	DCD 0
 ._c_uncaughttrapproc_return	DCD 0
 ._c_uncaughttrapproc_r14
 LDR     PC, _c_trapproc_return

 ._c_eventproc
 STR     R14, _c_eventproc_return	;store CLib's return address
;@@@ before calling user proc entry, need to check it's not branching
;    to CLib's handler
; LDR     R14, _c_eventproc_entry
; TEQ     R14, #0
; ADRNE   R14, _c_eventproc_r14		;return through us
; LDRNE   PC, _c_eventproc_entry		;call c function
 ._c_eventproc_r14
 MOV     a1, #1				;ignore event
 LDR     PC, _c_eventproc_return
 ._c_eventproc_entry		DCD 0
 ._c_eventproc_return		DCD 0

 ._c_unhandledeventproc
 STR     R14, _c_unhandledeventproc_return	;store CLib's return address
;@@@ before calling user proc entry, need to check it's not branching
;    to CLib's handler
; LDR     R14, _c_unhandledeventproc_entry
; TEQ     R14, #0
; ADRNE   R14, _c_unhandledeventproc_r14		;return through us
; LDRNE   PC, _c_unhandledeventproc_entry	;call c function
 ._c_unhandledeventproc_r14
 MOV     a1, #1				;ignore event
 LDR     PC, _c_unhandledeventproc_return
 ._c_unhandledeventproc_entry	DCD 0
 ._c_unhandledeventproc_return	DCD 0

 ._c_fasteventproc
 STR     R14, _c_fasteventproc_return		;store CLib's return address
; LDR     R14, _c_fasteventproc_entry
; TEQ     R14, #0
; ADRNE   R14, _c_fasteventproc_r14		;return through us
; LDRNE   PC, _c_fasteventproc_entry		;call c function
 ._c_fasteventproc_r14
 MOV     a1, #1				;ignore event
 LDR     PC, _c_fasteventproc_return
 ._c_fasteventproc_entry	DCD 0
 ._c_fasteventproc_return	DCD 0

 ._c_unwindproc
 STR     R14, _c_unwindproc_return	;store CLib's return address
 LDR     R14, _c_unwindproc_entry
 TEQ     R14, #0
 ADRNE   R14, _c_unwindproc_r14		;return through us
 LDRNE   PC, _c_unwindproc_entry	;call c function
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5998 CLib UnwindProc called", 0
 ALIGN
 ._c_nameproc_entry		DCD 0
 ._c_unwindproc_return		DCD 0
 ._c_unwindproc_r14
 LDR     PC, _c_unwindproc_return

 ._c_nameproc
 STR     R14, _c_nameproc_return	;store CLib's return address
 LDR     R14, _c_nameproc_entry
 TEQ     R14, #0
 ADRNE   R14, _c_nameproc_r14		;return through us
 LDRNE   PC, _c_nameproc_entry		;call c function
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5998 CLib NameProc called", 0
 ALIGN
 ._c_unwindproc_entry		DCD 0
 ._c_nameproc_return		DCD 0
 ._c_nameproc_r14
 LDR     PC, _c_nameproc_return




 ;Entry:
 ;R0 - operation
 ;R0, R12, R14 stacked

.CLib_kernel_osgbpb			;entry 15 in chunk 1 PRM4-284
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5997 _kernel_osgpbp called", 0
 ALIGN

 TEQ     R0, #3
 TEQNE   R0, #4
 MOVNE   R14, #15			;NO, pass call on
 BNE     C_entry_chunk1			;|+

 LDR     R14, [a3, #0 * 4]		;get R2
 STR     R14, [R12, #-4]!		;stack the load address
 LDR     R14, [R13, #2 * 4]		;get R14 from stack: {R0,R12,R14}
 STR     R14, [R12, #-4]!		;stack on C stack: {R14, loadaddr}
 TEMP    R0
 STR     R12, C_stack_ptr
 LOCK    R0
 LDMFD   R13!, {R0, R12, R14}		;clear down stack
 BL      C_vector_chunk_1 + (15 << 2)
 STMFD   R13!, {R2, R4, R12, R14}
 TEMP    R4
 LDR     R12, C_stack_ptr
 LDR     R14, [R12], #4			;get original R14 from stack
 ADDVS   R12, R12, #4			;drop load address from stack
 STRVS   R12, C_stack_ptr
 ORRVS   R14, R14, #1 << 28		;set V
 STR     R14, [R13, #3 * 4]		;put R14 on return stack: {R2, R4, R12, R14}
 BVS     _return2

 LDR     R2, [R12], #4			;pull the stacked load address
 STR     R12, C_stack_ptr
 LOCK    R4
 CMP     R2, #jit_appspace_end		;is it in application space?
 LDRLO   R4, [a3, #0 * 4]		;YES, get R4 from return vars (end addr)
 SUBLO   R4, R4, R2			; |   R4=size
 SWILO   XADFFS_ResetMemoryBlock	; |+  call hv_reset_memory_block
 ._return2
 LDMFD   R13!, {R2, R4, R12, R14}	;return to user code
 MSR     CPSR_f, R14			;restore PSR flags
 BIC     R14, R14, #&FC000003		;jump back to user code
ADD     PC, R14, #jit_code_start	;correct return address


 ;Entry:
 ;R0 - operation
 ;R0, R12, R14 stacked

.CLib_kernel_osfile			;entry 18 in chunk 1 PRM4-285
					;used in Empire Soccer 94 @ 9A54

; ADD     R0, PC, #0
; B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
; DCD     0
; DCB     "ADFF5996 _kernel_osfile called", 0
; ALIGN

 TEQ     R0, #12
 TEQNE   R0, #14
 TEQNE   R0, #16
 TEQNE   R0, #255			;is it a load operation?
 MOVNE   R14, #18			;NO,
 BNE     C_entry_chunk1			;|+  pass call on


 LDR     R14, [a3, #0 * 4]		;get R2
 TST     R14, #%11111111		;is there an address in R2?
 MOVNE   R14, #0			;NO
 LDREQ   R14, [a3, #1 * 4]		;YES, load address in R3
 TEMP    R0
 LDR     R12, C_stack_ptr
 STR     R14, [R12, #-4]!		;stack the load address
 LDR     R14, [R13, #2 * 4]		;get R14 from stack: {R0,R12,R14}
 STR     R14, [R12, #-4]!		;stack on C stack: {R14, loadaddr}
 STR     R12, C_stack_ptr
 LOCK    R0
 LDMFD   R13!, {R0, R12, R14}		;clear down stack
 BL      C_vector_chunk_1 + (18 << 2)
 STMFD   R13!, {R2, R4, R12, R14}
 TEMP    R2
 LDR     R12, C_stack_ptr
 LDR     R14, [R12], #4			;get original R14 from stack
 ADDVS   R12, R12, #4			;drop load address from stack
 STRVS   R12, C_stack_ptr
 ORRVS   R14, R14, #1 << 28		;set V
 STR     R14, [R13, #3 * 4]		;put R14 on return stack: {R2, R4, R12, R14}
 BVS     _return2

 LDR     R4, [R12], #4			;pull the stacked load address
 STR     R12, C_stack_ptr
 LOCK    R2
 TEQ     R4, #0				;did we specify the load address?
 MOVNE   R2, R4				;YES
 LDREQ   R2, [a3, #0 * 4]		;NO, get updated R2
 CMP     R2, #jit_appspace_end		;is it in application space?
 LDRLO   R4, [a3, #2 * 4]		;YES, get R4 from return vars (size)
 SWILO   XADFFS_ResetMemoryBlock	; |+  call hv_reset_memory_block
 ._return2
 LDMFD   R13!, {R2, R4, R12, R14}	;return to user code
 MSR     CPSR_f, R14			;restore PSR flags
 BIC     R14, R14, #&FC000003		;jump back to user code

ADD     PC, R14, #jit_code_start	;correct return address



.CLib_kernel_register_allocs		;entry 25 in chunk 1
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_register_allocs not supported", 0
 ALIGN


.CLib_kernel_moduleinit			;entry 38 in chunk 1
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_moduleinit not supported", 0
 ALIGN


.CLib_kernel_entermodule		;entry 42 in chunk 1
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_entermodule not supported", 0
 ALIGN


.CLib_kernel_register_slotextend	;entry 46 in chunk 1
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_register_slotextend not supported", 0
 ALIGN


.CLib_atexit				;entry 71 in chunk 2
 STMFD   R13!, {R0-R1}
 LDR     R1, _atexit_count
 CMP     R1, #32			;have we hit the limit?
 BEQ     _error				;YES
 ADR     R0, _entry
 ADD     R0, R0, R1, LSL #4		;R1 * 16
 ADD     R1, R1, #1
 STR     R1, _atexit_count

 ADD     v4, v4, #jit_code_start	;correct entry address
 STR     v4, [R0, #0]
 ADD     v4, R0, #4			;new function entry
 LDMFD   R13!, {R0-R1}
 BIC     R14, R14, #&FC000003
 ADD     R14, R14, #jit_code_start	;correct return address
 B       C_vector_chunk_2 + (71 << 2)

 ._error
 LDMFD   R13!, {R0-R1}			;clear stack
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib atexit limit reached", 0
 ALIGN

 ._atexit_count DCD 0

 ._return
 LDR     PC, [R13], #4
 ._entry
 #rept 32
   DCD 0
   STR     R14, [R13, #-4]!
   ADR     R14, _return
   LDR     PC, [PC, #-20]
 #endr


 ;Entry:
 ;R4 - address of compare function

.CLib_bsearch				;entry 75 in chunk 2
 ADD     R4, R4, #jit_code_start	;correct entry address
 BIC     R14, R14, #&FC000003
 ADD     R14, R14, #jit_code_start	;correct return address
 STR     R4, _entry
 ADR     R4, _call_code
 B       C_vector_chunk_2 + (75 << 2)

 ._entry	DCD 0
 ._call_code
 STR     R14, [R13, #-4]!
 ADR     R14, _return
 LDR     PC, _entry
 ._return
 LDR     PC, [R13], #4


 ;Entry:
 ;R3 - address of compare function

.CLib_qsort				;entry 76 in chunk 2
 ADD     R3, R3, #jit_code_start	;correct entry address
 BIC     R14, R14, #&FC000003
 ADD     R14, R14, #jit_code_start	;correct return address
 STR     R3, _entry
 ADR     R3, _call_code
 B       C_vector_chunk_2 + (76 << 2)
 ._entry	DCD 0
 ._call_code
 STR     R14, [R13, #-4]!
 ADR     R14, _return
 LDR     PC, _entry
 ._return
 LDR     PC, [R13], #4




 ;Entry:
 ;R1 - address of routine to continue execution

.CLib_main
 ADD     R1, R1, #jit_code_start	;correct entry address
 STR     R1, _c_main_entry
 ADR     R1, _c_main
 B       C_vector_chunk_2 + (18 << 2)	;_main
 ._c_main_entry DCD 0
 ._c_main
 STMFD   R13!, {R14}			;store CLib's return address
 ADD     R14, PC, #0			;get it to return to us
 LDR     PC, _c_main_entry		;call c function
 LDMFD   R13!, {PC}			;return to CLib


;Entry:
; R0 - signal number
; R1 - address of signal handler

.CLib_signal				;entry 128 in chunk 2 PRM4-311
 CMP     R0, #10			;is it valid?
 BHI     _error				;NO

 STR     R5, [R13, #-4]!
 SUB     R5, R1, #&8000
 CMP     R1, #jit_code_start
 ADRLO   R5, _entry - 16
 ADDLO   R1, R1, #jit_code_start	;correct entry address
 STRLO   R1, [R5, R0, LSL #4]!		;update the correct signal handler
 ADDLO   R1, R5, #4			;our entry point
 LDR     R5, [R13], #4
 BIC     R14, R14, #&FC000003
 ADD     R14, R14, #jit_code_start	;correct return address
 B       C_vector_chunk_2 + (128 << 2)


 ._error
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib signal invalid", 0
 ALIGN


 ._return
 LDR     PC, [R13], #4
 ._entry
 #rept 10				;10 defined signal handlers
   DCD 0
   STR     R14, [R13, #-4]!
   ADR     R14, _return
   LDR     PC, [PC, #-20]
 #endr


 ;Entry:
 ;R0 - SWI to call (without X bit set)

.CLib_swi				;entry 183 in chunk 2
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _swi not supported", 0
 ALIGN


.CLib_swix				;entry 184 in chunk 2
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _swix not supported", 0
 ALIGN


.CLib_kernel_unwind			;entry 4 in chunk 1 PRM4-281
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_unwind not supported", 0
 ALIGN
; STMFD   R13!, {a1, a2}
; LDR     a1, [a1, #24]			;get PC from stackframe
; LDR     a2, [a1, #0]
; BIC     a2, a2, #&FC000003		;clear flags
; STR     a2, [a1, #0]			;put back
; LDMFD   R13!, {a1, a2}
; B       C_vector_chunk_1 + (4 << 2)	;_kernel_unwind


.CLib_kernel_swi			;entry 9 in chunk 1 PRM4-283
 CMP     a2, #&8000			;is *in a valid address?
 BLO     _Clib_in_nullref		;NO

 STMFD   R13!, {a3, v1-v6, R12, lr}
 BIC     R12, a1, #1 << 31
 TST     a1, #1 << 31			;do we need to set X bit?
 ORREQ   R12, R12, #1 << 17		;YES, set X bit
 LDMIA   a2, {R0-R9}
 SWI     XOS_CallASWIR12 + (JIT_SWI_OS_Flag << 20)
 LDR     ip, [R13, #0]			;get a3 from stack
 STMIA   ip, {R0-R9}
 MOVVC   a1, #0
 BLVS    CLib_CopyError
 LDMFD   R13!, {a3, v1-v6, R12, lr}
 MSR     CPSR_f, lr			;restore PSR flags
 BIC     lr, lr, #&FC000003		;jump back to user code
 ADD     PC, lr, #jit_code_start	;correct return address

 ._Clib_in_nullref
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_swi *in NULL reference", 0
 ALIGN


.CLib_kernel_swi_c			;entry 45 in chunk 1 PRM4-283
 CMP     a2, #&8000			;is *in a valid address?
 BLO     _Clib_in_nullref		;NO

 STMFD   R13!, {a3, a4, v1-v6, R12, lr}
 BIC     R12, a1, #1 << 31
 TST     a1, #1 << 31			;do we need to set X bit?
 ORREQ   R12, R12, #1 << 17		;YES, set X bit
 LDMIA   a2, {R0-R9}
 SWI     XOS_CallASWIR12 + (JIT_SWI_OS_Flag << 20)
 LDMFD   R13, {ip, lr}			;get a3, a4 from stack
 STMIA   ip, {R0-R9}
 BVS     _error
 MOV     a1, #0
 MOVCC   ip, #0
 MOVCS   ip, #1
 ._error_return
 STR     ip, [lr]			;store C at [a4]
 LDMFD   R13!, {a3, a4, v1-v6, R12, lr}
 MSR     CPSR_f, lr			;restore PSR flags
 BIC     lr, lr, #&FC000003		;jump back to user code
 ADD     PC, lr, #jit_code_start	;correct return address

 ._Clib_in_nullref
 ADD     R0, PC, #0
 B       C_vector_chunk_1 + (47 << 2)	;_kernel_raise_error
 DCD     0
 DCB     "ADFF5999 CLib _kernel_swi_c *in NULL reference", 0
 ALIGN

 ._error
 BL      CLib_CopyError
 LDR     lr, [R13, #4]
 MOV     ip, #0
 B       _error_return

 .CLib_CopyError
 STMFD   R13!, {a2, ip, R14}
 MOV     a2, ip
 MOV     a3, ip
 MOV     a1, #&2B			;XOS_GenerateError
 BL      C_vector_chunk_1 + (9 << 2)	;_kernel_swi
 LDMFD   R13!, {a2, ip, PC}

 .CLib_end

#set CLib_chunk_1_vectors = C_inbound_table_1 - CLib_chunk_id + 4 + (16*4)
#set CLib_chunk_2_vectors = C_inbound_table_2 - CLib_chunk_id + 4 + (16*4)
