Where is the unknown token when using the Integrated Assembler (Intel syntax, neg instruction)?

I'm part of an existing project, and I'm working on support for
Clang's Integrated Assembler. The project has copious amounts of
inline assembly (both stand alone one-liners for shift and rotates;
and blocks for things like AES and GCM mode). Even better (maybe
worse?), it mixes AT&T and Intel because it supports Microsoft and GNU
platforms.

I'm having trouble understanding an error message from the assembler.
The message is on the use of 'neg' under the Intel dialect:

<inline asm>:3:7: note: instantiated into assembly here
         neg %rcx;
             ^

The code looks like:

int SomeFunction(int* ptr, int val1, int val2)
{
    int ret;
    __asm__ __volatile (
        ".intel_syntax" "\n"
        neg %1;
        ...
    )

   return ret;
}

I'm testing on x86_64, so I tried changing to 'negq %1;' with no joy.
(Taking a hint from
http://clang.llvm.org/compatibility.html#inline-asm):

<inline asm>:3:8: note: instantiated into assembly here
         negq %rcx;
             ^

I'm experiencing it with both Apple's Clang 3.2, and LLVM's Clang
3.6.0 built from sources (http://llvm.org/releases/).

Naively (and I stress naively), “unknown token in expression” appears
to be a bogus message since the assembly instruction its complaining
about does not seem to have a problem. So I suspect there is something
else the integrated assembler finds offensive.

Could anyone help me understand what the issue is?

Thanks in advance. Jeff.

I think it’s complaining about the % in %rcx. Intel assembly syntax doesn’t use the % prefix on registers.

I don’t think our backend knows how to expand operands using anything other than AT&T syntax. If this is the case, using .intel_syntax directives in inline assembly won’t work very well until something changes.

If you need intel syntax, what you could try doing is passing -fasm-blocks and writing MSVC / Intel style inline assembly, which looks like:

int SomeFunction(int* ptr, int val1, int val2) {
__asm {
neg val1
};
}

I would only recommend doing this if you already have ifdefs to support inline asm in MSVC.

I think it's complaining about the % in %rcx. Intel assembly syntax
doesn't use the % prefix on registers.

It does, if you are using gas :-(. ".intel_syntax prefix" will expect
prefix'ed registers. Unfortunately, we do not support this mode, only
".intel_syntax noprefix".

I don't think our backend knows how to expand operands using anything other

BTW, I filed a PR for this: https://llvm.org/bugs/show_bug.cgi?id=24232

I’m not interested in implementing “.intel_syntax prefix”, but I am interested in making this code parse.

No problem Reid.

We are going to try and refactor some of the assembly into S files to
relieve some of the pressures from Clang, and allow use of other
assemblers, like NASM.

We will still need those quick one- or three-liners, like rotate.

Jeff