1  /* { dg-do run { target { powerpc*-*-* } } } */
       2  /* { dg-options "-O2 -std=c99" } */
       3  
       4  #ifdef DEBUG
       5  #include <stdio.h>
       6  #endif
       7  
       8  #define RN_MASK  0x3LL             /* RN field mask */
       9  
      10  void abort (void);
      11  void __attribute__ ((noipa)) wrap_set_fpscr_rn (int val)
      12  {
      13    __builtin_set_fpscr_rn (val);
      14  }
      15  
      16  int main ()
      17  {
      18    int i;
      19    int val, bit;
      20    double fpscr_val;
      21    union blah {
      22      double d;
      23      unsigned long long ll;
      24    } conv_val;
      25    
      26    unsigned long long ll_value;
      27    register double  f14;
      28  
      29    /* __builtin_set_fpscr_rn() builtin can take a const or a variable
      30       value between 0 and 3 as the argument.
      31       __builtin_mtfsb0 and __builtin_mtfsb1 argument must be a constant 
      32       30 or 31.
      33    */
      34  
      35    /* Test reading the FPSCR register */
      36    __asm __volatile ("mffs %0" : "=f"(f14));
      37    conv_val.d = f14;
      38  
      39    if (conv_val.d != __builtin_mffs())
      40      {
      41  #ifdef DEBUG
      42         printf("ERROR, __builtin_mffs() returned 0x%llx, not the expecected value 0x%llx\n",
      43  	      __builtin_mffs(), conv_val.d);
      44  #else
      45         abort();
      46  #endif
      47      }		  
      48  
      49    /* Test float rounding mode builtin with const value argument.  */
      50    val = 3;
      51    __builtin_set_fpscr_rn (val);
      52    conv_val.d = __builtin_mffs();
      53    ll_value = conv_val.ll & RN_MASK;
      54  
      55    if (ll_value != 3)
      56      {
      57  #ifdef DEBUG
      58         printf("ERROR, __builtin_set_fpscr_rn(3) returned 0x%llx, not the expecected value 0x%x\n",
      59  	      ll_value, 3);
      60  #else
      61         abort();
      62  #endif
      63      }		  
      64  
      65    val = 2;
      66    __builtin_set_fpscr_rn (val);
      67    conv_val.d = __builtin_mffs();
      68    ll_value = conv_val.ll & RN_MASK;
      69  
      70    if (ll_value != val)
      71      {
      72  #ifdef DEBUG
      73         printf("ERROR, __builtin_set_fpscr_rn(val=%d) returned 0x%llx, not the expecected value 0x%x\n",
      74  	      val, ll_value, val);
      75  #else
      76         abort();
      77  #endif
      78      }		  
      79  
      80    /* Reset to 0 for testing */
      81    val = 0;
      82    __builtin_set_fpscr_rn (val);
      83  
      84    __builtin_mtfsb1(31);
      85    conv_val.d = __builtin_mffs();
      86    ll_value = conv_val.ll & 0x1LL;
      87  
      88    if (ll_value != 1)
      89      {
      90  #ifdef DEBUG
      91         printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n");
      92  #else
      93         abort();
      94  #endif
      95      }		  
      96  
      97    __builtin_mtfsb0(31);
      98    conv_val.d = __builtin_mffs();
      99    ll_value = conv_val.ll & 0x1LL;
     100  
     101    if (ll_value != 0)
     102      {
     103  #ifdef DEBUG
     104         printf("ERROR, __builtin_mtfsb0(31) did not set the bit to a 0.\n");
     105  #else
     106         abort();
     107  #endif
     108      }		  
     109  
     110   __builtin_mtfsb1(30);
     111    conv_val.d = __builtin_mffs();
     112    ll_value = conv_val.ll & 0x2LL;
     113  
     114    if (ll_value != 2)
     115      {
     116  #ifdef DEBUG
     117         printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 1.\n");
     118  #else
     119         abort();
     120  #endif
     121      }		  
     122  
     123    __builtin_mtfsb0(30);
     124    conv_val.d = __builtin_mffs();
     125    ll_value = conv_val.ll & 0x2LL;
     126  
     127    if (ll_value != 0)
     128      {
     129  #ifdef DEBUG
     130         printf("ERROR, __builtin_mtfsb1(31) did not set the bit to a 0.\n");
     131  #else
     132         abort();
     133  #endif
     134      }		  
     135  
     136    __builtin_mtfsb1(0);
     137    conv_val.d = __builtin_mffs();
     138    ll_value = conv_val.ll & (0x1LL << (31-0));
     139  
     140    if (ll_value != (0x1LL << (31-0)))
     141      {
     142  #ifdef DEBUG
     143         printf("ERROR, __builtin_mtfsb1(0) did not set the bit to a 1.\n");
     144  #else
     145         abort();
     146  #endif
     147      }		  
     148  
     149    __builtin_mtfsb0(0);
     150    conv_val.d = __builtin_mffs();
     151    ll_value = conv_val.ll & (0x1LL << (31-0));
     152  
     153    if (ll_value != 0)
     154      {
     155  #ifdef DEBUG
     156         printf("ERROR, __builtin_mtfsb0(0) did not set the bit to a 0.\n");
     157  #else
     158         abort();
     159  #endif
     160      }		  
     161  
     162  
     163    /* Test builtin float rounding mode with variable as argument.  */
     164    val = 0;
     165    wrap_set_fpscr_rn (val);
     166    conv_val.d = __builtin_mffs();
     167    ll_value = conv_val.ll & RN_MASK;
     168  
     169    if (ll_value != val)
     170      {
     171  #ifdef DEBUG
     172         printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n",
     173  	      val, val);
     174  #else
     175         abort();
     176  #endif
     177      }		  
     178  
     179    val = 3;
     180    wrap_set_fpscr_rn (val);
     181    conv_val.d = __builtin_mffs();
     182    ll_value = conv_val.ll & RN_MASK;
     183  
     184    if (ll_value != val)
     185      {
     186  #ifdef DEBUG
     187         printf("ERROR, __builtin_set_fpscr_rn(val=%d) did not set rounding mode to %x.\n",
     188  	      val, val);
     189  #else
     190         abort();
     191  #endif
     192      }		  
     193  }