+static ir_node *create_Const_from_bool(ir_mode *const mode, bool const v)
+{
+ return new_Const((v ? get_mode_one : get_mode_null)(mode));
+}
+
+static ir_node *create_conv_from_b(dbg_info *dbgi, ir_node *value,
+ ir_mode *dest_mode)
+{
+ if (is_Const(value)) {
+ return create_Const_from_bool(dest_mode, !is_Const_null(value));
+ }
+
+ ir_node *cond = new_d_Cond(dbgi, value);
+ ir_node *proj_true = new_Proj(cond, mode_X, pn_Cond_true);
+ ir_node *proj_false = new_Proj(cond, mode_X, pn_Cond_false);
+ ir_node *tblock = new_Block(1, &proj_true);
+ ir_node *fblock = new_Block(1, &proj_false);
+ set_cur_block(tblock);
+ ir_node *const1 = new_Const(get_mode_one(dest_mode));
+ ir_node *tjump = new_Jmp();
+ set_cur_block(fblock);
+ ir_node *const0 = new_Const(get_mode_null(dest_mode));
+ ir_node *fjump = new_Jmp();
+
+ ir_node *in[2] = { tjump, fjump };
+ ir_node *mergeblock = new_Block(2, in);
+ set_cur_block(mergeblock);
+ ir_node *phi_in[2] = { const1, const0 };
+ ir_node *phi = new_Phi(2, phi_in, dest_mode);
+ return phi;
+}
+
+static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
+{
+ ir_mode *value_mode = get_irn_mode(value);
+
+ if (value_mode == dest_mode)
+ return value;
+
+ if (dest_mode == mode_b) {
+ ir_node *zero = new_Const(get_mode_null(value_mode));
+ ir_node *cmp = new_d_Cmp(dbgi, value, zero, ir_relation_unordered_less_greater);
+ return cmp;
+ } else if (value_mode == mode_b) {
+ return create_conv_from_b(dbgi, value, dest_mode);
+ }
+
+ return new_d_Conv(dbgi, value, dest_mode);
+}
+
+/**
+ * Creates a SymConst node representing a wide string literal.
+ *
+ * @param literal the wide string literal
+ */
+static ir_node *wide_string_literal_to_firm(
+ const string_literal_expression_t *literal)
+{
+ ir_type *const global_type = get_glob_type();
+ ir_type *const elem_type = ir_type_wchar_t;
+ dbg_info *const dbgi = get_dbg_info(&literal->base.source_position);
+ ir_type *const type = new_type_array(1, elem_type);
+
+ ident *const id = id_unique("str.%u");
+ ir_entity *const entity = new_d_entity(global_type, id, type, dbgi);
+ set_entity_ld_ident(entity, id);
+ set_entity_visibility(entity, ir_visibility_private);
+ add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
+
+ ir_mode *const mode = get_type_mode(elem_type);
+ const size_t slen = wstrlen(&literal->value);
+
+ set_array_lower_bound_int(type, 0, 0);
+ set_array_upper_bound_int(type, 0, slen);
+ set_type_size_bytes(type, slen * get_mode_size_bytes(mode));
+ set_type_state(type, layout_fixed);
+
+ ir_initializer_t *initializer = create_initializer_compound(slen);
+ const char *p = literal->value.begin;
+ for (size_t i = 0; i < slen; ++i) {
+ assert(p < literal->value.begin + literal->value.size);
+ utf32 v = read_utf8_char(&p);
+ ir_tarval *tv = new_tarval_from_long(v, mode);
+ ir_initializer_t *val = create_initializer_tarval(tv);
+ set_initializer_compound_value(initializer, i, val);
+ }
+ set_entity_initializer(entity, initializer);
+
+ return create_symconst(dbgi, entity);
+}
+
+/**
+ * Creates a SymConst node representing a string constant.
+ *
+ * @param src_pos the source position of the string constant
+ * @param id_prefix a prefix for the name of the generated string constant
+ * @param value the value of the string constant
+ */
+static ir_node *string_to_firm(const source_position_t *const src_pos,
+ const char *const id_prefix,
+ const string_t *const value)
+{
+ ir_type *const global_type = get_glob_type();
+ dbg_info *const dbgi = get_dbg_info(src_pos);
+ ir_type *const type = new_type_array(1, ir_type_const_char);
+
+ ident *const id = id_unique(id_prefix);
+ ir_entity *const entity = new_d_entity(global_type, id, type, dbgi);
+ set_entity_ld_ident(entity, id);
+ set_entity_visibility(entity, ir_visibility_private);
+ add_entity_linkage(entity, IR_LINKAGE_CONSTANT);
+
+ ir_type *const elem_type = ir_type_const_char;
+ ir_mode *const mode = get_type_mode(elem_type);
+
+ const char* const string = value->begin;
+ const size_t slen = value->size;
+
+ set_array_lower_bound_int(type, 0, 0);
+ set_array_upper_bound_int(type, 0, slen);
+ set_type_size_bytes(type, slen);
+ set_type_state(type, layout_fixed);
+
+ ir_initializer_t *initializer = create_initializer_compound(slen);
+ for (size_t i = 0; i < slen; ++i) {
+ ir_tarval *tv = new_tarval_from_long(string[i], mode);
+ ir_initializer_t *val = create_initializer_tarval(tv);
+ set_initializer_compound_value(initializer, i, val);
+ }
+ set_entity_initializer(entity, initializer);
+
+ return create_symconst(dbgi, entity);
+}
+
+static bool try_create_integer(literal_expression_t *literal,
+ type_t *type, unsigned char base)
+{
+ const char *string = literal->value.begin;
+ size_t size = literal->value.size;
+
+ assert(type->kind == TYPE_ATOMIC);
+ atomic_type_kind_t akind = type->atomic.akind;
+
+ ir_mode *mode = atomic_modes[akind];
+ ir_tarval *tv = new_integer_tarval_from_str(string, size, 1, base, mode);
+ if (tv == tarval_bad)
+ return false;
+
+ literal->base.type = type;
+ literal->target_value = tv;
+ return true;
+}
+
+static void create_integer_tarval(literal_expression_t *literal)
+{
+ unsigned us = 0;
+ unsigned ls = 0;
+ const string_t *suffix = &literal->suffix;
+ /* parse suffix */
+ if (suffix->size > 0) {
+ for (const char *c = suffix->begin; *c != '\0'; ++c) {
+ if (*c == 'u' || *c == 'U') { ++us; }
+ if (*c == 'l' || *c == 'L') { ++ls; }