diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33bc27a6f34..f8c954d170e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2000-05-06 Richard Henderson + + * config/ia64/ia64.c (predicate_operator): New. + (ia64_print_operand): Handle 'J'. + (rtx_needs_barrier): Handle COND_EXEC. + * config/ia64/ia64.h (BRANCH_COST): Define. + (PREDICATE_CODES): Update. + * config/ia64/ia64.md: Docuement used unspec values. + (attr predicable): New. + (movxf, movxf_internal): New. + (extendsfdf2): Don't comment out nop. + (floatdidf2): Remove. + (truncxfsf2, truncxfdf2, floatdixf2): New. + (abssi2, absdi2): Put the neg in the "true" slot. + (conditional branch instructions): Mark not predicable. + (cmov*_internal): Use predicate_operator. Split to cond_exec. + (abs*_internal): Likewise. + (alloc, set_bsp): Mark not predicable. + (barrier, insn_group_barrier, flush_cache): Likewise. + (define_cond_exec): New. + 2000-05-06 Richard Henderson * c-decl.c: Include "tm_p.h". diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index d42467b9020..81ae2e6fa5f 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -468,6 +468,17 @@ call_multiple_values_operation (op, mode) return 1; } +/* Return 1 if this operator is valid for predication. */ + +int +predicate_operator (op, mode) + register rtx op; + enum machine_mode mode; +{ + enum rtx_code code = GET_CODE (op); + return ((GET_MODE (op) == mode || mode == VOIDmode) + && (code == EQ || code == NE)); +} /* Structure to be filled in by ia64_compute_frame_size with register save masks and offsets for the current function. */ @@ -1683,6 +1694,7 @@ ia64_print_operand_address (stream, address) F A floating point constant 0.0 emitted as f0, or 1.0 emitted as f1, or a floating point register emitted normally. I Invert a predicate register by adding 1. + J Select the proper predicate register for a condition. O Append .acq for volatile load. P Postincrement of a MEM. Q Append .rel for volatile store. @@ -1742,6 +1754,10 @@ ia64_print_operand (file, x, code) fputs (reg_names [REGNO (x) + 1], file); return; + case 'J': + fputs (reg_names [REGNO (XEXP (x, 0)) + (GET_CODE (x) == EQ)], file); + return; + case 'O': if (MEM_VOLATILE_P (x)) fputs(".acq", file); @@ -2382,6 +2398,27 @@ rtx_needs_barrier (x, flags, pred) } break; + case COND_EXEC: + /* X is a predicated instruction. */ + + cond = COND_EXEC_TEST (x); + if (pred) + abort (); + need_barrier = rtx_needs_barrier (cond, flags, 0); + + if (GET_CODE (cond) == EQ) + is_complemented = 1; + cond = XEXP (cond, 0); + if (GET_CODE (cond) != REG + && REGNO_REG_CLASS (REGNO (cond)) != PR_REGS) + abort (); + pred = REGNO (cond); + if (is_complemented) + ++pred; + + need_barrier |= rtx_needs_barrier (COND_EXEC_CODE (x), flags, pred); + return need_barrier; + case CLOBBER: #if 0 case USE: diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index b8a03c629da..686f728516c 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1922,9 +1922,13 @@ do { \ /* #define MEMORY_MOVE_COST(M,C,I) */ /* A C expression for the cost of a branch instruction. A value of 1 is the - default; other values are interpreted relative to that. */ -/* ??? Investigate. Might get better code by defining this. */ -/* #define BRANCH_COST */ + default; other values are interpreted relative to that. Used by the + if-conversion code as max instruction count. */ +/* ??? This requires investigation. The primary effect might be how + many additional insn groups we run into, vs how good the dynamic + branch predictor is. */ + +#define BRANCH_COST 6 /* Define this macro as a C expression which is nonzero if accessing less than a word of memory (i.e. a `char' or a `short') is no faster than accessing a @@ -2726,7 +2730,8 @@ do { \ { "reg_or_fp01_operand", {SUBREG, REG, CONST_DOUBLE, CONSTANT_P_RTX}}, \ { "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}}, \ { "adjusted_comparison_operator", {LT, GE, LTU, GEU}}, \ -{ "call_multiple_values_operation", {PARALLEL}}, +{ "call_multiple_values_operation", {PARALLEL}}, \ +{ "predicate_operator", {NE, EQ}}, /* An alias for a machine mode name. This is the machine mode that elements of a jump-table should have. */ diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 6f243f80a67..6b7eb159bfe 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -48,6 +48,33 @@ ;; ??? Add function unit scheduling info for Itanium (TM) processor. +;; Unspec usage: +;; +;; unspec: +;; 1 gr_spill +;; 2 gr_restore +;; 3 fr_spill +;; 4 fr_restore +;; 5 pr_spill +;; 8 popcnt +;; 9 unat_spill +;; 10 unat_restore +;; 13 cmpxchg_acq +;; 14 val_compare_and_swap +;; 16 lock_test_and_set +;; 17 op_and_fetch +;; 18 fetch_and_op +;; 19 fetchadd_acq +;; 20 bsp_value +;; +;; unspec_volatile: +;; 0 alloc +;; 1 blockage +;; 2 insn_group_barrier +;; 3 flush_cache +;; 4 pfs_restore +;; 5 set_bsp +;; 6 pr_restore ;; :::::::::::::::::::: ;; :: @@ -73,6 +100,10 @@ (define_attr "type" "unknown,A,I,M,F,B,L,S" (const_string "unknown")) +;; Predication. True iff this instruction can be predicated. + +(define_attr "predicable" "no,yes" (const_string "yes")) + ;; :::::::::::::::::::: ;; :: @@ -402,6 +433,29 @@ mov %0 = %1" [(set_attr "type" "F,M,M,M,M,A")]) +(define_expand "movxf" + [(set (match_operand:XF 0 "general_operand" "") + (match_operand:XF 1 "general_operand" ""))] + "" + " +{ + if (! reload_in_progress && ! reload_completed + && GET_CODE (operands[0]) == MEM + && GET_CODE (operands[1]) == MEM) + operands[1] = copy_to_mode_reg (XFmode, operands[1]); +}") + +(define_insn "*movxf_internal" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,m") + (match_operand:XF 1 "general_operand" "fG,m,fG"))] + "! memory_operand (operands[0], XFmode) + || ! memory_operand (operands[1], XFmode)" + "@ + mov %0 = %F1 + ldf %0 = %1%P1 + stf %0 = %F1%P0" + [(set_attr "type" "F,M,M")]) + ;; :::::::::::::::::::: ;; :: @@ -473,8 +527,8 @@ (float_extend:DF (match_operand:SF 1 "register_operand" "0,f")))] "" "@ - //nop - mov %0 = %1" + nop 0 + mov %0 = %1" [(set_attr "type" "unknown,F")]) (define_insn "truncdfsf2" @@ -484,17 +538,28 @@ "fnorm.s %0 = %1%B0" [(set_attr "type" "F")]) +(define_insn "truncxfsf2" + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] + "" + "fnorm.s %0 = %1%B0" + [(set_attr "type" "F")]) + +(define_insn "truncxfdf2" + [(set (match_operand:DF 0 "register_operand" "=f") + (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] + "" + "fnorm.d %0 = %1%B0" + [(set_attr "type" "F")]) + ;; Convert between signed integer types and floating point. -;; ??? Instead of having floatdidf2, we should have a floatditf2 pattern, -;; and then add conversions from tf to df and sf. - -(define_insn "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "e")))] +(define_insn "floatdixf2" + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:DI 1 "register_operand" "e")))] "" - "fcvt.xf %0 = %1\;;;\;fnorm.d %0 = %0%B0" - [(set_attr "type" "unknown")]) + "fcvt.xf %0 = %1" + [(set_attr "type" "F")]) (define_insn "fix_truncsfdi2" [(set (match_operand:DI 0 "register_operand" "=e") @@ -871,9 +936,9 @@ [(set (match_dup 2) (ge:CC (match_operand:SI 1 "register_operand" "") (const_int 0))) (set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI (ne:CC (match_dup 2) (const_int 0)) - (match_dup 1) - (neg:SI (match_dup 1))))] + (if_then_else:SI (eq:CC (match_dup 2) (const_int 0)) + (neg:SI (match_dup 1)) + (match_dup 1)))] "" " { @@ -1079,9 +1144,9 @@ [(set (match_dup 2) (ge:CC (match_operand:DI 1 "register_operand" "") (const_int 0))) (set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI (ne:CC (match_dup 2) (const_int 0)) - (match_dup 1) - (neg:DI (match_dup 1))))] + (if_then_else:DI (eq:CC (match_dup 2) (const_int 0)) + (neg:DI (match_dup 1)) + (match_dup 1)))] "" " { @@ -2076,7 +2141,8 @@ (pc)))] "" "(%I0) br.cond.dpnt %l1" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*beq_false" [(set (pc) @@ -2086,7 +2152,8 @@ (label_ref (match_operand 1 "" ""))))] "" "(%0) br.cond.dptk %l1" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*bne_true" [(set (pc) @@ -2096,7 +2163,8 @@ (pc)))] "" "(%0) br.cond.dptk %l1" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*bne_false" [(set (pc) @@ -2106,7 +2174,8 @@ (label_ref (match_operand 1 "" ""))))] "" "(%I0) br.cond.dpnt %l1" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) ;; :::::::::::::::::::: @@ -2326,195 +2395,222 @@ ;; DImode if_then_else patterns. ;; -(define_insn "*cmovne_internal" +(define_insn "*cmovdi_internal" [(set (match_operand:DI 0 "register_operand" "=r,r,m,r,r,m,r") - (if_then_else:DI (ne:CC (match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") - (match_operand:DI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") + (const_int 0)]) + (match_operand:DI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") + (match_operand:DI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] "" - "@ - (%I1) mov %0 = %3 - (%I1) ld8%O3 %0 = %3 - (%I1) st8%Q0 %0 = %3 - (%1) mov %0 = %2 - (%1) ld8%O2 %0 = %2 - (%1) st8%Q0 %0 = %2 - #" + "#" [(set_attr "type" "A,M,M,A,M,M,unknown")]) (define_split [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI (ne:CC (match_operand:CC 1 "register_operand" "") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "") - (match_operand:DI 3 "reg_or_22bit_operand" "")))] + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "") + (const_int 0)]) + (match_operand:DI 2 "reg_or_22bit_operand" "") + (match_operand:DI 3 "reg_or_22bit_operand" "")))] "(reload_completed - && ! rtx_equal_p (operands[0], operands[2]) - && ! rtx_equal_p (operands[0], operands[3]))" - [(set (match_dup 0) - (if_then_else:DI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (set (match_dup 0) - (if_then_else:DI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 0) - (match_dup 3)))] - "") - -;; ??? Unknown if this can be matched. - -(define_insn "*cmoveq_internal" - [(set (match_operand:DI 0 "register_operand" "=r,r,m,r,r,m,r") - (if_then_else:DI (eq:CC (match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") - (match_operand:DI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] - "" - "@ - (%1) mov %0 = %3 - (%1) ld8%O3 %0 = %3 - (%1) st8%Q0 %0 = %3 - (%I1) mov %0 = %2 - (%I1) ld8%O2 %0 = %2 - (%I1) st8%Q0 %0 = %2 - #" - [(set_attr "type" "A,M,M,A,M,M,unknown")]) - -;; ??? Unknown if this can be matched. + && (rtx_equal_p (operands[0], operands[2]) + || rtx_equal_p (operands[0], operands[3])))" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (match_dup 2)))] + " +{ + if (rtx_equal_p (operands[0], operands[2])) + { + operands[2] = operands[3]; + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); + } +}") (define_split [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI (eq:CC (match_operand:CC 1 "register_operand" "") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "") - (match_operand:DI 3 "reg_or_22bit_operand" "")))] - "(reload_completed - && ! rtx_equal_p (operands[0], operands[2]) - && ! rtx_equal_p (operands[0], operands[3]))" - [(set (match_dup 0) - (if_then_else:DI (eq:CC (match_dup 1) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (set (match_dup 0) - (if_then_else:DI (eq:CC (match_dup 1) (const_int 0)) - (match_dup 0) - (match_dup 3)))] - "") + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "") + (const_int 0)]) + (match_operand:DI 2 "reg_or_22bit_operand" "") + (match_operand:DI 3 "reg_or_22bit_operand" "")))] + "reload_completed" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (match_dup 2))) + (cond_exec + (match_dup 5) + (set (match_dup 0) (match_dup 3)))] + " +{ + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); +}") ;; Absolute value pattern. (define_insn "*absdi2_internal" [(set (match_operand:DI 0 "register_operand" "=r,r") - (if_then_else:DI (ne:CC (match_operand:CC 1 "register_operand" "c,c") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "0,rI") - (neg:DI (match_operand:DI 3 "reg_or_22bit_operand" "rI,rI"))))] + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" "rI,rI")) + (match_operand:DI 3 "reg_or_22bit_operand" "0,rI")))] "" - "@ - (%I1) sub %0 = r0, %3 - #" + "#" [(set_attr "type" "A,unknown")]) (define_split [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI (ne:CC (match_operand:CC 1 "register_operand" "") - (const_int 0)) - (match_operand:DI 2 "reg_or_22bit_operand" "") - (neg:DI (match_operand:DI 3 "reg_or_22bit_operand" ""))))] - "reload_completed && ! rtx_equal_p (operands[0], operands[2])" - [(set (match_dup 0) - (if_then_else:DI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (set (match_dup 0) - (if_then_else:DI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 0) - (neg:DI (match_dup 3))))] + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" "")) + (match_operand:DI 3 "reg_or_22bit_operand" "")))] + "reload_completed && rtx_equal_p (operands[0], operands[3])" + [(cond_exec + (match_dup 4) + (set (match_dup 0) + (neg:DI (match_dup 2))))] "") -;; ??? Unknown if this can be generated. If so, then add a define_split as -;; above. - -(define_insn "*absdi2_not_internal" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (if_then_else:DI (ne:CC (match_operand:CC 1 "register_operand" "c,c") - (const_int 0)) - (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" "rI,rI")) - (match_operand:DI 3 "reg_or_22bit_operand" "0,rI")))] - "" - "*abort ();" - [(set_attr "type" "unknown")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (if_then_else:DI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:DI (match_operand:DI 2 "reg_or_22bit_operand" "")) + (match_operand:DI 3 "reg_or_22bit_operand" "")))] + "reload_completed" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (neg:DI (match_dup 2)))) + (cond_exec + (match_dup 5) + (set (match_dup 0) (match_dup 3)))] + " +{ + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); +}") ;; ;; SImode if_then_else patterns. ;; -(define_insn "*cmovnesi_internal" +(define_insn "*cmovsi_internal" [(set (match_operand:SI 0 "register_operand" "=r,r,m,r,r,m,r") - (if_then_else:SI (ne:CC (match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") - (const_int 0)) - (match_operand:SI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") - (match_operand:SI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") + (const_int 0)]) + (match_operand:SI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") + (match_operand:SI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] "" - "@ - (%I1) mov %0 = %3 - (%I1) ld4%O3 %0 = %3 - (%I1) st4%Q0 %0 = %3 - (%1) mov %0 = %2 - (%1) ld4%O2 %0 = %2 - (%1) st4%Q0 %0 = %2 - #" + "#" [(set_attr "type" "A,M,M,A,M,M,unknown")]) (define_split [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI (ne:CC (match_operand:CC 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "reg_or_22bit_operand" "") - (match_operand:SI 3 "reg_or_22bit_operand" "")))] + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "") + (const_int 0)]) + (match_operand:SI 2 "reg_or_22bit_operand" "") + (match_operand:SI 3 "reg_or_22bit_operand" "")))] "(reload_completed - && ! rtx_equal_p (operands[0], operands[2]) - && ! rtx_equal_p (operands[0], operands[3]))" - [(set (match_dup 0) - (if_then_else:SI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (set (match_dup 0) - (if_then_else:SI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 0) - (match_dup 3)))] - "") + && (rtx_equal_p (operands[0], operands[2]) + || rtx_equal_p (operands[0], operands[3])))" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (match_dup 2)))] + " +{ + if (rtx_equal_p (operands[0], operands[2])) + { + operands[2] = operands[3]; + operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); + } +}") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "") + (const_int 0)]) + (match_operand:SI 2 "reg_or_22bit_operand" "") + (match_operand:SI 3 "reg_or_22bit_operand" "")))] + "reload_completed" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (match_dup 2))) + (cond_exec + (match_dup 5) + (set (match_dup 0) (match_dup 3)))] + " +{ + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); +}") (define_insn "*abssi2_internal" [(set (match_operand:SI 0 "register_operand" "=r,r") - (if_then_else:SI (ne:CC (match_operand:CC 1 "register_operand" "c,c") - (const_int 0)) - (match_operand:SI 2 "reg_or_22bit_operand" "0,rI") - (neg:SI (match_operand:SI 3 "reg_or_22bit_operand" "rI,rI"))))] + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:SI (match_operand:SI 3 "reg_or_22bit_operand" "rI,rI")) + (match_operand:SI 2 "reg_or_22bit_operand" "0,rI")))] "" - "@ - (%I1) sub %0 = r0, %3 - #" + "#" [(set_attr "type" "A,unknown")]) (define_split [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI (ne:CC (match_operand:CC 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "reg_or_22bit_operand" "") - (neg:SI (match_operand:SI 3 "reg_or_22bit_operand" ""))))] - "reload_completed && ! rtx_equal_p (operands[0], operands[2])" - [(set (match_dup 0) - (if_then_else:SI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 2) - (match_dup 0))) - (set (match_dup 0) - (if_then_else:SI (ne:CC (match_dup 1) (const_int 0)) - (match_dup 0) - (neg:SI (match_dup 3))))] + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:SI (match_operand:SI 2 "reg_or_22bit_operand" "")) + (match_operand:SI 3 "reg_or_22bit_operand" "")))] + "reload_completed && rtx_equal_p (operands[0], operands[3])" + [(cond_exec + (match_dup 4) + (set (match_dup 0) + (neg:SI (match_dup 2))))] "") +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (if_then_else:SI + (match_operator:CC 4 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c,c") + (const_int 0)]) + (neg:SI (match_operand:SI 2 "reg_or_22bit_operand" "")) + (match_operand:SI 3 "reg_or_22bit_operand" "")))] + "reload_completed" + [(cond_exec + (match_dup 4) + (set (match_dup 0) (neg:SI (match_dup 2)))) + (cond_exec + (match_dup 5) + (set (match_dup 0) (match_dup 3)))] + " +{ + operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); +}") + ;; :::::::::::::::::::: ;; :: @@ -2912,7 +3008,8 @@ (pc)))] "ia64_direct_return ()" "(%I0) br.ret.sptk.many rp" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*eq_not_return" [(set (pc) @@ -2922,7 +3019,8 @@ (return)))] "ia64_direct_return ()" "(%0) br.ret.sptk.many rp" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*ne_return" [(set (pc) @@ -2932,7 +3030,8 @@ (pc)))] "ia64_direct_return ()" "(%0) br.ret.sptk.many rp" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "*ne_not_return" [(set (pc) @@ -2942,7 +3041,8 @@ (return)))] "ia64_direct_return ()" "(%I0) br.ret.sptk.many rp" - [(set_attr "type" "B")]) + [(set_attr "type" "B") + (set_attr "predicable" "no")]) (define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] @@ -3041,7 +3141,8 @@ (use (match_operand:DI 4 "const_int_operand" "i"))] "" "alloc %0 = ar.pfs, %1, %2, %3, %4" - [(set_attr "type" "M")]) + [(set_attr "type" "M") + (set_attr "predicable" "no")]) (define_insn "gr_spill" [(set (match_operand:DI 0 "memory_operand" "=m") @@ -3138,7 +3239,8 @@ invala\; \ ;;\; \ mov ar.rsc=r19\;" - [(set_attr "type" "I")]) + [(set_attr "type" "unknown") + (set_attr "predicable" "no")]) ;; :::::::::::::::::::: ;; :: @@ -3162,13 +3264,15 @@ [(unspec_volatile [(const_int 0)] 1)] "" "" - [(set_attr "type" "unknown")]) + [(set_attr "type" "unknown") + (set_attr "predicable" "no")]) (define_insn "insn_group_barrier" [(unspec_volatile [(const_int 0)] 2)] "" ";;" - [(set_attr "type" "S")]) + [(set_attr "type" "S") + (set_attr "predicable" "no")]) ;; Non-local goto support. @@ -3259,7 +3363,8 @@ [(unspec_volatile [(match_operand:DI 0 "register_operand" "=&r")] 3)] "" "fc %0\;;;\;adds %0=31,%0\;;;\;fc %0\;;;\;sync.i\;srlz.i" - [(set_attr "type" "unknown")]) + [(set_attr "type" "unknown") + (set_attr "predicable" "no")]) ;; Builtin apply support. @@ -3694,3 +3799,12 @@ ia64_expand_op_and_fetch (IA64_NAND_OP, SImode, operands); DONE; }") + +;; Predication. + +(define_cond_exec + [(match_operator 0 "predicate_operator" + [(match_operand:CC 1 "register_operand" "c") + (const_int 0)])] + "" + "(%J0)")