Another round. This merges the movmd/movsd related patterns. Their primary difference was normal vs advanced mode, so we can just use the P mode iterator and significantly reduce duplication here.
This also merges two of the btst patterns and fixes the pattern's condition. This also allows the btst to be used more aggressively on the H8/SX where we see minor improvements in the generated code. The tstXX patterns get merged. Sadly the way we use output modifiers to print different registers is painful -- the more natural way would be to define the modifier to print a register in the size of the operand. Instead we have a distinct modifier for each size. The port exploits the sub-word addressibility in various places. As a result we can't combine the output templates as much as I'd like. I'm pondering cleaning that up as well. There's a bit of merging of arithmetic patterns. What probably gets in the way most of the time is differing constraints or pattern conditions. The former are always a blocker. The latter we can sometimes work around (or as in the case of btst point to a minor goof). Some of the length computations are table driven and were getting in the way of merging patterns. So rather than have a separate attributes for addb, addw, addl length computation, we have a single attribute and select the right table based on the size of the operand. That's it until tonight... Jeff
* config/h8300/h8300.c (h8300_insn_length_from_table): Consolidate ADDB, ADDW and ADDL into a single ADD attribute which selects the right table based on the size of the operand. * config/h8300/h8300.md (length_table): Corresponding changes. All references to "addb", "addw" and "addl" changed to "add". (btst patterns): Merge two variants into a single pattern. (tstqi, tsthi): Likewise. (addhi3_incdec, addsi3_incdec): Likewise. (subhi3_h8300hs, subsi3_h8300hs): Likewise. (mulhi3, mulsi3): Likewise. (udivhi3, udivsi3): Likewise. (divhi3, divsi3): Likewise. (andorqi3, andorhi3, andorsi3): Likewise. diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 697041e..01c765d 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -2551,14 +2551,14 @@ h8300_insn_length_from_table (rtx_insn *insn, rtx * operands) case LENGTH_TABLE_NONE: gcc_unreachable (); - case LENGTH_TABLE_ADDB: - return h8300_binary_length (insn, &addb_length_table); - - case LENGTH_TABLE_ADDW: - return h8300_binary_length (insn, &addw_length_table); - - case LENGTH_TABLE_ADDL: - return h8300_binary_length (insn, &addl_length_table); + case LENGTH_TABLE_ADD: + if (GET_MODE (operands[0]) == QImode) + return h8300_binary_length (insn, &addb_length_table); + else if (GET_MODE (operands[0]) == HImode) + return h8300_binary_length (insn, &addw_length_table); + else if (GET_MODE (operands[0]) == SImode) + return h8300_binary_length (insn, &addl_length_table); + gcc_unreachable (); case LENGTH_TABLE_LOGICB: return h8300_binary_length (insn, &logicb_length_table); diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 6084240..e654784 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -77,7 +77,7 @@ (define_attr "type" "branch,arith,bitbranch,call" (const_string "arith")) -(define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch" +(define_attr "length_table" "none,add,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch" (const_string "none")) ;; The size of instructions in bytes. @@ -752,17 +752,6 @@ [(set_attr "length" "2,4") (set_attr "cc" "set_zn,set_zn")]) -(define_insn "" - [(set (cc0) - (compare (zero_extract:HI (match_operand:HI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 "const_int_operand" "n")) - (const_int 0)))] - "TARGET_H8300" - "btst %Z1,%Y0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - (define_insn_and_split "*tst_extzv_1_n" [(set (cc0) (compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>") @@ -790,11 +779,11 @@ (define_insn "" [(set (cc0) - (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 "const_int_operand" "n")) + (compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r") + (const_int 1) + (match_operand 1 "const_int_operand" "n")) (const_int 0)))] - "(TARGET_H8300H || TARGET_H8300S) + "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) <= 15" "btst %Z1,%Y0" [(set_attr "length" "2") @@ -865,21 +854,18 @@ [(set_attr "length" "2,8,10") (set_attr "cc" "set_zn,set_zn,set_zn")]) -(define_insn "*tstqi" - [(set (cc0) - (compare (match_operand:QI 0 "register_operand" "r") - (const_int 0)))] - "" - "mov.b %X0,%X0" - [(set_attr "length" "2") - (set_attr "cc" "set_znv")]) - -(define_insn "*tsthi" +(define_insn "*tst<mode>" [(set (cc0) - (compare (match_operand:HI 0 "register_operand" "r") + (compare (match_operand:QHI 0 "register_operand" "r") (const_int 0)))] "" - "mov.w %T0,%T0" + { + if (<MODE>mode == QImode) + return "mov.b %X0,%X0"; + else if (<MODE>mode == HImode) + return "mov.w %T0,%T0"; + gcc_unreachable (); + } [(set_attr "length" "2") (set_attr "cc" "set_znv")]) @@ -918,7 +904,7 @@ (match_operand:QI 1 "h8300_src_operand" "rQi")))] "" "cmp.b %X1,%X0" - [(set_attr "length_table" "addb") + [(set_attr "length_table" "add") (set_attr "cc" "compare")]) (define_insn "*cmphi_h8300_znvc" @@ -949,7 +935,7 @@ gcc_unreachable (); } } - [(set_attr "length_table" "short_immediate,addw") + [(set_attr "length_table" "short_immediate,add") (set_attr "cc" "compare,compare")]) (define_insn "cmpsi" @@ -972,7 +958,7 @@ } } [(set_attr "length" "2,*") - (set_attr "length_table" "*,addl") + (set_attr "length_table" "*,add") (set_attr "cc" "compare,compare")]) ;; ---------------------------------------------------------------------- @@ -992,7 +978,7 @@ (match_operand:QI 2 "h8300_src_operand" "rQi")))] "h8300_operands_match_p (operands)" "add.b %X2,%X0" - [(set_attr "length_table" "addb") + [(set_attr "length_table" "add") (set_attr "cc" "set_zn")]) (define_insn "*addhi3_h8300" @@ -1055,15 +1041,19 @@ [(set_attr "length" "2,2,2,4,2") (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")]) -(define_insn "*addhi3_incdec" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (unspec:HI [(match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "incdec_operand" "M,O")] - UNSPEC_INCDEC))] +(define_insn "*add<mode>3_incdec" + [(set (match_operand:HSI 0 "register_operand" "=r,r") + (unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0") + (match_operand:HSI 2 "incdec_operand" "M,O")] + UNSPEC_INCDEC))] "TARGET_H8300H || TARGET_H8300S" - "@ - inc.w %2,%T0 - dec.w %G2,%T0" + { + if (which_alternative == 0) + return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0"; + else if (which_alternative == 1) + return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0"; + gcc_unreachable (); + } [(set_attr "length" "2,2") (set_attr "cc" "set_zn,set_zn")]) @@ -1077,7 +1067,7 @@ sub.w %G2:3,%T0 add.b %t2,%t0 add.w %T2,%T0" - [(set_attr "length_table" "short_immediate,short_immediate,*,addw") + [(set_attr "length_table" "short_immediate,short_immediate,*,add") (set_attr "length" "*,*,2,*") (set_attr "cc" "set_zn")]) @@ -1119,18 +1109,6 @@ (set (attr "cc") (symbol_ref "compute_plussi_cc (operands)"))]) -(define_insn "*addsi3_incdec" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (unspec:SI [(match_operand:SI 1 "register_operand" "0,0") - (match_operand:SI 2 "incdec_operand" "M,O")] - UNSPEC_INCDEC))] - "TARGET_H8300H || TARGET_H8300S" - "@ - inc.l %2,%S0 - dec.l %G2,%S0" - [(set_attr "length" "2,2") - (set_attr "cc" "set_zn,set_zn")]) - (define_split [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_dup 0) @@ -1162,7 +1140,7 @@ (match_operand:QI 2 "h8300_dst_operand" "rQ")))] "h8300_operands_match_p (operands)" "sub.b %X2,%X0" - [(set_attr "length_table" "addb") + [(set_attr "length_table" "add") (set_attr "cc" "set_zn")]) (define_insn "*subhi3_h8300" @@ -1176,15 +1154,19 @@ [(set_attr "length" "2,4") (set_attr "cc" "set_zn,clobber")]) -(define_insn "*subhi3_h8300hs" - [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ,rQ") - (minus:HI (match_operand:HI 1 "h8300_dst_operand" "0,0") - (match_operand:HI 2 "h8300_src_operand" "rQ,i")))] +(define_insn "*sub<mode>3_h8300hs" + [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ") + (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0") + (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))] "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)" - "@ - sub.w %T2,%T0 - sub.w %T2,%T0" - [(set_attr "length_table" "addw") + { + if (<MODE>mode == HImode) + return "sub.w %T2,%T0"; + else if (<MODE>mode == SImode) + return "sub.l %S2,%S0"; + gcc_unreachable (); + } + [(set_attr "length_table" "add") (set_attr "cc" "set_zn")]) (define_insn "*subsi3_h8300" @@ -1195,16 +1177,6 @@ "sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0" [(set_attr "length" "6")]) -(define_insn "*subsi3_h8300hs" - [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ") - (minus:SI (match_operand:SI 1 "h8300_dst_operand" "0,0") - (match_operand:SI 2 "h8300_src_operand" "rQ,i")))] - "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)" - "@ - sub.l %S2,%S0 - sub.l %S2,%S0" - [(set_attr "length_table" "addl") - (set_attr "cc" "set_zn")]) ;; ---------------------------------------------------------------------- ;; MULTIPLY INSTRUCTIONS @@ -1332,21 +1304,12 @@ ;; on a H8SX with a multiplier, whereas muls.w seems to be available ;; on all H8SX variants. -(define_insn "mulhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (mult:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))] +(define_insn "mul<mode>3" + [(set (match_operand:HSI 0 "register_operand" "=r") + (mult:HSI (match_operand:HSI 1 "register_operand" "%0") + (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))] "TARGET_H8300SX" - "muls.w\\t%T2,%T0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "mulsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))] - "TARGET_H8300SX" - "muls.l\\t%S2,%S0" + { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; } [(set_attr "length" "2") (set_attr "cc" "set_zn")]) @@ -1413,36 +1376,20 @@ ;; DIVIDE/MOD INSTRUCTIONS ;; ---------------------------------------------------------------------- -(define_insn "udivhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (udiv:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))] +(define_insn "udiv<mode>3" + [(set (match_operand:HSI 0 "register_operand" "=r") + (udiv:HSI (match_operand:HSI 1 "register_operand" "0") + (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))] "TARGET_H8300SX" - "divu.w\\t%T2,%T0" + { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; } [(set_attr "length" "2")]) -(define_insn "divhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (div:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))] +(define_insn "div<mode>3" + [(set (match_operand:HSI 0 "register_operand" "=r") + (div:HSI (match_operand:HSI 1 "register_operand" "0") + (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))] "TARGET_H8300SX" - "divs.w\\t%T2,%T0" - [(set_attr "length" "2")]) - -(define_insn "udivsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (udiv:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))] - "TARGET_H8300SX" - "divu.l\\t%S2,%S0" - [(set_attr "length" "2")]) - -(define_insn "divsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (div:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))] - "TARGET_H8300SX" - "divs.l\\t%S2,%S0" + { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; } [(set_attr "length" "2")]) (define_insn "udivmodqi4" @@ -1599,47 +1546,44 @@ "" "") -(define_insn "*andorqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r") - (match_operand:QI 3 "single_one_operand" "n")) - (match_operand:QI 1 "register_operand" "0")))] - "" - "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0" - [(set_attr "length" "6")]) +(define_insn "*andor<mode>3" + [(set (match_operand:QHSI 0 "register_operand" "=r") + (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r") + (match_operand:QHSI 3 "single_one_operand" "n")) + (match_operand:QHSI 1 "register_operand" "0")))] + "(<MODE>mode == QImode + || <MODE>mode == HImode + || (<MODE>mode == SImode + && (INTVAL (operands[3]) & 0xffff) != 0))" + { + if (<MODE>mode == QImode) + return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"; -(define_insn "*andorhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r") - (match_operand:HI 3 "single_one_operand" "n")) - (match_operand:HI 1 "register_operand" "0")))] - "" -{ - operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); - if (INTVAL (operands[3]) > 128) - { - operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); - return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0"; - } - return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0"; -} - [(set_attr "length" "6")]) + if (<MODE>mode == HImode) + { + operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); + if (INTVAL (operands[3]) > 128) + { + operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); + return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0"; + } + return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0"; + } -(define_insn "*andorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "single_one_operand" "n")) - (match_operand:SI 1 "register_operand" "0")))] - "(INTVAL (operands[3]) & 0xffff) != 0" -{ - operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); - if (INTVAL (operands[3]) > 128) - { - operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); - return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0"; - } - return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0"; -} + if (<MODE>mode == SImode) + { + operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); + if (INTVAL (operands[3]) > 128) + { + operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); + return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0"; + } + return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0"; + } + + gcc_unreachable (); + + } [(set_attr "length" "6")]) (define_insn "*andorsi3_shift_8"