re PR target/14040 (ARM cross compiler: error: could not split insn)
authorMark Mitchell <mark@codesourcery.com>
Thu, 1 Apr 2004 23:30:25 +0000 (23:30 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 1 Apr 2004 23:30:25 +0000 (23:30 +0000)
PR target/14040
* genemit.c (gen_split): Change prototype of generated code.
* genrecog.c (write_action): Adjust prototype for and calls to
gen_split_*.
* gensupport.c (struct queue_elem): Add split field.
(queue_pattern): Return a value.  Clear the split field.
(process_rtx): Maintain an association between an insn and the
split generated from it for a define_insn_and_split.
(process_one_cond_exec): Generate a new split for a
define_insn_and_split.
* config/arm/arm-protos.h (arm_split_constant): Add insn
parameter.
(emit_constant_insn): New function.
(arm_gen_constant): Use it.
* config/arm/arm.md: Adjust calls to arm_split_constant.

From-SVN: r80335

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/genemit.c
gcc/genrecog.c
gcc/gensupport.c

index a7493145a38b4e1103f49bd6524290d52bd1911d..eada5df2d2d743a029262b342db0d1680f5c5872 100644 (file)
@@ -1,3 +1,20 @@
+2004-04-01  Mark Mitchell  <mark@codesourcery.com>
+
+       * genemit.c (gen_split): Change prototype of generated code.
+       * genrecog.c (write_action): Adjust prototype for and calls to
+       gen_split_*.
+       * gensupport.c (struct queue_elem): Add split field.
+       (queue_pattern): Return a value.  Clear the split field.
+       (process_rtx): Maintain an association between an insn and the
+       split generated from it for a define_insn_and_split.
+       (process_one_cond_exec): Generate a new split for a
+       define_insn_and_split.
+       * config/arm/arm-protos.h (arm_split_constant): Add insn
+       parameter.
+       (emit_constant_insn): New function.
+       (arm_gen_constant): Use it.
+       * config/arm/arm.md: Adjust calls to arm_split_constant.
+
 2004-04-02  Jan Hubicka  <jh@suse.cz>
 
        * cgraph.c: Add overall comment.
index 986f1eca78efcc2fdb212d28399bf55a8dda7f4c..437455f452dd384fe0ccfe964a991fcca72d6f3a 100644 (file)
@@ -46,8 +46,8 @@ extern void arm_encode_call_attribute (tree, int);
 #ifdef RTX_CODE
 extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
 extern int const_ok_for_arm (HOST_WIDE_INT);
-extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx,
-                              rtx, int);
+extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
+                              HOST_WIDE_INT, rtx, rtx, int);
 extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
 extern int legitimate_pic_operand_p (rtx);
 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
index 1c42ad0046cf635de9d29789dcc9d6729c7d0871..b16836d5d698280ab04822e111e04961c5014f45 100644 (file)
@@ -61,8 +61,8 @@ const struct attribute_spec arm_attribute_table[];
 /* Forward function declarations.  */
 static arm_stack_offsets *arm_get_frame_offsets (void);
 static void arm_add_gc_roots (void);
-static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT,
-                            rtx, rtx, int, int);
+static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx,
+                            HOST_WIDE_INT, rtx, rtx, int, int);
 static unsigned bit_count (unsigned long);
 static int arm_address_register_rtx_p (rtx, int);
 static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
@@ -140,6 +140,7 @@ static rtx safe_vector_operand (rtx, enum machine_mode);
 static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
 static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
 static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void emit_constant_insn (rtx cond, rtx pattern);
 
 #ifdef OBJECT_FORMAT_ELF
 static void arm_elf_asm_named_section (const char *, unsigned int);
@@ -1343,9 +1344,16 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
    Return value is the number of insns emitted.  */
 
 int
-arm_split_constant (enum rtx_code code, enum machine_mode mode,
+arm_split_constant (enum rtx_code code, enum machine_mode mode, rtx insn,
                    HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
 {
+  rtx cond;
+
+  if (insn && GET_CODE (PATTERN (insn)) == COND_EXEC)
+    cond = COND_EXEC_TEST (PATTERN (insn));
+  else
+    cond = NULL_RTX;
+
   if (subtargets || code == SET
       || (GET_CODE (target) == REG && GET_CODE (source) == REG
          && REGNO (target) != REGNO (source)))
@@ -1360,7 +1368,9 @@ arm_split_constant (enum rtx_code code, enum machine_mode mode,
         Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
       */
       if (!after_arm_reorg
-         && (arm_gen_constant (code, mode, val, target, source, 1, 0)
+         && !cond
+         && (arm_gen_constant (code, mode, NULL_RTX, val, target, source, 
+                               1, 0)
              > arm_constant_limit + (code != SET)))
        {
          if (code == SET)
@@ -1388,7 +1398,8 @@ arm_split_constant (enum rtx_code code, enum machine_mode mode,
        }
     }
 
-  return arm_gen_constant (code, mode, val, target, source, subtargets, 1);
+  return arm_gen_constant (code, mode, cond, val, target, source, subtargets, 
+                          1);
 }
 
 static int
@@ -1418,11 +1429,23 @@ count_insns_for_constant (HOST_WIDE_INT remainder, int i)
   return num_insns;
 }
 
+/* Emit an instruction with the indicated PATTERN.  If COND is
+   non-NULL, conditionalize the execution of the instruction on COND
+   being true.  */
+
+static void
+emit_constant_insn (rtx cond, rtx pattern)
+{
+  if (cond)
+    pattern = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond), pattern);
+  emit_insn (pattern);
+}
+
 /* As above, but extra parameter GENERATE which, if clear, suppresses
    RTL generation.  */
 
 static int
-arm_gen_constant (enum rtx_code code, enum machine_mode mode,
+arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
                  HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
                  int generate)
 {
@@ -1460,8 +1483,9 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
       if (remainder == 0xffffffff)
        {
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target,
-                                   GEN_INT (ARM_SIGN_EXTEND (val))));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target,
+                                            GEN_INT (ARM_SIGN_EXTEND (val))));
          return 1;
        }
       if (remainder == 0)
@@ -1469,7 +1493,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
          if (reload_completed && rtx_equal_p (target, source))
            return 0;
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target, source));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target, source));
          return 1;
        }
       break;
@@ -1478,7 +1503,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
       if (remainder == 0)
        {
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target, const0_rtx));
          return 1;
        }
       if (remainder == 0xffffffff)
@@ -1486,7 +1512,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
          if (reload_completed && rtx_equal_p (target, source))
            return 0;
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target, source));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target, source));
          return 1;
        }
       can_invert = 1;
@@ -1498,14 +1525,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
          if (reload_completed && rtx_equal_p (target, source))
            return 0;
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target, source));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target, source));
          return 1;
        }
       if (remainder == 0xffffffff)
        {
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target,
-                                   gen_rtx_NOT (mode, source)));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target,
+                                            gen_rtx_NOT (mode, source)));
          return 1;
        }
 
@@ -1518,16 +1547,18 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
       if (remainder == 0)
        {
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target,
-                                   gen_rtx_NEG (mode, source)));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target,
+                                            gen_rtx_NEG (mode, source)));
          return 1;
        }
       if (const_ok_for_arm (val))
        {
          if (generate)
-           emit_insn (gen_rtx_SET (VOIDmode, target, 
-                                   gen_rtx_MINUS (mode, GEN_INT (val),
-                                                  source)));
+           emit_constant_insn (cond,
+                               gen_rtx_SET (VOIDmode, target, 
+                                            gen_rtx_MINUS (mode, GEN_INT (val),
+                                                           source)));
          return 1;
        }
       can_negate = 1;
@@ -1544,10 +1575,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
       || (can_invert && const_ok_for_arm (~val)))
     {
       if (generate)
-       emit_insn (gen_rtx_SET (VOIDmode, target,
-                               (source ? gen_rtx_fmt_ee (code, mode, source,
-                                                  GEN_INT (val))
-                                : GEN_INT (val))));
+       emit_constant_insn (cond,
+                           gen_rtx_SET (VOIDmode, target,
+                                        (source 
+                                         ? gen_rtx_fmt_ee (code, mode, source,
+                                                           GEN_INT (val))
+                                         : GEN_INT (val))));
       return 1;
     }
 
@@ -1600,10 +1633,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
              if (generate)
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
-                 emit_insn (gen_rtx_SET (VOIDmode, new_src, 
-                                         GEN_INT (temp1)));
-                 emit_insn (gen_ashrsi3 (target, new_src, 
-                                         GEN_INT (set_sign_bit_copies - 1)));
+                 emit_constant_insn (cond,
+                                     gen_rtx_SET (VOIDmode, new_src, 
+                                                  GEN_INT (temp1)));
+                 emit_constant_insn (cond,
+                                     gen_ashrsi3 (target, new_src, 
+                                                  GEN_INT (set_sign_bit_copies - 1)));
                }
              return 2;
            }
@@ -1615,10 +1650,12 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
              if (generate)
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
-                 emit_insn (gen_rtx_SET (VOIDmode, new_src,
-                                         GEN_INT (temp1)));
-                 emit_insn (gen_ashrsi3 (target, new_src, 
-                                         GEN_INT (set_sign_bit_copies - 1)));
+                 emit_constant_insn (cond,
+                                     gen_rtx_SET (VOIDmode, new_src,
+                                                  GEN_INT (temp1)));
+                 emit_constant_insn (cond,
+                                     gen_ashrsi3 (target, new_src, 
+                                                  GEN_INT (set_sign_bit_copies - 1)));
                }
              return 2;
            }
@@ -1643,16 +1680,18 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                  rtx new_src = (subtargets
                                 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
                                 : target);
-                 insns = arm_gen_constant (code, mode, temp2, new_src,
+                 insns = arm_gen_constant (code, mode, cond, temp2, new_src,
                                            source, subtargets, generate);
                  source = new_src;
                  if (generate)
-                   emit_insn (gen_rtx_SET
-                              (VOIDmode, target,
-                               gen_rtx_IOR (mode,
-                                            gen_rtx_ASHIFT (mode, source,
-                                                            GEN_INT (i)),
-                                            source)));
+                   emit_constant_insn 
+                     (cond,
+                      gen_rtx_SET
+                      (VOIDmode, target,
+                       gen_rtx_IOR (mode,
+                                    gen_rtx_ASHIFT (mode, source,
+                                                    GEN_INT (i)),
+                                    source)));
                  return insns + 1;
                }
            }
@@ -1666,12 +1705,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                  rtx new_src = (subtargets
                                 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
                                 : target);
-                 insns = arm_gen_constant (code, mode, temp1, new_src,
+                 insns = arm_gen_constant (code, mode, cond, temp1, new_src,
                                            source, subtargets, generate);
                  source = new_src;
                  if (generate)
-                   emit_insn
-                     (gen_rtx_SET (VOIDmode, target,
+                   emit_constant_insn
+                     (cond,
+                      gen_rtx_SET (VOIDmode, target,
                                    gen_rtx_IOR
                                    (mode,
                                     gen_rtx_LSHIFTRT (mode, source,
@@ -1698,9 +1738,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                {
                  rtx sub = subtargets ? gen_reg_rtx (mode) : target;
 
-                 emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
-                 emit_insn (gen_rtx_SET (VOIDmode, target, 
-                                         gen_rtx_fmt_ee (code, mode, source, sub)));
+                 emit_constant_insn (cond,
+                                     gen_rtx_SET (VOIDmode, sub, 
+                                                  GEN_INT (val)));
+                 emit_constant_insn (cond,
+                                     gen_rtx_SET (VOIDmode, target, 
+                                                  gen_rtx_fmt_ee (code, mode,
+                                                                  source, sub)));
                }
              return 2;
            }
@@ -1717,15 +1761,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
              rtx sub = subtargets ? gen_reg_rtx (mode) : target;
              rtx shift = GEN_INT (set_sign_bit_copies);
 
-             emit_insn (gen_rtx_SET (VOIDmode, sub,
-                                     gen_rtx_NOT (mode, 
-                                                  gen_rtx_ASHIFT (mode,
-                                                                  source, 
-                                                                  shift))));
-             emit_insn (gen_rtx_SET (VOIDmode, target,
-                                     gen_rtx_NOT (mode,
-                                                  gen_rtx_LSHIFTRT (mode, sub,
-                                                                    shift))));
+             emit_constant_insn 
+               (cond,
+                gen_rtx_SET (VOIDmode, sub,
+                             gen_rtx_NOT (mode, 
+                                          gen_rtx_ASHIFT (mode,
+                                                          source, 
+                                                          shift))));
+             emit_constant_insn 
+               (cond,
+                gen_rtx_SET (VOIDmode, target,
+                             gen_rtx_NOT (mode,
+                                          gen_rtx_LSHIFTRT (mode, sub,
+                                                            shift))));
            }
          return 2;
        }
@@ -1738,15 +1786,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
              rtx sub = subtargets ? gen_reg_rtx (mode) : target;
              rtx shift = GEN_INT (set_zero_bit_copies);
 
-             emit_insn (gen_rtx_SET (VOIDmode, sub,
-                                     gen_rtx_NOT (mode,
-                                                  gen_rtx_LSHIFTRT (mode,
-                                                                    source,
-                                                                    shift))));
-             emit_insn (gen_rtx_SET (VOIDmode, target,
-                                     gen_rtx_NOT (mode,
-                                                  gen_rtx_ASHIFT (mode, sub,
-                                                                  shift))));
+             emit_constant_insn
+               (cond,
+                gen_rtx_SET (VOIDmode, sub,
+                             gen_rtx_NOT (mode,
+                                          gen_rtx_LSHIFTRT (mode,
+                                                            source,
+                                                            shift))));
+             emit_constant_insn 
+               (cond,
+                gen_rtx_SET (VOIDmode, target,
+                             gen_rtx_NOT (mode,
+                                          gen_rtx_ASHIFT (mode, sub,
+                                                          shift))));
            }
          return 2;
        }
@@ -1756,16 +1808,19 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
          if (generate)
            {
              rtx sub = subtargets ? gen_reg_rtx (mode) : target;
-             emit_insn (gen_rtx_SET (VOIDmode, sub,
-                                     gen_rtx_NOT (mode, source)));
+             emit_constant_insn (cond,
+                                 gen_rtx_SET (VOIDmode, sub,
+                                              gen_rtx_NOT (mode, source)));
              source = sub;
              if (subtargets)
                sub = gen_reg_rtx (mode);
-             emit_insn (gen_rtx_SET (VOIDmode, sub,
-                                     gen_rtx_AND (mode, source, 
-                                                  GEN_INT (temp1))));
-             emit_insn (gen_rtx_SET (VOIDmode, target,
-                                     gen_rtx_NOT (mode, sub)));
+             emit_constant_insn (cond,
+                                 gen_rtx_SET (VOIDmode, sub,
+                                              gen_rtx_AND (mode, source, 
+                                                           GEN_INT (temp1))));
+             emit_constant_insn (cond,
+                                 gen_rtx_SET (VOIDmode, target,
+                                              gen_rtx_NOT (mode, sub)));
            }
          return 3;
        }
@@ -1784,14 +1839,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
              if (generate)
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
-                 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond, 
+                                           remainder | shift_mask,
                                            new_src, source, subtargets, 1);
                  source = new_src;
                }
              else
                {
                  rtx targ = subtargets ? NULL_RTX : target;
-                 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond,
+                                           remainder | shift_mask,
                                            targ, source, subtargets, 0);
                }
            }
@@ -1818,7 +1875,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                {
                  rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
 
-                 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond,
+                                           remainder | shift_mask,
                                            new_src, source, subtargets, 1);
                  source = new_src;
                }
@@ -1826,7 +1884,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                {
                  rtx targ = subtargets ? NULL_RTX : target;
 
-                 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
+                 insns = arm_gen_constant (AND, mode, cond,
+                                           remainder | shift_mask,
                                            targ, source, subtargets, 0);
                }
            }
@@ -1971,7 +2030,9 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode,
                else
                  temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
 
-               emit_insn (gen_rtx_SET (VOIDmode, new_src, temp1_rtx));
+               emit_constant_insn (cond,
+                                   gen_rtx_SET (VOIDmode, new_src, 
+                                                temp1_rtx));
                source = new_src;
              }
 
index 51f9487829592ef29026fd317c2604c44554b23a..7255b325997ee99c351b210dd0b6b367ac95f9e1 100644 (file)
   "
   if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT)
     {
-      arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
-                         operands[1],
+      arm_split_constant (PLUS, SImode, NULL_RTX,
+                         INTVAL (operands[2]), operands[0], operands[1],
                          (no_new_pseudos ? 0 : preserve_subexpressions_p ()));
       DONE;
     }
         || const_ok_for_arm (-INTVAL (operands[2])))"
   [(clobber (const_int 0))]
   "
-  arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0],
+  arm_split_constant (PLUS, SImode, curr_insn,
+                     INTVAL (operands[2]), operands[0],
                      operands[1], 0);
   DONE;
   "
     {
       if (TARGET_ARM)
         {
-          arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
+          arm_split_constant (MINUS, SImode, NULL_RTX,
+                             INTVAL (operands[1]), operands[0],
                              operands[2],
                              (no_new_pseudos ? 0
                               :  preserve_subexpressions_p ()));
    && !const_ok_for_arm (INTVAL (operands[1]))"
   [(clobber (const_int 0))]
   "
-  arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0],
-                     operands[2], 0);
+  arm_split_constant (MINUS, SImode, curr_insn,
+                      INTVAL (operands[1]), operands[0], operands[2], 0);
   DONE;
   "
   [(set_attr "length" "4,16")
     {
       if (GET_CODE (operands[2]) == CONST_INT)
         {
-          arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0],
+          arm_split_constant (AND, SImode, NULL_RTX,
+                             INTVAL (operands[2]), operands[0],
                              operands[1],
                              (no_new_pseudos
                               ? 0 : preserve_subexpressions_p ()));
        || const_ok_for_arm (~INTVAL (operands[2])))"
   [(clobber (const_int 0))]
   "
-  arm_split_constant  (AND, SImode, INTVAL (operands[2]), operands[0],
-                      operands[1], 0);
+  arm_split_constant  (AND, SImode, curr_insn, 
+                      INTVAL (operands[2]), operands[0], operands[1], 0);
   DONE;
   "
   [(set_attr "length" "4,4,16")
     {
       if (TARGET_ARM)
         {
-          arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
-                             operands[1],
+          arm_split_constant (IOR, SImode, NULL_RTX,
+                             INTVAL (operands[2]), operands[0], operands[1],
                              (no_new_pseudos
                              ? 0 : preserve_subexpressions_p ()));
           DONE;
    && !const_ok_for_arm (INTVAL (operands[2]))"
   [(clobber (const_int 0))]
   "
-  arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0],
-                     operands[1], 0);
+  arm_split_constant (IOR, SImode, curr_insn, 
+                      INTVAL (operands[2]), operands[0], operands[1], 0);
   DONE;
   "
   [(set_attr "length" "4,16")
           && !(const_ok_for_arm (INTVAL (operands[1]))
                || const_ok_for_arm (~INTVAL (operands[1]))))
         {
-           arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
-                             NULL_RTX,
+           arm_split_constant (SET, SImode, NULL_RTX,
+                              INTVAL (operands[1]), operands[0], NULL_RTX,
                              (no_new_pseudos ? 0
                               : preserve_subexpressions_p ()));
           DONE;
         || const_ok_for_arm (~INTVAL (operands[1]))))"
   [(clobber (const_int 0))]
   "
-  arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0],
-                     NULL_RTX, 0);
+  arm_split_constant (SET, SImode, NULL_RTX, 
+                      INTVAL (operands[1]), operands[0], NULL_RTX, 0);
   DONE;
   "
 )
index 00cf8423201dd366952de0d8397257227a9daa10..c31b1fb1909824891e65681081a6cdd7c45e1372 100644 (file)
@@ -599,8 +599,9 @@ gen_split (rtx split)
     }
   else
     {
-      printf ("extern rtx gen_split_%d (rtx *);\n", insn_code_number);
-      printf ("rtx\ngen_%s_%d (rtx *operands%s)\n", name, insn_code_number, unused);
+      printf ("extern rtx gen_split_%d (rtx, rtx *);\n", insn_code_number);
+      printf ("rtx\ngen_split_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n", 
+             insn_code_number, unused);
     }
   printf ("{\n");
 
index 2f5028cac8da4f5d6f92336187b71bfa8c22cacf..2d4c0911cd958f78a1633862c91398623d1417eb 100644 (file)
@@ -2086,7 +2086,7 @@ write_action (struct decision *p, struct decision_test *test,
          break;
 
        case SPLIT:
-         printf ("%sreturn gen_split_%d (operands);\n",
+         printf ("%sreturn gen_split_%d (insn, operands);\n",
                  indent, test->u.insn.code_number);
          break;
 
@@ -2583,7 +2583,7 @@ make_insn_sequence (rtx insn, enum routine_type type)
 
     case SPLIT:
       /* Define the subroutine we will call below and emit in genemit.  */
-      printf ("extern rtx gen_split_%d (rtx *);\n", next_insn_code);
+      printf ("extern rtx gen_split_%d (rtx, rtx *);\n", next_insn_code);
       break;
 
     case PEEPHOLE2:
index b8cf5e67a519ae72d2b33737e78c253e4fdd4d19..6cc957863bdd9603017ab500225167faff11e1be 100644 (file)
@@ -58,6 +58,9 @@ struct queue_elem
   const char *filename;
   int lineno;
   struct queue_elem *next;
+  /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
+     points to the generated DEFINE_SPLIT.  */
+  struct queue_elem *split;
 };
 
 static struct queue_elem *define_attr_queue;
@@ -69,8 +72,8 @@ static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
 static struct queue_elem *other_queue;
 static struct queue_elem **other_tail = &other_queue;
 
-static void queue_pattern (rtx, struct queue_elem ***,
-                          const char *, int);
+static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
+                                        const char *, int);
 
 /* Current maximum length of directory names in the search path
    for include files.  (Altered as we get more of them.)  */
@@ -134,9 +137,10 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
   return rt;
 }
 \f
-/* Queue PATTERN on LIST_TAIL.  */
+/* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
+   element.  */
 
-static void
+static struct queue_elem *
 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
               const char *filename, int lineno)
 {
@@ -145,8 +149,10 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail,
   e->filename = filename;
   e->lineno = lineno;
   e->next = NULL;
+  e->split = NULL;
   **list_tail = e;
   *list_tail = &e->next;
+  return e;
 }
 
 /* Recursively remove constraints from an rtx.  */
@@ -288,6 +294,8 @@ process_rtx (rtx desc, int lineno)
        rtx split;
        rtvec attr;
        int i;
+       struct queue_elem *insn_elem;
+       struct queue_elem *split_elem;
 
        /* Create a split with values from the insn_and_split.  */
        split = rtx_alloc (DEFINE_SPLIT);
@@ -315,8 +323,12 @@ process_rtx (rtx desc, int lineno)
        XVEC (desc, 4) = attr;
 
        /* Queue them.  */
-       queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno);
-       queue_pattern (split, &other_tail, read_rtx_filename, lineno);
+       insn_elem
+         = queue_pattern (desc, &define_insn_tail, read_rtx_filename, 
+                          lineno);
+       split_elem
+         = queue_pattern (split, &other_tail, read_rtx_filename, lineno);
+       insn_elem->split = split_elem;
        break;
       }
 
@@ -755,7 +767,8 @@ process_one_cond_exec (struct queue_elem *ce_elem)
   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
     {
       int alternatives, max_operand;
-      rtx pred, insn, pattern;
+      rtx pred, insn, pattern, split;
+      int i;
 
       if (! is_predicable (insn_elem))
        continue;
@@ -818,6 +831,40 @@ process_one_cond_exec (struct queue_elem *ce_elem)
 
       queue_pattern (insn, &other_tail, insn_elem->filename,
                     insn_elem->lineno);
+
+      if (!insn_elem->split)
+       continue;
+
+      /* If the original insn came from a define_insn_and_split,
+        generate a new split to handle the predicated insn. */
+      split = copy_rtx (insn_elem->split->data);
+      /* Predicate the pattern matched by the split.  */
+      pattern = rtx_alloc (COND_EXEC);
+      XEXP (pattern, 0) = pred;
+      if (XVECLEN (split, 0) == 1)
+       {
+         XEXP (pattern, 1) = XVECEXP (split, 0, 0);
+         XVECEXP (split, 0, 0) = pattern;
+         PUT_NUM_ELEM (XVEC (split, 0), 1);
+       }
+      else
+       {
+         XEXP (pattern, 1) = rtx_alloc (PARALLEL);
+         XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
+         XVEC (split, 0) = rtvec_alloc (1);
+         XVECEXP (split, 0, 0) = pattern;
+       }
+      /* Predicate all of the insns generated by the split.  */
+      for (i = 0; i < XVECLEN (split, 2); i++)
+       {
+         pattern = rtx_alloc (COND_EXEC);
+         XEXP (pattern, 0) = pred;
+         XEXP (pattern, 1) = XVECEXP (split, 2, i);
+         XVECEXP (split, 2, i) = pattern;
+       }
+      /* Add the new split to the queue.  */
+      queue_pattern (split, &other_tail, read_rtx_filename, 
+                    insn_elem->split->lineno);
     }
 }