arm_transform.c 46.9 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 "../beutil.h"
46
#include "../betranshlp.h"
47
48
49
#include "bearch_arm_t.h"

#include "arm_nodes_attr.h"
50
#include "archop.h"
51
52
53
54
55
56
57
58
#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
59

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

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


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

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

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

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

/**
92
 * construct 8bit values and rot amounts for a value
93
 */
Michael Beck's avatar
Michael Beck committed
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
129
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;
		}
	}
130
131
}

Michael Beck's avatar
Michael Beck committed
132
133
134
/**
 * Creates a arm_Const node.
 */
Michael Beck's avatar
Michael Beck committed
135
136
137
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);
138
139
140
141
142
	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
143
144
145
	/* ensure the const is schedules AFTER the barrier */
	add_irn_dep(res, be_abi_get_start_barrier(abi));
	return res;
146
147
}

Michael Beck's avatar
Michael Beck committed
148
149
150
/**
 * Creates a arm_Const_Neg node.
 */
Michael Beck's avatar
Michael Beck committed
151
152
153
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);
154
155
156
157
158
	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
159
160
161
	add_irn_dep(res, be_abi_get_start_barrier(abi));
	/* ensure the const is schedules AFTER the barrier */
	return res;
162
163
}

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

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

Michael Beck's avatar
Michael Beck committed
173
174
175
176
177
178
179
180
181
182
183
184
185
/**
 * 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
186
static ir_node *create_const_graph_value(be_abi_irg_t *abi, dbg_info *dbg, ir_node *block, unsigned int value) {
187
	ir_node *result;
Michael Beck's avatar
Michael Beck committed
188
189
	vals v, vn;
	int cnt;
Michael Beck's avatar
Michael Beck committed
190
	ir_mode *mode = mode_Iu;
191

Michael Beck's avatar
Michael Beck committed
192
193
194
195
196
	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
197
		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
198
199

		for (cnt = 1; cnt < vn.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
200
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode);
201
			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
202
			result = bic_i_node;
203
204
		}
	}
Michael Beck's avatar
Michael Beck committed
205
206
	else {
		/* add bits */
Michael Beck's avatar
Michael Beck committed
207
		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
208
209

		for (cnt = 1; cnt < v.ops; ++cnt) {
Michael Beck's avatar
Michael Beck committed
210
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode);
211
			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
212
213
			result = orr_i_node;
		}
214
215
216
217
	}
	return result;
}

218
219
220
221
222
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
Michael Beck's avatar
Michael Beck committed
223
static ir_node *create_const_graph(be_abi_irg_t *abi, ir_node *irn, ir_node *block) {
224
225
226
227
228
229
230
231
232
233
	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
234
	return create_const_graph_value(abi, get_irn_dbg_info(irn), block, value);
235
236
}

Michael Beck's avatar
Michael Beck committed
237
238
239
240
/**
 * 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) {
241
	unsigned mask_bits = (1 << result_bits) - 1;
Michael Beck's avatar
Michael Beck committed
242
243
	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);
244
245
}

Michael Beck's avatar
Michael Beck committed
246
247
248
249
250
/**
 * 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;
251
	int shift_width = 32 - result_bits;
Michael Beck's avatar
Michael Beck committed
252
253
254
	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);
255
256
257
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
258
259
260
/**
 * Transforms a Conv node.
 *
261
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
262
 */
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
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
281
					/* from float to float */
282
					return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
283
284
285
				}
				else {
					/* from float to int */
286
					return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
287
288
289
290
				}
			}
			else {
				/* from int to float */
291
				return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
292
293
			}
		}
Michael Beck's avatar
Michael Beck committed
294
		else if (USE_VFP(env_cg->isa)) {
295
296
297
			panic("VFP not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
298
299
300
301
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
302
303
	}
	else { /* complete in gp registers */
304
305
		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
306
307
		int min_bits;
		ir_mode *min_mode;
308

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

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

Michael Beck's avatar
Michael Beck committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/**
 * 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;
}
359
360

/**
361
 * Creates an ARM Add.
362
363
364
 *
 * @return the created arm Add node
 */
365
366
367
368
369
370
371
372
373
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
374
375
	int v;
	arm_shift_modifier mod;
376
	dbg_info *dbg = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
377

378
	if (mode_is_float(mode)) {
379
380
381
382
		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
383
			assert(mode != mode_E && "IEEE Extended FP not supported");
384
385
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
386
		}
387
388
389
390
391
392
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
	} else {
		assert(mode_is_numP(mode));
393
		mode = mode_Iu;
394
395

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

		/* check for MLA */
401
402
403
404
		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
405

406
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
407
		}
408
409
410
411
		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
412

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

Michael Beck's avatar
Michael Beck committed
416
		/* is the first a shifter */
417
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
418
		if (v) {
419
420
			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
421
422
		}
		/* is the second a shifter */
423
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
424
		if (v) {
425
426
			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
427
		}
428

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

/**
435
 * Creates an ARM Mul.
436
437
438
 *
 * @return the created arm Mul node
 */
439
440
441
442
443
444
445
446
447
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
448

449
	if (mode_is_float(mode)) {
450
451
452
453
		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
454
			assert(mode != mode_E && "IEEE Extended FP not supported");
455
			panic("VFP not supported yet\n");
456
			return NULL;
457
458
459
460
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
461
		}
462
	}
463
464
	assert(mode_is_numP(mode));
	mode = mode_Iu;
465
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
466
467
468
}

/**
469
 * Creates an ARM floating point Div.
470
 *
Michael Beck's avatar
Michael Beck committed
471
 * @param env   The transformation environment
472
473
 * @return the created arm fDiv node
 */
474
475
476
477
478
479
480
481
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
482

483
	assert(mode != mode_E && "IEEE Extended FP not supported");
484

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

#define GEN_INT_OP(op) \
499
500
501
502
503
504
	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; \
505
	ir_mode  *mode    = mode_Iu; \
506
507
	dbg_info *dbg     = get_irn_dbg_info(node); \
	int      v; \
Michael Beck's avatar
Michael Beck committed
508
509
	arm_shift_modifier mod; \
 \
510
511
512
513
	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
514
	/* is the first a shifter */ \
515
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
516
	if (v) { \
517
518
		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
519
520
	} \
	/* is the second a shifter */ \
521
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
522
	if (v) { \
523
524
		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
525
526
	} \
	/* Normal op */ \
527
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
528
529

/**
530
 * Creates an ARM And.
531
532
533
 *
 * @return the created arm And node
 */
534
535
536
static ir_node *gen_And(ir_node *node) {
	GEN_INT_OP(And);
}
537
538

/**
539
 * Creates an ARM Orr.
540
 *
Michael Beck's avatar
Michael Beck committed
541
 * @param env   The transformation environment
542
543
 * @return the created arm Or node
 */
544
545
546
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
547
548

/**
549
 * Creates an ARM Eor.
550
551
552
 *
 * @return the created arm Eor node
 */
553
554
555
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
556
557

/**
558
 * Creates an ARM Sub.
559
560
561
 *
 * @return the created arm Sub node
 */
562
563
564
565
566
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
567
	ir_node  *new_op2 = be_transform_node(op2);
568
569
570
571
	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
572
573
	arm_shift_modifier mod;

574
	if (mode_is_float(mode)) {
575
576
577
578
		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
579
			assert(mode != mode_E && "IEEE Extended FP not supported");
580
581
582
583
584
585
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
586
		}
Michael Beck's avatar
Michael Beck committed
587
	}
588
589
	else {
		assert(mode_is_numP(mode) && "unknown mode for Sub");
590
		mode = mode_Iu;
591
592
593
594
595

		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
596
597

		/* is the first a shifter */
598
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
599
		if (v) {
600
601
			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));
602
		}
Michael Beck's avatar
Michael Beck committed
603
		/* is the second a shifter */
604
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
605
		if (v) {
606
607
			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
608
609
		}
		/* normal sub */
610
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
611
612
613
614
	}
}

/**
615
 * Creates an ARM Shl.
616
 *
617
 * @return the created ARM Shl node
618
 */
619
620
621
622
623
624
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);
625
	ir_mode  *mode    = mode_Iu;
626
627
628
629
	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));
630
	}
631
	return new_rd_arm_Shl(dbg, current_ir_graph, block, new_op1, new_op2, mode);
632
633
634
}

/**
635
 * Creates an ARM Shr.
636
 *
637
 * @return the created ARM Shr node
638
 */
639
640
641
642
643
644
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);
645
	ir_mode  *mode    = mode_Iu;
646
647
648
649
	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));
650
	}
651
	return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
652
653
654
}

/**
655
 * Creates an ARM Shrs.
656
 *
657
 * @return the created ARM Shrs node
658
 */
659
660
661
662
663
664
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);
665
	ir_mode  *mode    = mode_Iu;
666
667
668
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
669
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ASR, get_arm_value(new_op2));
670
	}
671
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
672
673
674
675
676
}

/**
 * Transforms a Not node.
 *
677
 * @return the created ARM Not node
678
 */
679
680
681
682
683
684
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;
685
	ir_mode  *mode    = mode_Iu;
Michael Beck's avatar
Michael Beck committed
686
	arm_shift_modifier mod = ARM_SHF_NONE;
687
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
688
689

	if (v) {
690
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
691
692
		tv = new_tarval_from_long(v, mode_Iu);
	}
693
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, mode, mod, tv);
694
695
}

Michael Beck's avatar
Michael Beck committed
696
697
698
699
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
700
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
701
 */
702
703
static ir_node *gen_Abs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
704
	ir_node  *op      = get_Abs_op(node);
705
706
707
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
708

709
	if (mode_is_float(mode)) {
710
711
712
713
		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
714
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
715
716
717
718
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
719
		}
720
	}
721
722
	assert(mode_is_numP(mode));
	mode = mode_Iu;
723
	return new_rd_arm_Abs(dbg, current_ir_graph, block, new_op, mode);
724
725
726
727
728
}

/**
 * Transforms a Minus node.
 *
729
 * @return the created ARM Minus node
730
 */
731
732
733
734
735
736
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
737

738
	if (mode_is_float(mode)) {
739
740
741
742
		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
743
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
744
745
746
747
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
748
		}
749
	}
750
751
	assert(mode_is_numP(mode));
	mode = mode_Iu;
752
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
753
754
755
756
757
}

/**
 * Transforms a Load.
 *
758
 * @return the created ARM Load node
759
 */
760
static ir_node *gen_Load(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
761
762
763
764
765
766
767
768
769
	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;
770

Michael Beck's avatar
Michael Beck committed
771
	if (mode_is_float(mode)) {
772
773
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
774
			new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
775
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
776
			assert(mode != mode_E && "IEEE Extended FP not supported");
777
778
779
780
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
781
		}
782
	}
783
784
785
786
787
788
789
	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
790
				new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
791
				break;
792
			case 16:
Michael Beck's avatar
Michael Beck committed
793
				new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
794
				break;
795
			case 32:
Michael Beck's avatar
Michael Beck committed
796
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
797
798
				break;
			default:
Michael Beck's avatar
Michael Beck committed
799
				panic("mode size not supported\n");
800
801
802
803
804
			}
		} else {
			/* zero extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
805
				new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
806
				break;
807
			case 16:
Michael Beck's avatar
Michael Beck committed
808
				new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
809
				break;
810
			case 32:
Michael Beck's avatar
Michael Beck committed
811
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
812
813
				break;
			default:
Michael Beck's avatar
Michael Beck committed
814
				panic("mode size not supported\n");
815
816
			}
		}
817
	}
Michael Beck's avatar
Michael Beck committed
818
	set_irn_pinned(new_load, get_irn_pinned(node));
819
820
821
822
823
824
825
826

	/* check for special case: the loaded value might not be used */
	if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
		/* add a result proj and a Keep to produce a pseudo use */
		ir_node *proj = new_r_Proj(irg, block, new_load, mode_Iu, pn_arm_Load_res);
		be_new_Keep(arch_get_irn_reg_class(env_cg->arch_env, proj, -1), irg, block, 1, &proj);
	}

Michael Beck's avatar
Michael Beck committed
827
	return new_load;
828
829
830
831
832
}

/**
 * Transforms a Store.
 *
833
 * @return the created ARM Store node
834
 */
835
static ir_node *gen_Store(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
836
837
838
839
840
841
842
843
844
845
846
	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;
847

Michael Beck's avatar
Michael Beck committed
848
	if (mode_is_float(mode)) {
849
850
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
851
			new_store = new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
852
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
853
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
854
855
856
857
858
859
860
861
862
863
864
865
866
			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
867
		}
868
	}
Michael Beck's avatar
Michael Beck committed
869
870
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
871
872
}

873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
/**
 * 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));
894
	} else {
895
896
		/* SwitchJmp */
		ir_node *new_op = be_transform_node(selector);
897
898
899
900
901
902
903
904
905
906
907
		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;

908
		foreach_out_edge(node, edge) {
909
910
911
912
913
914
915
916
917
			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;
918
		n_projs = max - translation + 1;
919

920
		foreach_out_edge(node, edge) {
921
922
923
924
925
926
927
928
			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
929
		const_graph = create_const_graph_value(env_cg->birg->abi, dbg, block, translation);
930
931
		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);
932
933
934
935
936
937
938
939
	}
}

/**
 * Returns the name of a SymConst.
 * @param symc  the SymConst
 * @return name of the SymConst
 */
Michael Beck's avatar
Michael Beck committed
940
static ident *get_sc_ident(ir_node *symc) {
Michael Beck's avatar
Michael Beck committed
941
	ir_entity *ent;
942
943
944

	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
Michael Beck's avatar
Michael Beck committed
945
			return get_SymConst_name(symc);
946
947

		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
948
			ent = get_SymConst_entity(symc);
Michael Beck's avatar
Michael Beck committed
949
			set_entity_backend_marked(ent, 1);
Michael Beck's avatar
Michael Beck committed
950
			return get_entity_ld_ident(ent);
951
952
953
954
955
956
957
958

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

	return NULL;
}

Michael Beck's avatar
Michael Beck committed
959
/**
960
961
962
 * Transforms a Const node.
 *
 * @return The transformed ARM node.
Michael Beck's avatar
Michael Beck committed
963
 */
964
965
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
966
967
968
	ir_graph *irg = current_ir_graph;
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
969

Michael Beck's avatar
Michael Beck committed
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
	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");
		}
	}
986
987
	return create_const_graph(env_cg->birg->abi, node, block);
}
988
989

/**
990
 * Transforms a SymConst node.
991
 *
992
 * @return The transformed ARM node.
993
 */
994
995
static ir_node *gen_SymConst(ir_node *node) {
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
996
	ir_mode  *mode  = mode_Iu;
997
998
999
1000
1001
1002
	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 */
1003
1004
1005
	return res;
}

1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
/**
 * 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
1032
			new_mem, new_tarval_from_long(size, mode_Iu));
1033
}
1034
1035


Michael Beck's avatar
Michael Beck committed
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
/********************************************
 *  _                          _
 * | |                        | |
 * | |__   ___ _ __   ___   __| | ___  ___
 * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
 * | |_) |  __/ | | | (_) | (_| |  __/\__ \
 * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
 *
 ********************************************/

/**
 * 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) {
1055
	int offset = be_get_IncSP_offset(inc_sp);
Michael Beck's avatar
Michael Beck committed
1056

1057
	if (offset == BE_STACK_FRAME_SIZE_EXPAND)
Michael Beck's avatar
Michael Beck committed
1058
		return 0;
1059
1060

	return offset;
Michael Beck's avatar
Michael Beck committed
1061
1062
1063
}

#if 0
1064
1065
static ir_node *gen_StackParam(ir_node *irn) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
1066
1067
1068
1069
1070
1071
	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
1072
1073
1074
1075
1076
1077
1078
1079
1080

//	/* 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))
1081
			new_op = new_rd_ia32_fLoad(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1082
1083
		else {
			env->cg->used_x87 = 1;
1084
			new_op = new_rd_ia32_vfld(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1085
1086
1087
		}
	}
	else {
1088
		new_op = new_rd_ia32_Load(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar