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