From 00d2a828971594d3c3407ae1ee064e32e256c95c Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 28 May 1997 20:36:35 +0000 Subject: Added support for context switching the data used by the gcc m68k software floating point emulation code. Code implemented by Karen Sara Looney with much email assistance from Joel. --- c/src/exec/rtems/headers/attr.h | 2 +- c/src/exec/rtems/include/rtems/rtems/attr.h | 2 +- c/src/exec/score/cpu/m68k/cpu.c | 29 ++++++++++++ c/src/exec/score/cpu/m68k/cpu.h | 72 +++++++++++++++++++++++++++++ c/src/exec/score/cpu/m68k/cpu_asm.s | 7 +++ c/src/exec/score/src/thread.c | 2 +- cpukit/rtems/include/rtems/rtems/attr.h | 2 +- cpukit/score/cpu/m68k/cpu.c | 29 ++++++++++++ cpukit/score/src/thread.c | 2 +- 9 files changed, 142 insertions(+), 5 deletions(-) diff --git a/c/src/exec/rtems/headers/attr.h b/c/src/exec/rtems/headers/attr.h index cada11dbad..84f79f636f 100644 --- a/c/src/exec/rtems/headers/attr.h +++ b/c/src/exec/rtems/headers/attr.h @@ -47,7 +47,7 @@ typedef unsigned32 rtems_attribute; #define RTEMS_NO_PRIORITY_CEILING 0x00000000 #define RTEMS_PRIORITY_CEILING 0x00000040 -#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #define ATTRIBUTES_NOT_SUPPORTED 0 #else #define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT diff --git a/c/src/exec/rtems/include/rtems/rtems/attr.h b/c/src/exec/rtems/include/rtems/rtems/attr.h index cada11dbad..84f79f636f 100644 --- a/c/src/exec/rtems/include/rtems/rtems/attr.h +++ b/c/src/exec/rtems/include/rtems/rtems/attr.h @@ -47,7 +47,7 @@ typedef unsigned32 rtems_attribute; #define RTEMS_NO_PRIORITY_CEILING 0x00000000 #define RTEMS_PRIORITY_CEILING 0x00000040 -#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #define ATTRIBUTES_NOT_SUPPORTED 0 #else #define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT diff --git a/c/src/exec/score/cpu/m68k/cpu.c b/c/src/exec/score/cpu/m68k/cpu.c index 01fbabd957..afbac7f813 100644 --- a/c/src/exec/score/cpu/m68k/cpu.c +++ b/c/src/exec/score/cpu/m68k/cpu.c @@ -177,3 +177,32 @@ const unsigned char __BFFFOtable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #endif + +/*PAGE + * + * The following code context switches the software FPU emulation + * code provided with GCC. + */ + +#if (CPU_SOFTWARE_FP == TRUE) +extern Context_Control_fp _fpCCR; + +void CPU_Context_save_fp (void **fp_context_ptr) +{ + Context_Control_fp *fp; + + fp = (Context_Control_fp *) *fp_context_ptr; + + *fp = _fpCCR; +} + +void CPU_Context_restore_fp (void **fp_context_ptr) +{ + Context_Control_fp *fp; + + fp = (Context_Control_fp *) *fp_context_ptr; + + _fpCCR = *fp; +} +#endif + diff --git a/c/src/exec/score/cpu/m68k/cpu.h b/c/src/exec/score/cpu/m68k/cpu.h index bc83bf3138..46500e90f1 100644 --- a/c/src/exec/score/cpu/m68k/cpu.h +++ b/c/src/exec/score/cpu/m68k/cpu.h @@ -52,12 +52,22 @@ extern "C" { /* * Some family members have no FP, some have an FPU such as the * MC68881/MC68882 for the MC68020, others have it built in (MC68030, 040). + * + * NOTE: If on a CPU without hardware FP, then one can use software + * emulation. The gcc software FP emulation code has data which + * 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(__GCC__) +#define CPU_SOFTWARE_FP TRUE +#else +#define CPU_SOFTWARE_FP FALSE +#endif #endif /* @@ -107,6 +117,38 @@ typedef struct { void *a7_msp; /* (a7) master stack pointer */ } Context_Control; +/* + * 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 { + unsigned16 _exception_bits; + unsigned16 _trap_enable_bits; + unsigned16 _sticky_bits; + unsigned16 _rounding_mode; + unsigned16 _format; + unsigned16 _last_operation; + union { + float sf; + double df; + } _operand1; + union { + float sf; + double df; + } _operand2; +} Context_Control_fp; + +#else + /* * FP context save area for the M68881/M68882 numeric coprocessors. */ @@ -117,6 +159,7 @@ typedef struct { /* 12 bytes for FMOVEM CREGS */ /* 4 bytes for non-null flag */ } Context_Control_fp; +#endif /* * The following structure defines the set of information saved @@ -291,6 +334,34 @@ unsigned32 _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( \ @@ -305,6 +376,7 @@ unsigned32 _CPU_ISR_Get_level( void ); *(--(_fp_context)) = 0; \ *(_fp_area) = (unsigned8 *)(_fp_context); \ } +#endif /* end of Context handler macros */ diff --git a/c/src/exec/score/cpu/m68k/cpu_asm.s b/c/src/exec/score/cpu/m68k/cpu_asm.s index 4b203a8991..b288c9f2bb 100644 --- a/c/src/exec/score/cpu/m68k/cpu_asm.s +++ b/c/src/exec/score/cpu/m68k/cpu_asm.s @@ -51,8 +51,14 @@ restore: movml a0@,d1-d7/a2-a7 | restore context * * CPU_FP_CONTEXT_SIZE is higher than expected to account for the * -1 pushed at end of this sequence. + * + * Neither of these entries is required if we have software FPU + * emulation. But if we don't have an FPU or emulation, then + * we need the stub versions of these routines. */ +#if (CPU_SOFTWARE_FP == FALSE) + .set FPCONTEXT_ARG, 4 | save FP context argument .align 4 @@ -86,6 +92,7 @@ norst: frestore a0@+ | restore the fp state frame movl a0,a1@ | save pointer to saved context #endif rts +#endif /*PAGE * void _ISR_Handler() diff --git a/c/src/exec/score/src/thread.c b/c/src/exec/score/src/thread.c index e4a3614a53..b63ad619bd 100644 --- a/c/src/exec/score/src/thread.c +++ b/c/src/exec/score/src/thread.c @@ -212,7 +212,7 @@ void _Thread_Start_multitasking( void ) */ -#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) /* * don't need to worry about saving BSP's floating point state */ diff --git a/cpukit/rtems/include/rtems/rtems/attr.h b/cpukit/rtems/include/rtems/rtems/attr.h index cada11dbad..84f79f636f 100644 --- a/cpukit/rtems/include/rtems/rtems/attr.h +++ b/cpukit/rtems/include/rtems/rtems/attr.h @@ -47,7 +47,7 @@ typedef unsigned32 rtems_attribute; #define RTEMS_NO_PRIORITY_CEILING 0x00000000 #define RTEMS_PRIORITY_CEILING 0x00000040 -#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) #define ATTRIBUTES_NOT_SUPPORTED 0 #else #define ATTRIBUTES_NOT_SUPPORTED RTEMS_FLOATING_POINT diff --git a/cpukit/score/cpu/m68k/cpu.c b/cpukit/score/cpu/m68k/cpu.c index 01fbabd957..afbac7f813 100644 --- a/cpukit/score/cpu/m68k/cpu.c +++ b/cpukit/score/cpu/m68k/cpu.c @@ -177,3 +177,32 @@ const unsigned char __BFFFOtable[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #endif + +/*PAGE + * + * The following code context switches the software FPU emulation + * code provided with GCC. + */ + +#if (CPU_SOFTWARE_FP == TRUE) +extern Context_Control_fp _fpCCR; + +void CPU_Context_save_fp (void **fp_context_ptr) +{ + Context_Control_fp *fp; + + fp = (Context_Control_fp *) *fp_context_ptr; + + *fp = _fpCCR; +} + +void CPU_Context_restore_fp (void **fp_context_ptr) +{ + Context_Control_fp *fp; + + fp = (Context_Control_fp *) *fp_context_ptr; + + _fpCCR = *fp; +} +#endif + diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index e4a3614a53..b63ad619bd 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -212,7 +212,7 @@ void _Thread_Start_multitasking( void ) */ -#if ( CPU_HARDWARE_FP == TRUE ) +#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) /* * don't need to worry about saving BSP's floating point state */ -- cgit v1.2.3