arm_transform.c 46.4 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
static ir_node *create_const_node(be_abi_irg_t *abi, ir_node *irn, ir_node *block, long value) {
135
136
137
138
139
140
141
142
	tarval   *tv   = new_tarval_from_long(value, mode_Iu);
	dbg_info *dbg  = get_irn_dbg_info(irn);
	ir_mode  *mode = get_irn_mode(irn);
	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
static ir_node *create_const_neg_node(be_abi_irg_t *abi, ir_node *irn, ir_node *block, long value) {
152
153
154
155
156
157
158
159
	tarval   *tv   = new_tarval_from_long(value, mode_Iu);
	dbg_info *dbg  = get_irn_dbg_info(irn);
	ir_mode  *mode = get_irn_mode(irn);
	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
160
161
162
	add_irn_dep(res, be_abi_get_start_barrier(abi));
	/* ensure the const is schedules AFTER the barrier */
	return res;
163
164
}

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

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

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

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

197
198
199
	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;

Michael Beck's avatar
Michael Beck committed
200
201
	if (vn.ops < v.ops) {
		/* remove bits */
Michael Beck's avatar
Michael Beck committed
202
		result = create_const_neg_node(abi, irn, block, arm_encode_imm_w_shift(vn.shifts[0], vn.values[0]));
Michael Beck's avatar
Michael Beck committed
203
204
205

		for (cnt = 1; cnt < vn.ops; ++cnt) {
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(vn.shifts[cnt], vn.values[cnt]), mode_Iu);
206
			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
207
			result = bic_i_node;
208
209
		}
	}
Michael Beck's avatar
Michael Beck committed
210
211
	else {
		/* add bits */
Michael Beck's avatar
Michael Beck committed
212
		result = create_const_node(abi, irn, block, arm_encode_imm_w_shift(v.shifts[0], v.values[0]));
Michael Beck's avatar
Michael Beck committed
213
214
215

		for (cnt = 1; cnt < v.ops; ++cnt) {
			tarval *tv = new_tarval_from_long(arm_encode_imm_w_shift(v.shifts[cnt], v.values[cnt]), mode_Iu);
216
			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
217
218
			result = orr_i_node;
		}
219
220
221
222
	}
	return result;
}

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

Michael Beck's avatar
Michael Beck committed
242
static ir_node *gen_mask(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) {
243
	ir_node *block = get_nodes_block(irn);
244
	unsigned mask_bits = (1 << result_bits) - 1;
Michael Beck's avatar
Michael Beck committed
245
	ir_node *mask_node = create_const_graph_value(abi, irn, block, mask_bits);
246
247
	dbg_info *dbg = get_irn_dbg_info(irn);
	return new_rd_arm_And(dbg, current_ir_graph, block, op, mask_node, get_irn_mode(irn), ARM_SHF_NONE, NULL);
248
249
}

Michael Beck's avatar
Michael Beck committed
250
static ir_node *gen_sign_extension(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) {
251
	ir_node *block = get_nodes_block(irn);
252
	int shift_width = 32 - result_bits;
253
	ir_graph *irg = current_ir_graph;
Michael Beck's avatar
Michael Beck committed
254
	ir_node *shift_const_node = create_const_graph_value(abi, irn, block, shift_width);
255
256
257
	dbg_info *dbg = get_irn_dbg_info(irn);
	ir_node *lshift_node = new_rd_arm_Shl(dbg, irg, block, op, shift_const_node, get_irn_mode(op));
	ir_node *rshift_node = new_rd_arm_Shrs(dbg, irg, block, lshift_node, shift_const_node, get_irn_mode(irn));
258
259
260
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
261
262
263
/**
 * Transforms a Conv node.
 *
264
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
265
 */
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
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 (mode_needs_gp_reg(dst_mode))
		dst_mode = mode_Iu;

	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
287
					/* from float to float */
288
					return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
289
290
291
				}
				else {
					/* from float to int */
292
					return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
293
294
295
296
				}
			}
			else {
				/* from int to float */
297
				return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
298
299
			}
		}
Michael Beck's avatar
Michael Beck committed
300
		else if (USE_VFP(env_cg->isa)) {
301
302
303
			panic("VFP not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
304
305
306
307
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
308
309
	}
	else { /* complete in gp registers */
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
		int src_bits = get_mode_size_bits(src_mode);
		int dst_bits = get_mode_size_bits(dst_mode);
		int src_sign = get_mode_sign(src_mode);
		int dst_sign = get_mode_sign(dst_mode);

		if (src_bits == dst_bits) {
			/* kill 32 -> 32 convs */
			if (src_bits == 32) {
				return new_op;
			} else if (dst_bits < 32) {
			// 16 -> 16
				// unsigned -> unsigned
					// NOP
				// unsigned -> signed
					// sign extension (31:16)=(15)
				// signed -> unsigned
					// zero extension (31:16)=0
				// signed -> signed
					// NOP
				if (src_sign && !dst_sign) {
					return gen_mask(env_cg->birg->abi, node, new_op, dst_bits);
				} else {
					return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits);
				}
334
			} else {
335
336
				panic("Cannot handle mode %+F with %d bits\n", dst_mode, dst_bits);
				return NULL;
337
338
			}
		}
339
340
341
342
343
344
345
346
347
348
349
350
		else if (src_bits < dst_bits) {
			// 16 -> 32
				// unsigned -> unsigned
					// NOP
				// unsigned -> signed
					// NOP
				// signed -> unsigned
					// sign extension (31:16)=(15)
				// signed -> signed
					// sign extension (31:16)=(15)
			if (src_sign) {
				return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits);
351
			} else {
352
				return new_op;
353
354
			}
		}
355
356
357
358
359
360
361
362
363
364
365
366
		else {
			// 32 -> 16
				// unsigned -> unsigned
					// maskieren (31:16)=0
				// unsigned -> signed
					// maskieren (31:16)=0
				// signed -> unsigned
					// maskieren (31:16)=0
				// signed -> signed
					// sign extension (erledigt auch maskieren) (31:16)=(15)
			if (src_sign && dst_sign) {
				return gen_sign_extension(env_cg->birg->abi, node, new_op, dst_bits);
367
			} else {
368
				return gen_mask(env_cg->birg->abi, node, new_op, dst_bits);
369
370
371
372
373
			}
		}
	}
}

Michael Beck's avatar
Michael Beck committed
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/**
 * 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;
}
391
392

/**
393
 * Creates an ARM Add.
394
395
396
 *
 * @return the created arm Add node
 */
397
398
399
400
401
402
403
404
405
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
406
407
	int v;
	arm_shift_modifier mod;
408
	dbg_info *dbg = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
409

410
	if (mode_is_float(mode)) {
411
412
413
414
		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
415
			assert(mode != mode_E && "IEEE Extended FP not supported");
416
417
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
418
		}
419
420
421
422
423
424
425
426
		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
427
			return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
428
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
429
			return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
430
431

		/* check for MLA */
432
433
434
435
		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
436

437
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
438
		}
439
440
441
442
		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
443

444
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
445
		}
446

Michael Beck's avatar
Michael Beck committed
447
		/* is the first a shifter */
448
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
449
		if (v) {
450
451
			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
452
453
		}
		/* is the second a shifter */
454
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
455
		if (v) {
456
457
			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
458
		}
459

Michael Beck's avatar
Michael Beck committed
460
		/* normal ADD */
461
		return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
Michael Beck's avatar
Michael Beck committed
462
463
	}
}
464
465

/**
466
 * Creates an ARM Mul.
467
468
469
 *
 * @return the created arm Mul node
 */
470
471
472
473
474
475
476
477
478
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
479

480
	if (mode_is_float(mode)) {
481
482
483
484
		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
485
			assert(mode != mode_E && "IEEE Extended FP not supported");
486
487
488
489
490
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
491
		}
492
	}
493
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
494
495
496
}

/**
497
 * Creates an ARM floating point Div.
498
 *
Michael Beck's avatar
Michael Beck committed
499
 * @param env   The transformation environment
500
501
 * @return the created arm fDiv node
 */
502
503
504
505
506
507
508
509
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
510

511
	assert(mode != mode_E && "IEEE Extended FP not supported");
512

513
514
	env_cg->have_fp_insn = 1;
	if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
515
		return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, new_op1, new_op2, mode);
516
	else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
517
		assert(mode != mode_E && "IEEE Extended FP not supported");
518
519
520
521
522
		panic("VFP not supported yet\n");
	}
	else {
		panic("Softfloat not supported yet\n");
		return NULL;
Michael Beck's avatar
Michael Beck committed
523
	}
Michael Beck's avatar
Michael Beck committed
524
525
526
}

#define GEN_INT_OP(op) \
527
528
529
530
531
532
533
534
535
	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
536
537
	arm_shift_modifier mod; \
 \
538
539
540
541
	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
542
	/* is the first a shifter */ \
543
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
544
	if (v) { \
545
546
		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
547
548
	} \
	/* is the second a shifter */ \
549
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
550
	if (v) { \
551
552
		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
553
554
	} \
	/* Normal op */ \
555
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
556
557

/**
558
 * Creates an ARM And.
559
560
561
 *
 * @return the created arm And node
 */
562
563
564
static ir_node *gen_And(ir_node *node) {
	GEN_INT_OP(And);
}
565
566

/**
567
 * Creates an ARM Orr.
568
 *
Michael Beck's avatar
Michael Beck committed
569
 * @param env   The transformation environment
570
571
 * @return the created arm Or node
 */
572
573
574
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
575
576

/**
577
 * Creates an ARM Eor.
578
579
580
 *
 * @return the created arm Eor node
 */
581
582
583
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
584
585

/**
586
 * Creates an ARM Sub.
587
588
589
 *
 * @return the created arm Sub node
 */
590
591
592
593
594
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
595
	ir_node  *new_op2 = be_transform_node(op2);
596
597
598
599
	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
600
601
	arm_shift_modifier mod;

602
	if (mode_is_float(mode)) {
603
604
605
606
		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
607
			assert(mode != mode_E && "IEEE Extended FP not supported");
608
609
610
611
612
613
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
614
		}
Michael Beck's avatar
Michael Beck committed
615
	}
616
617
618
619
620
621
622
	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
623
624

		/* is the first a shifter */
625
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
626
		if (v) {
627
628
			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));
629
		}
Michael Beck's avatar
Michael Beck committed
630
		/* is the second a shifter */
631
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
632
		if (v) {
633
634
			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
635
636
		}
		/* normal sub */
637
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
638
639
640
641
	}
}

/**
642
 * Creates an ARM Shl.
643
 *
644
 * @return the created ARM Shl node
645
 */
646
647
648
649
650
651
652
653
654
655
656
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));
657
	}
658
	return new_rd_arm_Shl(dbg, current_ir_graph, block, new_op1, new_op2, mode);
659
660
661
}

/**
662
 * Creates an ARM Shr.
663
 *
664
 * @return the created ARM Shr node
665
 */
666
667
668
669
670
671
672
673
674
675
676
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));
677
	}
678
	return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
679
680
681
}

/**
682
 * Creates an ARM Shrs.
683
 *
684
 * @return the created ARM Shrs node
685
 */
686
687
688
689
690
691
692
693
694
695
696
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));
697
	}
698
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
699
700
701
702
703
}

/**
 * Transforms a Not node.
 *
704
 * @return the created ARM Not node
705
 */
706
707
708
709
710
711
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
712
	arm_shift_modifier mod = ARM_SHF_NONE;
713
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
714
715

	if (v) {
716
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
717
718
		tv = new_tarval_from_long(v, mode_Iu);
	}
719
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, get_irn_mode(node), mod, tv);
720
721
}

Michael Beck's avatar
Michael Beck committed
722
723
724
725
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
726
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
727
 */
728
729
730
731
732
733
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);
734

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

/**
 * Transforms a Minus node.
 *
753
 * @return the created ARM Minus node
754
 */
755
756
757
758
759
760
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
761

762
	if (mode_is_float(mode)) {
763
764
765
766
		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
767
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
768
769
770
771
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
772
		}
773
	}
774
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
775
776
777
778
779
}

/**
 * Transforms a Load.
 *
780
 * @return the created ARM Load node
781
 */
782
static ir_node *gen_Load(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
783
784
785
786
787
788
789
790
791
	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;
792

Michael Beck's avatar
Michael Beck committed
793
	if (mode_is_float(mode)) {
794
795
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
796
			new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
797
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
798
			assert(mode != mode_E && "IEEE Extended FP not supported");
799
800
801
802
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
803
		}
804
	}
805
806
807
808
809
810
811
	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
812
				new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
813
			case 16:
Michael Beck's avatar
Michael Beck committed
814
				new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
815
816
817
			case 32:
				break;
			default:
Michael Beck's avatar
Michael Beck committed
818
				panic("mode size not supported\n");
819
820
821
822
823
			}
		} else {
			/* zero extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
824
				new_load = new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
825
			case 16:
Michael Beck's avatar
Michael Beck committed
826
				new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
827
828
829
			case 32:
				break;
			default:
Michael Beck's avatar
Michael Beck committed
830
				panic("mode size not supported\n");
831
832
			}
		}
Michael Beck's avatar
Michael Beck committed
833
		new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
834
	}
Michael Beck's avatar
Michael Beck committed
835
836
	set_irn_pinned(new_load, get_irn_pinned(node));
	return new_load;
837
838
839
840
841
}

/**
 * Transforms a Store.
 *
842
 * @return the created ARM Store node
843
 */
844
static ir_node *gen_Store(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
845
846
847
848
849
850
851
852
853
854
855
	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;
856

Michael Beck's avatar
Michael Beck committed
857
	if (mode_is_float(mode)) {
858
859
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
860
			new_store = new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
861
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
862
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
863
864
865
866
867
868
869
870
871
872
873
874
875
			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
876
		}
877
	}
Michael Beck's avatar
Michael Beck committed
878
879
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
880
881
}

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
/**
 * 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));
903
	} else {
904
905
		/* SwitchJmp */
		ir_node *new_op = be_transform_node(selector);
906
907
908
909
910
911
912
913
914
915
916
		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;

917
		foreach_out_edge(node, edge) {
918
919
920
921
922
923
924
925
926
			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;
927
		n_projs = max - translation + 1;
928

929
		foreach_out_edge(node, edge) {
930
931
932
933
934
935
936
937
			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);
		}


938
939
940
		const_graph = create_const_graph_value(env_cg->birg->abi, node, block, translation);
		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);
941
942
943
944
945
946
947
948
	}
}

/**
 * Returns the name of a SymConst.
 * @param symc  the SymConst
 * @return name of the SymConst
 */
Michael Beck's avatar
Michael Beck committed
949
static ident *get_sc_ident(ir_node *symc) {
Michael Beck's avatar
Michael Beck committed
950
	ir_entity *ent;
951
952
953

	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
Michael Beck's avatar
Michael Beck committed
954
			return get_SymConst_name(symc);
955
956

		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
957
958
			ent = get_SymConst_entity(symc);
			mark_entity_visited(ent);
Michael Beck's avatar
Michael Beck committed
959
			return get_entity_ld_ident(ent);
960
961
962
963
964
965
966
967

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

	return NULL;
}

Michael Beck's avatar
Michael Beck committed
968
/**
969
970
971
 * Transforms a Const node.
 *
 * @return The transformed ARM node.
Michael Beck's avatar
Michael Beck committed
972
 */
973
974
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
975
976
977
	ir_graph *irg = current_ir_graph;
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
978

Michael Beck's avatar
Michael Beck committed
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
	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");
		}
	}
995
996
	return create_const_graph(env_cg->birg->abi, node, block);
}
997
998

/**
999
 * Transforms a SymConst node.
1000
 *
1001
 * @return The transformed ARM node.
1002
 */
1003
1004
1005
1006
1007
1008
1009
1010
1011
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 */
1012
1013
1014
	return res;
}

1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
/**
 * 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
1041
			new_mem, new_tarval_from_long(size, mode_Iu));
1042
}
1043
1044


Michael Beck's avatar
Michael Beck committed
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
/********************************************
 *  _                          _
 * | |                        | |
 * | |__   ___ _ __   ___   __| | ___  ___
 * | '_ \ / _ \ '_ \ / _ \ / _` |/ _ \/ __|
 * | |_) |  __/ | | | (_) | (_| |  __/\__ \
 * |_.__/ \___|_| |_|\___/ \__,_|\___||___/
 *
 ********************************************/

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

1066
	if (offset == BE_STACK_FRAME_SIZE_EXPAND)
Michael Beck's avatar
Michael Beck committed
1067
		return 0;
1068
1069

	return offset;
Michael Beck's avatar
Michael Beck committed
1070
1071
1072
}

#if 0
1073
1074
static ir_node *gen_StackParam(ir_node *irn) {
	ir_node  *block    = be_transform_node(get_nodes_block(node));
1075
1076
1077
1078
1079
1080
	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
1081
1082
1083
1084
1085
1086
1087
1088
1089

//	/* 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))
1090
			new_op = new_rd_ia32_fLoad(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1091
1092
		else {
			env->cg->used_x87 = 1;
1093
			new_op = new_rd_ia32_vfld(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1094
1095
1096
		}
	}
	else {
1097
		new_op = new_rd_ia32_Load(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
	}

	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));

1110
	return new_rd_Proj(env->dbg, env->irg, block, new_op, mode, 0);
Michael Beck's avatar
Michael Beck committed
1111
}
Matthias Braun's avatar
Matthias Braun committed
1112
#endif
Michael Beck's avatar
Michael Beck committed
1113
1114

/**
1115
 * Transforms a FrameAddr into an ARM Add.
Michael Beck's avatar
Michael Beck committed
1116
 */
1117
1118
1119
1120
1121
1122
1123
1124
1125
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);
	ir_mode   *mode   = get_irn_mode(node);
	dbg_info  *dbg    = get_irn_dbg_info(node);
	ir_node   *cnst;
Michael Beck's avatar
Michael Beck committed
1126
1127
1128
1129
1130
1131

	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);
	}
1132
	cnst = create_const_graph_value(env_cg->birg->abi, node, block, (unsigned)offset);
1133
	if (is_arm_Mov_i(cnst))
1134
1135
		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
1136
1137
}

Matthias Braun's avatar
Matthias Braun committed
1138
#if 0
Michael Beck's avatar
Michael Beck committed
1139
/**
1140
 * Transforms a FrameLoad into an ARM Load.
Michael Beck's avatar
Michael Beck committed
1141
 */
1142
static ir_node *gen_FrameLoad(ir_node *irn) {
1143
1144
1145
1146
1147
1148
	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));
Michael Beck's avatar
Michael Beck committed
1149
1150
1151

	if (mode_is_float(mode)) {
		if (USE_SSE2(env->cg))
1152
			new_op = new_rd_ia32_fLoad(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1153