summaryrefslogtreecommitdiff
path: root/gcc/optabs.h
diff options
context:
space:
mode:
authorams <ams@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-19 14:12:32 +0000
committerams <ams@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-19 14:12:32 +0000
commit5a574e8bc02ccbac0d8fb40b989a8a17af6917bc (patch)
tree79e47d7fd79f8a22d857e9e104cac40825bc24b0 /gcc/optabs.h
parent4755ceab65335b7efe910ae66128bdfea947256c (diff)
downloadgcc-5a574e8bc02ccbac0d8fb40b989a8a17af6917bc.tar.gz
2011-08-19 Andrew Stubbs <ams@codesourcery.com>
gcc/ * expr.c (expand_expr_real_2): Use widening_optab_handler. * genopinit.c (optabs): Use set_widening_optab_handler for $N. (gen_insn): $N now means $a must be wider than $b, not consecutive. * optabs.c (widened_mode): New function. (expand_widen_pattern_expr): Use widening_optab_handler. (expand_binop_directly): Likewise. (expand_binop): Likewise. * optabs.h (widening_optab_handlers): New struct. (optab_d): New member, 'widening'. (widening_optab_handler): New function. (set_widening_optab_handler): New function. * tree-ssa-math-opts.c (convert_mult_to_widen): Use widening_optab_handler. (convert_plusminus_to_widen): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177901 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.h')
-rw-r--r--gcc/optabs.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/gcc/optabs.h b/gcc/optabs.h
index c7cb123e442..0ea620c2fda 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -42,6 +42,11 @@ struct optab_handlers
int insn_code;
};
+struct widening_optab_handlers
+{
+ struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
+};
+
struct optab_d
{
enum rtx_code code;
@@ -50,6 +55,7 @@ struct optab_d
void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
enum machine_mode);
struct optab_handlers handlers[NUM_MACHINE_MODES];
+ struct widening_optab_handlers *widening;
};
typedef struct optab_d * optab;
@@ -879,6 +885,23 @@ optab_handler (optab op, enum machine_mode mode)
+ (int) CODE_FOR_nothing);
}
+/* Like optab_handler, but for widening_operations that have a TO_MODE and
+ a FROM_MODE. */
+
+static inline enum insn_code
+widening_optab_handler (optab op, enum machine_mode to_mode,
+ enum machine_mode from_mode)
+{
+ if (to_mode == from_mode || from_mode == VOIDmode)
+ return optab_handler (op, to_mode);
+
+ if (op->widening)
+ return (enum insn_code) (op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
+ + (int) CODE_FOR_nothing);
+
+ return CODE_FOR_nothing;
+}
+
/* Record that insn CODE should be used to implement mode MODE of OP. */
static inline void
@@ -887,6 +910,26 @@ set_optab_handler (optab op, enum machine_mode mode, enum insn_code code)
op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing;
}
+/* Like set_optab_handler, but for widening operations that have a TO_MODE
+ and a FROM_MODE. */
+
+static inline void
+set_widening_optab_handler (optab op, enum machine_mode to_mode,
+ enum machine_mode from_mode, enum insn_code code)
+{
+ if (to_mode == from_mode)
+ set_optab_handler (op, to_mode, code);
+ else
+ {
+ if (op->widening == NULL)
+ op->widening = (struct widening_optab_handlers *)
+ xcalloc (1, sizeof (struct widening_optab_handlers));
+
+ op->widening->handlers[(int) to_mode][(int) from_mode].insn_code
+ = (int) code - (int) CODE_FOR_nothing;
+ }
+}
+
/* Return the insn used to perform conversion OP from mode FROM_MODE
to mode TO_MODE; return CODE_FOR_nothing if the target does not have
such an insn. */