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 @@ ...@@ -3,6 +3,40 @@
* postreload.c (reload_cse_simplify_operands): Take attribute enabled * postreload.c (reload_cse_simplify_operands): Take attribute enabled
into account. 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> 2010-08-02 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/arm.c (COSTS_N_INSNS): Remove definition. * config/arm/arm.c (COSTS_N_INSNS): Remove definition.
......
...@@ -687,6 +687,9 @@ int arm_tune_cortex_a9 = 0; ...@@ -687,6 +687,9 @@ int arm_tune_cortex_a9 = 0;
/* Nonzero if generating Thumb instructions. */ /* Nonzero if generating Thumb instructions. */
int thumb_code = 0; int thumb_code = 0;
/* Nonzero if generating Thumb-1 instructions. */
int thumb1_code = 0;
/* Nonzero if we should define __THUMB_INTERWORK__ in the /* Nonzero if we should define __THUMB_INTERWORK__ in the
preprocessor. preprocessor.
XXX This is a bit of a hack, it's intended to help work around 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; ...@@ -718,6 +721,7 @@ enum arm_pcs arm_pcs_default;
int arm_ccfsm_state; int arm_ccfsm_state;
/* arm_current_cc is also used for Thumb-2 cond_exec blocks. */ /* arm_current_cc is also used for Thumb-2 cond_exec blocks. */
enum arm_cond_code arm_current_cc; enum arm_cond_code arm_current_cc;
rtx arm_target_insn; rtx arm_target_insn;
int arm_target_label; int arm_target_label;
/* The number of conditionally executed insns, including the current insn. */ /* The number of conditionally executed insns, including the current insn. */
...@@ -1572,7 +1576,8 @@ arm_override_options (void) ...@@ -1572,7 +1576,8 @@ arm_override_options (void)
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0; arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_tune_strongarm = (tune_flags & FL_STRONG) != 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_wbuf = (tune_flags & FL_WBUF) != 0;
arm_tune_xscale = (tune_flags & FL_XSCALE) != 0; arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0; arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
...@@ -7682,12 +7687,26 @@ arm_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED) ...@@ -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); 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 static int
arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost) arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
{ {
rtx i_pat, d_pat; 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 /* Some true dependencies can have a higher cost depending
on precisely how certain input operands are used. */ on precisely how certain input operands are used. */
if (arm_tune_xscale if (arm_tune_xscale
...@@ -19475,13 +19494,44 @@ thumb_exit (FILE *f, int reg_containing_return_addr) ...@@ -19475,13 +19494,44 @@ thumb_exit (FILE *f, int reg_containing_return_addr)
asm_fprintf (f, "\tbx\t%r\n", 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 void
thumb1_final_prescan_insn (rtx insn) thumb1_final_prescan_insn (rtx insn)
{ {
if (flag_print_asm_name) if (flag_print_asm_name)
asm_fprintf (asm_out_file, "%@ 0x%04x\n", asm_fprintf (asm_out_file, "%@ 0x%04x\n",
INSN_ADDRESSES (INSN_UID (insn))); 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 int
......
...@@ -412,9 +412,12 @@ extern int arm_arch7em; ...@@ -412,9 +412,12 @@ extern int arm_arch7em;
/* Nonzero if this chip can benefit from load scheduling. */ /* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched; 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; extern int thumb_code;
/* Nonzero if generating Thumb-1 code. */
extern int thumb1_code;
/* Nonzero if this chip is a StrongARM. */ /* Nonzero if this chip is a StrongARM. */
extern int arm_tune_strongarm; extern int arm_tune_strongarm;
...@@ -1593,6 +1596,7 @@ typedef struct GTY(()) arm_stack_offsets ...@@ -1593,6 +1596,7 @@ typedef struct GTY(()) arm_stack_offsets
} }
arm_stack_offsets; arm_stack_offsets;
#ifndef GENERATOR_FILE
/* A C structure for machine-specific, per-function data. /* A C structure for machine-specific, per-function data.
This is added to the cfun structure. */ This is added to the cfun structure. */
typedef struct GTY(()) machine_function typedef struct GTY(()) machine_function
...@@ -1623,8 +1627,16 @@ 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 /* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */ is not needed. */
int return_used_this_function; 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; machine_function;
#endif
/* As in the machine_function, a global set of call-via labels, for code /* As in the machine_function, a global set of call-via labels, for code
that is in text_section. */ that is in text_section. */
...@@ -2259,6 +2271,9 @@ extern int making_const_table; ...@@ -2259,6 +2271,9 @@ extern int making_const_table;
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1) #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_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 #undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \ #define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
TARGET_THUMB2 ? "\t.thumb\n" : "") TARGET_THUMB2 ? "\t.thumb\n" : "")
......
...@@ -151,6 +151,9 @@ ...@@ -151,6 +151,9 @@
; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6. ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6"))) (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
;; Operand number of an input operand that is shifted. Zero if the ;; Operand number of an input operand that is shifted. Zero if the
;; given instruction does not shift one of its input operands. ;; given instruction does not shift one of its input operands.
(define_attr "shift" "" (const_int 0)) (define_attr "shift" "" (const_int 0))
...@@ -339,7 +342,9 @@ ...@@ -339,7 +342,9 @@
; output of this insn ; output of this insn
(define_attr "conds" "use,set,clob,unconditional,nocond" (define_attr "conds" "use,set,clob,unconditional,nocond"
(if_then_else (eq_attr "type" "call") (if_then_else
(ior (eq_attr "is_thumb1" "yes")
(eq_attr "type" "call"))
(const_string "clob") (const_string "clob")
(if_then_else (eq_attr "neon_type" "none") (if_then_else (eq_attr "neon_type" "none")
(const_string "nocond") (const_string "nocond")
...@@ -1080,14 +1085,14 @@ ...@@ -1080,14 +1085,14 @@
" "
) )
(define_insn "*thumb1_subsi3_insn" (define_insn "thumb1_subsi3_insn"
[(set (match_operand:SI 0 "register_operand" "=l") [(set (match_operand:SI 0 "register_operand" "=l")
(minus:SI (match_operand:SI 1 "register_operand" "l") (minus:SI (match_operand:SI 1 "register_operand" "l")
(match_operand:SI 2 "register_operand" "l")))] (match_operand:SI 2 "reg_or_int_operand" "lPd")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"sub\\t%0, %1, %2" "sub\\t%0, %1, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
; ??? Check Thumb-2 split length ; ??? Check Thumb-2 split length
(define_insn_and_split "*arm_subsi3_insn" (define_insn_and_split "*arm_subsi3_insn"
...@@ -1962,7 +1967,7 @@ ...@@ -1962,7 +1967,7 @@
operands[2] = force_reg (SImode, operands[2] = force_reg (SImode,
GEN_INT (~INTVAL (operands[2]))); GEN_INT (~INTVAL (operands[2])));
emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1])); emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
DONE; DONE;
} }
...@@ -2023,9 +2028,9 @@ ...@@ -2023,9 +2028,9 @@
(and:SI (match_operand:SI 1 "register_operand" "%0") (and:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "l")))] (match_operand:SI 2 "register_operand" "l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"and\\t%0, %0, %2" "and\\t%0, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_insn "*andsi3_compare0" (define_insn "*andsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM) [(set (reg:CC_NOOV CC_REGNUM)
...@@ -2564,14 +2569,14 @@ ...@@ -2564,14 +2569,14 @@
[(set_attr "predicable" "yes")] [(set_attr "predicable" "yes")]
) )
(define_insn "bicsi3" (define_insn "thumb1_bicsi3"
[(set (match_operand:SI 0 "register_operand" "=l") [(set (match_operand:SI 0 "register_operand" "=l")
(and:SI (not:SI (match_operand:SI 1 "register_operand" "l")) (and:SI (not:SI (match_operand:SI 1 "register_operand" "l"))
(match_operand:SI 2 "register_operand" "0")))] (match_operand:SI 2 "register_operand" "0")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"bic\\t%0, %0, %1" "bic\\t%0, %1"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_insn "andsi_not_shiftsi_si" (define_insn "andsi_not_shiftsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r") [(set (match_operand:SI 0 "s_register_operand" "=r")
...@@ -2706,14 +2711,14 @@ ...@@ -2706,14 +2711,14 @@
(set_attr "predicable" "yes")] (set_attr "predicable" "yes")]
) )
(define_insn "*thumb1_iorsi3" (define_insn "*thumb1_iorsi3_insn"
[(set (match_operand:SI 0 "register_operand" "=l") [(set (match_operand:SI 0 "register_operand" "=l")
(ior:SI (match_operand:SI 1 "register_operand" "%0") (ior:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "l")))] (match_operand:SI 2 "register_operand" "l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"orr\\t%0, %0, %2" "orr\\t%0, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_peephole2 (define_peephole2
[(match_scratch:SI 3 "r") [(match_scratch:SI 3 "r")
...@@ -2830,14 +2835,14 @@ ...@@ -2830,14 +2835,14 @@
[(set_attr "predicable" "yes")] [(set_attr "predicable" "yes")]
) )
(define_insn "*thumb1_xorsi3" (define_insn "*thumb1_xorsi3_insn"
[(set (match_operand:SI 0 "register_operand" "=l") [(set (match_operand:SI 0 "register_operand" "=l")
(xor:SI (match_operand:SI 1 "register_operand" "%0") (xor:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "l")))] (match_operand:SI 2 "register_operand" "l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"eor\\t%0, %0, %2" "eor\\t%0, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_insn "*xorsi3_compare0" (define_insn "*xorsi3_compare0"
[(set (reg:CC_NOOV CC_REGNUM) [(set (reg:CC_NOOV CC_REGNUM)
...@@ -3264,8 +3269,8 @@ ...@@ -3264,8 +3269,8 @@
(match_operand:SI 2 "nonmemory_operand" "N,l")))] (match_operand:SI 2 "nonmemory_operand" "N,l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"lsl\\t%0, %1, %2" "lsl\\t%0, %1, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_expand "ashrdi3" (define_expand "ashrdi3"
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
...@@ -3320,8 +3325,8 @@ ...@@ -3320,8 +3325,8 @@
(match_operand:SI 2 "nonmemory_operand" "N,l")))] (match_operand:SI 2 "nonmemory_operand" "N,l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"asr\\t%0, %1, %2" "asr\\t%0, %1, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_expand "lshrdi3" (define_expand "lshrdi3"
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
...@@ -3379,8 +3384,8 @@ ...@@ -3379,8 +3384,8 @@
(match_operand:SI 2 "nonmemory_operand" "N,l")))] (match_operand:SI 2 "nonmemory_operand" "N,l")))]
"TARGET_THUMB1" "TARGET_THUMB1"
"lsr\\t%0, %1, %2" "lsr\\t%0, %1, %2"
[(set_attr "length" "2")] [(set_attr "length" "2")
) (set_attr "conds" "set")])
(define_expand "rotlsi3" (define_expand "rotlsi3"
[(set (match_operand:SI 0 "s_register_operand" "") [(set (match_operand:SI 0 "s_register_operand" "")
...@@ -4029,7 +4034,7 @@ ...@@ -4029,7 +4034,7 @@
(define_split (define_split
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
(zero_extend:SI (match_operand:HI 1 "register_operand" "l,m")))] (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
"!TARGET_THUMB2 && !arm_arch6" "!TARGET_THUMB2 && !arm_arch6"
[(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
...@@ -5086,8 +5091,8 @@ ...@@ -5086,8 +5091,8 @@
mov\\t%0, %1" mov\\t%0, %1"
[(set_attr "length" "2,2,4,4,2,2,2,2,2") [(set_attr "length" "2,2,4,4,2,2,2,2,2")
(set_attr "type" "*,*,*,*,load1,store1,load1,store1,*") (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
(set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")] (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")
) (set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
(define_split (define_split
[(set (match_operand:SI 0 "register_operand" "") [(set (match_operand:SI 0 "register_operand" "")
...@@ -5635,8 +5640,8 @@ ...@@ -5635,8 +5640,8 @@
return \"ldrh %0, %1\"; return \"ldrh %0, %1\";
}" }"
[(set_attr "length" "2,4,2,2,2,2") [(set_attr "length" "2,4,2,2,2,2")
(set_attr "type" "*,load1,store1,*,*,*")] (set_attr "type" "*,load1,store1,*,*,*")
) (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
(define_expand "movhi_bytes" (define_expand "movhi_bytes"
...@@ -5869,8 +5874,8 @@ ...@@ -5869,8 +5874,8 @@
mov\\t%0, %1" mov\\t%0, %1"
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "type" "*,load1,store1,*,*,*") (set_attr "type" "*,load1,store1,*,*,*")
(set_attr "pool_range" "*,32,*,*,*,*")] (set_attr "pool_range" "*,32,*,*,*,*")
) (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
;; HFmode moves ;; HFmode moves
(define_expand "movhf" (define_expand "movhf"
...@@ -5970,8 +5975,8 @@ ...@@ -5970,8 +5975,8 @@
" "
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "type" "*,load1,store1,*,*") (set_attr "type" "*,load1,store1,*,*")
(set_attr "pool_range" "*,1020,*,*,*")] (set_attr "pool_range" "*,1020,*,*,*")
) (set_attr "conds" "clob,nocond,nocond,nocond,nocond")])
(define_expand "movsf" (define_expand "movsf"
[(set (match_operand:SF 0 "general_operand" "") [(set (match_operand:SF 0 "general_operand" "")
...@@ -6046,7 +6051,8 @@ ...@@ -6046,7 +6051,8 @@
mov\\t%0, %1" mov\\t%0, %1"
[(set_attr "length" "2") [(set_attr "length" "2")
(set_attr "type" "*,load1,store1,load1,store1,*,*") (set_attr "type" "*,load1,store1,load1,store1,*,*")
(set_attr "pool_range" "*,*,*,1020,*,*,*")] (set_attr "pool_range" "*,*,*,1020,*,*,*")
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
) )
(define_expand "movdf" (define_expand "movdf"
...@@ -6681,26 +6687,38 @@ ...@@ -6681,26 +6687,38 @@
(define_insn "cbranchsi4_insn" (define_insn "cbranchsi4_insn"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "arm_comparison_operator" (match_operator 0 "arm_comparison_operator"
[(match_operand:SI 1 "s_register_operand" "l,*h") [(match_operand:SI 1 "s_register_operand" "l,l*h")
(match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")]) (match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"TARGET_THUMB1" "TARGET_THUMB1"
"* {
rtx t = prev_nonnote_insn (insn); rtx t = cfun->machine->thumb1_cc_insn;
if (t != NULL_RTX if (t != NULL_RTX)
&& INSN_P (t) {
&& INSN_CODE (t) == CODE_FOR_cbranchsi4_insn) if (!rtx_equal_p (cfun->machine->thumb1_cc_op0, operands[1])
{ || !rtx_equal_p (cfun->machine->thumb1_cc_op1, operands[2]))
t = XEXP (SET_SRC (PATTERN (t)), 0); t = NULL_RTX;
if (!rtx_equal_p (XEXP (t, 0), operands[1]) if (cfun->machine->thumb1_cc_mode == CC_NOOVmode)
|| !rtx_equal_p (XEXP (t, 1), operands[2])) {
if (!noov_comparison_operator (operands[0], VOIDmode))
t = NULL_RTX; t = NULL_RTX;
} }
else else if (cfun->machine->thumb1_cc_mode != CCmode)
t = NULL_RTX; t = NULL_RTX;
}
if (t == NULL_RTX) if (t == NULL_RTX)
output_asm_insn (\"cmp\\t%1, %2\", operands); {
output_asm_insn ("cmp\t%1, %2", operands);
cfun->machine->thumb1_cc_insn = insn;
cfun->machine->thumb1_cc_op0 = operands[1];
cfun->machine->thumb1_cc_op1 = operands[2];
cfun->machine->thumb1_cc_mode = CCmode;
}
else
/* Ensure we emit the right type of condition code on the jump. */
XEXP (operands[0], 0) = gen_rtx_REG (cfun->machine->thumb1_cc_mode,
CC_REGNUM);
switch (get_attr_length (insn)) switch (get_attr_length (insn))
{ {
...@@ -6708,7 +6726,7 @@ ...@@ -6708,7 +6726,7 @@
case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
} }
" }
[(set (attr "far_jump") [(set (attr "far_jump")
(if_then_else (if_then_else
(eq_attr "length" "8") (eq_attr "length" "8")
...@@ -6762,69 +6780,8 @@ ...@@ -6762,69 +6780,8 @@
(const_int 8))))] (const_int 8))))]
) )
(define_insn "*movsi_cbranchsi4" ;; Two peepholes to generate subtract of 0 instead of a move if the
[(set (pc) ;; condition codes will be useful.
(if_then_else
(match_operator 3 "arm_comparison_operator"
[(match_operand:SI 1 "s_register_operand" "0,l,l,l")
(const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
(match_dup 1))]
"TARGET_THUMB1"
"*{
if (which_alternative == 0)
output_asm_insn (\"cmp\t%0, #0\", operands);
else if (which_alternative == 1)
output_asm_insn (\"sub\t%0, %1, #0\", operands);
else
{
output_asm_insn (\"cmp\t%1, #0\", operands);
if (which_alternative == 2)
output_asm_insn (\"mov\t%0, %1\", operands);
else
output_asm_insn (\"str\t%1, %0\", operands);
}
switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
{
case 4: return \"b%d3\\t%l2\";
case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else
(ior (and (gt (symbol_ref ("which_alternative"))
(const_int 1))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(le (symbol_ref ("which_alternative"))
(const_int 1))
(if_then_else
(and (ge (minus (match_dup 2) (pc)) (const_int -250))
(le (minus (match_dup 2) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 2) (pc)) (const_int -2040))
(le (minus (match_dup 2) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
(if_then_else
(and (ge (minus (match_dup 2) (pc)) (const_int -248))
(le (minus (match_dup 2) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 2) (pc)) (const_int -2038))
(le (minus (match_dup 2) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))))]
)
(define_peephole2 (define_peephole2
[(set (match_operand:SI 0 "low_register_operand" "") [(set (match_operand:SI 0 "low_register_operand" "")
(match_operand:SI 1 "low_register_operand" "")) (match_operand:SI 1 "low_register_operand" ""))
...@@ -6834,14 +6791,12 @@ ...@@ -6834,14 +6791,12 @@
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"TARGET_THUMB1" "TARGET_THUMB1"
[(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
[(set (pc) (set (pc)
(if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)]) (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
(label_ref (match_dup 3)) (label_ref (match_dup 3))
(pc))) (pc)))]
(set (match_dup 0) (match_dup 1))])] "")
""
)
;; Sigh! This variant shouldn't be needed, but combine often fails to ;; Sigh! This variant shouldn't be needed, but combine often fails to
;; merge cases like this because the op1 is a hard register in ;; merge cases like this because the op1 is a hard register in
...@@ -6855,14 +6810,12 @@ ...@@ -6855,14 +6810,12 @@
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"TARGET_THUMB1" "TARGET_THUMB1"
[(parallel [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
[(set (pc) (set (pc)
(if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)]) (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
(label_ref (match_dup 3)) (label_ref (match_dup 3))
(pc))) (pc)))]
(set (match_dup 0) (match_dup 1))])] "")
""
)
(define_insn "*negated_cbranchsi4" (define_insn "*negated_cbranchsi4"
[(set (pc) [(set (pc)
...@@ -7024,41 +6977,57 @@ ...@@ -7024,41 +6977,57 @@
(const_int 8))))] (const_int 8))))]
) )
(define_insn "*andsi3_cbranch" (define_insn "*cbranchne_decr1"
[(set (pc) [(set (pc)
(if_then_else (if_then_else (match_operator 3 "equality_operator"
(match_operator 5 "equality_operator" [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
[(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
(match_operand:SI 3 "s_register_operand" "l,l,l,l"))
(const_int 0)]) (const_int 0)])
(label_ref (match_operand 4 "" "")) (label_ref (match_operand 4 "" ""))
(pc))) (pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
(and:SI (match_dup 2) (match_dup 3))) (plus:SI (match_dup 2) (const_int -1)))
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))] (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
"TARGET_THUMB1" "TARGET_THUMB1"
"* "*
{ {
rtx cond[2];
cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
? GEU : LTU),
VOIDmode, operands[2], const1_rtx);
cond[1] = operands[4];
if (which_alternative == 0) if (which_alternative == 0)
output_asm_insn (\"and\\t%0, %3\", operands); output_asm_insn (\"sub\\t%0, %2, #1\", operands);
else if (which_alternative == 1) else if (which_alternative == 1)
{ {
output_asm_insn (\"and\\t%1, %3\", operands); /* We must provide an alternative for a hi reg because reload
cannot handle output reloads on a jump instruction, but we
can't subtract into that. Fortunately a mov from lo to hi
does not clobber the condition codes. */
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
output_asm_insn (\"mov\\t%0, %1\", operands); output_asm_insn (\"mov\\t%0, %1\", operands);
} }
else else
{ {
output_asm_insn (\"and\\t%1, %3\", operands); /* Similarly, but the target is memory. */
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
output_asm_insn (\"str\\t%1, %0\", operands); output_asm_insn (\"str\\t%1, %0\", operands);
} }
switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
{ {
case 4: return \"b%d5\\t%l4\"; case 4:
case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; output_asm_insn (\"b%d0\\t%l1\", cond);
default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; return \"\";
case 6:
output_asm_insn (\"b%D0\\t.LCB%=\", cond);
return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
default:
output_asm_insn (\"b%D0\\t.LCB%=\", cond);
return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
} }
}" }
"
[(set (attr "far_jump") [(set (attr "far_jump")
(if_then_else (if_then_else
(ior (and (eq (symbol_ref ("which_alternative")) (ior (and (eq (symbol_ref ("which_alternative"))
...@@ -7067,10 +7036,9 @@ ...@@ -7067,10 +7036,9 @@
(eq_attr "length" "10")) (eq_attr "length" "10"))
(const_string "yes") (const_string "yes")
(const_string "no"))) (const_string "no")))
(set (attr "length") (set_attr_alternative "length"
(if_then_else [
(eq (symbol_ref ("which_alternative")) ;; Alternative 0
(const_int 0))
(if_then_else (if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -250)) (and (ge (minus (match_dup 4) (pc)) (const_int -250))
(le (minus (match_dup 4) (pc)) (const_int 256))) (le (minus (match_dup 4) (pc)) (const_int 256)))
...@@ -7080,6 +7048,7 @@ ...@@ -7080,6 +7048,7 @@
(le (minus (match_dup 4) (pc)) (const_int 2048))) (le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6) (const_int 6)
(const_int 8))) (const_int 8)))
;; Alternative 1
(if_then_else (if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248)) (and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256))) (le (minus (match_dup 4) (pc)) (const_int 256)))
...@@ -7088,490 +7057,90 @@ ...@@ -7088,490 +7057,90 @@
(and (ge (minus (match_dup 4) (pc)) (const_int -2038)) (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048))) (le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8) (const_int 8)
(const_int 10)))))] (const_int 10)))
) ;; Alternative 2
(define_insn "*orrsi3_cbranch_scratch"
[(set (pc)
(if_then_else
(match_operator 4 "equality_operator"
[(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
(match_operand:SI 2 "s_register_operand" "l"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (match_scratch:SI 0 "=l"))]
"TARGET_THUMB1"
"*
{
output_asm_insn (\"orr\\t%0, %2\", operands);
switch (get_attr_length (insn))
{
case 4: return \"b%d4\\t%l3\";
case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else (if_then_else
(eq_attr "length" "8") (and (ge (minus (match_dup 4) (pc)) (const_int -248))
(const_string "yes") (le (minus (match_dup 4) (pc)) (const_int 256)))
(const_string "no"))) (const_int 6)
(set (attr "length")
(if_then_else (if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -250)) (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 3) (pc)) (const_int 256))) (le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 4) (const_int 8)
(const_int 10)))
;; Alternative 3
(if_then_else (if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -2040)) (and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 3) (pc)) (const_int 2048))) (le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6) (const_int 6)
(const_int 8))))] (if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))])]
) )
(define_insn "*orrsi3_cbranch" (define_insn "*addsi3_cbranch"
[(set (pc) [(set (pc)
(if_then_else (if_then_else
(match_operator 5 "equality_operator" (match_operator 4 "arm_comparison_operator"
[(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1") [(plus:SI
(match_operand:SI 3 "s_register_operand" "l,l,l,l")) (match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
(match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
(const_int 0)]) (const_int 0)])
(label_ref (match_operand 4 "" "")) (label_ref (match_operand 5 "" ""))
(pc))) (pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m") (set
(ior:SI (match_dup 2) (match_dup 3))) (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))] (plus:SI (match_dup 2) (match_dup 3)))
"TARGET_THUMB1" (clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
"TARGET_THUMB1
&& (GET_CODE (operands[4]) == EQ
|| GET_CODE (operands[4]) == NE
|| GET_CODE (operands[4]) == GE
|| GET_CODE (operands[4]) == LT)"
"* "*
{ {
if (which_alternative == 0) rtx cond[3];
output_asm_insn (\"orr\\t%0, %3\", operands);
else if (which_alternative == 1) cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
{ cond[1] = operands[2];
output_asm_insn (\"orr\\t%1, %3\", operands); cond[2] = operands[3];
output_asm_insn (\"mov\\t%0, %1\", operands);
} if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
else else
{ output_asm_insn (\"add\\t%0, %1, %2\", cond);
output_asm_insn (\"orr\\t%1, %3\", operands);
if (which_alternative >= 2
&& which_alternative < 4)
output_asm_insn (\"mov\\t%0, %1\", operands);
else if (which_alternative >= 4)
output_asm_insn (\"str\\t%1, %0\", operands); output_asm_insn (\"str\\t%1, %0\", operands);
}
switch (get_attr_length (insn) - (which_alternative ? 2 : 0)) switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
{ {
case 4: return \"b%d5\\t%l4\"; case 4:
case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\"; return \"b%d4\\t%l5\";
default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\"; case 6:
return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
default:
return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
} }
}" }
"
[(set (attr "far_jump") [(set (attr "far_jump")
(if_then_else (if_then_else
(ior (and (eq (symbol_ref ("which_alternative")) (ior (and (lt (symbol_ref ("which_alternative"))
(const_int 0)) (const_int 2))
(eq_attr "length" "8")) (eq_attr "length" "8"))
(eq_attr "length" "10")) (eq_attr "length" "10"))
(const_string "yes") (const_string "yes")
(const_string "no"))) (const_string "no")))
(set (attr "length") (set (attr "length")
(if_then_else (if_then_else
(eq (symbol_ref ("which_alternative")) (lt (symbol_ref ("which_alternative"))
(const_int 0)) (const_int 2))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -250))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))))]
)
(define_insn "*xorsi3_cbranch_scratch"
[(set (pc)
(if_then_else
(match_operator 4 "equality_operator"
[(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
(match_operand:SI 2 "s_register_operand" "l"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (match_scratch:SI 0 "=l"))]
"TARGET_THUMB1"
"*
{
output_asm_insn (\"eor\\t%0, %2\", operands);
switch (get_attr_length (insn))
{
case 4: return \"b%d4\\t%l3\";
case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else
(eq_attr "length" "8")
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -250))
(le (minus (match_dup 3) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8))))]
)
(define_insn "*xorsi3_cbranch"
[(set (pc)
(if_then_else
(match_operator 5 "equality_operator"
[(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
(match_operand:SI 3 "s_register_operand" "l,l,l,l"))
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
(xor:SI (match_dup 2) (match_dup 3)))
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
"TARGET_THUMB1"
"*
{
if (which_alternative == 0)
output_asm_insn (\"eor\\t%0, %3\", operands);
else if (which_alternative == 1)
{
output_asm_insn (\"eor\\t%1, %3\", operands);
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else
{
output_asm_insn (\"eor\\t%1, %3\", operands);
output_asm_insn (\"str\\t%1, %0\", operands);
}
switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
{
case 4: return \"b%d5\\t%l4\";
case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else
(ior (and (eq (symbol_ref ("which_alternative"))
(const_int 0))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(eq (symbol_ref ("which_alternative"))
(const_int 0))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -250))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))))]
)
(define_insn "*bicsi3_cbranch_scratch"
[(set (pc)
(if_then_else
(match_operator 4 "equality_operator"
[(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
(match_operand:SI 1 "s_register_operand" "0"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (match_scratch:SI 0 "=l"))]
"TARGET_THUMB1"
"*
{
output_asm_insn (\"bic\\t%0, %2\", operands);
switch (get_attr_length (insn))
{
case 4: return \"b%d4\\t%l3\";
case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else
(eq_attr "length" "8")
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -250))
(le (minus (match_dup 3) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8))))]
)
(define_insn "*bicsi3_cbranch"
[(set (pc)
(if_then_else
(match_operator 5 "equality_operator"
[(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
(match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
(and:SI (not:SI (match_dup 3)) (match_dup 2)))
(clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
"TARGET_THUMB1"
"*
{
if (which_alternative == 0)
output_asm_insn (\"bic\\t%0, %3\", operands);
else if (which_alternative <= 2)
{
output_asm_insn (\"bic\\t%1, %3\", operands);
/* It's ok if OP0 is a lo-reg, even though the mov will set the
conditions again, since we're only testing for equality. */
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else
{
output_asm_insn (\"bic\\t%1, %3\", operands);
output_asm_insn (\"str\\t%1, %0\", operands);
}
switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
{
case 4: return \"b%d5\\t%l4\";
case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
}
}"
[(set (attr "far_jump")
(if_then_else
(ior (and (eq (symbol_ref ("which_alternative"))
(const_int 0))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(eq (symbol_ref ("which_alternative"))
(const_int 0))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -250))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))))]
)
(define_insn "*cbranchne_decr1"
[(set (pc)
(if_then_else (match_operator 3 "equality_operator"
[(match_operand:SI 2 "s_register_operand" "l,l,1,l")
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
(plus:SI (match_dup 2) (const_int -1)))
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
"TARGET_THUMB1"
"*
{
rtx cond[2];
cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
? GEU : LTU),
VOIDmode, operands[2], const1_rtx);
cond[1] = operands[4];
if (which_alternative == 0)
output_asm_insn (\"sub\\t%0, %2, #1\", operands);
else if (which_alternative == 1)
{
/* We must provide an alternative for a hi reg because reload
cannot handle output reloads on a jump instruction, but we
can't subtract into that. Fortunately a mov from lo to hi
does not clobber the condition codes. */
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else
{
/* Similarly, but the target is memory. */
output_asm_insn (\"sub\\t%1, %2, #1\", operands);
output_asm_insn (\"str\\t%1, %0\", operands);
}
switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
{
case 4:
output_asm_insn (\"b%d0\\t%l1\", cond);
return \"\";
case 6:
output_asm_insn (\"b%D0\\t.LCB%=\", cond);
return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
default:
output_asm_insn (\"b%D0\\t.LCB%=\", cond);
return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
}
}
"
[(set (attr "far_jump")
(if_then_else
(ior (and (eq (symbol_ref ("which_alternative"))
(const_int 0))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set_attr_alternative "length"
[
;; Alternative 0
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -250))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
;; Alternative 1
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))
;; Alternative 2
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))
;; Alternative 3
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -248))
(le (minus (match_dup 4) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))])]
)
(define_insn "*addsi3_cbranch"
[(set (pc)
(if_then_else
(match_operator 4 "arm_comparison_operator"
[(plus:SI
(match_operand:SI 2 "s_register_operand" "%0,l,*l,1,1,1")
(match_operand:SI 3 "reg_or_int_operand" "IJ,lL,*l,lIJ,lIJ,lIJ"))
(const_int 0)])
(label_ref (match_operand 5 "" ""))
(pc)))
(set
(match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
(plus:SI (match_dup 2) (match_dup 3)))
(clobber (match_scratch:SI 1 "=X,X,l,l,&l,&l"))]
"TARGET_THUMB1
&& (GET_CODE (operands[4]) == EQ
|| GET_CODE (operands[4]) == NE
|| GET_CODE (operands[4]) == GE
|| GET_CODE (operands[4]) == LT)"
"*
{
rtx cond[3];
cond[0] = (which_alternative < 2) ? operands[0] : operands[1];
cond[1] = operands[2];
cond[2] = operands[3];
if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
else
output_asm_insn (\"add\\t%0, %1, %2\", cond);
if (which_alternative >= 2
&& which_alternative < 4)
output_asm_insn (\"mov\\t%0, %1\", operands);
else if (which_alternative >= 4)
output_asm_insn (\"str\\t%1, %0\", operands);
switch (get_attr_length (insn) - ((which_alternative >= 2) ? 2 : 0))
{
case 4:
return \"b%d4\\t%l5\";
case 6:
return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
default:
return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
}
}
"
[(set (attr "far_jump")
(if_then_else
(ior (and (lt (symbol_ref ("which_alternative"))
(const_int 2))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(lt (symbol_ref ("which_alternative"))
(const_int 2))
(if_then_else (if_then_else
(and (ge (minus (match_dup 5) (pc)) (const_int -250)) (and (ge (minus (match_dup 5) (pc)) (const_int -250))
(le (minus (match_dup 5) (pc)) (const_int 256))) (le (minus (match_dup 5) (pc)) (const_int 256)))
...@@ -7660,126 +7229,6 @@ ...@@ -7660,126 +7229,6 @@
(const_int 8))))] (const_int 8))))]
) )
(define_insn "*subsi3_cbranch"
[(set (pc)
(if_then_else
(match_operator 4 "arm_comparison_operator"
[(minus:SI
(match_operand:SI 2 "s_register_operand" "l,l,1,l")
(match_operand:SI 3 "s_register_operand" "l,l,l,l"))
(const_int 0)])
(label_ref (match_operand 5 "" ""))
(pc)))
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
(minus:SI (match_dup 2) (match_dup 3)))
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
"TARGET_THUMB1
&& (GET_CODE (operands[4]) == EQ
|| GET_CODE (operands[4]) == NE
|| GET_CODE (operands[4]) == GE
|| GET_CODE (operands[4]) == LT)"
"*
{
if (which_alternative == 0)
output_asm_insn (\"sub\\t%0, %2, %3\", operands);
else if (which_alternative == 1)
{
/* We must provide an alternative for a hi reg because reload
cannot handle output reloads on a jump instruction, but we
can't subtract into that. Fortunately a mov from lo to hi
does not clobber the condition codes. */
output_asm_insn (\"sub\\t%1, %2, %3\", operands);
output_asm_insn (\"mov\\t%0, %1\", operands);
}
else
{
/* Similarly, but the target is memory. */
output_asm_insn (\"sub\\t%1, %2, %3\", operands);
output_asm_insn (\"str\\t%1, %0\", operands);
}
switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
{
case 4:
return \"b%d4\\t%l5\";
case 6:
return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
default:
return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
}
}
"
[(set (attr "far_jump")
(if_then_else
(ior (and (eq (symbol_ref ("which_alternative"))
(const_int 0))
(eq_attr "length" "8"))
(eq_attr "length" "10"))
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(eq (symbol_ref ("which_alternative"))
(const_int 0))
(if_then_else
(and (ge (minus (match_dup 5) (pc)) (const_int -250))
(le (minus (match_dup 5) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 5) (pc)) (const_int -2040))
(le (minus (match_dup 5) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8)))
(if_then_else
(and (ge (minus (match_dup 5) (pc)) (const_int -248))
(le (minus (match_dup 5) (pc)) (const_int 256)))
(const_int 6)
(if_then_else
(and (ge (minus (match_dup 5) (pc)) (const_int -2038))
(le (minus (match_dup 5) (pc)) (const_int 2048)))
(const_int 8)
(const_int 10)))))]
)
(define_insn "*subsi3_cbranch_scratch"
[(set (pc)
(if_then_else
(match_operator 0 "arm_comparison_operator"
[(minus:SI (match_operand:SI 1 "register_operand" "l")
(match_operand:SI 2 "nonmemory_operand" "l"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_THUMB1
&& (GET_CODE (operands[0]) == EQ
|| GET_CODE (operands[0]) == NE
|| GET_CODE (operands[0]) == GE
|| GET_CODE (operands[0]) == LT)"
"*
output_asm_insn (\"cmp\\t%1, %2\", operands);
switch (get_attr_length (insn))
{
case 4: return \"b%d0\\t%l3\";
case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
}
"
[(set (attr "far_jump")
(if_then_else
(eq_attr "length" "8")
(const_string "yes")
(const_string "no")))
(set (attr "length")
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -250))
(le (minus (match_dup 3) (pc)) (const_int 256)))
(const_int 4)
(if_then_else
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
(const_int 8))))]
)
;; Comparison and test insns ;; Comparison and test insns
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
;; The following multi-letter normal constraints have been used: ;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di ;; 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 ;; in Thumb-2 state: Ps, Pt, Pu, Pv, Pw, Px
;; The following memory constraints have been used: ;; The following memory constraints have been used:
...@@ -154,6 +154,11 @@ ...@@ -154,6 +154,11 @@
(match_test "TARGET_THUMB1 (match_test "TARGET_THUMB1
&& ival > 1020 && ival <= 1275"))) && 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" (define_constraint "Ps"
"@internal In Thumb-2 state a constant in the range -255 to +255" "@internal In Thumb-2 state a constant in the range -255 to +255"
(and (match_code "const_int") (and (match_code "const_int")
......
...@@ -235,6 +235,9 @@ ...@@ -235,6 +235,9 @@
(define_special_predicate "lt_ge_comparison_operator" (define_special_predicate "lt_ge_comparison_operator"
(match_code "lt,ge")) (match_code "lt,ge"))
(define_special_predicate "noov_comparison_operator"
(match_code "lt,ge,eq,ne"))
(define_special_predicate "minmax_operator" (define_special_predicate "minmax_operator"
(and (match_code "smin,smax,umin,umax") (and (match_code "smin,smax,umin,umax")
(match_test "mode == GET_MODE (op)"))) (match_test "mode == GET_MODE (op)")))
......
...@@ -99,8 +99,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -99,8 +99,8 @@ along with GCC; see the file COPYING3. If not see
#include "sdbout.h" #include "sdbout.h"
#endif #endif
/* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a /* Most ports that aren't using cc0 don't need to define CC_STATUS_INIT.
null default for it to save conditionalization later. */ So define a null default for it to save conditionalization later. */
#ifndef CC_STATUS_INIT #ifndef CC_STATUS_INIT
#define CC_STATUS_INIT #define CC_STATUS_INIT
#endif #endif
...@@ -2039,9 +2039,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, ...@@ -2039,9 +2039,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
#endif #endif
} }
} }
#ifdef HAVE_cc0
CC_STATUS_INIT; CC_STATUS_INIT;
#endif
if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn)) if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
debug_hooks->label (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