+/**
+ * Calculate the value of strlen if possible.
+ *
+ * @param left the left entity
+ * @param right the right entity
+ * @param res_tp the result type
+ *
+ * @return a Const node containing the strcmp() result or NULL
+ * if the evaluation fails
+ */
+static ir_node *eval_strcmp(ir_graph *irg, ir_entity *left, ir_entity *right,
+ ir_type *res_tp)
+{
+ ir_type *tp;
+ ir_mode *mode;
+ ir_initializer_t *init_l;
+ ir_initializer_t *init_r;
+ size_t size_l;
+ size_t size_r;
+ size_t size;
+ size_t i;
+
+ tp = get_entity_type(left);
+ if (! is_Array_type(tp))
+ return NULL;
+ tp = get_array_element_type(tp);
+ if (! is_Primitive_type(tp))
+ return NULL;
+ mode = get_type_mode(tp);
+
+ /* FIXME: This is too restrict, as the type char might be more the 8bits */
+ if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
+ return NULL;
+
+ tp = get_entity_type(right);
+ if (! is_Array_type(tp))
+ return NULL;
+ tp = get_array_element_type(tp);
+ if (! is_Primitive_type(tp))
+ return NULL;
+ mode = get_type_mode(tp);
+
+ /* FIXME: This is too restrict, as the type char might be more the 8bits */
+ if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
+ return NULL;
+
+ init_l = get_entity_initializer(left);
+ init_r = get_entity_initializer(right);
+ if (get_initializer_kind(init_l) != IR_INITIALIZER_COMPOUND ||
+ get_initializer_kind(init_r) != IR_INITIALIZER_COMPOUND)
+ return NULL;
+
+ size_l = get_initializer_compound_n_entries(init_l);
+ size_r = get_initializer_compound_n_entries(init_r);
+ size = size_l < size_r ? size_l : size_r;
+
+ for (i = 0; i != size; ++i) {
+ ir_initializer_t *const val_l = get_initializer_compound_value(init_l, i);
+ ir_tarval *const tv_l = get_initializer_value(val_l, mode);
+ ir_initializer_t *const val_r = get_initializer_compound_value(init_r, i);
+ ir_tarval *const tv_r = get_initializer_value(val_r, mode);
+
+ if (!tarval_is_constant(tv_l) || !tarval_is_constant(tv_r))
+ return NULL;
+
+ if (tv_l != tv_r) {
+ ir_mode *const res_mode = get_type_mode(res_tp);
+ ir_tarval *const res_l = tarval_convert_to(tv_l, res_mode);
+ ir_tarval *const res_r = tarval_convert_to(tv_r, res_mode);
+ ir_tarval *const tv = tarval_sub(res_l, res_r, res_mode);
+ return new_r_Const(irg, tv);
+ }
+
+ if (tarval_is_null(tv_l)) {
+ ir_tarval *const tv = get_mode_null(get_type_mode(res_tp));
+ return new_r_Const(irg, tv);
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * Checks if an entity represents the empty string.
+ *
+ * @param ent the entity
+ *
+ * @return non-zero if ent represents the empty string
+ */
+static int is_empty_string(ir_entity *ent)
+{
+ ir_type *tp = get_entity_type(ent);
+ ir_mode *mode;
+ ir_initializer_t *initializer;
+ ir_initializer_t *init0;
+
+ if (! is_Array_type(tp))
+ return 0;
+ tp = get_array_element_type(tp);
+ if (! is_Primitive_type(tp))
+ return 0;
+ mode = get_type_mode(tp);
+
+ /* FIXME: This is too restrict, as the type char might be more the 8bits */
+ if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
+ return 0;
+
+ initializer = get_entity_initializer(ent);
+ if (get_initializer_kind(initializer) != IR_INITIALIZER_COMPOUND)
+ return 0;
+
+ if (get_initializer_compound_n_entries(initializer) < 1)
+ return 0;
+
+ init0 = get_initializer_compound_value(initializer, 0);
+ return initializer_val_is_null(init0);
+}
+
+int i_mapper_strcmp(ir_node *call, void *ctx)
+{
+ ir_node *left = get_Call_param(call, 0);
+ ir_node *right = get_Call_param(call, 1);
+ ir_node *irn = NULL;
+ ir_node *exc = NULL;
+ ir_node *reg = NULL;
+ ir_type *call_tp = get_Call_type(call);
+ ir_type *res_tp = get_method_res_type(call_tp, 0);
+ ir_entity *ent_l, *ent_r;
+ ir_type *char_tp;
+ ir_node *v;
+