This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Thumb PR #15948: ICE with non-commutative cbranch operands
- From: Richard Earnshaw <rearnsha at gcc dot gnu dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Jun 2004 12:52:12 +0100
- Subject: [PATCH] Thumb PR #15948: ICE with non-commutative cbranch operands
- Organization: GNU
cbranch operations can't have output reloads (reload doesn't know where
to put them), so we have to handle the difficult cases internally. A
further complication for the compute-and-branch operations is that one
of the inputs has to be tied to the output value. Normally the
operations are commutative, so reload can re-order things to make them
work, but in the case of bic (bit-clear) this is not the case. We
therefore have to handle the case where the register allocator wants to
put the output in the same register as the second operand.
Fortunately, while the mov loreg, loreg instruction on Thumb alters the
condition codes it does it in a way that is identical to the preceding
big instruction. That means we only need one more instruction in that
case.
Tested on arm-elf.
2004-06-23 Richard Earnshaw <rearnsha@arm.com>
* PR target/15948
* arm.md (bicsi3_cbranch): Add alternative to handle tying operands
one and two.
R.
Index: arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.169
diff -p -r1.169 arm.md
*** arm.md 20 May 2004 14:59:43 -0000 1.169
--- arm.md 22 Jun 2004 11:15:49 -0000
***************
*** 6167,6188 ****
[(set (pc)
(if_then_else
(match_operator 5 "equality_operator"
! [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
! (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))
! (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
(and:SI (not:SI (match_dup 3)) (match_dup 2)))
! (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
"TARGET_THUMB"
"*
{
if (which_alternative == 0)
output_asm_insn (\"bic\\t%0, %3\", operands);
! else if (which_alternative == 1)
{
output_asm_insn (\"bic\\t%1, %3\", operands);
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else
--- 6167,6190 ----
[(set (pc)
(if_then_else
(match_operator 5 "equality_operator"
! [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
! (match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))
! (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
(and:SI (not:SI (match_dup 3)) (match_dup 2)))
! (clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
"TARGET_THUMB"
"*
{
if (which_alternative == 0)
output_asm_insn (\"bic\\t%0, %3\", operands);
! else if (which_alternative <= 2)
{
output_asm_insn (\"bic\\t%1, %3\", operands);
+ /* It's ok if OP0 is a lo-reg, even though the mov will set the
+ conditions again, since we're only testing for equality. */
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else