X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fi386.md;h=2210bc819d9e0b4b84536fe930d4a9c911aa6587;hb=1d96f528b5a9f296a1d6fbcdeb42cec1ff8dc32e;hp=b704fa7310e8ac1435f9cb3465ac67c1c9e93d00;hpb=9636738d250f3761bcec22f34fe778179e547c27;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b704fa7310e..2210bc819d9 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -861,13 +861,13 @@ (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) ;; Immediate operand constraint for integer modes. -(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")]) +(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) ;; General operand constraint for word modes. -(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")]) +(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) ;; Immediate operand constraint for double integer modes. -(define_mode_attr di [(SI "iF") (DI "e")]) +(define_mode_attr di [(SI "nF") (DI "e")]) ;; Immediate operand constraint for shifts. (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) @@ -876,7 +876,7 @@ (define_mode_attr general_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "x86_64_general_operand") (DI "x86_64_general_operand") (TI "x86_64_general_operand")]) @@ -884,21 +884,21 @@ (define_mode_attr general_szext_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "x86_64_szext_general_operand") (DI "x86_64_szext_general_operand")]) ;; Immediate operand predicate for integer modes. (define_mode_attr immediate_operand [(QI "immediate_operand") (HI "immediate_operand") - (SI "immediate_operand") + (SI "x86_64_immediate_operand") (DI "x86_64_immediate_operand")]) ;; Nonmemory operand predicate for integer modes. (define_mode_attr nonmemory_operand [(QI "nonmemory_operand") (HI "nonmemory_operand") - (SI "nonmemory_operand") + (SI "x86_64_nonmemory_operand") (DI "x86_64_nonmemory_operand")]) ;; Operand predicate for shifts. @@ -2039,7 +2039,7 @@ (const_string "ssemov") (eq_attr "alternative" "16,17") (const_string "ssecvt") - (match_operand:DI 1 "pic_32bit_operand" "") + (match_operand 1 "pic_32bit_operand" "") (const_string "lea") ] (const_string "imov"))) @@ -2184,7 +2184,7 @@ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") (match_operand:SI 1 "general_operand" - "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] + "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -2232,7 +2232,7 @@ (const_string "sselog1") (eq_attr "alternative" "7,8,9,10,11") (const_string "ssemov") - (match_operand:DI 1 "pic_32bit_operand" "") + (match_operand 1 "pic_32bit_operand" "") (const_string "lea") ] (const_string "imov"))) @@ -5425,13 +5425,22 @@ (set_attr "mode" "QI")]) (define_insn "*lea_1" - [(set (match_operand:P 0 "register_operand" "=r") - (match_operand:P 1 "no_seg_address_operand" "p"))] + [(set (match_operand:SWI48 0 "register_operand" "=r") + (match_operand:SWI48 1 "no_seg_address_operand" "p"))] "" "lea{}\t{%a1, %0|%0, %a1}" [(set_attr "type" "lea") (set_attr "mode" "")]) +(define_insn "*lea_1_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (match_operand:SI 1 "no_seg_address_operand" "p")))] + "TARGET_64BIT" + "lea{l}\t{%a1, %k0|%k0, %a1}" + [(set_attr "type" "lea") + (set_attr "mode" "SI")]) + (define_insn "*lea_2" [(set (match_operand:SI 0 "register_operand" "=r") (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] @@ -5453,7 +5462,7 @@ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") (plus:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") - (match_operand:SWI48 2 "" ",r,0,l"))) + (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands)" { @@ -5512,7 +5521,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") - (match_operand:SI 2 "general_operand" "g,0,li")))) + (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -5794,66 +5803,42 @@ (const_string "none"))) (set_attr "mode" "QI")]) -;; Convert lea to the lea pattern to avoid flags dependency. +;; Convert add to the lea pattern to avoid flags dependency. (define_split - [(set (match_operand 0 "register_operand" "") - (plus (match_operand 1 "register_operand" "") - (match_operand 2 "nonmemory_operand" ""))) + [(set (match_operand:SWI 0 "register_operand" "") + (plus:SWI (match_operand:SWI 1 "register_operand" "") + (match_operand:SWI 2 "" ""))) (clobber (reg:CC FLAGS_REG))] "reload_completed && ix86_lea_for_add_ok (insn, operands)" [(const_int 0)] { + enum machine_mode mode = mode; rtx pat; - enum machine_mode mode = GET_MODE (operands[0]); - - /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) - may confuse gen_lowpart. */ - if (mode != Pmode) - { - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_lowpart (Pmode, operands[2]); - } - - pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) - operands[0] = gen_lowpart (SImode, operands[0]); + { + mode = SImode; + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + operands[2] = gen_lowpart (mode, operands[2]); + } - if (TARGET_64BIT && mode != Pmode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + pat = gen_rtx_PLUS (mode, operands[1], operands[2]); emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; }) -;; Convert lea to the lea pattern to avoid flags dependency. -;; ??? This pattern handles immediate operands that do not satisfy immediate -;; operand predicate (TARGET_LEGITIMATE_CONSTANT_P) in the previous pattern. -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "x86_64_immediate_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && true_regnum (operands[0]) != true_regnum (operands[1])" - [(set (match_dup 0) - (plus:DI (match_dup 1) (match_dup 2)))]) - -;; Convert lea to the lea pattern to avoid flags dependency. +;; Convert add to the lea pattern to avoid flags dependency. (define_split [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))) + (match_operand:SI 2 "x86_64_nonmemory_operand" "")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && reload_completed - && ix86_lea_for_add_ok (insn, operands)" + "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" [(set (match_dup 0) - (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] -{ - operands[1] = gen_lowpart (DImode, operands[1]); - operands[2] = gen_lowpart (DImode, operands[2]); -}) + (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) (define_insn "*add_2" [(set (reg FLAGS_REG) @@ -5901,7 +5886,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "x86_64_general_operand" "rme")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -5979,7 +5964,7 @@ (define_insn "*addsi_3_zext" [(set (reg FLAGS_REG) (compare - (neg:SI (match_operand:SI 2 "general_operand" "g")) + (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme")) (match_operand:SI 1 "nonimmediate_operand" "%0"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6233,7 +6218,7 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) -;; The lea patterns for non-Pmodes needs to be matched by +;; The lea patterns for modes less than 32 bits need to be matched by ;; several insns converted to real lea by splitters. (define_insn_and_split "*lea_general_1" @@ -6241,8 +6226,7 @@ (plus (plus (match_operand 1 "index_register_operand" "l") (match_operand 2 "register_operand" "r")) (match_operand 3 "immediate_operand" "i")))] - "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode - || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) + "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) && GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE (operands[0]) == GET_MODE (operands[2]) @@ -6252,53 +6236,30 @@ "&& reload_completed" [(const_int 0)] { + enum machine_mode mode = SImode; rtx pat; - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_lowpart (Pmode, operands[2]); - operands[3] = gen_lowpart (Pmode, operands[3]); - pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), + + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + operands[2] = gen_lowpart (mode, operands[2]); + operands[3] = gen_lowpart (mode, operands[3]); + + pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]), operands[3]); - if (Pmode != SImode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; } [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn_and_split "*lea_general_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (plus:SI (plus:SI - (match_operand:SI 1 "index_register_operand" "l") - (match_operand:SI 2 "register_operand" "r")) - (match_operand:SI 3 "immediate_operand" "i"))))] - "TARGET_64BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) - (match_dup 2)) - (match_dup 3)) 0)))] -{ - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_lowpart (Pmode, operands[2]); - operands[3] = gen_lowpart (Pmode, operands[3]); -} - [(set_attr "type" "lea") - (set_attr "mode" "SI")]) - (define_insn_and_split "*lea_general_2" [(set (match_operand 0 "register_operand" "=r") (plus (mult (match_operand 1 "index_register_operand" "l") - (match_operand 2 "const248_operand" "i")) + (match_operand 2 "const248_operand" "n")) (match_operand 3 "nonmemory_operand" "ri")))] - "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode - || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) - && (!TARGET_PARTIAL_REG_STALL - || GET_MODE (operands[0]) == SImode - || optimize_function_for_size_p (cfun)) + "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) + && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) && GET_MODE (operands[0]) == GET_MODE (operands[1]) && (GET_MODE (operands[0]) == GET_MODE (operands[3]) || GET_MODE (operands[3]) == VOIDmode)" @@ -6306,110 +6267,68 @@ "&& reload_completed" [(const_int 0)] { + enum machine_mode mode = SImode; rtx pat; - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[3] = gen_lowpart (Pmode, operands[3]); - pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), - operands[3]); - if (Pmode != SImode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + operands[3] = gen_lowpart (mode, operands[3]); + + pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]), + operands[3]); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; } [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn_and_split "*lea_general_2_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (plus:SI (mult:SI - (match_operand:SI 1 "index_register_operand" "l") - (match_operand:SI 2 "const248_operand" "n")) - (match_operand:SI 3 "nonmemory_operand" "ri"))))] - "TARGET_64BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) - (match_dup 2)) - (match_dup 3)) 0)))] -{ - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[3] = gen_lowpart (Pmode, operands[3]); -} - [(set_attr "type" "lea") - (set_attr "mode" "SI")]) - (define_insn_and_split "*lea_general_3" [(set (match_operand 0 "register_operand" "=r") (plus (plus (mult (match_operand 1 "index_register_operand" "l") - (match_operand 2 "const248_operand" "i")) + (match_operand 2 "const248_operand" "n")) (match_operand 3 "register_operand" "r")) (match_operand 4 "immediate_operand" "i")))] - "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode - || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) - && (!TARGET_PARTIAL_REG_STALL - || GET_MODE (operands[0]) == SImode - || optimize_function_for_size_p (cfun)) + "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) + && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) && GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE (operands[0]) == GET_MODE (operands[3])" "#" "&& reload_completed" [(const_int 0)] { + enum machine_mode mode = SImode; rtx pat; - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[3] = gen_lowpart (Pmode, operands[3]); - operands[4] = gen_lowpart (Pmode, operands[4]); - pat = gen_rtx_PLUS (Pmode, - gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], - operands[2]), + + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + operands[3] = gen_lowpart (mode, operands[3]); + operands[4] = gen_lowpart (mode, operands[4]); + + pat = gen_rtx_PLUS (mode, + gen_rtx_PLUS (mode, + gen_rtx_MULT (mode, operands[1], + operands[2]), operands[3]), operands[4]); - if (Pmode != SImode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; } [(set_attr "type" "lea") (set_attr "mode" "SI")]) -(define_insn_and_split "*lea_general_3_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (plus:SI (plus:SI - (mult:SI - (match_operand:SI 1 "index_register_operand" "l") - (match_operand:SI 2 "const248_operand" "n")) - (match_operand:SI 3 "register_operand" "r")) - (match_operand:SI 4 "immediate_operand" "i"))))] - "TARGET_64BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) - (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) - (match_dup 2)) - (match_dup 3)) - (match_dup 4)) 0)))] -{ - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[3] = gen_lowpart (Pmode, operands[3]); - operands[4] = gen_lowpart (Pmode, operands[4]); -} - [(set_attr "type" "lea") - (set_attr "mode" "SI")]) - (define_insn_and_split "*lea_general_4" - [(set (match_operand:SWI 0 "register_operand" "=r") - (any_or:SWI (ashift:SWI (match_operand:SWI 1 "index_register_operand" "l") - (match_operand:SWI 2 "const_int_operand" "n")) - (match_operand 3 "const_int_operand" "n")))] - "(mode == DImode - || mode == SImode - || !TARGET_PARTIAL_REG_STALL - || optimize_function_for_size_p (cfun)) + [(set (match_operand 0 "register_operand" "=r") + (any_or (ashift + (match_operand 1 "index_register_operand" "l") + (match_operand 2 "const_int_operand" "n")) + (match_operand 3 "const_int_operand" "n")))] + "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) + && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))) + || GET_MODE (operands[0]) == SImode + || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) + && GET_MODE (operands[0]) == GET_MODE (operands[1]) && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" @@ -6417,23 +6336,29 @@ "&& reload_completed" [(const_int 0)] { + enum machine_mode mode = GET_MODE (operands[0]); rtx pat; - if (mode != DImode) - operands[0] = gen_lowpart (SImode, operands[0]); - operands[1] = gen_lowpart (Pmode, operands[1]); + + if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) + { + mode = SImode; + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + } + operands[2] = GEN_INT (1 << INTVAL (operands[2])); - pat = plus_constant (gen_rtx_MULT (Pmode, operands[1], operands[2]), + + pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]), INTVAL (operands[3])); - if (Pmode != SImode && mode != DImode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; } [(set_attr "type" "lea") (set (attr "mode") - (if_then_else (eq (symbol_ref "mode == DImode") (const_int 0)) - (const_string "SI") - (const_string "DI")))]) + (if_then_else (match_operand:DI 0 "" "") + (const_string "DI") + (const_string "SI")))]) ;; Subtract instructions @@ -6481,7 +6406,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g")))) + (match_operand:SI 2 "x86_64_general_operand" "rme")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\t{%2, %k0|%k0, %2}" @@ -6518,7 +6443,7 @@ [(set (reg FLAGS_REG) (compare (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "x86_64_general_operand" "rme")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6545,7 +6470,7 @@ (define_insn "*subsi_3_zext" [(set (reg FLAGS_REG) (compare (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g"))) + (match_operand:SI 2 "x86_64_general_operand" "rme"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_dup 1) @@ -6592,7 +6517,7 @@ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") (plus:SI (match_operator 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) - (match_operand:SI 2 "general_operand" "g"))))) + (match_operand:SI 2 "x86_64_general_operand" "rme"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" @@ -6607,7 +6532,7 @@ (minus:SI (match_operand:SI 1 "register_operand" "0") (plus:SI (match_operator 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) - (match_operand:SI 2 "general_operand" "g"))))) + (match_operand:SI 2 "x86_64_general_operand" "rme"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %k0|%k0, %2}" @@ -6661,7 +6586,7 @@ (compare:CCC (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "x86_64_general_operand" "rme")) (match_dup 1))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))] @@ -6748,7 +6673,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r,r") (zero_extend:DI (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") - (match_operand:SI 2 "general_operand" "K,i,mr")))) + (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && !(MEM_P (operands[1]) && MEM_P (operands[2]))" @@ -7374,7 +7299,7 @@ [(set (reg:CCNO FLAGS_REG) (compare:CCNO (and:SI (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "nonmemory_operand" "")) + (match_operand:SI 1 "x86_64_nonmemory_operand" "")) (const_int 0)))]) (define_expand "testqi_ccz_1" @@ -7440,7 +7365,7 @@ (compare (and:SWI124 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,,m") - (match_operand:SWI124 1 "general_operand" ",,")) + (match_operand:SWI124 1 "" ",,")) (const_int 0)))] "ix86_match_ccmode (insn, CCNOmode) && !(MEM_P (operands[0]) && MEM_P (operands[1]))" @@ -7730,7 +7655,7 @@ (define_insn "*andsi_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") - (match_operand:SI 2 "general_operand" "ri,rm,L"))) + (match_operand:SI 2 "x86_64_general_operand" "re,rm,L"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, SImode, operands)" { @@ -7777,7 +7702,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))) + (match_operand:SI 2 "x86_64_general_operand" "rme")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" "and{l}\t{%2, %k0|%k0, %2}" @@ -7925,7 +7850,7 @@ [(set (reg FLAGS_REG) (compare (and:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") - (match_operand:SWI124 2 "general_operand" ",")) + (match_operand:SWI124 2 "" ",")) (const_int 0))) (set (match_operand:SWI124 0 "nonimmediate_operand" "=,m") (and:SWI124 (match_dup 1) (match_dup 2)))] @@ -7940,7 +7865,7 @@ [(set (reg FLAGS_REG) (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "x86_64_general_operand" "rme")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] @@ -8157,7 +8082,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))) + (match_operand:SI 2 "x86_64_general_operand" "rme")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands)" "{l}\t{%2, %k0|%k0, %2}" @@ -8205,7 +8130,7 @@ (define_insn "*si_2_zext" [(set (reg FLAGS_REG) (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "x86_64_general_operand" "rme")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] @@ -9395,36 +9320,36 @@ (const_string "*"))) (set_attr "mode" "QI")]) -;; Convert lea to the lea pattern to avoid flags dependency. +;; Convert ashift to the lea pattern to avoid flags dependency. (define_split [(set (match_operand 0 "register_operand" "") (ashift (match_operand 1 "index_register_operand" "") (match_operand:QI 2 "const_int_operand" ""))) (clobber (reg:CC FLAGS_REG))] - "reload_completed + "GET_MODE (operands[0]) == GET_MODE (operands[1]) + && reload_completed && true_regnum (operands[0]) != true_regnum (operands[1])" [(const_int 0)] { - rtx pat; enum machine_mode mode = GET_MODE (operands[0]); - - if (mode != Pmode) - operands[1] = gen_lowpart (Pmode, operands[1]); - operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); - - pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); + rtx pat; if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) - operands[0] = gen_lowpart (SImode, operands[0]); + { + mode = SImode; + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + } - if (TARGET_64BIT && mode != Pmode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); + + pat = gen_rtx_MULT (mode, operands[1], operands[2]); emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); DONE; }) -;; Convert lea to the lea pattern to avoid flags dependency. +;; Convert ashift to the lea pattern to avoid flags dependency. (define_split [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI @@ -10364,7 +10289,7 @@ (zero_extract:SWI48 (match_operand:SWI48 0 "register_operand" "r") (const_int 1) - (match_operand:SWI48 1 "nonmemory_operand" "rN")) + (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) (const_int 0)))] "TARGET_USE_BT || optimize_function_for_size_p (cfun)" "bt{}\t{%1, %0|%0, %1}" @@ -12402,11 +12327,12 @@ (call:DI (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z")) (match_operand:DI 3 "" ""))) - (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)] "TARGET_64BIT" { - fputs (ASM_BYTE "0x66\n", asm_out_file); + if (!TARGET_X32) + fputs (ASM_BYTE "0x66\n", asm_out_file); output_asm_insn ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands); fputs (ASM_SHORT "0x6666\n", asm_out_file); @@ -12416,7 +12342,8 @@ return "call\t%P2"; } [(set_attr "type" "multi") - (set_attr "length" "16")]) + (set (attr "length") + (symbol_ref "TARGET_X32 ? 15 : 16"))]) (define_expand "tls_global_dynamic_64" [(parallel @@ -12424,7 +12351,7 @@ (call:DI (mem:QI (match_operand:DI 2 "constant_call_address_operand" "")) (const_int 0))) - (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TLS_GD)])]) (define_insn "*tls_local_dynamic_base_32_gnu" @@ -12517,10 +12444,32 @@ (define_mode_attr tp_seg [(SI "gs") (DI "fs")]) ;; Load and add the thread base pointer from %:0. +(define_insn "*load_tp_x32" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(const_int 0)] UNSPEC_TP))] + "TARGET_X32" + "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" + [(set_attr "type" "imov") + (set_attr "modrm" "0") + (set_attr "length" "7") + (set_attr "memory" "load") + (set_attr "imm_disp" "false")]) + +(define_insn "*load_tp_x32_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] + "TARGET_X32" + "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" + [(set_attr "type" "imov") + (set_attr "modrm" "0") + (set_attr "length" "7") + (set_attr "memory" "load") + (set_attr "imm_disp" "false")]) + (define_insn "*load_tp_" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(const_int 0)] UNSPEC_TP))] - "" + "!TARGET_X32" "mov{}\t{%%:0, %0|%0, PTR :0}" [(set_attr "type" "imov") (set_attr "modrm" "0") @@ -12528,12 +12477,39 @@ (set_attr "memory" "load") (set_attr "imm_disp" "false")]) +(define_insn "*add_tp_x32" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) + (match_operand:SI 1 "register_operand" "0"))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_X32" + "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" + [(set_attr "type" "alu") + (set_attr "modrm" "0") + (set_attr "length" "7") + (set_attr "memory" "load") + (set_attr "imm_disp" "false")]) + +(define_insn "*add_tp_x32_zext" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) + (match_operand:SI 1 "register_operand" "0")))) + (clobber (reg:CC FLAGS_REG))] + "TARGET_X32" + "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" + [(set_attr "type" "alu") + (set_attr "modrm" "0") + (set_attr "length" "7") + (set_attr "memory" "load") + (set_attr "imm_disp" "false")]) + (define_insn "*add_tp_" [(set (match_operand:P 0 "register_operand" "=r") (plus:P (unspec:P [(const_int 0)] UNSPEC_TP) (match_operand:P 1 "register_operand" "0"))) (clobber (reg:CC FLAGS_REG))] - "" + "!TARGET_X32" "add{}\t{%%:0, %0|%0, PTR :0}" [(set_attr "type" "alu") (set_attr "modrm" "0") @@ -12577,7 +12553,7 @@ ix86_tls_descriptor_calls_expanded_in_cfun = true; }) -(define_insn "*tls_dynamic_lea_32" +(define_insn "*tls_dynamic_gnu2_lea_32" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_operand:SI 1 "register_operand" "b") (const:SI @@ -12590,7 +12566,7 @@ (set_attr "length" "6") (set_attr "length_address" "4")]) -(define_insn "*tls_dynamic_call_32" +(define_insn "*tls_dynamic_gnu2_call_32" [(set (match_operand:SI 0 "register_operand" "=a") (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") (match_operand:SI 2 "register_operand" "0") @@ -12628,7 +12604,7 @@ (define_expand "tls_dynamic_gnu2_64" [(set (match_dup 2) - (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TLSDESC)) (parallel [(set (match_operand:DI 0 "register_operand" "") @@ -12641,9 +12617,9 @@ ix86_tls_descriptor_calls_expanded_in_cfun = true; }) -(define_insn "*tls_dynamic_lea_64" +(define_insn "*tls_dynamic_gnu2_lea_64" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TLSDESC))] "TARGET_64BIT && TARGET_GNU2_TLS" "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}" @@ -12652,9 +12628,9 @@ (set_attr "length" "7") (set_attr "length_address" "4")]) -(define_insn "*tls_dynamic_call_64" +(define_insn "*tls_dynamic_gnu2_call_64" [(set (match_operand:DI 0 "register_operand" "=a") - (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "") (match_operand:DI 2 "register_operand" "0") (reg:DI SP_REG)] UNSPEC_TLSDESC)) @@ -12673,7 +12649,7 @@ (reg:DI SP_REG)] UNSPEC_TLSDESC) (const:DI (unspec:DI - [(match_operand:DI 1 "tls_symbolic_operand" "")] + [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_DTPOFF)))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && TARGET_GNU2_TLS" @@ -15899,11 +15875,11 @@ (set_attr "prefix_rep" "1")]) (define_expand "strlen" - [(set (match_operand:SWI48x 0 "register_operand" "") - (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "") - (match_operand:QI 2 "immediate_operand" "") - (match_operand 3 "immediate_operand" "")] - UNSPEC_SCAS))] + [(set (match_operand:P 0 "register_operand" "") + (unspec:P [(match_operand:BLK 1 "general_operand" "") + (match_operand:QI 2 "immediate_operand" "") + (match_operand 3 "immediate_operand" "")] + UNSPEC_SCAS))] "" { if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) @@ -16021,8 +15997,8 @@ (define_expand "movcc" [(set (match_operand:SWIM 0 "register_operand" "") (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "") - (match_operand:SWIM 2 "general_operand" "") - (match_operand:SWIM 3 "general_operand" "")))] + (match_operand:SWIM 2 "" "") + (match_operand:SWIM 3 "" "")))] "" "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")