This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: gcs fix for internal error on Winnt/Alpha
- To: bob at guiduck dot com
- Subject: Re: gcs fix for internal error on Winnt/Alpha
- From: Richard Henderson <rth at cygnus dot com>
- Date: Thu, 13 Nov 1997 13:51:53 -0800
- Cc: egcs at cygnus dot com, law at cygnus dot com
- References: <346A07F7.4440@guiduck.com>
- Reply-To: Richard Henderson <rth at cygnus dot com>
On Wed, Nov 12, 1997 at 11:48:07AM -0800, bob wrote:
> (call_insn 49 48 52 (parallel[
> (call (mem:DI (reg:DI 83))
> (reg:DI 27 $27))
> (clobber (reg:DI 26 $26))
> ] ) -1 (nil)
> (nil)
> (nil))
Here's a patch as we discussed re call patterns and the trampoline.
r~
Thu Nov 13 13:45:39 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.
Index: alpha.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.c,v
retrieving revision 1.10.2.1
diff -u -p -d -r1.10.2.1 alpha.c
--- alpha.c 1997/11/04 21:15:42 1.10.2.1
+++ alpha.c 1997/11/13 21:42:18
@@ -525,7 +525,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: alpha.md
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.12.2.1
diff -u -p -d -r1.12.2.1 alpha.md
--- alpha.md 1997/11/04 21:15:45 1.12.2.1
+++ alpha.md 1997/11/13 21:42:19
@@ -3102,22 +3102,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]);
}")
;;
@@ -3215,7 +3210,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))])]
""
@@ -3224,13 +3219,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"
@@ -3292,13 +3282,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 ""
@@ -3328,14 +3319,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 ""
Index: win-nt.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/win-nt.h,v
retrieving revision 1.1.1.1
diff -u -p -d -r1.1.1.1 win-nt.h
--- win-nt.h 1997/08/11 15:57:21 1.1.1.1
+++ win-nt.h 1997/11/13 21:42:19
@@ -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)); \
+}