static void ini_reg_defs(void) { RegisterDefinition * d; regs_cnt = 0; regs_max = 800; regs_index = (RegisterDefinition *)loc_alloc_zero(sizeof(RegisterDefinition) * regs_max); for (d = regs_def; d->name != NULL; d++) { RegisterDefinition * r = alloc_reg(); assert(d->parent == NULL); *r = *d; if (strcmp(r->name, "sp") == 0) { r->role = "SP"; } else if (strcmp(r->name, "pc") == 0) { r->role = "PC"; pc_def = r; } else if (strcmp(r->name, "r0") == 0) { unsigned i; for (i = 1; i < 31; i++) { char name[64]; r = alloc_reg(); *r = *d; snprintf(name, sizeof(name), "r%d", i); r->name = loc_strdup(name); r->offset = d->offset + i * 8; r->dwarf_id = d->dwarf_id + i; r->eh_frame_id = d->eh_frame_id + i; } } } }
static inline void JIT_visit(ASTNode *node, int regs[], int reg) { switch(node->type) { case AST_BINARY_OP: { ASTBinaryOp *binary_op = (ASTBinaryOp*)node; int a_reg = alloc_reg(regs); JIT_visit(binary_op->lhs, regs, a_reg); int b_reg = alloc_reg(regs); JIT_visit(binary_op->rhs, regs, b_reg); switch(binary_op->op) { case '+': jit_addr_i(reg, a_reg, b_reg); break; case '-': jit_subr_i(reg, a_reg, b_reg); break; case '*': jit_mulr_i(reg, a_reg, b_reg); break; case '/': jit_divr_i(reg, a_reg, b_reg); break; } free_reg(regs, a_reg); free_reg(regs, b_reg); break; } case AST_INT: { jit_movi_i(reg, ((ASTInt*)node)->value); break; } } }
void emit_binop (string opcode, astree* root) { if (root->children[0]->reg == "") { postorder (root->children[0]); } //postorder (root->children[0]); root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " "; *current_string += root->reg + " = "; if (root->children[0]->reg != "") { *current_string += root->children[0]->reg; }else if (root->children[0]->attr[ATTR_null]) { *current_string += "0"; }else if (!root->children[0]->attr[ATTR_const]) { *current_string += mangle_global(root->children[0]); }else{ *current_string += *root->children[0]->lexinfo; } *current_string += " " + opcode + " "; if (root->children[1]->reg != "") { *current_string += root->children[1]->reg; }else if (root->children[1]->attr[ATTR_null]) { *current_string += "0"; }else if (!root->children[1]->attr[ATTR_const]) { *current_string += mangle_global(root->children[1]); }else{ *current_string += *root->children[1]->lexinfo; } *current_string += ";\n"; }
// We do 80% alloc and 20% alloc_region. void sim_alloc() { UInt32 rnd = tilf(0,99); if (rnd < 80) alloc_in_reg(); else alloc_reg(); }
void emit_while (astree* root) { *current_string += mangle_global (root) + ":;\n"; postorder (root->children[0]); *current_string += " "; if (root->children[0]->reg != "") { *current_string += "if(!" + root->children[0]->reg + ")"; }else if (root->children[0]->attr[ATTR_const]) { root->children[0]->reg = alloc_reg (root->children[0]); *current_string += type_reg(root->children[0]) + " " + root->children[0]->reg + " = "; *current_string += *root->children[0]->lexinfo; *current_string += ";\n "; *current_string += "if(!" + root->children[0]->reg + ")"; }else if (root->children[0]->attr[ATTR_variable]) { *current_string += "if(!" + mangle_global(root->children[0]) + ")"; } // do not print if operand *current_string += " goto break_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ";\n"; postorder (root->children[1]); *current_string += " goto while_" + to_string(root->filenr)+ "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ";\n"; *current_string += "break_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ":;\n"; }
void emit_ifelse (astree* root) { if (root->children.size() == 2) { emit_if (root); return; } postorder (root->children[0]); if (root->children[0]->attr[ATTR_const]) { root->children[0]->reg = alloc_reg (root->children[0]); *current_string += type_reg(root->children[0]) + " " + root->children[0]->reg + " = "; *current_string += *root->children[0]->lexinfo; *current_string += ";\n "; } *current_string += "if(!" + root->children[0]->reg + ")"; *current_string += " goto else_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ";\n"; postorder_stmts (root->children[1]); *current_string += " goto fi_" + to_string(root->filenr)+ "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ";\n"; *current_string += "else_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ":;\n"; postorder_stmts (root->children[2]); *current_string += "fi_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ":;\n"; }
void emit_call (astree* root) { astree* name; for (size_t i = 1; i < root->children.size(); ++ i) { emit (root->children.at(i)); } name = root->children[0]; root->reg = alloc_reg (name); *current_string += " "; if (!root->attr[ATTR_void]) { *current_string += type_reg (name) + " "; *current_string += root->reg + " = "; } *current_string += mangle_func (name) + "("; for (size_t i = 1; i < root->children.size(); ++ i) { if (root->children[i]->reg != "") { *current_string += root->children[i]->reg; }else if (!root->children[i]->attr[ATTR_const]) { *current_string += mangle_global(root->children[i]); }else{ *current_string += *root->children[i]->lexinfo; } if (i != root->children.size() - 1) *current_string += ", "; } *current_string += ");\n"; }
void emit_alloc_struct (astree* root) { root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " "; *current_string += root->reg + " = "; *current_string += "xcalloc (1, sizeof(struct " + mangle_typenm(root) + "));\n"; }
void emit_boolcon (astree* root) { root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + root->reg + " = "; if (root->symbol == TOK_TRUE) *current_string += " 1;\n"; else *current_string += " 0;\n"; }
/*get the reg descriptor of a variable or temp*/ struct reg_descriptor* get_reg(struct operand *op){ assert(op != NULL); switch(op -> type){ case OP_VAR:{ int i; for (i = 0; i < S_REG_NUM; ++i) if(operand_equal(s_reg[i].stored_op, op)) break; if(i < S_REG_NUM){ return &s_reg[i]; //find in s_reg } return alloc_reg(op); //not in register, alloc for it. } case OP_TEMP:{ int i; for (i = 0; i < T_REG_NUM - 1; ++i) if(operand_equal(t_reg[i].stored_op, op)) break; if(i < T_REG_NUM - 1){ /*after one use, the temp will be thrown out of register*/ t_reg[i].used = false; t_reg[i].stored_op = NULL; return &t_reg[i]; } return alloc_reg(op); //not in register, alloc for it. } case OP_CONST:{ fprintf(fp, "\tli %s, %d\n", t_reg[9].name, op -> value); return &t_reg[9]; } default: assert(0); } return NULL; }
void emit_unop (string operand, astree* root) { postorder (root->children[0]); root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " "; *current_string += root->reg + " = " + operand; if (root->children[0]->reg != "") { *current_string += root->children[0]->reg + ";\n"; }else if (root->children[0]->attr[ATTR_variable]) { *current_string += mangle_global (root->children[0]) + ";\n"; }else{ *current_string += *root->children[0]->lexinfo + ";\n"; } }
void emit_alloc_string (astree* root) { root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " "; *current_string += root->reg + " = "; *current_string += "xcalloc ("; if (root->children[0]->reg != "") { *current_string += root->children[0]->reg; }else if (root->children[0]->attr[ATTR_variable]) { *current_string += mangle_global (root->children[0]); }else{ *current_string += *root->children[0]->lexinfo; } *current_string += ", sizeof(char));\n"; }
/* Read back register into host side copy */ float_h fpu::read_reg(unsigned int reg) { if (reg < R0 || reg > R31) { return 0.0; } /* If register not allocated, allocate it now */ if (registers[reg].available) { alloc_reg(reg); } /* Sync the values of register */ float_h tmp_val = 0.0; int success = this->read_float(reg, tmp_val); registers[reg].value = tmp_val; return (success) ? registers[reg].value : -1; }
int comp_fini(bool status, mstr *obj, opctype retcode, oprtype *retopr, int src_len) { triple *ref; error_def(ERR_INDEXTRACHARS); if (status && source_column != src_len + 2 && source_buffer[source_column] != '\0') { status = FALSE; stx_error(ERR_INDEXTRACHARS); } if (status) { cg_phase = CGP_RESOLVE; assert(for_stack_ptr == for_stack); if (*for_stack_ptr) tnxtarg(*for_stack_ptr); ref = newtriple(retcode); if (retopr) ref->operand[0] = *retopr; start_fetches(OC_NOOP); resolve_ref(0); /* cannot fail because there are no MLAB_REF's in indirect code */ alloc_reg(); stp_gcol(0); assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; compile_time = FALSE; ind_code(obj); indr_stringpool.free = indr_stringpool.base; } else { assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; indr_stringpool.free = indr_stringpool.base; compile_time = FALSE; cg_phase = CGP_NOSTATE; } transform = TRUE; mcfree(); return status; }
void emit_field_select (astree* root) { root->reg = "*" + alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " "; *current_string += root->reg + " = &"; //oot->reg = "*" + root->reg; if (root->children[0]->reg != "") { *current_string += root->children[0]->reg; }else{ *current_string += mangle_global(root->children[0]); } *current_string += "->"; if (root->children[1]->reg != "") { *current_string += root->children[1]->reg; }else{ *current_string += mangle_global(root->children[1]); } *current_string += ";\n"; }
int JIT_evaluate(ASTNode *root) { #ifdef __APPLE__ // Mac OS X hack codeBuffer = mmap (NULL, 4096, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); #endif pifi function = (pifi) (jit_set_ip(codeBuffer).iptr); jit_leaf(1); int regs[MAX_REG] = {0}; int ret = alloc_reg(regs); JIT_visit(root, regs, ret); jit_ret(); jit_flush_code(codeBuffer, jit_get_ip().ptr); return function(); }
__bool CRegRequirementList::Alloc(struct blk_pin_t * p) { reg_item item; p->u2.mem_addr.section = ke_section_by_type(p->type); item.length = _type_size(p->type); if(!alloc_reg((void*)p, &p->u2.mem_addr, item.length, PIN_MAGIC)){ m_errcode = F8_LOW_REGISTERS; return __false; } item.blk_id = p->blk->uuid; item.pin_id = __vcall__(p->blk, id_by_pin, (p)); item.owner = p; item.addr = p->u2.mem_addr; m_rlist.insert(m_rlist.end(), item); return __true; }
void emit_alloc_array (astree* root) { //postorder (root->children[0]); //postorder (root->children[1]); root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root); cout << "type_reg is = " << type_reg (root) << endl; //if (root->attr[ATTR_vreg]) ;//*current_string += "*"; *current_string += " "; *current_string += root->reg + " = "; *current_string += "xcalloc ("; root->reg = root->reg; if (root->children[1]->reg != "") { *current_string += root->children[1]->reg; }if (root->children[1]->attr[ATTR_variable]) { *current_string += mangle_global (root->children[1]); }else{ *current_string += *root->children[1]->lexinfo; } if (root->attr[ATTR_struct]) *current_string += ", sizeof(struct "+type_reg (root) + "));\n"; else *current_string += ", sizeof(" + base (root) + "));\n"; }
void emit_index_select (astree* root) { postorder_stmts (root->children[1]); postorder_stmts (root->children[0]); root->reg = alloc_reg (root); *current_string += " "; *current_string += type_reg (root) + " *"; *current_string += root->reg + " = &"; if (root->attr[ATTR_vreg])root->reg = "*" + root->reg; if (root->children[0]->reg != "") { *current_string += root->children[0]->reg; }else{ *current_string += mangle_global(root->children[0]); } *current_string += "["; if (root->children[1]->reg != "") { *current_string += root->children[1]->reg; }else if (root->children[1]->attr[ATTR_const]) { *current_string += *root->children[1]->lexinfo; }else{ *current_string += mangle_global(root->children[1]); } *current_string += "];\n"; }
void emit_if (astree* root) { postorder_stmts (root->children[0]); if (root->children[0]->attr[ATTR_const]) { root->children[0]->reg = alloc_reg (root->children[0]); *current_string += type_reg(root->children[0]) + " " + root->children[0]->reg + " = "; *current_string += *root->children[0]->lexinfo; *current_string += ";\n "; *current_string += " if(!" + root->children[0]->reg + ")"; }else if (root->children[0]->reg != "") { *current_string += " if(!" + root->children[0]->reg + ")"; }else if (root->children[0]->attr[ATTR_variable]) { *current_string += " if(!" + mangle_global(root->children[0]) + ")"; } *current_string += " goto fi_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ";\n"; postorder_stmts (root->children[1]); *current_string += "fi_" + to_string(root->filenr) + "_" + to_string(root->linenr) + "_" + to_string(root->offset) + ":;\n"; }
void obj_code (uint4 src_lines, void *checksum_ctx) { int status; rhdtyp rhead; mline *mlx, *mly; var_tabent *vptr; int4 lnr_pad_len; intrpt_state_t prev_intrpt_state; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(!run_time); obj_init(); /* Define the routine name global symbol. */ define_symbol(GTM_MODULE_DEF_PSECT, (mstr *)&int_module_name, 0); memset(&rhead, 0, SIZEOF(rhead)); alloc_reg(); jmp_opto(); curr_addr = SIZEOF(rhdtyp); cg_phase = CGP_APPROX_ADDR; cg_phase_last = CGP_NOSTATE; code_gen(); code_size = curr_addr; cg_phase = CGP_ADDR_OPT; shrink_jmps(); comp_lits(&rhead); if ((cmd_qlf.qlf & CQ_MACHINE_CODE)) { cg_phase = CGP_ASSEMBLY; code_gen(); } if (!(cmd_qlf.qlf & CQ_OBJECT)) return; rhead.ptext_ptr = SIZEOF(rhead); set_rtnhdr_checksum(&rhead, (gtm_rtn_src_chksum_ctx *)checksum_ctx); rhead.vartab_ptr = code_size; rhead.vartab_len = mvmax; code_size += mvmax * SIZEOF(var_tabent); rhead.labtab_ptr = code_size; rhead.labtab_len = mlmax; code_size += mlmax * SIZEOF(lab_tabent); rhead.lnrtab_ptr = code_size; rhead.lnrtab_len = src_lines; rhead.compiler_qlf = cmd_qlf.qlf; if (cmd_qlf.qlf & CQ_EMBED_SOURCE) { rhead.routine_source_offset = TREF(routine_source_offset); rhead.routine_source_length = (uint4)(stringpool.free - stringpool.base) - TREF(routine_source_offset); } rhead.temp_mvals = sa_temps[TVAL_REF]; rhead.temp_size = sa_temps_offset[TCAD_REF]; code_size += src_lines * SIZEOF(int4); lnr_pad_len = PADLEN(code_size, SECTION_ALIGN_BOUNDARY); code_size += lnr_pad_len; DEFER_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); create_object_file(&rhead); ENABLE_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); cg_phase = CGP_MACHINE; code_gen(); /* Variable table: */ vptr = (var_tabent *)mcalloc(mvmax * SIZEOF(var_tabent)); if (mvartab) walktree(mvartab, cg_var, (char *)&vptr); else assert(0 == mvmax); emit_immed((char *)vptr, mvmax * SIZEOF(var_tabent)); /* Label table: */ if (mlabtab) walktree((mvar *)mlabtab, cg_lab, (char *)rhead.lnrtab_ptr); else assert(0 == mlmax); /* External entry definitions: */ emit_immed((char *)&(mline_root.externalentry->rtaddr), SIZEOF(mline_root.externalentry->rtaddr)); /* line 0 */ for (mlx = mline_root.child; mlx; mlx = mly) { if (mlx->table) emit_immed((char *)&(mlx->externalentry->rtaddr), SIZEOF(mlx->externalentry->rtaddr)); if (0 == (mly = mlx->child)) /* note assignment */ if (0 == (mly = mlx->sibling)) /* note assignment */ for (mly = mlx; ; ) { if (0 == (mly = mly->parent)) /* note assignment */ break; if (mly->sibling) { mly = mly->sibling; break; } } } if (0 != lnr_pad_len) /* emit padding so literal text pool starts on proper boundary */ emit_immed(PADCHARS, lnr_pad_len); # if !defined(__MVS__) && !defined(__s390__) /* assert not valid for instructions on OS390 */ assert(code_size == psect_use_tab[GTM_CODE]); # endif emit_literals(); DEFER_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); finish_object_file(); ENABLE_INTERRUPTS(INTRPT_IN_OBJECT_FILE_COMPILE, prev_intrpt_state); CLOSE_OBJECT_FILE(object_file_des, status); if (-1 == status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, errno); /* Ready to make object visible. Rename from tmp name to real routine name */ RENAME_TMP_OBJECT_FILE(object_file_name); }
void obj_code (uint4 src_lines, uint4 checksum) { rhdtyp rhead; mline *mlx, *mly; var_tabent *vptr; int4 lnr_pad_len; assert(!run_time); obj_init(); /* Define the routine name global symbol. */ define_symbol(GTM_MODULE_DEF_PSECT, (mstr *)&int_module_name, 0); memset(&rhead, 0, SIZEOF(rhead)); alloc_reg(); jmp_opto(); curr_addr = SIZEOF(rhdtyp); cg_phase = CGP_APPROX_ADDR; cg_phase_last = CGP_NOSTATE; code_gen(); code_size = curr_addr; cg_phase = CGP_ADDR_OPT; shrink_jmps(); comp_lits(&rhead); if ((cmd_qlf.qlf & CQ_MACHINE_CODE)) { cg_phase = CGP_ASSEMBLY; code_gen(); } if (!(cmd_qlf.qlf & CQ_OBJECT)) return; rhead.ptext_ptr = SIZEOF(rhead); rhead.checksum = checksum; rhead.vartab_ptr = code_size; rhead.vartab_len = mvmax; code_size += mvmax * SIZEOF(var_tabent); rhead.labtab_ptr = code_size; rhead.labtab_len = mlmax; code_size += mlmax * SIZEOF(lab_tabent); rhead.lnrtab_ptr = code_size; rhead.lnrtab_len = src_lines; rhead.compiler_qlf = cmd_qlf.qlf; rhead.temp_mvals = sa_temps[TVAL_REF]; rhead.temp_size = sa_temps_offset[TCAD_REF]; code_size += src_lines * SIZEOF(int4); lnr_pad_len = PADLEN(code_size, SECTION_ALIGN_BOUNDARY); code_size += lnr_pad_len; create_object_file(&rhead); cg_phase = CGP_MACHINE; code_gen(); /* Variable table: */ vptr = (var_tabent *)mcalloc(mvmax * SIZEOF(var_tabent)); if (mvartab) walktree(mvartab, cg_var, (char *)&vptr); else assert(0 == mvmax); emit_immed((char *)vptr, mvmax * SIZEOF(var_tabent)); /* Label table: */ if (mlabtab) walktree((mvar *)mlabtab, cg_lab, (char *)rhead.lnrtab_ptr); else assert(0 == mlmax); /* External entry definitions: */ emit_immed((char *)&(mline_root.externalentry->rtaddr), SIZEOF(mline_root.externalentry->rtaddr)); /* line 0 */ for (mlx = mline_root.child; mlx; mlx = mly) { if (mlx->table) emit_immed((char *)&(mlx->externalentry->rtaddr), SIZEOF(mlx->externalentry->rtaddr)); if (0 == (mly = mlx->child)) /* note assignment */ if (0 == (mly = mlx->sibling)) /* note assignment */ for (mly = mlx; ; ) { if (0 == (mly = mly->parent)) /* note assignment */ break; if (mly->sibling) { mly = mly->sibling; break; } } } if (0 != lnr_pad_len) /* emit padding so literal text pool starts on proper boundary */ emit_immed(PADCHARS, lnr_pad_len); #if !defined(__MVS__) && !defined(__s390__) /* assert not valid for instructions on OS390 */ assert(code_size == psect_use_tab[GTM_CODE]); #endif emit_literals(); close_object_file(); }
int comp_fini(int status, mstr *obj, opctype retcode, oprtype *retopr, oprtype *dst, mstr_len_t src_len) { triple *ref; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (status) { while (TK_SPACE == TREF(window_token)) /* Eat up trailing white space */ advancewindow(); if (TK_ERROR == TREF(window_token)) { status = EXPR_FAIL; stx_error(ERR_INDRCOMPFAIL); } else if ((TK_EOL != TREF(window_token)) || (source_column < src_len)) { status = EXPR_FAIL; stx_error(ERR_INDEXTRACHARS); } else { cg_phase = CGP_RESOLVE; assert(TREF(for_stack_ptr) == TADR(for_stack)); if (*TREF(for_stack_ptr)) tnxtarg(*TREF(for_stack_ptr)); ref = newtriple(retcode); if (retopr) ref->operand[0] = *retopr; if (OC_IRETMVAL == retcode) ref->operand[1] = *dst; start_fetches(OC_NOOP); resolve_ref(0); /* cannot fail because there are no MLAB_REF's in indirect code */ alloc_reg(); INVOKE_STP_GCOL(0); /* The above invocation of stp_gcol with a parameter of 0 is a critical part of compilation * (both routine compilations and indirect dynamic compilations). This collapses the indirect * (compilation) stringpool so that only the literals are left. This stringpool is then written * out to the compiled object as the literal pool for that compilation. Temporary stringpool * use for conversions or whatever are eliminated. Note the path is different in stp_gcol for * the indirect stringpool which is only used during compilations. */ assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; TREF(compile_time) = FALSE; ind_code(obj); indr_stringpool.free = indr_stringpool.base; } } else { /* If this assert fails, it means a syntax problem could have been caught earlier. Consider placing a more useful * and specific error message at that location. */ assert(FALSE); stx_error(ERR_INDRCOMPFAIL); } if (EXPR_FAIL == status) { assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; indr_stringpool.free = indr_stringpool.base; TREF(compile_time) = FALSE; cg_phase = CGP_NOSTATE; } TREF(transform) = TRUE; COMPILE_HASHTAB_CLEANUP; mcfree(); return status; }
void prefix_strcon (astree* root) { root->reg = alloc_reg(root); *strcon_prefix += "char* " + root->reg; *strcon_prefix += " = " + *root->lexinfo + ";\n"; }