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