added new licence header
[libfirm] / ir / ir / irreflect.h
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file irreflect.h
22  * @date 9.9.2004
23  * @author Sebastian Hack
24  * @brief Reflection for Firm operations.
25  *
26  * $Id$
27  */
28 #ifndef _FIRM_IR_REFLECT_H_
29 #define _FIRM_IR_REFLECT_H_
30
31 #include <limits.h>
32
33 #include "firm_types.h"
34 #include "irop.h"
35
36 #define RFLCT_MC(m) rflct_ms_ ## m
37 typedef enum {
38   RFLCT_MC(None)  = 0,
39   RFLCT_MC(Mem)   = 2,
40   RFLCT_MC(Bool)  = 4,
41   RFLCT_MC(IntS)  = 8,
42   RFLCT_MC(IntU)  = 16,
43   RFLCT_MC(Float) = 32,
44   RFLCT_MC(Ref)   = 64,
45   RFLCT_MC(Char)  = 128,
46   RFLCT_MC(X)     = 256,
47   RFLCT_MC(BB)    = 512,
48   RFLCT_MC(Cf)    = RFLCT_MC(X) | RFLCT_MC(BB),
49
50   RFLCT_MC(Int) = RFLCT_MC(IntS) | RFLCT_MC(IntU),
51   RFLCT_MC(Intb) = RFLCT_MC(Int) | RFLCT_MC(Bool),
52   RFLCT_MC(Num) = RFLCT_MC(Int) | RFLCT_MC(Float),
53   RFLCT_MC(NumP) = RFLCT_MC(Num) | RFLCT_MC(Ref),
54   RFLCT_MC(Data) = RFLCT_MC(NumP) | RFLCT_MC(Char),
55   RFLCT_MC(Datab) = RFLCT_MC(Data) | RFLCT_MC(Bool),
56   RFLCT_MC(DataM) = RFLCT_MC(Data) | RFLCT_MC(Mem),
57   RFLCT_MC(DataMX) = RFLCT_MC(Data) | RFLCT_MC(Mem) | RFLCT_MC(X),
58   RFLCT_MC(Lh) = RFLCT_MC(Mem) | RFLCT_MC(BB),
59
60   RFLCT_MC(Any) = -1
61
62 } rflct_mode_class_t;
63
64 typedef struct _rflct_arg_t {
65   const char *name;  /**< The name of the argument (just a description). */
66
67   int is_variadic; /**< non-zero, if this argument can have multiple parameters. */
68   rflct_mode_class_t accepted_modes; /**< The set of accepted modes. */
69
70   int mode_equals; /**< If not variadic: You can specify the index of
71                         another argument meaning, that the mode of the
72                         operand binding at this argument must be the same
73                         as the mode of the operand binding to the argument
74                         at index. If you don't want to express such a
75                         dependency, just give -1 here.
76
77                         If variadic: If true, the modes of all
78                         variadic operands binding to this argument
79                         must be the same. If false, they can differ. */
80 } rflct_arg_t;
81
82 typedef struct _rflct_sig_t {
83         int defs; /**< The number of defined arguments in the signature. */
84         int uses; /**< The number of used arguments in the signature. */
85
86         rflct_arg_t *args; /**< The arguments array. */
87 } rflct_sig_t;
88
89 #define RFLCT_ARG_IS_A(arg,modes) (((arg)->accepted_modes & modes) != 0)
90 #define RFLCT_ARG_VALID(arg) ((arg)->name != NULL)
91 #define RFLCT_SIG_VALID(sig) ((sig) != INT_MAX)
92
93 /**
94  * Get the mode class for an IR mode.
95  * @param mode An IR mode.
96  * @return The corresponding smallest reflection mode class.
97  */
98 rflct_mode_class_t rflct_get_mode_class(const ir_mode *mode);
99
100 /**
101  * Get the number of signatures for a Firm opcode.
102  * @param opc The opcode.
103  * @return The number of signatures for this opcode.
104  */
105 int rflct_get_signature_count(ir_opcode opc);
106
107 /**
108  * Try to get the signature, that matches to a given instance
109  * of a Firm node.
110  * @param irn The node.
111  * @return The first matching signature or -1, if no signature matches.
112  */
113 int rflct_get_signature(const ir_node *irn);
114
115 /**
116  * Get the number of in arguments.
117  * An in argument is a use of a value.
118  * @param opc The opcode.
119  * @param sig The signature you are refering to.
120  * @return The number of arguments.
121  */
122 int rflct_get_in_args_count(ir_opcode opc, int sig);
123
124 /**
125  * Get the number of out arguments.
126  * An out argument is a def of a value.
127  * @param opc The opcode.
128  * @param sig The signature you are refering to.
129  * @return The number of arguments.
130  */
131 int rflct_get_out_args_count(ir_opcode opc, int sig);
132
133 #define rflct_get_args_count(opc, sig, use) \
134   ((use) ? rflct_get_in_args_count(opc, sig) : rflct_get_out_args_count(opc, sig))
135
136 /**
137  * Get the array of use args.
138  * The array is terminated with an entry for which
139  * <code>RFLCT_ARG_VALID</code> is 0.
140  * @param opc The opcode.
141  * @param sig The signature you are referring to (Must be between
142  * 0 and the signature count).
143  * @return The array.
144  */
145 const rflct_arg_t *rflct_get_in_args(ir_opcode opc, int sig);
146
147 /**
148  * Get the array of def args.
149  * The array is terminated with an entry for which
150  * <code>RFLCT_ARG_VALID</code> is 0.
151  * @param opc The opcode.
152  * @param sig The signature you are referring to (Must be between
153  * 0 and the signature count).
154  * @return The array.
155  */
156 const rflct_arg_t *rflct_get_out_args(ir_opcode opc, int sig);
157
158 #define rflct_get_args(opc, sig, use) \
159   ((use) ? rflct_get_in_args(opc, sig) : rflct_get_out_args(opc, sig))
160
161 /**
162  * Make a string representation of a signature of an opcode.
163  * @param buf The buffer to put the string to.
164  * @param n The size of buf.
165  * @param opc The opcode.
166  * @param sig The signature.
167  * @return buf.
168  */
169 char *rflct_to_string(char *buf, int n, ir_opcode opc, int sig);
170
171 /**
172  * Get a string representation of a mode class.
173  * @param str The buffer to put the string to.
174  * @param n The size of the buffer.
175  * @param mc The mode class.
176  * @return str.
177  */
178 char *rflct_mode_class_name(char *str, int n, rflct_mode_class_t mc);
179
180 /**
181  * Create a new opcode.
182  * @param opc         The Firm opcode.
183  * @param name        A name.
184  * @param commutative non-zero, if the opcode is commutative.
185  */
186 void rflct_new_opcode(ir_opcode opc, const char *name, int commutative);
187
188 /**
189  * Add a signature to the opcode.
190  * @param opc  The opcode.
191  * @param sig  The signature.
192  * @return non-zero, if the signature was added successfully, false if no
193  * more signatures can be added to the opcode.
194  */
195 int rflct_opcode_add_signature(ir_opcode opc, rflct_sig_t *sig);
196
197 /**
198  * Allocate a new signature.
199  * @param defs Number of def arguments.
200  * @param uses Number of use arguments.
201  * @return An allocated signature.
202  */
203 rflct_sig_t *rflct_signature_allocate(int defs, int uses);
204
205 /**
206  * Set an argument in a signature.
207  *
208  * @param sig         The signature.
209  * @param is_use      non-zero, if the argument is a use, else it is
210  *                    considered a def.
211  * @param num         The index of the argument.
212  * @param name        The name of the argument.
213  * @param mc          The mode class of the argument.
214  * @param is_variadic non-zero, if the argument is variadic.
215  * @param mode_equals This variable has following meaning: If the
216  * argument is variadic, a 1 indicates that all operands binding to this
217  * argument must have the same mode. A 0 indicates, that their mode must
218  * be of the specified mode class but can differ. If the argument is non
219  * variadic, a positive number indicates, that the mode of the operand
220  * binding to this argument must be the same as the one binding to
221  * argument indexed by mode_equals. If the mode should not be dependent
222  * to another mode, set -1 here.
223  * @return The index of the argument. Only use this index in mode_equals
224  * parameters of other arguments.
225  */
226 int rflct_signature_set_arg(rflct_sig_t *sig, int is_use, int num,
227                 const char *name, rflct_mode_class_t mc, int is_variadic, int mode_equals);
228
229 /**
230  * Get the arguments array index for an argument.
231  * @param sig    The signature.
232  * @param is_use non-zero, if the argument indicates a use or def argument.
233  * @param num    The number of the argument.
234  * @return The index into the arguments array.
235  */
236 int rflct_signature_get_index(const rflct_sig_t *sig, int is_use, int num);
237
238
239 #endif /* _FIRM_IR_REFLECT_H_ */