head 1.2; access; symbols pkgsrc-2014Q3:1.1.0.100 pkgsrc-2014Q3-base:1.1 pkgsrc-2014Q2:1.1.0.98 pkgsrc-2014Q2-base:1.1 pkgsrc-2014Q1:1.1.0.96 pkgsrc-2014Q1-base:1.1 pkgsrc-2013Q4:1.1.0.94 pkgsrc-2013Q4-base:1.1 pkgsrc-2013Q3:1.1.0.92 pkgsrc-2013Q3-base:1.1 pkgsrc-2013Q2:1.1.0.90 pkgsrc-2013Q2-base:1.1 pkgsrc-2013Q1:1.1.0.88 pkgsrc-2013Q1-base:1.1 pkgsrc-2012Q4:1.1.0.86 pkgsrc-2012Q4-base:1.1 pkgsrc-2012Q3:1.1.0.84 pkgsrc-2012Q3-base:1.1 pkgsrc-2012Q2:1.1.0.82 pkgsrc-2012Q2-base:1.1 pkgsrc-2012Q1:1.1.0.80 pkgsrc-2012Q1-base:1.1 pkgsrc-2011Q4:1.1.0.78 pkgsrc-2011Q4-base:1.1 pkgsrc-2011Q3:1.1.0.76 pkgsrc-2011Q3-base:1.1 pkgsrc-2011Q2:1.1.0.74 pkgsrc-2011Q2-base:1.1 pkgsrc-2011Q1:1.1.0.72 pkgsrc-2011Q1-base:1.1 pkgsrc-2010Q4:1.1.0.70 pkgsrc-2010Q4-base:1.1 pkgsrc-2010Q3:1.1.0.68 pkgsrc-2010Q3-base:1.1 pkgsrc-2010Q2:1.1.0.66 pkgsrc-2010Q2-base:1.1 pkgsrc-2010Q1:1.1.0.64 pkgsrc-2010Q1-base:1.1 pkgsrc-2009Q4:1.1.0.62 pkgsrc-2009Q4-base:1.1 pkgsrc-2009Q3:1.1.0.60 pkgsrc-2009Q3-base:1.1 pkgsrc-2009Q2:1.1.0.58 pkgsrc-2009Q2-base:1.1 pkgsrc-2009Q1:1.1.0.56 pkgsrc-2009Q1-base:1.1 pkgsrc-2008Q4:1.1.0.54 pkgsrc-2008Q4-base:1.1 pkgsrc-2008Q3:1.1.0.52 pkgsrc-2008Q3-base:1.1 cube-native-xorg:1.1.0.50 cube-native-xorg-base:1.1 pkgsrc-2008Q2:1.1.0.48 pkgsrc-2008Q2-base:1.1 cwrapper:1.1.0.46 pkgsrc-2008Q1:1.1.0.44 pkgsrc-2008Q1-base:1.1 pkgsrc-2007Q4:1.1.0.42 pkgsrc-2007Q4-base:1.1 pkgsrc-2007Q3:1.1.0.40 pkgsrc-2007Q3-base:1.1 pkgsrc-2007Q2:1.1.0.38 pkgsrc-2007Q2-base:1.1 pkgsrc-2007Q1:1.1.0.36 pkgsrc-2007Q1-base:1.1 pkgsrc-2006Q4:1.1.0.34 pkgsrc-2006Q4-base:1.1 pkgsrc-2006Q3:1.1.0.32 pkgsrc-2006Q3-base:1.1 pkgsrc-2006Q2:1.1.0.30 pkgsrc-2006Q2-base:1.1 pkgsrc-2006Q1:1.1.0.28 pkgsrc-2006Q1-base:1.1 pkgsrc-2005Q4:1.1.0.26 pkgsrc-2005Q4-base:1.1 pkgsrc-2005Q3:1.1.0.24 pkgsrc-2005Q3-base:1.1 pkgsrc-2005Q2:1.1.0.22 pkgsrc-2005Q2-base:1.1 pkgsrc-2005Q1:1.1.0.20 pkgsrc-2005Q1-base:1.1 pkgsrc-2004Q4:1.1.0.18 pkgsrc-2004Q4-base:1.1 pkgsrc-2004Q3:1.1.0.16 pkgsrc-2004Q3-base:1.1 pkgsrc-2004Q2:1.1.0.14 pkgsrc-2004Q2-base:1.1 pkgsrc-2004Q1:1.1.0.12 pkgsrc-2004Q1-base:1.1 pkgsrc-2003Q4:1.1.0.10 pkgsrc-2003Q4-base:1.1 netbsd-1-6-1:1.1.0.6 netbsd-1-6-1-base:1.1 netbsd-1-6:1.1.0.8 netbsd-1-6-RELEASE-base:1.1 pkgviews:1.1.0.4 pkgviews-base:1.1 buildlink2:1.1.0.2 buildlink2-base:1.1 netbsd-1-5-PATCH003:1.1 netbsd-1-5-PATCH001:1.1; locks; strict; comment @# @; 1.2 date 2014.12.12.13.30.07; author joerg; state dead; branches; next 1.1; commitid zlrZJyUWaD8nOK1y; 1.1 date 2001.01.22.21.04.12; author msaitoh; state Exp; branches; next ; desc @@ 1.2 log @Remove cross/COMMON, nothing seems to use it and it hasn't t been changed in a decade. @ text @--- gcc/config/sh/sh.c.orig Wed Feb 24 10:44:34 1999 +++ gcc/config/sh/sh.c Mon Jan 22 21:09:51 2001 @@@@ -22,6 +22,8 @@@@ Improved by Jim Wilson (wilson@@cygnus.com). */ #include "config.h" +#include "system.h" +#include "insn-config.h" #include @@@@ -29,11 +31,15 @@@@ #include "tree.h" #include "flags.h" #include "insn-flags.h" +#include "except.h" #include "expr.h" +#include "function.h" #include "regs.h" #include "hard-reg-set.h" #include "output.h" #include "insn-attr.h" +#include "toplev.h" +#include "recog.h" int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch; @@@@ -131,7 +137,8 @@@@ switch (GET_CODE (x)) { case REG: - fprintf (stream, "@@%s", reg_names[REGNO (x)]); + case SUBREG: + fprintf (stream, "@@%s", reg_names[true_regnum (x)]); break; case PLUS: @@@@ -143,13 +150,19 @@@@ { case CONST_INT: fprintf (stream, "@@(%d,%s)", INTVAL (index), - reg_names[REGNO (base)]); + reg_names[true_regnum (base)]); break; case REG: - fprintf (stream, "@@(r0,%s)", - reg_names[MAX (REGNO (base), REGNO (index))]); + case SUBREG: + { + int base_num = true_regnum (base); + int index_num = true_regnum (index); + + fprintf (stream, "@@(r0,%s)", + reg_names[MAX (base_num,index_num)]); break; + } default: debug_rtx (x); @@@@ -159,11 +172,11 @@@@ break; case PRE_DEC: - fprintf (stream, "@@-%s", reg_names[REGNO (XEXP (x, 0))]); + fprintf (stream, "@@-%s", reg_names[true_regnum (XEXP (x, 0))]); break; case POST_INC: - fprintf (stream, "@@%s+", reg_names[REGNO (XEXP (x, 0))]); + fprintf (stream, "@@%s+", reg_names[true_regnum (XEXP (x, 0))]); break; default: @@@@ -230,16 +243,31 @@@@ fputs (reg_names[REGNO (x) + 1], (stream)); break; case MEM: - print_operand_address (stream, - XEXP (adj_offsettable_operand (x, 4), 0)); + if (GET_CODE (XEXP (x, 0)) != PRE_DEC + && GET_CODE (XEXP (x, 0)) != POST_INC) + x = adj_offsettable_operand (x, 4); + print_operand_address (stream, XEXP (x, 0)); break; } break; + case 'o': + switch (GET_CODE (x)) + { + case PLUS: fputs ("add", stream); break; + case MINUS: fputs ("sub", stream); break; + case MULT: fputs ("mul", stream); break; + case DIV: fputs ("div", stream); break; + } + break; default: switch (GET_CODE (x)) { case REG: - fputs (reg_names[REGNO (x)], (stream)); + if (REGNO (x) >= FIRST_FP_REG && REGNO (x) <= LAST_FP_REG + && GET_MODE_SIZE (GET_MODE (x)) > 4) + fprintf ((stream), "d%s", reg_names[REGNO (x)]+1); + else + fputs (reg_names[REGNO (x)], (stream)); break; case MEM: output_address (XEXP (x, 0)); @@@@ -402,6 +430,7 @@@@ if ((code != EQ && code != NE && (sh_compare_op1 != const0_rtx || code == GTU || code == GEU || code == LTU || code == LEU)) + || (mode == DImode && sh_compare_op1 != const0_rtx) || TARGET_SH3E && GET_MODE_CLASS (mode) == MODE_FLOAT) sh_compare_op1 = force_reg (mode, sh_compare_op1); @@@@ -694,9 +723,9 @@@@ char * output_ieee_ccmpeq (insn, operands) - rtx insn, operands; + rtx insn, *operands; { - output_branchy_insn (NE, "bt\t%l9\\;fcmp/eq\t%1,%0", insn, operands); + return output_branchy_insn (NE, "bt\t%l9\\;fcmp/eq\t%1,%0", insn, operands); } /* Output to FILE the start of the assembler file. */ @@@@ -1602,8 +1631,16 @@@@ case 5: { int i = 16 - size; - emit_insn (gen_shl_sext_ext (dest, source, GEN_INT (16 - insize), - GEN_INT (16))); + if (! rtx_equal_function_value_matters + && ! reload_in_progress && ! reload_completed) + emit_insn (gen_shl_sext_ext (dest, source, left_rtx, size_rtx)); + else + { + operands[0] = dest; + operands[2] = GEN_INT (16 - insize); + gen_shifty_hi_op (ASHIFT, operands); + emit_insn (gen_extendhisi2 (dest, gen_lowpart (HImode, dest))); + } /* Don't use gen_ashrsi3 because it generates new pseudos. */ while (--i >= 0) gen_ashift (ASHIFTRT, 1, dest); @@@@ -2124,7 +2161,7 @@@@ for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--) { part = XVECEXP (pattern, 0, i); - if (part == reg_part) + if (part == reg_part || GET_CODE (part) == CLOBBER) continue; if (reg_mentioned_p (reg, ((GET_CODE (part) == SET && GET_CODE (SET_DEST (part)) == REG) @@@@ -2464,6 +2501,13 @@@@ } else jump = emit_jump_insn_after (gen_return (), insn); + /* Emit a barrier so that reorg knows that any following instructions + are not reachable via a fall-through path. + But don't do this when not optimizing, since we wouldn't supress the + alignment for the barrier then, and could end up with out-of-range + pc-relative loads. */ + if (optimize) + emit_barrier_after (jump); emit_label_after (bp->near_label, insn); JUMP_LABEL (jump) = bp->far_label; if (! invert_jump (insn, label)) @@@@ -2481,7 +2525,7 @@@@ for (insn = first; insn; insn = NEXT_INSN (insn)) { - rtx vec_lab, pat, prev, prevpat, x; + rtx vec_lab, pat, prev, prevpat, x, braf_label; if (GET_CODE (insn) != JUMP_INSN || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC) @@@@ -2504,10 +2548,15 @@@@ if (GET_CODE (x) == LABEL_REF && XEXP (x, 0) == vec_lab) break; } + + /* Emit the reference label of the braf where it belongs, right after + the casesi_jump_2 (i.e. braf). */ + braf_label = XEXP (XEXP (SET_SRC (XVECEXP (prevpat, 0, 0)), 1), 0); + emit_label_after (braf_label, prev); + /* Fix up the ADDR_DIF_VEC to be relative to the reference address of the braf. */ - XEXP (XEXP (pat, 0), 0) - = XEXP (XEXP (SET_SRC (XVECEXP (prevpat, 0, 0)), 1), 0); + XEXP (XEXP (pat, 0), 0) = braf_label; } } --- gcc/config/sh/sh.h.orig Mon Jun 1 23:25:44 1998 +++ gcc/config/sh/sh.h Mon Jan 22 21:09:51 2001 @@@@ -1143,7 +1143,8 @@@@ else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \ && BASE_REGISTER_RTX_P (XEXP ((X), 0))) \ goto LABEL; \ - else if (GET_CODE (X) == PLUS && MODE != PSImode) \ + else if (GET_CODE (X) == PLUS \ + && ((MODE) != PSImode || reload_completed)) \ { \ rtx xop0 = XEXP ((X), 0); \ rtx xop1 = XEXP ((X), 1); \ @@@@ -1465,7 +1466,7 @@@@ and another. */ #define REGISTER_MOVE_COST(SRCCLASS, DSTCLASS) \ - ((DSTCLASS) == PR_REG ? 10 \ + ((DSTCLASS) == PR_REGS ? 10 \ : (((DSTCLASS) == FP_REGS && (SRCCLASS) == GENERAL_REGS) \ || ((DSTCLASS) == GENERAL_REGS && (SRCCLASS) == FP_REGS)) ? 4 \ : 1) @@@@ -1566,10 +1567,10 @@@@ } #define ASM_OUTPUT_REG_PUSH(file, v) \ - fprintf ((file), "\tmov.l\tr%s,-@@r15\n", (v)); + fprintf ((file), "\tmov.l\tr%d,@@-r15\n", (v)); #define ASM_OUTPUT_REG_POP(file, v) \ - fprintf ((file), "\tmov.l\t@@r15+,r%s\n", (v)); + fprintf ((file), "\tmov.l\t@@r15+,r%d\n", (v)); /* The assembler's names for the registers. RFP need not always be used as the Real framepointer; it can also be used as a normal general register. @@@@ -1957,3 +1958,5 @@@@ #define HAVE_ATEXIT #define SH_DYNAMIC_SHIFT_COST (TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20) + +#define DWARF_LINE_MIN_INSTR_LENGTH 2 --- gcc/config/sh/sh.md.orig Thu Apr 23 22:37:16 1998 +++ gcc/config/sh/sh.md Mon Jan 22 21:09:51 2001 @@@@ -661,7 +661,7 @@@@ ;; This reload would clobber the value in r0 we are trying to store. ;; If we let reload allocate r0, then this problem can never happen. -(define_insn "" +(define_insn "udivsi3_i1" [(set (match_operand:SI 0 "register_operand" "=z") (udiv:SI (reg:SI 4) (reg:SI 5))) (clobber (reg:SI 18)) @@@@ -674,9 +674,9 @@@@ (set_attr "needs_delay_slot" "yes")]) (define_expand "udivsi3" - [(set (reg:SI 4) (match_operand:SI 1 "general_operand" "")) + [(set (match_dup 3) (symbol_ref:SI "__udivsi3")) + (set (reg:SI 4) (match_operand:SI 1 "general_operand" "")) (set (reg:SI 5) (match_operand:SI 2 "general_operand" "")) - (set (match_dup 3) (symbol_ref:SI "__udivsi3")) (parallel [(set (match_operand:SI 0 "register_operand" "") (udiv:SI (reg:SI 4) (reg:SI 5))) @@@@ -685,9 +685,26 @@@@ (clobber (reg:SI 4)) (use (match_dup 3))])] "" - "operands[3] = gen_reg_rtx(SImode);") + " +{ + rtx first, last; -(define_insn "" + operands[3] = gen_reg_rtx(SImode); + /* Emit the move of the address to a pseudo outside of the libcall. */ + emit_move_insn (operands[3], + gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\")); + last = gen_udivsi3_i1 (operands[0], operands[3]); + first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); + emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); + last = emit_insn (last); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; +}") + +(define_insn "divsi3_i1" [(set (match_operand:SI 0 "register_operand" "=z") (div:SI (reg:SI 4) (reg:SI 5))) (clobber (reg:SI 18)) @@@@ -702,9 +719,9 @@@@ (set_attr "needs_delay_slot" "yes")]) (define_expand "divsi3" - [(set (reg:SI 4) (match_operand:SI 1 "general_operand" "")) + [(set (match_dup 3) (symbol_ref:SI "__sdivsi3")) + (set (reg:SI 4) (match_operand:SI 1 "general_operand" "")) (set (reg:SI 5) (match_operand:SI 2 "general_operand" "")) - (set (match_dup 3) (symbol_ref:SI "__sdivsi3")) (parallel [(set (match_operand:SI 0 "register_operand" "") (div:SI (reg:SI 4) (reg:SI 5))) @@@@ -715,13 +732,29 @@@@ (clobber (reg:SI 3)) (use (match_dup 3))])] "" - "operands[3] = gen_reg_rtx(SImode);") + " +{ + rtx first, last; + + operands[3] = gen_reg_rtx(SImode); + /* Emit the move of the address to a pseudo outside of the libcall. */ + emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\")); + last = gen_divsi3_i1 (operands[0], operands[3]); + first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]); + emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]); + last = emit_insn (last); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; +}") ;; ------------------------------------------------------------------------- ;; Multiplication instructions ;; ------------------------------------------------------------------------- -(define_insn "" +(define_insn "umulhisi3_i" [(set (reg:SI 21) (mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r")) (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))] @@@@ -729,7 +762,7 @@@@ "mulu %1,%0" [(set_attr "type" "smpy")]) -(define_insn "" +(define_insn "mulhisi3_i" [(set (reg:SI 21) (mult:SI (sign_extend:SI (match_operand:HI 0 "arith_reg_operand" "r")) @@@@ -748,7 +781,18 @@@@ (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI 21))] "" - "") + " +{ + rtx first, last; + + first = emit_insn (gen_mulhisi3_i (operands[1], operands[2])); + last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21)); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; +}") (define_expand "umulhisi3" [(set (reg:SI 21) @@@@ -759,7 +803,18 @@@@ (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI 21))] "" - "") + " +{ + rtx first, last; + + first = emit_insn (gen_umulhisi3_i (operands[1], operands[2])); + last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 21)); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; +}") ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate ;; a call to a routine which clobbers known registers. @@@@ -782,7 +837,6 @@@@ (define_expand "mulsi3_call" [(set (reg:SI 4) (match_operand:SI 1 "general_operand" "")) (set (reg:SI 5) (match_operand:SI 2 "general_operand" "")) - (set (match_dup 3) (symbol_ref:SI "__mulsi3")) (parallel[(set (match_operand:SI 0 "register_operand" "") (mult:SI (reg:SI 4) (reg:SI 5))) @@@@ -792,9 +846,9 @@@@ (clobber (reg:SI 3)) (clobber (reg:SI 2)) (clobber (reg:SI 1)) - (use (match_dup 3))])] + (use (match_operand:SI 3 "register_operand" ""))])] "" - "operands[3] = gen_reg_rtx(SImode);") + "") (define_insn "mul_l" [(set (reg:SI 21) @@@@ -813,82 +867,120 @@@@ "" " { + rtx first, last; + if (!TARGET_SH2) { - FAIL; - /* ??? Does this give worse or better code? */ - emit_insn (gen_mulsi3_call (operands[0], operands[1], operands[2])); - DONE; + /* The address must be set outside the libcall, + since it goes into a pseudo. */ + rtx addr = force_reg (SImode, gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\")); + rtx insns = gen_mulsi3_call (operands[0], operands[1], operands[2], addr); + first = XVECEXP (insns, 0, 0); + last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1); + emit_insn (insns); } + else + { + rtx macl = gen_rtx_REG (SImode, MACL_REG); + + first = emit_insn (gen_mul_l (operands[1], operands[2])); + /* consec_sets_giv can only recognize the first insn that sets a + giv as the giv insn. So we must tag this also with a REG_EQUAL + note. */ + last = emit_insn (gen_movsi_i ((operands[0]), macl)); + } + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; }") (define_insn "mulsidi3_i" - [(set (reg:DI 20) - (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) - (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))] + [(set (reg:SI 20) + (truncate:SI + (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) + (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) + (const_int 32)))) + (set (reg:SI 21) + (mult:SI (match_dup 0) + (match_dup 1)))] "TARGET_SH2" "dmuls.l %1,%0" [(set_attr "type" "dmpy")]) -(define_expand "mulsidi3" - [(set (reg:DI 20) +(define_insn "mulsidi3" + [(set (match_operand:DI 0 "arith_reg_operand" "=r") + (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) + (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) + (clobber (reg:DI 20))] + "TARGET_SH2" + "#") + +(define_split + [(set (match_operand:DI 0 "arith_reg_operand" "") (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) - (set (match_operand:DI 0 "arith_reg_operand" "") - (reg:DI 20))] + (clobber (reg:DI 20))] "TARGET_SH2" + [(const_int 0)] " { - /* We must swap the two words when copying them from MACH/MACL to the - output register. */ - if (TARGET_LITTLE_ENDIAN) - { - rtx low_dst = operand_subword (operands[0], 0, 1, DImode); - rtx high_dst = operand_subword (operands[0], 1, 1, DImode); - - emit_insn (gen_mulsidi3_i (operands[1], operands[2])); - - emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0])); - emit_move_insn (low_dst, gen_rtx (REG, SImode, 21)); - emit_move_insn (high_dst, gen_rtx (REG, SImode, 20)); - DONE; - } + rtx low_dst = gen_lowpart (SImode, operands[0]); + rtx high_dst = gen_highpart (SImode, operands[0]); + + emit_insn (gen_mulsidi3_i (operands[1], operands[2])); + + emit_move_insn (low_dst, gen_rtx_REG (SImode, 21)); + emit_move_insn (high_dst, gen_rtx_REG (SImode, 20)); + /* We need something to tag the possible REG_EQUAL notes on to. */ + emit_move_insn (operands[0], operands[0]); + DONE; }") (define_insn "umulsidi3_i" - [(set (reg:DI 20) - (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) - (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))] + [(set (reg:SI 20) + (truncate:SI + (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) + (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))) + (const_int 32)))) + (set (reg:SI 21) + (mult:SI (match_dup 0) + (match_dup 1)))] "TARGET_SH2" "dmulu.l %1,%0" [(set_attr "type" "dmpy")]) -(define_expand "umulsidi3" - [(set (reg:DI 20) +(define_insn "umulsidi3" + [(set (match_operand:DI 0 "arith_reg_operand" "=r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")) + (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r")))) + (clobber (reg:DI 20))] + "TARGET_SH2" + "#") + +(define_split + [(set (match_operand:DI 0 "arith_reg_operand" "") (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "")) (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))) - (set (match_operand:DI 0 "arith_reg_operand" "") - (reg:DI 20))] + (clobber (reg:DI 20))] "TARGET_SH2" + [(const_int 0)] " { - /* We must swap the two words when copying them from MACH/MACL to the - output register. */ - if (TARGET_LITTLE_ENDIAN) - { - rtx low_dst = operand_subword (operands[0], 0, 1, DImode); - rtx high_dst = operand_subword (operands[0], 1, 1, DImode); - - emit_insn (gen_umulsidi3_i (operands[1], operands[2])); - - emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0])); - emit_move_insn (low_dst, gen_rtx (REG, SImode, 21)); - emit_move_insn (high_dst, gen_rtx (REG, SImode, 20)); - DONE; - } + rtx low_dst = gen_lowpart (SImode, operands[0]); + rtx high_dst = gen_highpart (SImode, operands[0]); + + emit_insn (gen_umulsidi3_i (operands[1], operands[2])); + + emit_move_insn (low_dst, gen_rtx_REG (SImode, 21)); + emit_move_insn (high_dst, gen_rtx_REG (SImode, 20)); + /* We need something to tag the possible REG_EQUAL notes on to. */ + emit_move_insn (operands[0], operands[0]); + DONE; }") -(define_insn "" +(define_insn "smulsi3_highpart_i" [(set (reg:SI 20) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) @@@@ -909,9 +1001,27 @@@@ (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI 20))] "TARGET_SH2" - "") + " +{ + rtx first, last; -(define_insn "" + first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2])); + last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20)); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + /* expand_binop can't find a suitable code in mul_highpart_optab to + make a REG_EQUAL note from, so make one here. + ??? Alternatively, we could put this at the calling site of expand_binop, + i.e. expand_mult_highpart. */ + REG_NOTES (last) + = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))), + REG_NOTES (last)); + DONE; +}") + +(define_insn "umulsi3_highpart_i" [(set (reg:SI 20) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r")) @@@@ -932,7 +1042,18 @@@@ (set (match_operand:SI 0 "arith_reg_operand" "") (reg:SI 20))] "TARGET_SH2" - "") + " +{ + rtx first, last; + + first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2])); + last = emit_move_insn (operands[0], gen_rtx_REG (SImode, 20)); + /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop + invariant code motion can move it. */ + REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first)); + REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last)); + DONE; +}") ;; ------------------------------------------------------------------------- ;; Logical operations @@@@ -1825,19 +1946,20 @@@@ "" "sett") -;; t/r is first, so that it will be preferred over r/r when reloading a move -;; of a pseudo-reg into the T reg +;; t/r must come after r/r, lest reload will try to reload stuff like +;; (set (subreg:SI (mem:QI (plus:SI (reg:SI 15 r15) (const_int 12)) 0) 0) +;; (made from (set (subreg:SI (reg:QI 73) 0) ) into T. (define_insn "movsi_i" - [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,<,xl,x,l,r") - (match_operand:SI 1 "general_movsrc_operand" "r,Q,rI,m,xl,t,r,x,l,r,>,>,i"))] + [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r") + (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,i"))] " ! TARGET_SH3E && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" "@@ - cmp/pl %1 mov.l %1,%0 mov %1,%0 + cmp/pl %1 mov.l %1,%0 sts %1,%0 movt %0 @@@@ -1848,7 +1970,7 @@@@ lds.l %1,%0 lds.l %1,%0 fake %1,%0" - [(set_attr "type" "*,pcload_si,move,load_si,move,move,store,store,pstore,move,load,pload,pcload_si") + [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si") (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*")]) ;; t/r must come after r/r, lest reload will try to reload stuff like @@@@ -1856,8 +1978,8 @@@@ ;; ??? This allows moves from macl to fpul to be recognized, but these moves ;; will require a reload. (define_insn "movsi_ie" - [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r,y,r,y") - (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,m,xl,t,r,x,l,r,>,>,i,r,y,y"))] + [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,y,r,y,r,y") + (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,>,i,r,y,y"))] "TARGET_SH3E && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode))" @@@@ -1874,16 +1996,17 @@@@ lds %1,%0 lds.l %1,%0 lds.l %1,%0 + lds.l %1,%0 fake %1,%0 lds %1,%0 sts %1,%0 ! move optimized away" - [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si,gp_fpul,gp_fpul,nil") - (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")]) + [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,load,pcload_si,gp_fpul,gp_fpul,nil") + (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")]) (define_insn "movsi_i_lowpart" [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,m,r")) - (match_operand:SI 1 "general_movsrc_operand" "Q,rI,m,xl,t,r,i"))] + (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,xl,t,r,i"))] "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" "@@ @@@@ -2087,7 +2210,8 @@@@ FAIL; reg = XEXP (addr, 0); const_int = XEXP (addr, 1); - if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT) + if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2]) + && GET_CODE (const_int) == CONST_INT)) FAIL; emit_move_insn (operands[2], const_int); emit_move_insn (operands[0], @@@@ -2113,7 +2237,8 @@@@ FAIL; reg = XEXP (addr, 0); const_int = XEXP (addr, 1); - if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT) + if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2]) + && GET_CODE (const_int) == CONST_INT)) FAIL; emit_move_insn (operands[2], const_int); emit_move_insn (change_address (operands[1], VOIDmode, @@@@ -2249,7 +2374,7 @@@@ ;; This one has the additional purpose to record a possible scratch register ;; for the following branch. (define_insn "indirect_jump_scratch" - [(set (match_operand 0 "register_operand" "r") + [(set (match_operand 0 "register_operand" "=r") (unspec [(match_operand 1 "const_int_operand" "")] 4))] "" "" @@@@ -2478,7 +2603,7 @@@@ { int i; - emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx)); + emit_call_insn (gen_call (operands[0], const0_rtx)); for (i = 0; i < XVECLEN (operands[2], 0); i++) { @@@@ -2974,6 +3099,7 @@@@ (use (match_operand:SI 0 "arith_reg_operand" "r")) (use (reg:SI 6)) (clobber (reg:SI 17)) + (clobber (reg:SI 18)) (clobber (reg:SI 4)) (clobber (reg:SI 5)) (clobber (reg:SI 6)) @@@@ -3144,10 +3270,9 @@@@ size /= 8; orig_address = XEXP (operands[0], 0); - addr_target = gen_reg_rtx (SImode); shift_reg = gen_reg_rtx (SImode); emit_insn (gen_movsi (shift_reg, operands[3])); - emit_insn (gen_addsi3 (addr_target, orig_address, GEN_INT (size - 1))); + addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1)); operands[0] = change_address (operands[0], QImode, addr_target); emit_insn (gen_movqi (operands[0], gen_rtx (SUBREG, QImode, shift_reg, 0))); @ 1.1 log @patches for sh3. Sync with: gnu/dist/gcc/config/sh/sh.c rev. 1.7 sh.h rev. 1.5 sh.md rev. 1.7 @ text @@