[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