diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-11 23:54:11 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-11 23:54:11 +0000 |
commit | 0edc2b1cc887e4e3e9cdd3d45512e553d0ed4d84 (patch) | |
tree | a4a10ad41eb4009a3a451fc4518e9f29cc1010ab | |
parent | c6322c9a3ef07e3a3073e64c3edc4990419b346f (diff) | |
download | gcc-0edc2b1cc887e4e3e9cdd3d45512e553d0ed4d84.tar.gz |
* i386.md (add?i_3, add?i_5): New.
(add?i_4): Rename from add?i_3; Fix compare pattern.
(sub?i_3, xor?i_3, ior?i_3): New.
* genrecog.c (write_tree): Output code to clear insn_extract cache.
* genattrtab.c (write_attr_case): Gen call to extract_insn_cache
instead of extract_insn and extract_constrain_insn_cache instead of
extract_insn and constrain_operands.
* recog.c (extract_insn_cached, extract_constrain_insn_cached):
New functions.
(extract_insn): Clear which_alternative.
(constrain_operands): Set which_alternative to -1 when failed.
* recog.h (extract_constrain_insn_cached, extract_insn_cached):
Declare.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36342 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 281 | ||||
-rw-r--r-- | gcc/genattrtab.c | 11 | ||||
-rw-r--r-- | gcc/genrecog.c | 3 | ||||
-rw-r--r-- | gcc/recog.c | 28 | ||||
-rw-r--r-- | gcc/recog.h | 5 |
6 files changed, 329 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57693f69425..7643df0a864 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +Tue Sep 12 01:51:38 MET DST 2000 Jan Hubicka <jh@suse.cz> + + * i386.md (add?i_3, add?i_5): New. + (add?i_4): Rename from add?i_3; Fix compare pattern. + (sub?i_3, xor?i_3, ior?i_3): New. + + * genrecog.c (write_tree): Output code to clear insn_extract cache. + * genattrtab.c (write_attr_case): Gen call to extract_insn_cache + instead of extract_insn and extract_constrain_insn_cache instead of + extract_insn and constrain_operands. + * recog.c (extract_insn_cached, extract_constrain_insn_cached): + New functions. + (extract_insn): Clear which_alternative. + (constrain_operands): Set which_alternative to -1 when failed. + * recog.h (extract_constrain_insn_cached, extract_insn_cached): + Declare. + 2000-09-11 Matthew Hiller <hiller@redhat.com> * config/h8300/h8300.md (movstrictqi): Changed constraint modifier diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 51386bc0114..6e8022f6f44 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3997,10 +3997,55 @@ (set_attr "mode" "SI")]) (define_insn "*addsi_3" + [(set (reg 17) + (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) + (match_operand:SI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:SI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) + /* Current assemblers are broken and do not allow @GOTOFF in + ought but a memory context. */ + && ! pic_symbolic_operand (operands[2], VOIDmode)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (! rtx_equal_p (operands[0], operands[1])) + abort (); + if (operands[2] == const1_rtx) + return \"inc{l}\\t%0\"; + else if (operands[2] == constm1_rtx) + return \"dec{l}\\t%0\"; + else + abort(); + + default: + if (! rtx_equal_p (operands[0], operands[1])) + abort (); + /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. + Exceptions: -128 encodes smaller than 128, so swap sign and op. */ + if (GET_CODE (operands[2]) == CONST_INT + && (INTVAL (operands[2]) == 128 + || (INTVAL (operands[2]) < 0 + && INTVAL (operands[2]) != -128))) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + return \"sub{l}\\t{%2, %0|%0, %2}\"; + } + return \"add{l}\\t{%2, %0|%0, %2}\"; + } +}" + [(set (attr "type") + (if_then_else (match_operand:SI 2 "incdec_operand" "") + (const_string "incdec") + (const_string "alu"))) + (set_attr "mode" "SI")]) + +(define_insn "*addsi_4" [(set (reg:CC 17) - (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") - (match_operand:SI 2 "general_operand" "rmni,rni")) - (const_int 0))) + (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni,rni")) + (match_operand:SI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") (plus:SI (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, SImode, operands) @@ -4011,6 +4056,19 @@ [(set_attr "type" "alu") (set_attr "mode" "SI")]) +(define_insn "*addsi_5" + [(set (reg:CC 17) + (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni")) + (match_operand:SI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:SI 0 "=r"))] + "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) + /* Current assemblers are broken and do not allow @GOTOFF in + ought but a memory context. */ + && ! pic_symbolic_operand (operands[2], VOIDmode)" + "add{l}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "SI")]) + (define_expand "addhi3" [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -4151,10 +4209,49 @@ (set_attr "mode" "HI")]) (define_insn "*addhi_3" + [(set (reg 17) + (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) + (match_operand:HI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:HI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (operands[2] == const1_rtx) + return \"inc{w}\\t%0\"; + else if (operands[2] == constm1_rtx + || (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 65535)) + return \"dec{w}\\t%0\"; + abort(); + + default: + /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. + Exceptions: -128 encodes smaller than 128, so swap sign and op. */ + if (GET_CODE (operands[2]) == CONST_INT + && (INTVAL (operands[2]) == 128 + || (INTVAL (operands[2]) < 0 + && INTVAL (operands[2]) != -128))) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + 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 "mode" "HI")]) + +(define_insn "*addhi_4" [(set (reg:CC 17) - (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "rmni,rni")) - (const_int 0))) + (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni,rni")) + (match_operand:HI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") (plus:HI (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, HImode, operands)" @@ -4162,6 +4259,16 @@ [(set_attr "type" "alu") (set_attr "mode" "HI")]) +(define_insn "*addhi_5" + [(set (reg:CC 17) + (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni")) + (match_operand:HI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:HI 0 "=r"))] + "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "add{w}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "HI")]) + (define_expand "addqi3" [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") @@ -4310,10 +4417,46 @@ (set_attr "mode" "QI")]) (define_insn "*addqi_3" + [(set (reg 17) + (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) + (match_operand:QI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:QI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "* +{ + switch (get_attr_type (insn)) + { + case TYPE_INCDEC: + if (operands[2] == const1_rtx) + return \"inc{b}\\t%0\"; + else if (operands[2] == constm1_rtx + || (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 255)) + return \"dec{b}\\t%0\"; + abort(); + + default: + /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ + if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) < 0) + { + operands[2] = GEN_INT (-INTVAL (operands[2])); + return \"sub{b}\\t{%2, %0|%0, %2}\"; + } + 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 "mode" "QI")]) + +(define_insn "*addqi_4" [(set (reg:CC 17) - (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qmni,qni")) - (const_int 0))) + (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni,qni")) + (match_operand:QI 1 "nonimmediate_operand" "%0,0"))) (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") (plus:QI (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, QImode, operands)" @@ -4321,6 +4464,16 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) +(define_insn "*addqi_5" + [(set (reg:CC 17) + (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni")) + (match_operand:QI 1 "nonimmediate_operand" "%0"))) + (clobber (match_scratch:QI 0 "=r"))] + "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "add{b}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_insn "addqi_ext_1" [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") @@ -4478,6 +4631,18 @@ (const_int 0))) (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") (minus:SI (match_dup 1) (match_dup 2)))] + "ix86_match_ccmode (insn, CCNOmode) + && ix86_binary_operator_ok (MINUS, SImode, operands)" + "sub{l}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "SI")]) + +(define_insn "*subsi_3" + [(set (reg 17) + (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") + (match_operand:SI 2 "general_operand" "ri,rm"))) + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (minus:SI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\\t{%2, %0|%0, %2}" @@ -4510,6 +4675,18 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") (minus:HI (match_dup 1) (match_dup 2)))] + "ix86_match_ccmode (insn, CCNOmode) + && ix86_binary_operator_ok (MINUS, HImode, operands)" + "sub{w}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "HI")]) + +(define_insn "*subhi_3" + [(set (reg 17) + (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") + (match_operand:HI 2 "general_operand" "ri,rm"))) + (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (minus:HI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) && ix86_binary_operator_ok (MINUS, HImode, operands)" "sub{w}\\t{%2, %0|%0, %2}" @@ -4542,6 +4719,18 @@ (const_int 0))) (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") (minus:HI (match_dup 1) (match_dup 2)))] + "ix86_match_ccmode (insn, CCNOmode) + && ix86_binary_operator_ok (MINUS, QImode, operands)" + "sub{b}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "QI")]) + +(define_insn "*subqi_3" + [(set (reg 17) + (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") + (match_operand:QI 2 "general_operand" "qi,qm"))) + (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") + (minus:HI (match_dup 1) (match_dup 2)))] "ix86_match_ccmode (insn, CCmode) && ix86_binary_operator_ok (MINUS, QImode, operands)" "sub{b}\\t{%2, %0|%0, %2}" @@ -5491,6 +5680,18 @@ [(set_attr "type" "alu") (set_attr "mode" "SI")]) +(define_insn "*iorsi_3" + [(set (reg 17) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") + (match_operand:SI 2 "general_operand" "rim")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "or{l}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "SI")]) + (define_expand "iorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -5522,6 +5723,18 @@ [(set_attr "type" "alu") (set_attr "mode" "HI")]) +(define_insn "*iorhi_3" + [(set (reg 17) + (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") + (match_operand:HI 2 "general_operand" "rim")) + (const_int 0))) + (clobber (match_scratch:HI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "or{w}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "HI")]) + (define_expand "iorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") @@ -5556,6 +5769,19 @@ "or{b}\\t{%2, %0|%0, %2}" [(set_attr "type" "alu") (set_attr "mode" "QI")]) + +(define_insn "*iorqi_3" + [(set (reg 17) + (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") + (match_operand:QI 2 "general_operand" "qim")) + (const_int 0))) + (clobber (match_scratch:QI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "or{b}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "QI")]) + ;; Logical XOR instructions @@ -5593,6 +5819,18 @@ [(set_attr "type" "alu") (set_attr "mode" "SI")]) +(define_insn "*xorsi_3" + [(set (reg 17) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") + (match_operand:SI 2 "general_operand" "rim")) + (const_int 0))) + (clobber (match_scratch:SI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "xor{l}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "SI")]) + (define_expand "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "") (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") @@ -5624,6 +5862,18 @@ [(set_attr "type" "alu") (set_attr "mode" "HI")]) +(define_insn "*xorhi_3" + [(set (reg 17) + (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") + (match_operand:HI 2 "general_operand" "rim")) + (const_int 0))) + (clobber (match_scratch:HI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "xor{w}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "HI")]) + (define_expand "xorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "") (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") @@ -5678,6 +5928,19 @@ [(set_attr "type" "alu") (set_attr "mode" "QI")]) +(define_insn "*xorqi_cc_2" + [(set (reg 17) + (compare + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") + (match_operand:QI 2 "general_operand" "qim")) + (const_int 0))) + (clobber (match_scratch:QI 0 "=r"))] + "ix86_match_ccmode (insn, CCNOmode) + && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" + "xor{b}\\t{%2, %0|%0, %2}" + [(set_attr "type" "alu") + (set_attr "mode" "QI")]) + (define_insn "xorqi_cc_ext_1" [(set (reg:CCNO 17) (compare:CCNO diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index a6a9a9010ea..c8cd1933d66 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -5212,18 +5212,15 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, must_extract = must_constrain = address_used = 0; walk_attr_value (av->value); - if (must_extract) + if (must_constrain) { write_indent (indent + 2); - printf ("extract_insn (insn);\n"); + printf ("extract_constrain_insn_cached (insn);\n"); } - - if (must_constrain) + else if (must_extract) { write_indent (indent + 2); - printf ("if (! constrain_operands (reload_completed))\n"); - write_indent (indent + 2); - printf (" fatal_insn_not_found (insn);\n"); + printf ("extract_insn_cached (insn);\n"); } write_attr_set (attr, indent + 2, av->value, prefix, suffix, diff --git a/gcc/genrecog.c b/gcc/genrecog.c index e506f8d85b6..b512181e10d 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -2189,6 +2189,9 @@ peephole2%s (x0, insn, _pmatch_len)\n\ printf (" %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int"); + if (!subfunction) + printf (" recog_data.insn = NULL_RTX;\n"); + if (head->first) write_tree (head, "", type, 1); else diff --git a/gcc/recog.c b/gcc/recog.c index 87f8137f302..f1d5dee6c46 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2045,6 +2045,31 @@ adj_offsettable_operand (op, offset) abort (); } +/* Like extract_insn, but save insn extracted and don't extract again, when + called again for the same insn expecting that recog_data still contain the + valid information. This is used primary by gen_attr infrastructure that + often does extract insn again and again. */ +void +extract_insn_cached (insn) + rtx insn; +{ + if (recog_data.insn == insn && INSN_CODE (insn) >= 0) + return; + extract_insn (insn); + recog_data.insn = insn; +} +/* Do cached extract_insn, constrain_operand and complain about failures. + Used by insn_attrtab. */ +void +extract_constrain_insn_cached (insn) + rtx insn; +{ + extract_insn_cached (insn); + if (which_alternative == -1 + && !constrain_operands (reload_completed)) + fatal_insn_not_found (insn); +} + /* Analyze INSN and fill in recog_data. */ void @@ -2056,9 +2081,11 @@ extract_insn (insn) int noperands; rtx body = PATTERN (insn); + recog_data.insn = NULL; recog_data.n_operands = 0; recog_data.n_alternatives = 0; recog_data.n_dups = 0; + which_alternative = -1; switch (GET_CODE (body)) { @@ -2592,6 +2619,7 @@ constrain_operands (strict) which_alternative++; } + which_alternative = -1; /* If we are about to reject this, but we are not to test strictly, try a very loose test. Only return failure if it fails also. */ if (strict == 0) diff --git a/gcc/recog.h b/gcc/recog.h index d4fd4fd6934..3328af6850a 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -116,6 +116,8 @@ extern int recog PARAMS ((rtx, rtx, int *)); extern void add_clobbers PARAMS ((rtx, int)); extern void insn_extract PARAMS ((rtx)); extern void extract_insn PARAMS ((rtx)); +extern void extract_constrain_insn_cached PARAMS ((rtx)); +extern void extract_insn_cached PARAMS ((rtx)); extern void preprocess_constraints PARAMS ((void)); extern rtx peep2_next_insn PARAMS ((int)); extern int peep2_regno_dead_p PARAMS ((int, int)); @@ -186,6 +188,9 @@ struct recog_data /* The number of alternatives in the constraints for the insn. */ char n_alternatives; + + /* In case we are caching, hold insn data was generated for. */ + rtx insn; }; extern struct recog_data recog_data; |