> 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.

<https://github.com/mratsim/finite-fields/blob/97e40060cefeb4e2ef5fc5a1c355977caae79674/add_carry.nim#L73-L113>
    
    
    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".}
    
    
    Run

Reply via email to