This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARM, stack unwinding, and Firefox OS


On Thu, Apr 25, 2013 at 07:25:42PM -0700, Jed Davis wrote:
> I've attached a patch

Let's try that again....

--Jed

diff --git a/gcc-4.4.3/gcc/config/arm/arm.c b/gcc-4.4.3/gcc/config/arm/arm.c
index bef07e3..ce6acf1 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.c
+++ b/gcc-4.4.3/gcc/config/arm/arm.c
@@ -1381,6 +1381,21 @@ arm_override_options (void)
       target_flags &= ~MASK_APCS_FRAME;
     }
 
+  if (TARGET_THUMB2_FAKE_APCS_FRAME && !(insn_flags & FL_THUMB2))
+    {
+      warning (0, "ignoring -mthumb2-fake-apcs-frame for non-Thumb2 target");
+      target_flags &= ~MASK_THUMB2_FAKE_APCS_FRAME;
+    }
+
+  if (TARGET_THUMB2_FAKE_APCS_FRAME && TARGET_ARM)
+    {
+      target_flags &= ~MASK_THUMB2_FAKE_APCS_FRAME;
+      if (!TARGET_APCS_FRAME)
+	{
+	  warning (0, "-mthumb2-fake-apcs-frame but not -mapcs-frame specified when compiling for ARM");
+	}
+    }
+
   /* Callee super interworking implies thumb interworking.  Adding
      this to the flags here simplifies the logic elsewhere.  */
   if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
@@ -12696,6 +12711,11 @@ arm_compute_save_reg_mask (void)
   if (cfun->machine->lr_save_eliminated)
     save_reg_mask &= ~ (1 << LR_REGNUM);
 
+  if (TARGET_THUMB2_FAKE_APCS_FRAME && (save_reg_mask & (1 << LR_REGNUM)))
+    save_reg_mask |=
+      (1 << ARM_HARD_FRAME_POINTER_REGNUM)
+      | (1 << IP_REGNUM);
+
   if (TARGET_REALLY_IWMMXT
       && ((bit_count (save_reg_mask)
 	   + ARM_NUM_INTS (crtl->args.pretend_args_size +
@@ -14506,6 +14526,15 @@ arm_expand_prologue (void)
 	  RTX_FRAME_RELATED_P (insn) = 1;
 	}
     }
+  else if (TARGET_THUMB2_FAKE_APCS_FRAME &&
+	   (offsets->saved_regs_mask & (1 << ARM_HARD_FRAME_POINTER_REGNUM))) {
+    rtx arm_fp_rtx = gen_raw_REG (Pmode, ARM_HARD_FRAME_POINTER_REGNUM);
+
+    insn = GEN_INT (saved_regs);
+    insn = emit_insn (gen_addsi3 (arm_fp_rtx, stack_pointer_rtx, insn));
+    /* This is not "frame-related", because it doesn't set the frame
+       pointer that a debugger would use to find things. */
+  }
 
   if (offsets->outgoing_args != offsets->saved_args + saved_regs)
     {
diff --git a/gcc-4.4.3/gcc/config/arm/arm.h b/gcc-4.4.3/gcc/config/arm/arm.h
index 1189914..d50525e 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.h
+++ b/gcc-4.4.3/gcc/config/arm/arm.h
@@ -837,11 +837,12 @@ extern int arm_structure_size_boundary;
      is an easy way of ensuring that it remains valid for all	\
      calls.  */							\
   if (TARGET_APCS_FRAME || TARGET_CALLER_INTERWORKING		\
-      || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME)		\
+      || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME		\
+      || TARGET_THUMB2_FAKE_APCS_FRAME)				\
     {								\
       fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;		\
       call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;	\
-      if (TARGET_CALLER_INTERWORKING)				\
+      if (TARGET_CALLER_INTERWORKING || TARGET_THUMB2_FAKE_APCS_FRAME) \
 	global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1;		\
     }								\
   SUBTARGET_CONDITIONAL_REGISTER_USAGE				\
diff --git a/gcc-4.4.3/gcc/config/arm/arm.opt b/gcc-4.4.3/gcc/config/arm/arm.opt
index 6aca395..5c8c0c1 100644
--- a/gcc-4.4.3/gcc/config/arm/arm.opt
+++ b/gcc-4.4.3/gcc/config/arm/arm.opt
@@ -37,6 +37,10 @@ mapcs-frame
 Target Report Mask(APCS_FRAME)
 Generate APCS conformant stack frames
 
+mthumb2-fake-apcs-frame
+Target Report Mask(THUMB2_FAKE_APCS_FRAME)
+Emulate APCS conformant stack frames in Thumb2 code
+
 mapcs-reentrant
 Target Report Mask(APCS_REENT)
 Generate re-entrant, PIC code

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]