mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 03:40:26 +08:00
arm.md (cmpsi2_addneg): New ARM pattern.
* arm.md (cmpsi2_addneg): New ARM pattern. Add peephole2 to generate it. (cbranchne_decr1): New Thumb pattern. * arm.c (arm_addimm_operand): New insn predicate. * arm-protos.h: Add a prototype for it. * arm.h (PREDICATE_CODES): Add it. From-SVN: r72188
This commit is contained in:
parent
79ae11c4a3
commit
f9b9980e6d
@ -1,3 +1,12 @@
|
||||
2003-10-07 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.md (cmpsi2_addneg): New ARM pattern. Add peephole2 to generate
|
||||
it.
|
||||
(cbranchne_decr1): New Thumb pattern.
|
||||
* arm.c (arm_addimm_operand): New insn predicate.
|
||||
* arm-protos.h: Add a prototype for it.
|
||||
* arm.h (PREDICATE_CODES): Add it.
|
||||
|
||||
2003-10-07 Dorit Naishlos <dorit@il.ibm.com>
|
||||
|
||||
* sched-int.h (sched_info): New field
|
||||
|
@ -65,6 +65,7 @@ extern int arm_reload_memory_operand (rtx, enum machine_mode);
|
||||
extern int arm_rhs_operand (rtx, enum machine_mode);
|
||||
extern int arm_rhsm_operand (rtx, enum machine_mode);
|
||||
extern int arm_add_operand (rtx, enum machine_mode);
|
||||
extern int arm_addimm_operand (rtx, enum machine_mode);
|
||||
extern int arm_not_operand (rtx, enum machine_mode);
|
||||
extern int offsettable_memory_operand (rtx, enum machine_mode);
|
||||
extern int alignable_memory_operand (rtx, enum machine_mode);
|
||||
|
@ -3750,6 +3750,15 @@ arm_add_operand (rtx op, enum machine_mode mode)
|
||||
|| const_ok_for_arm (-INTVAL (op)))));
|
||||
}
|
||||
|
||||
/* Return TRUE for valid ARM constants (or when valid if negated). */
|
||||
int
|
||||
arm_addimm_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
return (GET_CODE (op) == CONST_INT
|
||||
&& (const_ok_for_arm (INTVAL (op))
|
||||
|| const_ok_for_arm (-INTVAL (op))));
|
||||
}
|
||||
|
||||
int
|
||||
arm_not_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
|
@ -2681,6 +2681,7 @@ extern int making_const_table;
|
||||
{"arm_hard_register_operand", {REG}}, \
|
||||
{"f_register_operand", {SUBREG, REG}}, \
|
||||
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"arm_addimm_operand", {CONST_INT}}, \
|
||||
{"fpa_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"fpa_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
|
||||
{"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
|
@ -667,6 +667,60 @@
|
||||
[(set_attr "conds" "set")]
|
||||
)
|
||||
|
||||
;; This is the canonicalization of addsi3_compare0_for_combiner when the
|
||||
;; addend is a constant.
|
||||
(define_insn "*cmpsi2_addneg"
|
||||
[(set (reg:CC CC_REGNUM)
|
||||
(compare:CC
|
||||
(match_operand:SI 1 "s_register_operand" "r,r")
|
||||
(match_operand:SI 2 "arm_addimm_operand" "I,L")))
|
||||
(set (match_operand:SI 0 "s_register_operand" "=r,r")
|
||||
(plus:SI (match_dup 1)
|
||||
(match_operand:SI 3 "arm_addimm_operand" "L,I")))]
|
||||
"TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
|
||||
"@
|
||||
sub%?s\\t%0, %1, %2
|
||||
add%?s\\t%0, %1, #%n2"
|
||||
[(set_attr "conds" "set")]
|
||||
)
|
||||
|
||||
;; Convert the sequence
|
||||
;; sub rd, rn, #1
|
||||
;; cmn rd, #1 (equivalent to cmp rd, #-1)
|
||||
;; bne dest
|
||||
;; into
|
||||
;; subs rd, rn, #1
|
||||
;; bcs dest ((unsigned)rn >= 1)
|
||||
;; similarly for the beq variant using bcc.
|
||||
;; This is a common looping idiom (while (n--))
|
||||
(define_peephole2
|
||||
[(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(plus:SI (match_operand:SI 1 "s_register_operand" "")
|
||||
(const_int -1)))
|
||||
(set (match_operand 2 "cc_register" "")
|
||||
(compare (match_dup 0) (const_int -1)))
|
||||
(set (pc)
|
||||
(if_then_else (match_operator 3 "equality_operator"
|
||||
[(match_dup 2) (const_int 0)])
|
||||
(match_operand 4 "" "")
|
||||
(match_operand 5 "" "")))]
|
||||
"TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
|
||||
[(parallel[
|
||||
(set (match_dup 2)
|
||||
(compare:CC
|
||||
(match_dup 1) (const_int 1)))
|
||||
(set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
|
||||
(set (pc)
|
||||
(if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
|
||||
(match_dup 4)
|
||||
(match_dup 5)))]
|
||||
"operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
|
||||
operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
|
||||
? GEU : LTU),
|
||||
VOIDmode,
|
||||
operands[2], const0_rtx);"
|
||||
)
|
||||
|
||||
;; The next four insns work because they compare the result with one of
|
||||
;; the operands, and we know that the use of the condition code is
|
||||
;; either GEU or LTU, so we can use the carry flag from the addition
|
||||
@ -5192,6 +5246,108 @@
|
||||
(const_int 8))))]
|
||||
)
|
||||
|
||||
(define_insn "*cbranchne_decr1"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 3 "equality_operator"
|
||||
[(match_operand:SI 2 "s_register_operand" "l,l,1,l")
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(pc)))
|
||||
(set (match_operand:SI 0 "s_register_operand" "=l,?h,?m,?m")
|
||||
(plus:SI (match_dup 2) (const_int -1)))
|
||||
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
|
||||
"TARGET_THUMB"
|
||||
"*
|
||||
{
|
||||
rtx cond[2];
|
||||
cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
|
||||
? GEU : LTU),
|
||||
VOIDmode, NULL, NULL);
|
||||
cond[1] = operands[4];
|
||||
|
||||
if (which_alternative == 0)
|
||||
output_asm_insn (\"sub\\t%0, %2, #1\", operands);
|
||||
else if (which_alternative == 1)
|
||||
{
|
||||
/* We must provide an alternative for a hi reg because reload
|
||||
cannot handle output reloads on a jump instruction, but we
|
||||
can't subtract into that. Fortunately a mov from lo to hi
|
||||
does not clobber the condition codes. */
|
||||
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
|
||||
output_asm_insn (\"mov\\t%0, %1\", operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Similarly, but the target is memory. */
|
||||
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
|
||||
output_asm_insn (\"str\\t%1, %0\", operands);
|
||||
}
|
||||
|
||||
switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
|
||||
{
|
||||
case 4:
|
||||
output_asm_insn (\"b%d0\\t%l1\", &cond);
|
||||
return \"\";
|
||||
case 6:
|
||||
output_asm_insn (\"b%D0\\t.LCB%=\", &cond);
|
||||
return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
|
||||
default:
|
||||
output_asm_insn (\"b%D0\\t.LCB%=\", &cond);
|
||||
return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
|
||||
}
|
||||
}
|
||||
"
|
||||
[(set (attr "far_jump")
|
||||
(if_then_else
|
||||
(ior (and (eq (symbol_ref ("which_alternative"))
|
||||
(const_int 0))
|
||||
(eq_attr "length" "8"))
|
||||
(eq_attr "length" "10"))
|
||||
(const_string "yes")
|
||||
(const_string "no")))
|
||||
(set_attr_alternative "length"
|
||||
[
|
||||
;; Alternative 0
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -250))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 256)))
|
||||
(const_int 4)
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 2048)))
|
||||
(const_int 6)
|
||||
(const_int 8)))
|
||||
;; Alternative 1
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 256)))
|
||||
(const_int 6)
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 2048)))
|
||||
(const_int 8)
|
||||
(const_int 10)))
|
||||
;; Alternative 2
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 256)))
|
||||
(const_int 6)
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 2048)))
|
||||
(const_int 8)
|
||||
(const_int 10)))
|
||||
;; Alternative 3
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 256)))
|
||||
(const_int 6)
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
|
||||
(le (minus (match_dup 4) (pc)) (const_int 2048)))
|
||||
(const_int 8)
|
||||
(const_int 10)))])]
|
||||
)
|
||||
|
||||
;; Comparison and test insns
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user