arm_transform.c 64.6 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

6
7
/**
 * @file
Michael Beck's avatar
Michael Beck committed
8
 * @brief   The codegenerator (transform FIRM into arm FIRM)
9
 * @author  Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
10
 */
11
#include "bearch_arm_t.h"
12
13
14
15
16
17
18
19
20
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "ircons.h"
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Matthias Braun's avatar
Matthias Braun committed
21
#include "panic.h"
22
#include "util.h"
23

24
25
26
27
#include "benode.h"
#include "beirg.h"
#include "beutil.h"
#include "betranshlp.h"
28
29
30

#include "arm_nodes_attr.h"
#include "arm_transform.h"
31
#include "arm_optimize.h"
32
#include "arm_new_nodes.h"
33
#include "arm_cconv.h"
34
35

#include "gen_arm_regalloc_if.h"
Matthias Braun's avatar
Matthias Braun committed
36
#include "gen_arm_new_nodes.h"
37

38
39
#define ARM_PO2_STACK_ALIGNMENT 3

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

42
static const arch_register_t *sp_reg = &arm_registers[REG_SP];
43
static be_stackorder_t       *stackorder;
44
45
46
static calling_convention_t  *cconv = NULL;
static pmap                  *node_to_stack;

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
static const arch_register_t *const callee_saves[] = {
	&arm_registers[REG_R4],
	&arm_registers[REG_R5],
	&arm_registers[REG_R6],
	&arm_registers[REG_R7],
	&arm_registers[REG_R8],
	&arm_registers[REG_R9],
	&arm_registers[REG_R10],
	&arm_registers[REG_R11],
	&arm_registers[REG_LR],
};

static const arch_register_t *const caller_saves[] = {
	&arm_registers[REG_R0],
	&arm_registers[REG_R1],
	&arm_registers[REG_R2],
	&arm_registers[REG_R3],
	&arm_registers[REG_LR],

	&arm_registers[REG_F0],
	&arm_registers[REG_F1],
	&arm_registers[REG_F2],
	&arm_registers[REG_F3],
	&arm_registers[REG_F4],
	&arm_registers[REG_F5],
	&arm_registers[REG_F6],
	&arm_registers[REG_F7],
};

Matthias Braun's avatar
Matthias Braun committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
void arm_gen_vals_from_word(uint32_t value, arm_vals *result)
{
	/* TODO: not optimal yet, as we only "shift" the value and don't take
	 * advantage of rotations */

	/* special case: we prefer shift amount 0 */
	if (value <= 0xFF) {
		result->values[0] = value;
		result->rors[0]   = 0;
		result->ops       = 1;
		return;
	}

	int initial = 0;
	result->ops = 0;
	do {
		while ((value & 0x3) == 0) {
			value  >>= 2;
			initial += 2;
		}

		result->values[result->ops] = value & 0xFF;
		result->rors[result->ops]   = (32-initial) % 32;
		++result->ops;

		value  >>= 8;
		initial += 8;
	} while (value != 0);
}

Michael Beck's avatar
Michael Beck committed
106
/**
107
 * create firm graph for a constant
Michael Beck's avatar
Michael Beck committed
108
 */
109
static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
Matthias Braun's avatar
Matthias Braun committed
110
                                         uint32_t value)
111
{
112
113
114
115
116
117
	/* 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 */
Matthias Braun's avatar
Matthias Braun committed
118
	arm_vals v;
119
	arm_gen_vals_from_word(value, &v);
Matthias Braun's avatar
Matthias Braun committed
120
	arm_vals vn;
121
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
122

Matthias Braun's avatar
Matthias Braun committed
123
	ir_node *result;
Michael Beck's avatar
Michael Beck committed
124
125
	if (vn.ops < v.ops) {
		/* remove bits */
126
		result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
Michael Beck's avatar
Michael Beck committed
127

Matthias Braun's avatar
Matthias Braun committed
128
		for (unsigned cnt = 1; cnt < vn.ops; ++cnt) {
129
130
			result = new_bd_arm_Bic_imm(dbgi, block, result,
			                            vn.values[cnt], vn.rors[cnt]);
131
		}
132
	} else {
Michael Beck's avatar
Michael Beck committed
133
		/* add bits */
134
		result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
Michael Beck's avatar
Michael Beck committed
135

Matthias Braun's avatar
Matthias Braun committed
136
		for (unsigned cnt = 1; cnt < v.ops; ++cnt) {
137
138
			result = new_bd_arm_Or_imm(dbgi, block, result,
			                           v.values[cnt], v.rors[cnt]);
Michael Beck's avatar
Michael Beck committed
139
		}
140
141
142
143
	}
	return result;
}

144
145
146
147
148
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
149
150
static ir_node *create_const_graph(ir_node *irn, ir_node *block)
{
Matthias Braun's avatar
Matthias Braun committed
151
152
	ir_tarval *tv   = get_Const_tarval(irn);
	ir_mode   *mode = get_tarval_mode(tv);
153
154
	if (mode_is_reference(mode)) {
		/* ARM is 32bit, so we can safely convert a reference tarval into Iu */
155
156
		assert(get_mode_size_bits(mode) == get_mode_size_bits(arm_mode_gp));
		tv = tarval_convert_to(tv, arm_mode_gp);
157
	}
Matthias Braun's avatar
Matthias Braun committed
158
	long value = get_tarval_long(tv);
159
	return create_const_graph_value(get_irn_dbg_info(irn), block, value);
160
161
}

Michael Beck's avatar
Michael Beck committed
162
/**
Michael Beck's avatar
Michael Beck committed
163
164
165
166
167
168
 * 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
169
 */
170
static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
Matthias Braun's avatar
Matthias Braun committed
171
                                   unsigned src_bits)
172
173
174
175
176
177
178
179
180
181
{
	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");
	}
182
183
}

Michael Beck's avatar
Michael Beck committed
184
185
186
/**
 * Generate code for a sign extension.
 */
187
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
Matthias Braun's avatar
Matthias Braun committed
188
                                   unsigned src_bits)
189
{
Matthias Braun's avatar
Matthias Braun committed
190
	unsigned shift_width = 32 - src_bits;
191
192
	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);
193
194
195
	return rshift_node;
}

196
197
198
static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                              ir_mode *orig_mode)
{
Matthias Braun's avatar
Matthias Braun committed
199
	unsigned bits = get_mode_size_bits(orig_mode);
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
	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)
{
Matthias Braun's avatar
Matthias Braun committed
218
219
	(void)transformed_node;
	(void)mode;
220
221
222
223
	/* TODO */
	return false;
}

Michael Beck's avatar
Michael Beck committed
224
225
226
/**
 * Transforms a Conv node.
 *
227
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
228
 */
229
230
static ir_node *gen_Conv(ir_node *node)
{
231
	ir_node  *block    = be_transform_nodes_block(node);
232
233
234
235
236
237
238
239
240
241
	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)) {
242
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
243
244
			if (mode_is_float(src_mode)) {
				if (mode_is_float(dst_mode)) {
Michael Beck's avatar
Michael Beck committed
245
					/* from float to float */
246
					return new_bd_arm_Mvf(dbg, block, new_op, dst_mode);
247
				} else {
Michael Beck's avatar
Michael Beck committed
248
					/* from float to int */
249
					panic("TODO");
Michael Beck's avatar
Michael Beck committed
250
				}
251
			} else {
Michael Beck's avatar
Michael Beck committed
252
				/* from int to float */
253
254
255
256
257
				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
258
			}
259
		} else {
260
			panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
261
		}
262
	} else { /* complete in gp registers */
Matthias Braun's avatar
Matthias Braun committed
263
264
		unsigned src_bits = get_mode_size_bits(src_mode);
		unsigned dst_bits = get_mode_size_bits(dst_mode);
Michael Beck's avatar
Michael Beck committed
265
		if (src_bits == dst_bits) {
Michael Beck's avatar
Michael Beck committed
266
			/* kill unnecessary conv */
Michael Beck's avatar
Michael Beck committed
267
			return new_op;
268
269
		}

Matthias Braun's avatar
Matthias Braun committed
270
271
		unsigned min_bits;
		ir_mode *min_mode;
272
273
274
		if (src_bits < dst_bits) {
			min_bits = src_bits;
			min_mode = src_mode;
Michael Beck's avatar
Michael Beck committed
275
		} else {
276
277
278
279
280
281
282
283
284
285
286
287
			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);
288
289
290
291
		}
	}
}

292
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
293
294
	uint8_t imm_8;
	uint8_t rot;
295
296
} arm_immediate_t;

297
static bool try_encode_val_as_immediate(uint32_t val, arm_immediate_t *const res)
298
299
300
301
302
{
	if (val <= 0xff) {
		res->imm_8 = val;
		res->rot   = 0;
		return true;
Michael Beck's avatar
Michael Beck committed
303
	}
304
305
306
307
308
309
310
	/* 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.
	 */
Matthias Braun's avatar
Matthias Braun committed
311
312
	unsigned low_pos  = ntz(val) & ~1u;
	unsigned high_pos = (32-nlz(val)+1) & ~1u;
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

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

332
333
334
335
typedef enum imm_match_t {
	IMM_NONE = 0,
	IMM_POS  = 1 << 0,
	IMM_NOT  = 1 << 1,
336
	IMM_NEG  = 1 << 2,
337
} imm_match_t;
338

339
static imm_match_t try_encode_as_immediate(ir_node const *const node, arm_immediate_t *const res, imm_match_t const match)
340
341
{
	if (!is_Const(node))
342
		return IMM_NONE;
343
	uint32_t const val = get_Const_long(node);
344
345
346
	return
		match & IMM_POS && try_encode_val_as_immediate( val, res) ? IMM_POS :
		match & IMM_NOT && try_encode_val_as_immediate(~val, res) ? IMM_NOT :
347
		match & IMM_NEG && try_encode_val_as_immediate(-val, res) ? IMM_NEG :
348
		IMM_NONE;
349
350
}

351
352
typedef enum {
	MATCH_NONE         = 0,
Michael Beck's avatar
Michael Beck committed
353
	MATCH_COMMUTATIVE  = 1 << 0,  /**< commutative node */
Michael Beck's avatar
Michael Beck committed
354
355
	MATCH_REVERSE      = 1 << 1,  /**< support reverse opcode */
	MATCH_SIZE_NEUTRAL = 1 << 2,
356
} match_flags_t;
357
ENUM_BITSET(match_flags_t)
358

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

Matthias Braun's avatar
Matthias Braun committed
373
374
375
static ir_node *gen_int_binop_ops(ir_node *node, ir_node *op1, ir_node *op2,
                                  match_flags_t flags,
                                  const arm_binop_factory_t *factory)
376
{
377
	ir_node  *block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
378
	dbg_info *dbgi  = get_irn_dbg_info(node);
379
380

	if (flags & MATCH_SIZE_NEUTRAL) {
381
382
		op1 = be_skip_downconv(op1, true);
		op2 = be_skip_downconv(op2, true);
383
384
	} else {
		assert(get_mode_size_bits(get_irn_mode(node)) == 32);
385
386
		op1 = be_skip_sameconv(op1);
		op2 = be_skip_sameconv(op2);
387
388
	}

Matthias Braun's avatar
Matthias Braun committed
389
	arm_immediate_t imm;
390
	if (try_encode_as_immediate(op2, &imm, IMM_POS) != IMM_NONE) {
Matthias Braun's avatar
Matthias Braun committed
391
		ir_node *new_op1 = be_transform_node(op1);
Michael Beck's avatar
Michael Beck committed
392
		return factory->new_binop_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
393
	}
Matthias Braun's avatar
Matthias Braun committed
394
	ir_node *new_op2 = be_transform_node(op2);
395
    if ((flags & (MATCH_COMMUTATIVE|MATCH_REVERSE)) && try_encode_as_immediate(op1, &imm, IMM_POS) != IMM_NONE) {
Michael Beck's avatar
Michael Beck committed
396
397
398
399
		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);
400
	}
Matthias Braun's avatar
Matthias Braun committed
401
	ir_node *new_op1 = be_transform_node(op1);
402

Michael Beck's avatar
Michael Beck committed
403
404
405
406
407
408
409
410
411
412
413
	/* 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) {
414
				ir_node *mov_op = get_irn_n(new_op2, n_arm_Mov_Rm);
Michael Beck's avatar
Michael Beck committed
415
416
417
418
419
420
421
422
423
424
				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) {
425
426
				ir_node *mov_op  = get_irn_n(new_op2, n_arm_Mov_Rm);
				ir_node *mov_sft = get_irn_n(new_op2, n_arm_Mov_Rs);
Michael Beck's avatar
Michael Beck committed
427
428
429
430
				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
431
432
433
434
435
		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
436
437
		}
	}
Michael Beck's avatar
Michael Beck committed
438
	if ((flags & (MATCH_COMMUTATIVE|MATCH_REVERSE)) && is_arm_Mov(new_op1)) {
Michael Beck's avatar
Michael Beck committed
439
		const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(new_op1);
Michael Beck's avatar
Michael Beck committed
440
		int idx = flags & MATCH_REVERSE ? 1 : 0;
Michael Beck's avatar
Michael Beck committed
441
442
443
444
445
446
447

		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:
Michael Beck's avatar
Michael Beck committed
448
			if (factory[idx].new_binop_reg_shift_imm) {
449
				ir_node *mov_op = get_irn_n(new_op1, n_arm_Mov_Rm);
Michael Beck's avatar
Michael Beck committed
450
				return factory[idx].new_binop_reg_shift_imm(dbgi, block, new_op2, mov_op,
Michael Beck's avatar
Michael Beck committed
451
452
453
454
455
456
457
458
					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
459
			if (factory[idx].new_binop_reg_shift_reg) {
460
461
				ir_node *mov_op  = get_irn_n(new_op1, n_arm_Mov_Rm);
				ir_node *mov_sft = get_irn_n(new_op1, n_arm_Mov_Rs);
Michael Beck's avatar
Michael Beck committed
462
				return factory[idx].new_binop_reg_shift_reg(dbgi, block, new_op2, mov_op, mov_sft,
Michael Beck's avatar
Michael Beck committed
463
464
465
					attr->shift_modifier);
			}
			break;
Matthias Braun's avatar
Matthias Braun committed
466
467
468
469
470
471

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
472
473
474
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
475
}
476

Matthias Braun's avatar
Matthias Braun committed
477
478
479
480
481
482
483
484
static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
                              const arm_binop_factory_t *factory)
{
	ir_node *op1 = get_binop_left(node);
	ir_node *op2 = get_binop_right(node);
	return gen_int_binop_ops(node, op1, op2, flags, factory);
}

485
486
487
488
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2,
                        bool negate_op)
{
	dbg_info *dbgi    = get_irn_dbg_info(node);
489
	ir_node  *block   = be_transform_nodes_block(node);
490
491
492
493
494
495
496
497
498
499
500
501
	ir_node  *new_op1 = be_transform_node(op1);
	if (is_Const(op2)) {
		ir_tarval *tv   = get_Const_tarval(op2);
		ir_mode   *mode = get_irn_mode(node);
		long       bits = get_mode_size_bits(mode);
		if (tarval_is_long(tv) && bits == 32) {
			long val = get_tarval_long(tv);
			val = (negate_op ? bits - val : val) & 31;
			return new_bd_arm_Mov_reg_shift_imm(dbgi, block, new_op1, ARM_SHF_ROR_IMM, val);
		}
	}

Matthias Braun's avatar
Matthias Braun committed
502
	ir_node *new_op2 = be_transform_node(op2);
503
504
505
506
507
508
509
	if (negate_op) {
		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);
}

Matthias Braun's avatar
Matthias Braun committed
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
static bool is_low_mask(ir_tarval *tv)
{
	return get_tarval_popcount(tv) == 16 && get_tarval_highest_bit(tv) == 15;
}

static bool is_high_mask(ir_tarval *tv)
{
	return get_tarval_popcount(tv) == 16 && get_tarval_lowest_bit(tv) == 16;
}

static ir_node *match_pkh(ir_node *node)
{
	assert(is_Or(node) || is_Add(node));
	ir_node *left  = get_binop_left(node);
	ir_node *right = get_binop_right(node);
	if (!is_And(left) || !is_And(right))
		return NULL;
	ir_node *left_right  = get_And_right(left);
	ir_node *right_right = get_And_right(right);
	if (!is_Const(left_right) || !is_Const(right_right))
		return NULL;
	/* we want the low-mask on the right side */
	if (is_high_mask(get_Const_tarval(left_right))) {
		ir_node *tmp = left;
yb9976's avatar
yb9976 committed
534
535
		left       = right;
		right      = tmp;
Matthias Braun's avatar
Matthias Braun committed
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
		left_right = right_right;
	} else if (!is_high_mask(get_Const_tarval(right_right))) {
		return NULL;
	}
	if (!is_low_mask(get_Const_tarval(left_right)))
		return NULL;
	ir_node *left_left  = get_And_left(left);
	ir_node *right_left = get_And_left(right);
	static const arm_binop_factory_t pkhbt_pkhtb_factory[2] = {
		{
			new_bd_arm_Pkhbt_reg,
			new_bd_arm_Pkhbt_imm,
			new_bd_arm_Pkhbt_reg_shift_reg,
			new_bd_arm_Pkhbt_reg_shift_imm
		},
		{
			new_bd_arm_Pkhtb_reg,
			new_bd_arm_Pkhtb_imm,
			new_bd_arm_Pkhtb_reg_shift_reg,
			new_bd_arm_Pkhtb_reg_shift_imm
		}
	};
	return gen_int_binop_ops(node, left_left, right_left, MATCH_REVERSE,
	                         pkhbt_pkhtb_factory);
}

562
/**
563
 * Creates an ARM Add.
564
565
566
 *
 * @return the created arm Add node
 */
567
568
static ir_node *gen_Add(ir_node *node)
{
569
570
571
572
573
574
575
	ir_node *rotl_left;
	ir_node *rotl_right;
	if (be_pattern_is_rotl(node, &rotl_left, &rotl_right)) {
		if (is_Minus(rotl_right))
			return gen_Ror(node, rotl_left, get_Minus_op(rotl_right), false);
		return gen_Ror(node, rotl_left, rotl_right, true);
	}
Matthias Braun's avatar
Matthias Braun committed
576
577
578
	ir_node *pkh = match_pkh(node);
	if (pkh != NULL)
		return pkh;
579

Michael Beck's avatar
Michael Beck committed
580
	ir_mode *mode = get_irn_mode(node);
581
	if (mode_is_float(mode)) {
582
		ir_node  *block   = be_transform_nodes_block(node);
583
584
585
586
587
		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);
588
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
589
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
590
		} else {
591
			panic("softfloat not lowered");
592
593
		}
	} else {
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
		ir_node *left  = get_Add_left(node);
		ir_node *right = get_Add_right(node);
		ir_node *mul_left;
		ir_node *mul_right;
		ir_node *other;
		if (is_Mul(left)) {
			mul_left  = get_Mul_left(left);
			mul_right = get_Mul_right(left);
			other     = right;
			goto create_mla;
		} else if (is_Mul(right)) {
			mul_left  = get_Mul_left(right);
			mul_right = get_Mul_right(right);
			other     = left;
create_mla:;
			dbg_info *dbgi      = get_irn_dbg_info(node);
610
			ir_node  *block     = be_transform_nodes_block(node);
611
612
613
614
			ir_node  *new_left  = be_transform_node(mul_left);
			ir_node  *new_right = be_transform_node(mul_right);
			ir_node  *new_add   = be_transform_node(other);
			if (arm_cg_config.variant < ARM_VARIANT_6)
615
				return new_bd_arm_Mla_v5(dbgi, block, new_left, new_right, new_add);
616
617
618
619
620
			else
				return new_bd_arm_Mla(dbgi, block, new_left, new_right,
				                      new_add);
		}

621
622
623
624
625
626
627
628
		arm_immediate_t imm;
		if (try_encode_as_immediate(right, &imm, IMM_NEG) != IMM_NONE) {
			dbg_info *const dbgi     = get_irn_dbg_info(node);
			ir_node  *const block    = be_transform_nodes_block(node);
			ir_node  *const new_left = be_transform_node(left);
			return new_bd_arm_Sub_imm(dbgi, block, new_left, imm.imm_8, imm.rot);
		}

629
630
631
632
633
634
635
636
637
		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
		};
		return gen_int_binop_ops(node, left, right,
		                         MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
		                         &add_factory);
Michael Beck's avatar
Michael Beck committed
638
639
	}
}
640

Matthias Braun's avatar
Matthias Braun committed
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
static ir_node *gen_arm_AddS_t(ir_node *node)
{
	static const arm_binop_factory_t adds_factory = {
		new_bd_arm_AddS_reg,
		new_bd_arm_AddS_imm,
		new_bd_arm_AddS_reg_shift_reg,
		new_bd_arm_AddS_reg_shift_imm,
	};
	ir_node *left  = get_irn_n(node, n_arm_AddS_t_left);
	ir_node *right = get_irn_n(node, n_arm_AddS_t_right);
	ir_node *res   = gen_int_binop_ops(node, left, right,
	                                   MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
	                                   &adds_factory);
	arch_set_irn_register_out(res, pn_arm_AddS_flags, &arm_registers[REG_FL]);
	return res;
}

static ir_node *gen_Proj_arm_AddS_t(ir_node *node)
{
660
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
661
662
663
664
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);
	switch ((pn_arm_AddS_t)pn) {
	case pn_arm_AddS_t_res:
665
		return be_new_Proj(new_pred, pn_arm_AddS_res);
Matthias Braun's avatar
Matthias Braun committed
666
	case pn_arm_AddS_t_flags:
667
		return be_new_Proj(new_pred, pn_arm_AddS_flags);
Matthias Braun's avatar
Matthias Braun committed
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
	}
	panic("%+F: Invalid proj number", node);
}

static ir_node *gen_arm_AdC_t(ir_node *node)
{
	ir_node *left  = get_irn_n(node, n_arm_AdC_t_left);
	ir_node *right = get_irn_n(node, n_arm_AdC_t_right);
	ir_node *flags = get_irn_n(node, n_arm_AdC_t_flags);
	/* TODO: handle complete set of shifter operands */
	ir_node *new_left  = be_transform_node(left);
	ir_node *new_right = be_transform_node(right);
	ir_node *new_flags = be_transform_node(flags);

	dbg_info *dbgi      = get_irn_dbg_info(node);
683
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
684
685
686
687
688
	ir_node  *res       = new_bd_arm_AdC_reg(dbgi, new_block, new_left,
	                                         new_right, new_flags);
	return res;
}

689
/**
690
 * Creates an ARM Mul.
691
692
693
 *
 * @return the created arm Mul node
 */
694
695
static ir_node *gen_Mul(ir_node *node)
{
696
	ir_node  *block   = be_transform_nodes_block(node);
697
698
699
700
701
702
	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
703

704
	if (mode_is_float(mode)) {
705
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
706
			return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
707
		} else {
708
			panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
709
		}
710
	}
711
	assert(mode_is_data(mode));
712
	if (arm_cg_config.variant < ARM_VARIANT_6) {
713
		return new_bd_arm_Mul_v5(dbg, block, new_op1, new_op2);
714
715
716
	} else {
		return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
	}
717
718
}

Matthias Braun's avatar
Matthias Braun committed
719
720
static ir_node *gen_arm_UMulL_t(ir_node *node)
{
721
	ir_node  *block     = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
722
723
724
725
726
727
728
729
730
731
	ir_node  *left      = get_irn_n(node, n_arm_UMulL_t_left);
	ir_node  *new_left  = be_transform_node(left);
	ir_node  *right     = get_irn_n(node, n_arm_UMulL_t_right);
	ir_node  *new_right = be_transform_node(right);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	return new_bd_arm_UMulL(dbgi, block, new_left, new_right);
}

static ir_node *gen_Proj_arm_UMulL_t(ir_node *node)
{
732
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
733
734
735
736
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);
	switch ((pn_arm_UMulL_t)pn) {
	case pn_arm_UMulL_t_low:
737
		return be_new_Proj(new_pred, pn_arm_UMulL_low);
Matthias Braun's avatar
Matthias Braun committed
738
	case pn_arm_UMulL_t_high:
739
		return be_new_Proj(new_pred, pn_arm_UMulL_high);
Matthias Braun's avatar
Matthias Braun committed
740
741
742
743
	}
	panic("%+F: Invalid proj number", node);
}

744
static ir_node *gen_Div(ir_node *node)
745
{
746
	ir_node  *block   = be_transform_nodes_block(node);
747
	ir_node  *op1     = get_Div_left(node);
748
	ir_node  *new_op1 = be_transform_node(op1);
749
	ir_node  *op2     = get_Div_right(node);
750
	ir_node  *new_op2 = be_transform_node(op2);
751
	ir_mode  *mode    = get_Div_resmode(node);
752
	dbg_info *dbg     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
753

754
755
	/* integer division should be replaced by builtin call */
	assert(mode_is_float(mode));
756

757
	if (arm_cg_config.fpu == ARM_FPU_FPA) {
758
		return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
759
	} else {
760
		panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
761
	}
Michael Beck's avatar
Michael Beck committed
762
763
}

764
765
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
766
767
768
769
770
771
	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
772
773
774
775
776
777
778
779
	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 */
780
	arm_immediate_t imm;
Michael Beck's avatar
Michael Beck committed
781
782
	ir_node *left  = get_And_left(node);
	ir_node *right = get_And_right(node);
Matthias Braun's avatar
Matthias Braun committed
783
784
785
786
787
788
789
790
	if (is_Not(right)) {
		ir_node *right_not = get_Not_op(right);
		return gen_int_binop_ops(node, left, right_not, MATCH_SIZE_NEUTRAL,
		                         &bic_factory);
	} else if (is_Not(left)) {
		ir_node *left_not = get_Not_op(left);
		return gen_int_binop_ops(node, right, left_not, MATCH_SIZE_NEUTRAL,
		                         &bic_factory);
791
	} else if (try_encode_as_immediate(right, &imm, IMM_NOT) != IMM_NONE) {
792
793
794
795
		dbg_info *const dbgi  = get_irn_dbg_info(node);
		ir_node  *const block = be_transform_nodes_block(node);
		ir_node  *const new_l = be_transform_node(left);
		return new_bd_arm_Bic_imm(dbgi, block, new_l, imm.imm_8, imm.rot);
Matthias Braun's avatar
Matthias Braun committed
796
797
798
	} else {
		return gen_int_binop(node, MATCH_COMMUTATIVE|MATCH_SIZE_NEUTRAL,
		                     &and_factory);
Michael Beck's avatar
Michael Beck committed
799
	}
800
}
801

802
803
static ir_node *gen_Or(ir_node *node)
{
804
805
806
807
808
809
810
	ir_node *rotl_left;
	ir_node *rotl_right;
	if (be_pattern_is_rotl(node, &rotl_left, &rotl_right)) {
		if (is_Minus(rotl_right))
			return gen_Ror(node, rotl_left, get_Minus_op(rotl_right), false);
		return gen_Ror(node, rotl_left, rotl_right, true);
	}
Matthias Braun's avatar
Matthias Braun committed
811
812
813
	ir_node *pkh = match_pkh(node);
	if (pkh != NULL)
		return pkh;
814

Michael Beck's avatar
Michael Beck committed
815
816
817
818
819
820
821
	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);
822
}
823

Matthias Braun's avatar
Matthias Braun committed
824
825
826
827
828
829
830
831
832
833
834
835
836
static ir_node *gen_arm_OrPl_t(ir_node *node)
{
	ir_node *left     = get_irn_n(node, n_arm_OrPl_t_left);
	ir_node *right    = get_irn_n(node, n_arm_OrPl_t_right);
	ir_node *falseval = get_irn_n(node, n_arm_OrPl_t_falseval);
	ir_node *flags    = get_irn_n(node, n_arm_OrPl_t_flags);
	/* TODO: handle complete set of shifter operands */
	ir_node *new_left     = be_transform_node(left);
	ir_node *new_right    = be_transform_node(right);
	ir_node *new_falseval = be_transform_node(falseval);
	ir_node *new_flags    = be_transform_node(flags);

	dbg_info *dbgi      = get_irn_dbg_info(node);
837
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
838
839
840
841
842
	ir_node  *res       = new_bd_arm_OrPl(dbgi, new_block, new_left, new_right,
	                                      new_falseval, new_flags);
	return res;
}

843
844
static ir_node *gen_Eor(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
845
846
847
848
849
850
	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
	};
Matthias Braun's avatar
Matthias Braun committed
851
852
	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
	                     &eor_factory);
853
}
854

855
856
static ir_node *gen_Sub(ir_node *node)
{
857
858
859
	ir_mode *mode  = get_irn_mode(node);
	ir_node *left  = get_Sub_left(node);
	ir_node *right = get_Sub_right(node);
860
	if (mode_is_float(mode)) {
861
		ir_node  *block     = be_transform_nodes_block(node);
862
863
864
865
		ir_node  *new_left  = be_transform_node(left);
		ir_node  *new_right = be_transform_node(right);
		dbg_info *dbgi      = get_irn_dbg_info(node);

866
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
867
			return new_bd_arm_Suf(dbgi, block, new_left, new_right, mode);
868
		} else {
869
			panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
870
		}
871
	} else {
872
873
		if (is_Mul(right) && arm_cg_config.variant >= ARM_VARIANT_6T2) {
			dbg_info *dbgi      = get_irn_dbg_info(node);
874
			ir_node  *block     = be_transform_nodes_block(node);
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
			ir_node  *mul_left  = get_Mul_left(right);
			ir_node  *mul_right = get_Mul_right(right);
			ir_node  *new_left  = be_transform_node(mul_left);
			ir_node  *new_right = be_transform_node(mul_right);
			ir_node  *new_sub   = be_transform_node(left);
			return new_bd_arm_Mls(dbgi, block, new_left, new_right, new_sub);
		}

		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
897
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL | MATCH_REVERSE, sub_rsb_factory);
Michael Beck's avatar
Michael Beck committed
898
	}
899
}
Michael Beck's avatar
Michael Beck committed
900

Matthias Braun's avatar
Matthias Braun committed
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
static ir_node *gen_arm_SubS_t(ir_node *node)
{
	static const arm_binop_factory_t subs_factory[2] = {
		{
			new_bd_arm_SubS_reg,
			new_bd_arm_SubS_imm,
			new_bd_arm_SubS_reg_shift_reg,
			new_bd_arm_SubS_reg_shift_imm,
		},
		{
			new_bd_arm_RsbS_reg,
			new_bd_arm_RsbS_imm,
			new_bd_arm_RsbS_reg_shift_reg,
			new_bd_arm_RsbS_reg_shift_imm,
		},
	};
	ir_node *left  = get_irn_n(node, n_arm_SubS_t_left);
	ir_node *right = get_irn_n(node, n_arm_SubS_t_right);
	ir_node *res   = gen_int_binop_ops(node, left, right,
	                                   MATCH_SIZE_NEUTRAL | MATCH_REVERSE,
	                                   subs_factory);
	assert((int)pn_arm_SubS_flags == (int)pn_arm_RsbS_flags);
	arch_set_irn_register_out(res, pn_arm_SubS_flags, &arm_registers[REG_FL]);
	return res;
}

static ir_node *gen_Proj_arm_SubS_t(ir_node *node)
{
929
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
930
931
932
933
934
935
	ir_node *pred     = get_Proj_pred(node);
	ir_node *new_pred = be_transform_node(pred);
	assert((int)pn_arm_SubS_flags == (int)pn_arm_RsbS_flags);
	assert((int)pn_arm_SubS_res == (int)pn_arm_RsbS_res);
	switch ((pn_arm_SubS_t)pn) {
	case pn_arm_SubS_t_res:
936
		return be_new_Proj(new_pred, pn_arm_SubS_res);
Matthias Braun's avatar
Matthias Braun committed
937
	case pn_arm_SubS_t_flags:
938
		return be_new_Proj(new_pred, pn_arm_SubS_flags);
Matthias Braun's avatar
Matthias Braun committed
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
	}
	panic("%+F: Invalid proj number", node);
}

static ir_node *gen_arm_SbC_t(ir_node *node)
{
	ir_node *left  = get_irn_n(node, n_arm_SbC_t_left);
	ir_node *right = get_irn_n(node, n_arm_SbC_t_right);
	ir_node *flags = get_irn_n(node, n_arm_SbC_t_flags);
	/* TODO: handle complete set of shifter operands */
	ir_node *new_left  = be_transform_node(left);
	ir_node *new_right = be_transform_node(right);
	ir_node *new_flags = be_transform_node(flags);

	dbg_info *dbgi      = get_irn_dbg_info(node);
954
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
955
956
957
958
959
	ir_node  *res       = new_bd_arm_SbC_reg(dbgi, new_block, new_left,
	                                         new_right, new_flags);
	return res;
}

Michael Beck's avatar
Michael Beck committed
960
961
962
963
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
964
965
966
967
968
969
970
971
972
973
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
974
975
976
977
978
979
980
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
981
static ir_node *make_shift(ir_node *node, match_flags_t flags,
982
		arm_shift_modifier_t shift_modifier)
983
{
984
	ir_node  *block = be_transform_nodes_block(node);
985
986
987
	ir_node  *op1   = get_binop_left(node);
	ir_node  *op2   = get_binop_right(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
988
	ir_mode  *mode  = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
989
990
	if (get_mode_modulo_shift(mode) != 256)
		panic("modulo shift!=256 not supported");
991

992
	if (flags & MATCH_SIZE_NEUTRAL) {
993
994
		op1 = be_skip_downconv(op1, true);
		op2 = be_skip_downconv(op2, true);
995
	}
996

Matthias Braun's avatar
Matthias Braun committed
997
	ir_node *new_op1 = be_transform_node(op1);
998
	if (is_Const(op2)) {
999
		unsigned int const val = get_Const_long(op2);
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
		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);
		}
	}

Matthias Braun's avatar
Matthias Braun committed
1013
	ir_node *new_op2 = be_transform_node(op2);
1014
1015
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
1016
1017
}

1018
1019
1020
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
1021
1022
}

1023
1024
1025
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
1026
1027
}

1028
1029
1030
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
1031
1032
}

1033
1034
static ir_node *gen_Not(ir_node *node)
{
1035
	ir_node  *block  = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1036
1037
1038
	ir_node  *op     = get_Not_op(node);
	ir_node  *new_op = be_transform_node(op);
	dbg_info *dbgi   = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
1039

Michael Beck's avatar
Michael Beck committed
1040
1041
1042
1043
1044
1045
1046
1047
1048
	/* 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) {
		case ARM_SHF_IMM:
		case ARM_SHF_ASR_IMM:
		case ARM_SHF_LSL_IMM:
		case ARM_SHF_LSR_IMM:
Matthias Braun's avatar
Matthias Braun committed
1049
		case ARM_SHF_ROR_IMM: {
1050
			ir_node *mov_op = get_irn_n(new_op, n_arm_Mov_Rm);
Michael Beck's avatar
Michael Beck committed
1051
1052
			return new_bd_arm_Mvn_reg_shift_imm(dbgi, block, mov_op,
				attr->shift_modifier, attr->shift_immediate);
Matthias Braun's avatar
Matthias Braun committed
1053
		}
Michael Beck's avatar
Michael Beck committed
1054
1055
1056
1057

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
Matthias Braun's avatar
Matthias Braun committed
1058
		case ARM_SHF_ROR_REG: {
1059
1060
			ir_node *mov_op  = get_irn_n(new_op, n_arm_Mov_Rm);
			ir_node *mov_sft = get_irn_n(new_op, n_arm_Mov_Rs);
Michael Beck's avatar
Michael Beck committed
1061
1062
			return new_bd_arm_Mvn_reg_shift_reg(dbgi, block, mov_op, mov_sft,
				attr->shift_modifier);
Matthias Braun's avatar
Matthias Braun committed
1063
		}
Matthias Braun's avatar
Matthias Braun committed
1064
1065
1066
1067
1068
1069

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
1070
1071
		}
	}
1072
1073

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
1074
1075
}

1076
1077
static ir_node *gen_Minus(ir_node *node)
{
1078
	ir_node  *block  = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1079
1080
1081
1082
	ir_node  *op     = get_Minus_op(node);
	ir_node  *new_op = be_transform_node(op);
	dbg_info *dbgi   = get_irn_dbg_info(node);
	ir_mode  *mode   = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
1083

1084
	if (mode_is_float(mode)) {
1085
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
1086
			return new_bd_arm_Mvf(dbgi, block, op, mode);
1087
		} else {
1088
			panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
1089
		}
1090
	}
1091
	assert(mode_is_data(mode));
1092
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
1093
1094
}

1095
1096
static ir_node *gen_Load(ir_node *node)
{
1097
	ir_node  *block   = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1098
1099
1100
1101
1102
1103
	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);
	dbg_info *dbgi    = get_irn_dbg_info(node);
1104
	if (get_Load_unaligned(node) == align_non_aligned)