Commit 5527bf14 by Richard Henderson

Makefile.in (OBJS): Add doloop.o.

	* Makefile.in (OBJS): Add doloop.o.
	* doloop.c: New file.

	* final.c (insn_current_reference_address): Return 0 before final.
	* flags.h (flag_branch_on_count_reg): Fix typos in commentary.
	* jump.c (any_uncondjump_p): Likewise.
	* loop.c (indirect_jump_in_function): Make static.
	(strength_reduce): Call doloop_optimize.
	(insert_bct, instrument_loop_bct): Remove.
	* loop.h (doloop_optimize): Prototype.
	* recog.c (split_all_insns): Split all INSN_P.
	* toplev.c (flag_branch_on_count_reg): Default on.

	* config/c4x/c4x.c (c4x_optimization_options): Don't set
	flag_branch_on_count_reg.
	* config/i386/i386.c (override_options): Likewise.
	* config/rs6000/rs6000.c (optimization_options): Likewise.

	* config/i386/i386.md (decrement_and_branch_on_count): Remove.
	(doloop_end): New.
	(dbra_ge): Remove, as well as all it's splitters.

	* config/rs6000/rs6000.md (decrement_and_branch_on_count): Remove.
	(doloop_end): New.

	* config/ia64/ia64-protos.h (ar_lc_reg_operand): Declare.
	(ia64_register_move_cost): Declare.
	* config/ia64/ia64.c (ar_lc_reg_operand): New.
	(struct ia64_frame_info): Add ar_size.
	(ia64_compute_frame_size): Set it.
	(save_restore_insns): Save and restore ar.lc.
	(ia64_register_move_cost): New, moved from header file.  Handle
	application registers.
	(REG_AR_PFS, REG_AR_EC): Remove.  Replace with AR_*_REGNUM numbers.
	(emit_insn_group_barriers): Special case doloop_end_internal.
	(ia64_epilogue_uses): Mark ar.lc live at end.
	* config/ia64/ia64.h (AR_CCV_REGNUM, AR_LC_REGNUM): New registers.
	(AR_EC_REGNUM, AR_PFS_REGNUM): New registers.
	(FIRST_PSEUDO_REGISTER): Make room.
	(AR_M_REGNO_P, AR_I_REGNO_P, AR_REGNO_P): New.
	(FIXED_REGISTERS, CALL_USED_REGISTERS): Update.
	(REG_ALLOC_ORDER): Update.
	(HARD_REGNO_MODE_OK): Update.
	(REGISTER_NAMES): Update.
	(enum reg_class): Add AR_M_REGS and AR_I_REGS.
	(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update.
	(REGNO_REG_CLASS): Update.
	(LEGITIMATE_ADDRESS_DISP): Displacement range is 9 bits, not 10.
	(REGISTER_MOVE_COST): Move out of line.
	(PREDICATE_CODES): Update.
	* config/ia64/ia64.md (movdi patterns): Handle ar register classes.
	(addsi3_plus1_alt, adddi3_plus1_alt): New.
	(shladd_elim splitter): Allow constants in the predicate.
	(doloop_end, doloop_end_internal): New.

From-SVN: r35358
parent 1cf0acdd
2000-07-30 Michael Hayes <mhayes@cygnus.com>
Richard Henderson <rth@cygnus.com>
* Makefile.in (OBJS): Add doloop.o.
* doloop.c: New file.
* final.c (insn_current_reference_address): Return 0 before final.
* flags.h (flag_branch_on_count_reg): Fix typos in commentary.
* jump.c (any_uncondjump_p): Likewise.
* loop.c (indirect_jump_in_function): Make static.
(strength_reduce): Call doloop_optimize.
(insert_bct, instrument_loop_bct): Remove.
* loop.h (doloop_optimize): Prototype.
* recog.c (split_all_insns): Split all INSN_P.
* toplev.c (flag_branch_on_count_reg): Default on.
* config/c4x/c4x.c (c4x_optimization_options): Don't set
flag_branch_on_count_reg.
* config/i386/i386.c (override_options): Likewise.
* config/rs6000/rs6000.c (optimization_options): Likewise.
* config/i386/i386.md (decrement_and_branch_on_count): Remove.
(doloop_end): New.
(dbra_ge): Remove, as well as all it's splitters.
* config/rs6000/rs6000.md (decrement_and_branch_on_count): Remove.
(doloop_end): New.
* config/ia64/ia64-protos.h (ar_lc_reg_operand): Declare.
(ia64_register_move_cost): Declare.
* config/ia64/ia64.c (ar_lc_reg_operand): New.
(struct ia64_frame_info): Add ar_size.
(ia64_compute_frame_size): Set it.
(save_restore_insns): Save and restore ar.lc.
(ia64_register_move_cost): New, moved from header file. Handle
application registers.
(REG_AR_PFS, REG_AR_EC): Remove. Replace with AR_*_REGNUM numbers.
(emit_insn_group_barriers): Special case doloop_end_internal.
(ia64_epilogue_uses): Mark ar.lc live at end.
* config/ia64/ia64.h (AR_CCV_REGNUM, AR_LC_REGNUM): New registers.
(AR_EC_REGNUM, AR_PFS_REGNUM): New registers.
(FIRST_PSEUDO_REGISTER): Make room.
(AR_M_REGNO_P, AR_I_REGNO_P, AR_REGNO_P): New.
(FIXED_REGISTERS, CALL_USED_REGISTERS): Update.
(REG_ALLOC_ORDER): Update.
(HARD_REGNO_MODE_OK): Update.
(REGISTER_NAMES): Update.
(enum reg_class): Add AR_M_REGS and AR_I_REGS.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update.
(REGNO_REG_CLASS): Update.
(LEGITIMATE_ADDRESS_DISP): Displacement range is 9 bits, not 10.
(REGISTER_MOVE_COST): Move out of line.
(PREDICATE_CODES): Update.
* config/ia64/ia64.md (movdi patterns): Handle ar register classes.
(addsi3_plus1_alt, adddi3_plus1_alt): New.
(shladd_elim splitter): Allow constants in the predicate.
(doloop_end, doloop_end_internal): New.
2000-07-30 Richard Henderson <rth@cygnus.com>
* genattrtab.c (struct insn_def): Add lineno member.
(struct insn_ent): Likewise.
(struct attr_desc): Likewise.
(struct delay_desc): Likewise.
(struct function_unit_op): Likewise.
(struct function_unit): Likewise.
(check_attr_value): Use message_with_line.
(check_defs): Likewise.
(expand_units): Likewise.
(check_attr_test): Take a lineno argument.
(gen_attr): Likewise.
(gen_insn): Likewise.
(gen_delay): Likewise.
(gen_unit): Likewise.
(main): Give it to them.
(convert_set_attr_alternative): Take an insn_def argument
instead of num_alt and insn_index.
(convert_set_attr): Likewise.
(write_test_expr): Protect INSN_ADDRESSES load
with INSN_ADDRESSES_SET_P.
2000-07-30 Richard Henderson <rth@cygnus.com> 2000-07-30 Richard Henderson <rth@cygnus.com>
* flow.c (init_propagate_block_info): Use pc_set. * flow.c (init_propagate_block_info): Use pc_set.
......
...@@ -689,7 +689,7 @@ OBJS = diagnostic.o \ ...@@ -689,7 +689,7 @@ OBJS = diagnostic.o \
function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o real.o \ function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o real.o \
builtins.o intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o \ builtins.o intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \ dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o combine.o varray.o \ integrate.o jump.o cse.o loop.o doloop.o unroll.o flow.o combine.o varray.o \
regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \ regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \
insn-peep.o reorg.o haifa-sched.o final.o recog.o reg-stack.o regrename.o \ insn-peep.o reorg.o haifa-sched.o final.o recog.o reg-stack.o regrename.o \
insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \ insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
...@@ -1338,6 +1338,8 @@ profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ ...@@ -1338,6 +1338,8 @@ profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h $(LOOP_H) insn-config.h \ loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h $(LOOP_H) insn-config.h \
insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \ insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \
$(BASIC_BLOCK_H) function.h toplev.h varray.h except.h cselib.h $(BASIC_BLOCK_H) function.h toplev.h varray.h except.h cselib.h
doloop.o : doloop.c $(CONFIG_H) system.h $(RTL_H) flags.h $(LOOP_H) \
insn-flags.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H)
unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h function.h \ unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h function.h \
$(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \ $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
hard-reg-set.h varray.h $(BASIC_BLOCK_H) hard-reg-set.h varray.h $(BASIC_BLOCK_H)
......
...@@ -295,10 +295,6 @@ c4x_optimization_options (level, size) ...@@ -295,10 +295,6 @@ c4x_optimization_options (level, size)
instructions. The benefit we gain we get by scheduling before instructions. The benefit we gain we get by scheduling before
register allocation is probably marginal anyhow. */ register allocation is probably marginal anyhow. */
flag_schedule_insns = 0; flag_schedule_insns = 0;
/* When optimizing, enable use of RPTB instruction. */
if (level >= 1)
flag_branch_on_count_reg = 1;
} }
......
...@@ -630,10 +630,6 @@ override_options () ...@@ -630,10 +630,6 @@ override_options ()
if (flag_fast_math) if (flag_fast_math)
target_flags &= ~MASK_IEEE_FP; target_flags &= ~MASK_IEEE_FP;
/* If we're planning on using `loop', use it. */
if (TARGET_USE_LOOP && optimize)
flag_branch_on_count_reg = 1;
/* It makes no sense to ask for just SSE builtins, so MMX is also turned /* It makes no sense to ask for just SSE builtins, so MMX is also turned
on by -msse. */ on by -msse. */
if (TARGET_SSE) if (TARGET_SSE)
......
...@@ -8327,27 +8327,32 @@ ...@@ -8327,27 +8327,32 @@
;; This is all complicated by the fact that since this is a jump insn ;; This is all complicated by the fact that since this is a jump insn
;; we must handle our own reloads. ;; we must handle our own reloads.
(define_expand "decrement_and_branch_on_count" (define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else [(use (match_operand 0 "" "")) ; loop pseudo
(ne (match_operand:SI 0 "register_operand" "") (use (match_operand 1 "" "")) ; iterations; zero if unknown
(const_int 1)) (use (match_operand 2 "" "")) ; max iterations
(label_ref (match_operand 1 "" "")) (use (match_operand 3 "" "")) ; loop level
(pc))) (use (match_operand 4 "" ""))] ; label
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:SI 2 ""))
(clobber (reg:CC 17))])]
"TARGET_USE_LOOP" "TARGET_USE_LOOP"
"") "
{
/* Only use cloop on innermost loops. */
if (INTVAL (operands[3]) > 1)
FAIL;
if (GET_MODE (operands[0]) != SImode)
FAIL;
emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
operands[0]));
DONE;
}")
(define_insn "*dbra_ne" (define_insn "doloop_end_internal"
[(set (pc) [(set (pc)
(if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
(const_int 1)) (const_int 1))
(label_ref (match_operand 0 "" "")) (label_ref (match_operand 0 "" ""))
(pc))) (pc)))
(set (match_operand:SI 2 "register_operand" "=1,*r,*m*r") (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
(plus:SI (match_dup 1) (plus:SI (match_dup 1)
(const_int -1))) (const_int -1)))
(clobber (match_scratch:SI 3 "=X,X,r")) (clobber (match_scratch:SI 3 "=X,X,r"))
...@@ -8372,55 +8377,24 @@ ...@@ -8372,55 +8377,24 @@
(const_string "ibr") (const_string "ibr")
(const_string "multi")))]) (const_string "multi")))])
(define_insn "*dbra_ge"
[(set (pc)
(if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:SI 2 "register_operand" "=1,*r,*m*r")
(plus:SI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:SI 3 "=X,X,r"))
(clobber (reg:CC 17))]
"TARGET_USE_LOOP && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
return \"#\";
if (get_attr_length (insn) == 2)
return \"loop\\t%l0\";
else
return \"dec{l}\\t%1\;jne\\t%l0\";
}"
[(set (attr "type")
(if_then_else (and (eq_attr "alternative" "0")
(and (ge (minus (match_dup 0) (pc))
(const_int -128))
(lt (minus (match_dup 0) (pc))
(const_int 124))))
(const_string "ibr")
(const_string "multi")))
(set_attr "ppro_uops" "many")])
(define_split (define_split
[(set (pc) [(set (pc)
(if_then_else (ne (match_operand:SI 1 "register_operand" "") (if_then_else (ne (match_operand:SI 1 "register_operand" "")
(const_int 1)) (const_int 1))
(match_operand 0 "" "") (match_operand 0 "" "")
(pc))) (pc)))
(set (match_operand:SI 2 "register_operand" "") (set (match_dup 1)
(plus:SI (match_dup 1) (plus:SI (match_dup 1)
(const_int -1))) (const_int -1)))
(clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 2 ""))
(clobber (reg:CC 17))] (clobber (reg:CC 17))]
"TARGET_USE_LOOP && reload_completed "TARGET_USE_LOOP
&& ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))" && reload_completed
[(set (match_dup 2) (match_dup 1)) && REGNO (operands[1]) != 2"
(parallel [(set (reg:CCZ 17) [(parallel [(set (reg:CCZ 17)
(compare:CCZ (plus:SI (match_dup 2) (const_int -1)) (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
(const_int 0))) (const_int 0)))
(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))]) (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
(set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0)) (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
(match_dup 0) (match_dup 0)
(pc)))] (pc)))]
...@@ -8432,12 +8406,15 @@ ...@@ -8432,12 +8406,15 @@
(const_int 1)) (const_int 1))
(match_operand 0 "" "") (match_operand 0 "" "")
(pc))) (pc)))
(set (match_operand:SI 2 "memory_operand" "") (set (match_operand:SI 2 "nonimmediate_operand" "")
(plus:SI (match_dup 1) (plus:SI (match_dup 1)
(const_int -1))) (const_int -1)))
(clobber (match_scratch:SI 3 "")) (clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 17))] (clobber (reg:CC 17))]
"TARGET_USE_LOOP && reload_completed" "TARGET_USE_LOOP
&& reload_completed
&& (! REG_P (operands[2])
|| ! rtx_equal_p (operands[1], operands[2]))"
[(set (match_dup 3) (match_dup 1)) [(set (match_dup 3) (match_dup 1))
(parallel [(set (reg:CCZ 17) (parallel [(set (reg:CCZ 17)
(compare:CCZ (plus:SI (match_dup 3) (const_int -1)) (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
...@@ -8449,52 +8426,6 @@ ...@@ -8449,52 +8426,6 @@
(pc)))] (pc)))]
"") "")
(define_split
[(set (pc)
(if_then_else (ge (match_operand:SI 1 "register_operand" "")
(const_int 0))
(match_operand 0 "" "")
(pc)))
(set (match_operand:SI 2 "register_operand" "")
(plus:SI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 17))]
"TARGET_USE_LOOP && reload_completed
&& ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
[(set (match_dup 2) (match_dup 1))
(parallel [(set (reg:CCNO 17)
(compare:CCNO (plus:SI (match_dup 2) (const_int -1))
(const_int 0)))
(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
(set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
(match_dup 0)
(pc)))]
"")
(define_split
[(set (pc)
(if_then_else (ge (match_operand:SI 1 "register_operand" "")
(const_int 0))
(match_operand 0 "" "")
(pc)))
(set (match_operand:SI 2 "memory_operand" "")
(plus:SI (match_dup 1)
(const_int -1)))
(clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 17))]
"TARGET_USE_LOOP && reload_completed"
[(set (match_dup 3) (match_dup 1))
(parallel [(set (reg:CCNO 17)
(compare:CCNO (plus:SI (match_dup 3) (const_int -1))
(const_int 0)))
(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
(set (match_dup 2) (match_dup 3))
(set (pc) (if_then_else (lt (reg:CCNO 17) (const_int 0))
(match_dup 0)
(pc)))]
"")
;; Call instructions. ;; Call instructions.
;; The predicates normally associated with named expanders are not properly ;; The predicates normally associated with named expanders are not properly
......
...@@ -59,6 +59,8 @@ extern void ia64_function_prologue PARAMS((FILE *, int)); ...@@ -59,6 +59,8 @@ extern void ia64_function_prologue PARAMS((FILE *, int));
extern void ia64_funtion_epilogue PARAMS((FILE *, int)); extern void ia64_funtion_epilogue PARAMS((FILE *, int));
extern int ia64_direct_return PARAMS((void)); extern int ia64_direct_return PARAMS((void));
extern int predicate_operator PARAMS((rtx, enum machine_mode)); extern int predicate_operator PARAMS((rtx, enum machine_mode));
extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
extern int ia64_move_ok PARAMS((rtx, rtx)); extern int ia64_move_ok PARAMS((rtx, rtx));
extern void ia64_expand_load_address PARAMS((rtx, rtx)); extern void ia64_expand_load_address PARAMS((rtx, rtx));
...@@ -102,6 +104,7 @@ extern int ia64_valid_type_attribute PARAMS((tree, tree, tree, tree)); ...@@ -102,6 +104,7 @@ extern int ia64_valid_type_attribute PARAMS((tree, tree, tree, tree));
extern void ia64_encode_section_info PARAMS((tree)); extern void ia64_encode_section_info PARAMS((tree));
#endif /* TREE_CODE */ #endif /* TREE_CODE */
extern int ia64_register_move_cost PARAMS((enum reg_class, enum reg_class));
extern int ia64_epilogue_uses PARAMS((int)); extern int ia64_epilogue_uses PARAMS((int));
extern void ia64_file_start PARAMS((FILE *)); extern void ia64_file_start PARAMS((FILE *));
extern void ia64_expand_prologue PARAMS((void)); extern void ia64_expand_prologue PARAMS((void));
......
...@@ -560,6 +560,19 @@ predicate_operator (op, mode) ...@@ -560,6 +560,19 @@ predicate_operator (op, mode)
&& (code == EQ || code == NE)); && (code == EQ || code == NE));
} }
/* Return 1 if this is the ar.lc register. */
int
ar_lc_reg_operand (op, mode)
register rtx op;
enum machine_mode mode;
{
return (GET_MODE (op) == DImode
&& (mode == DImode || mode == VOIDmode)
&& GET_CODE (op) == REG
&& REGNO (op) == AR_LC_REGNUM);
}
/* Return 1 if the operands of a move are ok. */ /* Return 1 if the operands of a move are ok. */
int int
...@@ -683,6 +696,7 @@ struct ia64_frame_info ...@@ -683,6 +696,7 @@ struct ia64_frame_info
long fr_pad_size; /* # bytes needed to align FP save area. */ long fr_pad_size; /* # bytes needed to align FP save area. */
long pr_size; /* # bytes needed to store predicate regs. */ long pr_size; /* # bytes needed to store predicate regs. */
long br_size; /* # bytes needed to store branch regs. */ long br_size; /* # bytes needed to store branch regs. */
long ar_size; /* # bytes needed to store AR regs. */
HARD_REG_SET mask; /* mask of saved registers. */ HARD_REG_SET mask; /* mask of saved registers. */
int initialized; /* != 0 is frame size already calculated. */ int initialized; /* != 0 is frame size already calculated. */
}; };
...@@ -713,6 +727,7 @@ ia64_compute_frame_size (size) ...@@ -713,6 +727,7 @@ ia64_compute_frame_size (size)
int fr_pad_size = 0; int fr_pad_size = 0;
int pr_size = 0; int pr_size = 0;
int br_size = 0; int br_size = 0;
int ar_size = 0;
int pretend_pad_size = 0; int pretend_pad_size = 0;
int tmp; int tmp;
int regno; int regno;
...@@ -772,6 +787,13 @@ ia64_compute_frame_size (size) ...@@ -772,6 +787,13 @@ ia64_compute_frame_size (size)
else else
fr_pad_size = 0; fr_pad_size = 0;
/* AR.LC, for reasons unexplained, is call saved. */
if (regs_ever_live[AR_LC_REGNUM])
{
SET_HARD_REG_BIT (mask, AR_LC_REGNUM);
ar_size = 8;
}
/* If we have an odd number of words of pretend arguments written to the /* If we have an odd number of words of pretend arguments written to the
stack, then the FR save area will be unaligned. We pad below this area stack, then the FR save area will be unaligned. We pad below this area
to keep things 16 byte aligned. This needs to be kept distinct, to to keep things 16 byte aligned. This needs to be kept distinct, to
...@@ -780,7 +802,7 @@ ia64_compute_frame_size (size) ...@@ -780,7 +802,7 @@ ia64_compute_frame_size (size)
pretend_pad_size = current_function_pretend_args_size % 16; pretend_pad_size = current_function_pretend_args_size % 16;
/* The 16 bytes is for the scratch area. */ /* The 16 bytes is for the scratch area. */
tmp = (size + gr_size + fr_pad_size + fr_size + pr_size + br_size tmp = (size + gr_size + fr_pad_size + fr_size + pr_size + br_size + ar_size
+ current_function_outgoing_args_size + 16); + current_function_outgoing_args_size + 16);
tmp += (current_function_pretend_args_size tmp += (current_function_pretend_args_size
? current_function_pretend_args_size - 16 ? current_function_pretend_args_size - 16
...@@ -810,6 +832,7 @@ ia64_compute_frame_size (size) ...@@ -810,6 +832,7 @@ ia64_compute_frame_size (size)
current_frame_info.fr_pad_size = fr_pad_size; current_frame_info.fr_pad_size = fr_pad_size;
current_frame_info.pr_size = pr_size; current_frame_info.pr_size = pr_size;
current_frame_info.br_size = br_size; current_frame_info.br_size = br_size;
current_frame_info.ar_size = ar_size;
COPY_HARD_REG_SET (current_frame_info.mask, mask); COPY_HARD_REG_SET (current_frame_info.mask, mask);
current_frame_info.initialized = reload_completed; current_frame_info.initialized = reload_completed;
...@@ -822,8 +845,11 @@ save_restore_insns (save_p) ...@@ -822,8 +845,11 @@ save_restore_insns (save_p)
{ {
rtx insn; rtx insn;
if (current_frame_info.gr_size + current_frame_info.fr_size if (current_frame_info.gr_size
+ current_frame_info.br_size + current_frame_info.pr_size) + current_frame_info.fr_size
+ current_frame_info.br_size
+ current_frame_info.pr_size
+ current_frame_info.ar_size)
{ {
rtx tmp_reg = gen_rtx_REG (DImode, GR_REG (2)); rtx tmp_reg = gen_rtx_REG (DImode, GR_REG (2));
rtx tmp_post_inc = gen_rtx_POST_INC (DImode, tmp_reg); rtx tmp_post_inc = gen_rtx_POST_INC (DImode, tmp_reg);
...@@ -833,6 +859,7 @@ save_restore_insns (save_p) ...@@ -833,6 +859,7 @@ save_restore_insns (save_p)
+ current_frame_info.fr_pad_size + current_frame_info.fr_pad_size
+ current_frame_info.br_size + current_frame_info.br_size
+ current_frame_info.pr_size + current_frame_info.pr_size
+ current_frame_info.ar_size
+ current_frame_info.var_size + current_frame_info.var_size
+ current_frame_info.pretend_size + current_frame_info.pretend_size
+ current_frame_info.pretend_pad_size)); + current_frame_info.pretend_pad_size));
...@@ -961,6 +988,29 @@ save_restore_insns (save_p) ...@@ -961,6 +988,29 @@ save_restore_insns (save_p)
if (save_p) if (save_p)
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
if (TEST_HARD_REG_BIT (current_frame_info.mask, AR_LC_REGNUM))
{
rtx src, dest;
if (save_p)
{
src = gen_rtx_REG (DImode, AR_LC_REGNUM);
dest = gen_rtx_MEM (DImode, tmp_post_inc);
}
else
{
src = gen_rtx_MEM (DImode, tmp_post_inc);
dest = gen_rtx_REG (DImode, AR_LC_REGNUM);
}
insn = emit_insn (gen_movdi (tmp2_reg, src));
if (save_p)
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_insn (gen_movdi (dest, tmp2_reg));
if (save_p)
RTX_FRAME_RELATED_P (insn) = 1;
}
} }
} }
...@@ -2149,6 +2199,28 @@ ia64_print_operand (file, x, code) ...@@ -2149,6 +2199,28 @@ ia64_print_operand (file, x, code)
return; return;
} }
/* Calulate the cost of moving data from a register in class FROM to
one in class TO. */
int
ia64_register_move_cost (from, to)
enum reg_class from, to;
{
int from_hard, to_hard;
int from_gr, to_gr;
from_hard = (from == BR_REGS || from == AR_M_REGS || from == AR_I_REGS);
to_hard = (to == BR_REGS || to == AR_M_REGS || to == AR_I_REGS);
from_gr = (from == GENERAL_REGS);
to_gr = (to == GENERAL_REGS);
if (from_hard && to_hard)
return 8;
else if ((from_hard && !to_gr) || (!from_gr && to_hard))
return 6;
return 2;
}
/* This function returns the register class required for a secondary /* This function returns the register class required for a secondary
register when copying between one of the registers in CLASS, and X, register when copying between one of the registers in CLASS, and X,
...@@ -2382,14 +2454,11 @@ ia64_override_options () ...@@ -2382,14 +2454,11 @@ ia64_override_options ()
complex). */ complex). */
#define REG_GP (GR_REG (1)) #define REG_GP (GR_REG (1))
#define REG_RP (BR_REG (0)) #define REG_RP (BR_REG (0))
#define REG_AR_PFS (FIRST_PSEUDO_REGISTER)
#define REG_AR_CFM (FIRST_PSEUDO_REGISTER + 1) #define REG_AR_CFM (FIRST_PSEUDO_REGISTER + 1)
/* ??? This will eventually need to be a hard register. */
#define REG_AR_EC (FIRST_PSEUDO_REGISTER + 2)
/* This is used for volatile asms which may require a stop bit immediately /* This is used for volatile asms which may require a stop bit immediately
before and after them. */ before and after them. */
#define REG_VOLATILE (FIRST_PSEUDO_REGISTER + 3) #define REG_VOLATILE (FIRST_PSEUDO_REGISTER + 2)
#define NUM_REGS (FIRST_PSEUDO_REGISTER + 4) #define NUM_REGS (FIRST_PSEUDO_REGISTER + 3)
/* For each register, we keep track of how many times it has been /* For each register, we keep track of how many times it has been
written in the current instruction group. If a register is written written in the current instruction group. If a register is written
...@@ -2521,14 +2590,12 @@ rws_access_reg (regno, flags, pred) ...@@ -2521,14 +2590,12 @@ rws_access_reg (regno, flags, pred)
/* Branches have several RAW exceptions that allow to avoid /* Branches have several RAW exceptions that allow to avoid
barriers. */ barriers. */
if (REGNO_REG_CLASS (regno) == BR_REGS || regno == REG_AR_PFS) if (REGNO_REG_CLASS (regno) == BR_REGS || regno == AR_PFS_REGNUM)
/* RAW dependencies on branch regs are permissible as long /* RAW dependencies on branch regs are permissible as long
as the writer is a non-branch instruction. Since we as the writer is a non-branch instruction. Since we
never generate code that uses a branch register written never generate code that uses a branch register written
by a branch instruction, handling this case is by a branch instruction, handling this case is
easy. */ easy. */
/* ??? This assumes that we don't emit br.cloop, br.cexit, br.ctop,
br.wexit, br.wtop. This is true currently. */
return 0; return 0;
if (REGNO_REG_CLASS (regno) == PR_REGS if (REGNO_REG_CLASS (regno) == PR_REGS
...@@ -2678,7 +2745,7 @@ rtx_needs_barrier (x, flags, pred) ...@@ -2678,7 +2745,7 @@ rtx_needs_barrier (x, flags, pred)
new_flags.is_write = 0; new_flags.is_write = 0;
/* ??? Why is this here? It seems unnecessary. */ /* ??? Why is this here? It seems unnecessary. */
need_barrier |= rws_access_reg (REG_GP, new_flags, pred); need_barrier |= rws_access_reg (REG_GP, new_flags, pred);
need_barrier |= rws_access_reg (REG_AR_EC, new_flags, pred); need_barrier |= rws_access_reg (AR_EC_REGNUM, new_flags, pred);
/* Avoid multiple register writes, in case this is a pattern with /* Avoid multiple register writes, in case this is a pattern with
multiple CALL rtx. This avoids an abort in rws_access_reg. */ multiple CALL rtx. This avoids an abort in rws_access_reg. */
...@@ -2688,7 +2755,7 @@ rtx_needs_barrier (x, flags, pred) ...@@ -2688,7 +2755,7 @@ rtx_needs_barrier (x, flags, pred)
{ {
new_flags.is_write = 1; new_flags.is_write = 1;
need_barrier |= rws_access_reg (REG_RP, new_flags, pred); need_barrier |= rws_access_reg (REG_RP, new_flags, pred);
need_barrier |= rws_access_reg (REG_AR_PFS, new_flags, pred); need_barrier |= rws_access_reg (AR_PFS_REGNUM, new_flags, pred);
need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred); need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred);
} }
break; break;
...@@ -2877,7 +2944,7 @@ rtx_needs_barrier (x, flags, pred) ...@@ -2877,7 +2944,7 @@ rtx_needs_barrier (x, flags, pred)
/* Alloc must always be the first instruction. Currently, we /* Alloc must always be the first instruction. Currently, we
only emit it at the function start, so we don't need to worry only emit it at the function start, so we don't need to worry
about emitting a stop bit before it. */ about emitting a stop bit before it. */
need_barrier = rws_access_reg (REG_AR_PFS, flags, pred); need_barrier = rws_access_reg (AR_PFS_REGNUM, flags, pred);
new_flags.is_write = 1; new_flags.is_write = 1;
need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred); need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred);
...@@ -2892,7 +2959,7 @@ rtx_needs_barrier (x, flags, pred) ...@@ -2892,7 +2959,7 @@ rtx_needs_barrier (x, flags, pred)
case 4: /* mov ar.pfs= */ case 4: /* mov ar.pfs= */
new_flags.is_write = 1; new_flags.is_write = 1;
need_barrier = rws_access_reg (REG_AR_PFS, new_flags, pred); need_barrier = rws_access_reg (AR_PFS_REGNUM, new_flags, pred);
break; break;
case 5: /* set_bsp */ case 5: /* set_bsp */
...@@ -2920,10 +2987,10 @@ rtx_needs_barrier (x, flags, pred) ...@@ -2920,10 +2987,10 @@ rtx_needs_barrier (x, flags, pred)
case RETURN: case RETURN:
new_flags.is_write = 0; new_flags.is_write = 0;
need_barrier = rws_access_reg (REG_RP, flags, pred); need_barrier = rws_access_reg (REG_RP, flags, pred);
need_barrier |= rws_access_reg (REG_AR_PFS, flags, pred); need_barrier |= rws_access_reg (AR_PFS_REGNUM, flags, pred);
new_flags.is_write = 1; new_flags.is_write = 1;
need_barrier |= rws_access_reg (REG_AR_EC, new_flags, pred); need_barrier |= rws_access_reg (AR_EC_REGNUM, new_flags, pred);
need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred); need_barrier |= rws_access_reg (REG_AR_CFM, new_flags, pred);
break; break;
...@@ -3042,6 +3109,12 @@ emit_insn_group_barriers (insns) ...@@ -3042,6 +3109,12 @@ emit_insn_group_barriers (insns)
if (INSN_CODE (insn) == CODE_FOR_epilogue_deallocate_stack) if (INSN_CODE (insn) == CODE_FOR_epilogue_deallocate_stack)
pat = XVECEXP (pat, 0, 0); pat = XVECEXP (pat, 0, 0);
/* ??? Similarly, the pattern we use for br.cloop
confuses the code above. The second element of the
vector is representative. */
else if (INSN_CODE (insn) == CODE_FOR_doloop_end_internal)
pat = XVECEXP (pat, 0, 1);
memset (rws_insn, 0, sizeof (rws_insn)); memset (rws_insn, 0, sizeof (rws_insn));
need_barrier |= rtx_needs_barrier (pat, flags, 0); need_barrier |= rtx_needs_barrier (pat, flags, 0);
...@@ -3164,6 +3237,9 @@ ia64_epilogue_uses (regno) ...@@ -3164,6 +3237,9 @@ ia64_epilogue_uses (regno)
if (regno == R_BR (0)) if (regno == R_BR (0))
return 1; return 1;
if (regno == AR_LC_REGNUM)
return 1;
return 0; return 0;
} }
......
...@@ -535,12 +535,11 @@ while (0) ...@@ -535,12 +535,11 @@ while (0)
/* Register Basics */ /* Register Basics */
/* Number of hardware registers known to the compiler. /* Number of hardware registers known to the compiler.
We have 128 general registers, 128 floating point registers, 64 predicate We have 128 general registers, 128 floating point registers,
registers, 8 branch registers, and one frame pointer register. */ 64 predicate registers, 8 branch registers, one frame pointer,
and several "application" registers. */
/* ??? Should add ar.lc, ar.ec and probably also ar.pfs. */ #define FIRST_PSEUDO_REGISTER 334
#define FIRST_PSEUDO_REGISTER 330
/* Ranges for the various kinds of registers. */ /* Ranges for the various kinds of registers. */
#define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3) #define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3)
...@@ -561,10 +560,23 @@ while (0) ...@@ -561,10 +560,23 @@ while (0)
#define IN_REG(REGNO) ((REGNO) + 112) #define IN_REG(REGNO) ((REGNO) + 112)
#define LOC_REG(REGNO) ((REGNO) + 32) #define LOC_REG(REGNO) ((REGNO) + 32)
#define AR_CCV_REGNUM 330
#define AR_LC_REGNUM 331
#define AR_EC_REGNUM 332
#define AR_PFS_REGNUM 333
#define IN_REGNO_P(REGNO) ((REGNO) >= IN_REG (0) && (REGNO) <= IN_REG (7)) #define IN_REGNO_P(REGNO) ((REGNO) >= IN_REG (0) && (REGNO) <= IN_REG (7))
#define LOC_REGNO_P(REGNO) ((REGNO) >= LOC_REG (0) && (REGNO) <= LOC_REG (79)) #define LOC_REGNO_P(REGNO) ((REGNO) >= LOC_REG (0) && (REGNO) <= LOC_REG (79))
#define OUT_REGNO_P(REGNO) ((REGNO) >= OUT_REG (0) && (REGNO) <= OUT_REG (7)) #define OUT_REGNO_P(REGNO) ((REGNO) >= OUT_REG (0) && (REGNO) <= OUT_REG (7))
#define AR_M_REGNO_P(REGNO) ((REGNO) == AR_CCV_REGNUM)
#define AR_I_REGNO_P(REGNO) ((REGNO) >= AR_LC_REGNUM \
&& (REGNO) < FIRST_PSEUDO_REGISTER)
#define AR_REGNO_P(REGNO) ((REGNO) >= AR_CCV_REGNUM \
&& (REGNO) < FIRST_PSEUDO_REGISTER)
/* ??? Don't really need two sets of macros. I like this one better because /* ??? Don't really need two sets of macros. I like this one better because
it is less typing. */ it is less typing. */
#define R_GR(REGNO) GR_REG (REGNO) #define R_GR(REGNO) GR_REG (REGNO)
...@@ -619,14 +631,14 @@ while (0) ...@@ -619,14 +631,14 @@ while (0)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Branch registers. */ \ /* Branch registers. */ \
0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \
/*FP RA*/ \ /*FP RA CCV LC EC PFS */ \
1, 1, \ 1, 1, 1, 1, 1, 1 \
} }
/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in /* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered
general) by function calls as well as for fixed registers. This macro (in general) by function calls as well as for fixed registers. This
therefore identifies the registers that are not available for general macro therefore identifies the registers that are not available for
allocation of values that must live across function calls. */ general allocation of values that must live across function calls. */
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{ /* General registers. */ \ { /* General registers. */ \
...@@ -654,8 +666,8 @@ while (0) ...@@ -654,8 +666,8 @@ while (0)
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
/* Branch registers. */ \ /* Branch registers. */ \
1, 0, 0, 0, 0, 0, 1, 1, \ 1, 0, 0, 0, 0, 0, 1, 1, \
/*FP RA*/ \ /*FP RA CCV LC EC PFS */ \
1, 1, \ 1, 1, 1, 1, 1, 1 \
} }
/* Define this macro if the target machine has register windows. This C /* Define this macro if the target machine has register windows. This C
...@@ -787,11 +799,11 @@ while (0) ...@@ -787,11 +799,11 @@ while (0)
R_PR (0), \ R_PR (0), \
/* Special branch registers. */ \ /* Special branch registers. */ \
R_BR (0), \ R_BR (0), \
/* Frame pointer. Return address. */ \ /* Other fixed registers. */ \
FRAME_POINTER_REGNUM, RETURN_ADDRESS_POINTER_REGNUM, \ FRAME_POINTER_REGNUM, RETURN_ADDRESS_POINTER_REGNUM, \
AR_CCV_REGNUM, AR_LC_REGNUM, AR_EC_REGNUM, AR_PFS_REGNUM \
} }
/* How Values Fit in Registers */ /* How Values Fit in Registers */
/* A C expression for the number of consecutive hard registers, starting at /* A C expression for the number of consecutive hard registers, starting at
...@@ -815,6 +827,7 @@ while (0) ...@@ -815,6 +827,7 @@ while (0)
(FR_REGNO_P (REGNO) ? (MODE) != CCmode \ (FR_REGNO_P (REGNO) ? (MODE) != CCmode \
: PR_REGNO_P (REGNO) ? (MODE) == CCmode \ : PR_REGNO_P (REGNO) ? (MODE) == CCmode \
: GR_REGNO_P (REGNO) ? (MODE) != XFmode \ : GR_REGNO_P (REGNO) ? (MODE) != XFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \
: 1) : 1)
/* A C expression that is nonzero if it is desirable to choose register /* A C expression that is nonzero if it is desirable to choose register
...@@ -877,6 +890,8 @@ enum reg_class ...@@ -877,6 +890,8 @@ enum reg_class
GR_REGS, GR_REGS,
FR_REGS, FR_REGS,
GR_AND_FR_REGS, GR_AND_FR_REGS,
AR_M_REGS,
AR_I_REGS,
ALL_REGS, ALL_REGS,
LIM_REG_CLASSES LIM_REG_CLASSES
}; };
...@@ -890,7 +905,8 @@ enum reg_class ...@@ -890,7 +905,8 @@ enum reg_class
constants. These names are used in writing some of the debugging dumps. */ constants. These names are used in writing some of the debugging dumps. */
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{ "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", \ { "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", \
"FR_REGS", "GR_AND_FR_REGS", "ALL_REGS" } "FR_REGS", "GR_AND_FR_REGS", "AR_M_REGS", "AR_I_REGS", \
"ALL_REGS" }
/* An initializer containing the contents of the register classes, as integers /* An initializer containing the contents of the register classes, as integers
which are bit masks. The Nth integer specifies the contents of class N. which are bit masks. The Nth integer specifies the contents of class N.
...@@ -901,35 +917,43 @@ enum reg_class ...@@ -901,35 +917,43 @@ enum reg_class
/* NO_REGS. */ \ /* NO_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x000 }, \ 0x00000000, 0x00000000, 0x0000 }, \
/* PR_REGS. */ \ /* PR_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0xFFFFFFFF, 0xFFFFFFFF, 0x000 }, \ 0xFFFFFFFF, 0xFFFFFFFF, 0x0000 }, \
/* BR_REGS. */ \ /* BR_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x0FF }, \ 0x00000000, 0x00000000, 0x00FF }, \
/* ADDL_REGS. */ \ /* ADDL_REGS. */ \
{ 0x0000000F, 0x00000000, 0x00000000, 0x00000000, \ { 0x0000000F, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x000 }, \ 0x00000000, 0x00000000, 0x0000 }, \
/* GR_REGS. */ \ /* GR_REGS. */ \
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x300 }, \ 0x00000000, 0x00000000, 0x0300 }, \
/* FR_REGS. */ \ /* FR_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0x00000000, 0x00000000, 0x000 }, \ 0x00000000, 0x00000000, 0x0000 }, \
/* GR_AND_FR_REGS. */ \ /* GR_AND_FR_REGS. */ \
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0x00000000, 0x00000000, 0x300 }, \ 0x00000000, 0x00000000, 0x0300 }, \
/* AR_M_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x0400 }, \
/* AR_I_REGS. */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
0x00000000, 0x00000000, 0x3800 }, \
/* ALL_REGS. */ \ /* ALL_REGS. */ \
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
0xFFFFFFFF, 0xFFFFFFFF, 0x3FF }, \ 0xFFFFFFFF, 0xFFFFFFFF, 0x3FFF }, \
} }
/* A C expression whose value is a register class containing hard register /* A C expression whose value is a register class containing hard register
...@@ -944,6 +968,8 @@ enum reg_class ...@@ -944,6 +968,8 @@ enum reg_class
: FR_REGNO_P (REGNO) ? FR_REGS \ : FR_REGNO_P (REGNO) ? FR_REGS \
: PR_REGNO_P (REGNO) ? PR_REGS \ : PR_REGNO_P (REGNO) ? PR_REGS \
: BR_REGNO_P (REGNO) ? BR_REGS \ : BR_REGNO_P (REGNO) ? BR_REGS \
: AR_M_REGNO_P (REGNO) ? AR_I_REGS \
: AR_I_REGNO_P (REGNO) ? AR_M_REGS \
: NO_REGS) : NO_REGS)
/* A macro whose definition is the name of the class to which a valid base /* A macro whose definition is the name of the class to which a valid base
...@@ -968,6 +994,8 @@ enum reg_class ...@@ -968,6 +994,8 @@ enum reg_class
: (CHAR) == 'a' ? ADDL_REGS \ : (CHAR) == 'a' ? ADDL_REGS \
: (CHAR) == 'b' ? BR_REGS \ : (CHAR) == 'b' ? BR_REGS \
: (CHAR) == 'c' ? PR_REGS \ : (CHAR) == 'c' ? PR_REGS \
: (CHAR) == 'd' ? AR_M_REGS \
: (CHAR) == 'e' ? AR_I_REGS \
: NO_REGS) : NO_REGS)
/* A C expression which is nonzero if register number NUM is suitable for use /* A C expression which is nonzero if register number NUM is suitable for use
...@@ -1816,8 +1844,8 @@ do { \ ...@@ -1816,8 +1844,8 @@ do { \
&& rtx_equal_p (R, XEXP (X, 0)) \ && rtx_equal_p (R, XEXP (X, 0)) \
&& (GET_CODE (XEXP (X, 1)) == REG \ && (GET_CODE (XEXP (X, 1)) == REG \
|| (GET_CODE (XEXP (X, 1)) == CONST_INT \ || (GET_CODE (XEXP (X, 1)) == CONST_INT \
&& INTVAL (XEXP (X, 1)) >= -512 \ && INTVAL (XEXP (X, 1)) >= -256 \
&& INTVAL (XEXP (X, 1)) < 512))) && INTVAL (XEXP (X, 1)) < 256)))
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
do { \ do { \
...@@ -1926,10 +1954,7 @@ do { \ ...@@ -1926,10 +1954,7 @@ do { \
one in class TO. */ one in class TO. */
#define REGISTER_MOVE_COST(FROM, TO) \ #define REGISTER_MOVE_COST(FROM, TO) \
((FROM) == BR_REGS && (TO) == BR_REGS ? 8 \ ia64_register_move_cost((FROM), (TO))
: (((FROM) == BR_REGS && (TO) != GENERAL_REGS) \
|| ((TO) == BR_REGS && (FROM) != GENERAL_REGS)) ? 6 \
: 2)
/* A C expression for the cost of moving data of mode M between a register and /* A C expression for the cost of moving data of mode M between a register and
memory. */ memory. */
...@@ -2363,7 +2388,7 @@ do { \ ...@@ -2363,7 +2388,7 @@ do { \
/* Branch registers. */ \ /* Branch registers. */ \
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
/* Frame pointer. Return address. */ \ /* Frame pointer. Return address. */ \
"sfp", "retaddr" \ "sfp", "retaddr", "ar.ccv", "ar.lc", "ar.ec", "ar.pfs" \
} }
/* If defined, a C initializer for an array of structures containing a name and /* If defined, a C initializer for an array of structures containing a name and
...@@ -2749,7 +2774,8 @@ do { \ ...@@ -2749,7 +2774,8 @@ do { \
{ "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \ { "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \
{ "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \ { "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \
{ "call_multiple_values_operation", {PARALLEL}}, \ { "call_multiple_values_operation", {PARALLEL}}, \
{ "predicate_operator", {NE, EQ}}, { "predicate_operator", {NE, EQ}}, \
{ "ar_lc_reg_operand", {REG}},
/* An alias for a machine mode name. This is the machine mode that elements of /* An alias for a machine mode name. This is the machine mode that elements of
a jump-table should have. */ a jump-table should have. */
......
...@@ -368,10 +368,12 @@ ...@@ -368,10 +368,12 @@
(define_insn "" (define_insn ""
[(cond_exec [(cond_exec
(match_operator 2 "predicate_operator" (match_operator 2 "predicate_operator"
[(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c") [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c,c,c")
(const_int 0)]) (const_int 0)])
(set (match_operand:DI 0 "register_operand" "=r,r,r, r,*f,*f, r,*b") (set (match_operand:DI 0 "register_operand"
(match_operand:DI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*b,rO")))] "=r,r,r, r,*f,*f, r,*b*e, r,*d")
(match_operand:DI 1 "nonmemory_operand"
"rO,J,i,*f,rO,*f,*b*e, rO,*d,rO")))]
"TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])" "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
"* "*
{ {
...@@ -383,6 +385,8 @@ ...@@ -383,6 +385,8 @@
\"(%J2) setf.sig %0 = %r1\", \"(%J2) setf.sig %0 = %r1\",
\"(%J2) mov %0 = %1\", \"(%J2) mov %0 = %1\",
\"(%J2) mov %0 = %1\", \"(%J2) mov %0 = %1\",
\"(%J2) mov %0 = %r1\",
\"(%J2) mov %0 = %1\",
\"(%J2) mov %0 = %r1\" \"(%J2) mov %0 = %r1\"
}; };
...@@ -403,14 +407,14 @@ ...@@ -403,14 +407,14 @@
return alt[which_alternative]; return alt[which_alternative];
}" }"
[(set_attr "type" "A,A,L,M,M,F,I,I") [(set_attr "type" "A,A,L,M,M,F,I,I,M,M")
(set_attr "predicable" "no")]) (set_attr "predicable" "no")])
(define_insn "*movdi_internal_astep" (define_insn "*movdi_internal_astep"
[(set (match_operand:DI 0 "destination_operand" [(set (match_operand:DI 0 "destination_operand"
"=r,r,r,r, m, r,*f,*f,*f, Q, r,*b") "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b*e, r,*d")
(match_operand:DI 1 "move_operand" (match_operand:DI 1 "move_operand"
"rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO"))] "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e, rO,*d,rO"))]
"TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])" "TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
"* "*
{ {
...@@ -426,6 +430,8 @@ ...@@ -426,6 +430,8 @@
\"ldf8 %0 = %1%P1\", \"ldf8 %0 = %1%P1\",
\"stf8 %0 = %1%P0\", \"stf8 %0 = %1%P0\",
\"mov %0 = %1\", \"mov %0 = %1\",
\"mov %0 = %r1\",
\"mov %0 = %1\",
\"mov %0 = %r1\" \"mov %0 = %r1\"
}; };
...@@ -435,14 +441,14 @@ ...@@ -435,14 +441,14 @@
return alt[which_alternative]; return alt[which_alternative];
}" }"
[(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I") [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,M,M")
(set_attr "predicable" "no")]) (set_attr "predicable" "no")])
(define_insn "*movdi_internal" (define_insn "*movdi_internal"
[(set (match_operand:DI 0 "destination_operand" [(set (match_operand:DI 0 "destination_operand"
"=r,r,r,r, m, r,*f,*f,*f, Q, r,*b") "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b*e, r,*d")
(match_operand:DI 1 "move_operand" (match_operand:DI 1 "move_operand"
"rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO"))] "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b*e, rO,*d,rO"))]
"! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])" "! TARGET_A_STEP && ia64_move_ok (operands[0], operands[1])"
"* "*
{ {
...@@ -458,6 +464,8 @@ ...@@ -458,6 +464,8 @@
\"%,ldf8 %0 = %1%P1\", \"%,ldf8 %0 = %1%P1\",
\"%,stf8 %0 = %1%P0\", \"%,stf8 %0 = %1%P0\",
\"%,mov %0 = %1\", \"%,mov %0 = %1\",
\"%,mov %0 = %r1\",
\"%,mov %0 = %1\",
\"%,mov %0 = %r1\" \"%,mov %0 = %r1\"
}; };
...@@ -467,7 +475,7 @@ ...@@ -467,7 +475,7 @@
return alt[which_alternative]; return alt[which_alternative];
}" }"
[(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I")]) [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I,M,M")])
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
...@@ -1104,6 +1112,15 @@ ...@@ -1104,6 +1112,15 @@
"add %0 = %1, %2, 1" "add %0 = %1, %2, 1"
[(set_attr "type" "A")]) [(set_attr "type" "A")])
(define_insn "*addsi3_plus1_alt"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
(const_int 2))
(const_int 1)))]
""
"add %0 = %1, %1, 1"
[(set_attr "type" "A")])
(define_expand "subsi3" (define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "reg_or_8bit_operand" "") (minus:SI (match_operand:SI 1 "reg_or_8bit_operand" "")
...@@ -1299,6 +1316,18 @@ ...@@ -1299,6 +1316,18 @@
"add %0 = %1, %2, 1" "add %0 = %1, %2, 1"
[(set_attr "type" "A")]) [(set_attr "type" "A")])
;; This has some of the same problems as shladd. We let the shladd
;; eliminator hack handle it, which results in the 1 being forced into
;; a register, but not more ugliness here.
(define_insn "*adddi3_plus1_alt"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r")
(const_int 2))
(const_int 1)))]
""
"add %0 = %1, %1, 1"
[(set_attr "type" "A")])
(define_insn "subdi3" (define_insn "subdi3"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (match_operand:DI 1 "reg_or_8bit_operand" "rK") (minus:DI (match_operand:DI 1 "reg_or_8bit_operand" "rK")
...@@ -1862,31 +1891,20 @@ ...@@ -1862,31 +1891,20 @@
;; doesn't succeed, then this remain a shladd pattern, and will be reloaded ;; doesn't succeed, then this remain a shladd pattern, and will be reloaded
;; incorrectly. ;; incorrectly.
(define_insn "*shladd_elim" (define_insn_and_split "*shladd_elim"
[(set (match_operand:DI 0 "register_operand" "=&r") [(set (match_operand:DI 0 "register_operand" "=&r")
(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r") (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "r")
(match_operand:DI 2 "shladd_operand" "n")) (match_operand:DI 2 "shladd_operand" "n"))
(match_operand:DI 3 "register_operand" "r")) (match_operand:DI 3 "nonmemory_operand" "r"))
(match_operand:DI 4 "nonmemory_operand" "rI")))] (match_operand:DI 4 "nonmemory_operand" "rI")))]
"reload_in_progress" "reload_in_progress"
"#" "* abort ();"
[(set_attr "type" "unknown")])
;; ??? Need to emit an instruction group barrier here because this gets split
;; after md_reorg.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "shladd_operand" ""))
(match_operand:DI 3 "register_operand" ""))
(match_operand:DI 4 "reg_or_14bit_operand" "")))]
"reload_completed" "reload_completed"
[(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2))
(match_dup 3))) (match_dup 3)))
(unspec_volatile [(const_int 0)] 2)
(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
"") ""
[(set_attr "type" "unknown")])
(define_insn "ashrdi3" (define_insn "ashrdi3"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
...@@ -2465,6 +2483,42 @@ ...@@ -2465,6 +2483,42 @@
;; :::::::::::::::::::: ;; ::::::::::::::::::::
;; :: ;; ::
;; :: Counted loop operations
;; ::
;; ::::::::::::::::::::
(define_expand "doloop_end"
[(use (match_operand 0 "" "")) ; loop pseudo
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
""
"
{
/* Only use cloop on innermost loops. */
if (INTVAL (operands[3]) > 1)
FAIL;
emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
operands[4]));
DONE;
}")
(define_insn "doloop_end_internal"
[(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0))
(match_dup 0)
(plus:DI (match_dup 0) (const_int -1))))]
""
"br.cloop.sptk.few %l1"
[(set_attr "type" "B")
(set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
;; :: Set flag operations ;; :: Set flag operations
;; :: ;; ::
;; :::::::::::::::::::: ;; ::::::::::::::::::::
...@@ -2706,32 +2760,32 @@ ...@@ -2706,32 +2760,32 @@
;; Errata 72 workaround. ;; Errata 72 workaround.
(define_insn "*cmovdi_internal_astep" (define_insn "*cmovdi_internal_astep"
[(set (match_operand:DI 0 "nonimmediate_operand" [(set (match_operand:DI 0 "nonimmediate_operand"
"=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b") "=r,*f,Q,*b*d*e,r,*f,Q,*b*d*e,r,*f,Q,*b*d*e")
(if_then_else:DI (if_then_else:DI
(match_operator:CC 4 "predicate_operator" (match_operator:CC 4 "predicate_operator"
[(match_operand:CC 1 "register_operand" [(match_operand:CC 1 "register_operand"
"c,c,c,c,c,c,c,c,c,c,c,c") "c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)]) (const_int 0)])
(match_operand:DI 2 "general_operand" (match_operand:DI 2 "general_operand"
"0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r") "0,0,0,0,ri*f*b*d*e,rO,*f,r,ri*f*b*d*e,rO,*f,r")
(match_operand:DI 3 "general_operand" (match_operand:DI 3 "general_operand"
"ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))] "ri*f*b*d*e,rO,*f,r,0,0,0,0,ri*f*b*d*e,rO,*f,r")))]
"TARGET_A_STEP" "TARGET_A_STEP"
"* abort ();" "* abort ();"
[(set_attr "predicable" "no")]) [(set_attr "predicable" "no")])
(define_insn "*cmovdi_internal" (define_insn "*cmovdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand" [(set (match_operand:DI 0 "nonimmediate_operand"
"=r,m,*f,Q,*b,r,m,*f,Q,*b,r,m,*f,Q,*b") "=r,m,*f,Q,*b*d*e,r,m,*f,Q,*b*d*e,r,m,*f,Q,*b*d*e")
(if_then_else:DI (if_then_else:DI
(match_operator:CC 4 "predicate_operator" (match_operator:CC 4 "predicate_operator"
[(match_operand:CC 1 "register_operand" [(match_operand:CC 1 "register_operand"
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)]) (const_int 0)])
(match_operand:DI 2 "general_operand" (match_operand:DI 2 "general_operand"
"0,0,0,0,0,rim*f*b,rO,rOQ,*f,r,rim*f*b,rO,rOQ,*f,r") "0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,r,rim*f*b*d*e,rO,rOQ,*f,r")
(match_operand:DI 3 "general_operand" (match_operand:DI 3 "general_operand"
"rim*f*b,rO,rOQ,*f,r,0,0,0,0,0,rim*f*b,rO,rOQ,*f,r")))] "rim*f*b*d*e,rO,rOQ,*f,r,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,r")))]
"! TARGET_A_STEP" "! TARGET_A_STEP"
"* abort ();" "* abort ();"
[(set_attr "predicable" "no")]) [(set_attr "predicable" "no")])
......
...@@ -400,11 +400,6 @@ optimization_options (level, size) ...@@ -400,11 +400,6 @@ optimization_options (level, size)
int level; int level;
int size ATTRIBUTE_UNUSED; int size ATTRIBUTE_UNUSED;
{ {
#ifdef HAVE_decrement_and_branch_on_count
/* When optimizing, enable use of BCT instruction. */
if (level >= 1)
flag_branch_on_count_reg = 1;
#endif
} }
/* Do anything needed at the start of the asm file. */ /* Do anything needed at the start of the asm file. */
......
...@@ -13291,16 +13291,30 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32); ...@@ -13291,16 +13291,30 @@ operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
;; Define the subtract-one-and-jump insns, starting with the template ;; Define the subtract-one-and-jump insns, starting with the template
;; so loop.c knows what to generate. ;; so loop.c knows what to generate.
(define_expand "decrement_and_branch_on_count" (define_expand "doloop_end"
[(use (match_operand 0 "register_operand" "")) [(use (match_operand 0 "" "")) ; loop pseudo
(use (label_ref (match_operand 1 "" "")))] (use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
"" ""
" "
{ {
/* Only use this on innermost loops. */
if (INTVAL (operands[3]) > 1)
FAIL;
if (TARGET_POWERPC64) if (TARGET_POWERPC64)
emit_jump_insn (gen_ctrdi (operands[0], operands[1])); {
if (GET_MODE (operands[0]) != DImode)
FAIL;
emit_jump_insn (gen_ctrdi (operands[0], operands[4]));
}
else else
emit_jump_insn (gen_ctrsi (operands[0], operands[1])); {
if (GET_MODE (operands[0]) != SImode)
FAIL;
emit_jump_insn (gen_ctrsi (operands[0], operands[4]));
}
DONE; DONE;
}") }")
......
This diff is collapsed. Click to expand it.
...@@ -918,9 +918,14 @@ int ...@@ -918,9 +918,14 @@ int
insn_current_reference_address (branch) insn_current_reference_address (branch)
rtx branch; rtx branch;
{ {
rtx dest; rtx dest, seq;
rtx seq = NEXT_INSN (PREV_INSN (branch)); int seq_uid;
int seq_uid = INSN_UID (seq);
if (! INSN_ADDRESSES_SET_P ())
return 0;
seq = NEXT_INSN (PREV_INSN (branch));
seq_uid = INSN_UID (seq);
if (GET_CODE (branch) != JUMP_INSN) if (GET_CODE (branch) != JUMP_INSN)
/* This can happen for example on the PA; the objective is to know the /* This can happen for example on the PA; the objective is to know the
offset to address something in front of the start of the function. offset to address something in front of the start of the function.
...@@ -929,6 +934,7 @@ insn_current_reference_address (branch) ...@@ -929,6 +934,7 @@ insn_current_reference_address (branch)
any alignment we'd encounter, so we skip the call to align_fuzz. */ any alignment we'd encounter, so we skip the call to align_fuzz. */
return insn_current_address; return insn_current_address;
dest = JUMP_LABEL (branch); dest = JUMP_LABEL (branch);
/* BRANCH has no proper alignment chain set, so use SEQ. */ /* BRANCH has no proper alignment chain set, so use SEQ. */
if (INSN_SHUID (branch) < INSN_SHUID (dest)) if (INSN_SHUID (branch) < INSN_SHUID (dest))
{ {
......
...@@ -375,7 +375,7 @@ extern int flag_schedule_speculative; ...@@ -375,7 +375,7 @@ extern int flag_schedule_speculative;
extern int flag_schedule_speculative_load; extern int flag_schedule_speculative_load;
extern int flag_schedule_speculative_load_dangerous; extern int flag_schedule_speculative_load_dangerous;
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple /* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */ by a cheaper branch, on a count register. */
extern int flag_branch_on_count_reg; extern int flag_branch_on_count_reg;
......
...@@ -2217,7 +2217,7 @@ any_uncondjump_p (insn) ...@@ -2217,7 +2217,7 @@ any_uncondjump_p (insn)
/* Return true when insn is a conditional jump. This function works for /* Return true when insn is a conditional jump. This function works for
instructions containing PC sets in PARALLELs. The instruction may have instructions containing PC sets in PARALLELs. The instruction may have
various other effects so before removing the jump you must verify various other effects so before removing the jump you must verify
safe_to_remove_jump_p. onlyjump_p.
Note that unlike condjump_p it returns false for unconditional jumps. */ Note that unlike condjump_p it returns false for unconditional jumps. */
......
...@@ -254,3 +254,5 @@ int loop_insn_first_p PARAMS ((rtx, rtx)); ...@@ -254,3 +254,5 @@ int loop_insn_first_p PARAMS ((rtx, rtx));
typedef rtx (*loop_insn_callback ) PARAMS ((struct loop *, rtx, int, int)); typedef rtx (*loop_insn_callback ) PARAMS ((struct loop *, rtx, int, int));
void for_each_insn_in_loop PARAMS ((struct loop *, loop_insn_callback)); void for_each_insn_in_loop PARAMS ((struct loop *, loop_insn_callback));
/* Forward declarations for non-static functions declared in doloop.c. */
int doloop_optimize PARAMS ((const struct loop *));
...@@ -2626,7 +2626,7 @@ split_all_insns (upd_life) ...@@ -2626,7 +2626,7 @@ split_all_insns (upd_life)
/* Can't use `next_real_insn' because that might go across /* Can't use `next_real_insn' because that might go across
CODE_LABELS and short-out basic blocks. */ CODE_LABELS and short-out basic blocks. */
next = NEXT_INSN (insn); next = NEXT_INSN (insn);
if (GET_CODE (insn) != INSN) if (! INSN_P (insn))
; ;
/* Don't split no-op move insns. These should silently /* Don't split no-op move insns. These should silently
......
...@@ -746,9 +746,9 @@ int flag_schedule_speculative_load_dangerous = 0; ...@@ -746,9 +746,9 @@ int flag_schedule_speculative_load_dangerous = 0;
int flag_single_precision_constant; int flag_single_precision_constant;
/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple /* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */ by a cheaper branch on a count register. */
int flag_branch_on_count_reg; int flag_branch_on_count_reg = 1;
/* -finhibit-size-directive inhibits output of .size for ELF. /* -finhibit-size-directive inhibits output of .size for ELF.
This is used only for compiling crtstuff.c, This is used only for compiling crtstuff.c,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment