[PATCH 2/4] sparc: Optimize context switch

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Apr 22 08:46:44 UTC 2014


The registers g2 through g4 are reserved for applications.  GCC uses
them as volatile registers by default.  So they are treated like
volatile registers in RTEMS as well.
---
 c/src/lib/libbsp/sparc/shared/irq_asm.S  |    6 +--
 cpukit/score/cpu/sparc/cpu.c             |   21 ++++----
 cpukit/score/cpu/sparc/rtems/score/cpu.h |   78 ++++++++++++++----------------
 doc/cpu_supplement/sparc.t               |    3 +
 4 files changed, 53 insertions(+), 55 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S
index fc4c0be..fd8269f 100644
--- a/c/src/lib/libbsp/sparc/shared/irq_asm.S
+++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S
@@ -52,8 +52,7 @@
         .align 4
         PUBLIC(_CPU_Context_switch)
 SYM(_CPU_Context_switch):
-        std     %g2, [%o0 + G2_OFFSET]       ! save the global registers
-        std     %g4, [%o0 + G4_OFFSET]
+        st      %g5, [%o0 + G5_OFFSET]       ! save the global registers
         std     %g6, [%o0 + G6_OFFSET]
 
         std     %l0, [%o0 + L0_OFFSET]       ! save the local registers
@@ -185,8 +184,7 @@ done_flushing:
         nop
         nop
 
-        ldd     [%o1 + G2_OFFSET], %g2        ! restore the global registers
-        ldd     [%o1 + G4_OFFSET], %g4
+        ld      [%o1 + G5_OFFSET], %g5        ! restore the global registers
         ldd     [%o1 + G6_OFFSET], %g6
 
         ! Load thread specific ISR dispatch prevention flag
diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c
index 73ed4fd..463ff47 100644
--- a/cpukit/score/cpu/sparc/cpu.c
+++ b/cpukit/score/cpu/sparc/cpu.c
@@ -35,13 +35,20 @@ RTEMS_STATIC_ASSERT(
     Context_Control_offset_ ## field \
   )
 
-SPARC_ASSERT_OFFSET(g2_g3, G2);
-SPARC_ASSERT_OFFSET(g4, G4);
 SPARC_ASSERT_OFFSET(g5, G5);
 SPARC_ASSERT_OFFSET(g6, G6);
 SPARC_ASSERT_OFFSET(g7, G7);
-SPARC_ASSERT_OFFSET(l0, L0);
-SPARC_ASSERT_OFFSET(l1, L1);
+
+RTEMS_STATIC_ASSERT(
+  offsetof(Context_Control, l0_and_l1) == L0_OFFSET,
+  Context_Control_offset_L0
+);
+
+RTEMS_STATIC_ASSERT(
+  offsetof(Context_Control, l0_and_l1) + 4 == L1_OFFSET,
+  Context_Control_offset_L1
+);
+
 SPARC_ASSERT_OFFSET(l2, L2);
 SPARC_ASSERT_OFFSET(l3, L3);
 SPARC_ASSERT_OFFSET(l4, L4);
@@ -61,12 +68,6 @@ SPARC_ASSERT_OFFSET(o7, O7);
 SPARC_ASSERT_OFFSET(psr, PSR);
 SPARC_ASSERT_OFFSET(isr_dispatch_disable, ISR_DISPATCH_DISABLE_STACK);
 
-RTEMS_STATIC_ASSERT(
-  (offsetof(Context_Control, g2_g3)
-     + offsetof(Context_Control, g4)) / 2 == G3_OFFSET,
-  Context_Control_offset_G3
-);
-
 /*
  *  This initializes the set of opcodes placed in each trap
  *  table entry.  The routine which installs a handler is responsible
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index d3ebf3e..dde29fc 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -404,16 +404,14 @@ typedef struct {
  * This structure defines the non-volatile integer and processor state context
  * for the SPARC architecture according to "SYSTEM V APPLICATION BINARY
  * INTERFACE - SPARC Processor Supplement", Third Edition.
+ *
+ * The registers g2 through g4 are reserved for applications.  GCC uses them as
+ * volatile registers by default.  So they are treated like volatile registers
+ * in RTEMS as well.
  */
 typedef struct {
-  /**
-   * Using a double g2_g3 will put everything in this structure on a
-   * double word boundary which allows us to use double word loads
-   * and stores safely in the context switch.
-   */
-  double     g2_g3;
-  /** This will contain the contents of the g4 register. */
-  uint32_t   g4;
+  /** This will contain reserved space for alignment. */
+  uint32_t   reserved_for_alignment;
   /** This will contain the contents of the g5 register. */
   uint32_t   g5;
   /** This will contain the contents of the g6 register. */
@@ -421,10 +419,14 @@ typedef struct {
   /** This will contain the contents of the g7 register. */
   uint32_t   g7;
 
-  /** This will contain the contents of the l0 register. */
-  uint32_t   l0;
-  /** This will contain the contents of the l1 register. */
-  uint32_t   l1;
+  /**
+   * This will contain the contents of the l0 and l1 registers.
+   *
+   * Using a double l0_and_l1 will put everything in this structure on a double
+   * word boundary which allows us to use double word loads and stores safely
+   * in the context switch.
+   */
+  double     l0_and_l1;
   /** This will contain the contents of the l2 register. */
   uint32_t   l2;
   /** This will contain the contents of the l3 register. */
@@ -488,61 +490,55 @@ typedef struct {
  */
 
 /** This macro defines an offset into the context for use in assembly. */
-#define G2_OFFSET    0x00
-/** This macro defines an offset into the context for use in assembly. */
-#define G3_OFFSET    0x04
-/** This macro defines an offset into the context for use in assembly. */
-#define G4_OFFSET    0x08
-/** This macro defines an offset into the context for use in assembly. */
-#define G5_OFFSET    0x0C
+#define G5_OFFSET    0x04
 /** This macro defines an offset into the context for use in assembly. */
-#define G6_OFFSET    0x10
+#define G6_OFFSET    0x08
 /** This macro defines an offset into the context for use in assembly. */
-#define G7_OFFSET    0x14
+#define G7_OFFSET    0x0C
 
 /** This macro defines an offset into the context for use in assembly. */
-#define L0_OFFSET    0x18
+#define L0_OFFSET    0x10
 /** This macro defines an offset into the context for use in assembly. */
-#define L1_OFFSET    0x1C
+#define L1_OFFSET    0x14
 /** This macro defines an offset into the context for use in assembly. */
-#define L2_OFFSET    0x20
+#define L2_OFFSET    0x18
 /** This macro defines an offset into the context for use in assembly. */
-#define L3_OFFSET    0x24
+#define L3_OFFSET    0x1C
 /** This macro defines an offset into the context for use in assembly. */
-#define L4_OFFSET    0x28
+#define L4_OFFSET    0x20
 /** This macro defines an offset into the context for use in assembly. */
-#define L5_OFFSET    0x2C
+#define L5_OFFSET    0x24
 /** This macro defines an offset into the context for use in assembly. */
-#define L6_OFFSET    0x30
+#define L6_OFFSET    0x28
 /** This macro defines an offset into the context for use in assembly. */
-#define L7_OFFSET    0x34
+#define L7_OFFSET    0x2C
 
 /** This macro defines an offset into the context for use in assembly. */
-#define I0_OFFSET    0x38
+#define I0_OFFSET    0x30
 /** This macro defines an offset into the context for use in assembly. */
-#define I1_OFFSET    0x3C
+#define I1_OFFSET    0x34
 /** This macro defines an offset into the context for use in assembly. */
-#define I2_OFFSET    0x40
+#define I2_OFFSET    0x38
 /** This macro defines an offset into the context for use in assembly. */
-#define I3_OFFSET    0x44
+#define I3_OFFSET    0x3C
 /** This macro defines an offset into the context for use in assembly. */
-#define I4_OFFSET    0x48
+#define I4_OFFSET    0x40
 /** This macro defines an offset into the context for use in assembly. */
-#define I5_OFFSET    0x4C
+#define I5_OFFSET    0x44
 /** This macro defines an offset into the context for use in assembly. */
-#define I6_FP_OFFSET 0x50
+#define I6_FP_OFFSET 0x48
 /** This macro defines an offset into the context for use in assembly. */
-#define I7_OFFSET    0x54
+#define I7_OFFSET    0x4C
 
 /** This macro defines an offset into the context for use in assembly. */
-#define O6_SP_OFFSET 0x58
+#define O6_SP_OFFSET 0x50
 /** This macro defines an offset into the context for use in assembly. */
-#define O7_OFFSET    0x5C
+#define O7_OFFSET    0x54
 
 /** This macro defines an offset into the context for use in assembly. */
-#define PSR_OFFSET   0x60
+#define PSR_OFFSET   0x58
 /** This macro defines an offset into the context for use in assembly. */
-#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x64
+#define ISR_DISPATCH_DISABLE_STACK_OFFSET 0x5C
 
 /** This defines the size of the context area for use in assembly. */
 #define CONTEXT_CONTROL_SIZE 0x68
diff --git a/doc/cpu_supplement/sparc.t b/doc/cpu_supplement/sparc.t
index 616f79f..320c250 100644
--- a/doc/cpu_supplement/sparc.t
+++ b/doc/cpu_supplement/sparc.t
@@ -397,6 +397,9 @@ describes the role of each of these registers:
 @end html
 @end ifset
 
+The registers g2 through g4 are reserved for applications.  GCC uses them as
+volatile registers by default.  So they are treated like volatile registers in
+RTEMS as well.
 
 @subsubsection Floating Point Registers
 
-- 
1.7.7




More information about the devel mailing list