summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/sparc/syscall/syscall.S
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2014-05-26 15:22:12 +0200
committerDaniel Hellstrom <daniel@gaisler.com>2014-05-28 17:33:22 +0200
commitd6f1ec91b6fd074e3a2b15f7ca8b2a8c73a39484 (patch)
tree811725cdfc49acf88fa10febf6c60965225c242b /c/src/lib/libcpu/sparc/syscall/syscall.S
parentLEON3: coding style clean bsp_irq_fixup() (diff)
downloadrtems-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.S28
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)