forked from Imagelibrary/rtems
SPARC: syscall optimizations and PSR-write fix
The last optimization missed was incorrect in regards to PSR write instruction delay must be 3 instructions. New optimizations: * align to 32-byte cache line. * rearrange code into three "blocks" of 4 instructions that is executed by syscall 2 and 3. This is to optimize for 16/32 byte cache lines. * use delay-slot instruction in trap table to reduce by one instruction. * use the fact that "wr %PSR" implements XOR to reduce by one instruction.
This commit is contained in:
@@ -32,6 +32,15 @@
|
|||||||
nop; \
|
nop; \
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System call optimized trap table entry
|
||||||
|
*/
|
||||||
|
#define SYSCALL_TRAP(_vector, _handler) \
|
||||||
|
mov %psr, %l0 ; \
|
||||||
|
sethi %hi(_handler), %l4 ; \
|
||||||
|
jmp %l4+%lo(_handler); \
|
||||||
|
subcc %g1, 3, %g0; ! prepare for syscall 3 check
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Software trap. Treat as BAD_TRAP for the time being...
|
* Software trap. Treat as BAD_TRAP for the time being...
|
||||||
*/
|
*/
|
||||||
@@ -156,7 +165,7 @@ SYM(CLOCK_SPEED):
|
|||||||
* installed before.
|
* installed before.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
|
SYSCALL_TRAP( 0x80, SYM(syscall) ); ! 80 syscall SW trap
|
||||||
SOFT_TRAP; SOFT_TRAP; ! 81 - 82
|
SOFT_TRAP; SOFT_TRAP; ! 81 - 82
|
||||||
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
|
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
|
||||||
|
|
||||||
|
|||||||
@@ -35,27 +35,27 @@
|
|||||||
* g3 = additional exit code 2
|
* g3 = additional exit code 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.align 32 ! Align to 32-byte cache-line
|
||||||
PUBLIC(syscall)
|
PUBLIC(syscall)
|
||||||
|
|
||||||
SYM(syscall):
|
SYM(syscall):
|
||||||
|
|
||||||
subcc %g1, 2, %g0 ! syscall 2, disable interrupts
|
! "subcc, %g1, 3, %g0" done in trap table
|
||||||
bne 3f
|
bne 2f ! syscall 3? enable interrupt
|
||||||
subcc %g1, 3, %g0 ! syscall 3, enable interrupts
|
|
||||||
or %l0, 0x0f00, %l4 ! set PIL=15
|
|
||||||
ba 9f
|
|
||||||
or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1
|
|
||||||
3:
|
|
||||||
bne 1f
|
|
||||||
and %i0, SPARC_PSR_PIL_MASK, %l4
|
and %i0, SPARC_PSR_PIL_MASK, %l4
|
||||||
andn %l0, SPARC_PSR_PIL_MASK, %l5
|
andn %l0, SPARC_PSR_PIL_MASK, %l5
|
||||||
or %l5, %l4, %l4
|
wr %l4, %l5, %psr ! Update PSR according to syscall 3
|
||||||
9: ! leave
|
1: ! leave, with 3 inst PSR-write delay
|
||||||
mov %l4, %psr ! Update PSR according to Syscall 2 or 3
|
|
||||||
mov 0, %g1 ! clear %g1
|
mov 0, %g1 ! clear %g1
|
||||||
|
or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1. No
|
||||||
|
! effect on syscall 3
|
||||||
jmpl %l2, %g0
|
jmpl %l2, %g0
|
||||||
rett %l2 + 4
|
rett %l2 + 4
|
||||||
1:
|
|
||||||
|
2: or %l0, 0x0f00, %l4 ! set PIL=15
|
||||||
|
subcc %g1, 2, %g0 ! syscall 2? disable interrupts
|
||||||
|
beq,a 1b ! Annul delay-slot for syscall 1
|
||||||
|
mov %l4, %psr ! Update PSR according to Syscall 2
|
||||||
ta 0 ! syscall 1 (not 2 or 3), halt
|
ta 0 ! syscall 1 (not 2 or 3), halt
|
||||||
|
|
||||||
PUBLIC(sparc_disable_interrupts)
|
PUBLIC(sparc_disable_interrupts)
|
||||||
|
|||||||
Reference in New Issue
Block a user