arm_transform.c 61.6 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
	/* 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
421
				ir_node *mov_op = get_irn_n(new_op2, 0);
Michael Beck's avatar
Michael Beck committed
422
423
424
425
426
427
428
429
430
431
				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
432
433
				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
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
				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
472
}
473
474

/**
475
 * Creates an ARM Add.
476
477
478
 *
 * @return the created arm Add node
 */
479
480
static ir_node *gen_Add(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
481
482
483
484
485
486
487
488
	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
489

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

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

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

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

/**
529
 * Creates an ARM Mul.
530
531
532
 *
 * @return the created arm Mul node
 */
533
534
static ir_node *gen_Mul(ir_node *node)
{
535
536
537
538
539
540
541
	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
542

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

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

567
	assert(mode != mode_E && "IEEE Extended FP not supported");
568

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

579
580
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
581
582
583
584
585
586
	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
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
	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
602
603

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &and_factory);
604
}
605

606
607
static ir_node *gen_Or(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
608
609
610
611
612
613
614
615
	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);
616
}
617

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

630
631
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
632
633
634
635
636
637
638
	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
	};

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

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

Michael Beck's avatar
Michael Beck committed
661
662
663
664
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
665
666
667
668
669
670
671
672
673
674
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
675
676
677
678
679
680
681
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
682
static ir_node *make_shift(ir_node *node, match_flags_t flags,
683
		arm_shift_modifier_t shift_modifier)
684
{
685
686
687
688
	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);
689
690
691
692
693
694
	ir_node  *new_op1;
	ir_node  *new_op2;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
695
	}
696

697
	new_op1 = be_transform_node(op1);
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
	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);
		}
	}

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

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

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

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

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

742
743
	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
744
745
}

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

753
	/* Note: there is no Rol on arm, we have to use Ror */
754
755
756
	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
757
758
}

759
760
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
761
762
763
764
765
766
767
768
769
	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
770
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
771
772
773
774
		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
775
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
776
777

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
778
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
779
780
781
782
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
783
784
785
786
787
788
789
790
791
792
793
794
795
	} 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);
		}
796
	} else if (is_Const(op2)) {
797
798
799
		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
800

801
802
803
804
		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);
805

806
807
808
			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
809
810
811
812
813
814
815
816
817
	}

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

	return rotate;
}

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

Michael Beck's avatar
Michael Beck committed
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
	/* 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) {
			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:
			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);
		}
	}
851
852

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
853
854
}

855
856
static ir_node *gen_Minus(ir_node *node)
{
857
858
859
	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);
860
	dbg_info *dbgi    = get_irn_dbg_info(node);
861
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
862

863
	if (mode_is_float(mode)) {
864
		if (USE_FPA(env_cg->isa)) {
865
			return new_bd_arm_Mvf(dbgi, block, op, mode);
866
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
867
			assert(mode != mode_E && "IEEE Extended FP not supported");
868
			panic("VFP not supported yet");
869
		} else {
870
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
871
		}
872
	}
873
	assert(mode_is_data(mode));
874
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
875
876
}

877
878
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
879
880
881
882
883
884
	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);
885
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
886
	ir_node  *new_load = NULL;
887

Michael Beck's avatar
Michael Beck committed
888
	if (mode_is_float(mode)) {
889
		if (USE_FPA(env_cg->isa)) {
890
891
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
892
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
893
			assert(mode != mode_E && "IEEE Extended FP not supported");
894
			panic("VFP not supported yet");
895
		} else {
896
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
897
		}
898
	} else {
899
		assert(mode_is_data(mode) && "unsupported mode for Load");
900

901
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
902
	}
Michael Beck's avatar
Michael Beck committed
903
	set_irn_pinned(new_load, get_irn_pinned(node));
904
905
906
907

	/* 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 */
908
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
909
		be_new_Keep(block, 1, &proj);
910
911
	}

Michael Beck's avatar
Michael Beck committed
912
	return new_load;
913
914
}

915
916
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
917
918
919
920
921
922
923
924
	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);
925
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
926
	ir_node *new_store = NULL;
927

Michael Beck's avatar
Michael Beck committed
928
	if (mode_is_float(mode)) {
929
		if (USE_FPA(env_cg->isa)) {
930
931
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
932
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
933
			assert(mode != mode_E && "IEEE Extended FP not supported");
934
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
935
		} else {
936
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
937
938
		}
	} else {
939
		assert(mode_is_data(mode) && "unsupported mode for Store");
940
941
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
942
	}
Michael Beck's avatar
Michael Beck committed
943
944
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
945
946
}

947
948
949
950
951
952
953
954
955
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);
}

956
957
static ir_node *gen_SwitchJmp(ir_node *node)
{
958
959
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
	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;
984

985
986
987
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
988

989
990
991
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
992

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
	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)) {
1010
1011
1012
1013
1014
1015
		/* 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);

1016
1017
1018
1019
1020
1021
1022
1023
		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 */
1024
			return new_bd_arm_CmfBra(dbgi, block, new_op1, new_op2, pnc);
1025
		}
1026
		/* Hmm: use need cmfe */
1027
		return new_bd_arm_CmfeBra(dbgi, block, new_op1, new_op2, pnc);
1028
1029
#endif
	}
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
	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);
1046
	}
1047

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

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

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

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

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

1079
#if 0
1080
1081
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1082
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1083
 */
1084
1085
static int is_fpa_immediate(tarval *tv)
{
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
	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;
	}

1100
	if (tarval_is_negative(tv)) {
1101
1102
1103
1104
1105
1106
		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
1107
			return res * j;
1108
	}
Michael Beck's avatar
Michael Beck committed
1109
	return fpa_max;
1110
}
1111
#endif