This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: mn10300 logical operations
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 22 Sep 2003 17:13:15 -0300
- Subject: Re: mn10300 logical operations
- Organization: GCC Team, Red Hat
- References: <orznh2ddbo.fsf@livre.redhat.lsd.ic.unicamp.br>
On Sep 17, 2003, Alexandre Oliva <aoliva@redhat.com> wrote:
> mn10300's logical operations don't set the C or V flags in a way that
> enables us to omit a `cmp' instruction followed by certain conditional
> branches.
Actually, they do. It's just shifts used for some `and' sequences
that don't, so this patch reverts the damage, and fixes the real
problem. Ideally, we should be able to tell whether the V bit would
be used to decide whether to emit the shorter sequence using shifts or
the full-fledged add instruction that would set the bit properly, but
I don't know of any way to do it, so this will have to do for now.
Tested on athlon-linux-gnu-x-mn10300-elf, installed.
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/mn10300/mn10300.md: Revert 2003-09-17's patch.
(andsi3): Set attr cc to set_zn when using shifts or adds.
Index: gcc/config/mn10300/mn10300.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mn10300/mn10300.md,v
retrieving revision 1.48
diff -u -p -r1.48 mn10300.md
--- gcc/config/mn10300/mn10300.md 18 Sep 2003 02:46:00 -0000 1.48
+++ gcc/config/mn10300/mn10300.md 22 Sep 2003 20:02:53 -0000
@@ -1224,7 +1224,22 @@
return \"and %1,%0\";
return \"and %2,%0\";
}"
- [(set_attr "cc" "none_0hit,set_zn,set_zn")])
+ [(set (attr "cc")
+ (cond
+ [
+ (eq (symbol_ref "which_alternative") (const_int 0)
+ ) (const_string "none_0hit")
+ (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) == 0x7fffffff
+ || INTVAL (operands[2]) == 0x3fffffff
+ || INTVAL (operands[2]) == 0x1fffffff
+ || INTVAL (operands[2]) == 0x0fffffff
+ || INTVAL (operands[2]) == 0x0ffffffe
+ || INTVAL (operands[2]) == 0xfffffffc
+ || INTVAL (operands[2]) == 0xfffffff8
+ || INTVAL (operands[2]) == 0xfffffff0)")
+ (const_int 0)) (const_string "set_zn")
+ ] (const_string "set_znv")))])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,dx")
@@ -1255,7 +1270,27 @@
return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
return \"and %2,%0\";
}"
- [(set_attr "cc" "none_0hit,set_zn")])
+ [(set (attr "cc")
+ (cond
+ [
+ (eq (symbol_ref "which_alternative") (const_int 0)
+ ) (const_string "none_0hit")
+ ;; Shifts don't set the V flag, but bitwise operations clear
+ ;; it (which correctly reflects the absence of overflow in a
+ ;; compare-with-zero that might follow). As for the
+ ;; 0xfffffffe case, the add may overflow, so we can't use the
+ ;; V flag.
+ (ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
+ && (INTVAL (operands[2]) == 0x7fffffff
+ || INTVAL (operands[2]) == 0x3fffffff
+ || INTVAL (operands[2]) == 0x1fffffff
+ || INTVAL (operands[2]) == 0x0fffffff
+ || INTVAL (operands[2]) == 0x0ffffffe
+ || INTVAL (operands[2]) == 0xfffffffc
+ || INTVAL (operands[2]) == 0xfffffff8
+ || INTVAL (operands[2]) == 0xfffffff0)")
+ (const_int 0)) (const_string "set_zn")
+ ] (const_string "set_znv")))])
;; ----------------------------------------------------------------------
;; OR INSTRUCTIONS
@@ -1291,7 +1326,7 @@
return \"or %1,%0\";
return \"or %2,%0\";
}"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx")
@@ -1299,7 +1334,7 @@
(match_operand:SI 2 "nonmemory_operand" "dxi")))]
""
"or %2,%0"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
;; ----------------------------------------------------------------------
;; XOR INSTRUCTIONS
@@ -1335,7 +1370,7 @@
return \"xor %1,%0\";
return \"xor %2,%0\";
}"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx")
@@ -1343,7 +1378,7 @@
(match_operand:SI 2 "nonmemory_operand" "dxi")))]
""
"xor %2,%0"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
@@ -1360,14 +1395,14 @@
(not:SI (match_operand:SI 1 "register_operand" "0,0")))]
"TARGET_AM33"
"not %0"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx")
(not:SI (match_operand:SI 1 "register_operand" "0")))]
""
"not %0"
- [(set_attr "cc" "set_zn")])
+ [(set_attr "cc" "set_znv")])
;; -----------------------------------------------------------------
;; BIT FIELDS
@@ -1404,7 +1439,7 @@
"@
bclr %N1,%A0
and %1,%0"
- [(set_attr "cc" "clobber,set_zn")])
+ [(set_attr "cc" "clobber,set_znv")])
(define_insn ""
[(set (match_operand:QI 0 "memory_operand" "=R,T")
@@ -1426,7 +1461,7 @@
"@
bset %U1,%A0
or %1,%0"
- [(set_attr "cc" "clobber,set_zn")])
+ [(set_attr "cc" "clobber,set_znv")])
(define_expand "iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
@@ -1449,7 +1484,7 @@
bset %U2,%A0
bset %2,%0
or %2,%0"
- [(set_attr "cc" "clobber,clobber,set_zn")])
+ [(set_attr "cc" "clobber,clobber,set_znv")])
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
@@ -1464,7 +1499,7 @@
bset %U2,%A0
bset %2,%0
or %2,%0"
- [(set_attr "cc" "clobber,clobber,set_zn")])
+ [(set_attr "cc" "clobber,clobber,set_znv")])
(define_insn ""
[(set (cc0)
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer