added copy attribute function (out_flags is a variable array on irg obstack)
[libfirm] / ir / be / ia32 / ia32_new_nodes.c
1 /**
2  * This file implements the creation of the achitecture specific firm opcodes
3  * and the coresponding node constructors for the ia32 assembler irg.
4  * @author Christian Wuerdig
5  * $Id$
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #ifdef HAVE_MALLOC_H
13 #include <malloc.h>
14 #endif
15
16 #ifdef HAVE_ALLOCA_H
17 #include <alloca.h>
18 #endif
19
20 #include <stdlib.h>
21
22 #include "irprog_t.h"
23 #include "irgraph_t.h"
24 #include "irnode_t.h"
25 #include "irmode_t.h"
26 #include "ircons_t.h"
27 #include "iropt_t.h"
28 #include "irop.h"
29 #include "firm_common_t.h"
30 #include "irvrfy_t.h"
31 #include "irprintf.h"
32
33 #include "../bearch.h"
34
35 #include "ia32_nodes_attr.h"
36 #include "ia32_new_nodes.h"
37 #include "gen_ia32_regalloc_if.h"
38 #include "gen_ia32_machine.h"
39
40 /**
41  * Returns the ident of a SymConst.
42  * @param symc  The SymConst
43  * @return The ident of the SymConst
44  */
45 static ident *get_sc_ident(ir_node *symc) {
46         entity  *ent;
47         ir_type *owner;
48         ident   *id;
49
50         switch (get_SymConst_kind(symc)) {
51                 case symconst_addr_name:
52                         return get_SymConst_name(symc);
53
54                 case symconst_addr_ent:
55                         ent   = get_SymConst_entity(symc);
56                         owner = get_entity_owner(ent);
57                         id    = get_entity_ld_ident(ent);
58                         if (owner == get_tls_type()) {
59                                 if (get_entity_visibility(ent) == visibility_external_allocated)
60                                         id = mangle(id, new_id_from_chars("@INDNTPOFF", 10));
61                                 else
62                                         id = mangle(id, new_id_from_chars("@NTPOFF", 7));
63                         }
64                         return id;
65
66                 default:
67                         assert(0 && "Unsupported SymConst");
68         }
69
70         return NULL;
71 }
72
73 /**
74  * returns true if a node has x87 registers
75  */
76 int ia32_has_x87_register(const ir_node *n) {
77         assert(is_ia32_irn(n) && "Need ia32 node.");
78         return is_irn_machine_user(n, 0);
79 }
80
81 /***********************************************************************************
82  *      _                                   _       _             __
83  *     | |                                 (_)     | |           / _|
84  *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
85  *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
86  * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
87  *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
88  *                       | |
89  *                       |_|
90  ***********************************************************************************/
91
92 /**
93  * Returns a string containing the names of all registers within the limited bitset
94  */
95 static char *get_limited_regs(const arch_register_req_t *req, char *buf, int max) {
96         bitset_t *bs   = bitset_alloca(req->cls->n_regs);
97         char     *p    = buf;
98         int       size = 0;
99         int       i, cnt;
100
101         req->limited(NULL, bs);
102
103         for (i = 0; i < req->cls->n_regs; i++) {
104                 if (bitset_is_set(bs, i)) {
105                         cnt = snprintf(p, max - size, " %s", req->cls->regs[i].name);
106                         if (cnt < 0) {
107                                 fprintf(stderr, "dumper problem, exiting\n");
108                                 exit(1);
109                         }
110
111                         p    += cnt;
112                         size += cnt;
113
114                         if (size >= max)
115                                 break;
116                 }
117         }
118
119         return buf;
120 }
121
122 /**
123  * Dumps the register requirements for either in or out.
124  */
125 static void dump_reg_req(FILE *F, ir_node *n, const ia32_register_req_t **reqs, int inout) {
126         char *dir = inout ? "out" : "in";
127         int   max = inout ? get_ia32_n_res(n) : get_irn_arity(n);
128         char *buf = alloca(1024);
129         int   i;
130
131         memset(buf, 0, 1024);
132
133         if (reqs) {
134                 for (i = 0; i < max; i++) {
135                         fprintf(F, "%sreq #%d =", dir, i);
136
137                         if (reqs[i]->req.type == arch_register_req_type_none) {
138                                 fprintf(F, " n/a");
139                         }
140
141                         if (reqs[i]->req.type & arch_register_req_type_normal) {
142                                 fprintf(F, " %s", reqs[i]->req.cls->name);
143                         }
144
145                         if (reqs[i]->req.type & arch_register_req_type_limited) {
146                                 fprintf(F, " %s", get_limited_regs(&reqs[i]->req, buf, 1024));
147                         }
148
149                         if (reqs[i]->req.type & arch_register_req_type_should_be_same) {
150                                 ir_fprintf(F, " same as %+F", get_irn_n(n, reqs[i]->same_pos));
151                         }
152
153                         if (reqs[i]->req.type & arch_register_req_type_should_be_different) {
154                                 ir_fprintf(F, " different from %+F", get_irn_n(n, reqs[i]->different_pos));
155                         }
156
157                         fprintf(F, "\n");
158                 }
159
160                 fprintf(F, "\n");
161         }
162         else {
163                 fprintf(F, "%sreq = N/A\n", dir);
164         }
165 }
166
167 /**
168  * Dumper interface for dumping ia32 nodes in vcg.
169  * @param n        the node to dump
170  * @param F        the output file
171  * @param reason   indicates which kind of information should be dumped
172  * @return 0 on success or != 0 on failure
173  */
174 static int ia32_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
175         ir_mode     *mode = NULL;
176         int          bad  = 0;
177         int          i, n_res, am_flav, flags;
178         const ia32_register_req_t **reqs;
179         const arch_register_t     **slots;
180
181         switch (reason) {
182                 case dump_node_opcode_txt:
183                         fprintf(F, "%s", get_irn_opname(n));
184                         break;
185
186                 case dump_node_mode_txt:
187                         mode = get_irn_mode(n);
188
189                         if (is_ia32_Ld(n) || is_ia32_St(n)) {
190                                 mode = get_ia32_ls_mode(n);
191                         }
192
193                         fprintf(F, "[%s]", mode ? get_mode_name(mode) : "?NOMODE?");
194                         break;
195
196                 case dump_node_nodeattr_txt:
197                         if (is_ia32_ImmConst(n) || is_ia32_ImmSymConst(n) || is_ia32_Cnst(n)) {
198                                 char       *pref = is_ia32_ImmSymConst(n) || (get_ia32_op_type(n) == ia32_SymConst) ? "SymC " : "";
199                                 const char *cnst = get_ia32_cnst(n);
200
201                                 fprintf(F, "[%s%s]", pref, cnst ? cnst : "NONE");
202                         }
203
204                         if (! is_ia32_Lea(n)) {
205                                 if (is_ia32_AddrModeS(n)) {
206                                         fprintf(F, "[AM S] ");
207                                 }
208                                 else if (is_ia32_AddrModeD(n)) {
209                                         fprintf(F, "[AM D] ");
210                                 }
211                         }
212
213                         break;
214
215                 case dump_node_info_txt:
216                         n_res = get_ia32_n_res(n);
217                         fprintf(F, "=== IA32 attr begin ===\n");
218
219                         /* dump IN requirements */
220                         if (get_irn_arity(n) > 0) {
221                                 reqs = get_ia32_in_req_all(n);
222                                 dump_reg_req(F, n, reqs, 0);
223                         }
224
225                         /* dump OUT requirements */
226                         if (n_res > 0) {
227                                 reqs = get_ia32_out_req_all(n);
228                                 dump_reg_req(F, n, reqs, 1);
229                         }
230
231                         /* dump assigned registers */
232                         slots = get_ia32_slots(n);
233                         if (slots && n_res > 0) {
234                                 for (i = 0; i < n_res; i++) {
235                                         const arch_register_t *reg;
236
237                                         /* retrieve "real" x87 register */
238                                         if (ia32_has_x87_register(n))
239                                                 reg = get_ia32_attr(n)->x87[i + 2];
240                                         else
241                                                 reg = slots[i];
242
243                                         fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
244                                 }
245                                 fprintf(F, "\n");
246                         }
247
248                         /* dump op type */
249                         fprintf(F, "op = ");
250                         switch (get_ia32_op_type(n)) {
251                                 case ia32_Normal:
252                                         fprintf(F, "Normal");
253                                         break;
254                                 case ia32_Const:
255                                         fprintf(F, "Const");
256                                         break;
257                                 case ia32_SymConst:
258                                         fprintf(F, "SymConst");
259                                         break;
260                                 case ia32_AddrModeD:
261                                         fprintf(F, "AM Dest (Load+Store)");
262                                         break;
263                                 case ia32_AddrModeS:
264                                         fprintf(F, "AM Source (Load)");
265                                         break;
266                                 default:
267                                         fprintf(F, "unknown (%d)", get_ia32_op_type(n));
268                                         break;
269                         }
270                         fprintf(F, "\n");
271
272                         /* dump immop type */
273                         fprintf(F, "immediate = ");
274                         switch (get_ia32_immop_type(n)) {
275                                 case ia32_ImmNone:
276                                         fprintf(F, "None");
277                                         break;
278                                 case ia32_ImmConst:
279                                         fprintf(F, "Const");
280                                         break;
281                                 case ia32_ImmSymConst:
282                                         fprintf(F, "SymConst");
283                                         break;
284                                 default:
285                                         fprintf(F, "unknown (%d)", get_ia32_immop_type(n));
286                                         break;
287                         }
288                         fprintf(F, "\n");
289
290                         /* dump supported am */
291                         fprintf(F, "AM support = ");
292                         switch (get_ia32_am_support(n)) {
293                                 case ia32_am_None:
294                                         fprintf(F, "none");
295                                         break;
296                                 case ia32_am_Source:
297                                         fprintf(F, "source only (Load)");
298                                         break;
299                                 case ia32_am_Dest:
300                                         fprintf(F, "dest only (Load+Store)");
301                                         break;
302                                 case ia32_am_Full:
303                                         fprintf(F, "full");
304                                         break;
305                                 default:
306                                         fprintf(F, "unknown (%d)", get_ia32_am_support(n));
307                                         break;
308                         }
309                         fprintf(F, "\n");
310
311                         /* dump am flavour */
312                         fprintf(F, "AM flavour =");
313                         am_flav = get_ia32_am_flavour(n);
314                         if (am_flav == ia32_am_N) {
315                                 fprintf(F, " none");
316                         }
317                         else {
318                                 if (am_flav & ia32_O) {
319                                         fprintf(F, " O");
320                                 }
321                                 if (am_flav & ia32_B) {
322                                         fprintf(F, " B");
323                                 }
324                                 if (am_flav & ia32_I) {
325                                         fprintf(F, " I");
326                                 }
327                                 if (am_flav & ia32_S) {
328                                         fprintf(F, " S");
329                                 }
330                         }
331                         fprintf(F, " (%d)\n", am_flav);
332
333                         /* dump AM offset */
334                         fprintf(F, "AM offset = ");
335                         if (get_ia32_am_offs(n)) {
336                                 fprintf(F, "%s", get_ia32_am_offs(n));
337                         }
338                         else {
339                                 fprintf(F, "n/a");
340                         }
341                         fprintf(F, "\n");
342
343                         /* dump AM scale */
344                         fprintf(F, "AM scale = %d\n", get_ia32_am_scale(n));
345
346                         /* dump pn code */
347                         fprintf(F, "pn_code = %ld\n", get_ia32_pncode(n));
348
349                         /* dump n_res */
350                         fprintf(F, "n_res = %d\n", get_ia32_n_res(n));
351
352                         /* dump use_frame */
353                         fprintf(F, "use_frame = %d\n", is_ia32_use_frame(n));
354
355                         /* commutative */
356                         fprintf(F, "commutative = %d\n", is_ia32_commutative(n));
357
358                         /* emit cl */
359                         fprintf(F, "emit cl instead of ecx = %d\n", is_ia32_emit_cl(n));
360
361                         /* got lea */
362                         fprintf(F, "got loea = %d\n", is_ia32_got_lea(n));
363
364                         /* got reload */
365                         fprintf(F, "got reload = %d\n", is_ia32_got_reload(n));
366
367                         /* dump latency */
368                         fprintf(F, "latency = %d\n", get_ia32_latency(n));
369
370                         /* dump flags */
371                         fprintf(F, "flags =");
372                         flags = get_ia32_flags(n);
373                         if (flags == arch_irn_flags_none) {
374                                 fprintf(F, " none");
375                         }
376                         else {
377                                 if (flags & arch_irn_flags_dont_spill) {
378                                         fprintf(F, " unspillable");
379                                 }
380                                 if (flags & arch_irn_flags_rematerializable) {
381                                         fprintf(F, " remat");
382                                 }
383                                 if (flags & arch_irn_flags_ignore) {
384                                         fprintf(F, " ignore");
385                                 }
386                                 if (flags & arch_irn_flags_modify_sp) {
387                                         fprintf(F, " modify_sp");
388                                 }
389                         }
390                         fprintf(F, " (%d)\n", flags);
391
392                         /* dump frame entity */
393                         fprintf(F, "frame entity = ");
394                         if (get_ia32_frame_ent(n)) {
395                                 ir_fprintf(F, "%+F", get_ia32_frame_ent(n));
396                         }
397                         else {
398                                 fprintf(F, "n/a");
399                         }
400                         fprintf(F, "\n");
401
402                         /* dump modes */
403                         fprintf(F, "ls_mode = ");
404                         if (get_ia32_ls_mode(n)) {
405                                 ir_fprintf(F, "%+F", get_ia32_ls_mode(n));
406                         }
407                         else {
408                                 fprintf(F, "n/a");
409                         }
410                         fprintf(F, "\n");
411
412                         fprintf(F, "res_mode = ");
413                         if (get_ia32_res_mode(n)) {
414                                 ir_fprintf(F, "%+F", get_ia32_res_mode(n));
415                         }
416                         else {
417                                 fprintf(F, "n/a");
418                         }
419                         fprintf(F, "\n");
420
421                         fprintf(F, "src_mode = ");
422                         if (get_ia32_src_mode(n)) {
423                                 ir_fprintf(F, "%+F", get_ia32_src_mode(n));
424                         }
425                         else {
426                                 fprintf(F, "n/a");
427                         }
428                         fprintf(F, "\n");
429
430                         fprintf(F, "tgt_mode = ");
431                         if (get_ia32_tgt_mode(n)) {
432                                 ir_fprintf(F, "%+F", get_ia32_tgt_mode(n));
433                         }
434                         else {
435                                 fprintf(F, "n/a");
436                         }
437                         fprintf(F, "\n");
438
439 #ifndef NDEBUG
440                         /* dump original ir node name */
441                         fprintf(F, "orig node = ");
442                         if (get_ia32_orig_node(n)) {
443                                 fprintf(F, "%s", get_ia32_orig_node(n));
444                         }
445                         else {
446                                 fprintf(F, "n/a");
447                         }
448                         fprintf(F, "\n");
449 #endif /* NDEBUG */
450
451                         fprintf(F, "=== IA32 attr end ===\n");
452                         /* end of: case dump_node_info_txt */
453                         break;
454         }
455
456         return bad;
457 }
458
459
460
461 /***************************************************************************************************
462  *        _   _                   _       __        _                    _   _               _
463  *       | | | |                 | |     / /       | |                  | | | |             | |
464  *   __ _| |_| |_ _ __   ___  ___| |_   / /_ _  ___| |_   _ __ ___   ___| |_| |__   ___   __| |___
465  *  / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
466  * | (_| | |_| |_| |    \__ \  __/ |_ / / (_| |  __/ |_  | | | | | |  __/ |_| | | | (_) | (_| \__ \
467  *  \__,_|\__|\__|_|    |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
468  *                                        __/ |
469  *                                       |___/
470  ***************************************************************************************************/
471
472 /**
473  * Returns an ident for the given tarval tv.
474  */
475 static ident *get_ident_for_tv(tarval *tv) {
476         char buf[1024];
477         int len = tarval_snprintf(buf, sizeof(buf), tv);
478         assert(len);
479         return new_id_from_str(buf);
480 }
481
482 /**
483  * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
484  * Firm was made by people hating const :-(
485  */
486 ia32_attr_t *get_ia32_attr(const ir_node *node) {
487         assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
488         return (ia32_attr_t *)get_irn_generic_attr((ir_node *)node);
489 }
490
491 /**
492  * Gets the type of an ia32 node.
493  */
494 ia32_op_type_t get_ia32_op_type(const ir_node *node) {
495         ia32_attr_t *attr = get_ia32_attr(node);
496         return attr->data.tp;
497 }
498
499 /**
500  * Sets the type of an ia32 node.
501  */
502 void set_ia32_op_type(ir_node *node, ia32_op_type_t tp) {
503         ia32_attr_t *attr = get_ia32_attr(node);
504         attr->data.tp     = tp;
505 }
506
507 /**
508  * Gets the immediate op type of an ia32 node.
509  */
510 ia32_immop_type_t get_ia32_immop_type(const ir_node *node) {
511         ia32_attr_t *attr = get_ia32_attr(node);
512         return attr->data.imm_tp;
513 }
514
515 /**
516  * Sets the immediate op type of an ia32 node.
517  */
518 void set_ia32_immop_type(ir_node *node, ia32_immop_type_t tp) {
519         ia32_attr_t *attr = get_ia32_attr(node);
520         attr->data.imm_tp = tp;
521 }
522
523 /**
524  * Gets the supported addrmode of an ia32 node
525  */
526 ia32_am_type_t get_ia32_am_support(const ir_node *node) {
527         ia32_attr_t *attr = get_ia32_attr(node);
528         return attr->data.am_support;
529 }
530
531 /**
532  * Sets the supported addrmode of an ia32 node
533  */
534 void set_ia32_am_support(ir_node *node, ia32_am_type_t am_tp) {
535         ia32_attr_t *attr     = get_ia32_attr(node);
536         attr->data.am_support = am_tp;
537 }
538
539 /**
540  * Gets the addrmode flavour of an ia32 node
541  */
542 ia32_am_flavour_t get_ia32_am_flavour(const ir_node *node) {
543         ia32_attr_t *attr = get_ia32_attr(node);
544         return attr->data.am_flavour;
545 }
546
547 /**
548  * Sets the addrmode flavour of an ia32 node
549  */
550 void set_ia32_am_flavour(ir_node *node, ia32_am_flavour_t am_flavour) {
551         ia32_attr_t *attr     = get_ia32_attr(node);
552         attr->data.am_flavour = am_flavour;
553 }
554
555 /**
556  * Joins all offsets to one string with adds.
557  */
558 char *get_ia32_am_offs(const ir_node *node) {
559         ia32_attr_t *attr = get_ia32_attr(node);
560         static char res[64];
561
562         snprintf(res, sizeof(res), "%+d", attr->am_offs);
563
564         return res;
565 }
566
567 /**
568  * Gets the addressmode offset as long.
569  */
570 int get_ia32_am_offs_int(const ir_node *node) {
571         ia32_attr_t *attr = get_ia32_attr(node);
572         return attr->am_offs;
573 }
574
575 /**
576  * Add an offset for addrmode.
577  */
578 static void extend_ia32_am_offs(ir_node *node, char *offset, char op) {
579         ia32_attr_t *attr = get_ia32_attr(node);
580         int res, o;
581
582         if (offset == NULL || offset[0] == '\0')
583                 return;
584
585         if (offset[0] == '-')
586                 res = sscanf(offset, "%d", &o);
587         else
588                 res = sscanf(offset, "%u", &o);
589         assert(res == 1);
590
591         if (op == '-')
592                 attr->am_offs -= o;
593         else if (op == '+')
594                 attr->am_offs += o;
595         else
596                 assert(0);
597 }
598
599 /**
600  * Add an offset for addrmode.
601  */
602 void add_ia32_am_offs(ir_node *node, const char *offset) {
603         extend_ia32_am_offs(node, (char *)offset, '+');
604 }
605
606 void add_ia32_am_offs_int(ir_node *node, int offset) {
607         ia32_attr_t *attr = get_ia32_attr(node);
608         attr->am_offs += offset;
609 }
610
611 /**
612  * Sub an offset for addrmode.
613  */
614 void sub_ia32_am_offs(ir_node *node, const char *offset) {
615         extend_ia32_am_offs(node, (char *)offset, '-');
616 }
617
618 /**
619  * Returns the symconst ident associated to addrmode.
620  */
621 ident *get_ia32_am_sc(const ir_node *node) {
622         ia32_attr_t *attr = get_ia32_attr(node);
623         return attr->am_sc;
624 }
625
626 /**
627  * Sets the symconst ident associated to addrmode.
628  */
629 void set_ia32_am_sc(ir_node *node, ident *sc) {
630         ia32_attr_t *attr = get_ia32_attr(node);
631         attr->am_sc       = sc;
632 }
633
634 /**
635  * Sets the sign bit for address mode symconst.
636  */
637 void set_ia32_am_sc_sign(ir_node *node) {
638         ia32_attr_t *attr     = get_ia32_attr(node);
639         attr->data.am_sc_sign = 1;
640 }
641
642 /**
643  * Clears the sign bit for address mode symconst.
644  */
645 void clear_ia32_am_sc_sign(ir_node *node) {
646         ia32_attr_t *attr     = get_ia32_attr(node);
647         attr->data.am_sc_sign = 0;
648 }
649
650 /**
651  * Returns the sign bit for address mode symconst.
652  */
653 int is_ia32_am_sc_sign(const ir_node *node) {
654         ia32_attr_t *attr = get_ia32_attr(node);
655         return attr->data.am_sc_sign;
656 }
657
658 /**
659  * Gets the addr mode const.
660  */
661 int get_ia32_am_scale(const ir_node *node) {
662         ia32_attr_t *attr = get_ia32_attr(node);
663         return attr->data.am_scale;
664 }
665
666 /**
667  * Sets the index register scale for addrmode.
668  */
669 void set_ia32_am_scale(ir_node *node, int scale) {
670         ia32_attr_t *attr   = get_ia32_attr(node);
671         attr->data.am_scale = scale;
672 }
673
674 /**
675  * Return the tarval of an immediate operation or NULL in case of SymConst
676  */
677 tarval *get_ia32_Immop_tarval(const ir_node *node) {
678         ia32_attr_t *attr = get_ia32_attr(node);
679     return attr->cnst_val.tv;
680 }
681
682 /**
683  * Sets the attributes of an immediate operation to the specified tarval
684  */
685 void set_ia32_Immop_tarval(ir_node *node, tarval *tv) {
686         ia32_attr_t *attr = get_ia32_attr(node);
687         attr->cnst_val.tv = tv;
688         attr->cnst        = get_ident_for_tv(tv);
689 }
690
691 /**
692  * Gets the string representation of the internal const (tv or symconst)
693  */
694 const char *get_ia32_cnst(const ir_node *node) {
695         ia32_attr_t *attr = get_ia32_attr(node);
696         if (! attr->cnst)
697                 return NULL;
698         return get_id_str(attr->cnst);
699 }
700
701 /**
702  * Sets the string representation of the internal const.
703  */
704 void set_ia32_cnst(ir_node *node, const char *cnst) {
705         ia32_attr_t *attr = get_ia32_attr(node);
706         attr->cnst        = new_id_from_str(cnst);
707 }
708
709 /**
710  * Gets the ident representation of the internal const (tv or symconst)
711  */
712 ident *get_ia32_id_cnst(const ir_node *node) {
713         ia32_attr_t *attr = get_ia32_attr(node);
714         return attr->cnst;
715 }
716
717 /**
718  * Sets the ident representation of the internal const.
719  */
720 void set_ia32_id_cnst(ir_node *node, ident *cnst) {
721         ia32_attr_t *attr = get_ia32_attr(node);
722         attr->cnst        = cnst;
723 }
724
725 /**
726  * Sets the uses_frame flag.
727  */
728 void set_ia32_use_frame(ir_node *node) {
729         ia32_attr_t *attr    = get_ia32_attr(node);
730         attr->data.use_frame = 1;
731 }
732
733 /**
734  * Clears the uses_frame flag.
735  */
736 void clear_ia32_use_frame(ir_node *node) {
737         ia32_attr_t *attr    = get_ia32_attr(node);
738         attr->data.use_frame = 0;
739 }
740
741 /**
742  * Gets the uses_frame flag.
743  */
744 int is_ia32_use_frame(const ir_node *node) {
745         ia32_attr_t *attr = get_ia32_attr(node);
746         return attr->data.use_frame;
747 }
748
749 /**
750  * Sets node to commutative.
751  */
752 void set_ia32_commutative(ir_node *node) {
753         ia32_attr_t *attr         = get_ia32_attr(node);
754         attr->data.is_commutative = 1;
755 }
756
757 /**
758  * Sets node to non-commutative.
759  */
760 void clear_ia32_commutative(ir_node *node) {
761         ia32_attr_t *attr         = get_ia32_attr(node);
762         attr->data.is_commutative = 0;
763 }
764
765 /**
766  * Checks if node is commutative.
767  */
768 int is_ia32_commutative(const ir_node *node) {
769         ia32_attr_t *attr = get_ia32_attr(node);
770         return attr->data.is_commutative;
771 }
772
773 /**
774  * Sets node emit_cl.
775  */
776 void set_ia32_emit_cl(ir_node *node) {
777         ia32_attr_t *attr  = get_ia32_attr(node);
778         attr->data.emit_cl = 1;
779 }
780
781 /**
782  * Clears node emit_cl.
783  */
784 void clear_ia32_emit_cl(ir_node *node) {
785         ia32_attr_t *attr  = get_ia32_attr(node);
786         attr->data.emit_cl = 0;
787 }
788
789 /**
790  * Checks if node needs %cl.
791  */
792 int is_ia32_emit_cl(const ir_node *node) {
793         ia32_attr_t *attr = get_ia32_attr(node);
794         return attr->data.emit_cl;
795 }
796
797 /**
798  * Sets node got_lea.
799  */
800 void set_ia32_got_lea(ir_node *node) {
801         ia32_attr_t *attr  = get_ia32_attr(node);
802         attr->data.got_lea = 1;
803 }
804
805 /**
806  * Clears node got_lea.
807  */
808 void clear_ia32_got_lea(ir_node *node) {
809         ia32_attr_t *attr  = get_ia32_attr(node);
810         attr->data.got_lea = 0;
811 }
812
813 /**
814  * Checks if node got lea.
815  */
816 int is_ia32_got_lea(const ir_node *node) {
817         ia32_attr_t *attr = get_ia32_attr(node);
818         return attr->data.got_lea;
819 }
820
821 /**
822  * Sets node got_reload.
823  */
824 void set_ia32_got_reload(ir_node *node) {
825         ia32_attr_t *attr     = get_ia32_attr(node);
826         attr->data.got_reload = 1;
827 }
828
829 /**
830  * Clears node got_reload.
831  */
832 void clear_ia32_got_reload(ir_node *node) {
833         ia32_attr_t *attr     = get_ia32_attr(node);
834         attr->data.got_reload = 0;
835 }
836
837 /**
838  * Checks if node got reload.
839  */
840 int is_ia32_got_reload(const ir_node *node) {
841         ia32_attr_t *attr = get_ia32_attr(node);
842         return attr->data.got_reload;
843 }
844
845 /**
846  * Gets the mode of the stored/loaded value (only set for Store/Load)
847  */
848 ir_mode *get_ia32_ls_mode(const ir_node *node) {
849         ia32_attr_t *attr = get_ia32_attr(node);
850         return attr->ls_mode;
851 }
852
853 /**
854  * Sets the mode of the stored/loaded value (only set for Store/Load)
855  */
856 void set_ia32_ls_mode(ir_node *node, ir_mode *mode) {
857         ia32_attr_t *attr = get_ia32_attr(node);
858         attr->ls_mode     = mode;
859 }
860
861 /**
862  * Gets the mode of the result.
863  */
864 ir_mode *get_ia32_res_mode(const ir_node *node) {
865         ia32_attr_t *attr = get_ia32_attr(node);
866         return attr->res_mode;
867 }
868
869 /**
870  * Sets the mode of the result.
871  */
872 void set_ia32_res_mode(ir_node *node, ir_mode *mode) {
873         ia32_attr_t *attr = get_ia32_attr(node);
874         attr->res_mode    = mode;
875 }
876
877 /**
878  * Gets the source mode of conversion.
879  */
880 ir_mode *get_ia32_src_mode(const ir_node *node) {
881         ia32_attr_t *attr = get_ia32_attr(node);
882         return attr->src_mode;
883 }
884
885 /**
886  * Sets the source mode of conversion.
887  */
888 void set_ia32_src_mode(ir_node *node, ir_mode *mode) {
889         ia32_attr_t *attr = get_ia32_attr(node);
890         attr->src_mode    = mode;
891 }
892
893 /**
894  * Gets the target mode of conversion.
895  */
896 ir_mode *get_ia32_tgt_mode(const ir_node *node) {
897         ia32_attr_t *attr = get_ia32_attr(node);
898         return attr->tgt_mode;
899 }
900
901 /**
902  * Sets the target mode of conversion.
903  */
904 void set_ia32_tgt_mode(ir_node *node, ir_mode *mode) {
905         ia32_attr_t *attr = get_ia32_attr(node);
906         attr->tgt_mode    = mode;
907 }
908
909 /**
910  * Gets the frame entity assigned to this node.
911  */
912 entity *get_ia32_frame_ent(const ir_node *node) {
913         ia32_attr_t *attr = get_ia32_attr(node);
914         return attr->frame_ent;
915 }
916
917 /**
918  * Sets the frame entity for this node.
919  */
920 void set_ia32_frame_ent(ir_node *node, entity *ent) {
921         ia32_attr_t *attr = get_ia32_attr(node);
922         attr->frame_ent   = ent;
923         set_ia32_use_frame(node);
924 }
925
926
927 /**
928  * Gets the instruction latency.
929  */
930 unsigned get_ia32_latency(const ir_node *node) {
931         ia32_attr_t *attr = get_ia32_attr(node);
932         return attr->latency;
933 }
934
935 /**
936 * Sets the instruction latency.
937 */
938 void set_ia32_latency(ir_node *node, unsigned latency) {
939         ia32_attr_t *attr = get_ia32_attr(node);
940         attr->latency     = latency;
941 }
942
943 /**
944  * Returns the argument register requirements of an ia32 node.
945  */
946 const ia32_register_req_t **get_ia32_in_req_all(const ir_node *node) {
947         ia32_attr_t *attr = get_ia32_attr(node);
948         return attr->in_req;
949 }
950
951 /**
952  * Sets the argument register requirements of an ia32 node.
953  */
954 void set_ia32_in_req_all(ir_node *node, const ia32_register_req_t **reqs) {
955         ia32_attr_t *attr = get_ia32_attr(node);
956         attr->in_req      = reqs;
957 }
958
959 /**
960  * Returns the result register requirements of an ia32 node.
961  */
962 const ia32_register_req_t **get_ia32_out_req_all(const ir_node *node) {
963         ia32_attr_t *attr = get_ia32_attr(node);
964         return attr->out_req;
965 }
966
967 /**
968  * Sets the result register requirements of an ia32 node.
969  */
970 void set_ia32_out_req_all(ir_node *node, const ia32_register_req_t **reqs) {
971         ia32_attr_t *attr = get_ia32_attr(node);
972         attr->out_req     = reqs;
973 }
974
975 /**
976  * Returns the argument register requirement at position pos of an ia32 node.
977  */
978 const ia32_register_req_t *get_ia32_in_req(const ir_node *node, int pos) {
979         ia32_attr_t *attr = get_ia32_attr(node);
980         return attr->in_req != NULL ? attr->in_req[pos] : NULL;
981 }
982
983 /**
984  * Returns the result register requirement at position pos of an ia32 node.
985  */
986 const ia32_register_req_t *get_ia32_out_req(const ir_node *node, int pos) {
987         ia32_attr_t *attr = get_ia32_attr(node);
988         return attr->out_req != NULL ? attr->out_req[pos] : NULL;
989 }
990
991 /**
992  * Sets the OUT register requirements at position pos.
993  */
994 void set_ia32_req_out(ir_node *node, const ia32_register_req_t *req, int pos) {
995         ia32_attr_t *attr  = get_ia32_attr(node);
996         attr->out_req[pos] = req;
997 }
998
999 /**
1000  * Sets the IN register requirements at position pos.
1001  */
1002 void set_ia32_req_in(ir_node *node, const ia32_register_req_t *req, int pos) {
1003         ia32_attr_t *attr = get_ia32_attr(node);
1004         attr->in_req[pos] = req;
1005 }
1006
1007 /**
1008  * Returns the register flag of an ia32 node.
1009  */
1010 arch_irn_flags_t get_ia32_flags(const ir_node *node) {
1011         ia32_attr_t *attr = get_ia32_attr(node);
1012         return attr->data.flags;
1013 }
1014
1015 /**
1016  * Sets the register flag of an ia32 node.
1017  */
1018 void set_ia32_flags(ir_node *node, arch_irn_flags_t flags) {
1019         ia32_attr_t *attr = get_ia32_attr(node);
1020         attr->data.flags  = flags;
1021 }
1022
1023 /**
1024  * Returns the result register slots of an ia32 node.
1025  */
1026 const arch_register_t **get_ia32_slots(const ir_node *node) {
1027         ia32_attr_t *attr = get_ia32_attr(node);
1028         return attr->slots;
1029 }
1030
1031 /**
1032  * Sets the number of results.
1033  */
1034 void set_ia32_n_res(ir_node *node, int n_res) {
1035         ia32_attr_t *attr = get_ia32_attr(node);
1036         attr->data.n_res  = n_res;
1037 }
1038
1039 /**
1040  * Returns the number of results.
1041  */
1042 int get_ia32_n_res(const ir_node *node) {
1043         ia32_attr_t *attr = get_ia32_attr(node);
1044         return attr->data.n_res;
1045 }
1046
1047 /**
1048  * Returns the flavour of an ia32 node,
1049  */
1050 ia32_op_flavour_t get_ia32_flavour(const ir_node *node) {
1051         ia32_attr_t *attr = get_ia32_attr(node);
1052         return attr->data.op_flav;
1053 }
1054
1055 /**
1056  * Sets the flavour of an ia32 node to flavour_Div/Mod/DivMod/Mul/Mulh.
1057  */
1058 void set_ia32_flavour(ir_node *node, ia32_op_flavour_t op_flav) {
1059         ia32_attr_t *attr  = get_ia32_attr(node);
1060         attr->data.op_flav = op_flav;
1061 }
1062
1063 /**
1064  * Returns the projnum code.
1065  */
1066 long get_ia32_pncode(const ir_node *node) {
1067         ia32_attr_t *attr = get_ia32_attr(node);
1068         return attr->pn_code;
1069 }
1070
1071 /**
1072  * Sets the projnum code
1073  */
1074 void set_ia32_pncode(ir_node *node, long code) {
1075         ia32_attr_t *attr = get_ia32_attr(node);
1076         attr->pn_code     = code;
1077 }
1078
1079 /**
1080  * Sets the flags for the n'th out.
1081  */
1082 void set_ia32_out_flags(ir_node *node, arch_irn_flags_t flags, int pos) {
1083         ia32_attr_t *attr = get_ia32_attr(node);
1084         assert(pos < (int) attr->data.n_res && "Invalid OUT position.");
1085         attr->out_flags[pos] = flags;
1086 }
1087
1088 /**
1089  * Gets the flags for the n'th out.
1090  */
1091 arch_irn_flags_t get_ia32_out_flags(const ir_node *node, int pos) {
1092         ia32_attr_t *attr = get_ia32_attr(node);
1093         return pos < (int)attr->data.n_res ? attr->out_flags[pos] : arch_irn_flags_none;
1094 }
1095
1096 /**
1097  * Get the list of available execution units.
1098  */
1099 const be_execution_unit_t ***get_ia32_exec_units(const ir_node *node) {
1100         ia32_attr_t *attr = get_ia32_attr(node);
1101         return attr->exec_units;
1102 }
1103
1104 #ifndef NDEBUG
1105
1106 /**
1107  * Returns the name of the original ir node.
1108  */
1109 const char *get_ia32_orig_node(const ir_node *node) {
1110         ia32_attr_t *attr = get_ia32_attr(node);
1111         return attr->orig_node;
1112 }
1113
1114 /**
1115  * Sets the name of the original ir node.
1116  */
1117 void set_ia32_orig_node(ir_node *node, const char *name) {
1118         ia32_attr_t *attr = get_ia32_attr(node);
1119         attr->orig_node   = name;
1120 }
1121
1122 #endif /* NDEBUG */
1123
1124 /******************************************************************************************************
1125  *                      _       _         _   _           __                  _   _
1126  *                     (_)     | |       | | | |         / _|                | | (_)
1127  *  ___ _ __   ___  ___ _  __ _| |   __ _| |_| |_ _ __  | |_ _   _ _ __   ___| |_ _  ___  _ __    ___
1128  * / __| '_ \ / _ \/ __| |/ _` | |  / _` | __| __| '__| |  _| | | | '_ \ / __| __| |/ _ \| '_ \  / __|
1129  * \__ \ |_) |  __/ (__| | (_| | | | (_| | |_| |_| |    | | | |_| | | | | (__| |_| | (_) | | | | \__ \
1130  * |___/ .__/ \___|\___|_|\__,_|_|  \__,_|\__|\__|_|    |_|  \__,_|_| |_|\___|\__|_|\___/|_| |_| |___/
1131  *     | |
1132  *     |_|
1133  ******************************************************************************************************/
1134
1135 /**
1136  * Gets the type of an ia32_Const.
1137  */
1138 unsigned get_ia32_Const_type(const ir_node *node) {
1139         ia32_attr_t *attr = get_ia32_attr(node);
1140
1141         assert(is_ia32_Cnst(node) && "Need ia32_Const to get type");
1142
1143         return attr->data.tp;
1144 }
1145
1146 /**
1147  * Sets the type of an ia32_Const.
1148  */
1149 void set_ia32_Const_type(ir_node *node, int type) {
1150         ia32_attr_t *attr = get_ia32_attr(node);
1151
1152         assert(is_ia32_Cnst(node) && "Need ia32_Const to set type");
1153         assert((type == ia32_Const || type == ia32_SymConst) && "Unsupported ia32_Const type");
1154
1155         attr->data.tp = type;
1156 }
1157
1158 /**
1159  * Copy the attributes from an ia32_Const to an Immop (Add_i, Sub_i, ...) node
1160  */
1161 void set_ia32_Immop_attr(ir_node *node, ir_node *cnst) {
1162         ia32_attr_t *na = get_ia32_attr(node);
1163         ia32_attr_t *ca = get_ia32_attr(cnst);
1164
1165         switch(get_ia32_Const_type(cnst)) {
1166                 case ia32_Const:
1167                         na->cnst_val.tv = ca->cnst_val.tv;
1168                         na->cnst        = ca->cnst;
1169                         set_ia32_immop_type(node, ia32_ImmConst);
1170                         break;
1171                 case ia32_SymConst:
1172                         na->cnst_val.sc = ca->cnst_val.sc;
1173                         na->cnst        = na->cnst_val.sc;
1174                         set_ia32_immop_type(node, ia32_ImmSymConst);
1175                         break;
1176                 default:
1177                         assert(0 && "Need ia32_Const to set Immop attr");
1178         }
1179 }
1180
1181 /**
1182  * Copy the attributes from Immop to an Immop
1183  */
1184 void copy_ia32_Immop_attr(ir_node *dst, ir_node *src) {
1185         ia32_attr_t *da = get_ia32_attr(dst);
1186         ia32_attr_t *sa = get_ia32_attr(src);
1187
1188         switch(get_ia32_immop_type(src)) {
1189                 case ia32_ImmConst:
1190                         da->cnst_val.tv = sa->cnst_val.tv;
1191                         da->cnst        = sa->cnst;
1192                         set_ia32_immop_type(dst, ia32_ImmConst);
1193                         break;
1194                 case ia32_ImmSymConst:
1195                         da->cnst_val.sc = sa->cnst_val.sc;
1196                         da->cnst        = sa->cnst;
1197                         set_ia32_immop_type(dst, ia32_ImmSymConst);
1198                         break;
1199                 default:
1200                         assert(0 && "Need Immop to copy Immop attr");
1201         }
1202 }
1203
1204 /**
1205  * Copy the attributes from a Firm Const/SymConst to an ia32_Const
1206  */
1207 void set_ia32_Const_attr(ir_node *ia32_cnst, ir_node *cnst) {
1208         ia32_attr_t *attr = get_ia32_attr(ia32_cnst);
1209         ir_mode *mode;
1210
1211         assert(is_ia32_Cnst(ia32_cnst) && "Need ia32_Const to set Const attr");
1212
1213         switch (get_irn_opcode(cnst)) {
1214                 case iro_Const:
1215                         attr->data.tp     = ia32_Const;
1216                         attr->cnst_val.tv = get_Const_tarval(cnst);
1217                         mode = get_tarval_mode(attr->cnst_val.tv);
1218                         if (mode_is_reference(mode) &&
1219                             get_mode_null(mode) == attr->cnst_val.tv) {
1220                                 attr->cnst_val.tv = get_mode_null(mode_Iu);
1221                         }
1222                         attr->cnst        = get_ident_for_tv(attr->cnst_val.tv);
1223                         break;
1224                 case iro_SymConst:
1225                         attr->data.tp     = ia32_SymConst;
1226                         attr->cnst_val.sc = get_sc_ident(cnst);
1227                         attr->cnst        = attr->cnst_val.sc;
1228                         break;
1229                 case iro_Unknown:
1230                         assert(0 && "Unknown Const NYI");
1231                         break;
1232                 default:
1233                         assert(0 && "Cannot create ia32_Const for this opcode");
1234         }
1235 }
1236
1237 /**
1238  * Sets the AddrMode(S|D) attribute
1239  */
1240 void set_ia32_AddrMode(ir_node *node, char direction) {
1241         ia32_attr_t *attr = get_ia32_attr(node);
1242
1243         switch (direction) {
1244                 case 'D':
1245                         attr->data.tp = ia32_AddrModeD;
1246                         break;
1247                 case 'S':
1248                         attr->data.tp = ia32_AddrModeS;
1249                         break;
1250                 default:
1251                         assert(0 && "wrong AM type");
1252         }
1253 }
1254
1255 /**
1256  * Returns whether or not the node is an immediate operation with Const.
1257  */
1258 int is_ia32_ImmConst(const ir_node *node) {
1259         ia32_attr_t *attr = get_ia32_attr(node);
1260         return (attr->data.imm_tp == ia32_ImmConst);
1261 }
1262
1263 /**
1264  * Returns whether or not the node is an immediate operation with SymConst.
1265  */
1266 int is_ia32_ImmSymConst(const ir_node *node) {
1267         ia32_attr_t *attr = get_ia32_attr(node);
1268         return (attr->data.imm_tp == ia32_ImmSymConst);
1269 }
1270
1271 /**
1272  * Returns whether or not the node is an AddrModeS node.
1273  */
1274 int is_ia32_AddrModeS(const ir_node *node) {
1275         ia32_attr_t *attr = get_ia32_attr(node);
1276         return (attr->data.tp == ia32_AddrModeS);
1277 }
1278
1279 /**
1280  * Returns whether or not the node is an AddrModeD node.
1281  */
1282 int is_ia32_AddrModeD(const ir_node *node) {
1283         ia32_attr_t *attr = get_ia32_attr(node);
1284         return (attr->data.tp == ia32_AddrModeD);
1285 }
1286
1287 /**
1288  * Checks if node is a Load or xLoad/vfLoad.
1289  */
1290 int is_ia32_Ld(const ir_node *node) {
1291         int op = get_ia32_irn_opcode(node);
1292         return op == iro_ia32_Load || op == iro_ia32_xLoad || op == iro_ia32_vfld || op == iro_ia32_fld;
1293 }
1294
1295 /**
1296  * Checks if node is a Store or xStore/vfStore.
1297  */
1298 int is_ia32_St(const ir_node *node) {
1299         int op = get_ia32_irn_opcode(node);
1300         return op == iro_ia32_Store || op == iro_ia32_xStore || op == iro_ia32_vfst || op == iro_ia32_fst || op == iro_ia32_fstp;
1301 }
1302
1303 /**
1304  * Checks if node is a Const or xConst/vfConst.
1305  */
1306 int is_ia32_Cnst(const ir_node *node) {
1307         int op = get_ia32_irn_opcode(node);
1308         return op == iro_ia32_Const || op == iro_ia32_xConst || op == iro_ia32_vfConst;
1309 }
1310
1311 /**
1312  * Returns the name of the OUT register at position pos.
1313  */
1314 const char *get_ia32_out_reg_name(const ir_node *node, int pos) {
1315         ia32_attr_t *attr = get_ia32_attr(node);
1316
1317         assert(pos < (int) attr->data.n_res && "Invalid OUT position.");
1318         assert(attr->slots[pos]  && "No register assigned");
1319
1320         return arch_register_get_name(attr->slots[pos]);
1321 }
1322
1323 /**
1324  * Returns the index of the OUT register at position pos within its register class.
1325  */
1326 int get_ia32_out_regnr(const ir_node *node, int pos) {
1327         ia32_attr_t *attr = get_ia32_attr(node);
1328
1329         assert(pos < (int) attr->data.n_res && "Invalid OUT position.");
1330         assert(attr->slots[pos]  && "No register assigned");
1331
1332         return arch_register_get_index(attr->slots[pos]);
1333 }
1334
1335 /**
1336  * Returns the OUT register at position pos.
1337  */
1338 const arch_register_t *get_ia32_out_reg(const ir_node *node, int pos) {
1339         ia32_attr_t *attr = get_ia32_attr(node);
1340
1341         assert(pos < (int) attr->data.n_res && "Invalid OUT position.");
1342         assert(attr->slots[pos]  && "No register assigned");
1343
1344         return attr->slots[pos];
1345 }
1346
1347 /**
1348  * Initializes the nodes attributes.
1349  */
1350 void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags, const ia32_register_req_t **in_reqs,
1351                                                   const ia32_register_req_t **out_reqs, const be_execution_unit_t ***execution_units,
1352                                                   int n_res, unsigned latency)
1353 {
1354         ia32_attr_t *attr = get_ia32_attr(node);
1355
1356         set_ia32_flags(node, flags);
1357         set_ia32_in_req_all(node, in_reqs);
1358         set_ia32_out_req_all(node, out_reqs);
1359         set_ia32_latency(node, latency);
1360         set_ia32_n_res(node, n_res);
1361
1362         attr->exec_units = execution_units;
1363
1364         attr->out_flags = NEW_ARR_D(int, get_irg_obstack(get_irn_irg(node)), n_res);
1365         memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0]));
1366
1367         memset((void *)attr->slots, 0, n_res * sizeof(attr->slots[0]));
1368 }
1369
1370 /***************************************************************************************
1371  *                  _                            _                   _
1372  *                 | |                          | |                 | |
1373  *  _ __   ___   __| | ___    ___ ___  _ __  ___| |_ _ __ _   _  ___| |_ ___  _ __ ___
1374  * | '_ \ / _ \ / _` |/ _ \  / __/ _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__/ __|
1375  * | | | | (_) | (_| |  __/ | (_| (_) | | | \__ \ |_| |  | |_| | (__| || (_) | |  \__ \
1376  * |_| |_|\___/ \__,_|\___|  \___\___/|_| |_|___/\__|_|   \__,_|\___|\__\___/|_|  |___/
1377  *
1378  ***************************************************************************************/
1379
1380 /* default compare operation to compare immediate ops */
1381 int ia32_compare_immop_attr(ia32_attr_t *a, ia32_attr_t *b) {
1382         int equ = 0;
1383
1384         if (a->data.tp == b->data.tp) {
1385                 equ = (a->cnst == b->cnst);
1386                 equ = equ ? (a->data.use_frame == b->data.use_frame) : 0;
1387
1388                 if (equ && a->data.use_frame && b->data.use_frame)
1389                         equ = (a->frame_ent == b->frame_ent);
1390         }
1391
1392         return !equ;
1393 }
1394
1395 /* compare converts */
1396 int ia32_compare_conv_attr(ia32_attr_t *a, ia32_attr_t *b) {
1397         int equ = ! ia32_compare_immop_attr(a, b);
1398
1399         equ = equ ? (a->src_mode == b->src_mode) && (a->tgt_mode == b->tgt_mode) : equ;
1400
1401         return !equ;
1402 }
1403
1404 /* copies the ia32 attributes */
1405 static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node) {
1406         ia32_attr_t *attr_old = get_ia32_attr(old_node);
1407         ia32_attr_t *attr_new = get_ia32_attr(new_node);
1408
1409         /* copy the attributes */
1410         memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
1411
1412         /* copy out flags */
1413         DUP_ARR_D(int, get_irg_obstack(get_irn_irg(new_node)), attr_old->out_flags);
1414 }
1415
1416 /**
1417  * Registers the ia32_copy_attr function for all ia32 opcodes.
1418  */
1419 void ia32_register_copy_attr_func(void) {
1420         unsigned i, f = get_ia32_opcode_first(), l = get_ia32_opcode_last();
1421
1422         for (i = f; i < l; i++) {
1423                 ir_op *op = get_irp_opcode(i);
1424                 op->ops.copy_attr = ia32_copy_attr;
1425         }
1426 }
1427
1428 /* Include the generated constructor functions */
1429 #include "gen_ia32_new_nodes.c.inl"