Esempio n. 1
0
unsigned get_type_size(type_t const *const type)
{
	switch (type->kind) {
	case TYPE_ERROR:
		return 0;
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_ENUM:
		return get_atomic_type_size(type->atomic.akind);
	case TYPE_COMPLEX:
		return get_atomic_type_size(type->atomic.akind) * 2;
	case TYPE_COMPOUND_STRUCT:
	case TYPE_COMPOUND_UNION:
		return type->compound.compound->size;
	case TYPE_FUNCTION:
	case TYPE_VOID:
		return 1; /* GCC extension. */
	case TYPE_REFERENCE:
	case TYPE_POINTER:
		return pointer_properties.size;
	case TYPE_ARRAY: {
		/* TODO: correct if element_type is aligned? */
		il_size_t element_size = get_type_size(type->array.element_type);
		return type->array.size * element_size;
	}
	case TYPE_TYPEDEF:
		return get_type_size(type->typedeft.typedefe->type);
	case TYPE_TYPEOF:
		return get_type_size(type->typeoft.typeof_type);
	case TYPE_BUILTIN_TEMPLATE:
		break;
	}
	panic("invalid type");
}
Esempio n. 2
0
unsigned get_type_size(type_t *type)
{
	switch (type->kind) {
	case TYPE_ERROR:
		return 0;
	case TYPE_ATOMIC:
	case TYPE_IMAGINARY:
	case TYPE_ENUM:
		return get_atomic_type_size(type->atomic.akind);
	case TYPE_COMPLEX:
		return get_atomic_type_size(type->atomic.akind) * 2;
	case TYPE_COMPOUND_UNION:
		layout_union_type(&type->compound);
		return type->compound.compound->size;
	case TYPE_COMPOUND_STRUCT:
		layout_struct_type(&type->compound);
		return type->compound.compound->size;
	case TYPE_FUNCTION:
		return 0; /* non-const (but "address-const") */
	case TYPE_REFERENCE:
	case TYPE_POINTER:
		return pointer_properties.size;
	case TYPE_ARRAY: {
		/* TODO: correct if element_type is aligned? */
		il_size_t element_size = get_type_size(type->array.element_type);
		return type->array.size * element_size;
	}
	case TYPE_TYPEDEF:
		return get_type_size(type->typedeft.typedefe->type);
	case TYPE_TYPEOF:
		return get_type_size(type->typeoft.typeof_type);
	}
	panic("invalid type in get_type_size");
}
Esempio n. 3
0
/**
 * Find the atomic type kind representing a given size (signed).
 */
atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size)
{
	static const atomic_type_kind_t possible_kinds[] = {
		ATOMIC_TYPE_UCHAR,
		ATOMIC_TYPE_USHORT,
		ATOMIC_TYPE_UINT,
		ATOMIC_TYPE_ULONG,
		ATOMIC_TYPE_ULONGLONG
	};
	for (size_t i = 0; i < ARRAY_SIZE(possible_kinds); ++i) {
		if (get_atomic_type_size(possible_kinds[i]) == size) {
			return possible_kinds[i];
		}
	}
	panic("couldn't find atomic type");
}
Esempio n. 4
0
/**
 * Find the atomic type kind representing a given size (signed).
 */
atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size)
{
	static atomic_type_kind_t kinds[32];

	assert(size < 32);
	atomic_type_kind_t kind = kinds[size];
	if (kind == ATOMIC_TYPE_INVALID) {
		static const atomic_type_kind_t possible_kinds[] = {
			ATOMIC_TYPE_UCHAR,
			ATOMIC_TYPE_USHORT,
			ATOMIC_TYPE_UINT,
			ATOMIC_TYPE_ULONG,
			ATOMIC_TYPE_ULONGLONG
		};
		for (size_t i = 0; i < lengthof(possible_kinds); ++i) {
			if (get_atomic_type_size(possible_kinds[i]) == size) {
				kind = possible_kinds[i];
				break;
			}
		}
		kinds[size] = kind;
	}
	return kind;
}
Esempio n. 5
0
static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
{
	unsigned flags = get_atomic_type_flags(kind);
	unsigned size  = get_atomic_type_size(kind);
	if (flags & ATOMIC_TYPE_FLAG_FLOAT) {
		if (kind == ATOMIC_TYPE_LONG_DOUBLE
		 && dialect.long_double_x87_80bit_float) {
			assert(size == 12 || size == 16);
			return new_float_mode("F80", irma_x86_extended_float, 15, 64,
			                      target.float_int_overflow);
		}
		switch (size) {
		case 4:
			return new_float_mode("F32", irma_ieee754, 8, 23,
			                      target.float_int_overflow);
		case 8:
			return new_float_mode("F64", irma_ieee754, 11, 52,
			                      target.float_int_overflow);
		case 16:
			return new_float_mode("F128", irma_ieee754, 15, 112,
			                      target.float_int_overflow);
		default: panic("unexpected kind");
		}
	} else if (flags & ATOMIC_TYPE_FLAG_INTEGER) {
		char            name[64];
		unsigned        bit_size     = size * 8;
		bool            is_signed    = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0;
		unsigned        modulo_shift = decide_modulo_shift(bit_size);

		snprintf(name, sizeof(name), "%s%u", is_signed ? "I" : "U", bit_size);
		return new_int_mode(name, irma_twos_complement, bit_size, is_signed,
		                    modulo_shift);
	}

	return NULL;
}