arm_transform.c 61 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2010 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
 * @brief   The codegenerator (transform FIRM into arm FIRM)
23
 * @author  Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
34
#include "config.h"

#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
35
#include "irprintf.h"
36
37
38
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
39
#include "error.h"
40

41
#include "../benode.h"
42
#include "../beirg.h"
43
#include "../beutil.h"
44
#include "../betranshlp.h"
45
46
#include "../beabihelper.h"
#include "../beabi.h"
47

48
#include "bearch_arm_t.h"
49
50
#include "arm_nodes_attr.h"
#include "arm_transform.h"
51
#include "arm_optimize.h"
52
53
#include "arm_new_nodes.h"
#include "arm_map_regs.h"
54
#include "arm_cconv.h"
55
56
57
58
59

#include "gen_arm_regalloc_if.h"

#include <limits.h>

60
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
Michael Beck's avatar
Michael Beck committed
61

62
63
/** hold the current code generator during transformation */
static arm_code_gen_t *env_cg;
64

65
66
static const arch_register_t *sp_reg = &arm_gp_regs[REG_SP];
static ir_mode               *mode_gp;
67
static ir_mode               *mode_fp;
68
69
70
71
72
73
static beabi_helper_env_t    *abihelper;
static calling_convention_t  *cconv = NULL;

static pmap                  *node_to_stack;

static bool mode_needs_gp_reg(ir_mode *mode)
74
{
75
	return mode_is_int(mode) || mode_is_reference(mode);
76
77
}

Michael Beck's avatar
Michael Beck committed
78
/**
79
 * create firm graph for a constant
Michael Beck's avatar
Michael Beck committed
80
 */
81
82
83
static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
                                         unsigned int value)
{
84
	ir_node *result;
85
	arm_vals v, vn;
Michael Beck's avatar
Michael Beck committed
86
	int cnt;
87

88
89
90
91
92
93
	/* We only have 8 bit immediates. So we possibly have to combine several
	 * operations to construct the desired value.
	 *
	 * we can either create the value by adding bits to 0 or by removing bits
	 * from an register with all bits set. Try which alternative needs fewer
	 * operations */
94
95
	arm_gen_vals_from_word(value, &v);
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
96
97
98

	if (vn.ops < v.ops) {
		/* remove bits */
99
100
		result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
101
102

		for (cnt = 1; cnt < vn.ops; ++cnt) {
103
104
			result = new_bd_arm_Bic_imm(dbgi, block, result,
			                            vn.values[cnt], vn.rors[cnt]);
105
		}
106
	} else {
Michael Beck's avatar
Michael Beck committed
107
		/* add bits */
108
109
		result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
110
111

		for (cnt = 1; cnt < v.ops; ++cnt) {
112
113
			result = new_bd_arm_Or_imm(dbgi, block, result,
			                           v.values[cnt], v.rors[cnt]);
Michael Beck's avatar
Michael Beck committed
114
		}
115
116
117
118
	}
	return result;
}

119
120
121
122
123
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
124
125
static ir_node *create_const_graph(ir_node *irn, ir_node *block)
{
126
127
	tarval  *tv = get_Const_tarval(irn);
	ir_mode *mode = get_tarval_mode(tv);
128
	unsigned value;
129
130
131
132
133
134
135

	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);
136
	return create_const_graph_value(get_irn_dbg_info(irn), block, value);
137
138
}

Michael Beck's avatar
Michael Beck committed
139
/**
Michael Beck's avatar
Michael Beck committed
140
141
142
143
144
145
 * Create an And that will zero out upper bits.
 *
 * @param dbgi     debug info
 * @param block    the basic block
 * @param op       the original node
 * param src_bits  number of lower bits that will remain
Michael Beck's avatar
Michael Beck committed
146
 */
147
148
149
150
151
152
153
154
155
156
157
158
static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	if (src_bits == 8) {
		return new_bd_arm_And_imm(dbgi, block, op, 0xFF, 0);
	} else if (src_bits == 16) {
		ir_node *lshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, 16);
		ir_node *rshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift, ARM_SHF_LSR_IMM, 16);
		return rshift;
	} else {
		panic("zero extension only supported for 8 and 16 bits");
	}
159
160
}

Michael Beck's avatar
Michael Beck committed
161
162
163
/**
 * Generate code for a sign extension.
 */
164
165
166
167
168
169
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	int shift_width = 32 - src_bits;
	ir_node *lshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, shift_width);
	ir_node *rshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift_node, ARM_SHF_ASR_IMM, shift_width);
170
171
172
	return rshift_node;
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                              ir_mode *orig_mode)
{
	int bits = get_mode_size_bits(orig_mode);
	if (bits == 32)
		return op;

	if (mode_is_signed(orig_mode)) {
		return gen_sign_extension(dbgi, block, op, bits);
	} else {
		return gen_zero_extension(dbgi, block, op, bits);
	}
}

/**
 * returns true if it is assured, that the upper bits of a node are "clean"
 * which means for a 16 or 8 bit value, that the upper bits in the register
 * are 0 for unsigned and a copy of the last significant bit for signed
 * numbers.
 */
static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
{
	(void) transformed_node;
	(void) mode;
	/* TODO */
	return false;
}

Michael Beck's avatar
Michael Beck committed
201
202
203
/**
 * Transforms a Conv node.
 *
204
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
205
 */
206
207
static ir_node *gen_Conv(ir_node *node)
{
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	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_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)) {
		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
222
					/* from float to float */
223
					return new_bd_arm_Mvf(dbg, block, new_op, dst_mode);
224
				} else {
Michael Beck's avatar
Michael Beck committed
225
					/* from float to int */
226
					panic("TODO");
Michael Beck's avatar
Michael Beck committed
227
				}
228
			} else {
Michael Beck's avatar
Michael Beck committed
229
				/* from int to float */
230
231
232
233
234
				if (!mode_is_signed(src_mode)) {
					panic("TODO");
				} else {
					return new_bd_arm_FltX(dbg, block, new_op, dst_mode);
				}
Michael Beck's avatar
Michael Beck committed
235
			}
236
		} else if (USE_VFP(env_cg->isa)) {
237
			panic("VFP not supported yet");
238
		} else {
239
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
240
		}
241
	} else { /* complete in gp registers */
242
243
		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
244
245
		int min_bits;
		ir_mode *min_mode;
246

Michael Beck's avatar
Michael Beck committed
247
		if (src_bits == dst_bits) {
Michael Beck's avatar
Michael Beck committed
248
			/* kill unnecessary conv */
Michael Beck's avatar
Michael Beck committed
249
			return new_op;
250
251
252
253
254
		}

		if (src_bits < dst_bits) {
			min_bits = src_bits;
			min_mode = src_mode;
Michael Beck's avatar
Michael Beck committed
255
		} else {
256
257
258
259
260
261
262
263
264
265
266
267
			min_bits = dst_bits;
			min_mode = dst_mode;
		}

		if (upper_bits_clean(new_op, min_mode)) {
			return new_op;
		}

		if (mode_is_signed(min_mode)) {
			return gen_sign_extension(dbg, block, new_op, min_bits);
		} else {
			return gen_zero_extension(dbg, block, new_op, min_bits);
268
269
270
271
		}
	}
}

272
273
274
275
276
277
278
typedef struct {
	unsigned char  imm_8;
	unsigned char  rot;
} arm_immediate_t;

static bool try_encode_as_immediate(const ir_node *node, arm_immediate_t *res)
{
Michael Beck's avatar
Michael Beck committed
279
	unsigned val, low_pos, high_pos;
280
281
282

	if (!is_Const(node))
		return false;
Michael Beck's avatar
Michael Beck committed
283

284
	val = get_tarval_long(get_Const_tarval(node));
Michael Beck's avatar
Michael Beck committed
285

286
287
288
289
290
291
292
293
294
	if (val == 0) {
		res->imm_8 = 0;
		res->rot   = 0;
		return true;
	}
	if (val <= 0xff) {
		res->imm_8 = val;
		res->rot   = 0;
		return true;
Michael Beck's avatar
Michael Beck committed
295
	}
296
297
298
299
300
301
302
	/* arm allows to use to rotate an 8bit immediate value by a multiple of 2
	   (= 0, 2, 4, 6, ...).
	   So we determine the smallest even position with a bit set
	   and the highest even position with no bit set anymore.
	   If the difference between these 2 is <= 8, then we can encode the value
	   as immediate.
	 */
Michael Beck's avatar
Michael Beck committed
303
304
	low_pos  = ntz(val) & ~1u;
	high_pos = (32-nlz(val)+1) & ~1u;
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	if (high_pos - low_pos <= 8) {
		res->imm_8 = val >> low_pos;
		res->rot   = 32 - low_pos;
		return true;
	}

	if (high_pos > 24) {
		res->rot = 34 - high_pos;
		val      = val >> (32-res->rot) | val << (res->rot);
		if (val <= 0xff) {
			res->imm_8 = val;
			return true;
		}
	}

	return false;
}

324
static bool is_downconv(const ir_node *node)
325
326
327
328
329
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
330
		return false;
331
332
333
334
335

	/* we only want to skip the conv when we're the only user
	 * (not optimal but for now...)
	 */
	if (get_irn_n_edges(node) > 1)
336
		return false;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
	return
		mode_needs_gp_reg(src_mode)  &&
		mode_needs_gp_reg(dest_mode) &&
		get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
}

static ir_node *arm_skip_downconv(ir_node *node)
{
	while (is_downconv(node))
		node = get_Conv_op(node);
	return node;
}

typedef enum {
	MATCH_NONE         = 0,
Michael Beck's avatar
Michael Beck committed
355
	MATCH_COMMUTATIVE  = 1 << 0,  /**< commutative node */
356
	MATCH_SIZE_NEUTRAL = 1 << 1,
Michael Beck's avatar
Michael Beck committed
357
	MATCH_SKIP_NOT     = 1 << 2,  /**< skip Not on ONE input */
358
359
} match_flags_t;

Michael Beck's avatar
Michael Beck committed
360
361
362
363
364
365
366
367
368
369
370
371
372
/**
 * possible binop constructors.
 */
typedef struct arm_binop_factory_t {
	/** normal reg op reg operation. */
	ir_node *(*new_binop_reg)(dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2);
	/** normal reg op imm operation. */
	ir_node *(*new_binop_imm)(dbg_info *dbgi, ir_node *block, ir_node *op1, unsigned char imm8, unsigned char imm_rot);
	/** barrel shifter reg op (reg shift reg operation. */
	ir_node *(*new_binop_reg_shift_reg)(dbg_info *dbgi, ir_node *block, ir_node *left, ir_node *right, ir_node *shift, arm_shift_modifier_t shift_modifier);
	/** barrel shifter reg op (reg shift imm operation. */
	ir_node *(*new_binop_reg_shift_imm)(dbg_info *dbgi, ir_node *block, ir_node *left, ir_node *right, arm_shift_modifier_t shift_modifier, unsigned shift_immediate);
} arm_binop_factory_t;
373
374

static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
Michael Beck's avatar
Michael Beck committed
375
		const arm_binop_factory_t *factory)
376
377
378
379
380
381
382
383
384
{
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *op1     = get_binop_left(node);
	ir_node  *new_op1;
	ir_node  *op2     = get_binop_right(node);
	ir_node  *new_op2;
	dbg_info *dbgi    = get_irn_dbg_info(node);
	arm_immediate_t imm;

Michael Beck's avatar
Michael Beck committed
385
386
387
388
389
390
391
392
	if (flags & MATCH_SKIP_NOT) {
		if (is_Not(op1))
			op1 = get_Not_op(op1);
		else if (is_Not(op2))
			op2 = get_Not_op(op2);
		else
			panic("cannot execute MATCH_SKIP_NOT");
	}
393
394
395
396
397
398
399
400
401
	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
	} else {
		assert(get_mode_size_bits(get_irn_mode(node)) == 32);
	}

	if (try_encode_as_immediate(op2, &imm)) {
		ir_node *new_op1 = be_transform_node(op1);
Michael Beck's avatar
Michael Beck committed
402
		return factory->new_binop_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
403
404
405
	}
	new_op2 = be_transform_node(op2);
    if ((flags & MATCH_COMMUTATIVE) && try_encode_as_immediate(op1, &imm)) {
Michael Beck's avatar
Michael Beck committed
406
		return factory->new_binop_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
407
408
409
	}
	new_op1 = be_transform_node(op1);

Michael Beck's avatar
Michael Beck committed
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
	/* check if we can fold in a Mov */
	if (is_arm_Mov(new_op2)) {
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op2);

		switch (attr->shift_modifier) {
			ir_node *mov_op, *mov_sft;

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
			if (factory->new_binop_reg_shift_imm) {
				mov_op = get_irn_n(new_op2, 0);
				return factory->new_binop_reg_shift_imm(dbgi, block, new_op1, mov_op,
					attr->shift_modifier, attr->shift_immediate);
			}
			break;

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
		case ARM_SHF_ROR_REG:
			if (factory->new_binop_reg_shift_reg) {
				mov_op  = get_irn_n(new_op2, 0);
				mov_sft = get_irn_n(new_op2, 1);
				return factory->new_binop_reg_shift_reg(dbgi, block, new_op1, mov_op, mov_sft,
					attr->shift_modifier);
			}
			break;
		}
	}
	if ((flags & MATCH_COMMUTATIVE) && is_arm_Mov(new_op1)) {
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op1);

		switch (attr->shift_modifier) {
			ir_node *mov_op, *mov_sft;

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
			if (factory->new_binop_reg_shift_imm) {
				mov_op = get_irn_n(new_op1, 0);
				return factory->new_binop_reg_shift_imm(dbgi, block, new_op2, mov_op,
					attr->shift_modifier, attr->shift_immediate);
			}
			break;

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
		case ARM_SHF_ROR_REG:
			if (factory->new_binop_reg_shift_reg) {
				mov_op  = get_irn_n(new_op1, 0);
				mov_sft = get_irn_n(new_op1, 1);
				return factory->new_binop_reg_shift_reg(dbgi, block, new_op2, mov_op, mov_sft,
					attr->shift_modifier);
			}
			break;
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
474
}
475
476

/**
477
 * Creates an ARM Add.
478
479
480
 *
 * @return the created arm Add node
 */
481
482
static ir_node *gen_Add(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
483
484
485
486
487
488
489
490
	static const arm_binop_factory_t add_factory = {
		new_bd_arm_Add_reg,
		new_bd_arm_Add_imm,
		new_bd_arm_Add_reg_shift_reg,
		new_bd_arm_Add_reg_shift_imm
	};

	ir_mode *mode = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
491

492
	if (mode_is_float(mode)) {
493
494
495
496
497
498
		ir_node  *block   = be_transform_node(get_nodes_block(node));
		ir_node  *op1     = get_Add_left(node);
		ir_node  *op2     = get_Add_right(node);
		dbg_info *dbgi    = get_irn_dbg_info(node);
		ir_node  *new_op1 = be_transform_node(op1);
		ir_node  *new_op2 = be_transform_node(op2);
499
		if (USE_FPA(env_cg->isa)) {
500
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
501
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
502
			assert(mode != mode_E && "IEEE Extended FP not supported");
503
			panic("VFP not supported yet");
504
		} else {
505
			panic("Softfloat not supported yet");
506
507
		}
	} else {
508
#if 0
Michael Beck's avatar
Michael Beck committed
509
		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
510
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
511
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
512
513
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
514

515
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
516
		}
Michael Beck's avatar
Michael Beck committed
517
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
518
519
520
			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
521

522
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
523
		}
524
#endif
525

Michael Beck's avatar
Michael Beck committed
526
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &add_factory);
Michael Beck's avatar
Michael Beck committed
527
528
	}
}
529
530

/**
531
 * Creates an ARM Mul.
532
533
534
 *
 * @return the created arm Mul node
 */
535
536
static ir_node *gen_Mul(ir_node *node)
{
537
538
539
540
541
542
543
	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);
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
544

545
	if (mode_is_float(mode)) {
546
		if (USE_FPA(env_cg->isa)) {
547
			return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
548
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
549
			assert(mode != mode_E && "IEEE Extended FP not supported");
550
			panic("VFP not supported yet");
551
		} else {
552
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
553
		}
554
	}
555
	assert(mode_is_data(mode));
556
	return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
557
558
}

559
560
static ir_node *gen_Quot(ir_node *node)
{
561
562
563
564
565
566
567
	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
568

569
	assert(mode != mode_E && "IEEE Extended FP not supported");
570

571
	if (USE_FPA(env_cg->isa)) {
572
		return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
573
	} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
574
		assert(mode != mode_E && "IEEE Extended FP not supported");
575
		panic("VFP not supported yet");
576
	} else {
577
		panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
578
	}
Michael Beck's avatar
Michael Beck committed
579
580
}

581
582
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
583
584
585
586
587
588
	static const arm_binop_factory_t and_factory = {
		new_bd_arm_And_reg,
		new_bd_arm_And_imm,
		new_bd_arm_And_reg_shift_reg,
		new_bd_arm_And_reg_shift_imm
	};
Michael Beck's avatar
Michael Beck committed
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
	static const arm_binop_factory_t bic_factory = {
		new_bd_arm_Bic_reg,
		new_bd_arm_Bic_imm,
		new_bd_arm_Bic_reg_shift_reg,
		new_bd_arm_Bic_reg_shift_imm
	};

	/* check for and not */
	ir_node *left  = get_And_left(node);
	ir_node *right = get_And_right(node);

	if (is_Not(left) || is_Not(right)) {
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL | MATCH_SKIP_NOT,
			&bic_factory);
	}
Michael Beck's avatar
Michael Beck committed
604
605

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &and_factory);
606
}
607

608
609
static ir_node *gen_Or(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
610
611
612
613
614
615
616
617
	static const arm_binop_factory_t or_factory = {
		new_bd_arm_Or_reg,
		new_bd_arm_Or_imm,
		new_bd_arm_Or_reg_shift_reg,
		new_bd_arm_Or_reg_shift_imm
	};

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &or_factory);
618
}
619

620
621
static ir_node *gen_Eor(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
622
623
624
625
626
627
628
629
	static const arm_binop_factory_t eor_factory = {
		new_bd_arm_Eor_reg,
		new_bd_arm_Eor_imm,
		new_bd_arm_Eor_reg_shift_reg,
		new_bd_arm_Eor_reg_shift_imm
	};

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &eor_factory);
630
}
631

632
633
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
634
635
636
637
638
639
640
	static const arm_binop_factory_t sub_factory = {
		new_bd_arm_Sub_reg,
		new_bd_arm_Sub_imm,
		new_bd_arm_Sub_reg_shift_reg,
		new_bd_arm_Sub_reg_shift_imm
	};

641
642
643
644
	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
645
	ir_node  *new_op2 = be_transform_node(op2);
646
	ir_mode  *mode    = get_irn_mode(node);
647
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
648

649
	if (mode_is_float(mode)) {
650
		if (USE_FPA(env_cg->isa)) {
651
			return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
652
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
653
			assert(mode != mode_E && "IEEE Extended FP not supported");
654
			panic("VFP not supported yet");
655
		} else {
656
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
657
		}
658
	} else {
Michael Beck's avatar
Michael Beck committed
659
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL, &sub_factory);
Michael Beck's avatar
Michael Beck committed
660
	}
661
}
Michael Beck's avatar
Michael Beck committed
662

Michael Beck's avatar
Michael Beck committed
663
664
665
666
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
667
668
669
670
671
672
673
674
675
676
static bool can_use_shift_constant(unsigned int val,
                                   arm_shift_modifier_t modifier)
{
	if (val <= 31)
		return true;
	if (val == 32 && modifier != ARM_SHF_LSL_REG && modifier != ARM_SHF_ROR_REG)
		return true;
	return false;
}

Michael Beck's avatar
Michael Beck committed
677
678
679
680
681
682
683
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
684
static ir_node *make_shift(ir_node *node, match_flags_t flags,
685
		arm_shift_modifier_t shift_modifier)
686
{
687
688
689
690
	ir_node  *block = be_transform_node(get_nodes_block(node));
	ir_node  *op1   = get_binop_left(node);
	ir_node  *op2   = get_binop_right(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
691
692
693
694
695
696
	ir_node  *new_op1;
	ir_node  *new_op2;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
697
	}
698

699
	new_op1 = be_transform_node(op1);
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
	if (is_Const(op2)) {
		tarval      *tv  = get_Const_tarval(op2);
		unsigned int val = get_tarval_long(tv);
		assert(tarval_is_long(tv));
		if (can_use_shift_constant(val, shift_modifier)) {
			switch (shift_modifier) {
			case ARM_SHF_LSL_REG: shift_modifier = ARM_SHF_LSL_IMM; break;
			case ARM_SHF_LSR_REG: shift_modifier = ARM_SHF_LSR_IMM; break;
			case ARM_SHF_ASR_REG: shift_modifier = ARM_SHF_ASR_IMM; break;
			case ARM_SHF_ROR_REG: shift_modifier = ARM_SHF_ROR_IMM; break;
			default: panic("unexpected shift modifier");
			}
			return new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1,
			                                    shift_modifier, val);
		}
	}

717
	new_op2 = be_transform_node(op2);
718
719
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
720
721
}

722
723
724
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
725
726
}

727
728
729
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
730
731
}

732
733
734
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
735
736
}

737
738
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
739
740
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
741
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
742
743
	ir_node  *new_op2 = be_transform_node(op2);

744
745
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    ARM_SHF_ROR_REG);
Michael Beck's avatar
Michael Beck committed
746
747
}

748
749
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
750
751
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
752
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
753
754
	ir_node  *new_op2 = be_transform_node(op2);

755
	/* Note: there is no Rol on arm, we have to use Ror */
756
757
758
	new_op2 = new_bd_arm_Rsb_imm(dbgi, block, new_op2, 32, 0);
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    ARM_SHF_ROR_REG);
Michael Beck's avatar
Michael Beck committed
759
760
}

761
762
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
763
764
765
766
767
768
769
770
771
	ir_node *rotate = NULL;
	ir_node *op1    = get_Rotl_left(node);
	ir_node *op2    = get_Rotl_right(node);

	/* Firm has only RotL, so we are looking for a right (op2)
	   operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
	   that means we can create a RotR. */

	if (is_Add(op2)) {
Michael Beck's avatar
Michael Beck committed
772
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
773
774
775
776
		if (is_Const(right)) {
			tarval  *tv   = get_Const_tarval(right);
			ir_mode *mode = get_irn_mode(node);
			long     bits = get_mode_size_bits(mode);
Michael Beck's avatar
Michael Beck committed
777
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
778
779

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
780
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
781
782
783
784
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
785
786
787
788
789
790
791
792
793
794
795
796
797
	} else if (is_Sub(op2)) {
		ir_node *left = get_Sub_left(op2);
		if (is_Const(left)) {
			tarval  *tv   = get_Const_tarval(left);
			ir_mode *mode = get_irn_mode(node);
			long     bits = get_mode_size_bits(mode);
			ir_node *right = get_Sub_right(op2);

			if (tarval_is_long(tv)          &&
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, right);
		}
798
	} else if (is_Const(op2)) {
799
800
801
		tarval  *tv   = get_Const_tarval(op2);
		ir_mode *mode = get_irn_mode(node);
		long     bits = get_mode_size_bits(mode);
Michael Beck's avatar
Michael Beck committed
802

803
804
805
806
		if (tarval_is_long(tv) && bits == 32) {
			ir_node  *block   = be_transform_node(get_nodes_block(node));
			ir_node  *new_op1 = be_transform_node(op1);
			dbg_info *dbgi    = get_irn_dbg_info(node);
807

808
809
810
			bits = (bits - get_tarval_long(tv)) & 31;
			rotate = new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1, ARM_SHF_ROR_IMM, bits);
		}
Michael Beck's avatar
Michael Beck committed
811
812
813
814
815
816
817
818
819
	}

	if (rotate == NULL) {
		rotate = gen_Rol(node, op1, op2);
	}

	return rotate;
}

820
821
static ir_node *gen_Not(ir_node *node)
{
822
823
824
	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);
825
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
826

827
828
829
	/* TODO: we could do alot more here with all the Mvn variations */

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
830
831
}

832
833
static ir_node *gen_Minus(ir_node *node)
{
834
835
836
	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);
837
	dbg_info *dbgi    = get_irn_dbg_info(node);
838
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
839

840
	if (mode_is_float(mode)) {
841
		if (USE_FPA(env_cg->isa)) {
842
			return new_bd_arm_Mvf(dbgi, block, op, mode);
843
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
844
			assert(mode != mode_E && "IEEE Extended FP not supported");
845
			panic("VFP not supported yet");
846
		} else {
847
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
848
		}
849
	}
850
	assert(mode_is_data(mode));
851
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
852
853
}

854
855
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
856
857
858
859
860
861
	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);
862
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
863
	ir_node  *new_load = NULL;
864

Michael Beck's avatar
Michael Beck committed
865
	if (mode_is_float(mode)) {
866
		if (USE_FPA(env_cg->isa)) {
867
868
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
869
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
870
			assert(mode != mode_E && "IEEE Extended FP not supported");
871
			panic("VFP not supported yet");
872
		} else {
873
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
874
		}
875
	} else {
876
		assert(mode_is_data(mode) && "unsupported mode for Load");
877

878
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
879
	}
Michael Beck's avatar
Michael Beck committed
880
	set_irn_pinned(new_load, get_irn_pinned(node));
881
882
883
884

	/* 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 */
885
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
886
		be_new_Keep(block, 1, &proj);
887
888
	}

Michael Beck's avatar
Michael Beck committed
889
	return new_load;
890
891
}

892
893
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
894
895
896
897
898
899
900
901
	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);
902
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
903
	ir_node *new_store = NULL;
904

Michael Beck's avatar
Michael Beck committed
905
	if (mode_is_float(mode)) {
906
		if (USE_FPA(env_cg->isa)) {
907
908
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
909
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
910
			assert(mode != mode_E && "IEEE Extended FP not supported");
911
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
912
		} else {
913
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
914
915
		}
	} else {
916
		assert(mode_is_data(mode) && "unsupported mode for Store");
917
918
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
919
	}
Michael Beck's avatar
Michael Beck committed
920
921
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
922
923
}

924
925
926
927
928
929
930
931
932
static ir_node *gen_Jmp(ir_node *node)
{
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	dbg_info *dbgi      = get_irn_dbg_info(node);

	return new_bd_arm_Jmp(dbgi, new_block);
}

933
934
static ir_node *gen_SwitchJmp(ir_node *node)
{
935
936
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
	dbg_info *dbgi     = get_irn_dbg_info(node);
	ir_node *new_op = be_transform_node(selector);
	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;

	foreach_out_edge(node, edge) {
		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;
	n_projs = max - translation + 1;
961

962
963
964
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
965

966
967
968
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
969

970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
	const_graph = create_const_graph_value(dbgi, block, translation);
	sub = new_bd_arm_Sub_reg(dbgi, block, new_op, const_graph);
	return new_bd_arm_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation);
}

static ir_node *gen_Cmp(ir_node *node)
{
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *op1      = get_Cmp_left(node);
	ir_node  *op2      = get_Cmp_right(node);
	ir_mode  *cmp_mode = get_irn_mode(op1);
	dbg_info *dbgi     = get_irn_dbg_info(node);
	ir_node  *new_op1;
	ir_node  *new_op2;
	bool      is_unsigned;

	if (mode_is_float(cmp_mode)) {
987
988
989
990
991
992
		/* TODO: this is broken... */
		new_op1 = be_transform_node(op1);
		new_op2 = be_transform_node(op2);

		return new_bd_arm_Cmfe(dbgi, block, new_op1, new_op2, false);

993
994
995
996
997
998
999
1000
		panic("FloatCmp NIY");
#if 0
		ir_node *new_op2  = be_transform_node(op2);
		/* floating point compare */
		pn_Cmp pnc = get_Proj_proj(selector);

		if (pnc & pn_Cmp_Uo) {
			/* check for unordered, need cmf */
1001
			return new_bd_arm_CmfBra(dbgi, block, new_op1, new_op2, pnc);
1002
		}
1003
		/* Hmm: use need cmfe */
1004
		return new_bd_arm_CmfeBra(dbgi, block, new_op1, new_op2, pnc);
1005
1006
#endif
	}
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
	assert(get_irn_mode(op2) == cmp_mode);
	is_unsigned = !mode_is_signed(cmp_mode);

	/* compare with 0 can be done with Tst */
	if (is_Const(op2) && tarval_is_null(get_Const_tarval(op2))) {
		new_op1 = be_transform_node(op1);
		new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op1, new_op1, false,
		                          is_unsigned);
	}
	if (is_Const(op1) && tarval_is_null(get_Const_tarval(op1))) {
		new_op2 = be_transform_node(op2);
		new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op2, new_op2, true,
		                          is_unsigned);
1023
	}
1024

Michael Beck's avatar
Michael Beck committed
1025
	/* integer compare, TODO: use shifter_op in all its combinations */
1026
1027
1028
1029
1030
1031
	new_op1 = be_transform_node(op1);
	new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
	new_op2 = be_transform_node(op2);
	new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
	return new_bd_arm_Cmp_reg(dbgi, block, new_op1, new_op2, false,
	                          is_unsigned);
1032
1033
}

1034
1035
1036
1037
1038
1039
1040
static ir_node *gen_Cond(ir_node *node)
{
	ir_node  *selector = get_Cond_selector(node);
	ir_mode  *mode     = get_irn_mode(selector);
	ir_node  *block;
	ir_node  *flag_node;
	dbg_info *dbgi;
1041

1042
1043
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
1044
	}
1045
1046
1047
1048
1049
	assert(is_Proj(selector));

	block     = be_transform_node(get_nodes_block(node));
	dbgi      = get_irn_dbg_info(node);
	flag_node = be_transform_node(get_Proj_pred(selector));
1050

1051
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
1052
1053
}

1054
1055
static tarval *fpa_imm[3][fpa_max];

1056
#if 0
1057
1058
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1059
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1060
 */
1061
1062
static int is_fpa_immediate(tarval *tv)
{
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
	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;
	}

1077
	if (tarval_is_negative(tv)) {
1078
1079
1080
1081
1082
1083
		tv = tarval_neg(tv);
		res = -1;
	}

	for (j = 0; j < fpa_max; ++j) {
		if (tv == fpa_imm[i][j])
Michael Beck's avatar
Michael Beck committed
1084
			return res * j;
1085
	}
Michael Beck's avatar
Michael Beck committed
1086
	return fpa_max;
1087
}
1088
#endif
1089

1090
1091
static ir_node *gen_Const(ir_node *node)
{
1092
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
1093
1094
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
1095

Michael Beck's avatar
Michael Beck committed
1096
1097
	if (mode_is_float(mode)) {
		if (USE_FPA(env_cg->isa)) {
1098
			tarval *tv = get_Const_tarval(node);
1099
			node       = new_bd_arm_fConst(dbg, block, tv);