Sameera Deshpande <sameera.deshpande@arm.com>
Greta Yorsh <greta.yorsh@arm.com>
+ * config/arm/arm-protos.h (output_return_instruction): New parameter and
+ int to bool change of parameter types.
+ * config/arm/arm.c (output_return_instruction): Likewise.
+ * config/arm/arm.md (arm_simple_return): New pattern.
+ (arm_return, cond_return, cond_return_inverted): Add new arguments.
+ * config/arm/thumb2.md (thumb2_return): Update condition and code.
+
+2012-06-18 Ian Bolton <ian.bolton@arm.com>
+ Sameera Deshpande <sameera.deshpande@arm.com>
+ Greta Yorsh <greta.yorsh@arm.com>
+
* config/arm/arm-protos.h (arm_expand_epilogue): New declaration.
* config/arm/arm.c (arm_expand_epilogue): New function.
* config/arm/arm.md (epilogue): Update condition and code.
extern const char *output_add_immediate (rtx *);
extern const char *arithmetic_instr (rtx, int);
extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
-extern const char *output_return_instruction (rtx, int, int);
+extern const char *output_return_instruction (rtx, bool, bool, bool);
extern void arm_poke_function_name (FILE *, const char *);
extern void arm_final_prescan_insn (rtx);
extern int arm_debugger_arg_offset (int, rtx);
/* Generate a function exit sequence. If REALLY_RETURN is false, then do
- everything bar the final return instruction. */
+ everything bar the final return instruction. If simple_return is true,
+ then do not output epilogue, because it has already been emitted in RTL. */
const char *
-output_return_instruction (rtx operand, int really_return, int reverse)
+output_return_instruction (rtx operand, bool really_return, bool reverse,
+ bool simple_return)
{
char conditional[10];
char instr[100];
offsets = arm_get_frame_offsets ();
live_regs_mask = offsets->saved_regs_mask;
- if (live_regs_mask)
+ if (!simple_return && live_regs_mask)
{
const char * return_reg;
{
/* The return has already been handled
by loading the LR into the PC. */
- really_return = 0;
+ return "";
}
}
arm_ccfsm_state += 2;
return \"\";
}
- return output_return_instruction (const_true_rtx, TRUE, FALSE);
+ return output_return_instruction (const_true_rtx, true, false, false);
}"
[(set_attr "type" "load1")
(set_attr "length" "12")
arm_ccfsm_state += 2;
return \"\";
}
- return output_return_instruction (operands[0], TRUE, FALSE);
+ return output_return_instruction (operands[0], true, false, false);
}"
[(set_attr "conds" "use")
(set_attr "length" "12")
arm_ccfsm_state += 2;
return \"\";
}
- return output_return_instruction (operands[0], TRUE, TRUE);
+ return output_return_instruction (operands[0], true, true, false);
}"
[(set_attr "conds" "use")
(set_attr "length" "12")
(set_attr "type" "load1")]
)
+(define_insn "*arm_simple_return"
+ [(simple_return)]
+ "TARGET_ARM"
+ "*
+ {
+ if (arm_ccfsm_state == 2)
+ {
+ arm_ccfsm_state += 2;
+ return \"\";
+ }
+ return output_return_instruction (const_true_rtx, true, false, true);
+ }"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")
+ (set_attr "predicable" "yes")]
+)
+
;; Generate a sequence of instructions to determine if the processor is
;; in 26-bit or 32-bit mode, and return the appropriate return address
;; mask.
(set_attr "length" "20")]
)
-;; Note: this is not predicable, to avoid issues with linker-generated
-;; interworking stubs.
(define_insn "*thumb2_return"
- [(return)]
- "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)"
- "*
- {
- return output_return_instruction (const_true_rtx, TRUE, FALSE);
- }"
- [(set_attr "type" "load1")
- (set_attr "length" "12")]
+ [(simple_return)]
+ "TARGET_THUMB2"
+ "* return output_return_instruction (const_true_rtx, true, false, true);"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")]
)
(define_insn_and_split "thumb2_eh_return"