ia32: Clean up ia32_get_op_estimated_cost().
[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         assert(is_ia32_irn(node));
649         const ir_op *op               = get_irn_op(node);
650         const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op);
651         return op_attr->latency;
652 }
653
654 const ir_switch_table *get_ia32_switch_table(const ir_node *node)
655 {
656         const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
657         return attr->table;
658 }
659
660 ia32_condition_code_t get_ia32_condcode(const ir_node *node)
661 {
662         const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
663         return attr->condition_code;
664 }
665
666 /**
667  * Sets the condition code of a node
668  */
669 void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
670 {
671         ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
672         attr->condition_code = code;
673 }
674
675 /**
676  * Returns the condition code of a node.
677  */
678 unsigned get_ia32_copyb_size(const ir_node *node)
679 {
680         const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
681         return attr->size;
682 }
683
684 /**
685  * Get the exception label attribute.
686  */
687 unsigned get_ia32_exc_label(const ir_node *node)
688 {
689         const ia32_attr_t *attr = get_ia32_attr_const(node);
690         return attr->data.has_except_label;
691 }
692
693 /**
694  * Set the exception label attribute.
695  */
696 void set_ia32_exc_label(ir_node *node, unsigned flag)
697 {
698         ia32_attr_t *attr = get_ia32_attr(node);
699         attr->data.has_except_label = flag;
700 }
701
702 /**
703  * Return the exception label id.
704  */
705 ir_label_t get_ia32_exc_label_id(const ir_node *node)
706 {
707         const ia32_attr_t *attr = get_ia32_attr_const(node);
708
709         assert(attr->data.has_except_label);
710         return attr->exc_label;
711 }
712
713 /**
714  * Assign the exception label id.
715  */
716 void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
717 {
718         ia32_attr_t *attr = get_ia32_attr(node);
719
720         assert(attr->data.has_except_label);
721         attr->exc_label = id;
722 }
723
724 #ifndef NDEBUG
725
726 static const char *ia32_get_old_node_name(const ir_node *irn)
727 {
728         ir_graph       *irg  = get_irn_irg(irn);
729         struct obstack *obst = be_get_be_obst(irg);
730
731         lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
732         obstack_1grow(obst, 0);
733         return (const char*)obstack_finish(obst);
734 }
735
736 /**
737  * Sets the name of the original ir node.
738  */
739 void set_ia32_orig_node(ir_node *node, const ir_node *old)
740 {
741         const char  *name = ia32_get_old_node_name(old);
742         ia32_attr_t *attr = get_ia32_attr(node);
743         attr->orig_node   = name;
744 }
745
746 #endif /* NDEBUG */
747
748 void ia32_swap_left_right(ir_node *node)
749 {
750         ia32_attr_t *attr  = get_ia32_attr(node);
751         ir_node     *left  = get_irn_n(node, n_ia32_binary_left);
752         ir_node     *right = get_irn_n(node, n_ia32_binary_right);
753
754         assert(is_ia32_commutative(node));
755         attr->data.ins_permuted = !attr->data.ins_permuted;
756         set_irn_n(node, n_ia32_binary_left,  right);
757         set_irn_n(node, n_ia32_binary_right, left);
758 }
759
760 /**
761  * Initializes the nodes attributes.
762  */
763 static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
764                                  const arch_register_req_t **in_reqs,
765                                  int n_res)
766 {
767         ir_graph        *irg  = get_irn_irg(node);
768         struct obstack  *obst = get_irg_obstack(irg);
769         ia32_attr_t     *attr = get_ia32_attr(node);
770         backend_info_t  *info;
771
772         arch_set_irn_flags(node, flags);
773         arch_set_irn_register_reqs_in(node, in_reqs);
774
775 #ifndef NDEBUG
776         attr->attr_type  |= IA32_ATTR_ia32_attr_t;
777 #endif
778
779         info            = be_get_info(node);
780         info->out_infos = NEW_ARR_DZ(reg_out_info_t, obst, n_res);
781 }
782
783 static void init_ia32_x87_attributes(ir_node *res)
784 {
785 #ifndef NDEBUG
786         ia32_attr_t *attr  = get_ia32_attr(res);
787         attr->attr_type   |= IA32_ATTR_ia32_x87_attr_t;
788 #endif
789         ir_graph *const irg = get_irn_irg(res);
790         ia32_request_x87_sim(irg);
791 }
792
793 static void init_ia32_asm_attributes(ir_node *res)
794 {
795 #ifndef NDEBUG
796         ia32_attr_t *attr  = get_ia32_attr(res);
797         attr->attr_type   |= IA32_ATTR_ia32_asm_attr_t;
798 #endif
799
800         ir_graph *const irg = get_irn_irg(res);
801         ia32_request_x87_sim(irg); /* asm might have fp operands. */
802 }
803
804 static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
805                                            int symconst_sign, int no_pic_adjust,
806                                            long offset)
807 {
808         ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
809
810 #ifndef NDEBUG
811         attr->attr.attr_type  |= IA32_ATTR_ia32_immediate_attr_t;
812 #endif
813         attr->symconst      = symconst;
814         attr->sc_sign       = symconst_sign;
815         attr->no_pic_adjust = no_pic_adjust;
816         attr->offset        = offset;
817 }
818
819 static void init_ia32_call_attributes(ir_node* res, unsigned pop,
820                                       ir_type* call_tp)
821 {
822         ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
823
824 #ifndef NDEBUG
825         attr->attr.attr_type  |= IA32_ATTR_ia32_call_attr_t;
826 #endif
827         attr->pop     = pop;
828         attr->call_tp = call_tp;
829 }
830
831 static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
832 {
833         ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
834
835 #ifndef NDEBUG
836         attr->attr.attr_type  |= IA32_ATTR_ia32_copyb_attr_t;
837 #endif
838         attr->size = size;
839 }
840
841 static void init_ia32_condcode_attributes(ir_node *res,
842                                           ia32_condition_code_t cc)
843 {
844         ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
845
846 #ifndef NDEBUG
847         attr->attr.attr_type  |= IA32_ATTR_ia32_condcode_attr_t;
848 #endif
849         attr->condition_code = cc;
850 }
851
852 static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
853 {
854         ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
855
856 #ifndef NDEBUG
857         attr->attr.attr_type  |= IA32_ATTR_ia32_climbframe_attr_t;
858 #endif
859         attr->count = count;
860 }
861
862 static void init_ia32_switch_attributes(ir_node *node,
863                                         const ir_switch_table *table)
864 {
865         ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(node);
866 #ifndef NDEBUG
867         attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
868 #endif
869         attr->table = table;
870
871         be_foreach_out(node, o) {
872                 arch_set_irn_register_req_out(node, o, arch_no_register_req);
873         }
874 }
875
876 /* default compare operation to compare attributes */
877 static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
878 {
879         if (a->data.tp != b->data.tp)
880                 return 1;
881
882         if (a->data.am_scale != b->data.am_scale
883             || a->data.am_sc_sign != b->data.am_sc_sign
884             || a->am_offs != b->am_offs
885             || a->am_sc != b->am_sc
886                 || a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
887             || a->ls_mode != b->ls_mode)
888                 return 1;
889
890         /* nodes with not yet assigned entities shouldn't be CSEd (important for
891          * unsigned int -> double conversions */
892         if (a->data.use_frame && a->frame_ent == NULL)
893                 return 1;
894         if (b->data.use_frame && b->frame_ent == NULL)
895                 return 1;
896
897         if (a->data.use_frame != b->data.use_frame
898             || a->frame_ent != b->frame_ent)
899                 return 1;
900
901         if (a->data.has_except_label != b->data.has_except_label)
902                 return 1;
903
904         if (a->data.ins_permuted != b->data.ins_permuted)
905                 return 1;
906
907         return 0;
908 }
909
910 /** Compare nodes attributes for all "normal" nodes. */
911 static int ia32_compare_nodes_attr(const ir_node *a, const ir_node *b)
912 {
913         const ia32_attr_t* attr_a = get_ia32_attr_const(a);
914         const ia32_attr_t* attr_b = get_ia32_attr_const(b);
915
916         return ia32_compare_attr(attr_a, attr_b);
917 }
918
919 /** Compare node attributes for nodes with condition code. */
920 static int ia32_compare_condcode_attr(const ir_node *a, const ir_node *b)
921 {
922         const ia32_condcode_attr_t *attr_a;
923         const ia32_condcode_attr_t *attr_b;
924
925         if (ia32_compare_nodes_attr(a, b))
926                 return 1;
927
928         attr_a = get_ia32_condcode_attr_const(a);
929         attr_b = get_ia32_condcode_attr_const(b);
930
931         if (attr_a->condition_code != attr_b->condition_code)
932                 return 1;
933
934         return 0;
935 }
936
937 /** Compare node attributes for call nodes. */
938 static int ia32_compare_call_attr(const ir_node *a, const ir_node *b)
939 {
940         const ia32_call_attr_t *attr_a;
941         const ia32_call_attr_t *attr_b;
942
943         if (ia32_compare_nodes_attr(a, b))
944                 return 1;
945
946         attr_a = get_ia32_call_attr_const(a);
947         attr_b = get_ia32_call_attr_const(b);
948
949         if (attr_a->pop != attr_b->pop)
950                 return 1;
951
952         if (attr_a->call_tp != attr_b->call_tp)
953                 return 1;
954
955         return 0;
956 }
957
958 /** Compare node attributes for CopyB nodes. */
959 static int ia32_compare_copyb_attr(const ir_node *a, const ir_node *b)
960 {
961         const ia32_copyb_attr_t *attr_a;
962         const ia32_copyb_attr_t *attr_b;
963
964         if (ia32_compare_nodes_attr(a, b))
965                 return 1;
966
967         attr_a = get_ia32_copyb_attr_const(a);
968         attr_b = get_ia32_copyb_attr_const(b);
969
970         if (attr_a->size != attr_b->size)
971                 return 1;
972
973         return 0;
974 }
975
976
977 /** Compare ASM node attributes. */
978 static int ia32_compare_asm_attr(const ir_node *a, const ir_node *b)
979 {
980         const ia32_asm_attr_t *attr_a;
981         const ia32_asm_attr_t *attr_b;
982
983         if (ia32_compare_nodes_attr(a, b))
984                 return 1;
985
986         attr_a = get_ia32_asm_attr_const(a);
987         attr_b = get_ia32_asm_attr_const(b);
988
989         if (attr_a->asm_text != attr_b->asm_text)
990                 return 1;
991
992         return 0;
993 }
994
995 /**
996  * Hash function for Immediates
997  */
998 static unsigned ia32_hash_Immediate(const ir_node *irn)
999 {
1000         const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
1001
1002         return hash_ptr(a->symconst) + (a->sc_sign << 16) + a->offset;
1003 }
1004
1005 /** Compare node attributes for Immediates. */
1006 static int ia32_compare_immediate_attr(const ir_node *a, const ir_node *b)
1007 {
1008         const ia32_immediate_attr_t *attr_a = get_ia32_immediate_attr_const(a);
1009         const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
1010
1011         if (attr_a->symconst != attr_b->symconst
1012                 || attr_a->sc_sign != attr_b->sc_sign
1013                 || attr_a->no_pic_adjust != attr_b->no_pic_adjust
1014                 || attr_a->offset != attr_b->offset) {
1015                 return 1;
1016         }
1017
1018         return 0;
1019 }
1020
1021 /** Compare node attributes for x87 nodes. */
1022 static int ia32_compare_x87_attr(const ir_node *a, const ir_node *b)
1023 {
1024         return ia32_compare_nodes_attr(a, b);
1025 }
1026
1027 /** Compare node attributes for ClimbFrame nodes. */
1028 static int ia32_compare_climbframe_attr(const ir_node *a, const ir_node *b)
1029 {
1030         const ia32_climbframe_attr_t *attr_a;
1031         const ia32_climbframe_attr_t *attr_b;
1032
1033         if (ia32_compare_nodes_attr(a, b))
1034                 return 1;
1035
1036         attr_a = get_ia32_climbframe_attr_const(a);
1037         attr_b = get_ia32_climbframe_attr_const(b);
1038
1039         if (attr_a->count != attr_b->count)
1040                 return 1;
1041
1042         return 0;
1043 }
1044
1045 /* copies the ia32 attributes */
1046 static void ia32_copy_attr(ir_graph *irg, const ir_node *old_node,
1047                            ir_node *new_node)
1048 {
1049         struct obstack    *obst     = get_irg_obstack(irg);
1050         const ia32_attr_t *attr_old = get_ia32_attr_const(old_node);
1051         ia32_attr_t       *attr_new = get_ia32_attr(new_node);
1052         backend_info_t    *old_info = be_get_info(old_node);
1053         backend_info_t    *new_info = be_get_info(new_node);
1054
1055         /* copy the attributes */
1056         memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
1057
1058         /* copy out flags */
1059         new_info->out_infos =
1060                 DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
1061         new_info->in_reqs = old_info->in_reqs;
1062         new_info->flags = old_info->flags;
1063 }
1064
1065 static void ia32_init_op(ir_op *op, unsigned latency)
1066 {
1067         ia32_op_attr_t *attr = OALLOCZ(&opcodes_obst, ia32_op_attr_t);
1068         attr->latency = latency;
1069         set_op_attr(op, attr);
1070 }
1071
1072 /* Include the generated constructor functions */
1073 #include "gen_ia32_new_nodes.c.inl"