CRC32 in Basic and inline assembler x86, x86_64

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

CRC32 in Basic and inline assembler x86, x86_64

Post by D.J.Peters »

The BASIC version can be used on __FB_ARM__ devices.
I never learned ARM assembler may be in future for FBSound 2.0 :-)

Joshy

Code: Select all

dim shared as ulong CRC32Table(255) => { _
&H00000000, &H77073096, &HEE0E612C, &H990951BA, _
&H076DC419, &H706AF48F, &HE963A535, &H9E6495A3, _
&H0EDB8832, &H79DCB8A4, &HE0D5E91E, &H97D2D988, _
&H09B64C2B, &H7EB17CBD, &HE7B82D07, &H90BF1D91, _
&H1DB71064, &H6AB020F2, &HF3B97148, &H84BE41DE, _
&H1ADAD47D, &H6DDDE4EB, &HF4D4B551, &H83D385C7, _
&H136C9856, &H646BA8C0, &HFD62F97A, &H8A65C9EC, _
&H14015C4F, &H63066CD9, &HFA0F3D63, &H8D080DF5, _
&H3B6E20C8, &H4C69105E, &HD56041E4, &HA2677172, _
&H3C03E4D1, &H4B04D447, &HD20D85FD, &HA50AB56B, _
&H35B5A8FA, &H42B2986C, &HDBBBC9D6, &HACBCF940, _
&H32D86CE3, &H45DF5C75, &HDCD60DCF, &HABD13D59, _
&H26D930AC, &H51DE003A, &HC8D75180, &HBFD06116, _
&H21B4F4B5, &H56B3C423, &HCFBA9599, &HB8BDA50F, _
&H2802B89E, &H5F058808, &HC60CD9B2, &HB10BE924, _
&H2F6F7C87, &H58684C11, &HC1611DAB, &HB6662D3D, _
&H76DC4190, &H01DB7106, &H98D220BC, &HEFD5102A, _
&H71B18589, &H06B6B51F, &H9FBFE4A5, &HE8B8D433, _
&H7807C9A2, &H0F00F934, &H9609A88E, &HE10E9818, _
&H7F6A0DBB, &H086D3D2D, &H91646C97, &HE6635C01, _
&H6B6B51F4, &H1C6C6162, &H856530D8, &HF262004E, _
&H6C0695ED, &H1B01A57B, &H8208F4C1, &HF50FC457, _
&H65B0D9C6, &H12B7E950, &H8BBEB8EA, &HFCB9887C, _
&H62DD1DDF, &H15DA2D49, &H8CD37CF3, &HFBD44C65, _
&H4DB26158, &H3AB551CE, &HA3BC0074, &HD4BB30E2, _
&H4ADFA541, &H3DD895D7, &HA4D1C46D, &HD3D6F4FB, _
&H4369E96A, &H346ED9FC, &HAD678846, &HDA60B8D0, _
&H44042D73, &H33031DE5, &HAA0A4C5F, &HDD0D7CC9, _
&H5005713C, &H270241AA, &HBE0B1010, &HC90C2086, _
&H5768B525, &H206F85B3, &HB966D409, &HCE61E49F, _
&H5EDEF90E, &H29D9C998, &HB0D09822, &HC7D7A8B4, _
&H59B33D17, &H2EB40D81, &HB7BD5C3B, &HC0BA6CAD, _
&HEDB88320, &H9ABFB3B6, &H03B6E20C, &H74B1D29A, _
&HEAD54739, &H9DD277AF, &H04DB2615, &H73DC1683, _
&HE3630B12, &H94643B84, &H0D6D6A3E, &H7A6A5AA8, _
&HE40ECF0B, &H9309FF9D, &H0A00AE27, &H7D079EB1, _
&HF00F9344, &H8708A3D2, &H1E01F268, &H6906C2FE, _
&HF762575D, &H806567CB, &H196C3671, &H6E6B06E7, _
&HFED41B76, &H89D32BE0, &H10DA7A5A, &H67DD4ACC, _
&HF9B9DF6F, &H8EBEEFF9, &H17B7BE43, &H60B08ED5, _
&HD6D6A3E8, &HA1D1937E, &H38D8C2C4, &H4FDFF252, _
&HD1BB67F1, &HA6BC5767, &H3FB506DD, &H48B2364B, _
&HD80D2BDA, &HAF0A1B4C, &H36034AF6, &H41047A60, _
&HDF60EFC3, &HA867DF55, &H316E8EEF, &H4669BE79, _
&HCB61B38C, &HBC66831A, &H256FD2A0, &H5268E236, _
&HCC0C7795, &HBB0B4703, &H220216B9, &H5505262F, _
&HC5BA3BBE, &HB2BD0B28, &H2BB45A92, &H5CB36A04, _
&HC2D7FFA7, &HB5D0CF31, &H2CD99E8B, &H5BDEAE1D, _
&H9B64C2B0, &HEC63F226, &H756AA39C, &H026D930A, _
&H9C0906A9, &HEB0E363F, &H72076785, &H05005713, _
&H95BF4A82, &HE2B87A14, &H7BB12BAE, &H0CB61B38, _
&H92D28E9B, &HE5D5BE0D, &H7CDCEFB7, &H0BDBDF21, _
&H86D3D2D4, &HF1D4E242, &H68DDB3F8, &H1FDA836E, _
&H81BE16CD, &HF6B9265B, &H6FB077E1, &H18B74777, _
&H88085AE6, &HFF0F6A70, &H66063BCA, &H11010B5C, _
&H8F659EFF, &HF862AE69, &H616BFFD3, &H166CCF45, _
&HA00AE278, &HD70DD2EE, &H4E048354, &H3903B3C2, _
&HA7672661, &HD06016F7, &H4969474D, &H3E6E77DB, _
&HAED16A4A, &HD9D65ADC, &H40DF0B66, &H37D83BF0, _
&HA9BCAE53, &HDEBB9EC5, &H47B2CF7F, &H30B5FFE9, _
&HBDBDF21C, &HCABAC28A, &H53B39330, &H24B4A3A6, _
&HBAD03605, &HCDD70693, &H54DE5729, &H23D967BF, _
&HB3667A2E, &HC4614AB8, &H5D681B02, &H2A6F2B94, _
&HB40BBE37, &HC30C8EA1, &H5A05DF1B, &H2D02EF8D }

function BasicCRC32(byval buffer as any ptr, byval nBytes as long) as ulong
  dim as ubyte ptr p = buffer
  dim as ubyte ptr e = p + nBytes
	dim as ulong crc = &HFFFFFFFF
	while (p<e)
		crc = crc32table((crc xor *p) and &HFF) xor (crc shr 8)
    p+=1
  wend  
	return crc xor &HFFFFFFFF
end function


function AsmCRC32(byval pAnyBuffer as const any ptr, byval BufferSize as integer) as ulong
  dim as ulong ptr pTable = @CRC32Table(0)
  dim as ubyte ptr pBuffer = cptr(ubyte ptr,pAnyBuffer)
  if pBuffer = 0 then return 0
  if BufferSize < 1 then Return 0

#if __FB_ASM__ = "intel"

 #ifndef __FB_64BIT__  
  asm
    mov edi,[pBuffer]
    mov esi,[pTable]
    mov ecx,[BufferSize]
    mov eax,&HFFFFFFFF
    mov edx,&H000000FF
    push ebp
    mov ebp,edx
    Xor edx,edx
    loop_it:
      mov dl,[edi]
      mov ebx,eax
      Xor eax,edx
      And eax,ebp
      Shr ebx,8
      mov eax,[esi+eax*4]
      inc edi
      Xor eax,ebx
      dec ecx
    jnz loop_it
    pop ebp
    Xor eax,&HFFFFFFFF
    mov [function],eax
  End asm
 #else
  asm
    mov rdi,[pBuffer]
    mov rsi,[pTable]
    mov rcx,[BufferSize]
    xor rax,rax          ' clear high part
    mov eax,&HFFFFFFFF   ' load low part
    mov edx,&H000000FF
    push rbp
    mov ebp,edx
    Xor edx,edx
    loop_it:
      mov dl,[rdi]
      mov ebx,eax
      Xor eax,edx
      And eax,ebp
      Shr ebx,8
      mov eax,[rsi+rax*4]
      inc edi
      Xor eax,ebx
      dec rcx
    jnz loop_it
    pop rbp
    Xor eax,&HFFFFFFFF
    mov [function],eax
  End asm
 #endif
#else
  #error 666: commpile with -asm intel !
#endif
End Function

dim as integer nBytes = 1024*1024
dim as ubyte ptr buffer = allocate(nBytes)
for i as integer = 0 to nBytes-1
  buffer[i]=rnd*256
next

dim as ulong CRC1,CRC2

print "Run CRC32 in BASIC 1000 times ..."

var t1=Timer()
for i as integer=1 to 1000  
  CRC1 = BasicCRC32(buffer,nBytes)
next
t1=Timer()-t1

#ifndef __FB_64BIT__
print "Run CRC32 in x86 Assembler 1000 times ..."
#else
print "Run CRC32 in x86_64 Assembler 1000 times ..."
#endif

var t2=Timer()
for i as integer=1 to 1000  
  CRC2 = AsmCRC32(buffer,nBytes)
next
t2 = Timer()-t2 

print "BASIC     : " & t1 & " 0x" & hex(CRC1,8)
print "Assembler : " & t2 & " 0x" & hex(CRC2,8)
sleep
Post Reply