diff options
Diffstat (limited to 'gcc/config/ia64/ia64.md')
-rw-r--r-- | gcc/config/ia64/ia64.md | 223 |
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")]) |