1*810390e3Srobert //=== lib/builtins/loongarch/fp_mode.c - Floaing-point mode utilities -*- C -*-===// 2*810390e3Srobert // 3*810390e3Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*810390e3Srobert // See https://llvm.org/LICENSE.txt for license information. 5*810390e3Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*810390e3Srobert // 7*810390e3Srobert //===----------------------------------------------------------------------===// 8*810390e3Srobert #include "../fp_mode.h" 9*810390e3Srobert 10*810390e3Srobert #define LOONGARCH_TONEAREST 0x0000 11*810390e3Srobert #define LOONGARCH_TOWARDZERO 0x0100 12*810390e3Srobert #define LOONGARCH_UPWARD 0x0200 13*810390e3Srobert #define LOONGARCH_DOWNWARD 0x0300 14*810390e3Srobert 15*810390e3Srobert #define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \ 16*810390e3Srobert LOONGARCH_UPWARD | LOONGARCH_DOWNWARD) 17*810390e3Srobert 18*810390e3Srobert #define LOONGARCH_INEXACT 0x10000 19*810390e3Srobert __fe_getround(void)20*810390e3SrobertCRT_FE_ROUND_MODE __fe_getround(void) { 21*810390e3Srobert #if __loongarch_frlen != 0 22*810390e3Srobert int fcsr; 23*810390e3Srobert # ifdef __clang__ 24*810390e3Srobert __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 25*810390e3Srobert # else 26*810390e3Srobert __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 27*810390e3Srobert # endif 28*810390e3Srobert fcsr &= LOONGARCH_RMODE_MASK; 29*810390e3Srobert switch (fcsr) { 30*810390e3Srobert case LOONGARCH_TOWARDZERO: 31*810390e3Srobert return CRT_FE_TOWARDZERO; 32*810390e3Srobert case LOONGARCH_DOWNWARD: 33*810390e3Srobert return CRT_FE_DOWNWARD; 34*810390e3Srobert case LOONGARCH_UPWARD: 35*810390e3Srobert return CRT_FE_UPWARD; 36*810390e3Srobert case LOONGARCH_TONEAREST: 37*810390e3Srobert default: 38*810390e3Srobert return CRT_FE_TONEAREST; 39*810390e3Srobert } 40*810390e3Srobert #else 41*810390e3Srobert return CRT_FE_TONEAREST; 42*810390e3Srobert #endif 43*810390e3Srobert } 44*810390e3Srobert __fe_raise_inexact(void)45*810390e3Srobertint __fe_raise_inexact(void) { 46*810390e3Srobert #if __loongarch_frlen != 0 47*810390e3Srobert int fcsr; 48*810390e3Srobert # ifdef __clang__ 49*810390e3Srobert __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 50*810390e3Srobert __asm__ __volatile__( 51*810390e3Srobert "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 52*810390e3Srobert # else 53*810390e3Srobert __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 54*810390e3Srobert __asm__ __volatile__( 55*810390e3Srobert "movgr2fcsr $r0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 56*810390e3Srobert # endif 57*810390e3Srobert #endif 58*810390e3Srobert return 0; 59*810390e3Srobert } 60