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

asm: fix sign-extended immediates #10216

Merged
merged 5 commits into from
Feb 13, 2025
Merged

Conversation

abrown
Copy link
Contributor

@abrown abrown commented Feb 10, 2025

#10200 described two main problems with sign-extended immediates in cranelift-assembler-x64: (a) the capstone pretty-printing had many peculiarities and (b) there is a potential for sign confusion when using sign-extending instructions. This PR solves (a) by parsing and re-printing capstone immediates into a very vanilla hex format: $0xff.... It solves (b) by adding new types (Simm{8|16|32}) for sign-extending instructions. Each commit message has more details.

This resolves #10200.

@abrown abrown requested a review from a team as a code owner February 10, 2025 23:17
@abrown abrown requested review from fitzgen and alexcrichton and removed request for a team and fitzgen February 10, 2025 23:17
As mentioned in bytecodealliance#10200, `capstone` has a peculiar way of pretty-printing
immediates, especially signed immediates. It is simpler (and perhaps
more clear) for us to just print immediates in one consistent format:
`0xffff...`, e.g. This change parses capstone's pretty-printed
immediates and converts them to our simpler format if the first attempt
to match this assembler's output with `capston` fails.
As pointed out in bytecodealliance#10200, it could be confusing for users for
`cranelift-assembler-x64` to pass unsigned integers to certain assembler
instructions and have them unexpectedly sign-extended. Well, it can't be
too surprising since these instructions have a `_sx*` suffix, but this
change implements @alexcrichton's additional suggestion to create
separate types for the immediates that may be sign-extended.

These new types (`Simm8`, `Simm16`, `Simm32`) are quite similar to their
vanilla counterparts (`Imm8`, `Imm16`, `Imm32`) but have additional
sign-extension logic when pretty-printed. This means the vanilla
versions can be simplified and the pre-existing `Simm32` is renamed to
the more appropriate `AmodeOffset`.
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:x64 Issues related to x64 codegen isle Related to the ISLE domain-specific language labels Feb 11, 2025
Copy link

Subscribe to Label Action

cc @cfallin, @fitzgen

This issue or pull request has been labeled: "cranelift", "cranelift:area:x64", "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.

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

This might be a bit of a silly question, but why not use uNN for AssemblerImmNN and iNN for AssemblerSimmNN? Do we benefit much from the differently-named versions with different methods/conversions?

Otherwise it sort of makes sense to me that instructions operate over logical values and they're represented with various bit-widths where uNN is always zero-extended to the operation width and iNN is sign-extended to the operation width (which doesn't change the logical meaning of the value, just extends the bit representation)

@@ -24,6 +24,7 @@ pedantic = "warn"
module_name_repetitions = { level = "allow", priority = 1 }
similar_names = { level = "allow", priority = 1 }
wildcard_imports = { level = "allow", priority = 1 }
too_many_lines = { level = "allow", priority = 1 }
Copy link
Member

Choose a reason for hiding this comment

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

Would you be ok doing:

[lints]
workspace = true

like other crates in the workspace? That way we can ensure that lints are applied uniformly to all crates invovled. If you want a specific clippy lint for this crate then it can be done with #![warn(clippy::...)] in the crate itself

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, let me do that in another PR because it's going to be 25 changes unrelated to this one.

fn is_imm32(&mut self, src: &GprMemImm) -> Option<AssemblerImm32> {
match src.clone().to_reg_mem_imm() {
RegMemImm::Imm { simm32 } => Some(AssemblerImm32::new(simm32)),
_ => None,
}
}

fn is_simm32(&mut self, src: &GprMemImm) -> Option<AssemblerSimm32> {
match src.clone().to_reg_mem_imm() {
RegMemImm::Imm { simm32 } => Some(AssemblerSimm32::new(simm32 as i32)),
Copy link
Member

Choose a reason for hiding this comment

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

Is as i32 necessary here? I thought simm32 was already i32?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's weirdly u32?

@abrown
Copy link
Contributor Author

abrown commented Feb 13, 2025

@alexcrichton, I'm going to merge this to move things forward and open up some other PRs as follow-ups.

This might be a bit of a silly question, but why not use uNN for AssemblerImmNN and iNN for AssemblerSimmNN? Do we benefit much from the differently-named versions with different methods/conversions?

Yeah, it may have made more sense at some point but now the extra Imm*::new(...) and Imm*::value() functions don't make much sense. We can just have some functions that do the appropriate pretty-printing.

@abrown abrown added this pull request to the merge queue Feb 13, 2025
Merged via the queue into bytecodealliance:main with commit b0b5d8f Feb 13, 2025
51 checks passed
@abrown abrown deleted the assembler-simm branch February 13, 2025 22:38
abrown added a commit that referenced this pull request Feb 13, 2025
This removes all the custom clippy allowances and just adopts the
project's Clippy settings. This was suggested over in [#10216].

[#10216]: #10216 (comment)
github-merge-queue bot pushed a commit that referenced this pull request Feb 14, 2025
* asm: switch to using workspace clippy settings

This removes all the custom clippy allowances and just adopts the
project's Clippy settings. This was suggested over in [#10216].

[#10216]: #10216 (comment)

* fix: add one more allow reason
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 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.

asm: pretty-printing signed immediates
2 participants