backend part is always WITH_LIBCORE :-)
[libfirm] / ir / ir / irmode_t.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
22  * @brief   Data modes of operations -- private header.
23  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil,
24  *          Michael Beck
25  * @version $Id$
26  */
27 #ifndef FIRM_IR_IRMODE_T_H
28 #define FIRM_IR_IRMODE_T_H
29
30 #include <assert.h>
31 #include "irmode.h"
32 #include "tv.h"
33
34 /**
35  * Contains relevant information about a mode.
36  *
37  * Necessary information about a mode is stored in this struct
38  * which is used by the tarval module to perform calculations
39  * and comparisons of values of a such described mode.
40  *
41  * ATTRIBUTES:
42  *  -  modecode code:           An unambiguous int (enum) for the mode
43  *  -  ident *name:             Name of this mode. Two modes are different if the name is different.
44  *  -  mode_sort sort:          sort of mode specifying possible usage categories
45  *  -  int    size:             size of the mode in Bits.
46  *  -  unsigned sign:1:         signedness of this mode
47  *  -  ... more to come
48  *  -  modulo_shift             specifies for modes of kind irms_int_number
49  *                              whether shift applies modulo to value of bits to shift
50  *
51  * SEE ALSO:
52  *    The tech report 1999-44 describing FIRM and predefined modes
53  *    tarval.h
54  */
55 struct ir_mode {
56         firm_kind         kind;       /**< distinguishes this node from others */
57         modecode          code;       /**< unambiguous identifier of a mode */
58         ident             *name;      /**< Name ident of this mode */
59
60         /* ----------------------------------------------------------------------- */
61         /* On changing this struct you have to evaluate the mode_are_equal function!*/
62         mode_sort         sort;          /**< coarse classification of this mode:
63                                           int, float, reference ...
64                                           (see irmode.h) */
65         mode_arithmetic   arithmetic;    /**< different arithmetic operations possible with a mode */
66         int               size;          /**< size of the mode in Bits. */
67         unsigned          sign:1;        /**< signedness of this mode */
68         unsigned int      modulo_shift;  /**< number of bits a values of this mode will be shifted */
69         unsigned          vector_elem;   /**< if this is not equal 1, this is a vector mode with
70                                           vector_elem number of elements, size contains the size
71                                           of all bits and must be dividable by vector_elem */
72
73         /* ----------------------------------------------------------------------- */
74         tarval            *min;         /**< the minimum value that can be expressed */
75         tarval            *max;         /**< the maximum value that can be expressed */
76         tarval            *null;        /**< the value 0 */
77         tarval            *one;         /**< the value 1 */
78         tarval            *minus_one;   /**< the value -1 */
79         ir_mode           *eq_signed;   /**< For pointer modes, the equivalent signed integer one. */
80         ir_mode           *eq_unsigned; /**< For pointer modes, the equivalent unsigned integer one. */
81         void              *link;        /**< To store some intermediate information */
82         const void        *tv_priv;     /**< tarval module will save private data here */
83 };
84
85
86 /* ------------------------------- *
87  * inline functions                *
88  * ------------------------------- */
89 extern ir_mode *mode_P_code, *mode_P_data;
90
91 static INLINE ir_mode *
92 _get_modeP_code(void) { return mode_P_code; }
93
94 static INLINE ir_mode *
95 _get_modeP_data(void) { return mode_P_data; }
96
97 static INLINE modecode
98 _get_mode_modecode(const ir_mode *mode) { return mode->code; }
99
100 static INLINE ident *
101 _get_mode_ident(const ir_mode *mode) { return mode->name; }
102
103 static INLINE mode_sort
104 _get_mode_sort(const ir_mode* mode) { return mode->sort; }
105
106 static INLINE int
107 _get_mode_size_bits(const ir_mode *mode) { return mode->size; }
108
109 static INLINE int
110 _get_mode_size_bytes(const ir_mode *mode) {
111         int size = _get_mode_size_bits(mode);
112         if ((size & 7) != 0) return -1;
113         return size >> 3;
114 }
115
116 static INLINE int
117 _get_mode_sign(const ir_mode *mode) { return mode->sign; }
118
119 static INLINE int
120 _get_mode_arithmetic(const ir_mode *mode) { return mode->arithmetic; }
121
122 static INLINE unsigned int
123 _get_mode_modulo_shift(const ir_mode *mode) { return mode->modulo_shift; }
124
125 static INLINE unsigned int
126 _get_mode_vector_elems(const ir_mode *mode) { return mode->vector_elem; }
127
128 static INLINE void *
129 _get_mode_link(const ir_mode *mode) { return mode->link; }
130
131 static INLINE void
132 _set_mode_link(ir_mode *mode, void *l) { mode->link = l; }
133
134 /* Functions to check, whether a modecode is signed, float, int, num, data,
135    datab or dataM. For more exact definitions read the corresponding pages
136    in the firm documentation or the following enumeration
137
138    The set of "float" is defined as:
139    ---------------------------------
140    float = {irm_F, irm_D, irm_E}
141
142    The set of "int" is defined as:
143    -------------------------------
144    int   = {irm_Bs, irm_Bu, irm_Hs, irm_Hu, irm_Is, irm_Iu, irm_Ls, irm_Lu}
145
146    The set of "num" is defined as:
147    -------------------------------
148    num   = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
149             irm_Is, irm_Iu, irm_Ls, irm_Lu}
150             = {float || int}
151
152    The set of "data" is defined as:
153    -------------------------------
154    data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
155             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P}
156             = {num || irm_C || irm_U || irm_P}
157
158    The set of "datab" is defined as:
159    ---------------------------------
160    datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
161             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
162             = {data || irm_b }
163
164    The set of "dataM" is defined as:
165    ---------------------------------
166    dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
167             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_M}
168             = {data || irm_M}
169 */
170
171 static INLINE int
172 _mode_is_signed(const ir_mode *mode) {
173         assert(mode);
174         return mode->sign;
175 }
176
177 static INLINE int
178 _mode_is_float(const ir_mode *mode) {
179         assert(mode);
180         return (_get_mode_sort(mode) == irms_float_number);
181 }
182
183 static INLINE int
184 _mode_is_int(const ir_mode *mode) {
185         assert(mode);
186         return (_get_mode_sort(mode) == irms_int_number);
187 }
188
189 static INLINE int
190 _mode_is_character(const ir_mode *mode) {
191         assert(mode);
192         return (_get_mode_sort(mode) == irms_character);
193 }
194
195 static INLINE int
196 _mode_is_reference(const ir_mode *mode) {
197         assert(mode);
198         return (_get_mode_sort(mode) == irms_reference);
199 }
200
201 static INLINE int
202 _mode_is_num(const ir_mode *mode) {
203         assert(mode);
204         return (_mode_is_int(mode) || _mode_is_float(mode));
205 }
206
207 static INLINE int
208 _mode_is_numP(const ir_mode *mode) {
209         assert(mode);
210         return (_mode_is_int(mode) || _mode_is_float(mode) || _mode_is_reference(mode));
211 }
212
213 static INLINE int
214 _mode_is_data(const ir_mode *mode) {
215         assert(mode);
216         return (_mode_is_numP(mode) || _get_mode_sort(mode) == irms_character);
217 }
218
219 static INLINE int
220 _mode_is_datab(const ir_mode *mode) {
221         assert(mode);
222         return (_mode_is_data(mode) || _get_mode_sort(mode) == irms_internal_boolean);
223 }
224
225 static INLINE int
226 _mode_is_dataM(const ir_mode *mode) {
227         assert(mode);
228         return (_mode_is_data(mode) || _get_mode_modecode(mode) == irm_M);
229 }
230
231 static INLINE int
232 _mode_is_float_vector(const ir_mode *mode) {
233         assert(mode);
234         return (_get_mode_sort(mode) == irms_float_number) && (_get_mode_vector_elems(mode) > 1);
235 }
236
237 static INLINE int
238 _mode_is_int_vector(const ir_mode *mode) {
239         assert(mode);
240         return (_get_mode_sort(mode) == irms_int_number) && (_get_mode_vector_elems(mode) > 1);
241 }
242
243 /** mode module initialization, call once before use of any other function **/
244 void init_mode(void);
245
246 /** mode module finalization. frees all memory.  */
247 void finish_mode(void);
248
249 #define get_modeP_code()               _get_modeP_code()
250 #define get_modeP_data()               _get_modeP_data()
251 #define get_mode_modecode(mode)        _get_mode_modecode(mode)
252 #define get_mode_ident(mode)           _get_mode_ident(mode)
253 #define get_mode_sort(mode)            _get_mode_sort(mode)
254 #define get_mode_size_bits(mode)       _get_mode_size_bits(mode)
255 #define get_mode_size_bytes(mode)      _get_mode_size_bytes(mode)
256 #define get_mode_sign(mode)            _get_mode_sign(mode)
257 #define get_mode_arithmetic(mode)      _get_mode_arithmetic(mode)
258 #define get_mode_modulo_shift(mode)    _get_mode_modulo_shift(mode)
259 #define get_mode_n_vector_elems(mode)  _get_mode_vector_elems(mode)
260 #define get_mode_link(mode)            _get_mode_link(mode)
261 #define set_mode_link(mode, l)         _set_mode_link(mode, l)
262 #define mode_is_signed(mode)           _mode_is_signed(mode)
263 #define mode_is_float(mode)            _mode_is_float(mode)
264 #define mode_is_int(mode)              _mode_is_int(mode)
265 #define mode_is_character(mode)        _mode_is_character(mode)
266 #define mode_is_reference(mode)        _mode_is_reference(mode)
267 #define mode_is_num(mode)              _mode_is_num(mode)
268 #define mode_is_numP(mode)             _mode_is_numP(mode)
269 #define mode_is_data(mode)             _mode_is_data(mode)
270 #define mode_is_datab(mode)            _mode_is_datab(mode)
271 #define mode_is_dataM(mode)            _mode_is_dataM(mode)
272 #define mode_is_float_vector(mode)     _mode_is_float_vector(mode)
273 #define mode_is_int_vector(mode)       _mode_is_int_vector(mode)
274
275 #endif