diff options
author | Daniel Hellstrom <daniel@gaisler.com> | 2014-05-26 15:22:12 +0200 |
---|---|---|
committer | Daniel Hellstrom <daniel@gaisler.com> | 2014-05-28 17:33:22 +0200 |
commit | d6f1ec91b6fd074e3a2b15f7ca8b2a8c73a39484 (patch) | |
tree | 811725cdfc49acf88fa10febf6c60965225c242b /c/src/lib/libcpu/sparc/syscall/syscall.S | |
parent | LEON3: coding style clean bsp_irq_fixup() (diff) | |
download | rtems-d6f1ec91b6fd074e3a2b15f7ca8b2a8c73a39484.tar.bz2 |
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.
Diffstat (limited to 'c/src/lib/libcpu/sparc/syscall/syscall.S')
-rw-r--r-- | c/src/lib/libcpu/sparc/syscall/syscall.S | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S index a0a860c912..a36ffaf220 100644 --- a/c/src/lib/libcpu/sparc/syscall/syscall.S +++ b/c/src/lib/libcpu/sparc/syscall/syscall.S @@ -35,27 +35,27 @@ * g3 = additional exit code 2 */ +.align 32 ! Align to 32-byte cache-line PUBLIC(syscall) SYM(syscall): - subcc %g1, 2, %g0 ! syscall 2, disable interrupts - bne 3f - 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 + ! "subcc, %g1, 3, %g0" done in trap table + bne 2f ! syscall 3? enable interrupt and %i0, SPARC_PSR_PIL_MASK, %l4 andn %l0, SPARC_PSR_PIL_MASK, %l5 - or %l5, %l4, %l4 -9: ! leave - mov %l4, %psr ! Update PSR according to Syscall 2 or 3 + wr %l4, %l5, %psr ! Update PSR according to syscall 3 +1: ! leave, with 3 inst PSR-write delay mov 0, %g1 ! clear %g1 - jmpl %l2, %g0 - rett %l2 + 4 -1: + or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1. No + ! effect on syscall 3 + jmpl %l2, %g0 + rett %l2 + 4 + +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 PUBLIC(sparc_disable_interrupts) |