arm_transform.c 45.5 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * 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.
 */

20
21
/**
 * @file
Michael Beck's avatar
Michael Beck committed
22
23
 * @brief   The codegenerator (transform FIRM into arm FIRM)
 * @author  Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
34
35
36
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "irvrfy.h"
#include "ircons.h"
Michael Beck's avatar
Michael Beck committed
37
#include "irprintf.h"
38
39
40
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
41
#include "error.h"
42
43

#include "../benode_t.h"
Michael Beck's avatar
Michael Beck committed
44
#include "../beirg_t.h"
45
#include "../betranshlp.h"
46
47
48
#include "bearch_arm_t.h"

#include "arm_nodes_attr.h"
49
#include "archop.h"
50
51
52
53
54
55
56
57
#include "arm_transform.h"
#include "arm_new_nodes.h"
#include "arm_map_regs.h"

#include "gen_arm_regalloc_if.h"

#include <limits.h>

Michael Beck's avatar
Michael Beck committed
58

59
60
/** hold the current code generator during transformation */
static arm_code_gen_t *env_cg;
61

62
extern ir_op *get_op_Mulh(void);
63
64
65
66
67
68
69
70
71
72
73
74


/****************************************************************************************************
 *                  _        _                        __                           _   _
 *                 | |      | |                      / _|                         | | (_)
 *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
 * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
 * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
 *
 ****************************************************************************************************/

75
76
77
78
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
	return mode_is_int(mode) || mode_is_character(mode) || mode_is_reference(mode);
}

79
typedef struct vals_ {
Michael Beck's avatar
Michael Beck committed
80
81
82
	int ops;
	unsigned char values[4];
	unsigned char shifts[4];
83
84
} vals;

85
86
87
88
89
90
/** Execute ROL. */
static unsigned do_rol(unsigned v, unsigned rol) {
	return (v << rol) | (v >> (32 - rol));
}

/**
91
 * construct 8bit values and rot amounts for a value
92
 */
Michael Beck's avatar
Michael Beck committed
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
static void gen_vals_from_word(unsigned int value, vals *result)
{
	int initial = 0;

	memset(result, 0, sizeof(*result));

	/* special case: we prefer shift amount 0 */
	if (value < 0x100) {
		result->values[0] = value;
		result->ops       = 1;
		return;
	}

	while (value != 0) {
		if (value & 0xFF) {
			unsigned v = do_rol(value, 8) & 0xFFFFFF;
			int shf = 0;
			for (;;) {
				if ((v & 3) != 0)
					break;
				shf += 2;
				v >>= 2;
			}
			v  &= 0xFF;
			shf = (initial + shf - 8) & 0x1F;
			result->values[result->ops] = v;
			result->shifts[result->ops] = shf;
			++result->ops;

			value ^= do_rol(v, shf) >> initial;
		}
		else {
			value >>= 8;
			initial += 8;
		}
	}
129
130
}

Michael Beck's avatar
Michael Beck committed
131
132
133
/**
 * Creates a arm_Const node.
 */
Michael Beck's avatar
Michael Beck committed
134
135
136
static ir_node *create_const_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) {
	ir_mode *mode  = mode_Iu;
	tarval   *tv   = new_tarval_from_long(value, mode);
137
138
139
140
141
	ir_node *res;

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
	res = new_rd_arm_Mov_i(dbg, current_ir_graph, block, mode, tv);
Michael Beck's avatar
Michael Beck committed
142
143
144
	/* ensure the const is schedules AFTER the barrier */
	add_irn_dep(res, be_abi_get_start_barrier(abi));
	return res;
145
146
}

Michael Beck's avatar
Michael Beck committed
147
148
149
/**
 * Creates a arm_Const_Neg node.
 */
Michael Beck's avatar
Michael Beck committed
150
151
152
static ir_node *create_const_neg_node(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, long value) {
	ir_mode *mode = mode_Iu;
	tarval  *tv   = new_tarval_from_long(value, mode);
153
154
155
156
157
	ir_node *res;

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
	res = new_rd_arm_Mvn_i(dbg, current_ir_graph, block, mode, tv);
Michael Beck's avatar
Michael Beck committed
158
159
160
	add_irn_dep(res, be_abi_get_start_barrier(abi));
	/* ensure the const is schedules AFTER the barrier */
	return res;
161
162
}

163
#define NEW_BINOP_NODE(opname, env, op1, op2) new_rd_arm_##opname(env->dbg, current_ir_graph, env->block, op1, op2, env->mode)
164

Michael Beck's avatar
Michael Beck committed
165
166
167
168
/**
 * Encodes an immediate with shifter operand
 */
static unsigned int arm_encode_imm_w_shift(unsigned int shift, unsigned int immediate) {
169
170
171
	return immediate | ((shift>>1)<<8);
}

Michael Beck's avatar
Michael Beck committed
172
173
174
175
176
177
178
179
180
181
182
183
184
/**
 * Decode an immediate with shifter operand
 */
unsigned int arm_decode_imm_w_shift(tarval *tv) {
	unsigned l = get_tarval_long(tv);
	unsigned rol = (l & ~0xFF) >> 7;

	return do_rol(l & 0xFF, rol);
}

/**
 * Creates a possible DAG for an constant.
 */
Michael Beck's avatar
Michael Beck committed
185
static ir_node *create_const_graph_value(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, unsigned int value) {
186
	ir_node *result;
Michael Beck's avatar
Michael Beck committed
187
188
	vals v, vn;
	int cnt;
Michael Beck's avatar
Michael Beck committed
189
	ir_mode *mode = mode_Iu;
190

Michael Beck's avatar
Michael Beck committed
191
192
193
194
195
	gen_vals_from_word(value, &v);
	gen_vals_from_word(~value, &vn);

	if (vn.ops < v.ops) {
		/* remove bits */
Michael Beck's avatar
Michael Beck committed
196
		result = create_const_neg_node(abi, dbg, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
Michael Beck's avatar
Michael Beck committed
197
198

		for (cnt = 1; cnt < vn.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
199
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode);
200
			ir_node *bic_i_node = new_rd_arm_Bic_i(dbg, current_ir_graph, block, result, mode, tv);
Michael Beck's avatar
Michael Beck committed
201
			result = bic_i_node;
202
203
		}
	}
Michael Beck's avatar
Michael Beck committed
204
205
	else {
		/* add bits */
Michael Beck's avatar
Michael Beck committed
206
		result = create_const_node(abi, dbg, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
Michael Beck's avatar
Michael Beck committed
207
208

		for (cnt = 1; cnt < v.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
209
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode);
210
			ir_node *orr_i_node = new_rd_arm_Or_i(dbg, current_ir_graph, block, result, mode, tv);
Michael Beck's avatar
Michael Beck committed
211
212
			result = orr_i_node;
		}
213
214
215
216
	}
	return result;
}

217
218
219
220
221
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
Michael Beck's avatar
Michael Beck committed
222
static ir_node *create_const_graph(be_abi_irg_t *abi, ir_node *irn, ir_node *block) {
223
224
225
226
227
228
229
230
231
232
	tarval  *tv = get_Const_tarval(irn);
	ir_mode *mode = get_tarval_mode(tv);
	int     value;

	if (mode_is_reference(mode)) {
		/* ARM is 32bit, so we can safely convert a reference tarval into Iu */
		assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
		tv = tarval_convert_to(tv, mode_Iu);
	}
	value = get_tarval_long(tv);
Michael Beck's avatar
Michael Beck committed
233
	return create_const_graph_value(abi, get_irn_dbg_info(irn), block, value);
234
235
}

Michael Beck's avatar
Michael Beck committed
236
237
238
239
/**
 * Create an And that will mask all upper bits
 */
static ir_node *gen_zero_extension(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
240
	unsigned mask_bits = (1 << result_bits) - 1;
Michael Beck's avatar
Michael Beck committed
241
242
	ir_node *mask_node = create_const_graph_value(abi, dbg, block, mask_bits);
	return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, mode_Iu, ARM_SHF_NONE, NULL);
243
244
}

Michael Beck's avatar
Michael Beck committed
245
246
247
248
249
/**
 * Generate code for a sign extension.
 */
static ir_node *gen_sign_extension(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
	ir_graph *irg   = current_ir_graph;
250
	int shift_width = 32 - result_bits;
Michael Beck's avatar
Michael Beck committed
251
252
253
	ir_node *shift_const_node = create_const_graph_value(abi, dbg, block, shift_width);
	ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, mode_Iu);
	ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, mode_Iu);
254
255
256
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
257
258
259
/**
 * Transforms a Conv node.
 *
260
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
261
 */
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
static ir_node *gen_Conv(ir_node *node) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *op       = get_Conv_op(node);
	ir_node  *new_op   = be_transform_node(op);
	ir_graph *irg      = current_ir_graph;
	ir_mode  *src_mode = get_irn_mode(op);
	ir_mode  *dst_mode = get_irn_mode(node);
	dbg_info *dbg      = get_irn_dbg_info(node);

	if (src_mode == dst_mode)
		return new_op;

	if (mode_is_float(src_mode) || mode_is_float(dst_mode)) {
		env_cg->have_fp_insn = 1;

		if (USE_FPA(env_cg->isa)) {
			if (mode_is_float(src_mode)) {
				if (mode_is_float(dst_mode)) {
Michael Beck's avatar
Michael Beck committed
280
					/* from float to float */
281
					return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
282
283
284
				}
				else {
					/* from float to int */
285
					return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
286
287
288
289
				}
			}
			else {
				/* from int to float */
290
				return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
291
292
			}
		}
Michael Beck's avatar
Michael Beck committed
293
		else if (USE_VFP(env_cg->isa)) {
294
295
296
			panic("VFP not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
297
298
299
300
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
301
302
	}
	else { /* complete in gp registers */
303
304
		int src_bits = get_mode_size_bits(src_mode);
		int dst_bits = get_mode_size_bits(dst_mode);
Michael Beck's avatar
Michael Beck committed
305
306
		int min_bits;
		ir_mode *min_mode;
307

Michael Beck's avatar
Michael Beck committed
308
309
310
		if (is_Load(skip_Proj(op))) {
			if (src_bits == dst_bits) {
				/* kill unneccessary conv */
311
				return new_op;
312
			}
Michael Beck's avatar
Michael Beck committed
313
314
			/* after a load, the bit size is already converted */
			src_bits = 32;
315
		}
Michael Beck's avatar
Michael Beck committed
316
317
318
319
320
321
322
323

		if (src_bits == dst_bits) {
			/* kill unneccessary conv */
			return new_op;
		} else if (dst_bits <= 32 && src_bits <= 32) {
			if (src_bits < dst_bits) {
				min_bits = src_bits;
				min_mode = src_mode;
324
			} else {
Michael Beck's avatar
Michael Beck committed
325
326
				min_bits = dst_bits;
				min_mode = dst_mode;
327
			}
Michael Beck's avatar
Michael Beck committed
328
329
			if (mode_is_signed(min_mode)) {
				return gen_sign_extension(env_cg->birg->abi, dbg, block, new_op, min_bits);
330
			} else {
Michael Beck's avatar
Michael Beck committed
331
				return gen_zero_extension(env_cg->birg->abi, dbg, block, new_op, min_bits);
332
			}
Michael Beck's avatar
Michael Beck committed
333
334
335
336
		} else {
			panic("Cannot handle Conv %+F->%+F with %d->%d bits\n", src_mode, dst_mode,
				src_bits, dst_bits);
			return NULL;
337
338
339
340
		}
	}
}

Michael Beck's avatar
Michael Beck committed
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
/**
 * Return true if an operand is a shifter operand
 */
static int is_shifter_operand(ir_node *n, arm_shift_modifier *pmod) {
	arm_shift_modifier mod = ARM_SHF_NONE;

	if (is_arm_Mov(n))
		mod = get_arm_shift_modifier(n);

	*pmod = mod;
	if (mod != ARM_SHF_NONE) {
		long v = get_tarval_long(get_arm_value(n));
		if (v < 32)
			return (int)v;
	}
	return 0;
}
358
359

/**
360
 * Creates an ARM Add.
361
362
363
 *
 * @return the created arm Add node
 */
364
365
366
367
368
369
370
371
372
static ir_node *gen_Add(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Add_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Add_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	ir_graph *irg     = current_ir_graph;
	ir_node  *new_op3;
Michael Beck's avatar
Michael Beck committed
373
374
	int v;
	arm_shift_modifier mod;
375
	dbg_info *dbg = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
376

377
	if (mode_is_float(mode)) {
378
379
380
381
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaAdd(dbg, irg, block, new_op1, new_op2, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
382
			assert(mode != mode_E && "IEEE Extended FP not supported");
383
384
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
385
		}
386
387
388
389
390
391
392
393
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
	} else {
		assert(mode_is_numP(mode));

		if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
394
			return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
395
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
396
			return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
397
398

		/* check for MLA */
399
400
401
402
		if (is_arm_Mul(new_op1) && get_irn_n_edges(new_op1) == 1) {
			new_op3 = new_op2;
			op2 = get_irn_n(new_op1, 1);
			op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
403

404
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
405
		}
406
407
408
409
		if (is_arm_Mul(new_op2) && get_irn_n_edges(new_op2) == 1) {
			new_op3 = new_op1;
			new_op1 = get_irn_n(new_op2, 0);
			new_op2 = get_irn_n(new_op2, 1);
Michael Beck's avatar
Michael Beck committed
410

411
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
412
		}
413

Michael Beck's avatar
Michael Beck committed
414
		/* is the first a shifter */
415
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
416
		if (v) {
417
418
			new_op1 = get_irn_n(new_op1, 0);
			return new_rd_arm_Add(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu));
Michael Beck's avatar
Michael Beck committed
419
420
		}
		/* is the second a shifter */
421
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
422
		if (v) {
423
424
			new_op2 = get_irn_n(new_op2, 0);
			return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu));
Michael Beck's avatar
Michael Beck committed
425
		}
426

Michael Beck's avatar
Michael Beck committed
427
		/* normal ADD */
428
		return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
Michael Beck's avatar
Michael Beck committed
429
430
	}
}
431
432

/**
433
 * Creates an ARM Mul.
434
435
436
 *
 * @return the created arm Mul node
 */
437
438
439
440
441
442
443
444
445
static ir_node *gen_Mul(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Mul_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Mul_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	ir_graph *irg     = current_ir_graph;
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
446

447
	if (mode_is_float(mode)) {
448
449
450
451
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaMul(dbg, irg, block, new_op1, new_op2, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
452
			assert(mode != mode_E && "IEEE Extended FP not supported");
453
454
455
456
457
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
458
		}
459
	}
460
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
461
462
463
}

/**
464
 * Creates an ARM floating point Div.
465
 *
Michael Beck's avatar
Michael Beck committed
466
 * @param env   The transformation environment
467
468
 * @return the created arm fDiv node
 */
469
470
471
472
473
474
475
476
static ir_node *gen_Quot(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Quot_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Quot_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
477

478
	assert(mode != mode_E && "IEEE Extended FP not supported");
479

480
481
	env_cg->have_fp_insn = 1;
	if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
482
		return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, new_op1, new_op2, mode);
483
	else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
484
		assert(mode != mode_E && "IEEE Extended FP not supported");
485
486
487
488
489
		panic("VFP not supported yet\n");
	}
	else {
		panic("Softfloat not supported yet\n");
		return NULL;
Michael Beck's avatar
Michael Beck committed
490
	}
Michael Beck's avatar
Michael Beck committed
491
492
493
}

#define GEN_INT_OP(op) \
494
495
496
497
498
499
500
501
502
	ir_node  *block   = be_transform_node(get_nodes_block(node)); \
	ir_node  *op1     = get_ ## op ## _left(node); \
	ir_node  *new_op1 = be_transform_node(op1); \
	ir_node  *op2     = get_ ## op ## _right(node); \
	ir_node  *new_op2 = be_transform_node(op2); \
	ir_graph *irg     = current_ir_graph; \
	ir_mode  *mode    = get_irn_mode(node); \
	dbg_info *dbg     = get_irn_dbg_info(node); \
	int      v; \
Michael Beck's avatar
Michael Beck committed
503
504
	arm_shift_modifier mod; \
 \
505
506
507
508
	if (is_arm_Mov_i(new_op1)) \
		return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1)); \
	if (is_arm_Mov_i(new_op2)) \
		return new_rd_arm_ ## op ## _i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2)); \
Michael Beck's avatar
Michael Beck committed
509
	/* is the first a shifter */ \
510
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
511
	if (v) { \
512
513
		new_op1 = get_irn_n(new_op1, 0); \
		return new_rd_arm_ ## op(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu)); \
Michael Beck's avatar
Michael Beck committed
514
515
	} \
	/* is the second a shifter */ \
516
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
517
	if (v) { \
518
519
		new_op2 = get_irn_n(new_op2, 0); \
		return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu)); \
Michael Beck's avatar
Michael Beck committed
520
521
	} \
	/* Normal op */ \
522
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
523
524

/**
525
 * Creates an ARM And.
526
527
528
 *
 * @return the created arm And node
 */
529
530
531
static ir_node *gen_And(ir_node *node) {
	GEN_INT_OP(And);
}
532
533

/**
534
 * Creates an ARM Orr.
535
 *
Michael Beck's avatar
Michael Beck committed
536
 * @param env   The transformation environment
537
538
 * @return the created arm Or node
 */
539
540
541
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
542
543

/**
544
 * Creates an ARM Eor.
545
546
547
 *
 * @return the created arm Eor node
 */
548
549
550
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
551
552

/**
553
 * Creates an ARM Sub.
554
555
556
 *
 * @return the created arm Sub node
 */
557
558
559
560
561
static ir_node *gen_Sub(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Sub_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Sub_right(node);
Michael Beck's avatar
Michael Beck committed
562
	ir_node  *new_op2 = be_transform_node(op2);
563
564
565
566
	ir_mode  *mode    = get_irn_mode(node);
	ir_graph *irg     = current_ir_graph;
	dbg_info *dbg     = get_irn_dbg_info(node);
	int      v;
Michael Beck's avatar
Michael Beck committed
567
568
	arm_shift_modifier mod;

569
	if (mode_is_float(mode)) {
570
571
572
573
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaSub(dbg, irg, block, new_op1, new_op2, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
574
			assert(mode != mode_E && "IEEE Extended FP not supported");
575
576
577
578
579
580
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
581
		}
Michael Beck's avatar
Michael Beck committed
582
	}
583
584
585
586
587
588
589
	else {
		assert(mode_is_numP(mode) && "unknown mode for Sub");

		if (is_arm_Mov_i(new_op1))
			return new_rd_arm_Rsb_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
		if (is_arm_Mov_i(new_op2))
			return new_rd_arm_Sub_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
590
591

		/* is the first a shifter */
592
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
593
		if (v) {
594
595
			new_op1 = get_irn_n(new_op1, 0);
			return new_rd_arm_Rsb(dbg, irg, block, new_op2, new_op1, mode, mod, new_tarval_from_long(v, mode_Iu));
596
		}
Michael Beck's avatar
Michael Beck committed
597
		/* is the second a shifter */
598
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
599
		if (v) {
600
601
			new_op2 = get_irn_n(new_op2, 0);
			return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, mod, new_tarval_from_long(v, mode_Iu));
Michael Beck's avatar
Michael Beck committed
602
603
		}
		/* normal sub */
604
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
605
606
607
608
	}
}

/**
609
 * Creates an ARM Shl.
610
 *
611
 * @return the created ARM Shl node
612
 */
613
614
615
616
617
618
619
620
621
622
623
static ir_node *gen_Shl(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shl_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shl_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSL, get_arm_value(new_op2));
624
	}
625
	return new_rd_arm_Shl(dbg, current_ir_graph, block, new_op1, new_op2, mode);
626
627
628
}

/**
629
 * Creates an ARM Shr.
630
 *
631
 * @return the created ARM Shr node
632
 */
633
634
635
636
637
638
639
640
641
642
643
static ir_node *gen_Shr(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shr_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shr_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_LSR, get_arm_value(new_op2));
644
	}
645
	return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
646
647
648
}

/**
649
 * Creates an ARM Shrs.
650
 *
651
 * @return the created ARM Shrs node
652
 */
653
654
655
656
657
658
659
660
661
662
663
static ir_node *gen_Shrs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_Shrs_left(node);
	ir_node  *new_op1 = be_transform_node(op1);
	ir_node  *op2     = get_Shrs_right(node);
	ir_node  *new_op2 = be_transform_node(op2);
	ir_mode  *mode    = get_irn_mode(node);
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ASR, get_arm_value(op2));
664
	}
665
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
666
667
668
669
670
}

/**
 * Transforms a Not node.
 *
671
 * @return the created ARM Not node
672
 */
673
674
675
676
677
678
static ir_node *gen_Not(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op      = get_Not_op(node);
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	tarval   *tv      = NULL;
Michael Beck's avatar
Michael Beck committed
679
	arm_shift_modifier mod = ARM_SHF_NONE;
680
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
681
682

	if (v) {
683
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
684
685
		tv = new_tarval_from_long(v, mode_Iu);
	}
686
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, get_irn_mode(node), mod, tv);
687
688
}

Michael Beck's avatar
Michael Beck committed
689
690
691
692
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
693
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
694
 */
695
696
697
698
699
700
static ir_node *gen_Abs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op      = get_Not_op(node);
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
701

702
	if (mode_is_float(mode)) {
703
704
705
706
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaAbs(dbg, current_ir_graph, block, new_op, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
707
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
708
709
710
711
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
712
		}
713
	}
714
	return new_rd_arm_Abs(dbg, current_ir_graph, block, new_op, mode);
715
716
717
718
719
}

/**
 * Transforms a Minus node.
 *
720
 * @return the created ARM Minus node
721
 */
722
723
724
725
726
727
static ir_node *gen_Minus(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op      = get_Minus_op(node);
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
728

729
	if (mode_is_float(mode)) {
730
731
732
733
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaMnv(dbg, current_ir_graph, block, op, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
734
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
735
736
737
738
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
739
		}
740
	}
741
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
742
743
744
745
746
}

/**
 * Transforms a Load.
 *
747
 * @return the created ARM Load node
748
 */
749
static ir_node *gen_Load(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
750
751
752
753
754
755
756
757
758
	ir_node  *block    = be_transform_node(get_nodes_block(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_Load_mode(node);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_node  *new_load = NULL;
759

Michael Beck's avatar
Michael Beck committed
760
	if (mode_is_float(mode)) {
761
762
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
763
			new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
764
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
765
			assert(mode != mode_E && "IEEE Extended FP not supported");
766
767
768
769
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
770
		}
771
	}
772
773
774
775
776
777
778
	else {
		assert(mode_is_numP(mode) && "unsupported mode for Load");

		if (mode_is_signed(mode)) {
			/* sign extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
779
				new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
780
				break;
781
			case 16:
Michael Beck's avatar
Michael Beck committed
782
				new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
783
				break;
784
			case 32:
Michael Beck's avatar
Michael Beck committed
785
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
786
787
				break;
			default:
Michael Beck's avatar
Michael Beck committed
788
				panic("mode size not supported\n");
789
790
791
792
793
			}
		} else {
			/* zero extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
794
				new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
795
				break;
796
			case 16:
Michael Beck's avatar
Michael Beck committed
797
				new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
798
				break;
799
			case 32:
Michael Beck's avatar
Michael Beck committed
800
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
801
802
				break;
			default:
Michael Beck's avatar
Michael Beck committed
803
				panic("mode size not supported\n");
804
805
			}
		}
806
	}
Michael Beck's avatar
Michael Beck committed
807
808
	set_irn_pinned(new_load, get_irn_pinned(node));
	return new_load;
809
810
811
812
813
}

/**
 * Transforms a Store.
 *
814
 * @return the created ARM Store node
815
 */
816
static ir_node *gen_Store(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
817
818
819
820
821
822
823
824
825
826
827
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *ptr      = get_Store_ptr(node);
	ir_node  *new_ptr  = be_transform_node(ptr);
	ir_node  *mem      = get_Store_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_node  *val      = get_Store_value(node);
	ir_node  *new_val  = be_transform_node(val);
	ir_mode  *mode     = get_irn_mode(val);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_node *new_store = NULL;
828

Michael Beck's avatar
Michael Beck committed
829
	if (mode_is_float(mode)) {
830
831
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
832
			new_store = new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
833
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
834
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
835
836
837
838
839
840
841
842
843
844
845
846
847
			panic("VFP not supported yet\n");
		} else {
			panic("Softfloat not supported yet\n");
		}
	} else {
		assert(mode_is_numP(mode) && "unsupported mode for Store");
		switch (get_mode_size_bits(mode)) {
		case 8:
			new_store = new_rd_arm_Storeb(dbg, irg, block, new_ptr, new_val, new_mem);
		case 16:
			new_store = new_rd_arm_Storeh(dbg, irg, block, new_ptr, new_val, new_mem);
		default:
			new_store = new_rd_arm_Store(dbg, irg, block, new_ptr, new_val, new_mem);
Michael Beck's avatar
Michael Beck committed
848
		}
849
	}
Michael Beck's avatar
Michael Beck committed
850
851
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
852
853
}

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
/**
 * Transforms a Cond.
 *
 * @return the created ARM Cond node
 */
static ir_node *gen_Cond(ir_node *node) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	ir_mode  *mode     = get_irn_mode(selector);

	if (mode == mode_b) {
		/* CondJmp */
		ir_node *cmp_node = get_Proj_pred(selector);
		ir_node *op1      = get_Cmp_left(cmp_node);
		ir_node *new_op1  = be_transform_node(op1);
		ir_node *op2      = get_Cmp_right(cmp_node);
		ir_node *new_op2  = be_transform_node(op2);

		return new_rd_arm_CondJmp(dbg, irg, block, new_op1, new_op2, get_Proj_proj(selector));
875
	} else {
876
877
		/* SwitchJmp */
		ir_node *new_op = be_transform_node(selector);
878
879
880
881
882
883
884
885
886
887
888
		ir_node *const_graph;
		ir_node *sub;

		ir_node *proj;
		const ir_edge_t *edge;
		int min = INT_MAX;
		int max = INT_MIN;
		int translation;
		int pn;
		int n_projs;

889
		foreach_out_edge(node, edge) {
890
891
892
893
894
895
896
897
898
			proj = get_edge_src_irn(edge);
			assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");

			pn = get_Proj_proj(proj);

			min = pn<min ? pn : min;
			max = pn>max ? pn : max;
		}
		translation = min;
899
		n_projs = max - translation + 1;
900

901
		foreach_out_edge(node, edge) {
902
903
904
905
906
907
908
909
			proj = get_edge_src_irn(edge);
			assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");

			pn = get_Proj_proj(proj) - translation;
			set_Proj_proj(proj, pn);
		}


Michael Beck's avatar
Michael Beck committed
910
		const_graph = create_const_graph_value(env_cg->birg->abi, dbg, block, translation);
911
912
		sub = new_rd_arm_Sub(dbg, irg, block, new_op, const_graph, mode, ARM_SHF_NONE, NULL);
		return new_rd_arm_SwitchJmp(dbg, irg, block, sub, n_projs, get_Cond_defaultProj(node) - translation);
913
914
915
916
917
918
919
920
	}
}

/**
 * Returns the name of a SymConst.
 * @param symc  the SymConst
 * @return name of the SymConst
 */
Michael Beck's avatar
Michael Beck committed
921
static ident *get_sc_ident(ir_node *symc) {
Michael Beck's avatar
Michael Beck committed
922
	ir_entity *ent;
923
924
925

	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
Michael Beck's avatar
Michael Beck committed
926
			return get_SymConst_name(symc);
927
928

		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
929
930
			ent = get_SymConst_entity(symc);
			mark_entity_visited(ent);
Michael Beck's avatar
Michael Beck committed
931
			return get_entity_ld_ident(ent);
932
933
934
935
936
937
938
939

		default:
			assert(0 && "Unsupported SymConst");
	}

	return NULL;
}

Michael Beck's avatar
Michael Beck committed
940
/**
941
942
943
 * Transforms a Const node.
 *
 * @return The transformed ARM node.
Michael Beck's avatar
Michael Beck committed
944
 */
945
946
static ir_node *gen_Const(ir_node *node) {
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
947
948
949
	ir_graph *irg = current_ir_graph;
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
950

Michael Beck's avatar
Michael Beck committed
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
	if (mode_is_float(mode)) {
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa)) {
			node = new_rd_arm_fpaConst(dbg, irg, block, get_Const_tarval(node));
			/* ensure the const is schedules AFTER the barrier */
			add_irn_dep(node, be_abi_get_start_barrier(env_cg->birg->abi));
			return node;
		}
		else if (USE_VFP(env_cg->isa)) {
			assert(mode != mode_E && "IEEE Extended FP not supported");
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
		}
	}
967
968
	return create_const_graph(env_cg->birg->abi, node, block);
}
969
970

/**
971
 * Transforms a SymConst node.
972
 *
973
 * @return The transformed ARM node.
974
 */
975
976
977
978
979
980
981
982
983
static ir_node *gen_SymConst(ir_node *node) {
	ir_node  *block = be_transform_node(get_nodes_block(node));
	ir_mode  *mode  = get_irn_mode(node);
	dbg_info *dbg   = get_irn_dbg_info(node);
	ir_node  *res;

	res = new_rd_arm_SymConst(dbg, current_ir_graph, block, mode, get_sc_ident(node));
	add_irn_dep(res, be_abi_get_start_barrier(env_cg->birg->abi));
	/* ensure the const is schedules AFTER the barrier */
984
985
986
	return res;
}

987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
/**
 * Transforms a CopyB node.
 *
 * @return The transformed ARM node.
 */
static ir_node *gen_CopyB(ir_node *node) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *src      = get_CopyB_src(node);
	ir_node  *new_src  = be_transform_node(src);
	ir_node  *dst      = get_CopyB_dst(node);
	ir_node  *new_dst  = be_transform_node(dst);
	ir_node  *mem      = get_CopyB_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	ir_graph *irg      = current_ir_graph;
	dbg_info *dbg      = get_irn_dbg_info(node);
	int      size      = get_type_size_bytes(get_CopyB_type(node));
	ir_node  *src_copy;
	ir_node  *dst_copy;

	src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], irg, block, new_src);
	dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], irg, block, new_dst);

 	return new_rd_arm_CopyB(dbg, irg, block, dst_copy, src_copy,
			new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
			new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
			new_rd_arm_EmptyReg(dbg, irg, block, mode_Iu),
Michael Beck's avatar
Michael Beck committed
1013
			new_mem, new_tarval_from_long(size, mode_Iu));
1014
}
1015
1016


Michael Beck's avatar
Michael Beck committed
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
/********************************************
 *  _                          _
 * | |                        | |
 * | |__   ___ _ __   ___   __| | ___  ___
 * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
 * | |_) |  __/ | | | (_) | (_| |  __/\__ \
 * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
 *
 ********************************************/

/**
 * Return an expanding stack offset.
 * Note that function is called in the transform phase
 * where the stack offsets are still relative regarding
 * the first (frame allocating) IncSP.
 * However this is exactly what we want because frame
 * access must be done relative the the fist IncSP ...
 */
static int get_sp_expand_offset(ir_node *inc_sp) {
1036
	int offset = be_get_IncSP_offset(inc_sp);
Michael Beck's avatar
Michael Beck committed
1037

1038
	if (offset == BE_STACK_FRAME_SIZE_EXPAND)
Michael Beck's avatar
Michael Beck committed
1039
		return 0;
1040
1041

	return offset;
Michael Beck's avatar
Michael Beck committed
1042
1043
1044
}

#if 0
1045
1046
static ir_node *gen_StackParam(ir_node *irn) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
1047
1048
1049
1050
1051
1052
	ir_node   *new_op = NULL;
	ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
	ir_node   *mem    = new_rd_NoMem(env->irg);
	ir_node   *ptr    = get_irn_n(irn, 0);
	ir_entity *ent    = be_get_frame_entity(irn);
	ir_mode   *mode   = env->mode;
Michael Beck's avatar
Michael Beck committed
1053
1054
1055
1056
1057
1058
1059
1060
1061

//	/* If the StackParam has only one user ->     */
//	/* put it in the Block where the user resides */
//	if (get_irn_n_edges(node) == 1) {
//		env->block = get_nodes_block(get_edge_src_irn(get_irn_out_edge_first(node)));
//	}

	if (mode_is_float(mode)) {
		if (USE_SSE2(env->cg))
1062
			new_op = new_rd_ia32_fLoad(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1063
1064
		else {
			env->cg->used_x87 = 1;
1065
			new_op = new_rd_ia32_vfld(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1066
1067
1068
		}
	}
	else {
1069
		new_op = new_rd_ia32_Load(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
	}

	set_ia32_frame_ent(new_op, ent);
	set_ia32_use_frame(new_op);

	set_ia32_am_support(new_op, ia32_am_Source);
	set_ia32_op_type(new_op, ia32_AddrModeS);
	set_ia32_am_flavour(new_op, ia32_B);
	set_ia32_ls_mode(new_op, mode);

	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));

1082
	return new_rd_Proj(env->dbg, env->irg, block, new_op, mode, 0);
Michael Beck's avatar
Michael Beck committed
1083
}
Matthias Braun's avatar
Matthias Braun committed
1084
#endif
Michael Beck's avatar
Michael Beck committed
1085
1086

/**
1087
 * Transforms a FrameAddr into an ARM Add.
Michael Beck's avatar
Michael Beck committed
1088
 */
1089
1090
1091
1092
1093
1094
1095
static ir_node *gen_be_FrameAddr(ir_node *node) {
	ir_node   *block  = be_transform_node(get_nodes_block(node));
	ir_entity *ent    = be_get_frame_entity(node);
	int       offset  = get_entity_offset(ent);
	ir_node   *op     = be_get_FrameAddr_frame(node);
	ir_node   *new_op = be_transform_node(op);
	dbg_info  *dbg    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
1096
	ir_mode   *mode   = mode_Iu;
1097
	ir_node   *cnst;
Michael Beck's avatar
Michael Beck committed
1098
1099
1100
1101
1102
1103

	if (be_is_IncSP(op)) {
		/* BEWARE: we get an offset which is absolute from an offset that
		   is relative. Both must be merged */
		offset += get_sp_expand_offset(op);
	}
Michael Beck's avatar
Michael Beck committed
1104
	cnst = create_const_graph_value(env_cg->birg->abi, dbg, block, (unsigned)offset);
1105
	if (is_arm_Mov_i(cnst))
1106
1107
		return new_rd_arm_Add_i(dbg, current_ir_graph, block, new_op, mode, get_arm_value(cnst));
	return new_rd_arm_Add(dbg, current_ir_graph, block, new_op, cnst, mode, ARM_SHF_NONE, NULL);
Michael Beck's avatar
Michael Beck committed
1108
1109
}

Matthias Braun's avatar
Matthias Braun committed
1110
#if 0
Michael Beck's avatar
Michael Beck committed
1111
/**
1112
 * Transforms a FrameLoad into an ARM Load.
Michael Beck's avatar
Michael Beck committed
1113
 */
1114
static ir_node *gen_FrameLoad(ir_node *irn) {
1115
1116
1117
1118
1119
1120
	ir_node   *new_op = NULL;
	ir_node   *noreg  = ia32_new_NoReg_gp(env->cg);
	ir_node   *mem    = get_irn_n(irn, 0);
	ir_node   *ptr    = get_irn_n(irn, 1);
	ir_entity *ent    = be_get_frame_entity(irn);
	ir_mode   *mode   = get_type_mode(get_entity_type(ent));