OSDN Git Service

* tree-nested.c (get_trampoline_type): Fix thinko.
[pf3gnuchains/gcc-fork.git] / gcc / optabs.h
index d3cfd74..9dd9813 100644 (file)
@@ -1,12 +1,12 @@
 /* Definitions for code generation pass of GNU compiler.
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
    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 2, or (at your option)
+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,
@@ -15,9 +15,8 @@ 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 COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #ifndef GCC_OPTABS_H
 #define GCC_OPTABS_H
@@ -40,15 +39,17 @@ Boston, MA 02110-1301, USA.  */
    A few optabs, such as move_optab and cmp_optab, are used
    by special code.  */
 
-struct optab_handlers GTY(())
+struct optab_handlers
 {
   enum insn_code insn_code;
-  rtx libfunc;
 };
 
-struct optab GTY(())
+struct optab
 {
   enum rtx_code code;
+  const char *libcall_basename;
+  char libcall_suffix;
+  void (*libcall_gen)(struct optab *, const char *name, char suffix, enum machine_mode);
   struct optab_handlers handlers[NUM_MACHINE_MODES];
 };
 typedef struct optab * optab;
@@ -56,9 +57,13 @@ typedef struct optab * optab;
 /* A convert_optab is for some sort of conversion operation between
    modes.  The first array index is the destination mode, the second
    is the source mode.  */
-struct convert_optab GTY(())
+struct convert_optab
 {
   enum rtx_code code;
+  const char *libcall_basename;
+  void (*libcall_gen)(struct convert_optab *, const char *name,
+                     enum machine_mode,
+                     enum machine_mode);
   struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
 };
 typedef struct convert_optab *convert_optab;
@@ -70,6 +75,20 @@ typedef struct convert_optab *convert_optab;
 /* Enumeration of valid indexes into optab_table.  */
 enum optab_index
 {
+  /* Fixed-point operators with signed/unsigned saturation */
+  OTI_ssadd,
+  OTI_usadd,
+  OTI_sssub,
+  OTI_ussub,
+  OTI_ssmul,
+  OTI_usmul,
+  OTI_ssdiv,
+  OTI_usdiv,
+  OTI_ssneg,
+  OTI_usneg,
+  OTI_ssashl,
+  OTI_usashl,
+
   OTI_add,
   OTI_addv,
   OTI_sub,
@@ -86,6 +105,34 @@ enum optab_index
   OTI_umul_widen,
   /* Widening multiply of one unsigned and one signed operand.  */
   OTI_usmul_widen,
+  /* Signed multiply and add with the result and addend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_smadd_widen,
+  /* Unsigned multiply and add with the result and addend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_umadd_widen,
+  /* Signed multiply and add with the result and addend one machine mode
+     wider than the multiplicand and multiplier.
+     All involved operations are saturating.  */
+  OTI_ssmadd_widen,
+  /* Unigned multiply and add with the result and addend one machine mode
+     wider than the multiplicand and multiplier.
+     All involved operations are saturating.  */
+  OTI_usmadd_widen,
+  /* Signed multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_smsub_widen,
+  /* Unsigned multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.  */
+  OTI_umsub_widen,
+  /* Signed multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.
+     All involved operations are saturating.  */
+  OTI_ssmsub_widen,
+  /* Unigned multiply and subtract the result and minuend one machine mode
+     wider than the multiplicand and multiplier.
+     All involved operations are saturating.  */
+  OTI_usmsub_widen,
 
   /* Signed divide */
   OTI_sdiv,
@@ -139,6 +186,8 @@ enum optab_index
   OTI_movstrict,
   /* Move, with a misaligned memory.  */
   OTI_movmisalign,
+  /* Nontemporal store.  */
+  OTI_storent,
 
   /* Unary operations */
   /* Negation */
@@ -179,6 +228,8 @@ enum optab_index
   OTI_expm1,
   /* Load exponent of a floating point number */
   OTI_ldexp,
+  /* Multiply floating-point number by integral power of radix */
+  OTI_scalb,
   /* Radix-independent exponent */
   OTI_logb,
   OTI_ilogb,
@@ -203,7 +254,8 @@ enum optab_index
   OTI_atan,
   /* Copy sign */
   OTI_copysign,
-
+  /* Signbit */
+  OTI_signbit,
   /* Test for infinite value */
   OTI_isinf,
 
@@ -276,24 +328,52 @@ enum optab_index
   OTI_vec_widen_umult_lo,
   OTI_vec_widen_smult_hi,
   OTI_vec_widen_smult_lo,
-  /* Extract and widen the high/low part of a vector of signed/unsigned 
-     elements.  */
+  /* Extract and widen the high/low part of a vector of signed or
+     floating point elements.  */
   OTI_vec_unpacks_hi,
   OTI_vec_unpacks_lo,
+  /* Extract and widen the high/low part of a vector of unsigned
+     elements.  */
   OTI_vec_unpacku_hi,
   OTI_vec_unpacku_lo,
+
+  /* Extract, convert to floating point and widen the high/low part of
+     a vector of signed or unsigned integer elements.  */
+  OTI_vec_unpacks_float_hi,
+  OTI_vec_unpacks_float_lo,
+  OTI_vec_unpacku_float_hi,
+  OTI_vec_unpacku_float_lo,
+
   /* Narrow (demote) and merge the elements of two vectors.  */
-  OTI_vec_pack_mod,
+  OTI_vec_pack_trunc,
   OTI_vec_pack_usat,
   OTI_vec_pack_ssat,
 
+  /* Convert to signed/unsigned integer, narrow and merge elements
+     of two vectors of floating point elements.  */
+  OTI_vec_pack_sfix_trunc,
+  OTI_vec_pack_ufix_trunc,
+
   /* Perform a raise to the power of integer.  */
   OTI_powi,
 
   OTI_MAX
 };
 
-extern GTY(()) optab optab_table[OTI_MAX];
+extern optab 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])
+#define ussub_optab (optab_table[OTI_ussub])
+#define ssmul_optab (optab_table[OTI_ssmul])
+#define usmul_optab (optab_table[OTI_usmul])
+#define ssdiv_optab (optab_table[OTI_ssdiv])
+#define usdiv_optab (optab_table[OTI_usdiv])
+#define ssneg_optab (optab_table[OTI_ssneg])
+#define usneg_optab (optab_table[OTI_usneg])
+#define ssashl_optab (optab_table[OTI_ssashl])
+#define usashl_optab (optab_table[OTI_usashl])
 
 #define add_optab (optab_table[OTI_add])
 #define sub_optab (optab_table[OTI_sub])
@@ -305,6 +385,14 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define smul_widen_optab (optab_table[OTI_smul_widen])
 #define umul_widen_optab (optab_table[OTI_umul_widen])
 #define usmul_widen_optab (optab_table[OTI_usmul_widen])
+#define smadd_widen_optab (optab_table[OTI_smadd_widen])
+#define umadd_widen_optab (optab_table[OTI_umadd_widen])
+#define ssmadd_widen_optab (optab_table[OTI_ssmadd_widen])
+#define usmadd_widen_optab (optab_table[OTI_usmadd_widen])
+#define smsub_widen_optab (optab_table[OTI_smsub_widen])
+#define umsub_widen_optab (optab_table[OTI_umsub_widen])
+#define ssmsub_widen_optab (optab_table[OTI_ssmsub_widen])
+#define usmsub_widen_optab (optab_table[OTI_usmsub_widen])
 #define sdiv_optab (optab_table[OTI_sdiv])
 #define smulv_optab (optab_table[OTI_smulv])
 #define sdivv_optab (optab_table[OTI_sdivv])
@@ -334,6 +422,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define mov_optab (optab_table[OTI_mov])
 #define movstrict_optab (optab_table[OTI_movstrict])
 #define movmisalign_optab (optab_table[OTI_movmisalign])
+#define storent_optab (optab_table[OTI_storent])
 
 #define neg_optab (optab_table[OTI_neg])
 #define negv_optab (optab_table[OTI_negv])
@@ -357,6 +446,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define exp2_optab (optab_table[OTI_exp2])
 #define expm1_optab (optab_table[OTI_expm1])
 #define ldexp_optab (optab_table[OTI_ldexp])
+#define scalb_optab (optab_table[OTI_scalb])
 #define logb_optab (optab_table[OTI_logb])
 #define ilogb_optab (optab_table[OTI_ilogb])
 #define log_optab (optab_table[OTI_log])
@@ -372,7 +462,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define tan_optab (optab_table[OTI_tan])
 #define atan_optab (optab_table[OTI_atan])
 #define copysign_optab (optab_table[OTI_copysign])
-
+#define signbit_optab (optab_table[OTI_signbit])
 #define isinf_optab (optab_table[OTI_isinf])
 
 #define cmp_optab (optab_table[OTI_cmp])
@@ -401,7 +491,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define reduc_umin_optab (optab_table[OTI_reduc_umin])
 #define reduc_splus_optab (optab_table[OTI_reduc_splus])
 #define reduc_uplus_optab (optab_table[OTI_reduc_uplus])
-                                                                                
+
 #define ssum_widen_optab (optab_table[OTI_ssum_widen])
 #define usum_widen_optab (optab_table[OTI_usum_widen])
 #define sdot_prod_optab (optab_table[OTI_sdot_prod])
@@ -422,13 +512,19 @@ extern GTY(()) optab optab_table[OTI_MAX];
 #define vec_widen_smult_hi_optab (optab_table[OTI_vec_widen_smult_hi])
 #define vec_widen_smult_lo_optab (optab_table[OTI_vec_widen_smult_lo])
 #define vec_unpacks_hi_optab (optab_table[OTI_vec_unpacks_hi])
-#define vec_unpacku_hi_optab (optab_table[OTI_vec_unpacku_hi])
 #define vec_unpacks_lo_optab (optab_table[OTI_vec_unpacks_lo])
+#define vec_unpacku_hi_optab (optab_table[OTI_vec_unpacku_hi])
 #define vec_unpacku_lo_optab (optab_table[OTI_vec_unpacku_lo])
-#define vec_pack_mod_optab (optab_table[OTI_vec_pack_mod])
+#define vec_unpacks_float_hi_optab (optab_table[OTI_vec_unpacks_float_hi])
+#define vec_unpacks_float_lo_optab (optab_table[OTI_vec_unpacks_float_lo])
+#define vec_unpacku_float_hi_optab (optab_table[OTI_vec_unpacku_float_hi])
+#define vec_unpacku_float_lo_optab (optab_table[OTI_vec_unpacku_float_lo])
+#define vec_pack_trunc_optab (optab_table[OTI_vec_pack_trunc])
 #define vec_pack_ssat_optab (optab_table[OTI_vec_pack_ssat])
 #define vec_pack_usat_optab (optab_table[OTI_vec_pack_usat])
-                                                                                
+#define vec_pack_sfix_trunc_optab (optab_table[OTI_vec_pack_sfix_trunc])
+#define vec_pack_ufix_trunc_optab (optab_table[OTI_vec_pack_ufix_trunc])
+
 #define powi_optab (optab_table[OTI_powi])
 
 /* Conversion optabs have their own table and indexes.  */
@@ -452,10 +548,15 @@ enum convert_optab_index
   COI_lfloor,
   COI_lceil,
 
+  COI_fract,
+  COI_fractuns,
+  COI_satfract,
+  COI_satfractuns,
+
   COI_MAX
 };
 
-extern GTY(()) convert_optab convert_optab_table[COI_MAX];
+extern convert_optab convert_optab_table[COI_MAX];
 
 #define sext_optab (convert_optab_table[COI_sext])
 #define zext_optab (convert_optab_table[COI_zext])
@@ -470,6 +571,10 @@ extern GTY(()) convert_optab convert_optab_table[COI_MAX];
 #define lround_optab (convert_optab_table[COI_lround])
 #define lfloor_optab (convert_optab_table[COI_lfloor])
 #define lceil_optab (convert_optab_table[COI_lceil])
+#define fract_optab (convert_optab_table[COI_fract])
+#define fractuns_optab (convert_optab_table[COI_fractuns])
+#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
@@ -478,7 +583,7 @@ 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 GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
+extern optab code_to_optab[NUM_RTX_CODE + 1];
 
 \f
 typedef rtx (*rtxfun) (rtx);
@@ -601,6 +706,10 @@ extern rtx expand_copysign (rtx, rtx, rtx);
    an input.  */
 extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
 
+/* Excapsulate the block in REG_LIBCALL, and REG_RETVAL reg notes and add 
+   REG_LIBCALL_ID notes to all insns in block.  */
+extern void maybe_encapsulate_block (rtx, rtx, rtx);
+
 /* Emit code to perform a series of operations on a multi-word quantity, one
    word at a time.  */
 extern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx);
@@ -620,7 +729,7 @@ enum can_compare_purpose
 
 /* Return the optab used for computing the given operation on the type
    given by the second argument.  */
-extern optab optab_for_tree_code (enum tree_code, tree);
+extern optab optab_for_tree_code (enum tree_code, const_tree);
 
 /* Nonzero if a compare of mode MODE can be done straightforwardly
    (without splitting it into pieces).  */
@@ -640,6 +749,9 @@ extern void set_optab_libfunc (optab, enum machine_mode, const char *);
 extern void set_conv_libfunc (convert_optab, enum machine_mode,
                              enum machine_mode, const char *);
 
+/* Generate code for a FIXED_CONVERT_EXPR.  */
+extern void expand_fixed_convert (rtx, rtx, int, int);
+
 /* Generate code for a FLOAT_EXPR.  */
 extern void expand_float (rtx, rtx, int);
 
@@ -658,4 +770,12 @@ extern rtx expand_vec_cond_expr (tree, rtx);
 /* Generate code for VEC_LSHIFT_EXPR and VEC_RSHIFT_EXPR.  */
 extern rtx expand_vec_shift_expr (tree, rtx);
 
+#define optab_handler(optab,mode) (&(optab)->handlers[(int) (mode)])
+#define convert_optab_handler(optab,mode,mode2) \
+       (&(optab)->handlers[(int) (mode)][(int) (mode2)])
+
+extern rtx optab_libfunc (optab optab, enum machine_mode mode);
+extern rtx optab_libfunc (optab optab, enum machine_mode mode);
+extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
+                                 enum machine_mode mode2);
 #endif /* GCC_OPTABS_H */