| ... | @@ -528,26 +528,20 @@ const CpuidLeaf = packed struct { | ... | @@ -528,26 +528,20 @@ const CpuidLeaf = packed struct { |
| 528 | }; | 528 | }; |
| 529 | | 529 | |
| 530 | fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { | 530 | fn cpuid(leaf_id: u32, subid: u32) CpuidLeaf { |
| 531 | // Workaround for https://github.com/ziglang/zig/issues/215 | | |
| 532 | // Inline assembly in zig only supports one output, | | |
| 533 | // so we pass a pointer to the struct. | | |
| 534 | var cpuid_leaf: CpuidLeaf = undefined; | | |
| 535 | | | |
| 536 | // valid for both x86 and x86_64 | 531 | // valid for both x86 and x86_64 |
| 537 | asm volatile ( | 532 | var eax: u32 = undefined; |
| 538 | \\ cpuid | 533 | var ebx: u32 = undefined; |
| 539 | \\ movl %%eax, 0(%[leaf_ptr]) | 534 | var ecx: u32 = undefined; |
| 540 | \\ movl %%ebx, 4(%[leaf_ptr]) | 535 | var edx: u32 = undefined; |
| 541 | \\ movl %%ecx, 8(%[leaf_ptr]) | 536 | asm volatile ("cpuid" |
| 542 | \\ movl %%edx, 12(%[leaf_ptr]) | 537 | : [_] "={eax}" (eax), |
| 543 | : | 538 | [_] "={ebx}" (ebx), |
| 544 | : [leaf_id] "{eax}" (leaf_id), | 539 | [_] "={ecx}" (ecx), |
| 545 | [subid] "{ecx}" (subid), | 540 | [_] "={edx}" (edx), |
| 546 | [leaf_ptr] "r" (&cpuid_leaf), | 541 | : [_] "{eax}" (leaf_id), |
| 547 | : "ebx", "edx" // "eax" and "ecx" are already inputs | 542 | [_] "{ecx}" (subid), |
| 548 | ); | 543 | ); |
| 549 | | 544 | return .{ .eax = eax, .ebx = ebx, .ecx = ecx, .edx = edx }; |
| 550 | return cpuid_leaf; | | |
| 551 | } | 545 | } |
| 552 | | 546 | |
| 553 | // Read control register 0 (XCR0). Used to detect features such as AVX. | 547 | // Read control register 0 (XCR0). Used to detect features such as AVX. |
| ... | @@ -555,8 +549,8 @@ fn getXCR0() u32 { | ... | @@ -555,8 +549,8 @@ fn getXCR0() u32 { |
| 555 | return asm volatile ( | 549 | return asm volatile ( |
| 556 | \\ xor %%ecx, %%ecx | 550 | \\ xor %%ecx, %%ecx |
| 557 | \\ xgetbv | 551 | \\ xgetbv |
| 558 | : [ret] "={eax}" (-> u32), | 552 | : [_] "={eax}" (-> u32), |
| 559 | : | 553 | : |
| 560 | : "edx", "ecx" // "eax" is already an output | 554 | : "edx", "ecx" |
| 561 | ); | 555 | ); |
| 562 | } | 556 | } |