I am trying to write an inline asm statement that atomically adds a number to a memory variable. Here's what I came up with: #define atomic_add(mem,val) asm volatile ("lock; add%z0 %1, %0": "+m" (mem): "ir" (val)) This appears to work fine on x86, but in 64-bit mode %z returns "ll" instead of "q" for 64-bit values like size_t, and thus the assembler complains like this: t.c:53: Error: no such instruction: `addll $3,x.5802(%rip)' If I understand %z correctly, this is exactly what it is meant for... right? Please make it return "q" in this case.
Please provide a testcase.
Uh, I did. Use the macro like this: int foo=2; atomic_add(foo,3); then try size_t as type of foo and compile on x86_64.
(In reply to comment #2) > Uh, I did. Use the macro like this: > > int foo=2; > atomic_add(foo,3); > > then try size_t as type of foo and compile on x86_64. > That is not a testcase. I need a valid C source code, which I can compile.
#include <stddef.h> #define atomic_add(mem,val) asm volatile ("lock; add%z0 %1, %0": "+m" (mem): "ir" (val)) int main() { size_t foo; atomic_add(foo,23); }
'z' is for x87 insns. You have to check size of size_t and use proper suffix in your code.
> 'z' is for x87 insns. Uh, what?! Let me quote the relevant "documentation" (gcc/config/i386/i386.md): ;; The special asm out single letter directives following a '%' are: ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of ;; operands[1]. No mention of floating point. > You have to check size of size_t and use > proper suffix in your code. No. The whole point of %z is that you can write asm statements in a way that does not specify the argument size explicitly in the statement.
(In reply to comment #6) > > 'z' is for x87 insns. > > Uh, what?! Let me quote the relevant "documentation" > (gcc/config/i386/i386.md): > > ;; The special asm out single letter directives following a '%' are: > ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of > ;; operands[1]. > This was written before x86-64 and movq is mentioned here. 64bit is for fildll/fildq. I don't know if all x86-64 assemblers support fildq.
Darwin assembler and GNU assembler support fildq (%rax). But Solaris assembler doesn't. Only fildll works with all assemblers. We can't generate the 'q' suffix for "%z".
I don't think it will hurt to generate fildq in 64bit if assembler supports it.
A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2009-04/msg00112.html
Stop setting the target milestone unless it is a regression.
Subject: Bug 39590 Author: uros Date: Sat Apr 25 08:10:51 2009 New Revision: 146761 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=146761 Log: PR target/39590 * configure.ac (HAVE_AS_IX86_FILDQ): On x86 targets check whether the configured assembler supports fildq and fistpq mnemonics. (HAVE_AS_IX86_FILDS): Rename from HAVE_GAS_FILDS_FISTS. * configure: Regenerated. * config.in: Ditto. * config/i386/i386.c (print_operand): Handle 'Z'. ['z']: Remove handling of special fild/fist suffixes. (output_fix_trunc): Use '%Z' to output suffix of fist{,p,tp} insn. * config/i386/i386.md (*floathi<mode>2_i387): Use '%Z' to output suffix of fild insn. (*floatsi<mode>2_vector_mixed): Ditto. (*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit): Ditto. (*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit): Ditto. (*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp): Ditto. (*float<SSEMODEI24:mode><X87MODEF:mode>2_i387): Ditto. * config/i386/gas.h (GAS_MNEMONICS): Remove. Modified: trunk/gcc/ChangeLog trunk/gcc/config.in trunk/gcc/config/i386/gas.h trunk/gcc/config/i386/i386.c trunk/gcc/config/i386/i386.md trunk/gcc/configure trunk/gcc/configure.ac
Fixed for 4.5.0.