OSDN Git Service

* expr.c (expand_assignment): Correct typo exposed by -Wall.
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
index de18bfd..6d3165d 100644 (file)
@@ -499,7 +499,7 @@ void
 emit_queue ()
 {
   register rtx p;
-  while (p = pending_chain)
+  while ((p = pending_chain))
     {
       QUEUED_INSN (p) = emit_insn (QUEUED_BODY (p));
       pending_chain = QUEUED_NEXT (p);
@@ -1657,7 +1657,10 @@ move_block_to_reg (regno, x, nregs, mode)
      enum machine_mode mode;
 {
   int i;
-  rtx pat, last;
+#ifdef HAVE_load_multiple
+  rtx pat; 
+  rtx last;
+#endif
 
   if (nregs == 0)
     return;
@@ -1700,7 +1703,10 @@ move_block_from_reg (regno, x, nregs, size)
      int size;
 {
   int i;
-  rtx pat, last;
+#ifdef HAVE_store_multiple
+  rtx pat; 
+  rtx last;
+#endif
   enum machine_mode mode;
 
   /* If SIZE is that of a mode no bigger than a word, just use that
@@ -2221,7 +2227,6 @@ emit_move_insn_1 (x, y)
     {
       /* Don't split destination if it is a stack push.  */
       int stack = push_operand (x, GET_MODE (x));
-      rtx insns;
 
       /* If this is a stack, push the highpart first, so it
         will be in the argument order.
@@ -2265,7 +2270,6 @@ emit_move_insn_1 (x, y)
   else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
     {
       rtx last_insn = 0;
-      rtx insns;
       
 #ifdef PUSH_ROUNDING
 
@@ -2600,8 +2604,8 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
 #ifdef HAVE_movstrqi
          if (HAVE_movstrqi
              && GET_CODE (size) == CONST_INT
-             && ((unsigned) INTVAL (size)
-                 < (1 << (GET_MODE_BITSIZE (QImode) - 1))))
+             && ((unsigned HOST_WIDE_INT) INTVAL (size)
+                 <= GET_MODE_MASK (QImode)))
            {
              rtx pat = gen_movstrqi (gen_rtx_MEM (BLKmode, temp),
                                      xinner, size, GEN_INT (align));
@@ -2615,8 +2619,8 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
 #ifdef HAVE_movstrhi
          if (HAVE_movstrhi
              && GET_CODE (size) == CONST_INT
-             && ((unsigned) INTVAL (size)
-                 < (1 << (GET_MODE_BITSIZE (HImode) - 1))))
+             && ((unsigned HOST_WIDE_INT) INTVAL (size)
+                 <= GET_MODE_MASK (HImode)))
            {
              rtx pat = gen_movstrhi (gen_rtx_MEM (BLKmode, temp),
                                      xinner, size, GEN_INT (align));
@@ -2651,6 +2655,18 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
                }
            }
 #endif
+#ifdef HAVE_movstrti
+  if (HAVE_movstrti)
+    {
+      rtx pat = gen_movstrti (gen_rtx (MEM, BLKmode, temp),
+                             xinner, size, GEN_INT (align));
+      if (pat != 0)
+       {
+         emit_insn (pat);
+         goto ret;
+       }
+    }
+#endif
 
 #ifndef ACCUMULATE_OUTGOING_ARGS
          /* If the source is referenced relative to the stack pointer,
@@ -2908,7 +2924,7 @@ expand_assignment (to, from, want_value, suggest_reg)
       if (TREE_CODE (to) == COMPONENT_REF
          && TREE_READONLY (TREE_OPERAND (to, 1)))
        {
-         if (offset = 0)
+         if (offset == 0)
            to_rtx = copy_rtx (to_rtx);
 
          RTX_UNCHANGING_P (to_rtx) = 1;
@@ -3871,8 +3887,6 @@ store_constructor (exp, target, cleared)
   else if (TREE_CODE (type) == SET_TYPE)
     {
       tree elt = CONSTRUCTOR_ELTS (exp);
-      rtx xtarget = XEXP (target, 0);
-      int set_word_size = TYPE_ALIGN (type);
       int nbytes = int_size_in_bytes (type), nbits;
       tree domain = TYPE_DOMAIN (type);
       tree domain_min, domain_max, bitlength;
@@ -3979,7 +3993,9 @@ store_constructor (exp, target, cleared)
          tree startbit = TREE_PURPOSE (elt);
          /* end of range of element, or element value */
          tree endbit   = TREE_VALUE (elt);
+#ifdef TARGET_MEM_FUNCTIONS
          HOST_WIDE_INT startb, endb;
+#endif
          rtx  bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
 
          bitlength_rtx = expand_expr (bitlength,
@@ -4358,8 +4374,14 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
          if (! integer_zerop (low_bound))
            index = fold (build (MINUS_EXPR, index_type, index, low_bound));
 
-         index = fold (build (MULT_EXPR, index_type, index,
-                              convert (index_type,
+         if (TREE_CODE (index) == INTEGER_CST)
+           {
+             index = convert (sbitsizetype, index);
+             index_type = TREE_TYPE (index);
+           }
+
+         index = fold (build (MULT_EXPR, sbitsizetype, index,
+                              convert (sbitsizetype,
                                        TYPE_SIZE (TREE_TYPE (exp)))));
 
          if (TREE_CODE (index) == INTEGER_CST
@@ -4368,9 +4390,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
          else
            {
              offset = size_binop (PLUS_EXPR, offset,
-                                  size_binop (FLOOR_DIV_EXPR, index,
-                                              size_int (BITS_PER_UNIT)));
-
+                                  convert (sizetype,
+                                           size_binop (FLOOR_DIV_EXPR, index,
+                                                       size_int (BITS_PER_UNIT))));
              if (contains_placeholder_p (offset))
                offset = build (WITH_RECORD_EXPR, sizetype, offset, exp);
            }
@@ -6936,7 +6958,6 @@ expand_expr (exp, target, tmode, modifier)
        tree slot = TREE_OPERAND (exp, 0);
        tree cleanups = NULL_TREE;
        tree exp1;
-       rtx temp;
 
        if (TREE_CODE (slot) != VAR_DECL)
          abort ();
@@ -7595,21 +7616,14 @@ expand_builtin_return_addr (fndecl_code, count, tem)
    them.  */
 
 rtx
-expand_builtin_setjmp (buf_addr, target)
+expand_builtin_setjmp (buf_addr, target, first_label, next_label)
      rtx buf_addr;
      rtx target;
+     rtx first_label, next_label;
 {
-  rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
+  rtx lab1 = gen_label_rtx ();
   enum machine_mode sa_mode = Pmode, value_mode;
   rtx stack_save;
-  int old_inhibit_defer_pop = inhibit_defer_pop;
-  int return_pops
-    =  RETURN_POPS_ARGS (get_identifier ("__dummy"),
-                        build_function_type (void_type_node, NULL_TREE),
-                        0);
-  rtx next_arg_reg;
-  CUMULATIVE_ARGS args_so_far;
-  rtx op0;
   int i;
 
   value_mode = TYPE_MODE (integer_type_node);
@@ -7631,11 +7645,11 @@ expand_builtin_setjmp (buf_addr, target)
      machine-dependent.  */
   emit_move_insn (gen_rtx_MEM (Pmode, buf_addr),
                  virtual_stack_vars_rtx);
-  emit_move_insn
-    (validize_mem (gen_rtx_MEM (Pmode,
+  emit_move_insn (validize_mem
+                 (gen_rtx_MEM (Pmode,
                                plus_constant (buf_addr,
                                               GET_MODE_SIZE (Pmode)))),
-     gen_rtx_LABEL_REF (Pmode, lab1));
+                 gen_rtx_LABEL_REF (Pmode, lab1));
 
 #ifdef HAVE_save_stack_nonlocal
   if (HAVE_save_stack_nonlocal)
@@ -7647,19 +7661,23 @@ expand_builtin_setjmp (buf_addr, target)
                                           2 * GET_MODE_SIZE (Pmode)));
   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
 
-#ifdef HAVE_setjmp
-  if (HAVE_setjmp)
-    emit_insn (gen_setjmp ());
+  /* If there is further processing to do, do it.  */
+#ifdef HAVE_builtin_setjmp_setup
+  if (HAVE_builtin_setjmp_setup)
+    emit_insn (gen_builtin_setjmp_setup (buf_addr));
 #endif
 
-  /* Set TARGET to zero and branch around the other case.  */
+  /* Set TARGET to zero and branch to the first-time-through label.  */
   emit_move_insn (target, const0_rtx);
-  emit_jump_insn (gen_jump (lab2));
+  emit_jump_insn (gen_jump (first_label));
   emit_barrier ();
   emit_label (lab1);
 
-  /* Note that setjmp clobbers FP when we get here, so we have to make
-     sure it's marked as used by this function.  */
+  /* Tell flow about the strange goings on.  */
+  current_function_has_nonlocal_label = 1;
+
+  /* Clobber the FP when we get here, so we have to make sure it's
+     marked as used by this function.  */
   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
 
   /* Mark the static chain as clobbered here so life information
@@ -7674,8 +7692,6 @@ expand_builtin_setjmp (buf_addr, target)
 #endif
     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
-  current_function_has_nonlocal_label = 1;
-
 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
   if (fixed_regs[ARG_POINTER_REGNUM])
     {
@@ -7703,49 +7719,107 @@ expand_builtin_setjmp (buf_addr, target)
     }
 #endif
 
+#ifdef HAVE_builtin_setjmp_receiver
+  if (HAVE_builtin_setjmp_receiver)
+    emit_insn (gen_builtin_setjmp_receiver (lab1));
+  else
+#endif
 #ifdef HAVE_nonlocal_goto_receiver
-  if (HAVE_nonlocal_goto_receiver)
-    emit_insn (gen_nonlocal_goto_receiver ());
+    if (HAVE_nonlocal_goto_receiver)
+      emit_insn (gen_nonlocal_goto_receiver ());
+    else
 #endif
-  /* The static chain pointer contains the address of dummy function.
-     We need to call it here to handle some PIC cases of restoring a
-     global pointer.  Then return 1.  */
-  op0 = copy_to_mode_reg (Pmode, static_chain_rtx);
+      ; /* Nothing */
 
-  /* We can't actually call emit_library_call here, so do everything
-     it does, which isn't much for a libfunc with no args.  */
-  op0 = memory_address (FUNCTION_MODE, op0);
+  /* Set TARGET, and branch to the next-time-through label.  */
+  emit_move_insn (target, gen_lowpart (GET_MODE (target), static_chain_rtx));
+  emit_jump_insn (gen_jump (next_label));
+  emit_barrier ();
 
-  INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE,
-                       gen_rtx_SYMBOL_REF (Pmode, "__dummy"), 1);
-  next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
+  return target;
+}
 
-#ifndef ACCUMULATE_OUTGOING_ARGS
-#ifdef HAVE_call_pop
-  if (HAVE_call_pop)
-    emit_call_insn (gen_call_pop (gen_rtx_MEM (FUNCTION_MODE, op0),
-                                 const0_rtx, next_arg_reg,
-                                 GEN_INT (return_pops)));
-  else
+void
+expand_builtin_longjmp (buf_addr, value)
+     rtx buf_addr, value;
+{
+  rtx fp, lab, stack;
+  enum machine_mode sa_mode;
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+  buf_addr = convert_memory_address (Pmode, buf_addr);
 #endif
+  buf_addr = force_reg (Pmode, buf_addr);
+
+  /* The value sent by longjmp is not allowed to be zero.  Force it
+     to one if so.  */
+  if (GET_CODE (value) == CONST_INT)
+    {
+      if (INTVAL (value) == 0)
+       value = const1_rtx;
+    }
+  else
+    {
+      lab = gen_label_rtx ();
+
+      emit_cmp_insn (value, const0_rtx, NE, NULL_RTX, GET_MODE (value), 0, 0);
+      emit_jump_insn (gen_bne (lab));
+      emit_move_insn (value, const1_rtx);
+      emit_label (lab);
+    }
+
+  /* Make sure the value is in the right mode to be copied to the chain.  */
+  if (GET_MODE (value) != VOIDmode)
+    value = gen_lowpart (GET_MODE (static_chain_rtx), value);
+
+#ifdef HAVE_builtin_longjmp
+  if (HAVE_builtin_longjmp)
+    {
+      /* Copy the "return value" to the static chain reg.  */
+      emit_move_insn (static_chain_rtx, value);
+      emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
+      emit_insn (gen_builtin_longjmp (buf_addr));
+    }
+  else
 #endif
+    {
+      fp = gen_rtx_MEM (Pmode, buf_addr);
+      lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
+                                              GET_MODE_SIZE (Pmode)));
 
-#ifdef HAVE_call
-    if (HAVE_call)
-      emit_call_insn (gen_call (gen_rtx_MEM (FUNCTION_MODE, op0),
-                               const0_rtx, next_arg_reg, const0_rtx));
-    else
+#ifdef HAVE_save_stack_nonlocal
+      sa_mode = (HAVE_save_stack_nonlocal
+                ? insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0]
+                : Pmode);
+#else
+      sa_mode = Pmode;
 #endif
-      abort ();
 
-#ifdef HAVE_builtin_setjmp_receiver
-  if (HAVE_builtin_setjmp_receiver)
-    emit_insn (gen_builtin_setjmp_receiver ());
+      stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
+                                                  2 * GET_MODE_SIZE (Pmode)));
+
+      /* Pick up FP, label, and SP from the block and jump.  This code is
+        from expand_goto in stmt.c; see there for detailed comments.  */
+#if HAVE_nonlocal_goto
+      if (HAVE_nonlocal_goto)
+       emit_insn (gen_nonlocal_goto (value, fp, stack, lab));
+      else
 #endif
+       {
+         lab = copy_to_reg (lab);
 
-  emit_move_insn (target, const1_rtx);
-  emit_label (lab2);
-  return target;
+         /* Copy the "return value" to the static chain reg.  */
+         emit_move_insn (static_chain_rtx, value);
+
+         emit_move_insn (hard_frame_pointer_rtx, fp);
+         emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
+
+         emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+         emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+         emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
+         emit_indirect_jump (lab);
+       }
+    }
 }
 
 \f
@@ -8024,9 +8098,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
     case BUILT_IN_ARGS_INFO:
       {
        int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
-       int i;
        int *word_ptr = (int *) &current_function_args_info;
+#if 0  
+       /* These are used by the code below that is if 0'ed away */
+       int i;
        tree type, elts, result;
+#endif
 
        if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
          fatal ("CUMULATIVE_ARGS type defined badly; see %s, line %d",
@@ -8540,7 +8617,6 @@ expand_builtin (exp, target, subtarget, mode, ignore)
       {
        tree arg1 = TREE_VALUE (arglist);
        tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
-       tree offset;
        tree len, len2;
 
        len = c_strlen (arg1);
@@ -8658,89 +8734,33 @@ expand_builtin (exp, target, subtarget, mode, ignore)
       if (arglist == 0
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
        break;
+      else
+       {
+         rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
+                                     VOIDmode, 0);
+         rtx lab = gen_label_rtx ();
+         rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
+         emit_label (lab);
+         return ret;
+       }
 
-      {
-       rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
-                                   VOIDmode, 0);
-       return expand_builtin_setjmp (buf_addr, target);
-      }
-
-      /* __builtin_longjmp is passed a pointer to an array of five words
-        and a value, which is a dummy.  It's similar to the C library longjmp
-        function but works with __builtin_setjmp above.  */
+      /* __builtin_longjmp is passed a pointer to an array of five words.
+        It's similar to the C library longjmp function but works with
+        __builtin_setjmp above.  */
     case BUILT_IN_LONGJMP:
       if (arglist == 0 || TREE_CHAIN (arglist) == 0
          || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
        break;
-
-      {
-       tree dummy_id = get_identifier ("__dummy");
-       tree dummy_type = build_function_type (void_type_node, NULL_TREE);
-       tree dummy_decl = build_decl (FUNCTION_DECL, dummy_id, dummy_type); 
-#ifdef POINTERS_EXTEND_UNSIGNED
-       rtx buf_addr
-         = force_reg (Pmode,
-                      convert_memory_address
-                      (Pmode,
-                       expand_expr (TREE_VALUE (arglist),
-                                    NULL_RTX, VOIDmode, 0)));
-#else
-       rtx buf_addr
-         = force_reg (Pmode, expand_expr (TREE_VALUE (arglist),
-                                          NULL_RTX,
-                                          VOIDmode, 0));
-#endif
-       rtx fp = gen_rtx_MEM (Pmode, buf_addr);
-       rtx lab = gen_rtx_MEM (Pmode,
-                              plus_constant (buf_addr,
-                                             GET_MODE_SIZE (Pmode)));
-       enum machine_mode sa_mode
-#ifdef HAVE_save_stack_nonlocal
-         = (HAVE_save_stack_nonlocal
-            ? insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0]
-            : Pmode);
-#else
-       = Pmode;
-#endif
-       rtx stack = gen_rtx_MEM (sa_mode,
-                                plus_constant (buf_addr,
-                                               2 * GET_MODE_SIZE (Pmode)));
-
-       DECL_EXTERNAL (dummy_decl) = 1;
-       TREE_PUBLIC (dummy_decl) = 1;
-       make_decl_rtl (dummy_decl, NULL_PTR, 1);
-
-       /* Expand the second expression just for side-effects.  */
-       expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
-                    const0_rtx, VOIDmode, 0);
-
-       assemble_external (dummy_decl);
-
-       /* Pick up FP, label, and SP from the block and jump.  This code is
-          from expand_goto in stmt.c; see there for detailed comments.  */
-#if HAVE_nonlocal_goto
-       if (HAVE_nonlocal_goto)
-         emit_insn (gen_nonlocal_goto (fp, lab, stack,
-                                       XEXP (DECL_RTL (dummy_decl), 0)));
       else
-#endif
        {
-         lab = copy_to_reg (lab);
-         emit_move_insn (hard_frame_pointer_rtx, fp);
-         emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
-
-         /* Put in the static chain register the address of the dummy
-            function.  */
-         emit_move_insn (static_chain_rtx, XEXP (DECL_RTL (dummy_decl), 0));
-         emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
-         emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
-         emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
-         emit_indirect_jump (lab);
+         rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
+                                     VOIDmode, 0);
+         rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
+                                  const0_rtx, VOIDmode, 0);
+         expand_builtin_longjmp (buf_addr, value);
+         return const0_rtx;
        }
 
-       return const0_rtx;
-      }
-
       /* Various hooks for the DWARF 2 __throw routine.  */
     case BUILT_IN_UNWIND_INIT:
       expand_builtin_unwind_init ();
@@ -9558,14 +9578,18 @@ init_pending_stack_adjust ()
 }
 
 /* When exiting from function, if safe, clear out any pending stack adjust
-   so the adjustment won't get done.  */
+   so the adjustment won't get done.
+
+   Note, if the current function calls alloca, then it must have a
+   frame pointer regardless of the value of flag_omit_frame_pointer.  */
 
 void
 clear_pending_stack_adjust ()
 {
 #ifdef EXIT_IGNORE_STACK
   if (optimize > 0
-      && ! flag_omit_frame_pointer && EXIT_IGNORE_STACK
+      && (! flag_omit_frame_pointer || current_function_calls_alloca)
+      && EXIT_IGNORE_STACK
       && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
       && ! flag_inline_functions)
     pending_stack_adjust = 0;
@@ -10442,7 +10466,7 @@ do_store_flag (exp, target, mode, only_cheap)
   rtx op0, op1;
   enum insn_code icode;
   rtx subtarget = target;
-  rtx result, label, pattern, jump_pat;
+  rtx result, label;
 
   /* If this is a TRUTH_NOT_EXPR, set a flag indicating we must invert the
      result at the end.  We can't simply invert the test since it would