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