From 3b7e9bcfcdacb7445822d60f46033d94bc90bb34 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Fri, 15 May 2009 07:20:38 +0000 Subject: cpu.c, cpu_asm.S, rtems/score/cpu.h: Cleanup of the floating point context initialization, save and restore code. --- cpukit/score/cpu/m68k/rtems/score/cpu.h | 288 +++++++++++++++++--------------- 1 file changed, 154 insertions(+), 134 deletions(-) (limited to 'cpukit/score/cpu/m68k/rtems') diff --git a/cpukit/score/cpu/m68k/rtems/score/cpu.h b/cpukit/score/cpu/m68k/rtems/score/cpu.h index c60faf34d1..85ea4247cd 100644 --- a/cpukit/score/cpu/m68k/rtems/score/cpu.h +++ b/cpukit/score/cpu/m68k/rtems/score/cpu.h @@ -25,7 +25,11 @@ extern "C" { #include /* pick up machine definitions */ #ifndef ASM -#include + #include +#else + /* FIXME */ + #define TRUE 1 + #define FALSE 0 #endif /* conditional compilation parameters */ @@ -77,16 +81,16 @@ extern "C" { * must be contexted switched on a per task basis. */ -#if ( M68K_HAS_FPU == 1 ) -#define CPU_HARDWARE_FP TRUE -#define CPU_SOFTWARE_FP FALSE -#else -#define CPU_HARDWARE_FP FALSE -#if defined(__GNUC__) -#define CPU_SOFTWARE_FP TRUE +#if ( M68K_HAS_FPU == 1 ) || ( M68K_HAS_EMAC == 1 ) + #define CPU_HARDWARE_FP TRUE + #define CPU_SOFTWARE_FP FALSE #else -#define CPU_SOFTWARE_FP FALSE -#endif + #define CPU_HARDWARE_FP FALSE + #if defined( __GNUC__ ) + #define CPU_SOFTWARE_FP TRUE + #else + #define CPU_SOFTWARE_FP FALSE + #endif #endif /* @@ -113,6 +117,7 @@ extern "C" { #define CPU_LITTLE_ENDIAN FALSE #ifndef ASM + /* structures */ /* @@ -133,83 +138,151 @@ typedef struct { void *a5; /* (a5) address register 5 */ void *a6; /* (a6) address register 6 */ void *a7_msp; /* (a7) master stack pointer */ - -#if (defined(__mcoldfire__)) -#if ( M68K_HAS_FPU == 1 ) - uint8_t fpu_dis; -#endif -#endif - -} Context_Control; + #if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 ) + uint8_t fpu_dis; + #endif +} Context_Control; #define _CPU_Context_Get_SP( _context ) \ (_context)->a7_msp /* - * Floating point context ares - */ - -#if (CPU_SOFTWARE_FP == TRUE) - -/* - * This is the same as gcc's view of the software FP condition code - * register _fpCCR. The implementation of the emulation code is - * in the gcc-VERSION/config/m68k directory. This structure is - * correct as of gcc 2.7.2.2. - */ - -typedef struct { - uint16_t _exception_bits; - uint16_t _trap_enable_bits; - uint16_t _sticky_bits; - uint16_t _rounding_mode; - uint16_t _format; - uint16_t _last_operation; - union { - float sf; - double df; - } _operand1; - union { - float sf; - double df; - } _operand2; -} Context_Control_fp; - -#elif (defined(__mcoldfire__)) - -/* - * FP context save area for the ColdFire core numeric coprocessors - */ -typedef struct { - uint8_t fp_save_area[84]; /* 16 bytes for FSAVE/FRESTORE */ - /* 64 bytes for FMOVEM FP0-7 */ - /* 4 bytes for non-null flag */ - -#if (M68K_HAS_EMAC == 1) - -/* - * EMAC context save area for the ColdFire core - */ - uint8_t emac_save_area[32]; /* 32 bytes for EMAC registers */ - -#endif - -} Context_Control_fp; - -#if ( M68K_HAS_FPU == 1 ) -extern uint32_t _CPU_cacr_shadow; + * Floating point context areas and support routines + */ + +#if ( CPU_SOFTWARE_FP == TRUE ) + /* + * This is the same as gcc's view of the software FP condition code + * register _fpCCR. The implementation of the emulation code is + * in the gcc-VERSION/config/m68k directory. This structure is + * correct as of gcc 2.7.2.2. + */ + typedef struct { + uint16_t _exception_bits; + uint16_t _trap_enable_bits; + uint16_t _sticky_bits; + uint16_t _rounding_mode; + uint16_t _format; + uint16_t _last_operation; + union { + float sf; + double df; + } _operand1; + union { + float sf; + double df; + } _operand2; + } Context_Control_fp; + + /* + * This software FP implementation is only for GCC. + */ + #define _CPU_Context_Fp_start( _base, _offset ) \ + ((void *) _Addresses_Add_offset( (_base), (_offset) ) ) + + #define _CPU_Context_Initialize_fp( _fp_area ) \ + { \ + Context_Control_fp *_fp; \ + _fp = *(Context_Control_fp **)_fp_area; \ + _fp->_exception_bits = 0; \ + _fp->_trap_enable_bits = 0; \ + _fp->_sticky_bits = 0; \ + _fp->_rounding_mode = 0; /* ROUND_TO_NEAREST */ \ + _fp->_format = 0; /* NIL */ \ + _fp->_last_operation = 0; /* NOOP */ \ + _fp->_operand1.df = 0; \ + _fp->_operand2.df = 0; \ + } #endif -#else -/* - * FP context save area for the M68881/M68882 numeric coprocessors. - */ -typedef struct { - uint8_t fp_save_area[332]; /* 216 bytes for FSAVE/FRESTORE */ - /* 96 bytes for FMOVEM FP0-7 */ - /* 12 bytes for FMOVEM CREGS */ - /* 4 bytes for non-null flag */ -} Context_Control_fp; +#if ( CPU_HARDWARE_FP == TRUE ) + #if defined( __mcoldfire__ ) + /* We need memset() to initialize the FP context */ + #include + + #if ( M68K_HAS_FPU == 1 ) + /* + * The Cache Control Register (CACR) has write-only access. It is also + * used to enable and disable the FPU. We need to maintain a copy of + * this register to allow per thread values. + */ + extern uint32_t _CPU_cacr_shadow; + #endif + + /* We assume that each ColdFire core with a FPU has also an EMAC unit */ + typedef struct { + uint32_t emac_macsr; + uint32_t emac_acc0; + uint32_t emac_acc1; + uint32_t emac_acc2; + uint32_t emac_acc3; + uint32_t emac_accext01; + uint32_t emac_accext23; + uint32_t emac_mask; + #if ( M68K_HAS_FPU == 1 ) + uint16_t fp_state_format; + uint16_t fp_state_fpcr; + double fp_state_op; + uint32_t fp_state_fpsr; + + /* + * We need to save the FP Instruction Address Register (FPIAR), because + * a context switch can occur within a FP exception before the handler + * was able to save this register. + */ + uint32_t fp_fpiar; + + double fp_data [8]; + #endif + } Context_Control_fp; + + #define _CPU_Context_Fp_start( _base, _offset ) \ + ((void *) _Addresses_Add_offset( (_base), (_offset) )) + + /* + * The reset value for all context relevant registers except the FP data + * registers is zero. The reset value of the FP data register is NAN. The + * restore of the reset FP state will reset the FP data registers, so the + * initial value of them can be arbitrary here. + */ + #define _CPU_Context_Initialize_fp( _fp_area ) \ + memset( *(_fp_area), 0, sizeof( Context_Control_fp ) ) + #else + /* + * FP context save area for the M68881/M68882 and 68060 numeric coprocessors. + */ + + #if defined( __mc68060__ ) + #define M68K_FP_STATE_SIZE 16 + #else + #define M68K_FP_STATE_SIZE 216 + #endif + + typedef struct { + /* + * M68K_FP_STATE_SIZE bytes for FSAVE/FRESTORE + * 96 bytes for FMOVEM FP0-7 + * 12 bytes for FMOVEM CREGS + * 4 bytes for non-null flag + */ + uint8_t fp_save_area [M68K_FP_STATE_SIZE + 112]; + } Context_Control_fp; + + #define _CPU_Context_Fp_start( _base, _offset ) \ + ( \ + (void *) _Addresses_Add_offset( \ + (_base), \ + (_offset) + CPU_CONTEXT_FP_SIZE - 4 \ + ) \ + ) + + #define _CPU_Context_Initialize_fp( _fp_area ) \ + { \ + uint32_t *_fp_context = (uint32_t *)*(_fp_area); \ + *(--(_fp_context)) = 0; \ + *(_fp_area) = (void *)(_fp_context); \ + } + #endif #endif /* @@ -264,6 +337,7 @@ typedef struct { SCORE_EXTERN _CPU_ISR_handler_entry _CPU_ISR_jump_table[256]; #endif /* M68K_HAS_VBR */ + #endif /* ASM */ /* constants */ @@ -404,60 +478,6 @@ uint32_t _CPU_ISR_Get_level( void ); : "0" ((_the_context)->sr), "1" ((_the_context)->a7_msp) ); \ } -/* - * Floating Point Context Area Support routines - */ - -#if (CPU_SOFTWARE_FP == TRUE) - -/* - * This software FP implementation is only for GCC. - */ - -#define _CPU_Context_Fp_start( _base, _offset ) \ - ((void *) _Addresses_Add_offset( (_base), (_offset) ) ) - - -#define _CPU_Context_Initialize_fp( _fp_area ) \ - { \ - Context_Control_fp *_fp; \ - _fp = *(Context_Control_fp **)_fp_area; \ - _fp->_exception_bits = 0; \ - _fp->_trap_enable_bits = 0; \ - _fp->_sticky_bits = 0; \ - _fp->_rounding_mode = 0; /* ROUND_TO_NEAREST */ \ - _fp->_format = 0; /* NIL */ \ - _fp->_last_operation = 0; /* NOOP */ \ - _fp->_operand1.df = 0; \ - _fp->_operand2.df = 0; \ - } -#else -#define _CPU_Context_Fp_start( _base, _offset ) \ - ((void *) \ - _Addresses_Add_offset( \ - (_base), \ - (_offset) + CPU_CONTEXT_FP_SIZE - 4 \ - ) \ - ) - -#if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 )) -#define _CPU_Context_Initialize_fp( _fp_area ) \ - { uint32_t *_fp_context = (uint32_t *)*(_fp_area); \ - \ - *(--(_fp_context)) = 0; \ - *(_fp_area) = (void *)(_fp_context); \ - asm volatile("movl %0,%%macsr": : "d" (0) ); \ - } -#else -#define _CPU_Context_Initialize_fp( _fp_area ) \ - { uint32_t *_fp_context = (uint32_t *)*(_fp_area); \ - \ - *(--(_fp_context)) = 0; \ - *(_fp_area) = (void *)(_fp_context); \ - } -#endif -#endif - /* end of Context handler macros */ /* -- cgit v1.2.3