aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-01-20 10:20:46 -0800
committerRichard Henderson <rth@gcc.gnu.org>2005-01-20 10:20:46 -0800
commit6b79c03c558a3f8b7862b1433e6481fb5f91c877 (patch)
tree68bb7e676a2dfb7449869c055a2d5eb342275f13 /gcc/config
parent35f46d96df776dce96043dbbe9241a55516bfaab (diff)
downloadgcc-6b79c03c558a3f8b7862b1433e6481fb5f91c877.zip
gcc-6b79c03c558a3f8b7862b1433e6481fb5f91c877.tar.gz
gcc-6b79c03c558a3f8b7862b1433e6481fb5f91c877.tar.bz2
i386.c (ix86_expand_push): New.
* config/i386/i386.c (ix86_expand_push): New. * config/i386/mmx.md (push<MMXMODE>1): New. * config/i386/sse.md (push<SSEMODE>1): New. * config/i386/i386-protos.h: Update. From-SVN: r93970
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c18
-rw-r--r--gcc/config/i386/mmx.md8
-rw-r--r--gcc/config/i386/sse.md8
4 files changed, 35 insertions, 0 deletions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 1b951b1..8be5408 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -126,6 +126,7 @@ extern void ix86_expand_clear (rtx);
extern void ix86_expand_move (enum machine_mode, rtx[]);
extern void ix86_expand_vector_move (enum machine_mode, rtx[]);
extern void ix86_expand_vector_move_misalign (enum machine_mode, rtx[]);
+extern void ix86_expand_push (enum machine_mode, rtx);
extern rtx ix86_fixup_binary_operands (enum rtx_code,
enum machine_mode, rtx[]);
extern void ix86_fixup_binary_operands_no_copy (enum rtx_code,
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 256d38f..2c1e9fd 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7754,6 +7754,24 @@ ix86_expand_vector_move_misalign (enum machine_mode mode, rtx operands[])
gcc_unreachable ();
}
+/* Expand a push in MODE. This is some mode for which we do not support
+ proper push instructions, at least from the registers that we expect
+ the value to live in. */
+
+void
+ix86_expand_push (enum machine_mode mode, rtx x)
+{
+ rtx tmp;
+
+ tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
+ GEN_INT (-GET_MODE_SIZE (mode)),
+ stack_pointer_rtx, 1, OPTAB_DIRECT);
+ if (tmp != stack_pointer_rtx)
+ emit_move_insn (stack_pointer_rtx, tmp);
+
+ tmp = gen_rtx_MEM (mode, stack_pointer_rtx);
+ emit_move_insn (tmp, x);
+}
/* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the
destination to use for the operation. If different from the true
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index ccee83d..d46fb36 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -175,6 +175,14 @@
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
+(define_expand "push<mode>1"
+ [(match_operand:MMXMODE 0 "register_operand" "")]
+ "TARGET_SSE"
+{
+ ix86_expand_push (<MODE>mode, operands[0]);
+ DONE;
+})
+
(define_expand "movmisalign<mode>"
[(set (match_operand:MMXMODE 0 "nonimmediate_operand" "")
(match_operand:MMXMODE 1 "nonimmediate_operand" ""))]
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 68c48ea..d15664b 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -194,6 +194,14 @@
operands[2] = CONST0_RTX (DFmode);
})
+(define_expand "push<mode>1"
+ [(match_operand:SSEMODE 0 "register_operand" "")]
+ "TARGET_SSE"
+{
+ ix86_expand_push (<MODE>mode, operands[0]);
+ DONE;
+})
+
(define_expand "movmisalign<mode>"
[(set (match_operand:SSEMODE 0 "nonimmediate_operand" "")
(match_operand:SSEMODE 1 "nonimmediate_operand" ""))]