There’s been a buzz about ChatGPT on the tech web recently, with some claiming to be outsourcing their (boilerplate dominated cargo cult?) coding to it.

With any new tool it’s interesting to try a corner case, and a real world problem. I’ve been playing around with embedded Rust, so it makes sense to see how well this new tool can help:

How can it help?

“pass an immediate value to a rust asm! macro.”

Question

It’s a plausible sounding answer but there are some big problems:

  • The asm! macro looks like it’s using GCC’s inline asm syntax. It looks like Rust used to use that syntax for an old style asm! macro, but it’s now depreciated and can be accessed as llvm_asm!.
  • There is no such keyword as immediate supported by the asm! macro.
  • The asm::immediate module or macro does not exist. It’s not called as a macro.
  • The example is describing how to place a value into a register operand of an instruction - clearly not an immediate value!

In reality it is a mishmash of examples of an obsolete feature taken incorrectly out of context, glued together with a plausible seeming but imaginary and impossible feature.

A quick google shows the actual syntax for passing an immediate to the old asm! macro as:

#![feature(asm)]
fn main() {
    unsafe { asm!("call $0" :: "i"(test as *const u8) :: "intel"); }
}
extern fn test() {}

Let’s try to get it to use the new style asm!

“pass an immediate value with the new rust asm! macro.”

The example no longer includes any attempt at passing an immediate value. The description has merged parts of the old and new syntax. The imm parameter attribute is what I’m looking for, but I can find no evidence that it actually exists!


What I’d like to do is this:

const MIE_MSI_BIT_MASK: u32 = 0x8;
...
csr_set_bits_imm_mie(MIE_MSI_BIT_MASK);

and generate the assembler code:

    csrrsi    zero, mie, 0x8

In C it would look like this:

/* mie, CSR set bits via immediate value mask (only up to 5 bits) */
#define CSR_SET_BITS_IMM_MIE(MASK)                 \
    __asm__ volatile ("csrrsi    zero, mie, %0"          \
                      : /* output: none */                        \
                      : "i" (MASK)  /* input : immediate  */      \
                      : /* clobbers: none */)

#define MIE_MSI_BIT_MASK     0x8

CSR_SET_BITS_IMM_MIE(MIE_MSI_BIT_MASK)

The real issue is getting a Rust constant item into a macro string.

My final question for ChatGPT:

“how can i pass a const item to a rust macro”

It’s suggested I use the constify! macro. The issue is I can’t find any evidence of this existing either. It’s not in const_fn. There is a constify_imm8! macro in in the coresimd crate.


My temporary solution is:

macro_rules! csr_set_bits_imm_mie {
    ( $value:expr ) => (
        unsafe {
            use core::arch::asm;
            asm!(concat!("csrrsi    zero, mie, ", stringify!($value)));
        }
    );
}
    csr_set_bits_imm_mie!(0x8);

This generates the correct code:

    csrrsi    zero, mie, 0x8

However, passing a constant as below:

const MIE_MSI_BIT_MASK: u32 = 0x8;

    csr_set_bits_imm_mie!(MIE_MSI_BIT_MASK);

Will inline the constant item token - not the value.

    csrrsi    zero, mie, MIE_MSI_BIT_MASK

Looking at the answers in details shows a mix of outcomes. There is plausable, but made-up, rubbish - or the plain impossible (red). There is also the reasonably correct starting points (green). Finally, some obsolete and/or not quite right but getting there (orange) sections. The purpose here is not to knitpick a dumb machine that isn’t really designed to do this, but to highlight the verbalist nature of the machine. While it can’t actually solve a problem like an engineer operating from first principles, it can make a great attempt at explaining a bogus solution.

Question

It’s actually amazing that ChatGPT can drill down to the correct technology area and infer plausible sounding, but not existent solutions.