public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: PR target/39911: The 'z' suffix doesn't work with 16bit   integer insn
@ 2009-04-26 20:47 H.J. Lu
  2009-04-27 12:16 ` Uros Bizjak
  0 siblings, 1 reply; 19+ messages in thread
From: H.J. Lu @ 2009-04-26 20:47 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2322 bytes --]

On Sun, Apr 26, 2009 at 11:46 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sun, Apr 26, 2009 at 10:00 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> H.J. Lu wrote:
>>>
>>> On Sat, Apr 25, 2009 at 1:15 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>>
>>>>
>>>> Hello!
>>>>
>>>> Attached patch reverts %z handling of HImode operands back to previous
>>>> (wrong) state until better fix is found. Unfortunately, integer and
>>>> x87 operators don't agree which suffix to use for integer operands.
>>>>
>>>> 2009-04-25  Uros Bizjak  <ubizjak@gmail.com>
>>>>
>>>>       PR target/39897
>>>>       * config/i386/i386.c (print_operand) ['z']: Revert handling of
>>>>       HImode operands.
>>>>
>>>> Tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline.
>>>>
>>>>
>>>
>>> This doesn't solve the problem. You need to add the 'w' suffix for integer
>>> instructions with memory operand.
>>>
>>
>> This is how %z always worked and that is excatly the reason why I try to fix
>> this wrong behaviour.
>>
>
> I am testing a patch in
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39911
>
> Since "%z' never really worked on integer instructions, I made "%Z" for
> integer instructions only while providing backward compatibility for existing
> asm statements.
>

This is the patch with a testcase. Tested on Linux/Intel64 with both 32/64 bits.
OK for trunk?

Thanks.

-- 
H.J.
---
gcc/

2009-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39911
	* config/i386/i386.c (ix86_file_end): Replace "%z0" with "%Z0".
	(output_set_got): Likewise.
	(output_set_got): Likewise.
	(x86_output_mi_thunk): Likewise.
	(print_operand): Restore 'z' handling.  Make 'Z' for integer
	insntructions only.
	(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.

gcc/testsuite/

2009-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39911
	* gcc.target/i386/pr39911.c: New.

[-- Attachment #2: gcc-pr39911-2.patch --]
[-- Type: text/plain, Size: 12315 bytes --]

gcc/

2009-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39911
	* config/i386/i386.c (ix86_file_end): Replace "%z0" with "%Z0".
	(output_set_got): Likewise.
	(output_set_got): Likewise.
	(x86_output_mi_thunk): Likewise.
	(print_operand): Restore 'z' handling.  Make 'Z' for integer
	insntructions only.
	(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.

gcc/testsuite/

2009-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/39911
	* gcc.target/i386/pr39911.c: New.

Index: testsuite/gcc.target/i386/pr39911.c
===================================================================
--- testsuite/gcc.target/i386/pr39911.c	(revision 0)
+++ testsuite/gcc.target/i386/pr39911.c	(revision 0)
@@ -0,0 +1,55 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+void 
+bar1 () 
+{
+  char 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" : "=q"(foo) : "ir"(23));
+  asm volatile ("add%z0 %1, %0": "+q" (foo): "ir" (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));
+}
+
+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));
+      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): "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));
+      asm volatile ("pop%z0 %0": : "r" (foo));
+    }
+}
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 146807)
+++ config/i386/i386.md	(working copy)
@@ -35,8 +35,9 @@
 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
 ;;      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 -- print the integer instruction suffix for the size of the current
+;;	operand
+;; 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.
@@ -5141,7 +5142,7 @@
   "TARGET_80387
    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
        || TARGET_MIX_SSE_I387)"
-  "fild%Z1\t%1"
+  "fild%z1\t%1"
   [(set_attr "type" "fmov")
    (set_attr "mode" "<MODE>")
    (set_attr "fp_int_src" "true")])
@@ -5251,7 +5252,7 @@
   "TARGET_SSE2 && TARGET_MIX_SSE_I387
    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
   "@
-   fild%Z1\t%1
+   fild%z1\t%1
    #"
   [(set_attr "type" "fmov,sseicvt")
    (set_attr "mode" "<MODE>,<ssevecmode>")
@@ -5312,7 +5313,7 @@
    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
   "@
-   fild%Z1\t%1
+   fild%z1\t%1
    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
   [(set_attr "type" "fmov,sseicvt,sseicvt")
@@ -5331,7 +5332,7 @@
    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
   "@
-   fild%Z1\t%1
+   fild%z1\t%1
    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
   [(set_attr "type" "fmov,sseicvt")
    (set_attr "prefix" "orig,maybe_vex")
@@ -5581,7 +5582,7 @@
   "TARGET_80387
    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
   "@
-   fild%Z1\t%1
+   fild%z1\t%1
    #"
   [(set_attr "type" "fmov,multi")
    (set_attr "mode" "<X87MODEF:MODE>")
@@ -5594,7 +5595,7 @@
 	  (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
   "TARGET_80387
    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
-  "fild%Z1\t%1"
+  "fild%z1\t%1"
   [(set_attr "type" "fmov")
    (set_attr "mode" "<X87MODEF:MODE>")
    (set_attr "fp_int_src" "true")])
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 146807)
+++ config/i386/i386.c	(working copy)
@@ -7491,7 +7491,7 @@ ix86_file_end (void)
 
       xops[0] = gen_rtx_REG (Pmode, regno);
       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
-      output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
+      output_asm_insn ("mov%Z0\t{%1, %0|%0, %1}", xops);
       output_asm_insn ("ret", xops);
     }
 
@@ -7531,7 +7531,7 @@ output_set_got (rtx dest, rtx label ATTR
       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
 
       if (!flag_pic)
-	output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
+	output_asm_insn ("mov%Z0\t{%2, %0|%0, %2}", xops);
       else
 	output_asm_insn ("call\t%a2", xops);
 
@@ -7546,7 +7546,7 @@ output_set_got (rtx dest, rtx label ATTR
 				 CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
 
       if (flag_pic)
-	output_asm_insn ("pop%z0\t%0", xops);
+	output_asm_insn ("pop%Z0\t%0", xops);
     }
   else
     {
@@ -7572,9 +7572,9 @@ output_set_got (rtx dest, rtx label ATTR
     return "";
 
   if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
-    output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
+    output_asm_insn ("add%Z0\t{%1, %0|%0, %1}", xops);
   else
-    output_asm_insn ("add%z0\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops);
+    output_asm_insn ("add%Z0\t{%1+[.-%a2], %0|%0, %1+(.-%a2)}", xops);
 
   return "";
 }
@@ -10847,8 +10847,9 @@ get_some_local_dynamic_name (void)
    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
         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 -- print the integer instruction suffix for the size of the current
+	operand
+   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.
@@ -10947,44 +10948,72 @@ print_operand (FILE *file, rtx x, int co
 	    putc ('t', file);
 	  return;
 
-	case 'Z':
-	  gcc_assert (MEM_P (x));
+	case 'z':
+	  /* 387 opcodes don't get size suffixes if the operands are
+	     registers.  */
+	  if (STACK_REG_P (x))
+	    return;
 
-	  /* fild/fist don't get size suffixes if using Intel opcodes.  */
+	  /* 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)))
 	    {
+	    case 1:
+	      /* Backward compability for asm statement.  */
+	      putc ('b', file);
+	      return;
+
 	    case 2:
-#ifdef HAVE_AS_IX86_FILDS
-	      putc ('s', file);
+	      /* Backward compability for asm statement.  */
+	      if (MEM_P (x))
+		{
+#ifdef HAVE_GAS_FILDS_FISTS
+		  putc ('s', file);
 #endif
+		  return;
+		}
+	      else
+		putc ('w', file);
 	      return;
 
 	    case 4:
-	      putc ('l', file);
+	      if (GET_MODE (x) == SFmode)
+		putc ('s', file);
+	      else
+		putc ('l', file);
+	      return;
+
+	    case 12:
+	    case 16:
+	      putc ('t', file);
 	      return;
 
 	    case 8:
-#ifdef HAVE_AS_IX86_FILDQ
-	      putc ('q', file);
-#else
-	      fputs ("ll", file);
-#endif
+	      /* Backward compability for asm statement.  */
+	      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
+		{
+		  if (MEM_P (x))
+		    fputs ("ll", file);
+		  else
+		    putc ('q', file);
+		}
+	      else
+		putc ('l', file);
 	      return;
 
 	    default:
 	      gcc_unreachable ();
 	    }
 	    
-	case 'z':
-	  /* 387 opcodes don't get size suffixes if the operands are
-	     registers.  */
-	  if (STACK_REG_P (x))
-	    return;
+	case 'Z':
+	  /* 'Z' is for integer insntructions only.  */
+	  gcc_assert (!STACK_REG_P (x)
+		      && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT);
 
-	  /* Likewise if using Intel opcodes.  */
+	  /* Intel syntax don't need size suffixes.  */
 	  if (ASSEMBLER_DIALECT == ASM_INTEL)
 	    return;
 
@@ -10996,36 +11025,15 @@ print_operand (FILE *file, rtx x, int co
 	      return;
 
 	    case 2:
-	      /* ??? This fails for HImode integer
-		 operator with memory operand.  */
-	      if (MEM_P (x))
-		{
-#ifdef HAVE_AS_IX86_FILDS
-		  putc ('s', file);
-#endif
-		  return;
-		}
-	      else
-		putc ('w', file);
+	      putc ('w', file);
 	      return;
 
 	    case 4:
-	      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
-		putc ('l', file);
-	      else
-		putc ('s', file);
+	      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);
+	      putc ('q', file);
 	      return;
 
 	    default:
@@ -12108,15 +12116,15 @@ output_fix_trunc (rtx insn, rtx *operand
   gcc_assert (GET_MODE (operands[1]) != TFmode);
 
   if (fisttp)
-      output_asm_insn ("fisttp%Z0\t%0", operands);
+      output_asm_insn ("fisttp%z0\t%0", operands);
   else
     {
       if (round_mode != I387_CW_ANY)
 	output_asm_insn ("fldcw\t%3", operands);
       if (stack_top_dies || dimode_p)
-	output_asm_insn ("fistp%Z0\t%0", operands);
+	output_asm_insn ("fistp%z0\t%0", operands);
       else
-	output_asm_insn ("fist%Z0\t%0", operands);
+	output_asm_insn ("fist%z0\t%0", operands);
       if (round_mode != I387_CW_ANY)
 	output_asm_insn ("fldcw\t%2", operands);
     }
@@ -26989,7 +26997,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUT
       /* Put the this parameter into %eax.  */
       xops[0] = this_param;
       xops[1] = this_reg = gen_rtx_REG (Pmode, AX_REG);
-      output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
+      output_asm_insn ("mov%Z1\t{%0, %1|%1, %0}", xops);
     }
   else
     this_reg = NULL_RTX;
@@ -27031,7 +27039,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUT
 
       xops[0] = gen_rtx_MEM (Pmode, this_reg);
       xops[1] = tmp;
-      output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
+      output_asm_insn ("mov%Z1\t{%0, %1|%1, %0}", xops);
 
       /* Adjust the this parameter.  */
       xops[0] = gen_rtx_MEM (Pmode, plus_constant (tmp, vcall_offset));
@@ -27044,7 +27052,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUT
 	  xops[0] = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, tmp, tmp2));
 	}
       xops[1] = this_reg;
-      output_asm_insn ("add%z1\t{%0, %1|%1, %0}", xops);
+      output_asm_insn ("add%Z1\t{%0, %1|%1, %0}", xops);
     }
 
   /* If necessary, drop THIS back to its stack slot.  */
@@ -27052,7 +27060,7 @@ x86_output_mi_thunk (FILE *file ATTRIBUT
     {
       xops[0] = this_reg;
       xops[1] = this_param;
-      output_asm_insn ("mov%z1\t{%0, %1|%1, %0}", xops);
+      output_asm_insn ("mov%Z1\t{%0, %1|%1, %0}", xops);
     }
 
   xops[0] = XEXP (DECL_RTL (function), 0);

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2009-04-28 17:16 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-26 20:47 PATCH: PR target/39911: The 'z' suffix doesn't work with 16bit integer insn H.J. Lu
2009-04-27 12:16 ` Uros Bizjak
2009-04-27 13:58   ` H.J. Lu
2009-04-27 14:11     ` Paolo Bonzini
2009-04-27 14:17       ` H.J. Lu
2009-04-27 15:23         ` Paolo Bonzini
2009-04-27 16:24           ` H.J. Lu
2009-04-27 16:36             ` Paolo Bonzini
2009-04-27 16:37               ` Paolo Bonzini
2009-04-27 16:49               ` H.J. Lu
2009-04-27 19:04             ` Uros Bizjak
2009-04-27 19:59               ` H.J. Lu
2009-04-27 20:28                 ` H.J. Lu
2009-04-27 20:37                   ` Uros Bizjak
2009-04-27 20:56                     ` H.J. Lu
2009-04-27 21:12                       ` Uros Bizjak
2009-04-27 21:19                         ` H.J. Lu
2009-04-28 16:46   ` H.J. Lu
2009-04-28 17:25     ` Uros Bizjak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).