arm_transform.c 63.5 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
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
16
#include "iredges_t.h"
17
18
19
20
#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_stack_env_t         stack_env;
44
45
static calling_convention_t  *cconv = NULL;

46
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
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],
};

75
76
77
78
79
static ir_node *get_initial_sp(ir_graph *const irg)
{
	return be_get_Start_proj(irg, &arm_registers[REG_SP]);
}

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

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

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

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

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

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

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

200
201
202
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
203
	unsigned bits = get_mode_size_bits(orig_mode);
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	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
222
223
	(void)transformed_node;
	(void)mode;
224
225
226
227
	/* TODO */
	return false;
}

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

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

296
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
297
298
	uint8_t imm_8;
	uint8_t rot;
299
300
} arm_immediate_t;

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

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

336
337
338
339
typedef enum imm_match_t {
	IMM_NONE = 0,
	IMM_POS  = 1 << 0,
	IMM_NOT  = 1 << 1,
340
	IMM_NEG  = 1 << 2,
341
} imm_match_t;
342

343
static imm_match_t try_encode_as_immediate(ir_node const *const node, arm_immediate_t *const res, imm_match_t const match)
344
345
{
	if (!is_Const(node))
346
		return IMM_NONE;
347
	uint32_t const val = get_Const_long(node);
348
349
350
	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 :
351
		match & IMM_NEG && try_encode_val_as_immediate(-val, res) ? IMM_NEG :
352
		IMM_NONE;
353
354
}

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

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

Matthias Braun's avatar
Matthias Braun committed
377
378
379
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)
380
{
381
	ir_node  *block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
382
	dbg_info *dbgi  = get_irn_dbg_info(node);
383
384

	if (flags & MATCH_SIZE_NEUTRAL) {
385
386
		op1 = be_skip_downconv(op1, true);
		op2 = be_skip_downconv(op2, true);
387
388
	} else {
		assert(get_mode_size_bits(get_irn_mode(node)) == 32);
389
390
		op1 = be_skip_sameconv(op1);
		op2 = be_skip_sameconv(op2);
391
392
	}

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

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

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

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
476
477
478
		}
	}
	return factory->new_binop_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
479
}
480

Matthias Braun's avatar
Matthias Braun committed
481
482
483
484
485
486
487
488
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);
}

489
490
491
492
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);
493
	ir_node  *block   = be_transform_nodes_block(node);
494
495
496
497
498
499
500
501
502
503
504
505
	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
506
	ir_node *new_op2 = be_transform_node(op2);
507
508
509
510
511
512
513
	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
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
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
538
539
		left       = right;
		right      = tmp;
Matthias Braun's avatar
Matthias Braun committed
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
		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);
}

566
/**
567
 * Creates an ARM Add.
568
569
570
 *
 * @return the created arm Add node
 */
571
572
static ir_node *gen_Add(ir_node *node)
{
573
574
575
576
577
578
579
	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
580
581
582
	ir_node *pkh = match_pkh(node);
	if (pkh != NULL)
		return pkh;
583

Michael Beck's avatar
Michael Beck committed
584
	ir_mode *mode = get_irn_mode(node);
585
	if (mode_is_float(mode)) {
586
		ir_node  *block   = be_transform_nodes_block(node);
587
588
589
590
591
		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);
592
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
593
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
594
		} else {
595
			panic("softfloat not lowered");
596
597
		}
	} else {
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
		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);
614
			ir_node  *block     = be_transform_nodes_block(node);
615
616
617
618
			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)
619
				return new_bd_arm_Mla_v5(dbgi, block, new_left, new_right, new_add);
620
621
622
623
624
			else
				return new_bd_arm_Mla(dbgi, block, new_left, new_right,
				                      new_add);
		}

625
626
627
628
629
630
631
632
		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);
		}

633
634
635
636
637
638
639
640
641
		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
642
643
	}
}
644

Matthias Braun's avatar
Matthias Braun committed
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
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)
{
664
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
665
666
667
668
	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:
669
		return be_new_Proj(new_pred, pn_arm_AddS_res);
Matthias Braun's avatar
Matthias Braun committed
670
	case pn_arm_AddS_t_flags:
671
		return be_new_Proj(new_pred, pn_arm_AddS_flags);
Matthias Braun's avatar
Matthias Braun committed
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
	}
	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);
687
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
688
689
690
691
692
	ir_node  *res       = new_bd_arm_AdC_reg(dbgi, new_block, new_left,
	                                         new_right, new_flags);
	return res;
}

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

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

Matthias Braun's avatar
Matthias Braun committed
723
724
static ir_node *gen_arm_UMulL_t(ir_node *node)
{
725
	ir_node  *block     = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
726
727
728
729
730
731
732
733
734
735
	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)
{
736
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
737
738
739
740
	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:
741
		return be_new_Proj(new_pred, pn_arm_UMulL_low);
Matthias Braun's avatar
Matthias Braun committed
742
	case pn_arm_UMulL_t_high:
743
		return be_new_Proj(new_pred, pn_arm_UMulL_high);
Matthias Braun's avatar
Matthias Braun committed
744
745
746
747
	}
	panic("%+F: Invalid proj number", node);
}

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

758
759
	/* integer division should be replaced by builtin call */
	assert(mode_is_float(mode));
760

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

768
769
static ir_node *gen_And(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
770
771
772
773
774
775
	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
776
777
778
779
780
781
782
783
	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 */
784
	arm_immediate_t imm;
Michael Beck's avatar
Michael Beck committed
785
786
	ir_node *left  = get_And_left(node);
	ir_node *right = get_And_right(node);
Matthias Braun's avatar
Matthias Braun committed
787
788
789
790
791
792
793
794
	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);
795
	} else if (try_encode_as_immediate(right, &imm, IMM_NOT) != IMM_NONE) {
796
797
798
799
		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
800
801
802
	} else {
		return gen_int_binop(node, MATCH_COMMUTATIVE|MATCH_SIZE_NEUTRAL,
		                     &and_factory);
Michael Beck's avatar
Michael Beck committed
803
	}
804
}
805

806
807
static ir_node *gen_Or(ir_node *node)
{
808
809
810
811
812
813
814
	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
815
816
817
	ir_node *pkh = match_pkh(node);
	if (pkh != NULL)
		return pkh;
818

Michael Beck's avatar
Michael Beck committed
819
820
821
822
823
824
825
	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);
826
}
827

Matthias Braun's avatar
Matthias Braun committed
828
829
830
831
832
833
834
835
836
837
838
839
840
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);
841
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
842
843
844
845
846
	ir_node  *res       = new_bd_arm_OrPl(dbgi, new_block, new_left, new_right,
	                                      new_falseval, new_flags);
	return res;
}

847
848
static ir_node *gen_Eor(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
849
850
851
852
853
854
	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
855
856
	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
	                     &eor_factory);
857
}
858

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

870
		if (arm_cg_config.fpu == ARM_FPU_FPA) {
871
			return new_bd_arm_Suf(dbgi, block, new_left, new_right, mode);
872
		} else {
873
			panic("softfloat not lowered");
Michael Beck's avatar
Michael Beck committed
874
		}
875
	} else {
876
877
		if (is_Mul(right) && arm_cg_config.variant >= ARM_VARIANT_6T2) {
			dbg_info *dbgi      = get_irn_dbg_info(node);
878
			ir_node  *block     = be_transform_nodes_block(node);
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
			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
901
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL | MATCH_REVERSE, sub_rsb_factory);
Michael Beck's avatar
Michael Beck committed
902
	}
903
}
Michael Beck's avatar
Michael Beck committed
904

Matthias Braun's avatar
Matthias Braun committed
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
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)
{
933
	unsigned pn       = get_Proj_num(node);
Matthias Braun's avatar
Matthias Braun committed
934
935
936
937
938
939
	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:
940
		return be_new_Proj(new_pred, pn_arm_SubS_res);
Matthias Braun's avatar
Matthias Braun committed
941
	case pn_arm_SubS_t_flags:
942
		return be_new_Proj(new_pred, pn_arm_SubS_flags);
Matthias Braun's avatar
Matthias Braun committed
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
	}
	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);
958
	ir_node  *new_block = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
959
960
961
962
963
	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
964
965
966
967
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
968
969
970
971
972
973
974
975
976
977
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
978
979
980
981
982
983
984
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
985
static ir_node *make_shift(ir_node *node, match_flags_t flags,
986
		arm_shift_modifier_t shift_modifier)
987
{
988
	ir_node  *block = be_transform_nodes_block(node);
989
990
991
	ir_node  *op1   = get_binop_left(node);
	ir_node  *op2   = get_binop_right(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
992
	ir_mode  *mode  = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
993
994
	if (get_mode_modulo_shift(mode) != 256)
		panic("modulo shift!=256 not supported");
995

996
	if (flags & MATCH_SIZE_NEUTRAL) {
997
998
		op1 = be_skip_downconv(op1, true);
		op2 = be_skip_downconv(op2, true);
999
	}
1000

Matthias Braun's avatar
Matthias Braun committed
1001
	ir_node *new_op1 = be_transform_node(op1);
1002
	if (is_Const(op2)) {
1003
		unsigned int const val = get_Const_long(op2);
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
		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
1017
	ir_node *new_op2 = be_transform_node(op2);
1018
1019
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
1020
1021
}

1022
1023
1024
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
1025
1026
}

1027
1028
1029
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
1030
1031
}

1032
1033
1034
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
1035
1036
}

1037
1038
static ir_node *gen_Not(ir_node *node)
{
1039
	ir_node  *block  = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1040
1041
1042
	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
1043

Michael Beck's avatar
Michael Beck committed
1044
1045
1046
1047
1048
1049
1050
1051
1052
	/* 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
1053
		case ARM_SHF_ROR_IMM: {
1054
			ir_node *mov_op = get_irn_n(new_op, n_arm_Mov_Rm);
Michael Beck's avatar
Michael Beck committed
1055
1056
			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
1057
		}
Michael Beck's avatar
Michael Beck committed
1058
1059
1060
1061

		case ARM_SHF_ASR_REG:
		case ARM_SHF_LSL_REG:
		case ARM_SHF_LSR_REG:
Matthias Braun's avatar
Matthias Braun committed
1062
		case ARM_SHF_ROR_REG: {
1063
1064
			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
1065
1066
			return new_bd_arm_Mvn_reg_shift_reg(dbgi, block, mov_op, mov_sft,
				attr->shift_modifier);
Matthias Braun's avatar
Matthias Braun committed
1067
		}
Matthias Braun's avatar
Matthias Braun committed
1068
1069
1070
1071
1072
1073

		case ARM_SHF_REG:
		case ARM_SHF_RRX:
			break;
		case ARM_SHF_INVALID:
			panic("invalid shift");
Michael Beck's avatar
Michael Beck committed
1074
1075
		}
	}
1076
1077

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
1078
1079
}

1080
1081
static ir_node *gen_Minus(ir_node *node)
{
1082
	ir_node  *block  = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1083
1084
1085
1086
	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
1087

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

1099
1100
static ir_node *gen_Load(ir_node *node)
{
1101
	ir_node  *block   = be_transform_nodes_block(node);
Matthias Braun's avatar
Matthias Braun committed
1102
1103
1104
1105
1106
1107
	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);
1108
	if (get_Load_unaligned(node) == align_non_aligned)
1109
		panic("unaligned Loads not supported yet");
1110