From 536e3f497eb8cbde60a6456edeaf1c13ed268763 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 26 Jul 2011 14:00:33 +0200 Subject: re PR target/47381 ([x32] internal compiler error: in gen_lowpart_general, at rtlhooks.c:59) PR target/47381 PR target/49832 PR target/49833 * config/i386/i386.md (i): Change SImode attribute to "e". (g): Change SImode attribute to "rme". (di): Change SImode attribute to "nF". (general_operand): Change SImode attribute to x86_64_general_operand. (general_szext_operand): Change SImode attribute to x86_64_szext_general_operand. (immediate_operand): Change SImode attribute to x86_64_immediate_operand. (nonmemory_operand): Change SImode attribute to x86_64_nonmemory_operand. (*movdi_internal_rex64): Remove mode from pic_32bit_operand check. (*movsi_internal): Ditto. Use "e" constraint in alternative 2. (*lea_1): Use SWI48 mode iterator. (*lea_1_zext): New insn pattern. (testsi_ccno_1): Use x86_64_nonmemory_operand predicate for operand 2. (*bt): Ditto. (*add1): Use x86_64_general_operand predicate for operand 2. Update operand constraints. (addsi_1_zext): Ditto. (*add2): Ditto. (*addsi_3_zext): Ditto. (*subsi_1_zext): Ditto. (*subsi_2_zext): Ditto. (*subsi_3_zext): Ditto. (*addsi3_carry_zext): Ditto. (*si3_zext_cc_overflow): Ditto. (*mulsi3_1_zext): Ditto. (*andsi_1): Ditto. (*andsi_1_zext): Ditto. (*andsi_2_zext): Ditto. (*si_1_zext): Ditto. (*si_2_zext): Ditto. (*test_1): Use predicate for operand 1. (*and_2): Ditto. (movcc): Use predicate for operands 1 and 2. (add->lea splitter): Check operand modes in insn constraint. Extend operands less than SImode wide to SImode. (add->lea zext splitter): Do not extend input operands to DImode. (*lea_general_1): Handle only QImode and HImode operands. (*lea_general_2): Ditto. (*lea_general_3): Ditto. (*lea_general_1_zext): Remove. (*lea_general_2_zext): Ditto. (*lea_general_3_zext): Ditto. (*lea_general_4): Check operand modes in insn constraint. Extend operands less than SImode wide to SImode. (ashift->lea splitter): Ditto. * config/i386/i386.c (ix86_print_operand_address): Print address registers with 'q' modifier on 64bit targets. * config/i386/predicates.md (pic_32bit_opreand): Define as special predicate. Reject non-SI and non-DI modes. From-SVN: r176788 --- gcc/ChangeLog | 73 ++++++++-- gcc/config/i386/i386.c | 11 +- gcc/config/i386/i386.md | 328 +++++++++++++++++------------------------- gcc/config/i386/predicates.md | 6 +- 4 files changed, 211 insertions(+), 207 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c93e5e3..913e202 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,61 @@ +2011-07-26 Uros Bizjak + H.J. Lu + + PR target/47381 + PR target/49832 + PR target/49833 + * config/i386/i386.md (i): Change SImode attribute to "e". + (g): Change SImode attribute to "rme". + (di): Change SImode attribute to "nF". + (general_operand): Change SImode attribute to x86_64_general_operand. + (general_szext_operand): Change SImode attribute to + x86_64_szext_general_operand. + (immediate_operand): Change SImode attribute to + x86_64_immediate_operand. + (nonmemory_operand): Change SImode attribute to + x86_64_nonmemory_operand. + (*movdi_internal_rex64): Remove mode from pic_32bit_operand check. + (*movsi_internal): Ditto. Use "e" constraint in alternative 2. + (*lea_1): Use SWI48 mode iterator. + (*lea_1_zext): New insn pattern. + (testsi_ccno_1): Use x86_64_nonmemory_operand predicate for operand 2. + (*bt): Ditto. + (*add1): Use x86_64_general_operand predicate for operand 2. + Update operand constraints. + (addsi_1_zext): Ditto. + (*add2): Ditto. + (*addsi_3_zext): Ditto. + (*subsi_1_zext): Ditto. + (*subsi_2_zext): Ditto. + (*subsi_3_zext): Ditto. + (*addsi3_carry_zext): Ditto. + (*si3_zext_cc_overflow): Ditto. + (*mulsi3_1_zext): Ditto. + (*andsi_1): Ditto. + (*andsi_1_zext): Ditto. + (*andsi_2_zext): Ditto. + (*si_1_zext): Ditto. + (*si_2_zext): Ditto. + (*test_1): Use predicate for operand 1. + (*and_2): Ditto. + (movcc): Use predicate for operands 1 and 2. + (add->lea splitter): Check operand modes in insn constraint. Extend + operands less than SImode wide to SImode. + (add->lea zext splitter): Do not extend input operands to DImode. + (*lea_general_1): Handle only QImode and HImode operands. + (*lea_general_2): Ditto. + (*lea_general_3): Ditto. + (*lea_general_1_zext): Remove. + (*lea_general_2_zext): Ditto. + (*lea_general_3_zext): Ditto. + (*lea_general_4): Check operand modes in insn constraint. Extend + operands less than SImode wide to SImode. + (ashift->lea splitter): Ditto. + * config/i386/i386.c (ix86_print_operand_address): Print address + registers with 'q' modifier on 64bit targets. + * config/i386/predicates.md (pic_32bit_opreand): Define as special + predicate. Reject non-SI and non-DI modes. + 2011-07-25 Andrew Pinski PR tree-opt/49671 @@ -68,13 +126,13 @@ * config/mmix/mmix.c (mmix_print_operand_punct_valid_p): Make static. Change return type to bool. Change argument type to bool. (mmix_print_operand, mmix_print_operand_address): Make static. - (mmix_intval, mmix_output_condition): Change 'x' argument type + (mmix_intval, mmix_output_condition): Change 'x' argument type to const_rtx. (TARGET_PRINT_OPERAND, TARGET_PRINT_OPERAND_ADDRESS, TARGET_PRINT_OPERAND_PUNCT_VALID_P): Define. 2011-07-25 Georg-Johann Lay - + PR target/39386 * config/avr/avr.c (out_shift_with_cnt): Use tmp_reg as shift counter for x << x and x >> x shifts. @@ -294,7 +352,7 @@ (EDGE_ALL_FLAGS, EDGE_COMPLEX): Include it. * bb-reorder.c: Include except.h. (fix_up_crossing_landing_pad): New. - (find_rarely_executed_basic_blocks_and_crossing_edges): Place + (find_rarely_executed_basic_blocks_and_crossing_edges): Place landing pads in the right partition. Duplicate as necessary. (partition_hot_cold_basic_blocks): Fix up DF info after duplicating landing pads. @@ -357,8 +415,7 @@ (producer_string): New variable. (gen_producer_string): New function. (gen_compile_unit_die): Use it. - (dwarf2out_finish): Fix up comp_unit_die () DW_AT_producer - if needed. + (dwarf2out_finish): Fix up comp_unit_die () DW_AT_producer if needed. * Makefile.in (dwarf2out.o): Depend on $(OPTS_H). * doc/invoke.texi: Document -grecord-gcc-switches and -gno-record-gcc-switches, add a -grecord-gcc-switches reference @@ -380,8 +437,7 @@ MS ABI in x32 mode. (ix86_init_builtins): Call ix86_init_builtins_va_builtins_abi only for TARGET_LP64. - (ix86_handle_abi_attribute): Check TARGET_LP64 instead of - TARGET_64BIT. + (ix86_handle_abi_attribute): Check TARGET_LP64 instead of TARGET_64BIT. 2011-07-22 Michael Meissner @@ -392,8 +448,7 @@ PR lto/49796 * cgraphunit.c (verify_edge_corresponds_to_fndecl): Return false - if decl node is in another partition, call cgraph_get_node only - once. + if decl node is in another partition, call cgraph_get_node only once. 2011-07-22 Uros Bizjak diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 96263ed..3668357 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14122,6 +14122,9 @@ ix86_print_operand_address (FILE *file, rtx addr) } else { + /* Print DImode registers on 64bit targets to avoid addr32 prefixes. */ + int code = TARGET_64BIT ? 'q' : 0; + if (ASSEMBLER_DIALECT == ASM_ATT) { if (disp) @@ -14136,11 +14139,11 @@ ix86_print_operand_address (FILE *file, rtx addr) putc ('(', file); if (base) - print_reg (base, 0, file); + print_reg (base, code, file); if (index) { putc (',', file); - print_reg (index, 0, file); + print_reg (index, code, file); if (scale != 1) fprintf (file, ",%d", scale); } @@ -14175,7 +14178,7 @@ ix86_print_operand_address (FILE *file, rtx addr) putc ('[', file); if (base) { - print_reg (base, 0, file); + print_reg (base, code, file); if (offset) { if (INTVAL (offset) >= 0) @@ -14191,7 +14194,7 @@ ix86_print_operand_address (FILE *file, rtx addr) if (index) { putc ('+', file); - print_reg (index, 0, file); + print_reg (index, code, file); if (scale != 1) fprintf (file, "*%d", scale); } diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b704fa7..98d60ec 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,39 +5803,36 @@ (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" ""))) (clobber (reg:CC FLAGS_REG))] - "reload_completed && ix86_lea_for_add_ok (insn, operands)" + "GET_MODE (operands[0]) == GET_MODE (operands[1]) + && (GET_MODE (operands[0]) == GET_MODE (operands[2]) + || GET_MODE (operands[2]) == VOIDmode) + && reload_completed && ix86_lea_for_add_ok (insn, operands)" [(const_int 0)] { - 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]); + 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]); + 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. +;; Convert add 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 @@ -5839,7 +5845,7 @@ [(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 @@ -5849,11 +5855,7 @@ "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 +5903,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 +5981,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 +6235,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 +6243,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 +6253,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 +6284,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 +6353,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 +6423,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 +6460,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 +6487,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 +6534,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 +6549,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 +6603,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 +6690,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 +7316,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 +7382,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 +7672,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 +7719,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 +7867,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 +7882,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 +8099,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 +8147,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 +9337,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]); + } + + operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); - if (TARGET_64BIT && mode != Pmode) - pat = gen_rtx_SUBREG (SImode, pat, 0); + 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 +10306,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}" @@ -16021,8 +15963,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;") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 2ef9129..0515519 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -366,9 +366,13 @@ ;; Return true when operand is PIC expression that can be computed by lea ;; operation. -(define_predicate "pic_32bit_operand" +(define_special_predicate "pic_32bit_operand" (match_code "const,symbol_ref,label_ref") { + if (GET_MODE (op) != SImode + && GET_MODE (op) != DImode) + return false; + if (!flag_pic) return false; /* Rule out relocations that translate into 64bit constants. */ -- cgit v1.1