This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[5/6, committed] RTP PIC support for MIPS VxWorks
- From: Richard Sandiford <richard at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 12 Apr 2007 18:55:02 +0100
- Subject: [5/6, committed] RTP PIC support for MIPS VxWorks
- References: <87mz1dtt4y.fsf@firetop.home>
The final patch adds an instance of:
get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM);
The %call* patterns also insist on using $25, and in rare cases
this can lead to spill failure.
>From a conceptual point of view, the requirement of the %call*
patterns to use $25 is bogus: the pattern can handle any GPR.
It is the constraints on the call, not the load, that should
cause $25 to be preferred. After all, if a call address is
loaded using a non-%call sequence, nothing forces that load
to use $25.
Or so goes the theory. As it turns out, the constraints
on the return value of a call instruction cause regclass
to assign a maximum cost to every alternative. I remember
reading this comment in regrename.c years ago:
/* ??? Many targets have output constraints on the SET_DEST
of a call insn, which is stupid, since these are certainly
ABI defined hard registers. [...] */
and I suddenly have reason to believe it ;)
Removing the constraints on the return value allow the constraints
on the address to have their desired effect. Thus calls to local
functions will now tend to load the address directly into $25
where possible.
Tested on mips64-linux-gnu and mips-wrs-vxworks. Applied to trunk.
Richard
gcc/
* config/mips/mips.md (load_call<mode>): Allow any general register.
destination.
(sibcall_value_internal, sibcall_value_multiple_internal)
(call_value_internal, call_value_split, call_value_multiple_internal)
(call_value_multiple_split): Remove constraints from operand 0.
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-04-12 09:54:35.000000000 +0100
+++ gcc/config/mips/mips.md 2007-04-12 09:56:04.000000000 +0100
@@ -5139,7 +5139,7 @@ (define_insn_and_split "exception_receiv
;; we tell the target-independent code that the address could be changed
;; by any call insn.
(define_insn "load_call<mode>"
- [(set (match_operand:P 0 "register_operand" "=c")
+ [(set (match_operand:P 0 "register_operand" "=d")
(unspec:P [(match_operand:P 1 "register_operand" "r")
(match_operand:P 2 "immediate_operand" "")
(reg:P FAKE_CALL_REGNO)]
@@ -5194,7 +5194,7 @@ (define_expand "sibcall_value"
})
(define_insn "sibcall_value_internal"
- [(set (match_operand 0 "register_operand" "=df,df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
(match_operand 2 "" "")))]
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
@@ -5202,10 +5202,10 @@ (define_insn "sibcall_value_internal"
[(set_attr "type" "call")])
(define_insn "sibcall_value_multiple_internal"
- [(set (match_operand 0 "register_operand" "=df,df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "j,S"))
(match_operand 2 "" "")))
- (set (match_operand 3 "register_operand" "=df,df")
+ (set (match_operand 3 "register_operand" "")
(call (mem:SI (match_dup 1))
(match_dup 2)))]
"TARGET_SIBCALLS && SIBLING_CALL_P (insn)"
@@ -5300,7 +5300,7 @@ (define_expand "call_value"
;; See comment for call_internal.
(define_insn_and_split "call_value_internal"
- [(set (match_operand 0 "register_operand" "=df,df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
(match_operand 2 "" "")))
(clobber (reg:SI 31))]
@@ -5319,7 +5319,7 @@ (define_insn_and_split "call_value_inter
(set_attr "extended_mips16" "no,yes")])
(define_insn "call_value_split"
- [(set (match_operand 0 "register_operand" "=df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
(match_operand 2 "" "")))
(clobber (reg:SI 31))
@@ -5330,10 +5330,10 @@ (define_insn "call_value_split"
;; See comment for call_internal.
(define_insn_and_split "call_value_multiple_internal"
- [(set (match_operand 0 "register_operand" "=df,df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
(match_operand 2 "" "")))
- (set (match_operand 3 "register_operand" "=df,df")
+ (set (match_operand 3 "register_operand" "")
(call (mem:SI (match_dup 1))
(match_dup 2)))
(clobber (reg:SI 31))]
@@ -5352,10 +5352,10 @@ (define_insn_and_split "call_value_multi
(set_attr "extended_mips16" "no,yes")])
(define_insn "call_value_multiple_split"
- [(set (match_operand 0 "register_operand" "=df")
+ [(set (match_operand 0 "register_operand" "")
(call (mem:SI (match_operand 1 "call_insn_operand" "cS"))
(match_operand 2 "" "")))
- (set (match_operand 3 "register_operand" "=df")
+ (set (match_operand 3 "register_operand" "")
(call (mem:SI (match_dup 1))
(match_dup 2)))
(clobber (reg:SI 31))