From 5906d0133520f77a2220aa61abe2ad428ac09e8f Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 2 Sep 2004 23:22:12 +0000 Subject: [PATCH] builtins.c (expand_builtin_cabs): Delete. 2004-09-02 Eric Christopher * builtins.c (expand_builtin_cabs): Delete. (expand_builtin): If unable to fold the values do a normal library call for builtin_cab*. (fold_builtin_cabs): Depend on optimize and optimize_size. * optabs.c (expand_cmplxdiv_straight): Delete. (expand_cmplxdiv_wide): Ditto. (expand_vector_binop): Ditto. (expand_vector_unop): Ditto. (expand_complex_abs): Delete. (expand_binop): Remove calls to above functions. Remove open coding of complex arithmetic. (expand_unop): Ditto. * optabs.h: Remove prototypes. From-SVN: r87000 --- gcc/ChangeLog | 86 ++-- gcc/builtins.c | 49 +-- gcc/optabs.c | 1132 +----------------------------------------------- gcc/optabs.h | 5 +- 4 files changed, 78 insertions(+), 1194 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9bf99a18d3a..b6e3cb29d88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-09-02 Eric Christopher + + * builtins.c (expand_builtin_cabs): Delete. + (expand_builtin): If unable to fold the values do a normal + library call for builtin_cab*. + (fold_builtin_cabs): Depend on optimize and optimize_size. + * optabs.c (expand_cmplxdiv_straight): Delete. + (expand_cmplxdiv_wide): Ditto. + (expand_vector_binop): Ditto. + (expand_vector_unop): Ditto. + (expand_complex_abs): Delete. + (expand_binop): Remove calls to above functions. + Remove open coding of complex arithmetic. + (expand_unop): Ditto. + * optabs.h: Remove prototypes. + 2004-09-02 Ziemowit Laski * c-decl.c (store_parm_decls_newstyle): Make externally visible. @@ -133,7 +149,7 @@ (struct algorithm): Change type of cost field to be mult_cost. (synth_mult): Change type of cost_limit argument to be a pointer to a mult_cost. Update all cost comparisons to use the - new mult_cost infrastructure. For alg_add_factor and + new mult_cost infrastructure. For alg_add_factor and alg_sub_factor operations, latency is lower than the rtx_cost. (choose_mult_variant): Update calls to synth_mult. Perform cost comparisons using the new mult_cost infrastructure. @@ -343,7 +359,7 @@ * config/arm/arm.c (arm_cxx_export_class_data): New function. (TARGET_CXX_EXPORT_CLASS_DATA): Use it. * doc/tm.texi (TARGET_CXX_EXPORT_CLASS_DATA): Document it. - + 2004-08-31 Kaz Kojima * config/sh/sh.c (output_branch): Check the insn length possibly @@ -384,7 +400,7 @@ (TARGET_CXX_KEY_METHOD_MAY_BE_INLINE): New macro. * config/arm/bpabi.h: Use __THUMB_INTERWORK__ instead of __THUMB_INTERWORK. - + 2004-08-31 Denis Chertykov PR target/15417 @@ -401,7 +417,7 @@ * config/darwin.c (darwin_make_decl_one_only): Allocate section names once per compilation, instead of once per symbol. - + 2004-08-31 Paolo Bonzini * Makefile.in (build_subdir): New substitution. @@ -420,7 +436,7 @@ * fixinc.in: New, from fixinc/fixincl.sh. * fixinc/*: Removed. - + 2004-08-31 Joseph S. Myers * attribs.c (strip_attrs): Remove. @@ -450,12 +466,12 @@ 2004-08-30 Andrew Pinski - * hard-reg-set.h: + * hard-reg-set.h: s/HOST_BITS_PER_WIDES_FAST_INT/HOST_BITS_PER_WIDEST_FAST_INT. * ChangeLog: Fix previous ChangeLog entry. PR rtl-opt/13987 - * config.host (use_long_long_for_widest_fast_int): New, default is + * config.host (use_long_long_for_widest_fast_int): New, default is off. (ia64-*-hpux*): Enable use_long_long_for_widest_fast_int. * configure.ac: If use_long_long_for_widest_fast_int, then @@ -468,7 +484,7 @@ * sbitmap.h (SBITMAP_ELT_BITS): Define based on HOST_BITS_PER_WIDEST_FAST_INT. (SBITMAP_ELT_TYPE): Define based on HOST_WIDEST_FAST_INT. - * hard-reg-set.h (HARD_REG_ELT_TYPE): Define based on + * hard-reg-set.h (HARD_REG_ELT_TYPE): Define based on HOST_WIDEST_FAST_INT instead of HOST_WIDE_INT. (HARD_REG_SET_LONGS): Likewise. @@ -515,7 +531,7 @@ 2004-08-30 Richard Henderson - * c-typeck.c (build_unary_op): Don't expand ADDR_EXPR of a + * c-typeck.c (build_unary_op): Don't expand ADDR_EXPR of a COMPONENT_REF to pointer arithmetic. * varasm.c (initializer_constant_valid_p): Allow "&(*c).f", for constant "c" as a valid constant initializer. Allow narrowing of @@ -769,7 +785,7 @@ 2004-08-29 Chao-ying Fu James E Wilson - + * config/mips/mips-modes.def (V2SF, CCV2, CCV4): New modes. Give CCV2 8 byte size and alignment. Give CCV4 16 byte size and alignment. * config/mips/mips-ps-3d.md: New file. @@ -811,7 +827,7 @@ (enum mips_builtins): New for MIPS builtin functions. (enum mips_function_type): New for the types of MIPS builtin functions. (enum mips_cmp_choice): New for the MIPS comparison builtin functions. - * config/mips/mips.md: New constants for paired single and MIPS-3D + * config/mips/mips.md: New constants for paired single and MIPS-3D instructions. Include the new mips-ps-3d.md file. (addv2sf3, subv2sf3, mulv2sf3, absv2sf2, negv2sf2, movv2sf, movv2sf_hardfloat_64bit): New named patterns. @@ -976,7 +992,7 @@ 2004-08-26 Fariborz Jahanian - * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Added + * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Added TFmode as additional register mode cloberred by call. 2004-08-26 Fariborz Jahanian @@ -997,7 +1013,7 @@ target mode. * config/rs6000/rs6000.md (movdi_update): Changed to movdi__update, to generate two versions. - + 2004-08-26 Daniel Berlin * Makefile.in (lambda-code.o): New. @@ -1016,11 +1032,11 @@ * lambda-mat.c: Include tree.h 2004-08-26 Daniel Berlin - Sebastian Pop - - * tree-data-ref.h: Include lambda.h + Sebastian Pop + + * tree-data-ref.h: Include lambda.h (free_dependence_relation): Declared here. - (free_dependence_relations): Ditto. + (free_dependence_relations): Ditto. (free_data_refs): Ditto. * tree-data-ref.c (free_dependence_relation): New function. (free_dependence_relations): Ditto. @@ -1038,7 +1054,7 @@ and classic_dist vectors. (analyze_all_data_dependences): Adjusted for using the new interface of compute_data_dependences_for_loop. Remove the statistics dump. - + 2004-08-26 Bob Wilson * config/xtensa/xtensa.c (xtensa_ld_opcodes, xtensa_st_opcodes): Delete. @@ -1064,7 +1080,7 @@ if the constant satisfies add_operand. 2004-08-25 Richard Henderson - + PR debug/10695 * config/alpha/alpha.c (emit_frame_store_1, emit_frame_store): New. (alpha_expand_prologue): Handle >32-bit frames. Generate proper @@ -1134,7 +1150,7 @@ (FOR_EACH_SSA_USE_OPERAND): New. Iterate over operands as uses. (FOR_EACH_SSA_DEF_OPERAND): New. Iterate over operands as defs. (FOR_EACH_SSA_MAYDEF_OPERAND): New. Iterate over V_MAY_DEFs. - * tree-ssa-operands.c (NULL_DEF_OPERAND_P, NULL_USE_OPERAND_P): New. + * tree-ssa-operands.c (NULL_DEF_OPERAND_P, NULL_USE_OPERAND_P): New. Empty operand pointers. * tree-flow-inline.h (op_iter_done): New. Return true if finished. (op_iter_next_use): New. Return next use_operand_p. @@ -1145,10 +1161,10 @@ (op_iter_init_def): New. Initialize structure and get the first def. (op_iter_init_tree): New. Initialize structure and get the first tree. (op_iter_next_maydef): New. Return next V_MAY_DEF operands. - (op_iter_init_maydef): New. Initialize structure and get the first + (op_iter_init_maydef): New. Initialize structure and get the first V_MAY_DEF operands. * tree-cfg.c (tree_duplicate_bb): Use new operand iterator. - * tree-dfa.c (compute_immediate_uses_for_stmt, + * tree-dfa.c (compute_immediate_uses_for_stmt, redirect_immediate_uses): Use new operand iterator. (v_may_defs_disappeared_p, v_must_defs_disappeared_p): Delete. (mark_new_vars_to_rename): Use new operand iterator. Count virtual @@ -1159,12 +1175,12 @@ rewrite_trees): Use new operand iterator. * tree-pretty-print.c (dump_vops): Use new operand iterator. * tree-sra.c (mark_all_v_defs): Use new operand iterator. - * tree-ssa-alias.c (compute_points_to_and_addr_escape, + * tree-ssa-alias.c (compute_points_to_and_addr_escape, dump_points_to_info): Use new operand iterator. - * tree-ssa-ccp.c (cp_lattice_meet, visit_stmt, initialize, - replace_uses_in, replace_vuse_in, likely_value, set_rhs): Use new + * tree-ssa-ccp.c (cp_lattice_meet, visit_stmt, initialize, + replace_uses_in, replace_vuse_in, likely_value, set_rhs): Use new operand iterator. - * tree-ssa-dce.c (mark_stmt_if_obviously_necessary, + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary, propagate_necessity): Use new operand iterator. * tree-ssa-dom.c (cprop_into_stmt, optimize_stmt): Use operand iterator. (register_definitions_for_stmt): Use new operand iterator. Take stmt as @@ -1173,7 +1189,7 @@ build_tree_conflict_graph): Use new operand iterator. * tree-ssa-loop-im.c (determine_max_movement, single_reachable_address, rewrite_mem_refs): Use new operand iterator. - * tree-ssa-loop-manip.c (find_uses_to_rename_stmt, + * tree-ssa-loop-manip.c (find_uses_to_rename_stmt, check_loop_closed_ssa_use): Use new operand iterator. * tree-ssa.c (verify_ssa, replace_immediate_uses): Use operand iterator. * tree-ssanames.c (release_defs): Use new operand iterator. @@ -1203,19 +1219,19 @@ to comments at start of function. * cfgbuild.c (make_edges): Add more details to hot/cold partitioning comment. - * cfgcleanup.c (try_simplify_condjump, try_forward_edges, - merge_blocks_move_predecessor_nojumps, - merge_blocks_move_successor_nojumps, merge_blocks_move, + * cfgcleanup.c (try_simplify_condjump, try_forward_edges, + merge_blocks_move_predecessor_nojumps, + merge_blocks_move_successor_nojumps, merge_blocks_move, try_crossjump_to_edge, try_crossjump_bb): Likewise. * cfglayout.c (fixup_reorder_chain): Likewise. * cfgrtl.c (rtl_can_merge_blocks, try_redirect_by_replacing_jump, cfg_layout_can_merge_blocks_p): Likewise. * ifcvt.c (find_if_case_1, find_if_case_2): Likewise. - * passes.c (rest_of_compilation): Update comments for calling + * passes.c (rest_of_compilation): Update comments for calling optimization that partitions hot/cold basic blocks. - * doc/invoke.texi: Update documentation of + * doc/invoke.texi: Update documentation of freorder-blocks-and-partition flag. - + 2004-08-25 Richard Sandiford * config/mips/mips.md (reg): Renamed mode attribute from ccreg. @@ -1246,7 +1262,7 @@ PR libstdc++/17005 (fix for HP-UX 11.11) * config.gcc (hppa*-*-*): Move MASK_BIG_SWITCH to target_cpu_default2. (hppa*-*-hpux*): Consolidate hppa1.0-*-* code. Rework handling of - tm_file including pa-hpux1010.h or pa-hpux1111.h when appropriate. + tm_file including pa-hpux1010.h or pa-hpux1111.h when appropriate. * config/pa/pa-hpux1010.h, config/pa/pa-hpux1111.h: New files. * config/pa/pa-hpux.h (TARGET_HPUX): Define. (LINK_SPEC): Handle march=1.0 option. @@ -1377,7 +1393,7 @@ Likewise. * config/xtensa/xtensa.c (xtensa_va_start, xtensa_gimplify_va_arg_expr): Likewise. - + * objc/objc-act.c (build_objc_string_object, build_objc_symtab_template, init_def_list, init_objc_symtab, init_module_descriptor, generate_static_references, diff --git a/gcc/builtins.c b/gcc/builtins.c index 2e019d3bfbf..b0d7c4c779e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -145,7 +145,6 @@ static bool integer_valued_real_p (tree); static tree fold_trunc_transparent_mathfn (tree); static bool readonly_data_expr (tree); static rtx expand_builtin_fabs (tree, rtx, rtx); -static rtx expand_builtin_cabs (tree, rtx); static rtx expand_builtin_signbit (tree, rtx); static tree fold_builtin_cabs (tree, tree); static tree fold_builtin_trunc (tree); @@ -377,7 +376,7 @@ c_readstr (const char *str, enum machine_mode mode) unsigned int i, j; gcc_assert (GET_MODE_CLASS (mode) == MODE_INT); - + c[0] = 0; c[1] = 0; ch = 1; @@ -391,7 +390,7 @@ c_readstr (const char *str, enum machine_mode mode) j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1; j *= BITS_PER_UNIT; gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT); - + if (ch) ch = (unsigned char) str[i]; c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT); @@ -758,7 +757,7 @@ expand_builtin_longjmp (rtx buf_addr, rtx value) for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) { gcc_assert (insn != last); - + if (JUMP_P (insn)) { REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx, @@ -1358,7 +1357,7 @@ expand_builtin_apply (rtx function, rtx arguments, rtx argsize) if ((mode = apply_result_mode[regno]) != VOIDmode) { gcc_assert (!valreg); /* HAVE_untyped_call required. */ - + valreg = gen_rtx_REG (mode, regno); } @@ -2030,7 +2029,7 @@ expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget) if (builtin_optab == sincos_optab) { int result; - + switch (DECL_FUNCTION_CODE (fndecl)) { case BUILT_IN_SIN: @@ -4620,7 +4619,7 @@ expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target, target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))), op_optab, op0, target, 1); gcc_assert (target); - + return convert_to_mode (target_mode, target, 0); } @@ -4897,30 +4896,6 @@ expand_builtin_fabs (tree arglist, rtx target, rtx subtarget) return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1)); } -/* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST. - Return 0 if a normal call should be emitted rather than expanding - the function inline. If convenient, the result should be placed - in target. */ - -static rtx -expand_builtin_cabs (tree arglist, rtx target) -{ - enum machine_mode mode; - tree arg; - rtx op0; - - if (arglist == 0 || TREE_CHAIN (arglist)) - return 0; - arg = TREE_VALUE (arglist); - if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE - || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE) - return 0; - - mode = TYPE_MODE (TREE_TYPE (arg)); - op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0); - return expand_complex_abs (mode, op0, target, 0); -} - /* Create a new constant string literal and return a char* pointer to it. The STRING_CST value is the LEN characters at STR. */ static tree @@ -5550,15 +5525,11 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, return target; break; + /* Just do a normal library call if we were unable to fold + the values. */ case BUILT_IN_CABS: case BUILT_IN_CABSF: case BUILT_IN_CABSL: - if (flag_unsafe_math_optimizations) - { - target = expand_builtin_cabs (arglist, target); - if (target) - return target; - } break; case BUILT_IN_EXP: @@ -6518,7 +6489,9 @@ fold_builtin_cabs (tree arglist, tree type) && real_zerop (TREE_OPERAND (arg, 1))) return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0))); - if (flag_unsafe_math_optimizations) + /* Don't do this when optimizing for size. */ + if (flag_unsafe_math_optimizations + && optimize && !optimize_size) { tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); diff --git a/gcc/optabs.c b/gcc/optabs.c index 0e8bb31984f..6c47b57f001 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -92,13 +92,6 @@ static GTY(()) rtx trap_rtx; static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx); static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int, int); -static int expand_cmplxdiv_straight (rtx, rtx, rtx, rtx, rtx, rtx, - enum machine_mode, int, - enum optab_methods, enum mode_class, - optab); -static int expand_cmplxdiv_wide (rtx, rtx, rtx, rtx, rtx, rtx, - enum machine_mode, int, enum optab_methods, - enum mode_class, optab); static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx, enum machine_mode *, int *, enum can_compare_purpose); @@ -121,9 +114,6 @@ static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode, enum rtx_code, int, rtx); static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *, enum machine_mode *, int *); -static rtx expand_vector_binop (enum machine_mode, optab, rtx, rtx, rtx, int, - enum optab_methods); -static rtx expand_vector_unop (enum machine_mode, optab, rtx, rtx, int); static rtx widen_clz (enum machine_mode, rtx, rtx); static rtx expand_parity (enum machine_mode, rtx, rtx); @@ -241,393 +231,6 @@ widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode, return result; } -/* Generate code to perform a straightforward complex divide. */ - -static int -expand_cmplxdiv_straight (rtx real0, rtx real1, rtx imag0, rtx imag1, - rtx realr, rtx imagr, enum machine_mode submode, - int unsignedp, enum optab_methods methods, - enum mode_class class, optab binoptab) -{ - rtx divisor; - rtx real_t, imag_t; - rtx temp1, temp2; - rtx res; - optab this_add_optab = add_optab; - optab this_sub_optab = sub_optab; - optab this_neg_optab = neg_optab; - optab this_mul_optab = smul_optab; - - if (binoptab == sdivv_optab) - { - this_add_optab = addv_optab; - this_sub_optab = subv_optab; - this_neg_optab = negv_optab; - this_mul_optab = smulv_optab; - } - - /* Don't fetch these from memory more than once. */ - real0 = force_reg (submode, real0); - real1 = force_reg (submode, real1); - - if (imag0 != 0) - imag0 = force_reg (submode, imag0); - - imag1 = force_reg (submode, imag1); - - /* Divisor: c*c + d*d. */ - temp1 = expand_binop (submode, this_mul_optab, real1, real1, - NULL_RTX, unsignedp, methods); - - temp2 = expand_binop (submode, this_mul_optab, imag1, imag1, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0 || temp2 == 0) - return 0; - - divisor = expand_binop (submode, this_add_optab, temp1, temp2, - NULL_RTX, unsignedp, methods); - if (divisor == 0) - return 0; - - if (imag0 == 0) - { - /* Mathematically, ((a)(c-id))/divisor. */ - /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */ - - /* Calculate the dividend. */ - real_t = expand_binop (submode, this_mul_optab, real0, real1, - NULL_RTX, unsignedp, methods); - - imag_t = expand_binop (submode, this_mul_optab, real0, imag1, - NULL_RTX, unsignedp, methods); - - if (real_t == 0 || imag_t == 0) - return 0; - - imag_t = expand_unop (submode, this_neg_optab, imag_t, - NULL_RTX, unsignedp); - } - else - { - /* Mathematically, ((a+ib)(c-id))/divider. */ - /* Calculate the dividend. */ - temp1 = expand_binop (submode, this_mul_optab, real0, real1, - NULL_RTX, unsignedp, methods); - - temp2 = expand_binop (submode, this_mul_optab, imag0, imag1, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0 || temp2 == 0) - return 0; - - real_t = expand_binop (submode, this_add_optab, temp1, temp2, - NULL_RTX, unsignedp, methods); - - temp1 = expand_binop (submode, this_mul_optab, imag0, real1, - NULL_RTX, unsignedp, methods); - - temp2 = expand_binop (submode, this_mul_optab, real0, imag1, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0 || temp2 == 0) - return 0; - - imag_t = expand_binop (submode, this_sub_optab, temp1, temp2, - NULL_RTX, unsignedp, methods); - - if (real_t == 0 || imag_t == 0) - return 0; - } - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, real_t, divisor, - realr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - real_t, divisor, realr, unsignedp); - - if (res == 0) - return 0; - - if (res != realr) - emit_move_insn (realr, res); - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, imag_t, divisor, - imagr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - imag_t, divisor, imagr, unsignedp); - - if (res == 0) - return 0; - - if (res != imagr) - emit_move_insn (imagr, res); - - return 1; -} - -/* Generate code to perform a wide-input-range-acceptable complex divide. */ - -static int -expand_cmplxdiv_wide (rtx real0, rtx real1, rtx imag0, rtx imag1, rtx realr, - rtx imagr, enum machine_mode submode, int unsignedp, - enum optab_methods methods, enum mode_class class, - optab binoptab) -{ - rtx ratio, divisor; - rtx real_t, imag_t; - rtx temp1, temp2, lab1, lab2; - enum machine_mode mode; - rtx res; - optab this_add_optab = add_optab; - optab this_sub_optab = sub_optab; - optab this_neg_optab = neg_optab; - optab this_mul_optab = smul_optab; - - if (binoptab == sdivv_optab) - { - this_add_optab = addv_optab; - this_sub_optab = subv_optab; - this_neg_optab = negv_optab; - this_mul_optab = smulv_optab; - } - - /* Don't fetch these from memory more than once. */ - real0 = force_reg (submode, real0); - real1 = force_reg (submode, real1); - - if (imag0 != 0) - imag0 = force_reg (submode, imag0); - - imag1 = force_reg (submode, imag1); - - /* XXX What's an "unsigned" complex number? */ - if (unsignedp) - { - temp1 = real1; - temp2 = imag1; - } - else - { - temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1); - temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1); - } - - if (temp1 == 0 || temp2 == 0) - return 0; - - mode = GET_MODE (temp1); - lab1 = gen_label_rtx (); - emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX, - mode, unsignedp, lab1); - - /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */ - - if (class == MODE_COMPLEX_FLOAT) - ratio = expand_binop (submode, binoptab, imag1, real1, - NULL_RTX, unsignedp, methods); - else - ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode, - imag1, real1, NULL_RTX, unsignedp); - - if (ratio == 0) - return 0; - - /* Calculate divisor. */ - - temp1 = expand_binop (submode, this_mul_optab, imag1, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - divisor = expand_binop (submode, this_add_optab, temp1, real1, - NULL_RTX, unsignedp, methods); - - if (divisor == 0) - return 0; - - /* Calculate dividend. */ - - if (imag0 == 0) - { - real_t = real0; - - /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */ - - imag_t = expand_binop (submode, this_mul_optab, real0, ratio, - NULL_RTX, unsignedp, methods); - - if (imag_t == 0) - return 0; - - imag_t = expand_unop (submode, this_neg_optab, imag_t, - NULL_RTX, unsignedp); - - if (real_t == 0 || imag_t == 0) - return 0; - } - else - { - /* Compute (a+ib)/(c+id) as - (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */ - - temp1 = expand_binop (submode, this_mul_optab, imag0, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - real_t = expand_binop (submode, this_add_optab, temp1, real0, - NULL_RTX, unsignedp, methods); - - temp1 = expand_binop (submode, this_mul_optab, real0, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - imag_t = expand_binop (submode, this_sub_optab, imag0, temp1, - NULL_RTX, unsignedp, methods); - - if (real_t == 0 || imag_t == 0) - return 0; - } - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, real_t, divisor, - realr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - real_t, divisor, realr, unsignedp); - - if (res == 0) - return 0; - - if (res != realr) - emit_move_insn (realr, res); - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, imag_t, divisor, - imagr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - imag_t, divisor, imagr, unsignedp); - - if (res == 0) - return 0; - - if (res != imagr) - emit_move_insn (imagr, res); - - lab2 = gen_label_rtx (); - emit_jump_insn (gen_jump (lab2)); - emit_barrier (); - - emit_label (lab1); - - /* |d| > |c|; use ratio c/d to scale dividend and divisor. */ - - if (class == MODE_COMPLEX_FLOAT) - ratio = expand_binop (submode, binoptab, real1, imag1, - NULL_RTX, unsignedp, methods); - else - ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode, - real1, imag1, NULL_RTX, unsignedp); - - if (ratio == 0) - return 0; - - /* Calculate divisor. */ - - temp1 = expand_binop (submode, this_mul_optab, real1, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - divisor = expand_binop (submode, this_add_optab, temp1, imag1, - NULL_RTX, unsignedp, methods); - - if (divisor == 0) - return 0; - - /* Calculate dividend. */ - - if (imag0 == 0) - { - /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */ - - real_t = expand_binop (submode, this_mul_optab, real0, ratio, - NULL_RTX, unsignedp, methods); - - imag_t = expand_unop (submode, this_neg_optab, real0, - NULL_RTX, unsignedp); - - if (real_t == 0 || imag_t == 0) - return 0; - } - else - { - /* Compute (a+ib)/(c+id) as - (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */ - - temp1 = expand_binop (submode, this_mul_optab, real0, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - real_t = expand_binop (submode, this_add_optab, temp1, imag0, - NULL_RTX, unsignedp, methods); - - temp1 = expand_binop (submode, this_mul_optab, imag0, ratio, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0) - return 0; - - imag_t = expand_binop (submode, this_sub_optab, temp1, real0, - NULL_RTX, unsignedp, methods); - - if (real_t == 0 || imag_t == 0) - return 0; - } - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, real_t, divisor, - realr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - real_t, divisor, realr, unsignedp); - - if (res == 0) - return 0; - - if (res != realr) - emit_move_insn (realr, res); - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, imag_t, divisor, - imagr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - imag_t, divisor, imagr, unsignedp); - - if (res == 0) - return 0; - - if (res != imagr) - emit_move_insn (imagr, res); - - emit_label (lab2); - - return 1; -} - /* Return the optab used for computing the operation given by the tree code, CODE. This function is not always usable (for example, it cannot give complete results for multiplication @@ -1586,257 +1189,6 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, delete_insns_since (last); } - /* Open-code the vector operations if we have no hardware support - for them. */ - if (class == MODE_VECTOR_INT || class == MODE_VECTOR_FLOAT) - return expand_vector_binop (mode, binoptab, op0, op1, target, - unsignedp, methods); - - /* We need to open-code the complex type operations: '+, -, * and /' */ - - /* At this point we allow operations between two similar complex - numbers, and also if one of the operands is not a complex number - but rather of MODE_FLOAT or MODE_INT. However, the caller - must make sure that the MODE of the non-complex operand matches - the SUBMODE of the complex operand. */ - - if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT) - { - rtx real0 = 0, imag0 = 0; - rtx real1 = 0, imag1 = 0; - rtx realr, imagr, res; - rtx seq, result; - int ok = 0; - - /* Find the correct mode for the real and imaginary parts. */ - enum machine_mode submode = GET_MODE_INNER (mode); - - if (submode == BLKmode) - abort (); - - start_sequence (); - - if (GET_MODE (op0) == mode) - { - real0 = gen_realpart (submode, op0); - imag0 = gen_imagpart (submode, op0); - } - else - real0 = op0; - - if (GET_MODE (op1) == mode) - { - real1 = gen_realpart (submode, op1); - imag1 = gen_imagpart (submode, op1); - } - else - real1 = op1; - - if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0)) - abort (); - - result = gen_reg_rtx (mode); - realr = gen_realpart (submode, result); - imagr = gen_imagpart (submode, result); - - switch (binoptab->code) - { - case PLUS: - /* (a+ib) + (c+id) = (a+c) + i(b+d) */ - case MINUS: - /* (a+ib) - (c+id) = (a-c) + i(b-d) */ - res = expand_binop (submode, binoptab, real0, real1, - realr, unsignedp, methods); - - if (res == 0) - break; - else if (res != realr) - emit_move_insn (realr, res); - - if (imag0 != 0 && imag1 != 0) - res = expand_binop (submode, binoptab, imag0, imag1, - imagr, unsignedp, methods); - else if (imag0 != 0) - res = imag0; - else if (binoptab->code == MINUS) - res = expand_unop (submode, - binoptab == subv_optab ? negv_optab : neg_optab, - imag1, imagr, unsignedp); - else - res = imag1; - - if (res == 0) - break; - else if (res != imagr) - emit_move_insn (imagr, res); - - ok = 1; - break; - - case MULT: - /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */ - - if (imag0 != 0 && imag1 != 0) - { - rtx temp1, temp2; - - /* Don't fetch these from memory more than once. */ - real0 = force_reg (submode, real0); - real1 = force_reg (submode, real1); - imag0 = force_reg (submode, imag0); - imag1 = force_reg (submode, imag1); - - temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX, - unsignedp, methods); - - temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX, - unsignedp, methods); - - if (temp1 == 0 || temp2 == 0) - break; - - res = (expand_binop - (submode, - binoptab == smulv_optab ? subv_optab : sub_optab, - temp1, temp2, realr, unsignedp, methods)); - - if (res == 0) - break; - else if (res != realr) - emit_move_insn (realr, res); - - temp1 = expand_binop (submode, binoptab, real0, imag1, - NULL_RTX, unsignedp, methods); - - /* Avoid expanding redundant multiplication for the common - case of squaring a complex number. */ - if (rtx_equal_p (real0, real1) && rtx_equal_p (imag0, imag1)) - temp2 = temp1; - else - temp2 = expand_binop (submode, binoptab, real1, imag0, - NULL_RTX, unsignedp, methods); - - if (temp1 == 0 || temp2 == 0) - break; - - res = (expand_binop - (submode, - binoptab == smulv_optab ? addv_optab : add_optab, - temp1, temp2, imagr, unsignedp, methods)); - - if (res == 0) - break; - else if (res != imagr) - emit_move_insn (imagr, res); - - ok = 1; - } - else - { - /* Don't fetch these from memory more than once. */ - real0 = force_reg (submode, real0); - real1 = force_reg (submode, real1); - - res = expand_binop (submode, binoptab, real0, real1, - realr, unsignedp, methods); - if (res == 0) - break; - else if (res != realr) - emit_move_insn (realr, res); - - if (imag0 != 0) - res = expand_binop (submode, binoptab, - real1, imag0, imagr, unsignedp, methods); - else - res = expand_binop (submode, binoptab, - real0, imag1, imagr, unsignedp, methods); - - if (res == 0) - break; - else if (res != imagr) - emit_move_insn (imagr, res); - - ok = 1; - } - break; - - case DIV: - /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */ - - if (imag1 == 0) - { - /* (a+ib) / (c+i0) = (a/c) + i(b/c) */ - - /* Don't fetch these from memory more than once. */ - real1 = force_reg (submode, real1); - - /* Simply divide the real and imaginary parts by `c' */ - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, real0, real1, - realr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - real0, real1, realr, unsignedp); - - if (res == 0) - break; - else if (res != realr) - emit_move_insn (realr, res); - - if (class == MODE_COMPLEX_FLOAT) - res = expand_binop (submode, binoptab, imag0, real1, - imagr, unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - imag0, real1, imagr, unsignedp); - - if (res == 0) - break; - else if (res != imagr) - emit_move_insn (imagr, res); - - ok = 1; - } - else - { - switch (flag_complex_divide_method) - { - case 0: - ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1, - realr, imagr, submode, - unsignedp, methods, - class, binoptab); - break; - - case 1: - ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1, - realr, imagr, submode, - unsignedp, methods, - class, binoptab); - break; - - default: - abort (); - } - } - break; - - default: - abort (); - } - - seq = get_insns (); - end_sequence (); - - if (ok) - { - rtx equiv = gen_rtx_fmt_ee (binoptab->code, mode, - copy_rtx (op0), copy_rtx (op1)); - emit_no_conflict_block (seq, result, op0, op1, equiv); - return result; - } - } - /* It can't be open-coded in this mode. Use a library call if one is available and caller says that's ok. */ @@ -1952,222 +1304,6 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, delete_insns_since (entry_last); return 0; } - -/* Like expand_binop, but for open-coding vectors binops. */ - -static rtx -expand_vector_binop (enum machine_mode mode, optab binoptab, rtx op0, - rtx op1, rtx target, int unsignedp, - enum optab_methods methods) -{ - enum machine_mode submode, tmode; - int size, elts, subsize, subbitsize, i; - rtx t, a, b, res, seq; - enum mode_class class; - - class = GET_MODE_CLASS (mode); - - size = GET_MODE_SIZE (mode); - submode = GET_MODE_INNER (mode); - - /* Search for the widest vector mode with the same inner mode that is - still narrower than MODE and that allows to open-code this operator. - Note, if we find such a mode and the handler later decides it can't - do the expansion, we'll be called recursively with the narrower mode. */ - for (tmode = GET_CLASS_NARROWEST_MODE (class); - GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode); - tmode = GET_MODE_WIDER_MODE (tmode)) - { - if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode) - && binoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) - submode = tmode; - } - - switch (binoptab->code) - { - case AND: - case IOR: - case XOR: - tmode = int_mode_for_mode (mode); - if (tmode != BLKmode) - submode = tmode; - case PLUS: - case MINUS: - case MULT: - case DIV: - subsize = GET_MODE_SIZE (submode); - subbitsize = GET_MODE_BITSIZE (submode); - elts = size / subsize; - - /* If METHODS is OPTAB_DIRECT, we don't insist on the exact mode, - but that we operate on more than one element at a time. */ - if (subsize == GET_MODE_UNIT_SIZE (mode) && methods == OPTAB_DIRECT) - return 0; - - start_sequence (); - - /* Errors can leave us with a const0_rtx as operand. */ - if (GET_MODE (op0) != mode) - op0 = copy_to_mode_reg (mode, op0); - if (GET_MODE (op1) != mode) - op1 = copy_to_mode_reg (mode, op1); - - if (!target) - target = gen_reg_rtx (mode); - - for (i = 0; i < elts; ++i) - { - /* If this is part of a register, and not the first item in the - word, we can't store using a SUBREG - that would clobber - previous results. - And storing with a SUBREG is only possible for the least - significant part, hence we can't do it for big endian - (unless we want to permute the evaluation order. */ - if (REG_P (target) - && (BYTES_BIG_ENDIAN - ? subsize < UNITS_PER_WORD - : ((i * subsize) % UNITS_PER_WORD) != 0)) - t = NULL_RTX; - else - t = simplify_gen_subreg (submode, target, mode, i * subsize); - if (CONSTANT_P (op0)) - a = simplify_gen_subreg (submode, op0, mode, i * subsize); - else - a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp, - NULL_RTX, submode, submode); - if (CONSTANT_P (op1)) - b = simplify_gen_subreg (submode, op1, mode, i * subsize); - else - b = extract_bit_field (op1, subbitsize, i * subbitsize, unsignedp, - NULL_RTX, submode, submode); - - if (binoptab->code == DIV) - { - if (class == MODE_VECTOR_FLOAT) - res = expand_binop (submode, binoptab, a, b, t, - unsignedp, methods); - else - res = expand_divmod (0, TRUNC_DIV_EXPR, submode, - a, b, t, unsignedp); - } - else - res = expand_binop (submode, binoptab, a, b, t, - unsignedp, methods); - - if (res == 0) - break; - - if (t) - emit_move_insn (t, res); - else - store_bit_field (target, subbitsize, i * subbitsize, submode, res); - } - break; - - default: - abort (); - } - - seq = get_insns (); - end_sequence (); - emit_insn (seq); - - return target; -} - -/* Like expand_unop but for open-coding vector unops. */ - -static rtx -expand_vector_unop (enum machine_mode mode, optab unoptab, rtx op0, - rtx target, int unsignedp) -{ - enum machine_mode submode, tmode; - int size, elts, subsize, subbitsize, i; - rtx t, a, res, seq; - - size = GET_MODE_SIZE (mode); - submode = GET_MODE_INNER (mode); - - /* Search for the widest vector mode with the same inner mode that is - still narrower than MODE and that allows to open-code this operator. - Note, if we find such a mode and the handler later decides it can't - do the expansion, we'll be called recursively with the narrower mode. */ - for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode)); - GET_MODE_SIZE (tmode) < GET_MODE_SIZE (mode); - tmode = GET_MODE_WIDER_MODE (tmode)) - { - if (GET_MODE_INNER (tmode) == GET_MODE_INNER (mode) - && unoptab->handlers[(int) tmode].insn_code != CODE_FOR_nothing) - submode = tmode; - } - /* If there is no negate operation, try doing a subtract from zero. */ - if (unoptab == neg_optab && GET_MODE_CLASS (submode) == MODE_INT - /* Avoid infinite recursion when an - error has left us with the wrong mode. */ - && GET_MODE (op0) == mode) - { - rtx temp; - temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0, - target, unsignedp, OPTAB_DIRECT); - if (temp) - return temp; - } - - if (unoptab == one_cmpl_optab) - { - tmode = int_mode_for_mode (mode); - if (tmode != BLKmode) - submode = tmode; - } - - subsize = GET_MODE_SIZE (submode); - subbitsize = GET_MODE_BITSIZE (submode); - elts = size / subsize; - - /* Errors can leave us with a const0_rtx as operand. */ - if (GET_MODE (op0) != mode) - op0 = copy_to_mode_reg (mode, op0); - - if (!target) - target = gen_reg_rtx (mode); - - start_sequence (); - - for (i = 0; i < elts; ++i) - { - /* If this is part of a register, and not the first item in the - word, we can't store using a SUBREG - that would clobber - previous results. - And storing with a SUBREG is only possible for the least - significant part, hence we can't do it for big endian - (unless we want to permute the evaluation order. */ - if (REG_P (target) - && (BYTES_BIG_ENDIAN - ? subsize < UNITS_PER_WORD - : ((i * subsize) % UNITS_PER_WORD) != 0)) - t = NULL_RTX; - else - t = simplify_gen_subreg (submode, target, mode, i * subsize); - if (CONSTANT_P (op0)) - a = simplify_gen_subreg (submode, op0, mode, i * subsize); - else - a = extract_bit_field (op0, subbitsize, i * subbitsize, unsignedp, - t, submode, submode); - - res = expand_unop (submode, unoptab, a, t, unsignedp); - - if (t) - emit_move_insn (t, res); - else - store_bit_field (target, subbitsize, i * subbitsize, submode, res); - } - - seq = get_insns (); - end_sequence (); - emit_insn (seq); - - return target; -} /* Expand a binary operator which has both signed and unsigned forms. UOPTAB is the optab for unsigned operations, and SOPTAB is for @@ -2459,14 +1595,14 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1, mode of OP0. Returns 1 if the call was successful. */ bool -expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, +expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1, enum rtx_code code) { enum machine_mode mode; enum machine_mode libval_mode; rtx libval; rtx insns; - + /* Exactly one of TARG0 or TARG1 should be non-NULL. */ if (!((targ0 != NULL_RTX) ^ (targ1 != NULL_RTX))) abort (); @@ -2477,13 +1613,13 @@ expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, /* The value returned by the library function will have twice as many bits as the nominal MODE. */ - libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode), + libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode), MODE_INT); start_sequence (); libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc, - NULL_RTX, LCT_CONST, + NULL_RTX, LCT_CONST, libval_mode, 2, - op0, mode, + op0, mode, op1, mode); /* Get the part of VAL containing the value that we want. */ libval = simplify_gen_subreg (mode, libval, libval_mode, @@ -2491,9 +1627,9 @@ expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1, insns = get_insns (); end_sequence (); /* Move the into the desired location. */ - emit_libcall_block (insns, targ0 ? targ0 : targ1, libval, + emit_libcall_block (insns, targ0 ? targ0 : targ1, libval, gen_rtx_fmt_ee (code, mode, op0, op1)); - + return true; } @@ -2740,48 +1876,6 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, return target; } - /* Open-code the complex negation operation. */ - else if (unoptab->code == NEG - && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)) - { - rtx target_piece; - rtx x; - rtx seq; - - /* Find the correct mode for the real and imaginary parts. */ - enum machine_mode submode = GET_MODE_INNER (mode); - - if (submode == BLKmode) - abort (); - - if (target == 0) - target = gen_reg_rtx (mode); - - start_sequence (); - - target_piece = gen_imagpart (submode, target); - x = expand_unop (submode, unoptab, - gen_imagpart (submode, op0), - target_piece, unsignedp); - if (target_piece != x) - emit_move_insn (target_piece, x); - - target_piece = gen_realpart (submode, target); - x = expand_unop (submode, unoptab, - gen_realpart (submode, op0), - target_piece, unsignedp); - if (target_piece != x) - emit_move_insn (target_piece, x); - - seq = get_insns (); - end_sequence (); - - emit_no_conflict_block (seq, target, op0, 0, - gen_rtx_fmt_e (unoptab->code, mode, - copy_rtx (op0))); - return target; - } - /* Try negating floating point values by flipping the sign bit. */ if (unoptab->code == NEG && class == MODE_FLOAT && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT) @@ -2881,9 +1975,6 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target, return target; } - if (class == MODE_VECTOR_FLOAT || class == MODE_VECTOR_INT) - return expand_vector_unop (mode, unoptab, op0, target, unsignedp); - /* It can't be done in this mode. Can we do it in a wider mode? */ if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT) @@ -3116,199 +2207,6 @@ expand_abs (enum machine_mode mode, rtx op0, rtx target, return target; } -/* Emit code to compute the absolute value of OP0, with result to - TARGET if convenient. (TARGET may be 0.) The return value says - where the result actually is to be found. - - MODE is the mode of the operand; the mode of the result is - different but can be deduced from MODE. - - UNSIGNEDP is relevant for complex integer modes. */ - -rtx -expand_complex_abs (enum machine_mode mode, rtx op0, rtx target, - int unsignedp) -{ - enum mode_class class = GET_MODE_CLASS (mode); - enum machine_mode wider_mode; - rtx temp; - rtx entry_last = get_last_insn (); - rtx last; - rtx pat; - optab this_abs_optab; - - /* Find the correct mode for the real and imaginary parts. */ - enum machine_mode submode = GET_MODE_INNER (mode); - - if (submode == BLKmode) - abort (); - - if (flag_force_mem) - op0 = force_not_mem (op0); - - last = get_last_insn (); - - this_abs_optab = ! unsignedp && flag_trapv - && (GET_MODE_CLASS(mode) == MODE_INT) - ? absv_optab : abs_optab; - - if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) - { - int icode = (int) this_abs_optab->handlers[(int) mode].insn_code; - enum machine_mode mode0 = insn_data[icode].operand[1].mode; - rtx xop0 = op0; - - if (target) - temp = target; - else - temp = gen_reg_rtx (submode); - - if (GET_MODE (xop0) != VOIDmode - && GET_MODE (xop0) != mode0) - xop0 = convert_to_mode (mode0, xop0, unsignedp); - - /* Now, if insn doesn't accept our operand, put it into a pseudo. */ - - if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)) - xop0 = copy_to_mode_reg (mode0, xop0); - - if (! (*insn_data[icode].operand[0].predicate) (temp, submode)) - temp = gen_reg_rtx (submode); - - pat = GEN_FCN (icode) (temp, xop0); - if (pat) - { - if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX - && ! add_equal_note (pat, temp, this_abs_optab->code, xop0, - NULL_RTX)) - { - delete_insns_since (last); - return expand_unop (mode, this_abs_optab, op0, NULL_RTX, - unsignedp); - } - - emit_insn (pat); - - return temp; - } - else - delete_insns_since (last); - } - - /* It can't be done in this mode. Can we open-code it in a wider mode? */ - - for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; - wider_mode = GET_MODE_WIDER_MODE (wider_mode)) - { - if (this_abs_optab->handlers[(int) wider_mode].insn_code - != CODE_FOR_nothing) - { - rtx xop0 = op0; - - xop0 = convert_modes (wider_mode, mode, xop0, unsignedp); - temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp); - - if (temp) - { - if (class != MODE_COMPLEX_INT) - { - if (target == 0) - target = gen_reg_rtx (submode); - convert_move (target, temp, 0); - return target; - } - else - return gen_lowpart (submode, temp); - } - else - delete_insns_since (last); - } - } - - /* Open-code the complex absolute-value operation - if we can open-code sqrt. Otherwise it's not worth while. */ - if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing - && ! flag_trapv) - { - rtx real, imag, total; - - real = gen_realpart (submode, op0); - imag = gen_imagpart (submode, op0); - - /* Square both parts. */ - real = expand_mult (submode, real, real, NULL_RTX, 0); - imag = expand_mult (submode, imag, imag, NULL_RTX, 0); - - /* Sum the parts. */ - total = expand_binop (submode, add_optab, real, imag, NULL_RTX, - 0, OPTAB_LIB_WIDEN); - - /* Get sqrt in TARGET. Set TARGET to where the result is. */ - target = expand_unop (submode, sqrt_optab, total, target, 0); - if (target == 0) - delete_insns_since (last); - else - return target; - } - - /* Now try a library call in this mode. */ - if (this_abs_optab->handlers[(int) mode].libfunc) - { - rtx insns; - rtx value; - - start_sequence (); - - /* Pass 1 for NO_QUEUE so we don't lose any increments - if the libcall is cse'd or moved. */ - value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc, - NULL_RTX, LCT_CONST, submode, 1, op0, mode); - insns = get_insns (); - end_sequence (); - - target = gen_reg_rtx (submode); - emit_libcall_block (insns, target, value, - gen_rtx_fmt_e (this_abs_optab->code, mode, op0)); - - return target; - } - - /* It can't be done in this mode. Can we do it in a wider mode? */ - - for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode; - wider_mode = GET_MODE_WIDER_MODE (wider_mode)) - { - if ((this_abs_optab->handlers[(int) wider_mode].insn_code - != CODE_FOR_nothing) - || this_abs_optab->handlers[(int) wider_mode].libfunc) - { - rtx xop0 = op0; - - xop0 = convert_modes (wider_mode, mode, xop0, unsignedp); - - temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp); - - if (temp) - { - if (class != MODE_COMPLEX_INT) - { - if (target == 0) - target = gen_reg_rtx (submode); - convert_move (target, temp, 0); - return target; - } - else - return gen_lowpart (submode, temp); - } - else - delete_insns_since (last); - } - } - - delete_insns_since (entry_last); - return 0; -} - /* Generate an instruction whose insn-code is INSN_CODE, with two operands: an output TARGET and an input OP0. TARGET *must* be nonzero, and the output is always stored there. @@ -4079,7 +2977,7 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison, break; } } - + if (mode == VOIDmode) abort (); @@ -5007,7 +3905,7 @@ expand_fix (rtx to, rtx from, int unsignedp) rtx insns; rtx value; rtx libfunc; - + convert_optab tab = unsignedp ? ufix_optab : sfix_optab; libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc; if (!libfunc) @@ -5543,11 +4441,11 @@ init_optabs (void) init_floating_libfuncs (unord_optab, "unord", '2'); /* Conversions. */ - init_interclass_conv_libfuncs (sfloat_optab, "float", + init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT); - init_interclass_conv_libfuncs (sfix_optab, "fix", + init_interclass_conv_libfuncs (sfix_optab, "fix", MODE_FLOAT, MODE_INT); - init_interclass_conv_libfuncs (ufix_optab, "fixuns", + init_interclass_conv_libfuncs (ufix_optab, "fixuns", MODE_FLOAT, MODE_INT); /* sext_optab is also used for FLOAT_EXTEND. */ @@ -5613,7 +4511,7 @@ debug_optab_libfuncs (void) int k; /* Dump the arithmetic optabs. */ - for (i = 0; i != (int) OTI_MAX; i++) + for (i = 0; i != (int) OTI_MAX; i++) for (j = 0; j < NUM_MACHINE_MODES; ++j) { optab o; @@ -5625,7 +4523,7 @@ debug_optab_libfuncs (void) { if (GET_CODE (h->libfunc) != SYMBOL_REF) abort (); - fprintf (stderr, "%s\t%s:\t%s\n", + fprintf (stderr, "%s\t%s:\t%s\n", GET_RTX_NAME (o->code), GET_MODE_NAME (j), XSTR (h->libfunc, 0)); @@ -5646,7 +4544,7 @@ debug_optab_libfuncs (void) { if (GET_CODE (h->libfunc) != SYMBOL_REF) abort (); - fprintf (stderr, "%s\t%s\t%s:\t%s\n", + fprintf (stderr, "%s\t%s\t%s:\t%s\n", GET_RTX_NAME (o->code), GET_MODE_NAME (j), GET_MODE_NAME (k), diff --git a/gcc/optabs.h b/gcc/optabs.h index 24c3c884940..7cf0f9a238a 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -419,7 +419,7 @@ extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int); /* Generate code to perform an operation on two operands with two results, using a library function. */ -extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, +extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx, enum rtx_code); /* Expand a unary arithmetic operation given optab rtx operand. */ @@ -429,9 +429,6 @@ extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int); extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int); extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int); -/* Expand the complex absolute value operation. */ -extern rtx expand_complex_abs (enum machine_mode, rtx, rtx, int); - /* Generate an instruction with a given INSN_CODE with an output and an input. */ extern void emit_unop_insn (int, rtx, rtx, enum rtx_code); -- 2.30.2