X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fi386.md;h=abe09cf7ee47d5356d734fb3ce945dd620ffa5d9;hp=8ff8643582eeca11910526714118a749ad5344bd;hb=207626077426df51abbc4d15327f4ee88e8d0c14;hpb=4e7b5df424573ac5e00e07e5cd253cab44e2f889 diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 8ff8643582e..abe09cf7ee4 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -724,6 +724,15 @@ ;; Base name for insn mnemonic. (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")]) +;; Mapping of shift-right operators +(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) + +;; Base name for define_insn +(define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")]) + +;; Base name for insn mnemonic. +(define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")]) + ;; Mapping of abs neg operators (define_code_iterator absneg [abs neg]) @@ -9529,7 +9538,7 @@ (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] "") -;; Arithmetic shift instructions +;; Shift instructions ;; DImode shifts are implemented using the i386 "shift double" opcode, ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count @@ -10207,25 +10216,25 @@ (const_string "*"))) (set_attr "mode" "")]) -;; See comment above `ashldi3' about how this works. +;; See comment above `ashl3' about how this works. -(define_expand "ashr3" +(define_expand "3" [(set (match_operand:SDWIM 0 "" "") - (ashiftrt:SDWIM (match_operand:SDWIM 1 "" "") - (match_operand:QI 2 "nonmemory_operand" "")))] + (any_shiftrt:SDWIM (match_operand:SDWIM 1 "" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" - "ix86_expand_binary_operator (ASHIFTRT, mode, operands); DONE;") + "ix86_expand_binary_operator (, mode, operands); DONE;") -(define_insn_and_split "*ashr3_doubleword" +(define_insn_and_split "*3_doubleword" [(set (match_operand:DWI 0 "register_operand" "=r") - (ashiftrt:DWI (match_operand:DWI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c"))) + (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "c"))) (clobber (reg:CC FLAGS_REG))] "" "#" "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" [(const_int 0)] - "ix86_split_ashr (operands, NULL_RTX, mode); DONE;" + "ix86_split_ (operands, NULL_RTX, mode); DONE;" [(set_attr "type" "multi")]) ;; By default we don't ask for a scratch register, because when DWImode @@ -10235,14 +10244,14 @@ (define_peephole2 [(match_scratch:DWIH 3 "r") (parallel [(set (match_operand: 0 "register_operand" "") - (ashiftrt: + (any_shiftrt: (match_operand: 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" ""))) (clobber (reg:CC FLAGS_REG))]) (match_dup 3)] "TARGET_CMOVE" [(const_int 0)] - "ix86_split_ashr (operands, operands[3], mode); DONE;") + "ix86_split_ (operands, operands[3], mode); DONE;") (define_insn "x86_64_shrd" [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") @@ -10354,234 +10363,20 @@ DONE; }) -(define_insn "*ashr3_1" - [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ASHIFTRT, mode, operands)" -{ - if (REG_P (operands[2])) - return "sar{}\t{%b2, %0|%0, %b2}"; - else if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{}\t%0"; - else - return "sar{}\t{%2, %0|%0, %2}"; -} - [(set_attr "type" "ishift") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 2 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "")]) - -(define_insn "*ashrsi3_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" -{ - if (REG_P (operands[2])) - return "sar{l}\t{%b2, %k0|%k0, %b2}"; - else if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{l}\t%k0"; - else - return "sar{l}\t{%2, %k0|%k0, %2}"; -} - [(set_attr "type" "ishift") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 2 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "SI")]) - -(define_insn "*ashrqi3_1_slp" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (ashiftrt:QI (match_dup 0) - (match_operand:QI 1 "nonmemory_operand" "cI"))) - (clobber (reg:CC FLAGS_REG))] - "(optimize_function_for_size_p (cfun) - || !TARGET_PARTIAL_REG_STALL - || (operands[1] == const1_rtx - && TARGET_SHIFT1))" -{ - if (REG_P (operands[1])) - return "sar{b}\t{%b1, %0|%0, %b1}"; - else if (operands[1] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{b}\t%0"; - else - return "sar{b}\t{%1, %0|%0, %1}"; -} - [(set_attr "type" "ishift1") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 1 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "QI")]) - -;; This pattern can't accept a variable shift count, since shifts by -;; zero don't affect the flags. We assume that shifts by constant -;; zero are optimized away. -(define_insn "*ashr3_cmp" - [(set (reg FLAGS_REG) - (compare - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "" "")) - (const_int 0))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=m") - (ashiftrt:SWI (match_dup 1) (match_dup 2)))] - "(optimize_function_for_size_p (cfun) - || !TARGET_PARTIAL_FLAG_REG_STALL - || (operands[2] == const1_rtx - && TARGET_SHIFT1)) - && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (ASHIFTRT, mode, operands)" -{ - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{}\t%0"; - else - return "sar{}\t{%2, %0|%0, %2}"; -} - [(set_attr "type" "ishift") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 2 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "")]) - -(define_insn "*ashrsi3_cmp_zext" - [(set (reg FLAGS_REG) - (compare - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "const_1_to_31_operand" "I")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] - "TARGET_64BIT - && (optimize_function_for_size_p (cfun) - || !TARGET_PARTIAL_FLAG_REG_STALL - || (operands[2] == const1_rtx - && TARGET_SHIFT1)) - && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" -{ - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{l}\t%k0"; - else - return "sar{l}\t{%2, %k0|%k0, %2}"; -} - [(set_attr "type" "ishift") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 2 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "SI")]) - -(define_insn "*ashr3_cconly" - [(set (reg FLAGS_REG) - (compare - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "" "")) - (const_int 0))) - (clobber (match_scratch:SWI 0 "="))] - "(optimize_function_for_size_p (cfun) - || !TARGET_PARTIAL_FLAG_REG_STALL - || (operands[2] == const1_rtx - && TARGET_SHIFT1)) - && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (ASHIFTRT, mode, operands)" -{ - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{}\t%0"; - else - return "sar{}\t{%2, %0|%0, %2}"; -} - [(set_attr "type" "ishift") - (set (attr "length_immediate") - (if_then_else - (and (match_operand 2 "const1_operand" "") - (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") - (const_int 0))) - (const_string "0") - (const_string "*"))) - (set_attr "mode" "")]) - -;; Logical shift instructions - -;; See comment above `ashldi3' about how this works. - -(define_expand "lshr3" - [(set (match_operand:SDWIM 0 "" "") - (lshiftrt:SDWIM (match_operand:SDWIM 1 "" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "ix86_expand_binary_operator (LSHIFTRT, mode, operands); DONE;") - -(define_insn_and_split "*lshr3_doubleword" - [(set (match_operand:DWI 0 "register_operand" "=r") - (lshiftrt:DWI (match_operand:DWI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c"))) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" - [(const_int 0)] - "ix86_split_lshr (operands, NULL_RTX, mode); DONE;" - [(set_attr "type" "multi")]) - -;; By default we don't ask for a scratch register, because when DWImode -;; values are manipulated, registers are already at a premium. But if -;; we have one handy, we won't turn it away. - -(define_peephole2 - [(match_scratch:DWIH 3 "r") - (parallel [(set (match_operand: 0 "register_operand" "") - (lshiftrt: - (match_operand: 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" ""))) - (clobber (reg:CC FLAGS_REG))]) - (match_dup 3)] - "TARGET_CMOVE" - [(const_int 0)] - "ix86_split_lshr (operands, operands[3], mode); DONE;") - -(define_insn "*lshr3_1" +(define_insn "*3_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=m") - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c"))) + (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "c"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (LSHIFTRT, mode, operands)" + "ix86_binary_operator_ok (, mode, operands)" { if (REG_P (operands[2])) - return "shr{}\t{%b2, %0|%0, %b2}"; + return "{}\t{%b2, %0|%0, %b2}"; else if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{}\t%0"; + return "{}\t%0"; else - return "shr{}\t{%2, %0|%0, %2}"; + return "{}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10593,21 +10388,21 @@ (const_string "*"))) (set_attr "mode" "")]) -(define_insn "*lshrsi3_1_zext" +(define_insn "*si3_1_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI")))) + (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "cI")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, SImode, operands)" + "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)" { if (REG_P (operands[2])) - return "shr{l}\t{%b2, %k0|%k0, %b2}"; + return "{l}\t{%b2, %k0|%k0, %b2}"; else if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{l}\t%k0"; + return "{l}\t%k0"; else - return "shr{l}\t{%2, %k0|%k0, %2}"; + return "{l}\t{%2, %k0|%k0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10619,10 +10414,10 @@ (const_string "*"))) (set_attr "mode" "SI")]) -(define_insn "*lshrqi3_1_slp" +(define_insn "*qi3_1_slp" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (lshiftrt:QI (match_dup 0) - (match_operand:QI 1 "nonmemory_operand" "cI"))) + (any_shiftrt:QI (match_dup 0) + (match_operand:QI 1 "nonmemory_operand" "cI"))) (clobber (reg:CC FLAGS_REG))] "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL @@ -10630,12 +10425,12 @@ && TARGET_SHIFT1))" { if (REG_P (operands[1])) - return "shr{b}\t{%b1, %0|%0, %b1}"; + return "{b}\t{%b1, %0|%0, %b1}"; else if (operands[1] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{b}\t%0"; + return "{b}\t%0"; else - return "shr{b}\t{%1, %0|%0, %1}"; + return "{b}\t{%1, %0|%0, %1}"; } [(set_attr "type" "ishift1") (set (attr "length_immediate") @@ -10650,26 +10445,27 @@ ;; This pattern can't accept a variable shift count, since shifts by ;; zero don't affect the flags. We assume that shifts by constant ;; zero are optimized away. -(define_insn "*lshr3_cmp" +(define_insn "*3_cmp" [(set (reg FLAGS_REG) (compare - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "" "")) + (any_shiftrt:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "" "")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=m") - (lshiftrt:SWI (match_dup 1) (match_dup 2)))] + (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL || (operands[2] == const1_rtx && TARGET_SHIFT1)) && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (LSHIFTRT, mode, operands)" + && ix86_binary_operator_ok (, mode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{}\t%0"; + return "{}\t%0"; else - return "shr{}\t{%2, %0|%0, %2}"; + return "{}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10681,27 +10477,27 @@ (const_string "*"))) (set_attr "mode" "")]) -(define_insn "*lshrsi3_cmp_zext" +(define_insn "*si3_cmp_zext" [(set (reg FLAGS_REG) (compare - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "const_1_to_31_operand" "I")) + (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "const_1_to_31_operand" "I")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI (lshiftrt:SI (match_dup 1) (match_dup 2))))] + (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] "TARGET_64BIT && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL || (operands[2] == const1_rtx && TARGET_SHIFT1)) && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (LSHIFTRT, SImode, operands)" + && ix86_binary_operator_ok (, SImode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{l}\t%k0"; + return "{l}\t%k0"; else - return "shr{l}\t{%2, %k0|%k0, %2}"; + return "{l}\t{%2, %k0|%k0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10713,11 +10509,12 @@ (const_string "*"))) (set_attr "mode" "SI")]) -(define_insn "*lshr3_cconly" +(define_insn "*3_cconly" [(set (reg FLAGS_REG) (compare - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "" "")) + (any_shiftrt:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "" "")) (const_int 0))) (clobber (match_scratch:SWI 0 "="))] "(optimize_function_for_size_p (cfun) @@ -10725,13 +10522,13 @@ || (operands[2] == const1_rtx && TARGET_SHIFT1)) && ix86_match_ccmode (insn, CCGOCmode) - && ix86_binary_operator_ok (LSHIFTRT, mode, operands)" + && ix86_binary_operator_ok (, mode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{}\t%0"; + return "{}\t%0"; else - return "shr{}\t{%2, %0|%0, %2}"; + return "{}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate")