aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2002-02-21 21:16:22 +0000
committerJakub Jelinek <jakub@redhat.com>2002-02-21 21:16:22 +0000
commit63ef86c09b98b44280d275b981f5734a31a8d19a (patch)
tree31afe5ea799d69d4a0af20187cac2e9efca3c060
parentfe7216ab8409ea5f4f9d21b2d93289b4e72e7e65 (diff)
PR optimization/4994
* config/i386/i386.md (movsi_1, movsf_1): Support MMX -> MMX register moves. * g++.dg/opt/mmx1.C: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@49939 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.md25
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/opt/mmx1.C65
4 files changed, 89 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2805d63dfc4..2419eb508ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,10 @@
-2002-02-20 Jakub Jelinek <jakub@redhat.com>
+2002-02-21 Jakub Jelinek <jakub@redhat.com>
+
+ PR optimization/4994
+ * config/i386/i386.md (movsi_1, movsf_1): Support MMX -> MMX
+ register moves.
+
+2002-02-21 Jakub Jelinek <jakub@redhat.com>
PR c++/4574
* expr.h (expand_and): Add mode argument.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1d7091d2d9b..a62fd2fcf38 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1734,8 +1734,8 @@
(set_attr "length_immediate" "1")])
(define_insn "*movsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*Y,!rm,!*Y")
- (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,rm,*Y,*Y"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=*a,r,*a,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
+ (match_operand:SI 1 "general_operand" "im,rinm,rinm,rin,rm,*y,*y,rm,*Y,*Y"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
{
switch (get_attr_type (insn))
@@ -1746,6 +1746,8 @@
return "movd\t{%1, %0|%0, %1}";
case TYPE_MMX:
+ if (get_attr_mode (insn) == DImode)
+ return "movq\t{%1, %0|%0, %1}";
return "movd\t{%1, %0|%0, %1}";
case TYPE_LEA:
@@ -1758,17 +1760,17 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "4,5")
+ (cond [(eq_attr "alternative" "4,5,6")
(const_string "mmx")
- (eq_attr "alternative" "6,7,8")
+ (eq_attr "alternative" "7,8,9")
(const_string "sse")
(and (ne (symbol_ref "flag_pic") (const_int 0))
(match_operand:SI 1 "symbolic_operand" ""))
(const_string "lea")
]
(const_string "imov")))
- (set_attr "modrm" "0,*,0,*,*,*,*,*,*")
- (set_attr "mode" "SI,SI,SI,SI,SI,SI,TI,SI,SI")])
+ (set_attr "modrm" "0,*,0,*,*,*,*,*,*,*")
+ (set_attr "mode" "SI,SI,SI,SI,SI,SI,DI,TI,SI,SI")])
;; Stores and loads of ax to arbitary constant address.
;; We fake an second form of instruction to force reload to load address
@@ -2713,8 +2715,8 @@
(set (mem:SF (reg:DI 7)) (match_dup 1))])
(define_insn "*movsf_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm")
- (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
+ (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,H,x,xm#rf,x#rf,rm,*y,*y"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -2766,12 +2768,15 @@
case 10:
return "movd\t{%1, %0|%0, %1}";
+ case 11:
+ return "movq\t{%1, %0|%0, %1}";
+
default:
abort();
}
}
- [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx")
- (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI")])
+ [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse,sse,sse,mmx,mmx,mmx")
+ (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
(define_insn "*swapsf"
[(set (match_operand:SF 0 "register_operand" "+f")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e778ef4a698..f9a45982a55 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -4,6 +4,8 @@
* gcc.dg/20020220-2.c: New test.
+ * g++.dg/opt/mmx1.C: New test.
+
2002-02-20 Alexandre Oliva <aoliva@redhat.com>
* gcc.c-torture/compile/20020110.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/mmx1.C b/gcc/testsuite/g++.dg/opt/mmx1.C
new file mode 100644
index 00000000000..e433d554aea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/mmx1.C
@@ -0,0 +1,65 @@
+// PR optimization/4994
+// This testcase ICEd because movsi was not supporting direct
+// mmx -> mmx register moves.
+// { dg-do compile }
+// { dg-options "-O2" }
+// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target i?86-*-* } }
+
+struct A {
+ unsigned a0;
+ bool a1 () { return !--a0; }
+ void a2 ();
+};
+
+struct B
+{
+ B ();
+ B (const B &);
+ ~B();
+ B &operator= (const B &);
+ B b0 (unsigned long x, int y = 0, int z = 10) const;
+
+private:
+ A *b1;
+ static A *b2;
+};
+
+inline B::~B()
+{
+ if (b1->a1 () && b1 == b2)
+ b1->a2();
+}
+
+struct C
+{
+ C *c0;
+};
+
+struct D
+{
+ C *d0;
+ D ();
+ D (const D &c0) {}
+ D &operator++ () {
+ C *x = d0; C *y = x->c0;
+ while (x == y->c0)
+ x = y;
+ d0 = x;
+ return *this;
+ }
+};
+
+B foo (const char *x, const B &y);
+
+void bar (void)
+{
+ B *y = 0;
+ B z;
+ for (unsigned long l = 0; l < 2147483647L * 2UL + 1; l++)
+ {
+ z = y->b0 (l);
+ *y = foo ("data", z);
+ }
+ D d;
+ ++d;
+}