===================================================================
@@ -274,10 +274,10 @@ enum ix86_tune_indices {
X86_TUNE_HIMODE_MATH,
X86_TUNE_PROMOTE_QI_REGS,
X86_TUNE_PROMOTE_HI_REGS,
- X86_TUNE_ADD_ESP_4,
- X86_TUNE_ADD_ESP_8,
- X86_TUNE_SUB_ESP_4,
- X86_TUNE_SUB_ESP_8,
+ X86_TUNE_SINGLE_POP,
+ X86_TUNE_DOUBLE_POP,
+ X86_TUNE_SINGLE_PUSH,
+ X86_TUNE_DOUBLE_PUSH,
X86_TUNE_INTEGER_DFMODE_MOVES,
X86_TUNE_PARTIAL_REG_DEPENDENCY,
X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY,
@@ -348,10 +348,10 @@ extern unsigned char ix86_tune_features[
#define TARGET_HIMODE_MATH ix86_tune_features[X86_TUNE_HIMODE_MATH]
#define TARGET_PROMOTE_QI_REGS ix86_tune_features[X86_TUNE_PROMOTE_QI_REGS]
#define TARGET_PROMOTE_HI_REGS ix86_tune_features[X86_TUNE_PROMOTE_HI_REGS]
-#define TARGET_ADD_ESP_4 ix86_tune_features[X86_TUNE_ADD_ESP_4]
-#define TARGET_ADD_ESP_8 ix86_tune_features[X86_TUNE_ADD_ESP_8]
-#define TARGET_SUB_ESP_4 ix86_tune_features[X86_TUNE_SUB_ESP_4]
-#define TARGET_SUB_ESP_8 ix86_tune_features[X86_TUNE_SUB_ESP_8]
+#define TARGET_SINGLE_POP ix86_tune_features[X86_TUNE_SINGLE_POP]
+#define TARGET_DOUBLE_POP ix86_tune_features[X86_TUNE_DOUBLE_POP]
+#define TARGET_SINGLE_PUSH ix86_tune_features[X86_TUNE_SINGLE_PUSH]
+#define TARGET_DOUBLE_PUSH ix86_tune_features[X86_TUNE_DOUBLE_PUSH]
#define TARGET_INTEGER_DFMODE_MOVES \
ix86_tune_features[X86_TUNE_INTEGER_DFMODE_MOVES]
#define TARGET_PARTIAL_REG_DEPENDENCY \
===================================================================
@@ -1749,7 +1749,7 @@
[(set_attr "type" "push")
(set_attr "mode" "<MODE>")])
-(define_insn "pop<mode>1"
+(define_insn "*pop<mode>1"
[(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
(match_operand:P 1 "pop_operand" ">"))]
""
@@ -17025,202 +17025,131 @@
;; alternative when no register is available later.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
+ "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
- (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
+ "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
+ (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
(clobber (mem:BLK (scratch)))])])
;; Convert esp subtractions to push.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
-
-(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
- (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
+
+(define_peephole2
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
+ [(clobber (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
+ (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
;; Convert epilogue deallocator to pop.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
- [(parallel [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))
+ "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])])
;; Two pops case is tricky, since pop causes dependency
;; on destination register. We use two registers if available.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (match_scratch:SI 1 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (match_scratch:P 2 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
- [(parallel [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))
+ "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])
- (set (match_dup 1) (mem:SI (post_inc:SI (reg:SI SP_REG))))])
+ (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))
(clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))
+ "optimize_insn_for_size_p ()
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
(clobber (mem:BLK (scratch)))])
- (set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))])
+ (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
;; Convert esp additions to pop.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
- ""
- [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))])
+ "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
;; Two pops case is tricky, since pop causes dependency
;; on destination register. We use two registers if available.
(define_peephole2
- [(match_scratch:SI 0 "r")
- (match_scratch:SI 1 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))
- (set (match_dup 1) (mem:SI (post_inc:SI (reg:SI SP_REG))))])
-
-(define_peephole2
- [(match_scratch:SI 0 "r")
- (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p ()"
- [(set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))
- (set (match_dup 0) (mem:SI (post_inc:SI (reg:SI SP_REG))))])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (clobber (mem:BLK (scratch)))])])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (clobber (mem:BLK (scratch)))])])
-
-;; Convert esp subtractions to push.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
- [(clobber (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
- (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
-
-;; Convert epilogue deallocator to pop.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
- [(parallel [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))
- (clobber (mem:BLK (scratch)))])])
-
-;; Two pops case is tricky, since pop causes dependency
-;; on destination register. We use two registers if available.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (match_scratch:DI 1 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
- [(parallel [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))
- (clobber (mem:BLK (scratch)))])
- (set (match_dup 1) (mem:DI (post_inc:DI (reg:DI SP_REG))))])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))
- (clobber (mem:BLK (scratch)))])]
- "optimize_insn_for_size_p ()"
- [(parallel [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))
- (clobber (mem:BLK (scratch)))])
- (set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))])
-
-;; Convert esp additions to pop.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))])
-
-;; Two pops case is tricky, since pop causes dependency
-;; on destination register. We use two registers if available.
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (match_scratch:DI 1 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))])]
- ""
- [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))
- (set (match_dup 1) (mem:DI (post_inc:DI (reg:DI SP_REG))))])
-
-(define_peephole2
- [(match_scratch:DI 0 "r")
- (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
- (clobber (reg:CC FLAGS_REG))])]
- "optimize_insn_for_size_p ()"
- [(set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))
- (set (match_dup 0) (mem:DI (post_inc:DI (reg:DI SP_REG))))])
+ [(match_scratch:P 1 "r")
+ (match_scratch:P 2 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
+ (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
+
+(define_peephole2
+ [(match_scratch:P 1 "r")
+ (parallel [(set (reg:P SP_REG)
+ (plus:P (reg:P SP_REG)
+ (match_operand:P 0 "const_int_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "optimize_insn_for_size_p ()
+ && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
+ [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
+ (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
;; Convert compares with 1 to shorter inc/dec operations when CF is not
;; required and register dies. Similarly for 128 to -128.
===================================================================
@@ -1480,21 +1480,21 @@ static unsigned int initial_ix86_tune_fe
/* X86_TUNE_PROMOTE_HI_REGS */
m_PPRO,
- /* X86_TUNE_ADD_ESP_4: Enable if add/sub is preferred over 1/2 push/pop. */
- m_ATOM | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT4 | m_NOCONA
- | m_CORE2 | m_GENERIC,
-
- /* X86_TUNE_ADD_ESP_8 */
- m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_K6_GEODE | m_386
- | m_486 | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ /* X86_TUNE_SINGLE_POP: Enable if single pop insn is preferred
+ over esp addition. */
+ m_386 | m_486 | m_PENT | m_PPRO,
- /* X86_TUNE_SUB_ESP_4 */
- m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_PENT4 | m_NOCONA | m_CORE2
- | m_GENERIC,
+ /* X86_TUNE_DOUBLE_POP: Enable if double pop insn is preferred
+ over esp addition. */
+ m_PENT,
- /* X86_TUNE_SUB_ESP_8 */
- m_AMD_MULTIPLE | m_ATOM | m_PPRO | m_386 | m_486
- | m_PENT4 | m_NOCONA | m_CORE2 | m_GENERIC,
+ /* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
+ over esp subtraction. */
+ m_386 | m_486 | m_PENT | m_K6_GEODE,
+
+ /* X86_TUNE_DOUBLE_PUSH. Enable if double push insn is preferred
+ over esp subtraction. */
+ m_PENT | m_K6_GEODE,
/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
for DFmode copies */