From 96f57e365c008c4825c9c88e90db818ec4c99aad Mon Sep 17 00:00:00 2001 From: mmitchel Date: Thu, 1 Apr 2004 23:30:25 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80335 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 17 ++++ gcc/config/arm/arm-protos.h | 4 +- gcc/config/arm/arm.c | 209 ++++++++++++++++++++++++++++---------------- gcc/config/arm/arm.md | 37 ++++---- gcc/genemit.c | 5 +- gcc/genrecog.c | 4 +- gcc/gensupport.c | 61 +++++++++++-- 7 files changed, 233 insertions(+), 104 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7493145a38..eada5df2d2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2004-04-01 Mark Mitchell + + * 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 * cgraph.c: Add overall comment. diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index 986f1eca78e..437455f452d 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -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); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1c42ad0046c..b16836d5d69 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 51f94878295..7255b325997 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -454,8 +454,8 @@ " 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; } @@ -493,7 +493,8 @@ || 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; " @@ -940,7 +941,8 @@ { 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 ())); @@ -974,8 +976,8 @@ && !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") @@ -1516,7 +1518,8 @@ { 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 ())); @@ -1583,8 +1586,8 @@ || 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") @@ -2069,8 +2072,8 @@ { 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; @@ -2094,8 +2097,8 @@ && !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") @@ -4146,8 +4149,8 @@ && !(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; @@ -4197,8 +4200,8 @@ || 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; " ) diff --git a/gcc/genemit.c b/gcc/genemit.c index 00cf8423201..c31b1fb1909 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -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"); diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 2f5028cac8d..2d4c0911cd9 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -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: diff --git a/gcc/gensupport.c b/gcc/gensupport.c index b8cf5e67a51..6cc957863bd 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -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; } -/* 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); } } -- 2.11.4.GIT