[PATCH 1/2] SPARC Floating Point Context switch

Gedare Bloom gedare at rtems.org
Thu Apr 30 14:46:32 UTC 2015


On Thu, Apr 30, 2015 at 5:38 AM, Alexander Krutwig
<alexander.krutwig at embedded-brains.de> wrote:
> two new Assembler Files for SPCONTEXT01 test on sparc
> 1) _CPU_Context_validate
> 2) _CPU_Context_volatile_clobber
>
> Update #2270.
> ---
>  cpukit/score/cpu/sparc/Makefile.am                 |   2 +
>  cpukit/score/cpu/sparc/rtems/score/cpu.h           |  12 +-
>  cpukit/score/cpu/sparc/sparc-context-validate.S    | 283 +++++++++++++++++++++
>  .../cpu/sparc/sparc-context-volatile-clobber.S     |  92 +++++++
>  4 files changed, 379 insertions(+), 10 deletions(-)
>  create mode 100644 cpukit/score/cpu/sparc/sparc-context-validate.S
>  create mode 100644 cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
>
> diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am
> index c6ea1c3..8cf4f4a 100644
> --- a/cpukit/score/cpu/sparc/Makefile.am
> +++ b/cpukit/score/cpu/sparc/Makefile.am
> @@ -11,6 +11,8 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
>
>  noinst_LIBRARIES = libscorecpu.a
>  libscorecpu_a_SOURCES = cpu.c cpu_asm.S
> +libscorecpu_a_SOURCES += sparc-context-volatile-clobber.S
> +libscorecpu_a_SOURCES += sparc-context-validate.S
>  libscorecpu_a_SOURCES += sparc-counter.c
>  libscorecpu_a_SOURCES += sparcv8-atomic.c
>  libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
> diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
> index 235b365..64e8750 100644
> --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
> +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
> @@ -1216,17 +1216,9 @@ void _CPU_Context_restore_fp(
>    Context_Control_fp **fp_context_ptr
>  );
>
> -static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
> -{
> -  /* TODO */
> -}
> +void _CPU_Context_volatile_clobber( uintptr_t pattern );
>
> -static inline void _CPU_Context_validate( uintptr_t pattern )
> -{
> -  while (1) {
> -    /* TODO */
> -  }
> -}
> +void _CPU_Context_validate( uintptr_t pattern );
>
>  typedef struct {
>    uint32_t trap;
> diff --git a/cpukit/score/cpu/sparc/sparc-context-validate.S b/cpukit/score/cpu/sparc/sparc-context-validate.S
> new file mode 100644
> index 0000000..b75cf83
> --- /dev/null
> +++ b/cpukit/score/cpu/sparc/sparc-context-validate.S
> @@ -0,0 +1,283 @@
> +/*
> + * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include <rtems/asm.h>
> +#include <rtems/score/cpu.h>
> +
> +#define FRAME_OFFSET_L0 68
> +#define FRAME_OFFSET_L1 72
> +#define FRAME_OFFSET_L2 76
> +#define FRAME_OFFSET_L3 80
> +#define FRAME_OFFSET_L4 84
> +#define FRAME_OFFSET_L5 88
> +#define FRAME_OFFSET_L6 92
> +#define FRAME_OFFSET_L7 96
> +#define FRAME_OFFSET_I0 100
> +#define FRAME_OFFSET_I1 104
> +#define FRAME_OFFSET_I2 108
> +#define FRAME_OFFSET_I3 112
> +#define FRAME_OFFSET_I4 116
> +#define FRAME_OFFSET_I5 120
> +#define FRAME_OFFSET_I6 124
> +#define FRAME_OFFSET_I7 128
> +#define FRAME_OFFSET_O7 132
> +#define BUFFER_STORAGE 136
> +#define FRAME_SIZE (BUFFER_STORAGE + 8)
> +
These belong in sparc.h? Also it may be better to define each offset
in terms of the previous one + 4.

> +#if ((FRAME_SIZE % 8) != 0)
> +#error "Frame size alignment violated"
> +#endif
> +
How is this ever the case?

> +        .align 4
> +        PUBLIC(_CPU_Context_validate)
> +SYM(_CPU_Context_validate):
> +
> +       add     %sp, -FRAME_SIZE, %sp
> +
> +       st      %l0, [%sp + FRAME_OFFSET_L0]
> +       st      %l1, [%sp + FRAME_OFFSET_L1]
> +       st      %l2, [%sp + FRAME_OFFSET_L2]
> +       st      %l3, [%sp + FRAME_OFFSET_L3]
> +       st      %l4, [%sp + FRAME_OFFSET_L4]
> +       st      %l5, [%sp + FRAME_OFFSET_L5]
> +       st      %l6, [%sp + FRAME_OFFSET_L6]
> +       st      %l7, [%sp + FRAME_OFFSET_L7]
> +       st      %i0, [%sp + FRAME_OFFSET_I0]
> +       st      %i1, [%sp + FRAME_OFFSET_I1]
> +       st      %i2, [%sp + FRAME_OFFSET_I2]
> +       st      %i3, [%sp + FRAME_OFFSET_I3]
> +       st      %i4, [%sp + FRAME_OFFSET_I4]
> +       st      %i5, [%sp + FRAME_OFFSET_I5]
> +       st      %i6, [%sp + FRAME_OFFSET_I6]
> +       st      %i7, [%sp + FRAME_OFFSET_I7]
> +
> +       /* Save callback address in case of error */
> +
> +       st      %o7, [%sp + FRAME_OFFSET_O7]
> +
> +.macro fill_register reg
> +       add     %g1, 1, %g1
> +       mov     %g1, \reg
> +.endm
> +
I forget if we have any recommendations for/against using .macro
directives in assembly. Anyone have thoughts?

> +       /* Fill */
> +
This terminology is misleading on sparc, where filling registers has a
usual meaning while register windowing.

> +       /* g1 is used for temporary values */
> +       mov     %o0, %g1
> +
> +       mov     %sp, %g2
> +
To use g2 i think you must declare it as scratch?

Some documentation on what this function does would be good, do we
have it somewhere else already?

> +       fill_register   %o1
> +       fill_register   %o2
> +       fill_register   %o3
> +       fill_register   %o4
> +       fill_register   %o5
Maybe mention that o6 (sp) isn't "filled'

> +       fill_register   %l0
> +       fill_register   %l1
> +       fill_register   %l2
> +       fill_register   %l3
> +       fill_register   %l4
> +       fill_register   %l5
> +       fill_register   %l6
> +       fill_register   %l7
> +       fill_register   %i0
> +       fill_register   %i1
> +       fill_register   %i2
> +       fill_register   %i3
> +       fill_register   %i4
> +       fill_register   %i5
> +       /* Don't fill register $i6 => frame pointer */
> +       fill_register   %i7
> +       fill_register   %y
> +
> +       /* g3 checks if the Floating Point Unit in the Processor Status
> +          Register (PSR) is set */
> +       mov     %psr, %g3
> +       sethi   %hi(4096), %g4
g3 and g4 must be declared scratch. what does ABI say about using
these registers without saving them here

> +       and     %g3, %g4, %g3
> +       cmp     %g3, 0
> +       be      check
> +        nop
> +
> +.macro fill_float_register reg
> +       add     %g1, 1, %g1
> +       st      %g1, [%sp+BUFFER_STORAGE]
> +       ld      [%sp+BUFFER_STORAGE], \reg
> +.endm
> +
> +       fill_float_register     %f0
> +       fill_float_register     %f1
> +       fill_float_register     %f2
> +       fill_float_register     %f3
> +       fill_float_register     %f4
> +       fill_float_register     %f5
> +       fill_float_register     %f6
> +       fill_float_register     %f7
> +       fill_float_register     %f8
> +       fill_float_register     %f9
> +       fill_float_register     %f10
> +       fill_float_register     %f11
> +       fill_float_register     %f12
> +       fill_float_register     %f13
> +       fill_float_register     %f14
> +       fill_float_register     %f15
> +       fill_float_register     %f16
> +       fill_float_register     %f17
> +       fill_float_register     %f18
> +       fill_float_register     %f19
> +       fill_float_register     %f20
> +       fill_float_register     %f21
> +       fill_float_register     %f22
> +       fill_float_register     %f23
> +       fill_float_register     %f24
> +       fill_float_register     %f25
> +       fill_float_register     %f26
> +       fill_float_register     %f27
> +       fill_float_register     %f28
> +       fill_float_register     %f29
> +       fill_float_register     %f30
> +       fill_float_register     %f31
> +
> +       /* Check normal registers*/
> +
> +check:
> +
> +.macro check_register reg
> +       add     %g1, 1, %g1
> +       cmp     %g1, \reg
> +       bne     restore
> +        nop
> +.endm
> +
> +       cmp     %g2, %sp
> +       bne     restore
> +
> +        mov    %o0, %g1
> +       fill_register   %o1
> +
> +       mov     %o0, %g1
> +
> +       check_register  %o1
> +       check_register  %o2
> +       check_register  %o3
> +       check_register  %o4
> +       check_register  %o5
> +       check_register  %l0
> +       check_register  %l1
> +       check_register  %l2
> +       check_register  %l3
> +       check_register  %l4
> +       check_register  %l5
> +       check_register  %l6
> +       check_register  %l7
> +       check_register  %i0
> +       check_register  %i1
> +       check_register  %i2
> +       check_register  %i3
> +       check_register  %i4
> +       check_register  %i5
> +       check_register  %i7
> +
> +       /* Check special purpose register Y */
> +       mov     %y, %o1
> +       check_register  %o1
> +
> +       cmp     %g3, 0
> +       bne     check_float
> +        nop
> +
> +       be      check
> +        nop
> +
> +       /* Restore non-volatile registers */
> +
> +restore:
> +
> +       ld      [%sp + FRAME_OFFSET_L0], %l0
> +       ld      [%sp + FRAME_OFFSET_L1], %l1
> +       ld      [%sp + FRAME_OFFSET_L2], %l2
> +       ld      [%sp + FRAME_OFFSET_L3], %l3
> +       ld      [%sp + FRAME_OFFSET_L4], %l4
> +       ld      [%sp + FRAME_OFFSET_L5], %l5
> +       ld      [%sp + FRAME_OFFSET_L6], %l6
> +       ld      [%sp + FRAME_OFFSET_L7], %l7
> +       ld      [%sp + FRAME_OFFSET_I0], %i0
> +       ld      [%sp + FRAME_OFFSET_I1], %i1
> +       ld      [%sp + FRAME_OFFSET_I2], %i2
> +       ld      [%sp + FRAME_OFFSET_I3], %i3
> +       ld      [%sp + FRAME_OFFSET_I4], %i4
> +       ld      [%sp + FRAME_OFFSET_I5], %i5
> +       ld      [%sp + FRAME_OFFSET_I6], %i6
> +       ld      [%sp + FRAME_OFFSET_I7], %i7
> +
> +       /* Load callback address and jump back*/
> +       ld      [%sp + FRAME_OFFSET_O7], %o7
> +       jmp     %o7+8
> +        add    %sp, FRAME_SIZE, %sp
> +
> +       /* Check floating-point registers */
> +
> +check_float:
> +
> +.macro check_float_register reg
> +       add     %g1, 1, %g1
> +       st      \reg, [%sp+BUFFER_STORAGE]
> +       ld      [%sp+BUFFER_STORAGE], %o1
> +       cmp     %g1, %o1
> +       bne     restore
> +        nop
> +.endm
> +
> +       check_float_register    %f0
> +       check_float_register    %f1
> +       check_float_register    %f2
> +       check_float_register    %f3
> +       check_float_register    %f4
> +       check_float_register    %f5
> +       check_float_register    %f6
> +       check_float_register    %f7
> +       check_float_register    %f8
> +       check_float_register    %f9
> +       check_float_register    %f10
> +       check_float_register    %f11
> +       check_float_register    %f12
> +       check_float_register    %f13
> +       check_float_register    %f14
> +       check_float_register    %f15
> +       check_float_register    %f16
> +       check_float_register    %f17
> +       check_float_register    %f18
> +       check_float_register    %f19
> +       check_float_register    %f20
> +       check_float_register    %f21
> +       check_float_register    %f22
> +       check_float_register    %f23
> +       check_float_register    %f24
> +       check_float_register    %f25
> +       check_float_register    %f26
> +       check_float_register    %f27
> +       check_float_register    %f28
> +       check_float_register    %f29
> +       check_float_register    %f30
> +       check_float_register    %f31
> +
> +       mov     %o0, %g1
> +       fill_register   %o1
> +
> +       b       check
> +        nop
> diff --git a/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S b/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
> new file mode 100644
> index 0000000..b30a303
> --- /dev/null
> +++ b/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
> @@ -0,0 +1,92 @@
> +/*
> + * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
> + *
> + *  embedded brains GmbH
> + *  Dornierstr. 4
> + *  82178 Puchheim
> + *  Germany
> + *  <rtems at embedded-brains.de>
> + *
> + * The license and distribution terms for this file may be
> + * found in the file LICENSE in this distribution or at
> + * http://www.rtems.org/license/LICENSE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +  #include "config.h"
> +#endif
> +
> +#include <rtems/asm.h>
> +#include <rtems/system.h>
> +
> +        .align 4
> +        PUBLIC(_CPU_Context_volatile_clobber)
> +SYM(_CPU_Context_volatile_clobber):
> +
> +.macro clobber_register reg
> +       sub     %o0, 1, %o0
> +       mov     %o0, \reg
> +.endm
> +
> +.macro clobber_fp_register reg
> +       sub     %o0, 1, %o0
> +       st      %o0, [%sp+72]
72?

> +       ld      [%sp+72], \reg
> +.endm
> +
> +       add     %sp, -80, %sp
-80?

> +       st      %o7, [%sp+76]
76?

> +
> +       clobber_register        %o1
> +       clobber_register        %o2
> +       clobber_register        %o3
> +       clobber_register        %o4
> +       clobber_register        %o5
> +       clobber_register        %o7
> +       clobber_register        %y
> +
> +       mov     %psr, %o1
> +       sethi   %hi(4096), %o2
> +       and     %o1, %o2, %o2
> +       cmp     %o2, 0
> +       be      clobber_return
> +        nop
> +
> +       clobber_fp_register     %f0
> +       clobber_fp_register     %f1
> +       clobber_fp_register     %f2
> +       clobber_fp_register     %f3
> +       clobber_fp_register     %f4
> +       clobber_fp_register     %f5
> +       clobber_fp_register     %f6
> +       clobber_fp_register     %f7
> +       clobber_fp_register     %f8
> +       clobber_fp_register     %f9
> +       clobber_fp_register     %f10
> +       clobber_fp_register     %f11
> +       clobber_fp_register     %f12
> +       clobber_fp_register     %f13
> +       clobber_fp_register     %f14
> +       clobber_fp_register     %f15
> +       clobber_fp_register     %f16
> +       clobber_fp_register     %f17
> +       clobber_fp_register     %f18
> +       clobber_fp_register     %f19
> +       clobber_fp_register     %f20
> +       clobber_fp_register     %f21
> +       clobber_fp_register     %f22
> +       clobber_fp_register     %f23
> +       clobber_fp_register     %f24
> +       clobber_fp_register     %f25
> +       clobber_fp_register     %f26
> +       clobber_fp_register     %f27
> +       clobber_fp_register     %f28
> +       clobber_fp_register     %f29
> +       clobber_fp_register     %f30
> +       clobber_fp_register     %f31
> +
> +clobber_return:
> +
> +       ld      [%sp+76], %o7
> +       jmp     %o7+8
> +        add    %sp, 80, %sp
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel



More information about the devel mailing list