1212397c6Schristos /* This file is part of SIS (SPARC instruction simulator) 2212397c6Schristos 3*1f4e7eb9Schristos Copyright (C) 1995-2024 Free Software Foundation, Inc. 4212397c6Schristos Contributed by Jiri Gaisler, European Space Agency 5212397c6Schristos 6212397c6Schristos This program is free software; you can redistribute it and/or modify 7212397c6Schristos it under the terms of the GNU General Public License as published by 8212397c6Schristos the Free Software Foundation; either version 3 of the License, or 9212397c6Schristos (at your option) any later version. 10212397c6Schristos 11212397c6Schristos This program is distributed in the hope that it will be useful, 12212397c6Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 13212397c6Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14212397c6Schristos GNU General Public License for more details. 15212397c6Schristos 16212397c6Schristos You should have received a copy of the GNU General Public License 17212397c6Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18212397c6Schristos 19212397c6Schristos /* This file implements the interface between the host and the simulated 20212397c6Schristos FPU. IEEE trap handling is done as follows: 21212397c6Schristos 1. In the host, all IEEE traps are masked 22212397c6Schristos 2. After each simulated FPU instruction, check if any exception 23212397c6Schristos occured by reading the exception bits from the host FPU status 24212397c6Schristos register (get_accex()). 25212397c6Schristos 3. Propagate any exceptions to the simulated FSR. 26212397c6Schristos 4. Clear host exception bits. 274e98e3e1Schristos */ 284e98e3e1Schristos 294b169a6bSchristos /* This must come before any other includes. */ 304b169a6bSchristos #include "defs.h" 314b169a6bSchristos 324e98e3e1Schristos #include "sis.h" 33212397c6Schristos #include <fenv.h> 344e98e3e1Schristos 35212397c6Schristos /* This routine should return the accrued exceptions */ 364e98e3e1Schristos int 374b169a6bSchristos get_accex(void) 384e98e3e1Schristos { 39212397c6Schristos int fexc, accx; 404e98e3e1Schristos 41212397c6Schristos fexc = fetestexcept (FE_ALL_EXCEPT); 42212397c6Schristos accx = 0; 43212397c6Schristos if (fexc & FE_INEXACT) 44212397c6Schristos accx |= 1; 45212397c6Schristos if (fexc & FE_DIVBYZERO) 46212397c6Schristos accx |= 2; 47212397c6Schristos if (fexc & FE_UNDERFLOW) 48212397c6Schristos accx |= 4; 49212397c6Schristos if (fexc & FE_OVERFLOW) 50212397c6Schristos accx |= 8; 51212397c6Schristos if (fexc & FE_INVALID) 52212397c6Schristos accx |= 0x10; 53212397c6Schristos return accx; 544e98e3e1Schristos } 554e98e3e1Schristos 564e98e3e1Schristos /* How to clear the accrued exceptions */ 574e98e3e1Schristos void 584b169a6bSchristos clear_accex(void) 594e98e3e1Schristos { 60212397c6Schristos feclearexcept (FE_ALL_EXCEPT); 614e98e3e1Schristos } 624e98e3e1Schristos 634e98e3e1Schristos /* How to map SPARC FSR onto the host */ 644e98e3e1Schristos void 654b169a6bSchristos set_fsr(uint32_t fsr) 664e98e3e1Schristos { 67212397c6Schristos int fround; 684e98e3e1Schristos 694e98e3e1Schristos fsr >>= 30; 704e98e3e1Schristos switch (fsr) { 714e98e3e1Schristos case 0: 72212397c6Schristos fround = FE_TONEAREST; 7303467a24Schristos break; 7403467a24Schristos case 1: 75212397c6Schristos fround = FE_TOWARDZERO; 7603467a24Schristos break; 77212397c6Schristos case 2: 78212397c6Schristos fround = FE_UPWARD; 79212397c6Schristos break; 8003467a24Schristos case 3: 81212397c6Schristos fround = FE_DOWNWARD; 8203467a24Schristos break; 834e98e3e1Schristos } 84212397c6Schristos fesetround (fround); 854e98e3e1Schristos } 86