16e6704b0SYouling Tang //=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- C -*-===// 26e6704b0SYouling Tang // 36e6704b0SYouling Tang // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46e6704b0SYouling Tang // See https://llvm.org/LICENSE.txt for license information. 56e6704b0SYouling Tang // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66e6704b0SYouling Tang // 76e6704b0SYouling Tang //===----------------------------------------------------------------------===// 86e6704b0SYouling Tang #include "../fp_mode.h" 96e6704b0SYouling Tang 106e6704b0SYouling Tang #define LOONGARCH_TONEAREST 0x0000 116e6704b0SYouling Tang #define LOONGARCH_TOWARDZERO 0x0100 126e6704b0SYouling Tang #define LOONGARCH_UPWARD 0x0200 136e6704b0SYouling Tang #define LOONGARCH_DOWNWARD 0x0300 146e6704b0SYouling Tang 156e6704b0SYouling Tang #define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \ 166e6704b0SYouling Tang LOONGARCH_UPWARD | LOONGARCH_DOWNWARD) 176e6704b0SYouling Tang 186e6704b0SYouling Tang #define LOONGARCH_INEXACT 0x10000 196e6704b0SYouling Tang __fe_getround(void)206e6704b0SYouling TangCRT_FE_ROUND_MODE __fe_getround(void) { 216e6704b0SYouling Tang #if __loongarch_frlen != 0 226e6704b0SYouling Tang int fcsr; 23*2b15c63fSYouling Tang # ifdef __clang__ 246e6704b0SYouling Tang __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 25*2b15c63fSYouling Tang # else 26*2b15c63fSYouling Tang __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 27*2b15c63fSYouling Tang # endif 286e6704b0SYouling Tang fcsr &= LOONGARCH_RMODE_MASK; 296e6704b0SYouling Tang switch (fcsr) { 306e6704b0SYouling Tang case LOONGARCH_TOWARDZERO: 316e6704b0SYouling Tang return CRT_FE_TOWARDZERO; 326e6704b0SYouling Tang case LOONGARCH_DOWNWARD: 336e6704b0SYouling Tang return CRT_FE_DOWNWARD; 346e6704b0SYouling Tang case LOONGARCH_UPWARD: 356e6704b0SYouling Tang return CRT_FE_UPWARD; 366e6704b0SYouling Tang case LOONGARCH_TONEAREST: 376e6704b0SYouling Tang default: 386e6704b0SYouling Tang return CRT_FE_TONEAREST; 396e6704b0SYouling Tang } 406e6704b0SYouling Tang #else 416e6704b0SYouling Tang return CRT_FE_TONEAREST; 426e6704b0SYouling Tang #endif 436e6704b0SYouling Tang } 446e6704b0SYouling Tang __fe_raise_inexact(void)456e6704b0SYouling Tangint __fe_raise_inexact(void) { 466e6704b0SYouling Tang #if __loongarch_frlen != 0 476e6704b0SYouling Tang int fcsr; 48*2b15c63fSYouling Tang # ifdef __clang__ 496e6704b0SYouling Tang __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 506e6704b0SYouling Tang __asm__ __volatile__( 516e6704b0SYouling Tang "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 52*2b15c63fSYouling Tang # else 53*2b15c63fSYouling Tang __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 54*2b15c63fSYouling Tang __asm__ __volatile__( 55*2b15c63fSYouling Tang "movgr2fcsr $r0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 56*2b15c63fSYouling Tang # endif 576e6704b0SYouling Tang #endif 586e6704b0SYouling Tang return 0; 596e6704b0SYouling Tang } 60