1//===----- lib/i386/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
9#include "../fp_mode.h"
10
11#define X87_TONEAREST  0x0000
12#define X87_DOWNWARD   0x0400
13#define X87_UPWARD     0x0800
14#define X87_TOWARDZERO 0x0c00
15#define X87_RMODE_MASK (X87_TONEAREST | X87_UPWARD | X87_DOWNWARD | X87_TOWARDZERO)
16
17FE_ROUND_MODE __fe_getround() {
18  // Assume that the rounding mode state for the fpu agrees with the SSE unit.
19  unsigned short cw;
20  __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
21
22  switch (cw & X87_RMODE_MASK) {
23    case X87_TONEAREST:
24      return FE_TONEAREST;
25    case X87_DOWNWARD:
26      return FE_DOWNWARD;
27    case X87_UPWARD:
28      return FE_UPWARD;
29    case X87_TOWARDZERO:
30      return FE_TOWARDZERO;
31  }
32  return FE_TONEAREST;
33}
34
35int __fe_raise_inexact() {
36  float f = 1.0f, g = 3.0f;
37  __asm__ __volatile__ ("fdivs %1" : "+t" (f) : "m" (g));
38  return 0;
39}
40