OSDN Git Service

* config/i386/i386.c (ix86_secondary_reload): New static function.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
index a68c7ec..a021e7c 100644 (file)
    (UNSPEC_SSE5_UNSIGNED_CMP   151)
    (UNSPEC_SSE5_TRUEFALSE      152)
    (UNSPEC_SSE5_PERMUTE                153)
-   (UNSPEC_SSE5_ASHIFT         154)
-   (UNSPEC_SSE5_LSHIFT         155)
-   (UNSPEC_FRCZ                        156)
-   (UNSPEC_CVTPH2PS            157)
-   (UNSPEC_CVTPS2PH            158)
+   (UNSPEC_FRCZ                        154)
+   (UNSPEC_CVTPH2PS            155)
+   (UNSPEC_CVTPS2PH            156)
 
    ; For AES support
    (UNSPEC_AESENC              159)
    (COM_TRUE_P                 5)
   ])
 
+;; Constants used in the SSE5 pperm instruction
+(define_constants
+  [(PPERM_SRC                  0x00)   /* copy source */
+   (PPERM_INVERT               0x20)   /* invert source */
+   (PPERM_REVERSE              0x40)   /* bit reverse source */
+   (PPERM_REV_INV              0x60)   /* bit reverse & invert src */
+   (PPERM_ZERO                 0x80)   /* all 0's */
+   (PPERM_ONES                 0xa0)   /* all 1's */
+   (PPERM_SIGN                 0xc0)   /* propagate sign bit */
+   (PPERM_INV_SIGN             0xe0)   /* invert & propagate sign */
+   (PPERM_SRC1                 0x00)   /* use first source byte */
+   (PPERM_SRC2                 0x10)   /* use second source byte */
+   ])
+
 ;; Registers by name.
 (define_constants
   [(AX_REG                      0)
 
 (define_code_iterator plusminus [plus minus])
 
-;; Base name for define_insn and insn mnemonic.
-(define_code_attr addsub [(plus "add") (minus "sub")])
+(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
+
+;; Base name for define_insn
+(define_code_attr plusminus_insn
+  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
+   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
+
+;; Base name for insn mnemonic.
+(define_code_attr plusminus_mnemonic
+  [(plus "add") (ss_plus "adds") (us_plus "addus")
+   (minus "sub") (ss_minus "subs") (us_minus "subus")])
 
 ;; Mark commutative operators as such in constraints.
-(define_code_attr comm [(plus "%") (minus "")])
+(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
+                       (minus "") (ss_minus "") (us_minus "")])
 
 ;; Mapping of signed max and min
 (define_code_iterator smaxmin [smax smin])
           ]
           (const_string "QI")))])
 
-(define_expand "reload_outqi"
-  [(parallel [(match_operand:QI 0 "" "=m")
-              (match_operand:QI 1 "register_operand" "r")
-              (match_operand:QI 2 "register_operand" "=&q")])]
-  ""
-{
-  rtx op0, op1, op2;
-  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
-
-  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
-  if (! q_regs_operand (op1, QImode))
-    {
-      emit_insn (gen_movqi (op2, op1));
-      op1 = op2;
-    }
-  emit_insn (gen_movqi (op0, op1));
-  DONE;
-})
-
 (define_insn "*swapqi_1"
   [(set (match_operand:QI 0 "register_operand" "+r")
        (match_operand:QI 1 "register_operand" "+r"))
   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
-  "@
-   cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
-   cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
+  "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
   [(set_attr "type" "sseicvt")
    (set_attr "mode" "<MODEF:MODE>")
    (set_attr "athlon_decode" "double,direct")
   [(set_attr "type" "alu")
    (set_attr "mode" "DI")])
 
-(define_insn "*<addsub><mode>3_cc_overflow"
+(define_insn "*<plusminus_insn><mode>3_cc_overflow"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
            (plusminus:SWI
    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
        (plusminus:SWI (match_dup 1) (match_dup 2)))]
   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-  "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
+  "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
   [(set_attr "type" "alu")
    (set_attr "mode" "<MODE>")])
 
   [(set_attr "type" "icmp")
    (set_attr "mode" "<MODE>")])
 
-(define_insn "*<addsub>si3_zext_cc_overflow"
+(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
   [(set (reg:CCC FLAGS_REG)
        (compare:CCC
            (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
    (set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
-  "<addsub>{l}\t{%2, %k0|%k0, %2}"
+  "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
   [(set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT
    && ix86_binary_operator_ok (XOR, DImode, operands)"
-  "@
-   xor{q}\t{%2, %0|%0, %2}
-   xor{q}\t{%2, %0|%0, %2}"
+  "xor{q}\t{%2, %0|%0, %2}"
   [(set_attr "type" "alu")
-   (set_attr "mode" "DI,DI")])
+   (set_attr "mode" "DI")])
 
 (define_insn "*xordi_2_rex64"
   [(set (reg FLAGS_REG)
   "TARGET_64BIT
    && ix86_match_ccmode (insn, CCNOmode)
    && ix86_binary_operator_ok (XOR, DImode, operands)"
-  "@
-   xor{q}\t{%2, %0|%0, %2}
-   xor{q}\t{%2, %0|%0, %2}"
+  "xor{q}\t{%2, %0|%0, %2}"
   [(set_attr "type" "alu")
-   (set_attr "mode" "DI,DI")])
+   (set_attr "mode" "DI")])
 
 (define_insn "*xordi_3_rex64"
   [(set (reg FLAGS_REG)
        (plus:SI (match_dup 3)
                 (const_int 4)))]
   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "{movsl|movsd}"
+  "movs{l|d}"
   [(set_attr "type" "str")
    (set_attr "mode" "SI")
    (set_attr "memory" "both")])
        (plus:DI (match_dup 3)
                 (const_int 4)))]
   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "{movsl|movsd}"
+  "movs{l|d}"
   [(set_attr "type" "str")
    (set_attr "mode" "SI")
    (set_attr "memory" "both")])
        (plus:SI (match_dup 1)
                 (const_int 4)))]
   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "{stosl|stosd}"
+  "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
        (plus:DI (match_dup 1)
                 (const_int 4)))]
   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "{stosl|stosd}"
+  "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
                                 operands[1], operands[0]);")
 
 ;; Conditional addition patterns
-(define_expand "addqicc"
-  [(match_operand:QI 0 "register_operand" "")
-   (match_operand 1 "comparison_operator" "")
-   (match_operand:QI 2 "register_operand" "")
-   (match_operand:QI 3 "const_int_operand" "")]
-  ""
-  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
-
-(define_expand "addhicc"
-  [(match_operand:HI 0 "register_operand" "")
+(define_expand "add<mode>cc"
+  [(match_operand:SWI 0 "register_operand" "")
    (match_operand 1 "comparison_operator" "")
-   (match_operand:HI 2 "register_operand" "")
-   (match_operand:HI 3 "const_int_operand" "")]
+   (match_operand:SWI 2 "register_operand" "")
+   (match_operand:SWI 3 "const_int_operand" "")]
   ""
   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
 
-(define_expand "addsicc"
-  [(match_operand:SI 0 "register_operand" "")
-   (match_operand 1 "comparison_operator" "")
-   (match_operand:SI 2 "register_operand" "")
-   (match_operand:SI 3 "const_int_operand" "")]
-  ""
-  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
-
-(define_expand "adddicc"
-  [(match_operand:DI 0 "register_operand" "")
-   (match_operand 1 "comparison_operator" "")
-   (match_operand:DI 2 "register_operand" "")
-   (match_operand:DI 3 "const_int_operand" "")]
-  "TARGET_64BIT"
-  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
-
 \f
 ;; Misc patterns (?)