OSDN Git Service

Backport from mainline
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Aug 2012 19:14:59 +0000 (19:14 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 1 Aug 2012 19:14:59 +0000 (19:14 +0000)
2012-03-09  Uros Bizjak  <ubizjak@gmail.com>

PR target/52530
* config/i386/i386.c (ix86_print_operand): Handle 'E' operand modifier.
(ix86_print_operand_address): Handle UNSPEC_LEA_ADDR. Do not fallback
to set code to 'q'.
* config/i386/i386.md (UNSPEC_LEA_ADDR): New unspec.
(*movdi_internal_rex64): Use %E operand modifier for lea.
(*movsi_internal): Ditto.
(*lea_1): Ditto.
(*lea<mode>_2): Ditto.
(*lea_{3,4,5,6}_zext): Ditto.
(*tls_global_dynamic_32_gnu): Ditto.
(*tls_global_dynamic_64): Ditto.
(*tls_dynamic_gnu2_lea_32): Ditto.
(*tls_dynamic_gnu2_lea_64): Ditto.
(pro_epilogue_adjust_stack_<mode>_add): Ditto.

testsuite/ChangeLog:

Backport from mainline
2012-03-11  Uros Bizjak  <ubizjak@gmail.com>

PR target/52530
* gcc.dg/torture/pr52530.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@190048 138bc75d-0d04-0410-961f-82ee72b054a4

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

index e0004d4..9d6dce4 100644 (file)
@@ -1,6 +1,27 @@
 2012-08-01  Uros Bizjak  <ubizjak@gmail.com>
 
        Backport from mainline
+       2012-03-09  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/52530
+       * config/i386/i386.c (ix86_print_operand): Handle 'E' operand modifier.
+       (ix86_print_operand_address): Handle UNSPEC_LEA_ADDR. Do not fallback
+       to set code to 'q'.
+       * config/i386/i386.md (UNSPEC_LEA_ADDR): New unspec.
+       (*movdi_internal_rex64): Use %E operand modifier for lea.
+       (*movsi_internal): Ditto.
+       (*lea_1): Ditto.
+       (*lea<mode>_2): Ditto.
+       (*lea_{3,4,5,6}_zext): Ditto.
+       (*tls_global_dynamic_32_gnu): Ditto.
+       (*tls_global_dynamic_64): Ditto.
+       (*tls_dynamic_gnu2_lea_32): Ditto.
+       (*tls_dynamic_gnu2_lea_64): Ditto.
+       (pro_epilogue_adjust_stack_<mode>_add): Ditto.
+
+2012-08-01  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
        2012-08-01  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (ix86_address_subreg_operand): Reject
index 340979a..3dc2b7e 100644 (file)
@@ -13812,6 +13812,7 @@ get_some_local_dynamic_name (void)
    Z -- likewise, with special suffixes for x87 instructions.
    * -- print a star (in certain assembler syntax)
    A -- print an absolute memory reference.
+   E -- print address with DImode register names if TARGET_64BIT.
    w -- print the operand as if it's a "word" (HImode) even if it isn't.
    s -- print a shift double count, followed by the assemblers argument
        delimiter.
@@ -13887,7 +13888,14 @@ ix86_print_operand (FILE *file, rtx x, int code)
          ix86_print_operand (file, x, 0);
          return;
 
+       case 'E':
+         /* Wrap address in an UNSPEC to declare special handling.  */
+         if (TARGET_64BIT)
+           x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
 
+         output_address (x);
+         return;
+           
        case 'L':
          if (ASSEMBLER_DIALECT == ASM_ATT)
            putc ('l', file);
@@ -14492,6 +14500,7 @@ ix86_print_operand_address (FILE *file, rtx addr)
   int scale;
   int ok;
   bool vsib = false;
+  int code = 0;
 
   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
     {
@@ -14502,6 +14511,12 @@ ix86_print_operand_address (FILE *file, rtx addr)
       addr = XVECEXP (addr, 0, 0);
       vsib = true;
     }
+  else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
+    {
+      gcc_assert (TARGET_64BIT);
+      ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
+      code = 'q';
+    }
   else
     ok = ix86_decompose_address (addr, &parts);
 
@@ -14574,15 +14589,15 @@ ix86_print_operand_address (FILE *file, rtx addr)
     }
   else
     {
-      int code = 0;
-
-      /* Print SImode registers for zero-extended addresses to force
-        addr32 prefix.  Otherwise print DImode registers to avoid it.  */
-      if (TARGET_64BIT)
-       code = ((GET_CODE (addr) == ZERO_EXTEND
-                || GET_CODE (addr) == AND)
-               ? 'l'
-               : 'q');
+      /* Print SImode register names for zero-extended
+        addresses to force addr32 prefix.  */
+      if (TARGET_64BIT
+         && (GET_CODE (addr) == ZERO_EXTEND
+             || GET_CODE (addr) == AND))
+       {
+         gcc_assert (!code);
+         code = 'l';
+       }
 
       if (ASSEMBLER_DIALECT == ASM_ATT)
        {
index 37cea79..2889166 100644 (file)
@@ -38,6 +38,7 @@
 ;; Z -- likewise, with special suffixes for x87 instructions.
 ;; * -- print a star (in certain assembler syntax)
 ;; A -- print an absolute memory reference.
+;; E -- print address with DImode register names if TARGET_64BIT.
 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
 ;; s -- print a shift double count, followed by the assemblers argument
 ;;     delimiter.
   UNSPEC_MS_TO_SYSV_CALL
   UNSPEC_CALL_NEEDS_VZEROUPPER
   UNSPEC_PAUSE
+  UNSPEC_LEA_ADDR
 
   ;; For SSE/MMX support:
   UNSPEC_FIX_NOTRUNC
       return "#";
 
     case TYPE_LEA:
-      return "lea{q}\t{%a1, %0|%0, %a1}";
+      return "lea{q}\t{%E1, %0|%0, %E1}";
 
     default:
       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
       else if (which_alternative == 2)
        return "movabs{q}\t{%1, %0|%0, %1}";
       else if (ix86_use_lea_for_mov (insn, operands))
-       return "lea{q}\t{%a1, %0|%0, %a1}";
+       return "lea{q}\t{%E1, %0|%0, %E1}";
       else
        return "mov{q}\t{%1, %0|%0, %1}";
     }
       return "movd\t{%1, %0|%0, %1}";
 
     case TYPE_LEA:
-      return "lea{l}\t{%a1, %0|%0, %a1}";
+      return "lea{l}\t{%E1, %0|%0, %E1}";
 
     default:
       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
       if (ix86_use_lea_for_mov (insn, operands))
-       return "lea{l}\t{%a1, %0|%0, %a1}";
+       return "lea{l}\t{%E1, %0|%0, %E1}";
       else
        return "mov{l}\t{%1, %0|%0, %1}";
     }
   [(set (match_operand:SI 0 "register_operand" "=r")
        (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %0|%0, %a1}"
+  "lea{l}\t{%E1, %0|%0, %E1}"
   "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
   [(const_int 0)]
 {
   [(set (match_operand:SWI48 0 "register_operand" "=r")
        (match_operand:SWI48 1 "lea_address_operand" "p"))]
   ""
-  "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
+  "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
   [(const_int 0)]
 {
        (zero_extend:DI
          (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  "lea{l}\t{%E1, %k0|%k0, %E1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
        (zero_extend:DI
          (match_operand:SI 1 "lea_address_operand" "j")))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  "lea{l}\t{%E1, %k0|%k0, %E1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
          (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
          (match_operand:DI 2 "const_32bit_mask" "n")))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  "lea{l}\t{%E1, %k0|%k0, %E1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
          (match_operand:DI 1 "lea_address_operand" "p")
          (match_operand:DI 2 "const_32bit_mask" "n")))]
   "TARGET_64BIT"
-  "lea{l}\t{%a1, %k0|%k0, %a1}"
+  "lea{l}\t{%E1, %k0|%k0, %E1}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")])
 
   "!TARGET_64BIT && TARGET_GNU_TLS"
 {
   output_asm_insn
-    ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
+    ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
   if (TARGET_SUN_TLS)
 #ifdef HAVE_AS_IX86_TLSGDPLT
     return "call\t%a2@tlsgdplt";
   if (!TARGET_X32)
     fputs (ASM_BYTE "0x66\n", asm_out_file);
   output_asm_insn
-    ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
+    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
   fputs (ASM_SHORT "0x6666\n", asm_out_file);
   fputs ("\trex64\n", asm_out_file);
   if (TARGET_SUN_TLS)
                  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
                              UNSPEC_TLSDESC))))]
   "!TARGET_64BIT && TARGET_GNU2_TLS"
-  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
+  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
   [(set_attr "type" "lea")
    (set_attr "mode" "SI")
    (set_attr "length" "6")
        (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
                   UNSPEC_TLSDESC))]
   "TARGET_64BIT && TARGET_GNU2_TLS"
-  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
+  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
   [(set_attr "type" "lea")
    (set_attr "mode" "DI")
    (set_attr "length" "7")
 
     default:
       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
-      return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
+      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
     }
 }
   [(set (attr "type")
index 731fd96..9fd8113 100644 (file)
@@ -1,3 +1,11 @@
+2012-08-01  Uros Bizjak  <ubizjak@gmail.com>
+
+       Backport from mainline
+       2012-03-11  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/52530
+       * gcc.dg/torture/pr52530.c: New test.
+
 2012-07-27  Anna Tikhonova  <anna.tikhonova@intel.com>
 
        * gcc.dg/20020201-1.c: Remove declarations for exit, abort,
diff --git a/gcc/testsuite/gcc.dg/pr52530.c b/gcc/testsuite/gcc.dg/pr52530.c
new file mode 100644 (file)
index 0000000..f7cdf1a
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+#if __SIZEOF_INT__ > 2
+struct foo
+{
+ int *f;
+ int i;
+};
+
+int baz;
+#else
+struct foo
+{
+ long *f;
+ long i;
+};
+
+long baz;
+#endif
+
+void __attribute__ ((noinline))
+bar (struct foo x)
+{
+ *(x.f) = x.i;
+}
+
+int
+main ()
+{
+  struct foo x = { &baz, 0xdeadbeef };
+
+  bar (x);
+
+  if (baz != 0xdeadbeef)
+    abort ();
+
+  return 0;
+}