TEMPLATE_transform.c 8.77 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
35

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

38
#include "../benode.h"
39
#include "../betranshlp.h"
Christian Würdig's avatar
Christian Würdig committed
40
41
42
43
44
45
46
47
#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"

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

50
51
52
53
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)
54
{
55
56
57
58
59
60
61
62
63
	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
64
65
}

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

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

76
77
78
79
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
80

81
static ir_node *gen_Quot(ir_node *node)
82
{
83
	return transform_binop(node, new_bd_TEMPLATE_fDiv);
Christian Würdig's avatar
Christian Würdig committed
84
85
}

86
87
88
89
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
90

91
92
93
94
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
95

96
static ir_node *gen_Add(ir_node *node)
97
{
98
99
100
101
102
103
	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
104
105
}

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

110
111
112
113
114
	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
115

116
static ir_node *gen_Mul(ir_node *node)
117
{
118
119
120
121
	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
122
	}
123
	return transform_binop(node, new_bd_TEMPLATE_Mul);
Christian Würdig's avatar
Christian Würdig committed
124
125
126
}


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

129
static ir_node *transform_unop(ir_node *node, new_unop_func new_func)
130
{
131
132
133
134
135
136
137
	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
138
139
}

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

144
145
146
147
148
	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
149

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

155
156
157
158
159
160
161
static ir_node *gen_Const(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);
	tarval   *value     = get_Const_tarval(node);
	ir_node  *result;
Christian Würdig's avatar
Christian Würdig committed
162

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

165
166
	/* 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
167

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

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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
187

188
static ir_node *gen_Store(ir_node *node)
189
{
190
191
192
193
194
195
196
197
198
199
200
201
202
	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
203
	}
204
	return new_bd_TEMPLATE_Store(dbgi, new_block, new_ptr, new_mem, new_val, mode);
Christian Würdig's avatar
Christian Würdig committed
205
206
}

207
208
209
210
211
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
212

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

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

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
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
245

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

251
static ir_node *bad_transform(ir_node *node)
252
{
253
	panic("TEMPLATE backend: unexpected node %+F", node);
Christian Würdig's avatar
Christian Würdig committed
254
255
256
257
}



258
static void set_transformer(ir_op *op, be_transform_func transform_func)
259
{
260
	op->ops.generic = (op_func)transform_func;
Christian Würdig's avatar
Christian Würdig committed
261
262
}

263
static void TEMPLATE_register_transformers(void)
264
{
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
	/* first clear the generic function pointer for all ops */
	clear_irp_opcodes_generic_func();

	set_transformer(op_Add,       gen_Add);
	set_transformer(op_And,       gen_And);
	set_transformer(op_Const,     gen_Const);
	set_transformer(op_Eor,       gen_Eor);
	set_transformer(op_Jmp,       gen_Jmp);
	set_transformer(op_Load,      gen_Load);
	set_transformer(op_Minus,     gen_Minus);
	set_transformer(op_Mul,       gen_Mul);
	set_transformer(op_Not,       gen_Not);
	set_transformer(op_Or,        gen_Or);
	set_transformer(op_Phi,       gen_Phi);
	set_transformer(op_Quot,      gen_Quot);
	set_transformer(op_Shl,       gen_Shl);
	set_transformer(op_Shr,       gen_Shr);
	set_transformer(op_Store,     gen_Store);
	set_transformer(op_Sub,       gen_Sub);

	/* TODO: implement missing nodes */


	/* you should not see the following nodes */
	set_transformer(op_ASM,       bad_transform);
	set_transformer(op_Builtin,   bad_transform);
	set_transformer(op_CallBegin, bad_transform);
	set_transformer(op_Cast,      bad_transform);
	set_transformer(op_Confirm,   bad_transform);
	set_transformer(op_DivMod,    bad_transform);
	set_transformer(op_EndExcept, bad_transform);
	set_transformer(op_EndReg,    bad_transform);
	set_transformer(op_Filter,    bad_transform);
	set_transformer(op_Free,      bad_transform);
	set_transformer(op_Id,        bad_transform);
	set_transformer(op_InstOf,    bad_transform);
	set_transformer(op_Mulh,      bad_transform);
	set_transformer(op_Mux,       bad_transform);
	set_transformer(op_Raise,     bad_transform);
	set_transformer(op_Sel,       bad_transform);
	set_transformer(op_Tuple,     bad_transform);
306
}
Christian Würdig's avatar
Christian Würdig committed
307
308

/**
309
 * Transform generic IR-nodes into TEMPLATE machine instructions
Christian Würdig's avatar
Christian Würdig committed
310
 */
311
void TEMPLATE_transform_graph(TEMPLATE_code_gen_t *cg)
312
{
313
314
	TEMPLATE_register_transformers();
	be_transform_graph(cg->irg, NULL);
Christian Würdig's avatar
Christian Würdig committed
315
}
316
317
318
319
320

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