+ * Creates a Const node representing a constant.
+ */
+static ir_node *literal_to_firm(const literal_expression_t *literal)
+{
+ type_t *type = skip_typeref(literal->base.type);
+ ir_mode *mode = get_ir_mode_storage(type);
+ const char *string = literal->value.begin;
+ size_t size = literal->value.size;
+ ir_tarval *tv;
+
+ switch (literal->base.kind) {
+ case EXPR_LITERAL_WIDE_CHARACTER: {
+ utf32 v = read_utf8_char(&string);
+ char buf[128];
+ size_t len = snprintf(buf, sizeof(buf), UTF32_PRINTF_FORMAT, v);
+
+ tv = new_tarval_from_str(buf, len, mode);
+ goto make_const;
+ }
+ case EXPR_LITERAL_CHARACTER: {
+ long long int v;
+ bool char_is_signed
+ = get_atomic_type_flags(ATOMIC_TYPE_CHAR) & ATOMIC_TYPE_FLAG_SIGNED;
+ if (size == 1 && char_is_signed) {
+ v = (signed char)string[0];
+ } else {
+ v = 0;
+ for (size_t i = 0; i < size; ++i) {
+ v = (v << 8) | ((unsigned char)string[i]);
+ }
+ }
+ char buf[128];
+ size_t len = snprintf(buf, sizeof(buf), "%lld", v);
+
+ tv = new_tarval_from_str(buf, len, mode);
+ goto make_const;
+ }
+ case EXPR_LITERAL_INTEGER:
+ case EXPR_LITERAL_INTEGER_OCTAL:
+ case EXPR_LITERAL_INTEGER_HEXADECIMAL:
+ assert(literal->target_value != NULL);
+ tv = literal->target_value;
+ goto make_const;
+ case EXPR_LITERAL_FLOATINGPOINT:
+ tv = new_tarval_from_str(string, size, mode);
+ goto make_const;
+ case EXPR_LITERAL_FLOATINGPOINT_HEXADECIMAL: {
+ char buffer[size + 2];
+ memcpy(buffer, "0x", 2);
+ memcpy(buffer+2, string, size);
+ tv = new_tarval_from_str(buffer, size+2, mode);
+ goto make_const;
+ }
+ case EXPR_LITERAL_BOOLEAN:
+ if (string[0] == 't') {
+ tv = get_mode_one(mode);
+ } else {
+ assert(string[0] == 'f');
+ tv = get_mode_null(mode);
+ }
+ goto make_const;
+ case EXPR_LITERAL_MS_NOOP:
+ tv = get_mode_null(mode);
+ goto make_const;
+ default:
+ break;
+ }
+ panic("Invalid literal kind found");
+
+make_const: ;
+ dbg_info *dbgi = get_dbg_info(&literal->base.source_position);
+ ir_node *res = new_d_Const(dbgi, tv);
+ ir_mode *mode_arith = get_ir_mode_arithmetic(type);
+ return create_conv(dbgi, res, mode_arith);
+}
+
+/*
+ * Allocate an area of size bytes aligned at alignment
+ * at a frame type.
+ */
+static ir_entity *alloc_trampoline(ir_type *frame_type, int size, unsigned alignment)
+{
+ static unsigned area_cnt = 0;
+ char buf[32];
+
+ ir_type *tp = new_type_array(1, ir_type_char);
+ set_array_bounds_int(tp, 0, 0, size);
+ set_type_alignment_bytes(tp, alignment);
+
+ snprintf(buf, sizeof(buf), "trampolin%u", area_cnt++);
+ ident *name = new_id_from_str(buf);
+ ir_entity *area = new_entity(frame_type, name, tp);
+
+ /* mark this entity as compiler generated */
+ set_entity_compiler_generated(area, 1);
+ return area;
+}
+
+/**
+ * Return a node representing a trampoline region
+ * for a given function entity.