133b8a553SYi Kong //===----- lib/arm/fp_mode.c - Floaing-point mode utilities -------*- C -*-===// 233b8a553SYi Kong // 333b8a553SYi Kong // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 433b8a553SYi Kong // See https://llvm.org/LICENSE.txt for license information. 533b8a553SYi Kong // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 633b8a553SYi Kong // 733b8a553SYi Kong //===----------------------------------------------------------------------===// 833b8a553SYi Kong 933b8a553SYi Kong #include <stdint.h> 1033b8a553SYi Kong 1133b8a553SYi Kong #include "../fp_mode.h" 1233b8a553SYi Kong 1333b8a553SYi Kong #define ARM_TONEAREST 0x0 1433b8a553SYi Kong #define ARM_UPWARD 0x1 1533b8a553SYi Kong #define ARM_DOWNWARD 0x2 1633b8a553SYi Kong #define ARM_TOWARDZERO 0x3 1733b8a553SYi Kong #define ARM_RMODE_MASK (ARM_TONEAREST | ARM_UPWARD | \ 1833b8a553SYi Kong ARM_DOWNWARD | ARM_TOWARDZERO) 1933b8a553SYi Kong #define ARM_RMODE_SHIFT 22 2033b8a553SYi Kong 21e2cd2f7dSAlex Richardson #define ARM_INEXACT 0x10 2233b8a553SYi Kong 2333b8a553SYi Kong #ifndef __ARM_FP 2433b8a553SYi Kong // For soft float targets, allow changing rounding mode by overriding the weak 2533b8a553SYi Kong // __arm_fe_default_rmode symbol. 26ed0bf875SAlex Richardson CRT_FE_ROUND_MODE __attribute__((weak)) __arm_fe_default_rmode = 27ed0bf875SAlex Richardson CRT_FE_TONEAREST; 2833b8a553SYi Kong #endif 2933b8a553SYi Kong __fe_getround(void)30*bdbfaf0cSAaron BallmanCRT_FE_ROUND_MODE __fe_getround(void) { 3133b8a553SYi Kong #ifdef __ARM_FP 3233b8a553SYi Kong uint32_t fpscr; 3333b8a553SYi Kong __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); 3433b8a553SYi Kong fpscr = fpscr >> ARM_RMODE_SHIFT & ARM_RMODE_MASK; 3533b8a553SYi Kong switch (fpscr) { 3633b8a553SYi Kong case ARM_UPWARD: 37ed0bf875SAlex Richardson return CRT_FE_UPWARD; 3833b8a553SYi Kong case ARM_DOWNWARD: 39ed0bf875SAlex Richardson return CRT_FE_DOWNWARD; 4033b8a553SYi Kong case ARM_TOWARDZERO: 41ed0bf875SAlex Richardson return CRT_FE_TOWARDZERO; 4233b8a553SYi Kong case ARM_TONEAREST: 4333b8a553SYi Kong default: 44ed0bf875SAlex Richardson return CRT_FE_TONEAREST; 4533b8a553SYi Kong } 4633b8a553SYi Kong #else 4733b8a553SYi Kong return __arm_fe_default_rmode; 4833b8a553SYi Kong #endif 4933b8a553SYi Kong } 5033b8a553SYi Kong __fe_raise_inexact(void)51*bdbfaf0cSAaron Ballmanint __fe_raise_inexact(void) { 5233b8a553SYi Kong #ifdef __ARM_FP 5333b8a553SYi Kong uint32_t fpscr; 5433b8a553SYi Kong __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); 5533b8a553SYi Kong __asm__ __volatile__("vmsr fpscr, %0" : : "ri" (fpscr | ARM_INEXACT)); 5633b8a553SYi Kong return 0; 5733b8a553SYi Kong #else 5833b8a553SYi Kong return 0; 5933b8a553SYi Kong #endif 6033b8a553SYi Kong } 61