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