Iain Buclaw
| https://issues.dlang.org/show_bug.cgi?id=20594
--- Comment #2 from Iain Buclaw <ibuclaw@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";
}
}
```
--
|