Hello! Attached patch introduces Yp register constraint, conditionalized on TARGET_PARTIAL_REG_STALL. Using this constraint, several *_lea patterns can be merged with their base patterns, resulting in many removed lines of code.
No functional changes otherwise. 2011-08-23 Uros Bizjak <ubiz...@gmail.com> * config/i386/constraints.md (Yp): New register constraint. * config/i386/i386.md (*addhi_1): Merge with *addhi_1_lea using Yp register constraint. (*addqi_1): Merge with *addqi_1_lea using Yp register constraint. (*ashlhi3_1): Merge with *ashlhi3_1_lea using Yp register constraint. (*ashlqi3_1): Merge with *ashlqi3_1_lea using Yp register constraint. Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. URos.
Index: i386.md =================================================================== --- i386.md (revision 178001) +++ i386.md (working copy) @@ -5650,52 +5650,14 @@ (set_attr "mode" "SI")]) (define_insn "*addhi_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "rn,rm"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") + (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) (clobber (reg:CC FLAGS_REG))] - "TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (PLUS, HImode, operands)" + "ix86_binary_operator_ok (PLUS, HImode, operands)" { switch (get_attr_type (insn)) { - case TYPE_INCDEC: - if (operands[2] == const1_rtx) - return "inc{w}\t%0"; - else - { - gcc_assert (operands[2] == constm1_rtx); - return "dec{w}\t%0"; - } - - default: - if (x86_maybe_negate_const_int (&operands[2], HImode)) - return "sub{w}\t{%2, %0|%0, %2}"; - - return "add{w}\t{%2, %0|%0, %2}"; - } -} - [(set (attr "type") - (if_then_else (match_operand:HI 2 "incdec_operand" "") - (const_string "incdec") - (const_string "alu"))) - (set (attr "length_immediate") - (if_then_else - (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) - (const_string "1") - (const_string "*"))) - (set_attr "mode" "HI")]) - -(define_insn "*addhi_1_lea" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r") - (match_operand:HI 2 "general_operand" "rmn,rn,0,ln"))) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (PLUS, HImode, operands)" -{ - switch (get_attr_type (insn)) - { case TYPE_LEA: return "#"; @@ -5739,63 +5701,16 @@ (const_string "*"))) (set_attr "mode" "HI,HI,HI,SI")]) -;; %%% Potential partial reg stall on alternative 2. What to do? +;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? (define_insn "*addqi_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") + (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) (clobber (reg:CC FLAGS_REG))] - "TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (PLUS, QImode, operands)" + "ix86_binary_operator_ok (PLUS, QImode, operands)" { - int widen = (which_alternative == 2); - switch (get_attr_type (insn)) - { - case TYPE_INCDEC: - if (operands[2] == const1_rtx) - return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; - else - { - gcc_assert (operands[2] == constm1_rtx); - return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; - } + bool widen = (which_alternative == 3 || which_alternative == 4); - default: - if (x86_maybe_negate_const_int (&operands[2], QImode)) - { - if (widen) - return "sub{l}\t{%2, %k0|%k0, %2}"; - else - return "sub{b}\t{%2, %0|%0, %2}"; - } - if (widen) - return "add{l}\t{%k2, %k0|%k0, %k2}"; - else - return "add{b}\t{%2, %0|%0, %2}"; - } -} - [(set (attr "type") - (if_then_else (match_operand:QI 2 "incdec_operand" "") - (const_string "incdec") - (const_string "alu"))) - (set (attr "length_immediate") - (if_then_else - (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" "")) - (const_string "1") - (const_string "*"))) - (set_attr "mode" "QI,QI,SI")]) - -;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? -(define_insn "*addqi_1_lea" - [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r") - (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln"))) - (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (PLUS, QImode, operands)" -{ - int widen = (which_alternative == 3 || which_alternative == 4); - switch (get_attr_type (insn)) { case TYPE_LEA: @@ -9294,53 +9209,11 @@ "operands[2] = gen_lowpart (SImode, operands[2]);") (define_insn "*ashlhi3_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") - (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "nonmemory_operand" "cI"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (ASHIFT, HImode, operands)" -{ - switch (get_attr_type (insn)) - { - case TYPE_ALU: - gcc_assert (operands[2] == const1_rtx); - return "add{w}\t%0, %0"; - - default: - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - return "sal{w}\t%0"; - else - return "sal{w}\t{%2, %0|%0, %2}"; - } -} - [(set (attr "type") - (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") - (const_int 0)) - (match_operand 0 "register_operand" "")) - (match_operand 2 "const1_operand" "")) - (const_string "alu") - ] - (const_string "ishift"))) - (set (attr "length_immediate") - (if_then_else - (ior (eq_attr "type" "alu") - (and (eq_attr "type" "ishift") - (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" "HI")]) - -(define_insn "*ashlhi3_1_lea" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") (match_operand:QI 2 "nonmemory_operand" "cI,M"))) (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (ASHIFT, HImode, operands)" + "ix86_binary_operator_ok (ASHIFT, HImode, operands)" { switch (get_attr_type (insn)) { @@ -9380,68 +9253,13 @@ (const_string "*"))) (set_attr "mode" "HI,SI")]) +;; %%% Potential partial reg stall on alternative 1. What to do? (define_insn "*ashlqi3_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") - (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (ASHIFT, QImode, operands)" -{ - switch (get_attr_type (insn)) - { - case TYPE_ALU: - gcc_assert (operands[2] == const1_rtx); - if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) - return "add{l}\t%k0, %k0"; - else - return "add{b}\t%0, %0"; - - default: - if (operands[2] == const1_rtx - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) - { - if (get_attr_mode (insn) == MODE_SI) - return "sal{l}\t%k0"; - else - return "sal{b}\t%0"; - } - else - { - if (get_attr_mode (insn) == MODE_SI) - return "sal{l}\t{%2, %k0|%k0, %2}"; - else - return "sal{b}\t{%2, %0|%0, %2}"; - } - } -} - [(set (attr "type") - (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") - (const_int 0)) - (match_operand 0 "register_operand" "")) - (match_operand 2 "const1_operand" "")) - (const_string "alu") - ] - (const_string "ishift"))) - (set (attr "length_immediate") - (if_then_else - (ior (eq_attr "type" "alu") - (and (eq_attr "type" "ishift") - (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" "QI,SI")]) - -;; %%% Potential partial reg stall on alternative 2. What to do? -(define_insn "*ashlqi3_1_lea" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) (clobber (reg:CC FLAGS_REG))] - "!TARGET_PARTIAL_REG_STALL - && ix86_binary_operator_ok (ASHIFT, QImode, operands)" + "ix86_binary_operator_ok (ASHIFT, QImode, operands)" { switch (get_attr_type (insn)) { Index: constraints.md =================================================================== --- constraints.md (revision 178001) +++ constraints.md (working copy) @@ -88,8 +88,11 @@ ;; We use the Y prefix to denote any number of conditional register sets: ;; z First SSE register. ;; 2 SSE2 enabled +;; 3 SSE3 enabled +;; 4 SSE4_1 enabled ;; i SSE2 inter-unit moves enabled ;; m MMX inter-unit moves enabled +;; p Integer register when TARGET_PARTIAL_REG_STALL is disabled ;; d Integer register when integer DFmode moves are enabled ;; x Integer register when integer XFmode moves are enabled @@ -113,6 +116,10 @@ "TARGET_MMX && TARGET_INTER_UNIT_MOVES ? MMX_REGS : NO_REGS" "@internal Any MMX register, when inter-unit moves are enabled.") +(define_register_constraint "Yp" + "TARGET_PARTIAL_REG_STALL ? NO_REGS : GENERAL_REGS" + "@internal Any integer register when TARGET_PARTIAL_REG_STALL is disabled.") + (define_register_constraint "Yd" "(TARGET_64BIT || (TARGET_INTEGER_DFMODE_MOVES && optimize_function_for_speed_p (cfun)))