From 39ee7fa95535337ab8e7a0423f3cf00c1bd4ea84 Mon Sep 17 00:00:00 2001 From: Olivier Hainque Date: Thu, 6 Mar 2003 01:32:29 +0100 Subject: [PATCH] alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '+'. * config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '+'. * config/alpha/alpha.c (print_operand, case '+'): New. * config/alpha/alpha.md (call_osf_1_noreturn): Document and use. (call_value_osf_1_noreturn): Likewise. From-SVN: r63882 --- gcc/ChangeLog | 7 +++++++ gcc/config/alpha/alpha.c | 7 +++++++ gcc/config/alpha/alpha.h | 5 ++++- gcc/config/alpha/alpha.md | 22 ++++++++++++++++------ 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8a7b8b3f6c5..5d76f719e8f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Wed Mar 5 19:34:18 2003 Olivier Hainque + + * config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '+'. + * config/alpha/alpha.c (print_operand, case '+'): New. + * config/alpha/alpha.md (call_osf_1_noreturn): Document and use. + (call_value_osf_1_noreturn): Likewise. + Wed Mar 5 18:55:02 2003 Richard Kenner * stmt.c (fixup_gotos): Change meaning of DONT_JUMP_IN. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index c21656df0b4..28b98735bf2 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -5916,6 +5916,13 @@ print_operand (file, x, code) fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file); break; + case '+': + /* Generates a nop after a noreturn call at the very end of the + function. */ + if (next_real_insn (current_output_insn) == 0) + fprintf (file, "\n\tnop"); + break; + case '#': if (alpha_this_literal_sequence_number == 0) alpha_this_literal_sequence_number = alpha_next_sequence_number++; diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 2c79fa8e935..27f28228fcb 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1720,11 +1720,14 @@ do { \ - Generates double precision suffix for floating point instructions (t for IEEE, g for VAX) + + + Generates a nop instruction after a noreturn call at the very end + of the function */ #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ ((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \ - || (CODE) == '#' || (CODE) == '*' || (CODE) == '&') + || (CODE) == '#' || (CODE) == '*' || (CODE) == '&' || (CODE) == '+') /* Print a memory address as an operand to reference that memory location. */ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 2d5285a688b..667464175f8 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -4687,6 +4687,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" "jsr $26,(%0),%2%J3" [(set_attr "type" "jsr")]) +;; We output a nop after noreturn calls at the very end of the function to +;; ensure that the return address always remains in the caller's code range, +;; as not doing so might confuse unwinding engines. +;; +;; The potential change in insn length is not reflected in the length +;; attributes at this stage. Since the extra space is only actually added at +;; the very end of the compilation process (via final/print_operand), it +;; really seems harmless and not worth the trouble of some extra computation +;; cost and complexity. + (define_insn "*call_osf_1_noreturn" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) (match_operand 1 "" "")) @@ -4695,9 +4705,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && find_reg_note (insn, REG_NORETURN, NULL_RTX)" "@ - jsr $26,($27),0 - bsr $26,$%0..ng - jsr $26,%0" + jsr $26,($27),0%+ + bsr $26,$%0..ng%+ + jsr $26,%0%+" [(set_attr "type" "jsr") (set_attr "length" "*,*,8")]) @@ -7920,9 +7930,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && find_reg_note (insn, REG_NORETURN, NULL_RTX)" "@ - jsr $26,($27),0 - bsr $26,$%1..ng - jsr $26,%1" + jsr $26,($27),0%+ + bsr $26,$%1..ng%+ + jsr $26,%1%+" [(set_attr "type" "jsr") (set_attr "length" "*,*,8")]) -- 2.30.2