From cc2e591b48e51df008d4e09d1f67f1195f8cbeb5 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 26 Mar 2001 15:56:34 +0200 Subject: [PATCH] i386.md (push mem DI peep2): New. * i386.md (push mem DI peep2): New. (mov 0, mov -1 peep2): Handle 64bit. (lea to arithmetics peep2): Handle 64bit leas. (rsp arithmetics to push/pop peep2s): New. * i386.md (truncdfsf2_3, trunctfsf2_2): Change predicate to memory_operand. From-SVN: r40847 --- gcc/ChangeLog | 9 ++ gcc/config/i386/i386.md | 181 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 183 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index db3c86df5d5..477517c0c15 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Mon Mar 26 15:55:08 CEST 2001 Jan Hubicka + + * i386.md (push mem DI peep2): New. + (mov 0, mov -1 peep2): Handle 64bit. + (lea to arithmetics peep2): Handle 64bit leas. + (rsp arithmetics to push/pop peep2s): New. + + * i386.md (truncdfsf2_3, trunctfsf2_2): Change predicate to memory_operand. + Mon Mar 26 14:35:18 CEST 2001 Jan Hubicka * i386.c (struct machine_function): Add save_varrargs_registers. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 6a23023f279..8f6c36b3115 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -4341,7 +4341,7 @@ (set_attr "mode" "DF,SF")]) (define_insn "truncdfsf2_3" - [(set (match_operand:SF 0 "nonimmediate_operand" "=m") + [(set (match_operand:SF 0 "memory_operand" "=m") (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] "TARGET_80387" @@ -4490,7 +4490,7 @@ (set_attr "mode" "SF")]) (define_insn "*trunctfsf2_2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=m") + [(set (match_operand:SF 0 "memory_operand" "=m") (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))] "TARGET_80387" @@ -15890,6 +15890,15 @@ (set (match_dup 0) (match_dup 2))] "") +(define_peephole2 + [(set (match_operand:DI 0 "push_operand" "") + (match_operand:DI 1 "memory_operand" "")) + (match_scratch:DI 2 "r")] + "! optimize_size && ! TARGET_PUSH_MEMORY" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (match_dup 2))] + "") + ;; We need to handle SFmode only, because DFmode and XFmode is split to ;; SImode pushes. (define_peephole2 @@ -16209,12 +16218,14 @@ (const_int 0))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode - || GET_MODE (operands[0]) == SImode) + || GET_MODE (operands[0]) == SImode + || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) && (! TARGET_USE_MOV0 || optimize_size) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (const_int 0)) (clobber (reg:CC 17))])] - "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));") + "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode, + true_regnum (operands[0]));") (define_peephole2 [(set (strict_low_part (match_operand 0 "register_operand" "")) @@ -16231,12 +16242,14 @@ [(set (match_operand 0 "register_operand" "") (const_int -1))] "(GET_MODE (operands[0]) == HImode - || GET_MODE (operands[0]) == SImode) + || GET_MODE (operands[0]) == SImode + || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) && (optimize_size || TARGET_PENTIUM) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (const_int -1)) (clobber (reg:CC 17))])] - "operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]));") + "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode, + true_regnum (operands[0]));") ;; Attempt to convert simple leas to adds. These can be created by ;; move expanders. @@ -16249,16 +16262,55 @@ (clobber (reg:CC 17))])] "") +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")) 0))] + "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" + [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) + (clobber (reg:CC 17))])] + "operands[2] = gen_lowpart (SImode, operands[2]);") + +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (match_dup 0) + (match_operand:DI 1 "x86_64_general_operand" "")))] + "peep2_regno_dead_p (0, FLAGS_REG)" + [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) + (clobber (reg:CC 17))])] + "") + (define_peephole2 [(set (match_operand:SI 0 "register_operand" "") (mult:SI (match_dup 0) - (match_operand:SI 1 "immediate_operand" "")))] + (match_operand:SI 1 "const_int_operand" "")))] "exact_log2 (INTVAL (operands[1])) >= 0 && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) (clobber (reg:CC 17))])] "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (mult:DI (match_dup 0) + (match_operand:DI 1 "const_int_operand" "")))] + "exact_log2 (INTVAL (operands[1])) >= 0 + && peep2_regno_dead_p (0, FLAGS_REG)" + [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) + (clobber (reg:CC 17))])] + "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "const_int_operand" "")) 0))] + "exact_log2 (INTVAL (operands[1])) >= 0 + && REGNO (operands[0]) == REGNO (operands[1]) + && peep2_regno_dead_p (0, FLAGS_REG)" + [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) + (clobber (reg:CC 17))])] + "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") + ;; The ESP adjustments can be done by the push and pop instructions. Resulting ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On ;; many CPUs it is also faster, since special hardware to avoid esp @@ -16456,6 +16508,121 @@ (clobber (match_dup 0))])] "") +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8))) + (set (reg:DI 6) (reg:DI 6)) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_SUB_ESP_4" + [(clobber (match_dup 0)) + (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0)) + (set (reg:DI 6) (reg:DI 6))])]) + +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16))) + (set (reg:DI 6) (reg:DI 6)) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_SUB_ESP_8" + [(clobber (match_dup 0)) + (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0)) + (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0)) + (set (reg:DI 6) (reg:DI 6))])]) + +;; Convert esp substractions to push. +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8))) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_SUB_ESP_4" + [(clobber (match_dup 0)) + (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))]) + +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16))) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_SUB_ESP_8" + [(clobber (match_dup 0)) + (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0)) + (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))]) + +;; Convert epilogue deallocator to pop. +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8))) + (set (reg:DI 6) (reg:DI 6)) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_ADD_ESP_4" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8))) + (set (reg:DI 6) (reg:DI 6))])] + "") + +;; 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 7) (plus:DI (reg:DI 7) (const_int 16))) + (set (reg:DI 6) (reg:DI 6)) + (clobber (reg:CC 17))])] + "optimize_size || !TARGET_ADD_ESP_8" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8))) + (set (reg:DI 6) (reg:DI 6))]) + (parallel [(set (match_dup 1) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])] + "") + +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16))) + (set (reg:DI 6) (reg:DI 6)) + (clobber (reg:CC 17))])] + "optimize_size" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8))) + (set (reg:DI 6) (reg:DI 6))]) + (parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])] + "") + +;; Convert esp additions to pop. +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8))) + (clobber (reg:CC 17))])] + "" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])] + "") + +;; 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 7) (plus:DI (reg:DI 7) (const_int 16))) + (clobber (reg:CC 17))])] + "" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))]) + (parallel [(set (match_dup 1) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])] + "") + +(define_peephole2 + [(match_scratch:DI 0 "r") + (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16))) + (clobber (reg:CC 17))])] + "optimize_size" + [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))]) + (parallel [(set (match_dup 0) (mem:DI (reg:DI 7))) + (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])] + "") + ;; Call-value patterns last so that the wildcard operand does not ;; disrupt insn-recog's switch tables. -- 2.30.2