From 8f7661f2b80a2bf7618e4436e416ef325ebae27e Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 1 Dec 1999 14:38:50 +0100 Subject: [PATCH] i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns rewrite splitters. * i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns rewrite splitters. From-SVN: r30740 --- gcc/ChangeLog | 3 + gcc/config/i386/i386.md | 250 ++++++++++++++++++++-------------------- 2 files changed, 130 insertions(+), 123 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b1cd260898..8f3c7e17f03 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,8 @@ Tue Nov 30 15:20:52 MET 1999 Jan Hubicka + * i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns, + rewrite splitters. + * i386.md (neg?f2_if): Split "r" and "f" to separate alternatives. (abs?f2_if): Likewise. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 99ba4ada803..562f08f29df 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2167,172 +2167,176 @@ ;; Zero extension instructions -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=r,?r") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm"))) - (clobber (reg:CC 17))] +(define_expand "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" - "* + " { - switch (get_attr_type (insn)) + if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) { - case TYPE_ALU1: - if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1])) - abort (); - operands[1] = GEN_INT (0xffff); - return \"and{l}\\t{%1, %0|%0, %1}\"; - default: - return \"movz{wl|x}\\t{%1, %0|%0, %1}\"; + operands[1] = force_reg (HImode, operands[1]); + emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); + DONE; } -}" - [(set (attr "type") - (if_then_else (and (eq_attr "alternative" "0") - (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND") - (const_int 0))) - (const_string "alu1") - (const_string "imovx")))]) +}") + +(define_insn "zero_extendhisi2_and" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) + (clobber (reg:CC 17))] + "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" + "#" + [(set_attr "type" "alu1")]) (define_split [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" ""))) + (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) (clobber (reg:CC 17))] - "reload_completed - && TARGET_ZERO_EXTEND_WITH_AND - && !reg_overlap_mentioned_p (operands[0], operands[1])" - [(parallel [(set (match_dup 0) (const_int 0)) - (clobber (reg:CC 17))]) - (set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "memory_operand" ""))) - (clobber (reg:CC 17))] - "reload_completed - && TARGET_ZERO_EXTEND_WITH_AND - && reg_overlap_mentioned_p (operands[0], operands[1])" - [(set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1)) - (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) + "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" + [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) (clobber (reg:CC 17))])] "") -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=q,r,r") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0,qm"))) - (clobber (reg:CC 17))] - "" - "* -{ - switch (get_attr_type (insn)) - { - case TYPE_ALU1: - if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1])) - abort (); - operands[1] = GEN_INT (0xff); - return \"and{l}\\t{%1, %k0|%k0, %1}\"; - default: - return \"movz{bw|x}\\t{%1, %0|%0, %1}\"; - } -}" - [(set (attr "type") - (cond [(and (eq_attr "alternative" "0") - (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND") - (const_int 0))) - (const_string "alu1") - (eq_attr "alternative" "1") - (const_string "alu1") - ] - (const_string "imovx")))]) +(define_insn "*zero_extendhisi2_movzwl" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] + "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" + "movz{wl|x}\\t{%1, %0|%0, %1}" + [(set_attr "type" "imovx")]) +(define_expand "zero_extendqihi2" + [(parallel + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) + (clobber (reg:CC 17))])] + "" + "") + +(define_insn "*zero_extendqihi2_and" + [(set (match_operand:HI 0 "register_operand" "=r,?&q") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) + (clobber (reg:CC 17))] + "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" + "#" + [(set_attr "type" "alu1")]) + +(define_insn "*zero_extendqihi2_movzbw_and" + [(set (match_operand:HI 0 "register_operand" "=r,r") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) + (clobber (reg:CC 17))] + "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" + "#" + [(set_attr "type" "imovx,alu1")]) + +(define_insn "*zero_extendqihi2_movzbw" + [(set (match_operand:HI 0 "register_operand" "=r") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" + "movz{bw|x}\\t{%1, %0|%0, %1}" + [(set_attr "type" "imovx")]) + +;; For the movzbw case strip only the clobber +(define_split + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) + (clobber (reg:CC 17))] + "reload_completed + && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) + && (!REG_P (operands[1]) || QI_REG_P (operands[1]))" + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) + +;; When source and destination does not overlap, clear destination +;; first and then do the movb (define_split [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) (clobber (reg:CC 17))] "reload_completed && QI_REG_P (operands[0]) - && TARGET_ZERO_EXTEND_WITH_AND + && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) && !reg_overlap_mentioned_p (operands[0], operands[1])" - [(parallel [(set (match_dup 0) (const_int 0)) - (clobber (reg:CC 17))]) - (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))] - "") - -(define_split - [(set (match_operand:HI 0 "register_operand" "") - (zero_extend:HI (match_operand:QI 1 "memory_operand" ""))) - (clobber (reg:CC 17))] - "reload_completed - && QI_REG_P (operands[0]) - && TARGET_ZERO_EXTEND_WITH_AND - && reg_overlap_mentioned_p (operands[0], operands[1])" - [(set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1)) - (parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) - (clobber (reg:CC 17))])] - "") + [(set (match_dup 0) (const_int 0)) + (set (strict_low_part (match_dup 2)) (match_dup 1))] + "operands[2] = gen_lowpart (QImode, operands[0]);") +;; Rest is handled by single and. (define_split [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) (clobber (reg:CC 17))] "reload_completed - && TARGET_ZERO_EXTEND_WITH_AND - && ! reg_overlap_mentioned_p (operands[0], operands[1])" - [(set (match_dup 0) (subreg:HI (match_dup 1) 0)) - (parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) + && true_regnum (operands[0]) == true_regnum (operands[1])" + [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) (clobber (reg:CC 17))])] "") -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=q,r,r") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,0,qm"))) - (clobber (reg:CC 17))] +(define_expand "zero_extendqisi2" + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) + (clobber (reg:CC 17))])] "" - "* -{ - switch (get_attr_type (insn)) - { - case TYPE_ALU1: - if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1])) - abort (); - operands[1] = GEN_INT (0xff); - return \"and{l}\\t{%1, %0|%0, %1}\"; - default: - return \"movz{bl|x}\\t{%1, %0|%0, %1}\"; - } -}" - [(set (attr "type") - (cond [(and (eq_attr "alternative" "0") - (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND") - (const_int 0))) - (const_string "alu1") - (eq_attr "alternative" "1") - (const_string "alu1") - ] - (const_string "imovx")))]) + "") +(define_insn "*zero_extendqisi2_and" + [(set (match_operand:SI 0 "register_operand" "=r,?&q") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) + (clobber (reg:CC 17))] + "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" + "#" + [(set_attr "type" "alu1")]) + +(define_insn "*zero_extendqisi2_movzbw_and" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) + (clobber (reg:CC 17))] + "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" + "#" + [(set_attr "type" "imovx,alu1")]) + +(define_insn "*zero_extendqisi2_movzbw" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" + "movz{bl|x}\\t{%1, %0|%0, %1}" + [(set_attr "type" "imovx")]) + +;; For the movzbl case strip only the clobber +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) + (clobber (reg:CC 17))] + "reload_completed + && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) + && (!REG_P (operands[1]) || QI_REG_P (operands[1]))" + [(set (match_dup 0) + (zero_extend:SI (match_dup 1)))]) + +;; When source and destination does not overlap, clear destination +;; first and then do the movb (define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) (clobber (reg:CC 17))] "reload_completed - && TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0]) - && (GET_CODE (operands[1]) == MEM || QI_REG_P (operands[1])) + && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) + && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) && !reg_overlap_mentioned_p (operands[0], operands[1])" - [(parallel [(set (match_dup 0) (const_int 0)) - (clobber (reg:CC 17))]) - (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))] - "") + [(set (match_dup 0) (const_int 0)) + (set (strict_low_part (match_dup 2)) (match_dup 1))] + "operands[2] = gen_lowpart (QImode, operands[0]);") +;; Rest is handled by single and. (define_split [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) (clobber (reg:CC 17))] "reload_completed - && TARGET_ZERO_EXTEND_WITH_AND - && ! reg_overlap_mentioned_p (operands[0], operands[1])" - [(set (match_dup 0) (subreg:SI (match_dup 1) 0)) - (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) + && true_regnum (operands[0]) == true_regnum (operands[1])" + [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) (clobber (reg:CC 17))])] "")