diff options
Diffstat (limited to 'gcc/optabs.cc')
-rw-r--r-- | gcc/optabs.cc | 110 |
1 files changed, 65 insertions, 45 deletions
diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 0a14b1e..5c9450f 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -1760,8 +1760,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, emit_move_insn (target_piece, x); } - insns = get_insns (); - end_sequence (); + insns = end_sequence (); if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD) { @@ -1839,8 +1838,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, outof_target, into_target, unsignedp, next_methods, shift_mask)) { - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_insn (insns); return target; @@ -1962,8 +1960,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, emit_move_insn (outof_target, inter); } - insns = get_insns (); - end_sequence (); + insns = end_sequence (); if (inter != 0) { @@ -2222,8 +2219,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1, NULL_RTX, LCT_CONST, mode, op0, mode, op1x, op1_mode); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); bool trapv = trapv_binoptab_p (binoptab); target = gen_reg_rtx (mode); @@ -2564,8 +2560,7 @@ expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, /* Get the part of VAL containing the value that we want. */ libval = simplify_gen_subreg (mode, libval, libval_mode, targ0 ? 0 : GET_MODE_SIZE (mode)); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); /* Move the into the desired location. */ emit_libcall_block (insns, targ0 ? targ0 : targ1, libval, gen_rtx_fmt_ee (code, mode, op0, op1)); @@ -2698,8 +2693,7 @@ expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target) goto fail; } - rtx_insn *seq = get_insns (); - end_sequence (); + rtx_insn *seq = end_sequence (); add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode); emit_insn (seq); @@ -2797,8 +2791,7 @@ expand_doubleword_clz_ctz_ffs (scalar_int_mode mode, rtx op0, rtx target, emit_label (after_label); convert_move (target, result, true); - seq = get_insns (); - end_sequence (); + seq = end_sequence (); add_equal_note (seq, target, optab_to_code (unoptab), xop0, NULL_RTX, mode); emit_insn (seq); @@ -2839,8 +2832,7 @@ expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target) t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT); - seq = get_insns (); - end_sequence (); + seq = end_sequence (); add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode); emit_insn (seq); @@ -3010,8 +3002,7 @@ expand_ctz (scalar_int_mode mode, rtx op0, rtx target) return 0; } - seq = get_insns (); - end_sequence (); + seq = end_sequence (); add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode); emit_insn (seq); @@ -3088,8 +3079,7 @@ expand_ffs (scalar_int_mode mode, rtx op0, rtx target) if (!temp) goto fail; - seq = get_insns (); - end_sequence (); + seq = end_sequence (); add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode); emit_insn (seq); @@ -3166,8 +3156,7 @@ expand_absneg_bit (rtx_code code, machine_mode mode, emit_move_insn (targ_piece, op0_piece); } - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_insn (insns); } @@ -3448,8 +3437,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, emit_move_insn (target_piece, x); } - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_insn (insns); return target; @@ -3550,8 +3538,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target, if the libcall is cse'd or moved. */ value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode, op0, mode); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); target = gen_reg_rtx (outmode); bool trapv = trapv_unoptab_p (unoptab); @@ -3999,8 +3986,7 @@ expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target, emit_move_insn (targ_piece, op0_piece); } - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_insn (insns); } @@ -4304,9 +4290,6 @@ can_compare_p (enum rtx_code code, machine_mode mode, && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing && insn_operand_matches (icode, 1, test)) return true; - if (purpose == ccp_cmov - && optab_handler (cmov_optab, mode) != CODE_FOR_nothing) - return true; mode = GET_MODE_WIDER_MODE (mode).else_void (); PUT_MODE (test, mode); @@ -4954,8 +4937,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison, start_sequence (); value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, cmp_mode, x, mode, y, mode); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); target = gen_reg_rtx (cmp_mode); emit_libcall_block (insns, target, value, equiv); @@ -5693,8 +5675,7 @@ expand_float (rtx to, rtx from, int unsignedp) value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, GET_MODE (to), from, GET_MODE (from)); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_libcall_block (insns, target, value, gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT, @@ -5930,8 +5911,7 @@ expand_fix (rtx to, rtx from, int unsignedp) value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, GET_MODE (to), from, GET_MODE (from)); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_libcall_block (insns, target, value, gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX, @@ -6022,8 +6002,7 @@ expand_fixed_convert (rtx to, rtx from, int uintp, int satp) start_sequence (); value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode, from, from_mode); - insns = get_insns (); - end_sequence (); + insns = end_sequence (); emit_libcall_block (insns, to, value, gen_rtx_fmt_e (optab_to_code (tab), to_mode, from)); @@ -6165,8 +6144,7 @@ gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode) } emit_insn (insn); - insn = get_insns (); - end_sequence (); + insn = end_sequence (); return insn; } @@ -6384,6 +6362,50 @@ expand_vec_perm_1 (enum insn_code icode, rtx target, return NULL_RTX; } +/* Check if vec_perm mask SEL is a constant equivalent to an and operation of + the non-zero vec_perm operand with some mask consisting of 0xffs and 0x00s, + assuming the other vec_perm operand is a constant vector of zeros. Return + the mask for the equivalent and operation, or NULL_RTX if the vec_perm can + not be modeled as an and. MODE is the mode of the value being anded. + ZERO_OP0_P is true if the first operand of the vec_perm is a constant vector + of zeros or false if the second operand of the vec_perm is a constant vector + of zeros. */ +rtx +vec_perm_and_mask (machine_mode mode, const vec_perm_indices &sel, + bool zero_op0_p) +{ + unsigned int nelt; + if (!GET_MODE_NUNITS (mode).is_constant (&nelt)) + return NULL_RTX; + + rtx_vector_builder builder (mode, nelt, 1); + machine_mode emode = GET_MODE_INNER (mode); + + for (unsigned int i = 0; i < nelt; i++) + { + if (zero_op0_p) + { + if (known_eq (sel[i], nelt + i)) + builder.quick_push (CONSTM1_RTX (emode)); + else if (known_lt (sel[i], nelt)) + builder.quick_push (CONST0_RTX (emode)); + else + return NULL_RTX; + } + else + { + if (known_eq (sel[i], i)) + builder.quick_push (CONSTM1_RTX (emode)); + else if (known_ge (sel[i], nelt)) + builder.quick_push (CONST0_RTX (emode)); + else + return NULL_RTX; + } + } + + return builder.build (); +} + /* Implement a permutation of vectors v0 and v1 using the permutation vector in SEL and return the result. Use TARGET to hold the result if nonnull and convenient. @@ -7803,8 +7825,7 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code, if (result) { /* PLUS worked so emit the insns and return. */ - tmp = get_insns (); - end_sequence (); + tmp = end_sequence (); emit_insn (tmp); return result; } @@ -7883,8 +7904,7 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code, /* For after, copy the value now. */ if (!unused_result && after) emit_move_insn (target, t1); - insn = get_insns (); - end_sequence (); + insn = end_sequence (); if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn)) return target; |