--- 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)));