+/* default compare operation to compare attributes */
+int ia32_compare_attr(const ia32_attr_t *a, const ia32_attr_t *b) {
+ if (a->data.tp != b->data.tp)
+ return 1;
+
+ if (a->data.am_scale != b->data.am_scale
+ || a->data.am_sc_sign != b->data.am_sc_sign
+ || a->am_offs != b->am_offs
+ || a->am_sc != b->am_sc
+ || a->ls_mode != b->ls_mode)
+ return 1;
+
+ /* nodes with not yet assigned entities shouldn't be CSEd (important for
+ * unsigned int -> double conversions */
+ if(a->data.use_frame && a->frame_ent == NULL)
+ return 1;
+ if(b->data.use_frame && b->frame_ent == NULL)
+ return 1;
+
+ if (a->data.use_frame != b->data.use_frame
+ || a->frame_ent != b->frame_ent)
+ return 1;
+
+ if (a->data.tp != b->data.tp)
+ return 1;
+
+ if (a->data.has_except_label != b->data.has_except_label)
+ return 1;
+
+ if (a->data.ins_permuted != b->data.ins_permuted
+ || a->data.cmp_unsigned != b->data.cmp_unsigned)
+ return 1;
+
+ return 0;
+}
+
+/** Compare nodes attributes for all "normal" nodes. */
+static
+int ia32_compare_nodes_attr(ir_node *a, ir_node *b)
+{
+ const ia32_attr_t* attr_a = get_ia32_attr_const(a);
+ const ia32_attr_t* attr_b = get_ia32_attr_const(b);
+
+ return ia32_compare_attr(attr_a, attr_b);
+}
+
+/** Compare node attributes for nodes with condition code. */
+static
+int ia32_compare_condcode_attr(ir_node *a, ir_node *b)
+{
+ const ia32_condcode_attr_t *attr_a;
+ const ia32_condcode_attr_t *attr_b;
+
+ if (ia32_compare_nodes_attr(a, b))
+ return 1;
+
+ attr_a = get_ia32_condcode_attr_const(a);
+ attr_b = get_ia32_condcode_attr_const(b);
+
+ if(attr_a->pn_code != attr_b->pn_code)
+ return 1;
+
+ return 0;
+}
+
+/** Compare node attributes for CopyB nodes. */
+static
+int ia32_compare_copyb_attr(ir_node *a, ir_node *b)
+{
+ const ia32_copyb_attr_t *attr_a;
+ const ia32_copyb_attr_t *attr_b;
+
+ if (ia32_compare_nodes_attr(a, b))
+ return 1;
+
+ attr_a = get_ia32_copyb_attr_const(a);
+ attr_b = get_ia32_copyb_attr_const(b);
+
+ if(attr_a->size != attr_b->size)
+ return 1;
+
+ return 0;
+}
+
+
+/** Compare ASM node attributes. */
+static
+int ia32_compare_asm_attr(ir_node *a, ir_node *b)
+{
+ const ia32_asm_attr_t *attr_a;
+ const ia32_asm_attr_t *attr_b;
+
+ if(ia32_compare_nodes_attr(a, b))
+ return 1;
+
+ attr_a = get_ia32_asm_attr_const(a);
+ attr_b = get_ia32_asm_attr_const(b);
+
+ if(attr_a->asm_text != attr_b->asm_text)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * Hash function for Immediates
+ */
+static unsigned ia32_hash_Immediate(const ir_node *irn) {
+ const ia32_immediate_attr_t *a = get_ia32_immediate_attr_const(irn);
+
+ return HASH_PTR(a->symconst) + (a->sc_sign << 16) + a->offset;
+}
+
+/** Compare node attributes for Immediates. */
+static
+int ia32_compare_immediate_attr(ir_node *a, ir_node *b)
+{
+ const ia32_immediate_attr_t *attr_a = get_ia32_immediate_attr_const(a);
+ const ia32_immediate_attr_t *attr_b = get_ia32_immediate_attr_const(b);
+
+ if(attr_a->symconst != attr_b->symconst ||
+ attr_a->sc_sign != attr_b->sc_sign ||
+ attr_a->offset != attr_b->offset)
+ return 1;
+
+ return 0;
+}
+
+/** Compare node attributes for x87 nodes. */
+static
+int ia32_compare_x87_attr(ir_node *a, ir_node *b)
+{
+ return ia32_compare_nodes_attr(a, b);
+}
+
+
+/* copies the ia32 attributes */
+static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node)
+{
+ ir_graph *irg = get_irn_irg(new_node);
+ struct obstack *obst = get_irg_obstack(irg);
+ const ia32_attr_t *attr_old = get_ia32_attr_const(old_node);
+ ia32_attr_t *attr_new = get_ia32_attr(new_node);
+
+ /* copy the attributes */
+ memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
+
+ /* copy out flags */
+ attr_new->out_flags =
+ DUP_ARR_D(int, obst, attr_old->out_flags);
+ /* copy register assignments */
+ attr_new->slots =
+ DUP_ARR_D(arch_register_t*, obst, attr_old->slots);
+}
+