From: rearnsha Date: Fri, 1 Apr 2005 11:02:26 +0000 (+0000) Subject: * arm.c (adjacent_mem_locations): Reject volatile memory refs. X-Git-Tag: upstream/4.9.2~62510 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94dee23105b88c9fc8dbd99f8b2895dd3009fc91;p=platform%2Fupstream%2Flinaro-gcc.git * arm.c (adjacent_mem_locations): Reject volatile memory refs. Also reject cases where this pattern will cause load delay stalls unless optimizing for size and it will produce a shorter sequence. * arm.md (arith_adjacent_mem): Make better use of ldm addressing variants to avoid pre-adjusting the base when possible. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97381 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 06f562d..f9bc5a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2005-04-01 Richard Earnshaw + * arm.c (adjacent_mem_locations): Reject volatile memory refs. + Also reject cases where this pattern will cause load delay stalls + unless optimizing for size and it will produce a shorter sequence. + * arm.md (arith_adjacent_mem): Make better use of ldm addressing + variants to avoid pre-adjusting the base when possible. + +2005-04-01 Richard Earnshaw + * arm.md (minmax_arithsi): Reject all eliminable registers, not just the frame and argument pointers. (strqi_preinc, strqi_predec, loadqi_preinc, loadqi_predec): Likewise. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index dc7d410f..66c36fb 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5139,6 +5139,10 @@ minmax_code (rtx x) int adjacent_mem_locations (rtx a, rtx b) { + /* We don't guarantee to preserve the order of these memory refs. */ + if (volatile_refs_p (a) || volatile_refs_p (b)) + return 0; + if ((GET_CODE (XEXP (a, 0)) == REG || (GET_CODE (XEXP (a, 0)) == PLUS && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT)) @@ -5178,6 +5182,17 @@ adjacent_mem_locations (rtx a, rtx b) return 0; val_diff = val1 - val0; + + if (arm_ld_sched) + { + /* If the target has load delay slots, then there's no benefit + to using an ldm instruction unless the offset is zero and + we are optimizing for size. */ + return (optimize_size && (REGNO (reg0) == REGNO (reg1)) + && (val0 == 0 || val1 == 0 || val0 == 4 || val1 == 4) + && (val_diff == 4 || val_diff == -4)); + } + return ((REGNO (reg0) == REGNO (reg1)) && (val_diff == 4 || val_diff == -4)); } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f86ce20..1a1c06a 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -9246,7 +9246,8 @@ { rtx ldm[3]; rtx arith[4]; - int val1 = 0, val2 = 0; + rtx base_reg; + HOST_WIDE_INT val1 = 0, val2 = 0; if (REGNO (operands[0]) > REGNO (operands[4])) { @@ -9258,12 +9259,21 @@ ldm[1] = operands[0]; ldm[2] = operands[4]; } - if (GET_CODE (XEXP (operands[2], 0)) != REG) - val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1)); - if (GET_CODE (XEXP (operands[3], 0)) != REG) + + base_reg = XEXP (operands[2], 0); + + if (!REG_P (base_reg)) + { + val1 = INTVAL (XEXP (base_reg, 1)); + base_reg = XEXP (base_reg, 0); + } + + if (!REG_P (XEXP (operands[3], 0))) val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); + arith[0] = operands[0]; arith[3] = operands[1]; + if (val1 < val2) { arith[1] = ldm[1]; @@ -9274,21 +9284,30 @@ arith[1] = ldm[2]; arith[2] = ldm[1]; } - if (val1 && val2) + + ldm[0] = base_reg; + if (val1 !=0 && val2 != 0) { - rtx ops[3]; - ldm[0] = ops[0] = operands[4]; - ops[1] = XEXP (XEXP (operands[2], 0), 0); - ops[2] = XEXP (XEXP (operands[2], 0), 1); - output_add_immediate (ops); - if (val1 < val2) - output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); + if (val1 == 4 || val2 == 4) + /* Other val must be 8, since we know they are adjacent and neither + is zero. */ + output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm); else - output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); + { + rtx ops[3]; + + ldm[0] = ops[0] = operands[4]; + ops[1] = base_reg; + ops[2] = GEN_INT (val1); + output_add_immediate (ops); + if (val1 < val2) + output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); + else + output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); + } } - else if (val1) + else if (val1 != 0) { - ldm[0] = XEXP (operands[3], 0); if (val1 < val2) output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); else @@ -9296,7 +9315,6 @@ } else { - ldm[0] = XEXP (operands[2], 0); if (val1 < val2) output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); else