This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

DWARF fix and minimal MMX patch


Hello guys,

	Two things in the patch. I'll start with the most important one.

1) expand_builtin_dwarf_reg_size

	It's getting ridiculous. I raised this point a couple of times
before. It gets in the way of my MMX patch. The code *is* buggy; it only
works for restricted cases DWARF register renumbering. I fixed it so it is
faithful to the required functionality for *all cases* if n_ranges != 3.
In fact, I propose we simply get rid of handling the special case of
n_ranges == 3 altogether:

rtx
expand_builtin_dwarf_reg_size (reg_tree, target)
     tree reg_tree;
     rtx target;
{
  tree t, t2;
  int i;

  t = build_int_2 (-1, 0);
  for(i = 0; i < FIRST_PSEUDO_REGISTER; ++i) {
    t2 = fold (build (EQ_EXPR, integer_type_node, reg_tree,
                      build_int_2 (i, 0)));
    t = fold (build (COND_EXPR, integer_type_node, t2,
                     build_int_2 (GET_MODE_SIZE (reg_raw_mode[i]), 0), t))
  }
  return expand_expr (t, target, Pmode, 0);
}

Does this make sense? I hope so.

2) Minimal MMX patch.

	I would *really* like egcs maintainers add this patch. This is a
lot simpler than the last patch. It doesn't do fancy stuff but it is
enough to support mmx intrinsics. see http://www.bigfoot.com/~hasdi for
examples. The reason why I would like built-in gcc support for mmx (rather
than hard inline assembly) is because:

	a) automatic register allocation
	b) common subexpression elimination

	You can also perform arithmetic operations with mmx registers but
the minimal patch does not support that. I think we should worry about
integrating the minimal version before adding bells and whistles.

	This version does not emit EMMS as before. After much feedback, I
figure that a programmer has a much better idea where to *not* place emms.
Before this, the patch generates EMMS, even if it is not needed in the
grand scheme of things. This cost me 20% performance in my 3d code.

	The patch also allows -mhard-float unlike before. This is very
dangerous (the compiler will simply issue a warning). Again, sometimes a
programmer has a better idea when or when not to use it.

	Please take a look at the new mmx.h. It is more efficient than
before.

	Good luck. Let me know how it turns out.

Hasdi

diff -r -u egcs-19981019/gcc/config/i386/i386.c egcs-mmx/gcc/config/i386/i386.c
--- egcs-19981019/gcc/config/i386/i386.c	Thu Oct 22 22:54:52 1998
+++ egcs-mmx/gcc/config/i386/i386.c	Thu Oct 22 20:50:50 1998
@@ -159,6 +159,9 @@
   /* FP registers */
   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
+  /* mmx TECHNOLOGY registers */
+  MMX_REGS,  MMX_REGS,  MMX_REGS,  MMX_REGS,
+  MMX_REGS,  MMX_REGS,  MMX_REGS,  MMX_REGS,
   /* arg pointer */
   INDEX_REGS
 };
@@ -395,6 +398,12 @@
   /* Keep nonleaf frame pointers.  */
   if (TARGET_OMIT_LEAF_FRAME_POINTER)
     flag_omit_frame_pointer = 1;
+
+  if (TARGET_3DNOW) target_flags |= MASK_MMX;
+
+  if (TARGET_MMX && TARGET_80387) {
+    warning ("-mmmx/-m3dnow conflicts with -mhard-float; please consider using -msoft-float");
+  }
 }
 
 /* A C statement (sans semicolon) to choose the order in which to
@@ -1112,6 +1121,24 @@
     optype1 = MEMOP;
   else
     optype1 = RNDOP;
+
+  /* Check for MMX registers */
+  if(MMX_REG_P(operands[0]) || MMX_REG_P(operands[1])) {
+    if(optype0 == PUSHOP) {
+      rtx xops[4];
+      
+      xops[0] = AT_SP (DImode);
+      xops[1] = operands[1];
+      xops[2] = stack_pointer_rtx;
+      xops[3] = GEN_INT (8);
+      
+      output_asm_insn (AS2 (sub%L2,%3,%2), xops);
+      output_asm_insn (AS2 (movq,%1,%0), xops);
+    } else {
+      output_asm_insn (AS2(movq,%1,%0), operands);
+    }
+    return "";
+  }
 
   /* Check for the cases that the operand constraints are not
      supposed to allow to happen.  Abort if we get one,
diff -r -u egcs-19981019/gcc/config/i386/i386.h egcs-mmx/gcc/config/i386/i386.h
--- egcs-19981019/gcc/config/i386/i386.h	Thu Oct 22 22:54:52 1998
+++ egcs-mmx/gcc/config/i386/i386.h	Thu Oct 22 20:59:11 1998
@@ -96,6 +96,8 @@
 #define MASK_DEBUG_ARG		000020000000	/* Debug function_arg */   
 #define MASK_SCHEDULE_PROLOGUE  000040000000    /* Emit prologue as rtl */
 #define MASK_STACK_PROBE	000100000000	/* Enable stack probing */
+#define MASK_MMX		000200000000	/* Use MMX registers */
+#define MASK_3DNOW		000400000000	/* Use 3DNOW! instructions */
 
 /* Use the floating point instructions */
 #define TARGET_80387 (target_flags & MASK_80387)
@@ -175,6 +177,8 @@
 #define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
 
 #define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
+#define TARGET_MMX (target_flags & MASK_MMX)
+#define TARGET_3DNOW (target_flags & MASK_3DNOW)
 
 #define TARGET_SWITCHES							\
 { { "80387",			 MASK_80387, "Use hardware fp" },	\
@@ -214,6 +218,10 @@
   { "no-debug-arg",		-MASK_DEBUG_ARG },			\
   { "stack-arg-probe",		 MASK_STACK_PROBE },			\
   { "no-stack-arg-probe",	-MASK_STACK_PROBE },			\
+  { "mmx",			 MASK_MMX, "Enable MMX registers" },	\
+  { "no-mmx",			-MASK_MMX, "Disable MMX registers" },	\
+  { "3dnow",			 MASK_3DNOW, "Enable 3DNOW! instructions" },\
+  { "no-3dnow",			-MASK_3DNOW, "Disable 3DNOW! instructions" },\
   { "windows",			0 },					\
   { "dll",			0 },					\
   SUBTARGET_SWITCHES							\
@@ -549,14 +557,16 @@
    eliminated during reloading in favor of either the stack or frame
    pointer. */
 
-#define FIRST_PSEUDO_REGISTER 17
+#define FIRST_PSEUDO_REGISTER 25
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
    On the 80386, the stack pointer is such, as is the arg pointer. */
 #define FIXED_REGISTERS \
 /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/       \
-{  0, 0, 0, 0, 0, 0, 0, 1, 0,  0,  0,  0,  0,  0,  0,  0,  1 }
+{  0, 0, 0, 0, 0, 0, 0, 1, 0,  0,  0,  0,  0,  0,  0,  0,  1,        \
+/*mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7*/                                  \
+    1,  1,  1,  1,  1,  1,  1,  1 }
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -567,7 +577,9 @@
 
 #define CALL_USED_REGISTERS \
 /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
-{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1,  \
+/*mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7*/                            \
+    1,  1,  1,  1,  1,  1,  1,  1 }
 
 /* Order in which to allocate registers.  Each register must be
    listed once, even those in FIXED_REGISTERS.  List frame pointer
@@ -590,7 +602,9 @@
 
 #define REG_ALLOC_ORDER \
 /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
-{  0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 10, 11, 12, 13, 14, 15, 16 }
+{  0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 10, 11, 12, 13, 14, 15, 16,  \
+/*mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7*/                            \
+   17, 18, 19, 20, 21, 22, 23, 24 }
 
 /* A C statement (sans semicolon) to choose the order in which to
    allocate hard registers for pseudo-registers local to a basic
@@ -624,6 +638,16 @@
          if (TEST_HARD_REG_BIT (x, i)) 			\
 	  fixed_regs[i] = call_used_regs[i] = 1; 	\
       }							\
+    if (TARGET_MMX || TARGET_3DNOW)                     \
+      {				                        \
+        int i; 					        \
+	HARD_REG_SET x;				        \
+        COPY_HARD_REG_SET (x, reg_class_contents[(int)MMX_REGS]); \
+        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )    \
+          if (TEST_HARD_REG_BIT (x, i)) 		\
+	    fixed_regs[i] = 0;                          \
+	    call_used_regs[i] = 1; 	                \
+      }						        \
   }
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -637,7 +661,7 @@
    */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)   \
-  (FP_REGNO_P (REGNO) ? 1 \
+  (FP_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) ? 1 \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
@@ -649,14 +673,16 @@
    for cross-compiler testing.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
-  ((REGNO) < 4 ? 1						\
+  ((REGNO) < 4 || MMX_REGNO_P(REGNO) ? 1			\
    : FP_REGNO_P (REGNO)						\
    ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT		\
        || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT)	\
       && GET_MODE_UNIT_SIZE (MODE) <= (LONG_DOUBLE_TYPE_SIZE == 96 ? 12 : 8))\
+   : MMX_REGNO_P (REGNO) ? (int) (MODE) == (int) (SImode) ||	\
+                           (int) (MODE) == (int) (DImode)	\
    : (int) (MODE) != (int) QImode ? 1				\
    : (reload_in_progress | reload_completed) == 1)
-
+     
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
    If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
@@ -687,6 +713,10 @@
 #define FIRST_STACK_REG FIRST_FLOAT_REG
 #define LAST_STACK_REG (FIRST_FLOAT_REG + 7)
 
+/* MMX regs */
+#define FIRST_MMX_REG 17
+#define LAST_MMX_REG 24
+
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms
    may be accessed via the stack pointer) in functions that seem suitable.
@@ -768,6 +798,7 @@
   GENERAL_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp %esp */
   FP_TOP_REG, FP_SECOND_REG,	/* %st(0) %st(1) */
   FLOAT_REGS,
+  MMX_REGS,                     /* %mm0 %mm1 %mm2 %mm3 %mm4 %mm5 %mm6 %mm7 */ 
   ALL_REGS, LIM_REG_CLASSES
 };
 
@@ -775,6 +806,8 @@
 
 #define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS))
 
+#define MMX_CLASS_P(CLASS) (reg_class_subset_p (CLASS, MMX_REGS))
+
 /* Give names of register classes as strings for dump file.   */
 
 #define REG_CLASS_NAMES \
@@ -787,6 +820,7 @@
    "GENERAL_REGS",			\
    "FP_TOP_REG", "FP_SECOND_REG",	\
    "FLOAT_REGS",			\
+   "MMX_REGS",				\
    "ALL_REGS" }
 
 /* Define which registers fit in which classes.
@@ -802,8 +836,9 @@
  {0x7f},				/* INDEX_REGS */		\
  {0x100ff},			/* GENERAL_REGS */		\
   {0x0100}, {0x0200},		/* FP_TOP_REG, FP_SECOND_REG */	\
-  {0xff00},			/* FLOAT_REGS */		\
- {0x1ffff}}
+  {0x000ff00},			/* FLOAT_REGS */		\
+  {0x1fe0000},			/* MMX_REGS */   		\
+  {0x1ffffff}}
 
 /* The same information, inverted:
    Return the class number of the smallest class containing
@@ -826,6 +861,9 @@
 #define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X)))
 #define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG)
   
+#define MMX_REG_P(X) (REG_P (X) && MMX_REGNO_P (REGNO (X)))
+#define MMX_REGNO_P(n) ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG)
+  
 #define STACK_REG_P(xop) (REG_P (xop) &&		       	\
 			  REGNO (xop) >= FIRST_STACK_REG &&	\
 			  REGNO (xop) <= LAST_STACK_REG)
@@ -864,7 +902,8 @@
    (C) == 'd' ? DREG :						\
    (C) == 'A' ? AD_REGS :					\
    (C) == 'D' ? DIREG :						\
-   (C) == 'S' ? SIREG : NO_REGS)
+   (C) == 'S' ? SIREG :						\
+   (C) == 'x' ? (TARGET_MMX ? MMX_REGS : NO_REGS): NO_REGS)
 
 /* The letters I, J, K, L and M in a register constraint string
    can be used to stand for particular ranges of immediate operands.
@@ -931,24 +970,29 @@
    ? (standard_80387_constant_p (X)					\
       ? reg_class_subset_p (CLASS, FLOAT_REGS) ? CLASS : FLOAT_REGS	\
       : NO_REGS)							\
+   : GET_CODE (X) == CONST_INT    && CLASS == MMX_REGS ? NO_REGS	\
+   : GET_CODE (X) == CONST_DOUBLE && CLASS == MMX_REGS ? NO_REGS	\
    : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \
    : ((CLASS) == ALL_REGS						\
       && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS	\
+   : ((CLASS) == MMX_REGS && GET_MODE (X) == SImode) ? GENERAL_REGS	\
    : (CLASS))
 
 /* If we are copying between general and FP registers, we need a memory
    location.  */
 
-#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \
-  ((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2))	\
-   || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2)))
+#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) 		\
+  ((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2))		\
+   || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))	\
+   || (MMX_CLASS_P (CLASS1) && ! MMX_CLASS_P (CLASS2))		\
+   || (! MMX_CLASS_P (CLASS1) && MMX_CLASS_P (CLASS2)))
 
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 /* On the 80386, this is the size of MODE in words,
    except in the FP regs, where a single reg is always enough.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)	\
- (FLOAT_CLASS_P (CLASS) ? 1 :		\
+ (FLOAT_CLASS_P (CLASS) || MMX_CLASS_P (CLASS)? 1 :	\
   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* A C expression whose value is nonzero if pseudos that have been
@@ -2145,7 +2189,8 @@
 #define REGISTER_MOVE_COST(CLASS1, CLASS2)				\
   (((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2))		\
     || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))) ? 10	\
-   : 2)
+   : ((MMX_CLASS_P (CLASS1) && ! MMX_CLASS_P (CLASS2)) ||		\
+      (! MMX_CLASS_P (CLASS1) && MMX_CLASS_P (CLASS2))) ? 6 : 2)
 
 
 /* A C expression for the cost of moving data of mode M between a
@@ -2342,7 +2387,8 @@
 
 #define HI_REGISTER_NAMES \
 {"ax","dx","cx","bx","si","di","bp","sp",          \
- "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","" }
+ "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","", \
+ "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" }
 
 #define REGISTER_NAMES HI_REGISTER_NAMES
 
@@ -2572,7 +2618,8 @@
 	 case 4:					\
 	 case 8:					\
 	 case 12:					\
-	   if (! FP_REG_P (X)) fputs ("e", FILE);	\
+	   if (! FP_REG_P (X) && ! MMX_REG_P (X))       \
+             fputs ("e", FILE);                         \
 	 case 2:					\
 	   fputs (hi_reg_name[REGNO (X)], FILE);	\
 	   break;					\
@@ -2604,7 +2651,7 @@
 	 { fputs ("argp", FILE); break; }		\
        if (STACK_TOP_P (X))				\
 	 { fputs ("st(0)", FILE); break; }		\
-       if (FP_REG_P (X))				\
+       if (FP_REG_P (X) || MMX_REG_P(X))		\
 	 { fputs (hi_name[REGNO(X)], FILE); break; }	\
        switch (GET_MODE_SIZE (GET_MODE (X)))		\
 	 {						\
diff -r -u egcs-19981019/gcc/config/i386/i386.md egcs-mmx/gcc/config/i386/i386.md
--- egcs-19981019/gcc/config/i386/i386.md	Thu Oct 22 22:54:52 1998
+++ egcs-mmx/gcc/config/i386/i386.md	Thu Oct 22 21:25:45 1998
@@ -951,18 +951,44 @@
 ;; (since pushes are not general_operands on the 386).
 
 (define_insn ""
-  [(set (match_operand:SI 0 "push_operand" "=<")
-	(match_operand:SI 1 "nonmemory_operand" "rn"))]
+  [(set (match_operand:SI 0 "push_operand" "=<,<")
+	(match_operand:SI 1 "nonmemory_operand" "rn,x"))]
   "flag_pic"
-  "* return AS1 (push%L0,%1);"
-  [(set_attr "memory" "store")])
+  "*
+{
+  if(which_alternative == 1) {
+    rtx xops[4];
+    xops[0] = AT_SP (SImode);
+    xops[1] = operands[1];
+    xops[2] = stack_pointer_rtx;
+    xops[3] = GEN_INT (4);
+    output_asm_insn (AS2 (sub%L0,%3,%2), xops);
+    output_asm_insn (AS2 (movd,%1,%0), xops);
+    RET;
+  } else
+    return AS1 (push%L0,%1);
+}"
+  [(set_attr "memory" "store,store")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "push_operand" "=<")
-	(match_operand:SI 1 "nonmemory_operand" "ri"))]
+  [(set (match_operand:SI 0 "push_operand" "=<,<")
+	(match_operand:SI 1 "nonmemory_operand" "ri,x"))]
   "!flag_pic"
-  "* return AS1 (push%L0,%1);"
-  [(set_attr "memory" "store")])
+  "*
+{
+  if(which_alternative == 1) {
+    rtx xops[4];
+    xops[0] = AT_SP (SImode);
+    xops[1] = operands[1];
+    xops[2] = stack_pointer_rtx;
+    xops[3] = GEN_INT (4);
+    output_asm_insn (AS2 (sub%L0,%3,%2), xops);
+    output_asm_insn (AS2 (movd,%1,%0), xops);
+    RET;
+  } else
+    return AS1 (push%L0,%1);
+}"
+  [(set_attr "memory" "store,store")])
 
 ;; On a 386, it is faster to push MEM directly.
 
@@ -1003,8 +1029,8 @@
 ;; On i486, incl reg is faster than movl $1,reg.
 
 (define_insn ""
-  [(set (match_operand:SI 0 "general_operand" "=g,r,r")
-	(match_operand:SI 1 "general_operand" "rn,i,m"))]
+  [(set (match_operand:SI 0 "general_operand" "=g,r,r,x,x,m")
+	(match_operand:SI 1 "general_operand" "rn,i,m,x,m,x"))]
   "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
     || (GET_CODE (operands[1]) != MEM))
    && flag_pic"
@@ -1012,6 +1038,9 @@
 {
   rtx link;
 
+  if (which_alternative >= 3 && which_alternative <= 5) {
+     return AS2 (movd,%1,%0);
+  }
   /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes
      longer.  */
   if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
@@ -1037,18 +1066,21 @@
 
   return AS2 (mov%L0,%1,%0);
 }"
-  [(set_attr "type" "integer,integer,memory")
-   (set_attr "memory" "*,*,load")])
+  [(set_attr "type" "integer,integer,memory,integer,memory,memory")
+   (set_attr "memory" "*,*,load,*,load,store")])
 
 (define_insn ""
-  [(set (match_operand:SI 0 "general_operand" "=g,r")
-	(match_operand:SI 1 "general_operand" "ri,m"))]
+  [(set (match_operand:SI 0 "general_operand" "=g,r,x,x,m")
+	(match_operand:SI 1 "general_operand" "ri,m,x,m,x"))]
   "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
     || (GET_CODE (operands[1]) != MEM))
    && !flag_pic"
   "*
 {
   rtx link;
+  if (which_alternative >= 2 && which_alternative <= 4) {
+     return AS2 (movd,%1,%0);
+  }
   if ((ix86_cpu != PROCESSOR_K6 || optimize_size)
       && operands[1] == const0_rtx && REG_P (operands[0]))
     return AS2 (xor%L0,%0,%0);
@@ -1069,8 +1101,8 @@
 
   return AS2 (mov%L0,%1,%0);
 }"
-  [(set_attr "type" "integer,memory")
-   (set_attr "memory" "*,load")])
+  [(set_attr "type" "integer,memory,integer,memory,memory")
+   (set_attr "memory" "*,load,*,load,store")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "push_operand" "=<")
@@ -1747,7 +1779,7 @@
 
 (define_insn ""
   [(set (match_operand:DI 0 "push_operand" "=<")
-	(match_operand:DI 1 "general_operand" "riF"))]
+	(match_operand:DI 1 "general_operand" "xriF"))]
   ""
   "* return output_move_double (operands);")
 
@@ -1774,13 +1806,13 @@
 }")
 
 (define_insn ""
-  [(set (match_operand:DI 0 "general_operand" "=g,r")
-	(match_operand:DI 1 "general_operand" "riF,m"))]
+  [(set (match_operand:DI 0 "general_operand" "=g,rx,x,m")
+	(match_operand:DI 1 "general_operand" "riF,m,x,x"))]
   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM)
    || (GET_CODE (operands[1]) != MEM)"
   "* return output_move_double (operands);"
-  [(set_attr "type" "integer,memory")
-   (set_attr "memory" "*,load")])
+  [(set_attr "type" "integer,memory,integer,memory")
+   (set_attr "memory" "*,load,*,store")])
 
 
 ;;- conversion instructions
diff -r -u egcs-19981019/gcc/config/i386/linux.h egcs-mmx/gcc/config/i386/linux.h
--- egcs-19981019/gcc/config/i386/linux.h	Thu Oct 22 22:54:52 1998
+++ egcs-mmx/gcc/config/i386/linux.h	Thu Oct 22 22:29:04 1998
@@ -117,6 +117,8 @@
  : (n) == 6 ? 5 \
  : (n) == 7 ? 4 \
  : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \
+ : ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG) ? (n)+4 \
+ : ((n) == 16) ? (20) \
  : (-1))
 
 /* Output assembler code to FILE to increment profiler label # LABELNO
diff -r -u egcs-19981019/gcc/dwarf2out.c egcs-mmx/gcc/dwarf2out.c
--- egcs-19981019/gcc/dwarf2out.c	Thu Oct 22 08:40:29 1998
+++ egcs-mmx/gcc/dwarf2out.c	Thu Oct 22 22:51:23 1998
@@ -642,28 +642,13 @@
     }
   else
     {
-      /* Initialize last_end to be larger than any possible
-	 DWARF_FRAME_REGNUM.  */
-      int last_end = 0x7fffffff;
-      --n_ranges;
-      t = build_int_2 (ranges[n_ranges].size, 0);
-      do
-	{
-	  int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
-	  int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end);
-	  if (beg < 0)
-	    continue;
-	  if (end >= last_end)
-	    abort ();
-	  last_end = end;
-	  if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg)
-	    abort ();
-	  t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
-			    build_int_2 (end, 0)));
-	  t = fold (build (COND_EXPR, integer_type_node, t2,
-			   build_int_2 (ranges[n_ranges].size, 0), t));
-	}
-      while (--n_ranges >= 0);
+      t = build_int_2 (-1, 0);
+      for(i = 0; i < FIRST_PSEUDO_REGISTER; ++i) {
+	t2 = fold (build (EQ_EXPR, integer_type_node, reg_tree,
+			  build_int_2 (i, 0)));
+	t = fold (build (COND_EXPR, integer_type_node, t2,
+			 build_int_2 (GET_MODE_SIZE (reg_raw_mode[i]), 0), t));
+      }
     }
   return expand_expr (t, target, Pmode, 0);
 }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]