summaryrefslogtreecommitdiff
path: root/gcc/config/rx
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-31 02:32:08 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-31 02:32:08 +0000
commitbbcffae89d5907a05150153b62a554fac3d99d13 (patch)
tree5086d1d41cbf5a74bb5649d040be9a8309736065 /gcc/config/rx
parent9631b129ee947613f09a8e4ce3c979f5a6cdfb76 (diff)
downloadgcc-bbcffae89d5907a05150153b62a554fac3d99d13.tar.gz
* config/rx/predicates.md (rx_constshift_operand): New.
* config/rx/rx.md (zs_cond): New. (cbranchsi4): Remove mode. (*cbranchsi4_<code>): Likewise. (*tstbranchsi4_<code>): New. (*tstbranchsi4r_<code>): New. (*tstbranchsi4m_eq): New. (*tstbranchsi4m_ne): New. (cbranchsf4): Remove mode. (*cbranchsf4_<code>): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162731 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rx')
-rw-r--r--gcc/config/rx/predicates.md7
-rw-r--r--gcc/config/rx/rx.md116
2 files changed, 114 insertions, 9 deletions
diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md
index 94e5f5630c2..d8def87d6e8 100644
--- a/gcc/config/rx/predicates.md
+++ b/gcc/config/rx/predicates.md
@@ -45,6 +45,13 @@
}
)
+(define_predicate "rx_constshift_operand"
+ (match_code "const_int")
+ {
+ return IN_RANGE (INTVAL (op), 0, 31);
+ }
+)
+
;; Check that the operand is suitable as the source operand
;; for a logic or arithmeitc instruction. Registers, integers
;; and a restricted subset of memory addresses are allowed.
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index aeba85ffe39..0ad53637596 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -24,6 +24,9 @@
(define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu
unordered ordered ])
+;; Likewise, but only the ones that use Z or S.
+(define_code_iterator zs_cond [eq ne gtu geu ltu leu ])
+
;; This code iterator is used for sign- and zero- extensions.
(define_mode_iterator small_int_modes [(HI "") (QI "")])
@@ -157,9 +160,9 @@
(define_expand "cbranchsi4"
[(set (pc)
- (if_then_else (match_operator:SI 0 "comparison_operator"
- [(match_operand:SI 1 "register_operand")
- (match_operand:SI 2 "rx_source_operand")])
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "rx_source_operand")])
(label_ref (match_operand 3 ""))
(pc)))
]
@@ -169,7 +172,7 @@
(define_insn_and_split "*cbranchsi4_<code>"
[(set (pc)
- (if_then_else (most_cond:SI (match_operand:SI 0 "register_operand" "r")
+ (if_then_else (most_cond (match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "rx_source_operand" "riQ"))
(label_ref (match_operand 2 "" ""))
(pc)))
@@ -189,11 +192,106 @@
"
)
+;; -----------------------------------------------------------------------------
+;; These two are the canonical TST/branch insns. However, GCC
+;; generates a wide variety of tst-like patterns, we catch those
+;; below.
+(define_insn_and_split "*tstbranchsi4_<code>"
+ [(set (pc)
+ (if_then_else (zs_cond (and:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "rx_source_operand" "riQ"))
+ (const_int 0))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ ]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "
+ emit_insn (gen_tstsi (operands[0], operands[1]));
+
+ emit_jump_insn (gen_conditional_branch (operands[2],
+ gen_rtx_fmt_ee (<zs_cond:CODE>, CCmode,
+ gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
+ "
+)
+
+;; Inverse of above
+(define_insn_and_split "*tstbranchsi4r_<code>"
+ [(set (pc)
+ (if_then_else (zs_cond (and:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "rx_source_operand" "riQ"))
+ (const_int 0))
+ (pc)
+ (label_ref (match_operand 2 "" ""))))
+ ]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ "
+ emit_insn (gen_tstsi (operands[0], operands[1]));
+
+ emit_jump_insn (gen_conditional_branch (operands[2],
+ gen_rtx_fmt_ee (reverse_condition (<zs_cond:CODE>), CCmode,
+ gen_rtx_REG (CCmode, CC_REG), const0_rtx)));
+ "
+)
+
+;; Various other ways that GCC codes "var & const"
+
+(define_insn_and_split "*tstbranchsi4m_eq"
+ [(set (pc)
+ (if_then_else (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand 1 "rx_constshift_operand" "i")
+ (match_operand 2 "rx_constshift_operand" "i"))
+ (const_int 0))
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ ]
+ ""
+ "#"
+ ""
+ [(set (pc)
+ (if_then_else (eq (and:SI (match_dup 0)
+ (match_dup 4))
+ (const_int 0))
+ (label_ref (match_dup 3))
+ (pc)))
+ ]
+ "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));"
+)
+
+(define_insn_and_split "*tstbranchsi4m_ne"
+ [(set (pc)
+ (if_then_else (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (match_operand 1 "rx_constshift_operand" "i")
+ (match_operand 2 "rx_constshift_operand" "i"))
+ (const_int 0))
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ ]
+ ""
+ "#"
+ ""
+ [(set (pc)
+ (if_then_else (ne (and:SI (match_dup 0)
+ (match_dup 4))
+ (const_int 0))
+ (label_ref (match_dup 3))
+ (pc)))
+ ]
+ "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));"
+)
+
+;; -----------------------------------------------------------------------------
+
(define_expand "cbranchsf4"
[(set (pc)
- (if_then_else (match_operator:SF 0 "comparison_operator"
- [(match_operand:SF 1 "register_operand")
- (match_operand:SF 2 "rx_source_operand")])
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SF 1 "register_operand")
+ (match_operand:SF 2 "rx_source_operand")])
(label_ref (match_operand 3 ""))
(pc)))
]
@@ -203,8 +301,8 @@
(define_insn_and_split "*cbranchsf4_<code>"
[(set (pc)
- (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r")
- (match_operand:SF 1 "rx_source_operand" "rFiQ"))
+ (if_then_else (most_cond (match_operand:SF 0 "register_operand" "r")
+ (match_operand:SF 1 "rx_source_operand" "rFiQ"))
(label_ref (match_operand 2 "" ""))
(pc)))
]