[Issue 20594] [GCC ASM] Should the asm { } syntax be modernized for D2?

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed Feb 15 20:23:31 UTC 2023


https://issues.dlang.org/show_bug.cgi?id=20594

--- Comment #2 from Iain Buclaw <ibuclaw at gdcproject.org> ---
Another alternative that may prove nicer, is the use of `arg => value` instead.
 This also allows for each argument/property of the GCC-style assembler
statement to be optionally added.

However, there is also DIP88 to consider, which has adopted `arg: value` for
named parameters.  So can't ignore the original alternative syntax suggested in
2020.

If going for named arguments, can also add a few more to expose the underbelly
of the implementation to the user, for example `volatile` and `inline`.

Alternative syntax #1
```
asm @safe @nogc nothrow pure {
    "insn-template",          // can be CTFE-able expression with string result
    inputs   => ("a", value), // simple example, single input/output
    outputs  => [             // complex example, multiple input/outputs
        ("=a", result),
        ("=g", overflow)
    ],
    clobber  => "eax",        // or ["eax", "memory", ...]
    goto     => label,        // or [label1, label2, ...]
    volatile => true,         // default true, accept "false" as optimization
    inline   => true,         // default false, allow pragma(inline, true) to
                              // set if not specified
}
```

Alternative syntax #2
```
asm @safe @nogc nothrow pure {
    "insn-template",       // can be CTFE-able expression with string result
    inputs: ("a", value),  // simple example, single input/output
    outputs: [             // complex example, multiple input/outputs
        ("=a", result),
        ("=g", overflow)
    ],
    clobber: "eax",        // or ["eax", "memory", ...]
    goto: label,           // or [label1, label2, ...]
    volatile: true,        // default true, accept "false" as optimization
    inline: true,          // default false, allow pragma(inline, true) to
                           // set if not specified
}
```

Example 1:
```
int foo(int count)
{
    version (GNU_Alternate1_Asm)
    {
        asm { "dec %0, jb %l[stop]",
              goto => stop,
              outputs => ("+r", count);
              volatile => false;
        }
    }
    else version (GNU_Alternate2_Asm)
    {
        asm { "dec %0, jb %l[stop]",
              goto: stop,
              outputs: ("+r", count);
              volatile: false;
        }
    }
    else  // old-style syntax
    {
        asm { "dec %0, jb %l[stop]"
              : "+r" (count)
              : /* No inputs */
              : /* No clobbers */
              : stop;
        }
    }
  return count;
stop:
  return 0;
}
```

Example 2:
```
version (GNU_Alternate1_Asm)
{
    asm pure nothrow @nogc {
        "cpuid",
        outputs => [("=a", a), ("=b", b)],
        inputs  => ("a", 0x8000_001E),
        clobber => ["ecx", "edx"];
    }
}
else version (GNU_Alternate2_Asm)
{
    asm pure nothrow @nogc {
        "cpuid",
        outputs: [("=a", a), ("=b", b)],
        inputs:  ("a", 0x8000_001E),
        clobber: ["ecx", "edx"];
    }
}
else  // old-style syntax
{
    asm pure nothrow @nogc {
        "cpuid"
        : "=a" (a), "=b" (b)
        : "a" (0x8000_001E)
        : "ecx", "edx";
    }
}
```

--


More information about the Digitalmars-d-bugs mailing list