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