From 202f590eca3f213c602c3422d9506787a3aaeb66 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 14 Nov 1997 06:23:25 -0800 Subject: [PATCH] alpha.c (call_operand): Any reg is valid for WinNT. * alpha.c (call_operand): Any reg is valid for WinNT. * alpha.md (call_nt, call_value_nt): Don't force address into $27. (anon nt calls): Add 'R' alternative. * alpha/win-nt.h (TRAMPOLINE_TEMPLATE, TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE): Handle lack of original $27 and 32-bit ptrs. From-SVN: r16487 --- gcc/ChangeLog | 8 +++++++ gcc/config/alpha/alpha.c | 3 ++- gcc/config/alpha/alpha.md | 36 ++++++++++++------------------ gcc/config/alpha/win-nt.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f0ed57..fd2e24c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Fri Nov 14 07:24:20 1997 Richard Henderson + + * alpha.c (call_operand): Any reg is valid for WinNT. + * alpha.md (call_nt, call_value_nt): Don't force address into $27. + (anon nt calls): Add 'R' alternative. + * alpha/win-nt.h (TRAMPOLINE_TEMPLATE, TRAMPOLINE_SIZE, + INITIALIZE_TRAMPOLINE): Handle lack of original $27 and 32-bit ptrs. + Fri Nov 14 06:59:33 1997 Jeffrey A Law (law@cygnus.com) * calls.c (expand_call): Handle pcc_struct_value correctly for C++. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index db40afc..5bb64d4 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -542,7 +542,8 @@ call_operand (op, mode) return 0; return (GET_CODE (op) == SYMBOL_REF - || (GET_CODE (op) == REG && (TARGET_OPEN_VMS || REGNO (op) == 27))); + || (GET_CODE (op) == REG + && (TARGET_OPEN_VMS || TARGET_WINDOWS_NT || REGNO (op) == 27))); } /* Return 1 if OP is a valid Alpha comparison operator. Here we know which diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 8fbb0e3..0694a6f 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -3216,22 +3216,17 @@ }") (define_expand "call_nt" - [(parallel [(call (mem:DI (match_operand:DI 0 "" "")) + [(parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" "")) (clobber (reg:DI 26))])] "" " { if (GET_CODE (operands[0]) != MEM) abort (); - operands[0] = XEXP (operands[0], 0); - if (GET_CODE (operands[1]) != SYMBOL_REF - && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27)) - { - rtx tem = gen_rtx (REG, DImode, 27); - emit_move_insn (tem, operands[1]); - operands[1] = tem; - } + operands[0] = XEXP (operands[0], 0); + if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG) + operands[0] = force_reg (DImode, operands[0]); }") ;; @@ -3329,7 +3324,7 @@ (define_expand "call_value_nt" [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_operand:DI 1 "" "")) + (call (mem:DI (match_operand 1 "" "")) (match_operand 2 "" ""))) (clobber (reg:DI 26))])] "" @@ -3338,13 +3333,8 @@ abort (); operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[1]) != SYMBOL_REF - && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27)) - { - rtx tem = gen_rtx (REG, DImode, 27); - emit_move_insn (tem, operands[1]); - operands[1] = tem; - } + if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG) + operands[1] = force_reg (DImode, operands[1]); }") (define_expand "call_value_vms" @@ -3406,13 +3396,14 @@ [(set_attr "type" "jsr")]) (define_insn "" - [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i")) + [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) (match_operand 1 "" "")) (clobber (reg:DI 26))] "TARGET_WINDOWS_NT" "@ jsr $26,(%0) - bsr $26,%0" + bsr $26,%0 + jsr $26,%0" [(set_attr "type" "jsr")]) (define_insn "" @@ -3442,14 +3433,15 @@ [(set_attr "type" "jsr")]) (define_insn "" - [(set (match_operand 0 "register_operand" "=rf,rf") - (call (mem:DI (match_operand:DI 1 "call_operand" "r,i")) + [(set (match_operand 0 "register_operand" "=rf,rf,rf") + (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i")) (match_operand 2 "" ""))) (clobber (reg:DI 26))] "TARGET_WINDOWS_NT" "@ jsr $26,(%1) - bsr $26,%1" + bsr $26,%1 + jsr $26,%1" [(set_attr "type" "jsr")]) (define_insn "" diff --git a/gcc/config/alpha/win-nt.h b/gcc/config/alpha/win-nt.h index c831da4..768256e 100644 --- a/gcc/config/alpha/win-nt.h +++ b/gcc/config/alpha/win-nt.h @@ -70,3 +70,59 @@ Boston, MA 02111-1307, USA. */ %{!mwindows:-subsystem console -e _mainCRTStartup} \ %{mcrtmt:LIBCMT.LIB%s KERNEL32.LIB%s} %{!mcrtmt:LIBC.LIB%s KERNEL32.LIB%s} \ %{v}" + + +/* Output assembler code for a block containing the constant parts + of a trampoline, leaving space for the variable parts. + + The trampoline should set the static chain pointer to value placed + into the trampoline and should branch to the specified routine. */ + +#undef TRAMPOLINE_TEMPLATE +#define TRAMPOLINE_TEMPLATE(FILE) \ +{ \ + fprintf (FILE, "\tbr $27,$LTRAMPP\n"); \ + fprintf (FILE, "$LTRAMPP:\n\tldl $1,12($27)\n"); \ + fprintf (FILE, "\tldl $27,16($27)\n"); \ + fprintf (FILE, "\tjmp $31,($27),0\n"); \ + fprintf (FILE, "\t.long 0,0\n"); \ +} + +/* Length in units of the trampoline for entering a nested function. */ + +#undef TRAMPOLINE_SIZE +#define TRAMPOLINE_SIZE 24 + +/* Emit RTL insns to initialize the variable parts of a trampoline. + FNADDR is an RTX for the address of the function's pure code. + CXT is an RTX for the static chain value for the function. + + This differs from the standard version in that: + + We are not passed the current address in any register, and so have to + load it ourselves. + + We do not initialize the "hint" field because it only has an 8k + range and so the target is in range of something on the stack. + Omitting the hint saves a bogus branch-prediction cache line load. + + Always have an executable stack -- no need for a system call. + */ + +#undef INITIALIZE_TRAMPOLINE +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ +{ \ + rtx _addr, _val; \ + \ + _addr = memory_address (Pmode, plus_constant ((TRAMP), 16)); \ + _val = force_reg(Pmode, (FNADDR)); \ + emit_move_insn (gen_rtx (MEM, SImode, _addr), \ + gen_rtx (SUBREG, SImode, _val, 0)); \ + _addr = memory_address (Pmode, plus_constant ((TRAMP), 20)); \ + _val = force_reg(Pmode, (CXT)); \ + emit_move_insn (gen_rtx (MEM, SImode, _addr), \ + gen_rtx (SUBREG, SImode, _val, 0)); \ + \ + emit_insn (gen_rtx (UNSPEC_VOLATILE, VOIDmode, \ + gen_rtvec (1, const0_rtx), 0)); \ +} -- 2.7.4