From 68121397dfcf2c390c53a49a7cad768c097d1ada Mon Sep 17 00:00:00 2001 From: thorpej Date: Fri, 6 Sep 2002 14:54:48 +0000 Subject: [PATCH] * config/arm/arm-protos.h (arm_gen_return_addr_mask): New prototype. * config/arm/arm.c (arm_gen_return_addr_mask): New function. * config/arm/arm.h (MASK_RETURN_ADDR): Use arm_gen_return_addr_mask if not APCS26 and not Thumb or ARMv4-or-higher. Use gen_int_mode rather than GEN_INT. * config/arm/arm.md (UNSPEC_CHECK_ARCH): Define. (return_addr_mask, *check_arch2): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56883 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/arm/arm-protos.h | 1 + gcc/config/arm/arm.c | 13 +++++++++++++ gcc/config/arm/arm.h | 6 ++++-- gcc/config/arm/arm.md | 28 ++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b352d17c60d..815e75ba140 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2002-09-06 Jason Thorpe + + * config/arm/arm-protos.h (arm_gen_return_addr_mask): New + prototype. + * config/arm/arm.c (arm_gen_return_addr_mask): New function. + * config/arm/arm.h (MASK_RETURN_ADDR): Use arm_gen_return_addr_mask + if not APCS26 and not Thumb or ARMv4-or-higher. Use gen_int_mode + rather than GEN_INT. + * config/arm/arm.md (UNSPEC_CHECK_ARCH): Define. + (return_addr_mask, *check_arch2): New. + 2002-09-06 Ulrich Weigand * config/s390/s390.md ("*adddi3_cc", "*adddi3_cconly", diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index dbd950616c2..b4e65c24d93 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -107,6 +107,7 @@ extern int arm_gen_movstrqi PARAMS ((rtx *)); extern rtx arm_gen_rotated_half_load PARAMS ((rtx)); extern enum machine_mode arm_select_cc_mode PARAMS ((RTX_CODE, rtx, rtx)); extern rtx arm_gen_compare_reg PARAMS ((RTX_CODE, rtx, rtx)); +extern rtx arm_gen_return_addr_mask PARAMS ((void)); extern void arm_reload_in_hi PARAMS ((rtx *)); extern void arm_reload_out_hi PARAMS ((rtx *)); extern void arm_reorg PARAMS ((rtx)); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 93c571dd534..e5667649895 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -4914,6 +4914,19 @@ arm_gen_compare_reg (code, x, y) return cc_reg; } +/* 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; +} + void arm_reload_in_hi (operands) rtx * operands; diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index ce1961ddf05..e282d5c75a8 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2753,8 +2753,10 @@ extern int making_const_table; 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 (RETURN_ADDR_MASK26)) \ - : (GEN_INT ((unsigned long)0xffffffff))) + ((!TARGET_APCS_32) ? (gen_int_mode (RETURN_ADDR_MASK26, Pmode)) \ + : (arm_arch4 || TARGET_THUMB) ? \ + (gen_int_mode ((unsigned long)0xffffffff, Pmode)) \ + : arm_gen_return_addr_mask ()) /* Define the codes that are matched by predicates in arm.c */ diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 9dee56538e4..15fbde73f04 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -69,6 +69,7 @@ ; instructions setting registers for EH handling ; and stack frame generation. Operand 0 is the ; register to "use". + (UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode. ] ) @@ -6797,6 +6798,33 @@ (set_attr "type" "load")] ) +;; 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. + +(define_expand "return_addr_mask" + [(set (match_dup 1) + (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) + (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 + "TARGET_ARM" + " + 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)] UNSPEC_CHECK_ARCH) + (const_int 0)))] + "TARGET_ARM" + "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" -- 2.11.4.GIT