Exemplo n.º 1
0
/**
 * Perform some fixups for variadic functions.
 * To make the rest of the frontend code easier to understand we add
 * "dummy" parameters until the number of parameters transmitted in registers.
 * (because otherwise the backend wouldn't store the value of the register
 *  parameters into memory for the VLA magic)
 */
static bool sparc_variadic_fixups(ir_graph *const irg, calling_convention_t *const cconv)
{
	ir_entity *entity = get_irg_entity(irg);
	ir_type   *mtp    = get_entity_type(entity);
	if (!is_method_variadic(mtp))
		return false;

	if (cconv->n_param_regs >= SPARC_N_PARAM_REGS)
		return false;

	size_t                    const n_params     = get_method_n_params(mtp);
	size_t                    const n_ress       = get_method_n_ress(mtp);
	size_t                    const new_n_params = n_params + (SPARC_N_PARAM_REGS - cconv->n_param_regs);
	unsigned                  const cc_mask      = get_method_calling_convention(mtp);
	mtp_additional_properties const props        = get_method_additional_properties(mtp);
	ir_type                  *const new_mtp      = new_type_method(new_n_params, n_ress, true, cc_mask, props);

	type_dbg_info *const dbgi = get_type_dbg_info(mtp);
	set_type_dbg_info(new_mtp, dbgi);

	for (size_t i = 0; i < n_ress; ++i) {
		ir_type *type = get_method_res_type(mtp, i);
		set_method_res_type(new_mtp, i, type);
	}
	for (size_t i = 0; i < n_params; ++i) {
		ir_type *type = get_method_param_type(mtp, i);
		set_method_param_type(new_mtp, i, type);
	}
	ir_type *const frame_type  = get_irg_frame_type(irg);
	ir_mode *const gp_reg_mode = sparc_reg_classes[CLASS_sparc_gp].mode;
	ir_type *const gp_reg_type = get_type_for_mode(gp_reg_mode);
	for (size_t i = n_params; i < new_n_params; ++i) {
		set_method_param_type(new_mtp, i, gp_reg_type);
		new_parameter_entity(frame_type, i, gp_reg_type);
	}

	set_entity_type(entity, new_mtp);
	return true;
}
Exemplo n.º 2
0
void gcji_setup_rtti_entity(class_t *cls, ir_type *type)
{
	ir_entity *rtti_entity = oo_get_class_rtti_entity(type);
	assert(type_java_lang_class != NULL);
	set_entity_type(rtti_entity, type_java_lang_class);

	ir_entity *name_ent = gcji_emit_utf8_const(
			cls->constants[cls->constants[cls->this_class]->classref.name_index], 1);

	uint16_t   accflags     = cls->access_flags;
	ir_entity *method_table = emit_method_table(type);
	ir_entity *field_table  = emit_field_table(type);

	ir_graph *ccode = get_const_code_irg();
	ir_node  *size_in_bytes	= new_r_Size(ccode, mode_int, type);

	int16_t field_count = cls->n_fields;
	int16_t static_field_count = 0;
	for (int16_t i = 0; i < field_count; i++) {
		if ((cls->fields[i]->access_flags & ACCESS_FLAG_STATIC) != 0)
			++static_field_count;
	}

	ir_entity *superclass_rtti = NULL;
	if (get_class_n_supertypes(type) > 0) {
		ir_type *superclass = get_class_supertype(type, 0);
		/* TODO: search for first non-interface instead of taking the
		 * first one and hoping it is a non-interface */
		assert(!oo_get_class_is_interface(superclass));

		superclass_rtti = gcji_get_rtti_entity(superclass);
	}

	ir_node *vtable_init = get_vtable_ref(type);

	int16_t interface_count = cls->n_interfaces;
	ir_entity *interfaces = emit_interface_table(type);

	// w/o slots 0=rtti. see lower_oo.c
	int16_t vtable_method_count = oo_get_class_vtable_size(type)
		- (ddispatch_get_index_of_first_method() - ddispatch_get_vptr_points_to_index());

	ir_node *class_vtable = get_vtable_ref(type_java_lang_class);

	/* initializer for base class java.lang.Object */
	ir_initializer_t *base_init = create_initializer_compound(1);
	set_compound_init_node(base_init, 0, class_vtable);

	/* initializer for java.lang.Class */
	unsigned NUM_FIELDS = 39;
	ir_initializer_t *init = create_initializer_compound(NUM_FIELDS);
	size_t f = 0;
	set_initializer_compound_value(init, f++, base_init);
	set_compound_init_num(init, f++, mode_P, 407000);
	set_compound_init_entref(init, f++, name_ent);
	set_compound_init_num(init, f++, mode_ushort, accflags);
	set_compound_init_entref(init, f++, superclass_rtti);
	// _Jv_Constants inlined. not sure if this is needed for compiled code.
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);

	set_compound_init_entref(init, f++, method_table);
	set_compound_init_num(init, f++, mode_short, cls->n_methods);
	set_compound_init_num(init, f++, mode_short, vtable_method_count);

	set_compound_init_entref(init, f++, field_table);
	set_compound_init_node(init, f++, size_in_bytes);
	set_compound_init_num(init, f++, mode_short, field_count);
	set_compound_init_num(init, f++, mode_short, static_field_count);
	set_compound_init_node(init, f++, vtable_init);

	// most of the following fields are set at runtime during the class linking.
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);

	set_compound_init_entref(init, f++, interfaces);
	set_compound_init_null(init, f++);
	set_compound_init_num(init, f++, mode_short, interface_count);

	set_compound_init_num(init, f++, mode_byte, 1); // state

	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++);
	set_compound_init_null(init, f++); // engine
	set_compound_init_null(init, f++);
	assert(f == NUM_FIELDS);

	set_entity_initializer(rtti_entity, init);
	set_entity_alignment(rtti_entity, 32);

	add_pointer_in_jcr_segment(rtti_entity);
}