aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorAdam Nemet <anemet@caviumnetworks.com>2008-09-04 21:24:31 +0000
committerAdam Nemet <nemet@gcc.gnu.org>2008-09-04 21:24:31 +0000
commitc84241327480cec52608beaba811faf1f09e0b03 (patch)
treedc0bd06f267d1ef48787f27859cb224f630704eb /gcc/config/mips
parent49912bcd97ec640f130fcf1551ea472d50f06f53 (diff)
downloadgcc-c84241327480cec52608beaba811faf1f09e0b03.zip
gcc-c84241327480cec52608beaba811faf1f09e0b03.tar.gz
gcc-c84241327480cec52608beaba811faf1f09e0b03.tar.bz2
mips.h (ISA_HAS_EXTS): New macro.
* config/mips/mips.h (ISA_HAS_EXTS): New macro. * config/mips/mips.md (*ashr_trunc<mode>): Name the pattern combining an arithmetic right shift by more than 31 and a trunction. Don't match for out-of-range shift amounts. Set attribute mode to <MODE>. (*lshr32_trunc<mode>): Name the pattern combining a logical right shift by 32 and and a truncation. Set attribute mode to <MODE>. (*<optab>_trunc<mode>_exts): New pattern for truncated right shifts by less than 32. (extv): Change predicate on first operand to accept registers. Change predicate of the other operands from immediate_operand to const_int_operand. Expand exts when source is a register. (extzv): Change predicate of the constant operands from immediate_operand to const_int_operand. (extzv<mode>): Change predicate of the constant operands from immediate_operand to const_int_operand and no constraint. Also remove mode. (*extzv_trunc<mode>_exts): New pattern. testsuite/ * gcc.target/mips/truncate-2.c: New test. * gcc.target/mips/octeon-exts-1.c: New test. * gcc.target/mips/octeon-exts-2.c: New test. * gcc.target/mips/octeon-exts-3.c: New test. * gcc.target/mips/octeon-exts-4.c: New test. From-SVN: r140009
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips.h3
-rw-r--r--gcc/config/mips/mips.md72
2 files changed, 63 insertions, 12 deletions
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index a3f47f7..4677546 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -1012,6 +1012,9 @@ enum mips_code_readable_setting {
/* ISA includes the cins instruction. */
#define ISA_HAS_CINS TARGET_OCTEON
+/* ISA includes the exts instruction. */
+#define ISA_HAS_EXTS TARGET_OCTEON
+
/* ISA includes the pop instruction. */
#define ISA_HAS_POP TARGET_OCTEON
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 04dd30a..0f478cf 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -772,6 +772,10 @@
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
+;; This code iterator allows the two right shift instructions to be
+;; generated from the same template.
+(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
+
;; This code iterator allows the three shift instructions to be generated
;; from the same template.
(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
@@ -2683,17 +2687,17 @@
;; Combiner patterns to optimize shift/truncate combinations.
-(define_insn ""
+(define_insn "*ashr_trunc<mode>"
[(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI
(ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "const_arith_operand" ""))))]
- "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32"
+ "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)"
"dsra\t%0,%1,%2"
[(set_attr "type" "shift")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn ""
+(define_insn "*lshr32_trunc<mode>"
[(set (match_operand:SUBDI 0 "register_operand" "=d")
(truncate:SUBDI
(lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
@@ -2701,8 +2705,19 @@
"TARGET_64BIT && !TARGET_MIPS16"
"dsra\t%0,%1,32"
[(set_attr "type" "shift")
- (set_attr "mode" "SI")])
+ (set_attr "mode" "<MODE>")])
+;; Logical shift by 32 or more results in proper SI values so
+;; truncation is removed by the middle end.
+(define_insn "*<optab>_trunc<mode>_exts"
+ [(set (match_operand:SUBDI 0 "register_operand" "=d")
+ (truncate:SUBDI
+ (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "const_arith_operand" ""))))]
+ "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32"
+ "exts\t%0,%1,%2,31"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
;; Combiner patterns for truncate/sign_extend combinations. The SI versions
;; use the shift/truncate patterns above.
@@ -3353,24 +3368,46 @@
(define_expand "extv"
[(set (match_operand 0 "register_operand")
- (sign_extract (match_operand:QI 1 "memory_operand")
- (match_operand 2 "immediate_operand")
- (match_operand 3 "immediate_operand")))]
+ (sign_extract (match_operand 1 "nonimmediate_operand")
+ (match_operand 2 "const_int_operand")
+ (match_operand 3 "const_int_operand")))]
"!TARGET_MIPS16"
{
if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
INTVAL (operands[2]),
INTVAL (operands[3])))
DONE;
+ else if (register_operand (operands[1], GET_MODE (operands[0]))
+ && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32)
+ {
+ if (GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_extvdi (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ emit_insn (gen_extvsi (operands[0], operands[1], operands[2],
+ operands[3]));
+ DONE;
+ }
else
FAIL;
})
+(define_insn "extv<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "")
+ (match_operand 3 "const_int_operand" "")))]
+ "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32"
+ "exts\t%0,%1,%3,%m2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
+
(define_expand "extzv"
[(set (match_operand 0 "register_operand")
(zero_extract (match_operand 1 "nonimmediate_operand")
- (match_operand 2 "immediate_operand")
- (match_operand 3 "immediate_operand")))]
+ (match_operand 2 "const_int_operand")
+ (match_operand 3 "const_int_operand")))]
"!TARGET_MIPS16"
{
if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
@@ -3395,14 +3432,25 @@
(define_insn "extzv<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
- (match_operand:SI 2 "immediate_operand" "I")
- (match_operand:SI 3 "immediate_operand" "I")))]
+ (match_operand 2 "const_int_operand" "")
+ (match_operand 3 "const_int_operand" "")))]
"mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
INTVAL (operands[3]))"
"<d>ext\t%0,%1,%3,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
+(define_insn "*extzv_trunc<mode>_exts"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (truncate:GPR
+ (zero_extract:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "")
+ (match_operand 3 "const_int_operand" ""))))]
+ "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
+ "exts\t%0,%1,%3,31"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
(define_expand "insv"
[(set (zero_extract (match_operand 0 "nonimmediate_operand")