61 lines · c
1//===----- lib/aarch64/fp_mode.c - Floaing-point mode utilities ---*- C -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include <stdint.h>10 11#include "../fp_mode.h"12 13#define AARCH64_TONEAREST 0x014#define AARCH64_UPWARD 0x115#define AARCH64_DOWNWARD 0x216#define AARCH64_TOWARDZERO 0x317#define AARCH64_RMODE_MASK (AARCH64_TONEAREST | AARCH64_UPWARD | \18 AARCH64_DOWNWARD | AARCH64_TOWARDZERO)19#define AARCH64_RMODE_SHIFT 2220 21#define AARCH64_INEXACT 0x1022 23#ifndef __ARM_FP24// For soft float targets, allow changing rounding mode by overriding the weak25// __aarch64_fe_default_rmode symbol.26CRT_FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode =27 CRT_FE_TONEAREST;28#endif29 30CRT_FE_ROUND_MODE __fe_getround(void) {31#ifdef __ARM_FP32 uint64_t fpcr;33 __asm__ __volatile__("mrs %0, fpcr" : "=r" (fpcr));34 fpcr = fpcr >> AARCH64_RMODE_SHIFT & AARCH64_RMODE_MASK;35 switch (fpcr) {36 case AARCH64_UPWARD:37 return CRT_FE_UPWARD;38 case AARCH64_DOWNWARD:39 return CRT_FE_DOWNWARD;40 case AARCH64_TOWARDZERO:41 return CRT_FE_TOWARDZERO;42 case AARCH64_TONEAREST:43 default:44 return CRT_FE_TONEAREST;45 }46#else47 return __aarch64_fe_default_rmode;48#endif49}50 51int __fe_raise_inexact(void) {52#ifdef __ARM_FP53 uint64_t fpsr;54 __asm__ __volatile__("mrs %0, fpsr" : "=r" (fpsr));55 __asm__ __volatile__("msr fpsr, %0" : : "ri" (fpsr | AARCH64_INEXACT));56 return 0;57#else58 return 0;59#endif60}61