From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72765 invoked by alias); 21 Jan 2020 09:28:55 -0000 Mailing-List: contact newlib-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: newlib-cvs-owner@sourceware.org Received: (qmail 72746 invoked by uid 9078); 21 Jan 2020 09:28:55 -0000 Date: Tue, 21 Jan 2020 09:28:00 -0000 Message-ID: <20200121092855.72745.qmail@sourceware.org> Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: newlib-cvs@sourceware.org Subject: [newlib-cygwin] riscv: Map between ieeefp.h exception bits and RISC-V FCSR bits X-Act-Checkin: newlib-cygwin X-Git-Author: Keith Packard X-Git-Refname: refs/heads/master X-Git-Oldrev: 8e74c7119fb7f95662bb4986570a98496f259400 X-Git-Newrev: 5377a847764461493c620644f6530892344d1cdd X-SW-Source: 2020-q1/txt/msg00006.txt https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=5377a847764461493c620644f6530892344d1cdd commit 5377a847764461493c620644f6530892344d1cdd Author: Keith Packard Date: Mon Jan 20 22:46:36 2020 -0800 riscv: Map between ieeefp.h exception bits and RISC-V FCSR bits If we had architecture-specific exception bits, we could just set them to match the processor, but instead ieeefp.h is shared by all targets so we need to map between the public values and the register contents. Signed-off-by: Keith Packard Diff: --- newlib/libc/machine/riscv/ieeefp.c | 40 +++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/newlib/libc/machine/riscv/ieeefp.c b/newlib/libc/machine/riscv/ieeefp.c index c458322..60ecacf 100644 --- a/newlib/libc/machine/riscv/ieeefp.c +++ b/newlib/libc/machine/riscv/ieeefp.c @@ -40,6 +40,40 @@ frm_fp_rnd (unsigned frm) } } +static fp_except +frm_fp_except (unsigned except) +{ + fp_except fp = 0; + if (except & (1 << 0)) + fp |= FP_X_IMP; + if (except & (1 << 1)) + fp |= FP_X_UFL; + if (except & (1 << 2)) + fp |= FP_X_OFL; + if (except & (1 << 3)) + fp |= FP_X_DX; + if (except & (1 << 4)) + fp |= FP_X_INV; + return fp; +} + +static unsigned +frm_except(fp_except fp) +{ + unsigned except = 0; + if (fp & FP_X_IMP) + except |= (1 << 0); + if (fp & FP_X_UFL) + except |= (1 << 1); + if (fp & FP_X_OFL) + except |= (1 << 2); + if (fp & FP_X_DX) + except |= (1 << 3); + if (fp & FP_X_INV) + except |= (1 << 4); + return except; +} + #endif /* __riscv_flen */ fp_except @@ -63,7 +97,7 @@ fp_except fpgetsticky(void) { #ifdef __riscv_flen - return frsr () & 0x1f; + return frm_fp_except(frsr ()); #else return 0; #endif /* __riscv_flen */ @@ -102,8 +136,8 @@ fpsetsticky(fp_except sticky) { #ifdef __riscv_flen unsigned fsr = frsr (); - fssr (sticky & 0x1f | fsr & ~0x1f); - return fsr & 0x1f; + fssr (frm_except(sticky) | (fsr & ~0x1f)); + return frm_fp_except(fsr); #else return -1; #endif /* __riscv_flen */