aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@freesoft.cz>1998-11-06 00:16:12 +0100
committerJeff Law <law@gcc.gnu.org>1998-11-05 16:16:12 -0700
commit724d568a1fd6821dc4dbfadbb8dc148a290397e5 (patch)
tree4f735782df99f95716f02d3f2122998800bc4bc2 /gcc
parent3fffed0742ce78ed0f8a19ad7231e2c43115885e (diff)
downloadgcc-724d568a1fd6821dc4dbfadbb8dc148a290397e5.zip
gcc-724d568a1fd6821dc4dbfadbb8dc148a290397e5.tar.gz
gcc-724d568a1fd6821dc4dbfadbb8dc148a290397e5.tar.bz2
i386.md (extendsidi2): Use # in the output template.
* i386.md (extendsidi2): Use # in the output template. (extendsidi splitters): New splitters. From-SVN: r23543
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md84
2 files changed, 75 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 20138d4..2c66a79 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Fri Nov 6 00:10:00 1998 Jan Hubicka (hubicka@freesoft.cz)
+
+ * i386.md (extendsidi2): Use # in the output template.
+ (extendsidi splitters): New splitters.
+
Thu Nov 5 07:59:05 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
* jump.c (init_label_info, delete_barrier_successors,
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 7f381a1..e1f026a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2045,26 +2045,82 @@
;;- sign extension instructions
(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r")))
+ (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
""
- "*
+ "#")
+
+;; Extend to memory case when source register does die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "(flow2_completed
+ && dead_or_set_p (insn, operands[1])
+ && !reg_mentioned_p (operands[1], operands[0]))"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
+ (set (match_dup 4) (match_dup 1))]
+ "split_di (&operands[0], 1, &operands[3], &operands[4]);")
+
+;; Extend to memory case when source register does not die.
+(define_split
+ [(set (match_operand:DI 0 "memory_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_operand:SI 2 "register_operand" ""))]
+ "flow2_completed"
+ [(const_int 0)]
+ "
{
- if (REGNO (operands[0]) == 0)
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[1]) == 0
+ && true_regnum (operands[2]) == 1
+ && (optimize_size || !TARGET_PENTIUM))
{
- /* This used to be cwtl, but that extends HI to SI somehow. */
-#ifdef INTEL_SYNTAX
- return \"cdq\";
-#else
- return \"cltd\";
-#endif
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[1]));
+ }
+ else
+ {
+ emit_move_insn (operands[2], operands[1]);
+ emit_insn (gen_ashrsi3_31 (operands[2], operands[2]));
+ }
+ emit_move_insn (operands[4], operands[2]);
+ DONE;
+}")
+
+;; Extend to register case. Optimize case where source and destination
+;; registers match and cases where we can use cltd.
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
+ (clobber (match_scratch:SI 2 ""))]
+ "reload_completed"
+ [(const_int 0)]
+ "
+{
+ split_di (&operands[0], 1, &operands[3], &operands[4]);
+
+ if (true_regnum (operands[3]) != true_regnum (operands[1]))
+ emit_move_insn (operands[3], operands[1]);
+
+ /* Generate a cltd if possible and doing so it profitable. */
+ if (true_regnum (operands[3]) == 0
+ && (optimize_size || !TARGET_PENTIUM))
+ {
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[3]));
+ DONE;
}
- operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- output_asm_insn (AS2 (mov%L0,%0,%1), operands);
+ if (true_regnum (operands[4]) != true_regnum (operands[1]))
+ emit_move_insn (operands[4], operands[1]);
- operands[0] = GEN_INT (31);
- return AS2 (sar%L1,%0,%1);
+ emit_insn (gen_ashrsi3_31 (operands[4], operands[4]));
+ DONE;
}")
;; Note that the i386 programmers' manual says that the opcodes