OSDN Git Service

* expr.c (force_operand): Use expand_simple_* to handle more
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 May 2002 11:23:21 +0000 (11:23 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 4 May 2002 11:23:21 +0000 (11:23 +0000)
cases.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53154 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index 426ac86..6d8a2e7 100644 (file)
@@ -1,3 +1,8 @@
+Sat May  4 13:20:54 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+       * expr.c (force_operand): Use expand_simple_* to handle more
+       cases.
+
 2002-05-04  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * c-lex.c (lex_string): Let cpp_parse_escape handles truncation
index 46cf042..dc4c335 100644 (file)
@@ -5432,16 +5432,13 @@ rtx
 force_operand (value, target)
      rtx value, target;
 {
-  optab binoptab = 0;
-  /* Use a temporary to force order of execution of calls to
-     `force_operand'.  */
-  rtx tmp;
-  rtx op2;
+  rtx op1, op2;
   /* Use subtarget as the target for operand 0 of a binary operation.  */
   rtx subtarget = get_subtarget (target);
+  enum rtx_code code = GET_CODE (value);
 
   /* Check for a PIC address load.  */
-  if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
+  if ((code == PLUS || code == MINUS)
       && XEXP (value, 0) == pic_offset_table_rtx
       && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
          || GET_CODE (XEXP (value, 1)) == LABEL_REF
@@ -5453,60 +5450,88 @@ force_operand (value, target)
       return subtarget;
     }
 
-  if (GET_CODE (value) == PLUS)
-    binoptab = add_optab;
-  else if (GET_CODE (value) == MINUS)
-    binoptab = sub_optab;
-  else if (GET_CODE (value) == MULT)
+  if (code == ZERO_EXTEND || code == SIGN_EXTEND)
     {
-      op2 = XEXP (value, 1);
-      if (!CONSTANT_P (op2)
-         && !(GET_CODE (op2) == REG && op2 != subtarget))
-       subtarget = 0;
-      tmp = force_operand (XEXP (value, 0), subtarget);
-      return expand_mult (GET_MODE (value), tmp,
-                         force_operand (op2, NULL_RTX),
-                         target, 1);
+      if (!target)
+       target = gen_reg_rtx (GET_MODE (value));
+      convert_move (force_operand (XEXP (value, 0), NULL), target,
+                   code == ZERO_EXTEND);
+      return target;
     }
 
-  if (binoptab)
+  if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c')
     {
       op2 = XEXP (value, 1);
-      if (!CONSTANT_P (op2)
-         && !(GET_CODE (op2) == REG && op2 != subtarget))
+      if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget))
        subtarget = 0;
-      if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT)
+      if (code == MINUS && GET_CODE (op2) == CONST_INT)
        {
-         binoptab = add_optab;
+         code = PLUS;
          op2 = negate_rtx (GET_MODE (value), op2);
        }
 
       /* Check for an addition with OP2 a constant integer and our first
-        operand a PLUS of a virtual register and something else.  In that
-        case, we want to emit the sum of the virtual register and the
-        constant first and then add the other value.  This allows virtual
-        register instantiation to simply modify the constant rather than
-        creating another one around this addition.  */
-      if (binoptab == add_optab && GET_CODE (op2) == CONST_INT
+         operand a PLUS of a virtual register and something else.  In that
+         case, we want to emit the sum of the virtual register and the
+         constant first and then add the other value.  This allows virtual
+         register instantiation to simply modify the constant rather than
+         creating another one around this addition.  */
+      if (code == PLUS && GET_CODE (op2) == CONST_INT
          && GET_CODE (XEXP (value, 0)) == PLUS
          && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
          && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER
          && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER)
        {
-         rtx temp = expand_binop (GET_MODE (value), binoptab,
-                                  XEXP (XEXP (value, 0), 0), op2,
-                                  subtarget, 0, OPTAB_LIB_WIDEN);
-         return expand_binop (GET_MODE (value), binoptab, temp,
-                              force_operand (XEXP (XEXP (value, 0), 1), 0),
-                              target, 0, OPTAB_LIB_WIDEN);
+         rtx temp = expand_simple_binop (GET_MODE (value), code,
+                                         XEXP (XEXP (value, 0), 0), op2,
+                                         subtarget, 0, OPTAB_LIB_WIDEN);
+         return expand_simple_binop (GET_MODE (value), code, temp,
+                                     force_operand (XEXP (XEXP (value,
+                                                                0), 1), 0),
+                                     target, 0, OPTAB_LIB_WIDEN);
+       }
+
+      op1 = force_operand (XEXP (value, 0), subtarget);
+      op2 = force_operand (op2, NULL_RTX);
+      switch (code)
+       {
+       case MULT:
+         return expand_mult (GET_MODE (value), op1, op2, target, 1);
+       case DIV:
+         if (!INTEGRAL_MODE_P (GET_MODE (value)))
+           return expand_simple_binop (GET_MODE (value), code, op1, op2,
+                                       target, 1, OPTAB_LIB_WIDEN);
+         else
+           return expand_divmod (0,
+                                 FLOAT_MODE_P (GET_MODE (value))
+                                 ? RDIV_EXPR : TRUNC_DIV_EXPR,
+                                 GET_MODE (value), op1, op2, target, 0);
+         break;
+       case MOD:
+         return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
+                               target, 0);
+         break;
+       case UDIV:
+         return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
+                               target, 1);
+         break;
+       case UMOD:
+         return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
+                               target, 1);
+         break;
+       case ASHIFTRT:
+         return expand_simple_binop (GET_MODE (value), code, op1, op2,
+                                     target, 0, OPTAB_LIB_WIDEN);
+         break;
+       default:
+         return expand_simple_binop (GET_MODE (value), code, op1, op2,
+                                     target, 1, OPTAB_LIB_WIDEN);
        }
-
-      tmp = force_operand (XEXP (value, 0), subtarget);
-      return expand_binop (GET_MODE (value), binoptab, tmp,
-                          force_operand (op2, NULL_RTX),
-                          target, 0, OPTAB_LIB_WIDEN);
-      /* We give UNSIGNEDP = 0 to expand_binop
-        because the only operations we are expanding here are signed ones.  */
+    }
+  if (GET_RTX_CLASS (code) == '1')
+    {
+      op1 = force_operand (XEXP (value, 0), NULL_RTX);
+      return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
     }
 
 #ifdef INSN_SCHEDULING