📄 shexcept.src
字号:
; (r3) = function address
; (r4) = 1st function argument
; (r5) = 2nd function argument
; (r6) = 3rd function argument
kc50: jmp @r3
nop
.endf
.aif SH_CPU eq h'40
LEAF_ENTRY _GetAndClearFloatCode
sts.l fpscr, r1
mov r1, r0
mov #h'3f000, r2
and r2, r0
not r2, r2
and r2, r1
lds r1, fpscr
shlr8 r0
shlr2 r0
shlr2 r0
rts
nop
.endf
LEAF_ENTRY _GetCauseFloatCode
sts.l fpscr, r0
mov #h'3f000, r2
and r2, r0
shlr8 r0
shlr2 r0
rts
shlr2 r0
.endf
LEAF_ENTRY _DisableFPU
stc SR, r0
mov #h'00008000, r1
or r0, r1
ldc r1, SR
rts
nop
.endf
LEAF_ENTRY _SaveFloatContext
stc SR, r0
mov #h'ffff7fff, r1
and r0, r1
ldc r1, SR
add #THREAD_CONTEXT_OFFSET, r4
add #CtxFpul+4, r4
sts.l fpul, @-r4
sts.l fpscr, @-r4
add #(4*16)+8, r4 ; (r4) = ptr to end of CtxFRegs
add #(4*16), r4 ; (r4) = ptr to end of CtxXFregs
mov #0, r1
lds r1, fpscr
.data.w h'FBFD ; frchg instr.
fmov.s fr15, @-r4
fmov.s fr14, @-r4
fmov.s fr13, @-r4
fmov.s fr12, @-r4
fmov.s fr11, @-r4
fmov.s fr10, @-r4
fmov.s fr9, @-r4
fmov.s fr8, @-r4
fmov.s fr7, @-r4
fmov.s fr6, @-r4
fmov.s fr5, @-r4
fmov.s fr4, @-r4
fmov.s fr3, @-r4
fmov.s fr2, @-r4
fmov.s fr1, @-r4
fmov.s fr0, @-r4
.data.w h'FBFD ; frchg instr.
fmov.s fr15, @-r4
fmov.s fr14, @-r4
fmov.s fr13, @-r4
fmov.s fr12, @-r4
fmov.s fr11, @-r4
fmov.s fr10, @-r4
fmov.s fr9, @-r4
fmov.s fr8, @-r4
fmov.s fr7, @-r4
fmov.s fr6, @-r4
fmov.s fr5, @-r4
fmov.s fr4, @-r4
fmov.s fr3, @-r4
fmov.s fr2, @-r4
fmov.s fr1, @-r4
fmov.s fr0, @-r4
ldc r0, SR
rts
nop
.endf
LEAF_ENTRY _RestoreFloatContext
stc SR, r0
mov #h'ffff7fff, r1
and r0, r1
ldc r1, SR
add #THREAD_CONTEXT_OFFSET, r4
add #CtxFpscr, r4
mov.l @r4+, r2 ; (r2) = new value for FPSCR
mov.l @r4+, r3 ; (r3) = new value for FPUL
mov #0, r1
lds r1, fpscr
fmov.s @r4+, fr0
fmov.s @r4+, fr1
fmov.s @r4+, fr2
fmov.s @r4+, fr3
fmov.s @r4+, fr4
fmov.s @r4+, fr5
fmov.s @r4+, fr6
fmov.s @r4+, fr7
fmov.s @r4+, fr8
fmov.s @r4+, fr9
fmov.s @r4+, fr10
fmov.s @r4+, fr11
fmov.s @r4+, fr12
fmov.s @r4+, fr13
fmov.s @r4+, fr14
fmov.s @r4+, fr15
.data.w h'FBFD ; frchg instr.
fmov.s @r4+, fr0
fmov.s @r4+, fr1
fmov.s @r4+, fr2
fmov.s @r4+, fr3
fmov.s @r4+, fr4
fmov.s @r4+, fr5
fmov.s @r4+, fr6
fmov.s @r4+, fr7
fmov.s @r4+, fr8
fmov.s @r4+, fr9
fmov.s @r4+, fr10
fmov.s @r4+, fr11
fmov.s @r4+, fr12
fmov.s @r4+, fr13
fmov.s @r4+, fr14
fmov.s @r4+, fr15
lds r2, fpscr
lds r3, fpul
ldc r0, SR
rts
nop
.endf
.aelse
;
; SH3DSP DSP Context Save and restore
;
LEAF_ENTRY _SaveSH3DSPContext
stc SR, r0
mov #h'1000, r1
or r0, r1
ldc r1, SR
mov #(THREAD_CONTEXT_OFFSET+CtxDSPRegs), r5
add r5, r4
mov r4, r5
stc.l RE, @-r5 ; Repeat End register
stc.l RS, @-r5 ; Repeat Start
stc.l MOD, @-r5 ; Modulo addressing register
sts.l DSR, @-r5 ; DSP Status register
movs.l A0, @r4+ ; Save DSP Regs A0,A1
movs.l A1, @r4+
movs.l M0, @r4+ ; M0, M1
movs.l M1, @r4+
movs.l X0, @r4+ ; X0, X1
movs.l X1, @r4+
movs.l Y0, @r4+ ; Y0, Y1
movs.l Y1, @r4+
movs.w A0G, @r4+ ; Save the guard bits.
movs.w A1G, @r4+
ldc r0, SR
rts
nop
.endf
LEAF_ENTRY _RestoreSH3DSPContext
stc SR, r0
mov #h'1000, r1
or r0, r1
ldc r1, SR
mov #(THREAD_CONTEXT_OFFSET+CtxDsr), r5
add r5, r4
lds.l @r4+, DSR ; DSP Status Register
ldc.l @r4+, MOD ; Modulo addressing register
ldc.l @r4+, RS ; Repeat Start
ldc.l @r4+, RE ; Repeat End
movs.l @r4+, A0 ; Restore DSP registers A0, A1
movs.l @r4+, A1
movs.l @r4+, M0 ; M0, M1
movs.l @r4+, M1
movs.l @r4+, X0 ; X0, X1
movs.l @r4+, X1
movs.l @r4+, Y0 ; Y0, Y1
movs.l @r4+, Y1
movs.w @r4+, A0G ; Restore the guard bits.
movs.w @r4+, A1G
ldc r0, SR
rts
nop
.endf
.aendi
.PAGE
; This code is copied to the kernel's data page so that it is accessible from
; the kernel & user code. The kernel checks if it is interrupting an interlocked
; api by range checking the PC to be between UserKPage+0x380 & UserKPage+0x400.
; The routines are organized such that they can be restarted by masking off the
; lower 3 bits of the PC. Each routine is at most 4 instructions with the store
; instruction as the last instruction in the 4 inst. block.
.align 8
LEAF_ENTRY _InterlockedAPIs
ILMaskByte:
mov.b @r4, r0 ; (r0) = original byte value
and r5, r0 ; clear some bits
or r6, r0 ; set some bits
mov.b r0, @r4 ; update byte value
rts
nop
.align 8
ILPopList:
mov.l @r4, r0 ; (r0) = ptr to item at head
nop
tst r0, r0
bf popx ; list is not empty
rts
nop
.align 8
bra ILPopList ; restart from popx: due to interrupt comes here
nop
popx: mov.l @r0, r1
mov.l r1, @r4
rts
nop
.align 8
ILPushList:
mov.l @r4, r0 ; (r0) = old head of list
nop
mov.l r0, @r5 ; store linkage
mov.l r5, @r4 ; store new list head
rts
nop
.align 8
ILExchange:
mov.l @r4, r0 ; (r0) = original contents
nop
nop
mov.l r5, @r4 ; store new contents
rts
nop
.align 8
ILCmpExchange:
mov.l @r4, r0 ; (r0) = original contents
cmp/eq r0, r6
bf ICExEnd ; no match, skip store
mov.l r5, @r4 ; store new contents
ICExEnd: rts
nop
.align 8
ILIncrement:
mov.l @r4, r0 ; (r0) = original contents
nop ; load delay + align end label
add #1, r0
mov.l r0, @r4 ; store new contents
rts
nop
.align 8
; NOTE: Must not damage R3 which may contain the saved return address from
; an InterlockedDecrement call!
ILXAdd:
mov.l @r4, r0 ; (r0) = original contents
mov r5, r1 ; (r1) = increment value
add r0, r1
mov.l r1, @r4 ; store new contents
rts
nop
.align 8
.export _InterlockedEnd
_InterlockedEnd:
.endf
; CaptureContext is invoked in kernel context on the user thread's stack to
; build a context structure to be used for exception unwinding.
;
; (r15) = aligned stack pointer
; (r0-r14), etc. - CPU state at the time of exception
LEAF_ENTRY _CaptureContext
.aif SH_CPU eq h'40
add #h'80-CtxSizeof, r15 ; must happen BEFORE the prolog
add #CtxR15-h'80, r15
.aelse
add #CtxR15-CtxSizeof, r15 ; must happen BEFORE the prolog
nop
.aendi
.endf
NESTED_ENTRY xxCaptureContext
mov.l r15, @(0,r15) ; for the unwinder (updated by EXceptionDispatch)
mov.l r14, @-r15
stc SPC, r14
mov.l r14, @(CtxFir-CtxR14,r15) ; for unwinding (updated by ExceptionDispatch)
stc SSR, r14
mov.l r14, @(CtxPsr-CtxR14,r15)
mov.l r13, @-r15
mov.l r12, @-r15
mov.l r11, @-r15
mov.l r10, @-r15
mov.l r9, @-r15
mov.l r8, @-r15
mov.l r7, @-r15
mov.l r6, @-r15
mov.l r5, @-r15
mov.l r4, @-r15
mov.l r3, @-r15
mov.l r2, @-r15
mov.l r1, @-r15
mov.l r0, @-r15
stc GBR, r2
mov.l r2, @-r15
sts MACL, r2
mov.l r2, @-r15
mov #CONTEXT_FULL, r1
sts MACH, r2
mov.l r2, @-r15
sts PR, @-r15
mov r15, r14 ; (r14) = ptr to context.PR
PROLOG_END
mov.l r1, @-r15 ; set context flags
mov #_ExceptionDispatch, r0
mov r15, r4 ; (r4) = arg1 = ptr to context structure
jsr @r0
add #-16, r15 ; allocate arg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -