OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / explow.c
index b2763e3..719421f 100644 (file)
@@ -56,28 +56,16 @@ trunc_int_for_mode (c, mode)
   if (mode == BImode)
     return c & 1 ? STORE_FLAG_VALUE : 0;
 
-  /* We clear out all bits that don't belong in MODE, unless they and our
-     sign bit are all one.  So we get either a reasonable negative
-     value or a reasonable unsigned value.  */
+  /* Sign-extend for the requested mode.  */
 
-  if (width < HOST_BITS_PER_WIDE_INT
-      && ((c & ((HOST_WIDE_INT) (-1) << (width - 1)))
-           != ((HOST_WIDE_INT) (-1) << (width - 1))))
-    c &= ((HOST_WIDE_INT) 1 << width) - 1;
-
-  /* If this would be an entire word for the target, but is not for
-     the host, then sign-extend on the host so that the number will look
-     the same way on the host that it would on the target.
-
-     For example, when building a 64 bit alpha hosted 32 bit sparc
-     targeted compiler, then we want the 32 bit unsigned value -1 to be
-     represented as a 64 bit value -1, and not as 0x00000000ffffffff.
-     The later confuses the sparc backend.  */
-
-  if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT
-      && BITS_PER_WORD == width
-      && (c & ((HOST_WIDE_INT) 1 << (width - 1))))
-    c |= ((HOST_WIDE_INT) (-1) << width);
+  if (width < HOST_BITS_PER_WIDE_INT)
+    {
+      HOST_WIDE_INT sign = 1;
+      sign <<= width - 1;
+      c &= (sign << 1) - 1;
+      c ^= sign;
+      c -= sign;
+    }
 
   return c;
 }
@@ -129,15 +117,10 @@ plus_constant_wide (x, c)
       if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
          && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
        {
-         /* Any rtl we create here must go in a saveable obstack, since
-            we might have been called from within combine.  */
-         push_obstacks_nochange ();
-         rtl_in_saveable_obstack ();
          tem
            = force_const_mem (GET_MODE (x),
                               plus_constant (get_pool_constant (XEXP (x, 0)),
                                              c));
-         pop_obstacks ();
          if (memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
            return tem;
        }
@@ -391,6 +374,11 @@ convert_memory_address (to_mode, x)
     case CONST_DOUBLE:
       return x;
 
+    case SUBREG:
+      if (GET_MODE (SUBREG_REG (x)) == to_mode)
+       return SUBREG_REG (x);
+      break;
+
     case LABEL_REF:
       temp = gen_rtx_LABEL_REF (to_mode, XEXP (x, 0));
       LABEL_REF_NONLOCAL_P (temp) = LABEL_REF_NONLOCAL_P (x);
@@ -400,6 +388,7 @@ convert_memory_address (to_mode, x)
       temp = gen_rtx_SYMBOL_REF (to_mode, XSTR (x, 0));
       SYMBOL_REF_FLAG (temp) = SYMBOL_REF_FLAG (x);
       CONSTANT_POOL_ADDRESS_P (temp) = CONSTANT_POOL_ADDRESS_P (x);
+      STRING_POOL_ADDRESS_P (temp) = STRING_POOL_ADDRESS_P (x);
       return temp;
 
     case CONST:
@@ -1298,15 +1287,10 @@ allocate_dynamic_stack_space (size, target, known_align)
 #endif
 
   if (MUST_ALIGN)
-    {
-      if (GET_CODE (size) == CONST_INT)
-       size = GEN_INT (INTVAL (size)
-                       + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1));
-      else
-       size = expand_binop (Pmode, add_optab, size,
-                            GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
-                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
-    }
+    size
+      = force_operand (plus_constant (size, 
+                                     BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1),
+                      NULL_RTX);
 
 #ifdef SETJMP_VIA_SAVE_AREA
   /* If setjmp restores regs from a save area in the stack frame,
@@ -1329,12 +1313,12 @@ allocate_dynamic_stack_space (size, target, known_align)
 #if !defined(PREFERRED_STACK_BOUNDARY) || !defined(MUST_ALIGN) || (PREFERRED_STACK_BOUNDARY != BIGGEST_ALIGNMENT)
        /* If anyone creates a target with these characteristics, let them
           know that our optimization cannot work correctly in such a case.  */
-       abort();
+       abort ();
 #endif
 
        if (GET_CODE (size) == CONST_INT)
          {
-           int new = INTVAL (size) / align * align;
+           HOST_WIDE_INT new = INTVAL (size) / align * align;
 
            if (INTVAL (size) != new)
              setjmpless_size = GEN_INT (new);
@@ -1399,9 +1383,10 @@ allocate_dynamic_stack_space (size, target, known_align)
   if (flag_stack_check && ! STACK_CHECK_BUILTIN)
     probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size);
 
-  /* Don't use a TARGET that isn't a pseudo.  */
+  /* Don't use a TARGET that isn't a pseudo or is the wrong mode.  */
   if (target == 0 || GET_CODE (target) != REG
-      || REGNO (target) < FIRST_PSEUDO_REGISTER)
+      || REGNO (target) < FIRST_PSEUDO_REGISTER
+      || GET_MODE (target) != Pmode)
     target = gen_reg_rtx (Pmode);
 
   mark_reg_pointer (target, known_align);
@@ -1426,7 +1411,6 @@ allocate_dynamic_stack_space (size, target, known_align)
       if (mode == VOIDmode)
        mode = Pmode;
 
-      size = convert_modes (mode, ptr_mode, size, 1);
       pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate;
       if (pred && ! ((*pred) (size, mode)))
        size = copy_to_mode_reg (mode, size);
@@ -1439,7 +1423,6 @@ allocate_dynamic_stack_space (size, target, known_align)
 #ifndef STACK_GROWS_DOWNWARD
       emit_move_insn (target, virtual_stack_dynamic_rtx);
 #endif
-      size = convert_modes (Pmode, ptr_mode, size, 1);
 
       /* Check stack bounds if necessary.  */
       if (current_function_limit_stack)
@@ -1478,6 +1461,7 @@ allocate_dynamic_stack_space (size, target, known_align)
                                 REG_NOTES (note_target));
        }
 #endif /* SETJMP_VIA_SAVE_AREA */
+
 #ifdef STACK_GROWS_DOWNWARD
   emit_move_insn (target, virtual_stack_dynamic_rtx);
 #endif
@@ -1562,12 +1546,20 @@ probe_stack_range (first, size)
   /* First see if the front end has set up a function for us to call to
      check the stack.  */
   if (stack_check_libfunc != 0)
-    emit_library_call (stack_check_libfunc, 0, VOIDmode, 1,
-                      memory_address (QImode,
-                                      gen_rtx (STACK_GROW_OP, Pmode,
-                                               stack_pointer_rtx,
-                                               plus_constant (size, first))),
-                      ptr_mode);
+    {
+      rtx addr = memory_address (QImode,
+                                gen_rtx (STACK_GROW_OP, Pmode,
+                                         stack_pointer_rtx,
+                                         plus_constant (size, first)));
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+      if (GET_MODE (addr) != ptr_mode)
+       addr = convert_memory_address (ptr_mode, addr);
+#endif
+
+      emit_library_call (stack_check_libfunc, 0, VOIDmode, 1, addr,
+                        ptr_mode);
+    }
 
   /* Next see if we have an insn to check the stack.  Use it if so.  */
 #ifdef HAVE_check_stack