Exemplo n.º 1
0
static ir_tarval *fold_binary_sub(binary_expression_t const *const binexpr)
{
	ir_tarval *const l        = fold_expression(binexpr->left);
	ir_tarval *const r        = fold_expression(binexpr->right);
	type_t    *const type     = skip_typeref(binexpr->base.type);
	ir_mode   *const res_mode = get_ir_mode_arithmetic(type);
	type_t    *const typel    = skip_typeref(binexpr->left->base.type);
	if (is_type_pointer(typel)) {
		type_t *const elem  = skip_typeref(typel->pointer.points_to);
		type_t *const typer = skip_typeref(binexpr->right->base.type);
		if (is_type_pointer(typer)) {
			ir_tarval *const size = get_type_size_tarval(elem, res_mode);
			ir_tarval *const diff = tarval_sub(l, r);
			return tarval_div(diff, size);
		} else {
			ir_mode   *const mode = get_tarval_mode(r);
			ir_tarval *const size = get_type_size_tarval(elem, mode);
			ir_tarval *const rr   = tarval_mul(r, size);
			return tarval_sub(l, rr);
		}
	} else {
		ir_tarval *const conv_l = tarval_convert_to(l, res_mode);
		ir_tarval *const conv_r = tarval_convert_to(r, res_mode);
		return tarval_sub(conv_l, conv_r);
	}
}
Exemplo n.º 2
0
static ir_tarval *fold_binary_add(binary_expression_t const *const binexpr)
{
	ir_tarval *const l     = fold_expression(binexpr->left);
	ir_tarval *const r     = fold_expression(binexpr->right);
	ir_tarval       *ll    = l;
	ir_tarval       *rr    = r;
	type_t    *const typel = skip_typeref(binexpr->left->base.type);
	type_t    *const typer = skip_typeref(binexpr->right->base.type);
	if (is_type_pointer(typel)) {
		type_t    *const elem = skip_typeref(typel->pointer.points_to);
		ir_mode   *const mode = get_ir_mode_arithmetic(typer);
		ir_tarval *const size = get_type_size_tarval(elem, mode);
		rr = tarval_mul(rr, size);
	} else if (is_type_pointer(typer)) {
		type_t    *const elem = skip_typeref(typer->pointer.points_to);
		ir_mode   *const mode = get_ir_mode_arithmetic(typel);
		ir_tarval *const size = get_type_size_tarval(elem, mode);
		ll = tarval_mul(ll, size);
	} else {
		type_t  *const type = skip_typeref(binexpr->base.type);
		ir_mode *const mode = get_ir_mode_arithmetic(type);
		ll = tarval_convert_to(l, mode);
		rr = tarval_convert_to(r, mode);
	}
	return tarval_add(ll, rr);
}
Exemplo n.º 3
0
static ir_tarval *fold_expression_to_address(expression_t const *const expr)
{
	switch (expr->kind) {
	case EXPR_SELECT: {
		select_expression_t const *const sel = &expr->select;
		type_t    *const type        = skip_typeref(sel->compound->base.type);
		ir_tarval *const base_addr   = is_type_pointer(type) ? fold_expression(sel->compound) : fold_expression_to_address(sel->compound);
		ir_mode   *const mode        = get_tarval_mode(base_addr);
		ir_mode   *const mode_offset = get_reference_offset_mode(mode);
		ir_tarval *const offset      = new_tarval_from_long(sel->compound_entry->compound_member.offset, mode_offset);
		return tarval_add(base_addr, offset);
	}

	case EXPR_ARRAY_ACCESS: {
		ir_tarval *const base_addr = fold_expression_to_address(expr->array_access.array_ref);
		ir_tarval *const idx       = fold_expression(expr->array_access.index);
		ir_mode   *const mode      = get_ir_mode_arithmetic(type_size_t);
		ir_tarval *const idx_conv  = tarval_convert_to(idx, mode);
		type_t    *const elem_type = skip_typeref(expr->array_access.array_ref->base.type);
		ir_tarval *const elem_size = get_type_size_tarval(elem_type, mode);
		return tarval_add(base_addr, tarval_mul(idx_conv, elem_size));
	}

	case EXPR_UNARY_DEREFERENCE:
		return fold_expression(expr->unary.value);

	default:
		panic("unexpected expression kind");
	}
}
Exemplo n.º 4
0
static unsigned get_address_alignment(expression_t const *const expr)
{
	if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) {
		return get_object_alignment(expr->unary.value);
	} else {
		type_t *const type = skip_typeref(expr->base.type);
		assert(is_type_pointer(type));
		return get_type_alignment(type->pointer.points_to);
	}
}
Exemplo n.º 5
0
type_t *handle_attribute_mode(const attribute_t *attribute, type_t *orig_type)
{
	type_t *type = skip_typeref(orig_type);

	/* at least: byte, word, pointer, list of machine modes
	 * __XXX___ is interpreted as XXX */

	/* This isn't really correct, the backend should provide a list of machine
	 * specific modes (according to gcc philosophy that is...) */
	attribute_argument_t *arg = attribute->a.arguments;
	if (arg == NULL) {
		errorf(&attribute->pos, "__attribute__((mode(X))) misses argument");
		return orig_type;
	}

	const char         *symbol_str = arg->v.symbol->string;
	bool                sign       = is_type_signed(type);
	atomic_type_kind_t  akind;
	if (streq_underscore("QI",   symbol_str) ||
	    streq_underscore("byte", symbol_str)) {
		akind = sign ? ATOMIC_TYPE_CHAR : ATOMIC_TYPE_UCHAR;
	} else if (streq_underscore("HI", symbol_str)) {
		akind = sign ? ATOMIC_TYPE_SHORT : ATOMIC_TYPE_USHORT;
	} else if (streq_underscore("SI",      symbol_str)
	        || streq_underscore("word",    symbol_str)
	        || streq_underscore("pointer", symbol_str)) {
		akind = sign ? ATOMIC_TYPE_INT : ATOMIC_TYPE_UINT;
	} else if (streq_underscore("DI", symbol_str)) {
		akind = sign ? ATOMIC_TYPE_LONGLONG : ATOMIC_TYPE_ULONGLONG;
	} else {
		warningf(WARN_OTHER, &attribute->pos, "ignoring unknown mode '%s'",
		         symbol_str);
		return orig_type;
	}

	if (type->kind == TYPE_ATOMIC || type->kind == TYPE_ENUM) {
		type_t *copy       = duplicate_type(type);
		copy->atomic.akind = akind;
		return identify_new_type(copy);
	} else if (is_type_pointer(type)) {
		warningf(WARN_OTHER, &attribute->pos, "__attribute__((mode)) on pointers not implemented yet (ignored)");
		return type;
	}

	errorf(&attribute->pos,
	       "__attribute__((mode)) only allowed on integer, enum or pointer type");
	return orig_type;
}
Exemplo n.º 6
0
static void write_pointer_type(const pointer_type_t *type)
{
	type_t *orig_points_to = type->points_to;
	type_t *points_to      = skip_typeref(type->points_to);
	if (is_type_atomic(points_to, ATOMIC_TYPE_CHAR)
	    && orig_points_to->kind != TYPE_TYPEDEF) {
		fputs("String", out);
		return;
	}
	if (is_type_pointer(points_to)) {
		/* hack... */
		fputs("java.nio.Buffer", out);
		return;
	}
	fputs("Pointer", out);
}
Exemplo n.º 7
0
static ir_tarval *fold_call_builtin(call_expression_t const *const call)
{
	expression_t const *const function = call->function;
	assert(function->kind == EXPR_REFERENCE);
	reference_expression_t const *const ref = &function->reference;
	assert(ref->entity->kind == ENTITY_FUNCTION);

	type_t *expr_type = skip_typeref(ref->base.type);
	assert(is_type_pointer(expr_type));
	type_t *function_type = skip_typeref(expr_type->pointer.points_to);
	assert(is_type_function(function_type));

	switch (ref->entity->function.btk) {
	case BUILTIN_INF: return fold_builtin_inf(function_type);
	case BUILTIN_NAN: return fold_builtin_nan(call, function_type);
	default:
		panic("builtin is no constant");
	}
}