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

20
21
/**
 * @file
Michael Beck's avatar
Michael Beck committed
22
 * @brief   The codegenerator (transform FIRM into arm FIRM)
23
 * @author  Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
24
25
 * @version $Id$
 */
26
27
28
29
30
31
32
33
34
#include "config.h"

#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "irgmod.h"
#include "iredges.h"
#include "irvrfy.h"
#include "ircons.h"
Michael Beck's avatar
Michael Beck committed
35
#include "irprintf.h"
36
37
38
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
Michael Beck's avatar
Michael Beck committed
39
#include "error.h"
40

41
#include "../benode.h"
42
#include "../beirg.h"
43
#include "../beutil.h"
44
#include "../betranshlp.h"
45
46
#include "../beabihelper.h"
#include "../beabi.h"
47

48
#include "bearch_arm_t.h"
49
50
#include "arm_nodes_attr.h"
#include "arm_transform.h"
51
#include "arm_optimize.h"
52
53
#include "arm_new_nodes.h"
#include "arm_map_regs.h"
54
#include "arm_cconv.h"
55
56
57
58
59

#include "gen_arm_regalloc_if.h"

#include <limits.h>

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

62
63
/** hold the current code generator during transformation */
static arm_code_gen_t *env_cg;
64

65
66
static const arch_register_t *sp_reg = &arm_gp_regs[REG_SP];
static ir_mode               *mode_gp;
67
static ir_mode               *mode_fp;
68
69
70
71
72
73
static beabi_helper_env_t    *abihelper;
static calling_convention_t  *cconv = NULL;

static pmap                  *node_to_stack;

static bool mode_needs_gp_reg(ir_mode *mode)
74
{
75
	return mode_is_int(mode) || mode_is_reference(mode);
76
77
}

Michael Beck's avatar
Michael Beck committed
78
/**
79
 * create firm graph for a constant
Michael Beck's avatar
Michael Beck committed
80
 */
81
82
83
static ir_node *create_const_graph_value(dbg_info *dbgi, ir_node *block,
                                         unsigned int value)
{
84
	ir_node *result;
85
	arm_vals v, vn;
Michael Beck's avatar
Michael Beck committed
86
	int cnt;
87

88
89
90
91
92
93
	/* We only have 8 bit immediates. So we possibly have to combine several
	 * operations to construct the desired value.
	 *
	 * we can either create the value by adding bits to 0 or by removing bits
	 * from an register with all bits set. Try which alternative needs fewer
	 * operations */
94
95
	arm_gen_vals_from_word(value, &v);
	arm_gen_vals_from_word(~value, &vn);
Michael Beck's avatar
Michael Beck committed
96
97
98

	if (vn.ops < v.ops) {
		/* remove bits */
99
100
		result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
101
102

		for (cnt = 1; cnt < vn.ops; ++cnt) {
103
104
			result = new_bd_arm_Bic_imm(dbgi, block, result,
			                            vn.values[cnt], vn.rors[cnt]);
105
		}
106
	} else {
Michael Beck's avatar
Michael Beck committed
107
		/* add bits */
108
109
		result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
		be_dep_on_frame(result);
Michael Beck's avatar
Michael Beck committed
110
111

		for (cnt = 1; cnt < v.ops; ++cnt) {
112
113
			result = new_bd_arm_Or_imm(dbgi, block, result,
			                           v.values[cnt], v.rors[cnt]);
Michael Beck's avatar
Michael Beck committed
114
		}
115
116
117
118
	}
	return result;
}

119
120
121
122
123
/**
 * Create a DAG constructing a given Const.
 *
 * @param irn  a Firm const
 */
124
125
static ir_node *create_const_graph(ir_node *irn, ir_node *block)
{
126
127
	tarval  *tv = get_Const_tarval(irn);
	ir_mode *mode = get_tarval_mode(tv);
128
	unsigned value;
129
130
131
132
133
134
135

	if (mode_is_reference(mode)) {
		/* ARM is 32bit, so we can safely convert a reference tarval into Iu */
		assert(get_mode_size_bits(mode) == get_mode_size_bits(mode_Iu));
		tv = tarval_convert_to(tv, mode_Iu);
	}
	value = get_tarval_long(tv);
136
	return create_const_graph_value(get_irn_dbg_info(irn), block, value);
137
138
}

Michael Beck's avatar
Michael Beck committed
139
/**
Michael Beck's avatar
Michael Beck committed
140
141
142
143
144
145
 * Create an And that will zero out upper bits.
 *
 * @param dbgi     debug info
 * @param block    the basic block
 * @param op       the original node
 * param src_bits  number of lower bits that will remain
Michael Beck's avatar
Michael Beck committed
146
 */
147
148
149
150
151
152
153
154
155
156
157
158
static ir_node *gen_zero_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	if (src_bits == 8) {
		return new_bd_arm_And_imm(dbgi, block, op, 0xFF, 0);
	} else if (src_bits == 16) {
		ir_node *lshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, 16);
		ir_node *rshift = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift, ARM_SHF_LSR_IMM, 16);
		return rshift;
	} else {
		panic("zero extension only supported for 8 and 16 bits");
	}
159
160
}

Michael Beck's avatar
Michael Beck committed
161
162
163
/**
 * Generate code for a sign extension.
 */
164
165
166
167
168
169
static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                                   int src_bits)
{
	int shift_width = 32 - src_bits;
	ir_node *lshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, op, ARM_SHF_LSL_IMM, shift_width);
	ir_node *rshift_node = new_bd_arm_Mov_reg_shift_imm(dbgi, block, lshift_node, ARM_SHF_ASR_IMM, shift_width);
170
171
172
	return rshift_node;
}

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
                              ir_mode *orig_mode)
{
	int bits = get_mode_size_bits(orig_mode);
	if (bits == 32)
		return op;

	if (mode_is_signed(orig_mode)) {
		return gen_sign_extension(dbgi, block, op, bits);
	} else {
		return gen_zero_extension(dbgi, block, op, bits);
	}
}

/**
 * returns true if it is assured, that the upper bits of a node are "clean"
 * which means for a 16 or 8 bit value, that the upper bits in the register
 * are 0 for unsigned and a copy of the last significant bit for signed
 * numbers.
 */
static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
{
	(void) transformed_node;
	(void) mode;
	/* TODO */
	return false;
}

Michael Beck's avatar
Michael Beck committed
201
202
203
/**
 * Transforms a Conv node.
 *
204
 * @return The created ia32 Conv node
Michael Beck's avatar
Michael Beck committed
205
 */
206
207
static ir_node *gen_Conv(ir_node *node)
{
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *op       = get_Conv_op(node);
	ir_node  *new_op   = be_transform_node(op);
	ir_mode  *src_mode = get_irn_mode(op);
	ir_mode  *dst_mode = get_irn_mode(node);
	dbg_info *dbg      = get_irn_dbg_info(node);

	if (src_mode == dst_mode)
		return new_op;

	if (mode_is_float(src_mode) || mode_is_float(dst_mode)) {
		if (USE_FPA(env_cg->isa)) {
			if (mode_is_float(src_mode)) {
				if (mode_is_float(dst_mode)) {
Michael Beck's avatar
Michael Beck committed
222
					/* from float to float */
223
					return new_bd_arm_Mvf(dbg, block, new_op, dst_mode);
224
				} else {
Michael Beck's avatar
Michael Beck committed
225
					/* from float to int */
226
					panic("TODO");
Michael Beck's avatar
Michael Beck committed
227
				}
228
			} else {
Michael Beck's avatar
Michael Beck committed
229
				/* from int to float */
230
231
232
233
234
				if (!mode_is_signed(src_mode)) {
					panic("TODO");
				} else {
					return new_bd_arm_FltX(dbg, block, new_op, dst_mode);
				}
Michael Beck's avatar
Michael Beck committed
235
			}
236
		} else if (USE_VFP(env_cg->isa)) {
237
			panic("VFP not supported yet");
238
		} else {
239
			panic("Softfloat not supported yet");
Michael Beck's avatar
Michael Beck committed
240
		}
241
	} else { /* complete in gp registers */
242
243
		int src_bits = get_mode_size_bits(src_mode);
		int dst_bits = get_mode_size_bits(dst_mode);
Michael Beck's avatar
Michael Beck committed
244
245
		int min_bits;
		ir_mode *min_mode;
246

Michael Beck's avatar
Michael Beck committed
247
		if (src_bits == dst_bits) {
Michael Beck's avatar
Michael Beck committed
248
			/* kill unnecessary conv */
Michael Beck's avatar
Michael Beck committed
249
			return new_op;
250
251
252
253
254
		}

		if (src_bits < dst_bits) {
			min_bits = src_bits;
			min_mode = src_mode;
Michael Beck's avatar
Michael Beck committed
255
		} else {
256
257
258
259
260
261
262
263
264
265
266
267
			min_bits = dst_bits;
			min_mode = dst_mode;
		}

		if (upper_bits_clean(new_op, min_mode)) {
			return new_op;
		}

		if (mode_is_signed(min_mode)) {
			return gen_sign_extension(dbg, block, new_op, min_bits);
		} else {
			return gen_zero_extension(dbg, block, new_op, min_bits);
268
269
270
271
		}
	}
}

272
273
274
275
276
277
278
typedef struct {
	unsigned char  imm_8;
	unsigned char  rot;
} arm_immediate_t;

static bool try_encode_as_immediate(const ir_node *node, arm_immediate_t *res)
{
Michael Beck's avatar
Michael Beck committed
279
	unsigned val, low_pos, high_pos;
280
281
282

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

284
	val = get_tarval_long(get_Const_tarval(node));
Michael Beck's avatar
Michael Beck committed
285

286
287
288
289
290
291
292
293
294
	if (val == 0) {
		res->imm_8 = 0;
		res->rot   = 0;
		return true;
	}
	if (val <= 0xff) {
		res->imm_8 = val;
		res->rot   = 0;
		return true;
Michael Beck's avatar
Michael Beck committed
295
	}
296
297
298
299
300
301
302
	/* arm allows to use to rotate an 8bit immediate value by a multiple of 2
	   (= 0, 2, 4, 6, ...).
	   So we determine the smallest even position with a bit set
	   and the highest even position with no bit set anymore.
	   If the difference between these 2 is <= 8, then we can encode the value
	   as immediate.
	 */
Michael Beck's avatar
Michael Beck committed
303
304
	low_pos  = ntz(val) & ~1u;
	high_pos = (32-nlz(val)+1) & ~1u;
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

	if (high_pos - low_pos <= 8) {
		res->imm_8 = val >> low_pos;
		res->rot   = 32 - low_pos;
		return true;
	}

	if (high_pos > 24) {
		res->rot = 34 - high_pos;
		val      = val >> (32-res->rot) | val << (res->rot);
		if (val <= 0xff) {
			res->imm_8 = val;
			return true;
		}
	}

	return false;
}

324
static bool is_downconv(const ir_node *node)
325
326
327
328
329
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
330
		return false;
331
332
333
334
335

	/* we only want to skip the conv when we're the only user
	 * (not optimal but for now...)
	 */
	if (get_irn_n_edges(node) > 1)
336
		return false;
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
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
387
388
389
390

	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
391
}
392
393

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

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

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

432
			return new_bd_arm_Mla(dbgi, block, new_op1, new_op2, new_op3);
Michael Beck's avatar
Michael Beck committed
433
		}
434
#endif
435

436
437
		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
438
439
	}
}
440
441

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

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

470
471
static ir_node *gen_Quot(ir_node *node)
{
472
473
474
475
476
477
478
	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
479

480
	assert(mode != mode_E && "IEEE Extended FP not supported");
481

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

492
493
494
495
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);
496
}
497

498
499
500
501
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);
502
}
503

504
505
506
507
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);
508
}
509

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

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

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

	if (flags & MATCH_SIZE_NEUTRAL) {
		op1 = arm_skip_downconv(op1);
		op2 = arm_skip_downconv(op2);
569
	}
570

571
	new_op1 = be_transform_node(op1);
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
	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);
		}
	}

589
	new_op2 = be_transform_node(op2);
590
591
	return new_bd_arm_Mov_reg_shift_reg(dbgi, block, new_op1, new_op2,
	                                    shift_modifier);
592
593
}

594
595
596
static ir_node *gen_Shl(ir_node *node)
{
	return make_shift(node, MATCH_SIZE_NEUTRAL, ARM_SHF_LSL_REG);
597
598
}

599
600
601
static ir_node *gen_Shr(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_LSR_REG);
602
603
}

604
605
606
static ir_node *gen_Shrs(ir_node *node)
{
	return make_shift(node, MATCH_NONE, ARM_SHF_ASR_REG);
607
608
}

609
610
static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
611
612
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
613
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
614
615
	ir_node  *new_op2 = be_transform_node(op2);

616
617
	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
618
619
}

620
621
static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
{
Michael Beck's avatar
Michael Beck committed
622
623
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
624
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
625
626
	ir_node  *new_op2 = be_transform_node(op2);

627
	/* Note: there is no Rol on arm, we have to use Ror */
628
629
630
	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
631
632
}

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

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

675
676
677
678
		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);
679

680
681
682
			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
683
684
685
686
687
688
689
690
691
	}

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

	return rotate;
}

692
693
static ir_node *gen_Not(ir_node *node)
{
694
695
696
	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);
697
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
698

699
700
701
	/* TODO: we could do alot more here with all the Mvn variations */

	return new_bd_arm_Mvn_reg(dbgi, block, new_op);
702
703
}

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

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

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

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

750
		new_load = new_bd_arm_Ldr(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
751
	}
Michael Beck's avatar
Michael Beck committed
752
	set_irn_pinned(new_load, get_irn_pinned(node));
753
754
755
756

	/* 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 */
757
		ir_node *proj = new_r_Proj(new_load, mode_Iu, pn_arm_Ldr_res);
758
		be_new_Keep(block, 1, &proj);
759
760
	}

Michael Beck's avatar
Michael Beck committed
761
	return new_load;
762
763
}

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

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

796
797
798
799
800
801
802
803
804
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);
}

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

834
835
836
	foreach_out_edge(node, edge) {
		proj = get_edge_src_irn(edge);
		assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
837

838
839
840
		pn = get_Proj_proj(proj) - translation;
		set_Proj_proj(proj, pn);
	}
841

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

865
866
867
868
869
870
871
872
		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 */
873
			return new_bd_arm_CmfBra(dbgi, block, new_op1, new_op2, pnc);
874
		}
875
		/* Hmm: use need cmfe */
876
		return new_bd_arm_CmfeBra(dbgi, block, new_op1, new_op2, pnc);
877
878
#endif
	}
879

880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
	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);
895
	}
896

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

906
907
908
909
910
911
912
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;
913

914
915
	if (mode != mode_b) {
		return gen_SwitchJmp(node);
916
	}
917
918
919
920
921
	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));
922

923
	return new_bd_arm_B(dbgi, block, flag_node, get_Proj_proj(selector));
924
925
}

926
927
static tarval *fpa_imm[3][fpa_max];

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

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

962
963
static ir_node *gen_Const(ir_node *node)
{
964
	ir_node  *block = be_transform_node(get_nodes_block(node));
Michael Beck's avatar
Michael Beck committed
965
966
	ir_mode *mode = get_irn_mode(node);
	dbg_info *dbg = get_irn_dbg_info(node);
967

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

984
985
986
987
988
989
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;
990

991
	new_node = new_bd_arm_SymConst(dbgi, block, entity, 0);
992
993
	be_dep_on_frame(new_node);
	return new_node;
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
1069
1070
1071
1072
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);
}

1073
1074
static ir_node *gen_CopyB(ir_node *node)
{
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
	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;