aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1994-06-18 13:53:45 -0700
committerJim Wilson <wilson@gcc.gnu.org>1994-06-18 13:53:45 -0700
commitabdf3eea96d2ffcac162ff32b08d973ce29a1aff (patch)
treeb0d963db4669f5e9d949dfe9bc23f6a6cc0c3008 /gcc
parent9c066566b07986915e603c5117965a6f27983f08 (diff)
downloadgcc-abdf3eea96d2ffcac162ff32b08d973ce29a1aff.zip
gcc-abdf3eea96d2ffcac162ff32b08d973ce29a1aff.tar.gz
gcc-abdf3eea96d2ffcac162ff32b08d973ce29a1aff.tar.bz2
(truncdisi2): Change from define_insn to define_expand.
(truncdihi2, truncdiqi2, extendsidi2): Likewise. (extendsidi2_internal): New pattern. From-SVN: r7520
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/mips/mips.md106
1 files changed, 66 insertions, 40 deletions
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index f21c90a..a89d114 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1833,34 +1833,49 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "SF")
(set_attr "length" "1")])
-;; ??? This should be a define expand.
-;; See the zero_extendsidi2 pattern.
-(define_insn "truncdisi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (truncate:SI (match_operand:DI 1 "register_operand" "d")))]
+
+;; The optimizer doesn't deal well with truncate operators, so we completely
+;; avoid them by using define expands here.
+
+(define_expand "truncdisi2"
+ [(set (match_operand:DI 2 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "d")
+ (const_int 32)))
+ (set (match_operand:DI 3 "register_operand" "=d")
+ (ashiftrt:DI (match_dup 2)
+ (const_int 32)))
+ (set (match_operand:SI 0 "register_operand" "=d")
+ (subreg:SI (match_dup 3) 0))]
"TARGET_64BIT"
- "dsll\\t%0,%1,32\;dsra\\t%0,%0,32"
- [(set_attr "type" "darith")
- (set_attr "mode" "SI")
- (set_attr "length" "2")])
+ "
+{
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+}")
-(define_insn "truncdihi2"
- [(set (match_operand:HI 0 "register_operand" "=d")
- (truncate:HI (match_operand:DI 1 "register_operand" "d")))]
+(define_expand "truncdihi2"
+ [(set (match_operand:DI 2 "register_operand" "=d")
+ (and:DI (match_operand:DI 1 "register_operand" "d")
+ (const_int 65535)))
+ (set (match_operand:HI 0 "register_operand" "=d")
+ (subreg:HI (match_dup 2) 0))]
"TARGET_64BIT"
- "andi\\t%0,%1,0xffff"
- [(set_attr "type" "darith")
- (set_attr "mode" "HI")
- (set_attr "length" "1")])
+ "
+{
+ operands[2] = gen_reg_rtx (DImode);
+}")
-(define_insn "truncdiqi2"
- [(set (match_operand:QI 0 "register_operand" "=d")
- (truncate:QI (match_operand:DI 1 "register_operand" "d")))]
+(define_expand "truncdiqi2"
+ [(set (match_operand:DI 2 "register_operand" "=d")
+ (and:DI (match_operand:DI 1 "register_operand" "d")
+ (const_int 255)))
+ (set (match_operand:QI 0 "register_operand" "=d")
+ (subreg:QI (match_dup 2) 0))]
"TARGET_64BIT"
- "andi\\t%0,%1,0x00ff"
- [(set_attr "type" "darith")
- (set_attr "mode" "QI")
- (set_attr "length" "1")])
+ "
+{
+ operands[2] = gen_reg_rtx (DImode);
+}")
;;
;; ....................
@@ -1870,8 +1885,7 @@ move\\t%0,%z4\\n\\
;; ....................
;; Extension insns.
-;; Those for integer source operand
-;; are ordered widest source type first.
+;; Those for integer source operand are ordered widest source type first.
(define_expand "zero_extendsidi2"
[(set (match_operand:DI 0 "register_operand" "")
@@ -1903,7 +1917,6 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "DI")
(set_attr "length" "1,2")])
-
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
@@ -1988,24 +2001,37 @@ move\\t%0,%z4\\n\\
;; ....................
;; Extension insns.
-;; Those for integer source operand
-;; are ordered widest source type first.
-
-;; ??? This should be a define_expand.
+;; Those for integer source operand are ordered widest source type first.
-(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=d,d,d")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,R,m")))]
+(define_expand "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
"TARGET_64BIT"
- "*
+ "
{
- if (which_alternative == 0)
- return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\";
- return mips_move_1word (operands, insn, FALSE);
-}"
- [(set_attr "type" "arith,load,load")
+ if (optimize && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_not_mem (operands[1]);
+
+ if (GET_CODE (operands[1]) != MEM)
+ {
+ rtx op1 = gen_lowpart (DImode, operands[1]);
+ rtx temp = gen_reg_rtx (DImode);
+ rtx shift = gen_rtx (CONST_INT, VOIDmode, 32);
+
+ emit_insn (gen_ashldi3 (temp, op1, shift));
+ emit_insn (gen_ashrdi3 (operands[0], temp, shift));
+ DONE;
+ }
+}")
+
+(define_insn "extendsidi2_internal"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (sign_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
+ "TARGET_64BIT"
+ "* return mips_move_1word (operands, insn, FALSE);"
+ [(set_attr "type" "load")
(set_attr "mode" "DI")
- (set_attr "length" "2,1,2")])
+ (set_attr "length" "1,2")])
;; These patterns originally accepted general_operands, however, slightly
;; better code is generated by only accepting register_operands, and then