⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oxccai.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
			/* 1 ADDRESS MODE */
			case jmploopop:
			case jmpcontinueop:
			case jmpbreakop:
			case jmpgotoop:
				ENCODE(jmp, LWORD, s1: LOCATION, dat: pnode->d.data->Uulong);
				break;
			case ljmptrueop:
			case ljmpfalseop:
			case jmptrueop:
			case jmpfalseop:
				break;
			case retdataop:
				break;

			/* 2 ADDRESS MODE */
			case getvalop:
			case derefop:
			case assignop:
			case duptmpop:
			case truthop:
			case negop:
			case complop:
			case notop:
			case copyop:
			case castop:
			case clrdatop:
			case compsavop:
			case totmpop:
			case retstructop:
			case switchop:
			case argop:
				break;

			/* 3 ADDRESS MODE */
			case plusop:
			case minusop:
			case mulop:
			case divop:
			case lshop:
			case rshop:
			case modop:
			case orop:
			case xorop:
			case andop:
				break;
			case eqop:
			case neqop:
			case ltop:
			case gtop:
			case leop:
			case geop:
				break;
			case getbitfieldop:
			case putbitfieldop:
				break;
			case callfuncop:
				break;

			default:
				break;
		}
		return iv->cod_usedtail;
}
static int
get_size(int type, int size)
{
	switch(type)
	{
		case	D_ARRAY:
		case	D_STRUCT:
		case	D_FUNCTION:
			return 4;

		default:
			return size;
	}
	return 0;
}
static void
set_op(PND pnd, PopA ptr, unsigned char otype)
{
unsigned char optype  = otype & 0xe0;
unsigned char isize = otype & 0x1f;

	pnd->data = (DATUM *)ptr;
	if(optype <= OPIMMED4)
	{
		pnd->dtype = optype >> 5;
		pnd->quals = Q_CONST;
		pnd->size = isize;
		pnd->opsize = get_size(pnd->dtype, isize);
		pnd->atype = A_IMMED;
#if 0
		switch(pnd->dtype)
		{
			case D_SIGNED:
			{
				if(isize > 8)
				{
					memcpy(&pnd->data, ptr, isize);
				}
				else if(isize == 8)
				{
					pnd->data.Udouble = *((double*)ptr);
				}
				else
				{
				long l[2];
					l[0] = 0;
					l[1] = 0;
					if(isize == 4)
						l[0] = *((long*)ptr);
					else if(isize == 2)
						l[0] = *((short*)ptr);
					else if(isize == 1)
						l[0] = *((char*)ptr);
					if(l[0] < 0)
						l[1] = -1;
					pnd->data.Udouble = *((double*)l);
				}
				break;
			}
			case D_UNSIGNED:
			case D_POINTER:
			{
				if(isize > 8)
				{
					memcpy(&pnd->data, ptr, isize);
				}
				else if(isize == 8)
				{
					pnd->data.Udouble = *((double*)ptr);
				}
				else
				{
				unsigned long l[2];
					l[0] = 0;
					l[1] = 0;
					if(isize == 4)
						l[0] = *((unsigned long*)ptr);
					else if(isize == 2)
						l[0] = *((unsigned short*)ptr);
					else if(isize == 1)
						l[0] = *((unsigned char*)ptr);
					pnd->data.Udouble = *((double*)l);
				}
				break;
			}
			case D_FLOAT:
			{
				if(isize == 4)
				{
					pnd->data.Udouble = *((float*)ptr);
				}
				else if(isize > 8)
				{
#if SUPPORT_LONG_DOUBLE
					pnd->data.Ulongdouble = *((long double)ptr);
#else
					pnd->data.Udouble = 0.0;
#endif
				}
				else
				{
					pnd->data.Udouble = *((double*)ptr);
				}
				break;
			}
		}/* END: switch */
#endif
	} /* END: OPIMMED */
	else
	{
	unsigned short type = GS(ptr->dtype);
		pnd->dtype = type & 0xff;
		pnd->quals = (type >> 8) & 0xff;
		pnd->size = GL(ptr->dsize);
		pnd->opsize = get_size(pnd->dtype, pnd->size);
		pnd->atype = GS(ptr->atype);

		if(optype == OPAUTO)
		{
			if(GL(ptr->pofs) >= 0)
			{
				pnd->atype &= ~A_AUTO;
				pnd->atype |= A_PARAM;
			}
		}
	}
}
static void *
decode_anf(Piv iv, unsigned char *p)
{
void *dptr;
void *lptr;
void *rptr;

	if(iv->debug >= '1')
		cfeprintf("DECODE inst(%u) `%s'\n", *p, oxgenops[*p]);

	if(*p == 0)
		return POP->next;

	iv->ob->p = p;
	switch(*p)
	{
		case regainop:
		case grabop:
		case retvoidop:
		{/* 0 address mode */
			break;
		}
		case jmploopop:
		case jmpcontinueop:
		case jmpbreakop:
		case jmpgotoop:
		case ljmptrueop:
		case jmptrueop:
		case ljmpfalseop:
		case jmpfalseop:
		case funcstartop:
		case funcstopop:
		case retdataop:
		{/* 1 address mode */
			dptr = (p+8);
			set_op(&iv->ob->d, dptr, p[1]);
			break;
		}
		case getvalop:
		case derefop:
		case assignop:
		case duptmpop:
		case truthop:
		case aliastmpop:
		case negop:
		case complop:
		case notop:
		case copyop:
		case clrdatop:
		case compsavop:
		case totmpop:
		case retstructop:
		case switchop:
		case argop:
		case castop:
		{/* 2 address mode */
			dptr = (p+8);
			lptr = (((char*)dptr) + (p[1] & 0x1f));
			set_op(&iv->ob->d, dptr, p[1]);
			set_op(&iv->ob->l, lptr, p[2]);
			break;
		}
		case plusop:
		case minusop:
		case mulop:
		case divop:
		case modop:
		case orop:
		case xorop:
		case andop:
		case eqop:
		case neqop:
		case ltop:
		case gtop:
		case leop:
		case geop:
		case lshop:
		case rshop:
		case getbitfieldop:
		case callfuncop:
		case putbitfieldop:
		{/* 3 address mode */
			dptr = (p+8);
			lptr = (((char*)dptr) + (p[1] & 0x1f));
			rptr = (((char*)lptr) + (p[2] & 0x1f));
			set_op(&iv->ob->d, dptr, p[1]);
			set_op(&iv->ob->l, lptr, p[2]);
			set_op(&iv->ob->r, rptr, p[3]);
			break;
		}
		default:
		{
			return POP->next;
		}
	}/* END: switch(*p) */

	/* Save pointers to the machine instructions generated by this ANF code */
	iv->ob->startinst = iv->cod;
	iv->ob->endinst = gen_inst(iv, iv->ob);

	if(iv->cod != iv->ob->startinst)
	{/* instructions were generated */
		link_ob(iv);
	}
	return POP->next;
}/* END: decode_anf() */

static void *
skip_bracket(unsigned char *p)
{
long opcode = *p;
int opcount = 0;

	for(;;)
	{
		if(*p == opcode)
			++opcount;
		else if(*p == endop && GL(POP->data) == opcode)
		{
			if(--opcount == 0) {
				return p;
			}
		}
		else if(*p == endfileop || *p == endallop)
		{
			PERROR(pName ":ERROR: Malformed input file3=%u=%p",*p, p);
		}
		p = POP->next;
	}
	return 0;
}
static void *
do_arrayelem(Piv iv, unsigned char *p)
{/* Arrange output for the stack machine */
void *sp = p;
unsigned char *q = skip_bracket(p);
void *sadims[10];
void *sadimsq[10];
void *spdims[10];	
void *spdimsq[10];
int sacnt, spcnt, i;

	/* Scan over the bracket and pick up the dimension computations */
	sacnt = spcnt = 0;
	p = POP->next;
	while(p < q)
	{
		if(*p == arraydimsop)
		{
		void *qq = skip_bracket(p);
			sadims[sacnt] = p;
			sadimsq[sacnt++] = qq;
			p = qq;
		}
		else if(*p == ptrdimsop)
		{
		void *qq = skip_bracket(p);
			spdims[spcnt] = p;
			spdimsq[spcnt++] = qq;
			p = qq;
		}
		p = POP->next;
	}
	/* Dump the dimension computations in stack order */
	for(i = spcnt-1; i >= 0; --i)
	{
		do_bracket(iv, spdims[i], spdimsq[i]);
	}
	for(i = sacnt-1; i >= 0; --i)
	{
		do_bracket(iv, sadims[i], sadimsq[i]);
	}

	/* Dump the remainder of the array element bracket */
	p = sp;
	sacnt = spcnt = 0;
	p = POP->next;
 	while(p < q)
	{
		if(*p == arraydimsop)
			p = ((Pop)sadimsq[sacnt++])->next;
		else if(*p == ptrdimsop)
			p = ((Pop)spdimsq[spcnt++])->next;
		else
			p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static int
funcret_used(PopT op, unsigned char *p)
{
long tmpnum;
	if(		op->dtype == 0
		&&	op->dsize == 0)
	{
		return 1;						/* void function */
	}
	tmpnum = op->tmpnum;

	while(*p != funcexitop)
	{
		if(*p && *p <= (unsigned char)100)
		{
		unsigned char *qp = p+8;
			if(*p == callfuncop)
			{/* function using same temp */
				if(GL(((PopT)qp)->tmpnum) == tmpnum)
				{
					return 1;		/* not used earlier */
				}
			}
			else
			{
				if((p[1]&0xe0) == OPRET)
				{
 					if(GL(((PopT)qp)->tmpnum) == tmpnum)
					{
						return 0;			/* ret used */
					}
				}				
				qp += p[1]&0x1f;
				if((p[2]&0xe0) == OPRET)
				{
					if(GL(((PopT)qp)->tmpnum) == tmpnum)
					{
						return 0;			/* ret used */
					}
				}
				qp += p[2]&0x1f;
				if((p[3]&0xe0) == OPRET)
				{
					if(GL(((PopT)qp)->tmpnum) == tmpnum)
					{
						return 0;			/* ret used */
					}
				}
			}
		}
		p = POP->next;
	}
	return 1;					/* ret not used */
}
static unsigned char
check_for_builtin(Piv iv, unsigned char *p, int flag)
{
short symnum;
long key[2];
unsigned char *result;

	if(flag == 0)
	{
		symnum = GS(((PopA)(p+20))->symnum);
	}
	else if(flag == 1)
	{
		symnum = GS(((PopI)(p+16))->s.symnum);
	}
	else if(flag == 2)
	{
		symnum = GS(POPI->s.symnum);
	}
	else return 0;

	key[0] = symnum;
	key[1] = 0;
	if(SymFind(iv->builtintbl, key, &result) == 1)
		return *result;
	return 0;
}
static void *
do_funcall(Piv iv, unsigned char *p)
{
void *sp = p;
unsigned char *q = skip_bracket(p);
int argcnt, i, dump;
void *argloads[100];
void *argloadsq[100];
char *callop = 0;
unsigned char builtin = 0;

	/* Scan over the bracket and pick up argument loads */
	argcnt = 0;
	p = POP->next;
	while(p < q)
	{
		if(*p == getvalop && callop == 0)
		{
			builtin = check_for_builtin(iv, p, 0);
		}
		else if(*p == callfuncop)
			callop = p;
		else if(*p == argloadop)
		{
		void *qq = skip_bracket(p);
			argloads[argcnt] = p;
			argloadsq[argcnt++] = qq;
			p = qq;
		}
		p = POP->next;
	}

	/* Check out whether the function return is used */
	dump = funcret_used((PopT)(callop+8), q);

	/* Calling an interpreter builtin ?? */
	if(builtin)
	{
		iv->in_builtin = 1;

		/* Dump the argument loads in order */
		/* The ARG instruction will be suppressed because iv->in_builtin > 0 */
		for(i = 0; i < argcnt; ++i)
		{
			do_bracket(iv, argloads[i], argloadsq[i]);
		}
	}
	else
	{
		/* Generate the CALLSETUP instruction */
		p = sp;
		p = POP->next;
		while(p < q)
		{
			if(*p == argloadop)
				break;
			else
				p = do_something(iv, p);
		}			

		/* Dump the argument loads in order */
		for(i = 0; i < argcnt; ++i)
		{
			do_bracket(iv, argloads[i], argloadsq[i]);
		}
		/* Generate the CALL instruction */
	}
	return ((Pop)q)->next;
}
static void *
do_cond(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_twopath(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_logical(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_binop(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_strelem(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_ptrelem(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_argload(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_preincr(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}
	return ((Pop)q)->next;
}
static void *
do_postincr(Piv iv, unsigned char *p)
{
unsigned char *q = skip_bracket(p);

	p = POP->next;
	while(p < q)
	{
	  p = do_something(iv, p);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -