OSDN Git Service

Typo in test
[pf3gnuchains/gcc-fork.git] / gcc / optabs.h
index 1c518e5..be61f54 100644 (file)
@@ -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.
@@ -190,6 +190,11 @@ enum optab_index
   OTI_pow,
   /* Arc tangent of y/x */
   OTI_atan2,
+  /* Floating multiply/add */
+  OTI_fma,
+  OTI_fms,
+  OTI_fnma,
+  OTI_fnms,
 
   /* Move instruction.  */
   OTI_mov,
@@ -371,8 +376,6 @@ enum optab_index
   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])
@@ -434,6 +437,10 @@ extern struct optab_d optab_table[OTI_MAX];
 #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])
@@ -574,8 +581,6 @@ enum convert_optab_index
   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])
@@ -676,8 +681,6 @@ struct direct_optab_d
 };
 typedef struct direct_optab_d *direct_optab;
 
-extern struct direct_optab_d direct_optab_table[(int) DOI_MAX];
-
 #ifdef HAVE_conditional_move
 #define movcc_optab (&direct_optab_table[(int) DOI_movcc])
 #endif
@@ -715,6 +718,33 @@ extern struct direct_optab_d direct_optab_table[(int) DOI_MAX];
 #define sync_lock_release_optab \
   (&direct_optab_table[(int) DOI_sync_lock_release])
 \f
+/* Target-dependent globals.  */
+struct target_optabs {
+  /* Tables of patterns that may have an associated libcall.  */
+  struct optab_d x_optab_table[(int) OTI_MAX];
+
+  /* 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];
+};
+
+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
+
+#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)
+\f
 /* Define functions given in optabs.c.  */
 
 extern rtx expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
@@ -761,8 +791,8 @@ extern rtx expand_copysign (rtx, rtx, rtx);
 
 /* Generate an instruction with a given INSN_CODE with an output and
    an input.  */
-extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
-extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);
+extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
+extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
 
 /* An extra flag to control optab_for_tree_code's behavior.  This is needed to
    distinguish between machines with a vector shift that takes a scalar for the
@@ -893,4 +923,152 @@ set_direct_optab_handler (direct_optab op, 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);
+
+extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
+                                 rtx operand);
+
+/* Describes the type of an expand_operand.  Each value is associated
+   with a create_*_operand function; see the comments above those
+   functions for details.  */
+enum expand_operand_type {
+  EXPAND_FIXED,
+  EXPAND_OUTPUT,
+  EXPAND_INPUT,
+  EXPAND_CONVERT_TO,
+  EXPAND_CONVERT_FROM,
+  EXPAND_ADDRESS,
+  EXPAND_INTEGER
+};
+
+/* Information about an operand for instruction expansion.  */
+struct expand_operand {
+  /* The type of operand.  */
+  ENUM_BITFIELD (expand_operand_type) type : 8;
+
+  /* True if any conversion should treat VALUE as being unsigned
+     rather than signed.  Only meaningful for certain types.  */
+  unsigned int unsigned_p : 1;
+
+  /* Unused; available for future use.  */
+  unsigned int unused : 7;
+
+  /* The mode passed to the convert_*_operand function.  It has a
+     type-dependent meaning.  */
+  ENUM_BITFIELD (machine_mode) mode : 16;
+
+  /* The value of the operand.  */
+  rtx value;
+};
+
+/* Initialize OP with the given fields.  Initialise the other fields
+   to their default values.  */
+
+static inline void
+create_expand_operand (struct expand_operand *op,
+                      enum expand_operand_type type,
+                      rtx value, enum machine_mode mode,
+                      bool unsigned_p)
+{
+  op->type = type;
+  op->unsigned_p = unsigned_p;
+  op->unused = 0;
+  op->mode = mode;
+  op->value = value;
+}
+
+/* Make OP describe an operand that must use rtx X, even if X is volatile.  */
+
+static inline void
+create_fixed_operand (struct expand_operand *op, rtx x)
+{
+  create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
+}
+
+/* Make OP describe an output operand that must have mode MODE.
+   X, if nonnull, is a suggestion for where the output should be stored.
+   It is OK for VALUE to be inconsistent with MODE, although it will just
+   be ignored in that case.  */
+
+static inline void
+create_output_operand (struct expand_operand *op, rtx x,
+                      enum machine_mode mode)
+{
+  create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
+}
+
+/* Make OP describe an input operand that must have mode MODE and
+   value VALUE; MODE cannot be VOIDmode.  The backend may request that
+   VALUE be copied into a different kind of rtx before being passed
+   as an operand.  */
+
+static inline void
+create_input_operand (struct expand_operand *op, rtx value,
+                     enum machine_mode mode)
+{
+  create_expand_operand (op, EXPAND_INPUT, value, mode, false);
+}
+
+/* Like create_input_operand, except that VALUE must first be converted
+   to mode MODE.  UNSIGNED_P says whether VALUE is unsigned.  */
+
+static inline void
+create_convert_operand_to (struct expand_operand *op, rtx value,
+                          enum machine_mode mode, bool unsigned_p)
+{
+  create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
+}
+
+/* Make OP describe an input operand that should have the same value
+   as VALUE, after any mode conversion that the backend might request.
+   If VALUE is a CONST_INT, it should be treated as having mode MODE.
+   UNSIGNED_P says whether VALUE is unsigned.  */
+
+static inline void
+create_convert_operand_from (struct expand_operand *op, rtx value,
+                            enum machine_mode mode, bool unsigned_p)
+{
+  create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
+}
+
+extern void create_convert_operand_from_type (struct expand_operand *op,
+                                             rtx value, tree type);
+
+/* Make OP describe an input Pmode address operand.  VALUE is the value
+   of the address, but it may need to be converted to Pmode first.  */
+
+static inline void
+create_address_operand (struct expand_operand *op, rtx value)
+{
+  create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
+}
+
+/* Make OP describe an input operand that has value INTVAL and that has
+   no inherent mode.  This function should only be used for operands that
+   are always expand-time constants.  The backend may request that INTVAL
+   be copied into a different kind of rtx, but it must specify the mode
+   of that rtx if so.  */
+
+static inline void
+create_integer_operand (struct expand_operand *op, HOST_WIDE_INT intval)
+{
+  create_expand_operand (op, EXPAND_INTEGER, GEN_INT (intval), VOIDmode, false);
+}
+
+extern bool maybe_legitimize_operands (enum insn_code icode,
+                                      unsigned int opno, unsigned int nops,
+                                      struct expand_operand *ops);
+extern rtx maybe_gen_insn (enum insn_code icode, unsigned int nops,
+                          struct expand_operand *ops);
+extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
+                              struct expand_operand *ops);
+extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
+                                   struct expand_operand *ops);
+extern void expand_insn (enum insn_code icode, unsigned int nops,
+                        struct expand_operand *ops);
+extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
+                             struct expand_operand *ops);
+
+extern rtx prepare_operand (enum insn_code, rtx, int, enum machine_mode,
+                           enum machine_mode, int);
+
 #endif /* GCC_OPTABS_H */