Ignore:
Timestamp:
05/15/09 07:20:38 (13 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, 5, master
Children:
4670d91
Parents:
6ec6ceb9
Message:

cpu.c, cpu_asm.S, rtems/score/cpu.h: Cleanup of the floating point context initialization, save and restore code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/score/cpu/m68k/rtems/score/cpu.h

    r6ec6ceb9 r3b7e9bc  
    2626#include <rtems/score/m68k.h>              /* pick up machine definitions */
    2727#ifndef ASM
    28 #include <rtems/score/types.h>
     28  #include <rtems/score/types.h>
     29#else
     30  /* FIXME */
     31  #define TRUE 1
     32  #define FALSE 0
    2933#endif
    3034
     
    7882 */
    7983
    80 #if ( M68K_HAS_FPU == 1 )
    81 #define CPU_HARDWARE_FP    TRUE
    82 #define CPU_SOFTWARE_FP    FALSE
     84#if ( M68K_HAS_FPU == 1 ) || ( M68K_HAS_EMAC == 1 )
     85  #define CPU_HARDWARE_FP TRUE
     86  #define CPU_SOFTWARE_FP FALSE
    8387#else
    84 #define CPU_HARDWARE_FP    FALSE
    85 #if defined(__GNUC__)
    86 #define CPU_SOFTWARE_FP    TRUE
    87 #else
    88 #define CPU_SOFTWARE_FP    FALSE
    89 #endif
     88  #define CPU_HARDWARE_FP FALSE
     89  #if defined( __GNUC__ )
     90    #define CPU_SOFTWARE_FP TRUE
     91  #else
     92    #define CPU_SOFTWARE_FP FALSE
     93  #endif
    9094#endif
    9195
     
    114118
    115119#ifndef ASM
     120
    116121/* structures */
    117122
     
    134139  void       *a6;                /* (a6) address register 6 */
    135140  void       *a7_msp;            /* (a7) master stack pointer */
    136 
    137 #if (defined(__mcoldfire__))
    138 #if ( M68K_HAS_FPU == 1 )
    139   uint8_t   fpu_dis;
    140 #endif
    141 #endif
    142 
    143 }   Context_Control;
     141  #if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 )
     142    uint8_t   fpu_dis;
     143  #endif
     144} Context_Control;
    144145
    145146#define _CPU_Context_Get_SP( _context ) \
     
    147148
    148149/*
    149  *  Floating point context ares
    150  */
    151 
    152 #if (CPU_SOFTWARE_FP == TRUE)
    153 
    154 /*
    155  *  This is the same as gcc's view of the software FP condition code
    156  *  register _fpCCR.  The implementation of the emulation code is
    157  *  in the gcc-VERSION/config/m68k directory.  This structure is
    158  *  correct as of gcc 2.7.2.2.
    159  */
    160 
    161 typedef struct {
    162   uint16_t     _exception_bits;
    163   uint16_t     _trap_enable_bits;
    164   uint16_t     _sticky_bits;
    165   uint16_t     _rounding_mode;
    166   uint16_t     _format;
    167   uint16_t     _last_operation;
    168   union {
    169     float sf;
    170     double df;
    171   } _operand1;
    172   union {
    173     float sf;
    174     double df;
    175   } _operand2;
    176 } Context_Control_fp;
    177 
    178 #elif (defined(__mcoldfire__))
    179 
    180 /*
    181  *  FP context save area for the ColdFire core numeric coprocessors
    182  */
    183 typedef struct {
    184   uint8_t     fp_save_area[84];     /*    16 bytes for FSAVE/FRESTORE    */
    185                                     /*    64 bytes for FMOVEM FP0-7      */
    186                                     /*     4 bytes for non-null flag     */
    187 
    188 #if (M68K_HAS_EMAC == 1)
    189 
    190 /*
    191  *  EMAC context save area for the ColdFire core
    192  */
    193   uint8_t     emac_save_area[32];   /*  32 bytes for EMAC registers      */
    194 
    195 #endif
    196 
    197 } Context_Control_fp;
    198 
    199 #if ( M68K_HAS_FPU == 1 )
    200 extern uint32_t _CPU_cacr_shadow;
    201 #endif
    202 
    203 #else
    204 /*
    205  *  FP context save area for the M68881/M68882 numeric coprocessors.
    206  */
    207 typedef struct {
    208   uint8_t     fp_save_area[332];    /*   216 bytes for FSAVE/FRESTORE    */
    209                                     /*    96 bytes for FMOVEM FP0-7      */
    210                                     /*    12 bytes for FMOVEM CREGS      */
    211                                     /*     4 bytes for non-null flag     */
    212 } Context_Control_fp;
     150 *  Floating point context areas and support routines
     151 */
     152
     153#if ( CPU_SOFTWARE_FP == TRUE )
     154  /*
     155   *  This is the same as gcc's view of the software FP condition code
     156   *  register _fpCCR.  The implementation of the emulation code is
     157   *  in the gcc-VERSION/config/m68k directory.  This structure is
     158   *  correct as of gcc 2.7.2.2.
     159   */
     160  typedef struct {
     161    uint16_t _exception_bits;
     162    uint16_t _trap_enable_bits;
     163    uint16_t _sticky_bits;
     164    uint16_t _rounding_mode;
     165    uint16_t _format;
     166    uint16_t _last_operation;
     167    union {
     168      float sf;
     169      double df;
     170    } _operand1;
     171    union {
     172      float sf;
     173      double df;
     174    } _operand2;
     175  } Context_Control_fp;
     176
     177  /*
     178   *  This software FP implementation is only for GCC.
     179   */
     180  #define _CPU_Context_Fp_start( _base, _offset ) \
     181     ((void *) _Addresses_Add_offset( (_base), (_offset) ) )
     182
     183  #define _CPU_Context_Initialize_fp( _fp_area ) \
     184     { \
     185       Context_Control_fp *_fp; \
     186       _fp = *(Context_Control_fp **)_fp_area; \
     187       _fp->_exception_bits = 0; \
     188       _fp->_trap_enable_bits = 0; \
     189       _fp->_sticky_bits = 0; \
     190       _fp->_rounding_mode = 0;  /* ROUND_TO_NEAREST */ \
     191       _fp->_format = 0;         /* NIL */ \
     192       _fp->_last_operation = 0; /* NOOP */ \
     193       _fp->_operand1.df = 0; \
     194       _fp->_operand2.df = 0; \
     195     }
     196#endif
     197
     198#if ( CPU_HARDWARE_FP == TRUE )
     199  #if defined( __mcoldfire__ )
     200    /* We need memset() to initialize the FP context */
     201    #include <string.h>
     202
     203    #if ( M68K_HAS_FPU == 1 )
     204      /*
     205       * The Cache Control Register (CACR) has write-only access.  It is also
     206       * used to enable and disable the FPU.  We need to maintain a copy of
     207       * this register to allow per thread values.
     208       */
     209      extern uint32_t _CPU_cacr_shadow;
     210    #endif
     211
     212    /* We assume that each ColdFire core with a FPU has also an EMAC unit */
     213    typedef struct {
     214      uint32_t emac_macsr;
     215      uint32_t emac_acc0;
     216      uint32_t emac_acc1;
     217      uint32_t emac_acc2;
     218      uint32_t emac_acc3;
     219      uint32_t emac_accext01;
     220      uint32_t emac_accext23;
     221      uint32_t emac_mask;
     222      #if ( M68K_HAS_FPU == 1 )
     223        uint16_t fp_state_format;
     224        uint16_t fp_state_fpcr;
     225        double fp_state_op;
     226        uint32_t fp_state_fpsr;
     227
     228        /*
     229         * We need to save the FP Instruction Address Register (FPIAR), because
     230         * a context switch can occur within a FP exception before the handler
     231         * was able to save this register.
     232         */
     233        uint32_t fp_fpiar;
     234
     235        double fp_data [8];
     236      #endif
     237    } Context_Control_fp;
     238
     239    #define _CPU_Context_Fp_start( _base, _offset ) \
     240      ((void *) _Addresses_Add_offset( (_base), (_offset) ))
     241
     242    /*
     243     * The reset value for all context relevant registers except the FP data
     244     * registers is zero.  The reset value of the FP data register is NAN.  The
     245     * restore of the reset FP state will reset the FP data registers, so the
     246     * initial value of them can be arbitrary here.
     247     */
     248    #define _CPU_Context_Initialize_fp( _fp_area ) \
     249      memset( *(_fp_area), 0, sizeof( Context_Control_fp ) )
     250  #else
     251    /*
     252     *  FP context save area for the M68881/M68882 and 68060 numeric coprocessors.
     253     */
     254
     255    #if defined( __mc68060__ )
     256      #define M68K_FP_STATE_SIZE 16
     257    #else
     258      #define M68K_FP_STATE_SIZE 216
     259    #endif
     260
     261    typedef struct {
     262      /*
     263       * M68K_FP_STATE_SIZE bytes for FSAVE/FRESTORE
     264       * 96 bytes for FMOVEM FP0-7
     265       * 12 bytes for FMOVEM CREGS
     266       * 4 bytes for non-null flag
     267       */
     268      uint8_t fp_save_area [M68K_FP_STATE_SIZE + 112];
     269    } Context_Control_fp;
     270
     271    #define _CPU_Context_Fp_start( _base, _offset ) \
     272       ( \
     273         (void *) _Addresses_Add_offset( \
     274            (_base), \
     275            (_offset) + CPU_CONTEXT_FP_SIZE - 4 \
     276         ) \
     277       )
     278
     279    #define _CPU_Context_Initialize_fp( _fp_area ) \
     280       { \
     281         uint32_t   *_fp_context = (uint32_t *)*(_fp_area); \
     282         *(--(_fp_context)) = 0; \
     283         *(_fp_area) = (void *)(_fp_context); \
     284       }
     285    #endif
    213286#endif
    214287
     
    265338
    266339#endif /* M68K_HAS_VBR */
     340
    267341#endif /* ASM */
    268342
     
    404478        : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \
    405479  }
    406 
    407 /*
    408  *  Floating Point Context Area Support routines
    409  */
    410 
    411 #if (CPU_SOFTWARE_FP == TRUE)
    412 
    413 /*
    414  *  This software FP implementation is only for GCC.
    415  */
    416 
    417 #define _CPU_Context_Fp_start( _base, _offset ) \
    418    ((void *) _Addresses_Add_offset( (_base), (_offset) ) )
    419 
    420 
    421 #define _CPU_Context_Initialize_fp( _fp_area ) \
    422    { \
    423    Context_Control_fp *_fp; \
    424    _fp = *(Context_Control_fp **)_fp_area; \
    425    _fp->_exception_bits = 0; \
    426    _fp->_trap_enable_bits = 0; \
    427    _fp->_sticky_bits = 0; \
    428    _fp->_rounding_mode = 0;  /* ROUND_TO_NEAREST */ \
    429    _fp->_format = 0;         /* NIL */ \
    430    _fp->_last_operation = 0;  /* NOOP */ \
    431    _fp->_operand1.df = 0; \
    432    _fp->_operand2.df = 0; \
    433    }
    434 #else
    435 #define _CPU_Context_Fp_start( _base, _offset ) \
    436    ((void *) \
    437      _Addresses_Add_offset( \
    438         (_base), \
    439         (_offset) + CPU_CONTEXT_FP_SIZE - 4 \
    440      ) \
    441    )
    442 
    443 #if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 ))
    444 #define _CPU_Context_Initialize_fp( _fp_area ) \
    445    { uint32_t   *_fp_context = (uint32_t *)*(_fp_area); \
    446      \
    447      *(--(_fp_context)) = 0; \
    448      *(_fp_area) = (void *)(_fp_context); \
    449      asm volatile("movl %0,%%macsr": : "d" (0) ); \
    450    }
    451 #else
    452 #define _CPU_Context_Initialize_fp( _fp_area ) \
    453    { uint32_t   *_fp_context = (uint32_t *)*(_fp_area); \
    454      \
    455      *(--(_fp_context)) = 0; \
    456      *(_fp_area) = (void *)(_fp_context); \
    457    }
    458 #endif
    459 #endif
    460480
    461481/* end of Context handler macros */
Note: See TracChangeset for help on using the changeset viewer.