arm_transform.c 50.8 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

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
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
77
	return mode_is_int(mode) || mode_is_reference(mode);
78
79
}

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.
 */
135
static ir_node *create_const_node(dbg_info *dbg, ir_node *block, long value) {
Michael Beck's avatar
Michael Beck committed
136
137
	ir_mode *mode  = mode_Iu;
	tarval   *tv   = new_tarval_from_long(value, mode);
138
	ir_graph *irg  = current_ir_graph;
139
140
141
142
	ir_node *res;

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
143
144
145
	res = new_rd_arm_Mov_i(dbg, irg, block, mode, tv);
	/* ensure the const is scheduled AFTER the stack frame */
	add_irn_dep(res, get_irg_frame(irg));
Michael Beck's avatar
Michael Beck committed
146
	return res;
147
148
}

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

	if (mode_needs_gp_reg(mode))
		mode = mode_Iu;
160
161
162
	res = new_rd_arm_Mvn_i(dbg, irg, block, mode, tv);
	/* ensure the const is scheduled AFTER the stack frame */
	add_irn_dep(res, get_irg_frame(irg));
Michael Beck's avatar
Michael Beck committed
163
	return res;
164
165
}

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

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
248
249
250
/**
 * Generate code for a sign extension.
 */
251
static ir_node *gen_sign_extension(dbg_info *dbg, ir_node *block, ir_node *op, int result_bits) {
Michael Beck's avatar
Michael Beck committed
252
	ir_graph *irg   = current_ir_graph;
253
	int shift_width = 32 - result_bits;
254
	ir_node *shift_const_node = create_const_graph_value(dbg, block, shift_width);
Michael Beck's avatar
Michael Beck committed
255
256
	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);
257
258
259
	return rshift_node;
}

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

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

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

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

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

380
	if (mode_is_float(mode)) {
381
		env_cg->have_fp_insn = 1;
382
383
384
385
386
387
388
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_fpaMvf_i(new_op1))
				return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
			if (is_arm_fpaMvf_i(new_op2))
				return new_rd_arm_fpaAdf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
			return new_rd_arm_fpaAdf(dbg, irg, block, new_op1, new_op2, mode);
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
389
			assert(mode != mode_E && "IEEE Extended FP not supported");
390
391
			panic("VFP not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
392
		}
393
394
395
396
397
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
		}
	} else {
398
		assert(mode_is_data(mode));
399
		mode = mode_Iu;
400
401

		if (is_arm_Mov_i(new_op1))
Michael Beck's avatar
Michael Beck committed
402
			return new_rd_arm_Add_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
403
		if (is_arm_Mov_i(new_op2))
Michael Beck's avatar
Michael Beck committed
404
			return new_rd_arm_Add_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
Michael Beck's avatar
Michael Beck committed
405
406

		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
407
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
408
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
409
410
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
411

412
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
413
		}
Michael Beck's avatar
Michael Beck committed
414
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
415
416
417
			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
418

419
			return new_rd_arm_Mla(dbg, irg, block, new_op1, new_op2, new_op3, mode);
Michael Beck's avatar
Michael Beck committed
420
		}
421

Michael Beck's avatar
Michael Beck committed
422
		/* is the first a shifter */
423
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
424
		if (v) {
425
426
			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
427
428
		}
		/* is the second a shifter */
429
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
430
		if (v) {
431
432
			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
433
		}
434

Michael Beck's avatar
Michael Beck committed
435
		/* normal ADD */
436
		return new_rd_arm_Add(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
Michael Beck's avatar
Michael Beck committed
437
438
	}
}
439
440

/**
441
 * Creates an ARM Mul.
442
443
444
 *
 * @return the created arm Mul node
 */
445
446
447
448
449
450
451
452
453
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
454

455
	if (mode_is_float(mode)) {
456
		env_cg->have_fp_insn = 1;
457
458
459
460
461
462
463
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_Mov_i(new_op1))
				return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
			if (is_arm_Mov_i(new_op2))
				return new_rd_arm_fpaMuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
			return new_rd_arm_fpaMuf(dbg, irg, block, new_op1, new_op2, mode);
		}
464
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
465
			assert(mode != mode_E && "IEEE Extended FP not supported");
466
			panic("VFP not supported yet\n");
467
			return NULL;
468
469
470
471
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
472
		}
473
	}
474
	assert(mode_is_data(mode));
475
	mode = mode_Iu;
476
	return new_rd_arm_Mul(dbg, irg, block, new_op1, new_op2, mode);
477
478
479
}

/**
480
 * Creates an ARM floating point Div.
481
 *
Michael Beck's avatar
Michael Beck committed
482
 * @param env   The transformation environment
483
484
 * @return the created arm fDiv node
 */
485
486
487
488
489
490
491
492
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
493

494
	assert(mode != mode_E && "IEEE Extended FP not supported");
495

496
	env_cg->have_fp_insn = 1;
497
498
499
500
501
502
503
	if (USE_FPA(env_cg->isa)) {
		if (is_arm_Mov_i(new_op1))
			return new_rd_arm_fpaRdf_i(dbg, current_ir_graph, block, new_op2, mode, get_arm_value(new_op1));
		if (is_arm_Mov_i(new_op2))
			return new_rd_arm_fpaDvf_i(dbg, current_ir_graph, block, new_op1, mode, get_arm_value(new_op2));
		return new_rd_arm_fpaDvf(dbg, current_ir_graph, 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
	}
Michael Beck's avatar
Michael Beck committed
511
512
513
}

#define GEN_INT_OP(op) \
514
515
516
517
518
519
	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; \
520
	ir_mode  *mode    = mode_Iu; \
521
522
	dbg_info *dbg     = get_irn_dbg_info(node); \
	int      v; \
Michael Beck's avatar
Michael Beck committed
523
524
	arm_shift_modifier mod; \
 \
525
526
527
528
	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
529
	/* is the first a shifter */ \
530
	v = is_shifter_operand(new_op1, &mod); \
Michael Beck's avatar
Michael Beck committed
531
	if (v) { \
532
533
		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
534
535
	} \
	/* is the second a shifter */ \
536
	v = is_shifter_operand(new_op2, &mod); \
Michael Beck's avatar
Michael Beck committed
537
	if (v) { \
538
539
		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
540
541
	} \
	/* Normal op */ \
542
	return new_rd_arm_ ## op(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL) \
543
544

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

/**
554
 * Creates an ARM Orr.
555
 *
Michael Beck's avatar
Michael Beck committed
556
 * @param env   The transformation environment
557
558
 * @return the created arm Or node
 */
559
560
561
static ir_node *gen_Or(ir_node *node) {
	GEN_INT_OP(Or);
}
562
563

/**
564
 * Creates an ARM Eor.
565
566
567
 *
 * @return the created arm Eor node
 */
568
569
570
static ir_node *gen_Eor(ir_node *node) {
	GEN_INT_OP(Eor);
}
571
572

/**
573
 * Creates an ARM Sub.
574
575
576
 *
 * @return the created arm Sub node
 */
577
578
579
580
581
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
582
	ir_node  *new_op2 = be_transform_node(op2);
583
584
585
586
	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
587
588
	arm_shift_modifier mod;

589
	if (mode_is_float(mode)) {
590
		env_cg->have_fp_insn = 1;
591
592
593
594
595
596
597
		if (USE_FPA(env_cg->isa)) {
			if (is_arm_Mov_i(new_op1))
				return new_rd_arm_fpaRsf_i(dbg, irg, block, new_op2, mode, get_arm_value(new_op1));
			if (is_arm_Mov_i(new_op2))
				return new_rd_arm_fpaSuf_i(dbg, irg, block, new_op1, mode, get_arm_value(new_op2));
			return new_rd_arm_fpaSuf(dbg, irg, block, new_op1, new_op2, mode);
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
598
			assert(mode != mode_E && "IEEE Extended FP not supported");
599
600
601
602
603
604
			panic("VFP not supported yet\n");
			return NULL;
		}
		else {
			panic("Softfloat not supported yet\n");
			return NULL;
Michael Beck's avatar
Michael Beck committed
605
		}
Michael Beck's avatar
Michael Beck committed
606
	}
607
	else {
608
		assert(mode_is_data(mode) && "unknown mode for Sub");
609
		mode = mode_Iu;
610
611
612
613
614

		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
615
616

		/* is the first a shifter */
617
		v = is_shifter_operand(new_op1, &mod);
Michael Beck's avatar
Michael Beck committed
618
		if (v) {
619
620
			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));
621
		}
Michael Beck's avatar
Michael Beck committed
622
		/* is the second a shifter */
623
		v = is_shifter_operand(new_op2, &mod);
Michael Beck's avatar
Michael Beck committed
624
		if (v) {
625
626
			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
627
628
		}
		/* normal sub */
629
		return new_rd_arm_Sub(dbg, irg, block, new_op1, new_op2, mode, ARM_SHF_NONE, NULL);
630
631
632
633
	}
}

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

/**
654
 * Creates an ARM Shr.
655
 *
656
 * @return the created ARM Shr node
657
 */
658
659
660
661
662
663
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);
664
	ir_mode  *mode    = mode_Iu;
665
666
667
668
	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));
669
	}
670
	return new_rd_arm_Shr(dbg, current_ir_graph, block, new_op1, new_op2, mode);
671
672
673
}

/**
674
 * Creates an ARM Shrs.
675
 *
676
 * @return the created ARM Shrs node
677
 */
678
679
680
681
682
683
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);
684
	ir_mode  *mode    = mode_Iu;
685
686
687
	dbg_info *dbg     = get_irn_dbg_info(node);

	if (is_arm_Mov_i(new_op2)) {
688
		return new_rd_arm_Mov(dbg, current_ir_graph, block, new_op1, mode, ARM_SHF_ASR, get_arm_value(new_op2));
689
	}
690
	return new_rd_arm_Shrs(dbg, current_ir_graph, block, new_op1, new_op2, mode);
691
692
693
694
695
}

/**
 * Transforms a Not node.
 *
696
 * @return the created ARM Not node
697
 */
698
699
700
701
702
703
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;
704
	ir_mode  *mode    = mode_Iu;
Michael Beck's avatar
Michael Beck committed
705
	arm_shift_modifier mod = ARM_SHF_NONE;
706
	int      v        = is_shifter_operand(new_op, &mod);
Michael Beck's avatar
Michael Beck committed
707
708

	if (v) {
709
		new_op = get_irn_n(new_op, 0);
Michael Beck's avatar
Michael Beck committed
710
711
		tv = new_tarval_from_long(v, mode_Iu);
	}
712
	return new_rd_arm_Mvn(dbg, current_ir_graph, block, new_op, mode, mod, tv);
713
714
}

Michael Beck's avatar
Michael Beck committed
715
716
717
718
/**
 * Transforms an Abs node.
 *
 * @param env   The transformation environment
719
 * @return the created ARM Abs node
Michael Beck's avatar
Michael Beck committed
720
 */
721
722
static ir_node *gen_Abs(ir_node *node) {
	ir_node  *block   = be_transform_node(get_nodes_block(node));
723
	ir_node  *op      = get_Abs_op(node);
724
725
726
	ir_node  *new_op  = be_transform_node(op);
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
727

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

/**
 * Transforms a Minus node.
 *
748
 * @return the created ARM Minus node
749
 */
750
751
752
753
754
755
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
756

757
	if (mode_is_float(mode)) {
758
759
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
760
			return new_rd_arm_fpaMvf(dbg, current_ir_graph, block, op, mode);
761
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
762
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
763
764
765
766
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
767
		}
768
	}
769
	assert(mode_is_data(mode));
770
	mode = mode_Iu;
771
	return new_rd_arm_Rsb_i(dbg, current_ir_graph, block, new_op, mode, get_mode_null(mode));
772
773
774
775
776
}

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

Michael Beck's avatar
Michael Beck committed
790
	if (mode_is_float(mode)) {
791
792
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
793
			new_load = new_rd_arm_fpaLdf(dbg, irg, block, new_ptr, new_mem, mode);
794
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
795
			assert(mode != mode_E && "IEEE Extended FP not supported");
796
797
798
799
			panic("VFP not supported yet\n");
		}
		else {
			panic("Softfloat not supported yet\n");
Michael Beck's avatar
Michael Beck committed
800
		}
801
	}
802
	else {
803
		assert(mode_is_data(mode) && "unsupported mode for Load");
804
805
806
807
808

		if (mode_is_signed(mode)) {
			/* sign extended loads */
			switch (get_mode_size_bits(mode)) {
			case 8:
Michael Beck's avatar
Michael Beck committed
809
				new_load = new_rd_arm_Loadbs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
810
				break;
811
			case 16:
Michael Beck's avatar
Michael Beck committed
812
				new_load = new_rd_arm_Loadhs(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
813
				break;
814
			case 32:
Michael Beck's avatar
Michael Beck committed
815
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
816
817
				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);
Michael Beck's avatar
Michael Beck committed
825
				break;
826
			case 16:
Michael Beck's avatar
Michael Beck committed
827
				new_load = new_rd_arm_Loadh(dbg, irg, block, new_ptr, new_mem);
Michael Beck's avatar
Michael Beck committed
828
				break;
829
			case 32:
Michael Beck's avatar
Michael Beck committed
830
				new_load = new_rd_arm_Load(dbg, irg, block, new_ptr, new_mem);
831
832
				break;
			default:
Michael Beck's avatar
Michael Beck committed
833
				panic("mode size not supported\n");
834
835
			}
		}
836
	}
Michael Beck's avatar
Michael Beck committed
837
	set_irn_pinned(new_load, get_irn_pinned(node));
838
839
840
841
842
843
844
845

	/* 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
846
	return new_load;
847
848
849
850
851
}

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

Michael Beck's avatar
Michael Beck committed
867
	if (mode_is_float(mode)) {
868
869
		env_cg->have_fp_insn = 1;
		if (USE_FPA(env_cg->isa))
Michael Beck's avatar
Michael Beck committed
870
			new_store = new_rd_arm_fpaStf(dbg, irg, block, new_ptr, new_val, new_mem, mode);
871
		else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
872
			assert(mode != mode_E && "IEEE Extended FP not supported");
Michael Beck's avatar
Michael Beck committed
873
874
875
876
877
			panic("VFP not supported yet\n");
		} else {
			panic("Softfloat not supported yet\n");
		}
	} else {
878
		assert(mode_is_data(mode) && "unsupported mode for Store");
Michael Beck's avatar
Michael Beck committed
879
880
881
882
883
884
885
		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
886
		}
887
	}
Michael Beck's avatar
Michael Beck committed
888
889
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
890
891
}

892
893
894
895
896
897
898
899
900
901
902
903
904
/**
 * 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) {
905
		/* an conditional jump */
906
907
908
909
910
911
		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);

912
913
914
915
916
917
918
919
920
921
922
923
924
925
		if (mode_is_float(get_irn_mode(op1))) {
			/* floating point compare */
			pn_Cmp pnc = get_Proj_proj(selector);

			if (pnc & pn_Cmp_Uo) {
				/* check for unordered, need cmf */
				return new_rd_arm_fpaCmfBra(dbg, irg, block, new_op1, new_op2, pnc);
			}
			/* Hmm: use need cmfe */
			return new_rd_arm_fpaCmfeBra(dbg, irg, block, new_op1, new_op2, pnc);
		} else {
			/* integer compare */
			return new_rd_arm_CmpBra(dbg, irg, block, new_op1, new_op2, get_Proj_proj(selector));
		}
926
	} else {
927
928
		/* SwitchJmp */
		ir_node *new_op = be_transform_node(selector);
929
930
931
932
933
934
935
936
937
938
939
		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;

940
		foreach_out_edge(node, edge) {
941
942
943
944
945
946
947
948
949
			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;
950
		n_projs = max - translation + 1;
951

952
		foreach_out_edge(node, edge) {
953
954
955
956
957
958
959
			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);
		}

960
		const_graph = create_const_graph_value(dbg, block, translation);
961
962
		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);
963
964
965
966
967
968
969
970
	}
}

/**
 * Returns the name of a SymConst.
 * @param symc  the SymConst
 * @return name of the SymConst
 */
Michael Beck's avatar
Michael Beck committed
971
static ident *get_sc_ident(ir_node *symc) {
Michael Beck's avatar
Michael Beck committed
972
	ir_entity *ent;
973
974
975

	switch (get_SymConst_kind(symc)) {
		case symconst_addr_name:
Michael Beck's avatar
Michael Beck committed
976
			return get_SymConst_name(symc);
977
978

		case symconst_addr_ent:
Michael Beck's avatar
Michael Beck committed
979
			ent = get_SymConst_entity(symc);
Michael Beck's avatar
Michael Beck committed
980
			set_entity_backend_marked(ent, 1);
Michael Beck's avatar
Michael Beck committed
981
			return get_entity_ld_ident(ent);
982
983
984
985
986
987
988
989

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

	return NULL;
}

990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
enum fpa_immediates {
	fpa_null = 0,
	fpa_one,
	fpa_two,
	fpa_three,
	fpa_four,
	fpa_five,
	fpa_ten,
	fpa_half,
	fpa_max
};

static tarval *fpa_imm[3][fpa_max];

1004
1005
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1006
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1007
1008
 */
static int is_fpa_immediate(tarval *tv) {
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
	ir_mode *mode = get_tarval_mode(tv);
	int i, j, res = 1;

	switch (get_mode_size_bits(mode)) {
	case 32:
		i = 0;
		break;
	case 64:
		i = 1;
		break;
	default:
		i = 2;
	}

	if (tarval_cmp(tv, get_tarval_null(mode)) & pn_Cmp_Lt) {
		tv = tarval_neg(tv);
		res = -1;
	}

	for (j = 0; j < fpa_max; ++j) {
		if (tv == fpa_imm[i][j])
			return res;
	}
1032
1033
1034
	return 0;
}

Michael Beck's avatar
Michael Beck committed
1035
/**
1036
1037
1038
 * Transforms a Const node.
 *
 * @return The transformed ARM node.