Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid using ebx as an asm! operand #185

Merged
merged 3 commits into from
Oct 5, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions measureme/src/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,16 +543,20 @@ mod hw {
asm!(
// Dummy `cpuid(0)` to serialize instruction execution.
"xor eax, eax",
// LLVM sometimes reserves `ebx` for its internal use, we so we need to use
// a scratch register for it instead.
"mov {tmp_rbx:r}, rbx",
"cpuid",
"mov rbx, {tmp_rbx:r}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noticed this. This is frustrating, as it makes cpuid undesirably troublesome (I wish Intel and AMD would agree on e.g. mfence/lfence being serializing). I suspect that using a LLVM intrinsic for cpuid would result in shorter codegen, can you try this? Either way, can you PM me on Zulip?

I've let that rustc PR sit, sadly (long story short, other factors forced us to abandon the grant it was part of), and it would be good to take stock of what's useful and what's just hacks we only needed to get the results we wanted.


"mov ecx, {rdpmc_ecx:e}",
"rdpmc",
rdpmc_ecx = in(reg) reg_idx,
tmp_rbx = out(reg) _,
out("eax") lo,
out("edx") hi,

// `cpuid` clobbers (not overwritten by `rdpmc`).
out("ebx") _,
out("ecx") _,

options(nostack),
Expand All @@ -574,7 +578,11 @@ mod hw {
asm!(
// Dummy `cpuid(0)` to serialize instruction execution.
"xor eax, eax",
// LLVM sometimes reserves `ebx` for its internal use, we so we need to use
// a scratch register for it instead.
"mov {tmp_rbx:r}, rbx",
"cpuid",
"mov rbx, {tmp_rbx:r}",

"mov ecx, {a_rdpmc_ecx:e}",
"rdpmc",
Expand All @@ -586,11 +594,11 @@ mod hw {
a_rdpmc_eax = out(reg) a_lo,
a_rdpmc_edx = out(reg) a_hi,
b_rdpmc_ecx = in(reg) b_reg_idx,
tmp_rbx = out(reg) _,
out("eax") b_lo,
out("edx") b_hi,

// `cpuid` clobbers (not overwritten by `rdpmc`).
out("ebx") _,
out("ecx") _,

options(nostack),
Expand Down