arm_transform.c 57.2 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

20
21
/**
 * @file
Michael Beck's avatar
Michael Beck committed
22
 * @brief   The codegenerator (transform FIRM into arm FIRM)
23
 * @author  Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
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
				panic("TODO");
Michael Beck's avatar
Michael Beck committed
231
			}
232
		} else if (USE_VFP(env_cg->isa)) {
233
			panic("VFP not supported yet");
234
		} else {
235
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
236
		}
237
	} else { /* complete in gp registers */
238
239
		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
240
241
		int min_bits;
		ir_mode *min_mode;
242

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

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

268
269
270
271
272
273
274
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
275
	unsigned val, low_pos, high_pos;
276
277
278

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

280
	val = get_tarval_long(get_Const_tarval(node));
Michael Beck's avatar
Michael Beck committed
281

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

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

320
static bool is_downconv(const ir_node *node)
321
322
323
324
325
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
326
		return false;
327
328
329
330
331

	/* 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)
332
		return false;
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

	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,
	MATCH_COMMUTATIVE  = 1 << 0,
	MATCH_SIZE_NEUTRAL = 1 << 1,
} match_flags_t;

typedef ir_node* (*new_binop_reg_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, ir_node *op2);
typedef ir_node* (*new_binop_imm_func) (dbg_info *dbgi, ir_node *block, ir_node *op1, unsigned char imm8, unsigned char imm_rot);

static ir_node *gen_int_binop(ir_node *node, match_flags_t flags,
		new_binop_reg_func new_reg, new_binop_imm_func new_imm)
{
	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;

	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);
		return new_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
	}
	new_op2 = be_transform_node(op2);
    if ((flags & MATCH_COMMUTATIVE) && try_encode_as_immediate(op1, &imm)) {
		return new_imm(dbgi, block, new_op2, imm.imm_8, imm.rot);
	}
	new_op1 = be_transform_node(op1);

	return new_reg(dbgi, block, new_op1, new_op2);
Michael Beck's avatar
Michael Beck committed
387
}
388
389

/**
390
 * Creates an ARM Add.
391
392
393
 *
 * @return the created arm Add node
 */
394
395
static ir_node *gen_Add(ir_node *node)
{
396
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
397

398
	if (mode_is_float(mode)) {
399
400
401
402
403
404
		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);
405
		if (USE_FPA(env_cg->isa)) {
406
			return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
407
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
408
			assert(mode != mode_E && "IEEE Extended FP not supported");
409
			panic("VFP not supported yet");
410
		} else {
411
			panic("Softfloat not supported yet");
412
413
		}
	} else {
414
#if 0
Michael Beck's avatar
Michael Beck committed
415
		/* check for MLA */
Michael Beck's avatar
Michael Beck committed
416
		if (is_arm_Mul(new_op1) && get_irn_n_edges(op1) == 1) {
417
			new_op3 = new_op2;
Michael Beck's avatar
Michael Beck committed
418
419
			new_op2 = get_irn_n(new_op1, 1);
			new_op1 = get_irn_n(new_op1, 0);
Michael Beck's avatar
Michael Beck committed
420

421
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
422
		}
Michael Beck's avatar
Michael Beck committed
423
		if (is_arm_Mul(new_op2) && get_irn_n_edges(op2) == 1) {
424
425
426
			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
427

428
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
429
		}
430
#endif
431

432
433
		return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
				new_bd_arm_Add_reg, new_bd_arm_Add_imm);
Michael Beck's avatar
Michael Beck committed
434
435
	}
}
436
437

/**
438
 * Creates an ARM Mul.
439
440
441
 *
 * @return the created arm Mul node
 */
442
443
static ir_node *gen_Mul(ir_node *node)
{
444
445
446
447
448
449
450
	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
451

452
	if (mode_is_float(mode)) {
453
		if (USE_FPA(env_cg->isa)) {
454
			return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
455
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
456
			assert(mode != mode_E && "IEEE Extended FP not supported");
457
			panic("VFP not supported yet");
458
		} else {
459
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
460
		}
461
	}
462
	assert(mode_is_data(mode));
463
	return new_bd_arm_Mul(dbg, block, new_op1, new_op2);
464
465
}

466
467
static ir_node *gen_Quot(ir_node *node)
{
468
469
470
471
472
473
474
	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
475

476
	assert(mode != mode_E && "IEEE Extended FP not supported");
477

478
	if (USE_FPA(env_cg->isa)) {
479
		return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
480
	} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
481
		assert(mode != mode_E && "IEEE Extended FP not supported");
482
		panic("VFP not supported yet");
483
	} else {
484
		panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
485
	}
Michael Beck's avatar
Michael Beck committed
486
487
}

488
489
490
491
static ir_node *gen_And(ir_node *node)
{
	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
			new_bd_arm_And_reg, new_bd_arm_And_imm);
492
}
493

494
495
496
497
static ir_node *gen_Or(ir_node *node)
{
	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
			new_bd_arm_Or_reg, new_bd_arm_Or_imm);
498
}
499

500
501
502
503
static ir_node *gen_Eor(ir_node *node)
{
	return gen_int_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
			new_bd_arm_Eor_reg, new_bd_arm_Eor_imm);
504
}
505

506
507
static ir_node *gen_Sub(ir_node *node)
{
508
509
510
511
	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
512
	ir_node  *new_op2 = be_transform_node(op2);
513
	ir_mode  *mode    = get_irn_mode(node);
514
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
515

516
	if (mode_is_float(mode)) {
517
		if (USE_FPA(env_cg->isa)) {
518
			return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
519
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
520
			assert(mode != mode_E && "IEEE Extended FP not supported");
521
			panic("VFP not supported yet");
522
		} else {
523
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
524
		}
525
526
527
	} else {
		return gen_int_binop(node, MATCH_SIZE_NEUTRAL,
				new_bd_arm_Sub_reg, new_bd_arm_Sub_imm);
Michael Beck's avatar
Michael Beck committed
528
	}
529
}
Michael Beck's avatar
Michael Beck committed
530

Michael Beck's avatar
Michael Beck committed
531
532
533
534
/**
 * Checks if a given value can be used as an immediate for the given
 * ARM shift mode.
 */
535
536
537
538
539
540
541
542
543
544
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
545
546
547
548
549
550
551
/**
 * generate an ARM shift instruction.
 *
 * @param node            the node
 * @param flags           matching flags
 * @param shift_modifier  initial encoding of the desired shift operation
 */
552
static ir_node *make_shift(ir_node *node, match_flags_t flags,
553
		arm_shift_modifier_t shift_modifier)
554
{
555
556
557
558
	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);
559
560
561
562
563
564
	ir_node  *new_op1;
	ir_node  *new_op2;

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
565
	}
566

567
	new_op1 = be_transform_node(op1);
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
	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);
		}
	}

585
	new_op2 = be_transform_node(op2);
586
587
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
588
589
}

590
591
592
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
593
594
}

595
596
597
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
598
599
}

600
601
602
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
603
604
}

605
606
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
607
608
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
609
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
610
611
	ir_node  *new_op2 = be_transform_node(op2);

612
613
	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
614
615
}

616
617
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
618
619
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
620
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
621
622
	ir_node  *new_op2 = be_transform_node(op2);

623
	/* Note: there is no Rol on arm, we have to use Ror */
624
625
626
	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
627
628
}

629
630
static ir_node *gen_Rotl(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
631
632
633
634
635
636
637
638
639
	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
640
		ir_node *right = get_Add_right(op2);
Michael Beck's avatar
Michael Beck committed
641
642
643
644
		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
645
			ir_node *left = get_Add_left(op2);
Michael Beck's avatar
Michael Beck committed
646
647

			if (is_Minus(left) &&
Michael Beck's avatar
Michael Beck committed
648
			    tarval_is_long(tv)          &&
Michael Beck's avatar
Michael Beck committed
649
650
651
652
			    get_tarval_long(tv) == bits &&
			    bits                == 32)
				rotate = gen_Ror(node, op1, get_Minus_op(left));
		}
Michael Beck's avatar
Michael Beck committed
653
654
655
656
657
658
659
660
661
662
663
664
665
	} 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);
		}
666
	} else if (is_Const(op2)) {
667
668
669
		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
670

671
672
673
674
		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);
675

676
677
678
			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
679
680
681
682
683
684
685
686
687
	}

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

	return rotate;
}

688
689
static ir_node *gen_Not(ir_node *node)
{
690
691
692
	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);
693
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
694

695
696
697
	/* TODO: we could do alot more here with all the Mvn variations */

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
698
699
}

700
701
static ir_node *gen_Minus(ir_node *node)
{
702
703
704
	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);
705
	dbg_info *dbgi    = get_irn_dbg_info(node);
706
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
707

708
	if (mode_is_float(mode)) {
709
		if (USE_FPA(env_cg->isa)) {
710
			return new_bd_arm_Mvf(dbgi, block, op, mode);
711
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
712
			assert(mode != mode_E && "IEEE Extended FP not supported");
713
			panic("VFP not supported yet");
714
		} else {
715
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
716
		}
717
	}
718
	assert(mode_is_data(mode));
719
	return new_bd_arm_Rsb_imm(dbgi, block, new_op, 0, 0);
720
721
}

722
723
static ir_node *gen_Load(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
724
725
726
727
728
729
	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);
730
	dbg_info *dbgi      = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
731
	ir_node  *new_load = NULL;
732

Michael Beck's avatar
Michael Beck committed
733
	if (mode_is_float(mode)) {
734
		if (USE_FPA(env_cg->isa)) {
735
736
			new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
			                          NULL, 0, 0, false);
737
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
738
			assert(mode != mode_E && "IEEE Extended FP not supported");
739
			panic("VFP not supported yet");
740
		} else {
741
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
742
		}
743
	} else {
744
		assert(mode_is_data(mode) && "unsupported mode for Load");
745

746
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
747
	}
Michael Beck's avatar
Michael Beck committed
748
	set_irn_pinned(new_load, get_irn_pinned(node));
749
750
751
752

	/* 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 */
753
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
754
		be_new_Keep(block, 1, &proj);
755
756
	}

Michael Beck's avatar
Michael Beck committed
757
	return new_load;
758
759
}

760
761
static ir_node *gen_Store(ir_node *node)
{
Michael Beck's avatar
Michael Beck committed
762
763
764
765
766
767
768
769
	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);
770
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
771
	ir_node *new_store = NULL;
772

Michael Beck's avatar
Michael Beck committed
773
	if (mode_is_float(mode)) {
774
		if (USE_FPA(env_cg->isa)) {
775
776
			new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
			                           new_mem, mode, NULL, 0, 0, false);
777
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
778
			assert(mode != mode_E && "IEEE Extended FP not supported");
779
			panic("VFP not supported yet");
Michael Beck's avatar
Michael Beck committed
780
		} else {
781
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
782
783
		}
	} else {
784
		assert(mode_is_data(mode) && "unsupported mode for Store");
785
786
		new_store = new_bd_arm_Str(dbgi, block, new_ptr, new_val, new_mem, mode,
		                           NULL, 0, 0, false);
787
	}
Michael Beck's avatar
Michael Beck committed
788
789
	set_irn_pinned(new_store, get_irn_pinned(node));
	return new_store;
790
791
}

792
793
794
795
796
797
798
799
800
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);
}

801
802
static ir_node *gen_SwitchJmp(ir_node *node)
{
803
804
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *selector = get_Cond_selector(node);
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
	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;
829

830
831
832
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
833

834
835
836
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
837

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
	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)) {
855
856
857
858
859
860
		/* 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);

861
862
863
864
865
866
867
868
		panic("FloatCmp NIY");
#if 0
		ir_node *new_op2  = be_transform_node(op2);
		/* floating point compare */
		pn_Cmp pnc = get_Proj_proj(selector);

		if (pnc & pn_Cmp_Uo) {
			/* check for unordered, need cmf */
869
			return new_bd_arm_CmfBra(dbgi, block, new_op1, new_op2, pnc);
870
		}
871
		/* Hmm: use need cmfe */
872
		return new_bd_arm_CmfeBra(dbgi, block, new_op1, new_op2, pnc);
873
874
#endif
	}
875

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
	assert(get_irn_mode(op2) == cmp_mode);
	is_unsigned = !mode_is_signed(cmp_mode);

	/* compare with 0 can be done with Tst */
	if (is_Const(op2) && tarval_is_null(get_Const_tarval(op2))) {
		new_op1 = be_transform_node(op1);
		new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op1, new_op1, false,
		                          is_unsigned);
	}
	if (is_Const(op1) && tarval_is_null(get_Const_tarval(op1))) {
		new_op2 = be_transform_node(op2);
		new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
		return new_bd_arm_Tst_reg(dbgi, block, new_op2, new_op2, true,
		                          is_unsigned);
891
	}
892

Michael Beck's avatar
Michael Beck committed
893
	/* integer compare, TODO: use shifter_op in all its combinations */
894
895
896
897
898
899
	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);
900
901
}

902
903
904
905
906
907
908
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;
909

910
911
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
912
	}
913
914
915
916
917
	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));
918

919
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
920
921
}

922
923
static tarval *fpa_imm[3][fpa_max];

924
#if 0
925
926
/**
 * Check, if a floating point tarval is an fpa immediate, i.e.
927
 * one of 0, 1, 2, 3, 4, 5, 10, or 0.5.
928
 */
929
930
static int is_fpa_immediate(tarval *tv)
{
931
932
933
934
935
936
937
938
939
940
941
942
943
944
	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;
	}

945
	if (tarval_is_negative(tv)) {
946
947
948
949
950
951
		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
952
			return res * j;
953
	}
Michael Beck's avatar
Michael Beck committed
954
	return fpa_max;
955
}
956
#endif
957

958
959
static ir_node *gen_Const(ir_node *node)
{
960
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
961
962
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
963

Michael Beck's avatar
Michael Beck committed
964
965
	if (mode_is_float(mode)) {
		if (USE_FPA(env_cg->isa)) {
966
			tarval *tv = get_Const_tarval(node);
967
			node       = new_bd_arm_fConst(dbg, block, tv);
968
			be_dep_on_frame(node);
Michael Beck's avatar
Michael Beck committed
969
			return node;
970
		} else if (USE_VFP(env_cg->isa)) {
Michael Beck's avatar
Michael Beck committed
971
			assert(mode != mode_E && "IEEE Extended FP not supported");
972
			panic("VFP not supported yet");
973
		} else {
974
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
975
976
		}
	}
977
	return create_const_graph(node, block);
978
}
979

980
981
982
983
984
985
static ir_node *gen_SymConst(ir_node *node)
{
	ir_node   *block  = be_transform_node(get_nodes_block(node));
	ir_entity *entity = get_SymConst_entity(node);
	dbg_info  *dbgi   = get_irn_dbg_info(node);
	ir_node   *new_node;
986

987
	new_node = new_bd_arm_SymConst(dbgi, block, entity, 0);
988
989
	be_dep_on_frame(new_node);
	return new_node;
990
991
}

992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
static ir_node *ints_to_double(dbg_info *dbgi, ir_node *block, ir_node *node0,
                               ir_node *node1)
{
	/* the good way to do this would be to use the stm (store multiple)
	 * instructions, since our input is nearly always 2 consecutive 32bit
	 * registers... */
	ir_graph *irg   = current_ir_graph;
	ir_node  *stack = get_irg_frame(irg);
	ir_node  *nomem = new_NoMem();
	ir_node  *str0  = new_bd_arm_Str(dbgi, block, stack, node0, nomem, mode_gp,
	                                 NULL, 0, 0, true);
	ir_node  *str1  = new_bd_arm_Str(dbgi, block, stack, node1, nomem, mode_gp,
	                                 NULL, 0, 4, true);
	ir_node  *in[2] = { str0, str1 };
	ir_node  *sync  = new_r_Sync(block, 2, in);
	ir_node  *ldf;
	set_irn_pinned(str0, op_pin_state_floats);
	set_irn_pinned(str1, op_pin_state_floats);

	ldf = new_bd_arm_Ldf(dbgi, block, stack, sync, mode_D, NULL, 0, 0, true);
	set_irn_pinned(ldf, op_pin_state_floats);

	return new_Proj(ldf, mode_fp, pn_arm_Ldf_res);
}

static ir_node *int_to_float(dbg_info *dbgi, ir_node *block, ir_node *node)
{
	ir_graph *irg   = current_ir_graph;
	ir_node  *stack = get_irg_frame(irg);
	ir_node  *nomem = new_NoMem();
	ir_node  *str   = new_bd_arm_Str(dbgi, block, stack, node, nomem, mode_gp,
	                                 NULL, 0, 0, true);
	ir_node  *ldf;
	set_irn_pinned(str, op_pin_state_floats);

	ldf = new_bd_arm_Ldf(dbgi, block, stack, str, mode_F, NULL, 0, 0, true);
	set_irn_pinned(ldf, op_pin_state_floats);

	return new_Proj(ldf, mode_fp, pn_arm_Ldf_res);
}

static ir_node *float_to_int(dbg_info *dbgi, ir_node *block, ir_node *node)
{
	ir_graph *irg   = current_ir_graph;
	ir_node  *stack = get_irg_frame(irg);
	ir_node  *nomem = new_NoMem();
	ir_node  *stf   = new_bd_arm_Stf(dbgi, block, stack, node, nomem, mode_F,
	                                 NULL, 0, 0, true);
	ir_node  *ldr;
	set_irn_pinned(stf, op_pin_state_floats);

	ldr = new_bd_arm_Ldr(dbgi, block, stack, stf, mode_gp, NULL, 0, 0, true);
	set_irn_pinned(ldr, op_pin_state_floats);

	return new_Proj(ldr, mode_gp, pn_arm_Ldr_res);
}

static void double_to_ints(dbg_info *dbgi, ir_node *block, ir_node *node,
                           ir_node **out_value0, ir_node **out_value1)
{
	ir_graph *irg   = current_ir_graph;
	ir_node  *stack = get_irg_frame(irg);
	ir_node  *nomem = new_NoMem();
	ir_node  *stf   = new_bd_arm_Stf(dbgi, block, stack, node, nomem, mode_D,
	                                 NULL, 0, 0, true);
	ir_node  *ldr0, *ldr1;
	set_irn_pinned(stf, op_pin_state_floats);

	ldr0 = new_bd_arm_Ldr(dbgi, block, stack, stf, mode_gp, NULL, 0, 0, true);
	set_irn_pinned(ldr0, op_pin_state_floats);
	ldr1 = new_bd_arm_Ldr(dbgi, block, stack, stf, mode_gp, NULL, 0, 4, true);
	set_irn_pinned(ldr1, op_pin_state_floats);

	*out_value0 = new_Proj(ldr0, mode_gp, pn_arm_Ldr_res);
	*out_value1 = new_Proj(ldr1, mode_gp, pn_arm_Ldr_res);
}

1069
1070
static ir_node *gen_CopyB(ir_node *node)
{
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *src      = get_CopyB_src(node);
	ir_node  *new_src  = be_transform_node(src);
	ir_node  *dst      = get_CopyB_dst(node);
	ir_node  *new_dst  = be_transform_node(dst);
	ir_node  *mem      = get_CopyB_mem(node);
	ir_node  *new_mem  = be_transform_node(mem);
	dbg_info *dbg      = get_irn_dbg_info(node);
	int      size      = get_type_size_bytes(get_CopyB_type(node));
	ir_node  *src_copy;
	ir_node  *dst_copy;

1083
1084
	src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_src);
	dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_dst);