A minimal implementation of asm! is actually not that complicated since 90% of the work can be offloaded by invoking the system assembler. Here's a rough outline of how it could work:
-
Run register allocation on the asm fragment, using the constraints specified in the
asm!. You may need to extend your compiler's register allocator to support this. -
Perform string substitution to replace the placeholders with actual register names.
-
Generate an external asm file with the following contents (replace
${ID}with some unique identifier):
.section .text.inline_asm_${ID},"ax",@progbits
.globl inline_asm_${ID}
.type inline_asm_${ID}, @function
inline_asm_${ID}:
/* <insert asm string here with registers filled in> */
jmp inline_asm_${ID}_return
.size inline_asm_${ID}, . - inline_asm_${ID}
- For the actual code generation of the
asm!in your compiler, just emit a jump to the external asm block, and a label for the external asm to return to:
// ...
jmp inline_asm_${ID}
.globl inline_asm_${ID}_return
inline_asm_${ID}_return:
// ...
- Assemble and link in the generated extern asm files.