1 //=== lib/builtins/loongarch/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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #include "../fp_mode.h" 9 10 #define LOONGARCH_TONEAREST 0x0000 11 #define LOONGARCH_TOWARDZERO 0x0100 12 #define LOONGARCH_UPWARD 0x0200 13 #define LOONGARCH_DOWNWARD 0x0300 14 15 #define LOONGARCH_RMODE_MASK (LOONGARCH_TONEAREST | LOONGARCH_TOWARDZERO | \ 16 LOONGARCH_UPWARD | LOONGARCH_DOWNWARD) 17 18 #define LOONGARCH_INEXACT 0x10000 19 20 CRT_FE_ROUND_MODE __fe_getround(void) { 21 #if __loongarch_frlen != 0 22 int fcsr; 23 # ifdef __clang__ 24 __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 25 # else 26 __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 27 # endif 28 fcsr &= LOONGARCH_RMODE_MASK; 29 switch (fcsr) { 30 case LOONGARCH_TOWARDZERO: 31 return CRT_FE_TOWARDZERO; 32 case LOONGARCH_DOWNWARD: 33 return CRT_FE_DOWNWARD; 34 case LOONGARCH_UPWARD: 35 return CRT_FE_UPWARD; 36 case LOONGARCH_TONEAREST: 37 default: 38 return CRT_FE_TONEAREST; 39 } 40 #else 41 return CRT_FE_TONEAREST; 42 #endif 43 } 44 45 int __fe_raise_inexact(void) { 46 #if __loongarch_frlen != 0 47 int fcsr; 48 # ifdef __clang__ 49 __asm__ __volatile__("movfcsr2gr %0, $fcsr0" : "=r" (fcsr)); 50 __asm__ __volatile__( 51 "movgr2fcsr $fcsr0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 52 # else 53 __asm__ __volatile__("movfcsr2gr %0, $r0" : "=r" (fcsr)); 54 __asm__ __volatile__( 55 "movgr2fcsr $r0, %0" :: "r" (fcsr | LOONGARCH_INEXACT)); 56 # endif 57 #endif 58 return 0; 59 } 60