alpha.c (call_operand): Any reg is valid for WinNT.
authorRichard Henderson <rth@cygnus.com>
Fri, 14 Nov 1997 14:23:25 +0000 (06:23 -0800)
committerJeff Law <law@gcc.gnu.org>
Fri, 14 Nov 1997 14:23:25 +0000 (07:23 -0700)
        * 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
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.md
gcc/config/alpha/win-nt.h

index 7f0ed57..fd2e24c 100644 (file)
@@ -1,3 +1,11 @@
+Fri Nov 14 07:24:20 1997  Richard Henderson  <rth@cygnus.com>
+
+       * 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++.
index db40afc..5bb64d4 100644 (file)
@@ -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
index 8fbb0e3..0694a6f 100644 (file)
 }")
 
 (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]);
 }")
 
 ;;
 
 (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))])]
   ""
     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"
   [(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 ""
   [(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 ""
index c831da4..768256e 100644 (file)
@@ -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));                  \
+}