Mercurial > hg > CbC > CbC_gcc
diff gcc/optabs.h @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/optabs.h Tue May 25 18:58:51 2010 +0900 +++ b/gcc/optabs.h Tue Mar 22 17:18:12 2011 +0900 @@ -1,5 +1,5 @@ /* Definitions for code generation pass of GNU compiler. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -29,10 +29,6 @@ For example, add_optab applies to addition. - The insn_code slot is the enum insn_code that says how to - generate an insn for this operation on a particular machine mode. - It is CODE_FOR_nothing if there is no such insn on the target machine. - The `lib_call' slot is the name of the library function that can be used to perform the operation. @@ -40,14 +36,17 @@ struct optab_handlers { - enum insn_code insn_code; + /* I - CODE_FOR_nothing, where I is either the insn code of the + associated insn generator or CODE_FOR_nothing if there is no such + insn on the target machine. */ + int insn_code; }; struct optab_d { enum rtx_code code; + char libcall_suffix; const char *libcall_basename; - char libcall_suffix; void (*libcall_gen)(struct optab_d *, const char *name, char suffix, enum machine_mode); struct optab_handlers handlers[NUM_MACHINE_MODES]; @@ -191,6 +190,11 @@ OTI_pow, /* Arc tangent of y/x */ OTI_atan2, + /* Floating multiply/add */ + OTI_fma, + OTI_fms, + OTI_fnma, + OTI_fnms, /* Move instruction. */ OTI_mov, @@ -372,8 +376,6 @@ OTI_MAX }; -extern struct optab_d optab_table[OTI_MAX]; - #define ssadd_optab (&optab_table[OTI_ssadd]) #define usadd_optab (&optab_table[OTI_usadd]) #define sssub_optab (&optab_table[OTI_sssub]) @@ -435,6 +437,10 @@ #define umax_optab (&optab_table[OTI_umax]) #define pow_optab (&optab_table[OTI_pow]) #define atan2_optab (&optab_table[OTI_atan2]) +#define fma_optab (&optab_table[OTI_fma]) +#define fms_optab (&optab_table[OTI_fms]) +#define fnma_optab (&optab_table[OTI_fnma]) +#define fnms_optab (&optab_table[OTI_fnms]) #define mov_optab (&optab_table[OTI_mov]) #define movstrict_optab (&optab_table[OTI_movstrict]) @@ -575,8 +581,6 @@ COI_MAX }; -extern struct convert_optab_d convert_optab_table[COI_MAX]; - #define sext_optab (&convert_optab_table[COI_sext]) #define zext_optab (&convert_optab_table[COI_zext]) #define trunc_optab (&convert_optab_table[COI_trunc]) @@ -595,79 +599,152 @@ #define satfract_optab (&convert_optab_table[COI_satfract]) #define satfractuns_optab (&convert_optab_table[COI_satfractuns]) -/* These arrays record the insn_code of insns that may be needed to - perform input and output reloads of special objects. They provide a - place to pass a scratch register. */ -extern enum insn_code reload_in_optab[NUM_MACHINE_MODES]; -extern enum insn_code reload_out_optab[NUM_MACHINE_MODES]; - /* Contains the optab used for each rtx code. */ extern optab code_to_optab[NUM_RTX_CODE + 1]; typedef rtx (*rtxfun) (rtx); +/* Enumerates operations that have a named .md pattern associated + with them, but which are not implemented as library functions. */ +enum direct_optab_index +{ #ifdef HAVE_conditional_move -/* Indexed by the machine mode, gives the insn code to make a conditional - move insn. */ - -extern enum insn_code movcc_gen_code[NUM_MACHINE_MODES]; + /* Conditional move operations. */ + DOI_movcc, #endif -/* Indexed by the machine mode, gives the insn code for vector conditional - operation. */ + /* Operations that use a scratch register to perform input and output + reloads of special objects. */ + DOI_reload_in, + DOI_reload_out, -extern enum insn_code vcond_gen_code[NUM_MACHINE_MODES]; -extern enum insn_code vcondu_gen_code[NUM_MACHINE_MODES]; + /* Vector conditional operations. */ + DOI_vcond, + DOI_vcondu, + + /* Block move operation. */ + DOI_movmem, -/* This array records the insn_code of insns to perform block moves. */ -extern enum insn_code movmem_optab[NUM_MACHINE_MODES]; + /* Block set operation. */ + DOI_setmem, + + /* Various types of block compare operation. */ + DOI_cmpstr, + DOI_cmpstrn, + DOI_cmpmem, -/* This array records the insn_code of insns to perform block sets. */ -extern enum insn_code setmem_optab[NUM_MACHINE_MODES]; + /* Synchronization primitives. This first set is atomic operation for + which we don't care about the resulting value. */ + DOI_sync_add, + DOI_sync_sub, + DOI_sync_ior, + DOI_sync_and, + DOI_sync_xor, + DOI_sync_nand, -/* These arrays record the insn_code of two different kinds of insns - to perform block compares. */ -extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES]; -extern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES]; -extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES]; + /* This second set is atomic operations in which we return the value + that existed in memory before the operation. */ + DOI_sync_old_add, + DOI_sync_old_sub, + DOI_sync_old_ior, + DOI_sync_old_and, + DOI_sync_old_xor, + DOI_sync_old_nand, -/* Synchronization primitives. This first set is atomic operation for - which we don't care about the resulting value. */ -extern enum insn_code sync_add_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_sub_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_ior_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_and_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_xor_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_nand_optab[NUM_MACHINE_MODES]; + /* This third set is atomic operations in which we return the value + that resulted after performing the operation. */ + DOI_sync_new_add, + DOI_sync_new_sub, + DOI_sync_new_ior, + DOI_sync_new_and, + DOI_sync_new_xor, + DOI_sync_new_nand, + + /* Atomic compare and swap. */ + DOI_sync_compare_and_swap, + + /* Atomic exchange with acquire semantics. */ + DOI_sync_lock_test_and_set, + + /* Atomic clear with release semantics. */ + DOI_sync_lock_release, + + DOI_MAX +}; -/* This second set is atomic operations in which we return the value - that existed in memory before the operation. */ -extern enum insn_code sync_old_add_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_old_and_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES]; +/* A structure that says which insn should be used to perform an operation + in a particular mode. */ +struct direct_optab_d +{ + struct optab_handlers handlers[NUM_MACHINE_MODES]; +}; +typedef struct direct_optab_d *direct_optab; -/* This third set is atomic operations in which we return the value - that resulted after performing the operation. */ -extern enum insn_code sync_new_add_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_new_and_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES]; -extern enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES]; +#ifdef HAVE_conditional_move +#define movcc_optab (&direct_optab_table[(int) DOI_movcc]) +#endif +#define reload_in_optab (&direct_optab_table[(int) DOI_reload_in]) +#define reload_out_optab (&direct_optab_table[(int) DOI_reload_out]) +#define vcond_optab (&direct_optab_table[(int) DOI_vcond]) +#define vcondu_optab (&direct_optab_table[(int) DOI_vcondu]) +#define movmem_optab (&direct_optab_table[(int) DOI_movmem]) +#define setmem_optab (&direct_optab_table[(int) DOI_setmem]) +#define cmpstr_optab (&direct_optab_table[(int) DOI_cmpstr]) +#define cmpstrn_optab (&direct_optab_table[(int) DOI_cmpstrn]) +#define cmpmem_optab (&direct_optab_table[(int) DOI_cmpmem]) +#define sync_add_optab (&direct_optab_table[(int) DOI_sync_add]) +#define sync_sub_optab (&direct_optab_table[(int) DOI_sync_sub]) +#define sync_ior_optab (&direct_optab_table[(int) DOI_sync_ior]) +#define sync_and_optab (&direct_optab_table[(int) DOI_sync_and]) +#define sync_xor_optab (&direct_optab_table[(int) DOI_sync_xor]) +#define sync_nand_optab (&direct_optab_table[(int) DOI_sync_nand]) +#define sync_old_add_optab (&direct_optab_table[(int) DOI_sync_old_add]) +#define sync_old_sub_optab (&direct_optab_table[(int) DOI_sync_old_sub]) +#define sync_old_ior_optab (&direct_optab_table[(int) DOI_sync_old_ior]) +#define sync_old_and_optab (&direct_optab_table[(int) DOI_sync_old_and]) +#define sync_old_xor_optab (&direct_optab_table[(int) DOI_sync_old_xor]) +#define sync_old_nand_optab (&direct_optab_table[(int) DOI_sync_old_nand]) +#define sync_new_add_optab (&direct_optab_table[(int) DOI_sync_new_add]) +#define sync_new_sub_optab (&direct_optab_table[(int) DOI_sync_new_sub]) +#define sync_new_ior_optab (&direct_optab_table[(int) DOI_sync_new_ior]) +#define sync_new_and_optab (&direct_optab_table[(int) DOI_sync_new_and]) +#define sync_new_xor_optab (&direct_optab_table[(int) DOI_sync_new_xor]) +#define sync_new_nand_optab (&direct_optab_table[(int) DOI_sync_new_nand]) +#define sync_compare_and_swap_optab \ + (&direct_optab_table[(int) DOI_sync_compare_and_swap]) +#define sync_lock_test_and_set_optab \ + (&direct_optab_table[(int) DOI_sync_lock_test_and_set]) +#define sync_lock_release_optab \ + (&direct_optab_table[(int) DOI_sync_lock_release]) + +/* Target-dependent globals. */ +struct target_optabs { + /* Tables of patterns that may have an associated libcall. */ + struct optab_d x_optab_table[(int) OTI_MAX]; -/* Atomic compare and swap. */ -extern enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES]; + /* Tables of patterns for converting one mode to another. */ + struct convert_optab_d x_convert_optab_table[(int) COI_MAX]; + + /* Tables of patterns for direct optabs (i.e. those which cannot be + implemented using a libcall). */ + struct direct_optab_d x_direct_optab_table[(int) DOI_MAX]; +}; -/* Atomic exchange with acquire semantics. */ -extern enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES]; +extern struct target_optabs default_target_optabs; +#if SWITCHABLE_TARGET +extern struct target_optabs *this_target_optabs; +#else +#define this_target_optabs (&default_target_optabs) +#endif -/* Atomic clear with release semantics. */ -extern enum insn_code sync_lock_release[NUM_MACHINE_MODES]; - +#define optab_table \ + (this_target_optabs->x_optab_table) +#define convert_optab_table \ + (this_target_optabs->x_convert_optab_table) +#define direct_optab_table \ + (this_target_optabs->x_direct_optab_table) + /* Define functions given in optabs.c. */ extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op, @@ -782,9 +859,66 @@ /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR. */ extern rtx expand_vec_shift_expr (sepops, rtx); -#define optab_handler(optab,mode) (&(optab)->handlers[(int) (mode)]) -#define convert_optab_handler(optab,mode,mode2) \ - (&(optab)->handlers[(int) (mode)][(int) (mode2)]) +/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing + if the target does not have such an insn. */ + +static inline enum insn_code +optab_handler (optab op, enum machine_mode mode) +{ + return (enum insn_code) (op->handlers[(int) mode].insn_code + + (int) CODE_FOR_nothing); +} + +/* Record that insn CODE should be used to implement mode MODE of OP. */ + +static inline void +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; +} + +/* 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. */ + +static inline enum insn_code +convert_optab_handler (convert_optab op, enum machine_mode to_mode, + enum machine_mode from_mode) +{ + return ((enum insn_code) + (op->handlers[(int) to_mode][(int) from_mode].insn_code + + (int) CODE_FOR_nothing)); +} + +/* Record that insn CODE should be used to perform conversion OP + from mode FROM_MODE to mode TO_MODE. */ + +static inline void +set_convert_optab_handler (convert_optab op, enum machine_mode to_mode, + enum machine_mode from_mode, enum insn_code code) +{ + op->handlers[(int) to_mode][(int) from_mode].insn_code + = (int) code - (int) CODE_FOR_nothing; +} + +/* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing + if the target does not have such an insn. */ + +static inline enum insn_code +direct_optab_handler (direct_optab op, enum machine_mode mode) +{ + return (enum insn_code) (op->handlers[(int) mode].insn_code + + (int) CODE_FOR_nothing); +} + +/* Record that insn CODE should be used to implement mode MODE of OP. */ + +static inline void +set_direct_optab_handler (direct_optab op, enum machine_mode mode, + enum insn_code code) +{ + op->handlers[(int) mode].insn_code = (int) code - (int) CODE_FOR_nothing; +} extern rtx optab_libfunc (optab optab, enum machine_mode mode); extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,