From 002cef58de4da1ebd8ab34df6368faf4ca7cc6f9 Mon Sep 17 00:00:00 2001 From: "m.hayes" Date: Wed, 25 Nov 1998 19:59:39 +0000 Subject: [PATCH] * config/c4x/c4x.c: (c4x_override_options): For compatibility with old target options clear flag_branch_on_count_reg if -mno-rptb specified and set flag_argument_alias is -mno-aliases specified. (c4x_output_cbranch): Handle a sequence of insns rather than a single insn. (c4x_rptb_insert): Do not emit a RPTB insn if the RC register has not been allocated as the loop counter. (c4x_address_conflict): Do not allow two volatile memory references. (valid_parallel_operands_4, valid_parallel_operands_5, valid_parallel_operands_6): Reject pattern if the register destination of the first set is used as part of an address in the second set. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23879 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++- gcc/config/c4x/c4x.c | 141 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 55 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0181a9..f53c400 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -16,9 +16,12 @@ Thu Nov 26 15:16:05 1998 Michael Hayes specified. (c4x_output_cbranch): Handle a sequence of insns rather than a single insn. - (c4x_rptb_insert): Don not emit a RPTB insn if the RC register + (c4x_rptb_insert): Do not emit a RPTB insn if the RC register has not been allocated as the loop counter. - (c4x_address_conflict): + (c4x_address_conflict): Do not allow two volatile memory references. + (valid_parallel_operands_4, valid_parallel_operands_5, + valid_parallel_operands_6): Reject pattern if the register destination + of the first set is used as part of an address in the second set. Thu Nov 26 14:56:32 1998 Michael Hayes diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c index b63b863..b7b02c4 100644 --- a/gcc/config/c4x/c4x.c +++ b/gcc/config/c4x/c4x.c @@ -159,9 +159,6 @@ tree interrupt_tree = NULL_TREE; void c4x_override_options () { - /* Convert foo / 8.0 into foo * 0.125, etc. */ - flag_fast_math = 1; - if (c4x_rpts_cycles_string) c4x_rpts_cycles = atoi (c4x_rpts_cycles_string); else @@ -204,8 +201,21 @@ c4x_override_options () else target_flags &= ~C3X_FLAG; + /* Convert foo / 8.0 into foo * 0.125, etc. */ + flag_fast_math = 1; + + /* We should phase out the following at some stage. + This provides compatibility with the old -mno-rptb option. */ + if (!TARGET_RPTB && flag_branch_on_count_reg) + flag_branch_on_count_reg = 0; + + /* We should phase out the following at some stage. + This provides compatibility with the old -mno-aliases option. */ + if (!TARGET_ALIASES && !flag_argument_noalias) + flag_argument_noalias = 1; } +/* This is called before c4x_override_options. */ void c4x_optimization_options (level, size) int level; @@ -213,7 +223,7 @@ c4x_optimization_options (level, size) { /* When optimizing, enable use of RPTB instruction. */ if (level >= 1) - flag_branch_on_count_reg = 1; + flag_branch_on_count_reg = 1; } /* Write an ASCII string. */ @@ -1419,30 +1429,26 @@ c4x_gen_compare_reg (code, x, y) } char * -c4x_output_cbranch (reversed, insn) - int reversed; - rtx insn; +c4x_output_cbranch (form, seq) + char *form; + rtx seq; { int delayed = 0; int annultrue = 0; int annulfalse = 0; rtx delay; char *cp; - static char str[20]; + static char str[100]; if (final_sequence) { delay = XVECEXP (final_sequence, 0, 1); - delayed = !INSN_ANNULLED_BRANCH_P (insn); - annultrue = INSN_ANNULLED_BRANCH_P (insn) && !INSN_FROM_TARGET_P (delay); - annulfalse = INSN_ANNULLED_BRANCH_P (insn) && INSN_FROM_TARGET_P (delay); + delayed = !INSN_ANNULLED_BRANCH_P (seq); + annultrue = INSN_ANNULLED_BRANCH_P (seq) && !INSN_FROM_TARGET_P (delay); + annulfalse = INSN_ANNULLED_BRANCH_P (seq) && INSN_FROM_TARGET_P (delay); } - cp = str; - *cp++ = 'b'; - *cp++ = '%'; - if (reversed) - *cp++ = 'I'; - *cp++ = '0'; + strcpy (str, form); + cp = &str [strlen (str)]; if (delayed) { *cp++ = '%'; @@ -1466,7 +1472,6 @@ c4x_output_cbranch (reversed, insn) return str; } - void c4x_print_operand (file, op, letter) FILE *file; /* file to write to */ @@ -2040,10 +2045,19 @@ c4x_rptb_insert (insn) { rtx end_label; rtx start_label; - + rtx count_reg; + + /* If the count register has not been allocated to RC, say if + there is a movstr pattern in the loop, then do not insert a + RPTB instruction. Instead we emit a decrement and branch + at the end of the loop. */ + count_reg = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0), 0); + if (REGNO (count_reg) != RC_REGNO) + return; + /* Extract the start label from the jump pattern (rptb_end). */ start_label = XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0); - + /* We'll have to update the basic blocks. */ end_label = gen_label_rtx (); emit_label_after (end_label, insn); @@ -3123,6 +3137,9 @@ c4x_address_conflict (op0, op1, store0, store1) int disp0; int disp1; + if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1)) + return 1; + c4x_S_address_parse (op0, &base0, &incdec0, &index0, &disp0); c4x_S_address_parse (op1, &base1, &incdec1, &index1, &disp1); @@ -3137,12 +3154,7 @@ c4x_address_conflict (op0, op1, store0, store1) have an aliased address if both locations are not marked volatile, it is probably safer to flag a potential conflict if either location is volatile. */ - if (!TARGET_ALIASES) - { - if (MEM_VOLATILE_P (op0) && MEM_VOLATILE_P (op1)) - return 1; - } - else + if (!flag_argument_alias) { if (MEM_VOLATILE_P (op0) || MEM_VOLATILE_P (op1)) return 1; @@ -3222,6 +3234,14 @@ valid_parallel_operands_4 (operands, mode) par_ind_operand() operands. Thus of the 4 operands, only 2 should be REGs and the other 2 should be MEMs. */ + /* This test prevents the multipack pass from using this pattern if + op0 is used as an index or base register in op3, since this combination + will require reloading. */ + if (GET_CODE (op0) == REG + && GET_CODE (op3) == MEM + && reg_mentioned_p (op0, XEXP (op3, 0))) + return 0; + /* LDI||LDI */ if (GET_CODE (op0) == REG && GET_CODE (op2) == REG) return (REGNO (op0) != REGNO (op2)) @@ -3246,6 +3266,7 @@ valid_parallel_operands_4 (operands, mode) return 0; } + /* We only use this to check operands 1 and 2 since these may be commutative. It will need extending for the C32 opcodes. */ int @@ -3254,23 +3275,36 @@ valid_parallel_operands_5 (operands, mode) enum machine_mode mode ATTRIBUTE_UNUSED; { int regs = 0; - rtx op0 = operands[1]; - rtx op1 = operands[2]; + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx op2 = operands[2]; + rtx op3 = operands[3]; if (GET_CODE (op0) == SUBREG) op0 = SUBREG_REG (op0); - if (GET_CODE (op1) == SUBREG) - op1 = SUBREG_REG (op1); + if (GET_CODE (op2) == SUBREG) + op2 = SUBREG_REG (op2); /* The patterns should only allow ext_low_reg_operand() or par_ind_operand() operands. */ if (GET_CODE (op0) == REG) regs++; - if (GET_CODE (op1) == REG) + if (GET_CODE (op2) == REG) regs++; - return regs == 1; + if (regs != 1) + return 0; + + /* This test prevents the multipack pass from using this pattern if + op0 is used as an index or base register in op3, since this combination + will require reloading. */ + if (GET_CODE (op0) == REG + && GET_CODE (op3) == MEM + && reg_mentioned_p (op0, XEXP (op3, 0))) + return 0; + + return 1; } @@ -3280,47 +3314,48 @@ valid_parallel_operands_6 (operands, mode) enum machine_mode mode ATTRIBUTE_UNUSED; { int regs = 0; - rtx op0 = operands[1]; - rtx op1 = operands[2]; - rtx op2 = operands[4]; - rtx op3 = operands[5]; + rtx op0 = operands[0]; + rtx op1 = operands[1]; + rtx op2 = operands[2]; + rtx op4 = operands[4]; + rtx op5 = operands[5]; - if (GET_CODE (op0) == SUBREG) - op0 = SUBREG_REG (op0); if (GET_CODE (op1) == SUBREG) op1 = SUBREG_REG (op1); if (GET_CODE (op2) == SUBREG) op2 = SUBREG_REG (op2); - if (GET_CODE (op3) == SUBREG) - op3 = SUBREG_REG (op3); + if (GET_CODE (op4) == SUBREG) + op4 = SUBREG_REG (op4); + if (GET_CODE (op5) == SUBREG) + op5 = SUBREG_REG (op5); /* The patterns should only allow ext_low_reg_operand() or par_ind_operand() operands. Thus of the 4 input operands, only 2 should be REGs and the other 2 should be MEMs. */ - if (GET_CODE (op0) == REG) - regs++; if (GET_CODE (op1) == REG) regs++; if (GET_CODE (op2) == REG) regs++; - if (GET_CODE (op3) == REG) + if (GET_CODE (op4) == REG) + regs++; + if (GET_CODE (op5) == REG) regs++; /* The new C30/C40 silicon dies allow 3 regs of the 4 input operands. Perhaps we should count the MEMs as well? */ - return regs == 2; -} + if (regs != 2) + return 0; + /* This test prevents the multipack pass from using this pattern if + op0 is used as an index or base register in op4 or op5, since + this combination will require reloading. */ + if (GET_CODE (op0) == REG + && ((GET_CODE (op4) == MEM && reg_mentioned_p (op0, XEXP (op4, 0))) + || (GET_CODE (op5) == MEM && reg_mentioned_p (op0, XEXP (op5, 0))))) + return 0; -int -legitimize_parallel_operands_6 (operands, mode) - rtx *operands; - enum machine_mode mode; -{ - /* It's gonna be hard to legitimize operands for a parallel - instruction... TODO... */ - return valid_parallel_operands_6 (operands, mode); + return 1; } -- 2.7.4