1// { dg-do run { target { powerpc64*-*-linux* } } }
2// { dg-options "-fexceptions -fnon-call-exceptions" }
3
4#include <signal.h>
5#include <stdlib.h>
6#include <fenv.h>
7
8#define SET_CR(R,V) __asm__ __volatile__ ("mtcrf %0,%1" : : "n" (1<<(7-R)), "r" (V<<(4*(7-R))) : "cr" #R)
9#define GET_CR(R) ({ int tmp; __asm__ __volatile__ ("mfcr %0" : "=r" (tmp)); (tmp >> 4*(7-R)) & 15; })
10
11void sighandler (int signo, siginfo_t * si, void * uc)
12{
13  SET_CR(2, 3);
14  SET_CR(3, 2);
15  SET_CR(4, 1);
16
17  throw 0;
18}
19
20float test (float a, float b) __attribute__ ((__noinline__));
21float test (float a, float b)
22{
23  float x;
24  asm ("mtcrf %1,%2" : "=f" (x) : "n" (1 << (7-3)), "r" (0), "0" (b) : "cr3");
25  return a / x;
26}
27
28int main ()
29{
30  struct sigaction sa;
31  int status;
32
33  sa.sa_sigaction = sighandler;
34  sa.sa_flags = SA_SIGINFO;
35
36  status = sigaction (SIGFPE, & sa, NULL);
37
38  feenableexcept (FE_DIVBYZERO);
39
40  SET_CR(2, 6);
41  SET_CR(3, 9);
42  SET_CR(4, 12);
43
44  try {
45    test (1, 0);
46  }
47  catch (...) {
48    return GET_CR(2) != 6 || GET_CR(3) != 9 || GET_CR(4) != 12;
49  }
50
51  return 1;
52}
53
54
55