otherwise nothing
R -- print the prefix for register names.
z -- print the opcode suffix for the size of the current operand.
- Z -- likewise, with special suffixes for fild/fist instructions.
+ Z -- likewise, with special suffixes for x87 instructions.
* -- print a star (in certain assembler syntax)
A -- print an absolute memory reference.
w -- print the operand as if it's a "word" (HImode) even if it isn't.
putc ('t', file);
return;
- case 'Z':
- gcc_assert (MEM_P (x));
+ case 'z':
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
+ {
+ /* Opcodes don't get size suffixes if using Intel opcodes. */
+ if (ASSEMBLER_DIALECT == ASM_INTEL)
+ return;
+
+ switch (GET_MODE_SIZE (GET_MODE (x)))
+ {
+ case 1:
+ putc ('b', file);
+ return;
+
+ case 2:
+ putc ('w', file);
+ return;
+
+ case 4:
+ putc ('l', file);
+ return;
+
+ case 8:
+ putc ('q', file);
+ return;
+
+ default:
+ output_operand_lossage
+ ("invalid operand size for operand code '%c'", code);
+ return;
+ }
+ }
- /* fild/fist don't get size suffixes if using Intel opcodes. */
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+ warning
+ (0, "non-integer operand used with operand code '%c'", code);
+ /* FALLTHRU */
+
+ case 'Z':
+ /* 387 opcodes don't get size suffixes if using Intel opcodes. */
if (ASSEMBLER_DIALECT == ASM_INTEL)
return;
- switch (GET_MODE_SIZE (GET_MODE (x)))
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
{
- case 2:
+ switch (GET_MODE_SIZE (GET_MODE (x)))
+ {
+ case 2:
#ifdef HAVE_AS_IX86_FILDS
- putc ('s', file);
+ putc ('s', file);
#endif
- return;
+ return;
- case 4:
- putc ('l', file);
- return;
+ case 4:
+ putc ('l', file);
+ return;
- case 8:
+ case 8:
#ifdef HAVE_AS_IX86_FILDQ
- putc ('q', file);
+ putc ('q', file);
#else
- fputs ("ll", file);
+ fputs ("ll", file);
#endif
- return;
+ return;
- default:
- gcc_unreachable ();
+ default:
+ break;
+ }
}
-
- case 'z':
- /* 387 opcodes don't get size suffixes if the operands are
- registers. */
- if (STACK_REG_P (x))
- return;
-
- /* Likewise if using Intel opcodes. */
- if (ASSEMBLER_DIALECT == ASM_INTEL)
- return;
-
- /* This is the size of op from size of operand. */
- switch (GET_MODE_SIZE (GET_MODE (x)))
+ else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
{
- case 1:
- putc ('b', file);
- return;
+ /* 387 opcodes don't get size suffixes
+ if the operands are registers. */
+ if (STACK_REG_P (x))
+ return;
- case 2:
- /* ??? This fails for HImode integer
- operator with memory operand. */
- if (MEM_P (x))
+ switch (GET_MODE_SIZE (GET_MODE (x)))
{
-#ifdef HAVE_AS_IX86_FILDS
+ case 4:
putc ('s', file);
-#endif
return;
- }
- else
- putc ('w', file);
- return;
- case 4:
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- putc ('l', file);
- else
- putc ('s', file);
- return;
+ case 8:
+ putc ('l', file);
+ return;
- case 8:
- if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
- putc ('q', file);
- else
- putc ('l', file);
- return;
+ case 12:
+ case 16:
+ putc ('t', file);
+ return;
- case 12:
- case 16:
- putc ('t', file);
+ default:
+ break;
+ }
+ }
+ else
+ {
+ output_operand_lossage
+ ("invalid operand type used with operand code '%c'", code);
return;
-
- default:
- gcc_unreachable ();
}
+ output_operand_lossage
+ ("invalid operand size for operand code '%c'", code);
+ return;
+
case 'd':
case 'b':
case 'w':
if (MEM_P (operands[2]))
{
- p = "%z2\t%2";
+ p = "%Z2\t%2";
break;
}
case DIV:
if (MEM_P (operands[1]))
{
- p = "r%z1\t%1";
+ p = "r%Z1\t%1";
break;
}
if (MEM_P (operands[2]))
{
- p = "%z2\t%2";
+ p = "%Z2\t%2";
break;
}
static const char * const alt[16] =
{
- "fcom%z2\t%y2\n\tfnstsw\t%0",
- "fcomp%z2\t%y2\n\tfnstsw\t%0",
- "fucom%z2\t%y2\n\tfnstsw\t%0",
- "fucomp%z2\t%y2\n\tfnstsw\t%0",
+ "fcom%Z2\t%y2\n\tfnstsw\t%0",
+ "fcomp%Z2\t%y2\n\tfnstsw\t%0",
+ "fucom%Z2\t%y2\n\tfnstsw\t%0",
+ "fucomp%Z2\t%y2\n\tfnstsw\t%0",
- "ficom%z2\t%y2\n\tfnstsw\t%0",
- "ficomp%z2\t%y2\n\tfnstsw\t%0",
+ "ficom%Z2\t%y2\n\tfnstsw\t%0",
+ "ficomp%Z2\t%y2\n\tfnstsw\t%0",
NULL,
NULL,
return "fstp\t%y0";
}
if (STACK_TOP_P (operands[0]))
- return "fld%z1\t%y1";
+ return "fld%Z1\t%y1";
return "fst\t%y0";
}
else if (MEM_P (operands[0]))
{
gcc_assert (REG_P (operands[1]));
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0";
+ return "fstp%Z0\t%y0";
else
{
/* There is no non-popping store to memory for XFmode.
So if we need one, follow the store with a load. */
if (GET_MODE (operands[0]) == XFmode)
- return "fstp%z0\t%y0\n\tfld%z0\t%y0";
+ return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
else
- return "fst%z0\t%y0";
+ return "fst%Z0\t%y0";
}
}
else
--- /dev/null
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+void
+bar1 ()
+{
+ char foo;
+ asm volatile ("mov%z0 %1, %0": "=m" (foo): "iq" (-23));
+ asm volatile ("add%z0 %1, %0": "+m" (foo): "iq" (23));
+ asm volatile ("mov%z0 %1, %0": "=q" (foo): "iq" (-23));
+ asm volatile ("add%z0 %1, %0": "+q" (foo): "iq" (23));
+}
+
+void
+bar2 ()
+{
+ short foo;
+ asm volatile ("mov%z0 %1, %0": "=m" (foo): "ir" (-23));
+ asm volatile ("add%z0 %1, %0": "+m" (foo): "ir" (23));
+ asm volatile ("mov%z0 %1, %0": "=r" (foo): "ir" (-23));
+ asm volatile ("add%z0 %1, %0": "+r" (foo): "ir" (23));
+
+ asm volatile ("pop%z0 %0": "=m" (foo));
+ asm volatile ("pop%z0 %0": "=r" (foo));
+}
+
+void
+bar3 ()
+{
+ int foo;
+ asm volatile ("mov%z0 %1, %0": "=m" (foo): "ir" (-23));
+ asm volatile ("add%z0 %1, %0": "+m" (foo): "ir" (23));
+ asm volatile ("mov%z0 %1, %0": "=r" (foo): "ir" (-23));
+ asm volatile ("add%z0 %1, %0": "+r" (foo): "ir" (23));
+
+ if (sizeof (void *) == sizeof (int))
+ {
+ asm volatile ("pop%z0 %0": "=m" (foo));
+ asm volatile ("pop%z0 %0": "=r" (foo));
+ }
+}
+
+void
+bar4 ()
+{
+ if (sizeof (void *) == sizeof (long long))
+ {
+ long long foo;
+ asm volatile ("mov%z0 %1, %0": "=m" (foo): "er" (-23));
+ asm volatile ("add%z0 %1, %0": "+m" (foo): "er" (23));
+ asm volatile ("mov%z0 %1, %0": "=r" (foo): "er" (-23));
+ asm volatile ("add%z0 %1, %0": "+r" (foo): "er" (23));
+
+ asm volatile ("pop%z0 %0": "=m" (foo));
+ asm volatile ("pop%z0 %0": "=r" (foo));
+ }
+}