DRVTiny

bit_scan_f.pl

Aug 5th, 2021
846
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/perl
  2. use 5.16.1;
  3. use strict;
  4. use warnings;
  5. use Inline C => <<'...';
  6. void bit_scan_f(int n, int start) {
  7.   int res[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  8.   __asm__ __volatile__ (
  9.        "xorl %%eax, %%eax\n"
  10.        "leaq (%[res]), %%rdi\n"
  11.        "movl %1, %%ecx\n"
  12.        "movl %0, %%edx\n"
  13.        "inloop:\n"
  14.        "shrl %%cl, %%edx\n"
  15.        "orl %%edx, %%edx\n"
  16.        "jz outloop\n"
  17.        "bsf %%edx, %%ecx\n"
  18.        "addl %%ecx, %%eax\n"
  19.        "movl %%eax, (%%rdi)\n"
  20.        "leaq 4(%%rdi), %%rdi\n"
  21.        "incl %%eax\n"
  22.        "incl %%ecx\n"
  23.        "jmp inloop\n"
  24.        "outloop:\n"
  25.        "cmpl $32, %%eax\n"
  26.        "jge skip128\n"
  27.        "movl $128, (%%rdi)\n"
  28.        "skip128:\n"
  29.       :
  30.       : "r"(n),"r"(start),[res]"r"(&res)
  31.       : "%eax", "%ecx", "%edx", "%rdi"
  32.   );
  33.   Inline_Stack_Vars;
  34.   Inline_Stack_Reset;  
  35.   for (int i=0; i<32; i++) {
  36.     if (res[i] == 128) { break; }
  37.     Inline_Stack_Push(sv_2mortal(newSViv(res[i])));
  38. //    printf("%d: %d\n", i, res[i]);
  39.   }
  40.   Inline_Stack_Done;
  41. }
  42. ...
  43.  
  44. say '[' .
  45.     join(', ' => bit_scan_f($ARGV[0] // 0 + 0, $ARGV[1] // 0))
  46.     . ']';
  47.  
RAW Paste Data