arm_transform.c 45.3 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
243
244
/**
 * Creates code for a Firm Const node.
 */
Michael Beck's avatar
Michael Beck committed
245
static ir_node *gen_arm_Const(ir_node *irn, ir_node *block, arm_code_gen_t *cg) {
246
247
248
249
	ir_graph *irg = current_ir_graph;
	ir_mode *mode = get_irn_mode(irn);
	dbg_info *dbg = get_irn_dbg_info(irn);

Michael Beck's avatar
Michael Beck committed
250
	if (mode_is_float(mode)) {
251
		cg->have_fp_insn = 1;
Michael Beck's avatar
Michael Beck committed
252
253
254
255
256
257
		if (USE_FPA(cg->isa)) {
			irn = new_rd_arm_fpaConst(dbg, irg, block, get_Const_tarval(irn));
			/* ensure the const is schedules AFTER the barrier */
			add_irn_dep(irn, be_abi_get_start_barrier(cg->birg->abi));
			return irn;
		}
Michael Beck's avatar
Michael Beck committed
258
259
260
261
		else if (USE_VFP(cg->isa))
			assert(mode != mode_E && "IEEE Extended FP not supported");
		assert(0 && "NYI");
	}
Michael Beck's avatar
Michael Beck committed
262
	return create_const_graph(cg->birg->abi, irn, block);
263
264
}

Michael Beck's avatar
Michael Beck committed
265
static ir_node *gen_mask(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) {
266
	ir_node *block = get_nodes_block(irn);
267
	unsigned mask_bits = (1 << result_bits) - 1;
Michael Beck's avatar
Michael Beck committed
268
	ir_node *mask_node = create_const_graph_value(abi, irn, block, mask_bits);
269
270
	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);
271
272
}

Michael Beck's avatar
Michael Beck committed
273
static ir_node *gen_sign_extension(be_abi_irg_t *abi, ir_node *irn, ir_node *op, int result_bits) {
274
	ir_node *block = get_nodes_block(irn);
275
	int shift_width = 32 - result_bits;
276
	ir_graph *irg = current_ir_graph;
Michael Beck's avatar
Michael Beck committed
277
	ir_node *shift_const_node = create_const_graph_value(abi, irn, block, shift_width);
278
279
280
	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));
281
282
283
	return rshift_node;
}

Michael Beck's avatar
Michael Beck committed
284
285
286
/**
 * Transforms a Conv node.
 *
287
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
288
 */
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
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
310
					/* from float to float */
311
					return new_rd_arm_fpaMov(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
312
313
314
				}
				else {
					/* from float to int */
315
					return new_rd_arm_fpaFix(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
316
317
318
319
				}
			}
			else {
				/* from int to float */
320
				return new_rd_arm_fpaFlt(dbg, irg, block, new_op, dst_mode);
Michael Beck's avatar
Michael Beck committed
321
322
			}
		}
323
324
325
326
		else {
			panic("VFP not supported yet\n");
			return NULL;
		}
Michael Beck's avatar
Michael Beck committed
327
328
	}
	else { /* complete in gp registers */
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
		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);
				}
353
			} else {
354
355
				panic("Cannot handle mode %+F with %d bits\n", dst_mode, dst_bits);
				return NULL;
356
357
			}
		}
358
359
360
361
362
363
364
365
366
367
368
369
		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);
370
			} else {
371
				return new_op;
372
373
			}
		}
374
375
376
377
378
379
380
381
382
383
384
385
		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);
386
			} else {
387
				return gen_mask(env_cg->birg->abi, node, new_op, dst_bits);
388
389
390
391
392
			}
		}
	}
}

Michael Beck's avatar
Michael Beck committed
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
/**
 * 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;
}
410
411

/**
412
 * Creates an ARM Add.
413
414
415
 *
 * @return the created arm Add node
 */
416
417
418
419
420
421
422
423
424
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
425
426
	int v;
	arm_shift_modifier mod;
427
	dbg_info *dbg = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
428

429
	if (mode_is_float(mode)) {
430
431
432
433
		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
434
			assert(mode != mode_E && "IEEE Extended FP not supported");
435
436
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
437
		}
438
439
440
441
442
443
444
445
446
447
448
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
	} else {
		assert(mode_is_numP(mode));

		if (is_arm_Mov_i(new_op1))
			return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_value(op1));
		if (is_arm_Mov_i(new_op2))
			return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_value(op2));
Michael Beck's avatar
Michael Beck committed
449
450

		/* check for MLA */
451
452
453
454
		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
455

456
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
457
		}
458
459
460
461
		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
462

463
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
464
		}
465

Michael Beck's avatar
Michael Beck committed
466
		/* is the first a shifter */
467
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
468
		if (v) {
469
470
			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
471
472
		}
		/* is the second a shifter */
473
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
474
		if (v) {
475
476
			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
477
		}
478

Michael Beck's avatar
Michael Beck committed
479
		/* normal ADD */
480
		return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
Michael Beck's avatar
Michael Beck committed
481
482
	}
}
483
484

/**
485
 * Creates an ARM Mul.
486
487
488
 *
 * @return the created arm Mul node
 */
489
490
491
492
493
494
495
496
497
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
498

499
	if (mode_is_float(mode)) {
500
501
502
503
		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
504
			assert(mode != mode_E && "IEEE Extended FP not supported");
505
506
507
508
509
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
510
		}
511
	}
512
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
513
514
515
}

/**
516
 * Creates an ARM floating point Div.
517
 *
Michael Beck's avatar
Michael Beck committed
518
 * @param env   The transformation environment
519
520
 * @return the created arm fDiv node
 */
521
522
523
524
525
526
527
528
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
529

530
	assert(mode != mode_E && "IEEE Extended FP not supported");
531

532
533
	env_cg->have_fp_insn = 1;
	if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
534
		return new_rd_arm_fpaDiv(dbg, current_ir_graph, block, op1, op2, mode);
535
	else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
536
		assert(mode != mode_E && "IEEE Extended FP not supported");
537
538
539
540
541
		panic("VFP not supported yet\n");
	}
	else {
		panic("Softfloat not supported yet\n");
		return NULL;
Michael Beck's avatar
Michael Beck committed
542
	}
Michael Beck's avatar
Michael Beck committed
543
544
545
}

#define GEN_INT_OP(op) \
546
547
548
549
550
551
552
553
554
	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
555
556
	arm_shift_modifier mod; \
 \
557
558
559
560
	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
561
	/* is the first a shifter */ \
562
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
563
	if (v) { \
564
565
		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
566
567
	} \
	/* is the second a shifter */ \
568
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
569
	if (v) { \
570
571
		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
572
573
	} \
	/* Normal op */ \
574
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
575
576

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

/**
586
 * Creates an ARM Orr.
587
 *
Michael Beck's avatar
Michael Beck committed
588
 * @param env   The transformation environment
589
590
 * @return the created arm Or node
 */
591
592
593
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
594
595

/**
596
 * Creates an ARM Eor.
597
598
599
 *
 * @return the created arm Eor node
 */
600
601
602
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
603
604

/**
605
 * Creates an ARM Sub.
606
607
608
 *
 * @return the created arm Sub node
 */
609
610
611
612
613
614
615
616
617
618
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);
	ir_node  *new_op2 = be_transform_node(node);
	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
619
620
	arm_shift_modifier mod;

621
	if (mode_is_float(mode)) {
622
623
624
625
		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
626
			assert(mode != mode_E && "IEEE Extended FP not supported");
627
628
629
630
631
632
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
633
		}
Michael Beck's avatar
Michael Beck committed
634
	}
635
636
637
638
639
640
641
	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
642
643

		/* is the first a shifter */
644
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
645
		if (v) {
646
647
			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));
648
		}
Michael Beck's avatar
Michael Beck committed
649
		/* is the second a shifter */
650
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
651
		if (v) {
652
653
			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
654
655
		}
		/* normal sub */
656
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
657
658
659
660
	}
}

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

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

/**
701
 * Creates an ARM Shrs.
702
 *
703
 * @return the created ARM Shrs node
704
 */
705
706
707
708
709
710
711
712
713
714
715
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));
716
	}
717
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
718
719
720
721
722
}

/**
 * Transforms a Not node.
 *
723
 * @return the created ARM Not node
724
 */
725
726
727
728
729
730
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
731
	arm_shift_modifier mod = ARM_SHF_NONE;
732
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
733
734

	if (v) {
735
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
736
737
		tv = new_tarval_from_long(v, mode_Iu);
	}
738
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, get_irn_mode(node), mod, tv);
739
740
}

Michael Beck's avatar
Michael Beck committed
741
742
743
744
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
745
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
746
 */
747
748
749
750
751
752
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);
753

754
	if (mode_is_float(mode)) {
755
756
757
758
		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
759
			assert(mode != mode_E && "IEEE Extended FP not supported");
760
			assert(0 && "NYI");
Michael Beck's avatar
Michael Beck committed
761
		}
762
	}
763
	return new_rd_arm_Abs(dbg, current_ir_graph, block, new_op, mode);
764
765
766
767
768
}

/**
 * Transforms a Minus node.
 *
769
 * @return the created ARM Minus node
770
 */
771
772
773
774
775
776
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
777

778
	if (mode_is_float(mode)) {
779
780
781
782
		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
783
			assert(mode != mode_E && "IEEE Extended FP not supported");
784
			assert(0 && "NYI");
Michael Beck's avatar
Michael Beck committed
785
		}
786
	}
787
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
788
789
790
791
792
}

/**
 * Transforms a Load.
 *
793
 * @return the created ARM Load node
794
 */
795
796
797
798
799
800
801
802
803
static ir_node *gen_Load(ir_node *node) {
	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);
804

Michael Beck's avatar
Michael Beck committed
805
	if (mode_is_float(mode)) {
806
807
808
809
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
810
			assert(mode != mode_E && "IEEE Extended FP not supported");
811
812
813
814
815
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
816
		}
817
	}
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
	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:
				return new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
			case 16:
				return new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
			case 32:
				break;
			default:
				assert(!"mode size not supported");
			}
		} else {
			/* zero extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
				return new_rd_arm_Loadb(dbg, irg, block, new_ptr, new_mem);
			case 16:
				return new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
			case 32:
				break;
			default:
				assert(!"mode size not supported");
			}
		}
		return new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
847
848
849
850
851
852
	}
}

/**
 * Transforms a Store.
 *
853
 * @return the created ARM Store node
854
 */
855
856
857
858
859
860
861
862
863
864
865
static ir_node *gen_Store(ir_node *node) {
	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);
866

Michael Beck's avatar
Michael Beck committed
867
	if (mode_is_float(mode)) {
868
869
870
871
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
			return new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
872
			assert(mode != mode_E && "IEEE Extended FP not supported");
873
			assert(0 && "NYI");
Michael Beck's avatar
Michael Beck committed
874
		}
875
	}
876
877
878
879
880
881
882
883

	switch (get_mode_size_bits(mode)) {
	case 8:
		return new_rd_arm_Storeb(dbg, irg, block, new_ptr, new_val, new_mem);
	case 16:
		return new_rd_arm_Storeh(dbg, irg, block, new_ptr, new_val, new_mem);
	default:
		return new_rd_arm_Store(dbg, irg, block, new_ptr, new_val, new_mem);
884
885
886
	}
}

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

922
		foreach_out_edge(node, edge) {
923
924
925
926
927
928
929
930
931
			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;
932
		n_projs = max - translation + 1;
933

934
		foreach_out_edge(node, edge) {
935
936
937
938
939
940
941
942
			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);
		}


943
944
945
		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);
946
947
948
949
950
951
952
953
	}
}

/**
 * Returns the name of a SymConst.
 * @param symc  the SymConst
 * @return name of the SymConst
 */
Michael Beck's avatar
Michael Beck committed
954
static ident *get_sc_ident(ir_node *symc) {
Michael Beck's avatar
Michael Beck committed
955
	ir_entity *ent;
956
957
958

	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
Michael Beck's avatar
Michael Beck committed
959
			return get_SymConst_name(symc);
960
961

		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
962
963
			ent = get_SymConst_entity(symc);
			mark_entity_visited(ent);
Michael Beck's avatar
Michael Beck committed
964
			return get_entity_ld_ident(ent);
965
966
967
968
969
970
971
972

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

	return NULL;
}

Michael Beck's avatar
Michael Beck committed
973
/**
974
975
976
 * Transforms a Const node.
 *
 * @return The transformed ARM node.
Michael Beck's avatar
Michael Beck committed
977
 */
978
979
980
981
static ir_node *gen_Const(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);
982

983
984
	return create_const_graph(env_cg->birg->abi, node, block);
}
985
986
987


/**
988
 * Transforms a SymConst node.
989
 *
990
 * @return The transformed ARM node.
991
 */
992
993
994
995
996
997
998
999
1000
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 */
1001
1002
1003
	return res;
}

1004
1005
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),
			mem, new_tarval_from_long(size, mode_Iu));
}
1032
1033


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

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

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

	return offset;
Michael Beck's avatar
Michael Beck committed
1059
1060
1061
}

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

//	/* 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))
1079
			new_op = new_rd_ia32_fLoad(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1080
1081
		else {
			env->cg->used_x87 = 1;
1082
			new_op = new_rd_ia32_vfld(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1083
1084
1085
		}
	}
	else {
1086
		new_op = new_rd_ia32_Load(env->dbg, env->irg, block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
	}

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

1099
	return new_rd_Proj(env->dbg, env->irg, block, new_op, mode, 0);
Michael Beck's avatar
Michael Beck committed
1100
}
Matthias Braun's avatar
Matthias Braun committed
1101
#endif
Michael Beck's avatar
Michael Beck committed
1102
1103

/**
1104
 * Transforms a FrameAddr into an ARM Add.
Michael Beck's avatar
Michael Beck committed
1105
 */
1106
1107
1108
1109
1110
1111
1112
1113
1114
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
1115
1116
1117
1118
1119
1120

	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);
	}
1121
	cnst = create_const_graph_value(env_cg->birg->abi, node, block, (unsigned)offset);
1122
	if (is_arm_Mov_i(cnst))
1123
1124
		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
1125
1126
}

Matthias Braun's avatar
Matthias Braun committed
1127
#if 0
Michael Beck's avatar
Michael Beck committed
1128
/**
1129
 * Transforms a FrameLoad into an ARM Load.
Michael Beck's avatar
Michael Beck committed
1130
 */
1131
static ir_node *gen_FrameLoad(ir_node *irn) {
1132
1133
1134
1135
1136
1137
	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
1138
1139
1140

	if (mode_is_float(mode)) {
		if (USE_SSE2(env->cg))
1141
			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
1142
1143
		else {
			env->cg->used_x87 = 1;
1144
			new_op = new_rd_ia32_vfld(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1145
1146
1147
		}
	}
	else {
1148
		new_op = new_rd_ia32_Load(env->dbg, current_ir_graph, env->block, ptr, noreg, mem, mode_T);
Michael Beck's avatar
Michael Beck committed
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
	}

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

	return new_op;
}
Matthias Braun's avatar
Matthias Braun committed
1163
#endif
Michael Beck's avatar
Michael Beck committed
1164
1165

/**
1166
 * Transform a be_AddSP into an arm_AddSP. Eat up const sizes.
Michael Beck's avatar
Michael Beck committed
1167
 */
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
static ir_node *gen_be_AddSP(ir_node *node) {
	ir_node  *block  = be_transform_node(get_nodes_block(node));
	ir_node  *sz     = get_irn_n(node, be_pos_AddSP_size);
	ir_node  *new_sz = be_transform_node(sz);
	ir_node  *sp     = get_irn_n(node, be_pos_AddSP_old_sp);
	ir_node  *new_sp = be_transform_node(sp);
	ir_graph *irg    = current_ir_graph;
	dbg_info *dbgi   = get_irn_dbg_info(node);
	ir_node  *nomem  = new_NoMem();
	ir_node  *new_op;

	/* ARM stack grows in reverse direction, make a SubSP */
	new_op = new_rd_arm_SubSP(dbgi, irg, block, new_sp, new_sz, nomem);
Michael Beck's avatar
Michael Beck committed
1181

1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238