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