ObjFW  Diff

Differences From Artifact [2e4f49497d]:

To Artifact [df1cd50578]:


43
44
45
46
47
48
49

50

51
52

53
54
55
56

57
58


59
60

61
62
63
64
65
66
67



68





69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59


60
61
62

63
64

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99
100
101
102
103







+
-
+


+




+
-
-
+
+

-
+

-





+
+
+

+
+
+
+
+














-
-
-



+







#ifdef __HAIKU__
# include <FindDirectory.h>
#endif
#ifdef __QNX__
# include <sys/syspage.h>
#endif

#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
struct cpuid_regs {
struct x86_regs {
	uint32_t eax, ebx, ecx, edx;
};
#endif

static size_t pageSize;
static size_t numberOfCPUs;

#if defined(OF_X86_64_ASM)
static OF_INLINE struct cpuid_regs OF_CONST_FUNC
cpuid(uint32_t eax, uint32_t ecx)
static OF_INLINE struct x86_regs OF_CONST_FUNC
x86_cpuid(uint32_t eax, uint32_t ecx)
{
	struct cpuid_regs regs;
	struct x86_regs regs;

#if defined(OF_X86_64_ASM)
	__asm__(
	    "cpuid"
	    : "=a"(regs.eax), "=b"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);

	return regs;
}
#elif defined(OF_X86_ASM)
static OF_INLINE struct x86_regs OF_CONST_FUNC
x86_cpuid(uint32_t eax, uint32_t ecx)
{
	struct x86_regs regs;

	/*
	 * This workaround is required by GCC when using -fPIC, as ebx is a
	 * special register in PIC code. Yes, GCC is indeed not able to just
	 * push a register onto the stack before the __asm__ block and to pop
	 * it afterwards.
	 */
	__asm__(
	    "pushl	%%ebx\n\t"
	    "cpuid\n\t"
	    "movl	%%ebx, %1\n\t"
	    "popl	%%ebx"
	    : "=a"(regs.eax), "=r"(regs.ebx), "=c"(regs.ecx), "=d"(regs.edx)
	    : "a"(eax), "c"(ecx)
	);
#else
	regs.eax = regs.ebx = regs.ecx = regs.edx = 0;
#endif

	return regs;
}
#endif

@implementation OFSystemInfo
+ (void)initialize
{
	if (self != [OFSystemInfo class])
		return;

294
295
296
297
298
299
300

301

302
303
304
305
306
307
308
309
310
311
312
313



314
315

316
317
318

319
320
321
322
323

324
325
326
327
328

329
330
331
332
333

334
335
336
337
338

339
340
341
342
343

344
345
346
347
348

349
350
351
352
353

354
355
356
357
358

359

360
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

331
332
333
334
335

336
337
338
339
340

341
342
343
344
345

346
347
348
349
350

351
352
353
354
355

356
357
358
359
360

361
362
363
364
365

366
367
368
369
370

371
372
373
374







+
-
+












+
+
+


+


-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+

+

	objc_autoreleasePoolPop(pool);
	return [var autorelease];
#endif
}

+ (OFString*)CPUVendor
{
#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
	struct cpuid_regs regs = cpuid(0, 0);
	struct x86_regs regs = x86_cpuid(0, 0);
	char buffer[12];

	if (regs.eax == 0)
		return nil;

	memcpy(buffer, &regs.ebx, 4);
	memcpy(buffer + 4, &regs.edx, 4);
	memcpy(buffer + 8, &regs.ecx, 4);

	return [OFString stringWithCString: buffer
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 12];
#else
	return nil;
#endif
}

#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
+ (bool)supportsMMX
{
	return (cpuid(1, 0).edx & (1 << 23));
	return (x86_cpuid(1, 0).edx & (1 << 23));
}

+ (bool)supportsSSE
{
	return (cpuid(1, 0).edx & (1 << 25));
	return (x86_cpuid(1, 0).edx & (1 << 25));
}

+ (bool)supportsSSE2
{
	return (cpuid(1, 0).edx & (1 << 26));
	return (x86_cpuid(1, 0).edx & (1 << 26));
}

+ (bool)supportsSSE3
{
	return (cpuid(1, 0).ecx & (1 << 0));
	return (x86_cpuid(1, 0).ecx & (1 << 0));
}

+ (bool)supportsSSSE3
{
	return (cpuid(1, 0).ecx & (1 << 9));
	return (x86_cpuid(1, 0).ecx & (1 << 9));
}

+ (bool)supportsSSE41
{
	return (cpuid(1, 0).ecx & (1 << 19));
	return (x86_cpuid(1, 0).ecx & (1 << 19));
}

+ (bool)supportsSSE42
{
	return (cpuid(1, 0).ecx & (1 << 20));
	return (x86_cpuid(1, 0).ecx & (1 << 20));
}

+ (bool)supportsAVX
{
	return (cpuid(1, 0).ecx & (1 << 28));
	return (x86_cpuid(1, 0).ecx & (1 << 28));
}

+ (bool)supportsAVX2
{
	return cpuid(0, 0).eax >= 7 && (cpuid(7, 0).ebx & (1 << 5));
	return x86_cpuid(0, 0).eax >= 7 && (x86_cpuid(7, 0).ebx & (1 << 5));
}
#endif
@end