summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-22 08:20:40 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2004-07-22 08:20:40 +0000
commit83e2a11b2613ddd8dfc024700b1c86729b058300 (patch)
tree4646f9e5e0b2387d4bcc7fc94aff9d320ae0030d /gcc/optabs.c
parent280450faa1152c283c0bb88b31337cee8e569ff5 (diff)
downloadgcc-83e2a11b2613ddd8dfc024700b1c86729b058300.tar.gz
2004-07-22 Paolo Bonzini <bonzini@gnu.org>
* tree-cfg.c (gimplify_val): Move from tree-complex.c. (gimplify_build1): Move from tree-complex.c do_unop. (gimplify_build2): Move from tree-complex.c do_binop. (gimplify_build3): New. * tree-complex.c (gimplify_val, do_unop, do_binop): Remove. Adjust throughout to call the functions above. * tree-flow.h: Declare the functions above. * tree-nested.c (gimplify_val): Rename to... (tsi_gimplify_val): ... this. * Makefile.in (tree_complex.o): Update dependencies. (stor-layout.o): Depend on regs.h. * c-common.c (handle_vector_size_attribute): Update for vector types without corresponding vector modes. * expr.c (expand_expr): Treat VECTOR_CST's like CONSTRUCTORS if a corresponding vector mode is not available. * print-tree.c (print_node): Print nunits for vector types * regclass.c (have_regs_of_mode): New. (init_reg_sets_1): Initialize it and use it instead of allocatable_regs_of_mode. * regs.h (have_regs_of_mode): Declare it. * stor-layout.c (layout_type): Pick a mode for vector types. * tree-complex.c (build_word_mode_vector_type, tree_vec_extract, build_replicated_const, do_unop, do_binop, do_plus_minus, do_negate, expand_vector_piecewise, expand_vector_parallel, expand_vector_addition, expand_vector_operations_1, expand_vector_operations, tree_lower_operations, pass_lower_vector_ssa, pass_pre_expand): New. (expand_complex_operations, pass_lower_complex): Remove. * tree-optimize.c (init_tree_optimization_passes): Adjust pass ordering for changes in tree-complex.c. * tree-pass.h: Declare new passes. * tree.c (finish_vector_type): Remove. (make_vector_type): New. (build_vector_type_for_mode, build_vector_type): Rewritten. * tree.def (VECTOR_TYPE): Document where the number of subparts is stored. * tree.h (TYPE_VECTOR_SUBPARTS): Use TYPE_PRECISION field. (make_vector): Remove declaration. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85039 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 2440a86dc94..1f013f37a60 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -628,6 +628,89 @@ expand_cmplxdiv_wide (rtx real0, rtx real1, rtx imag0, rtx imag1, rtx realr,
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
+ or division) but probably ought to be relied on more widely
+ throughout the expander. */
+optab
+optab_for_tree_code (enum tree_code code, tree type)
+{
+ bool trapv;
+ switch (code)
+ {
+ case BIT_AND_EXPR:
+ return and_optab;
+
+ case BIT_IOR_EXPR:
+ return ior_optab;
+
+ case BIT_NOT_EXPR:
+ return one_cmpl_optab;
+
+ case BIT_XOR_EXPR:
+ return xor_optab;
+
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
+
+ case RDIV_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
+
+ case LSHIFT_EXPR:
+ return ashl_optab;
+
+ case RSHIFT_EXPR:
+ return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
+
+ case LROTATE_EXPR:
+ return rotl_optab;
+
+ case RROTATE_EXPR:
+ return rotr_optab;
+
+ case MAX_EXPR:
+ return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
+
+ case MIN_EXPR:
+ return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
+
+ default:
+ break;
+ }
+
+ trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
+ switch (code)
+ {
+ case PLUS_EXPR:
+ return trapv ? addv_optab : add_optab;
+
+ case MINUS_EXPR:
+ return trapv ? subv_optab : sub_optab;
+
+ case MULT_EXPR:
+ return trapv ? smulv_optab : smul_optab;
+
+ case NEGATE_EXPR:
+ return trapv ? negv_optab : neg_optab;
+
+ case ABS_EXPR:
+ return trapv ? absv_optab : abs_optab;
+
+ default:
+ return NULL;
+ }
+}
+
+
/* Wrapper around expand_binop which takes an rtx code to specify
the operation to perform, not an optab pointer. All other
arguments are the same. */
@@ -2804,7 +2887,8 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
}
/* If there is no negate operation, try doing a subtract from zero.
- The US Software GOFAST library needs this. */
+ The US Software GOFAST library needs this. FIXME: This is *wrong*
+ for floating-point operations due to negative zeros! */
if (unoptab->code == NEG)
{
rtx temp;