i386.c (print_reg): Use ANY_FP_REG instead of FP_REG
authorJan Hubicka <jh@suse.cz>
Tue, 13 Feb 2001 12:33:15 +0000 (13:33 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 13 Feb 2001 12:33:15 +0000 (12:33 +0000)
* i386.c (print_reg): Use ANY_FP_REG instead of FP_REG
* i386.h (MASK_128BIT_LONG_DOUBLE): Renumber
(MASK_SSE2): New.
(MASK_MIX_SSE_I387): New.
(TARGET_SSE): SSE2 imply SSE.
(TARGET_SSE2, TARGET_MIX_SSE_I387): New.
(TARGET_SWITCHES): Add "sse2", "mix-sse-i387".
(enum reg_class): Add new classes.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(ANY_FP_REG_P, ANY_FP_REGNO_P, SSE_REG_P, SSE_FLOAT_MODE): New macros.
(REG_CLASS_FROM_LETTER): 'x' and 'y' is SSE_REGS only when SSE is
supported. Add 'Y' to be SSE_REGS when SSE2 is supported.
(CLASS_MAX_NREGS): Use new macros.
(REGISTER_MOVE_COST): Rewrite using SECONDARY_MEMORY_MAYBE_NEEDED.
* i386.md (pushsf, movsf): Support SSE.
(pushdf_nointeger, pushdf_integer, pushdf): Support SSE, update
splitters to use ANY_FP_REGNO_P.
(movdf_nointeger, movdf_integer): Likewise.

From-SVN: r39628

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

index 6e2895cd3f82199c4ed3ae1c5c44f30dd9019045..d75143ef8fc9b3a9144fd0cbca2ee33d273909ed 100644 (file)
@@ -1,3 +1,25 @@
+Tue Feb 13 13:31:33 CET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.c (print_reg): Use ANY_FP_REG instead of FP_REG
+       * i386.h (MASK_128BIT_LONG_DOUBLE): Renumber
+       (MASK_SSE2): New.
+       (MASK_MIX_SSE_I387): New.
+       (TARGET_SSE): SSE2 imply SSE.
+       (TARGET_SSE2, TARGET_MIX_SSE_I387): New.
+       (TARGET_SWITCHES): Add "sse2", "mix-sse-i387".
+       (enum reg_class): Add new classes.
+       (REG_CLASS_NAMES): Likewise.
+       (REG_CLASS_CONTENTS): Likewise.
+       (ANY_FP_REG_P, ANY_FP_REGNO_P, SSE_REG_P, SSE_FLOAT_MODE): New macros.
+       (REG_CLASS_FROM_LETTER): 'x' and 'y' is SSE_REGS only when SSE is
+       supported. Add 'Y' to be SSE_REGS when SSE2 is supported.
+       (CLASS_MAX_NREGS): Use new macros.
+       (REGISTER_MOVE_COST): Rewrite using SECONDARY_MEMORY_MAYBE_NEEDED.
+       * i386.md (pushsf, movsf): Support SSE.
+       (pushdf_nointeger, pushdf_integer, pushdf): Support SSE, update
+       splitters to use ANY_FP_REGNO_P.
+       (movdf_nointeger, movdf_integer): Likewise.
+
 2001-02-13  Alexandre Oliva  <aoliva@redhat.com>
 
        * combine.c (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD): New macro.
index 49d8376f83b772281b0bd04aa1c362f8d84b039e..84e11b5fec87afd72323eb6cdb4a16a9f2ee4fa6 100644 (file)
@@ -3285,7 +3285,7 @@ print_reg (x, code, file)
     case 4:
     case 8:
     case 12:
-      if (! FP_REG_P (x))
+      if (! ANY_FP_REG_P (x))
        putc ('e', file);
       /* FALLTHRU */
     case 16:
index 3f06d08037fad392ac38f81d789203cc1488b004..0a1d4417aec1c15809cea9913c60c47fac8979f6 100644 (file)
@@ -104,7 +104,9 @@ extern int target_flags;
 #define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
 #define MASK_MMX               0x00010000      /* Support MMX regs/builtins */
 #define MASK_SSE               0x00020000      /* Support SSE regs/builtins */
-#define MASK_128BIT_LONG_DOUBLE 0x00040000     /* long double size is 128bit */
+#define MASK_SSE2              0x00040000      /* Support SSE2 regs/builtins */
+#define MASK_128BIT_LONG_DOUBLE 0x00080000     /* long double size is 128bit */
+#define MASK_MIX_SSE_I387      0x00100000      /* Mix SSE and i387 instructions */
 
 /* Temporary codegen switches */
 #define MASK_INTEL_SYNTAX      0x00000200
@@ -226,7 +228,9 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
 
 #define ASSEMBLER_DIALECT ((target_flags & MASK_INTEL_SYNTAX) != 0)
 
-#define TARGET_SSE ((target_flags & MASK_SSE) != 0)
+#define TARGET_SSE ((target_flags & (MASK_SSE | MASK_SSE2)) != 0)
+#define TARGET_SSE2 ((target_flags & MASK_SSE2) != 0)
+#define TARGET_MIX_SSE_I387 ((target_flags & MASK_MIX_SSE_I387) != 0)
 #define TARGET_MMX ((target_flags & MASK_MMX) != 0)
 
 #define TARGET_SWITCHES                                                              \
@@ -298,9 +302,17 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
   { "no-mmx",                  -MASK_MMX,                                    \
     N_("Do not support MMX builtins") },                                     \
   { "sse",                      MASK_SSE,                                    \
-    N_("Support MMX and SSE builtins") },                                    \
+    N_("Support MMX and SSE builtins and code generation") },                \
   { "no-sse",                  -MASK_SSE,                                    \
-    N_("Do not support MMX and SSE builtins") },                             \
+    N_("Do not support MMX and SSE builtins and code generation") },         \
+  { "sse2",                     MASK_SSE2,                                   \
+    N_("Support MMX, SSE and SSE2 builtins and code generation") },          \
+  { "no-sse2",                 -MASK_SSE2,                                   \
+    N_("Do not support MMX, SSE and SSE2 builtins and code generation") },    \
+  { "mix-sse-i387",             MASK_MIX_SSE_I387,                           \
+    N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
+  { "nomix-sse-i387",          -MASK_MIX_SSE_I387,                           \
+    N_("Use both SSE and i387 instruction sets for floating point arithmetics") },\
   { "128bit-long-double",       MASK_128BIT_LONG_DOUBLE,                     \
     N_("sizeof(long double) is 16.") },                                              \
   { "96bit-long-double",       -MASK_128BIT_LONG_DOUBLE,                     \
@@ -765,7 +777,8 @@ extern int ix86_arch;
       : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
 
 #define VALID_SSE_REG_MODE(MODE) \
-    ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode)
+    ((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
+     || (MODE) == SFmode || (TARGET_SSE2 && (MODE) == DFmode))
 
 #define VALID_MMX_REG_MODE(MODE) \
     ((MODE) == DImode || (MODE) == V8QImode || (MODE) == V4HImode \
@@ -939,7 +952,12 @@ enum reg_class
   FLOAT_REGS,
   SSE_REGS,
   MMX_REGS,
-  FLOAT_INT_REGS,              /* FLOAT_REGS and GENERAL_REGS.  */
+  FP_TOP_SSE_REGS,
+  FP_SECOND_SSE_REGS,
+  FLOAT_SSE_REGS,
+  FLOAT_INT_REGS,
+  INT_SSE_REGS,
+  FLOAT_INT_SSE_REGS,
   ALL_REGS, LIM_REG_CLASSES
 };
 
@@ -968,7 +986,12 @@ enum reg_class
    "FLOAT_REGS",                       \
    "SSE_REGS",                         \
    "MMX_REGS",                         \
+   "FP_TOP_SSE_REGS",                  \
+   "FP_SECOND_SSE_REGS",               \
+   "FLOAT_SSE_REGS",                   \
    "FLOAT_INT_REGS",                   \
+   "INT_SSE_REGS",                     \
+   "FLOAT_INT_SSE_REGS",               \
    "ALL_REGS" }
 
 /* Define which registers fit in which classes.
@@ -989,7 +1012,12 @@ enum reg_class
     { 0xff00,  0x0 },                  /* FLOAT_REGS */                \
 { 0x1fe00000,  0x0 },                  /* SSE_REGS */                  \
 { 0xe0000000, 0x1f },                  /* MMX_REGS */                  \
+{ 0x1fe00100,  0x0 },                  /* FP_TOP_SSE_REG */            \
+{ 0x1fe00200,  0x0 },                  /* FP_SECOND_SSE_REG */         \
+{ 0x1fe0ff00,  0x0 },                  /* FLOAT_SSE_REGS */            \
    { 0x1ffff,  0x0 },                  /* FLOAT_INT_REGS */            \
+{ 0x1fe100ff,  0x0 },                  /* INT_SSE_REGS */              \
+{ 0x1fe1ffff,  0x0 },                  /* FLOAT_INT_SSE_REGS */        \
 { 0xffffffff, 0x1f }                                                   \
 }
 
@@ -1013,8 +1041,14 @@ enum reg_class
 
 #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 ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X)))
+#define ANY_FP_REGNO_P(n) (FP_REGNO_P (n) || SSE_REGNO_P (n))
 
 #define SSE_REGNO_P(n) ((n) >= FIRST_SSE_REG && (n) <= LAST_SSE_REG)
+#define SSE_REG_P(n) (REG_P (n) && SSE_REGNO_P (REGNO (n)))
+
+#define SSE_FLOAT_MODE_P(m) \
+  ((TARGET_SSE && (m) == SFmode) || (TARGET_SSE2 && (m) == DFmode))
 
 #define MMX_REGNO_P(n) ((n) >= FIRST_MMX_REG && (n) <= LAST_MMX_REG)
 #define MMX_REG_P(xop) (REG_P (xop) && MMX_REGNO_P (REGNO (xop)))
@@ -1058,8 +1092,9 @@ enum reg_class
    (C) == 'b' ? BREG :                                         \
    (C) == 'c' ? CREG :                                         \
    (C) == 'd' ? DREG :                                         \
-   (C) == 'x' ? SSE_REGS :                                     \
-   (C) == 'y' ? MMX_REGS :                                     \
+   (C) == 'x' ? TARGET_SSE ? SSE_REGS : NO_REGS :              \
+   (C) == 'Y' ? TARGET_SSE2? SSE_REGS : NO_REGS :              \
+   (C) == 'y' ? TARGET_MMX ? MMX_REGS : NO_REGS :              \
    (C) == 'A' ? AD_REGS :                                      \
    (C) == 'D' ? DIREG :                                                \
    (C) == 'S' ? SIREG : NO_REGS)
index df16d5b608deda166332363185c5452f9f5926cf..72b242b8c6843ff1f97b30fe000ae0ee99763de5 100644 (file)
   "ix86_expand_move (SFmode, operands); DONE;")
 
 (define_insn "*pushsf"
-  [(set (match_operand:SF 0 "push_operand" "=<,<")
-       (match_operand:SF 1 "general_no_elim_operand" "f#r,rFm#f"))]
+  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
+       (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x"))]
   ""
   "*
 {
 
     case 1:
       return \"push{l}\\t%1\";
+    case 2:
+      return \"#\";
 
     default:
       abort ();
     }
 }"
-  [(set_attr "type" "multi,push")
-   (set_attr "mode" "SF,SI")])
+  [(set_attr "type" "multi,push,multi")
+   (set_attr "mode" "SF,SI,SF")])
 
 (define_split
   [(set (match_operand:SF 0 "push_operand" "")
 (define_split
   [(set (match_operand:SF 0 "push_operand" "")
        (match_operand:SF 1 "register_operand" ""))]
-  "FP_REGNO_P (REGNO (operands[1]))"
+  "ANY_FP_REGNO_P (REGNO (operands[1]))"
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
    (set (mem:SF (reg:SI 7)) (match_dup 1))])
 
 (define_insn "*movsf_1"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,m")
-       (match_operand:SF 1 "general_operand" "fm#r,f#r,G,rmF#f,Fr#f"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,m")
+       (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,xm#rf,x#rf"))]
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && (reload_in_progress || reload_completed
        || GET_CODE (operands[1]) != CONST_DOUBLE
     case 3:
     case 4:
       return \"mov{l}\\t{%1, %0|%0, %1}\";
+    case 5:
+    case 6:
+      return \"movss\\t{%1, %0|%0, %1}\";
 
     default:
       abort();
     }
 }"
-  [(set_attr "type" "fmov,fmov,fmov,imov,imov")
-   (set_attr "mode" "SF,SF,SF,SI,SI")])
+  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sse,sse")
+   (set_attr "mode" "SF,SF,SF,SI,SI,SF,SF")])
 
 (define_split
   [(set (match_operand:SF 0 "nonimmediate_operand" "")
    && GET_CODE (operands[1]) == MEM
    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+   && !(SSE_REG_P (operands[0]) 
+        || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
    && (!(FP_REG_P (operands[0]) || 
         (GET_CODE (operands[0]) == SUBREG
          && FP_REG_P (SUBREG_REG (operands[0]))))
        (match_operand:SF 1 "register_operand" "+f"))
    (set (match_dup 1)
        (match_dup 0))]
-  ""
+  "reload_completed || !TARGET_SSE2"
   "*
 {
   if (STACK_TOP_P (operands[0]))
 ;; pattern for optimize_size too.
 
 (define_insn "*pushdf_nointeger"
-  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
-       (match_operand:DF 1 "general_no_elim_operand" "f,Fo#f,*r#f"))]
+  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
+       (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y"))]
   "!TARGET_INTEGER_DFMODE_MOVES"
   "*
 {
 
     case 1:
     case 2:
+    case 3:
       return \"#\";
 
     default:
     }
 }"
   [(set_attr "type" "multi")
-   (set_attr "mode" "DF,SI,SI")])
+   (set_attr "mode" "DF,SI,SI,DF")])
 
 (define_insn "*pushdf_integer"
-  [(set (match_operand:DF 0 "push_operand" "=<,<")
-       (match_operand:DF 1 "general_no_elim_operand" "f#r,rFo#f"))]
+  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
+       (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
   "TARGET_INTEGER_DFMODE_MOVES"
   "*
 {
        return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
 
     case 1:
+    case 2:
       return \"#\";
 
     default:
     }
 }"
   [(set_attr "type" "multi")
-   (set_attr "mode" "DF,SI")])
+   (set_attr "mode" "DF,SI,DF")])
 
 ;; %%% Kill this when call knows how to work this out.
 (define_split
   [(set (match_operand:DF 0 "push_operand" "")
        (match_operand:DF 1 "register_operand" ""))]
-  "reload_completed && FP_REGNO_P (REGNO (operands[1]))"
+  "reload_completed && ANY_FP_REGNO_P (REGNO (operands[1]))"
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
    (set (mem:DF (reg:SI 7)) (match_dup 1))]
   "")
 ;; when optimizing for size.
 
 (define_insn "*movdf_nointeger"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,f,*r,o")
-       (match_operand:DF 1 "general_operand" "fm,f,G,*roF,F*r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,m")
+       (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,Ym#f,Y#f"))]
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
    && (reload_in_progress || reload_completed
     case 3:
     case 4:
       return \"#\";
+    case 5:
+    case 6:
+      return \"movsd\\t{%1, %0|%0, %1}\";
 
     default:
       abort();
     }
 }"
-  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
-   (set_attr "mode" "DF,DF,DF,SI,SI")])
+  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
+   (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
 
 (define_insn "*movdf_integer"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
-       (match_operand:DF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,m")
+       (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,Ym#rf,Y#rf"))]
   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
    && (reload_in_progress || reload_completed
     case 4:
       return \"#\";
 
+    case 5:
+    case 6:
+      return \"movsd\\t{%1, %0|%0, %1}\";
+
     default:
       abort();
     }
 }"
-  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
-   (set_attr "mode" "DF,DF,DF,SI,SI")])
+  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sse,sse")
+   (set_attr "mode" "DF,DF,DF,SI,SI,DF,DF")])
 
 (define_split
   [(set (match_operand:DF 0 "nonimmediate_operand" "")
        (match_operand:DF 1 "general_operand" ""))]
   "reload_completed
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
-   && ! (FP_REG_P (operands[0]) || 
+   && ! (ANY_FP_REG_P (operands[0]) || 
         (GET_CODE (operands[0]) == SUBREG
-         && FP_REG_P (SUBREG_REG (operands[0]))))
-   && ! (FP_REG_P (operands[1]) || 
+         && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
+   && ! (ANY_FP_REG_P (operands[1]) || 
         (GET_CODE (operands[1]) == SUBREG
-         && FP_REG_P (SUBREG_REG (operands[1]))))"
+         && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
   [(set (match_dup 2) (match_dup 5))
    (set (match_dup 3) (match_dup 6))]
   "if (ix86_split_long_move (operands)) DONE;")
    && GET_CODE (operands[1]) == MEM
    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
+   && !(SSE_REG_P (operands[0]) 
+        || (GET_CODE (operands[0]) == SUBREG && SSE_REG_P (operands[0])))
    && standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
   [(set (match_dup 0)
        (match_dup 1))]
        (match_operand:DF 1 "register_operand" "+f"))
    (set (match_dup 1)
        (match_dup 0))]
-  ""
+  "reload_completed || !TARGET_SSE2"
   "*
 {
   if (STACK_TOP_P (operands[0]))
    && (GET_MODE (operands[0]) == XFmode
        || GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == DFmode)
-   && (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
+   && (!REG_P (operands[1]) || !ANY_FP_REGNO_P (REGNO (operands[1])))"
   [(const_int 0)]
   "if (!ix86_split_long_move (operands)) abort (); DONE;")
 
 (define_split
   [(set (match_operand:XF 0 "push_operand" "")
        (match_operand:XF 1 "register_operand" ""))]
-  "FP_REGNO_P (REGNO (operands[1]))"
+  "ANY_FP_REGNO_P (REGNO (operands[1]))"
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
    (set (mem:XF (reg:SI 7)) (match_dup 1))])
 
 (define_split
   [(set (match_operand:TF 0 "push_operand" "")
        (match_operand:TF 1 "register_operand" ""))]
-  "FP_REGNO_P (REGNO (operands[1]))"
+  "ANY_FP_REGNO_P (REGNO (operands[1]))"
   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
    (set (mem:TF (reg:SI 7)) (match_dup 1))])
 
   "reload_completed
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
-   && ! (FP_REG_P (operands[0]) || 
+   && ! (ANY_FP_REG_P (operands[0]) || 
         (GET_CODE (operands[0]) == SUBREG
-         && FP_REG_P (SUBREG_REG (operands[0]))))
-   && ! (FP_REG_P (operands[1]) || 
+         && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
+   && ! (ANY_FP_REG_P (operands[1]) || 
         (GET_CODE (operands[1]) == SUBREG
-         && FP_REG_P (SUBREG_REG (operands[1]))))"
+         && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
   [(set (match_dup 2) (match_dup 5))
    (set (match_dup 3) (match_dup 6))
    (set (match_dup 4) (match_dup 7))]