- Reworked backends to put out register_requirements into backend_info_t
[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         assert(is_ppc32_irn(node) && "need ppc node to get attributes");
121         return (ppc32_attr_t *)get_irn_generic_attr(node);
122 }
123
124 const ppc32_attr_t *get_ppc32_attr_const(const ir_node *node) {
125         assert(is_ppc32_irn(node) && "need ppc node to get attributes");
126         return (const ppc32_attr_t *)get_irn_generic_attr_const(node);
127 }
128
129
130
131 /**
132  * Returns the argument register requirements of a ppc node.
133  */
134 const arch_register_req_t **get_ppc32_in_req_all(const ir_node *node) {
135         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
136         return attr->in_req;
137 }
138
139 /**
140  * Returns the argument register requirement at position pos of an ppc node.
141  */
142 const arch_register_req_t *get_ppc32_in_req(const ir_node *node, int pos) {
143         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
144         return attr->in_req[pos];
145 }
146
147 /**
148  * Returns the result register requirement at position pos of an ppc node.
149  */
150 const arch_register_req_t *get_ppc32_out_req(const ir_node *node, int pos)
151 {
152         const backend_info_t *info = be_get_info(node);
153         return info->out_infos[pos].req;
154 }
155
156 /**
157  * Sets the IN register requirements at position pos.
158  */
159 void set_ppc32_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
160         ppc32_attr_t *attr  = get_ppc32_attr(node);
161         attr->in_req[pos] = req;
162 }
163
164 /**
165  * Sets the type of the constant (if any)
166  * May be either iro_Const or iro_SymConst
167  */
168 /* void set_ppc32_type(const ir_node *node, opcode type) {
169         ppc32_attr_t *attr = get_ppc32_attr(node);
170         attr->type      = type;
171 }  */
172
173 /**
174  * Returns the type of the content (if any)
175  */
176 ppc32_attr_content_type get_ppc32_type(const ir_node *node) {
177         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
178         return attr->content_type;
179 }
180
181 /**
182  * Sets a tarval type content (also updating the content_type)
183  */
184 void set_ppc32_constant_tarval(ir_node *node, tarval *const_tarval) {
185         ppc32_attr_t *attr = get_ppc32_attr(node);
186         attr->content_type = ppc32_ac_Const;
187         attr->data.constant_tarval = const_tarval;
188 }
189
190 /**
191  * Returns a tarval type constant
192  */
193 tarval *get_ppc32_constant_tarval(const ir_node *node) {
194         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
195         return attr->data.constant_tarval;
196 }
197
198 /**
199  * Sets an ident type constant (also updating the content_type)
200  */
201 void set_ppc32_symconst_ident(ir_node *node, ident *symconst_ident) {
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         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
212         return attr->data.symconst_ident;
213 }
214
215
216 /**
217  * Sets an entity (also updating the content_type)
218  */
219 void set_ppc32_frame_entity(ir_node *node, ir_entity *ent) {
220         ppc32_attr_t *attr = get_ppc32_attr(node);
221         attr->content_type = ppc32_ac_FrameEntity;
222         attr->data.frame_entity = ent;
223 }
224
225 /**
226  * Returns an entity
227  */
228 ir_entity *get_ppc32_frame_entity(const ir_node *node) {
229         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
230         return attr->data.frame_entity;
231 }
232
233 /**
234  * Sets a Rlwimi const (also updating the content_type)
235  */
236 void set_ppc32_rlwimi_const(ir_node *node, unsigned shift, unsigned maskA, unsigned maskB) {
237         ppc32_attr_t *attr = get_ppc32_attr(node);
238         attr->content_type = ppc32_ac_RlwimiConst;
239         attr->data.rlwimi_const.shift = shift;
240         attr->data.rlwimi_const.maskA = maskA;
241         attr->data.rlwimi_const.maskB = maskB;
242 }
243
244 /**
245  * Returns the rlwimi const structure
246  */
247 const rlwimi_const_t *get_ppc32_rlwimi_const(const ir_node *node) {
248         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
249         return &attr->data.rlwimi_const;
250 }
251
252 /**
253  * Sets a Proj number (also updating the content_type)
254  */
255 void set_ppc32_proj_nr(ir_node *node, int proj_nr) {
256         ppc32_attr_t *attr = get_ppc32_attr(node);
257         attr->content_type = ppc32_ac_BranchProj;
258         attr->data.proj_nr = proj_nr;
259 }
260
261 /**
262  * Returns the proj number
263  */
264 int get_ppc32_proj_nr(const ir_node *node) {
265         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
266         return attr->data.proj_nr;
267 }
268
269 /**
270  * Sets an offset for a memory access (also updating the content_type)
271  */
272 void set_ppc32_offset(ir_node *node, int offset) {
273         ppc32_attr_t *attr = get_ppc32_attr(node);
274         attr->content_type = ppc32_ac_Offset;
275         attr->data.offset  = offset;
276 }
277
278 /**
279  * Returns the offset
280  */
281 int get_ppc32_offset(const ir_node *node) {
282         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
283         return attr->data.offset;
284 }
285
286 /**
287  * Sets the offset mode (ppc32_ao_None, ppc32_ao_Lo16, ppc32_ao_Hi16 or ppc32_ao_Ha16)
288  */
289 void set_ppc32_offset_mode(ir_node *node, ppc32_attr_offset_mode mode) {
290         ppc32_attr_t *attr = get_ppc32_attr(node);
291         attr->offset_mode = mode;
292 }
293
294 /**
295  * Returns the offset mode
296  */
297 ppc32_attr_offset_mode get_ppc32_offset_mode(const ir_node *node) {
298         const ppc32_attr_t *attr = get_ppc32_attr_const(node);
299         return attr->offset_mode;
300 }
301
302
303 /**
304  * Initializes ppc specific node attributes
305  */
306 void init_ppc32_attributes(ir_node *node, int flags,
307                                                  const arch_register_req_t **in_reqs,
308                                                  const be_execution_unit_t ***execution_units,
309                                                  int n_res) {
310         ir_graph       *irg  = get_irn_irg(node);
311         struct obstack *obst = get_irg_obstack(irg);
312         ppc32_attr_t   *attr = get_ppc32_attr(node);
313         backend_info_t  *info;
314         (void) execution_units;
315
316         arch_irn_set_flags(node, flags);
317         attr->in_req  = in_reqs;
318
319         attr->content_type = ppc32_ac_None;
320         attr->offset_mode  = ppc32_ao_Illegal;
321         attr->data.empty   = NULL;
322
323         info            = be_get_info(node);
324         info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
325         memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
326 }
327
328
329 /***************************************************************************************
330  *                  _                            _                   _
331  *                 | |                          | |                 | |
332  *  _ __   ___   __| | ___    ___ ___  _ __  ___| |_ _ __ _   _  ___| |_ ___  _ __ ___
333  * | '_ \ / _ \ / _` |/ _ \  / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
334  * | | | | (_) | (_| |  __/ | (_| (_) | | | \__ \ |_| |  | |_| | (__| || (_) | |  \__ \
335  * |_| |_|\___/ \__,_|\___|  \___\___/|_| |_|___/\__|_|   \__,_|\___|\__\___/|_|  |___/
336  *
337  ***************************************************************************************/
338
339 /* Include the generated constructor functions */
340 #include "gen_ppc32_new_nodes.c.inl"