PR target/20342
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Apr 2005 22:53:08 +0000 (22:53 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Apr 2005 22:53:08 +0000 (22:53 +0000)
        PR target/20447
        * config/i386/i386.c (print_operand): Handle vector zeros.
        (ix86_split_to_parts): Handle CONST_VECTOR.
        (ix86_hard_regno_mode_ok): Allow MMX modes in general regs.
        (ix86_modes_tieable_p): Use ix86_hard_regno_mode_ok to decide
        what modes to tie for MMX and SSE registers.
        * config/i386/i386.h (MMX_REG_MODE_P): Remove.
        * config/i386/i386.md: Extend move 0 -> xor peephole to apply
        to vector modes as well.
        * config/i386/predicates.md (const0_operand): Handle VOIDmode
        properly as an input mode.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@97663 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 69e4e3d..846d436 100644 (file)
@@ -1,3 +1,18 @@
+2005-04-05  Richard Henderson  <rth@redhat.com>
+
+       PR target/20342
+       PR target/20447
+       * config/i386/i386.c (print_operand): Handle vector zeros.
+       (ix86_split_to_parts): Handle CONST_VECTOR.
+       (ix86_hard_regno_mode_ok): Allow MMX modes in general regs.
+       (ix86_modes_tieable_p): Use ix86_hard_regno_mode_ok to decide
+       what modes to tie for MMX and SSE registers.
+       * config/i386/i386.h (MMX_REG_MODE_P): Remove.
+       * config/i386/i386.md: Extend move 0 -> xor peephole to apply
+       to vector modes as well.
+       * config/i386/predicates.md (const0_operand): Handle VOIDmode
+       properly as an input mode.
+
 2005-04-05  Andrew MacLeod  <amacleod@redhat.com>
 
        * tree-ssa-operands.c (verify_abort): Use %p for pointers.
index 5eeb548..e762fa7 100644 (file)
@@ -6773,6 +6773,17 @@ print_operand (FILE *file, rtx x, int code)
 
   else
     {
+      /* We have patterns that allow zero sets of memory, for instance.
+        In 64-bit mode, we should probably support all 8-byte vectors,
+        since we can in fact encode that into an immediate.  */
+      if (GET_CODE (x) == CONST_VECTOR)
+       {
+         if (x == CONST0_RTX (GET_MODE (x)))
+           x = const0_rtx;
+         else
+           abort ();
+       }
+
       if (code != 'P')
        {
          if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
@@ -10350,8 +10361,18 @@ ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
       operand = copy_rtx (operand);
       PUT_MODE (operand, Pmode);
       parts[0] = parts[1] = parts[2] = operand;
+      return size;
     }
-  else if (!TARGET_64BIT)
+
+  if (GET_CODE (operand) == CONST_VECTOR)
+    {
+      enum machine_mode imode = int_mode_for_mode (mode);
+      operand = simplify_subreg (imode, operand, mode, 0);
+      gcc_assert (operand != NULL);
+      mode = imode;
+    }
+
+  if (!TARGET_64BIT)
     {
       if (mode == DImode)
        split_di (&operand, 1, &parts[0], &parts[1]);
@@ -15111,15 +15132,30 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
       return (VALID_MMX_REG_MODE (mode)
              || VALID_MMX_REG_MODE_3DNOW (mode));
     }
-  /* We handle both integer and floats in the general purpose registers.
-     In future we should be able to handle vector modes as well.  */
-  if (!VALID_INT_MODE_P (mode) && !VALID_FP_MODE_P (mode))
-    return 0;
-  /* Take care for QImode values - they can be in non-QI regs, but then
-     they do cause partial register stalls.  */
-  if (regno < 4 || mode != QImode || TARGET_64BIT)
+
+  if (mode == QImode)
+    {
+      /* Take care for QImode values - they can be in non-QI regs,
+        but then they do cause partial register stalls.  */
+      if (regno < 4 || TARGET_64BIT)
+       return 1;
+      if (!TARGET_PARTIAL_REG_STALL)
+       return 1;
+      return reload_in_progress || reload_completed;
+    }
+  /* We handle both integer and floats in the general purpose registers.  */
+  else if (VALID_INT_MODE_P (mode))
+    return 1;
+  else if (VALID_FP_MODE_P (mode))
+    return 1;
+  /* Lots of MMX code casts 8 byte vector modes to DImode.  If we then go
+     on to use that value in smaller contexts, this can easily force a 
+     pseudo to be allocated to GENERAL_REGS.  Since this is no worse than
+     supporting DImode, allow it.  */
+  else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
     return 1;
-  return reload_in_progress || reload_completed || !TARGET_PARTIAL_REG_STALL;
+
+  return 0;
 }
 
 /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a 
@@ -15172,12 +15208,14 @@ ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
 
   /* If MODE2 is only appropriate for an SSE register, then tie with 
      any other mode acceptable to SSE registers.  */
-  if (SSE_REG_MODE_P (mode2))
+  if (GET_MODE_SIZE (mode2) >= 8
+      && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
     return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
 
   /* If MODE2 is appropriate for an MMX (or SSE) register, then tie
      with any other mode acceptable to MMX registers.  */
-  if (MMX_REG_MODE_P (mode2))
+  if (GET_MODE_SIZE (mode2) == 8
+      && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
     return ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1);
 
   return false;
index 819b0b2..ffba1d7 100644 (file)
@@ -1109,11 +1109,6 @@ do {                                                                     \
    || (MODE) == V8HImode || (MODE) == V2DFmode || (MODE) == V2DImode   \
    || (MODE) == V4SFmode || (MODE) == V4SImode)
 
-/* Return true for modes passed in MMX registers.  */
-#define MMX_REG_MODE_P(MODE) \
- ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode       \
-   || (MODE) == V2SFmode)
-
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.  */
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE)        \
index 6c5962b..1795469 100644 (file)
 ;; Attempt to always use XOR for zeroing registers.
 (define_peephole2
   [(set (match_operand 0 "register_operand" "")
-       (const_int 0))]
-  "(GET_MODE (operands[0]) == QImode
-    || GET_MODE (operands[0]) == HImode
-    || GET_MODE (operands[0]) == SImode
-    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
+       (match_operand 1 "const0_operand" ""))]
+  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
    && (! TARGET_USE_MOV0 || optimize_size)
    && GENERAL_REG_P (operands[0])
    && peep2_regno_dead_p (0, FLAGS_REG)"
   [(parallel [(set (match_dup 0) (const_int 0))
              (clobber (reg:CC FLAGS_REG))])]
-  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
-                             operands[0]);")
+{
+  operands[0] = gen_lowpart (word_mode, operands[0]);
+})
 
 (define_peephole2
   [(set (strict_low_part (match_operand 0 "register_operand" ""))
index 66f2505..668c7c0 100644 (file)
 
 ;; Match exactly zero.
 (define_predicate "const0_operand"
-  (and (match_code "const_int,const_double,const_vector")
-       (match_test "op == CONST0_RTX (mode)")))
+  (match_code "const_int,const_double,const_vector")
+{
+  if (mode == VOIDmode)
+    mode = GET_MODE (op);
+  return op == CONST0_RTX (mode);
+})
 
 ;; Match exactly one.
 (define_predicate "const1_operand"