Skip to content

Support for const string interpolation into inline assembly #132083

Open
@dingxiangfei2009

Description

@dingxiangfei2009
Contributor

Related to this comment.

Maybe related to #93332

This feature request targets the inline assembly macro asm! and globally scope assembly global_asm! to support direct string interpolation into the assembly template.

The semantic works very much like a format! in a narrower sense, that only constant string is supported. The proposed macro word is interpolate $expr where $expr is a const-evaluatable expression that yields a &'static str constant value.

An example of how it would work is as follows.

trait Helper {
    const SRC: &'static str;
}

fn make_it_work<H: Helper>(h: &H, x: i64) {
    asm!(
        "mov {0}, {1}",
        in(reg) x,
        interpolate H::SRC
    );
}

struct H;
impl Helper for H {
    const SRC: &'static str = "MAGIC";
}

fn invoke() {
    make_it_work(&H, 42);
}

The one and only instantiation of asm! macro, when completely expanded through codegen, might have yield the following assembly line.

    mov rcx, MAGIC

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 23, 2024
dingxiangfei2009

dingxiangfei2009 commented on Oct 23, 2024

@dingxiangfei2009
ContributorAuthor

Requests from #132012 (comment) is fulfilled.

Bonus question I guess.

Do we want in(..) and out(..) constraints to accept const values as well? I imagine that it would be helpful to additionally mark registers clobbered, for instance.

dingxiangfei2009

dingxiangfei2009 commented on Oct 23, 2024

@dingxiangfei2009
ContributorAuthor

@rustbot claim

added
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
A-inline-assemblyArea: Inline assembly (`asm!(…)`)
T-langRelevant to the language team
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Oct 24, 2024
Lokathor

Lokathor commented on Oct 25, 2024

@Lokathor
Contributor

I'm unclear why this is interpolate instead of sticking with const. The value is still a constant input to the asm, as far as I can tell.

thomcc

thomcc commented on Oct 25, 2024

@thomcc
Member

It might be surprising to users that const on a string doesn't somehow give the assemnbly a refrerence to that constant string, rather than interpolating it directly.

kulst

kulst commented on Jan 26, 2025

@kulst

One possible use-case for a feature like this might be implementing special operations for the NVPTX target:
In the assembly of this target the type of the operands is encoded in the instruction. NVPTX also has very special instructions that to my knowledge do not really have a complementary operation in the Rust language. Therefore to use such instructions from Rust inline assembly might be necessary:

One special instruction in NVPTX is to fetch from texture memory. To fetch from texture memory that stores f32 values an inline assembly instruction looks like this:

#[inline]
pub unsafe fn _tex_1d_fetch_f32(tex_object: u64, x: i32) -> f32 {
    let mut res: f32;
    asm! {
        "tex.1d.v4.f32.s32 {{{f1}, {f2}, {f3}, {f4}}}, [{tex_object}, {{{x}}}];",
        tex_object = in(reg64) tex_object,
        x = in(reg32) x,
        f1 = out(reg32) res,
        f2 = out(reg32) _,
        f3 = out(reg32) _,
        f4 = out(reg32) _,
    }
    res
}

With the proposed solution this function could be made generic over the 32 Bit type it fetches and the 32 Bit type of the indexing variable x:

#[inline]
pub unsafe fn _tex_1d_fetch_32<T : TexDType32, U: TexCType> (tex_object: u64, x: U) -> T {
    let mut res: T;
    asm! {
        "tex.1d.v4.{dtype}.{ctype} {{{f1}, {f2}, {f3}, {f4}}}, [{tex_object}, {{{x}}}];",
        tex_object = in(reg64) tex_object,
        x = in(reg32) x,
        f1 = out(reg32) res,
        f2 = out(reg32) _,
        f3 = out(reg32) _,
        f4 = out(reg32) _,
        dtype = interpolate T::TYPE,
        ctype = interpolate U::TYPE,
    }
    res
}

(It would be benefitial to be generic over the register size as well, but this is another topic I think. Another way to implement such special operations could be using LLVM intrinsics. However, I do not know if LLVM intrinsics do exist for all special NVPTX instructions and how stable these are.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

A-inline-assemblyArea: Inline assembly (`asm!(…)`)C-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @thomcc@Lokathor@dingxiangfei2009@jieyouxu@rustbot

      Issue actions

        Support for const string interpolation into inline assembly · Issue #132083 · rust-lang/rust