News:

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

Sorry if this is a common question

Started by savage, June 13, 2006, 03:08:37 PM

Previous topic - Next topic

savage

what's the easiest way to get an absolute value of an sse register?
I'm thinking I could use AND 07FFFFFFFFF..... or something, but is there a better way?

dsouza123

Signed integers use twos complement encoding.
For switching signs
not reg  ; xor reg, -1
add 1

For example using a signed byte:
00000010 == 2
00000001 == 1
00000000 == 0
11111111 == -1
11111110 == -2

If you knew it was negative then the equivalent of this

xor reg, -1
add reg, 1

would give the positive version.


SSE code equivalent to this would do it no matter the sign of the integer.

mov reg, reg0
and reg,10000000  ; for byte sized signed integer
cmp reg, 0
je past
xor reg0, -1
add reg0, 1
past:

redskull

i don't know about SSE registers, but maybe something like this could be converted?  (for eax)

CDQ
XOR EAX, EDX
SUB EAX, EDX
Strange women, lying in ponds, distributing swords, is no basis for a system of government

savage

wow, yeah, guys, im asking about SSE =P

for regular registers i can just do

AND eax, 07FFF FFFFh

The problem is you can't use immediate values for sse instructions, so I was trying to avoid using a weird looking constant, it's not a big deal, I was just making sure there's not a faster way

dsouza123

AND eax, 07FFF FFFF wont give the correct absolute value.

The -1 will turn into 2147483647, surely not what you expected.

Redskull's code works correctly.

This code with tweaks may work, but it isn't tested .

.data
  number dq somenum, somenum
  minusone dq -1, -1
  zero dq 0, 0
  justhi dq  10..0b, 10..0b

.code
  movaps xmm1, minusone
  movaps xmm2, number
  movaps xmm3, xmm2
  andps xmm3, justhi
  comisd xmm3, justhi
  je past
  movaps xmm1, zero
past:
  xorps  xmm2, xmm1
  psubq  xmm2, xmm1

Ossa

dsouza123 is right, take a look at this: http://ossa.the-wot.co.uk/tutorial_asm1_tex.htm#1_6

It is something that I wrote a while back to explain 2's complement. Your code will only work for signed magnitude values, but Intel processors use 2's complement.

Ossa
Website (very old): ossa.the-wot.co.uk

redskull

Quote from: dsouza123 on June 14, 2006, 04:42:38 PM
Redskull's code works correctly.

Just for the record, i'm totally not claiming to have thought that code up; the original was a 16-bit version using CWD, taken from a book i can't remember long ago.  Again, sorry I can't help with SSE registers :'(

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

savage

Quote from: Ossa on June 14, 2006, 04:47:23 PM
dsouza123 is right, take a look at this: http://ossa.the-wot.co.uk/tutorial_asm1_tex.htm#1_6

It is something that I wrote a while back to explain 2's complement. Your code will only work for signed magnitude values, but Intel processors use 2's complement.

Ossa

I feel stupid now, DUHHHHHHHHHHHHHHHHHHHHHH. 
Sorry guys, my neurons aren't exactly working this week.  :green2

savage

What about

   mov edx, eax
   sub eax, edx
   sub eax, edx

and

   movaps xmm1, xmm0
   subps xmm0, xmm1
   subps xmm0, xmm1

Ossa

Quote from: savage on June 15, 2006, 03:23:11 PM
   mov edx, eax
   sub eax, edx
   sub eax, edx

Therefore:

mov edx, eax    ; edx = eax = val
sub eax, edx    ; eax = 0, edx = val
sub eax, edx    ; eax = 0 - val = -val


I don't think that that's what you want to do.

Ossa
Website (very old): ossa.the-wot.co.uk

savage

I never said that.
You liar!   :cheekygreen:

I have a huge headache.  I think my brain is falling out of my ear. 

Why is it so hard to get the absolute value.  Arrrg

Ossa

This probably won't assemble (I haven't had time to check) but should work... there MUST be a better way though... I don't use MMX/SSE much, so I'm not the one to ask though:

mask1 dd  10000000h,  10000000h,  10000000h,  10000000h

movdqa   xmm2, xmm1
pand     xmm1, mask1
pcmpeqd  xmm1, mask1 ; xmm1 has all 1s for any dword that is negative

pxor     xmm3, xmm3
psubd    xmm3, xmm2 ; xmm3 = -xmm2

pand     xmm3, xmm1
pandn    xmm1, xmm2
por      xmm1, xmm3


[edit] Now that I finally looked at redskull's code, try this - I don't know of any sign extension instructions for SSE but I'll go have a look now:

mask1 dd  10000000h,  10000000h,  10000000h,  10000000h

movdqa   xmm2, xmm1
pand     xmm2, mask1
pcmpeqd  xmm2, mask1 ; xmm1 has all 1s for any dword that is negative

pxor     xmm1, xmm2
psubd    xmm1, xmm2


(for non-dowrd things, you just change the mask and the psubd instruction)

[/edit]

Ossa
Website (very old): ossa.the-wot.co.uk

savage

how does this look:

   movaps xmm1, xmm0
   cmpnltps xmm1, 0  ; obviously this shouldnt be immediate, but just an example
   andps xmm1, xmm0
   subps xmm0, xmm1
   subps xmm0, xmm1


Ossa

Wait - you're using FLOATS ??? well then, you first method WILL work and it is much the best.

[edit] The code that has been discussed so far is for integers, but you are using float SSE instructions there... which are you using? [/edit]

Ossa
Website (very old): ossa.the-wot.co.uk

savage

Well I'd like to have the best method for both.