Use is_Bad() where appropriate
[libfirm] / ir / ir / irreflect.h
index 1416771..c0db562 100644 (file)
@@ -1,20 +1,18 @@
 /**
- * @file reflect.h
+ * @file irreflect.h
  * @date 9.9.2004
  * @author Sebastian Hack
  * @brief Reflection for Firm operations.
  *
  * $Id$
  */
-
-#ifndef __REFLECT_H
-#define __REFLECT_H
+#ifndef _FIRM_IR_REFLECT_H_
+#define _FIRM_IR_REFLECT_H_
 
 #include <limits.h>
-#include <stdbool.h>
 
+#include "firm_types.h"
 #include "irop.h"
-#include "irnode.h"
 
 #define RFLCT_MC(m) rflct_ms_ ## m
 typedef enum {
@@ -44,10 +42,10 @@ typedef enum {
 
 } rflct_mode_class_t;
 
-typedef struct {
+typedef struct _rflct_arg_t {
   const char *name;  /**< The name of the argument (just a description). */
 
-  bool is_variadic; /**< True, if this argument can have multiple parameters. */
+  int is_variadic; /**< non-zero, if this argument can have multiple parameters. */
   rflct_mode_class_t accepted_modes; /**< The set of accepted modes. */
 
   int mode_equals; /**< If not variadic: You can specify the index of
@@ -62,6 +60,13 @@ typedef struct {
                        must be the same. If false, they can differ. */
 } rflct_arg_t;
 
+typedef struct _rflct_sig_t {
+       int defs; /**< The number of defined arguments in the signature. */
+       int uses; /**< The number of used arguments in the signature. */
+
+       rflct_arg_t *args; /**< The arguments array. */
+} rflct_sig_t;
+
 #define RFLCT_ARG_IS_A(arg,modes) (((arg)->accepted_modes & modes) != 0)
 #define RFLCT_ARG_VALID(arg) ((arg)->name != NULL)
 #define RFLCT_SIG_VALID(sig) ((sig) != INT_MAX)
@@ -86,7 +91,7 @@ int rflct_get_signature_count(opcode opc);
  * @param irn The node.
  * @return The first matching signature or -1, if no signature matches.
  */
-int rflct_get_signature(ir_node *irn);
+int rflct_get_signature(const ir_node *irn);
 
 /**
  * Get the number of in arguments.
@@ -106,6 +111,9 @@ int rflct_get_in_args_count(opcode opc, int sig);
  */
 int rflct_get_out_args_count(opcode opc, int sig);
 
+#define rflct_get_args_count(opc, sig, use) \
+  ((use) ? rflct_get_in_args_count(opc, sig) : rflct_get_out_args_count(opc, sig))
+
 /**
  * Get the array of use args.
  * The array is terminated with an entry for which
@@ -128,6 +136,9 @@ const rflct_arg_t *rflct_get_in_args(opcode opc, int sig);
  */
 const rflct_arg_t *rflct_get_out_args(opcode opc, int sig);
 
+#define rflct_get_args(opc, sig, use) \
+  ((use) ? rflct_get_in_args(opc, sig) : rflct_get_out_args(opc, sig))
+
 /**
  * Make a string representation of a signature of an opcode.
  * @param buf The buffer to put the string to.
@@ -147,4 +158,63 @@ char *rflct_to_string(char *buf, int n, opcode opc, int sig);
  */
 char *rflct_mode_class_name(char *str, int n, rflct_mode_class_t mc);
 
-#endif
+/**
+ * Create a new opcode.
+ * @param opc         The Firm opcode.
+ * @param name        A name.
+ * @param commutative non-zero, if the opcode is commutative.
+ */
+void rflct_new_opcode(opcode opc, const char *name, int commutative);
+
+/**
+ * Add a signature to the opcode.
+ * @param opc  The opcode.
+ * @param sig  The signature.
+ * @return non-zero, if the signature was added successfully, false if no
+ * more signatures can be added to the opcode.
+ */
+int rflct_opcode_add_signature(opcode opc, rflct_sig_t *sig);
+
+/**
+ * Allocate a new signature.
+ * @param defs Number of def arguments.
+ * @param uses Number of use arguments.
+ * @return An allocated signature.
+ */
+rflct_sig_t *rflct_signature_allocate(int defs, int uses);
+
+/**
+ * Set an argument in a signature.
+ *
+ * @param sig         The signature.
+ * @param is_use      non-zero, if the argument is a use, else it is
+ *                    considered a def.
+ * @param num         The index of the argument.
+ * @param name        The name of the argument.
+ * @param mc          The mode class of the argument.
+ * @param is_variadic non-zero, if the argument is variadic.
+ * @param mode_equals This variable has following meaning: If the
+ * argument is variadic, a 1 indicates that all operands binding to this
+ * argument must have the same mode. A 0 indicates, that their mode must
+ * be of the specified mode class but can differ. If the argument is non
+ * variadic, a positive number indicates, that the mode of the operand
+ * binding to this argument must be the same as the one binding to
+ * argument indexed by mode_equals. If the mode should not be dependent
+ * to another mode, set -1 here.
+ * @return The index of the argument. Only use this index in mode_equals
+ * parameters of other arguments.
+ */
+int rflct_signature_set_arg(rflct_sig_t *sig, int is_use, int num,
+               const char *name, rflct_mode_class_t mc, int is_variadic, int mode_equals);
+
+/**
+ * Get the arguments array index for an argument.
+ * @param sig    The signature.
+ * @param is_use non-zero, if the argument indicates a use or def argument.
+ * @param num    The number of the argument.
+ * @return The index into the arguments array.
+ */
+int rflct_signature_get_index(const rflct_sig_t *sig, int is_use, int num);
+
+
+#endif /* _FIRM_IR_REFLECT_H_ */