[rtems commit] sparc: Optimize context switch

Sebastian Huber sebh at rtems.org
Mon Apr 28 08:02:52 UTC 2014


Module:    rtems
Branch:    master
Commit:    b2ec2d15971503466e1debf596dc84b6af0f9b13
Changeset: http://git.rtems.org/rtems/commit/?id=b2ec2d15971503466e1debf596dc84b6af0f9b13

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Apr 22 07:46:56 2014 +0200

sparc: Optimize context switch

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 1b5dbca..3e33134 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
 




More information about the vc mailing list