TEMPLATE_transform.c 7.75 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
/**
 * @file
 * @brief   code selection (transform FIRM into TEMPLATE FIRM)
 * @version $Id$
 */
25
#include "config.h"
Christian Würdig's avatar
Christian Würdig committed
26
27
28
29
30
31
32
33
34

#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "ircons.h"
#include "iropt_t.h"
#include "debug.h"
35
#include "error.h"
Christian Würdig's avatar
Christian Würdig committed
36

37
#include "../benode.h"
38
#include "../betranshlp.h"
Christian Würdig's avatar
Christian Würdig committed
39
40
41
42
43
44
45
46
#include "bearch_TEMPLATE_t.h"

#include "TEMPLATE_nodes_attr.h"
#include "TEMPLATE_transform.h"
#include "TEMPLATE_new_nodes.h"

#include "gen_TEMPLATE_regalloc_if.h"

47
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
Christian Würdig's avatar
Christian Würdig committed
48

49
50
51
52
typedef ir_node* (*new_binop_func)(dbg_info *dbgi, ir_node *block,
                                   ir_node *left, ir_node *right);

static ir_node *transform_binop(ir_node *node, new_binop_func new_func)
53
{
54
55
56
57
58
59
60
61
62
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_node  *left      = get_binop_left(node);
	ir_node  *new_left  = be_transform_node(left);
	ir_node  *right     = get_binop_right(node);
	ir_node  *new_right = be_transform_node(right);

	return new_func(dbgi, new_block, new_left, new_right);
Christian Würdig's avatar
Christian Würdig committed
63
64
}

65
static ir_node *gen_And(ir_node *node)
66
{
67
	return transform_binop(node, new_bd_TEMPLATE_And);
Christian Würdig's avatar
Christian Würdig committed
68
69
}

70
static ir_node *gen_Or(ir_node *node)
71
{
72
	return transform_binop(node, new_bd_TEMPLATE_Or);
Christian Würdig's avatar
Christian Würdig committed
73
74
}

75
76
77
78
static ir_node *gen_Eor(ir_node *node)
{
	return transform_binop(node, new_bd_TEMPLATE_Xor);
}
Christian Würdig's avatar
Christian Würdig committed
79

80
static ir_node *gen_Div(ir_node *node)
81
{
82
83
	ir_mode *mode = get_Div_resmode(node);
	assert(mode_is_float(mode));
84
	return transform_binop(node, new_bd_TEMPLATE_fDiv);
Christian Würdig's avatar
Christian Würdig committed
85
86
}

87
88
89
90
static ir_node *gen_Shl(ir_node *node)
{
	return transform_binop(node, new_bd_TEMPLATE_Shl);
}
Christian Würdig's avatar
Christian Würdig committed
91

92
93
94
95
static ir_node *gen_Shr(ir_node *node)
{
	return transform_binop(node, new_bd_TEMPLATE_Shr);
}
Christian Würdig's avatar
Christian Würdig committed
96

97
static ir_node *gen_Add(ir_node *node)
98
{
99
100
101
102
103
104
	ir_mode *mode = get_irn_mode(node);

	if (mode_is_float(mode)) {
		return transform_binop(node, new_bd_TEMPLATE_fAdd);
	}
	return transform_binop(node, new_bd_TEMPLATE_Add);
Christian Würdig's avatar
Christian Würdig committed
105
106
}

107
108
109
static ir_node *gen_Sub(ir_node *node)
{
	ir_mode *mode = get_irn_mode(node);
Christian Würdig's avatar
Christian Würdig committed
110

111
112
113
114
115
	if (mode_is_float(mode)) {
		return transform_binop(node, new_bd_TEMPLATE_fSub);
	}
	return transform_binop(node, new_bd_TEMPLATE_Sub);
}
Christian Würdig's avatar
Christian Würdig committed
116

117
static ir_node *gen_Mul(ir_node *node)
118
{
119
120
121
122
	ir_mode *mode = get_irn_mode(node);

	if (mode_is_float(mode)) {
		return transform_binop(node, new_bd_TEMPLATE_fMul);
Christian Würdig's avatar
Christian Würdig committed
123
	}
124
	return transform_binop(node, new_bd_TEMPLATE_Mul);
Christian Würdig's avatar
Christian Würdig committed
125
126
127
}


128
typedef ir_node* (*new_unop_func)(dbg_info *dbgi, ir_node *block, ir_node *op);
Christian Würdig's avatar
Christian Würdig committed
129

130
static ir_node *transform_unop(ir_node *node, new_unop_func new_func)
131
{
132
133
134
135
136
137
138
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_node  *op        = get_unop_op(node);
	ir_node  *new_op    = be_transform_node(op);

	return new_func(dbgi, new_block, new_op);
Christian Würdig's avatar
Christian Würdig committed
139
140
}

141
142
143
static ir_node *gen_Minus(ir_node *node)
{
	ir_mode *mode = get_irn_mode(node);
Christian Würdig's avatar
Christian Würdig committed
144

145
146
147
148
149
	if (mode_is_float(mode)) {
		return transform_unop(node, new_bd_TEMPLATE_fMinus);
	}
	return transform_unop(node, new_bd_TEMPLATE_Minus);
}
Christian Würdig's avatar
Christian Würdig committed
150

151
static ir_node *gen_Not(ir_node *node)
152
{
153
	return transform_unop(node, new_bd_TEMPLATE_Not);
Christian Würdig's avatar
Christian Würdig committed
154
155
}

156
157
static ir_node *gen_Const(ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
158
159
160
161
162
	ir_node   *block     = get_nodes_block(node);
	ir_node   *new_block = be_transform_node(block);
	dbg_info  *dbgi      = get_irn_dbg_info(node);
	ir_tarval *value     = get_Const_tarval(node);
	ir_node   *result;
Christian Würdig's avatar
Christian Würdig committed
163

164
	result = new_bd_TEMPLATE_Const(dbgi, new_block, value);
Christian Würdig's avatar
Christian Würdig committed
165

166
167
	/* make sure the node does not float above the barrier into the prologue */
	be_dep_on_frame(result);
Christian Würdig's avatar
Christian Würdig committed
168

169
170
	return result;
}
Christian Würdig's avatar
Christian Würdig committed
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
static ir_node *gen_Load(ir_node *node)
{
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_node  *ptr       = get_Load_ptr(node);
	ir_node  *new_ptr   = be_transform_node(ptr);
	ir_node  *mem       = get_Load_mem(node);
	ir_node  *new_mem   = be_transform_node(mem);
	ir_mode  *mode      = get_irn_mode(node);

	if (mode_is_float(mode)) {
		return new_bd_TEMPLATE_fLoad(dbgi, new_block, new_ptr, new_mem, mode);
	}
	return new_bd_TEMPLATE_Load(dbgi, new_block, new_ptr, new_mem, mode);
}
Christian Würdig's avatar
Christian Würdig committed
188

189
static ir_node *gen_Store(ir_node *node)
190
{
191
192
193
194
195
196
197
198
199
200
201
202
203
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_node  *ptr       = get_Store_ptr(node);
	ir_node  *new_ptr   = be_transform_node(ptr);
	ir_node  *val       = get_Store_value(node);
	ir_node  *new_val   = be_transform_node(val);
	ir_node  *mem       = get_Store_mem(node);
	ir_node  *new_mem   = be_transform_node(mem);
	ir_mode  *mode      = get_irn_mode(node);

	if (mode_is_float(mode)) {
		return new_bd_TEMPLATE_fStore(dbgi, new_block, new_ptr, new_val, new_mem, mode);
Christian Würdig's avatar
Christian Würdig committed
204
	}
205
	return new_bd_TEMPLATE_Store(dbgi, new_block, new_ptr, new_mem, new_val, mode);
Christian Würdig's avatar
Christian Würdig committed
206
207
}

208
209
210
211
212
static ir_node *gen_Jmp(ir_node *node)
{
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
Christian Würdig's avatar
Christian Würdig committed
213

214
215
	return new_bd_TEMPLATE_Jmp(dbgi, new_block);
}
Christian Würdig's avatar
Christian Würdig committed
216
217

/**
218
 * returns true if mode should be stored in a general purpose register
Christian Würdig's avatar
Christian Würdig committed
219
 */
220
static inline bool mode_needs_gp_reg(ir_mode *mode)
221
{
222
	return mode_is_int(mode) || mode_is_reference(mode);
Christian Würdig's avatar
Christian Würdig committed
223
224
}

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
static ir_node *gen_Phi(ir_node *node)
{
	const arch_register_req_t *req;
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_mode  *mode      = get_irn_mode(node);
	ir_graph *irg       = get_irn_irg(node);
	ir_node  *phi;

	if (mode_needs_gp_reg(mode)) {
		mode = mode_Iu;
		req  = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].class_req;
	} else {
		req = arch_no_register_req;
	}

	phi = new_ir_node(dbgi, irg, new_block, op_Phi, mode, get_irn_arity(node),
	                  get_irn_in(node)+1);
	copy_node_attr(irg, node, phi);
	be_duplicate_deps(node, phi);
Christian Würdig's avatar
Christian Würdig committed
246

247
248
249
250
	arch_set_out_register_req(phi, 0, req);
	be_enqueue_preds(node);
	return phi;
}
Christian Würdig's avatar
Christian Würdig committed
251

252
static void TEMPLATE_register_transformers(void)
253
{
254
255
256
257
258
	be_start_transform_setup();

	be_set_transform_function(op_Add,   gen_Add);
	be_set_transform_function(op_And,   gen_And);
	be_set_transform_function(op_Const, gen_Const);
259
	be_set_transform_function(op_Div,   gen_Div);
260
261
262
263
264
265
266
267
268
269
270
271
	be_set_transform_function(op_Eor,   gen_Eor);
	be_set_transform_function(op_Jmp,   gen_Jmp);
	be_set_transform_function(op_Load,  gen_Load);
	be_set_transform_function(op_Minus, gen_Minus);
	be_set_transform_function(op_Mul,   gen_Mul);
	be_set_transform_function(op_Not,   gen_Not);
	be_set_transform_function(op_Or,    gen_Or);
	be_set_transform_function(op_Phi,   gen_Phi);
	be_set_transform_function(op_Shl,   gen_Shl);
	be_set_transform_function(op_Shr,   gen_Shr);
	be_set_transform_function(op_Store, gen_Store);
	be_set_transform_function(op_Sub,   gen_Sub);
272
}
Christian Würdig's avatar
Christian Würdig committed
273
274

/**
275
 * Transform generic IR-nodes into TEMPLATE machine instructions
Christian Würdig's avatar
Christian Würdig committed
276
 */
277
void TEMPLATE_transform_graph(ir_graph *irg)
278
{
279
	TEMPLATE_register_transformers();
280
	be_transform_graph(irg, NULL);
Christian Würdig's avatar
Christian Würdig committed
281
}
282
283
284
285
286

void TEMPLATE_init_transform(void)
{
	FIRM_DBG_REGISTER(dbg, "firm.be.TEMPLATE.transform");
}