So here is my variant of this procedure. It's optimized for small amounts of data. It uses SSE2 if data is 16 byte or bigger.
Returns #False if data contains only zeros, returns #True otherwise.
Code: Select all
Procedure NoneZero(*DestBufStart, DestBufSize.i)
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!push edi
!push ebx
!mov edi,[p.p_DestBufStart+8]
!mov edx,[p.v_DestBufSize+8]
!mov ecx,edx
!mov ebx,ecx
!shr edx,4
!and ecx,15
!shr ecx,2
!and ebx,3
!test edx,edx
!je NoneZero_FirstEnd
!pxor xmm1,xmm1
!align 4
!NoneZero_FirstStart:
!movdqu xmm0,[edi]
!pcmpeqb xmm0,xmm1
!add edi,16
!pmovmskb eax,xmm0
!cmp eax,$0000FFFF
!jne NoneZero_EndTrueSse
!dec edx
!jne NoneZero_FirstStart
!emms
!align 4
!NoneZero_FirstEnd:
!test ecx,ecx
!je NoneZero_SecondEnd
!align 4
!NoneZero_SecondStart:
!mov eax,[edi]
!test eax,eax
!jne NoneZero_EndTrue
!add edi,4
!dec ecx
!jne NoneZero_SecondStart
!align 4
!NoneZero_SecondEnd:
!test ebx,ebx
!je NoneZero_ThirdEnd
!align 4
!NoneZero_ThirdStart:
!mov al,[edi]
!test al,al
!jne NoneZero_EndTrue
!inc edi
!dec ebx
!jne NoneZero_ThirdStart
!align 4
!NoneZero_ThirdEnd:
!pop ebx
!pop edi
ProcedureReturn #False
!NoneZero_EndTrue:
!pop ebx
!pop edi
ProcedureReturn #True
!NoneZero_EndTrueSse:
!pop ebx
!pop edi
!emms
ProcedureReturn #True
CompilerCase #PB_Processor_x64
!push rdi
!push rbx
!mov rdi,[p.p_DestBufStart+16]
!mov rdx,[p.v_DestBufSize+16]
!mov rcx,rdx
!mov rbx,rcx
!shr rdx,4
!and rcx,15
!shr rcx,2
!and rbx,3
!test rdx,rdx
!je NoneZero_FirstEnd
!pxor xmm1,xmm1
!align 8
!NoneZero_FirstStart:
!movdqu xmm0,[rdi]
!pcmpeqb xmm0,xmm1
!add rdi,16
!pmovmskb eax,xmm0
!cmp eax,$0000FFFF
!jne NoneZero_EndTrueSse
!dec rdx
!jne NoneZero_FirstStart
!emms
!align 8
!NoneZero_FirstEnd:
!test rcx,rcx
!je NoneZero_SecondEnd
!align 8
!NoneZero_SecondStart:
!mov eax,[rdi]
!test eax,eax
!jne NoneZero_EndTrue
!add rdi,4
!dec rcx
!jne NoneZero_SecondStart
!align 8
!NoneZero_SecondEnd:
!test rbx,rbx
!je NoneZero_ThirdEnd
!align 8
!NoneZero_ThirdStart:
!mov al,[rdi]
!test al,al
!jne NoneZero_EndTrue
!inc rdi
!dec rbx
!jne NoneZero_ThirdStart
!align 8
!NoneZero_ThirdEnd:
!pop rbx
!pop rdi
ProcedureReturn #False
!NoneZero_EndTrue:
!pop rbx
!pop rdi
ProcedureReturn #True
!NoneZero_EndTrueSse:
!pop rbx
!pop rdi
!emms
ProcedureReturn #True
CompilerEndSelect
EndProcedure