aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha/alpha.md')
-rw-r--r--gcc/config/alpha/alpha.md65
1 files changed, 43 insertions, 22 deletions
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 9961617a3dc..cafee4453e7 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -4276,6 +4276,20 @@
}
}")
+(define_insn "*call_osf_1_noreturn"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
+ (match_operand 1 "" ""))
+ (clobber (reg:DI 27))
+ (clobber (reg:DI 26))]
+ "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS
+ && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ "@
+ jsr $26,($27),0
+ bsr $26,$%0..ng
+ jsr $26,%0"
+ [(set_attr "type" "jsr")
+ (set_attr "length" "*,*,8")])
+
(define_insn "*call_osf_1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
(match_operand 1 "" ""))
@@ -4659,7 +4673,7 @@
"
{
alpha_split_tfmode_pair (operands);
- if (rtx_equal_p (operands[0], operands[3]))
+ if (reg_overlap_mentioned_p (operands[0], operands[3]))
{
rtx tmp;
tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
@@ -4717,7 +4731,7 @@
st%, %R1,%0"
[(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-(define_insn "*movsf_fix"
+(define_insn "*movsi_fix"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
"! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
@@ -5886,22 +5900,6 @@
DONE;
}")
-(define_expand "eh_epilogue"
- [(use (match_operand:DI 0 "register_operand" "r"))
- (use (match_operand:DI 1 "register_operand" "r"))
- (use (match_operand:DI 2 "register_operand" "r"))]
- "! TARGET_OPEN_VMS"
- "
-{
- cfun->machine->eh_epilogue_sp_ofs = operands[1];
- if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
- {
- rtx ra = gen_rtx_REG (Pmode, 26);
- emit_move_insn (ra, operands[2]);
- operands[2] = ra;
- }
-}")
-
;; In creating a large stack frame, NT _must_ use ldah+lda to load
;; the frame size into a register. We use this pattern to ensure
;; we get lda instead of addq.
@@ -5961,13 +5959,36 @@
[(set_attr "length" "12")
(set_attr "type" "multi")])
-(define_insn "exception_receiver"
- [(unspec_volatile [(const_int 0)] 7)]
+(define_expand "exception_receiver"
+ [(unspec_volatile [(match_dup 0)] 7)]
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
- "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
- [(set_attr "length" "12")
+ "
+{
+ if (TARGET_LD_BUGGY_LDGP)
+ operands[0] = alpha_gp_save_rtx ();
+ else
+ operands[0] = const0_rtx;
+}")
+
+(define_insn "*exception_receiver_1"
+ [(unspec_volatile [(const_int 0)] 7)]
+ "! TARGET_LD_BUGGY_LDGP"
+ "ldgp $29,0($26)"
+ [(set_attr "length" "8")
(set_attr "type" "multi")])
+;; ??? We don't represent the usage of $29 properly in address loads
+;; and function calls. This leads to the following move being deleted
+;; as dead code unless it is represented as a volatile unspec.
+
+(define_insn "*exception_receiver_2"
+ [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")] 7)]
+ "TARGET_LD_BUGGY_LDGP"
+ "@
+ mov %0,$29
+ ldq $29,%0"
+ [(set_attr "type" "ilog,ild")])
+
(define_expand "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] 1)
(set (reg:DI 27) (mem:DI (reg:DI 29)))