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