OSDN Git Service

Backport from mainline
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.c
index 63622ab..25ec814 100644 (file)
@@ -6078,25 +6078,28 @@ classify_argument (enum machine_mode mode, const_tree type,
     case CHImode:
     case CQImode:
       {
-       int size = (bit_offset % 64)+ (int) GET_MODE_BITSIZE (mode);
+       int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
 
-       if (size <= 32)
+       /* Analyze last 128 bits only.  */
+       size = (size - 1) & 0x7f;
+
+       if (size < 32)
          {
            classes[0] = X86_64_INTEGERSI_CLASS;
            return 1;
          }
-       else if (size <= 64)
+       else if (size < 64)
          {
            classes[0] = X86_64_INTEGER_CLASS;
            return 1;
          }
-       else if (size <= 64+32)
+       else if (size < 64+32)
          {
            classes[0] = X86_64_INTEGER_CLASS;
            classes[1] = X86_64_INTEGERSI_CLASS;
            return 2;
          }
-       else if (size <= 64+64)
+       else if (size < 64+64)
          {
            classes[0] = classes[1] = X86_64_INTEGER_CLASS;
            return 2;
@@ -16986,16 +16989,23 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
   int ok;
 
   /* FIXME: Handle zero-extended addresses.  */
-  if (GET_CODE (operands[1]) == ZERO_EXTEND
-      || GET_CODE (operands[1]) == AND)
+  if (SImode_address_operand (operands[1], VOIDmode))
     return false;
 
   /* Check we need to optimize.  */
   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
     return false;
 
-  /* Check it is correct to split here.  */
-  if (!ix86_ok_to_clobber_flags(insn))
+  /* The "at least two components" test below might not catch simple
+     move insns if parts.base is non-NULL and parts.disp is const0_rtx
+     as the only components in the address, e.g. if the register is
+     %rbp or %r13.  As this test is much cheaper and moves are the
+     common case, do this check first.  */
+  if (REG_P (operands[1]))
+    return false;
+  /* Check if it is OK to split here.  */
+  if (!ix86_ok_to_clobber_flags (insn))
     return false;
 
   ok = ix86_decompose_address (operands[1], &parts);
@@ -24266,16 +24276,8 @@ ix86_constant_alignment (tree exp, int align)
 int
 ix86_data_alignment (tree type, int align)
 {
-  /* A data structure, equal or greater than the size of a cache line
-     (64 bytes in the Pentium 4 and other recent Intel processors, including
-     processors based on Intel Core microarchitecture) should be aligned
-     so that its base address is a multiple of a cache line size.  */
-
   int max_align
-    = MIN ((unsigned) ix86_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
-
-  if (max_align < BITS_PER_WORD)
-    max_align = BITS_PER_WORD;
+    = optimize_size ? BITS_PER_WORD : MIN (256, MAX_OFILE_ALIGNMENT);
 
   if (AGGREGATE_TYPE_P (type)
       && TYPE_SIZE (type)
@@ -29780,7 +29782,9 @@ rdrand_step:
       mode4 = insn_data[icode].operand[5].mode;
 
       if (target == NULL_RTX
-         || GET_MODE (target) != insn_data[icode].operand[0].mode)
+         || GET_MODE (target) != insn_data[icode].operand[0].mode
+         || !insn_data[icode].operand[0].predicate (target,
+                                                    GET_MODE (target)))
        subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
       else
        subtarget = target;