1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19 
20 /**
21  * @file
22  * @brief  This file implements the creation of the architecture specific firm
23  *         opcodes and the corresponding node constructors for the arm
24  *         assembler irg.
25  * @author Oliver Richter, Tobias Gneist
26  */
27 #include "config.h"
28 
29 #include <stdlib.h>
30 #include <stdbool.h>
31 
32 #include "irprog_t.h"
33 #include "irgraph_t.h"
34 #include "irnode_t.h"
35 #include "irmode_t.h"
36 #include "ircons_t.h"
37 #include "iropt_t.h"
38 #include "irop.h"
39 #include "irprintf.h"
40 #include "xmalloc.h"
41 
42 #include "bearch.h"
43 
44 #include "arm_nodes_attr.h"
45 #include "arm_new_nodes.h"
46 #include "arm_optimize.h"
47 
48 #include "beabi.h"
49 #include "bearch_arm_t.h"
50 
arm_has_symconst_attr(const ir_node * node)51 static bool arm_has_symconst_attr(const ir_node *node)
52 {
53 	return is_arm_SymConst(node) || is_arm_FrameAddr(node) || is_arm_Bl(node);
54 }
55 
has_load_store_attr(const ir_node * node)56 static bool has_load_store_attr(const ir_node *node)
57 {
58 	return is_arm_Ldr(node) || is_arm_Str(node) || is_arm_LinkLdrPC(node)
59 		|| is_arm_Ldf(node) || is_arm_Stf(node);
60 }
61 
has_shifter_operand(const ir_node * node)62 static bool has_shifter_operand(const ir_node *node)
63 {
64 	return is_arm_Add(node) || is_arm_And(node) || is_arm_Or(node)
65 		|| is_arm_Eor(node) || is_arm_Bic(node) || is_arm_Sub(node)
66 		|| is_arm_Rsb(node) || is_arm_Mov(node) || is_arm_Mvn(node)
67 		|| is_arm_Cmp(node) || is_arm_Tst(node) || is_arm_LinkMovPC(node);
68 }
69 
has_cmp_attr(const ir_node * node)70 static bool has_cmp_attr(const ir_node *node)
71 {
72 	return is_arm_Cmp(node) || is_arm_Tst(node);
73 }
74 
has_farith_attr(const ir_node * node)75 static bool has_farith_attr(const ir_node *node)
76 {
77 	return is_arm_Adf(node) || is_arm_Muf(node) || is_arm_Suf(node)
78 	    || is_arm_Dvf(node) || is_arm_Mvf(node) || is_arm_FltX(node);
79 }
80 
81 /**
82  * Dumper interface for dumping arm nodes in vcg.
83  * @param F        the output file
84  * @param n        the node to dump
85  * @param reason   indicates which kind of information should be dumped
86  */
arm_dump_node(FILE * F,const ir_node * n,dump_reason_t reason)87 static void arm_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
88 {
89 	switch (reason) {
90 	case dump_node_opcode_txt:
91 		fprintf(F, "%s", get_irn_opname(n));
92 
93 		if (arm_has_symconst_attr(n)) {
94 			const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(n);
95 			if (attr->entity != NULL) {
96 				fputc(' ', F);
97 				fputs(get_entity_name(attr->entity), F);
98 			}
99 		}
100 		break;
101 
102 	case dump_node_mode_txt:
103 		/* mode isn't relevant in the backend */
104 		break;
105 
106 	case dump_node_nodeattr_txt:
107 		/* TODO: dump shift modifiers */
108 		break;
109 
110 	case dump_node_info_txt:
111 		arch_dump_reqs_and_registers(F, n);
112 
113 		if (has_load_store_attr(n)) {
114 			const arm_load_store_attr_t *attr
115 				= get_arm_load_store_attr_const(n);
116 			ir_fprintf(F, "load_store_mode = %+F\n", attr->load_store_mode);
117 			ir_fprintf(F, "entity = %+F\n", attr->entity);
118 			fprintf(F, "offset = %ld\n", attr->offset);
119 			fprintf(F, "is_frame_entity = %s\n",
120 					attr->is_frame_entity ? "yes" : "no");
121 			fprintf(F, "entity_sign = %s\n",
122 					attr->entity_sign ? "yes" : "no");
123 		}
124 		if (has_shifter_operand(n)) {
125 			const arm_shifter_operand_t *attr
126 				= get_arm_shifter_operand_attr_const(n);
127 			switch (attr->shift_modifier) {
128 			case ARM_SHF_REG:
129 				break;
130 			case ARM_SHF_IMM:
131 				fprintf(F, "modifier = imm %d ror %d\n",
132 						attr->immediate_value, attr->shift_immediate);
133 				break;
134 			case ARM_SHF_ASR_IMM:
135 				fprintf(F, "modifier = V >>s %d\n", attr->shift_immediate);
136 				break;
137 			case ARM_SHF_ASR_REG:
138 				fprintf(F, "modifier = V >>s R\n");
139 				break;
140 			case ARM_SHF_LSL_IMM:
141 				fprintf(F, "modifier = V << %d\n", attr->shift_immediate);
142 				break;
143 			case ARM_SHF_LSL_REG:
144 				fprintf(F, "modifier = V << R\n");
145 				break;
146 			case ARM_SHF_LSR_IMM:
147 				fprintf(F, "modifier = V >> %d\n", attr->shift_immediate);
148 				break;
149 			case ARM_SHF_LSR_REG:
150 				fprintf(F, "modifier = V >> R\n");
151 				break;
152 			case ARM_SHF_ROR_IMM:
153 				fprintf(F, "modifier = V ROR %d\n", attr->shift_immediate);
154 				break;
155 			case ARM_SHF_ROR_REG:
156 				fprintf(F, "modifier = V ROR R\n");
157 				break;
158 			case ARM_SHF_RRX:
159 				fprintf(F, "modifier = RRX\n");
160 				break;
161 			default:
162 			case ARM_SHF_INVALID:
163 				fprintf(F, "modifier = INVALID SHIFT MODIFIER\n");
164 				break;
165 			}
166 		}
167 		if (has_cmp_attr(n)) {
168 			const arm_cmp_attr_t *attr = get_arm_cmp_attr_const(n);
169 			fprintf(F, "cmp_attr =");
170 			if (attr->is_unsigned) {
171 				fprintf(F, " unsigned");
172 			}
173 			if (attr->ins_permuted) {
174 				fprintf(F, " inputs swapped");
175 			}
176 			fputc('\n', F);
177 		}
178 		if (arm_has_symconst_attr(n)) {
179 			const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(n);
180 
181 			fprintf(F, "entity = ");
182 			if (attr->entity != NULL) {
183 				fprintf(F, "'%s'", get_entity_name(attr->entity));
184 			} else {
185 				fputs("NULL", F);
186 			}
187 			fputc('\n', F);
188 			fprintf(F, "frame offset = %d\n", attr->fp_offset);
189 		}
190 		if (has_farith_attr(n)) {
191 			const arm_farith_attr_t *attr = get_arm_farith_attr_const(n);
192 			ir_fprintf(F, "arithmetic mode = %+F\n", attr->mode);
193 		}
194 		break;
195 	}
196 }
197 
get_arm_attr(ir_node * node)198 arm_attr_t *get_arm_attr(ir_node *node)
199 {
200 	assert(is_arm_irn(node) && "need arm node to get attributes");
201 	return (arm_attr_t*)get_irn_generic_attr(node);
202 }
203 
get_arm_attr_const(const ir_node * node)204 const arm_attr_t *get_arm_attr_const(const ir_node *node)
205 {
206 	assert(is_arm_irn(node) && "need arm node to get attributes");
207 	return (const arm_attr_t*)get_irn_generic_attr_const(node);
208 }
209 
has_symconst_attr(const ir_node * node)210 static bool has_symconst_attr(const ir_node *node)
211 {
212 	return is_arm_SymConst(node) || is_arm_FrameAddr(node) || is_arm_Bl(node);
213 }
214 
get_arm_SymConst_attr(ir_node * node)215 arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node)
216 {
217 	assert(has_symconst_attr(node));
218 	return (arm_SymConst_attr_t*)get_irn_generic_attr(node);
219 }
220 
get_arm_SymConst_attr_const(const ir_node * node)221 const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node)
222 {
223 	assert(has_symconst_attr(node));
224 	return (const arm_SymConst_attr_t*)get_irn_generic_attr_const(node);
225 }
226 
get_arm_fConst_attr_const(const ir_node * node)227 static const arm_fConst_attr_t *get_arm_fConst_attr_const(const ir_node *node)
228 {
229 	assert(is_arm_fConst(node));
230 	return (const arm_fConst_attr_t*)get_irn_generic_attr_const(node);
231 }
232 
get_arm_fConst_attr(ir_node * node)233 static arm_fConst_attr_t *get_arm_fConst_attr(ir_node *node)
234 {
235 	assert(is_arm_fConst(node));
236 	return (arm_fConst_attr_t*)get_irn_generic_attr(node);
237 }
238 
get_arm_farith_attr(ir_node * node)239 arm_farith_attr_t *get_arm_farith_attr(ir_node *node)
240 {
241 	assert(has_farith_attr(node));
242 	return (arm_farith_attr_t*)get_irn_generic_attr(node);
243 }
244 
get_arm_farith_attr_const(const ir_node * node)245 const arm_farith_attr_t *get_arm_farith_attr_const(const ir_node *node)
246 {
247 	assert(has_farith_attr(node));
248 	return (const arm_farith_attr_t*)get_irn_generic_attr_const(node);
249 }
250 
get_arm_CondJmp_attr(ir_node * node)251 arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node)
252 {
253 	assert(is_arm_B(node));
254 	return (arm_CondJmp_attr_t*)get_irn_generic_attr(node);
255 }
256 
get_arm_CondJmp_attr_const(const ir_node * node)257 const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node)
258 {
259 	assert(is_arm_B(node));
260 	return (const arm_CondJmp_attr_t*)get_irn_generic_attr_const(node);
261 }
262 
get_arm_SwitchJmp_attr(ir_node * node)263 arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr(ir_node *node)
264 {
265 	assert(is_arm_SwitchJmp(node));
266 	return (arm_SwitchJmp_attr_t*)get_irn_generic_attr(node);
267 }
268 
get_arm_SwitchJmp_attr_const(const ir_node * node)269 const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node)
270 {
271 	assert(is_arm_SwitchJmp(node));
272 	return (const arm_SwitchJmp_attr_t*)get_irn_generic_attr_const(node);
273 }
274 
get_arm_CopyB_attr(ir_node * node)275 arm_CopyB_attr_t *get_arm_CopyB_attr(ir_node *node)
276 {
277 	assert(is_arm_CopyB(node));
278 	return (arm_CopyB_attr_t*)get_irn_generic_attr(node);
279 }
280 
get_arm_CopyB_attr_const(const ir_node * node)281 const arm_CopyB_attr_t *get_arm_CopyB_attr_const(const ir_node *node)
282 {
283 	assert(is_arm_CopyB(node));
284 	return (const arm_CopyB_attr_t*)get_irn_generic_attr_const(node);
285 }
286 
get_fConst_value(const ir_node * node)287 ir_tarval *get_fConst_value(const ir_node *node)
288 {
289 	const arm_fConst_attr_t *attr = get_arm_fConst_attr_const(node);
290 	return attr->tv;
291 }
292 
set_fConst_value(ir_node * node,ir_tarval * tv)293 void set_fConst_value(ir_node *node, ir_tarval *tv)
294 {
295 	arm_fConst_attr_t *attr = get_arm_fConst_attr(node);
296 	attr->tv = tv;
297 }
298 
get_arm_CondJmp_relation(const ir_node * node)299 ir_relation get_arm_CondJmp_relation(const ir_node *node)
300 {
301 	const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node);
302 	return attr->relation;
303 }
304 
set_arm_CondJmp_relation(ir_node * node,ir_relation relation)305 void set_arm_CondJmp_relation(ir_node *node, ir_relation relation)
306 {
307 	arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node);
308 	attr->relation = relation;
309 }
310 
311 /* Set the ARM machine node attributes to default values. */
init_arm_attributes(ir_node * node,arch_irn_flags_t flags,const arch_register_req_t ** in_reqs,int n_res)312 static void init_arm_attributes(ir_node *node, arch_irn_flags_t flags,
313                          const arch_register_req_t ** in_reqs,
314 						 int n_res)
315 {
316 	ir_graph       *irg  = get_irn_irg(node);
317 	struct obstack *obst = get_irg_obstack(irg);
318 	arm_attr_t     *attr = get_arm_attr(node);
319 	backend_info_t *info;
320 
321 	arch_set_irn_flags(node, flags);
322 	arch_set_irn_register_reqs_in(node, in_reqs);
323 	attr->is_load_store    = false;
324 
325 	info            = be_get_info(node);
326 	info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
327 	memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
328 }
329 
init_arm_load_store_attributes(ir_node * res,ir_mode * ls_mode,ir_entity * entity,int entity_sign,long offset,bool is_frame_entity)330 static void init_arm_load_store_attributes(ir_node *res, ir_mode *ls_mode,
331                                            ir_entity *entity,
332                                            int entity_sign, long offset,
333                                            bool is_frame_entity)
334 {
335 	arm_load_store_attr_t *attr = get_arm_load_store_attr(res);
336 	attr->load_store_mode    = ls_mode;
337 	attr->entity             = entity;
338 	attr->entity_sign        = entity_sign;
339 	attr->is_frame_entity    = is_frame_entity;
340 	attr->offset             = offset;
341 	attr->base.is_load_store = true;
342 }
343 
init_arm_shifter_operand(ir_node * res,unsigned immediate_value,arm_shift_modifier_t shift_modifier,unsigned shift_immediate)344 static void init_arm_shifter_operand(ir_node *res, unsigned immediate_value,
345                                      arm_shift_modifier_t shift_modifier,
346                                      unsigned shift_immediate)
347 {
348 	arm_shifter_operand_t *attr = get_arm_shifter_operand_attr(res);
349 	attr->immediate_value = immediate_value;
350 	attr->shift_modifier  = shift_modifier;
351 	attr->shift_immediate = shift_immediate;
352 }
353 
init_arm_cmp_attr(ir_node * res,bool ins_permuted,bool is_unsigned)354 static void init_arm_cmp_attr(ir_node *res, bool ins_permuted, bool is_unsigned)
355 {
356 	arm_cmp_attr_t *attr = get_arm_cmp_attr(res);
357 	attr->ins_permuted = ins_permuted;
358 	attr->is_unsigned  = is_unsigned;
359 }
360 
init_arm_SymConst_attributes(ir_node * res,ir_entity * entity,int symconst_offset)361 static void init_arm_SymConst_attributes(ir_node *res, ir_entity *entity,
362                                          int symconst_offset)
363 {
364 	arm_SymConst_attr_t *attr = get_arm_SymConst_attr(res);
365 	attr->entity    = entity;
366 	attr->fp_offset = symconst_offset;
367 }
368 
init_arm_farith_attributes(ir_node * res,ir_mode * mode)369 static void init_arm_farith_attributes(ir_node *res, ir_mode *mode)
370 {
371 	arm_farith_attr_t *attr = get_arm_farith_attr(res);
372 	attr->mode = mode;
373 }
374 
init_arm_CopyB_attributes(ir_node * res,unsigned size)375 static void init_arm_CopyB_attributes(ir_node *res, unsigned size)
376 {
377 	arm_CopyB_attr_t *attr = get_arm_CopyB_attr(res);
378 	attr->size = size;
379 }
380 
init_arm_SwitchJmp_attributes(ir_node * res,const ir_switch_table * table)381 static void init_arm_SwitchJmp_attributes(ir_node *res,
382                                           const ir_switch_table *table)
383 {
384 	unsigned n_outs = arch_get_irn_n_outs(res);
385 	unsigned o;
386 
387 	arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(res);
388 	attr->table = table;
389 
390 	for (o = 0; o < n_outs; ++o) {
391 		arch_set_irn_register_req_out(res, o, arch_no_register_req);
392 	}
393 }
394 
cmp_attr_arm(const ir_node * a,const ir_node * b)395 static int cmp_attr_arm(const ir_node *a, const ir_node *b)
396 {
397 	(void) a;
398 	(void) b;
399 	return 0;
400 }
401 
cmp_attr_arm_SymConst(const ir_node * a,const ir_node * b)402 static int cmp_attr_arm_SymConst(const ir_node *a, const ir_node *b)
403 {
404 	const arm_SymConst_attr_t *attr_a;
405 	const arm_SymConst_attr_t *attr_b;
406 
407 	if (cmp_attr_arm(a, b))
408 		return 1;
409 
410 	attr_a = get_arm_SymConst_attr_const(a);
411 	attr_b = get_arm_SymConst_attr_const(b);
412 	return attr_a->entity != attr_b->entity
413 		|| attr_a->fp_offset != attr_b->fp_offset;
414 }
415 
cmp_attr_arm_CopyB(const ir_node * a,const ir_node * b)416 static int cmp_attr_arm_CopyB(const ir_node *a, const ir_node *b)
417 {
418 	const arm_CopyB_attr_t *attr_a;
419 	const arm_CopyB_attr_t *attr_b;
420 
421 	if (cmp_attr_arm(a, b))
422 		return 1;
423 
424 	attr_a = get_arm_CopyB_attr_const(a);
425 	attr_b = get_arm_CopyB_attr_const(b);
426 	return attr_a->size != attr_b->size;
427 }
428 
cmp_attr_arm_CondJmp(const ir_node * a,const ir_node * b)429 static int cmp_attr_arm_CondJmp(const ir_node *a, const ir_node *b)
430 {
431 	(void) a;
432 	(void) b;
433 	/* never identical */
434 	return 1;
435 }
436 
cmp_attr_arm_SwitchJmp(const ir_node * a,const ir_node * b)437 static int cmp_attr_arm_SwitchJmp(const ir_node *a, const ir_node *b)
438 {
439 	(void) a;
440 	(void) b;
441 	/* never identical */
442 	return 1;
443 }
444 
cmp_attr_arm_fConst(const ir_node * a,const ir_node * b)445 static int cmp_attr_arm_fConst(const ir_node *a, const ir_node *b)
446 {
447 	const arm_fConst_attr_t *attr_a;
448 	const arm_fConst_attr_t *attr_b;
449 
450 	if (cmp_attr_arm(a, b))
451 		return 1;
452 
453 	attr_a = get_arm_fConst_attr_const(a);
454 	attr_b = get_arm_fConst_attr_const(b);
455 
456 	return attr_a->tv != attr_b->tv;
457 }
458 
459 
get_arm_load_store_attr(ir_node * node)460 arm_load_store_attr_t *get_arm_load_store_attr(ir_node *node)
461 {
462 	return (arm_load_store_attr_t*) get_irn_generic_attr(node);
463 }
464 
get_arm_load_store_attr_const(const ir_node * node)465 const arm_load_store_attr_t *get_arm_load_store_attr_const(const ir_node *node)
466 {
467 	return (const arm_load_store_attr_t*) get_irn_generic_attr_const(node);
468 }
469 
get_arm_shifter_operand_attr(ir_node * node)470 arm_shifter_operand_t *get_arm_shifter_operand_attr(ir_node *node)
471 {
472 	return (arm_shifter_operand_t*) get_irn_generic_attr(node);
473 }
474 
get_arm_shifter_operand_attr_const(const ir_node * node)475 const arm_shifter_operand_t *get_arm_shifter_operand_attr_const(
476 		const ir_node *node)
477 {
478 	return (const arm_shifter_operand_t*) get_irn_generic_attr_const(node);
479 }
480 
get_arm_cmp_attr(ir_node * node)481 arm_cmp_attr_t *get_arm_cmp_attr(ir_node *node)
482 {
483 	return (arm_cmp_attr_t*) get_irn_generic_attr(node);
484 }
485 
get_arm_cmp_attr_const(const ir_node * node)486 const arm_cmp_attr_t *get_arm_cmp_attr_const(const ir_node *node)
487 {
488 	return (const arm_cmp_attr_t*) get_irn_generic_attr_const(node);
489 }
490 
cmp_attr_arm_load_store(const ir_node * a,const ir_node * b)491 static int cmp_attr_arm_load_store(const ir_node *a, const ir_node *b)
492 {
493 	const arm_load_store_attr_t *attr_a;
494 	const arm_load_store_attr_t *attr_b;
495 
496 	if (cmp_attr_arm(a, b))
497 		return 1;
498 
499 	attr_a = get_arm_load_store_attr_const(a);
500 	attr_b = get_arm_load_store_attr_const(b);
501 	if (attr_a->entity != attr_b->entity
502 			|| attr_a->entity_sign != attr_b->entity_sign
503 			|| attr_a->offset != attr_b->offset)
504 		return 1;
505 
506 	return 0;
507 }
508 
cmp_attr_arm_shifter_operand(const ir_node * a,const ir_node * b)509 static int cmp_attr_arm_shifter_operand(const ir_node *a, const ir_node *b)
510 {
511 	const arm_shifter_operand_t *attr_a;
512 	const arm_shifter_operand_t *attr_b;
513 
514 	if (cmp_attr_arm(a, b))
515 		return 1;
516 
517 	attr_a = get_arm_shifter_operand_attr_const(a);
518 	attr_b = get_arm_shifter_operand_attr_const(b);
519 	if (attr_a->shift_modifier != attr_b->shift_modifier
520 			|| attr_a->immediate_value != attr_b->immediate_value
521 			|| attr_a->shift_immediate != attr_b->shift_immediate)
522 		return 1;
523 
524 	return 0;
525 }
526 
cmp_attr_arm_cmp(const ir_node * a,const ir_node * b)527 static int cmp_attr_arm_cmp(const ir_node *a, const ir_node *b)
528 {
529 	const arm_cmp_attr_t *attr_a;
530 	const arm_cmp_attr_t *attr_b;
531 
532 	if (cmp_attr_arm(a, b))
533 		return 1;
534 
535 	attr_a = get_arm_cmp_attr_const(a);
536 	attr_b = get_arm_cmp_attr_const(b);
537 	if (attr_a->ins_permuted != attr_b->ins_permuted
538 			|| attr_a->is_unsigned != attr_b->is_unsigned)
539 		return 1;
540 	return 0;
541 }
542 
cmp_attr_arm_farith(const ir_node * a,const ir_node * b)543 static int cmp_attr_arm_farith(const ir_node *a, const ir_node *b)
544 {
545 	const arm_farith_attr_t *attr_a;
546 	const arm_farith_attr_t *attr_b;
547 
548 	if (cmp_attr_arm(a, b))
549 		return 1;
550 
551 	attr_a = get_arm_farith_attr_const(a);
552 	attr_b = get_arm_farith_attr_const(b);
553 	return attr_a->mode != attr_b->mode;
554 }
555 
556 /** copies the ARM attributes of a node. */
arm_copy_attr(ir_graph * irg,const ir_node * old_node,ir_node * new_node)557 static void arm_copy_attr(ir_graph *irg, const ir_node *old_node,
558                           ir_node *new_node)
559 {
560 	struct obstack   *obst    = get_irg_obstack(irg);
561 	const arm_attr_t *attr_old = get_arm_attr_const(old_node);
562 	arm_attr_t       *attr_new = get_arm_attr(new_node);
563 	backend_info_t   *old_info = be_get_info(old_node);
564 	backend_info_t   *new_info = be_get_info(new_node);
565 
566 	/* copy the attributes */
567 	memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
568 
569 	/* copy out flags */
570 	new_info->flags = old_info->flags;
571 	new_info->out_infos =
572 		DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
573 	new_info->in_reqs = old_info->in_reqs;
574 }
575 
576 
577 /* Include the generated constructor functions */
578 #include "gen_arm_new_nodes.c.inl"
579