Skip to content

x64: Migrate mulx to the new assembler #10887

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

Merged
merged 2 commits into from
Jun 2, 2025

Conversation

alexcrichton
Copy link
Member

This is an interesting instruction as it has a relatively unique shape compared to many others. The VEX encoding is used to give it a 3-operand form, although it still has an implicit 4th operand as well. The other unique part about this instruction is that if the two write-only operands are the same then that has a different semantic meaning than if they are different.

Modeling the two-output form of the instruction was pretty easy, the only changes needed were to add the r32a and r32b locations as previously only r32 was available. Modeling the one-output form of the instruction led to a "hook" where these instructions specify that they use a custom regalloc function. That skips the auto-generated regalloc entirely and defers to a new custom submodule in the assembler crate. These custom variants handle only having a single write operand on the instruction.

@alexcrichton alexcrichton requested a review from a team as a code owner May 31, 2025 18:24
@alexcrichton alexcrichton requested review from fitzgen and abrown and removed request for a team and fitzgen May 31, 2025 18:24
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:x64 Issues related to x64 codegen cranelift:meta Everything related to the meta-language. isle Related to the ISLE domain-specific language labels May 31, 2025
Copy link

Subscribe to Label Action

cc @cfallin, @fitzgen

This issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "cranelift:meta", "isle"

Thus the following users have been cc'd because of the following labels:

  • cfallin: isle
  • fitzgen: isle

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

// opposed to when the operands are different to calculate both the high
// and low halves.
inst("mulxl", fmt("RVM", [w(r32a), w(r32b), r(rm32), r(implicit(edx))]), vex(LZ)._f2()._0f38().w0().op(0xF6), _64b | compat | bmi2).custom_visit(),
inst("mulxq", fmt("RVM", [w(r64a), w(r64b), r(rm64), r(implicit(rdx))]), vex(LZ)._f2()._0f38().w1().op(0xF6), _64b | bmi2).custom_visit(),
Copy link
Member

Choose a reason for hiding this comment

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

I really like this custom* idea: I'd been mulling over how to do custom encodings for nop and custom printing for comparisons and felt we needed an escape hatch for very special instructions. And I like that we just expect custom::visit_{inst} to be present, which should be pretty clear in compile errors.

I don't know if you were thinking this way, but maybe in the future we can go to .custom(Visit | Encode | Display) which would result in an appropriate call to custom::visit::{inst}, custom::encode::{inst}, and custom::display::{inst}. Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that's reasonable yeah!

(_ Unit (emit (MInst.MulX size src1 src2 (writable_invalid_gpr) dst))))
dst))
(rule (x64_mulx_hi $I32 src1 src2) (x64_mulxl_rvm_hi src2 src1))
(rule (x64_mulx_hi $I64 src1 src2) (x64_mulxq_rvm_hi src2 src1))
Copy link
Member

Choose a reason for hiding this comment

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

I guess there's no way to pass the same temporary register in... I wonder if eventually we need to allow even more fine-grained control from ISLE — a few new gen_asm.rs rules?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was wondering the same yeah, but I figured that if it's just mulx then there's no need to go to such lengths, so I figured I'd leave it as-is for now. If the number of instructions needing this grows though I can see how making new ISLE helpers would be reasonable

@abrown abrown added this pull request to the merge queue Jun 2, 2025
@alexcrichton alexcrichton removed this pull request from the merge queue due to a manual request Jun 2, 2025
This is an interesting instruction as it has a relatively unique shape
compared to many others. The VEX encoding is used to give it a 3-operand
form, although it still has an implicit 4th operand as well. The other
unique part about this instruction is that if the two write-only
operands are the same then that has a different semantic meaning than if
they are different.

Modeling the two-output form of the instruction was pretty easy, the
only changes needed were to add the `r32a` and `r32b` locations as
previously only `r32` was available. Modeling the one-output form of the
instruction led to a "hook" where these instructions specify that they
use a custom regalloc function. That skips the auto-generated regalloc
entirely and defers to a new `custom` submodule in the assembler crate.
These custom variants handle only having a single write operand on the
instruction.
@alexcrichton alexcrichton enabled auto-merge June 2, 2025 18:03
@alexcrichton alexcrichton added this pull request to the merge queue Jun 2, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jun 2, 2025
@alexcrichton alexcrichton added this pull request to the merge queue Jun 2, 2025
Merged via the queue into bytecodealliance:main with commit 4955f5a Jun 2, 2025
53 checks passed
@alexcrichton alexcrichton deleted the x64-mulx branch June 2, 2025 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift:area:x64 Issues related to x64 codegen cranelift:meta Everything related to the meta-language. cranelift Issues related to the Cranelift code generator isle Related to the ISLE domain-specific language
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants