Merge pull request #622 from killabytenow/master
[mono.git] / mono / utils / mono-hwcap-arm.c
1 /*
2  * mono-hwcap-arm.c: ARM 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-arm.h"
22
23 #if defined(PLATFORM_ANDROID)
24 #include <stdio.h>
25 #elif defined(__linux__)
26 #include <sys/auxv.h>
27 #endif
28
29 gboolean mono_hwcap_arm_is_v5 = FALSE;
30 gboolean mono_hwcap_arm_is_v6 = FALSE;
31 gboolean mono_hwcap_arm_is_v7 = FALSE;
32 gboolean mono_hwcap_arm_is_v7s = FALSE;
33 gboolean mono_hwcap_arm_has_vfp = FALSE;
34 gboolean mono_hwcap_arm_has_thumb = FALSE;
35 gboolean mono_hwcap_arm_has_thumb2 = FALSE;
36
37 void
38 mono_hwcap_init (void)
39 {
40 #if defined(PLATFORM_ANDROID)
41         /* We can't use the auxiliary vector on Android due to
42          * permissions, so fall back to /proc/cpuinfo.
43          */
44
45         char buf [512];
46         char *line;
47
48         FILE *file = fopen ("/proc/cpuinfo", "r");
49
50         if (file) {
51                 while ((line = fgets (buf, 512, file))) {
52                         if (!strncmp (line, "Processor", 9)) {
53                                 char *ver = strstr (line, "(v");
54
55                                 if (ver) {
56                                         if (ver [2] >= '5')
57                                                 mono_hwcap_arm_is_v5 = TRUE;
58
59                                         if (ver [2] >= '6')
60                                                 mono_hwcap_arm_is_v6 = TRUE;
61
62                                         if (ver [2] >= '7')
63                                                 mono_hwcap_arm_is_v7 = TRUE;
64
65                                         /* TODO: Find a way to detect v7s. */
66                                 }
67
68                                 continue;
69                         }
70
71                         if (!strncmp (line, "Features", 8)) {
72                                 char *thumb = strstr (line, "thumb");
73
74                                 if (thumb)
75                                         mono_hwcap_arm_has_thumb = TRUE;
76
77                                 /* TODO: Find a way to detect Thumb 2. */
78
79                                 char *vfp = strstr (line, "vfp")
80
81                                 if (vfp)
82                                         mono_hwcap_arm_has_vfp = TRUE;
83
84                                 continue;
85                         }
86                 }
87
88                 fclose (file);
89         }
90 #elif defined(__linux__)
91         unsigned long hwcap;
92         unsigned long platform;
93
94         if ((hwcap = getauxval(AT_HWCAP))) {
95                 /* HWCAP_ARM_THUMB */
96                 if (hwcap & 0x00000004)
97                         mono_hwcap_arm_has_thumb = TRUE;
98
99                 /* HWCAP_ARM_VFP */
100                 if (hwcap & 0x00000064)
101                         mono_hwcap_arm_has_vfp = TRUE;
102
103                 /* TODO: Find a way to detect Thumb 2. */
104         }
105
106         if ((platform = getauxval(AT_PLATFORM))) {
107                 const char *str = (const char *) platform;
108
109                 if (str [1] >= '5')
110                         mono_hwcap_arm_is_v5 = TRUE;
111
112                 if (str [1] >= '6')
113                         mono_hwcap_arm_is_v6 = TRUE;
114
115                 if (str [1] >= '7')
116                         mono_hwcap_arm_is_v7 = TRUE;
117
118                 /* TODO: Find a way to detect v7s. */
119         }
120 #endif
121 }