⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vrtlib16.s

📁 VRTX操作系统
💻 S
📖 第 1 页 / 共 3 页
字号:
  IF EnsureNoFPSupport = {FALSE}
        LDR     a2, fp_finalise            ; finalise FP code if present
        CMP     a2, #0
        MOVNE   lr, pc
        MOVNE   pc, a2
  ENDIF
	LDR	r3, =_user_exit
	LDR	r3,[r3]
	CMP	r3, #0
	BLNE	__call_via_r3	;jump to user exit handler if present
	MOV	lr, pc		;else loop forever
	NOP			
	NOP
	MOV	pc, lr		;loop forever


		
;----------------------------------------------------------------------------;
        AREA    |C$$code$$__rt_fpavailable|, CODE, READONLY, INTERWORK				 ;
; The code area containing __rt_fpavailable                                  ;
;----------------------------------------------------------------------------;

|__rt_fpavailable|
;
; int __rt_fpavailable(); return non-0 if FP support code linked.

  IF EnsureNoFPSupport = {FALSE}
        LDR     a1, fp_initialise
  ELSE
        MOV     a1, #0
  ENDIF
        RET


;----------------------------------------------------------------------------;
       AREA    |C$$code$$__jmp|, CODE, READONLY, INTERWORK							 ;
; The code area containing setjmp, longjmp                                   ;
;----------------------------------------------------------------------------;
; Setjmp and longjmp support.                                                ;
;                                                                            ;
; NOTES                                                                      ;
;                                                                            ;
; 1/ Specific to C and not implementable in C.                               ;
;                                                                            ;
; 2/ Interacts with stack management and possibly with memory management.    ;
;    e.g. on a chunked stack, longjmp must de-allocate jumped-over chunks.   ;
;                                                                            ;
; 3/ Must know whether the floating-point instruction-set is supported!      ;
;    (DEPENDS ON __rt_fpavailable to discover this).                         ;
;                                                                            ;
;----------------------------------------------------------------------------;

        MAP 0                 ; This structure maps the jmp_buf
sj_v1   #       4             ; data type assumed by the C compiler.
sj_v2   #       4             ; First, space to save the v-registers...
sj_v3   #       4
sj_v4   #       4
sj_v5   #       4
sj_v6   #       4
sj_sl   #       4             ; then the frame registers sl, fp, sp (ap),
sj_fp   #       4             ; and pc/lr...
sj_ap   #       4
sj_pc   #       4
sj_f4   #       3*4           ; and finally the floating-point reisters,
sj_f5   #       3*4           ; used only if floating point support is
sj_f6   #       3*4           ; available.
sj_f7   #       3*4


|setjmp|                      ; setjmp
;
; int setjmp(jmp_buf env);
; Saves everything that might count as a register variable in 'env'.

        STMIA   a1!, {v1-v6, r10, fp, sp, lr}
        MOV     v6, a1                 ; v6 safe in env - use to point past
                                       ; saved lr (at 1st FP slot)
        BL      |__rt_fpavailable|
        CMP     a1, #0
        BEQ     setjmp_return          ; no fp
        STFE    f4, [v6, #sj_f4-sj_f4]
        STFE    f5, [v6, #sj_f5-sj_f4]
        STFE    f6, [v6, #sj_f6-sj_f4]
        STFE    f7, [v6, #sj_f7-sj_f4]
        MOV     a1, #0                 ; must return 0 from a direct call
setjmp_return
        LDMDB   v6, {v6, r10, fp, sp, lr}
        RET

|longjmp|                                                          ; longjmp ;
; int longjmp(jmp_buf env, int val);

        MOV     v1, a1                 ; save env ptr over call to fpavailable
        MOVS    v6, a2                 ; ensure non-0 return value...
        MOVEQ   v6, #1                 ; (must NOT return 0 on longjmp(env, 0))
        BL      |__rt_fpavailable|
        CMP     a1, #0
        BEQ     longjmp_return
        LDFE    f7, [v1, #sj_f7]
        LDFE    f6, [v1, #sj_f6]
        LDFE    f5, [v1, #sj_f5]
        LDFE    f4, [v1, #sj_f4]
longjmp_return
        MOV     a1, v6
        LDMIA   v1, {v1-v6, r10, fp, sp, lr}
        RET


	CODE16
;----------------------------------------------------------------------------;
      AREA    |C$$code$$__16__rt_stkovf|, CODE, READONLY, INTERWORK						 ;
; The code area containing __16__rt_stkovf_*                                 ;
;----------------------------------------------------------------------------;

|__16__rt_stkovf_split_small|
;
; Enter here when a C function with frame size <= 256 bytes underflows
; the stack low-water mark + StackSlop (sl).  Falls into the big-frame case.


|__16__rt_stkovf_split_big|
;
; Enter here when a C function with frame size > 256 bytes would underflow
; the stack low-water mark + StackSlop (sl). No stack space is been claimed

        PUSH    {r0,r1}
	MOV	r1,#DefaultStackIncrement	;0 default stack increment
        MOV     r0, r1                          ; the default increment
        MOV     r1, r10 	; r10 is sl
        SUB     r1, r0
        LDR     r0, =StackSlop
        SUB     r1, r0                          ; new stack low-water mark
        MOV     r10, r1    	;r10 is sl
        POP     {r0, r1}
        SUB     sp, sp, #8*4                    ; Room for R8..R15
        PUSH    {r0-r7}
        MOV     r7, lr
        ADR     r0, StackOverflowError16
	MOV	r1, #StackOverflowErrorLen
	MOV	r8, r1				;store message length in r8
        BL      save_regs_and_trap16

        ALIGN
StackOverflowError16
        DCD     3
        DCB     "stack overflow", 0
        ALIGN

;----------------------------------------------------------------------------;
        AREA    |C$$code$$__rt_trap16|, CODE, READONLY, INTERWORK
; The code area containing __rt_trap                                         ;
;----------------------------------------------------------------------------;
; Support for low-level failures - currently stack overflow and divide by 0. ;
; If there is a higher level handler, call it otherwise, print a message and ;
; exit gracefully.                                                           ;
;                                                                            ;
; NOTES                                                                      ;
;                                                                            ;
; typedef struct { unsigned code; char message[252];} __rt_error;            ;
; typedef struct { unsigned r[16];} __rt_registers;                          ;
;                                                                            ;
;----------------------------------------------------------------------------;

__rt_trap16
;
; void __rt_trap16(__rt_error *e, __rt_registers *r);
	PUSH    {r0}                  ; save e in case handler returns...
	LDR	r3, = cpu_interrupt_disable
	BL	call_via_r3
        LDR     r3, =__err_handler
        CMP     r3, #0
        BEQ     %F0

	BL      call_via_r3           ; Call the routine pointed to by R3
        		              ; Note: BL sets bit 0 of LR so return will
                                      ; be to Thumb state. This is why we use this
                                      ; rather than the sequence
                                      ;         MOV     lr, pc
                                      ;         BX      r3
                                      ; which may return to ARM state!

0
        ADR     r0, RTErrorHead16       ; No handler, or handler returned
	MOV	r1, #RTErrorHeadLen     ;length of run time error text
	LDR	r3,=vmc_write
	CMP	r3,#0			;check if vmc_write BSP present
	BEQ	%F1
	BL	call_via_r3		;call vmc_write could be arm or thumb
        POP     {r0}
        ADD     r0, #4
	MOV	r1, r8			;r8 contains length of error message
	LDR	r3,=vmc_write		;vmc_write may destroy r3 so reload
	BL	call_via_r3
        ADR     r0, RTErrorTail16
	MOV	r1,#RTErrorTailLen	;length of program terminated text   
	LDR	r3,=vmc_write        
	BL	call_via_r3

1       MOV     a1, #255
 	BL      __rt_exit16             ; and terminate with non-zero exit code
	
call_via_r3
        BX      r3

; SP has already been decremented by 16 * 4 and R0..R7 saved.
; IP points to the error description
; R7 contains the LR register which has been destroyed as a BL was required
; to get here.

save_regs_and_trap16
	PUSH	{r0,r1}		;save regs r0,r1 used by cpu_interrupt_disable
	LDR	r3, = cpu_interrupt_disable
	BL	call_via_r3
	POP	{r0,r1}
        MOV     ip, r0
        MOV     r0, r8
        MOV     r1, r9
        MOV     r2, r10
        MOV     r3, r11
        MOV     r4, r12
        ADD     r5, sp, #16*4         ; Take account of previous SP adjustment
        ADD     r6, sp, #8*4          ; Pointer to hi reg save area
        STMIA   r6!, {r0-r5, r7}
        STR     r7, [sp, #15*4]       ; Save my pc as callers lr
        MOV     a2, sp
        MOV     a1, ip
        B       __rt_trap16

        ALIGN
RTErrorHead16
        DCB     10, 13, "run time error: ", 0

        ALIGN
RTErrorTail16
        DCB     10, 13, "program terminated", 10, 13, 10, 13, 0

        ALIGN

	
_user_exit	DCD	|user_exit|
;----------------------------------------------------------------------------;
        AREA    |C$$code$$__exit16|, CODE, READONLY, INTERWORK
; The code area containing __main, __rt_exit                                 ;
;----------------------------------------------------------------------------;

__rt_exit16                                  ; exit
;
; void __rt_exit16(int code);
; Terminate execution, optionally setting return code (ignored here).
; MUST NOT RETURN.

	LDR	r3, =_user_exit
	LDR	r3,[r3]
	CMP	r3, #0
	BEQ	loop_forever
	BL	call_via_r3_exit	;jump to user exit handler if present
loop_forever
	MOV	lr, pc
	NOP
	NOP
	MOV	pc, lr		;loop forever

call_via_r3_exit
        BX      r3


  IF EnsureNoFPSupport = {FALSE}
fp_initialise
        DCD     |__fp_initialise|
fp_finalise
        DCD     |__fp_finalise|
  ENDIF

	ALIGN

	CODE32
;----------------------------------------------------------------------------;
       AREA    |C$$code$$__divide|, CODE, READONLY, INTERWORK							 ;
; The code area containing __rt_sdiv, __rt_udiv, __rt_sdiv_10, __rt_udiv10   ;
;----------------------------------------------------------------------------;
; GENERIC ARM FUNCTIONS - divide and remainder.                              ;
;                                                                            ;
; NOTES                                                                      ;
;                                                                            ;
; 1/ You may wish to make these functions part of your O/S kernel, replacing ;
;    the implementations here by branches to the relevant entry addresses.   ;
;                                                                            ;
; 2/ Each divide function is a div-rem function, returning the quotient in   ;
;    r0 and the remainder in r1. Thus (r0, r1) -> (r0/r1, r0%r1). This is    ;
;    understood by the C compiler.                                           ;
;                                                                            ;
; 3/ Because of its importance in many applications, divide by 10 is treated ;
;    as a special case. The C compiler recognises divide by 10 and generates ;
;    calls to __rt_{u,s}div10, as appropriate.                               ;
;                                                                            ;
; 4/ Each of the implementations below has been coded with smallness as a    ;
;    higher priority than speed.  Unrolling the loops will allow faster      ;
;    execution, but will produce much larger code.  If the speed of divides  ;
;    is critical then unrolled versions can be extracted from the ARM ANSI C ;
;    Library.                                                                ;
;                                                                            ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -