diff --git a/include/fenv.h b/include/fenv.h new file mode 100644 index 0000000000..81e44a8a62 --- /dev/null +++ b/include/fenv.h @@ -0,0 +1,44 @@ +/**************************************************************************** + * include/fenv.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_FENV_H +#define __INCLUDE_FENV_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FE_TONEAREST 0 +#define FE_DOWNWARD 1 +#define FE_UPWARD 2 +#define FE_TOWARDZERO 3 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int fegetround(void); +int fesetround(int round); + +#endif /* __INCLUDE_FENV_H */ \ No newline at end of file diff --git a/libs/libc/machine/arm/Make.defs b/libs/libc/machine/arm/Make.defs index d9d60cee11..c1b096e931 100644 --- a/libs/libc/machine/arm/Make.defs +++ b/libs/libc/machine/arm/Make.defs @@ -46,5 +46,7 @@ ifeq ($(CONFIG_CXX_EXCEPTION),y) CSRCS += gnu_unwind_find_exidx.c endif +CSRCS += arm_fenv.c + DEPPATH += --dep-path machine/arm VPATH += :machine/arm diff --git a/libs/libc/machine/arm/arm_fenv.c b/libs/libc/machine/arm/arm_fenv.c new file mode 100644 index 0000000000..12ca8c43b7 --- /dev/null +++ b/libs/libc/machine/arm/arm_fenv.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * libs/libc/machine/arm/arm_fenv.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ARM_FPSCR_TONEAREST 0x00000000 +#define ARM_FPSCR_DOWNWARD 0x00400000 +#define ARM_FPSCR_UPWARD 0x00800000 +#define ARM_FPSCR_TOWARDZERO 0x00c00000 + +#define ARM_FPSCR_ROUNDMASK 0x00c00000 + +#define SET_FPSCR(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r)) +#define GET_FPSCR(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int fegetround(void) +{ + int ret = FE_TONEAREST; + +#ifndef __SOFTFP__ + int fpscr = 0; + + GET_FPSCR(fpscr); + + fpscr &= ARM_FPSCR_ROUNDMASK; + + switch (fpscr) + { + case ARM_FPSCR_TONEAREST: + ret = FE_TONEAREST; + break; + + case ARM_FPSCR_DOWNWARD: + ret = FE_DOWNWARD; + break; + + case ARM_FPSCR_UPWARD: + ret = FE_UPWARD; + break; + + case ARM_FPSCR_TOWARDZERO: + ret = FE_TOWARDZERO; + break; + + default: + assert(0); + break; + } + +#endif + + return ret; +} + +int fesetround(int round) +{ +#ifndef __SOFTFP__ + int fpscr = 0; + + GET_FPSCR(fpscr); + fpscr &= ~(ARM_FPSCR_ROUNDMASK); + + switch (fpscr) + { + case FE_TONEAREST: + round = ARM_FPSCR_TONEAREST; + break; + + case FE_DOWNWARD: + round = ARM_FPSCR_DOWNWARD; + break; + + case FE_UPWARD: + round = ARM_FPSCR_UPWARD; + break; + + case FE_TOWARDZERO: + round = ARM_FPSCR_TOWARDZERO; + break; + + default: + assert(0); + break; + } + + fpscr |= round; + SET_FPSCR(fpscr); +#endif + return (0); +}