C99 feature removed.
[libfirm] / ir / be / amd64 / amd64_transform.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   code selection (transform FIRM into amd64 FIRM)
23  * @version $Id: amd64_transform.c 26673 2009-10-01 16:43:13Z matze $
24  */
25 #include "config.h"
26
27 #include "irnode_t.h"
28 #include "irgraph_t.h"
29 #include "irmode_t.h"
30 #include "irgmod.h"
31 #include "iredges.h"
32 #include "irvrfy.h"
33 #include "ircons.h"
34 #include "iropt_t.h"
35 #include "debug.h"
36
37 #include "../benode.h"
38 #include "../betranshlp.h"
39 #include "bearch_amd64_t.h"
40
41 #include "amd64_nodes_attr.h"
42 #include "amd64_transform.h"
43 #include "amd64_new_nodes.h"
44
45 #include "gen_amd64_regalloc_if.h"
46
47 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
48
49 /** holds the current code generator during transformation */
50 static amd64_code_gen_t *env_cg;
51
52 /* Some support functions: */
53
54 /**
55  * Create a DAG constructing a given Const.
56  *
57  * @param irn  a Firm const
58  */
59 static ir_node *create_const_graph(ir_node *irn, ir_node *block)
60 {
61         tarval  *tv    = get_Const_tarval(irn);
62         ir_mode *mode  = get_tarval_mode(tv);
63         dbg_info *dbgi = get_irn_dbg_info(irn);
64         unsigned value;
65
66         if (mode_is_reference(mode)) {
67                 /* AMD64 is 64bit, so we can safely convert a reference tarval into Iu */
68                 assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
69                 tv = tarval_convert_to(tv, mode_Iu);
70         }
71
72         value = get_tarval_long(tv);
73         printf ("TEST GENERATE %d\n", value);
74
75         return new_bd_amd64_Immediate(dbgi, block, value);
76 }
77
78 /* Op transformers: */
79
80 /**
81  * Transforms a Const node.
82  *
83  * @return The transformed AMD64 node.
84  */
85 static ir_node *gen_Const(ir_node *node) {
86         ir_node  *block = be_transform_node(get_nodes_block(node));
87         ir_mode  *mode  = get_irn_mode(node);
88         ir_node *res = create_const_graph(node, block);
89         (void) mode;
90
91         be_dep_on_frame(res);
92
93         return res;
94 }
95
96 /**
97  * Transforms a SymConst node.
98  *
99  * @return The transformed ARM node.
100  */
101 static ir_node *gen_SymConst(ir_node *node)
102 {
103         ir_node   *block  = be_transform_node(get_nodes_block(node));
104         ir_entity *entity = get_SymConst_entity(node);
105         dbg_info  *dbgi   = get_irn_dbg_info(node);
106         ir_node   *new_node;
107
108         new_node = new_bd_amd64_SymConst(dbgi, block, entity);
109         be_dep_on_frame(new_node);
110         return new_node;
111 }
112
113 /**
114  * Transforms an Add node.
115  *
116  * @return The transformed AMD64 node.
117  */
118 static ir_node *gen_Add(ir_node *node) {
119         ir_node  *block = be_transform_node(get_nodes_block(node));
120         /* ir_mode  *mode  = get_irn_mode(node); */
121         ir_node  *op1   = get_Add_left(node);
122         ir_node  *op2   = get_Add_right(node);
123         dbg_info *dbgi  = get_irn_dbg_info(node);
124         ir_node  *new_op1 = be_transform_node(op1);
125         ir_node  *new_op2 = be_transform_node(op2);
126
127         ir_node *res = new_bd_amd64_Add(dbgi, block, new_op1, new_op2);
128         be_dep_on_frame (res);
129         return res;
130 }
131
132
133
134 /* Boilerplate code for transformation: */
135
136 static void amd64_pretransform_node(void)
137 {
138         amd64_code_gen_t *cg = env_cg;
139         (void) cg;
140 }
141
142 static void set_transformer(ir_op *op, be_transform_func amd64_transform_func)
143 {
144         op->ops.generic = (op_func)amd64_transform_func;
145 }
146
147 static void amd64_register_transformers(void)
148 {
149         clear_irp_opcodes_generic_func();
150
151         set_transformer(op_Const,        gen_Const);
152         set_transformer(op_SymConst,     gen_SymConst);
153         set_transformer(op_Add,          gen_Add);
154 }
155
156
157 void amd64_transform_graph(amd64_code_gen_t *cg)
158 {
159         amd64_register_transformers();
160         env_cg = cg;
161         be_transform_graph(cg->irg, amd64_pretransform_node);
162 }
163
164 void amd64_init_transform(void)
165 {
166         FIRM_DBG_REGISTER(dbg, "firm.be.amd64.transform");
167 }