Пример #1
0
static void chlabs(Term t)
{
	if(is_list(t))
	{
		List l;
		for(l=t;l;l=ListTail(l))
		{
			Term m=ListFirst(l);
			if(is_label(m))
				ChangeList(l,ListNth(labm,ListMember(labl,m)));
			else
				chlabs(m);
		}
	}
	if(is_compound(t))
	{
		int i;
		for(i=1;i<=CompoundArity(t);i++)
		{
			Term m=CompoundArgN(t,i);
			if(is_label(m))
				SetCompoundArg(t,i,ListNth(labm,ListMember(labl,m)));
			else
				chlabs(m);
		}
	}
}
Пример #2
0
static void lablist(Term t)
{
	if(is_list(t))
	{
		List l;
		for(l=t;l;l=ListTail(l))
		{
			Term m=ListFirst(l);
			if(is_label(m) && !ListMember(labl,m))
				labl=AppendFirst(labl,m);
			else
				lablist(m);
		}
	}
	if(is_compound(t))
	{
		int i;
		for(i=1;i<=CompoundArity(t);i++)
		{
			Term m=CompoundArgN(t,i);
			if(is_label(m) && !ListMember(labl,m))
				labl=AppendFirst(labl,m);
			else
				lablist(m);
		}
	}
}
Пример #3
0
static void	set_champ_labels(t_labels **labels, char **file_content)
{
  int		cur_case;

  cur_case = -1;
  while (file_content[++cur_case])
    {
      if (is_instruction(file_content[cur_case]) != -1 &&
	  is_label(file_content[cur_case]) != -1 && !(*labels))
	add_label(labels, ".");
      if (is_label(file_content[cur_case]) != -1)
	add_label(labels, get_label(file_content[cur_case]));
    }
}
Пример #4
0
int assemble(uint32_t *out_buf, char *asm_buf) {
	char asm_line[COL_MAX];
	char term0[COL_MAX];
	output_alias = out_buf;

	while (mygets(asm_line, asm_buf, COL_MAX) != NULL) {
		if (set_term0(asm_line, term0) == 1) {
			if (is_comment(asm_line, term0)) {
				// blank(comment)
			} else if (is_directive(asm_line, term0)) {
				exec_directive(asm_line, term0);
			} else if (is_label(asm_line, term0)) {
				register_label(asm_line, term0);
			} else { 
				encode_and_output(asm_line, term0);
			}
		} else {
			// blank(empty line)
		}
		input_line_cnt++;
	}

	resolve_label();

	return output_cnt;
}
Пример #5
0
void first_pass(char *file_in) {
    FILE *fp = fopen(file_in, "r");
    char info[512];
    while (!feof(fp)) {
        fscanf(fp, "%511[^\n]\n", info);
        if (!is_empty(info)) {
            program_counter += 4;
            if (is_label(info)) {
                printf("info: %s - PC: %i\n", info, program_counter - 4);
                program_counter -= 4;
                strtok(info, ":");
                char *copy = (char *) calloc(512, sizeof(char));
    		    alloc_check(copy, "first_pass");
                strcpy(copy, info);
                insert_addr_label(addr_label, copy, program_counter);
            }
        }
    }
    print_addr_label_list();
    memory_end = program_counter;
    ldr_const_array = (uint32_t *) calloc(memory_end, sizeof(uint32_t));    
    alloc_check(ldr_const_array, "first_pass");
    program_counter = 0;
    fclose(fp);
}
Пример #6
0
/*
  This function sorts the first token of the record. The first token can be an
  instruction, a directive or a label. Anything else results in an error,
  indicated here as type UNKNOWN. It gets called again when the first token is
  a LABEL to determine the type of the following token.
*/
struct firsttoken sort(char *token){
  struct firsttoken result;
  struct symbol_entry* entry;
  result.instptr = NULL;
  result.dirptr = NULL;
  result.type = UNKNOWN;

  if(result.instptr = get_inst(token)){       //Check INST list
    result.type = INST;
    return result;
  }
  else if(result.dirptr = get_dir(token)){    //Check DIR list
    result.type = DIR;
    return result;
  }
  else if(is_label(token)){                   //Check Label rules
    result.type = LABEL;
    if(entry = get_entry(token)){
      if(entry->type == REGTYPE){       //Ensures that the "valid" label is
        result.type = UNKNOWN;          //not a register. If it's a reg
      }                                 //return UNKNOWN to show error.
    }
    return result;
  }
  else if(*token = ';'){                //For the cases in which the comment
    result.type = COMMENT;              //starts further into the line
  }
  return result;                        //If none of the above return UNKNOWN
}
Пример #7
0
static int 	parse_label(t_parser *parser, char **my_tab, t_labels **list)
{
  if (my_tab && my_tab[0] && my_tab[0][0] != '\n'
      && my_tab[0][0] != COMMENT_CHAR)
  {
    if (is_label(my_tab[0]) == 1)
    {
      if (exist(my_tab[0], (*list)) == 1)
      {
        label_already_error(parser->line_nb, my_tab[0]);
        return (1);
      }
      else
      {
        if (add_label(my_tab[0], parser->current_address, list) == 0)
          return (1);
        if (my_tab[1] != NULL)
          parse_line_instruction(parser, my_tab + 1);
      }
    }
    else
    {
      if (parse_line_instruction(parser, my_tab) == 1)
        return (1);
    }
  }
  return (0);
}
Пример #8
0
instruction* make_instruction(char** tokens) {
	if (is_label(*tokens)) {
		return decode_mnemonic_instruction_with_label(tokens);
	}
	if (is_a_minemonic(*tokens)) {
		return decode_mnemonic_instruction(tokens);
	} else if (is_a_diretiva(*tokens)) {
		return decode_diretiva_instruction(tokens);
	}

	return NULL ;
}
static void add_label(struct brw_program_instruction *i)
{
    struct label_item **p = &label_table;

    assert(is_label(i));

    while(*p)
        p = &((*p)->next);
    *p = calloc(1, sizeof(**p));
    (*p)->name = label_name(i);
    (*p)->addr = i->inst_offset;
}
Пример #10
0
void
M2c::do_proc_def(ProcDef *pd)
{
    const char *cur_pname = (get_name(pd)).chars();
    debug(3, "Processing procedure %s", cur_pname);

    // create a list to hold any .file op's found in the middle
    // of the text segment -- cannot print them there
    List<IdString> file_strings;

    claim(is_kind_of<InstrList>(get_body(pd)), "Body is not an InstrList");
    cur_body = static_cast<InstrList*>(get_body(pd));

    printer->print_proc_begin(pd);

    // print the procedure symbol table
    process_sym_table(pd->get_symbol_table());

    // walk the instruction list once to record all vr defs
    cur_handle = start(cur_body);
    process_vr_decls(pd);
    cur_handle = start(cur_body);

    Instr *mi = *cur_handle;
    if (mi->peek_annote(k_proc_entry) == NULL) {
	// Entry point to procedure is not the first instruction,
	// generate goto to instruction with k_proc_entry note.
	fprintf(out, "\n\tgoto %s_entry_pt;\n", cur_pname);
    } else {
	// simple entry point
	claim(is_null(mi));
	++cur_handle;	
    }

    // output procedure body
    while (cur_handle != end(cur_body)) {
	mi = *cur_handle;

	// do some work on a non-simple procedure entry point
	if (mi->peek_annote(k_proc_entry) != NULL) {
	    // generate label for earlier goto
	    claim(is_null(mi));
	    fprintf(out, "\n%s_entry_pt:\n", cur_pname);
	}
	printer->print_instr(mi);
	++cur_handle;
    }
    // procedure body must not end with a label
    if (is_label(mi))
	fputs("\t/* empty statement */;\n", out);
    fprintf(out, "}\t/* end of %s */\n\n", cur_pname);
}
Пример #11
0
char	is_valid_line(char *line, int line_number)
{
	if (ft_strlen(line) > 0)
	{
		if (is_name_descr(line) || is_comment_descr(line) || is_empty_line(line)
			|| is_comment_line(line) || is_command(line) || is_label(line))
			return (1);
		ft_putstr_fd("Line n ", 2);
		ft_putnbr_fd(line_number, 2);
		ft_putendl_fd(" is wrong formated", 2);
		return (0);
	}
	return (1);
}
Пример #12
0
static void	set_labels_instruction(t_labels **labels, char **file_content)
{
  int		cur_case;
  t_labels	*labls;

  cur_case = -1;
  labls = *labels;
  while (file_content[++cur_case])
    {
      if (is_label(file_content[cur_case]) != -1)
	labls = search_in_labels(labls, get_label(file_content[cur_case]));
      if (is_instruction(file_content[cur_case]) != -1)
	add_instruction(&(labls->lst_cmd),
			get_name_instruction(file_content[cur_case]),
			get_params(get_instruction(file_content[cur_case])));
    }
}
/*
 * Receive an opened source file.
 */
hashtable_t *create_instruction_symbol_table(FILE *source_file, uint32_t *number_of_instructions) {

  hashtable_t *hashtable = create_hashtable(MACHINE_MEMORY_CAPACITY);

  /*Allocate memory for line with the added NULL character. */
  char *line = (char*) malloc((MAX_LENGTH_OF_LINE + 1) * sizeof(char));

  int counter_address = 0;
  *number_of_instructions = 0;

  //Reads one line at a time until it reaches the end of file.
  while(fgets(line, MAX_LENGTH_OF_LINE, source_file) != NULL) {
    
    //If it encounters an empty line it just moves to the next line.
    if(isEmpty(line) || (line[0] == '/' && line[1] == '/')) {
      continue;
    }

    //Replaces the new line character with a null character.
    char *new_line_char;
    if((new_line_char = strchr(line, '\n')) != NULL) {
      *new_line_char = '\0';
    }
 
    //If the line read represents a label then it is inserted into the symbol hash table.
    if(is_label(line)) {
      char *label = line;
      *(label + (strlen(label) - 1)) = '\0';
      insert_pair(hashtable, label, counter_address);
      continue;
    }

    counter_address += BYTES_PER_INSTRUCTION;
     (*number_of_instructions)++;
  }

  free(line);

  return hashtable;
}
Пример #14
0
int		gere_instruction(char **words, char *s, t_asmline *line)
{
  char		*lbl;

  if (words[0] && is_label(words[0]))
    {
      line->code = -1;
      lbl = my_strdup(words[0]);
      get_command_args(words, line->argv);
      line->argv[0] = lbl;
    }
  else if (words[0] && words[1])
    {
      line->code = get_command_id(words[0]);
      get_command_arg_type(words + 1, line->type);
      get_command_args(words + 1, line->argv);
    }
  else
    return (0);
  if (line->code > 0)
    verif_args(line, s);
  return (1);
}
Пример #15
0
bool	is_command(char **words, char *s, t_cmd *line, char **label_index)
{
  char	*lbl;

  if (words[0] && is_label(words[0]))
    {
      line->cmd_code = T_LABEL;
      lbl = my_strdup(words[0]);
      get_command_args(words, line->arg.argv);
      line->arg.argv[0] = lbl;
      (void)label_index;
    }
  else if (words[0] && words[1])
    {
      line->cmd_code = get_command_id(words[0]);
      get_command_arg_type(words + 1, line->arg.type);
      get_command_args(words + 1, line->arg.argv);
    }
  else
    return (FALSE);
  if (line->cmd_code > T_NONE)
    check_args(line, s);
  return (TRUE);
}
Пример #16
0
Term ProcLet(Term t, Term ind)
	{
	Term t1,nm,sub,kl=0;
	List il,ol,l1;	
	int transf_fl=0;
	
	Atom anti1=0, anti2=0;
	
	ol=il=NewList();
	t1=ConsumeCompoundArg(t,1);
	FreeAtomic(t);
	
	t1=ProcessAlias(t1);
	
	if(is_compound(t1) && CompoundArity(t1)==2 && CompoundName(t1)==OPR_COMMA)
		{
		Term a1,a2;
		a1=ConsumeCompoundArg(t1,1);
		a2=ConsumeCompoundArg(t1,2);
		FreeAtomic(t1);
		ProcLet(MakeCompound1(OPR_LET,a1),0);
		ProcLet(MakeCompound1(OPR_LET,a2),0);
		return 0;
		}
		
		
	if(!is_compound(t1) || CompoundArity(t1)!=2 || 
	 (CompoundName(t1)!=OPR_EQSIGN && CompoundName(t1)!=OPR_RARROW))
		{
		ErrorInfo(325);
		printf("bad argument in let statement\n");
		return 0;
		}
		
	if(CompoundName(t1)==OPR_EQSIGN && is_atom(CompoundArg1(t1)) &&
		is_atom(CompoundArg2(t1)) &&
		(CompoundArg2(t1)==A_GAMMA5 || GetAtomProperty(CompoundArg2(t1),
		A_GAMMA5)))
		{
		SetAtomProperty(CompoundArg1(t1),A_GAMMA5,NewInteger(1));
		}
		
	if(CompoundName(t1)==OPR_RARROW)
		transf_fl=1;
	
	if(CompoundName(t1)==OPR_EQSIGN && is_atom(CompoundArg1(t1)) &&
			is_compound(CompoundArg2(t1)) && 
			CompoundName(CompoundArg2(t1))==A_ANTI &&
			is_atom(CompoundArg1(CompoundArg2(t1))))
		{
		anti1=CompoundArg1(t1);
		anti2=CompoundArg1(CompoundArg2(t1));
		}
		
	nm=ConsumeCompoundArg(t1,1);
	sub=ConsumeCompoundArg(t1,2);
	FreeAtomic(t1);
	
	if(transf_fl)
		allow_transf_lets=0;
	
	if(is_compound(nm) && (CompoundName(nm)==OPR_USCORE ||
								 CompoundName(nm)==OPR_CARET))
		nm=SplitIndices(nm,&il);
	
	if(!is_atom(nm))
		{
		ErrorInfo(325);
		printf("bad left argument in let call\n");
		FreeAtomic(sub);
		FreeAtomic(t1);
		return 0;
		}
		
	if(transf_fl)
		{
		if(!is_parameter(nm) && !is_particle(nm,NULL))
			{
			ErrorInfo(728);
			printf("Unknown object '%s'.\n",AtomValue(nm));
			return 0;
			}
		}
	
	if(GetAtomProperty(nm,A_KEEP_LETS))
	{
		Term prp;
		kl=ExprTo1kl(CopyTerm(sub));
		if(kl==0)
			return 0;
		prp=GetAtomProperty(nm,A_KEEP_LETS);
		SetCompoundArg(prp,1,kl);
	}
	
	sub=ExprTo1(sub);
	
	alg1_set_cos0(sub);
	
	if(sub==0)
		return 0;
	if(transf_fl)
		allow_transf_lets=1;
			
	t1=CopyTerm(CompoundArg2(sub));

	
	if(is_empty_list(il))
		{
		l1=t1;
		while(!is_empty_list(l1))
			{
			Term t;
			t=CompoundArg2(ListFirst(l1));
			if(!is_label(t))
				{
				ErrorInfo(326);
				printf("unbalanced index '");
				WriteTerm(t);
				printf("' in let statement\n");
				FreeAtomic(sub);
				FreeAtomic(t1);
				FreeAtomic(ol);
				return 0;
				}
			ol=AppendLast(ol,t);
			l1=ListTail(l1);
			}
		/* mk_let(nm,sub,ol,t1); */
		}
	else
		{
		List t2;
		t2=0;
		if(ListLength(il)!=ListLength(t1))
				{
				ErrorInfo(327);
				printf("distinct indices number ");
				printf("in let statement.\n");
				FreeAtomic(sub);
				FreeAtomic(t1);
				return 0;
				}			
		l1=t1;
		while(!is_empty_list(l1))
			{
			Term t;
			t=CompoundArg2(ListFirst(l1));
			if(!is_atom(t) || !ListMember(il,t))
				{
				ErrorInfo(326);
				printf("unbalanced index '");
				WriteTerm(t);
				printf("' in let statement\n");
				FreeAtomic(sub);
				FreeAtomic(t1);
				FreeAtomic(ol);
				return 0;
				}
			ol=AppendLast(ol,t);
			l1=ListTail(l1);
			}
		l1=il;
		while(!is_empty_list(l1))
			{
			List l2;
			if(!ListMember(ol,ListFirst(l1)))
				{
				ErrorInfo(326);
				printf("unbalanced index '");
				WriteTerm(t);
				printf("' in let statement\n");
				FreeAtomic(sub);
				FreeAtomic(t1);
				FreeAtomic(ol);
				return 0;
				}
				
			for(l2=t1;l2;l2=ListTail(l2))
				if(ListFirst(l1)==CompoundArg2(ListFirst(l2)))
					{
					t2=AppendLast(t2,ListFirst(l2));
					break;
					}
				
			l1=ListTail(l1);
			}
		RemoveList(t1);
		t1=t2;
		FreeAtomic(ol);
		ol=il;		
		}	
	
	/* mk_let(nm,sub,ol,t1); */
	
	
	l1=t1;
	while(!is_empty_list(l1))
		{
		SetCompoundArg(ListFirst(l1),2,0);
		l1=ListTail(l1);
		}
		
	/*WriteTerm(sub); puts(""); getchar();*/

		
	t=MakeCompound(OPR_LET,5);
	SetCompoundArg(t,1,sub);
	SetCompoundArg(t,2,ol);
	SetCompoundArg(t,3,alg1_inv_alg(sub));
	
	
	if(transf_fl==0)
		{
		Term tt;
		tt=alg1_guess_mpl(sub);
		if(tt)
		{
			SetCompoundArg(t,4,NewInteger(1));
			SetCompoundArg(t,5,tt);
		}
		else
		{
			int tp;
			tt=alg1_guess_mtr(sub, &tp);
			if(tt)
			{
				SetCompoundArg(t,4,NewInteger(tp));
				SetCompoundArg(t,5,tt);
			}
		}
		
		ReportRedefined(nm,"let-substitution");
		SetAtomProperty(nm,PROP_INDEX,t1);
		SetAtomProperty(nm,PROP_TYPE,t);
		alg1_let_cw(nm);
		if(anti1 && anti2)
			{
			SetAtomProperty(anti1,A_ANTI,anti2);
			SetAtomProperty(anti2,A_ANTI,anti1);
			}
		else
			if(only_prm(CompoundArg1(t)))
				SetAtomProperty(nm,A_ANTI,nm);
		return 0;
		}
		
	l1=GetAtomProperty(nm,PROP_INDEX);
	if(!EqualTerms(l1,t1))
		{
		ErrorInfo(729);
		puts("transformed object has other indices types");
		return 0;
		}
	if(GetAtomProperty(nm,OPR_LET))
		{
		WarningInfo(0);
		printf("Warning: transformation rule for '%s' is redefined.\n",
			AtomValue(nm));
		}
	SetAtomProperty(nm,OPR_LET,t);
	return 0;
	}
Пример #17
0
int main(int argc, char ** argv)
{
    long filesize;
    uint8_t *filebuf;
    char disbuf[1024];
    z80inst instbuf;
    uint8_t * cur;
    FILE * f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    filesize = ftell(f);
    fseek(f, 0, SEEK_SET);
    filebuf = malloc(filesize);
    fread(filebuf, 1, filesize, f);
    fclose(f);
    deferred *def = NULL, *tmpd;
    uint16_t offset = 0;
    for(uint8_t opt = 2; opt < argc; ++opt) {
        if (argv[opt][0] == '-') {
            FILE * address_log;
            switch (argv[opt][1])
            {
            case 'l':
                labels = 1;
                break;
            case 'a':
                addr = 1;
                break;
            case 'o':
                only = 1;
                break;
            case 'f':
                opt++;
                if (opt >= argc) {
                    fputs("-f must be followed by a filename\n", stderr);
                    exit(1);
                }
                address_log = fopen(argv[opt], "r");
                if (!address_log) {
                    fprintf(stderr, "Failed to open %s for reading\n", argv[opt]);
                    exit(1);
                }
                while (fgets(disbuf, sizeof(disbuf), address_log)) {
                    if (disbuf[0]) {
                        uint16_t address = strtol(disbuf, NULL, 16);
                        if (address) {
                            def = defer(address, def);
                            reference(address);
                        }
                    }
                }
                break;
            case 's':
                opt++;
                if (opt >= argc) {
                    fputs("-s must be followed by a start offset in hex\n", stderr);
                    exit(1);
                }
                offset = strtol(argv[opt], NULL, 16);
                break;
            }
        } else {
            uint16_t address = strtol(argv[opt], NULL, 16);
            def = defer(address, def);
            reference(address);
        }
    }
    uint16_t start = offset;
    uint8_t *encoded, *next;
    uint32_t size;
    if (!def || !only) {
        def = defer(start, def);
    }
    uint16_t address;
    while(def) {
        do {
            encoded = NULL;
            address = def->address;
            if (!is_visited(address)) {
                encoded = filebuf + address - offset;
            }
            tmpd = def;
            def = def->next;
            free(tmpd);
        } while(def && encoded == NULL);
        if (!encoded) {
            break;
        }
        for(;;) {
            if ((address - offset) > filesize || is_visited(address) || address < offset) {
                break;
            }
            visit(address);
            next = z80_decode(encoded, &instbuf);
            address += (next-encoded);
            encoded = next;

            //z80_disasm(&instbuf, disbuf);
            //printf("%X: %s\n", address, disbuf);
            switch (instbuf.op)
            {
            case Z80_JR:
                address += instbuf.immed;
                encoded = filebuf + address - offset;
                break;
            case Z80_JRCC:
                reference(address + instbuf.immed);
                def = defer(address + instbuf.immed, def);
                break;
            case Z80_JP:
                address = instbuf.immed;
                encoded = filebuf + address - offset;
                break;
            case Z80_JPCC:
            case Z80_CALL:
            case Z80_CALLCC:
            case Z80_RST:
                reference(instbuf.immed);
                def = defer(instbuf.immed, def);
                break;
            default:
                if (z80_is_terminal(&instbuf)) {
                    address = filesize + 1;
                }
            }
        }
    }
    if (labels) {
        for (address = filesize; address < (64*1024); address++) {
            if (is_label(address)) {
                printf("ADR_%X equ $%X\n", address, address);
            }
        }
        puts("");
    }
    for (address = offset; address < filesize + offset; address++) {
        if (is_visited(address)) {
            encoded = filebuf + address - offset;
            z80_decode(encoded, &instbuf);
            if (labels) {
                /*m68k_disasm_labels(&instbuf, disbuf);
                if (is_label(instbuf.address)) {
                	printf("ADR_%X:\n", instbuf.address);
                }
                if (addr) {
                	printf("\t%s\t;%X\n", disbuf, instbuf.address);
                } else {
                	printf("\t%s\n", disbuf);
                }*/
            } else {
                z80_disasm(&instbuf, disbuf, address);
                printf("%X: %s\n", address, disbuf);
            }
        }
    }
    return 0;
}
Пример #18
0
        {
        std::cerr << filename << ":" << line_num << ": Unknown preprocessor directive";
        cli_exit(-1);
        }
      }
    // comment
    else if(std::regex_search(line, result, std::regex("^\s*//\s*(.*)")))
      {
      continue;
      }
    // #ifdef
    else if(std::regex_search(line, result, std::regex("^#ifdef (.+)")))
      {
      std::string label = *result.begin();

      label_stack_t::iterator it = std::find_if(label_stack.begin(), label_stack.end(), is_label(label));
      if(it == label_stack.end())
        {
        num_disable = num_disable + 1;
        label_stack.push_back(label_stack_t::value_type(label, 1));
        }
      continue;
      }
    // #ifndef
    else if(std::regex_search(line, result, std::regex("^#ifndef (.+)")))
      {
      std::string label = *result.begin();

      label_stack_t::iterator it = std::find_if(label_stack.begin(), label_stack.end(), is_label(label));
      if(it != label_stack.end())
        {
int main(int argc, char **argv)
{
	char *output_file = NULL;
	char *entry_table_file = NULL;
	FILE *output = stdout;
	FILE *export_file;
	struct brw_program_instruction *entry, *entry1, *tmp_entry;
	int err, inst_offset;
	char o;
	void *mem_ctx;

	while ((o = getopt_long(argc, argv, "e:l:o:g:abW", longopts, NULL)) != -1) {
		switch (o) {
		case 'o':
			if (strcmp(optarg, "-") != 0)
				output_file = optarg;

			break;

		case 'g': {
			char *dec_ptr, *end_ptr;
			unsigned long decimal;

			gen_level = strtol(optarg, &dec_ptr, 10) * 10;

			if (*dec_ptr == '.') {
				decimal = strtoul(++dec_ptr, &end_ptr, 10);
				if (end_ptr != dec_ptr && *end_ptr == '\0') {
					if (decimal > 10) {
						fprintf(stderr, "Invalid Gen X decimal version\n");
						exit(1);
					}
					gen_level += decimal;
				}
			}

			if (gen_level < 40 || gen_level > 90) {
				usage();
				exit(1);
			}

			break;
		}

		case 'a':
			advanced_flag = 1;
			break;
		case 'b':
			binary_like_output = 1;
			break;

		case 'e':
			need_export = 1;
			if (strcmp(optarg, "-") != 0)
				export_filename = optarg;
			break;

		case 'l':
			if (strcmp(optarg, "-") != 0)
				entry_table_file = optarg;
			break;

		case 'W':
			warning_flags |= WARN_ALL;
			break;

		default:
			usage();
			exit(1);
		}
	}
	argc -= optind;
	argv += optind;
	if (argc != 1) {
		usage();
		exit(1);
	}

	if (strcmp(argv[0], "-") != 0) {
		input_filename = argv[0];
		yyin = fopen(input_filename, "r");
		if (yyin == NULL) {
			perror("Couldn't open input file");
			exit(1);
		}
	}

	brw_init_context(&genasm_brw_context, gen_level);
	mem_ctx = ralloc_context(NULL);
	brw_init_compile(&genasm_brw_context, &genasm_compile, mem_ctx);

	err = yyparse();

	if (strcmp(argv[0], "-"))
		fclose(yyin);

	yylex_destroy();

	if (err || errors)
		exit (1);

	if (output_file) {
		output = fopen(output_file, "w");
		if (output == NULL) {
			perror("Couldn't open output file");
			exit(1);
		}

	}

	if (read_entry_file(entry_table_file)) {
		fprintf(stderr, "Read entry file error\n");
		exit(1);
	}
	inst_offset = 0 ;
	for (entry = compiled_program.first;
		entry != NULL; entry = entry->next) {
	    entry->inst_offset = inst_offset;
	    entry1 = entry->next;
	    if (entry1 && is_label(entry1) && is_entry_point(entry1)) {
		// insert NOP instructions until (inst_offset+1) % 4 == 0
		while (((inst_offset+1) % 4) != 0) {
		    tmp_entry = calloc(sizeof(*tmp_entry), 1);
		    tmp_entry->insn.gen.header.opcode = BRW_OPCODE_NOP;
		    entry->next = tmp_entry;
		    tmp_entry->next = entry1;
		    entry = tmp_entry;
		    tmp_entry->inst_offset = ++inst_offset;
		}
	    }
	    if (!is_label(entry))
              inst_offset++;
	}

	for (entry = compiled_program.first; entry; entry = entry->next)
	    if (is_label(entry))
		add_label(entry);

	if (need_export) {
		if (export_filename) {
			export_file = fopen(export_filename, "w");
		} else {
			export_file = fopen("export.inc", "w");
		}
		for (entry = compiled_program.first;
			entry != NULL; entry = entry->next) {
		    if (is_label(entry))
			fprintf(export_file, "#define %s_IP %d\n",
				label_name(entry), (IS_GENx(5) ? 2 : 1)*(entry->inst_offset));
		}
		fclose(export_file);
	}

	for (entry = compiled_program.first; entry; entry = entry->next) {
	    struct relocation *reloc = &entry->reloc;

	    if (!is_relocatable(entry))
		continue;

	    if (reloc->first_reloc_target)
		reloc->first_reloc_offset = label_to_addr(reloc->first_reloc_target, entry->inst_offset) - entry->inst_offset;

	    if (reloc->second_reloc_target)
		reloc->second_reloc_offset = label_to_addr(reloc->second_reloc_target, entry->inst_offset) - entry->inst_offset;

	    if (reloc->second_reloc_offset) { // this is a branch instruction with two offset arguments
                set_branch_two_offsets(entry, reloc->first_reloc_offset, reloc->second_reloc_offset);
	    } else if (reloc->first_reloc_offset) {
                set_branch_one_offset(entry, reloc->first_reloc_offset);
	    }
	}

	if (binary_like_output)
		fprintf(output, "%s", binary_prepend);

	for (entry = compiled_program.first;
		entry != NULL;
		entry = entry1) {
	    entry1 = entry->next;
	    if (!is_label(entry))
		print_instruction(output, &entry->insn.gen);
	    else
		free(entry->insn.label.name);
	    free(entry);
	}
	if (binary_like_output)
		fprintf(output, "};");

	free_entry_point_table(entry_point_table);
	free_hash_table(declared_register_table);
	free_label_table(label_table);

	fflush (output);
	if (ferror (output)) {
	    perror ("Could not flush output file");
	    if (output_file)
		unlink (output_file);
	    err = 1;
	}
	return err;
}