Conversation
src/core/thread/osthread.d
Outdated
| asm { "stp x21, x22, %0" : "=m" regs[ 2], "=m" regs[3]; } | ||
| asm { "stp x23, x24, %0" : "=m" regs[ 4], "=m" regs[5]; } | ||
| asm { "stp x25, x26, %0" : "=m" regs[ 6], "=m" regs[7]; } | ||
| asm { "stp x27, x28, %0" : "=m" regs[ 8], "=m" regs[9]; } |
There was a problem hiding this comment.
The 2nd output operand is unused in the template, but I've added it to let LLVM know that 2 registers are stored per asm statement.
| * the slightly different meaning the function must neither be inlined | ||
| * nor naked. | ||
| */ | ||
| package(core.thread) void* getStackTop() nothrow @nogc |
There was a problem hiding this comment.
This was only refactored because I think the previously naked getStackTop() would have returned a wrong stack-top (caller's frame base) in this fallback case.
src/core/thread/osthread.d
Outdated
| static foreach (i; 0 .. regs.length) | ||
| {{ | ||
| enum int j = 16 + i; // source register | ||
| asm { (store ~ " $"~j.stringof~", %0") : "=m" regs[i]; } |
There was a problem hiding this comment.
I've verified that these multiple asm statements with an indirect output operand each yield a final asm equivalent to the previous implementation (which didn't mark the regs memory as being clobbered).
There was a problem hiding this comment.
Btw, {{ => separate scope for each static foreach iteration, required to prevent enum int j clashes. That enum is required to constant-fold the source register number, so that it can be converted to a string via j.stringof.
__asm is still useful in a couple of places (e.g., one-liners), so I haven't replaced all occurrences. core.cpuid now uses the existing assembly for GDC.
__asmis still useful in a couple of places (e.g., one-liners), so I haven't replaced all occurrences.core.cpuidnow uses the existing assembly for GDC.