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