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!: options should work multiple times, to simplify macros #73193

Closed
joshtriplett opened this issue Jun 10, 2020 · 18 comments · Fixed by #73227
Closed

asm!: options should work multiple times, to simplify macros #73193

joshtriplett opened this issue Jun 10, 2020 · 18 comments · Fixed by #73227
Assignees
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. F-asm `#![feature(asm)]` (not `llvm_asm`) T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@joshtriplett
Copy link
Member

joshtriplett commented Jun 10, 2020

To simplify the implementation of macros wrapping asm!, I think options should work if specified multiple times, with the semantic that no conflicting options may be provided. (We could also do "last option wins", but I think I'd slightly prefer "don't specify conflicting options" instead.)

This would, for instance, make it much easier to implement an asm_att! macro that passes all its arguments to asm! and adds options(att_syntax), without having to scan all the tokens it receives, look for an existing options, and append to it if found.

Sample code that I think should work (printing 9):

#![feature(asm)]

fn main() {
    let mut i: u32 = 5;
    unsafe {
        asm!(
            "add $4, %rax",
            inout("rax") i,
            options(att_syntax),
            options(nostack),
        );
    }
    println!("{}", i);
}
@joshtriplett joshtriplett added A-inline-assembly Area: Inline assembly (`asm!(…)`) T-lang Relevant to the language team, which will review and decide on the PR/issue. F-asm `#![feature(asm)]` (not `llvm_asm`) labels Jun 10, 2020
@Amanieu
Copy link
Member

Amanieu commented Jun 10, 2020

That seems like an extremely niche use case that would only really enable an asm_att! macro and nothing else. I don't expect such a macro to actually be used in practice since adding options(att_syntax) is already very easy.

@joshtriplett
Copy link
Member Author

A large codebase that uses primarily AT&T syntax will want to spell it as briefly as possible; I expect to see such a macro in common use.

If you believe this would complicate the parser unnecessarily, then I would be open to a crate-based solution that shows how to implement the macro taking existing options into account.

@cesarb
Copy link
Contributor

cesarb commented Jun 10, 2020

with the semantic that no conflicting options may be provided. (We could also do "last option wins", but I think I'd slightly prefer "don't specify conflicting options" instead.)

I think a simpler semantic would be "multiple options is identical to a single options with the options concatenated". That is, options(A, B), options(C, D) would have the exact same semantics as options(A, B, C, D).

This would be good not only for macros, but also for readability (some people might prefer multiple options, one on each line, instead of being forced to use a single options, when the list of options starts to get too long).

@joshtriplett
Copy link
Member Author

@cesarb That sounds reasonable to me.

@Amanieu
Copy link
Member

Amanieu commented Jun 10, 2020

This is actually a very trivial change to the parsers, so it should be easy to add.

@Amanieu Amanieu added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Jun 10, 2020
@camelid
Copy link
Member

camelid commented Jun 10, 2020

@rustbot claim

@rustbot rustbot assigned rustbot and unassigned Amanieu Jun 10, 2020
@camelid
Copy link
Member

camelid commented Jun 10, 2020

Oops, didn't realize it was claimed! Sorry

@rustbot release-assignment

I assume you were planning to do this, @Amanieu?

@rustbot rustbot removed their assignment Jun 10, 2020
@Amanieu
Copy link
Member

Amanieu commented Jun 10, 2020

No no, go ahead, you can have it.

@camelid
Copy link
Member

camelid commented Jun 10, 2020

Thanks! I’ll give it a try :)

@rustbot claim

@camelid
Copy link
Member

camelid commented Jun 11, 2020

How should I handle diagnostics? There are multiple errors that show where the error in the options occurred, e.g.:

ecx.struct_span_err(span, "the `nomem` and `readonly` options are mutually exclusive")
    .emit();

The way I'm doing the multiple options is to just let it bitwise-OR the different flags into the AsmArgs.options field, and instead of having options_span: Option<Span>, have options_spans: Option<Vec<Span>>. The problem is that then you can't tell where the options came from. Should I change options to be a Vec<ast::InlineAsmOptions>?

Advice?

@camelid
Copy link
Member

camelid commented Jun 11, 2020

Also, perhaps there should be a simple diagnostic for checking for duplicate options?

@camelid
Copy link
Member

camelid commented Jun 11, 2020

Alternatively, the errors could just be reported on all the options spans.

@Amanieu
Copy link
Member

Amanieu commented Jun 11, 2020

Error reporting can take a Vec<Span> to report multiple error sources at once.

@Amanieu
Copy link
Member

Amanieu commented Jun 11, 2020

You can add a diagnostic for setting the same option multiple times by just checking if it has already been ORed in.

@camelid
Copy link
Member

camelid commented Jun 11, 2020

You can add a diagnostic for setting the same option multiple times by just checking if it has already been ORed in.

Yeah, that's what I was thinking

@camelid
Copy link
Member

camelid commented Jun 11, 2020

Error reporting can take a Vec<Span> to report multiple error sources at once.

Is it okay to .clone() the Vec<Span>?

@Amanieu
Copy link
Member

Amanieu commented Jun 11, 2020

Sure.

@nagisa
Copy link
Member

nagisa commented Jun 12, 2020

Last option overrides is a better design if the goal is to enable macros. That way invocations of the same asm! with att-syntax-by-default can still opt into intel syntax by appending what otherwise would be a conflicting option.

(EDIT: OTOH I think nomem vs readonly strongly informs the design towards no conflicting options)

@bors bors closed this as completed in 45d6aef Jun 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. F-asm `#![feature(asm)]` (not `llvm_asm`) T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants