/** * perform a function call * called from "hier11", this routine will either call the named * function, or if the supplied ptr is zero, will call the contents * of HL * @param ptr name of the function */ void callfunction(char *ptr) { int nargs; nargs = 0; blanks (); if (ptr == 0) gen_push (HL_REG); while (!streq (line + lptr, ")")) { if (endst ()) break; expression (NO); if (ptr == 0) gen_swap_stack (); gen_push (HL_REG); nargs = nargs + INTSIZE; if (!match (",")) break; } needbrack (")"); if (aflag) gnargs(nargs / INTSIZE); if (ptr) gen_call (ptr); else callstk (); stkp = gen_modify_stack (stkp + nargs); }
/** * store the specified object type in the primary register * at the address in secondary register (on the top of the stack) * @param typeobj */ void gen_put_indirect(char typeobj) { gen_pop (); if (typeobj & CCHAR) { //gen_call("ccpchar"); output_line("mov \ta,l"); output_line("stax\td"); } else { if (uflag) { output_line("shlx"); } else { gen_call("ccpint"); } } }
/** * fetch the specified object type indirect through the primary * register into the primary register * @param typeobj object type */ void gen_get_indirect(char typeobj, int reg) { if (typeobj == CCHAR) { if (reg & DE_REG) { gen_swap(); } gen_call("ccgchar"); } else if (typeobj == UCHAR) { if (reg & DE_REG) { gen_swap(); } //gen_call("cguchar"); output_line("mov \tl,m"); output_line("mvi \th,0"); } else { // int if (uflag) { if (reg & HL_REG) { gen_swap(); } output_line("lhlx"); } else { gen_call("ccgint"); } } }
void gen_list_call(cmem *b,TRASH *t,GEN_OP *o,GEN_ITEM_CALL *it,GEN_LIST_CALL *lc){ int n=rnd()%4+2; GEN_ITEM_CALL list[7]; int n_o=rnd()%(n+1); int n_i=rnd()%n; int n_c=rnd()%n; bool st=o->st; for (int i=0;i<n;i++){ if (i==n_o){ o->st=st; }else{ o->st=false; } list[i].offset=b->size; list[i].narg=rnd()%8; o->narg=list[i].narg; gen_call_op(b,t,o); } o->st=st; cmem g; init_reg_var(t); it->offset=b->size; for (int i=0;i<n;i++){ int k=rnd()%8; gen_block(&g,t,k); restore_regs(&g,t); if (n_c==i && lc){//вставляем call из аргумена for (int j=0;j<lc->count;j++){ gen_list_push(&g,t,lc->list[j].narg); _CALL_C(&g,(lc->list[j].offset)-(b->size+9+g.size+5)); int k=rnd()%8; gen_block(&g,t,k); restore_regs(&g,t); } } if ((n_i==i) && n_o==n && o->st){//между call инструкция!!! gen_op(&g,o); } gen_list_push(&g,t,list[i].narg); _CALL_C(&g,(list[i].offset)-(b->size+9+g.size+5)); } restore_regs(&g,t); GEN_CALL gc; gc.loc=t->l_size; gc.narg=it->narg; gen_call(b,&gc,&g); }
/** * multiply the primary register by the length of some variable * @param type * @param size */ void gen_multiply(int type, int size) { switch (type) { case CINT: case UINT: gen_multiply_by_two(); break; case STRUCT: gen_immediate2(); output_number(size); newline(); gen_call("ccmul"); break ; default: break; } }
void gen_call_op(cmem *b,TRASH *t,GEN_OP *o){ cmem g; init_reg_var(t); int n1=rnd()%10+3; int n2=rnd()%10+3; gen_block(&g,t,n1); if (o->st){ restore_reg(&g,t,o->reg1); restore_reg(&g,t,o->reg2); t->lc+=gen_op(&g,o); } gen_block(&g,t,n2); restore_regs(&g,t); GEN_CALL c; c.loc=t->l_size; c.narg=o->narg; gen_call(b,&c,&g); }
/** * fetch a static memory cell into the primary register * @param sym */ void gen_get_memory(SYMBOL *sym) { if ((sym->identity != POINTER) && (sym->type == CCHAR)) { output_with_tab ("lda\t"); output_string (sym->name); newline (); gen_call ("ccsxt"); } else if ((sym->identity != POINTER) && (sym->type == UCHAR)) { output_with_tab("lda\t"); output_string(sym->name); newline(); output_line("mov \tl,a"); output_line("mvi \th,#0"); } else { output_with_tab ("lhld\t"); output_string (sym->name); newline (); } }
const out_val *gen_expr_funcall(const expr *e, out_ctx *octx) { const out_val *fn_ret; if(0){ out_comment(octx, "start manual __asm__"); ICE("same"); #if 0 fprintf(cc_out[SECTION_TEXT], "%s\n", e->funcargs[0]->data_store->data.str); #endif out_comment(octx, "end manual __asm__"); }else{ /* continue with normal funcall */ const out_val *fn, **args = NULL; fn = gen_expr(e->expr, octx); if(e->funcargs){ expr **aiter; for(aiter = e->funcargs; *aiter; aiter++){ expr *earg = *aiter; const out_val *arg; /* should be of size int or larger (for integral types) * or double (for floating types) */ arg = gen_expr(earg, octx); dynarray_add(&args, arg); } } /* consumes fn and args */ fn_ret = gen_call(e->expr, NULL, fn, args, octx, &e->expr->where); dynarray_free(const out_val **, args, NULL); if(!expr_func_passable(GEN_CONST_CAST(expr *, e))) out_ctrl_end_undefined(octx); } return fn_ret; }
void jvmcodegen::gen_node(const ast::node_ptr &node) { switch (node->type) { // case ast::no_node: gen_node(node); break; case ast::integer_node: gen_integer(node); break; case ast::string_node: gen_string(node); break; case ast::if_stmt_node: gen_if_stmt(node); break; case ast::while_stmt_node: gen_while_stmt(node); break; case ast::return_stmt_node: gen_return_stmt(node); break; case ast::variable_node: gen_variable(node); break; case ast::assign_stmt_node: gen_assign_stmt(node); break; case ast::call_node: gen_call(node); break; case ast::op_arithm_node: gen_op_arithm(node); break; case ast::op_logical_node: gen_op_logical(node); break; case ast::program_node: gen_program(node); break; case ast::type_node: gen_type(node); break; case ast::argument_node: gen_argument(node); break; case ast::variable_decl_node: gen_variable_decl(node); break; case ast::function_decl_node: gen_function_decl(node); break; case ast::read_stmt_node: gen_read_stmt(node); break; case ast::write_stmt_node: gen_write_stmt(node); break; } }
/** * less than (signed) */ void gen_less_than(void) { gen_pop(); gen_call ("cclt"); }
/** * not equal */ void gen_not_equal(void) { gen_pop(); gen_call ("ccne"); }
/** * equal */ void gen_equal(void) { gen_pop(); gen_call ("cceq"); }
/** * Convert primary value into logical value (0 if 0, 1 otherwise) */ void gen_convert_primary_reg_value_to_bool(void) { gen_call ("ccbool"); }
/** * unsigned divide the secondary register by the primary * (quotient in primary, remainder in secondary) */ void gen_udiv(void) { gen_pop(); gen_call ("ccudiv"); }
/** * greater than or equal (signed) */ void gen_greater_or_equal(void) { gen_pop(); gen_call ("ccge"); }
/** * arithmetic shift left the secondary register the number of * times in the primary register (results in primary register) */ void gen_arithm_shift_left(void) { gen_pop (); gen_call ("ccasl"); }
/** * logically shift right the secondary register the number of * times in the primary register (results in primary register) */ void gen_logical_shift_right(void) { gen_pop(); gen_call ("cclsr"); }
/** * arithmetic shift right the secondary register the number of * times in the primary register (results in primary register) */ void gen_arithm_shift_right(void) { gen_pop(); gen_call ("ccasr"); }
/** * 'and' the primary and secondary registers */ void gen_and(void) { gen_pop(); gen_call ("ccand"); }
/** * exclusive 'or' the primary and secondary registers */ void gen_xor(void) { gen_pop(); gen_call ("ccxor"); }
/** * inclusive 'or' the primary and secondary registers */ void gen_or(void) { gen_pop(); gen_call ("ccor"); }
/** * less than or equal (signed) */ void gen_less_or_equal(void) { gen_pop(); gen_call ("ccle"); }
/** * greater than (signed) */ void gen_greater_than(void) { gen_pop(); gen_call ("ccgt"); }
/** * less than or equal (unsigned) */ void gen_unsigned_less_or_equal(void) { gen_pop(); gen_call ("ccule"); }
/** * less than (unsigned) */ void gen_unsigned_less_than(void) { gen_pop(); gen_call ("ccult"); }
/** * greater than or equal (unsigned) */ void gen_unsigned_greater_or_equal(void) { gen_pop(); gen_call ("ccuge"); }
/** * greater than (unsigned) */ void gen_usigned_greater_than(void) { gen_pop(); gen_call ("ccugt"); }
/** * logical complement of primary register */ void gen_logical_negation(void) { gen_call ("cclneg"); }
/** * two's complement of primary register */ void gen_twos_complement(void) { gen_call ("ccneg"); }
/** * one's complement of primary register */ void gen_complement(void) { gen_call ("cccom"); }