arm_transform.c 63.2 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
#include "config.h"

#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "ircons.h"
Michael Beck's avatar
Michael Beck committed
34
#include "irprintf.h"
35
36
37
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
38
#include "error.h"
39

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

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

#include "gen_arm_regalloc_if.h"

#include <limits.h>

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

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

64
65
static const arch_register_t *sp_reg = &arm_gp_regs[REG_SP];
static ir_mode               *mode_gp;
66
static ir_mode               *mode_fp;
67
68
69
70
71
72
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)
73
{
74
	return mode_is_int(mode) || mode_is_reference(mode);
75
76
}

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

87
88
89
90
91
92
	/* 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 */
93
94
	arm_gen_vals_from_word(value, &v);
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
95
96
97

	if (vn.ops < v.ops) {
		/* remove bits */
98
99
		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
100
101

		for (cnt = 1; cnt < vn.ops; ++cnt) {
102
103
			result = new_bd_arm_Bic_imm(dbgi, block, result,
			                            vn.values[cnt], vn.rors[cnt]);
104
		}
105
	} else {
Michael Beck's avatar
Michael Beck committed
106
		/* add bits */
107
108
		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
109
110

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

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

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

Michael Beck's avatar
Michael Beck committed
138
/**
Michael Beck's avatar
Michael Beck committed
139
140
141
142
143
144
 * 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
145
 */
146
147
148
149
150
151
152
153
154
155
156
157
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");
	}
158
159
}

Michael Beck's avatar
Michael Beck committed
160
161
162
/**
 * Generate code for a sign extension.
 */
163
164
165
166
167
168
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);
169
170
171
	return rshift_node;
}

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

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

		if (src_bits < dst_bits) {
			min_bits = src_bits;
			min_mode = src_mode;
Michael Beck's avatar
Michael Beck committed
254
		} else {
255
256
257
258
259
260
261
262
263
264
265
266
			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);
267
268
269
270
		}
	}
}

271
272
273
274
275
276
277
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
278
	unsigned val, low_pos, high_pos;
279
280
281

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

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

285
286
287
288
289
290
291
292
293
	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
294
	}
295
296
297
298
299
300
301
	/* 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
302
303
	low_pos  = ntz(val) & ~1u;
	high_pos = (32-nlz(val)+1) & ~1u;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

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

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

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

	/* 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)
335
		return false;
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

	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
354
	MATCH_COMMUTATIVE  = 1 << 0,  /**< commutative node */
Michael Beck's avatar
Michael Beck committed
355
356
357
	MATCH_REVERSE      = 1 << 1,  /**< support reverse opcode */
	MATCH_SIZE_NEUTRAL = 1 << 2,
	MATCH_SKIP_NOT     = 1 << 3,  /**< 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
	}
	new_op2 = be_transform_node(op2);
Michael Beck's avatar
Michael Beck committed
405
406
407
408
409
    if ((flags & (MATCH_COMMUTATIVE|MATCH_REVERSE)) && try_encode_as_immediate(op1, &imm)) {
		if (flags & MATCH_REVERSE)
			return factory[1].new_binop_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
		else
			return factory[0].new_binop_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
410
411
412
	}
	new_op1 = be_transform_node(op1);

Michael Beck's avatar
Michael Beck committed
413
414
415
416
417
418
419
420
421
422
423
	/* 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) {
		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) {
Michael Beck's avatar
Michael Beck committed
424
				ir_node *mov_op = get_irn_n(new_op2, 0);
Michael Beck's avatar
Michael Beck committed
425
426
427
428
429
430
431
432
433
434
				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) {
Michael Beck's avatar
Michael Beck committed
435
436
				ir_node *mov_op  = get_irn_n(new_op2, 0);
				ir_node *mov_sft = get_irn_n(new_op2, 1);
Michael Beck's avatar
Michael Beck committed
437
438
439
440
				return factory->new_binop_reg_shift_reg(dbgi, block, new_op1, mov_op, mov_sft,
					attr->shift_modifier);
			}
			break;
Matthias Braun's avatar
Matthias Braun committed
441
442
443
444
445
		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
446
447
		}
	}
Michael Beck's avatar
Michael Beck committed
448
	if ((flags & (MATCH_COMMUTATIVE|MATCH_REVERSE)) && is_arm_Mov(new_op1)) {
Michael Beck's avatar
Michael Beck committed
449
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op1);
Michael Beck's avatar
Michael Beck committed
450
		int idx = flags & MATCH_REVERSE ? 1 : 0;
Michael Beck's avatar
Michael Beck committed
451
452

		switch (attr->shift_modifier) {
Matthias Braun's avatar
Matthias Braun committed
453
		ir_node *mov_op, *mov_sft;
Michael Beck's avatar
Michael Beck committed
454
455
456
457
458
459

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
Michael Beck's avatar
Michael Beck committed
460
			if (factory[idx].new_binop_reg_shift_imm) {
Michael Beck's avatar
Michael Beck committed
461
				mov_op = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
462
				return factory[idx].new_binop_reg_shift_imm(dbgi, block, new_op2, mov_op,
Michael Beck's avatar
Michael Beck committed
463
464
465
466
467
468
469
470
					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:
Michael Beck's avatar
Michael Beck committed
471
			if (factory[idx].new_binop_reg_shift_reg) {
Michael Beck's avatar
Michael Beck committed
472
473
				mov_op  = get_irn_n(new_op1, 0);
				mov_sft = get_irn_n(new_op1, 1);
Michael Beck's avatar
Michael Beck committed
474
				return factory[idx].new_binop_reg_shift_reg(dbgi, block, new_op2, mov_op, mov_sft,
Michael Beck's avatar
Michael Beck committed
475
476
477
					attr->shift_modifier);
			}
			break;
Matthias Braun's avatar
Matthias Braun committed
478
479
480
481
482
483

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
484
485
486
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
487
}
488
489

/**
490
 * Creates an ARM Add.
491
492
493
 *
 * @return the created arm Add node
 */
494
495
static ir_node *gen_Add(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
496
497
498
499
500
501
502
503
	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
504

505
	if (mode_is_float(mode)) {
506
507
508
509
510
511
		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);
512
		if (USE_FPA(env_cg->isa)) {
513
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
514
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
515
			assert(mode != mode_E && "IEEE Extended FP not supported");
516
			panic("VFP not supported yet");
517
		} else {
518
			panic("Softfloat not supported yet");
519
520
		}
	} else {
521
#if 0
Michael Beck's avatar
Michael Beck committed
522
		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
523
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
524
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
525
526
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
527

528
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
529
		}
Michael Beck's avatar
Michael Beck committed
530
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
531
532
533
			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
534

535
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
536
		}
537
#endif
538

Michael Beck's avatar
Michael Beck committed
539
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &add_factory);
Michael Beck's avatar
Michael Beck committed
540
541
	}
}
542
543

/**
544
 * Creates an ARM Mul.
545
546
547
 *
 * @return the created arm Mul node
 */
548
549
static ir_node *gen_Mul(ir_node *node)
{
550
551
552
553
554
555
556
	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
557

558
	if (mode_is_float(mode)) {
559
		if (USE_FPA(env_cg->isa)) {
560
			return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
561
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
562
			assert(mode != mode_E && "IEEE Extended FP not supported");
563
			panic("VFP not supported yet");
564
		} else {
565
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
566
		}
567
	}
568
	assert(mode_is_data(mode));
569
	return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
570
571
}

572
573
static ir_node *gen_Quot(ir_node *node)
{
574
575
576
577
578
579
580
	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
581

582
	assert(mode != mode_E && "IEEE Extended FP not supported");
583

584
	if (USE_FPA(env_cg->isa)) {
585
		return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
586
	} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
587
		assert(mode != mode_E && "IEEE Extended FP not supported");
588
		panic("VFP not supported yet");
589
	} else {
590
		panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
591
	}
Michael Beck's avatar
Michael Beck committed
592
593
}

594
595
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
596
597
598
599
600
601
	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
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
	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
617
618

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &and_factory);
619
}
620

621
622
static ir_node *gen_Or(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
623
624
625
626
627
628
629
630
	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);
631
}
632

633
634
static ir_node *gen_Eor(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
635
636
637
638
639
640
641
642
	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);
643
}
644

645
646
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
647
648
649
650
651
652
653
654
655
656
657
658
659
	static const arm_binop_factory_t sub_rsb_factory[2] = {
		{
			new_bd_arm_Sub_reg,
			new_bd_arm_Sub_imm,
			new_bd_arm_Sub_reg_shift_reg,
			new_bd_arm_Sub_reg_shift_imm
		},
		{
			new_bd_arm_Rsb_reg,
			new_bd_arm_Rsb_imm,
			new_bd_arm_Rsb_reg_shift_reg,
			new_bd_arm_Rsb_reg_shift_imm
		}
Michael Beck's avatar
Michael Beck committed
660
661
	};

662
663
664
665
	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
666
	ir_node  *new_op2 = be_transform_node(op2);
667
	ir_mode  *mode    = get_irn_mode(node);
668
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
669

670
	if (mode_is_float(mode)) {
671
		if (USE_FPA(env_cg->isa)) {
672
			return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
673
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
674
			assert(mode != mode_E && "IEEE Extended FP not supported");
675
			panic("VFP not supported yet");
676
		} else {
677
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
678
		}
679
	} else {
Michael Beck's avatar
Michael Beck committed
680
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL | MATCH_REVERSE, sub_rsb_factory);
Michael Beck's avatar
Michael Beck committed
681
	}
682
}
Michael Beck's avatar
Michael Beck committed
683

Michael Beck's avatar
Michael Beck committed
684
685
686
687
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
688
689
690
691
692
693
694
695
696
697
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
698
699
700
701
702
703
704
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
705
static ir_node *make_shift(ir_node *node, match_flags_t flags,
706
		arm_shift_modifier_t shift_modifier)
707
{
708
709
710
711
	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);
712
713
714
715
716
717
	ir_node  *new_op1;
	ir_node  *new_op2;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
718
	}
719

720
	new_op1 = be_transform_node(op1);
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	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);
		}
	}

738
	new_op2 = be_transform_node(op2);
739
740
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
741
742
}

743
744
745
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
746
747
}

748
749
750
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
751
752
}

753
754
755
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
756
757
}

758
759
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
760
761
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
762
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
763
764
	ir_node  *new_op2 = be_transform_node(op2);

765
766
	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
767
768
}

769
770
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
771
772
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
773
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
774
775
	ir_node  *new_op2 = be_transform_node(op2);

776
	/* Note: there is no Rol on arm, we have to use Ror */
777
778
779
	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
780
781
}

782
783
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
784
785
786
787
788
789
790
791
792
	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
793
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
794
795
796
797
		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
798
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
799
800

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
801
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
802
803
804
805
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
806
807
808
809
810
811
812
813
814
815
816
817
818
	} 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);
		}
819
	} else if (is_Const(op2)) {
820
821
822
		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
823

824
825
826
827
		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);
828

829
830
831
			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
832
833
834
835
836
837
838
839
840
	}

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

	return rotate;
}

841
842
static ir_node *gen_Not(ir_node *node)
{
843
844
845
	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);
846
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
847

Michael Beck's avatar
Michael Beck committed
848
849
850
851
852
	/* check if we can fold in a Mov */
	if (is_arm_Mov(new_op)) {
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op);

		switch (attr->shift_modifier) {
Matthias Braun's avatar
Matthias Braun committed
853
		ir_node *mov_op, *mov_sft;
Michael Beck's avatar
Michael Beck committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871

		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
		case ARM_SHF_ROR_IMM:
			mov_op = get_irn_n(new_op, 0);
			return new_bd_arm_Mvn_reg_shift_imm(dbgi, block, mov_op,
				attr->shift_modifier, attr->shift_immediate);

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
		case ARM_SHF_ROR_REG:
			mov_op  = get_irn_n(new_op, 0);
			mov_sft = get_irn_n(new_op, 1);
			return new_bd_arm_Mvn_reg_shift_reg(dbgi, block, mov_op, mov_sft,
				attr->shift_modifier);
Matthias Braun's avatar
Matthias Braun committed
872
873
874
875
876
877

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
878
879
		}
	}
880
881

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
882
883
}

884
885
static ir_node *gen_Minus(ir_node *node)
{
886
887
888
	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);
889
	dbg_info *dbgi    = get_irn_dbg_info(node);
890
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
891

892
	if (mode_is_float(mode)) {
893
		if (USE_FPA(env_cg->isa)) {
894
			return new_bd_arm_Mvf(dbgi, block, op, mode);
895
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
896
			assert(mode != mode_E && "IEEE Extended FP not supported");
897
			panic("VFP not supported yet");
898
		} else {
899
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
900
		}
901
	}
902
	assert(mode_is_data(mode));
903
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
904
905
}

906
907
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
908
909
910
911
912
913
	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);
914
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
915
	ir_node  *new_load = NULL;
916

Michael Beck's avatar
Michael Beck committed
917
	if (mode_is_float(mode)) {
918
		if (USE_FPA(env_cg->isa)) {
919
920
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
921
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
922
			assert(mode != mode_E && "IEEE Extended FP not supported");
923
			panic("VFP not supported yet");
924
		} else {
925
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
926
		}
927
	} else {
928
		assert(mode_is_data(mode) && "unsupported mode for Load");
929

930
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
931
	}
Michael Beck's avatar
Michael Beck committed
932
	set_irn_pinned(new_load, get_irn_pinned(node));
933
934
935
936

	/* 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 */
937
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
938
		be_new_Keep(block, 1, &proj);
939
940
	}

Michael Beck's avatar
Michael Beck committed
941
	return new_load;
942
943
}

944
945
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
946
947
948
949
950
951
952
953
	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);
954
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
955
	ir_node *new_store = NULL;
956

Michael Beck's avatar
Michael Beck committed
957
	if (mode_is_float(mode)) {
958
		if (USE_FPA(env_cg->isa)) {
959
960
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
961
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
962
			assert(mode != mode_E && "IEEE Extended FP not supported");
963
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
964
		} else {
965
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
966
967
		}
	} else {
968
		assert(mode_is_data(mode) && "unsupported mode for Store");
969
970
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
971
	}
Michael Beck's avatar
Michael Beck committed
972
973
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
974
975
}

976
977
978
979
980
981
982
983
984
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);
}

985
986
static ir_node *gen_SwitchJmp(ir_node *node)
{
987
988
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
	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;
1013

1014
1015
1016
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1017

1018
1019
1020
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
1021

1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	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)) {
1039
1040
1041
1042
1043
		/* 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);
1044
	}
1045

1046
1047
1048
	assert(get_irn_mode(op2) == cmp_mode);
	is_unsigned = !mode_is_signed(cmp_mode);

Michael Beck's avatar
Michael Beck committed
1049
	/* integer compare, TODO: use shifter_op in all its combinations */
1050
1051
1052
1053
1054
1055
	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);
1056
1057
}

1058
1059
1060
1061
1062
1063
1064
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;
1065

1066
1067
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
1068
	}
1069
1070
1071
1072
1073
	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));
1074

1075
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
1076
1077
}

1078
1079
static tarval *fpa_imm[3][fpa_max];

1080
#if 0
1081
1082
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1083
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1084