diff options
author | ams <ams@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-19 14:12:32 +0000 |
---|---|---|
committer | ams <ams@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-19 14:12:32 +0000 |
commit | 5a574e8bc02ccbac0d8fb40b989a8a17af6917bc (patch) | |
tree | 79e47d7fd79f8a22d857e9e104cac40825bc24b0 /gcc/optabs.h | |
parent | 4755ceab65335b7efe910ae66128bdfea947256c (diff) | |
download | gcc-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.h | 43 |
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. */ |