aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/i386/i386-protos.h6
-rw-r--r--gcc/config/i386/i386.c95
-rw-r--r--gcc/config/i386/i386.h14
-rw-r--r--gcc/config/i386/i386.md14
5 files changed, 143 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f2b8704..90ab387 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,17 @@
-Wed Mar 21 10:25:13 CET 2001 Jan Hubicka <jh@use.cz>
+Wed Mar 21 10:53:57 CET 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (pushqi1): New.
+ * i386-protos.h (x86_64_general_operand, x86_64_szext_general_operand,
+ x86_64_nonmemory_operand, x86_64_szext_nonmemory_operand,
+ x86_64_immediate_operand, x86_64_immediate_operand,
+ x86_64_zext_immediate_operand): Declare.
+ * i386.c (x86_64_general_operand, x86_64_szext_general_operand,
+ x86_64_nonmemory_operand, x86_64_szext_nonmemory_operand,
+ x86_64_immediate_operand, x86_64_immediate_operand,
+ x86_64_zext_immediate_operand): define.
+ * i386.h (PREDICATE_CODES): Add new predicates.
+
+Wed Mar 21 10:25:13 CET 2001 Jan Hubicka <jh@suse.cz>
* i386.md (pophi1, popqi1, pushqi1): Remove.
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index e4639a3..aaa2394 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -43,6 +43,12 @@ extern int standard_80387_constant_p PARAMS ((rtx));
extern int standard_sse_constant_p PARAMS ((rtx));
extern int symbolic_reference_mentioned_p PARAMS ((rtx));
+extern int x86_64_general_operand PARAMS ((rtx, enum machine_mode));
+extern int x86_64_szext_general_operand PARAMS ((rtx, enum machine_mode));
+extern int x86_64_nonmemory_operand PARAMS ((rtx, enum machine_mode));
+extern int x86_64_szext_nonmemory_operand PARAMS ((rtx, enum machine_mode));
+extern int x86_64_immediate_operand PARAMS ((rtx, enum machine_mode));
+extern int x86_64_zext_immediate_operand PARAMS ((rtx, enum machine_mode));
extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 20b7eca..91dee40 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1127,6 +1127,101 @@ function_arg (cum, mode, type, named)
}
+/* Return nonzero if OP is general operand representable on x86_64. */
+
+int
+x86_64_general_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT)
+ return general_operand (op, mode);
+ if (nonimmediate_operand (op, mode))
+ return 1;
+ return x86_64_sign_extended_value (op);
+}
+
+/* Return nonzero if OP is general operand representable on x86_64
+ as eighter sign extended or zero extended constant. */
+
+int
+x86_64_szext_general_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT)
+ return general_operand (op, mode);
+ if (nonimmediate_operand (op, mode))
+ return 1;
+ return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
+}
+
+/* Return nonzero if OP is nonmemory operand representable on x86_64. */
+
+int
+x86_64_nonmemory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT)
+ return nonmemory_operand (op, mode);
+ if (register_operand (op, mode))
+ return 1;
+ return x86_64_sign_extended_value (op);
+}
+
+/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */
+
+int
+x86_64_movabs_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT || !flag_pic)
+ return nonmemory_operand (op, mode);
+ if (register_operand (op, mode) || x86_64_sign_extended_value (op))
+ return 1;
+ if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
+ return 1;
+ return 0;
+}
+
+/* Return nonzero if OP is nonmemory operand representable on x86_64. */
+
+int
+x86_64_szext_nonmemory_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT)
+ return nonmemory_operand (op, mode);
+ if (register_operand (op, mode))
+ return 1;
+ return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
+}
+
+/* Return nonzero if OP is immediate operand representable on x86_64. */
+
+int
+x86_64_immediate_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (!TARGET_64BIT)
+ return immediate_operand (op, mode);
+ return x86_64_sign_extended_value (op);
+}
+
+/* Return nonzero if OP is immediate operand representable on x86_64. */
+
+int
+x86_64_zext_immediate_operand (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ return x86_64_zero_extended_value (op);
+}
+
/* Return nonzero if OP is (const_int 1), else return zero. */
int
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 02c6e2a..697f221 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3022,6 +3022,20 @@ do { long l; \
/* Define the codes that are matched by predicates in i386.c. */
#define PREDICATE_CODES \
+ {"x86_64_immediate_operand", {CONST_INT, SUBREG, REG, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_nonmemory_operand", {CONST_INT, SUBREG, REG, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_movabs_operand", {CONST_INT, SUBREG, REG, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_szext_nonmemory_operand", {CONST_INT, SUBREG, REG, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_general_operand", {CONST_INT, SUBREG, REG, MEM, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_szext_general_operand", {CONST_INT, SUBREG, REG, MEM, \
+ SYMBOL_REF, LABEL_REF, CONST}}, \
+ {"x86_64_zext_immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, \
+ SYMBOL_REF, LABEL_REF}}, \
{"const_int_1_operand", {CONST_INT}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6eae78c..77392fe 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1858,6 +1858,20 @@
""
"ix86_expand_move (QImode, operands); DONE;")
+;; emit_push_insn when it calls move_by_pieces requires an insn to
+;; "push a byte". But actually we use pushw, which has the effect
+;; of rounding the amount pushed up to a halfword.
+
+(define_insn "*pushqi2"
+ [(set (match_operand:QI 0 "push_operand" "=X,X")
+ (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
+ "!TARGET_64BIT"
+ "@
+ push{w}\\t{|word ptr }%1
+ push{w}\\t%w1"
+ [(set_attr "type" "push")
+ (set_attr "mode" "HI")])
+
;; Situation is quite tricky about when to choose full sized (SImode) move
;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
;; partial register dependency machines (such as AMD Athlon), where QImode