summaryrefslogtreecommitdiff
path: root/gcc/expmed.h
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/expmed.h
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'gcc/expmed.h')
-rw-r--r--gcc/expmed.h200
1 files changed, 200 insertions, 0 deletions
diff --git a/gcc/expmed.h b/gcc/expmed.h
new file mode 100644
index 000000000..37f575571
--- /dev/null
+++ b/gcc/expmed.h
@@ -0,0 +1,200 @@
+/* Target-dependent costs for expmed.c.
+ Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option; any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef EXPMED_H
+#define EXPMED_H 1
+
+enum alg_code {
+ alg_unknown,
+ alg_zero,
+ alg_m, alg_shift,
+ alg_add_t_m2,
+ alg_sub_t_m2,
+ alg_add_factor,
+ alg_sub_factor,
+ alg_add_t2_m,
+ alg_sub_t2_m,
+ alg_impossible
+};
+
+/* This structure holds the "cost" of a multiply sequence. The
+ "cost" field holds the total rtx_cost of every operator in the
+ synthetic multiplication sequence, hence cost(a op b) is defined
+ as rtx_cost(op) + cost(a) + cost(b), where cost(leaf) is zero.
+ The "latency" field holds the minimum possible latency of the
+ synthetic multiply, on a hypothetical infinitely parallel CPU.
+ This is the critical path, or the maximum height, of the expression
+ tree which is the sum of rtx_costs on the most expensive path from
+ any leaf to the root. Hence latency(a op b) is defined as zero for
+ leaves and rtx_cost(op) + max(latency(a), latency(b)) otherwise. */
+
+struct mult_cost {
+ short cost; /* Total rtx_cost of the multiplication sequence. */
+ short latency; /* The latency of the multiplication sequence. */
+};
+
+/* This macro is used to compare a pointer to a mult_cost against an
+ single integer "rtx_cost" value. This is equivalent to the macro
+ CHEAPER_MULT_COST(X,Z) where Z = {Y,Y}. */
+#define MULT_COST_LESS(X,Y) ((X)->cost < (Y) \
+ || ((X)->cost == (Y) && (X)->latency < (Y)))
+
+/* This macro is used to compare two pointers to mult_costs against
+ each other. The macro returns true if X is cheaper than Y.
+ Currently, the cheaper of two mult_costs is the one with the
+ lower "cost". If "cost"s are tied, the lower latency is cheaper. */
+#define CHEAPER_MULT_COST(X,Y) ((X)->cost < (Y)->cost \
+ || ((X)->cost == (Y)->cost \
+ && (X)->latency < (Y)->latency))
+
+/* This structure records a sequence of operations.
+ `ops' is the number of operations recorded.
+ `cost' is their total cost.
+ The operations are stored in `op' and the corresponding
+ logarithms of the integer coefficients in `log'.
+
+ These are the operations:
+ alg_zero total := 0;
+ alg_m total := multiplicand;
+ alg_shift total := total * coeff
+ alg_add_t_m2 total := total + multiplicand * coeff;
+ alg_sub_t_m2 total := total - multiplicand * coeff;
+ alg_add_factor total := total * coeff + total;
+ alg_sub_factor total := total * coeff - total;
+ alg_add_t2_m total := total * coeff + multiplicand;
+ alg_sub_t2_m total := total * coeff - multiplicand;
+
+ The first operand must be either alg_zero or alg_m. */
+
+struct algorithm
+{
+ struct mult_cost cost;
+ short ops;
+ /* The size of the OP and LOG fields are not directly related to the
+ word size, but the worst-case algorithms will be if we have few
+ consecutive ones or zeros, i.e., a multiplicand like 10101010101...
+ In that case we will generate shift-by-2, add, shift-by-2, add,...,
+ in total wordsize operations. */
+ enum alg_code op[MAX_BITS_PER_WORD];
+ char log[MAX_BITS_PER_WORD];
+};
+
+/* The entry for our multiplication cache/hash table. */
+struct alg_hash_entry {
+ /* The number we are multiplying by. */
+ unsigned HOST_WIDE_INT t;
+
+ /* The mode in which we are multiplying something by T. */
+ enum machine_mode mode;
+
+ /* The best multiplication algorithm for t. */
+ enum alg_code alg;
+
+ /* The cost of multiplication if ALG_CODE is not alg_impossible.
+ Otherwise, the cost within which multiplication by T is
+ impossible. */
+ struct mult_cost cost;
+
+ /* Optimized for speed? */
+ bool speed;
+};
+
+/* The number of cache/hash entries. */
+#if HOST_BITS_PER_WIDE_INT == 64
+#define NUM_ALG_HASH_ENTRIES 1031
+#else
+#define NUM_ALG_HASH_ENTRIES 307
+#endif
+
+/* Target-dependent globals. */
+struct target_expmed {
+ /* Each entry of ALG_HASH caches alg_code for some integer. This is
+ actually a hash table. If we have a collision, that the older
+ entry is kicked out. */
+ struct alg_hash_entry x_alg_hash[NUM_ALG_HASH_ENTRIES];
+
+ /* True if x_alg_hash might already have been used. */
+ bool x_alg_hash_used_p;
+
+ /* Nonzero means divides or modulus operations are relatively cheap for
+ powers of two, so don't use branches; emit the operation instead.
+ Usually, this will mean that the MD file will emit non-branch
+ sequences. */
+ bool x_sdiv_pow2_cheap[2][NUM_MACHINE_MODES];
+ bool x_smod_pow2_cheap[2][NUM_MACHINE_MODES];
+
+ /* Cost of various pieces of RTL. Note that some of these are indexed by
+ shift count and some by mode. */
+ int x_zero_cost[2];
+ int x_add_cost[2][NUM_MACHINE_MODES];
+ int x_neg_cost[2][NUM_MACHINE_MODES];
+ int x_shift_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ int x_shiftadd_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ int x_shiftsub0_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ int x_shiftsub1_cost[2][NUM_MACHINE_MODES][MAX_BITS_PER_WORD];
+ int x_mul_cost[2][NUM_MACHINE_MODES];
+ int x_sdiv_cost[2][NUM_MACHINE_MODES];
+ int x_udiv_cost[2][NUM_MACHINE_MODES];
+ int x_mul_widen_cost[2][NUM_MACHINE_MODES];
+ int x_mul_highpart_cost[2][NUM_MACHINE_MODES];
+};
+
+extern struct target_expmed default_target_expmed;
+#if SWITCHABLE_TARGET
+extern struct target_expmed *this_target_expmed;
+#else
+#define this_target_expmed (&default_target_expmed)
+#endif
+
+#define alg_hash \
+ (this_target_expmed->x_alg_hash)
+#define alg_hash_used_p \
+ (this_target_expmed->x_alg_hash_used_p)
+#define sdiv_pow2_cheap \
+ (this_target_expmed->x_sdiv_pow2_cheap)
+#define smod_pow2_cheap \
+ (this_target_expmed->x_smod_pow2_cheap)
+#define zero_cost \
+ (this_target_expmed->x_zero_cost)
+#define add_cost \
+ (this_target_expmed->x_add_cost)
+#define neg_cost \
+ (this_target_expmed->x_neg_cost)
+#define shift_cost \
+ (this_target_expmed->x_shift_cost)
+#define shiftadd_cost \
+ (this_target_expmed->x_shiftadd_cost)
+#define shiftsub0_cost \
+ (this_target_expmed->x_shiftsub0_cost)
+#define shiftsub1_cost \
+ (this_target_expmed->x_shiftsub1_cost)
+#define mul_cost \
+ (this_target_expmed->x_mul_cost)
+#define sdiv_cost \
+ (this_target_expmed->x_sdiv_cost)
+#define udiv_cost \
+ (this_target_expmed->x_udiv_cost)
+#define mul_widen_cost \
+ (this_target_expmed->x_mul_widen_cost)
+#define mul_highpart_cost \
+ (this_target_expmed->x_mul_highpart_cost)
+
+#endif