Skip to content

met unrecognized instruction mnemonic error when naked function uses macro defined in global_asm! #134960

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

Closed
zjp-CN opened this issue Dec 31, 2024 · 7 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. F-naked_functions `#![feature(naked_functions)]`

Comments

@zjp-CN
Copy link
Contributor

zjp-CN commented Dec 31, 2024

I tried this code with cargo b --target riscv64gc-unknown-none-elf

#![no_std]
#![feature(naked_functions)]

core::arch::global_asm!(
    r"
.macro LDR rd, rs, off
    ld \rd, \off*8(\rs)
.endm
",
);

#[naked]
/// # Safety
pub unsafe extern "C" fn context_switch() {
    unsafe {
        core::arch::naked_asm!(
            "
        // omit code around
        LDR     s11, a1, 13

        ret",
        )
    }
}

I expected to see this happen: the code compiles.

Instead, this happened: macro in global_asm! is not recognized in naked_asm!.

error: unrecognized instruction mnemonic, did you mean: fld, ld?
  |
note: instantiated into assembly here
 --> <inline asm>:8:9
  |
8 |         LDR     s11, a1, 13
  |         ^

Actually the code does compile until nightly-2024-12-12. I use cargo-bisect-rustc to find out the regressed commit is 1daec06 , which points to #128004 .

Is this a desired behavior change? How could the code compile on latest nightly rustc?

BTW the code above compiles with cargo check --target riscv64gc-unknown-none-elf, why is that?

Meta

rustc --version --verbose:

rustc 1.85.0-nightly (7f75bfa1a 2024-12-30)
binary: rustc
commit-hash: 7f75bfa1ad4e9a9d33a179a90603001515e91991
commit-date: 2024-12-30
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6
@zjp-CN zjp-CN added the C-bug Category: This is a bug. label Dec 31, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Dec 31, 2024
@jieyouxu jieyouxu added the F-naked_functions `#![feature(naked_functions)]` label Dec 31, 2024
@bjorn3
Copy link
Member

bjorn3 commented Dec 31, 2024

There is no guarantee that any assembler state is preserved between inline asm blocks. In fact if we could, we would explicitly prevent you from using this. As for why it no longer works in this case: It is possible that the naked function definition got moved to before the global asm, or to another codegen unit.

@Noratrieb Noratrieb closed this as not planned Won't fix, can't repro, duplicate, stale Dec 31, 2024
zjp-CN added a commit to os-checker/taskctx that referenced this issue Jan 2, 2025
@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jan 2, 2025
@fs-99
Copy link

fs-99 commented Mar 9, 2025

I agree that there should not be a guarantee between inline asm! blocks, but isn't global_asm! used exactly for this kind of stuff (macros, constants, stuff to be used in multiple places)?

@Noratrieb
Copy link
Member

No, it's intended for stuff like defining global constants or functions, not touching assembler state. It's explicitly documented that you must not modify or rely on assembler state: https://doc.rust-lang.org/stable/reference/inline-assembly.html#r-asm.ts-args.llvm-syntax

@fs-99
Copy link

fs-99 commented Mar 9, 2025

Thank you, could you please tell me a better way to do this? And how does this change assembler state?
global asm:

.set REG_SIZE, 8
.macro load_gp i, basereg=t6
    ld x\i, ((\i)*REG_SIZE)(\basereg)
.endm

asm! asm:

.set i, 1
.rept 31
    load_gp %i, t6
    .set i, i+1
.endr

I want to keep these inside rust, not asm files.

I'm trying to learn, but I just don't understand the things which changed between a few months ago where I last touched this code and it still worked and now.

@Noratrieb
Copy link
Member

A macro adds a the macro definition to the assembler state.
You can do this by using rust macros to abstract your inline assembly. i'm not sure how to best do it in this case, but you may find such a solution.

but I just don't understand the things which changed

these macros make the code order sensitive, so what probably happened is that some random thing in the compiler changed to order the stuff differently

@zjp-CN
Copy link
Contributor Author

zjp-CN commented Mar 9, 2025

I want to keep these inside rust, not asm files.

Seems like you can try what I suggested to do here.

@fs-99
Copy link

fs-99 commented Mar 9, 2025

Thank you both, now I just have to figure out why .rept won't work, I probably should go do some more assembly programming

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. F-naked_functions `#![feature(naked_functions)]`
Projects
None yet
Development

No branches or pull requests

6 participants