a5f7f8ceb6fb7f1a1f9d860a1ab86b0fed0af1d3
[iec.git] / src / type3_AndroidCloud / anbox-master / external / cpu_features / src / utils / list_cpu_features.c
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "cpu_features_macros.h"
20 #include "cpuinfo_aarch64.h"
21 #include "cpuinfo_arm.h"
22 #include "cpuinfo_mips.h"
23 #include "cpuinfo_ppc.h"
24 #include "cpuinfo_x86.h"
25
26 static void PrintEscapedAscii(const char* str) {
27   putchar('"');
28   for (; str && *str; ++str) {
29     switch (*str) {
30       case '\"':
31       case '\\':
32       case '/':
33       case '\b':
34       case '\f':
35       case '\n':
36       case '\r':
37       case '\t':
38         putchar('\\');
39     }
40     putchar(*str);
41   }
42   putchar('"');
43 }
44
45 static void PrintVoid(void) {}
46 static void PrintComma(void) { putchar(','); }
47 static void PrintLineFeed(void) { putchar('\n'); }
48 static void PrintOpenBrace(void) { putchar('{'); }
49 static void PrintCloseBrace(void) { putchar('}'); }
50 static void PrintOpenBracket(void) { putchar('['); }
51 static void PrintCloseBracket(void) { putchar(']'); }
52 static void PrintString(const char* field) { printf("%s", field); }
53 static void PrintAlignedHeader(const char* field) { printf("%-15s : ", field); }
54 static void PrintIntValue(int value) { printf("%d", value); }
55 static void PrintDecHexValue(int value) {
56   printf("%3d (0x%02X)", value, value);
57 }
58 static void PrintJsonHeader(const char* field) {
59   PrintEscapedAscii(field);
60   putchar(':');
61 }
62
63 typedef struct {
64   void (*Start)(void);
65   void (*ArrayStart)(void);
66   void (*ArraySeparator)(void);
67   void (*ArrayEnd)(void);
68   void (*PrintString)(const char* value);
69   void (*PrintValue)(int value);
70   void (*EndField)(void);
71   void (*StartField)(const char* field);
72   void (*End)(void);
73 } Printer;
74
75 static Printer getJsonPrinter(void) {
76   return (Printer){
77       .Start = &PrintOpenBrace,
78       .ArrayStart = &PrintOpenBracket,
79       .ArraySeparator = &PrintComma,
80       .ArrayEnd = &PrintCloseBracket,
81       .PrintString = &PrintEscapedAscii,
82       .PrintValue = &PrintIntValue,
83       .EndField = &PrintComma,
84       .StartField = &PrintJsonHeader,
85       .End = &PrintCloseBrace,
86   };
87 }
88
89 static Printer getTextPrinter(void) {
90   return (Printer){
91       .Start = &PrintVoid,
92       .ArrayStart = &PrintVoid,
93       .ArraySeparator = &PrintComma,
94       .ArrayEnd = &PrintVoid,
95       .PrintString = &PrintString,
96       .PrintValue = &PrintDecHexValue,
97       .EndField = &PrintLineFeed,
98       .StartField = &PrintAlignedHeader,
99       .End = &PrintVoid,
100   };
101 }
102
103 // Prints a named numeric value in both decimal and hexadecimal.
104 static void PrintN(const Printer p, const char* field, int value) {
105   p.StartField(field);
106   p.PrintValue(value);
107   p.EndField();
108 }
109
110 // Prints a named string.
111 static void PrintS(const Printer p, const char* field, const char* value) {
112   p.StartField(field);
113   p.PrintString(value);
114   p.EndField();
115 }
116
117 static int cmp(const void* p1, const void* p2) {
118   return strcmp(*(const char* const*)p1, *(const char* const*)p2);
119 }
120
121 #define DEFINE_PRINT_FLAGS(HasFeature, FeatureName, FeatureType, LastEnum) \
122   static void PrintFlags(const Printer p, const FeatureType* features) {   \
123     size_t i;                                                              \
124     const char* ptrs[LastEnum] = {0};                                      \
125     size_t count = 0;                                                      \
126     for (i = 0; i < LastEnum; ++i) {                                       \
127       if (HasFeature(features, i)) {                                       \
128         ptrs[count] = FeatureName(i);                                      \
129         ++count;                                                           \
130       }                                                                    \
131     }                                                                      \
132     qsort(ptrs, count, sizeof(char*), cmp);                                \
133     p.StartField("flags");                                                 \
134     p.ArrayStart();                                                        \
135     for (i = 0; i < count; ++i) {                                          \
136       if (i > 0) p.ArraySeparator();                                       \
137       p.PrintString(ptrs[i]);                                              \
138     }                                                                      \
139     p.ArrayEnd();                                                          \
140   }
141
142 #if defined(CPU_FEATURES_ARCH_X86)
143 DEFINE_PRINT_FLAGS(GetX86FeaturesEnumValue, GetX86FeaturesEnumName, X86Features,
144                    X86_LAST_)
145 #elif defined(CPU_FEATURES_ARCH_ARM)
146 DEFINE_PRINT_FLAGS(GetArmFeaturesEnumValue, GetArmFeaturesEnumName, ArmFeatures,
147                    ARM_LAST_)
148 #elif defined(CPU_FEATURES_ARCH_AARCH64)
149 DEFINE_PRINT_FLAGS(GetAarch64FeaturesEnumValue, GetAarch64FeaturesEnumName,
150                    Aarch64Features, AARCH64_LAST_)
151 #elif defined(CPU_FEATURES_ARCH_MIPS)
152 DEFINE_PRINT_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName,
153                    MipsFeatures, MIPS_LAST_)
154 #elif defined(CPU_FEATURES_ARCH_PPC)
155 DEFINE_PRINT_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
156                    PPC_LAST_)
157 #endif
158
159 static void PrintFeatures(const Printer printer) {
160 #if defined(CPU_FEATURES_ARCH_X86)
161   char brand_string[49];
162   const X86Info info = GetX86Info();
163   FillX86BrandString(brand_string);
164   PrintS(printer, "arch", "x86");
165   PrintS(printer, "brand", brand_string);
166   PrintN(printer, "family", info.family);
167   PrintN(printer, "model", info.model);
168   PrintN(printer, "stepping", info.stepping);
169   PrintS(printer, "uarch",
170          GetX86MicroarchitectureName(GetX86Microarchitecture(&info)));
171   PrintFlags(printer, &info.features);
172 #elif defined(CPU_FEATURES_ARCH_ARM)
173   const ArmInfo info = GetArmInfo();
174   PrintS(printer, "arch", "ARM");
175   PrintN(printer, "implementer", info.implementer);
176   PrintN(printer, "architecture", info.architecture);
177   PrintN(printer, "variant", info.variant);
178   PrintN(printer, "part", info.part);
179   PrintN(printer, "revision", info.revision);
180   PrintFlags(printer, &info.features);
181 #elif defined(CPU_FEATURES_ARCH_AARCH64)
182   const Aarch64Info info = GetAarch64Info();
183   PrintS(printer, "arch", "aarch64");
184   PrintN(printer, "implementer", info.implementer);
185   PrintN(printer, "variant", info.variant);
186   PrintN(printer, "part", info.part);
187   PrintN(printer, "revision", info.revision);
188   PrintFlags(printer, &info.features);
189 #elif defined(CPU_FEATURES_ARCH_MIPS)
190   const MipsInfo info = GetMipsInfo();
191   PrintS(printer, "arch", "mips");
192   PrintFlags(printer, &info.features);
193 #elif defined(CPU_FEATURES_ARCH_PPC)
194   const PPCInfo info = GetPPCInfo();
195   const PPCPlatformStrings strings = GetPPCPlatformStrings();
196   PrintS(printer, "arch", "ppc");
197   PrintS(printer, "platform", strings.platform);
198   PrintS(printer, "model", strings.model);
199   PrintS(printer, "machine", strings.machine);
200   PrintS(printer, "cpu", strings.cpu);
201   PrintS(printer, "instruction set", strings.type.platform);
202   PrintS(printer, "microarchitecture", strings.type.base_platform);
203   PrintFlags(printer, &info.features);
204 #endif
205 }
206
207 static void showUsage(const char* name) {
208   printf(
209       "\n"
210       "Usage: %s [options]\n"
211       "      Options:\n"
212       "      -h | --help     Show help message.\n"
213       "      -j | --json     Format output as json instead of plain text.\n"
214       "\n",
215       name);
216 }
217
218 int main(int argc, char** argv) {
219   Printer printer = getTextPrinter();
220   int i = 1;
221   for (; i < argc; ++i) {
222     const char* arg = argv[i];
223     if (strcmp(arg, "-j") == 0 || strcmp(arg, "--json") == 0) {
224       printer = getJsonPrinter();
225     } else {
226       showUsage(argv[0]);
227       if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0)
228         return EXIT_SUCCESS;
229       return EXIT_FAILURE;
230     }
231   }
232   printer.Start();
233   PrintFeatures(printer);
234   printer.End();
235   PrintLineFeed();
236   return EXIT_SUCCESS;
237 }