[PATCH] SPARC: syscall optimizations and PSR-write fix
Daniel Hellstrom
daniel at gaisler.com
Mon May 26 16:12:17 UTC 2014
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.
---
c/src/lib/libbsp/sparc/shared/start/start.S | 11 ++++++++++-
c/src/lib/libcpu/sparc/syscall/syscall.S | 24 ++++++++++++------------
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/c/src/lib/libbsp/sparc/shared/start/start.S b/c/src/lib/libbsp/sparc/shared/start/start.S
index 65dd559..070387f 100644
--- a/c/src/lib/libbsp/sparc/shared/start/start.S
+++ b/c/src/lib/libbsp/sparc/shared/start/start.S
@@ -33,6 +33,15 @@
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...
*/
@@ -156,7 +165,7 @@ SYM(CLOCK_SPEED):
* 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
TRAP( 0x83, SYM(window_flush_trap_handler) ); ! 83 flush windows SW trap
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S
index a0a860c..e6e2704 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? disable 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
mov 0, %g1 ! clear %g1
+ or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1. No
+ ! effect on syscall 2
jmpl %l2, %g0
rett %l2 + 4
-1:
+
+2: or %l0, 0x0f00, %l4 ! set PIL=15
+ subcc %g1, 2, %g0 ! syscall 2? enable 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)
--
1.7.0.4
More information about the devel
mailing list