mirror of
				https://github.com/facebook/zstd.git
				synced 2025-10-31 16:47:48 +02:00 
			
		
		
		
	[cpu] Backport fix for rbx clobbering on Windows with Clang
Backport folly fix for rbx clobbering: f22f88b8b9
This supercedes PR #3646.
			
			
This commit is contained in:
		
				
					committed by
					
						 Nick Terrell
						Nick Terrell
					
				
			
			
				
	
			
			
			
						parent
						
							4bd911ae41
						
					
				
				
					commit
					94c102038b
				
			| @@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { | ||||
|     U32 f7b = 0; | ||||
|     U32 f7c = 0; | ||||
| #if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) | ||||
| #if !defined(__clang__) | ||||
|     int reg[4]; | ||||
|     __cpuid((int*)reg, 0); | ||||
|     { | ||||
| @@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { | ||||
|             f7c = (U32)reg[2]; | ||||
|         } | ||||
|     } | ||||
| #else | ||||
|     /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in | ||||
|      * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs | ||||
|      * to due to being a reserved register. So in that case, do the `cpuid` | ||||
|      * ourselves. Clang supports inline assembly anyway. | ||||
|      */ | ||||
|     U32 n; | ||||
|     __asm__( | ||||
|         "pushq %%rbx\n\t" | ||||
|         "cpuid\n\t" | ||||
|         "popq %%rbx\n\t" | ||||
|         : "=a"(n) | ||||
|         : "a"(0) | ||||
|         : "rcx", "rdx"); | ||||
|     if (n >= 1) { | ||||
|       U32 f1a; | ||||
|       __asm__( | ||||
|           "pushq %%rbx\n\t" | ||||
|           "cpuid\n\t" | ||||
|           "popq %%rbx\n\t" | ||||
|           : "=a"(f1a), "=c"(f1c), "=d"(f1d) | ||||
|           : "a"(1) | ||||
|           :); | ||||
|     } | ||||
|     if (n >= 7) { | ||||
|       __asm__( | ||||
|           "pushq %%rbx\n\t" | ||||
|           "cpuid\n\t" | ||||
|           "movq %%rbx, %%rax\n\t" | ||||
|           "popq %%rbx" | ||||
|           : "=a"(f7b), "=c"(f7c) | ||||
|           : "a"(7), "c"(0) | ||||
|           : "rdx"); | ||||
|     } | ||||
| #endif | ||||
| #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) | ||||
|     /* The following block like the normal cpuid branch below, but gcc | ||||
|      * reserves ebx for use of its pic register so we must specially | ||||
|   | ||||
		Reference in New Issue
	
	Block a user