Commit 906668bb by Bernd Schmidt Committed by Bernd Schmidt

final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.

	* final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.
	* config/arm/arm.c (thumb1_code): New variable.
	(arm_override_options): Set it.
	(thumb1_final_prescan_insn): Keep track of condition code status.
	(arm_adjust_cost): For Thumb, try to keep cc-setting insns next to
	jumps that depend on them.
	* config/arm/arm.h (thumb1_code): Declare variable.
	(struct machine_function): Guard with #ifndef GENERATOR_FILE.  Add
	members thumb1_cc_insn, thumb1_cc_op0, thumb1_cc_op1 and
	thumb1_cc_mode.
	(CC_STATUS_INIT): New macro.
	* config/arm/constraints.md (Pd): New constraint.
	* config/arm/predicates.md (noov_comparison_operator): New predicate.
	* config/arm/arm.md (is_thumb1): New define_attr.
	(conds): Set default to "clob" when generating Thumb1 code.
	(thumb1_bicsi3): Renamed from bicsi3.  All uses changed.  Condition
	code are set.  Use two-operand assembly syntax.
	(thumb1_subsi3_insn): Condition codes are set.  Now a properly named
	pattern.
	(thumb1_andsi3_insn, thumb1_iorsi3_insn, thumb1_xorsi3_insn): Condition
	codes are set.  Use two-operand assembly syntax.
	(zero_extendhisi splitter): Remove constraints.
	(thumb1_movsi_insn, thumb1_movhi_insn, thumb1_movqi_insn, thumb1_movhf,
	thumb1_movsf_insn): Set conds attribute as appropriate.
	(cbranchsi4_insn): Use condition code status from struct
	machine_function to determine whether the comparison can be eliminated.
	Discourage the alternative using high registers.
	(movsi_cbranchsi4, andsi3_cbranch, orrsi3_cbranch_scratch,
	orrsi3_cbranch, xorsi3_cbranch_scratch, xorsi3_cbranch,
	bicsi3_cbranch_scratch, bicsi3_cbranch, subsi3_cbranch_scratch,
	subsi3_cbranch): Delete.
	(movsi_cbranchsi4 peepholes): Rewrite to generate a sequence of
	one subtract and one cbranch insn.

From-SVN: r162813
parent f37e278a
......@@ -3,6 +3,40 @@
* postreload.c (reload_cse_simplify_operands): Take attribute enabled
into account.
* final.c (final_scan_insn): Call CC_STATUS_INIT unconditionally.
* config/arm/arm.c (thumb1_code): New variable.
(arm_override_options): Set it.
(thumb1_final_prescan_insn): Keep track of condition code status.
(arm_adjust_cost): For Thumb, try to keep cc-setting insns next to
jumps that depend on them.
* config/arm/arm.h (thumb1_code): Declare variable.
(struct machine_function): Guard with #ifndef GENERATOR_FILE. Add
members thumb1_cc_insn, thumb1_cc_op0, thumb1_cc_op1 and
thumb1_cc_mode.
(CC_STATUS_INIT): New macro.
* config/arm/constraints.md (Pd): New constraint.
* config/arm/predicates.md (noov_comparison_operator): New predicate.
* config/arm/arm.md (is_thumb1): New define_attr.
(conds): Set default to "clob" when generating Thumb1 code.
(thumb1_bicsi3): Renamed from bicsi3. All uses changed. Condition
code are set. Use two-operand assembly syntax.
(thumb1_subsi3_insn): Condition codes are set. Now a properly named
pattern.
(thumb1_andsi3_insn, thumb1_iorsi3_insn, thumb1_xorsi3_insn): Condition
codes are set. Use two-operand assembly syntax.
(zero_extendhisi splitter): Remove constraints.
(thumb1_movsi_insn, thumb1_movhi_insn, thumb1_movqi_insn, thumb1_movhf,
thumb1_movsf_insn): Set conds attribute as appropriate.
(cbranchsi4_insn): Use condition code status from struct
machine_function to determine whether the comparison can be eliminated.
Discourage the alternative using high registers.
(movsi_cbranchsi4, andsi3_cbranch, orrsi3_cbranch_scratch,
orrsi3_cbranch, xorsi3_cbranch_scratch, xorsi3_cbranch,
bicsi3_cbranch_scratch, bicsi3_cbranch, subsi3_cbranch_scratch,
subsi3_cbranch): Delete.
(movsi_cbranchsi4 peepholes): Rewrite to generate a sequence of
one subtract and one cbranch insn.
2010-08-02 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/arm.c (COSTS_N_INSNS): Remove definition.
......
......@@ -687,6 +687,9 @@ int arm_tune_cortex_a9 = 0;
/* Nonzero if generating Thumb instructions. */
int thumb_code = 0;
/* Nonzero if generating Thumb-1 instructions. */
int thumb1_code = 0;
/* Nonzero if we should define __THUMB_INTERWORK__ in the
preprocessor.
XXX This is a bit of a hack, it's intended to help work around
......@@ -718,6 +721,7 @@ enum arm_pcs arm_pcs_default;
int arm_ccfsm_state;
/* arm_current_cc is also used for Thumb-2 cond_exec blocks. */
enum arm_cond_code arm_current_cc;
rtx arm_target_insn;
int arm_target_label;
/* The number of conditionally executed insns, including the current insn. */
......@@ -1572,7 +1576,8 @@ arm_override_options (void)
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
thumb_code = (TARGET_ARM == 0);
thumb_code = TARGET_ARM == 0;
thumb1_code = TARGET_THUMB1 != 0;
arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
......@@ -7682,12 +7687,26 @@ arm_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
{
return TARGET_32BIT ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
}
/* This function implements the target macro TARGET_SCHED_ADJUST_COST.
It corrects the value of COST based on the relationship between
INSN and DEP through the dependence LINK. It returns the new
value. */
static int
arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
{
rtx i_pat, d_pat;
/* When generating Thumb-1 code, we want to place flag-setting operations
close to a conditional branch which depends on them, so that we can
omit the comparison. */
if (TARGET_THUMB1
&& REG_NOTE_KIND (link) == 0
&& recog_memoized (insn) == CODE_FOR_cbranchsi4_insn
&& recog_memoized (dep) >= 0
&& get_attr_conds (dep) == CONDS_SET)
return 0;
/* Some true dependencies can have a higher cost depending
on precisely how certain input operands are used. */
if (arm_tune_xscale
......@@ -19475,13 +19494,44 @@ thumb_exit (FILE *f, int reg_containing_return_addr)
asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
}
/* Scan INSN just before assembler is output for it.
For Thumb-1, we track the status of the condition codes; this
information is used in the cbranchsi4_insn pattern. */
void
thumb1_final_prescan_insn (rtx insn)
{
if (flag_print_asm_name)
asm_fprintf (asm_out_file, "%@ 0x%04x\n",
INSN_ADDRESSES (INSN_UID (insn)));
/* Don't overwrite the previous setter when we get to a cbranch. */
if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
{
enum attr_conds conds;
if (cfun->machine->thumb1_cc_insn)
{
if (modified_in_p (cfun->machine->thumb1_cc_op0, insn)
|| modified_in_p (cfun->machine->thumb1_cc_op1, insn))
CC_STATUS_INIT;
}
conds = get_attr_conds (insn);
if (conds == CONDS_SET)
{
rtx set = single_set (insn);
cfun->machine->thumb1_cc_insn = insn;
cfun->machine->thumb1_cc_op0 = SET_DEST (set);
cfun->machine->thumb1_cc_op1 = const0_rtx;
cfun->machine->thumb1_cc_mode = CC_NOOVmode;
if (INSN_CODE (insn) == CODE_FOR_thumb1_subsi3_insn)
{
rtx src1 = XEXP (SET_SRC (set), 1);
if (src1 == const0_rtx)
cfun->machine->thumb1_cc_mode = CCmode;
}
}
else if (conds != CONDS_NOCOND)
cfun->machine->thumb1_cc_insn = NULL_RTX;
}
}
int
......
......@@ -412,9 +412,12 @@ extern int arm_arch7em;
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
/* Nonzero if generating thumb code. */
/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2. */
extern int thumb_code;
/* Nonzero if generating Thumb-1 code. */
extern int thumb1_code;
/* Nonzero if this chip is a StrongARM. */
extern int arm_tune_strongarm;
......@@ -1593,6 +1596,7 @@ typedef struct GTY(()) arm_stack_offsets
}
arm_stack_offsets;
#ifndef GENERATOR_FILE
/* A C structure for machine-specific, per-function data.
This is added to the cfun structure. */
typedef struct GTY(()) machine_function
......@@ -1623,8 +1627,16 @@ typedef struct GTY(()) machine_function
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
int return_used_this_function;
/* When outputting Thumb-1 code, record the last insn that provides
information about condition codes, and the comparison operands. */
rtx thumb1_cc_insn;
rtx thumb1_cc_op0;
rtx thumb1_cc_op1;
/* Also record the CC mode that is supported. */
enum machine_mode thumb1_cc_mode;
}
machine_function;
#endif
/* As in the machine_function, a global set of call-via labels, for code
that is in text_section. */
......@@ -2259,6 +2271,9 @@ extern int making_const_table;
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CC_STATUS_INIT \
do { cfun->machine->thumb1_cc_insn = NULL_RTX; } while (0)
#undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
TARGET_THUMB2 ? "\t.thumb\n" : "")
......
......@@ -30,7 +30,7 @@
;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di
;; in Thumb-1 state: Pa, Pb, Pc
;; in Thumb-1 state: Pa, Pb, Pc, Pd
;; in Thumb-2 state: Ps, Pt, Pu, Pv, Pw, Px
;; The following memory constraints have been used:
......@@ -154,6 +154,11 @@
(match_test "TARGET_THUMB1
&& ival > 1020 && ival <= 1275")))
(define_constraint "Pd"
"@internal In Thumb-1 state a constant in the range 0 to 7"
(and (match_code "const_int")
(match_test "TARGET_THUMB1 && ival >= 0 && ival <= 7")))
(define_constraint "Ps"
"@internal In Thumb-2 state a constant in the range -255 to +255"
(and (match_code "const_int")
......
......@@ -235,6 +235,9 @@
(define_special_predicate "lt_ge_comparison_operator"
(match_code "lt,ge"))
(define_special_predicate "noov_comparison_operator"
(match_code "lt,ge,eq,ne"))
(define_special_predicate "minmax_operator"
(and (match_code "smin,smax,umin,umax")
(match_test "mode == GET_MODE (op)")))
......
......@@ -99,8 +99,8 @@ along with GCC; see the file COPYING3. If not see
#include "sdbout.h"
#endif
/* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a
null default for it to save conditionalization later. */
/* Most ports that aren't using cc0 don't need to define CC_STATUS_INIT.
So define a null default for it to save conditionalization later. */
#ifndef CC_STATUS_INIT
#define CC_STATUS_INIT
#endif
......@@ -2039,9 +2039,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif
}
}
#ifdef HAVE_cc0
CC_STATUS_INIT;
#endif
if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
debug_hooks->label (insn);
......
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