Commit fe209e10 authored by Kevin Bracey's avatar Kevin Bracey
Browse files

Had one of those weekend brainstorms - managed to speed up SWI despatcher...

Had one of those weekend brainstorms - managed to speed up SWI despatcher _and_ add Thumb support to it.

Fixed OS_BreakPt - was confused by PC/PSR split.

Version 5.24. Not tagged
parent d58cdce2
No related merge requests found
......@@ -9,6 +9,6 @@
Module_MajorVersion SETS "5.24"
Module_Version SETA 524
Module_MinorVersion SETS ""
Module_Date SETS "13 Apr 2000"
Module_Date SETS "17 Apr 2000"
Module_FullVersion SETS "5.24"
END
......@@ -5,11 +5,11 @@
*/
#define Module_MajorVersion_CMHG 5.24
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 13 Apr 2000
#define Module_Date_CMHG 17 Apr 2000
#define Module_MajorVersion "5.24"
#define Module_Version 524
#define Module_MinorVersion ""
#define Module_Date "13 Apr 2000"
#define Module_Date "17 Apr 2000"
#define Module_FullVersion "5.24"
......@@ -1505,7 +1505,11 @@ Export_SvcTable |#| &400
ASSERT ?Export_SvcTable = ?SvcTable
ASSERT SvcTable = &01F033FC ; Required for SVC table pokers, 1.20 compatible
[ No26bitCode
SWIDespatch_Size * 33*4
|
SWIDespatch_Size * 31*4 ; can save 2 instructions if 26-bit (no Thumb)
]
SWIDespatch |#| SWIDespatch_Size
......
......@@ -988,9 +988,9 @@ checkmoshandlers
CallAVector_SWI ; R9 is the vector number (!!)
STR lr, [sp, #-4]! ; save caller PSR on stack
MOV R10, R9
msr AL, CPSR_f, R14 ; restore caller CCs
msr ,CPSR_f, R12 ; restore caller CCs (including V)
BL CallVector
mrs AL, r10, CPSR ; restore CCs
mrs ,r10, CPSR ; restore CCs
LDR lr, [sp], #4
AND r10, r10, #&F0000000
BIC lr, lr, #&F0000000
......
......@@ -72,12 +72,16 @@ $l LDR $reg1, =VIDC
]
MEND
; Fake a 26-bit pc, given a PSR currently in lr, and the 32-bit address on
; Fake a 26-bit pc, given a PSR currently in lr (or reg), and the 32-bit address on
; the stack. The stacked address is pulled, and the result is left in lr.
MACRO
FakeLR $temp, $dontpull
FakeLR $temp, $dontpull, $reg
[ "$reg" = ""
AND $temp,lr,#&F0000003
|
AND $temp,$reg,#&F0000003
]
AND lr,lr,#I32_bit+F32_bit
ORR $temp,$temp,lr,LSL #IF32_26Shift
[ "$dontpull" = "dontpull"
......@@ -394,6 +398,7 @@ EndData
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI return handler: checks callback
; no branches or interlocks in the common case: V clear, no callback
SVCDespatcher ROUT
......@@ -411,31 +416,32 @@ SLVK_TestV * {PC}-SWIRelocation
SLVK * {PC}-SWIRelocation
! 0,"SLVK at ":CC:(:STR:SLVK)
LDR r11, [sp], #4
LDR r12, [sp], #4
MOV r10, #0
LDRB r11, [r10, #CallBack_Flag]
TST lr, #V_bit
BEQ %FT40
BNE %FT50
SWIReturnWithCallBackFlag * {PC}-SWIRelocation
! 0,"SWIReturnWithCallBackFlag at ":CC:(:STR:SWIReturnWithCallBackFlag)
40 TEQ r11, #0
msr EQ ,CPSR_c, #I32_bit + SVC32_mode ; IRQs off for SPSR use
msr EQ ,SPSR_cxsf, lr
LDREQ lr, [sp], #4
Pull "r10-r12", EQ
MOVEQS pc, lr
B callback_checking + SWIRelocation
! 0,"VSetReturn at ":CC:(:STR:({PC}-SWIRelocation))
TST r11, #Auto_Error_SWI_bit
BEQ VSet_GenerateError + SWIRelocation
50 TST r12, #Auto_Error_SWI_bit
BNE %BT40
SWIReturn * {PC}-SWIRelocation
! 0,"SWIReturn at ":CC:(:STR:SWIReturn)
B VSet_GenerateError + SWIRelocation
40 MOV r10, #0
LDRB r11, [r10, #CallBack_Flag]
CMP r11, #0
BNE callback_checking + SWIRelocation
SWIReturnNoCallback * {PC}-SWIRelocation
! 0,"SWIReturnNoCallback at ":CC:(:STR:SWIReturnNoCallback)
back_to_user * SWIReturnNoCallback
msr AL, CPSR_c, #I32_bit + SVC32_mode ; IRQs off for SPSR use
back_to_user_irqs_already_off * {PC}-SWIRelocation
msr AL, SPSR_cxsf, lr
LDR lr, [sp], #4
Pull "r10-r12"
MOVS pc, lr
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; The SWI Despatch routine
......@@ -443,28 +449,30 @@ back_to_user_irqs_already_off * {PC}-SWIRelocation
SVC * {PC}-SWIRelocation
Push "r10-r12"
LDR r11, [r14, #-4] ; r11 = calling instruction
STR r14, [r13, #-4]! ; push return address
mrs AL, r14, SPSR ; r14 = saved PSR
[ No26bitCode
mrs ,r12, SPSR ; r12 = saved PSR
TST r12, #T32_bit ; depending on processor state (ARM/Thumb)
LDREQ r11, [r14, #-4] ; extract SWI number to r11
LDRNEB r11, [r14, #-2] ; (ordering to prevent interlocks)
BICEQ r11, r11, #&FF000000
|
LDR r11, [r14, #-4] ; extract SWI number to r11
mrs ,r12, SPSR ; r12 = saved PSR
BIC r11, r11, #&FF000000 ; (ordering to prevent interlocks)
]
SVCContinue * {PC}-SWIRelocation
Push "r11,r14" ; push SWI number and return address
BIC r11, r11, #&FF000000
STR r11, [r13, #-4]! ; push SWI number
[ StrongARM
SVC_CallASWI * {PC}-SWIRelocation ; CallASWI,CallASWIR12 re-entry point
]
BICS r11, r11, #Auto_Error_SWI_bit
BEQ SWIWriteC + SWIRelocation
AND r10, r14, #I32_bit+F32_bit
AND r10, r12, #I32_bit+F32_bit
ORR r10, r10, #SVC2632 ; set IFTMMMMM = IF0x0011
msr AL, CPSR_c, r10 ; restore caller's IRQ state
msr ,CPSR_c, r10 ; restore caller's IRQ state
CMP r11, #OS_BreakPt
CMPNE r11, #OS_CallAVector
BICNE r14, r14, #V_bit ; clear V unless BreakPoint/CallVector
BIC r14, r12, #V_bit ; clear V (some SWIs need original PSR in r12)
CMP r11, #OS_WriteI
LDRLO pc, [pc, r11, LSL #2]
......@@ -681,7 +689,10 @@ VSet_GenerateError ROUT
Pull lr ; which raises error; otherwise just
BIC lr, lr, #V_bit ; return with V clear: error claimed!
B SWIReturn
MOV r10, #0 ; set up r10 and r11 as required
LDRB r11, [r10, #CallBack_Flag]
B SWIReturnWithCallBackFlag
LTORG
......@@ -755,12 +766,11 @@ ErrHandler ROUT
callback_checking
TST lr, #I32_bit+&0F ; user 26/32 mode, ints enabled?
[ {FALSE} ; original code
msr NE ,CPSR_c, #I32_bit + SVC32_mode
msr NE ,SPSR_cxsf, lr
LDRNE lr, [sp], #4
Pull "r10-r12", NE
MOVNES pc, lr ; Skip the branch for SVC code speed
|
BNE SWIReturnNoCallback ; hey, it'll be in the cache (probably)
]
; Further checks: postpone callback if returning V set and R0->RAM
......@@ -775,7 +785,13 @@ callback_checking
LDRB r11, [r10, #CallBack_Flag]
ORR r11, r11, #CBack_Postpone ; signal to IRQs
STRB r11, [r10, #CallBack_Flag]
B back_to_user_irqs_already_off
back_to_user
msr ,CPSR_c, #I32_bit + SVC32_mode
back_to_user_irqs_already_off
msr ,SPSR_cxsf, lr
LDR lr, [sp], #4
Pull "r10-r12"
MOVS pc, lr
Do_CallBack ; CallBack allowed:
TST r11, #CBack_VectorReq ; now process any vector entries
......@@ -879,13 +895,14 @@ process_callback_chain ROUT
; SWI OS_WriteC
; In r11 = 0 (look, up there ^) !
; r12 = SPSR
SWIWriteC ROUT
msr ,CPSR_c, #SVC2632 ; enable interrupts
BIC lr, lr, #V_bit ; clear caller's V cos we didn't before
Push lr
BIC lr, r12, #V_bit ; clear caller's V cos we didn't before
STR lr, [sp, #-4]!
LDR r11, [r11, #VecPtrTab+WrchV*4] ; load top node pointer
CMP r11, #ROM
......
......@@ -244,22 +244,25 @@ SENTERSWI
SBRKPT ROUT
ADD sp, sp, #4 ; discard stacked R11
MOV r12, #0
LDR r12, [r12, #BrkBf]
ADD sp, sp, #4 ; discard stacked SWI number
MOV r10, #0
LDR r10, [r10, #BrkBf]
[ No26bitCode
STR r14, [r12, #16*4] ; PSR
TST r14, #&0F
Pull R14
STR r12, [r10, #16*4] ; original PSR (with V)
Pull r14
TST r12, #T32_bit
SUBEQ r14, r14, #4
SUBNE r14, r14, #2 ; r14 = PC of the SWI
TST r12, #2_01111
|
FakeLR r11
FakeLR r11,,r12 ; r12+[sp] -> lr (r11 temp reg)
SUB r14, r14, #4 ; r14 = PC of the SWI
TST r14, #SVC_mode
]
SUB r14, R14, #4
STR r14, [r12, #15*4] ; PC of the SWI put in.
STR r14, [r10, #15*4] ; PC of the SWI put in.
BNE %FT01 ; NE if not in user mode
STMIA r12!, {r0}
MOV r0, r12
STMIA r10!, {r0}
MOV r0, r10
LDMFD sp, {r10-r12}
[ SASTMhatbroken
......@@ -275,23 +278,27 @@ SBRKPT ROUT
MOV r12, #BrkAd_ws
LDMIA r12, {r12, pc} ; call breakpoint handler
01 AND r11, r14, #&0F ; SWI mode?
; Non-user mode case
01 AND r11, r12, #2_01111 ; SVC26/SVC32 mode?
TEQ r11, #SVC_mode
BEQ %FT02 ; [yes]
STMIA r12!, {r0}
MOV r0, r12
LDMFD sp, {r10-r12} ; Not banked if IRQ mode
msr ,CPSR_c, R14 ; get at registers
; Non-user, non-supervisor - must be IRQ, ABT, UND or SYS (no SWIs from FIQ)
STMIA r10!, {r0}
MOV r0, r10
BIC r14, r12, #T32_bit ; don't go into Thumb mode
LDMFD sp, {r10-r12} ; Not banked
msr ,CPSR_c, R14 ; get at registers r13 and r14
STMIA r0, {r1-r14}
WritePSRc SVC_mode, r12
B %BT10
; Supervisor mode case
02 MOV r14, r12 ; supervisor mode. R14 in buffer dead
LDMFD sp!, {r10-r12}
STMIA r14, {r0-r14}
STMIA r14, {r0-r13}
LDR r12, =&DEADDEAD
STR r12, [r14, #14*4] ; mark R14 as dead
B %BT10
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......
......@@ -1303,8 +1303,16 @@ SWIWriteS ROUT
BVS %FT90
Pull "R0, R14"
85
[ No26bitCode
TST R14, #T32_bit
ADDNE R10, R10, #1 ; if Thumb
BICNE R10, R10, #1 ; round up to next halfword boundary
ADDEQ R10, R10, #3 ; else
BICEQ R10, R10, #3 ; round up to next word boundary
|
ADD R10, R10, #3
BIC R10, R10, #3 ; round up to next word boundary
]
STR R10, [R13, #4] ; Poke new address into stack
ExitSWIHandler
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment