diff options
Diffstat (limited to 'gnu/usr.bin/gcc')
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/alpha/alpha.c | 190 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/alpha/openbsd.h | 7 |
2 files changed, 122 insertions, 75 deletions
diff --git a/gnu/usr.bin/gcc/gcc/config/alpha/alpha.c b/gnu/usr.bin/gcc/gcc/config/alpha/alpha.c index 2f60fadcb38..e4fa8386c32 100644 --- a/gnu/usr.bin/gcc/gcc/config/alpha/alpha.c +++ b/gnu/usr.bin/gcc/gcc/config/alpha/alpha.c @@ -7106,96 +7106,136 @@ alpha_expand_prologue () Note that we are only allowed to adjust sp once in the prologue. */ - if (frame_size <= 32768) + if (flag_stack_check || STACK_CHECK_BUILTIN) { - if (frame_size > 4096) + if (frame_size <= 32768) { - int probed = 4096; - - do - emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK - ? -probed + 64 - : -probed))); - while ((probed += 8192) < frame_size); + if (frame_size > 4096) + { + int probed = 4096; + + do + emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK + ? -probed + 64 + : -probed))); + while ((probed += 8192) < frame_size); + + /* We only have to do this probe if we aren't saving + registers. */ + if (sa_size == 0 && probed + 4096 < frame_size) + emit_insn (gen_probe_stack (GEN_INT (-frame_size))); + } - /* We only have to do this probe if we aren't saving registers. */ - if (sa_size == 0 && probed + 4096 < frame_size) - emit_insn (gen_probe_stack (GEN_INT (-frame_size))); + if (frame_size != 0) + FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (TARGET_ABI_UNICOSMK + ? -frame_size + 64 + : -frame_size)))); } + else + { + /* Here we generate code to set R22 to SP + 4096 and set R23 to the + number of 8192 byte blocks to probe. We then probe each block + in the loop and then set SP to the proper location. If the + amount remaining is > 4096, we have to do one more probe if we + are not saving any registers. */ - if (frame_size != 0) - FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (TARGET_ABI_UNICOSMK - ? -frame_size + 64 - : -frame_size)))); - } - else - { - /* Here we generate code to set R22 to SP + 4096 and set R23 to the - number of 8192 byte blocks to probe. We then probe each block - in the loop and then set SP to the proper location. If the - amount remaining is > 4096, we have to do one more probe if we - are not saving any registers. */ + HOST_WIDE_INT blocks = (frame_size + 4096) / 8192; + HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; + rtx ptr = gen_rtx_REG (DImode, 22); + rtx count = gen_rtx_REG (DImode, 23); + rtx seq; - HOST_WIDE_INT blocks = (frame_size + 4096) / 8192; - HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; - rtx ptr = gen_rtx_REG (DImode, 22); - rtx count = gen_rtx_REG (DImode, 23); - rtx seq; + emit_move_insn (count, GEN_INT (blocks)); + emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, + GEN_INT (TARGET_ABI_UNICOSMK + ? 4096 - 64 : 4096))); - emit_move_insn (count, GEN_INT (blocks)); - emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, - GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096))); + /* Because of the difficulty in emitting a new basic block this + late in the compilation, generate the loop as a single insn. */ + emit_insn (gen_prologue_stack_probe_loop (count, ptr)); - /* Because of the difficulty in emitting a new basic block this - late in the compilation, generate the loop as a single insn. */ - emit_insn (gen_prologue_stack_probe_loop (count, ptr)); + if (leftover > 4096 && sa_size == 0) + { + rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover)); + MEM_VOLATILE_P (last) = 1; + emit_move_insn (last, const0_rtx); + } - if (leftover > 4096 && sa_size == 0) - { - rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover)); - MEM_VOLATILE_P (last) = 1; - emit_move_insn (last, const0_rtx); - } + if (TARGET_ABI_WINDOWS_NT) + { + /* For NT stack unwind (done by 'reverse execution'), it's + not OK to take the result of a loop, even though the value + is already in ptr, so we reload it via a single operation + and subtract it to sp. + + Yes, that's correct -- we have to reload the whole constant + into a temporary via ldah+lda then subtract from sp. To + ensure we get ldah+lda, we use a special pattern. */ + + HOST_WIDE_INT lo, hi; + lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; + hi = frame_size - lo; + + emit_move_insn (ptr, GEN_INT (hi)); + emit_insn (gen_nt_lda (ptr, GEN_INT (lo))); + seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, + ptr)); + } + else + { + seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, + GEN_INT (-leftover))); + } - if (TARGET_ABI_WINDOWS_NT) + /* This alternative is special, because the DWARF code cannot + possibly intuit through the loop above. So we invent this + note it looks at instead. */ + RTX_FRAME_RELATED_P (seq) = 1; + REG_NOTES (seq) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (TARGET_ABI_UNICOSMK + ? -frame_size + 64 + : -frame_size))), + REG_NOTES (seq)); + } + } + else + { + if (frame_size <= 32768) { - /* For NT stack unwind (done by 'reverse execution'), it's - not OK to take the result of a loop, even though the value - is already in ptr, so we reload it via a single operation - and subtract it to sp. - - Yes, that's correct -- we have to reload the whole constant - into a temporary via ldah+lda then subtract from sp. To - ensure we get ldah+lda, we use a special pattern. */ - - HOST_WIDE_INT lo, hi; - lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; - hi = frame_size - lo; - - emit_move_insn (ptr, GEN_INT (hi)); - emit_insn (gen_nt_lda (ptr, GEN_INT (lo))); - seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, - ptr)); + if (frame_size != 0) + FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (TARGET_ABI_UNICOSMK + ? -frame_size + 64 + : -frame_size)))); } else { - seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, - GEN_INT (-leftover))); + rtx count = gen_rtx_REG (DImode, 23); + rtx seq; + + emit_move_insn (count, GEN_INT (TARGET_ABI_UNICOSMK + ? -frame_size + 64 + : -frame_size)); + seq = emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, + count)); + + /* This alternative is special, because the DWARF code cannot + possibly intuit through the loop above. So we invent this + note it looks at instead. */ + RTX_FRAME_RELATED_P (seq) = 1; + REG_NOTES (seq) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (TARGET_ABI_UNICOSMK + ? -frame_size + 64 + : -frame_size))), + REG_NOTES (seq)); } - - /* This alternative is special, because the DWARF code cannot - possibly intuit through the loop above. So we invent this - note it looks at instead. */ - RTX_FRAME_RELATED_P (seq) = 1; - REG_NOTES (seq) - = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, stack_pointer_rtx, - gen_rtx_PLUS (Pmode, stack_pointer_rtx, - GEN_INT (TARGET_ABI_UNICOSMK - ? -frame_size + 64 - : -frame_size))), - REG_NOTES (seq)); } if (!TARGET_ABI_UNICOSMK) diff --git a/gnu/usr.bin/gcc/gcc/config/alpha/openbsd.h b/gnu/usr.bin/gcc/gcc/config/alpha/openbsd.h index d0175ef1615..7ba13cdd227 100644 --- a/gnu/usr.bin/gcc/gcc/config/alpha/openbsd.h +++ b/gnu/usr.bin/gcc/gcc/config/alpha/openbsd.h @@ -20,6 +20,9 @@ Boston, MA 02111-1307, USA. */ /* Controlling the compilation driver. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS) + /* alpha needs __start. */ #undef LINK_SPEC #define LINK_SPEC \ @@ -65,3 +68,7 @@ Boston, MA 02111-1307, USA. */ /* .set on alpha is not used to output labels. */ #undef SET_ASM_OP + +/* don't want no friggin' stack checks. */ +#undef STACK_CHECK_BUILTIN +#define STACK_CHECK_BUILTIN 0 |