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

📄 vfpsubarch.s

📁 realview22.rar
💻 S
字号:
;;; vfpsubarch.s
;;; sub-architecture support for:
;;; the VFP9, VFP10, VFP11 family of co-processors
;;; the VFP10 rev0 co-processor
;;; Copyright (C) ARM Limited, 2002. All rights reserved.


        AREA |.text|, CODE, READONLY

        CODE32

;;; int _VFP_ExceptionState_Size(void)
;;; returns the size of the buffer used by
;;; _VFP_Save_ExceptionState and _VFP_Restore_ExceptionState

_VFP_ExceptionState_Size PROC

        MOV r0, #12
        BX lr

        ENDP

;;; void _VFP_Save_ExceptionState(void *)
;;; r0 points to a buffer reserved for the result

_VFP_Save_ExceptionState PROC

        FMRX r1, FPEXC
        FMRX r2, FPINST
;;; The FPINST2 register does not exist on VFP10rev0, so we test FP2V
        TST r1, #(1 << 28) ;; check FP2V: FPINST2 is valid
        FMRXNE r3, FPINST2
        STMIA r0, {r1, r2, r3}
        BX lr

        ENDP

;;; void _VFP_Restore_ExceptionState(void *)
;;; r0 points to a buffer initialized by _VFP_Save_ExceptionState

_VFP_Restore_ExceptionState PROC

        LDMIA r0, {r1, r2, r3}

;;; FPEXC must be restored first: This ensures the EX bit is set if
;;; this function is interrupted while there is state in the exception
;;; registers.

        FMXR FPEXC, r1
        FMXR FPINST, r2
;;; The FPINST2 register does not exist on VFP10rev0, so we test FP2V
        TST r1, #(1 << 28) ;; check FP2V: FPINST2 is valid
        FMXRNE FPINST2, r3
        BX lr

        ENDP

;;; bool _VFP_IsComputeException(unsigned int)
;;; r0 contains the bounced instruction, and is ignored.
;;; on return r0 is:
;;;   0 for a bounce caused by an illegal instruction
;;;   1 for any other bounce

_VFP_Is_Compute_Exception PROC

        FMRX r0, FPEXC
;;; return 1 for a pending computational bounce, EX bit set
;;; return 0 for an illegal instruction bounce, EX bit clear
        MOV r0, r0, LSR #31 ;; return EX, bit 31
        BX lr

        ENDP

;;; bool _VFP_Collect_Trap_Description(
;;;          _VFP_Computation_Description *desc, unsigned int instr)
;;; r0 points to some memory reserved for the result
;;; r1 contains the bounced instruction, and is ignored.
;;; on return r0 is:
;;;   0 for an imprecise bounce, return to bounced instruction
;;;   1 for a precise bounce, return to next instruction

_VFP_Collect_Trap_Description PROC

        FMRX r12, FPEXC

;;; collect faulting instruction description in r2
        FMRX r2, FPINST
        BIC r2, r2, #0x00000e00 ;; clear top cp_num bits [11..9]
        BIC r2, r2, #0xff000000 ;; clear cond & CDP bits [31..24]

;;; check for VFP10 rev0
;;; VFP10 rev0 FPSID value is 0x410000A0
;;; VFP10 rev1 FPSID value is 0x410101A0
;;; bits [23..16] give the architecture version
;;; bits [15..8] give the part number
        FMRX r1, FPSID
        LDR r3, =0x410000A0 ;; ID code for VFP10 rev0
        CMP r1, r3

;;; VFP10 rev0 vector length is out-by-one for some instructions
        BEQ fixup_vfp10r0_vlen

vfp10r0_vlen_standard

;;; get the remaining vector length from FPEXC VECITR bits [10..8]
;;; this is in ((vector length - 1) % 8) format, as in the FPSCR
        ADD r1, r12, #(1 << 8) ;; add one for the faulting iteration
        AND r1, r1, #(7 << 8) ;; mask out bits [10..8]

vfp10r0_vlen_fixed
;;; vlen in r1, starting at bit 8

        ORR r2, r2, r1, LSL #16 ;; move to bits [26..24], and add to op

        TST r12, #(1 << 28) ;; check FP2V: FPINST2 is valid
        BNE collect_op2

;;; write out computation description
;;; no second operation, so count is 1
        MOV r1, #1
        MOV r3, #0  ;; clear reserved words
        STMIA r0!, {r1, r3} ;; write count, flags
        STMIA r0!, {r2, r3} ;; write first entry

;;; clear exception flag
;;; EX must be clear before attempting to read the FPSCR
        BIC r12, r12, #(1 << 31) ;; clear EX bit 31
        FMXR FPEXC, r12

;;; check inexact enable, IXE, bit 12 of FPSCR
        FMRX r0, FPSCR
        MOV r0, r0, LSR #12
        AND r0, r0, #1

;;; return 0 for imprecise bounce, IXE = 0,
;;;     re-execute bounced instruction
;;; return 1 for precise bounce, IXE = 1,
;;;     do not re-execute bounced instruction

        BX lr

collect_op2

;;; r0 points to the computation description
;;; r2 contains op[0]
;;; r12 is a copy of FPEXC
;;; FP2V is set

;;; collect pending instruction in FPINST2
        FMRX r3, FPINST2
        BIC r3, r3, #0x00000e00 ;; clear top cp_num bits [11..9]
        ;; bits [31..28] contain the cond field
        ;; bits [27..24] are always 0b1110
        ;; bit 4 is always zero
        BIC r3, r3, #0xff000000 ;; clear bits [31..24]

;;; clear exception flag
;;; EX must be clear before attempting to read the FPSCR
;;; also the FP2V bit is sticky and must be cleared on bounce
        BIC r12, r12, #((1 << 31)|(1 << 28)) ;; clear EX and FP2V
        FMXR FPEXC, r12

;;; use vector length in FPSCR LEN field bits [18..16]
;;; this is in ((vector length - 1) % 8) format, as required for op
        FMRX r1, FPSCR
        AND r1, r1, #(7 << 16) ;; mask out bits [18..16]
        ORR r3, r3, r1, LSL #8 ;; move to bits [26..24], and add to op

;;; write out computation description
;;; op count is 2
        MOV r1, #2
        MOV r12, #0  ;; clear reserved words
        STMIA r0!, {r1, r12} ;; count, flags
        STMIA r0!, {r2, r12} ;; 1st entry
        STMIA r0!, {r3, r12} ;; 2nd entry

;;; return 0 for imprecise bounce
        MOV r0, #0
        BX lr

fixup_vfp10r0_vlen

;;; r0 points to the computation description
;;; r2 contains the instruction bits of op[0]
;;; r12 is a copy of FPEXC

;;; The VFP10rev0 returns the pre-incremented vector-length for
;;; FMULD, FSQRT and FDIV instructions.

;;; The op decode bits are:
;;;   31        23        15         7       0
;;; 0b 0000 0000 pXqr ---- XXXX XXX- NsX0 XXXX
;;; with Fn in bits [19..16] and
;;; the precision (0 is single, 1 is double) in bit 8

P_BIT   EQU  (1 << 23)
Q_BIT   EQU  (1 << 21)
R_BIT   EQU  (1 << 20)
FN_BIT3 EQU  (1 << 19)
FN_BIT2 EQU  (1 << 18)
FN_BIT1 EQU  (1 << 17)
FN_BIT0 EQU  (1 << 16)
PRECISION_BIT EQU (1 << 8)
N_BIT   EQU  (1 << 7)
S_BIT   EQU  (1 << 6)

;;; Attempt to match op to one of these instructions:
;;; FDIV has pqrs == 1000
;;; FMULD has pqrs == 0100, and bit 8 is set
;;; FSQRT has pqrs == 1111, Fn == 0001 and N is set
;;; Vector length is ignored for all the extended instructions
;;; with Fn >= 2, (compares and conversions)

        MVN r1, r2
        TST r2, #P_BIT
        BNE p_set
        ;; pqrs == 0xxx
        TST r1, #Q_BIT    ;; no match if NE
        ;; if EQ, then pqrs == 01xx
        TSTEQ r2, #R_BIT  ;; no match if NE
        ;; if EQ, then pqrs == 010x
        TSTEQ r2, #S_BIT  ;; no match if NE
        ;; if EQ, then pqrs == 0100, we have an FMUL
        TSTEQ r1, #PRECISION_BIT ;; no match if NE
        ;; if EQ, then we have an FMULD
        BNE vfp10r0_vlen_standard
        B vlen_needs_fix

p_set
        ;; pqrs == 1xxx
        TST r2, #S_BIT
        BNE s_set
        ;; pqrs == 1xx0
        TST r2, #(Q_BIT | R_BIT)  ;; no match if NE
        ;; if EQ, then pqrs == 1000, we have an FDIV
        BNE vfp10r0_vlen_standard
        B vlen_needs_fix
s_set
        ;; pqrs == 1xx1
        TST r1, #(Q_BIT | R_BIT | FN_BIT0) ;; no match if NE
        ;; if EQ, then pqrs == 1111, Fn == xxx1
        TSTEQ r2, #(FN_BIT3 | FN_BIT2 | FN_BIT1) ;; no match if NE
        ;; if EQ, then pqrs == 1111, Fn == 0001
        TSTEQ r1, #N_BIT
        ;; if EQ, then we have an FSQRT

        BNE vfp10r0_vlen_standard
;;; fall-through

vlen_needs_fix

;;; Get the remaining vector length from FPEXC VECITR bits [10..8]
;;; Do NOT add one for the faulting iteration
        AND r1, r12, #(7 << 8) ;; mask out bits [10..8]

        B vfp10r0_vlen_fixed

        ENDP

        EXPORT _VFP_ExceptionState_Size
        EXPORT _VFP_Save_ExceptionState
        EXPORT _VFP_Restore_ExceptionState
        EXPORT _VFP_Is_Compute_Exception
        EXPORT _VFP_Collect_Trap_Description

        END
;;; end of file vfpsubarch.s

⌨️ 快捷键说明

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