aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2009-04-28 08:54:02 +0200
committerUros Bizjak <uros@gcc.gnu.org>2009-04-28 08:54:02 +0200
commitb91322f2ba88548f5137cea907c85cd74b0b90a8 (patch)
treee907955ebd25213e01b632ca3ab28601b9dcb477 /gcc
parent297c37173212c85e2e0c61cb9a1fd89fa9d44f25 (diff)
downloadgcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.zip
gcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.tar.gz
gcc-b91322f2ba88548f5137cea907c85cd74b0b90a8.tar.bz2
re PR target/39911 (The 'z' suffix doesn't work with 16bit integer insn)
PR target/39911 * config/i386/i386.c (print_operand) ['Z']: Handle floating point and integer modes for x87 operands. Do not ICE for unsupported size, generate error instead. Generate error for unsupported operand types. ['z']: Do not handle HImode memory operands specially. Warning for floating-point operands. Fallthru to 'Z' for unsupported operand types. Do not ICE for unsupported size, generate error instead. (output_387_binary_op): Use %Z to output operands. (output_fp_compare): Ditto. (output_387_reg_move): Ditto. testsuite/ChangeLog: PR target/39911 * gcc.target/i386/pr39911.c: New test. From-SVN: r146874
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/i386/i386.c168
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr39911.c57
5 files changed, 173 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 153e71b..601b0b1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2009-04-28 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/39911
+ * config/i386/i386.c (print_operand) ['Z']: Handle floating point
+ and integer modes for x87 operands. Do not ICE for unsupported size,
+ generate error instead. Generate error for unsupported operand types.
+ ['z']: Do not handle HImode memory operands specially. Warning
+ for floating-point operands. Fallthru to 'Z' for unsupported operand
+ types. Do not ICE for unsupported size, generate error instead.
+ (output_387_binary_op): Use %Z to output operands.
+ (output_fp_compare): Ditto.
+ (output_387_reg_move): Ditto.
+
2009-04-28 Ben Elliston <bje@au.ibm.com>
PR c++/35652
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 704b0f2..650325a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10851,7 +10851,7 @@ get_some_local_dynamic_name (void)
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.
@@ -10950,91 +10950,111 @@ print_operand (FILE *file, rtx x, int code)
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':
@@ -11833,7 +11853,7 @@ output_387_binary_op (rtx insn, rtx *operands)
if (MEM_P (operands[2]))
{
- p = "%z2\t%2";
+ p = "%Z2\t%2";
break;
}
@@ -11863,13 +11883,13 @@ output_387_binary_op (rtx insn, rtx *operands)
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;
}
@@ -12241,13 +12261,13 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
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,
@@ -28782,22 +28802,22 @@ output_387_reg_move (rtx insn, rtx *operands)
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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d315580..2979431 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -36,7 +36,7 @@
;; 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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 53a8125..91e2337 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2009-04-28 Uros Bizjak <ubizjak@gmail.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/39911
+ * gcc.target/i386/pr39911.c: New test.
+
2009-04-28 Paul Thomas <pault@gcc.gnu.org>
PR fortran/39879
@@ -24,7 +30,8 @@
* gcc.dg/Wconversion-real.c: Require large_double.
* gcc.dg/cdce1.c: Require large_double instead of checking targets.
- * gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c: Skip if doubles are too small.
+ * gcc.c-torture/execute/ieee/unsafe-fp-assoc-1.c: Skip if doubles
+ are too small.
* gcc.c-torture/execute/ieee/20010226-1.c: Mark all floating point
constants as long.
diff --git a/gcc/testsuite/gcc.target/i386/pr39911.c b/gcc/testsuite/gcc.target/i386/pr39911.c
new file mode 100644
index 0000000..fe63ff0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr39911.c
@@ -0,0 +1,57 @@
+/* { 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));
+ }
+}