Merge pull request #823 from DavidKarlas/master
[mono.git] / mono / utils / mono-hwcap-s390x.c
1 /*
2  * mono-hwcap-s390x.c: S/390x hardware feature detection
3  *
4  * Authors:
5  *    Alex Rønne Petersen (alexrp@xamarin.com)
6  *    Elijah Taylor (elijahtaylor@google.com)
7  *    Miguel de Icaza (miguel@xamarin.com)
8  *    Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
9  *    Paolo Molaro (lupus@xamarin.com)
10  *    Rodrigo Kumpera (kumpera@gmail.com)
11  *    Sebastien Pouliot (sebastien@xamarin.com)
12  *    Zoltan Varga (vargaz@xamarin.com)
13  *
14  * Copyright 2003 Ximian, Inc.
15  * Copyright 2003-2011 Novell, Inc
16  * Copyright 2006 Broadcom
17  * Copyright 2007-2008 Andreas Faerber
18  * Copyright 2011-2013 Xamarin Inc
19  */
20
21 #include "mono/utils/mono-hwcap-s390x.h"
22
23 #include <signal.h>
24
25 gboolean mono_hwcap_s390x_has_ld = FALSE;
26
27 #if defined(MONO_CROSS_COMPILE)
28 void
29 mono_hwcap_arch_init (void)
30 {
31 }
32 #else
33 static void
34 catch_sigill (int sig_no, siginfo_t *info, gpointer act)
35 {
36         mono_hwcap_s390x_has_ld = FALSE;
37 }
38
39 void
40 mono_hwcap_arch_init (void)
41 {
42         mono_hwcap_s390x_has_ld = TRUE;
43
44         struct sigaction sa, *old_sa;
45
46         /* Determine if we have a long displacement facility
47          * by executing the STY instruction. If it fails, we
48          * catch the SIGILL and assume the answer is no.
49          */
50         sa.sa_sigaction = catch_sigill;
51         sigemptyset (&sa.sa_mask);
52         sa.sa_flags = SA_SIGINFO;
53
54         sigaction (SIGILL, &sa, old_sa);
55
56         __asm__ __volatile__ (
57                 "LGHI\t0,1\n\t"
58                 "LA\t1,%0\n\t"
59                 ".byte\t0xe3,0x00,0x10,0x00,0x00,0x50\n\t"
60                 : "=m" (mono_hwcap_s390x_has_ld)
61                 :
62                 : "0", "1"
63         );
64
65         sigaction (SIGILL, old_sa, NULL);
66 }
67 #endif
68
69 void
70 mono_hwcap_print (FILE *f)
71 {
72         g_fprintf (f, "mono_hwcap_s390x_has_ld = %i\n", mono_hwcap_s390x_has_ld);
73 }