0

In the following code, I can get the result of mm0 - mm1 in mm0 by PSUBSW instruction. When I compiled on Mac book air by gcc.

But, PSUBSW instruction is explained that we can get the result of mm1 - mm0 in mm1 in Intel developer's manual: PSUBSW mm, mm/m64, Subtract signed packed words in mm/m64 from signed packed words in mm and saturate results.

#include <stdio.h>

int
main()
{
  short int a[4] = {1111,1112,1113,1114};
  short int b[4] = {1111,2112,3113,4114};
  short int c[4];

  asm volatile (
  "movq (%1),%%mm0\n\t"
  "movq (%2),%%mm1\n\t"
  "psubsw %%mm1,%%mm0\n\t"
  "movq %%mm0,%0\n\t"
  "emms"
  : "=g"(c): "r"(&a),"r"(&b));

  printf("%d %d %d %d\n", c[0], c[1], c[2], c[3]);

  return 0;
}

What is this difference? Which is the src, mm0 or mm1? If this difference is Intel syntax and AT&T syntax.

Jens
  • 8,423
  • 9
  • 58
  • 78
kuni255
  • 83
  • 8
  • Note that you don't have to write SIMD assembly to vectorize your code. If you write a loop `for (int i=0; i<4; ++i) { c[i] = a[i] - b[i]; }` then GCC can vectorize it for you. See more details in [this](http://stackoverflow.com/questions/409300/how-to-vectorize-with-gcc) thread and [this](http://gcc.gnu.org/projects/tree-ssa/vectorization.html) GNU manual. – Jens May 03 '14 at 12:14

1 Answers1

3

In the GNU manual it states that gcc is based not on the Intel assembly language, but rather on a language that descends from the AT&T Unix assembler. There are two main camps on assembly syntax:

  • Intel: opcode dest, src
  • AT&T: opcode src, dest

In your example you're using AT&T syntax, the default. However, if you prefer to switch to Intel syntax, you can either compile with -masm=intel or use the following:

__asm__(".intel_syntax;" ...);

You can find more discussions of that topic in this or this Stackoverflow thread, or read more here.

Community
  • 1
  • 1
Jens
  • 8,423
  • 9
  • 58
  • 78
  • Thank you for your answering. I understood that there is the difference that the order of the operand is reversed between AT&T syntax and Intel syntax in the instruction which has two operands. – kuni255 May 03 '14 at 10:37
  • It can be confusing at times :) What I do to find out which syntax is valid, I try to store an immediate into a register: `__asm__("mov $0, %eax");` and that will complain about the position of the immediate or the register naming. See [here](http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#s3) for more details. – Jens May 03 '14 at 12:02