diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-05 22:39:56 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-05 22:39:56 +0000 |
commit | 32a8f7479af35b16d9bb89514526ba5442fc72e0 (patch) | |
tree | 530fa030e24babd155a9fddf78cc18bc048ea0c1 /gcc/config/alpha | |
parent | 004e23c43c8caeb9121f6b03327f8d348104795a (diff) | |
download | gcc-32a8f7479af35b16d9bb89514526ba5442fc72e0.tar.gz |
* config/alpha/alpha.c (print_operand) [+]: Remove.
(alpha_end_function): Print nop if call at end of function.
* config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Remove +.
* config/alpha/alpha.md (UNSPEC_LDGP1): New.
(call_osf_1_er_noreturn, call_value_osf_1_er_noreturn): New.
(call_osf_2_er_nogp, call_value_osf_2_er_nogp): New.
(call_osf_2_er, call_value_osf_2_er): Merge the ldgp highpart into
the call pattern. Update peepholes to match.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123529 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/alpha')
-rw-r--r-- | gcc/config/alpha/alpha.c | 18 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 5 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 175 |
3 files changed, 118 insertions, 80 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 817aa479479..976111462c1 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -4990,13 +4990,6 @@ print_operand (FILE *file, rtx x, int 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++; @@ -8221,6 +8214,17 @@ alpha_expand_epilogue (void) void alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED) { + rtx insn; + + /* 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. */ + insn = get_last_insn (); + if (!INSN_P (insn)) + insn = prev_active_insn (insn); + if (GET_CODE (insn) == CALL_INSN) + output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL); + #if TARGET_ABI_OPEN_VMS alpha_write_linkage (file, fnname, decl); #endif diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 382fe120565..a52ae2c5727 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1363,14 +1363,11 @@ 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 2e9e1311405..7f323af83ea 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -26,6 +26,7 @@ (define_constants [(UNSPEC_ARG_HOME 0) + (UNSPEC_LDGP1 1) (UNSPEC_INSXH 2) (UNSPEC_MSKXH 3) (UNSPEC_CVTQL 4) @@ -4759,6 +4760,20 @@ emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]); }) +(define_insn "*call_osf_1_er_noreturn" + [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) + (match_operand 1 "" "")) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF + && find_reg_note (insn, REG_NORETURN, NULL_RTX)" + "@ + jsr $26,($27),0 + bsr $26,%0\t\t!samegp + ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#" + [(set_attr "type" "jsr") + (set_attr "length" "*,*,8")]) + (define_insn "*call_osf_1_er" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) (match_operand 1 "" "")) @@ -4785,10 +4800,10 @@ || find_reg_note (insn, REG_NORETURN, NULL_RTX))" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (use (reg:DI 29)) (use (match_dup 0)) - (use (match_dup 3))])] + (use (match_dup 3)) + (clobber (reg:DI 26))])] { if (CONSTANT_P (operands[0])) { @@ -4816,14 +4831,13 @@ || find_reg_note (insn, REG_NORETURN, NULL_RTX))" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1)) (use (match_dup 0)) - (use (match_dup 4))]) - (set (reg:DI 29) - (unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1)) - (set (reg:DI 29) - (unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))] + (use (match_dup 4)) + (clobber (reg:DI 26))]) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))] { if (CONSTANT_P (operands[0])) { @@ -4839,32 +4853,34 @@ operands[4] = const0_rtx; } operands[3] = GEN_INT (alpha_next_sequence_number++); + operands[5] = pic_offset_table_rtx; }) -;; We add a blockage unspec_volatile to prevent insns from moving down -;; from above the call to in between the call and the ldah gpdisp. +(define_insn "*call_osf_2_er_nogp" + [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) + (match_operand 1 "" "")) + (use (reg:DI 29)) + (use (match_operand 2 "" "")) + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "jsr $26,(%0),%2%J3" + [(set_attr "type" "jsr")]) (define_insn "*call_osf_2_er" [(call (mem:DI (match_operand:DI 0 "register_operand" "c")) (match_operand 1 "" "")) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (set (reg:DI 29) + (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")] + UNSPEC_LDGP1)) (use (match_operand 2 "" "")) - (use (match_operand 3 "const_int_operand" ""))] + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:DI 26))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" - "jsr $26,(%0),%2%J3" + "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4" [(set_attr "type" "jsr") - (set_attr "cannot_copy" "true")]) - -;; 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. + (set_attr "cannot_copy" "true") + (set_attr "length" "8")]) (define_insn "*call_osf_1_noreturn" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) @@ -4874,9 +4890,9 @@ "! 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")]) @@ -4893,8 +4909,6 @@ [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) -;; Note that the DEC assembler expands "jmp foo" with $at, which -;; doesn't do what we want. (define_insn "*sibcall_osf_1_er" [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) (match_operand 1 "" "")) @@ -4906,6 +4920,8 @@ [(set_attr "type" "jsr") (set_attr "length" "*,8")]) +;; Note that the DEC assembler expands "jmp foo" with $at, which +;; doesn't do what we want. (define_insn "*sibcall_osf_1" [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s")) (match_operand 1 "" "")) @@ -5070,10 +5086,6 @@ ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't ;; want to have to include pal.h in our .s file. -;; -;; Technically the type for call_pal is jsr, but we use that for determining -;; if we need a GP. Use ibr instead since it has the same EV5 scheduling -;; characteristics. (define_insn "imb" [(unspec_volatile [(const_int 0)] UNSPECV_IMB)] "" @@ -7925,6 +7937,21 @@ ;; The call patterns are at the end of the file because their ;; wildcard operand0 interferes with nice recognition. +(define_insn "*call_value_osf_1_er_noreturn" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) + (match_operand 2 "" ""))) + (use (reg:DI 29)) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF + && find_reg_note (insn, REG_NORETURN, NULL_RTX)" + "@ + jsr $26,($27),0 + bsr $26,%1\t\t!samegp + ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#" + [(set_attr "type" "jsr") + (set_attr "length" "*,*,8")]) + (define_insn "*call_value_osf_1_er" [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s")) @@ -7954,10 +7981,10 @@ [(parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) (match_dup 2))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (use (reg:DI 29)) (use (match_dup 1)) - (use (match_dup 4))])] + (use (match_dup 4)) + (clobber (reg:DI 26))])] { if (CONSTANT_P (operands[1])) { @@ -7987,14 +8014,13 @@ [(parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) (match_dup 2))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (set (match_dup 6) + (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1)) (use (match_dup 1)) - (use (match_dup 5))]) - (set (reg:DI 29) - (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) - (set (reg:DI 29) - (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))] + (use (match_dup 5)) + (clobber (reg:DI 26))]) + (set (match_dup 6) + (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))] { if (CONSTANT_P (operands[1])) { @@ -8010,23 +8036,36 @@ operands[5] = const0_rtx; } operands[4] = GEN_INT (alpha_next_sequence_number++); + operands[6] = pic_offset_table_rtx; }) -;; We add a blockage unspec_volatile to prevent insns from moving down -;; from above the call to in between the call and the ldah gpdisp. -(define_insn "*call_value_osf_2_er" +(define_insn "*call_value_osf_2_er_nogp" [(set (match_operand 0 "" "") (call (mem:DI (match_operand:DI 1 "register_operand" "c")) (match_operand 2 "" ""))) - (set (reg:DI 26) - (plus:DI (pc) (const_int 4))) - (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE) + (use (reg:DI 29)) (use (match_operand 3 "" "")) - (use (match_operand 4 "" ""))] + (use (match_operand 4 "" "")) + (clobber (reg:DI 26))] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "jsr $26,(%1),%3%J4" + [(set_attr "type" "jsr")]) + +(define_insn "*call_value_osf_2_er" + [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "register_operand" "c")) + (match_operand 2 "" ""))) + (set (reg:DI 29) + (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")] + UNSPEC_LDGP1)) + (use (match_operand 3 "" "")) + (use (match_operand 4 "" "")) + (clobber (reg:DI 26))] + "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" + "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5" [(set_attr "type" "jsr") - (set_attr "cannot_copy" "true")]) + (set_attr "cannot_copy" "true") + (set_attr "length" "8")]) (define_insn "*call_value_osf_1_noreturn" [(set (match_operand 0 "" "") @@ -8037,9 +8076,9 @@ "! 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")]) @@ -8060,12 +8099,11 @@ (parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) (const_int 0))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) (use (match_dup 1)) - (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))]) - (set (match_dup 5) - (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) + (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL)) + (clobber (reg:DI 26))]) (set (match_dup 5) (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] { @@ -8092,14 +8130,13 @@ (parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) (const_int 0))) - (set (reg:DI 26) (plus:DI (pc) (const_int 4))) - (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1)) (use (match_dup 1)) - (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))]) - (set (reg:DI 29) - (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1)) - (set (reg:DI 29) - (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))] + (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL)) + (clobber (reg:DI 26))]) + (set (match_dup 5) + (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))] { operands[3] = gen_rtx_REG (Pmode, 27); operands[4] = GEN_INT (alpha_next_sequence_number++); |