コード例 #1
0
ファイル: compile.c プロジェクト: tinkertim/slash
NODE(sl_node_def_t, def)
{
    sl_vm_insn_t insn;
    sl_compile_state_t sub_cs;
    size_t i, on_reg;
    init_compile_state(&sub_cs, cs->vm, cs, node->req_arg_count + node->opt_arg_count + 1);
    for(i = 0; i < node->req_arg_count; i++) {
        st_insert(sub_cs.vars, (st_data_t)node->req_args[i], (st_data_t)(i + 1));
    }
    for(i = 0; i < node->opt_arg_count; i++) {
        st_insert(sub_cs.vars, (st_data_t)node->opt_args[i].name, (st_data_t)(node->req_arg_count + i + 1));
    }
    sub_cs.section->name = node->name;
    sub_cs.section->req_registers = node->req_arg_count;
    sub_cs.section->arg_registers = node->req_arg_count + node->opt_arg_count;
    sub_cs.section->opt_skip = sl_alloc(cs->vm->arena, sizeof(size_t) * (node->opt_arg_count + 1));
    
    for(i = 0; i < node->opt_arg_count; i++) {
        sub_cs.section->opt_skip[i] = sub_cs.section->insns_count;
        compile_node(&sub_cs, node->opt_args[i].default_value, node->req_arg_count + i + 1);
    }
    sub_cs.section->opt_skip[node->opt_arg_count] = sub_cs.section->insns_count;
    
    compile_node(&sub_cs, node->body, 0);
    insn.opcode = SL_OP_RETURN;
    emit(&sub_cs, insn);
    insn.uint = 0;
    emit(&sub_cs, insn);
    
    if(node->on) {
        on_reg = reg_alloc(cs);
        compile_node(cs, node->on, on_reg);
        insn.opcode = SL_OP_DEFINE_ON;
        emit(cs, insn);
        insn.uint = on_reg;
        emit(cs, insn);
        reg_free(cs, on_reg);
    } else {
        insn.opcode = SL_OP_DEFINE;
        emit(cs, insn);
    }
    insn.imm = node->name;
    emit(cs, insn);
    insn.section = sub_cs.section;
    emit(cs, insn);
    insn.uint = dest;
    emit(cs, insn);
}
コード例 #2
0
ファイル: compile.c プロジェクト: Hmaal/slash
static void
emit_assignment(sl_compile_state_t* cs, sl_node_base_t* lval, size_t reg)
{
    sl_node_assign_var_t a_var;
    sl_node_send_t send;

    size_t dest_reg = reg_alloc(cs);

    sl_node__register_t node;
    node.base.type = SL_NODE__REGISTER;
    node.base.line = 0;
    node.reg = reg;

    switch(lval->type) {
        case SL_NODE_VAR:    a_var.base.type = SL_NODE_ASSIGN_VAR;    break;
        case SL_NODE_IVAR:   a_var.base.type = SL_NODE_ASSIGN_IVAR;   break;
        case SL_NODE_CVAR:   a_var.base.type = SL_NODE_ASSIGN_CVAR;   break;
        case SL_NODE_CONST:  a_var.base.type = SL_NODE_ASSIGN_CONST;  break;
        case SL_NODE_ARRAY:  a_var.base.type = SL_NODE_ASSIGN_ARRAY;  break;
        case SL_NODE_SEND:
            /* special case that turns a.b = 1 into a.send("b=", 1) */
            /* this is separate to the other method of handling send assignments
               which also handles compound assignments. */
            memcpy(&send, lval, sizeof(sl_node_send_t));
            send.id = sl_id_make_setter(cs->vm, send.id);
            sl_node_base_t** args = sl_alloc(cs->vm->arena, sizeof(sl_node_base_t*) * (send.arg_count + 1));
            memcpy(args, send.args, sizeof(sl_node_base_t*) * send.arg_count);
            args[send.arg_count++] = (sl_node_base_t*)&node;
            send.args = args;
            compile_node(cs, (sl_node_base_t*)&send, dest_reg);
            reg_free(cs, dest_reg);
            return;
        default: {
            SLVAL err = sl_make_cstring(cs->vm, "Invalid lval in assignment");
            err = sl_make_error2(cs->vm, cs->vm->lib.SyntaxError, err);
            sl_error_add_frame(cs->vm, err, sl_make_cstring(cs->vm, "<compiler>"), sl_make_cstring(cs->vm, (char*)cs->section->filename), sl_make_int(cs->vm, lval->line));
            sl_throw(cs->vm, err);
        }
    }

    a_var.base.line = 0;
    a_var.lval = (void*)lval;
    a_var.rval = (sl_node_base_t*)&node;
    compile_node(cs, (sl_node_base_t*)&a_var, dest_reg);

    reg_free(cs, dest_reg);
}
コード例 #3
0
ファイル: reg_alloc.c プロジェクト: scrossuk/ancient-code
void reg_alloc(rd_instr * code,
	rd_vlist * vlist,
	rd_vlist * mem_list,
	unsigned int reg_offset,
	unsigned int reg_num,
	unsigned int match_types,
	unsigned int assign_type){

	rga_reg_offset = reg_offset;
	num_registers = reg_num;
	rga_match_types = match_types;

	flow_graph * graph = flow_generate_graph(code, vlist, reg_offset, reg_num, match_types);
	initialise(vlist, reg_num);
	build(graph);
	#ifdef DEBUG_MODE
	debug();
	#endif
	make_worklist();
	while(true){
		if(!rga_node_list_isempty(simplifyWorklist)){
			simplify();
		}else if(!rga_move_list_isempty(worklistMoves)){
			coalesce();
		}else if(!rga_node_list_isempty(freezeWorklist)){
			freeze();
		}else if(!rga_node_list_isempty(spillWorklist)){
			select_spill();
		}else{
			break;
		}
	}
	assign_colours();
	if(!rga_node_list_isempty(spilledNodes)){
		rewrite_program(graph, vlist, mem_list);
		#ifdef DEBUG_MODE
		rdgen_show();
		#endif
		clean_up();
		reg_alloc(code, vlist, mem_list, reg_offset, reg_num, match_types, assign_type);
	}else{
		assign_registers(vlist, assign_type);	
		clean_up();
	}
}
コード例 #4
0
ファイル: compile.c プロジェクト: Hmaal/slash
NODE(sl_node_def_t, def)
{
    sl_compile_state_t sub_cs;
    size_t i, on_reg;
    size_t init_regs = 1 + node->req_arg_count + node->opt_arg_count;
    if(node->rest_arg) {
        init_regs++;
    }
    init_compile_state(&sub_cs, cs->vm, cs, init_regs);
    for(i = 0; i < node->req_arg_count; i++) {
        sl_st_insert(sub_cs.vars, (sl_st_data_t)node->req_args[i], (sl_st_data_t)(i + 1));
    }
    for(i = 0; i < node->opt_arg_count; i++) {
        sl_st_insert(sub_cs.vars, (sl_st_data_t)node->opt_args[i].name, (sl_st_data_t)(node->req_arg_count + i + 1));
    }
    if(node->rest_arg) {
        sl_st_insert(sub_cs.vars, (sl_st_data_t)node->rest_arg, (sl_st_data_t)(node->req_arg_count + node->opt_arg_count + 1));
        sub_cs.section->has_extra_rest_arg = 1;
    }
    sub_cs.section->name = node->name;
    sub_cs.section->req_registers = node->req_arg_count;
    sub_cs.section->arg_registers = node->req_arg_count + node->opt_arg_count;
    sub_cs.section->opt_skip = sl_alloc(cs->vm->arena, sizeof(size_t) * (node->opt_arg_count + 1));

    for(i = 0; i < node->opt_arg_count; i++) {
        sub_cs.section->opt_skip[i] = sub_cs.section->insns_count;
        compile_node(&sub_cs, node->opt_args[i].default_value, node->req_arg_count + i + 1);
    }
    sub_cs.section->opt_skip[node->opt_arg_count] = sub_cs.section->insns_count;

    compile_node(&sub_cs, node->body, 0);
    op_return(&sub_cs, 0);

    if(node->on) {
        on_reg = reg_alloc(cs);
        compile_node(cs, node->on, on_reg);
        op_define_on(cs, on_reg, node->name, node->doc, sub_cs.section, dest);
        reg_free(cs, on_reg);
    } else {
        op_define(cs, node->name, node->doc, sub_cs.section, dest);
    }
}
コード例 #5
0
ファイル: genir.c プロジェクト: doremi/dcc
void gen_mov_code(int num)
{
	int reg = reg_alloc();  /* need argument? */
    printf("mov r%d, #%d\n", reg, num);
}