arm_transform.c 62.9 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 */
Michael Beck's avatar
Michael Beck committed
356
357
358
	MATCH_REVERSE      = 1 << 1,  /**< support reverse opcode */
	MATCH_SIZE_NEUTRAL = 1 << 2,
	MATCH_SKIP_NOT     = 1 << 3,  /**< skip Not on ONE input */
359
360
} match_flags_t;

Michael Beck's avatar
Michael Beck committed
361
362
363
364
365
366
367
368
369
370
371
372
373
/**
 * 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;
374
375

static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
Michael Beck's avatar
Michael Beck committed
376
		const arm_binop_factory_t *factory)
377
378
379
380
381
382
383
384
385
{
	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
386
387
388
389
390
391
392
393
	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");
	}
394
395
396
397
398
399
400
401
402
	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
403
		return factory->new_binop_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
404
405
	}
	new_op2 = be_transform_node(op2);
Michael Beck's avatar
Michael Beck committed
406
407
408
409
410
    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);
411
412
413
	}
	new_op1 = be_transform_node(op1);

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

		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:
Michael Beck's avatar
Michael Beck committed
456
			if (factory[idx].new_binop_reg_shift_imm) {
Michael Beck's avatar
Michael Beck committed
457
				mov_op = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
458
				return factory[idx].new_binop_reg_shift_imm(dbgi, block, new_op2, mov_op,
Michael Beck's avatar
Michael Beck committed
459
460
461
462
463
464
465
466
					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
467
			if (factory[idx].new_binop_reg_shift_reg) {
Michael Beck's avatar
Michael Beck committed
468
469
				mov_op  = get_irn_n(new_op1, 0);
				mov_sft = get_irn_n(new_op1, 1);
Michael Beck's avatar
Michael Beck committed
470
				return factory[idx].new_binop_reg_shift_reg(dbgi, block, new_op2, mov_op, mov_sft,
Michael Beck's avatar
Michael Beck committed
471
472
473
474
475
476
					attr->shift_modifier);
			}
			break;
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
477
}
478
479

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

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

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

525
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
526
		}
527
#endif
528

Michael Beck's avatar
Michael Beck committed
529
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &add_factory);
Michael Beck's avatar
Michael Beck committed
530
531
	}
}
532
533

/**
534
 * Creates an ARM Mul.
535
536
537
 *
 * @return the created arm Mul node
 */
538
539
static ir_node *gen_Mul(ir_node *node)
{
540
541
542
543
544
545
546
	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
547

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

562
563
static ir_node *gen_Quot(ir_node *node)
{
564
565
566
567
568
569
570
	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
571

572
	assert(mode != mode_E && "IEEE Extended FP not supported");
573

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

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

	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, &and_factory);
609
}
610

611
612
static ir_node *gen_Or(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
613
614
615
616
617
618
619
620
	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);
621
}
622

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

635
636
static ir_node *gen_Sub(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
637
638
639
640
641
642
643
644
645
646
647
648
649
	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
650
651
	};

652
653
654
655
	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
656
	ir_node  *new_op2 = be_transform_node(op2);
657
	ir_mode  *mode    = get_irn_mode(node);
658
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
659

660
	if (mode_is_float(mode)) {
661
		if (USE_FPA(env_cg->isa)) {
662
			return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
663
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
664
			assert(mode != mode_E && "IEEE Extended FP not supported");
665
			panic("VFP not supported yet");
666
		} else {
667
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
668
		}
669
	} else {
Michael Beck's avatar
Michael Beck committed
670
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL | MATCH_REVERSE, sub_rsb_factory);
Michael Beck's avatar
Michael Beck committed
671
	}
672
}
Michael Beck's avatar
Michael Beck committed
673

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

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
708
	}
709

710
	new_op1 = be_transform_node(op1);
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	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);
		}
	}

728
	new_op2 = be_transform_node(op2);
729
730
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
731
732
}

733
734
735
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
736
737
}

738
739
740
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
741
742
}

743
744
745
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
746
747
}

748
749
static ir_node *gen_Ror(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
756
	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_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
761
762
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
763
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
764
765
	ir_node  *new_op2 = be_transform_node(op2);

766
	/* Note: there is no Rol on arm, we have to use Ror */
767
768
769
	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
770
771
}

772
773
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
774
775
776
777
778
779
780
781
782
	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
783
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
784
785
786
787
		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
788
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
789
790

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
791
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
792
793
794
795
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
796
797
798
799
800
801
802
803
804
805
806
807
808
	} 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);
		}
809
	} else if (is_Const(op2)) {
810
811
812
		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
813

814
815
816
817
		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);
818

819
820
821
			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
822
823
824
825
826
827
828
829
830
	}

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

	return rotate;
}

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

Michael Beck's avatar
Michael Beck committed
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
	/* 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);
		}
	}
864
865

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
866
867
}

868
869
static ir_node *gen_Minus(ir_node *node)
{
870
871
872
	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);
873
	dbg_info *dbgi    = get_irn_dbg_info(node);
874
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
875

876
	if (mode_is_float(mode)) {
877
		if (USE_FPA(env_cg->isa)) {
878
			return new_bd_arm_Mvf(dbgi, block, op, mode);
879
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
880
			assert(mode != mode_E && "IEEE Extended FP not supported");
881
			panic("VFP not supported yet");
882
		} else {
883
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
884
		}
885
	}
886
	assert(mode_is_data(mode));
887
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
888
889
}

890
891
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
892
893
894
895
896
897
	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);
898
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
899
	ir_node  *new_load = NULL;
900

Michael Beck's avatar
Michael Beck committed
901
	if (mode_is_float(mode)) {
902
		if (USE_FPA(env_cg->isa)) {
903
904
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
905
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
906
			assert(mode != mode_E && "IEEE Extended FP not supported");
907
			panic("VFP not supported yet");
908
		} else {
909
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
910
		}
911
	} else {
912
		assert(mode_is_data(mode) && "unsupported mode for Load");
913

914
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
915
	}
Michael Beck's avatar
Michael Beck committed
916
	set_irn_pinned(new_load, get_irn_pinned(node));
917
918
919
920

	/* 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 */
921
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
922
		be_new_Keep(block, 1, &proj);
923
924
	}

Michael Beck's avatar
Michael Beck committed
925
	return new_load;
926
927
}

928
929
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
930
931
932
933
934
935
936
937
	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);
938
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
939
	ir_node *new_store = NULL;
940

Michael Beck's avatar
Michael Beck committed
941
	if (mode_is_float(mode)) {
942
		if (USE_FPA(env_cg->isa)) {
943
944
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
945
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
946
			assert(mode != mode_E && "IEEE Extended FP not supported");
947
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
948
		} else {
949
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
950
951
		}
	} else {
952
		assert(mode_is_data(mode) && "unsupported mode for Store");
953
954
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
955
	}
Michael Beck's avatar
Michael Beck committed
956
957
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
958
959
}

960
961
962
963
964
965
966
967
968
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);
}

969
970
static ir_node *gen_SwitchJmp(ir_node *node)
{
971
972
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
	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;
997

998
999
1000
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
1001

1002
1003
1004
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
1005

1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
	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)) {
1023
1024
1025
1026
1027
		/* 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);
1028
	}
1029

1030
1031
1032
	assert(get_irn_mode(op2) == cmp_mode);
	is_unsigned = !mode_is_signed(cmp_mode);

Michael Beck's avatar
Michael Beck committed
1033
	/* integer compare, TODO: use shifter_op in all its combinations */
1034
1035
1036
1037
1038
1039
	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);
1040
1041
}

1042
1043
1044
1045
1046
1047
1048
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;
1049

1050
1051
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
1052
	}
1053
1054
1055
1056
1057
	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));
1058

1059
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
1060
1061
}

1062
1063
static tarval *fpa_imm[3][fpa_max];

1064
#if 0
1065
1066
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
1067
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
1068
 */
1069
1070
static int is_fpa_immediate(tarval *tv)
{
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
	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;
	}

1085
	if (tarval_is_negative(tv)) {
1086
1087
1088
1089
1090
1091
		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
1092
			return res * j;
1093
	}
Michael Beck's avatar
Michael Beck committed
1094
	return fpa_max;
1095
}