paq7asm.asm
Upload User: lian147
Upload Date: 2021-07-11
Package Size: 177k
Code Size: 4k
Development Platform:

Visual C++

  1. ; NASM assembly language code for PAQ7.
  2. ; (C) 2005, Matt Mahoney.
  3. ; This is free software under GPL, http://www.gnu.org/licenses/gpl.txt
  4. ;
  5. ;   MINGW g++:     nasm paq7asm.asm -f win32 --prefix _
  6. ;   DJGPP g++:     nasm paq7asm.asm -f coff  --prefix _
  7. ;   Borland, Mars: nasm paq7asm.asm -f obj   --prefix _
  8. ;   Linux:         nasm paq7asm.asm -f elf
  9. ;
  10. ; For other Windows compilers try -f win32 or -f obj.  Some old versions
  11. ; of Linux should use -f aout instead of -f elf.
  12. ;
  13. ; This code will only work on a Pentium-MMX or higher.  It doesn't
  14. ; use extended (Katmai/SSE) instructions.  It won't work
  15. ; in 64-bit mode.
  16. section .text use32 class=CODE
  17. ; Reset after MMX
  18. global do_emms
  19. do_emms:
  20.   emms
  21.   ret
  22. ; Vector product a*b of n signed words, returning signed dword scaled
  23. ; down by 8 bits. n is rounded up to a multiple of 8.
  24. global dot_product ; (short* a, short* b, int n)
  25. align 16
  26. dot_product:
  27.   mov eax, [esp+4]      ; a
  28.   mov edx, [esp+8]      ; b
  29.   mov ecx, [esp+12]     ; n
  30.   add ecx, 7            ; n rounding up
  31.   and ecx, -8
  32.   jz .done
  33.   sub eax, 8
  34.   sub edx, 8
  35.   pxor mm0, mm0         ; sum = 0
  36. .loop:                  ; each loop sums 4 products
  37.   movq mm1, [eax+ecx*2] ; put halves of vector product in mm0
  38.   pmaddwd mm1, [edx+ecx*2]
  39.   movq mm2, [eax+ecx*2-8]
  40.   pmaddwd mm2, [edx+ecx*2-8]
  41.   psrad mm1, 8
  42.   psrad mm2, 8
  43.   paddd mm0, mm1
  44.   paddd mm0, mm2
  45.   sub ecx, 8
  46.   ja .loop
  47.   movq mm1, mm0         ; add 2 halves of mm0 and return in eax
  48.   psrlq mm1, 32
  49.   paddd mm0, mm1
  50.   movd eax, mm0
  51.   emms
  52. .done
  53.   ret
  54. ; This should work on a Pentium 4 or higher in 32-bit mode,
  55. ; but it isn't much faster than the MMX version so I don't use it.
  56. global dot_product_sse2 ; (short* a, short* b, int n)
  57. align 16
  58. dot_product_sse2:
  59.   mov eax, [esp+4]      ; a
  60.   mov edx, [esp+8]      ; b
  61.   mov ecx, [esp+12]     ; n
  62.   add ecx, 7            ; n rounding up
  63.   and ecx, -8
  64.   jz .done
  65.   sub eax, 16
  66.   sub edx, 16
  67.   pxor xmm0, xmm0       ; sum = 0
  68. .loop:                  ; each loop sums 4 products
  69.   movdqa xmm1, [eax+ecx*2] ; put parital sums of vector product in xmm0
  70.   pmaddwd xmm1, [edx+ecx*2]
  71.   psrad xmm1, 8
  72.   paddd xmm0, xmm1
  73.   sub ecx, 8
  74.   ja .loop
  75.   movdqa xmm1, xmm0      ; add 4 parts of xmm0 and return in eax
  76.   psrldq xmm1, 8
  77.   paddd xmm0, xmm1
  78.   movdqa xmm1, xmm0
  79.   psrldq xmm1, 4
  80.   paddd xmm0, xmm1
  81.   movd eax, xmm0
  82. .done
  83.   ret
  84. ; Train n neural network weights w[n] on inputs t[n] and err.
  85. ; w[i] += t[i]*err*2+1 >> 17 bounded to +- 32K.
  86. ; n is rounded up to a multiple of 8.
  87. global train ; (short* t, short* w, int n, int err)
  88. align 16
  89. train:
  90.   mov eax, [esp+16]     ; err
  91.   and eax, 0xffff       ; put 4 copies of err in mm0
  92.   movd mm0, eax
  93.   movd mm1, eax
  94.   psllq mm1, 16
  95.   por mm0, mm1
  96.   movq mm1, mm0
  97.   psllq mm1, 32
  98.   por mm0, mm1
  99.   pcmpeqb mm1, mm1      ; 4 copies of 1 in mm1
  100.   psrlw mm1, 15
  101.   mov eax, [esp+4]      ; t
  102.   mov edx, [esp+8]      ; w
  103.   mov ecx, [esp+12]     ; n
  104.   add ecx, 7            ; n/8 rounding up
  105.   and ecx, -8
  106.   sub eax, 8
  107.   sub edx, 8
  108.   jz .done
  109. .loop:                  ; each iteration adjusts 8 weights
  110.   movq mm2, [edx+ecx*2] ; w[i]
  111.   movq mm3, [eax+ecx*2] ; t[i]
  112.   movq mm4, [edx+ecx*2-8] ; w[i]
  113.   movq mm5, [eax+ecx*2-8] ; t[i]
  114.   paddsw mm3, mm3
  115.   paddsw mm5, mm5
  116.   pmulhw mm3, mm0
  117.   pmulhw mm5, mm0
  118.   paddsw mm3, mm1
  119.   paddsw mm5, mm1
  120.   psraw mm3, 1
  121.   psraw mm5, 1
  122.   paddsw mm2, mm3
  123.   paddsw mm4, mm5
  124.   movq [edx+ecx*2], mm2
  125.   movq [edx+ecx*2-8], mm4
  126.   sub ecx, 8
  127.   ja .loop
  128. .done:
  129.   emms
  130.   ret