Fix from Richard Earnshaw to make MASK_RETURN_ADDR work on both 26-bit and
32-bit ARMs, switching at run time.
This commit is contained in:
parent
73322f1e45
commit
7bdb61e034
|
@ -5397,6 +5397,18 @@ output_return_instruction (operand, really_return, reverse)
|
|||
return "";
|
||||
}
|
||||
|
||||
/* Generate a sequence of insns that will generate the correct return
|
||||
address mask depending on the physical architecture that the program
|
||||
is running on. */
|
||||
rtx
|
||||
arm_gen_return_addr_mask ()
|
||||
{
|
||||
rtx reg = gen_reg_rtx (Pmode);
|
||||
|
||||
emit_insn (gen_return_addr_mask (reg));
|
||||
return reg;
|
||||
}
|
||||
|
||||
/* Return nonzero if optimizing and the current function is volatile.
|
||||
Such functions never return, and many memory cycles can be saved
|
||||
by not storing register values that will never be needed again.
|
||||
|
|
|
@ -2117,12 +2117,16 @@ do { \
|
|||
|
||||
/* Used to mask out junk bits from the return address, such as
|
||||
processor state, interrupt status, condition codes and the like. */
|
||||
#define MASK_RETURN_ADDR \
|
||||
#define MASK_RETURN_ADDR \
|
||||
/* If we are generating code for an ARM2/ARM3 machine or for an ARM6 \
|
||||
in 26 bit mode, the condition codes must be masked out of the \
|
||||
return address. This does not apply to ARM6 and later processors \
|
||||
when running in 32 bit mode. */ \
|
||||
((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff)))
|
||||
when running in 32 bit mode, but if we are not targeting archv4 \
|
||||
or later, assume this may be ARM2/3 running in 32-bit compatible \
|
||||
code mode. */ \
|
||||
((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) \
|
||||
: arm_arch4 ? (GEN_INT (0xffffffff)) \
|
||||
: arm_gen_return_addr_mask ())
|
||||
|
||||
/* The remainder of this file is only needed for building the compiler
|
||||
itself, not for the collateral. */
|
||||
|
@ -2221,6 +2225,7 @@ int arm_gen_movstrqi PROTO ((Rtx *));
|
|||
Rtx gen_rotated_half_load PROTO ((Rtx));
|
||||
Mmode arm_select_cc_mode RTX_CODE_PROTO ((Rcode, Rtx, Rtx));
|
||||
Rtx gen_compare_reg RTX_CODE_PROTO ((Rcode, Rtx, Rtx, int));
|
||||
Rtx arm_gen_return_addr_mask PROTO ((void));
|
||||
void arm_reload_in_hi PROTO ((Rtx *));
|
||||
void arm_reload_out_hi PROTO ((Rtx *));
|
||||
void arm_reorg PROTO ((Rtx));
|
||||
|
|
|
@ -4323,6 +4323,29 @@
|
|||
[(set_attr "conds" "use")
|
||||
(set_attr "type" "load")])
|
||||
|
||||
(define_expand "return_addr_mask"
|
||||
[(set (match_dup 1)
|
||||
(compare:CC_NOOV (unspec [(const_int 0)] 4)
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(if_then_else:SI (eq (match_dup 1) (const_int 0))
|
||||
(const_int -1)
|
||||
(const_int 67108860)))] ; 0x03fffffc
|
||||
""
|
||||
"
|
||||
operands[1] = gen_rtx_REG (CC_NOOVmode, 24);
|
||||
")
|
||||
|
||||
(define_insn "*check_arch2"
|
||||
[(set (match_operand:CC_NOOV 0 "cc_register" "")
|
||||
(compare:CC_NOOV (unspec [(const_int 0)] 4)
|
||||
(const_int 0)))]
|
||||
""
|
||||
"teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "conds" "set")]
|
||||
)
|
||||
|
||||
;; Call subroutine returning any type.
|
||||
|
||||
(define_expand "untyped_call"
|
||||
|
|
Loading…
Reference in New Issue