OSDN Git Service

PR target/39911
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Apr 2009 06:54:02 +0000 (06:54 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Apr 2009 06:54:02 +0000 (06:54 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146874 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr39911.c [new file with mode: 0644]

index 153e71b..601b0b1 100644 (file)
@@ -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
index 704b0f2..650325a 100644 (file)
@@ -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
index d315580..2979431 100644 (file)
@@ -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.
index 53a8125..91e2337 100644 (file)
@@ -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 (file)
index 0000000..fe63ff0
--- /dev/null
@@ -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));
+    }
+}