示例#1
0
int main(int argc, char* argv[]){

	int pos = 5;
	int val = 3;

	generate_function("my_func", SIZE, pos, val);

	return 0;

}
示例#2
0
void
generate ( node_t *root )
{
    if ( root == NULL )
        return;
    switch ( root->type )
    {
        case PROGRAM_N:
			//Generate data head
			printf(DATA_HEAD);
			//Generate unique labels for strings
			generate_data_segment(root);
			//Create an entry point
			printf(TEXT_HEAD, root->children[0]->children[0]->entry->label );
		
			for (int i=0; i<root->n_children; i++ )
			{
       			generate(root->children[i]);
			}
			
            break;
        case FUNCTION_LIST_N:
;
			for (int i=0; i<root->n_children; i++ )
			{
       			generate(root->children[i]);
			}
            break;
        case FUNCTION_N:
			generate_function(root);
			generate(root->children[2]);

            break;
        case BLOCK_N:
			for (int i=0; i<root->n_children; i++ )
			{
       			generate(root->children[i]);
			}
            break;
        case DECLARATION_LIST_N:
			for (int i=0; i<root->n_children; i++ )
			{
       			generate(root->children[i]);
			}
            break;
        case DECLARATION_N:
			generate_declaration(root);
            break;
        case STATEMENT_LIST_N:
			for (int i=0; i<root->n_children; i++ )
			{
       			generate(root->children[i]);
			}
            break;
        case ASSIGNMENT_STATEMENT_N:
			assign_bound_name(root);
            break;
        case RETURN_STATEMENT_N:
			//The result is also an expression
			generate_expression(root->children[0]);
			printf("\t pushl %%eax \t /*Push of the final result*/\n");
			printf("\t ret \t /*Return control*/\n");
            break;
        case PRINT_STATEMENT_N:
            break;
        case NULL_STATEMENT_N:
            /* A proper implementation of the CONTINUE statement is more
             * trouble than it is worth at this point; since it is not the
             * most central of features, we skip it.
             * (Of course, if you really want to make one...)
             */
            printf ( "\t/* CONTINUE */\n" );
            break;
        case IF_STATEMENT_N:
            break;
        case WHILE_STATEMENT_N:
            break;
							  
        case EXPRESSION_N:
        case INTEGER_N:
        case VARIABLE_N:
			generate_expression(root);
            break;
							  
        default:
            fprintf ( stderr, "Warning: did not generate assembly for '%s'\n", root->type);
            break;

    }
	
}
示例#3
0
文件: generate.c 项目: bearlang/cub
static code_block *generate_block(code_block *parent, block_statement *block,
    block_iter iter, void *iter_data) {
  for (symbol_entry *c = block->class_head; c; c = c->next) {
    generate_class_stub(parent->system, c->classtype);
  }

  for (symbol_entry *f = block->function_head; f; f = f->next) {
    generate_function_stub(parent->system, f->function);
  }

  for (symbol_entry *c = block->class_head; c; c = c->next) {
    generate_class(parent->system, c->classtype);
  }

  for (symbol_entry *f = block->function_head; f; f = f->next) {
    generate_function(parent->system, f->function);
  }

  for (statement *node = block->body; node; node = node->next) {
    switch (node->type) {
    case S_BLOCK: {
      code_block *body = fork_block(parent);
      body = generate_block(body, (block_statement*) node, NULL, NULL);
      parent = rejoin_block(parent, body);
    } break;
    case S_BREAK:
    case S_CONTINUE:
      generate_control(parent, (control_statement*) node);
      parent = NULL;
      break;
    case S_DEFINE:
      parent = generate_define(parent, (define_statement*) node);
      break;
    case S_LET:
      parent = generate_let(parent, (let_statement*) node);
      break;
    case S_DO_WHILE:
    case S_WHILE:
      parent = generate_loop(parent, (loop_statement*) node);
      break;
    case S_EXPRESSION: {
      expression_statement *express = (expression_statement*) node;
      parent = generate_expression(parent, express->value);
    } break;
    case S_IF:
      parent = generate_if(parent, (if_statement*) node);
      break;
    case S_RETURN:
      generate_return(parent, (return_statement*) node);
      parent = NULL;
      break;
    // already processed
    case S_CLASS:
    case S_FUNCTION:
    case S_TYPEDEF:
      break;
    }

    // most recently processed statement terminates abruptly
    if (parent == NULL) {
      if (node->next) {
        fprintf(stderr, "not reachable\n");
      }

      return NULL;
    }

    if (iter != NULL) {
      iter(parent, iter_data);
    }
  }

  return parent;
}
示例#4
0
文件: icode.c 项目: Yuffster/fluffOS
void
i_generate_node (parse_node_t * expr) {
    if (!expr) return;
    
    if (expr->line && expr->line != line_being_generated)
        switch_to_line(expr->line);
    switch (expr->kind) {
    case NODE_FUNCTION:
      {
          unsigned short num;
          
          /* In the following we know that this function wins all the */
          /* rest  - Sym                                              */

          num = FUNCTION_TEMP(expr->v.number)->u.index;
          FUNC(num)->address = generate_function(FUNC(num),
                                  expr->r.expr, expr->l.number);
          break;
      }
    case NODE_TERNARY_OP:
        i_generate_node(expr->l.expr);
        expr = expr->r.expr;
    case NODE_BINARY_OP:
        i_generate_node(expr->l.expr);
        /* fall through */
    case NODE_UNARY_OP:
        i_generate_node(expr->r.expr);
        /* fall through */
    case NODE_OPCODE:
        end_pushes();
        ins_byte(expr->v.number);
        break;
    case NODE_TERNARY_OP_1:
        i_generate_node(expr->l.expr);
        expr = expr->r.expr;
        /* fall through */
    case NODE_BINARY_OP_1:
        i_generate_node(expr->l.expr);
        i_generate_node(expr->r.expr);
        end_pushes();
        ins_byte(expr->v.number);
        ins_byte(expr->type);
        break;
    case NODE_UNARY_OP_1:
        i_generate_node(expr->r.expr);
        /* fall through */
    case NODE_OPCODE_1:
        if (expr->v.number == F_LOCAL) {
            if (try_to_push(PUSH_LOCAL, expr->l.number)) break;
        } else if (expr->v.number == F_GLOBAL) {
            if (try_to_push(PUSH_GLOBAL, expr->l.number)) break;
        }
        end_pushes();
        ins_byte(expr->v.number);
        ins_byte(expr->l.number);
        break;
    case NODE_OPCODE_2:
        end_pushes();
        ins_byte(expr->v.number);
        ins_byte(expr->l.number);
        if (expr->v.number == F_LOOP_COND_NUMBER)
#if SIZEOF_LONG == 8
            ins_long(expr->r.number);
#else
	    ins_int(expr->r.number);
#endif
        else 
            ins_byte(expr->r.number);
        break;
    case NODE_RETURN:
        {
            int n;
            n = foreach_depth;
            end_pushes();
            while (n--)
                ins_byte(F_EXIT_FOREACH);

            if (expr->r.expr) {
                i_generate_node(expr->r.expr);
                end_pushes();
                ins_byte(F_RETURN);
            } else ins_byte(F_RETURN_ZERO);
            break;
        }
    case NODE_STRING:
        if (try_to_push(PUSH_STRING, expr->v.number)) break;
        if (expr->v.number <= 0xff) {
            ins_byte(F_SHORT_STRING);
            ins_byte(expr->v.number);
        } else {
            ins_byte(F_STRING);
            ins_short(expr->v.number);
        }
        break;
    case NODE_REAL:
        end_pushes();
        ins_byte(F_REAL);
        ins_real(expr->v.real);
        break;
    case NODE_NUMBER:
        write_number(expr->v.number);
        break;
    case NODE_LAND_LOR:
        i_generate_node(expr->l.expr);
        i_generate_forward_branch(expr->v.number);
        i_generate_node(expr->r.expr);
        if (expr->l.expr->kind == NODE_BRANCH_LINK)
            i_update_forward_branch_links(expr->v.number,expr->l.expr);
        else 
            i_update_forward_branch("&& or ||");
        break;
    case NODE_BRANCH_LINK:
        i_generate_node(expr->l.expr);
        end_pushes();
        ins_byte(0);
        expr->v.number = CURRENT_PROGRAM_SIZE;
        ins_short(0);
        i_generate_node(expr->r.expr);
        break;
    case NODE_CALL_2:
        generate_expr_list(expr->r.expr);
        end_pushes();
        ins_byte(expr->v.number);
        ins_byte(expr->l.number >> 16);
        ins_short(expr->l.number & 0xffff);
        ins_byte((expr->r.expr ? expr->r.expr->kind : 0));
        break;
    case NODE_CALL_1:
        generate_expr_list(expr->r.expr);
        end_pushes();
        if (expr->v.number == F_CALL_FUNCTION_BY_ADDRESS) {
            expr->l.number = comp_def_index_map[expr->l.number];
        }
        ins_byte(expr->v.number);
        ins_short(expr->l.number);
        ins_byte((expr->r.expr ? expr->r.expr->kind : 0));
        break;
    case NODE_CALL:
        generate_expr_list(expr->r.expr);
        end_pushes();
        ins_byte(expr->v.number);
        ins_short(expr->l.number);
        break;
    case NODE_TWO_VALUES:
        i_generate_node(expr->l.expr);
        i_generate_node(expr->r.expr);
        break;
    case NODE_CONTROL_JUMP:
        {
            int kind = expr->v.number;
            end_pushes();
            ins_byte(F_BRANCH);
            expr->v.expr = branch_list[kind];
            expr->l.number = CURRENT_PROGRAM_SIZE;
            ins_short(0);
            branch_list[kind] = expr;
            break;
        }
    case NODE_PARAMETER:
        {
            int which = expr->v.number + current_num_values;
            if (try_to_push(PUSH_LOCAL, which)) break;
            ins_byte(F_LOCAL);
            ins_byte(which);
            break;
        }
    case NODE_PARAMETER_LVALUE:
        end_pushes();
        ins_byte(F_LOCAL_LVALUE);
        ins_byte(expr->v.number + current_num_values);
        break;
    case NODE_IF:
        i_generate_if_branch(expr->v.expr, 0);
        i_generate_node(expr->l.expr);
        if (expr->r.expr) {
            i_generate_else();
            i_generate_node(expr->r.expr);
        }
        i_update_forward_branch("if");
        break;
    case NODE_LOOP:
        i_generate_loop(expr->type, expr->v.expr, expr->l.expr, expr->r.expr);
        break;
    case NODE_FOREACH:
        {
            int tmp = 0;

            i_generate_node(expr->v.expr);
            end_pushes();
            ins_byte(F_FOREACH);
            if (expr->l.expr->v.number == F_GLOBAL_LVALUE) 
                tmp |= FOREACH_RIGHT_GLOBAL;
            else if (expr->l.expr->v.number == F_REF_LVALUE)
                tmp |= FOREACH_REF;
            if (expr->r.expr) {
                if (tmp & FOREACH_RIGHT_GLOBAL)
                    tmp = (tmp & ~FOREACH_RIGHT_GLOBAL) | FOREACH_LEFT_GLOBAL;

                tmp |= FOREACH_MAPPING;
                if (expr->r.expr->v.number == F_GLOBAL_LVALUE) 
                    tmp |= FOREACH_RIGHT_GLOBAL;
                else if (expr->r.expr->v.number == F_REF_LVALUE)
                    tmp |= FOREACH_REF;
            }
            ins_byte(tmp);
            ins_byte(expr->l.expr->l.number);
            if (expr->r.expr)
                ins_byte(expr->r.expr->l.number);
        }
        break;
    case NODE_CASE_NUMBER:
    case NODE_CASE_STRING:
        if (expr->v.expr) {
            parse_node_t *other = expr->v.expr;
            expr->v.number = 1;
            other->l.expr = expr->l.expr;
            other->v.number = CURRENT_PROGRAM_SIZE;
            expr->l.expr = other;
        } else {
            expr->v.number = CURRENT_PROGRAM_SIZE;
        }
        end_pushes();
        break;
    case NODE_DEFAULT:
        expr->v.number = CURRENT_PROGRAM_SIZE;
        end_pushes();
        break;
    case NODE_SWITCH_STRINGS:
    case NODE_SWITCH_NUMBERS:
    case NODE_SWITCH_DIRECT:
    case NODE_SWITCH_RANGES:
        {
            long addr, last_break;
            parse_node_t *sub = expr->l.expr;
            parse_node_t *save_switch_breaks = branch_list[CJ_BREAK_SWITCH];
            
            i_generate_node(sub);
            branch_list[CJ_BREAK_SWITCH] = 0;
            end_pushes();
            ins_byte(F_SWITCH);
            addr = CURRENT_PROGRAM_SIZE;
            /* all these are addresses in here are relative to addr now,
             * which is also the value of pc in f_switch().  Note that
             * addr is one less than it was in older drivers.
             */
            ins_byte(0xff); /* kind of table */
            ins_short(0); /* address of table */
            ins_short(0); /* end of table */
            ins_short(0); /* default address */
            i_generate_node(expr->r.expr);
            if (expr->v.expr && expr->v.expr->kind == NODE_DEFAULT) {
                upd_short(addr + 5, expr->v.expr->v.number - addr,
                          "switch");
                expr->v.expr = expr->v.expr->l.expr;
            } else {
                upd_short(addr + 5, CURRENT_PROGRAM_SIZE - addr, "switch");
            }
            /* just in case the last case doesn't have a break */
            end_pushes();
            ins_byte(F_BRANCH);
            last_break = CURRENT_PROGRAM_SIZE;
            ins_short(0);
            /* build table */
            upd_short(addr + 1, CURRENT_PROGRAM_SIZE - addr, "switch");
#ifdef BINARIES
            if (pragmas & PRAGMA_SAVE_BINARY) {
                if (expr->kind == NODE_SWITCH_STRINGS) {
                    short sw;
                    sw = addr - 1;
                    add_to_mem_block(A_PATCH, (char *)&sw, sizeof sw);
                }
            }
#endif
            if (expr->kind == NODE_SWITCH_DIRECT) {
                parse_node_t *pn = expr->v.expr;
                while (pn) {
                    ins_rel_short(pn->v.number - addr);
                    pn = pn->l.expr;
                }
                ins_int(expr->v.expr->r.number);
                mem_block[A_PROGRAM].block[addr] = (char)0xfe;
            } else {
                int table_size = 0;
                int power_of_two = 1;
                int i = 0;
                parse_node_t *pn = expr->v.expr;
                
                while (pn) {
                    if (expr->kind == NODE_SWITCH_STRINGS) {
                        if (pn->r.number) {
                            INS_POINTER((POINTER_INT)
                                        PROG_STRING(pn->r.number));
                        } else 
                            INS_POINTER((POINTER_INT)0);
                    } else
                        INS_POINTER((POINTER_INT)pn->r.expr);
                    if (pn->v.number == 1)
                        ins_short(1);
                    else
                        ins_rel_short(pn->v.number - addr);
                    pn = pn->l.expr;
                    table_size += 1;
                }
                while ((power_of_two<<1) <= table_size) {
                    power_of_two <<= 1;
                    i++;
                }
                if (expr->kind != NODE_SWITCH_STRINGS)
                    mem_block[A_PROGRAM].block[addr] = (char)(0xf0+i);
                else
                    mem_block[A_PROGRAM].block[addr] = (char)(i*0x10+0x0f);
            }
            i_update_branch_list(branch_list[CJ_BREAK_SWITCH], "switch break");
            branch_list[CJ_BREAK_SWITCH] = save_switch_breaks;
            upd_short(last_break, CURRENT_PROGRAM_SIZE - last_break, "switch break");
            upd_short(addr+3, CURRENT_PROGRAM_SIZE - addr, "switch");
            break;
        }
    case NODE_CATCH:
        {
            int addr;

            end_pushes();
            ins_byte(F_CATCH);
            addr = CURRENT_PROGRAM_SIZE;
            ins_short(0);
            i_generate_node(expr->r.expr);
            ins_byte(F_END_CATCH);
            upd_short(addr, CURRENT_PROGRAM_SIZE - addr, "catch");
            break;
        }
    case NODE_TIME_EXPRESSION:
        {
            end_pushes();
            ins_byte(F_TIME_EXPRESSION);
            i_generate_node(expr->r.expr);
            ins_byte(F_END_TIME_EXPRESSION);
            break;
        }
    case NODE_LVALUE_EFUN:
        i_generate_node(expr->l.expr);
        generate_lvalue_list(expr->r.expr);
        break;
    case NODE_FUNCTION_CONSTRUCTOR:
        if (expr->r.expr) {
            generate_expr_list(expr->r.expr);
            end_pushes();
            ins_byte(F_AGGREGATE);
            ins_short(expr->r.expr->kind);
        } else {
            end_pushes();
            ins_byte(F_CONST0);
        }
        end_pushes();

        ins_byte(F_FUNCTION_CONSTRUCTOR);
        ins_byte(expr->v.number & 0xff);

        switch (expr->v.number & 0xff) {
        case FP_SIMUL:
            ins_short(expr->v.number >> 8);
            break;
        case FP_LOCAL:
            ins_short(comp_def_index_map[expr->v.number >> 8]);
            break;
        case FP_EFUN:
            ins_short(predefs[expr->v.number >> 8].token);
            break;
        case FP_FUNCTIONAL:
        case FP_FUNCTIONAL | FP_NOT_BINDABLE:
            {
                int addr, save_current_num_values = current_num_values;
                ins_byte(expr->v.number >> 8);
                addr = CURRENT_PROGRAM_SIZE;
                ins_short(0);
                current_num_values = expr->r.expr ? expr->r.expr->kind : 0;
                i_generate_node(expr->l.expr);
                current_num_values = save_current_num_values;
                end_pushes();
                ins_byte(F_RETURN);
                upd_short(addr, CURRENT_PROGRAM_SIZE - addr - 2,
                          "function pointer");
                break;
            }
        }
        break;
    case NODE_ANON_FUNC:
        {
            int addr;
            int save_fd = foreach_depth;

            foreach_depth = 0;
            end_pushes();
            ins_byte(F_FUNCTION_CONSTRUCTOR);
            if (expr->v.number & 0x10000)
                ins_byte(FP_ANONYMOUS | FP_NOT_BINDABLE);
            else
                ins_byte(FP_ANONYMOUS);
            ins_byte(expr->v.number & 0xff);
            ins_byte(expr->l.number);
            addr = CURRENT_PROGRAM_SIZE;
            ins_short(0);
            i_generate_node(expr->r.expr);
            upd_short(addr, CURRENT_PROGRAM_SIZE - addr - 2,
                      "function pointer");
            foreach_depth = save_fd;
            break;
        }
    case NODE_EFUN:
        {
            int novalue_used = expr->v.number & NOVALUE_USED_FLAG;
            int f = expr->v.number & ~NOVALUE_USED_FLAG;
            
            generate_expr_list(expr->r.expr);
            end_pushes();
            if (f < ONEARG_MAX) {
                ins_byte(f);
            } else {
                /* max_arg == -1 must use F_EFUNV so that varargs expansion works*/
                if (expr->l.number < 4 && instrs[f].max_arg != -1)
                    ins_byte(F_EFUN0 + expr->l.number);
                else {
                    ins_byte(F_EFUNV);
                    ins_byte(expr->l.number);
                }
                ins_byte(f - ONEARG_MAX);
            }
            if (novalue_used) {
                /* the value of a void efun was used.  Put in a zero. */
                ins_byte(F_CONST0);
            }
            break;
	}
        default:
            fatal("Unknown node %i in i_generate_node.\n", expr->kind);
    }
示例#5
0
void
main_cuc (char *filename)
{
  int i, j;
  char tmp1[256];
  char filename_cut[256];
#if 0				/* Select prefix, based on binary program name */
  for (i = 0; i < sizeof (filename_cut); i++)
    {
      if (isalpha (filename[i]))
	filename_cut[i] = filename[i];
      else
	{
	  filename_cut[i] = '\0';
	  break;
	}
    }
#else
  strcpy (filename_cut, "cu");
#endif

  PRINTF ("Entering OpenRISC Custom Unit Compiler command prompt\n");
  PRINTF ("Using profile file \"%s\" and memory profile file \"%s\".\n",
	  config.sim.prof_fn, config.sim.mprof_fn);
  sprintf (tmp1, "%s.log", filename_cut);
  PRINTF ("Analyzing. (log file \"%s\").\n", tmp1);
  assert (flog = fopen (tmp1, "wt+"));

  /* Loads in the specified timings table */
  PRINTF ("Using timings from \"%s\" at %s\n", config.cuc.timings_fn,
	  generate_time_pretty (tmp1, config.sim.clkcycle_ps));
  load_timing_table (config.cuc.timings_fn);
  runtime.cuc.cycle_duration = 1000. * config.sim.clkcycle_ps;
  PRINTF ("Multicycle logic %s, bursts %s, %s memory order.\n",
	  config.cuc.no_multicycle ? "OFF" : "ON",
	  config.cuc.enable_bursts ? "ON" : "OFF",
	  config.cuc.memory_order ==
	  MO_NONE ? "no" : config.cuc.memory_order ==
	  MO_WEAK ? "weak" : config.cuc.memory_order ==
	  MO_STRONG ? "strong" : "exact");

  prof_set (1, 0);
  assert (prof_acquire (config.sim.prof_fn) == 0);

  if (config.cuc.calling_convention)
    PRINTF ("Assuming OpenRISC standard calling convention.\n");

  /* Try all functions except "total" */
  for (i = 0; i < prof_nfuncs - 1; i++)
    {
      long orig_time;
      unsigned long start_addr, end_addr;
      orig_time = prof_func[i].cum_cycles;
      start_addr = prof_func[i].addr;

      /* Extract the function from the binary */
      sprintf (tmp1, "%s.bin", prof_func[i].name);
      end_addr = extract_function (tmp1, start_addr);

      log ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
	   start_addr, end_addr);
      PRINTF ("Testing function %s (%08lx - %08lx)\n", prof_func[i].name,
	      start_addr, end_addr);
      func[i] =
	analyse_function (prof_func[i].name, orig_time, start_addr, end_addr,
			  config.cuc.memory_order, prof_func[i].calls);
      func_v[i] = 0;
    }
  set_func_deps ();

  while (1)
    {
      char *s;
    wait_command:
      PRINTF ("(cuc) ");
      fflush (stdout);
    wait_command_empty:
      s = fgets (tmp1, sizeof tmp1, stdin);
      usleep (100);
      if (!s)
	goto wait_command_empty;
      for (s = tmp1; *s != '\0' && *s != '\n' && *s != '\r'; s++);
      *s = '\0';

      /* quit command */
      if (strcmp (tmp1, "q") == 0 || strcmp (tmp1, "quit") == 0)
	{
	  /* Delete temporary files */
	  for (i = 0; i < prof_nfuncs - 1; i++)
	    {
	      sprintf (tmp1, "%s.bin", prof_func[i].name);
	      log ("Deleting temporary file %s %s\n", tmp1,
		   remove (tmp1) ? "FAILED" : "OK");
	      sprintf (tmp1, "%s.bin.bb", prof_func[i].name);
	      log ("Deleting temporary file %s %s\n", tmp1,
		   remove (tmp1) ? "FAILED" : "OK");
	    }
	  break;

	  /* profile command */
	}
      else if (strcmp (tmp1, "p") == 0 || strcmp (tmp1, "profile") == 0)
	{
	  int ntime = 0;
	  int size = 0;
	  PRINTF
	    ("-----------------------------------------------------------------------------\n");
	  PRINTF
	    ("|function name       |calls|avg cycles  |old%%| max. f.  | impr. f.| options |\n");
	  PRINTF
	    ("|--------------------+-----+------------+----+----------|---------+---------|\n");
	  for (j = 0; j < prof_nfuncs; j++)
	    {
	      int bestcyc = 0, besti = 0;
	      char tmp[100];
	      for (i = 0; i < prof_nfuncs; i++)
		if (prof_func[i].cum_cycles > bestcyc)
		  {
		    bestcyc = prof_func[i].cum_cycles;
		    besti = i;
		  }
	      i = besti;
	      PRINTF ("|%-20s|%5li|%12.1f|%3.0f%%| ",
		      strstrip (tmp, prof_func[i].name, 20),
		      prof_func[i].calls,
		      ((double) prof_func[i].cum_cycles / prof_func[i].calls),
		      (100. * prof_func[i].cum_cycles / prof_cycles));
	      if (func[i])
		{
		  double f = 1.0;
		  if (func_v[i])
		    {
		      int nt = calc_cycles (func[i]);
		      int s = calc_size (func[i]);
		      f = 1. * func[i]->orig_time / nt;
		      ntime += nt;
		      size += s;
		    }
		  else
		    ntime += prof_func[i].cum_cycles;
		  PRINTF ("%8.1f |%8.1f | %-8s|\n",
			  1.f * prof_func[i].cum_cycles /
			  func[i]->timings.new_time, f,
			  format_func_options (tmp, func[i]));
		}
	      else
		{
		  PRINTF ("     N/A |     N/A |     N/A |\n");
		  ntime += prof_func[i].cum_cycles;
		}
	      prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
	    }
	  for (i = 0; i < prof_nfuncs; i++)
	    prof_func[i].cum_cycles = -prof_func[i].cum_cycles;
	  PRINTF
	    ("-----------------------------------------------------------------------------\n");
	  PRINTF
	    ("Total %i cycles (was %i), total added gates = %i. Speed factor %.1f\n",
	     ntime, prof_cycles, size, 1. * prof_cycles / ntime);

	  /* debug command */
	}
      else if (strncmp (tmp1, "d", 1) == 0 || strncmp (tmp1, "debug", 5) == 0)
	{
	  sscanf (tmp1, "%*s %i", &cuc_debug);
	  if (cuc_debug < 0)
	    cuc_debug = 0;
	  if (cuc_debug > 9)
	    cuc_debug = 9;

	  /* generate command */
	}
      else if (strcmp (tmp1, "g") == 0 || strcmp (tmp1, "generate") == 0)
	{
	  /* check for function dependencies */
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      func[i]->tmp = func_v[i];
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      for (j = 0; j < func[i]->nfdeps; j++)
		if (!func[i]->fdeps[j] || !func[i]->fdeps[j]->tmp)
		  {
		    PRINTF
		      ("Function %s must be selected for translation (required by %s)\n",
		       prof_func[j].name, prof_func[i].name);
		    goto wait_command;
		  }
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i] && func_v[i])
	      generate_function (func[i], prof_func[i].name, filename_cut);
	  generate_main (prof_nfuncs, func, filename_cut);

	  /* list command */
	}
      else if (strcmp (tmp1, "l") == 0 || strcmp (tmp1, "list") == 0)
	{
	  /* check for function dependencies */
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func_v[i])
	      {
		PRINTF ("%s\n", prof_func[i].name);
	      }

	  /* selectall command */
	}
      else if (strcmp (tmp1, "sa") == 0 || strcmp (tmp1, "selectall") == 0)
	{
	  int f;
	  for (f = 0; f < prof_nfuncs; f++)
	    if (func[f])
	      {
		func_v[f] = 1;
		PRINTF ("Function %s selected for translation.\n",
			prof_func[f].name);
	      }

	  /* select command */
	}
      else if (strncmp (tmp1, "s", 1) == 0
	       || strncmp (tmp1, "select", 6) == 0)
	{
	  char tmp[50], ch;
	  int p, o, b, f;
	  p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
	  if (p < 1)
	    PRINTF ("Invalid parameters.\n");
	  else
	    {
	      /* Check if we have valid option */
	      for (f = 0; f < prof_nfuncs; f++)
		if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
		  break;
	      if (f < prof_nfuncs)
		{
		  if (p == 1)
		    {
		      if (func[f])
			{
			  func_v[f] = 1;
			  PRINTF ("Function %s selected for translation.\n",
				  prof_func[f].name);
			}
		      else
			PRINTF ("Function %s not suitable for translation.\n",
				prof_func[f].name);
		    }
		  else
		    {
		      if (!func_v[f])
			PRINTF
			  ("Function %s not yet selected for translation.\n",
			   prof_func[f].name);
		      if (p < 3)
			goto invalid_option;
		      for (o = 0;
			   option_char[o] != '\0' && option_char[o] != ch;
			   o++);
		      if (!option_char[o])
			goto invalid_option;
		      if (b < 0 || b >= func[f]->num_bb)
			goto invalid_option;
		      if (o < 0 || o >= func[f]->bb[b].ntim)
			goto invalid_option;

		      /* select an option */
		      func[f]->bb[b].selected_tim = o;
		      if (func[f]->bb[b].tim[o].nshared)
			{
			  PRINTF ("Option has shared instructions: ");
			  print_shared (func[f], func[f]->bb[b].tim[o].shared,
					func[f]->bb[b].tim[o].nshared);
			  PRINTF ("\n");
			}
		      goto wait_command;
		    invalid_option:
		      PRINTF ("Invalid option.\n");
		    }
		}
	      else
		PRINTF ("Invalid function.\n");
	    }

	  /* unselect command */
	}
      else if (strncmp (tmp1, "u", 1) == 0
	       || strncmp (tmp1, "unselect", 8) == 0)
	{
	  char tmp[50], ch;
	  int p, o, b, f;
	  p = sscanf (tmp1, "%*s %s %i%c", tmp, &b, &ch);
	  if (p < 1)
	    PRINTF ("Invalid parameters.\n");
	  else
	    {
	      /* Check if we have valid option */
	      for (f = 0; f < prof_nfuncs; f++)
		if (strcmp (prof_func[f].name, tmp) == 0 && func[f])
		  break;
	      if (f < prof_nfuncs)
		{
		  if (p == 1)
		    {
		      if (func[f])
			{
			  func_v[f] = 0;
			  PRINTF ("Function %s unselected for translation.\n",
				  prof_func[f].name);
			}
		      else
			PRINTF ("Function %s not suitable for translation.\n",
				prof_func[f].name);
		    }
		  else
		    {
		      if (p < 3)
			goto invalid_option;
		      for (o = 0;
			   option_char[o] != '\0' && option_char[o] != ch;
			   o++);
		      if (!option_char[o])
			goto invalid_option;
		      if (b < 0 || b >= func[f]->num_bb)
			goto invalid_option;
		      if (o < 0 || o >= func[f]->bb[b].ntim)
			goto invalid_option;

		      /* select an option */
		      func[f]->bb[b].selected_tim = -1;
		    }
		}
	      else
		PRINTF ("Invalid function.\n");
	    }

	  /* options command */
	}
      else if (strcmp (tmp1, "o") == 0 || strcmp (tmp1, "options") == 0)
	{
	  int any = 0;
	  PRINTF ("Available options:\n");
	  for (i = 0; i < prof_nfuncs; i++)
	    if (func[i])
	      {
		options_cmd (i, func[i]);
		any = 1;
	      }
	  if (any)
	    PRINTF
	      ("-----------------------------------------------------------------------------\n");
	  else
	    PRINTF ("Sorry. No available options.\n");

	  /* Ignore empty string */
	}
      else if (strcmp (tmp1, "") == 0)
	{

	  /* help command */
	}
      else
	{
	  if (strcmp (tmp1, "h") != 0 && strcmp (tmp1, "help") != 0)
	    PRINTF ("Unknown command.\n");
	  PRINTF ("OpenRISC Custom Unit Compiler command prompt\n");
	  PRINTF ("Available commands:\n");
	  PRINTF ("  h | help                   displays this help\n");
	  PRINTF ("  q | quit                   returns to or1ksim prompt\n");
	  PRINTF
	    ("  p | profile                displays function profiling\n");
	  PRINTF ("  d | debug #                sets debug level (0-9)\n");
	  PRINTF
	    ("  o | options                displays available options\n");
	  PRINTF
	    ("  s | select func [option]   selects an option/function\n");
	  PRINTF
	    ("  u | unselect func [option] unselects an option/function\n");
	  PRINTF ("  g | generate               generates verilog file\n");
	  PRINTF
	    ("  l | list                   displays selected functions\n");
	}
    }

  /* Dispose memory */
  for (i = 0; i < prof_nfuncs - 1; i++)
    if (func[i])
      free_func (func[i]);

  fclose (flog);
}
示例#6
0
文件: compile.c 项目: MUME/mudlle
static void generate_component(component comp, fncode fn)
{
  clist args;

  set_lineno(comp->lineno, fn);

  switch (comp->vclass)
    {
    case c_assign:
      {
	ulong offset;
        bool is_static;
	variable_class vclass = env_lookup(comp->u.assign.symbol, &offset,
                                           false, true, &is_static);
	component val = comp->u.assign.value;

	if (val->vclass == c_closure)
	  {
	    /* Defining a function, give it a name */
	    if (vclass == global_var)
	      val->u.closure->varname = comp->u.assign.symbol;
	    else
	      {
		char *varname = allocate(fnmemory(fn), strlen(comp->u.assign.symbol) + 7);

		sprintf(varname, "local-%s", comp->u.assign.symbol);
		val->u.closure->varname = varname;
	      }
	  }

        if (is_static)
          {
            ins1(op_recall + vclass, offset, fn);
            generate_component(comp->u.assign.value, fn);
            mexecute(g_symbol_set, NULL, 2, fn);
            break;
          }

	generate_component(comp->u.assign.value, fn);

	set_lineno(comp->lineno, fn);

        if (vclass == global_var)
	  massign(offset, comp->u.assign.symbol, fn);
	else
	  ins1(op_assign + vclass, offset, fn);
	/* Note: varname becomes a dangling pointer when fnmemory(fn) is
	   deallocated, but it is never used again so this does not cause
	   a problem. */
	break;
      }
    case c_vref:
    case c_recall:
      {
        bool is_vref = comp->vclass == c_vref;
	ulong offset;
        bool is_static;
	variable_class vclass = env_lookup(comp->u.recall, &offset,
                                           true, is_vref, &is_static);

        if (is_static)
          {
            assert(vclass != global_var);
            ins1(op_recall + vclass, offset, fn);
            ulong gidx = is_vref ? g_make_symbol_ref : g_symbol_get;
            mexecute(gidx, NULL, 1, fn);
            break;
          }
	if (vclass != global_var)
          ins1((is_vref ? op_vref : op_recall) + vclass, offset, fn);
        else if (is_vref)
          {
            if (!mwritable(offset, comp->u.recall))
              return;
            ins_constant(makeint(offset), fn);
          }
        else
          mrecall(offset, comp->u.recall, fn);
        if (is_vref)
          mexecute(g_make_variable_ref, "make_variable_ref", 1, fn);
	break;
      }
    case c_constant:
      ins_constant(make_constant(comp->u.cst), fn);
      break;
    case c_closure:
      {
	uword idx;

	idx = add_constant(generate_function(comp->u.closure, false, fn), fn);
	if (idx < ARG1_MAX) ins1(op_closure_code1, idx, fn);
	else ins2(op_closure_code2, idx, fn);
	break;
      }
    case c_block:
      generate_block(comp->u.blk, fn);
      break;
    case c_labeled:
      start_block(comp->u.labeled.name, fn);
      generate_component(comp->u.labeled.expression, fn);
      end_block(fn);
      break;
    case c_exit:
      generate_component(comp->u.labeled.expression, fn);
      if (!exit_block(comp->u.labeled.name, fn)) {
	if (!comp->u.labeled.name)
	  log_error("no loop to exit from");
	else
	  log_error("no block labeled %s", comp->u.labeled.name);
      }
      break;
    case c_execute:
      {
	uword count;

	generate_args(comp->u.execute->next, fn, &count);
	set_lineno(comp->lineno, fn);
	generate_execute(comp->u.execute->c, count, fn);
	break;
      }
    case c_builtin:
      args = comp->u.builtin.args;

      switch (comp->u.builtin.fn)
	{
	case b_if: {
          block cb = new_codeblock(fnmemory(fn), NULL,
                                   new_clist(fnmemory(fn), args->next->c,
                                             new_clist(fnmemory(fn),
                                                       component_undefined,
                                                       NULL)),
                                   NULL, NULL, -1);
	  generate_if(args->c, new_component(fnmemory(fn),
                                             args->next->c->lineno,
                                             c_block, cb),
		      component_undefined, fn);
	  break;
        }
	case b_ifelse:
	  generate_if(args->c, args->next->c, args->next->next->c, fn);
	  break;
	case b_sc_and: case b_sc_or:
	  generate_if(comp, component_true, component_false, fn);
	  break;

	case b_while:
	  generate_while(args->c, args->next->c, fn);
	  break;

	case b_loop:
	  {
	    label loop = new_label(fn);

            env_start_loop();
	    set_label(loop, fn);
	    start_block(NULL, fn);
	    generate_component(args->c, fn);
	    branch(op_loop1, loop, fn);
	    end_block(fn);
            env_end_loop();
	    adjust_depth(1, fn);
	    break;
	  }

	case b_add: case b_subtract:
	case b_ref: case b_set:
	case b_bitor: case b_bitand:
	case b_not:
	case b_eq: case b_ne:
	case b_lt: case b_le: case b_ge: case b_gt:
	  {
	    uword count;

	    assert(comp->u.builtin.fn < last_builtin);
	    generate_args(args, fn, &count);
	    set_lineno(comp->lineno, fn);
	    ins0(builtin_ops[comp->u.builtin.fn], fn);
	    break;
	  }
	default:
	  {
	    uword count;

	    assert(comp->u.builtin.fn < last_builtin);
	    generate_args(args, fn, &count);
	    set_lineno(comp->lineno, fn);
	    mexecute(builtin_functions[comp->u.builtin.fn], NULL, count, fn);
	    break;
	  }
	}
      break;
    default: abort();
    }
}
示例#7
0
文件: compile.c 项目: MUME/mudlle
                          : "");
  const char *nicename = (f->body->nicename
                            ? f->body->nicename
                            : "");
  compile_level = seclev;
  erred = false;
  env_reset();
  fncode top = new_fncode(true);
  env_push(NULL, top);		/* Environment must not be totally empty */
  block body = new_toplevel_codeblock(fnmemory(top), f->statics, f->body);
  function func = new_function(fnmemory(top), TYPESET_ANY, sl, NULL,
                               new_component(fnmemory(top), 0, c_block, body),
                               body->lineno,
                               filename, nicename);
  func->varname = "top-level";
  struct icode *cc = generate_function(func, true, top);

  GCPRO1(cc);
  generate_fncode(top, NULL, NULL, NULL, NULL, 0, NULL, TYPESET_ANY, seclev);
  uword dummy;
  env_pop(&dummy);
  delete_fncode(top);
  UNGCPRO();

  if (erred)
    return NULL;
  return alloc_closure0(&cc->code);
}

struct call_info {
  value f, *result;
示例#8
0
void generate_component(component comp, const char *mlabel, bool discard, fncode fn)
{
  clist args;

  switch (comp->vclass)
    {
    case c_assign:
      {
	u16 offset;
	mtype t;
	variable_class vclass = env_lookup(comp->l, comp->u.assign.symbol, &offset, &t, FALSE);
	component val = comp->u.assign.value;

	if (val->vclass == c_closure)
	  {
	    /* Defining a function, give it a name */
	    if (vclass == global_var)
	      val->u.closure->varname = comp->u.assign.symbol;
	    else
	      {
		char *varname = allocate(fnmemory(fn), strlen(comp->u.assign.symbol) + 7);

		sprintf(varname, "local-%s", comp->u.assign.symbol);
		val->u.closure->varname = varname;
	      }
	  }
	generate_component(comp->u.assign.value, NULL, FALSE, fn);
	if (t != stype_any)
	  ins0(OPmscheck4 + t, fn);
	if (vclass == global_var)
	  massign(comp->l, offset, comp->u.assign.symbol, fn);
	else if (vclass == closure_var)
	  ins1(OPmwritec, offset, fn);
	else
	  ins1(OPmwritel, offset, fn);
	/* Note: varname becomes a dangling pointer when fnmemory(fn) is
	   deallocated, but it is never used again so this does not cause
	   a problem. */
	break;
      }
    case c_recall:
      scompile_recall(comp->l, comp->u.recall, fn);
      break;
    case c_constant:
      ins_constant(make_constant(comp->u.cst, FALSE, fn), fn);
      break;
    case c_scheme:
      scheme_compile_mgc(comp->l, make_constant(comp->u.cst, TRUE, fn), discard, fn);
      discard = FALSE;
      break;
    case c_closure:
      generate_function(comp->u.closure, fn);
      break;
    case c_block:
      generate_block(comp->u.blk, discard, fn);
      discard = FALSE;
      break;
    case c_decl: 
      {
	vlist decl, next;

	/* declare variables one at a time (any x = y, y = 2; is an error) */
	for (decl = comp->u.decls; decl; decl = next)
	  {
	    next = decl->next;
	    decl->next = NULL;

	    env_declare(decl);
	    generate_decls(decl, fn);
	  }
	generate_component(component_undefined, NULL, FALSE, fn);
	break;
      }
    case c_labeled: {
      start_block(comp->u.labeled.name, FALSE, discard, fn);
      generate_component(comp->u.labeled.expression, comp->u.labeled.name, discard, fn);
      end_block(fn);
      discard = FALSE;
      break;
    }
    case c_exit:
      {
	bool discard_exit;
	label exitlab = exit_block(comp->u.labeled.name, FALSE, &discard_exit, fn);

	if (comp->u.labeled.expression != component_undefined && discard_exit)
	  warning(comp->l, "break result is ignored");
	generate_component(comp->u.labeled.expression, NULL, discard_exit, fn);
	if (exitlab)
	  branch(OPmba3, exitlab, fn);
	else 
	  {
	    if (!comp->u.labeled.name)
	      log_error(comp->l, "No loop to exit from");
	    else
	      log_error(comp->l, "No block labeled %s", comp->u.labeled.name);
	  }
	/* Callers expect generate_component to increase stack depth by 1  */
	if (discard_exit)
	  adjust_depth(1, fn);
	break;
      }
    case c_continue:
      {
	bool discard_exit; /* Meaningless for continue blocks */
	label exitlab = exit_block(comp->u.labeled.name, TRUE, &discard_exit, fn);

	if (exitlab)
	  branch(OPmba3, exitlab, fn);
	else 
	  {
	    if (comp->u.labeled.name[0] == '<')
	      log_error(comp->l, "No loop to continue");
	    else
	      log_error(comp->l, "No loop labeled %s", comp->u.labeled.name);
	  }
	/* Callers expect generate_component to increase stack depth by 1 (*/
	adjust_depth(1, fn);
	break;
      }
    case c_execute:
      {
	u16 count;

	generate_args(comp->u.execute->next, fn, &count);
	generate_execute(comp->u.execute->c, count, fn);
	break;
      }
    case c_builtin:
      args = comp->u.builtin.args;

      switch (comp->u.builtin.fn)
	{
	case b_if:
	  generate_if(args->c, args->next->c, NULL, TRUE, fn);
	  generate_component(component_undefined, NULL, FALSE, fn);
	  break;
	case b_ifelse:
	  generate_if(args->c, args->next->c, args->next->next->c, discard, fn);
	  discard = FALSE;
	  break;
	case b_sc_and: case b_sc_or:
	  generate_if(comp, component_true, component_false, discard, fn);
	  discard = FALSE;
	  break;

	case b_while:
	  enter_loop(fn);
	  generate_while(args->c, args->next->c, mlabel, discard, fn);
	  exit_loop(fn);
	  discard = FALSE;
	  break;

	case b_dowhile:
	  enter_loop(fn);
	  generate_dowhile(args->c, args->next->c, mlabel, discard, fn);
	  exit_loop(fn);
	  discard = FALSE;
	  break;

	case b_for:
	  enter_loop(fn);
	  generate_for(args->c, args->next->c, args->next->next->c,
		       args->next->next->next->c, mlabel, discard, fn);
	  exit_loop(fn);
	  discard = FALSE;
	  break;

	default:
	  {
	    u16 count;

	    assert(comp->u.builtin.fn < last_builtin);
	    generate_args(args, fn, &count);
	    ins0(builtin_ops[comp->u.builtin.fn], fn);
	    break;
	  }
	case b_cons:
	  {
	    u16 count;
	    u16 goffset;
	    mtype t;

	    assert(comp->u.builtin.fn < last_builtin);
	    generate_args(args, fn, &count);
	    goffset = global_lookup(fnglobals(fn),
				    builtin_functions[comp->u.builtin.fn], &t);
	    mexecute(comp->l, goffset, NULL, count, fn);
	    break;
	  }
	}
      break;
    default: assert(0);
    }
  if (discard)
    ins0(OPmpop, fn);
}
示例#9
0
  void Compiler::compile_builder(jit::Context& ctx, LLVMState* ls, JITMethodInfo& info,
                                     jit::Builder& work)
  {
    llvm::Function* func = info.function();

    if(!work.generate_body()) {
      function_ = NULL;
      // This is too noisy to report
      // llvm::outs() << "not supported yet.\n";
      return;
    }

    // Hook up the return pad and return phi.
    work.generate_hard_return();

    if(ls->jit_dump_code() & cSimple) {
      llvm::outs() << "[[[ LLVM Simple IR ]]]\n";
      llvm::outs() << *func << "\n";
    }

    std::vector<BasicBlock*> to_remove;
    bool Broken = false;
    for(Function::iterator I = func->begin(), E = func->end(); I != E; ++I) {
      if(I->empty()) {
        BasicBlock& bb = *I;
        // No one jumps to it....
        if(llvm::pred_begin(&bb) == llvm::pred_end(&bb)) {
          to_remove.push_back(&bb);
        } else {
          llvm::outs() << "Basic Block is empty and used!\n";
        }
      } else if(!I->back().isTerminator()) {
        llvm::errs() << "Basic Block does not have terminator!\n";
        llvm::errs() << *I << "\n";
        llvm::errs() << "\n";
        Broken = true;
      }
    }

    for(std::vector<BasicBlock*>::iterator i = to_remove.begin();
        i != to_remove.end();
        ++i) {
      (*i)->eraseFromParent();
    }

    if(Broken or llvm::verifyFunction(*func, PrintMessageAction)) {
      llvm::outs() << "ERROR: complication error detected.\n";
      llvm::outs() << "ERROR: Please report the above message and the\n";
      llvm::outs() << "       code below to http://github.com/rubinius/rubinius/issues\n";
      llvm::outs() << *func << "\n";
      function_ = NULL;
      return;
    }

    ls->passes()->run(*func);

    if(ls->jit_dump_code() & cOptimized) {
      llvm::outs() << "[[[ LLVM Optimized IR: "
        << ls->symbol_cstr(info.method()->name()) << " ]]]\n";
      llvm::outs() << *func << "\n";
    }

    function_ = func;

    generate_function(ls);

    // Inject the RuntimeData objects used into the original CompiledMethod
    // Do this way after we've validated the IR so things are consistent.
    ctx.runtime_data_holder()->set_function(func, mci_->address(), mci_->size());

    info.method()->set_jit_data(ctx.runtime_data_holder());
    ls->shared().om->add_code_resource(ctx.runtime_data_holder());

  }
示例#10
0
文件: codegen.c 项目: sorakun/Eve_old
string gen_code(string file, tThread * main)
{
    debugf("generating code\n");
    int i;
    string fname  = strdup(file); //  .c
    string fname2 = strdup(file); // .h
    string ext  = strdup(".c");
    string ext2 = strdup(".h");
    strcat(fname, ext);
    strcat(fname2, ext2);
    out= fopen(fname, "w");
    hout = fopen(fname2, "w");

    fprintf(out, "#include <eve.h>\n#include <stdlib.h>\n#include <string.h>\n");
    for(i=0; i<included_files_count; i++)
    {
        fprintf(out, "#include <%s.h>\n", included_files[i]);
        fprintf(hout, "#include <%s.h>\n", included_files[i]);
    }

    fprintf(out, "#include \"%s\"\n", fname2);
    // generating types in hout (.h)
    fprintf(hout, "\n/* data types */\n", fname2);
    for (i = BASIC_TYPES_COUNT-1; i<global_types_count; i++)
    {
        if (global_types[i].type_kind == __ctype)
            continue;
        if((global_types[i].type_kind == __none) || (global_types[i].type_kind == __array))
        {
            fprintf(hout, "typedef %s ", global_types[i].pointerto);
            if(global_types[i].pointer)
            {
                fprintf(hout, " *");
            }
            fprintf(hout, " %s;\n", global_types[i].name);
        }
        else if (global_types[i].type_kind == __enum)
        {
            fprintf(hout, "typedef enum %s{\n", global_types[i].name);
            int j = 0;
            for(; j<global_types[i].ecount; j++)
            {
                fprintf(hout, "%s, ", global_types[i].enums[j]);
            }
            fprintf(hout, "\n}%s;\n", global_types[i].name);
        }
        else if (global_types[i].type_kind == __pclass) // next type is class, generate it automatically
        {
            fprintf(hout, "struct %s;\n", global_types[i+1].class_info.name);
            // generate next type.
            fprintf(hout, "typedef struct %s * %s;\n", global_types[i].pointerto, global_types[i].name);

            fprintf(hout, "typedef struct %s{\n", global_types[i+1].class_info.name);
            int j = 0;
            for(; j<global_types[i+1].class_info.vcount; j++)
            {
                fprintf(hout, "%s %s;\n", global_types[i+1].class_info.variables[j].type, global_types[i+1].class_info.variables[j].name);
            }
            fprintf(hout, "\n}%s;\n", global_types[i+1].class_info.name);

            for(j = 0; j < global_types[i+1].class_info.mcount; j++)
            {
                generate_function(global_types[i+1].class_info.methodes[j], 1);
            }
            // next type already generate!
            i++;

        }
    }

    // generating global variables
    fprintf(hout, "\n/* global variables */\n", fname2);
    for (i=0; i < main->vcount; i++)
    {
        if (main->vars[i].mod != _none)
            fprintf(hout, "%s ", mod_to_str(main->vars[i].mod));
        fprintf(hout, "%s ", main->vars[i].type);

        fprintf(hout, "%s;\n", main->vars[i].name);
    }

    for (i=0; i < global_functions_count; i++)
    {
        if(!global_functions[i]->cdef)
            generate_function(global_functions[i], 0);
    }
    fclose(out);
    fclose(hout);
    free(ext);
    free(ext2);
    free(fname2);
    return fname;
}