News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

a shift (shl shr) on a 64 bits constants

Started by ToutEnMasm, June 11, 2009, 06:13:05 AM

Previous topic - Next topic

ToutEnMasm


Ok , thinks are more clear now.
I prefered (perhaps i am false in that) the shl on to dwords than the sse soluce.

Quote
Are you wanting an equate (EQU) or a memory qword? What context are you using this in?
This is to make work speech recognition (SAPI).The sample I follow use the instruction below.
SPEI is a macro (SDK spi51.h or .sdk) who made a shift on constants of qword size.
If it is not possible to make it only in declaration,i have no choice.I take the qword in data as a soluce
Quote
   cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION));
SPEI_RECOGNITION= 38  ; made a shl of 38


jj2007

Here's a full set of choices :bg

include \masm32\include\masm32rt.inc
.686
.xmm

;; simple and non-SSE2, 29 bytes **************

shl64 MACRO arg, ct
mov eax, dword ptr arg
mov edx, dword ptr &arg&+4
shld edx, eax, ct
shl eax, ct
mov dword ptr arg, eax
mov dword ptr &arg&+4, edx
ENDM

shr64 MACRO arg, ct
mov eax, dword ptr arg
mov edx, dword ptr &arg&+4
shrd eax, edx, ct
shr edx, ct
mov dword ptr arg, eax
mov dword ptr &arg&+4, edx
ENDM

;; elegant but SSE2 only, 30 bytes **************

shl64x MACRO arg, ct
  movq xmm0, arg
  push ct
  movd xmm1, dword ptr [esp]
  psllq xmm0, xmm1
  movq arg, xmm0
  add esp, 4
ENDM

shr64x MACRO arg, ct
  movq xmm0, arg
  push ct
  movd xmm1, dword ptr [esp]
  psrlq xmm0, xmm1
  movq arg, xmm0
  add esp, 4
ENDM

;; the complicated way, non-SSE2, 37 bytes ********

shl64z MACRO arg, ct
mov ecx, ct
mov eax, dword ptr arg
mov edx, dword ptr &arg&+4
.Repeat
shl edx, 1
shl eax, 1
adc edx, 0 ; yep ;-)
dec ecx
.Until Zero?
mov dword ptr arg, eax
mov dword ptr &arg&+4, edx
ENDM

shr64z MACRO arg, ct
mov ecx, ct
mov eax, dword ptr arg
mov edx, dword ptr &arg&+4
.Repeat
shr eax, 1
shr edx, 1
jnc @F
btc eax, 31
@@: dec ecx
.Until Zero?
mov dword ptr arg, eax
mov dword ptr &arg&+4, edx
ENDM

.data
MyQw dq 0000FFFFFFFF0000h

.code
start:
print "MyQw, original = ", 9
print xqword$(MyQw), 13, 10
shl64 MyQw, 3
print "MyQw, shl3 =    ", 9
print xqword$(MyQw), 13, 10
shr64 MyQw, 3
print "MyQw, shr3 =    ", 9
print xqword$(MyQw), 13, 10, 10

print "MyQw, original = ", 9
print xqword$(MyQw), 13, 10
shl64x MyQw, 3
print "MyQw, shl3 =    ", 9
print xqword$(MyQw), 13, 10
shr64x MyQw, 3
print "MyQw, shr3 =    ", 9
print xqword$(MyQw), 13, 10, 10

print "MyQw, original = ", 9
print xqword$(MyQw), 13, 10
shl64z MyQw, 3
print "MyQw, shl3 =    ", 9
print xqword$(MyQw), 13, 10
shr64z MyQw, 3
print "MyQw, shr3 =    ", 9
print xqword$(MyQw), 13, 10, 10

getkey
exit
end start

ToutEnMasm


FORTRANS

#18
Hi,

   Instead of;


.Repeat
        shl     edx, 1
        shl     eax, 1
        adc     edx, 0 ; yep ;-)
        dec     ecx
.Until Zero?

.Repeat
        shr     eax, 1
        shr     edx, 1
        jnc      @F
        btc     eax, 31
@@:     dec     ecx
.Until Zero?


Why not


.Repeat
        shl     eax, 1
        RCL     edx, 1
        dec     ecx
.Until Zero?

.Repeat
        shr     edx, 1
        RCR     eax, 1
        dec     ecx
.Until Zero?


   Seems nicer to me?

Steve N.

Edit, out of order registers.

ToutEnMasm


Not so marvelous and not so nicer , a little problem occure.
the SHL couldnt pass 31 shift , if 38 failed
This one work
Quote
QSHL MACRO aqword, ct
   local value
   IF ct GE 32
       value equ ct - 31
   
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, value
      shl eax, value
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx
      ;-------------------------
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, 31
      shl eax, 31
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx         
   ELSE
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, ct
      shl eax, ct
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx   
   ENDIF
ENDM

jj2007

Quote from: ToutEnMasm on June 12, 2009, 02:48:23 PM

Not so marvelous and not so nicer , a little problem occure.
the SHL couldnt pass 31 shift , if 38 failed
This one work
Quote
QSHL MACRO aqword, ct
   local value
   IF ct GE 32
       value equ ct - 31
   
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, value
      shl eax, value
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx
      ;-------------------------
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, 31
      shl eax, 31
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx         
   ELSE
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]
      shld edx, eax, ct
      shl eax, ct
      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx   
   ENDIF
ENDM

Maybe it could be shortened a bit?

IF ct GE 32
    value equ ct - 31
mov edx, dword ptr aqword[0]
shl edx, value
mov dword ptr aqword[0], 0
mov dword ptr aqword[4], edx
ELSE

ToutEnMasm


Quote
Maybe it could be shortened a bit?
No,i have tested it whith 1      38  shl , then 38 shr , finish = 1

jj2007

Quote from: ToutEnMasm on June 12, 2009, 03:44:19 PM

Quote
Maybe it could be shortened a bit?
No,i have tested it whith 1      38  shl , then 38 shr , finish = 1

I did not doubt that your version works, but look e.g. at this part:

      mov dword ptr aqword[0], eax
      mov dword ptr aqword[4], edx
      ;-------------------------
      mov eax, dword ptr aqword[0]
      mov edx, dword ptr aqword[+4]

Doesn't it look, ehm, a little bit redundant? Furthermore, shifting 32+ bits out of eax means that eax must be zero. Shifting exactly 32 bits out means edx=eax  :wink

ToutEnMasm

 :bdg
Quote
Doesn't it look, ehm, a little bit redundant?
Not a little,really redundant.I have delet this lines in the talkback sample i am uploading.

raymond

It could also be done with the FPU as follows as long as the shift does not result in an unsigned integer exceeding 63 bits.

finit    ;should be done once at start of program
         ;to insure the full 64 bits for the mantissa

fild count    ;should obviously be less than 63
fild aqword   ;declared as a qword
fscale
fistp aqword  ;replaces the previous value by the shifted one
fstp st       ;cleanup

When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

ToutEnMasm

Hello,
Is it possible to made a shift right with the FPU ?

jj2007

Quote from: raymond on June 13, 2009, 03:52:06 AM
It could also be done with the FPU as follows as long as the shift does not result in an unsigned integer exceeding 63 bits.
Which means it fails already for
aqword dq 1234567812345678h
and shiftcount>2

Quote from: ToutEnMasm on June 13, 2009, 04:57:30 AM
Is it possible to made a shift right with the FPU ?

Probably it works by inverting the number before and after the left shift.
But see above... the behaviour is very different from a normal shl.

sinsi

Light travels faster than sound, that's why some people seem bright until you hear them.

jj2007

Here is snippet using the FPU. But as mentioned above, make sure the resulting value is a qword. There is no "shift bits out" with the FPU...

MyCt = 8

MyQw4 dq 12345678h

shl64f MyQw4, MyCt
print xqword$(MyQw4), 13, 10
shr64f MyQw4, MyCt
print xqword$(MyQw4), 13, 10
...
shl64f MACRO aqword, count
  push count
  fild dword ptr [esp] ; should obviously be less than 63
  fild aqword ; declared as a qword
  mov eax, dword ptr aqword
  mov edx, dword ptr aqword[4]
  fscale
  fistp qword ptr aqword ; replaces the previous value by the shifted one
  mov eax, dword ptr aqword
  mov edx, dword ptr aqword[4]
  fstp st       ;cleanup
  pop eax
ENDM

shr64f MACRO aqword, count
  fld1
  fild aqword ; declared as a qword
  mov eax, dword ptr aqword
  mov edx, dword ptr aqword[4]
  fdivr st, st(1) ; 1/x
  push count
  fild dword ptr [esp] ; should obviously be less than 63
  fxch
  fscale
  fld1
  fdiv st, st(1) ; 1/x
  fistp qword ptr aqword ; replaces the previous value by the shifted one
  mov eax, dword ptr aqword
  mov edx, dword ptr aqword[4]
  REPEAT 3
fstp st  ; cleanup
  ENDM
  pop eax
ENDM

NightWare