Error Output Operand Constraint Contains
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up ARM inline assembly - input operand constraint contains '=' up vote 1 down vote favorite This is my current code: void int32hex(u32 val, char *out) { asm("rev %[dst], %[src]" :: [dst]"=r"(val), [src]"r"(val)); binhex((u8*)&val, 4, out); } My idea is to take the argument val, flip it (endianness) using the rev instruction, and then pass it on. From what I've read, the above code seems to be correct, the destination register has the =r flag, which implies that the register can be written to. However, when run though GCC, I get the error: input operand constraint contains '=' If I change the flag to simply r then it will compile fine, but the value of val does not change. c gcc assembly arm inline-assembly share|improve this question asked Nov 2 '13 at 0:49 asdasd 883610 add a comment| 1 Answer 1 active oldest votes up vote 4 down vote accepted The error is telling you what is going wrong -- the = constraint applies only to outputs, not inputs, and your asm pattern has two inputs (one confusingly called 'dst') and no outputs. You probably meant to have 'dst' be an output: asm("rev %[dst], %[src]" : [dst]"=r"(val) : [src]"r"(val)); share|improve this answer answered Nov 2 '13 at 0:55 Chris Dodd 61.2k359118 1 asm("rev %[swap], %[swap]" : [swap] "=r" (val) : "0" (val)); might be better. You can use the "0" specifier to say the input is the same as a given output; this will sometimes generate better code as the register will be the same. Also, the src/dst is confusing as you note. –artless noise Nov 4 '13 at 16:58 @artlessnoi
for asms To: egcs-patches at cygnus dot com Subject: Better constraint checking for asms From: Bernd Schmidt
not guess which registers or memory locations contain the data you want to use. You must specify an assembler instruction template much like what appears in a machine description, plus https://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Extended-Asm.html an operand constraint string for each operand. For example, here is how https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Extended-Asm.html to use the 68881's fsinx instruction: asm ("fsinx %1,%0" : "=f" (result) : "f" (angle)); Here angle is the C expression for the input operand while result is that of the output operand. Each has ‘"f"’ as its operand constraint, saying that a floating-point register is required. The error output ‘=’ in ‘=f’ indicates that the operand is an output; all output operands' constraints must use ‘=’. The constraints use the same language used in the machine description (see Constraints). Each operand is described by an operand-constraint string followed by the C expression in parentheses. A colon separates the assembler template from the first output operand and another separates the last error output operand output operand from the first input, if any. Commas separate the operands within each group. The total number of operands is currently limited to 30; this limitation may be lifted in some future version of GCC. If there are no output operands but there are input operands, you must place two consecutive colons surrounding the place where the output operands would go. As of GCC version 3.1, it is also possible to specify input and output operands using symbolic names which can be referenced within the assembler code. These names are specified inside square brackets preceding the constraint string, and can be referenced inside the assembler code using %[name] instead of a percentage sign followed by the operand number. Using named operands the above example could look like: asm ("fsinx %[angle],%[output]" : [output] "=f" (result) : [angle] "f" (angle)); Note that the symbolic operand names have no relation whatsoever to other C identifiers. You may use any name you like, even those of existing C symbols, but you must ensure that no two operands within the same assembler construct u
you need not guess which registers or memory locations will contain the data you want to use. You must specify an assembler instruction template much like what appears in a machine description, plus an operand constraint string for each operand. For example, here is how to use the 68881's fsinx instruction: asm ("fsinx %1,%0" : "=f" (result) : "f" (angle)); Here angle is the C expression for the input operand while result is that of the output operand. Each has "f" as its operand constraint, saying that a floating point register is required. The = in =f indicates that the operand is an output; all output operands' constraints must use =. The constraints use the same language used in the machine description (see Constraints). Each operand is described by an operand-constraint string followed by the C expression in parentheses. A colon separates the assembler template from the first output operand and another separates the last output operand from the first input, if any. Commas separate the operands within each group. The total number of operands is currently limited to 30; this limitation may be lifted in some future version of GCC. If there are no output operands but there are input operands, you must place two consecutive colons surrounding the place where the output operands would go. As of GCC version 3.1, it is also possible to specify input and output operands using symbolic names which can be referenced within the assembler code. These names are specified inside square brackets preceding the constraint string, and can be referenced inside the assembler code using %[name] instead of a percentage sign followed by the operand number. Using named operands the above example could look like: asm ("fsinx %[angle],%[output]" : [output] "=f" (result) : [angle] "f" (angle)); Note that the symbolic operand names have no relation whatsoever to other C identifiers. You may use any name you like, even those of existing C symbols, but must ensure that no two operands within the same assembler construct use the same symbolic name. Output operand expressions must be lvalues; the compiler can check this. The input operands need not be lvalues. The compiler cannot check whether th