Merge pull request #820 from brendanzagaeski/master
[mono.git] / mono / utils / mono-hwcap-ppc.c
1 /*
2  * mono-hwcap-ppc.c: PowerPC 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-ppc.h"
22
23 #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
24 #include <string.h>
25 #include <sys/auxv.h>
26 #endif
27
28 gboolean mono_hwcap_ppc_has_icache_snoop = FALSE;
29 gboolean mono_hwcap_ppc_is_isa_2x = FALSE;
30 gboolean mono_hwcap_ppc_is_isa_64 = FALSE;
31 gboolean mono_hwcap_ppc_has_move_fpr_gpr = FALSE;
32 gboolean mono_hwcap_ppc_has_multiple_ls_units = FALSE;
33
34 #if defined(MONO_CROSS_COMPILE)
35 void
36 mono_hwcap_arch_init (void)
37 {
38 }
39 #else
40 void
41 mono_hwcap_arch_init (void)
42 {
43 #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
44         unsigned long hwcap;
45         unsigned long platform;
46
47         if ((hwcap = getauxval(AT_HWCAP))) {
48                 /* PPC_FEATURE_ICACHE_SNOOP */
49                 if (hwcap & 0x00002000)
50                         mono_hwcap_ppc_has_icache_snoop = TRUE;
51
52                 /* PPC_FEATURE_POWER4, PPC_FEATURE_POWER5, PPC_FEATURE_POWER5_PLUS,
53                    PPC_FEATURE_CELL_BE, PPC_FEATURE_PA6T, PPC_FEATURE_ARCH_2_05 */
54                 if (hwcap & (0x00080000 | 0x00040000 | 0x00020000 | 0x00010000 | 0x00000800 | 0x00001000))
55                         mono_hwcap_ppc_is_isa_2x = TRUE;
56
57                 /* PPC_FEATURE_64 */
58                 if (hwcap & 0x40000000)
59                         mono_hwcap_ppc_is_isa_64 = TRUE;
60
61                 /* PPC_FEATURE_POWER6_EXT */
62                 if (hwcap & 0x00000200)
63                         mono_hwcap_ppc_has_move_fpr_gpr = TRUE;
64         }
65
66         if ((platform = getauxval(AT_PLATFORM))) {
67                 const char *str = (const char *) platform;
68
69                 if (!strcmp (str, "ppc970") || (!strncmp (str, "power", 5) && str [5] >= '4' && str [5] <= '7'))
70                         mono_hwcap_ppc_has_multiple_ls_units = TRUE;
71         }
72 #endif
73 }
74 #endif
75
76 void
77 mono_hwcap_print (FILE* f)
78 {
79         g_fprintf (f, "mono_hwcap_ppc_has_icache_snoop = %i\n", mono_hwcap_ppc_has_icache_snoop);
80         g_fprintf (f, "mono_hwcap_ppc_is_isa_2x = %i\n", mono_hwcap_ppc_is_isa_2x);
81         g_fprintf (f, "mono_hwcap_ppc_is_isa_64 = %i\n", mono_hwcap_ppc_is_isa_64);
82         g_fprintf (f, "mono_hwcap_ppc_has_move_fpr_gpr = %i\n", mono_hwcap_ppc_has_move_fpr_gpr);
83         g_fprintf (f, "mono_hwcap_ppc_has_multiple_ls_units = %i\n", mono_hwcap_ppc_has_multiple_ls_units);
84 }