2 * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Handling of ia32 specific firm opcodes.
23 * @author Christian Wuerdig
25 * This file implements the creation of the architecture specific firm opcodes
26 * and the corresponding node constructors for the ia32 assembler irg.
35 #include "irgraph_t.h"
41 #include "irverify_t.h"
45 #include "raw_bitset.h"
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"
58 * Dumper interface for dumping ia32 nodes in vcg.
59 * @param n the node to dump
60 * @param F the output file
61 * @param reason indicates which kind of information should be dumped
62 * @return 0 on success or != 0 on failure
64 static void ia32_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
69 case dump_node_opcode_txt:
70 fprintf(F, "%s", get_irn_opname(n));
72 if (is_ia32_Immediate(n) || is_ia32_Const(n)) {
73 const ia32_immediate_attr_t *attr
74 = get_ia32_immediate_attr_const(n);
81 fputs(get_entity_name(attr->symconst), F);
83 if (attr->offset != 0 || attr->symconst == NULL) {
84 if (attr->offset > 0 && attr->symconst != NULL) {
87 fprintf(F, "%ld", attr->offset);
88 if (attr->no_pic_adjust) {
89 fputs("(no_pic_adjust)", F);
94 const ia32_attr_t *attr = get_ia32_attr_const(n);
96 if (attr->am_sc != NULL || attr->am_offs != 0)
99 if (attr->am_sc != NULL) {
100 if (attr->data.am_sc_sign) {
103 fputs(get_entity_name(attr->am_sc), F);
104 if (attr->data.am_sc_no_pic_adjust) {
105 fputs("(no_pic_adjust)", F);
108 if (attr->am_offs != 0) {
109 if (attr->am_offs > 0 && attr->am_sc != NULL) {
112 fprintf(F, "%d", attr->am_offs);
115 if (attr->am_sc != NULL || attr->am_offs != 0)
120 case dump_node_mode_txt:
121 mode = get_ia32_ls_mode(n);
123 fprintf(F, "[%s]", get_mode_name(mode));
126 case dump_node_nodeattr_txt:
127 if (! is_ia32_Lea(n)) {
128 if (is_ia32_AddrModeS(n)) {
129 fprintf(F, "[AM S] ");
130 } else if (is_ia32_AddrModeD(n)) {
131 fprintf(F, "[AM D] ");
137 case dump_node_info_txt:
138 arch_dump_reqs_and_registers(F, n);
142 switch (get_ia32_op_type(n)) {
144 fprintf(F, "Normal");
147 fprintf(F, "AM Dest (Load+Store)");
150 fprintf(F, "AM Source (Load)");
153 fprintf(F, "unknown (%d)", (int)get_ia32_op_type(n));
158 /* dump supported am */
159 fprintf(F, "AM support = ");
160 switch (get_ia32_am_support(n)) {
161 case ia32_am_none: fputs("none\n", F); break;
162 case ia32_am_unary: fputs("source (unary)\n", F); break;
163 case ia32_am_binary: fputs("source (binary)\n", F); break;
166 fprintf(F, "unknown (%d)\n", (int)get_ia32_am_support(n));
171 if (get_ia32_am_offs_int(n) != 0) {
172 fprintf(F, "AM offset = %d\n", get_ia32_am_offs_int(n));
175 /* dump AM symconst */
176 if (get_ia32_am_sc(n) != NULL) {
177 ir_entity *ent = get_ia32_am_sc(n);
178 ident *id = get_entity_ld_ident(ent);
179 fprintf(F, "AM symconst = %s\n", get_id_str(id));
183 fprintf(F, "AM scale = %u\n", get_ia32_am_scale(n));
186 if (is_ia32_CMovcc(n) || is_ia32_Setcc(n) || is_ia32_Jcc(n)) {
187 ia32_attr_t *attr = get_ia32_attr(n);
188 fprintf(F, "condition_code = 0x%X\n", (unsigned)get_ia32_condcode(n));
189 fprintf(F, "ins_permuted = %u\n", (unsigned)attr->data.ins_permuted);
191 else if (is_ia32_CopyB(n) || is_ia32_CopyB_i(n)) {
192 fprintf(F, "size = %u\n", get_ia32_copyb_size(n));
195 fprintf(F, "use_frame = %d\n", is_ia32_use_frame(n));
196 fprintf(F, "commutative = %d\n", is_ia32_commutative(n));
197 fprintf(F, "need stackent = %d\n", is_ia32_need_stackent(n));
198 fprintf(F, "is reload = %d\n", is_ia32_is_reload(n));
199 fprintf(F, "latency = %u\n", get_ia32_latency(n));
201 /* dump frame entity */
202 fprintf(F, "frame entity = ");
203 if (get_ia32_frame_ent(n)) {
204 ir_fprintf(F, "%+F", get_ia32_frame_ent(n));
212 fprintf(F, "ls_mode = ");
213 if (get_ia32_ls_mode(n)) {
214 ir_fprintf(F, "%+F", get_ia32_ls_mode(n));
222 /* dump original ir node name */
223 fprintf(F, "orig node = ");
224 if (get_ia32_orig_node(n)) {
225 fprintf(F, "%s", get_ia32_orig_node(n));
239 ia32_attr_t *get_ia32_attr(ir_node *node)
241 assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
242 return (ia32_attr_t *)get_irn_generic_attr(node);
245 const ia32_attr_t *get_ia32_attr_const(const ir_node *node)
247 assert(is_ia32_irn(node) && "need ia32 node to get ia32 attributes");
248 return (const ia32_attr_t*) get_irn_generic_attr_const(node);
251 ia32_x87_attr_t *get_ia32_x87_attr(ir_node *node)
253 ia32_attr_t *attr = get_ia32_attr(node);
254 ia32_x87_attr_t *x87_attr = CAST_IA32_ATTR(ia32_x87_attr_t, attr);
258 const ia32_x87_attr_t *get_ia32_x87_attr_const(const ir_node *node)
260 const ia32_attr_t *attr = get_ia32_attr_const(node);
261 const ia32_x87_attr_t *x87_attr = CONST_CAST_IA32_ATTR(ia32_x87_attr_t, attr);
265 const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node)
267 const ia32_attr_t *attr = get_ia32_attr_const(node);
268 const ia32_asm_attr_t *asm_attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, attr);
273 ia32_immediate_attr_t *get_ia32_immediate_attr(ir_node *node)
275 ia32_attr_t *attr = get_ia32_attr(node);
276 ia32_immediate_attr_t *imm_attr = CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
281 const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node)
283 const ia32_attr_t *attr = get_ia32_attr_const(node);
284 const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr);
289 ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node)
291 ia32_attr_t *attr = get_ia32_attr(node);
292 ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
297 const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node)
299 const ia32_attr_t *attr = get_ia32_attr_const(node);
300 const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr);
305 ia32_switch_attr_t *get_ia32_switch_attr(ir_node *node)
307 ia32_attr_t *attr = get_ia32_attr(node);
308 ia32_switch_attr_t *switch_attr = CAST_IA32_ATTR(ia32_switch_attr_t, attr);
312 const ia32_switch_attr_t *get_ia32_switch_attr_const(const ir_node *node)
314 const ia32_attr_t *attr = get_ia32_attr_const(node);
315 const ia32_switch_attr_t *switch_attr = CONST_CAST_IA32_ATTR(ia32_switch_attr_t, attr);
319 ia32_call_attr_t *get_ia32_call_attr(ir_node *node)
321 ia32_attr_t *attr = get_ia32_attr(node);
322 ia32_call_attr_t *call_attr = CAST_IA32_ATTR(ia32_call_attr_t, attr);
327 const ia32_call_attr_t *get_ia32_call_attr_const(const ir_node *node)
329 const ia32_attr_t *attr = get_ia32_attr_const(node);
330 const ia32_call_attr_t *call_attr = CONST_CAST_IA32_ATTR(ia32_call_attr_t, attr);
335 ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node)
337 ia32_attr_t *attr = get_ia32_attr(node);
338 ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
343 const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node)
345 const ia32_attr_t *attr = get_ia32_attr_const(node);
346 const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr);
351 ia32_climbframe_attr_t *get_ia32_climbframe_attr(ir_node *node)
353 ia32_attr_t *attr = get_ia32_attr(node);
354 ia32_climbframe_attr_t *climbframe_attr = CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
356 return climbframe_attr;
359 const ia32_climbframe_attr_t *get_ia32_climbframe_attr_const(const ir_node *node)
361 const ia32_attr_t *attr = get_ia32_attr_const(node);
362 const ia32_climbframe_attr_t *climbframe_attr = CONST_CAST_IA32_ATTR(ia32_climbframe_attr_t, attr);
364 return climbframe_attr;
368 * Gets the type of an ia32 node.
370 ia32_op_type_t get_ia32_op_type(const ir_node *node)
372 const ia32_attr_t *attr = get_ia32_attr_const(node);
373 return (ia32_op_type_t)attr->data.tp;
377 * Sets the type of an ia32 node.
379 void set_ia32_op_type(ir_node *node, ia32_op_type_t tp)
381 ia32_attr_t *attr = get_ia32_attr(node);
385 ia32_am_type_t get_ia32_am_support(const ir_node *node)
387 const ia32_attr_t *attr = get_ia32_attr_const(node);
388 return (ia32_am_type_t)attr->data.am_arity;
392 * Sets the supported address mode of an ia32 node
394 void set_ia32_am_support(ir_node *node, ia32_am_type_t arity)
396 ia32_attr_t *attr = get_ia32_attr(node);
397 attr->data.am_arity = arity;
401 * Gets the address mode offset as int.
403 int get_ia32_am_offs_int(const ir_node *node)
405 const ia32_attr_t *attr = get_ia32_attr_const(node);
406 return attr->am_offs;
410 * Sets the address mode offset from an int.
412 void set_ia32_am_offs_int(ir_node *node, int offset)
414 ia32_attr_t *attr = get_ia32_attr(node);
415 attr->am_offs = offset;
418 void add_ia32_am_offs_int(ir_node *node, int offset)
420 ia32_attr_t *attr = get_ia32_attr(node);
421 attr->am_offs += offset;
425 * Returns the symconst entity associated to address mode.
427 ir_entity *get_ia32_am_sc(const ir_node *node)
429 const ia32_attr_t *attr = get_ia32_attr_const(node);
434 * Sets the symconst entity associated to address mode.
436 void set_ia32_am_sc(ir_node *node, ir_entity *entity)
438 ia32_attr_t *attr = get_ia32_attr(node);
439 attr->am_sc = entity;
443 * Sets the sign bit for address mode symconst.
445 void set_ia32_am_sc_sign(ir_node *node)
447 ia32_attr_t *attr = get_ia32_attr(node);
448 attr->data.am_sc_sign = 1;
452 * Clears the sign bit for address mode symconst.
454 void clear_ia32_am_sc_sign(ir_node *node)
456 ia32_attr_t *attr = get_ia32_attr(node);
457 attr->data.am_sc_sign = 0;
461 * Returns the sign bit for address mode symconst.
463 int is_ia32_am_sc_sign(const ir_node *node)
465 const ia32_attr_t *attr = get_ia32_attr_const(node);
466 return attr->data.am_sc_sign;
469 void set_ia32_am_tls_segment(ir_node *node, bool value)
471 ia32_attr_t *attr = get_ia32_attr(node);
472 attr->data.am_tls_segment = value;
475 bool get_ia32_am_tls_segment(const ir_node *node)
477 const ia32_attr_t *attr = get_ia32_attr_const(node);
478 return attr->data.am_tls_segment;
482 * Gets the addr mode const.
484 unsigned get_ia32_am_scale(const ir_node *node)
486 const ia32_attr_t *attr = get_ia32_attr_const(node);
487 return attr->data.am_scale;
491 * Sets the index register scale for address mode.
493 void set_ia32_am_scale(ir_node *node, unsigned scale)
495 ia32_attr_t *attr = get_ia32_attr(node);
496 assert(scale <= 3 && "AM scale out of range [0 ... 3]");
497 attr->data.am_scale = scale;
500 void ia32_copy_am_attrs(ir_node *to, const ir_node *from)
502 set_ia32_ls_mode(to, get_ia32_ls_mode(from));
503 set_ia32_am_scale(to, get_ia32_am_scale(from));
504 set_ia32_am_sc(to, get_ia32_am_sc(from));
505 if (is_ia32_am_sc_sign(from))
506 set_ia32_am_sc_sign(to);
507 add_ia32_am_offs_int(to, get_ia32_am_offs_int(from));
508 set_ia32_frame_ent(to, get_ia32_frame_ent(from));
509 if (is_ia32_use_frame(from))
510 set_ia32_use_frame(to);
514 * Sets the uses_frame flag.
516 void set_ia32_use_frame(ir_node *node)
518 ia32_attr_t *attr = get_ia32_attr(node);
519 attr->data.use_frame = 1;
523 * Clears the uses_frame flag.
525 void clear_ia32_use_frame(ir_node *node)
527 ia32_attr_t *attr = get_ia32_attr(node);
528 attr->data.use_frame = 0;
532 * Gets the uses_frame flag.
534 int is_ia32_use_frame(const ir_node *node)
536 const ia32_attr_t *attr = get_ia32_attr_const(node);
537 return attr->data.use_frame;
541 * Sets node to commutative.
543 void set_ia32_commutative(ir_node *node)
545 ia32_attr_t *attr = get_ia32_attr(node);
546 attr->data.is_commutative = 1;
550 * Sets node to non-commutative.
552 void clear_ia32_commutative(ir_node *node)
554 ia32_attr_t *attr = get_ia32_attr(node);
555 attr->data.is_commutative = 0;
559 * Checks if node is commutative.
561 int is_ia32_commutative(const ir_node *node)
563 const ia32_attr_t *attr = get_ia32_attr_const(node);
564 return attr->data.is_commutative;
567 void set_ia32_need_stackent(ir_node *node)
569 ia32_attr_t *attr = get_ia32_attr(node);
570 attr->data.need_stackent = 1;
573 void clear_ia32_need_stackent(ir_node *node)
575 ia32_attr_t *attr = get_ia32_attr(node);
576 attr->data.need_stackent = 0;
579 int is_ia32_need_stackent(const ir_node *node)
581 const ia32_attr_t *attr = get_ia32_attr_const(node);
582 return attr->data.need_stackent;
585 void set_ia32_is_reload(ir_node *node)
587 ia32_attr_t *attr = get_ia32_attr(node);
588 attr->data.is_reload = 1;
591 int is_ia32_is_reload(const ir_node *node)
593 const ia32_attr_t *attr = get_ia32_attr_const(node);
594 return attr->data.is_reload;
597 void set_ia32_is_spill(ir_node *node)
599 ia32_attr_t *attr = get_ia32_attr(node);
600 attr->data.is_spill = 1;
603 int is_ia32_is_spill(const ir_node *node)
605 const ia32_attr_t *attr = get_ia32_attr_const(node);
606 return attr->data.is_spill;
609 void set_ia32_is_remat(ir_node *node)
611 ia32_attr_t *attr = get_ia32_attr(node);
612 attr->data.is_remat = 1;
615 int is_ia32_is_remat(const ir_node *node)
617 const ia32_attr_t *attr = get_ia32_attr_const(node);
618 return attr->data.is_remat;
622 * Gets the mode of the stored/loaded value (only set for Store/Load)
624 ir_mode *get_ia32_ls_mode(const ir_node *node)
626 const ia32_attr_t *attr = get_ia32_attr_const(node);
627 return attr->ls_mode;
631 * Sets the mode of the stored/loaded value (only set for Store/Load)
633 void set_ia32_ls_mode(ir_node *node, ir_mode *mode)
635 ia32_attr_t *attr = get_ia32_attr(node);
636 attr->ls_mode = mode;
640 * Gets the frame entity assigned to this node.
642 ir_entity *get_ia32_frame_ent(const ir_node *node)
644 const ia32_attr_t *attr = get_ia32_attr_const(node);
645 return attr->frame_ent;
649 * Sets the frame entity for this node.
651 void set_ia32_frame_ent(ir_node *node, ir_entity *ent)
653 ia32_attr_t *attr = get_ia32_attr(node);
654 attr->frame_ent = ent;
656 set_ia32_use_frame(node);
658 clear_ia32_use_frame(node);
663 * Gets the instruction latency.
665 unsigned get_ia32_latency(const ir_node *node)
667 const ir_op *op = get_irn_op(node);
668 const ia32_op_attr_t *op_attr = (ia32_op_attr_t*) get_op_attr(op);
669 return op_attr->latency;
672 const ir_switch_table *get_ia32_switch_table(const ir_node *node)
674 const ia32_switch_attr_t *attr = get_ia32_switch_attr_const(node);
678 ia32_condition_code_t get_ia32_condcode(const ir_node *node)
680 const ia32_condcode_attr_t *attr = get_ia32_condcode_attr_const(node);
681 return attr->condition_code;
685 * Sets the condition code of a node
687 void set_ia32_condcode(ir_node *node, ia32_condition_code_t code)
689 ia32_condcode_attr_t *attr = get_ia32_condcode_attr(node);
690 attr->condition_code = code;
694 * Returns the condition code of a node.
696 unsigned get_ia32_copyb_size(const ir_node *node)
698 const ia32_copyb_attr_t *attr = get_ia32_copyb_attr_const(node);
703 * Get the exception label attribute.
705 unsigned get_ia32_exc_label(const ir_node *node)
707 const ia32_attr_t *attr = get_ia32_attr_const(node);
708 return attr->data.has_except_label;
712 * Set the exception label attribute.
714 void set_ia32_exc_label(ir_node *node, unsigned flag)
716 ia32_attr_t *attr = get_ia32_attr(node);
717 attr->data.has_except_label = flag;
721 * Return the exception label id.
723 ir_label_t get_ia32_exc_label_id(const ir_node *node)
725 const ia32_attr_t *attr = get_ia32_attr_const(node);
727 assert(attr->data.has_except_label);
728 return attr->exc_label;
732 * Assign the exception label id.
734 void set_ia32_exc_label_id(ir_node *node, ir_label_t id)
736 ia32_attr_t *attr = get_ia32_attr(node);
738 assert(attr->data.has_except_label);
739 attr->exc_label = id;
745 * Returns the name of the original ir node.
747 const char *get_ia32_orig_node(const ir_node *node)
749 const ia32_attr_t *attr = get_ia32_attr_const(node);
750 return attr->orig_node;
753 static const char *ia32_get_old_node_name(const ir_node *irn)
755 ir_graph *irg = get_irn_irg(irn);
756 struct obstack *obst = be_get_be_obst(irg);
758 lc_eoprintf(firm_get_arg_env(), obst, "%+F", irn);
759 obstack_1grow(obst, 0);
760 return (const char*)obstack_finish(obst);
764 * Sets the name of the original ir node.
766 void set_ia32_orig_node(ir_node *node, const ir_node *old)
768 const char *name = ia32_get_old_node_name(old);
769 ia32_attr_t *attr = get_ia32_attr(node);
770 attr->orig_node = name;
777 * Returns whether or not the node is an AddrModeS node.
779 int is_ia32_AddrModeS(const ir_node *node)
781 const ia32_attr_t *attr = get_ia32_attr_const(node);
782 return (attr->data.tp == ia32_AddrModeS);
786 * Returns whether or not the node is an AddrModeD node.
788 int is_ia32_AddrModeD(const ir_node *node)
790 const ia32_attr_t *attr = get_ia32_attr_const(node);
791 return (attr->data.tp == ia32_AddrModeD);
794 void ia32_swap_left_right(ir_node *node)
796 ia32_attr_t *attr = get_ia32_attr(node);
797 ir_node *left = get_irn_n(node, n_ia32_binary_left);
798 ir_node *right = get_irn_n(node, n_ia32_binary_right);
800 assert(is_ia32_commutative(node));
801 attr->data.ins_permuted = !attr->data.ins_permuted;
802 set_irn_n(node, n_ia32_binary_left, right);
803 set_irn_n(node, n_ia32_binary_right, left);
807 * Initializes the nodes attributes.
809 static void init_ia32_attributes(ir_node *node, arch_irn_flags_t flags,
810 const arch_register_req_t **in_reqs,
813 ir_graph *irg = get_irn_irg(node);
814 struct obstack *obst = get_irg_obstack(irg);
815 ia32_attr_t *attr = get_ia32_attr(node);
816 backend_info_t *info;
818 arch_set_irn_flags(node, flags);
819 arch_set_irn_register_reqs_in(node, in_reqs);
822 attr->attr_type |= IA32_ATTR_ia32_attr_t;
825 info = be_get_info(node);
826 info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
827 memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
830 static void init_ia32_x87_attributes(ir_node *res)
832 ir_graph *irg = get_irn_irg(res);
833 ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
835 ia32_attr_t *attr = get_ia32_attr(res);
836 attr->attr_type |= IA32_ATTR_ia32_x87_attr_t;
840 irg_data->do_x87_sim = 1;
843 static void init_ia32_asm_attributes(ir_node *res)
846 ia32_attr_t *attr = get_ia32_attr(res);
847 attr->attr_type |= IA32_ATTR_ia32_asm_attr_t;
853 static void init_ia32_immediate_attributes(ir_node *res, ir_entity *symconst,
854 int symconst_sign, int no_pic_adjust,
857 ia32_immediate_attr_t *attr = (ia32_immediate_attr_t*)get_irn_generic_attr(res);
860 attr->attr.attr_type |= IA32_ATTR_ia32_immediate_attr_t;
862 attr->symconst = symconst;
863 attr->sc_sign = symconst_sign;
864 attr->no_pic_adjust = no_pic_adjust;
865 attr->offset = offset;
868 static void init_ia32_call_attributes(ir_node* res, unsigned pop,
871 ia32_call_attr_t *attr = (ia32_call_attr_t*)get_irn_generic_attr(res);
874 attr->attr.attr_type |= IA32_ATTR_ia32_call_attr_t;
877 attr->call_tp = call_tp;
880 static void init_ia32_copyb_attributes(ir_node *res, unsigned size)
882 ia32_copyb_attr_t *attr = (ia32_copyb_attr_t*)get_irn_generic_attr(res);
885 attr->attr.attr_type |= IA32_ATTR_ia32_copyb_attr_t;
890 static void init_ia32_condcode_attributes(ir_node *res,
891 ia32_condition_code_t cc)
893 ia32_condcode_attr_t *attr = (ia32_condcode_attr_t*)get_irn_generic_attr(res);
896 attr->attr.attr_type |= IA32_ATTR_ia32_condcode_attr_t;
898 attr->condition_code = cc;
901 static void init_ia32_climbframe_attributes(ir_node *res, unsigned count)
903 ia32_climbframe_attr_t *attr = (ia32_climbframe_attr_t*)get_irn_generic_attr(res);
906 attr->attr.attr_type |= IA32_ATTR_ia32_climbframe_attr_t;
911 static void init_ia32_switch_attributes(ir_node *node,
912 const ir_switch_table *table)
914 unsigned n_outs = arch_get_irn_n_outs(node);
917 ia32_switch_attr_t *attr = (ia32_switch_attr_t*) get_irn_generic_attr(node);
919 attr->attr.attr_type |= IA32_ATTR_ia32_switch_attr_t;
923 for (o = 0; o < n_outs; ++o) {
924 arch_set_irn_register_req_out(node, o, arch_no_register_req);
928 /* default compare operation to compare attributes */
929 static int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b)
931 if (a->data.tp != b->data.tp)
934 if (a->data.am_scale != b->data.am_scale
935 || a->data.am_sc_sign != b->data.am_sc_sign
936 || a->am_offs != b->am_offs
937 || a->am_sc != b->am_sc
938 || a->data.am_sc_no_pic_adjust != b->data.am_sc_no_pic_adjust
939 || a->ls_mode != b->ls_mode)
942 /* nodes with not yet assigned entities shouldn't be CSEd (important for
943 * unsigned int -> double conversions */
944 if (a->data.use_frame && a->frame_ent == NULL)
946 if (b->data.use_frame && b->frame_ent == NULL)
949 if (a->data.use_frame != b->data.use_frame
950 || a->frame_ent != b->frame_ent)
953 if (a->data.has_except_label != b->data.has_except_label)
956 if (a->data.ins_permuted != b->data.ins_permuted)
962 /** Compare nodes attributes for all "normal" nodes. */
963 static int ia32_compare_nodes_attr(const ir_node *a, const ir_node *b)
965 const ia32_attr_t* attr_a = get_ia32_attr_const(a);
966 const ia32_attr_t* attr_b = get_ia32_attr_const(b);
968 return ia32_compare_attr(attr_a, attr_b);
971 /** Compare node attributes for nodes with condition code. */
972 static int ia32_compare_condcode_attr(const ir_node *a, const ir_node *b)
974 const ia32_condcode_attr_t *attr_a;
975 const ia32_condcode_attr_t *attr_b;
977 if (ia32_compare_nodes_attr(a, b))
980 attr_a = get_ia32_condcode_attr_const(a);
981 attr_b = get_ia32_condcode_attr_const(b);
983 if (attr_a->condition_code != attr_b->condition_code)
989 /** Compare node attributes for call nodes. */
990 static int ia32_compare_call_attr(const ir_node *a, const ir_node *b)
992 const ia32_call_attr_t *attr_a;
993 const ia32_call_attr_t *attr_b;
995 if (ia32_compare_nodes_attr(a, b))
998 attr_a = get_ia32_call_attr_const(a);
999 attr_b = get_ia32_call_attr_const(b);
1001 if (attr_a->pop != attr_b->pop)
1004 if (attr_a->call_tp != attr_b->call_tp)
1010 /** Compare node attributes for CopyB nodes. */
1011 static int ia32_compare_copyb_attr(const ir_node *a, const ir_node *b)
1013 const ia32_copyb_attr_t *attr_a;
1014 const ia32_copyb_attr_t *attr_b;
1016 if (ia32_compare_nodes_attr(a, b))
1019 attr_a = get_ia32_copyb_attr_const(a);
1020 attr_b = get_ia32_copyb_attr_const(b);
1022 if (attr_a->size != attr_b->size)
1029 /** Compare ASM node attributes. */
1030 static int ia32_compare_asm_attr(const ir_node *a, const ir_node *b)
1032 const ia32_asm_attr_t *attr_a;
1033 const ia32_asm_attr_t *attr_b;
1035 if (ia32_compare_nodes_attr(a, b))
1038 attr_a = get_ia32_asm_attr_const(a);
1039 attr_b = get_ia32_asm_attr_const(b);
1041 if (attr_a->asm_text != attr_b->asm_text)
1048 * Hash function for Immediates
1050 static unsigned ia32_hash_Immediate(const ir_node *irn)
1052 const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
1054 return HASH_PTR(a->symconst) + (a->sc_sign << 16) + a->offset;
1057 /** Compare node attributes for Immediates. */
1058 static int ia32_compare_immediate_attr(const ir_node *a, const ir_node *b)
1060 const ia32_immediate_attr_t *attr_a = get_ia32_immediate_attr_const(a);
1061 const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
1063 if (attr_a->symconst != attr_b->symconst
1064 || attr_a->sc_sign != attr_b->sc_sign
1065 || attr_a->no_pic_adjust != attr_b->no_pic_adjust
1066 || attr_a->offset != attr_b->offset) {
1073 /** Compare node attributes for x87 nodes. */
1074 static int ia32_compare_x87_attr(const ir_node *a, const ir_node *b)
1076 return ia32_compare_nodes_attr(a, b);
1079 /** Compare node attributes for ClimbFrame nodes. */
1080 static int ia32_compare_climbframe_attr(const ir_node *a, const ir_node *b)
1082 const ia32_climbframe_attr_t *attr_a;
1083 const ia32_climbframe_attr_t *attr_b;
1085 if (ia32_compare_nodes_attr(a, b))
1088 attr_a = get_ia32_climbframe_attr_const(a);
1089 attr_b = get_ia32_climbframe_attr_const(b);
1091 if (attr_a->count != attr_b->count)
1097 /* copies the ia32 attributes */
1098 static void ia32_copy_attr(ir_graph *irg, const ir_node *old_node,
1101 struct obstack *obst = get_irg_obstack(irg);
1102 const ia32_attr_t *attr_old = get_ia32_attr_const(old_node);
1103 ia32_attr_t *attr_new = get_ia32_attr(new_node);
1104 backend_info_t *old_info = be_get_info(old_node);
1105 backend_info_t *new_info = be_get_info(new_node);
1107 /* copy the attributes */
1108 memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
1110 /* copy out flags */
1111 new_info->out_infos =
1112 DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
1113 new_info->in_reqs = old_info->in_reqs;
1114 new_info->flags = old_info->flags;
1117 /* Include the generated constructor functions */
1118 #include "gen_ia32_new_nodes.c.inl"