irdump: dump interfaces take const ir_node* now
[libfirm] / ir / be / ia32 / ia32_new_nodes.c
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       Handling of ia32 specific firm opcodes.
23  * @author      Christian Wuerdig
24  *
25  * This file implements the creation of the architecture specific firm opcodes
26  * and the corresponding node constructors for the ia32 assembler irg.
27  */
28 #include "config.h"
29
30 #include <stdlib.h>
31 #include <stdbool.h>
32
33 #include "irargs_t.h"
34 #include "irprog_t.h"
35 #include "irgraph_t.h"
36 #include "irnode_t.h"
37 #include "irmode_t.h"
38 #include "ircons_t.h"
39 #include "iropt_t.h"
40 #include "irop.h"
41 #include "irverify_t.h"
42 #include "irprintf.h"
43 #include "iredges.h"
44 #include "error.h"
45 #include "raw_bitset.h"
46 #include "xmalloc.h"
47
48 #include "bearch.h"
49 #include "beinfo.h"
50
51 #include "bearch_ia32_t.h"
52 #include "ia32_common_transform.h"
53 #include "ia32_nodes_attr.h"
54 #include "ia32_new_nodes.h"
55 #include "gen_ia32_regalloc_if.h"
56
57 /**
58  * Dumper interface for dumping ia32 nodes in vcg.
59  * @param n        the node to dump
60  * @param F        the output file
61  * @param reason   indicates which kind of information should be dumped
62  * @return 0 on success or != 0 on failure
63  */
64 static void ia32_dump_node(FILE *F, const ir_node *n, dump_reason_t reason)
65 {
66         ir_mode *mode = NULL;
67
68         switch (reason) {
69                 case dump_node_opcode_txt:
70                         fprintf(F, "%s", get_irn_opname(n));
71
72                         if (is_ia32_Immediate(n) || is_ia32_Const(n)) {
73                                 const ia32_immediate_attr_t *attr
74                                         = get_ia32_immediate_attr_const(n);
75
76                                 fputc(' ', F);
77                                 if (attr->symconst) {
78                                         if (attr->sc_sign) {
79                                                 fputc('-', F);
80                                         }
81                                         fputs(get_entity_name(attr->symconst), F);
82                                 }
83                                 if (attr->offset != 0 || attr->symconst == NULL) {
84                                         if (attr->offset > 0 && attr->symconst != NULL) {
85                                                 fputc('+', F);
86                                         }
87                                         fprintf(F, "%ld", attr->offset);
88                                         if (attr->no_pic_adjust) {
89                                                 fputs("(no_pic_adjust)", F);
90                                         }
91                                 }
92                         }
93                         else {
94                                 const ia32_attr_t *attr = get_ia32_attr_const(n);
95
96                                 if (attr->am_sc != NULL || attr->am_offs != 0)
97                                         fputs(" [", F);
98
99                                 if (attr->am_sc != NULL) {
100                                         if (attr->data.am_sc_sign) {
101                                                 fputc('-', F);
102                                         }
103                                         fputs(get_entity_name(attr->am_sc), F);
104                                         if (attr->data.am_sc_no_pic_adjust) {
105                                                 fputs("(no_pic_adjust)", F);
106                                         }
107                                 }
108                                 if (attr->am_offs != 0) {
109                                         if (attr->am_offs > 0 && attr->am_sc != NULL) {
110                                                 fputc('+', F);
111                                         }
112                                         fprintf(F, "%d", attr->am_offs);
113                                 }
114
115                                 if (attr->am_sc != NULL || attr->am_offs != 0)
116                                         fputc(']', F);
117                         }
118                         break;
119
120                 case dump_node_mode_txt:
121                         mode = get_ia32_ls_mode(n);
122                         if (mode != NULL)
123                                 fprintf(F, "[%s]", get_mode_name(mode));
124                         break;
125
126                 case dump_node_nodeattr_txt:
127                         if (! is_ia32_Lea(n)) {
128                                 if (is_ia32_AddrModeS(n)) {
129                                         fprintf(F, "[AM S] ");
130                                 } else if (is_ia32_AddrModeD(n)) {
131                                         fprintf(F, "[AM D] ");
132                                 }
133                         }
134
135                         break;
136
137                 case dump_node_info_txt:
138                         arch_dump_reqs_and_registers(F, n);
139
140                         /* dump op type */
141                         fprintf(F, "op = ");
142                         switch (get_ia32_op_type(n)) {
143                                 case ia32_Normal:
144                                         fprintf(F, "Normal");
145                                         break;
146                                 case ia32_AddrModeD:
147                                         fprintf(F, "AM Dest (Load+Store)");
148                                         break;
149                                 case ia32_AddrModeS:
150                                         fprintf(F, "AM Source (Load)");
151                                         break;
152                                 default:
153                                         fprintf(F, "unknown (%d)", (int)get_ia32_op_type(n));
154                                         break;
155                         }
156                         fprintf(F, "\n");
157
158                         /* dump supported am */
159                         fprintf(F, "AM support = ");
160                         switch (get_ia32_am_support(n)) {
161                                 case ia32_am_none:   fputs("none\n",            F); break;
162                                 case ia32_am_unary:  fputs("source (unary)\n",  F); break;
163                                 case ia32_am_binary: fputs("source (binary)\n", F); break;
164
165                                 default:
166                                         fprintf(F, "unknown (%d)\n", (int)get_ia32_am_support(n));
167                                         break;
168                         }
169
170                         /* dump AM offset */
171                         if (get_ia32_am_offs_int(n) != 0) {
172                                 fprintf(F, "AM offset = %d\n", get_ia32_am_offs_int(n));
173                         }
174
175                         /* dump AM symconst */
176                         if (get_ia32_am_sc(n) != NULL) {
177                                 ir_entity *ent = get_ia32_am_sc(n);
178                                 ident *id = get_entity_ld_ident(ent);
179                                 fprintf(F, "AM symconst = %s\n", get_id_str(id));
180                         }
181
182                         /* dump AM scale */
183                         fprintf(F, "AM scale = %u\n", get_ia32_am_scale(n));
184
185                         /* dump pn code */
186                         if (is_ia32_CMovcc(n) || is_ia32_Setcc(n) || is_ia32_Jcc(n)) {
187                                 const ia32_attr_t *attr = get_ia32_attr_const(n);
188                                 fprintf(F, "condition_code = 0x%X\n", (unsigned)get_ia32_condcode(n));
189                                 fprintf(F, "ins_permuted = %u\n", (unsigned)attr->data.ins_permuted);
190                         }
191                         else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
192                                 fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
193                         }
194
195                         fprintf(F, "use_frame = %d\n",     is_ia32_use_frame(n));
196                         fprintf(F, "commutative = %d\n",   is_ia32_commutative(n));
197                         fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
198                         fprintf(F, "is reload = %d\n",     is_ia32_is_reload(n));
199                         fprintf(F, "latency = %u\n",       get_ia32_latency(n));
200
201                         /* dump frame entity */
202                         fprintf(F, "frame entity = ");
203                         if (get_ia32_frame_ent(n)) {
204                                 ir_fprintf(F, "%+F", get_ia32_frame_ent(n));
205                         }
206                         else {
207                                 fprintf(F, "n/a");
208                         }
209                         fprintf(F, "\n");
210
211                         /* dump modes */
212                         fprintf(F, "ls_mode = ");
213                         if (get_ia32_ls_mode(n)) {
214                                 ir_fprintf(F, "%+F", get_ia32_ls_mode(n));
215                         }
216                         else {
217                                 fprintf(F, "n/a");
218                         }
219                         fprintf(F, "\n");
220
221 #ifndef NDEBUG
222                         /* dump original ir node name */
223                         fprintf(F, "orig node = ");
224                         if (get_ia32_orig_node(n)) {
225                                 fprintf(F, "%s", get_ia32_orig_node(n));
226                         }
227                         else {
228                                 fprintf(F, "n/a");
229                         }
230                         fprintf(F, "\n");
231 #endif /* NDEBUG */
232
233                         break;
234         }
235 }
236
237
238
239 ia32_attr_t *get_ia32_attr(ir_node *node)
240 {
241         assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
242         return (ia32_attr_t *)get_irn_generic_attr(node);
243 }
244
245 const ia32_attr_t *get_ia32_attr_const(const ir_node *node)
246 {
247         assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
248         return (const ia32_attr_t*) get_irn_generic_attr_const(node);
249 }
250
251 ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node)
252 {
253         ia32_attr_t     *attr     = get_ia32_attr(node);
254         ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
255         return x87_attr;
256 }
257
258 const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node)
259 {
260         const ia32_attr_t     *attr     = get_ia32_attr_const(node);
261         const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
262         return x87_attr;
263 }
264
265 const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node)
266 {
267         const ia32_attr_t     *attr     = get_ia32_attr_const(node);
268         const ia32_asm_attr_t *asm_attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, attr);
269
270         return asm_attr;
271 }
272
273 ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node)
274 {
275         ia32_attr_t           *attr      = get_ia32_attr(node);
276         ia32_immediate_attr_t *imm_attr  = CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
277
278         return imm_attr;
279 }
280
281 const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
282 {
283         const ia32_attr_t           *attr     = get_ia32_attr_const(node);
284         const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
285
286         return imm_attr;
287 }
288
289 ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
290 {
291         ia32_attr_t          *attr    = get_ia32_attr(node);
292         ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
293
294         return cc_attr;
295 }
296
297 const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node)
298 {
299         const ia32_attr_t          *attr    = get_ia32_attr_const(node);
300         const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
301
302         return cc_attr;
303 }
304
305 ia32_switch_attr_t *get_ia32_switch_attr(ir_node *node)
306 {
307         ia32_attr_t        *attr        = get_ia32_attr(node);
308         ia32_switch_attr_t *switch_attr = CAST_IA32_ATTR(ia32_switch_attr_t, attr);
309         return switch_attr;
310 }
311
312 const ia32_switch_attr_t *get_ia32_switch_attr_const(const ir_node *node)
313 {
314         const ia32_attr_t        *attr        = get_ia32_attr_const(node);
315         const ia32_switch_attr_t *switch_attr = CONST_CAST_IA32_ATTR(ia32_switch_attr_t, attr);
316         return switch_attr;
317 }
318
319 ia32_call_attr_t *get_ia32_call_attr(ir_node *node)
320 {
321         ia32_attr_t      *attr      = get_ia32_attr(node);
322         ia32_call_attr_t *call_attr = CAST_IA32_ATTR(ia32_call_attr_t, attr);
323
324         return call_attr;
325 }
326
327 const ia32_call_attr_t *get_ia32_call_attr_const(const ir_node *node)
328 {
329         const ia32_attr_t      *attr      = get_ia32_attr_const(node);
330         const ia32_call_attr_t *call_attr = CONST_CAST_IA32_ATTR(ia32_call_attr_t, attr);
331
332         return call_attr;
333 }
334
335 ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node)
336 {
337         ia32_attr_t       *attr       = get_ia32_attr(node);
338         ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
339
340         return copyb_attr;
341 }
342
343 const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node)
344 {
345         const ia32_attr_t       *attr       = get_ia32_attr_const(node);
346         const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
347
348         return copyb_attr;
349 }
350
351 ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node)
352 {
353         ia32_attr_t            *attr            = get_ia32_attr(node);
354         ia32_climbframe_attr_t *climbframe_attr = CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
355
356         return climbframe_attr;
357 }
358
359 const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node)
360 {
361         const ia32_attr_t            *attr            = get_ia32_attr_const(node);
362         const ia32_climbframe_attr_t *climbframe_attr = CONST_CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
363
364         return climbframe_attr;
365 }
366
367 /**
368  * Gets the type of an ia32 node.
369  */
370 ia32_op_type_t get_ia32_op_type(const ir_node *node)
371 {
372         const ia32_attr_t *attr = get_ia32_attr_const(node);
373         return (ia32_op_type_t)attr->data.tp;
374 }
375
376 /**
377  * Sets the type of an ia32 node.
378  */
379 void set_ia32_op_type(ir_node *node, ia32_op_type_t tp)
380 {
381         ia32_attr_t *attr = get_ia32_attr(node);
382         attr->data.tp     = tp;
383 }
384
385 ia32_am_type_t get_ia32_am_support(const ir_node *node)
386 {
387         const ia32_attr_t *attr = get_ia32_attr_const(node);
388         return (ia32_am_type_t)attr->data.am_arity;
389 }
390
391 /**
392  * Sets the supported address mode of an ia32 node
393  */
394 void set_ia32_am_support(ir_node *node, ia32_am_type_t arity)
395 {
396         ia32_attr_t *attr   = get_ia32_attr(node);
397         attr->data.am_arity = arity;
398 }
399
400 /**
401  * Gets the address mode offset as int.
402  */
403 int get_ia32_am_offs_int(const ir_node *node)
404 {
405         const ia32_attr_t *attr = get_ia32_attr_const(node);
406         return attr->am_offs;
407 }
408
409 /**
410  * Sets the address mode offset from an int.
411  */
412 void set_ia32_am_offs_int(ir_node *node, int offset)
413 {
414         ia32_attr_t *attr = get_ia32_attr(node);
415         attr->am_offs = offset;
416 }
417
418 void add_ia32_am_offs_int(ir_node *node, int offset)
419 {
420         ia32_attr_t *attr = get_ia32_attr(node);
421         attr->am_offs += offset;
422 }
423
424 /**
425  * Returns the symconst entity associated to address mode.
426  */
427 ir_entity *get_ia32_am_sc(const ir_node *node)
428 {
429         const ia32_attr_t *attr = get_ia32_attr_const(node);
430         return attr->am_sc;
431 }
432
433 /**
434  * Sets the symconst entity associated to address mode.
435  */
436 void set_ia32_am_sc(ir_node *node, ir_entity *entity)
437 {
438         ia32_attr_t *attr = get_ia32_attr(node);
439         attr->am_sc       = entity;
440 }
441
442 /**
443  * Sets the sign bit for address mode symconst.
444  */
445 void set_ia32_am_sc_sign(ir_node *node)
446 {
447         ia32_attr_t *attr     = get_ia32_attr(node);
448         attr->data.am_sc_sign = 1;
449 }
450
451 /**
452  * Clears the sign bit for address mode symconst.
453  */
454 void clear_ia32_am_sc_sign(ir_node *node)
455 {
456         ia32_attr_t *attr     = get_ia32_attr(node);
457         attr->data.am_sc_sign = 0;
458 }
459
460 /**
461  * Returns the sign bit for address mode symconst.
462  */
463 int is_ia32_am_sc_sign(const ir_node *node)
464 {
465         const ia32_attr_t *attr = get_ia32_attr_const(node);
466         return attr->data.am_sc_sign;
467 }
468
469 void set_ia32_am_tls_segment(ir_node *node, bool value)
470 {
471         ia32_attr_t *attr = get_ia32_attr(node);
472         attr->data.am_tls_segment = value;
473 }
474
475 bool get_ia32_am_tls_segment(const ir_node *node)
476 {
477         const ia32_attr_t *attr = get_ia32_attr_const(node);
478         return attr->data.am_tls_segment;
479 }
480
481 /**
482  * Gets the addr mode const.
483  */
484 unsigned get_ia32_am_scale(const ir_node *node)
485 {
486         const ia32_attr_t *attr = get_ia32_attr_const(node);
487         return attr->data.am_scale;
488 }
489
490 /**
491  * Sets the index register scale for address mode.
492  */
493 void set_ia32_am_scale(ir_node *node, unsigned scale)
494 {
495         ia32_attr_t *attr = get_ia32_attr(node);
496         assert(scale <= 3 && "AM scale out of range [0 ... 3]");
497         attr->data.am_scale = scale;
498 }
499
500 void ia32_copy_am_attrs(ir_node *to, const ir_node *from)
501 {
502         set_ia32_ls_mode(to, get_ia32_ls_mode(from));
503         set_ia32_am_scale(to, get_ia32_am_scale(from));
504         set_ia32_am_sc(to, get_ia32_am_sc(from));
505         if (is_ia32_am_sc_sign(from))
506                 set_ia32_am_sc_sign(to);
507         add_ia32_am_offs_int(to, get_ia32_am_offs_int(from));
508         set_ia32_frame_ent(to, get_ia32_frame_ent(from));
509         if (is_ia32_use_frame(from))
510                 set_ia32_use_frame(to);
511 }
512
513 /**
514  * Sets the uses_frame flag.
515  */
516 void set_ia32_use_frame(ir_node *node)
517 {
518         ia32_attr_t *attr    = get_ia32_attr(node);
519         attr->data.use_frame = 1;
520 }
521
522 /**
523  * Clears the uses_frame flag.
524  */
525 void clear_ia32_use_frame(ir_node *node)
526 {
527         ia32_attr_t *attr    = get_ia32_attr(node);
528         attr->data.use_frame = 0;
529 }
530
531 /**
532  * Gets the uses_frame flag.
533  */
534 int is_ia32_use_frame(const ir_node *node)
535 {
536         const ia32_attr_t *attr = get_ia32_attr_const(node);
537         return attr->data.use_frame;
538 }
539
540 /**
541  * Sets node to commutative.
542  */
543 void set_ia32_commutative(ir_node *node)
544 {
545         ia32_attr_t *attr         = get_ia32_attr(node);
546         attr->data.is_commutative = 1;
547 }
548
549 /**
550  * Sets node to non-commutative.
551  */
552 void clear_ia32_commutative(ir_node *node)
553 {
554         ia32_attr_t *attr         = get_ia32_attr(node);
555         attr->data.is_commutative = 0;
556 }
557
558 /**
559  * Checks if node is commutative.
560  */
561 int is_ia32_commutative(const ir_node *node)
562 {
563         const ia32_attr_t *attr = get_ia32_attr_const(node);
564         return attr->data.is_commutative;
565 }
566
567 void set_ia32_need_stackent(ir_node *node)
568 {
569         ia32_attr_t *attr     = get_ia32_attr(node);
570         attr->data.need_stackent = 1;
571 }
572
573 void clear_ia32_need_stackent(ir_node *node)
574 {
575         ia32_attr_t *attr     = get_ia32_attr(node);
576         attr->data.need_stackent = 0;
577 }
578
579 int is_ia32_need_stackent(const ir_node *node)
580 {
581         const ia32_attr_t *attr = get_ia32_attr_const(node);
582         return attr->data.need_stackent;
583 }
584
585 void set_ia32_is_reload(ir_node *node)
586 {
587         ia32_attr_t *attr = get_ia32_attr(node);
588         attr->data.is_reload = 1;
589 }
590
591 int is_ia32_is_reload(const ir_node *node)
592 {
593         const ia32_attr_t *attr = get_ia32_attr_const(node);
594         return attr->data.is_reload;
595 }
596
597 void set_ia32_is_spill(ir_node *node)
598 {
599         ia32_attr_t *attr = get_ia32_attr(node);
600         attr->data.is_spill = 1;
601 }
602
603 int is_ia32_is_spill(const ir_node *node)
604 {
605         const ia32_attr_t *attr = get_ia32_attr_const(node);
606         return attr->data.is_spill;
607 }
608
609 void set_ia32_is_remat(ir_node *node)
610 {
611         ia32_attr_t *attr = get_ia32_attr(node);
612         attr->data.is_remat = 1;
613 }
614
615 int is_ia32_is_remat(const ir_node *node)
616 {
617         const ia32_attr_t *attr = get_ia32_attr_const(node);
618         return attr->data.is_remat;
619 }
620
621 /**
622  * Gets the mode of the stored/loaded value (only set for Store/Load)
623  */
624 ir_mode *get_ia32_ls_mode(const ir_node *node)
625 {
626         const ia32_attr_t *attr = get_ia32_attr_const(node);
627         return attr->ls_mode;
628 }
629
630 /**
631  * Sets the mode of the stored/loaded value (only set for Store/Load)
632  */
633 void set_ia32_ls_mode(ir_node *node, ir_mode *mode)
634 {
635         ia32_attr_t *attr = get_ia32_attr(node);
636         attr->ls_mode     = mode;
637 }
638
639 /**
640  * Gets the frame entity assigned to this node.
641  */
642 ir_entity *get_ia32_frame_ent(const ir_node *node)
643 {
644         const ia32_attr_t *attr = get_ia32_attr_const(node);
645         return attr->frame_ent;
646 }
647
648 /**
649  * Sets the frame entity for this node.
650  */
651 void set_ia32_frame_ent(ir_node *node, ir_entity *ent)
652 {
653         ia32_attr_t *attr = get_ia32_attr(node);
654         attr->frame_ent   = ent;
655         if (ent != NULL)
656                 set_ia32_use_frame(node);
657         else
658                 clear_ia32_use_frame(node);
659 }
660
661
662 /**
663  * Gets the instruction latency.
664  */
665 unsigned get_ia32_latency(const ir_node *node)
666 {
667         const ir_op *op               = get_irn_op(node);
668         const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op);
669         return op_attr->latency;
670 }
671
672 const ir_switch_table *get_ia32_switch_table(const ir_node *node)
673 {
674         const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
675         return attr->table;
676 }
677
678 ia32_condition_code_t get_ia32_condcode(const ir_node *node)
679 {
680         const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
681         return attr->condition_code;
682 }
683
684 /**
685  * Sets the condition code of a node
686  */
687 void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
688 {
689         ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
690         attr->condition_code = code;
691 }
692
693 /**
694  * Returns the condition code of a node.
695  */
696 unsigned get_ia32_copyb_size(const ir_node *node)
697 {
698         const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
699         return attr->size;
700 }
701
702 /**
703  * Get the exception label attribute.
704  */
705 unsigned get_ia32_exc_label(const ir_node *node)
706 {
707         const ia32_attr_t *attr = get_ia32_attr_const(node);
708         return attr->data.has_except_label;
709 }
710
711 /**
712  * Set the exception label attribute.
713  */
714 void set_ia32_exc_label(ir_node *node, unsigned flag)
715 {
716         ia32_attr_t *attr = get_ia32_attr(node);
717         attr->data.has_except_label = flag;
718 }
719
720 /**
721  * Return the exception label id.
722  */
723 ir_label_t get_ia32_exc_label_id(const ir_node *node)
724 {
725         const ia32_attr_t *attr = get_ia32_attr_const(node);
726
727         assert(attr->data.has_except_label);
728         return attr->exc_label;
729 }
730
731 /**
732  * Assign the exception label id.
733  */
734 void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
735 {
736         ia32_attr_t *attr = get_ia32_attr(node);
737
738         assert(attr->data.has_except_label);
739         attr->exc_label = id;
740 }
741
742 #ifndef NDEBUG
743
744 /**
745  * Returns the name of the original ir node.
746  */
747 const char *get_ia32_orig_node(const ir_node *node)
748 {
749         const ia32_attr_t *attr = get_ia32_attr_const(node);
750         return attr->orig_node;
751 }
752
753 static const char *ia32_get_old_node_name(const ir_node *irn)
754 {
755         ir_graph       *irg  = get_irn_irg(irn);
756         struct obstack *obst = be_get_be_obst(irg);
757
758         lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
759         obstack_1grow(obst, 0);
760         return (const char*)obstack_finish(obst);
761 }
762
763 /**
764  * Sets the name of the original ir node.
765  */
766 void set_ia32_orig_node(ir_node *node, const ir_node *old)
767 {
768         const char  *name = ia32_get_old_node_name(old);
769         ia32_attr_t *attr = get_ia32_attr(node);
770         attr->orig_node   = name;
771 }
772
773 #endif /* NDEBUG */
774
775
776 /**
777  * Returns whether or not the node is an AddrModeS node.
778  */
779 int is_ia32_AddrModeS(const ir_node *node)
780 {
781         const ia32_attr_t *attr = get_ia32_attr_const(node);
782         return (attr->data.tp == ia32_AddrModeS);
783 }
784
785 /**
786  * Returns whether or not the node is an AddrModeD node.
787  */
788 int is_ia32_AddrModeD(const ir_node *node)
789 {
790         const ia32_attr_t *attr = get_ia32_attr_const(node);
791         return (attr->data.tp == ia32_AddrModeD);
792 }
793
794 void ia32_swap_left_right(ir_node *node)
795 {
796         ia32_attr_t *attr  = get_ia32_attr(node);
797         ir_node     *left  = get_irn_n(node, n_ia32_binary_left);
798         ir_node     *right = get_irn_n(node, n_ia32_binary_right);
799
800         assert(is_ia32_commutative(node));
801         attr->data.ins_permuted = !attr->data.ins_permuted;
802         set_irn_n(node, n_ia32_binary_left,  right);
803         set_irn_n(node, n_ia32_binary_right, left);
804 }
805
806 /**
807  * Initializes the nodes attributes.
808  */
809 static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
810                                  const arch_register_req_t **in_reqs,
811                                  int n_res)
812 {
813         ir_graph        *irg  = get_irn_irg(node);
814         struct obstack  *obst = get_irg_obstack(irg);
815         ia32_attr_t     *attr = get_ia32_attr(node);
816         backend_info_t  *info;
817
818         arch_set_irn_flags(node, flags);
819         arch_set_irn_register_reqs_in(node, in_reqs);
820
821 #ifndef NDEBUG
822         attr->attr_type  |= IA32_ATTR_ia32_attr_t;
823 #endif
824
825         info            = be_get_info(node);
826         info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
827         memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
828 }
829
830 static void init_ia32_x87_attributes(ir_node *res)
831 {
832         ir_graph        *irg      = get_irn_irg(res);
833         ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
834 #ifndef NDEBUG
835         ia32_attr_t *attr  = get_ia32_attr(res);
836         attr->attr_type   |= IA32_ATTR_ia32_x87_attr_t;
837 #else
838         (void) res;
839 #endif
840         irg_data->do_x87_sim = 1;
841 }
842
843 static void init_ia32_asm_attributes(ir_node *res)
844 {
845 #ifndef NDEBUG
846         ia32_attr_t *attr  = get_ia32_attr(res);
847         attr->attr_type   |= IA32_ATTR_ia32_asm_attr_t;
848 #else
849         (void) res;
850 #endif
851 }
852
853 static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
854                                            int symconst_sign, int no_pic_adjust,
855                                            long offset)
856 {
857         ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
858
859 #ifndef NDEBUG
860         attr->attr.attr_type  |= IA32_ATTR_ia32_immediate_attr_t;
861 #endif
862         attr->symconst      = symconst;
863         attr->sc_sign       = symconst_sign;
864         attr->no_pic_adjust = no_pic_adjust;
865         attr->offset        = offset;
866 }
867
868 static void init_ia32_call_attributes(ir_node* res, unsigned pop,
869                                       ir_type* call_tp)
870 {
871         ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
872
873 #ifndef NDEBUG
874         attr->attr.attr_type  |= IA32_ATTR_ia32_call_attr_t;
875 #endif
876         attr->pop     = pop;
877         attr->call_tp = call_tp;
878 }
879
880 static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
881 {
882         ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
883
884 #ifndef NDEBUG
885         attr->attr.attr_type  |= IA32_ATTR_ia32_copyb_attr_t;
886 #endif
887         attr->size = size;
888 }
889
890 static void init_ia32_condcode_attributes(ir_node *res,
891                                           ia32_condition_code_t cc)
892 {
893         ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
894
895 #ifndef NDEBUG
896         attr->attr.attr_type  |= IA32_ATTR_ia32_condcode_attr_t;
897 #endif
898         attr->condition_code = cc;
899 }
900
901 static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
902 {
903         ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
904
905 #ifndef NDEBUG
906         attr->attr.attr_type  |= IA32_ATTR_ia32_climbframe_attr_t;
907 #endif
908         attr->count = count;
909 }
910
911 static void init_ia32_switch_attributes(ir_node *node,
912                                         const ir_switch_table *table)
913 {
914         unsigned n_outs = arch_get_irn_n_outs(node);
915         unsigned o;
916
917         ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(node);
918 #ifndef NDEBUG
919         attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
920 #endif
921         attr->table = table;
922
923         for (o = 0; o < n_outs; ++o) {
924                 arch_set_irn_register_req_out(node, o, arch_no_register_req);
925         }
926 }
927
928 /* default compare operation to compare attributes */
929 static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
930 {
931         if (a->data.tp != b->data.tp)
932                 return 1;
933
934         if (a->data.am_scale != b->data.am_scale
935             || a->data.am_sc_sign != b->data.am_sc_sign
936             || a->am_offs != b->am_offs
937             || a->am_sc != b->am_sc
938                 || a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
939             || a->ls_mode != b->ls_mode)
940                 return 1;
941
942         /* nodes with not yet assigned entities shouldn't be CSEd (important for
943          * unsigned int -> double conversions */
944         if (a->data.use_frame && a->frame_ent == NULL)
945                 return 1;
946         if (b->data.use_frame && b->frame_ent == NULL)
947                 return 1;
948
949         if (a->data.use_frame != b->data.use_frame
950             || a->frame_ent != b->frame_ent)
951                 return 1;
952
953         if (a->data.has_except_label != b->data.has_except_label)
954                 return 1;
955
956         if (a->data.ins_permuted != b->data.ins_permuted)
957                 return 1;
958
959         return 0;
960 }
961
962 /** Compare nodes attributes for all "normal" nodes. */
963 static int ia32_compare_nodes_attr(const ir_node *a, const ir_node *b)
964 {
965         const ia32_attr_t* attr_a = get_ia32_attr_const(a);
966         const ia32_attr_t* attr_b = get_ia32_attr_const(b);
967
968         return ia32_compare_attr(attr_a, attr_b);
969 }
970
971 /** Compare node attributes for nodes with condition code. */
972 static int ia32_compare_condcode_attr(const ir_node *a, const ir_node *b)
973 {
974         const ia32_condcode_attr_t *attr_a;
975         const ia32_condcode_attr_t *attr_b;
976
977         if (ia32_compare_nodes_attr(a, b))
978                 return 1;
979
980         attr_a = get_ia32_condcode_attr_const(a);
981         attr_b = get_ia32_condcode_attr_const(b);
982
983         if (attr_a->condition_code != attr_b->condition_code)
984                 return 1;
985
986         return 0;
987 }
988
989 /** Compare node attributes for call nodes. */
990 static int ia32_compare_call_attr(const ir_node *a, const ir_node *b)
991 {
992         const ia32_call_attr_t *attr_a;
993         const ia32_call_attr_t *attr_b;
994
995         if (ia32_compare_nodes_attr(a, b))
996                 return 1;
997
998         attr_a = get_ia32_call_attr_const(a);
999         attr_b = get_ia32_call_attr_const(b);
1000
1001         if (attr_a->pop != attr_b->pop)
1002                 return 1;
1003
1004         if (attr_a->call_tp != attr_b->call_tp)
1005                 return 1;
1006
1007         return 0;
1008 }
1009
1010 /** Compare node attributes for CopyB nodes. */
1011 static int ia32_compare_copyb_attr(const ir_node *a, const ir_node *b)
1012 {
1013         const ia32_copyb_attr_t *attr_a;
1014         const ia32_copyb_attr_t *attr_b;
1015
1016         if (ia32_compare_nodes_attr(a, b))
1017                 return 1;
1018
1019         attr_a = get_ia32_copyb_attr_const(a);
1020         attr_b = get_ia32_copyb_attr_const(b);
1021
1022         if (attr_a->size != attr_b->size)
1023                 return 1;
1024
1025         return 0;
1026 }
1027
1028
1029 /** Compare ASM node attributes. */
1030 static int ia32_compare_asm_attr(const ir_node *a, const ir_node *b)
1031 {
1032         const ia32_asm_attr_t *attr_a;
1033         const ia32_asm_attr_t *attr_b;
1034
1035         if (ia32_compare_nodes_attr(a, b))
1036                 return 1;
1037
1038         attr_a = get_ia32_asm_attr_const(a);
1039         attr_b = get_ia32_asm_attr_const(b);
1040
1041         if (attr_a->asm_text != attr_b->asm_text)
1042                 return 1;
1043
1044         return 0;
1045 }
1046
1047 /**
1048  * Hash function for Immediates
1049  */
1050 static unsigned ia32_hash_Immediate(const ir_node *irn)
1051 {
1052         const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
1053
1054         return HASH_PTR(a->symconst) + (a->sc_sign << 16) + a->offset;
1055 }
1056
1057 /** Compare node attributes for Immediates. */
1058 static int ia32_compare_immediate_attr(const ir_node *a, const ir_node *b)
1059 {
1060         const ia32_immediate_attr_t *attr_a = get_ia32_immediate_attr_const(a);
1061         const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
1062
1063         if (attr_a->symconst != attr_b->symconst
1064                 || attr_a->sc_sign != attr_b->sc_sign
1065                 || attr_a->no_pic_adjust != attr_b->no_pic_adjust
1066                 || attr_a->offset != attr_b->offset) {
1067                 return 1;
1068         }
1069
1070         return 0;
1071 }
1072
1073 /** Compare node attributes for x87 nodes. */
1074 static int ia32_compare_x87_attr(const ir_node *a, const ir_node *b)
1075 {
1076         return ia32_compare_nodes_attr(a, b);
1077 }
1078
1079 /** Compare node attributes for ClimbFrame nodes. */
1080 static int ia32_compare_climbframe_attr(const ir_node *a, const ir_node *b)
1081 {
1082         const ia32_climbframe_attr_t *attr_a;
1083         const ia32_climbframe_attr_t *attr_b;
1084
1085         if (ia32_compare_nodes_attr(a, b))
1086                 return 1;
1087
1088         attr_a = get_ia32_climbframe_attr_const(a);
1089         attr_b = get_ia32_climbframe_attr_const(b);
1090
1091         if (attr_a->count != attr_b->count)
1092                 return 1;
1093
1094         return 0;
1095 }
1096
1097 /* copies the ia32 attributes */
1098 static void ia32_copy_attr(ir_graph *irg, const ir_node *old_node,
1099                            ir_node *new_node)
1100 {
1101         struct obstack    *obst     = get_irg_obstack(irg);
1102         const ia32_attr_t *attr_old = get_ia32_attr_const(old_node);
1103         ia32_attr_t       *attr_new = get_ia32_attr(new_node);
1104         backend_info_t    *old_info = be_get_info(old_node);
1105         backend_info_t    *new_info = be_get_info(new_node);
1106
1107         /* copy the attributes */
1108         memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
1109
1110         /* copy out flags */
1111         new_info->out_infos =
1112                 DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
1113         new_info->in_reqs = old_info->in_reqs;
1114         new_info->flags = old_info->flags;
1115 }
1116
1117 /* Include the generated constructor functions */
1118 #include "gen_ia32_new_nodes.c.inl"