News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Is there a better way to test an XMM register for all bits set to 1?

Started by Rav, August 29, 2022, 08:58:35 AM

Previous topic - Next topic

Rav

Given the following snippet of code:

movdqu xmm1,[esi] ; Load an OWORD.
ptest xmm1,xmm1 ; See if all bits are 0.
jz IsAllZeros ; Jump if so.
pcmpeqw xmm0,xmm0 ; Set another XMM register to have all bits set to 1.
pxor xmm1,xmm0 ; XOR that with our loaded OWORD, which will turn any 1 bits to 0 (destroys xmm1; not important).
ptest xmm1,xmm1 ; See if all XOR'd bits are now 0, meaning all bits in our loaded OWORD were 1.
jz IsAllOnes ; Jump if so.

Testing an XMM register to see if all 128 bits are 0 is simple -- that's just PTEST and JZ.  But is there a better (faster) way to test if all 128 bits are 1 than the method I'm using above?  I couldn't find a compare instruction that would test the entire XMM register as one unit (all 128 bits).

Thanks.

jj2007

include \masm32\include\masm32rt.inc
.686p
.xmm
.code
Align 16
MinusOne OWORD -1
MyOm1 OWORD -1
MyO0 OWORD 0
MyOp1 OWORD +1
start:
  cls
  movdqu xmm1, MyOm1
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
print "all ones", 13, 10
  .elseif Zero?
print "all zeros", 13, 10
  .else
print "not all ones", 13, 10
  .endif
  movdqu xmm1, MyOp1
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
print "all ones", 13, 10
  .elseif Zero?
print "all zeros", 13, 10
  .else
print "not all ones", 13, 10
  .endif
  movdqu xmm1, MyO0
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
inkey "all ones"
  .elseif Zero?
print "all zeros", 13, 10
  .else
inkey "not all ones"
  .endif
  exit
end start

Rav

Perfect!  Thank you!  I had read about the carry flag being set based on the result of AND NOT, but I couldn't think of what to AND NOT it with to always come up with the correct answer.  Thanks again.


Quote from: jj2007 on August 29, 2022, 10:02:34 AM
include \masm32\include\masm32rt.inc
.686p
.xmm
.code
Align 16
MinusOne OWORD -1
MyOm1 OWORD -1
MyO0 OWORD 0
MyOp1 OWORD +1
start:
  cls
  movdqu xmm1, MyOm1
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
print "all ones", 13, 10
  .elseif Zero?
print "all zeros", 13, 10
  .else
print "not all ones", 13, 10
  .endif
  movdqu xmm1, MyOp1
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
print "all ones", 13, 10
  .elseif Zero?
print "all zeros", 13, 10
  .else
print "not all ones", 13, 10
  .endif
  movdqu xmm1, MyO0
  ptest xmm1, MinusOne ; See if all bits are 1
  .if Carry?
inkey "all ones"
  .elseif Zero?
print "all zeros", 13, 10
  .else
inkey "not all ones"
  .endif
  exit
end start


hutch--


    comisd      ; compare two dbl values and set eflags (jz jnz je jne etc...)

InfiniteLoop

vmovdqu xmm0,xmmword ptr []
vpcmpeqd xmm1,xmm1,xmm1
vptest xmm0,xmm1

jc [] ;all 1's, CF == 1

jnc[] ;else, CF ==0

CF == (NOT xmm0 & xmm1 == 0)