Click here to Skip to main content
15,914,795 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Why is my result on psubw not correct? I expected -4,-4,-4,-4 for movq B3+16, mm2 and -12,-12,-12,-12 for movq B3+24, mm3

C++
#include "stdafx.h"
#include "emmintrin.h"
#include <iostream>
#include <iomanip>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
   short B2[4][4]; //input 2-D array
   short B3[4][4]; // output
   int n = 0;
   for (int i = 0; i < 4; i++)
     for (int j = 0; j < 4; j++, n++)
        B2[i][j] = n;

   __asm{
      movq mm0, B2
      movq mm1, B2+8
      movq mm2, B2+16
      movq mm3, B2+24

      // add-sub register element
      paddw mm0, mm3 // mm0+mm3, result correct
      paddw mm1, mm2 // mm1+mm2, result correct
      psubw mm2, mm1 // mm1-mm2, result not correct
      psubw mm3, mm0 // mm0-mm3, result not correct
  
      // move result in B3
      movq B3, mm0
      movq B3+8, mm1
      movq B3+16, mm2
      movq B3+24, mm3
      emms
   }

   for (int i = 0; i < 4; i++)
   {
      for (int j = 0; j < 4; j++)
         cout << B2[i][j] << " ";
      cout << endl;
   }

   cout << endl;

   for (int i = 0; i < 4; i++)
   {
      for (int j = 0; j < 4; j++)
         cout << B3[i][j] << " ";
      cout << endl;
   }

   return 0;
}
Posted
Updated 13-Jul-10 2:55am
v2

1 solution

This is the right sequence of opcodes to obtain what you want:

C++
__asm
{
   movq mm0, B2
   movq mm1, B2+8
   movq mm2, B2+16
   movq mm3, B2+24
   paddw mm0, mm3 // mm0 + mm3
   paddw mm1, mm2 // mm1 + mm2
   movq B3, mm0
   movq B3+8, mm1
   movq mm0, B2
   movq mm1, B2+8
   psubw mm1, mm2 // mm1 - mm2
   psubw mm0, mm3 // mm0 - mm3
   movq B3+16, mm1
   movq B3+24, mm0
   emms
}
 
Share this answer
 
v2
Comments
Nish Nishant 13-Jul-10 12:21pm    
Reason for my vote of 5
Worth a 5!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900