Example #1
0
/*
 *	DEFW
 */
int op_dw(void)
{
	register int i, len, temp;
	register char *p;
	register char *s;

	if (!gencode)
		return(0);
	p = operand;
	i = len = 0;
	if (pass == 1)
		if (*label)
			put_label();
	while (*p) {
		s = tmp;
		while (*p != ',' && *p != '\0')
			*s++ = *p++;
		*s = '\0';
		if (pass == 2) {
			temp = eval(tmp);
			ops[i++] = temp & 0xff;
			ops[i++] = temp >> 8;
			if (i >= OPCARRAY)
				fatal(F_INTERN, "Op-Code buffer overflow");
		}
		len += 2;
		if (*p == ',')
			p++;
	}
Example #2
0
/*
 *	Pass 1:
 *	  - process one line of source
 *
 *	Output: 1 line processed
 *		0 EOF
 */
int p1_line(void)
{
	register char *p;
	register int i;
	register struct opc *op;

	if ((p = fgets(line, MAXLINE, srcfp)) == NULL)
		return(0);
	c_line++;
	p = get_label(label, p);
	p = get_opcode(opcode, p);
	p = get_arg(operand, p);
	if (strcmp(opcode, ENDFILE) == 0)
		return(0);
	if (*opcode) {
		if ((op = search_op(opcode)) != NULL) {
			i = (*op->op_fun)(op->op_c1, op->op_c2);
			if (gencode)
				pc += i;
		} else
			asmerr(E_ILLOPC);
	} else
		if (*label)
			put_label();
	return(1);
}
Example #3
0
//
// Output all code and labels in the peep list.
//
void PeepList::flush()
{
	static bool first = true;
	txtoStream* oofs;
	OCODE *ip;

/*
	if (pass == 2) {
		if (first) {
			compiler.storeTables();
			first = false;
		}
		oofs = new txtoStream();
		oofs->open(irfile, std::ios::out | std::ios::app);
		currentFn->pl.storeHex(*oofs);
		oofs->close();
		delete oofs;
	}
*/
	for (ip = head; ip; ip = ip->fwd)
	{
		if (ip->opcode == op_label)
			put_label((int)ip->oper1, "", GetNamespace(), 'C');
		else
			ip->store(ofs);
	}
}
Example #4
0
void doinit(SYM *sp)
{
	char lbl[200];

	lbl[0] = 0;
	if (sp->storage_class == sc_thread) {
		seg(tlsseg);
		nl();
	}
	else if (sp->storage_class == sc_static || lastst==assign) {
		seg(dataseg);          /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	else {
		seg(bssseg);            /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	if(sp->storage_class == sc_static || sp->storage_class == sc_thread) {
		put_label(sp->value.i, sp->name);
	}
	else {
		if (sp->storage_class == sc_global)
			strcpy(lbl, "public ");
		strcat(lbl, sp->name);
		gen_strlab(lbl);
	}
	if( lastst != assign) {
		genstorage(sp->tp->size);
	}
	else {
		NextToken();
		InitializeType(sp->tp);
	}
    endinit();
}
Example #5
0
void dump_muldivval(void)
{
	int tag = FALSE;
	if (prm_asmfile) {
		fprintf(outputFile,"\n");
		if (muldivlink) {
			tag = TRUE;
			align(4);
		}
		while (muldivlink) {
			put_label(muldivlink->label);
			if (muldivlink->size == 0)
				fprintf(outputFile,"\tDD\t0%xH\n",muldivlink->value);
			else if (muldivlink->size == 6)
				fprintf(outputFile,"\tDD\t%f\n",muldivlink->floatvalue);
			else if (muldivlink->size == 8)
				fprintf(outputFile,"\tDQ\t%f\n",muldivlink->floatvalue);
			else
				fprintf(outputFile,"\tDT\t%f\n",muldivlink->floatvalue);
			muldivlink = muldivlink->link;
		}
		if (tag)
			fprintf(outputFile,"\n");
	}
}
Example #6
0
/*
 *	DEFM
 */
int op_dm(void)
{
	register int i;
	register char *p;

	if (!gencode)
		return(0);
	i = 0;
	p = operand;
	if (pass == 1)
		if (*label)
			put_label();
	if (*p != STRSEP) {
		asmerr(E_MISHYP);
		return(0);
	}
	p++;
	while (*p != STRSEP) {
		if (*p == '\n' || *p == '\0') {
			asmerr(E_MISHYP);
			break;
		}
		ops[i++] = *p++;
		if (i >= OPCARRAY)
			fatal(F_INTERN, "Op-Code buffer overflow");
	}
	return(i);
}
Example #7
0
PRIVATE void put_storage P1 (SYM *, sp)
{
    SIZE    al = alignment_of_type (typeof (sp));

    put_bseg (al);
    if (is_static (sp)) {
	put_label (sp->value.l);
    } else {
	put_name (sp);
    }
    oprintf ("\t.space\t%ld%s", typeof (sp)->size, newline);
}
Example #8
0
/*
 *      output all code and labels in the peep list.
 */
void flush_peep()
{
	if (opt_nopeep==FALSE)
		opt_peep();         /* do the peephole optimizations */
  while( peep_head != NULL )
  {
		if( peep_head->opcode == op_label )
			put_label((int64_t)peep_head->oper1,"",GetNamespace(),'C');
		else
			put_ocode(peep_head);
		peep_head = peep_head->fwd;
  }
}
Example #9
0
/*

 * output all code and labels in the peep list.
 */
void flush_peep P1 (unsigned, level)
{
    register CODE *ip;
    SWITCH *sw;
    EXPR   *ep2;
    LABEL   i;

    opt3 (level);		/* do the peephole optimizations */
    for (ip = peep_head; ip != NIL_CODE; ip = ip->fwd) {
	if (ip->opcode == op_label) {
	    put_label (ip->oper1->u.offset->v.l);
	} else
	    put_code (ip);
    }
    peep_head = NIL_CODE;
    for (sw = swtables; sw; sw = sw->next) {
	put_kseg (alignment_of_type (tp_pointer));
	put_label (sw->tablab);
	ep2 = mk_lcon (UNDEF_LABEL);
	/* generate the switch jump table as a series of 2-byte offsets
	 * This limits the amount of code that can be generated in a
	 * function to less then 32K.  I believe that this is a reasonable
	 * restriction.
	 */
	{
	    EXPR   *ep, *ep1;

	    ep1 = mk_lcon (sw->beglab);
	    ep = mk_node (en_sub, ep2, ep1, tp_void);
	    for (i = 0; i < sw->numlabs; i++) {
		ep2->v.l = sw->labels[i];
		put_short (ep);
	    }
	}
    }
    swtables = NIL_SWITCH;
}
Example #10
0
/*
 *	DEFS
 */
int op_ds(void)
{
	register int val;

	if (!gencode)
		return(0);
	if (pass == 1)
		if (*label)
			put_label();
	sd_val = pc;
	sd_flag = 3;
	val = eval(operand);
	if ((pass == 2) && !dump_flag)
		obj_fill(val);
	pc += val;
	return(0);
}
Example #11
0
void dumplits(void)
/*
 *      dump the string literal pool.
 */
{
        while( strtab != 0) {
                cseg();
                nl();
                put_label(strtab->label);
								genstring(strtab->str,strtab->type);
								if (strtab->type)
									genword(0);
								else
									genbyte(0);
                strtab = strtab->next;
                }
        nl();
}
Example #12
0
void doinit(SYM *sp)
{
	char lbl[200];

	lbl[0] = 0;
	if (sp->storage_class == sc_thread) {
		seg(tlsseg);
		nl();
	}
	else if (sp->storage_class == sc_static || lastst==assign) {
		seg(dataseg);          /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	else {
		seg(bssseg);            /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	if(sp->storage_class == sc_static || sp->storage_class == sc_thread) {
		put_label(sp->value.i, sp->name, GetNamespace(), 'D');
	}
	else {
		if (sp->storage_class == sc_global) {
			strcpy(lbl, "public ");
			if (curseg==dataseg)
				strcat(lbl, "data ");
			else if (curseg==bssseg)
				strcat(lbl, "bss ");
			else if (curseg==tlsseg)
				strcat(lbl, "tls ");
		}
		strcat(lbl, sp->name);
		gen_strlab(lbl);
	}
	if( lastst != assign) {
		genstorage(sp->tp->size);
	}
	else {
		NextToken();
		InitializeType(sp->tp);
	}
    endinit();
	if (sp->storage_class == sc_global)
		fprintf(output,"\nendpublic\n");
}
Example #13
0
/*
 *      dump the string literal pool.
 */
void dumplits()
{
    char            *cp;

    cseg();
    nl();
    align(8);
    nl();
    while( strtab != NULL) {
        nl();
        put_label(strtab->label,strtab->str);
        cp = strtab->str;
        while(*cp)
            GenerateChar(*cp++);
        GenerateChar(0);
        strtab = strtab->next;
    }
    nl();
}
Example #14
0
/*
 *	DEFB
 */
int op_db(void)
{
	register int i;
	register char *p;
	register char *s;

	if (!gencode)
		return(0);
	i = 0;
	p = operand;
	if (pass == 1)
		if (*label)
			put_label();
	while (*p) {
		if (*p == STRSEP) {
			p++;
			while (*p != STRSEP) {
				if (*p == '\n' || *p == '\0') {
					asmerr(E_MISHYP);
					goto hyp_error;
				}
				ops[i++] = *p++;
				if (i >= OPCARRAY)
				    fatal(F_INTERN, "Op-Code buffer overflow");
			}
			p++;
		} else {
			s = tmp;
			while (*p != ',' && *p != '\0')
				*s++ = *p++;
			*s = '\0';
			ops[i++] = eval(tmp);
			if (i >= OPCARRAY)
				fatal(F_INTERN, "Op-Code buffer overflow");
		}
		if (*p == ',')
			p++;
	}
hyp_error:
	return(i);
}
Example #15
0
/*
 * dump the string literal pool.
 * if we are producing single copies of strings (which should therefore
 * be read only we put them in the text segment - else in the data segment.
 */
PRIVATE void put_literals P0 (void)
{
    const CHAR *cp;
    size_t  len;

    if (lang_option == LANG_KANDR) {
	put_dseg (alignment_of_type (tp_char));
    } else {
	put_kseg (alignment_of_type (tp_char));
    }
    for (; strtab != 0; strtab = strtab->next) {
	nl ();
	put_label (strtab->label);
	cp = strtab->str;
	for (len = strtab->len; len--;)
	    put_byte ((UVAL) *cp++);
	put_byte (Ox0UL);

    }
    nl ();
}
Example #16
0
void doinit(SYM *sp)
{
	static bool first = true;
	char lbl[200];
  int algn;
  enum e_sg oseg;
  char buf[500];
  std::streampos endpoint;
	TYP *tp;

  hasPointer = false;
  if (first) {
	  firstPrim = true;
	  first = false;
  }

  oseg = noseg;
	lbl[0] = 0;
	// Initialize constants into read-only data segment. Constants may be placed
	// in ROM along with code.
	if (sp->isConst) {
    oseg = rodataseg;
  }
	if (sp->storage_class == sc_thread) {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,8);
        else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,8);
        else
            algn = 2;
		seg(oseg==noseg ? tlsseg : oseg,algn);
		nl();
	}
	else if (sp->storage_class == sc_static || lastst==assign) {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,8);
        else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,8);
        else
            algn = 2;
		seg(oseg==noseg ? dataseg : oseg,algn);          /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	else {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,8);
        else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,8);
        else
            algn = 2;
		seg(oseg==noseg ? (lastst==assign ? dataseg : bssseg) : oseg,algn);            /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	
	if (sp->storage_class == sc_static || sp->storage_class == sc_thread) {
		//strcpy_s(glbl, sizeof(glbl), gen_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D'));
		if (sp->tp->IsSkippable()) {
			patchpoint = ofs.tellp();
			sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$FFF0200000000001\n");
			ofs.printf(buf);
		}
		sp->realname = my_strdup(put_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D'));
		strcpy_s(glbl2, sizeof(glbl2), gen_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D'));
	}
	else {
		if (sp->storage_class == sc_global) {
			strcpy_s(lbl, sizeof(lbl), "public ");
			if (curseg==dataseg)
				strcat_s(lbl, sizeof(lbl), "data ");
			else if (curseg==bssseg)
				strcat_s(lbl, sizeof(lbl), "bss ");
			else if (curseg==tlsseg)
				strcat_s(lbl, sizeof(lbl), "tls ");
		}
		strcat_s(lbl, sizeof(lbl), sp->name->c_str());
		if (sp->tp->IsSkippable()) {
			patchpoint = ofs.tellp();
			sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$FFF0200000000001\n");
			ofs.printf(buf);
		}
		strcpy_s(glbl2, sizeof(glbl2), sp->name->c_str());
		gen_strlab(lbl);
	}
	if (lastst == kw_firstcall) {
        GenerateByte(1);
        return;
    }
	else if( lastst != assign) {
		hasPointer = sp->tp->FindPointer();
		genstorage(sp->tp->size);
	}
	else {
		NextToken();
		hasPointer = sp->tp->FindPointer();
		typ_sp = 0;
		tp = sp->tp;
		push_typ(tp);
		while (tp = tp->GetBtp()) {
			push_typ(tp);
		}
		brace_level = 0;
		sp->tp->Initialize(nullptr);
		if (sp->tp->numele == 0) {
			if (sp->tp->GetBtp()) {
				if (sp->tp->GetBtp()->type == bt_char || sp->tp->GetBtp()->type == bt_uchar
					|| sp->tp->GetBtp()->type == bt_ichar || sp->tp->GetBtp()->type == bt_iuchar
					) {
					sp->tp->numele = laststrlen;
					sp->tp->size = laststrlen;
				}
			}
		}
	}
	if (!hasPointer && sp->tp->IsSkippable()) {
		endpoint = ofs.tellp();
		ofs.seekp(patchpoint);
		sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$%I64X\n", ((genst_cumulative + 7LL) >> 3LL) | 0xFFF0200000000000LL);
		ofs.printf(buf);
		ofs.seekp(endpoint);
		genst_cumulative = 0;
	}
Example #17
0
void doinit(SYM *sp)
{
	char lbl[200];
  int algn;
  enum e_sg oseg;

  oseg = noseg;
	lbl[0] = 0;
	// Initialize constants into read-only data segment. Constants may be placed
	// in ROM along with code.
	if (sp->isConst) {
    oseg = rodataseg;
  }
	if (sp->storage_class == sc_thread) {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,2);
        else if (sp->tp->type==bt_pointer && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,2);
        else
            algn = 2;
		seg(oseg==noseg ? tlsseg : oseg,algn);
		nl();
	}
	else if (sp->storage_class == sc_static || lastst==assign) {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,2);
        else if (sp->tp->type==bt_pointer && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,2);
        else
            algn = 2;
		seg(oseg==noseg ? dataseg : oseg,algn);          /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	else {
        if (sp->tp->type==bt_struct || sp->tp->type==bt_union)
           algn = imax(sp->tp->alignment,2);
        else if (sp->tp->type==bt_pointer && sp->tp->val_flag)
           algn = imax(sp->tp->GetBtp()->alignment,2);
        else
            algn = 2;
		seg(oseg==noseg ? bssseg : oseg,algn);            /* initialize into data segment */
		nl();                   /* start a new line in object */
	}
	if(sp->storage_class == sc_static || sp->storage_class == sc_thread) {
		sp->realname = my_strdup(put_label(sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D'));
	}
	else {
		if (sp->storage_class == sc_global) {
			strcpy_s(lbl, sizeof(lbl), "public ");
			if (curseg==dataseg)
				strcat_s(lbl, sizeof(lbl), "data ");
			else if (curseg==bssseg)
				strcat_s(lbl, sizeof(lbl), "bss ");
			else if (curseg==tlsseg)
				strcat_s(lbl, sizeof(lbl), "tls ");
		}
		strcat_s(lbl, sizeof(lbl), sp->name->c_str());
		gen_strlab(lbl);
	}
	if (lastst == kw_firstcall) {
        GenerateByte(1);
        return;
    }
	else if( lastst != assign) {
		genstorage(sp->tp->size);
	}
	else {
		NextToken();
		InitializeType(sp->tp);
	}
    endinit();
	if (sp->storage_class == sc_global)
		ofs.printf("\nendpublic\n");
}
Example #18
0
void dumplits()
{
	char *cp;
	int64_t nn;
	slit *lit;

	dfs.printf("<Dumplits>\n");
	roseg();
	if (casetab) {
		nl();
		align(8);
		nl();
	}
	while (casetab != nullptr) {
		nl();
		if (casetab->pass == 2)
			put_label(casetab->label, "", casetab->nmspace, 'D');
		for (nn = 0; nn < casetab->num; nn++) {
			if (casetab->cases[nn].pass==2)
				GenerateLabelReference(casetab->cases[nn].label, 0);
		}
		casetab = casetab->next;
	}
	if (quadtab) {
		nl();
		align(8);
		nl();
	}

	// Dumping to ro segment - no need for GC skip
	/*
	nn = GetQuadtabLen();
	if (nn) {
		sprintf_s(buf, sizeof(buf), "\tdw\t$%I64X ; GC_skip\n", nn | 0xFFF0200000000000LL);
		ofs.printf("%s", buf);
	}
	*/
	while(quadtab != nullptr) {
		nl();
		if (DataLabels[quadtab->label]) {
			put_label(quadtab->label, "", quadtab->nmspace, 'D');
			ofs.printf("\tdh\t");
			quadtab->Pack(64);
			ofs.printf("%s", quadtab->ToString(64));
			outcol += 35;
		}
		quadtab = quadtab->next;
	}
	if (strtab) {
		nl();
		align(8);
		nl();
	}

	//nn = GetStrtabLen();
	//if (nn) {
	//	sprintf_s(buf, sizeof(buf), "\tdw\t$%I64X ; GC_skip\n", nn | 0xFFF0200000000000LL);
	//	ofs.printf("%s", buf);
	//}
	for (lit = strtab; lit; lit = lit->next) {
		ENODE *ep;
		agr = ep = (ENODE *)lit->str;
		dfs.printf(".");
		nl();
		if (!lit->isString) {
			if (DataLabels[lit->label])
				put_label(lit->label, strip_crlf(&lit->str[1]), lit->nmspace, 'D');
		}
		else
			put_label(lit->label,strip_crlf(&lit->str[1]),lit->nmspace,'D');
		if (lit->isString) {
			cp = lit->str;
			switch (*cp) {
			case 'B':
				cp++;
				while (*cp)
					GenerateByte(*cp++);
				GenerateByte(0);
				break;
			case 'C':
				cp++;
				while (*cp)
					GenerateChar(*cp++);
				GenerateChar(0);
				break;
			case 'H':
				cp++;
				while (*cp)
					GenerateHalf(*cp++);
				GenerateHalf(0);
				break;
			case 'W':
				cp++;
				while (*cp)
					GenerateWord(*cp++);
				GenerateWord(0);
				break;
			}
		}
		else {
			if (DataLabels[lit->label]) {
				ep->PutStructConst(ofs);
			}
		}
	}
	strtab = nullptr;
	nl();
	dfs.printf("</Dumplits>\n");
}
Example #19
0
/*
 *  Examines dataflow and checks if data is already in a register
 *  when read-accesses to external ram occurs
 *  needs multiple-passes to work
 */
int flow_dataflow P2 (CODE *, peep_head, int, level)
{
    FLOWLISTENTRY *RegUsage[MAX_REG + 1];
    int     LabelChanges;
    BOOL    headless;		/* is true when currently no entrypoint for code was found 

				 * (after a jump before the first label is found 
				 */
    REG     reg;
    register CODE *ip;
    int     replacecount = 0;
    static int totreplace = 0;

#ifdef DEBUG
    int     Round = 1;

#endif /* DEBUG */

    do {
	DPRINTF ((DEBUG_FLOW, "Dataflow, round %d...", Round++));
	LabelChanges = 0;
	/* currently no entrypoint found */
	headless = FALSE;
	/* clear all lists to start analysis */
	clear_regusage (&(RegUsage[0]));
	for (ip = peep_head; ip != NIL_CODE; ip = ip->fwd) {
	    /*
	     * invalidate all entries with references to registers
	     * modified in this instruction
	     */
	    validate_regusage (ip, &(RegUsage[0]));

	    switch (ip->opcode) {
	    case op_ldi_ldi:
	    case op_ldf_ldf:
		/* destination now references to source */
		new_flow_list (&(RegUsage[ip->dst2->preg]), ip->dst2->preg,
			       ip->src21, ip->type);
		if (is_am_register (ip->src21)) {
		    /* dest references now to the same list of values as source */
		    add_list_to_flow_list (&(RegUsage[ip->dst2->preg]),
					   RegUsage[ip->src21->preg]);
		    /* source refers now also to destination */
		    add_flow_list (&(RegUsage[ip->src21->preg]),
				   ip->src21->preg, ip->dst2, ip->type);
		}
		/*FALLTHRU */
	    case op_ldi:
	    case op_ldf:
	    case op_ldiu:
	    case op_ldfu:
		/* destination now references to source */
		new_flow_list (&(RegUsage[ip->dst->preg]), ip->dst->preg,
			       ip->src1, ip->type);
		if (is_am_register (ip->src1)) {
		    /* dest references now to the same list of values as source */
		    add_list_to_flow_list (&(RegUsage[ip->dst->preg]),
					   RegUsage[ip->src1->preg]);
		    /* source refers now also to destination */
		    add_flow_list (&(RegUsage[ip->src1->preg]),
				   ip->src1->preg, ip->dst, ip->type);
		}
		break;

	    case op_ldi_sti:
	    case op_ldf_stf:
		/* destination now references to source */
		new_flow_list (&(RegUsage[ip->dst->preg]), ip->dst->preg,
			       ip->src1, ip->type);
		if (is_am_register (ip->src1)) {
		    /* dest references now to the same list of values as source */
		    add_list_to_flow_list (&(RegUsage[ip->dst->preg]),
					   RegUsage[ip->src1->preg]);
		    /* source refers now also to destination */
		    add_flow_list (&(RegUsage[ip->src1->preg]),
				   ip->src1->preg, ip->dst, ip->type);
		}
		/* source of sti refers now also to destination */
		add_flow_list (&(RegUsage[ip->src21->preg]), ip->src21->preg,
			       ip->dst2, ip->type);
		break;

	    case op_sti_sti:
	    case op_stf_stf:
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src2->preg]), ip->src2->preg,
			       ip->dst2, ip->type);
		/*FALLTHRU */
	    case op_sti:
	    case op_stf:
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			       ip->dst, ip->type);
		break;

	    case op_absf_stf:
	    case op_absi_sti:
	    case op_addf3_stf:
	    case op_addi3_sti:
	    case op_and3_sti:
	    case op_ash3_sti:
	    case op_fix_sti:
	    case op_float_stf:
	    case op_lsh3_sti:
	    case op_mpyf3_stf:
	    case op_mpyi3_sti:
	    case op_negf_stf:
	    case op_negi_sti:
	    case op_not_sti:
	    case op_or3_sti:
	    case op_subf3_stf:
	    case op_subi3_sti:
	    case op_xor3_sti:
		/* source of sti refers now also to destination */
		add_flow_list (&(RegUsage[ip->src2->preg]), ip->src2->preg,
			       ip->dst2, ip->type);
		if ((ip->dst != NULL) && (is_am_register (ip->dst))) {
		    /* destination of operation does not reference to anywhere now */
		    RegUsage[ip->dst->preg] = NULL;
		}
		break;

	    case op_blo:
	    case op_bls:
	    case op_bhi:
	    case op_bhs:
	    case op_beq:
	    case op_bne:
	    case op_blt:
	    case op_ble:
	    case op_bgt:
	    case op_bge:
	    case op_bz:
	    case op_bnz:
	    case op_bp:
	    case op_bn:
	    case op_bnn:
		/* attach aktual registerusageinfo to label of jumpdestination */
		LabelChanges +=
		    attach_regusage_to_label (ip, &(RegUsage[0]), level);
		break;

	    case op_label:
		if (headless == TRUE) {
		    /* first entrypoint of this piece of code, so use whole information from label */
		    copy_regusage_from_label (ip, &(RegUsage[0]), level);
		    headless = FALSE;
		} else {
		    /* not first entrypoint, so merge information from label */
		    LabelChanges +=
			merge_regusage_from_label (ip, &(RegUsage[0]), level);
		}
		break;

	    case op_bu:
	    case op_br:
		/* attach aktual registerusageinfo to label of jumpdestination */
		LabelChanges +=
		    attach_regusage_to_label (ip, &(RegUsage[0]), level);
		/* FALLTHRU */

	    case op_retsu:
	    case op_retiu:
		/* no information abaout registers availlable now */
		clear_regusage (&(RegUsage[0]));
		/* since no entrypoint found now (unconditional controltransfer) */
		headless = TRUE;
		break;

	    case op_asm:
		/* clear whole list, asm can do anything to registers and memory */
		clear_regusage (&(RegUsage[0]));
		break;

	    case op_rpts:
	    case op_rptb:
		/* remove all references to and from blockrepeatregisters */
		RegUsage[REG_RC] = NULL;
		RegUsage[REG_RS] = NULL;
		RegUsage[REG_RE] = NULL;
		remove_from_regusage (RegUsage, REG_RC);
		remove_from_regusage (RegUsage, REG_RS);
		remove_from_regusage (RegUsage, REG_RE);
		break;

	    case op_call:
	    case op_trapu:
	    case op_xcall:
	    case op_callu:
		/* remove all references to and from temporary registers */
		clear_tempreg_usage (&(RegUsage[0]));
		/*
		 * we do not know what called routine does
		 * with memory
		 */
		remove_from_regusage (RegUsage, REG_MEMORY);
		/* FALLTHRU */

	    case op_push:
	    case op_pop:
	    case op_pushf:
	    case op_popf:
	    case op_pushnopeep:
	    case op_pushfnopeep:
		/* references from SP are no longer valid */
		RegUsage[REG_SP] = NULL;
		/* FALLTHRU */

	    default:
		if ((ip->dst != NULL) && (is_am_register (ip->dst))) {
		    /* destination of operation does not reference to anywhere now */
		    RegUsage[ip->dst->preg] = NULL;
		}
		if ((ip->dst2 != NULL) && (is_am_register (ip->dst2))) {
		    /* destination of operation does not reference to anywhere now */
		    RegUsage[ip->dst2->preg] = NULL;
		}
		break;

	    }
	}
	DPRINTF ((DEBUG_FLOW, " %d changes \n", LabelChanges));
    } while (LabelChanges != 0);

    DPRINTF ((DEBUG_FLOW, "%s\n", "Dataflow, REPLACEMENT ROUND"));
    LabelChanges = 0;
    /* currently no entrypoint found */
    headless = FALSE;
    /* clear all lists to start analysis */
    clear_regusage (&(RegUsage[0]));
    for (ip = peep_head; ip != NIL_CODE; ip = ip->fwd) {
	/*
	 * invalidate all entries with references to registers
	 * modified in this instruction
	 */
#ifdef ENHANCED_FLOW
	validate_addressregusage (ip, &(RegUsage[0]));
#else
	validate_regusage (ip, &(RegUsage[0]));
#endif
	switch (ip->opcode) {
	case op_ldi_ldi:
	case op_ldf_ldf:
	    if (
		(reg =
		 search_in_regusage (&(RegUsage[0]), ip->src1,
				     ip->type)) >= 0) {
		DPRINTF (
			 (DEBUG_FLOW, "FoundReplacement for src1 %d",
			  (int) reg));
		if (is_exchangable (&(ip->src1), reg)) {
		    replacecount++;
		    totreplace++;
		    Update_Peep_Info (ip);
		}
	    }
	    if (
		(reg =
		 search_in_regusage (&(RegUsage[0]), ip->src21,
				     ip->type)) >= 0) {
		DPRINTF (
			 (DEBUG_FLOW, "FoundReplacement for src21 %d",
			  (int) reg));
		if (is_exchangable (&(ip->src21), reg)) {
		    replacecount++;
		    totreplace++;
		    Update_Peep_Info (ip);
		}
	    }
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* destination now references to source */
	    new_flow_list (&(RegUsage[ip->dst->preg]), ip->dst->preg,
			   ip->src1, ip->type);
	    if (is_am_register (ip->src1)) {
		/* dest references now to the same list of values as source */
		add_list_to_flow_list (&(RegUsage[ip->dst->preg]),
				       RegUsage[ip->src1->preg]);
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			       ip->dst, ip->type);
	    }
	    /* destination now references to source */
	    new_flow_list (&(RegUsage[ip->dst2->preg]), ip->dst2->preg,
			   ip->src21, ip->type);
	    if (is_am_register (ip->src21)) {
		/* dest references now to the same list of values as source */
		add_list_to_flow_list (&(RegUsage[ip->dst2->preg]),
				       RegUsage[ip->src21->preg]);
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src21->preg]), ip->src21->preg,
			       ip->dst2, ip->type);
	    }
	    break;

	case op_ldi:
	case op_ldf:
	case op_ldiu:
	case op_ldfu:
	    if (
		(reg =
		 search_in_regusage (&(RegUsage[0]), ip->src1,
				     ip->type)) >= 0) {
		DPRINTF (
			 (DEBUG_FLOW, "FoundReplacement for src1 %d",
			  (int) reg));
		if (is_exchangable (&(ip->src1), reg)) {
		    replacecount++;
		    totreplace++;
		    Update_Peep_Info (ip);
		}
	    }
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* destination now references to source */
	    new_flow_list (&(RegUsage[ip->dst->preg]), ip->dst->preg,
			   ip->src1, ip->type);
	    if (is_am_register (ip->src1)) {
		/* dest references now to the same list of values as source */
		add_list_to_flow_list (&(RegUsage[ip->dst->preg]),
				       RegUsage[ip->src1->preg]);
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			       ip->dst, ip->type);
	    }
	    break;

	case op_ldi_sti:
	case op_ldf_stf:
	    if (
		(reg =
		 search_in_regusage (&(RegUsage[0]), ip->src1,
				     ip->type)) >= 0) {
		DPRINTF (
			 (DEBUG_FLOW, "FoundReplacement for src1 %d",
			  (int) reg));
		if (is_exchangable (&(ip->src1), reg)) {
		    replacecount++;
		    totreplace++;
		    Update_Peep_Info (ip);
		}
	    }
	    if (
		(reg =
		 search_in_regusage (&(RegUsage[0]), ip->src21,
				     ip->type)) >= 0) {
		DPRINTF (
			 (DEBUG_FLOW, "FoundReplacement for src21 %d",
			  (int) reg));
		if (is_exchangable (&(ip->src21), reg)) {
		    replacecount++;
		    totreplace++;
		    Update_Peep_Info (ip);
		}
	    }
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* destination now references to source */
	    new_flow_list (&(RegUsage[ip->dst->preg]), ip->dst->preg,
			   ip->src1, ip->type);
	    if (is_am_register (ip->src1)) {
		/* dest references now to the same list of values as source */
		add_list_to_flow_list (&(RegUsage[ip->dst->preg]),
				       RegUsage[ip->src1->preg]);
		/* source refers now also to destination */
		add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			       ip->dst, ip->type);
	    }
	    /* source of sti refers now also to destination */
	    add_flow_list (&(RegUsage[ip->src21->preg]), ip->src21->preg,
			   ip->dst2, ip->type);
	    break;

	case op_sti_sti:
	case op_stf_stf:
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* source refers now also to destination */
	    add_flow_list (&(RegUsage[ip->src2->preg]), ip->src2->preg,
			   ip->dst2, ip->type);
	    /* source refers now also to destination */
	    add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			   ip->dst, ip->type);
	    break;

	case op_sti:
	case op_stf:
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* source refers now also to destination */
	    add_flow_list (&(RegUsage[ip->src1->preg]), ip->src1->preg,
			   ip->dst, ip->type);
	    break;


	case op_absf_stf:
	case op_absi_sti:
	case op_addf3_stf:
	case op_addi3_sti:
	case op_and3_sti:
	case op_ash3_sti:
	case op_fix_sti:
	case op_float_stf:
	case op_lsh3_sti:
	case op_mpyf3_stf:
	case op_mpyi3_sti:
	case op_negf_stf:
	case op_negi_sti:
	case op_not_sti:
	case op_or3_sti:
	case op_subf3_stf:
	case op_subi3_sti:
	case op_xor3_sti:
#if 0
/* 
 * sorry, currently no replace possible, since
 * src1 must be r0-r7
 * src2 must be restricted indirect
 * src21 must be r0-r7
 */
	    if (ip->src1 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src1,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src1 %d",
			      reg));
		    if (is_exchangable (&(ip->src1), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    if (ip->src2 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src2,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src2 %d",
			      reg));
		    if (is_exchangable (&(ip->src2), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
#endif
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* source of sti refers now also to destination */
	    add_flow_list (&(RegUsage[ip->src21->preg]), ip->src21->preg,
			   ip->dst2, ip->type);
	    if ((ip->dst != NULL)
		&& (is_am_register (ip->dst))) {
		/* destination of operation does not reference to anywhere now */
		RegUsage[ip->dst->preg] = NULL;
	    }
	    break;
	case op_label:
	    if (headless == TRUE) {
		/* first entrypoint of this piece of code, so use whole information from label */
		copy_regusage_from_label (ip, &(RegUsage[0]), level);
		headless = FALSE;
	    } else {
		/* not first entrypoint, so merge information from label */
		LabelChanges +=
		    merge_regusage_from_label (ip, &(RegUsage[0]), level);
	    }
	    /*
	     *  Remove regusage-entry from label
	     */
	    ip->src21 = NULL;
	    break;

	case op_bu:
	    if ((ip->src1 != NULL) && (ip->src1->mode != am_immed)) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src1,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src1 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src1), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    /* FALLTHRU */
	case op_br:
	    /* FALLTHRU */
	case op_retsu:
	case op_retiu:
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* no information abaout registers availlable now */
	    clear_regusage (&(RegUsage[0]));
	    /* since no entrypoint found now (unconditional controltransfer) */
	    headless = TRUE;
	    break;

	case op_asm:
	    /* clear whole list, asm can do anything to registers and memory */
	    clear_regusage (&(RegUsage[0]));
	    break;

	case op_rpts:
	    if (ip->src1 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src1,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src1 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src1), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    /* FALLTHRU */

	case op_rptb:
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* remove all references to and from blockrepeatregisters */
	    RegUsage[REG_RC] = NULL;
	    RegUsage[REG_RS] = NULL;
	    RegUsage[REG_RE] = NULL;
	    remove_from_regusage (RegUsage, REG_RC);
	    remove_from_regusage (RegUsage, REG_RS);
	    remove_from_regusage (RegUsage, REG_RE);
	    break;

	case op_callu:
	    if ((ip->src1 != NULL) && (ip->src1->mode != am_immed)) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src1,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src1 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src1), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    /* FALLTHRU */
	case op_call:
	case op_trapu:
	case op_xcall:
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    /* remove all references to and from temporary registers */
	    clear_tempreg_usage (&(RegUsage[0]));
	    /*
	     * we do not know what called routine does
	     * with memory
	     */
	    remove_from_regusage (RegUsage, REG_MEMORY);
	    /* FALLTHRU */

	case op_push:
	case op_pop:
	case op_pushf:
	case op_popf:
	case op_pushnopeep:
	case op_pushfnopeep:
	    /* references from SP are no longer valid */
	    RegUsage[REG_SP] = NULL;
	    /* FALLTHRU */

	default:
	    if (ip->src1 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src1,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src1 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src1), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    if (ip->src2 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src2,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src2 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src2), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    if (ip->src21 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src21,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src21 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src21), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
	    if (ip->src22 != NULL) {
		if (
		    (reg =
		     search_in_regusage (&(RegUsage[0]), ip->src22,
					 ip->type)) >= 0) {
		    DPRINTF (
			     (DEBUG_FLOW, "FoundReplacement for src22 %d",
			      (int) reg));
		    if (is_exchangable (&(ip->src22), reg)) {
			replacecount++;
			totreplace++;
			Update_Peep_Info (ip);
		    }
		}
	    }
#ifdef USE_ALL_OPCODES
	    /* FALLTHRU */
	    /* do no replacements with parallel mul/add */
	case op_mpf3_adf3:
	case op_mpf3_sbf3:
	case op_mpi3_adi3:
	case op_mpi3_sbi3:
#endif /* USE_ALL_OPCODES */
#ifdef ENHANCED_FLOW
	    validate_regusage (ip, &(RegUsage[0]));
#endif
	    if ((ip->dst != NULL) && (is_am_register (ip->dst))) {
		/* destination of operation does not reference to anywhere now */
		RegUsage[ip->dst->preg] = NULL;
	    }
	    if ((ip->dst2 != NULL) && (is_am_register (ip->dst2))) {
		/* destination of operation does not reference to anywhere now */
		RegUsage[ip->dst2->preg] = NULL;
	    }
	    break;

	}
#ifdef DEBUG
	if (is_debugging (DEBUG_FLOW)) {
	    FHANDLE save = output;

	    output = debugfile;
	    if (ip->opcode == op_label) {
		put_label (ip->src1->u.offset->v.l);
	    } else {
		put_code (ip);
	    }
	    output = save;
	    print_regusage (&(RegUsage[0]));
	}
#endif /* DEBUG */
    }
    DPRINTF ((DEBUG_FLOW, "Replaced %d ", replacecount));
    DPRINTF ((DEBUG_FLOW, "Total %d \n", totreplace));
    return replacecount;
}