4

I'm trying to write some inline assembly code with KNC instructions for Xeon Phi platform, using the k1om-mpss-linux-gcc compiler. I want to use a mask register into my code in order to vectorize my computation. Here it is my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <assert.h>
#include <stdint.h>

void* aligned_malloc(size_t size, size_t alignment) {

    uintptr_t r = (uintptr_t)malloc(size + --alignment + sizeof(uintptr_t));
    uintptr_t t = r + sizeof(uintptr_t);
    uintptr_t o =(t + alignment) & ~(uintptr_t)alignment;
    if (!r) return NULL;
    ((uintptr_t*)o)[-1] = r;
    return (void*)o;
}

int main(int argc, char* argv[])
{
    const int vectorSize = 16;
    int * n_arr = (int *) aligned_malloc(16 * sizeof(int),64);
    int * lenS_arr = (int *) aligned_malloc(16 * sizeof(int),64);
    int * tt_i = (int *) aligned_malloc(16 * sizeof(int),64);
    int * tt = (int *) aligned_malloc(16 * sizeof(int),64);
    int n = 5;
    int lenS = 16;
    int i;

    for(i=0; i< 16; i++){
        tt_i[i] = 1;
        n_arr[i] = n;
        lenS_arr[i] = lenS;
    }
    __asm__("vmovdqa32 %1,%%zmm0\n\t"
            "vmovdqa32 %2,%%zmm1\n\t"
            "vmovdqa32 %3,%%zmm2\n\t"
            "vpaddd %%zmm0,%%zmm1,%%zmm0\n\t"
            "vpcmpgtd %%zmm0,%%zmm2,%%k1\n\t"
            "vpsubd %%zmm2,%%zmm0,%%zmm0 {{%%k1}}\n\t"
            "vmovdqa32 %%zmm1,%0;"
            : "=m" (tt[0]) : "m" (tt_i[0]), "m" (n_arr[0]), "m" (lenS_arr[0]));
    for (i=0; i <16 ; i++)
    {
        printf("tt_i[%d] = %d --- tt[%d] = %d\n",i, tt_i[i], i, tt[i]);
    }

    return 0;
}

And when I compile the code, I've got this error:

error: invalid 'asm': nested assembly dialect alternatives

Which is related to the this assembly line:

"vpsubd %%zmm2,%%zmm0,%%zmm0 {{%%k1}}\n\t"

Any thoughts about this error?

rkhb
  • 14,159
  • 7
  • 32
  • 60
Hamid_UMB
  • 317
  • 4
  • 16

1 Answers1

5

Try using %{%%k1%} in the inline asm to get {%k1} into the actual asm output. { and } need to be escaped.


A google search on the error message: nested assembly dialect alternatives found a mailing list post about asm dialect alternatives, including an example testcase.

{} in GNU C inline asm already has a special meaning: providing alternatives for different ASM dialects.

Using {{%%k1}} looks to gcc like nested alternatives, which is invalid.

The test-case / example is:

int main (void) {
  int f = 0;
  asm ("{movl $42, %%eax | mov eax, 42}" : :);
  asm ("{movl $41, %0||mov %0, 43}" : "=r"(f));
  if (f != 42)
    abort ();

  return 0;
}
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    You could also check out gcc's docs for (asm)[https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#AssemblerTemplate). – David Wohlferd Dec 17 '15 at 07:06
  • @DavidWohlferd: duh, good point, of course it's documented. Thanks :). Updated my answer with a solution as well as identifying the problem. – Peter Cordes Dec 17 '15 at 07:19
  • Actually, until relatively recently it *wasn't* doc'ed. That whole inline asm section finally annoyed someone who was prepared to do something about it. – David Wohlferd Dec 17 '15 at 20:13