I am looking into using the PDEP/PEXT machine instructions as part of Nim proc:s and it seems to me that the asm keyword requires that you somehow know which registers contains which variable.
So I am thinking using the intrinsic C functions like: unsigned __int64 _pext_u64(unsigned __int64 src, unsigned __int64 mask); through the foreign function interface makes more sense.
Is this right or am I missing something?
you somehow know which registers contains which variable.
You can use the backticks to get existing variables, see the docs at https://nim-lang.org/docs/manual.html#statements-and-expressions-assembler-statement
I am looking into using the PDEP/PEXT machine instructions as part of Nim proc:s and it seems to me that the asm keyword requires that you somehow know which registers contains which variable.
No you can use GCC/Clang extended ASM.
func add256_asm(a: var BigInt[256], b: BigInt[256]) {.noinline.}=
  var tmp: uint64
  
  when defined(gcc):
    asm """
      movq 0+%[b], %[tmp]
      addq %[tmp], 0+%[a]
      
      movq 8+%[b], %[tmp]
      adcq %[tmp], 8+%[a]
      
      movq 16+%[b], %[tmp]
      adcq %[tmp], 16+%[a]
      
      movq 24+%[b], %[tmp]
      adcq %[tmp], 24+%[a]
      : [tmp] "+r" (`tmp`), [a] "=&m" (`a->limbs[0]`)
      : [b] "m"(`b->limbs[0]`)
      : "cc"
    """
  elif defined(clang):
    # https://lists.llvm.org/pipermail/llvm-dev/2017-August/116202.html
    # Remove the 0 from 8+0 when the proc is inline ....
    asm """
      movq 0+0%[b], %[tmp]
      addq %[tmp], 0+0%[a]
      
      movq 8+0%[b], %[tmp]
      adcq %[tmp], 8+0%[a]
      
      movq 16+0%[b], %[tmp]
      adcq %[tmp], 16+0%[a]
      
      movq 24+0%[b], %[tmp]
      adcq %[tmp], 24+0%[a]
      : [tmp] "+r" (`tmp`), [a] "=&m" (`a->limbs[0]`)
      : [b] "m"(`b->limbs[0]`)
      : "cc"
    """
  else:
    {.error: "Unsupported compiler".}