X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fia64%2Fia64.md;h=18e6cb3ace6445481f629c67bac81daeadc245b5;hb=7a979707f55fcaf9f028bba6c7a39dd169329dd3;hp=4b9a4b95b3227131fef6ed8ec771f9642483d3b4;hpb=e265a6da77f2623966ed1a19d1ab6b809ec97fef;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 4b9a4b95b32..18e6cb3ace6 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -1,5 +1,5 @@ ;; IA-64 Machine description template -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 ;; Free Software Foundation, Inc. ;; Contributed by James E. Wilson and ;; David Mosberger . @@ -18,8 +18,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. @@ -56,6 +56,7 @@ (UNSPEC_DTPREL 2) (UNSPEC_LTOFF_TPREL 3) (UNSPEC_TPREL 4) + (UNSPEC_DTPMOD 5) (UNSPEC_LD_BASE 9) (UNSPEC_GR_SPILL 10) @@ -77,6 +78,9 @@ (UNSPEC_RET_ADDR 26) (UNSPEC_SETF_EXP 27) (UNSPEC_FR_SQRT_RECIP_APPROX 28) + (UNSPEC_SHRP 29) + (UNSPEC_COPYSIGN 30) + (UNSPEC_VECT_EXTR 31) ]) (define_constants @@ -89,342 +93,8 @@ (UNSPECV_PSAC_NORMAL 6) (UNSPECV_SETJMP_RECEIVER 7) ]) - -;; :::::::::::::::::::: -;; :: -;; :: Predicates -;; :: -;; :::::::::::::::::::: - -;; True if OP is a valid operand for the MEM of a CALL insn. -(define_predicate "call_operand" - (ior (match_code "symbol_ref") - (match_operand 0 "register_operand"))) - -;; True if OP refers to any kind of symbol. -;; For roughly the same reasons that pmode_register_operand exists, this -;; predicate ignores its mode argument. -(define_special_predicate "symbolic_operand" - (match_code "symbol_ref,const,label_ref")) - -;; True if OP is a SYMBOL_REF which refers to a function. -(define_predicate "function_operand" - (and (match_code "symbol_ref") - (match_test "SYMBOL_REF_FUNCTION_P (op)"))) - -;; True if OP refers to a symbol, and is appropriate for a GOT load. -(define_predicate "got_symbolic_operand" - (match_operand 0 "symbolic_operand" "") -{ - switch (GET_CODE (op)) - { - case LABEL_REF: - return true; - - case SYMBOL_REF: - /* This sort of load should not be used for things in sdata. */ - return !SYMBOL_REF_SMALL_ADDR_P (op); - - case CONST: - /* Accept only (plus (symbol_ref) (const_int)). */ - op = XEXP (op, 0); - if (GET_CODE (op) != PLUS - || GET_CODE (XEXP (op, 0)) != SYMBOL_REF - || GET_CODE (XEXP (op, 1)) != CONST_INT) - return false; - - /* Ok if we're not using GOT entries at all. */ - if (TARGET_NO_PIC || TARGET_AUTO_PIC) - return true; - - /* The low 14 bits of the constant have been forced to zero - by ia64_expand_load_address, so that we do not use up so - many GOT entries. Prevent cse from undoing this. */ - op = XEXP (op, 1); - return (INTVAL (op) & 0x3fff) == 0; - - default: - abort (); - } -}) - -;; True if OP refers to a symbol in the sdata section. -(define_predicate "sdata_symbolic_operand" - (match_code "symbol_ref,const") -{ - switch (GET_CODE (op)) - { - case CONST: - op = XEXP (op, 0); - if (GET_CODE (op) != PLUS - || GET_CODE (XEXP (op, 0)) != SYMBOL_REF) - return false; - op = XEXP (op, 0); - /* FALLTHRU */ - - case SYMBOL_REF: - if (CONSTANT_POOL_ADDRESS_P (op)) - return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold; - else - return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op); - - default: - abort (); - } -}) - -;; Like nonimmediate_operand, but don't allow MEMs that try to use a -;; POST_MODIFY with a REG as displacement. -(define_predicate "destination_operand" - (and (match_operand 0 "nonimmediate_operand") - (match_test "GET_CODE (op) != MEM - || GET_CODE (XEXP (op, 0)) != POST_MODIFY - || GET_CODE (XEXP (XEXP (XEXP (op, 0), 1), 1)) != REG"))) - -;; Like memory_operand, but don't allow post-increments. -(define_predicate "not_postinc_memory_operand" - (and (match_operand 0 "memory_operand") - (match_test "GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != RTX_AUTOINC"))) - -;; True if OP is a general operand, excluding tls symbolic operands. -(define_predicate "move_operand" - (and (match_operand 0 "general_operand") - (not (match_test - "GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (op)")))) - -;; True if OP is a register operand that is (or could be) a GR reg. -(define_predicate "gr_register_operand" - (match_operand 0 "register_operand") -{ - unsigned int regno; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno)); -}) - -;; True if OP is a register operand that is (or could be) an FR reg. -(define_predicate "fr_register_operand" - (match_operand 0 "register_operand") -{ - unsigned int regno; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER || FR_REGNO_P (regno)); -}) - -;; True if OP is a register operand that is (or could be) a GR/FR reg. -(define_predicate "grfr_register_operand" - (match_operand 0 "register_operand") -{ - unsigned int regno; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER - || GENERAL_REGNO_P (regno) - || FR_REGNO_P (regno)); -}) - -;; True if OP is a nonimmediate operand that is (or could be) a GR reg. -(define_predicate "gr_nonimmediate_operand" - (match_operand 0 "nonimmediate_operand") -{ - unsigned int regno; - - if (GET_CODE (op) == MEM) - return true; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno)); -}) - -;; True if OP is a nonimmediate operand that is (or could be) a FR reg. -(define_predicate "fr_nonimmediate_operand" - (match_operand 0 "nonimmediate_operand") -{ - unsigned int regno; - - if (GET_CODE (op) == MEM) - return true; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER || FR_REGNO_P (regno)); -}) - -;; True if OP is a nonimmediate operand that is (or could be) a GR/FR reg. -(define_predicate "grfr_nonimmediate_operand" - (match_operand 0 "nonimmediate_operand") -{ - unsigned int regno; - - if (GET_CODE (op) == MEM) - return true; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - - regno = REGNO (op); - return (regno >= FIRST_PSEUDO_REGISTER - || GENERAL_REGNO_P (regno) - || FR_REGNO_P (regno)); -}) - -;; True if OP is a GR register operand, or zero. -(define_predicate "gr_reg_or_0_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "op == const0_rtx")))) - -;; True if OP is a GR register operand, or a 5 bit immediate operand. -(define_predicate "gr_reg_or_5bit_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "INTVAL (op) >= 0 && INTVAL (op) < 32")))) - -;; True if OP is a GR register operand, or a 6 bit immediate operand. -(define_predicate "gr_reg_or_6bit_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_M (INTVAL (op))")))) - -;; True if OP is a GR register operand, or an 8 bit immediate operand. -(define_predicate "gr_reg_or_8bit_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_K (INTVAL (op))")))) - -;; True if OP is a GR/FR register operand, or an 8 bit immediate operand. -(define_predicate "grfr_reg_or_8bit_operand" - (ior (match_operand 0 "grfr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_K (INTVAL (op))")))) - -;; True if OP is a register operand, or an 8 bit adjusted immediate operand. -(define_predicate "gr_reg_or_8bit_adjusted_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_L (INTVAL (op))")))) - -;; True if OP is a register operand, or is valid for both an 8 bit -;; immediate and an 8 bit adjusted immediate operand. This is necessary -;; because when we emit a compare, we don't know what the condition will be, -;; so we need the union of the immediates accepted by GT and LT. -(define_predicate "gr_reg_or_8bit_and_adjusted_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_K (INTVAL (op)) - && CONST_OK_FOR_L (INTVAL (op))")))) - -;; True if OP is a register operand, or a 14 bit immediate operand. -(define_predicate "gr_reg_or_14bit_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_I (INTVAL (op))")))) - -;; True if OP is a register operand, or a 22 bit immediate operand. -(define_predicate "gr_reg_or_22bit_operand" - (ior (match_operand 0 "gr_register_operand") - (and (match_code "const_int") - (match_test "CONST_OK_FOR_J (INTVAL (op))")))) - -;; True if OP is a 6 bit immediate operand. -(define_predicate "shift_count_operand" - (and (match_code "const_int") - (match_test "CONST_OK_FOR_M (INTVAL (op))"))) - -;; True if OP is a 5 bit immediate operand. -(define_predicate "shift_32bit_count_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) >= 0 && INTVAL (op) < 32"))) - -;; True if OP is one of the immediate valuse 2, 4, 8, or 16. -(define_predicate "shladd_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) == 2 || INTVAL (op) == 4 || - INTVAL (op) == 8 || INTVAL (op) == 16"))) - -;; True if OP is one of the immediate values -16, -8, -4, -1, 1, 4, 8, 16. -(define_predicate "fetchadd_operand" - (and (match_code "const_int") - (match_test "INTVAL (op) == -16 || INTVAL (op) == -8 || - INTVAL (op) == -4 || INTVAL (op) == -1 || - INTVAL (op) == 1 || INTVAL (op) == 4 || - INTVAL (op) == 8 || INTVAL (op) == 16"))) - - -;; True if OP is a floating-point constant zero, one, or a register. -(define_predicate "fr_reg_or_fp01_operand" - (ior (match_operand 0 "fr_register_operand") - (and (match_code "const_double") - (match_test "CONST_DOUBLE_OK_FOR_G (op)")))) - -;; Like fr_reg_or_fp01_operand, but don't allow any SUBREGs. -(define_predicate "xfreg_or_fp01_operand" - (and (match_operand 0 "fr_reg_or_fp01_operand") - (not (match_code "subreg")))) - -;; True if this is a comparison operator, which accepts a normal 8-bit -;; signed immediate operand. -(define_predicate "normal_comparison_operator" - (match_code "eq,ne,gt,le,gtu,leu")) - -;; True if this is a comparison operator, which accepts an adjusted 8-bit -;; signed immediate operand. -(define_predicate "adjusted_comparison_operator" - (match_code "lt,ge,ltu,geu")) - -;; True if this is a signed inequality operator. -(define_predicate "signed_inequality_operator" - (match_code "ge,gt,le,lt")) - -;; True if this operator is valid for predication. -(define_predicate "predicate_operator" - (match_code "eq,ne")) - -;; True if this operator can be used in a conditional operation. -(define_predicate "condop_operator" - (match_code "plus,minus,ior,xor,and")) - -;; These three are hardware registers that can only be addressed in -;; DImode. It's not strictly necessary to test mode == DImode here, -;; but it makes decent insurance against someone writing a -;; match_operand wrong. - -;; True if this is the ar.lc register. -(define_predicate "ar_lc_reg_operand" - (and (match_code "reg") - (match_test "mode == DImode && REGNO (op) == AR_LC_REGNUM"))) - -;; True if this is the ar.ccv register. -(define_predicate "ar_ccv_reg_operand" - (and (match_code "reg") - (match_test "mode == DImode && REGNO (op) == AR_CCV_REGNUM"))) - -;; True if this is the ar.pfs register. -(define_predicate "ar_pfs_reg_operand" - (and (match_code "reg") - (match_test "mode == DImode && REGNO (op) == AR_PFS_REGNUM"))) - -;; True if OP is valid as a base register in a reg + offset address. -;; ??? Should I copy the flag_omit_frame_pointer and cse_not_expected -;; checks from pa.c basereg_operand as well? Seems to be OK without them -;; in test runs. -(define_predicate "basereg_operand" - (match_operand 0 "register_operand") -{ - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - return REG_POINTER (op); -}) +(include "predicates.md") ;; :::::::::::::::::::: ;; :: @@ -454,9 +124,9 @@ (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld, - chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0, - syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f, - nop_i,nop_m,nop_x,lfetch,pre_cycle" + chk_s,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf, + st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop, + nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle" (const_string "unknown")) ;; chk_s has an I and an M form; use type A for convenience. @@ -465,7 +135,8 @@ (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M") (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M") (eq_attr "itanium_class" "lfetch") (const_string "M") - (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A") + (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog,mmalua") + (const_string "A") (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F") (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F") (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I") @@ -494,8 +165,12 @@ (define_attr "empty" "no,yes" (const_string "no")) - +;; True iff this insn must be the first insn of an instruction group. +;; This is true for the alloc instruction, and will also be true of others +;; when we have full intrinsics support. +(define_attr "first_insn" "no,yes" (const_string "no")) + ;; DFA descriptions of ia64 processors used for insn scheduling and ;; bundling. @@ -506,9 +181,6 @@ (automata_option "w") -;;(automata_option "no-minimization") - - (include "itanium1.md") (include "itanium2.md") @@ -693,9 +365,8 @@ "mov pr = %1, -1" }; - if (which_alternative == 2 && ! TARGET_NO_PIC - && symbolic_operand (operands[1], VOIDmode)) - abort (); + gcc_assert (which_alternative != 2 || TARGET_NO_PIC + || !symbolic_operand (operands[1], VOIDmode)); return alt[which_alternative]; } @@ -704,53 +375,54 @@ (define_split [(set (match_operand 0 "register_operand" "") (match_operand 1 "symbolic_operand" ""))] - "reload_completed && ! TARGET_NO_PIC" + "reload_completed" [(const_int 0)] { - ia64_expand_load_address (operands[0], operands[1]); - DONE; + if (ia64_expand_load_address (operands[0], operands[1])) + DONE; + else + FAIL; }) (define_expand "load_fptr" - [(set (match_dup 2) - (plus:DI (reg:DI 1) (match_operand 1 "function_operand" ""))) - (set (match_operand:DI 0 "register_operand" "") (match_dup 3))] - "" + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (match_dup 2) (match_operand 1 "function_operand" ""))) + (set (match_dup 0) (match_dup 3))] + "reload_completed" { - operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); - operands[3] = gen_const_mem (DImode, operands[2]); + operands[2] = pic_offset_table_rtx; + operands[3] = gen_const_mem (DImode, operands[0]); }) (define_insn "*load_fptr_internal1" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))] - "" + "reload_completed" "addl %0 = @ltoff(@fptr(%1)), gp" [(set_attr "itanium_class" "ialu")]) (define_insn "load_gprel" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))] - "" + "reload_completed" "addl %0 = @gprel(%1), gp" [(set_attr "itanium_class" "ialu")]) -(define_insn "gprel64_offset" +(define_insn "*gprel64_offset" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] - "" + "reload_completed" "movl %0 = @gprel(%1)" [(set_attr "itanium_class" "long_i")]) (define_expand "load_gprel64" - [(set (match_dup 2) - (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3))) - (set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_dup 3) (match_dup 2)))] - "" + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 2))) + (set (match_dup 0) + (plus:DI (match_dup 2) (match_dup 0)))] + "reload_completed" { - operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); - operands[3] = pic_offset_table_rtx; + operands[2] = pic_offset_table_rtx; }) ;; This is used as a placeholder for the return address during early @@ -776,7 +448,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s")) (match_operand:DI 2 "register_operand" "a")))] - "" + "reload_completed" { if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) return "%,addl %0 = @ltoffx(%1), %2"; @@ -789,7 +461,7 @@ [(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")))] - "" + "reload_completed" { if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) return "%,ld8.mov %0 = [%1], %2"; @@ -798,34 +470,41 @@ } [(set_attr "itanium_class" "ld")]) -(define_insn "load_ltoff_dtpmod" +(define_insn_and_split "load_dtpmod" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (reg:DI 1) - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] - UNSPEC_LTOFF_DTPMOD)))] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] + UNSPEC_DTPMOD))] "" - "addl %0 = @ltoff(@dtpmod(%1)), gp" - [(set_attr "itanium_class" "ialu")]) + "#" + "reload_completed" + [(set (match_dup 0) + (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPMOD) + (match_dup 2))) + (set (match_dup 0) (match_dup 3))] +{ + operands[2] = pic_offset_table_rtx; + operands[3] = gen_const_mem (DImode, operands[0]); +}) -(define_insn "load_ltoff_dtprel" +(define_insn "*load_ltoff_dtpmod" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (reg:DI 1) - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] - UNSPEC_LTOFF_DTPREL)))] - "" - "addl %0 = @ltoff(@dtprel(%1)), gp" + (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] + UNSPEC_LTOFF_DTPMOD) + (match_operand:DI 2 "register_operand" "a")))] + "reload_completed" + "addl %0 = @ltoff(@dtpmod(%1)), %2" [(set_attr "itanium_class" "ialu")]) (define_expand "load_dtprel" [(set (match_operand:DI 0 "register_operand" "") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_DTPREL))] "" "") (define_insn "*load_dtprel64" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] UNSPEC_DTPREL))] "TARGET_TLS64" "movl %0 = @dtprel(%1)" @@ -833,57 +512,73 @@ (define_insn "*load_dtprel22" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] UNSPEC_DTPREL))] "" "addl %0 = @dtprel(%1), r0" [(set_attr "itanium_class" "ialu")]) +(define_insn_and_split "*load_dtprel_gd" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] + UNSPEC_DTPREL))] + "" + "#" + "reload_completed" + [(set (match_dup 0) + (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPREL) + (match_dup 2))) + (set (match_dup 0) (match_dup 3))] +{ + operands[2] = pic_offset_table_rtx; + operands[3] = gen_const_mem (DImode, operands[0]); +}) + +(define_insn "*load_ltoff_dtprel" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] + UNSPEC_LTOFF_DTPREL) + (match_operand:DI 2 "register_operand" "a")))] + "" + "addl %0 = @ltoff(@dtprel(%1)), %2" + [(set_attr "itanium_class" "ialu")]) + (define_expand "add_dtprel" [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_DTPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] + UNSPEC_DTPREL) + (match_operand:DI 2 "register_operand" "")))] "!TARGET_TLS64" "") (define_insn "*add_dtprel14" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_DTPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] + UNSPEC_DTPREL) + (match_operand:DI 2 "register_operand" "r")))] "TARGET_TLS14" - "adds %0 = @dtprel(%2), %1" + "adds %0 = @dtprel(%1), %2" [(set_attr "itanium_class" "ialu")]) (define_insn "*add_dtprel22" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "register_operand" "a") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_DTPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] + UNSPEC_DTPREL) + (match_operand:DI 2 "register_operand" "a")))] "TARGET_TLS22" - "addl %0 = @dtprel(%2), %1" - [(set_attr "itanium_class" "ialu")]) - -(define_insn "load_ltoff_tprel" - [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (reg:DI 1) - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] - UNSPEC_LTOFF_TPREL)))] - "" - "addl %0 = @ltoff(@tprel(%1)), gp" + "addl %0 = @dtprel(%1), %2" [(set_attr "itanium_class" "ialu")]) (define_expand "load_tprel" [(set (match_operand:DI 0 "register_operand" "") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] UNSPEC_TPREL))] "" "") (define_insn "*load_tprel64" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] UNSPEC_TPREL))] "TARGET_TLS64" "movl %0 = @tprel(%1)" @@ -891,36 +586,61 @@ (define_insn "*load_tprel22" [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] + (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] UNSPEC_TPREL))] "" "addl %0 = @tprel(%1), r0" [(set_attr "itanium_class" "ialu")]) +(define_insn_and_split "*load_tprel_ie" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")] + UNSPEC_TPREL))] + "" + "#" + "reload_completed" + [(set (match_dup 0) + (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_TPREL) + (match_dup 2))) + (set (match_dup 0) (match_dup 3))] +{ + operands[2] = pic_offset_table_rtx; + operands[3] = gen_const_mem (DImode, operands[0]); +}) + +(define_insn "*load_ltoff_tprel" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")] + UNSPEC_LTOFF_TPREL) + (match_operand:DI 2 "register_operand" "a")))] + "" + "addl %0 = @ltoff(@tprel(%1)), %2" + [(set_attr "itanium_class" "ialu")]) + (define_expand "add_tprel" [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_TPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] + UNSPEC_TPREL) + (match_operand:DI 2 "register_operand" "")))] "!TARGET_TLS64" "") (define_insn "*add_tprel14" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "register_operand" "r") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_TPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] + UNSPEC_TPREL) + (match_operand:DI 2 "register_operand" "r")))] "TARGET_TLS14" - "adds %0 = @tprel(%2), %1" + "adds %0 = @tprel(%1), %2" [(set_attr "itanium_class" "ialu")]) (define_insn "*add_tprel22" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (match_operand:DI 1 "register_operand" "a") - (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] - UNSPEC_TPREL)))] + (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] + UNSPEC_TPREL) + (match_operand:DI 2 "register_operand" "a")))] "TARGET_TLS22" - "addl %0 = @tprel(%2), %1" + "addl %0 = @tprel(%1), %2" [(set_attr "itanium_class" "ialu")]) ;; With no offsettable memory references, we've got to have a scratch @@ -1016,93 +736,8 @@ (match_operand:XF 1 "general_operand" ""))] "" { - rtx op0 = operands[0]; - - if (GET_CODE (op0) == SUBREG) - op0 = SUBREG_REG (op0); - - /* We must support XFmode loads into general registers for stdarg/vararg - and unprototyped calls. We split them into DImode loads for convenience. - We don't need XFmode stores from general regs, because a stdarg/vararg - routine does a block store to memory of unnamed arguments. */ - - if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0))) - { - /* We're hoping to transform everything that deals with XFmode - quantities and GR registers early in the compiler. */ - if (no_new_pseudos) - abort (); - - /* Struct to register can just use TImode instead. */ - if ((GET_CODE (operands[1]) == SUBREG - && GET_MODE (SUBREG_REG (operands[1])) == TImode) - || (GET_CODE (operands[1]) == REG - && GR_REGNO_P (REGNO (operands[1])))) - { - rtx op1 = operands[1]; - - if (GET_CODE (op1) == SUBREG) - op1 = SUBREG_REG (op1); - else - /* ??? Maybe we should make a SUBREG here? */ - op1 = gen_rtx_REG (TImode, REGNO (op1)); - - emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1); - DONE; - } - - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)), - operand_subword (operands[1], 0, 0, XFmode)); - emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1), - operand_subword (operands[1], 1, 0, XFmode)); - DONE; - } - - /* If the quantity is in a register not known to be GR, spill it. */ - if (register_operand (operands[1], XFmode)) - operands[1] = spill_xfmode_operand (operands[1], 1); - - if (GET_CODE (operands[1]) == MEM) - { - rtx out[2]; - - out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0)); - out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1); - - emit_move_insn (out[0], adjust_address (operands[1], DImode, 0)); - emit_move_insn (out[1], adjust_address (operands[1], DImode, 8)); - DONE; - } - - abort (); - } - - if (! reload_in_progress && ! reload_completed) - { - operands[1] = spill_xfmode_operand (operands[1], 0); - - if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG) - { - rtx memt, memx, in = operands[1]; - if (CONSTANT_P (in)) - in = validize_mem (force_const_mem (XFmode, in)); - if (GET_CODE (in) == MEM) - memt = adjust_address (in, TImode, 0); - else - { - memt = assign_stack_temp (TImode, 16, 0); - memx = adjust_address (memt, XFmode, 0); - emit_move_insn (memx, in); - } - emit_move_insn (op0, memt); - DONE; - } - - if (! ia64_move_ok (operands[0], operands[1])) - operands[1] = force_reg (XFmode, operands[1]); - } + if (ia64_expand_movxf_movrf (XFmode, operands)) + DONE; }) ;; ??? There's no easy way to mind volatile acquire/release semantics. @@ -1117,6 +752,26 @@ stfe %0 = %F1%P0" [(set_attr "itanium_class" "fmisc,fld,stf")]) +;; Same as for movxf, but for RFmode. +(define_expand "movrf" + [(set (match_operand:RF 0 "general_operand" "") + (match_operand:RF 1 "general_operand" ""))] + "" +{ + if (ia64_expand_movxf_movrf (RFmode, operands)) + DONE; +}) + +(define_insn "*movrf_internal" + [(set (match_operand:RF 0 "destination_operand" "=f,f, m") + (match_operand:RF 1 "general_operand" "fG,m,fG"))] + "ia64_move_ok (operands[0], operands[1])" + "@ + mov %0 = %F1 + ldf.fill %0 = %1%P1 + stf.spill %0 = %F1%P0" + [(set_attr "itanium_class" "fmisc,fld,stf")]) + ;; Better code generation via insns that deal with TFmode register pairs ;; directly. Same concerns apply as for TImode. (define_expand "movtf" @@ -1131,7 +786,7 @@ }) (define_insn_and_split "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m") + [(set (match_operand:TF 0 "destination_operand" "=r,r,m") (match_operand:TF 1 "general_operand" "ri,m,r"))] "ia64_move_ok (operands[0], operands[1])" "#" @@ -1202,10 +857,10 @@ (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))] "" "@ - zxt4 %0 = %1 + addp4 %0 = %1, r0 ld4%O1 %0 = %1%P1 fmix.r %0 = f0, %1" - [(set_attr "itanium_class" "xtd,ld,fmisc")]) + [(set_attr "itanium_class" "ialu,ld,fmisc")]) ;; Convert between floating point types of different sizes. @@ -1474,6 +1129,15 @@ [(set_attr "itanium_class" "ishf")]) ;; Combine doesn't like to create bit-field insertions into zero. +(define_insn "*shladdp4_internal" + [(set (match_operand:DI 0 "gr_register_operand" "=r") + (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") + (match_operand:DI 2 "shladd_log2_operand" "n")) + (match_operand:DI 3 "const_int_operand" "n")))] + "ia64_depz_field_mask (operands[3], operands[2]) + INTVAL (operands[2]) == 32" + "shladdp4 %0 = %1, %2, r0" + [(set_attr "itanium_class" "ialu")]) + (define_insn "*depz_internal" [(set (match_operand:DI 0 "gr_register_operand" "=r") (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") @@ -2646,7 +2310,7 @@ op2_xf = gen_reg_rtx (XFmode); expand_float (op2_xf, operands[2], 0); - if (TARGET_INLINE_INT_DIV_LAT) + if (TARGET_INLINE_INT_DIV == INL_MIN_LAT) emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); else emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); @@ -2692,7 +2356,7 @@ op2_xf = gen_reg_rtx (XFmode); expand_float (op2_xf, operands[2], 1); - if (TARGET_INLINE_INT_DIV_LAT) + if (TARGET_INLINE_INT_DIV == INL_MIN_LAT) emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); else emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); @@ -2726,7 +2390,7 @@ (clobber (match_scratch:XF 4 "=&f")) (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:BI 6 "=c"))] - "TARGET_INLINE_INT_DIV_LAT" + "TARGET_INLINE_INT_DIV == INL_MIN_LAT" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) @@ -2785,7 +2449,7 @@ (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "TARGET_INLINE_INT_DIV_THR" + "TARGET_INLINE_INT_DIV == INL_MAX_THR" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) @@ -2878,7 +2542,25 @@ "fnegabs %0 = %1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "minsf3" +(define_insn "copysignsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN))] + "" + "fmerge.s %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "*ncopysignsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN)))] + "" + "fmerge.ns %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "sminsf3" [(set (match_operand:SF 0 "fr_register_operand" "=f") (smin:SF (match_operand:SF 1 "fr_register_operand" "f") (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] @@ -2886,7 +2568,7 @@ "fmin %0 = %1, %F2" [(set_attr "itanium_class" "fmisc")]) -(define_insn "maxsf3" +(define_insn "smaxsf3" [(set (match_operand:SF 0 "fr_register_operand" "=f") (smax:SF (match_operand:SF 1 "fr_register_operand" "f") (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] @@ -2946,7 +2628,7 @@ "TARGET_INLINE_FLOAT_DIV" { rtx insn; - if (TARGET_INLINE_FLOAT_DIV_LAT) + if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]); else insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]); @@ -2961,13 +2643,13 @@ (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" "#" "&& reload_completed" [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6))) (use (const_int 1))])) @@ -3018,13 +2700,13 @@ (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" "#" "&& reload_completed" [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) (minus:XF (match_dup 10) @@ -3093,14 +2775,14 @@ "TARGET_INLINE_SQRT" { rtx insn; - if (TARGET_INLINE_SQRT_LAT) #if 0 + if (TARGET_INLINE_SQRT == INL_MIN_LAT) insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]); + else #else - abort (); + gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); #endif - else - insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]); + insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]); emit_insn (insn); DONE; }) @@ -3123,7 +2805,7 @@ (clobber (match_scratch:XF 5 "=&f")) ;; Register p6 in optimization guide. (clobber (match_scratch:BI 6 "=c"))] - "TARGET_INLINE_SQRT_THR" + "TARGET_INLINE_SQRT == INL_MAX_THR" "#" "&& reload_completed" [ ;; exponent of +1/2 in r2 @@ -3292,7 +2974,25 @@ "fnegabs %0 = %1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "mindf3" +(define_insn "copysigndf3" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN))] + "" + "fmerge.s %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "*ncopysigndf3" + [(set (match_operand:DF 0 "register_operand" "=f") + (neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN)))] + "" + "fmerge.ns %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "smindf3" [(set (match_operand:DF 0 "fr_register_operand" "=f") (smin:DF (match_operand:DF 1 "fr_register_operand" "f") (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] @@ -3300,7 +3000,7 @@ "fmin %0 = %1, %F2" [(set_attr "itanium_class" "fmisc")]) -(define_insn "maxdf3" +(define_insn "smaxdf3" [(set (match_operand:DF 0 "fr_register_operand" "=f") (smax:DF (match_operand:DF 1 "fr_register_operand" "f") (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] @@ -3410,7 +3110,7 @@ "TARGET_INLINE_FLOAT_DIV" { rtx insn; - if (TARGET_INLINE_FLOAT_DIV_LAT) + if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]); else insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]); @@ -3426,13 +3126,13 @@ (clobber (match_scratch:XF 4 "=&f")) (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:BI 6 "=c"))] - "TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" "#" "&& reload_completed" [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9))) (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7))) (use (const_int 1))])) @@ -3506,13 +3206,13 @@ (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:DF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" "#" "&& reload_completed" [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) (minus:XF (match_dup 10) @@ -3573,14 +3273,14 @@ "TARGET_INLINE_SQRT" { rtx insn; - if (TARGET_INLINE_SQRT_LAT) #if 0 + if (TARGET_INLINE_SQRT == INL_MIN_LAT) insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]); + else #else - abort (); + gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); #endif - else - insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]); + insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]); emit_insn (insn); DONE; }) @@ -3603,7 +3303,7 @@ (clobber (match_scratch:XF 5 "=&f")) ;; Register p6 in optimization guide. (clobber (match_scratch:BI 6 "=c"))] - "TARGET_INLINE_SQRT_THR" + "TARGET_INLINE_SQRT == INL_MAX_THR" "#" "&& reload_completed" [ ;; exponent of +1/2 in r2 @@ -3848,7 +3548,25 @@ "fnegabs %0 = %F1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "minxf3" +(define_insn "copysignxf3" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN))] + "" + "fmerge.s %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "*ncopysignxf3" + [(set (match_operand:XF 0 "register_operand" "=f") + (neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") + (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")] + UNSPEC_COPYSIGN)))] + "" + "fmerge.ns %0 = %F2, %F1" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "sminxf3" [(set (match_operand:XF 0 "fr_register_operand" "=f") (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] @@ -3856,7 +3574,7 @@ "fmin %0 = %F1, %F2" [(set_attr "itanium_class" "fmisc")]) -(define_insn "maxxf3" +(define_insn "smaxxf3" [(set (match_operand:XF 0 "fr_register_operand" "=f") (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] @@ -4056,7 +3774,7 @@ "TARGET_INLINE_FLOAT_DIV" { rtx insn; - if (TARGET_INLINE_FLOAT_DIV_LAT) + if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]); else insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]); @@ -4073,13 +3791,13 @@ (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:XF 6 "=&f")) (clobber (match_scratch:BI 7 "=c"))] - "TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 3) (minus:XF (match_dup 8) @@ -4151,13 +3869,13 @@ (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:XF 4 "=&f")) (clobber (match_scratch:BI 5 "=c"))] - "TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) - (use (const_int 1))]) + (use (const_int 0))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) (minus:XF (match_dup 6) @@ -4230,14 +3948,14 @@ "TARGET_INLINE_SQRT" { rtx insn; - if (TARGET_INLINE_SQRT_LAT) #if 0 + if (TARGET_INLINE_SQRT == INL_MIN_LAT) insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]); + else #else - abort (); + gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); #endif - else - insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]); + insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]); emit_insn (insn); DONE; }) @@ -4262,7 +3980,7 @@ (clobber (match_scratch:XF 6 "=&f")) ;; Register p6 in optimization guide. (clobber (match_scratch:BI 7 "=c"))] - "TARGET_INLINE_SQRT_THR" + "TARGET_INLINE_SQRT == INL_MAX_THR" "#" "&& reload_completed" [ ;; exponent of +1/2 in r2 @@ -4583,7 +4301,7 @@ (match_operand:DI 3 "nonmemory_operand" "r")) (match_operand:DI 4 "nonmemory_operand" "rI")))] "reload_in_progress" - "* abort ();" + "* gcc_unreachable ();" "reload_completed" [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -4654,6 +4372,151 @@ ;; :::::::::::::::::::: ;; :: +;; :: 128 bit Integer Shifts and Rotates +;; :: +;; :::::::::::::::::::: + +(define_expand "ashlti3" + [(set (match_operand:TI 0 "gr_register_operand" "") + (ashift:TI (match_operand:TI 1 "gr_register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")))] + "" +{ + if (!dshift_count_operand (operands[2], DImode)) + FAIL; +}) + +(define_insn_and_split "*ashlti3_internal" + [(set (match_operand:TI 0 "gr_register_operand" "=&r") + (ashift:TI (match_operand:TI 1 "gr_register_operand" "r") + (match_operand:DI 2 "dshift_count_operand" "n")))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + HOST_WIDE_INT shift = INTVAL (operands[2]); + rtx rl = gen_lowpart (DImode, operands[0]); + rtx rh = gen_highpart (DImode, operands[0]); + rtx lo = gen_lowpart (DImode, operands[1]); + rtx shiftlo = GEN_INT (shift & 63); + + if (shift & 64) + { + emit_move_insn (rl, const0_rtx); + if (shift & 63) + emit_insn (gen_ashldi3 (rh, lo, shiftlo)); + else + emit_move_insn (rh, lo); + } + else + { + rtx hi = gen_highpart (DImode, operands[1]); + + emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63))); + emit_insn (gen_ashldi3 (rl, lo, shiftlo)); + } + DONE; +}) + +(define_expand "ashrti3" + [(set (match_operand:TI 0 "gr_register_operand" "") + (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")))] + "" +{ + if (!dshift_count_operand (operands[2], DImode)) + FAIL; +}) + +(define_insn_and_split "*ashrti3_internal" + [(set (match_operand:TI 0 "gr_register_operand" "=&r") + (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") + (match_operand:DI 2 "dshift_count_operand" "n")))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + HOST_WIDE_INT shift = INTVAL (operands[2]); + rtx rl = gen_lowpart (DImode, operands[0]); + rtx rh = gen_highpart (DImode, operands[0]); + rtx hi = gen_highpart (DImode, operands[1]); + rtx shiftlo = GEN_INT (shift & 63); + + if (shift & 64) + { + if (shift & 63) + emit_insn (gen_ashrdi3 (rl, hi, shiftlo)); + else + emit_move_insn (rl, hi); + emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63))); + } + else + { + rtx lo = gen_lowpart (DImode, operands[1]); + + emit_insn (gen_shrp (rl, hi, lo, shiftlo)); + emit_insn (gen_ashrdi3 (rh, hi, shiftlo)); + } + DONE; +}) + +(define_expand "lshrti3" + [(set (match_operand:TI 0 "gr_register_operand" "") + (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "") + (match_operand:DI 2 "nonmemory_operand" "")))] + "" +{ + if (!dshift_count_operand (operands[2], DImode)) + FAIL; +}) + +(define_insn_and_split "*lshrti3_internal" + [(set (match_operand:TI 0 "gr_register_operand" "=&r") + (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") + (match_operand:DI 2 "dshift_count_operand" "n")))] + "" + "#" + "reload_completed" + [(const_int 0)] +{ + HOST_WIDE_INT shift = INTVAL (operands[2]); + rtx rl = gen_lowpart (DImode, operands[0]); + rtx rh = gen_highpart (DImode, operands[0]); + rtx hi = gen_highpart (DImode, operands[1]); + rtx shiftlo = GEN_INT (shift & 63); + + if (shift & 64) + { + if (shift & 63) + emit_insn (gen_lshrdi3 (rl, hi, shiftlo)); + else + emit_move_insn (rl, hi); + emit_move_insn (rh, const0_rtx); + } + else + { + rtx lo = gen_lowpart (DImode, operands[1]); + + emit_insn (gen_shrp (rl, hi, lo, shiftlo)); + emit_insn (gen_lshrdi3 (rh, hi, shiftlo)); + } + DONE; +}) + +(define_insn "shrp" + [(set (match_operand:DI 0 "gr_register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r") + (match_operand:DI 2 "gr_register_operand" "r") + (match_operand:DI 3 "shift_count_operand" "M")] + UNSPEC_SHRP))] + "" + "shrp %0 = %1, %2, %3" + [(set_attr "itanium_class" "ishf")]) + +;; :::::::::::::::::::: +;; :: ;; :: 32 bit Integer Logical operations ;; :: ;; :::::::::::::::::::: @@ -5190,7 +5053,7 @@ "rim,rim,rim, rim, *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 (); } + { gcc_unreachable (); } [(set_attr "predicable" "no")]) (define_split @@ -5293,7 +5156,7 @@ "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))] "ia64_move_ok (operands[0], operands[2]) && ia64_move_ok (operands[0], operands[3])" - { abort (); } + { gcc_unreachable (); } [(set_attr "predicable" "no")]) (define_insn "*abssi2_internal" @@ -5692,12 +5555,10 @@ start_sequence (); set = single_set (last); - if (! rtx_equal_p (SET_DEST (set), op0) - || GET_CODE (SET_SRC (set)) != MEM) - abort (); + gcc_assert (rtx_equal_p (SET_DEST (set), op0) + && GET_CODE (SET_SRC (set)) == MEM); addr = XEXP (SET_SRC (set), 0); - if (rtx_equal_p (addr, op0)) - abort (); + gcc_assert (!rtx_equal_p (addr, op0)); } /* Jump table elements are stored pc-relative. That is, a displacement @@ -5795,7 +5656,8 @@ "" "alloc %0 = ar.pfs, %1, %2, %3, %4" [(set_attr "itanium_class" "syst_m0") - (set_attr "predicable" "no")]) + (set_attr "predicable" "no") + (set_attr "first_insn" "yes")]) ;; Modifies ar.unat (define_expand "gr_spill" @@ -6044,10 +5906,8 @@ int i = (INTVAL (operands[1])); int j = (INTVAL (operands[2])); - if (i != 0 && i != 1) - abort (); - if (j < 0 || j > 3) - abort (); + gcc_assert (i == 0 || i == 1); + gcc_assert (j >= 0 && j <= 3); return alt[i][j]; } [(set_attr "itanium_class" "lfetch")]) @@ -6134,88 +5994,6 @@ }) -;;; Intrinsics support. - -(define_expand "mf" - [(set (mem:BLK (match_dup 0)) - (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))] - "" -{ - operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode)); - MEM_VOLATILE_P (operands[0]) = 1; -}) - -(define_insn "*mf_internal" - [(set (match_operand:BLK 0 "" "") - (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))] - "" - "mf" - [(set_attr "itanium_class" "syst_m")]) - -(define_insn "fetchadd_acq_si" - [(set (match_operand:SI 0 "gr_register_operand" "=r") - (match_operand:SI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (unspec:SI [(match_dup 1) - (match_operand:SI 2 "fetchadd_operand" "n")] - UNSPEC_FETCHADD_ACQ))] - "" - "fetchadd4.acq %0 = %1, %2" - [(set_attr "itanium_class" "sem")]) - -(define_insn "fetchadd_acq_di" - [(set (match_operand:DI 0 "gr_register_operand" "=r") - (match_operand:DI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (unspec:DI [(match_dup 1) - (match_operand:DI 2 "fetchadd_operand" "n")] - UNSPEC_FETCHADD_ACQ))] - "" - "fetchadd8.acq %0 = %1, %2" - [(set_attr "itanium_class" "sem")]) - -(define_insn "cmpxchg_acq_si" - [(set (match_operand:SI 0 "gr_register_operand" "=r") - (match_operand:SI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (unspec:SI [(match_dup 1) - (match_operand:SI 2 "gr_register_operand" "r") - (match_operand:DI 3 "ar_ccv_reg_operand" "")] - UNSPEC_CMPXCHG_ACQ))] - "" - "cmpxchg4.acq %0 = %1, %2, %3" - [(set_attr "itanium_class" "sem")]) - -(define_insn "cmpxchg_acq_di" - [(set (match_operand:DI 0 "gr_register_operand" "=r") - (match_operand:DI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (unspec:DI [(match_dup 1) - (match_operand:DI 2 "gr_register_operand" "r") - (match_operand:DI 3 "ar_ccv_reg_operand" "")] - UNSPEC_CMPXCHG_ACQ))] - "" - "cmpxchg8.acq %0 = %1, %2, %3" - [(set_attr "itanium_class" "sem")]) - -(define_insn "xchgsi" - [(set (match_operand:SI 0 "gr_register_operand" "=r") - (match_operand:SI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (match_operand:SI 2 "gr_register_operand" "r"))] - "" - "xchg4 %0 = %1, %2" - [(set_attr "itanium_class" "sem")]) - -(define_insn "xchgdi" - [(set (match_operand:DI 0 "gr_register_operand" "=r") - (match_operand:DI 1 "not_postinc_memory_operand" "+S")) - (set (match_dup 1) - (match_operand:DI 2 "gr_register_operand" "r"))] - "" - "xchg8 %0 = %1, %2" - [(set_attr "itanium_class" "sem")]) - ;; Predication. (define_cond_exec @@ -6283,3 +6061,18 @@ "addp4_optimize_ok (operands[1], operands[2])" "addp4 %0 = %1, %2" [(set_attr "itanium_class" "ialu")]) + +;; +;; Get instruction pointer + +(define_insn "ip_value" + [(set (match_operand:DI 0 "register_operand" "=r") + (pc))] + "" + "mov %0 = ip" + [(set_attr "itanium_class" "ialu")]) + +;; Vector operations +(include "vect.md") +;; Atomic operations +(include "sync.md")