📄 float.c
字号:
/* * This file is part of SIS. * * SIS, SPARC instruction simulator. Copyright (C) 1995 Jiri Gaisler, European * Space Agency * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 675 * Mass Ave, Cambridge, MA 02139, USA. * * * This file implements the interface between the host and the simulated * FPU. IEEE trap handling is done as follows: * 1. In the host, all IEEE traps are masked * 2. After each simulated FPU instruction, check if any exception occured * by reading the exception bits from the host FPU status register * (get_accex()). * 3. Propagate any exceptions to the simulated FSR. * 4. Clear host exception bits * * * This can also be done using ieee_flags() library routine on sun. */#include "sis.h"/* Forward declarations */extern uint32 _get_sw PARAMS ((void));extern uint32 _get_cw PARAMS ((void));static void __setfpucw PARAMS ((unsigned short fpu_control));/* This host dependent routine should return the accrued exceptions */intget_accex(){#ifdef sparc return ((_get_fsr_raw() >> 5) & 0x1F);#elif i386 uint32 accx; accx = _get_sw() & 0x3f; accx = ((accx & 1) << 4) | ((accx & 2) >> 1) | ((accx & 4) >> 1) | (accx & 8) | ((accx & 16) >> 2) | ((accx & 32) >> 5); return(accx);#else return(0);#warning no fpu trap support for this target#endif}/* How to clear the accrued exceptions */voidclear_accex(){#ifdef sparc set_fsr((_get_fsr_raw() & ~0x3e0));#elif i386 asm("\n"".text\n"" fnclex\n""\n"" ");#else#warning no fpu trap support for this target#endif}/* How to map SPARC FSR onto the host */voidset_fsr(fsr)uint32 fsr;{#ifdef sparc _set_fsr_raw(fsr & ~0x0f800000);#elif i386 void __setfpucw(unsigned short fpu_control); uint32 rawfsr; fsr >>= 30; switch (fsr) { case 0: case 2: break; case 1: fsr = 3; case 3: fsr = 1; } rawfsr = _get_cw(); rawfsr |= (fsr << 10) | 0x3ff; __setfpucw(rawfsr);#else#warning no fpu trap support for this target#endif}/* Host dependent support functions */#ifdef sparc asm("\n""\n"".text\n"" .align 4\n"" .global __set_fsr_raw,_set_fsr_raw\n""__set_fsr_raw:\n""_set_fsr_raw:\n"" save %sp,-104,%sp\n"" st %i0,[%fp+68]\n"" ld [%fp+68], %fsr\n"" mov 0,%i0\n"" ret\n"" restore\n""\n"" .align 4\n"" .global __get_fsr_raw\n"" .global _get_fsr_raw\n""__get_fsr_raw:\n""_get_fsr_raw:\n"" save %sp,-104,%sp\n"" st %fsr,[%fp+68]\n"" ld [%fp+68], %i0\n"" ret\n"" restore\n""\n"" ");#elif i386 asm("\n""\n"".text\n"" .align 8\n"".globl _get_sw,__get_sw\n""__get_sw:\n""_get_sw:\n"" pushl %ebp\n"" movl %esp,%ebp\n"" movl $0,%eax\n"" fnstsw %ax\n"" movl %ebp,%esp\n"" popl %ebp\n"" ret\n""\n"" .align 8\n"".globl _get_cw,__get_cw\n""__get_cw:\n""_get_cw:\n"" pushl %ebp\n"" movl %esp,%ebp\n"" subw $2,%esp\n"" fnstcw -2(%ebp)\n"" movw -2(%ebp),%eax\n"" movl %ebp,%esp\n"" popl %ebp\n"" ret\n""\n""\n"" ");#else#warning no fpu trap support for this target#endif#if i386/* #if defined _WIN32 || defined __GO32__ *//* This is so floating exception handling works on NT These definitions are from the linux fpu_control.h, which doesn't exist on NT. default to: - extended precision - rounding to nearest - exceptions on overflow, zero divide and NaN*/#define _FPU_DEFAULT 0x1372 #define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */static void__setfpucw(unsigned short fpu_control){ volatile unsigned short cw; /* If user supplied _fpu_control, use it ! */ if (!fpu_control) { /* use defaults */ fpu_control = _FPU_DEFAULT; } /* Get Control Word */ __asm__ volatile ("fnstcw %0" : "=m" (cw) : ); /* mask in */ cw &= _FPU_RESERVED; cw = cw | (fpu_control & ~_FPU_RESERVED); /* set cw */ __asm__ volatile ("fldcw %0" :: "m" (cw));}/* #endif */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -