diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2007-09-07 11:34:36 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2007-09-07 11:34:36 +0200 |
commit | c664bb1b461cfee89b2e9b65c5fe827f3da40173 (patch) | |
tree | c3dbe04692829d5d6c7aa612624f074c72b9b5ae /libgfortran | |
parent | 7ab6a03bf54b50672cd941d781cfa087e305845e (diff) | |
download | gcc-c664bb1b461cfee89b2e9b65c5fe827f3da40173.zip gcc-c664bb1b461cfee89b2e9b65c5fe827f3da40173.tar.gz gcc-c664bb1b461cfee89b2e9b65c5fe827f3da40173.tar.bz2 |
fpu-387.h: Include cpuid.h.
* config/fpu-387.h: Include cpuid.h.
(set_fpu): Use __get_cpuid to check for SSE.
From-SVN: r128234
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 62 | ||||
-rw-r--r-- | libgfortran/config/fpu-387.h | 61 |
2 files changed, 60 insertions, 63 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 9fc369e..3042685 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,8 @@ +2007-09-07 Uros Bizjak <ubizjak@gmail.com> + + * config/fpu-387.h: Include cpuid.h. + (set_fpu): Use __get_cpuid to check for SSE. + 2007-09-06 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/33298 @@ -15,9 +20,9 @@ 2007-09-05 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/33253 - * io/write.c (nml_write_obj): Set the delimiter correctly before calling - write_character. (namelist_write): Clean up the code a little and add - comments to clarify what its doing. + * io/write.c (nml_write_obj): Set the delimiter correctly before + calling write_character. (namelist_write): Clean up the code a little + and add comments to clarify what its doing. 2007-09-04 Jerry DeLisle <jvdelisle@gcc.gnu.org> @@ -29,8 +34,8 @@ (output_float): Delete. (write_float): Delete. * io/write_float.def (calculate_sign): Added. (output_float): Refactored to be independent of kind and added to this - file for inclusion. (write_infnan): New function to write "Infinite" or - "NaN" depending on flags passed, independent of kind. + file for inclusion. (write_infnan): New function to write "Infinite" + or "NaN" depending on flags passed, independent of kind. (CALCULATE_EXP): New macro to build kind specific functions. Use it. (OUTPUT_FLOAT_FMT_G): New macro, likewise. Use it. (DTOA, DTOAL): Macros to implement "decimal to ascii". @@ -41,8 +46,8 @@ 2007-09-03 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/33253 - * io/list_read.c (read_character): Use DELIM_APOSTROPHE and DELIM_QUOTE - in check of first character in string. + * io/list_read.c (read_character): Use DELIM_APOSTROPHE and + DELIM_QUOTE in check of first character in string. 2007-09-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> @@ -503,8 +508,8 @@ (output_float): Delete. (write_float): Delete. * io/write_float.def (calculate_sign): Added. (output_float): Refactored to be independent of kind and added to this - file for inclusion. (write_infnan): New function to write "Infinite" or - "NaN" depending on flags passed, independent of kind. + file for inclusion. (write_infnan): New function to write "Infinite" + or "NaN" depending on flags passed, independent of kind. (CALCULATE_EXP): New macro to build kind specific functions. Use it. (OUTPUT_FLOAT_FMT_G): New macro, likewise. Use it. (DTOA, DTOAL): Macros to implement "decimal to ascii". @@ -934,7 +939,8 @@ 2007-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/32752 - * io/unix.c (unix_stream): Move buffer pointer adjacent to small_buffer. + * io/unix.c (unix_stream): Move buffer pointer adjacent to + small_buffer. * io/transfer.c (formatted_transfer_scalar): If stream I/O, set bytes_used to zero. Fix off by one error in calculation of pos and skips. Eliminate duplicate pending_spaces check. @@ -950,8 +956,8 @@ PR libgfortran/32702 * io/unix.c (unix_stream): Restore buffer pointer and small_buffer. (fd_alloc): If the number of bytes needed is greater than the default - BUFFER_SIZE, allocate a new buffer large enough. Free the old buffer if - necessary. (fd_sfree): Restore use of buffer pointer. + BUFFER_SIZE, allocate a new buffer large enough. Free the old buffer + if necessary. (fd_sfree): Restore use of buffer pointer. (fd_close): Likewise. (fd_open): Likewise. (init_error_stream): Likewise. @@ -973,8 +979,8 @@ 2007-07-08 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/32678 - * io/transfer.c (formatted_transfer_scalar): Don't allow pending_spaces - to go negative. + * io/transfer.c (formatted_transfer_scalar): Don't allow + pending_spaces to go negative. 2007-07-08 Thomas Koenig <tkoenig@gcc.gnu.org> @@ -1149,8 +1155,9 @@ 2007-05-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> - * io/transfer.c (unformatted_read): Use size from front end eliminating - use of size_from_real_kind. (unformatted_write): Ditto. + * io/transfer.c (unformatted_read): Use size from front end + eliminating use of size_from_real_kind. + (unformatted_write): Ditto. 2007-05-23 Steve Ellcey <sje@cup.hp.com> @@ -1227,8 +1234,8 @@ _gfortran_runtime_error_at. * libgfortran.h: Add comment to reference error codes in front end. (library_start): Locate prototype with library_end macro and add - a new comment. Add prototype for runtime_error_at. Export prototype for - generate_error. + a new comment. Add prototype for runtime_error_at. Export prototype + for generate_error. * io/lock.c (library_start): Fix check for error condition. * io/transfer.c (data_transfer_init): Add library check. @@ -1569,15 +1576,16 @@ 2007-03-27 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/31052 - * io/transfer.c (next_record_r): Do not call test_endfile if in namelist - mode. + * io/transfer.c (next_record_r): Do not call test_endfile if in + namelist mode. 2007-03-25 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/31199 * io/io.h: Add saved_pos to gfc_unit structure. * io/open.c (new_unit): Initialize saved_pos. - * io/transfer.c (data_transfer_init): Set max_pos to value in saved_pos. + * io/transfer.c (data_transfer_init): Set max_pos to value in + saved_pos. (next_record_w): Fix whitespace. (finalze_transfer): Calculate max_pos for ADVANCE="no" and save it for later use. If not ADVANCE="no" set saved_pos to zero. @@ -1592,8 +1600,8 @@ PR libfortran/31052 * file_pos.c: Update Copyright year. - * io/open.c (test_endfile): Restore test_endfile to fix SPEC regression. - Update Copyright year. + * io/open.c (test_endfile): Restore test_endfile to fix SPEC + regression. Update Copyright year. * io/io.h: Same. * io/unix.c (is_special): Add missing type for this function. Update Copyright year. @@ -1649,8 +1657,8 @@ 2007-03-14 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libfortran/31051 - * io/transfer.c (formatted_transfer_scalar): Adjust position for pending - spaces when in writing mode. Clean up some formatting. + * io/transfer.c (formatted_transfer_scalar): Adjust position for + pending spaces when in writing mode. Clean up some formatting. 2007-03-14 Thomas Koenig <Thomas.Koenig@online.de> @@ -2126,8 +2134,8 @@ s->file_length == -1. (fd_alloc_w_at): Do not adjust file_length if file is not seekable. (fd_seek): If not seekable, just return success. - (fd_truncate): If not seekable, no need to truncate. Return failure if - seek fails and the stream is not a pipe. + (fd_truncate): If not seekable, no need to truncate. Return failure + if seek fails and the stream is not a pipe. (fd_to_stream): Make test for non-seekable file more robust. 2007-01-01 Steven G. Kargl <kargls@comcast.net> diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index cc2ef4f..f96f715 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -28,79 +28,68 @@ License along with libgfortran; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define SSE (1 << 25) +#ifndef __x86_64__ +#include "cpuid.h" +#endif static int has_sse (void) { -#ifdef __x86_64__ - return 1; -#else +#ifndef __x86_64__ unsigned int eax, ebx, ecx, edx; - /* See if we can use cpuid. */ - asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" - "pushl %0; popfl; pushfl; popl %0; popfl" - : "=&r" (eax), "=&r" (ebx) - : "i" (0x00200000)); - - if (((eax ^ ebx) & 0x00200000) == 0) - return 0; - - /* Check the highest input value for eax. */ - asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" - : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0)); - - if (eax == 0) + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; - asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" - : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) - : "0" (1)); - - if (edx & SSE) - return 1; - - return 0; + return edx & bit_SSE; +#else + return 1; #endif } -void set_fpu (void) -{ - unsigned short cw; - unsigned int cw_sse; - - /* i387 -- see linux <fpu_control.h> header file for details. */ +/* i387 -- see linux <fpu_control.h> header file for details. */ #define _FPU_MASK_IM 0x01 #define _FPU_MASK_DM 0x02 #define _FPU_MASK_ZM 0x04 #define _FPU_MASK_OM 0x08 #define _FPU_MASK_UM 0x10 #define _FPU_MASK_PM 0x20 + +void set_fpu (void) +{ + unsigned short cw; + asm volatile ("fnstcw %0" : "=m" (cw)); - cw |= _FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_PM; + + cw |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM + | _FPU_MASK_UM | _FPU_MASK_PM); + if (options.fpe & GFC_FPE_INVALID) cw &= ~_FPU_MASK_IM; if (options.fpe & GFC_FPE_DENORMAL) cw &= ~_FPU_MASK_DM; if (options.fpe & GFC_FPE_ZERO) cw &= ~_FPU_MASK_ZM; if (options.fpe & GFC_FPE_OVERFLOW) cw &= ~_FPU_MASK_OM; if (options.fpe & GFC_FPE_UNDERFLOW) cw &= ~_FPU_MASK_UM; if (options.fpe & GFC_FPE_PRECISION) cw &= ~_FPU_MASK_PM; + asm volatile ("fldcw %0" : : "m" (cw)); if (has_sse()) { - /* SSE */ + unsigned int cw_sse; + asm volatile ("stmxcsr %0" : "=m" (cw_sse)); - cw_sse &= 0xFFFF0000; + + cw_sse &= 0xffff0000; cw_sse |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_PM ) << 7; + if (options.fpe & GFC_FPE_INVALID) cw_sse &= ~(_FPU_MASK_IM << 7); if (options.fpe & GFC_FPE_DENORMAL) cw_sse &= ~(_FPU_MASK_DM << 7); if (options.fpe & GFC_FPE_ZERO) cw_sse &= ~(_FPU_MASK_ZM << 7); if (options.fpe & GFC_FPE_OVERFLOW) cw_sse &= ~(_FPU_MASK_OM << 7); if (options.fpe & GFC_FPE_UNDERFLOW) cw_sse &= ~(_FPU_MASK_UM << 7); if (options.fpe & GFC_FPE_PRECISION) cw_sse &= ~(_FPU_MASK_PM << 7); + asm volatile ("ldmxcsr %0" : : "m" (cw_sse)); } } |