From 7a03376c1bd0fc0d5008d3222c623601e7080b43 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sat, 19 Aug 2023 11:25:27 +0100 Subject: [PATCH 1/3] cpu: Allow FPCSR to be read/written in user mode As per spec update 1.4 we allow FPCSR to be read and written in user mode. This allows user mode programs to use the FPU as intended in a POSIX environment like gnu libc. --- cpu/or32/insnset.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpu/or32/insnset.c b/cpu/or32/insnset.c index 35c096c..4b29b73 100755 --- a/cpu/or32/insnset.c +++ b/cpu/or32/insnset.c @@ -904,7 +904,8 @@ INSTRUCTION (l_mtspr) { uint16_t regno = PARAM0 | PARAM2; uorreg_t value = PARAM1; - if (cpu_state.sprs[SPR_SR] & SPR_SR_SM) + if ((regno == SPR_FPCSR) || + (cpu_state.sprs[SPR_SR] & SPR_SR_SM)) mtspr(regno, value); else { PRINTF("WARNING: trying to write SPR while SR[SUPV] is cleared.\n"); @@ -915,10 +916,11 @@ INSTRUCTION (l_mfspr) { uint16_t regno = PARAM1 | PARAM2; uorreg_t value = mfspr(regno); - if ((cpu_state.sprs[SPR_SR] & SPR_SR_SM) || + if ((regno == SPR_FPCSR) || + (cpu_state.sprs[SPR_SR] & SPR_SR_SM) || // TODO: Check if this SPR should actually be allowed to be read with // SR's SM==0 and SUMRA==1 - (!(cpu_state.sprs[SPR_SR] & SPR_SR_SM) && + (!(cpu_state.sprs[SPR_SR] & SPR_SR_SM) && (cpu_state.sprs[SPR_SR] & SPR_SR_SUMRA))) SET_PARAM0(value); else From 52cbe3897c74efa1bd0d49ac18078ada25010449 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sat, 19 Aug 2023 11:24:12 +0100 Subject: [PATCH 2/3] testsuite/test-code-or1k: Rename excpt_break to excpt_fpu Preparing to make some FPU exception tests, the old excpt_break vector is incorrectly named to fix the name can call it excpt_fpu. --- testsuite/test-code-or1k/except-test/except-test-s.S | 8 ++++---- testsuite/test-code-or1k/except-test/except-test.c | 2 +- testsuite/test-code-or1k/except/except.S | 8 ++++---- testsuite/test-code-or1k/mc-common/except-mc.S | 8 ++++---- testsuite/test-code-or1k/support/support.c | 2 +- testsuite/test-code-or1k/support/support.h | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/testsuite/test-code-or1k/except-test/except-test-s.S b/testsuite/test-code-or1k/except-test/except-test-s.S index 7e22592..cc062f8 100644 --- a/testsuite/test-code-or1k/except-test/except-test-s.S +++ b/testsuite/test-code-or1k/except-test/except-test-s.S @@ -66,7 +66,7 @@ stack: .extern excpt_itlbmiss .extern excpt_range .extern excpt_syscall - .extern excpt_break + .extern excpt_fpu .extern excpt_trap /* Our special text section is used to guarantee this code goes first @@ -334,14 +334,14 @@ syscall_vector: l.addi r3,r3,8 .org 0xd00 -break_vector: +fpu_vector: l.addi r1,r1,-120 l.sw 0x1c(r1),r9 l.sw 0x20(r1),r10 l.movhi r9,hi(store_regs) l.ori r9,r9,lo(store_regs) - l.movhi r10,hi(excpt_break) - l.ori r10,r10,lo(excpt_break) + l.movhi r10,hi(excpt_fpu) + l.ori r10,r10,lo(excpt_fpu) l.jr r9 l.nop l.nop diff --git a/testsuite/test-code-or1k/except-test/except-test.c b/testsuite/test-code-or1k/except-test/except-test.c index 71e6669..25aa2d6 100644 --- a/testsuite/test-code-or1k/except-test/except-test.c +++ b/testsuite/test-code-or1k/except-test/except-test.c @@ -143,7 +143,7 @@ extern unsigned long excpt_dtlbmiss; extern unsigned long excpt_itlbmiss; extern unsigned long excpt_range; extern unsigned long excpt_syscall; -extern unsigned long excpt_break; +extern unsigned long excpt_fpu; extern unsigned long excpt_trap; diff --git a/testsuite/test-code-or1k/except/except.S b/testsuite/test-code-or1k/except/except.S index 2eeed76..10abcad 100644 --- a/testsuite/test-code-or1k/except/except.S +++ b/testsuite/test-code-or1k/except/except.S @@ -51,7 +51,7 @@ stack: .extern excpt_itlbmiss .extern excpt_range .extern excpt_syscall - .extern excpt_break + .extern excpt_fpu .extern excpt_trap .section .except,"ax" @@ -235,15 +235,15 @@ syscall_vector: OR1K_DELAYED_NOP(OR1K_INST(l.jr r10)) .org 0xd00 -break_vector: +fpu_vector: l.addi r1,r1,-EXCEPT_STACK_SIZE l.sw 0x18(r1),r9 OR1K_DELAYED_NOP(OR1K_INST(l.jal store_regs)) l.nop l.movhi r9,hi(end_except) l.ori r9,r9,lo(end_except) - l.movhi r10,hi(excpt_break) - l.ori r10,r10,lo(excpt_break) + l.movhi r10,hi(excpt_fpu) + l.ori r10,r10,lo(excpt_fpu) l.lwz r10,0(r10) OR1K_DELAYED_NOP(OR1K_INST(l.jr r10)) diff --git a/testsuite/test-code-or1k/mc-common/except-mc.S b/testsuite/test-code-or1k/mc-common/except-mc.S index 7ad98f5..db03beb 100644 --- a/testsuite/test-code-or1k/mc-common/except-mc.S +++ b/testsuite/test-code-or1k/mc-common/except-mc.S @@ -48,7 +48,7 @@ stack: .extern excpt_itlbmiss .extern excpt_range .extern excpt_syscall - .extern excpt_break + .extern excpt_fpu .extern excpt_trap .section .except,"ax" @@ -264,14 +264,14 @@ syscall_vector: OR1K_DELAYED_NOP(OR1K_INST(l.jr r10)) .org 0xd00 -break_vector: +fpu_vector: l.addi r1,r1,-116 l.sw 0x18(r1),r9 OR1K_DELAYED_NOP(OR1K_INST(l.jal store_regs)) l.movhi r9,hi(end_except) l.ori r9,r9,lo(end_except) - l.movhi r10,hi(excpt_break) - l.ori r10,r10,lo(excpt_break) + l.movhi r10,hi(excpt_fpu) + l.ori r10,r10,lo(excpt_fpu) l.lwz r10,0(r10) OR1K_DELAYED_NOP(OR1K_INST(l.jr r10)) diff --git a/testsuite/test-code-or1k/support/support.c b/testsuite/test-code-or1k/support/support.c index 29b2b97..7535a3a 100644 --- a/testsuite/test-code-or1k/support/support.c +++ b/testsuite/test-code-or1k/support/support.c @@ -48,7 +48,7 @@ unsigned long excpt_dtlbmiss = (unsigned long) excpt_dummy; unsigned long excpt_itlbmiss = (unsigned long) excpt_dummy; unsigned long excpt_range = (unsigned long) excpt_dummy; unsigned long excpt_syscall = (unsigned long) excpt_dummy; -unsigned long excpt_break = (unsigned long) excpt_dummy; +unsigned long excpt_fpu = (unsigned long) excpt_dummy; unsigned long excpt_trap = (unsigned long) excpt_dummy; diff --git a/testsuite/test-code-or1k/support/support.h b/testsuite/test-code-or1k/support/support.h index 62affd6..83626e0 100644 --- a/testsuite/test-code-or1k/support/support.h +++ b/testsuite/test-code-or1k/support/support.h @@ -90,7 +90,7 @@ extern unsigned long int excpt_dtlbmiss; extern unsigned long int excpt_itlbmiss; extern unsigned long int excpt_range; extern unsigned long int excpt_syscall; -extern unsigned long int excpt_break; +extern unsigned long int excpt_fpu; extern unsigned long int excpt_trap; #endif From c6ff9558d114cf1c245dd8b96799d22eeda6f11e Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Sat, 19 Aug 2023 11:28:03 +0100 Subject: [PATCH 3/3] testsuite/test-code-or1k: Test exceptions and usermode FPCSR read/write A test is added to allow testing that FPCSR can be read and written in user mode. This include writing the FPEE bit to enable exceptions. --- testsuite/or1ksim.tests/Makefile.am | 1 + testsuite/or1ksim.tests/Makefile.in | 1 + testsuite/or1ksim.tests/fpee.exp | 40 ++ testsuite/test-code-or1k/Makefile.am | 1 + testsuite/test-code-or1k/Makefile.in | 1 + testsuite/test-code-or1k/configure | 3 +- testsuite/test-code-or1k/configure.ac | 1 + testsuite/test-code-or1k/fpee/Makefile.am | 34 ++ testsuite/test-code-or1k/fpee/Makefile.in | 628 ++++++++++++++++++++++ testsuite/test-code-or1k/fpee/fpee.c | 117 ++++ 10 files changed, 826 insertions(+), 1 deletion(-) create mode 100644 testsuite/or1ksim.tests/fpee.exp create mode 100644 testsuite/test-code-or1k/fpee/Makefile.am create mode 100644 testsuite/test-code-or1k/fpee/Makefile.in create mode 100644 testsuite/test-code-or1k/fpee/fpee.c diff --git a/testsuite/or1ksim.tests/Makefile.am b/testsuite/or1ksim.tests/Makefile.am index 82608f0..5adb752 100644 --- a/testsuite/or1ksim.tests/Makefile.am +++ b/testsuite/or1ksim.tests/Makefile.am @@ -52,6 +52,7 @@ EXTRA_DIST = cfg/or1k/acv-gpio.cfg \ cfg/or1k/fp.cfg \ cfg/or1knd/fp.cfg \ fp.exp \ + fpee.exp \ functest.exp \ int-test.exp \ cfg/or1k/inst-set-test.cfg \ diff --git a/testsuite/or1ksim.tests/Makefile.in b/testsuite/or1ksim.tests/Makefile.in index ab3724b..8dd9e1a 100644 --- a/testsuite/or1ksim.tests/Makefile.in +++ b/testsuite/or1ksim.tests/Makefile.in @@ -317,6 +317,7 @@ EXTRA_DIST = cfg/or1k/acv-gpio.cfg \ cfg/or1k/fp.cfg \ cfg/or1knd/fp.cfg \ fp.exp \ + fpee.exp \ functest.exp \ int-test.exp \ cfg/or1k/inst-set-test.cfg \ diff --git a/testsuite/or1ksim.tests/fpee.exp b/testsuite/or1ksim.tests/fpee.exp new file mode 100644 index 0000000..138b4ef --- /dev/null +++ b/testsuite/or1ksim.tests/fpee.exp @@ -0,0 +1,40 @@ +# fpee.exp. Floating point exception DejaGNU tests + +# Copyright (C) 2023 OpenRISC Developers + +# Contributor Stafford Horne + +# This file is part of OpenRISC 1000 Architectural Simulator. + +# 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 3 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, see . */ + +# ----------------------------------------------------------------------------- +# This code is commented throughout for use with Doxygen. +# ----------------------------------------------------------------------------- + + +# Run the floating point test +run_or1ksim "fpee" \ + [list "Switching to User Mode" \ + "Enabling FPU Exceptions" \ + "Exceptions enabled, now DIV 3.14 / 0" \ + "Got fpe: " \ + "report(0x7f800000);" \ + "report(0x00000801);" \ + "One more, now MUL 3.14 * MAX" \ + "Got fpe: " \ + "report(0x7f800000);" \ + "report(0x00000109);" \ + "exit(0)"] \ + "fp.cfg" "fpee/fpee" diff --git a/testsuite/test-code-or1k/Makefile.am b/testsuite/test-code-or1k/Makefile.am index b2b5d87..d14af71 100644 --- a/testsuite/test-code-or1k/Makefile.am +++ b/testsuite/test-code-or1k/Makefile.am @@ -55,6 +55,7 @@ SUBDIRS = support \ ext \ fbtest \ fp \ + fpee \ testfloat \ functest \ flag \ diff --git a/testsuite/test-code-or1k/Makefile.in b/testsuite/test-code-or1k/Makefile.in index 1865610..cbfec1a 100644 --- a/testsuite/test-code-or1k/Makefile.in +++ b/testsuite/test-code-or1k/Makefile.in @@ -386,6 +386,7 @@ SUBDIRS = support \ ext \ fbtest \ fp \ + fpee \ testfloat \ functest \ flag \ diff --git a/testsuite/test-code-or1k/configure b/testsuite/test-code-or1k/configure index 14444d7..a25ad9c 100755 --- a/testsuite/test-code-or1k/configure +++ b/testsuite/test-code-or1k/configure @@ -13246,7 +13246,7 @@ printf "%s\n" "#define SIZEOF_INT 4" >>confdefs.h printf "%s\n" "#define SIZEOF_LONG 4" >>confdefs.h -ac_config_files="$ac_config_files Makefile acv-gpio/Makefile acv-uart/Makefile atomic/Makefile basic/Makefile cache/Makefile cbasic/Makefile cfg/Makefile dhry/Makefile dmatest/Makefile eth/Makefile except/Makefile except-test/Makefile exit/Makefile ext/Makefile fbtest/Makefile fp/Makefile testfloat/Makefile functest/Makefile flag/Makefile int-test/Makefile int-logger/Makefile inst-set-test/Makefile kbdtest/Makefile local-global/Makefile loop/Makefile mc-async/Makefile mc-dram/Makefile mc-ssram/Makefile mc-sync/Makefile mc-common/Makefile mem-test/Makefile mmu/Makefile mul/Makefile mycompress/Makefile support/Makefile tick/Makefile uos/Makefile upcalls/Makefile pcu/Makefile" +ac_config_files="$ac_config_files Makefile acv-gpio/Makefile acv-uart/Makefile atomic/Makefile basic/Makefile cache/Makefile cbasic/Makefile cfg/Makefile dhry/Makefile dmatest/Makefile eth/Makefile except/Makefile except-test/Makefile exit/Makefile ext/Makefile fbtest/Makefile fp/Makefile fpee/Makefile testfloat/Makefile functest/Makefile flag/Makefile int-test/Makefile int-logger/Makefile inst-set-test/Makefile kbdtest/Makefile local-global/Makefile loop/Makefile mc-async/Makefile mc-dram/Makefile mc-ssram/Makefile mc-sync/Makefile mc-common/Makefile mem-test/Makefile mmu/Makefile mul/Makefile mycompress/Makefile support/Makefile tick/Makefile uos/Makefile upcalls/Makefile pcu/Makefile" cat >confcache <<\_ACEOF @@ -14282,6 +14282,7 @@ do "ext/Makefile") CONFIG_FILES="$CONFIG_FILES ext/Makefile" ;; "fbtest/Makefile") CONFIG_FILES="$CONFIG_FILES fbtest/Makefile" ;; "fp/Makefile") CONFIG_FILES="$CONFIG_FILES fp/Makefile" ;; + "fpee/Makefile") CONFIG_FILES="$CONFIG_FILES fpee/Makefile" ;; "testfloat/Makefile") CONFIG_FILES="$CONFIG_FILES testfloat/Makefile" ;; "functest/Makefile") CONFIG_FILES="$CONFIG_FILES functest/Makefile" ;; "flag/Makefile") CONFIG_FILES="$CONFIG_FILES flag/Makefile" ;; diff --git a/testsuite/test-code-or1k/configure.ac b/testsuite/test-code-or1k/configure.ac index b5c7c9a..662124c 100644 --- a/testsuite/test-code-or1k/configure.ac +++ b/testsuite/test-code-or1k/configure.ac @@ -148,6 +148,7 @@ AC_CONFIG_FILES([Makefile \ ext/Makefile \ fbtest/Makefile \ fp/Makefile \ + fpee/Makefile \ testfloat/Makefile \ functest/Makefile \ flag/Makefile \ diff --git a/testsuite/test-code-or1k/fpee/Makefile.am b/testsuite/test-code-or1k/fpee/Makefile.am new file mode 100644 index 0000000..6417090 --- /dev/null +++ b/testsuite/test-code-or1k/fpee/Makefile.am @@ -0,0 +1,34 @@ +# Makefile.am for or1ksim testsuite CPU test program: fpee + +# Copyright (C) OpenRISC Developers, 2023 + +# Contributor Stafford Horne + +# This file is part of OpenRISC 1000 Architectural Simulator. + +# 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 3 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, see . */ + +# ----------------------------------------------------------------------------- +# This code is commented throughout for use with Doxygen. +# ----------------------------------------------------------------------------- + +# A test program of the floating point exceptions test +check_PROGRAMS = fpee + +fpee_SOURCES = fpee.c + +fpee_LDFLAGS = -T$(srcdir)/../default.ld + +fpee_LDADD = ../except/except.lo \ + ../support/libsupport.la diff --git a/testsuite/test-code-or1k/fpee/Makefile.in b/testsuite/test-code-or1k/fpee/Makefile.in new file mode 100644 index 0000000..c6e631f --- /dev/null +++ b/testsuite/test-code-or1k/fpee/Makefile.in @@ -0,0 +1,628 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile.am for or1ksim testsuite CPU test program: fpee + +# Copyright (C) OpenRISC Developers, 2023 + +# Contributor Stafford Horne + +# This file is part of OpenRISC 1000 Architectural Simulator. + +# 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 3 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, see . */ + +# ----------------------------------------------------------------------------- +# This code is commented throughout for use with Doxygen. +# ----------------------------------------------------------------------------- +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = fpee$(EXEEXT) +subdir = fpee +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am_fpee_OBJECTS = fpee.$(OBJEXT) +fpee_OBJECTS = $(am_fpee_OBJECTS) +fpee_DEPENDENCIES = ../except/except.lo ../support/libsupport.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +fpee_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(fpee_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/../../depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/fpee.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(fpee_SOURCES) +DIST_SOURCES = $(fpee_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/../../depcomp \ + $(top_srcdir)/../../mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SIM = @SIM@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +fpee_SOURCES = fpee.c +fpee_LDFLAGS = -T$(srcdir)/../default.ld +fpee_LDADD = ../except/except.lo \ + ../support/libsupport.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu fpee/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu fpee/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +fpee$(EXEEXT): $(fpee_OBJECTS) $(fpee_DEPENDENCIES) $(EXTRA_fpee_DEPENDENCIES) + @rm -f fpee$(EXEEXT) + $(AM_V_CCLD)$(fpee_LINK) $(fpee_OBJECTS) $(fpee_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpee.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/fpee.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/fpee.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/testsuite/test-code-or1k/fpee/fpee.c b/testsuite/test-code-or1k/fpee/fpee.c new file mode 100644 index 0000000..387919b --- /dev/null +++ b/testsuite/test-code-or1k/fpee/fpee.c @@ -0,0 +1,117 @@ +/* fpee.c. Test of Or1ksim floating point exceptions + + Copyright (C) 2023 OpenRISC Developers + + Contributor Stafford Horne + + This file is part of OpenRISC 1000 Architectural Simulator. + + 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 3 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, see . */ + +#include +#include + +#include "spr-defs.h" +#include "support.h" + +static void enter_user_mode() +{ + int32_t sr; + + sr = mfspr(SPR_SR); + sr &= ~SPR_SR_SM; + mtspr(SPR_SR, sr); +} + +void enable_fpe() +{ + unsigned long fpcsr = SPR_FPCSR_FPEE; + mtspr(SPR_FPCSR, fpcsr); +} + +/* A divide routine using the or1k FPU, this ensures the result + does not overwrite the inputs in case we have looping + as we saw with a bug in QEMU. + + Return uint32_t to avoid having to link to floating point + routines. + */ +static uint32_t fpu_div(float a, float b) +{ + uint32_t c = 0; + asm volatile("lf.div.s %0, %1, %2" + : "+r" (c) + : "r" (a), "r" (b)); + return c; +} + +/* A multiply routine using the or1k FPU, this ensure the result + does not overwrite the inputs in case we have looping as we + with a bug in QEMU. + + Return uint32_t to avoid having to link to floating point + routines, + */ +static uint32_t fpu_mul(float a, float b) +{ + uint32_t c = 0; + asm volatile("lf.mul.s %0, %1, %2" : "+r" (c) : "r" (a), "r" (b)); + return c; +} + +static int handle_count = 0; + +static void fpe_handler() +{ + uint32_t epcr = mfspr(SPR_EPCR_BASE); + + printf("Got fpe: %lx\n", epcr); + + if (handle_count++ > 0) + { + printf("Oh no, multiple exceptions, abort QEMU/Kernel/normal?!\n"); + exit(1); + } +} + +int main() +{ + uint32_t result; + + /* Setup FPU exception handler. */ + excpt_fpu = (unsigned long) fpe_handler; + + printf("Switching to User Mode\n"); + enter_user_mode(); + + printf("Enabling FPU Exceptions\n"); + enable_fpe(); + + printf("Exceptions enabled, now DIV 3.14 / 0!\n"); + result = fpu_div(3.14f, 0.0f); + /* Verify we see infinity. */ + report((unsigned long) result); + /* Verify we see DZF set. */ + report(mfspr(SPR_FPCSR)); + mtspr(SPR_FPCSR, mfspr(SPR_FPCSR) & ~SPR_FPCSR_ALLF); + + handle_count = 0; + printf("One more, now MUL 3.14 * MAX!\n"); + result = fpu_mul(3.14f, FLT_MAX); + /* Verify we see infinity. */ + report((unsigned long) result); + /* Verify we see Inexact and Overflow flags set. */ + report(mfspr(SPR_FPCSR)); + mtspr(SPR_FPCSR, mfspr(SPR_FPCSR) & ~SPR_FPCSR_ALLF); +}