diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-11 20:40:02 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-11 20:40:02 +0000 |
commit | c4c75aaf74258efe115516494d9a5ed17c659c4e (patch) | |
tree | b427c3490d6002d893977647a51c3916ae696fb5 /gcc/config | |
parent | 191a91984d33a3ff45d5ca51a9a3adb60bc55aae (diff) | |
download | gcc-c4c75aaf74258efe115516494d9a5ed17c659c4e.tar.gz |
* config/i386/i386.md (any_shiftrt): New code iterator.
(shiftrt_insn): New code attribute.
(shiftrt): Ditto.
(<shiftrt_insn><mode>3): Macroize expander from ashr<mode>3 and
lshr<mode>3 using any_shiftrt code iterator.
(*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from
*ashr<mode>3_doubleword and *lshr<mode>3_doubleword using
any_shiftrt code iterator.
(*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2
pattern from corresponding peephole2 patterns.
(*<shiftrt_insn><mode>3_1): Macroize insn from *ashr<mode>3_1
and *lshr<mode>3_1 using any_shiftrt code iterator.
(*<shiftrt_insn>si3_1_zext): Ditto from *ashrsi3_1_zext
and *lshrsi3_1_zext.
(*<shiftrt_insn>qi3_1_slp): Ditto from *ashrqi3_1_slp
and *lshrqi3_1_slp.
(*<shiftrt_insn><mode>3_cmp): Ditto from *ashr<mode>3_cmp
and *lshr<mode>3_cmp.
(*<shiftrt_insn><mode>3_cmp_zext): Ditto from *ashr<mode>3_cmp_zext
and *lshr<mode>3_cmp_zext.
(*<shiftrt_insn><mode>3_cconly): Ditto from *ashr<mode>3_cconly
and *lshr<mode>3_cconly.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158205 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.md | 329 |
1 files changed, 63 insertions, 266 deletions
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" "<MODE>")]) -;; See comment above `ashldi3' about how this works. +;; See comment above `ashl<mode>3' about how this works. -(define_expand "ashr<mode>3" +(define_expand "<shiftrt_insn><mode>3" [(set (match_operand:SDWIM 0 "<shift_operand>" "") - (ashiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") - (match_operand:QI 2 "nonmemory_operand" "")))] + (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" - "ix86_expand_binary_operator (ASHIFTRT, <MODE>mode, operands); DONE;") + "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") -(define_insn_and_split "*ashr<mode>3_doubleword" +(define_insn_and_split "*<shiftrt_insn><mode>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" "<S>c"))) + (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "<S>c"))) (clobber (reg:CC FLAGS_REG))] "" "#" "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" [(const_int 0)] - "ix86_split_ashr (operands, NULL_RTX, <MODE>mode); DONE;" + "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>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:<DWI> 0 "register_operand" "") - (ashiftrt:<DWI> + (any_shiftrt:<DWI> (match_operand:<DWI> 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], <DWI>mode); DONE;") + "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;") (define_insn "x86_64_shrd" [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") @@ -10354,234 +10363,20 @@ DONE; }) -(define_insn "*ashr<mode>3_1" - [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c<S>"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)" -{ - if (REG_P (operands[2])) - return "sar{<imodesuffix>}\t{%b2, %0|%0, %b2}"; - else if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{<imodesuffix>}\t%0"; - else - return "sar{<imodesuffix>}\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" "<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 "*ashr<mode>3_cmp" - [(set (reg FLAGS_REG) - (compare - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) - (const_int 0))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>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>mode, operands)" -{ - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{<imodesuffix>}\t%0"; - else - return "sar{<imodesuffix>}\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" "<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 "*ashr<mode>3_cconly" - [(set (reg FLAGS_REG) - (compare - (ashiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) - (const_int 0))) - (clobber (match_scratch:SWI 0 "=<r>"))] - "(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>mode, operands)" -{ - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sar{<imodesuffix>}\t%0"; - else - return "sar{<imodesuffix>}\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" "<MODE>")]) - -;; Logical shift instructions - -;; See comment above `ashldi3' about how this works. - -(define_expand "lshr<mode>3" - [(set (match_operand:SDWIM 0 "<shift_operand>" "") - (lshiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "ix86_expand_binary_operator (LSHIFTRT, <MODE>mode, operands); DONE;") - -(define_insn_and_split "*lshr<mode>3_doubleword" - [(set (match_operand:DWI 0 "register_operand" "=r") - (lshiftrt:DWI (match_operand:DWI 1 "register_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "<S>c"))) - (clobber (reg:CC FLAGS_REG))] - "" - "#" - "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" - [(const_int 0)] - "ix86_split_lshr (operands, NULL_RTX, <MODE>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:<DWI> 0 "register_operand" "") - (lshiftrt:<DWI> - (match_operand:<DWI> 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], <DWI>mode); DONE;") - -(define_insn "*lshr<mode>3_1" +(define_insn "*<shiftrt_insn><mode>3_1" [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "c<S>"))) + (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "c<S>"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)" + "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" { if (REG_P (operands[2])) - return "shr{<imodesuffix>}\t{%b2, %0|%0, %b2}"; + return "<shiftrt>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; else if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{<imodesuffix>}\t%0"; + return "<shiftrt>{<imodesuffix>}\t%0"; else - return "shr{<imodesuffix>}\t{%2, %0|%0, %2}"; + return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10593,21 +10388,21 @@ (const_string "*"))) (set_attr "mode" "<MODE>")]) -(define_insn "*lshrsi3_1_zext" +(define_insn "*<shiftrt_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 (<CODE>, SImode, operands)" { if (REG_P (operands[2])) - return "shr{l}\t{%b2, %k0|%k0, %b2}"; + return "<shiftrt>{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 "<shiftrt>{l}\t%k0"; else - return "shr{l}\t{%2, %k0|%k0, %2}"; + return "<shiftrt>{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 "*<shiftrt_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 "<shiftrt>{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 "<shiftrt>{b}\t%0"; else - return "shr{b}\t{%1, %0|%0, %1}"; + return "<shiftrt>{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 "*lshr<mode>3_cmp" +(define_insn "*<shiftrt_insn><mode>3_cmp" [(set (reg FLAGS_REG) (compare - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) + (any_shiftrt:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) (const_int 0))) (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>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>mode, operands)" + && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{<imodesuffix>}\t%0"; + return "<shiftrt>{<imodesuffix>}\t%0"; else - return "shr{<imodesuffix>}\t{%2, %0|%0, %2}"; + return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") @@ -10681,27 +10477,27 @@ (const_string "*"))) (set_attr "mode" "<MODE>")]) -(define_insn "*lshrsi3_cmp_zext" +(define_insn "*<shiftrt_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 (<CODE>, SImode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{l}\t%k0"; + return "<shiftrt>{l}\t%k0"; else - return "shr{l}\t{%2, %k0|%k0, %2}"; + return "<shiftrt>{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 "*lshr<mode>3_cconly" +(define_insn "*<shiftrt_insn><mode>3_cconly" [(set (reg FLAGS_REG) (compare - (lshiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) + (any_shiftrt:SWI + (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) (const_int 0))) (clobber (match_scratch:SWI 0 "=<r>"))] "(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>mode, operands)" + && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" { if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "shr{<imodesuffix>}\t%0"; + return "<shiftrt>{<imodesuffix>}\t%0"; else - return "shr{<imodesuffix>}\t{%2, %0|%0, %2}"; + return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}"; } [(set_attr "type" "ishift") (set (attr "length_immediate") |