Hi, This patch adds x32 LEA insn support. The main issue is
gen_lowpart (Pmode, operands[1]); doesn't work on symbol. This patch avoids it. Also we shouldn't generate 32bit store with x32 PIC source. Any comments? Thanks. H.J. 2011-07-22 H.J. Lu <hongjiu...@intel.com> * config/i386/constraints.md (Ys): Rewritten. (Ye): Updated. (Yl): Likewise. * config/i386/constraints.md (i): Replace "i" with "Ye". (l): New. (g): Replace "g" with "rmYe". (general_operand): Replace general_operand with with si_general_operand on SI. (general_szext_operand): Likewise. (*add<mode>_1): Replace <i> with <l>. (addsi_1_zext): Replace general_operand with si_general_operand and "g" with "rmYe". (*addsi_2_zext): Likewise. (*subsi_1_zext): Likewise. (*subsi_2_zext): Likewise. (*subsi_3_zext): Likewise. (*addsi3_carry_zext): Likewise. (*subsi3_carry_zext): Likewise. (*andsi_1): Likewise. (*andsi_1_zext): Likewise. (*andsi_2_zext): Likewise. (LEA split): Replace nonmemory_operand with si_lea_nonmemory_operand and "i" with "Ye". (*lea_general_2): Likewise. (*lea_general_2_zext): Likewise. (*lea_general_1): Replace immediate_operand with si_lea_immediate_operand and "i" with "Ye". (*lea_general_1_zext): Likewise. (*lea_general_3): Likewise. (*lea_general_3_zext): Likewise. config/i386/predicates.md (si_general_operand): New. (si_lea_immediate_operand): Likewise. (si_lea_nonmemory_operand): Likewise. diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 8d3e45a..a5d54a1 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -123,6 +123,31 @@ "optimize_function_for_speed_p (cfun) ? GENERAL_REGS : NO_REGS" "@internal Any integer register when integer XFmode moves are enabled.") +;; Constant constraints. +;; We also use the Y prefix to denote constant constraints: +;; s Immediate constant source operand for store +;; e Immediate constant for SImode +;; l Immediate constant for lea + +(define_constraint "Ys" + "@internal Immediate constant source operand for store." + (and (match_operand 0 "immediate_operand") + (ior (match_test "!TARGET_X32") + (not (match_operand 0 "pic_32bit_operand"))))) + +(define_constraint "Ye" + "@internal Immediate constant for SImode." + (if_then_else (and (match_test "TARGET_X32") + (match_test "flag_pic")) + (match_operand 0 "x86_64_immediate_operand") + (match_operand 0 "immediate_operand"))) + +(define_constraint "Yl" + "@internal Immediate constant for lea." + (if_then_else (match_test "TARGET_X32") + (match_operand 0 "si_lea_immediate_operand") + (match_operand 0 "immediate_operand"))) + (define_constraint "z" "@internal Constant call address operand." (match_operand 0 "constant_call_address_operand")) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b704fa7..02b6fd6 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -861,10 +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 "Ye") (DI "e")]) + +;; Immediate operand constraint for integer modes with lea. +(define_mode_attr l [(QI "n") (HI "n") (SI "Yl") (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 "rmYe") (DI "rme")]) ;; Immediate operand constraint for double integer modes. (define_mode_attr di [(SI "iF") (DI "e")]) @@ -876,7 +879,7 @@ (define_mode_attr general_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "si_general_operand") (DI "x86_64_general_operand") (TI "x86_64_general_operand")]) @@ -884,7 +887,7 @@ (define_mode_attr general_szext_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "si_general_operand") (DI "x86_64_szext_general_operand")]) ;; Immediate operand predicate for integer modes. @@ -2180,11 +2198,13 @@ [(const_int 0)] "ix86_split_long_move (operands); DONE;") +;; Use "Ys" constraint to disallow store with X32 PIC operand as +;; immediate. (define_insn "*movsi_internal" [(set (match_operand:SI 0 "nonimmediate_operand" - "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") + "=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 ,rYs,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -5453,7 +5473,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 "<general_operand>" "<g>,r<i>,0,l<i>"))) + (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<l>"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" { @@ -5512,7 +5532,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 "si_general_operand" "rmYe,0,lYl")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -5844,7 +5864,7 @@ [(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 "si_lea_nonmemory_operand" "")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" @@ -5901,7 +5921,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 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6240,7 +6260,7 @@ [(set (match_operand 0 "register_operand" "=r") (plus (plus (match_operand 1 "index_register_operand" "l") (match_operand 2 "register_operand" "r")) - (match_operand 3 "immediate_operand" "i")))] + (match_operand 3 "si_lea_immediate_operand" "Ye")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) @@ -6273,7 +6293,7 @@ (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"))))] + (match_operand:SI 3 "si_lea_immediate_operand" "Ye"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6293,7 +6313,7 @@ [(set (match_operand 0 "register_operand" "=r") (plus (mult (match_operand 1 "index_register_operand" "l") (match_operand 2 "const248_operand" "i")) - (match_operand 3 "nonmemory_operand" "ri")))] + (match_operand 3 "si_lea_nonmemory_operand" "rYe")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL @@ -6326,7 +6346,7 @@ (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"))))] + (match_operand:SI 3 "si_lea_nonmemory_operand" "rYe"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6346,7 +6366,7 @@ (plus (plus (mult (match_operand 1 "index_register_operand" "l") (match_operand 2 "const248_operand" "i")) (match_operand 3 "register_operand" "r")) - (match_operand 4 "immediate_operand" "i")))] + (match_operand 4 "si_lea_immediate_operand" "Ye")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL @@ -6384,7 +6404,7 @@ (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"))))] + (match_operand:SI 4 "si_lea_immediate_operand" "Ye"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6481,7 +6501,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 "si_general_operand" "rmYe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\t{%2, %k0|%k0, %2}" @@ -6518,7 +6538,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 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6545,7 +6565,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 "si_general_operand" "rmYe"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_dup 1) @@ -6592,7 +6612,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 "si_general_operand" "rmYe"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" @@ -6607,7 +6627,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 "si_general_operand" "rmYe"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %k0|%k0, %2}" @@ -7730,7 +7750,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 "si_general_operand" "rYe,rm,L"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, SImode, operands)" { @@ -7777,7 +7797,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 "si_general_operand" "rmYe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" "and{l}\t{%2, %k0|%k0, %2}" @@ -7940,7 +7960,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 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 2ef9129..267136a 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1188,3 +1198,24 @@ return false; return true; }) + +;; Test for a valid general operand for SImode. +(define_predicate "si_general_operand" + (if_then_else (and (match_test "TARGET_X32") + (match_test "flag_pic")) + (match_operand 0 "x86_64_general_operand") + (match_operand 0 "general_operand"))) + +;; Test for a valid immediate operand for lea in SImode. +(define_predicate "si_lea_immediate_operand" + (and (match_operand 0 "immediate_operand") + (ior (match_test "!TARGET_X32") + (match_test "GET_MODE (op) != SImode") + (match_test "!SYMBOLIC_CONST (op)")))) + +;; Test for a valid nonmemory operand for lea in SImode. +(define_predicate "si_lea_nonmemory_operand" + (and (match_operand 0 "nonmemory_operand") + (ior (match_test "!TARGET_X32") + (match_test "GET_MODE (op) != SImode") + (match_test "!SYMBOLIC_CONST (op)"))))