aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/ia64/ia64.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/ia64/ia64.md')
-rw-r--r--gcc/config/ia64/ia64.md223
1 files changed, 153 insertions, 70 deletions
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index c2275494c25..4d177c21aed 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -83,6 +83,7 @@
(UNSPECV_SET_BSP 4)
(UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls
(UNSPECV_PSAC_NORMAL 6)
+ (UNSPECV_SETJMP_RECEIVER 7)
])
;; ::::::::::::::::::::
@@ -506,22 +507,41 @@
(define_expand "load_symptr"
[(set (match_operand:DI 2 "register_operand" "")
- (plus:DI (match_dup 4) (match_operand:DI 1 "got_symbolic_operand" "")))
- (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
+ (plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" ""))
+ (match_dup 3)))
+ (set (match_operand:DI 0 "register_operand" "")
+ (lo_sum:DI (match_dup 2) (match_dup 1)))]
""
{
- operands[3] = gen_rtx_MEM (DImode, operands[2]);
- operands[4] = pic_offset_table_rtx;
- RTX_UNCHANGING_P (operands[3]) = 1;
+ operands[3] = pic_offset_table_rtx;
})
-(define_insn "*load_symptr_internal1"
+(define_insn "*load_symptr_high"
[(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (reg:DI 1) (match_operand 1 "got_symbolic_operand" "s")))]
+ (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
+ (match_operand:DI 2 "register_operand" "a")))]
""
- "addl %0 = @ltoff(%1), gp"
+{
+ if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
+ return "%,addl %0 = @ltoffx(%1), %2";
+ else
+ return "%,addl %0 = @ltoff(%1), %2";
+}
[(set_attr "itanium_class" "ialu")])
+(define_insn "*load_symptr_low"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand 2 "got_symbolic_operand" "s")))]
+ ""
+{
+ if (HAVE_AS_LTOFFX_LDXMOV_RELOCS)
+ return "%,ld8.mov %0 = [%1], %2";
+ else
+ return "%,ld8 %0 = [%1]";
+}
+ [(set_attr "itanium_class" "ld")])
+
(define_insn "load_ltoff_dtpmod"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (reg:DI 1)
@@ -1034,7 +1054,7 @@
[(set (match_operand:DF 0 "register_operand" "=f")
(float:DF (match_operand:DI 1 "register_operand" "f")))]
"!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;fnorm.d %0 = %0"
+ "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
[(set_attr "itanium_class" "fcvtfx")])
;; ??? Suboptimal. This should be split somehow.
@@ -1042,7 +1062,7 @@
[(set (match_operand:SF 0 "register_operand" "=f")
(float:SF (match_operand:DI 1 "register_operand" "f")))]
"!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;fnorm.s %0 = %0"
+ "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
[(set_attr "itanium_class" "fcvtfx")])
(define_insn "fix_truncsfdi2"
@@ -4424,9 +4444,9 @@
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:DI 2 "move_operand"
- "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
+ "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
(match_operand:DI 3 "move_operand"
- "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
+ "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4530,9 +4550,9 @@
[(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:SI 2 "move_operand"
- "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
+ "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO")
(match_operand:SI 3 "move_operand"
- "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
+ "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4663,7 +4683,7 @@
(use (match_operand 3 "" ""))]
""
{
- ia64_expand_call (NULL_RTX, operands[0], operands[2], 0);
+ ia64_expand_call (NULL_RTX, operands[0], operands[2], false);
DONE;
})
@@ -4674,7 +4694,7 @@
(use (match_operand 3 "" ""))]
""
{
- ia64_expand_call (NULL_RTX, operands[0], operands[2], 1);
+ ia64_expand_call (NULL_RTX, operands[0], operands[2], true);
DONE;
})
@@ -4693,7 +4713,7 @@
(use (match_operand 4 "" ""))]
""
{
- ia64_expand_call (operands[0], operands[1], operands[3], 0);
+ ia64_expand_call (operands[0], operands[1], operands[3], false);
DONE;
})
@@ -4705,7 +4725,7 @@
(use (match_operand 4 "" ""))]
""
{
- ia64_expand_call (operands[0], operands[1], operands[3], 1);
+ ia64_expand_call (operands[0], operands[1], operands[3], true);
DONE;
})
@@ -4737,59 +4757,125 @@
DONE;
})
-(define_insn "call_nopic"
- [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
- (match_operand 1 "" ""))
- (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
+(define_insn "call_nogp"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
+ (const_int 0))
+ (clobber (match_operand:DI 1 "register_operand" "=b,b"))]
""
- "br.call%+.many %2 = %0"
+ "br.call%+.many %1 = %0"
[(set_attr "itanium_class" "br,scall")])
-(define_insn "call_value_nopic"
+(define_insn "call_value_nogp"
[(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" "b,i"))
- (match_operand 2 "" "")))
- (clobber (match_operand:DI 3 "register_operand" "=b,b"))]
+ (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
+ (const_int 0)))
+ (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
""
- "br.call%+.many %3 = %1"
+ "br.call%+.many %2 = %1"
[(set_attr "itanium_class" "br,scall")])
-(define_insn "sibcall_nopic"
- [(call (mem:DI (match_operand:DI 0 "call_operand" "b,i"))
- (match_operand 1 "" ""))
- (use (match_operand:DI 2 "register_operand" "=b,b"))
- (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
+(define_insn "sibcall_nogp"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i"))
+ (const_int 0))]
""
"br%+.many %0"
[(set_attr "itanium_class" "br,scall")])
-(define_insn "call_pic"
- [(call (mem (match_operand 0 "call_operand" "b,i"))
- (match_operand 1 "" ""))
- (use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL))
- (clobber (match_operand:DI 2 "register_operand" "=b,b"))]
+(define_insn "call_gp"
+ [(call (mem (match_operand 0 "call_operand" "?r,i"))
+ (const_int 1))
+ (clobber (match_operand:DI 1 "register_operand" "=b,b"))
+ (clobber (match_scratch:DI 2 "=&r,X"))
+ (clobber (match_scratch:DI 3 "=b,X"))]
""
- "br.call%+.many %2 = %0"
+ "#"
[(set_attr "itanium_class" "br,scall")])
-(define_insn "call_value_pic"
+;; Irritatingly, we don't have access to INSN within the split body.
+;; See commentary in ia64_split_call as to why these aren't peep2.
+(define_split
+ [(call (mem (match_operand 0 "call_operand" ""))
+ (const_int 1))
+ (clobber (match_operand:DI 1 "register_operand" ""))
+ (clobber (match_scratch:DI 2 ""))
+ (clobber (match_scratch:DI 3 ""))]
+ "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(const_int 0)]
+{
+ ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
+ operands[3], true, false);
+ DONE;
+})
+
+(define_split
+ [(call (mem (match_operand 0 "call_operand" ""))
+ (const_int 1))
+ (clobber (match_operand:DI 1 "register_operand" ""))
+ (clobber (match_scratch:DI 2 ""))
+ (clobber (match_scratch:DI 3 ""))]
+ "reload_completed"
+ [(const_int 0)]
+{
+ ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2],
+ operands[3], false, false);
+ DONE;
+})
+
+(define_insn "call_value_gp"
[(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" "b,i"))
- (match_operand 2 "" "")))
- (use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL))
- (clobber (match_operand:DI 3 "register_operand" "=b,b"))]
+ (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
+ (const_int 1)))
+ (clobber (match_operand:DI 2 "register_operand" "=b,b"))
+ (clobber (match_scratch:DI 3 "=&r,X"))
+ (clobber (match_scratch:DI 4 "=b,X"))]
""
- "br.call%+.many %3 = %1"
+ "#"
[(set_attr "itanium_class" "br,scall")])
-(define_insn "sibcall_pic"
- [(call (mem:DI (match_operand:DI 0 "call_operand" "bi"))
- (match_operand 1 "" ""))
- (use (unspec [(reg:DI 1)] UNSPEC_PIC_CALL))
- (use (match_operand:DI 2 "register_operand" "=b"))
- (use (match_operand:DI 3 "ar_pfs_reg_operand" ""))]
+(define_split
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" ""))
+ (const_int 1)))
+ (clobber (match_operand:DI 2 "register_operand" ""))
+ (clobber (match_scratch:DI 3 ""))
+ (clobber (match_scratch:DI 4 ""))]
+ "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
+ [(const_int 0)]
+{
+ ia64_split_call (operands[0], operands[1], operands[2], operands[3],
+ operands[4], true, false);
+ DONE;
+})
+
+(define_split
+ [(set (match_operand 0 "" "")
+ (call (mem:DI (match_operand:DI 1 "call_operand" ""))
+ (const_int 1)))
+ (clobber (match_operand:DI 2 "register_operand" ""))
+ (clobber (match_scratch:DI 3 ""))
+ (clobber (match_scratch:DI 4 ""))]
+ "reload_completed"
+ [(const_int 0)]
+{
+ ia64_split_call (operands[0], operands[1], operands[2], operands[3],
+ operands[4], false, false);
+ DONE;
+})
+
+(define_insn_and_split "sibcall_gp"
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
+ (const_int 1))
+ (clobber (match_scratch:DI 1 "=&r,X"))
+ (clobber (match_scratch:DI 2 "=b,X"))]
""
- "br%+.many %0"
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+{
+ ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1],
+ operands[2], true, true);
+ DONE;
+}
[(set_attr "itanium_class" "br")])
(define_insn "return_internal"
@@ -5040,7 +5126,10 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))]
""
- ";;\;mov %0 = ar.bsp"
+ "*
+{
+ return \";;\;%,mov %0 = ar.bsp\";
+}"
[(set_attr "itanium_class" "frar_i")])
(define_insn "set_bsp"
@@ -5073,7 +5162,8 @@
[(unspec [(const_int 0)] UNSPEC_FLUSHRS)]
""
";;\;flushrs\;;;"
- [(set_attr "itanium_class" "rse_m")])
+ [(set_attr "itanium_class" "rse_m")
+ (set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -5243,21 +5333,14 @@
DONE;
})
-;; The rest of the setjmp processing happens with the nonlocal_goto expander.
-;; ??? This is not tested.
-(define_expand "builtin_setjmp_setup"
- [(use (match_operand:DI 0 "" ""))]
- ""
-{
- emit_move_insn (ia64_gp_save_reg (0), gen_rtx_REG (DImode, GR_REG (1)));
- DONE;
-})
-
-(define_expand "builtin_setjmp_receiver"
- [(use (match_operand:DI 0 "" ""))]
+(define_insn_and_split "builtin_setjmp_receiver"
+ [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)]
""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
{
- emit_move_insn (gen_rtx_REG (DImode, GR_REG (1)), ia64_gp_save_reg (0));
+ ia64_reload_gp ();
DONE;
})
@@ -5348,7 +5431,7 @@
(set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
(unspec:SI [(match_dup 1)
(match_operand:SI 2 "gr_register_operand" "r")
- (match_operand:SI 3 "ar_ccv_reg_operand" "")]
+ (match_operand 3 "ar_ccv_reg_operand" "")]
UNSPEC_CMPXCHG_ACQ))]
""
"cmpxchg4.acq %0 = %1, %2, %3"
@@ -5438,7 +5521,7 @@
[(plus:SI (match_operand:SI 1 "basereg_operand" "r")
(match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))]
UNSPEC_ADDP4))]
- ""
+ "addp4_optimize_ok (operands[1], operands[2])"
"addp4 %0 = %2, %1"
[(set_attr "itanium_class" "ialu")])
@@ -5448,6 +5531,6 @@
[(plus:SI (match_operand:SI 1 "gr_register_operand" "r")
(match_operand:SI 2 "basereg_operand" "r"))]
UNSPEC_ADDP4))]
- ""
+ "addp4_optimize_ok (operands[1], operands[2])"
"addp4 %0 = %1, %2"
[(set_attr "itanium_class" "ialu")])