make firm (mostly) -Wmissing-prototypes clean
[libfirm] / ir / be / ppc32 / ppc32_new_nodes.c
1 /*
2  * Copyright (C) 1995-2008 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  This file implements the creation of the architecture specific firm
23  *         opcodes and the corresponding node constructors for the ppc assembler
24  *         irg.
25  * @author  Moritz Kroll, Jens Mueller
26  * @version $Id$
27  */
28 #include "config.h"
29
30 #include <stdlib.h>
31
32 #include "irprog_t.h"
33 #include "irgraph_t.h"
34 #include "irnode_t.h"
35 #include "irmode_t.h"
36 #include "ircons_t.h"
37 #include "iropt_t.h"
38 #include "irop.h"
39 #include "irvrfy_t.h"
40 #include "irprintf.h"
41 #include "xmalloc.h"
42
43 #include "../bearch.h"
44
45 #include "ppc32_nodes_attr.h"
46 #include "ppc32_new_nodes.h"
47 #include "gen_ppc32_regalloc_if.h"
48
49
50
51 /***********************************************************************************
52  *      _                                   _       _             __
53  *     | |                                 (_)     | |           / _|
54  *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
55  *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
56  * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
57  *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
58  *                       | |
59  *                       |_|
60  ***********************************************************************************/
61
62 /**
63  * Dumper interface for dumping ppc32 nodes in vcg.
64  * @param n        the node to dump
65  * @param F        the output file
66  * @param reason   indicates which kind of information should be dumped
67  * @return 0 on success or != 0 on failure
68  */
69 static int ppc32_dump_node(ir_node *n, FILE *F, dump_reason_t reason)
70 {
71         ir_mode     *mode = NULL;
72         int          bad  = 0;
73
74         switch (reason) {
75                 case dump_node_opcode_txt:
76                         fprintf(F, "%s", get_irn_opname(n));
77                         break;
78
79                 case dump_node_mode_txt:
80                         mode = get_irn_mode(n);
81
82                         if (mode) {
83                                 fprintf(F, "[%s]", get_mode_name(mode));
84                         }
85                         else {
86                                 fprintf(F, "[?NOMODE?]");
87                         }
88                         break;
89
90                 case dump_node_nodeattr_txt:
91
92                         /* TODO: dump some attributes which should show up */
93                         /* in node name in dump (e.g. consts or the like)  */
94
95                         break;
96
97                 case dump_node_info_txt:
98                         arch_dump_reqs_and_registers(F, n);
99                         break;
100         }
101
102
103         return bad;
104 }
105
106
107
108 /***************************************************************************************************
109  *        _   _                   _       __        _                    _   _               _
110  *       | | | |                 | |     / /       | |                  | | | |             | |
111  *   __ _| |_| |_ _ __   ___  ___| |_   / /_ _  ___| |_   _ __ ___   ___| |_| |__   ___   __| |___
112  *  / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
113  * | (_| | |_| |_| |    \__ \  __/ |_ / / (_| |  __/ |_  | | | | | |  __/ |_| | | | (_) | (_| \__ \
114  *  \__,_|\__|\__|_|    |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
115  *                                        __/ |
116  *                                       |___/
117  ***************************************************************************************************/
118
119 ppc32_attr_t *get_ppc32_attr(ir_node *node)
120 {
121         assert(is_ppc32_irn(node) && "need ppc node to get attributes");
122         return (ppc32_attr_t *)get_irn_generic_attr(node);
123 }
124
125 const ppc32_attr_t *get_ppc32_attr_const(const ir_node *node)
126 {
127         assert(is_ppc32_irn(node) && "need ppc node to get attributes");
128         return (const ppc32_attr_t *)get_irn_generic_attr_const(node);
129 }
130
131
132
133 /**
134  * Returns the argument register requirements of a ppc node.
135  */
136 const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node)
137 {
138         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
139         return attr->in_req;
140 }
141
142 /**
143  * Returns the argument register requirement at position pos of an ppc node.
144  */
145 const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos)
146 {
147         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
148         return attr->in_req[pos];
149 }
150
151 /**
152  * Sets the IN register requirements at position pos.
153  */
154 void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos)
155 {
156         ppc32_attr_t *attr  = get_ppc32_attr(node);
157         attr->in_req[pos] = req;
158 }
159
160 /**
161  * Sets the type of the constant (if any)
162  * May be either iro_Const or iro_SymConst
163  */
164 /* void set_ppc32_type(const ir_node *node, opcode type) {
165         ppc32_attr_t *attr = get_ppc32_attr(node);
166         attr->type      = type;
167 }  */
168
169 /**
170  * Returns the type of the content (if any)
171  */
172 ppc32_attr_content_type get_ppc32_type(const ir_node *node)
173 {
174         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
175         return attr->content_type;
176 }
177
178 /**
179  * Sets a tarval type content (also updating the content_type)
180  */
181 void set_ppc32_constant_tarval(ir_node *node, tarval *const_tarval)
182 {
183         ppc32_attr_t *attr = get_ppc32_attr(node);
184         attr->content_type = ppc32_ac_Const;
185         attr->data.constant_tarval = const_tarval;
186 }
187
188 /**
189  * Returns a tarval type constant
190  */
191 tarval *get_ppc32_constant_tarval(const ir_node *node)
192 {
193         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
194         return attr->data.constant_tarval;
195 }
196
197 /**
198  * Sets an ident type constant (also updating the content_type)
199  */
200 void set_ppc32_symconst_ident(ir_node *node, ident *symconst_ident)
201 {
202         ppc32_attr_t *attr = get_ppc32_attr(node);
203         attr->content_type = ppc32_ac_SymConst;
204         attr->data.symconst_ident = symconst_ident;
205 }
206
207 /**
208  * Returns an ident type constant
209  */
210 ident *get_ppc32_symconst_ident(const ir_node *node)
211 {
212         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
213         return attr->data.symconst_ident;
214 }
215
216
217 /**
218  * Sets an entity (also updating the content_type)
219  */
220 void set_ppc32_frame_entity(ir_node *node, ir_entity *ent)
221 {
222         ppc32_attr_t *attr = get_ppc32_attr(node);
223         attr->content_type = ppc32_ac_FrameEntity;
224         attr->data.frame_entity = ent;
225 }
226
227 /**
228  * Returns an entity
229  */
230 ir_entity *get_ppc32_frame_entity(const ir_node *node)
231 {
232         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
233         return attr->data.frame_entity;
234 }
235
236 /**
237  * Sets a Rlwimi const (also updating the content_type)
238  */
239 void set_ppc32_rlwimi_const(ir_node *node, unsigned shift, unsigned maskA, unsigned maskB)
240 {
241         ppc32_attr_t *attr = get_ppc32_attr(node);
242         attr->content_type = ppc32_ac_RlwimiConst;
243         attr->data.rlwimi_const.shift = shift;
244         attr->data.rlwimi_const.maskA = maskA;
245         attr->data.rlwimi_const.maskB = maskB;
246 }
247
248 /**
249  * Returns the rlwimi const structure
250  */
251 const rlwimi_const_t *get_ppc32_rlwimi_const(const ir_node *node)
252 {
253         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
254         return &attr->data.rlwimi_const;
255 }
256
257 /**
258  * Sets a Proj number (also updating the content_type)
259  */
260 void set_ppc32_proj_nr(ir_node *node, int proj_nr)
261 {
262         ppc32_attr_t *attr = get_ppc32_attr(node);
263         attr->content_type = ppc32_ac_BranchProj;
264         attr->data.proj_nr = proj_nr;
265 }
266
267 /**
268  * Returns the proj number
269  */
270 int get_ppc32_proj_nr(const ir_node *node)
271 {
272         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
273         return attr->data.proj_nr;
274 }
275
276 /**
277  * Sets an offset for a memory access (also updating the content_type)
278  */
279 void set_ppc32_offset(ir_node *node, int offset)
280 {
281         ppc32_attr_t *attr = get_ppc32_attr(node);
282         attr->content_type = ppc32_ac_Offset;
283         attr->data.offset  = offset;
284 }
285
286 /**
287  * Returns the offset
288  */
289 int get_ppc32_offset(const ir_node *node)
290 {
291         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
292         return attr->data.offset;
293 }
294
295 /**
296  * Sets the offset mode (ppc32_ao_None, ppc32_ao_Lo16, ppc32_ao_Hi16 or ppc32_ao_Ha16)
297  */
298 void set_ppc32_offset_mode(ir_node *node, ppc32_attr_offset_mode mode)
299 {
300         ppc32_attr_t *attr = get_ppc32_attr(node);
301         attr->offset_mode = mode;
302 }
303
304 /**
305  * Returns the offset mode
306  */
307 ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node)
308 {
309         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
310         return attr->offset_mode;
311 }
312
313
314 /**
315  * Initializes ppc specific node attributes
316  */
317 static void init_ppc32_attributes(ir_node *node, int flags,
318                                   const arch_register_req_t **in_reqs,
319                                   const be_execution_unit_t ***execution_units,
320                                   int n_res)
321 {
322         ir_graph       *irg  = get_irn_irg(node);
323         struct obstack *obst = get_irg_obstack(irg);
324         ppc32_attr_t   *attr = get_ppc32_attr(node);
325         backend_info_t  *info;
326         (void) execution_units;
327
328         arch_irn_set_flags(node, flags);
329         attr->in_req  = in_reqs;
330
331         attr->content_type = ppc32_ac_None;
332         attr->offset_mode  = ppc32_ao_Illegal;
333         attr->data.empty   = NULL;
334
335         info            = be_get_info(node);
336         info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
337         memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
338 }
339
340
341 /***************************************************************************************
342  *                  _                            _                   _
343  *                 | |                          | |                 | |
344  *  _ __   ___   __| | ___    ___ ___  _ __  ___| |_ _ __ _   _  ___| |_ ___  _ __ ___
345  * | '_ \ / _ \ / _` |/ _ \  / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
346  * | | | | (_) | (_| |  __/ | (_| (_) | | | \__ \ |_| |  | |_| | (__| || (_) | |  \__ \
347  * |_| |_|\___/ \__,_|\___|  \___\___/|_| |_|___/\__|_|   \__,_|\___|\__\___/|_|  |___/
348  *
349  ***************************************************************************************/
350
351 /* Include the generated constructor functions */
352 #include "gen_ppc32_new_nodes.c.inl"