assembly constraints

I’m trying to compile the following inline assembly:

static inline int cas_int(A_int_t *ptr, int oldv, int newv)
{
    int prev;
    __asm__ __volatile__ ("lock ; cmpxchg %2,%3"
                          : "=a" (prev), "=m" (ptr->v)
                          : "q" (newv), "m" (ptr->v), "0" (oldv)
                          : "memory");
    return prev;
}

and I get the following error:

PGC-S-0354-Can’t find a register in class ‘AREG’ for extended ASM operand 4 (x.c: 114)

It seems that pgcc has trouble assigning prev and oldv to the same register (eax). Is this a compiler bug, or is there something in my code?

Here are my compiler details:

% pgcc -V
pgcc 7.1-6 32-bit target on x86 Linux -tp piv
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2007, STMicroelectronics, Inc. All Rights Reserved.

Thanks!
-d

Hi d,

This was a compiler bug (TPR#14969) which occurred only in the 7.1 and 7.2 32-bit compilers. It was fixed as of the 8.0 release. Unfortunately, I don’t have a workaround except for upgrading.

  • Mat

Hi Mat,

Thanks for fast reply! But I’m still having the same issue with 8.0:

PGC-S-0354-Can’t find a register in class ‘AREG’ for extended ASM operand 4 (x.c: 97)
PGC/x86 Linux 8.0-5: compilation completed with severe errors

Here’s the compiler details:
% pgcc -V
pgcc 8.0-5 32-bit target on x86 Linux -tp piv
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2009, STMicroelectronics, Inc. All Rights Reserved.

Any ideas?

Thanks,
-d

Hi d,

Can you please either post here or send an example case to PGI Customer support (trs@pgroup.com)? I was able to compile the above example without issue, but I needed to guess what ‘A_int_t’ was defined as. So a complete stand-alone example exhibiting the problem would be great.

Thanks,
Mat

Thanks again Mat. Here’s a complete simplified example:

volatile int d = 10;
int prev, newv=10, oldv=20;


int main ()
{
    asm ("lock ; cmpxchg %2,%3"
         : "=a" (prev), "=m" (d)
         : "q" (newv), "m" (d), "0" (oldv)
         : "memory");

  return 0;
}

% pgcc x.c
PGC-S-0354-Can’t find a register in class ‘AREG’ for extended ASM operand 4 (x.c: 7)
PGC/x86 Linux 8.0-5: compilation completed with severe errors

Thanks!
-d

Hi d,

Looks to be a different problem then TPR#14969, but it is compiler issue since we should be able to support this syntax. I’ve created a new problem report (TPR#15784) and have sent it on to our engineers. Hopefully they can have it resolved shortly. Note, I added your email to the report so that you’ll be notified once it’s fixed.

Thank you!
Mat

I noticed that if I move the oldv parameter before newv (and change the parameters for cmpxchg appropriately) it works fine. I.e.,

         : "0" (oldv), "q" (newv), "m" (d)

-d

The problems associated with TPR 15784 have been corrected in the 9.0-1 release.

Thanks for the submission,
dave