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

📄 pass2.c

📁 < 虚拟机设计与实现> 的source code, linux版本
💻 C
📖 第 1 页 / 共 4 页
字号:
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		case 'N':
			if (strcmp((*tptr).text, "NOT") == 0)
			{ 
				I2R(NOT, tptr);
			}
			else if (strcmp((*tptr).text, "NOP") == 0)
			{ 
				I(NOP, tptr);
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		case 'O':
			if (strcmp((*tptr).text, "OR") == 0)
			{ 
				I3R(OR, tptr);
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		case 'P':
			if (strcmp((*tptr).text, "PUSHB") == 0)
			{ 
				IR(PUSHB, tptr);
			}
			else if (strcmp((*tptr).text, "PUSHW") == 0)
			{ 
				IR(PUSHW, tptr);
			}
			else if (strcmp((*tptr).text, "PUSHD") == 0)
			{ 
				IR(PUSHD, tptr);
			}
			else if (strcmp((*tptr).text, "PUSHQ") == 0)
			{ 
				IR(PUSHQ, tptr);
			}
			else if (strcmp((*tptr).text, "PUSHF1") == 0)
			{ 
				IF(PUSHF1, tptr);
			}
			else if (strcmp((*tptr).text, "PUSHF2") == 0)
			{ 
				ID(PUSHF2, tptr);
			}
			else if (strcmp((*tptr).text, "POPB") == 0)
			{ 
				IR(POPB, tptr);
			}
			else if (strcmp((*tptr).text, "POPW") == 0)
			{ 
				IR(POPW, tptr);
			}
			else if (strcmp((*tptr).text, "POPD") == 0)
			{ 
				IR(POPD, tptr);
			}
			else if (strcmp((*tptr).text, "POPQ") == 0)
			{ 
				IR(POPQ, tptr);
			}
			else if (strcmp((*tptr).text, "POPF1") == 0)
			{ 
				IF(POPF1, tptr);
			}
			else if (strcmp((*tptr).text, "POPF2") == 0)
			{ 
				ID(POPF2, tptr);
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		case 'S':
			if (strcmp((*tptr).text, "SB") == 0)
			{ 
				I2R(SB, tptr);
			}
			else if (strcmp((*tptr).text, "SW") == 0)
			{ 
				I2R(SW, tptr);
			}
			else if (strcmp((*tptr).text, "SD") == 0)
			{ 
				I2R(SD, tptr);
			}
			else if (strcmp((*tptr).text, "SQ") == 0)
			{ 
				I2R(SQ, tptr);
			}
			else if (strcmp((*tptr).text, "SF1") == 0)
			{ 
				IFR(SF1, tptr);
			}
			else if (strcmp((*tptr).text, "SF2") == 0)
			{ 
				IDR(SF2, tptr);
			}
			else if (strcmp((*tptr).text, "SRA") == 0)
			{ 
				I3R(SRA, tptr);
			}
			else if (strcmp((*tptr).text, "SRL") == 0)
			{ 
				I3R(SRL, tptr);
			}
			else if (strcmp((*tptr).text, "SL") == 0)
			{ 
				I3R(SL, tptr);
			}
			else if (strcmp((*tptr).text, "SUB") == 0)
			{ 
				I3R(SUB, tptr);
			}
			else if (strcmp((*tptr).text, "SLT") == 0)
			{ 
				I3R(SLT, tptr);
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		case 'X':
			if (strcmp((*tptr).text, "XOR") == 0)
			{ 
				I3R(XOR, tptr);
			}
			else
			{
				ERROR2("processInstructionPass2(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
				return;
			}
            break;
			
		default:
			ERROR3("processInstructionPass2(): %s on line %lu type %s not a valid opcode\n", 
				              (*tptr).text, (*tptr).line, TokStr[(*tptr).type]);
			return;
		}/*end switch*/
	}
	else
	{
		ERROR3("processInstructionPass2(): %s on line %lu type %s not a valid opcode\n",
			       (*tptr).text, (*tptr).line, TokStr[(*tptr).type]);
	}
	return;

}

void I(U1 opcode, struct Token *tptr) /* Instruction */
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;
	
	nBYTES = 1;
	sprintf(lineNumber, "%lu", (*tptr).line);

	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = opcode;

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("I(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}

/*------------------------------------------------------------------*/

void IB(U1 opcode, struct Token * tptr)
{
	char number[8];
	struct Token t;
	U1 bRet;
	U1 nBYTES;

	nBYTES = 2; 

	sprintf(lineNumber, "%lu", (*tptr).line);

	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = opcode;

	bRet = match(&t, TOK_INT_CONST);
	if (bRet == TRUE)
	{
		sprintf(number, "%d", (U1)t.val);
		strcat(listingfile_line, number);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("IB(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("IB(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}/*end IB*/

/*-----------------------------------------------------------------*/

void IR(U1 opcode, struct Token * tptr) /* Instruction IntegerRegister */
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;

	nBYTES = 2;

	sprintf(lineNumber, "%lu", (*tptr).line);

	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = opcode;

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("IR(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("IR(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}/*end IR*/

/*------------------------------------------------------------------*/

/* Instruction IntegerRegister Constant */

void IRC(U1 opcode, U1 bytes, struct Token *tptr) 
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;

	nBYTES = 2 + bytes; /*bytes = 1,2,4,8 ( byte->qword )*/

	sprintf(lineNumber, "%lu", (*tptr).line);

	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = opcode;

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("IRC(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}

	bRet = match(&t, TOK_COMMA);
	if (bRet == TRUE)
	{ 
		strcat(listingfile_line, t.text); 
	}
	else
	{ 
        ERROR2("IRC(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;  
	}

	t = getNextLineToken();
	if (t.type == TOK_INT_CONST)
	{
		strcat(listingfile_line, t.text);
		switch (bytes)
		{
		case 1:
			encoded[2] = (U1)t.val; 
			break;
			
		case 2:
			wordToBytecode((U2)t.val, &encoded[2]);
			break;
			
		case 4:
			dwordToBytecode((U4)t.val, &encoded[2]);
			break;
			
		case 8:
			qwordToBytecode((U8)t.val, &encoded[2]);			break;
		}
	}
	else if (t.type == TOK_CHAR_CONST)
	{
		strcat(listingfile_line, t.text);
		encoded[2] = 0;
		encoded[3] = 0;
		encoded[4] = 0;
		encoded[5] = 0;
		encoded[6] = 0;
		encoded[7] = 0;
		encoded[8] = 0;
		encoded[9] = 0;
		
		/*encode in big-endian format*/
		switch(bytes)
		{
		case 1:
			encoded[2] = (U1)t.val;
			break;
			
		case 2:
			encoded[3] = (U1)t.val;
			break;
			
		case 4:
			encoded[5] = (U1)t.val;
			break;
			
		case 8:
			encoded[9] = (U1)t.val;
			break;
		}
	}
	else
	{ 
        ERROR2("IRC(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("IRC(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;  
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;
	
}/*end IRC*/

/*------------------------------------------------------------------*/

/* Instruction IntegerRegisters identifier */

void IRA(struct Token * tptr) 
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;
	struct HashTbl * hptr;

	nBYTES = 2 + 8; /*address = 8 bytes*/

	sprintf(lineNumber, "%lu", (*tptr).line);

	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = LAD;

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("IRA(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}

	bRet = match(&t,TOK_COMMA);
	if (bRet == TRUE)
	{ 
		strcat(listingfile_line, t.text); 
	}
	else
	{ 
        ERROR2("IRA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;  
	}

	t = getNextLineToken();
	if (t.type == TOK_IDENTIFIER)
	{
		strcat(listingfile_line, t.text);

		/*symbol must exist*/

		hptr = queryHashTbl(t.text);
		if (hptr == NULL)
		{
			ERROR2("IRA(): line %lu, undefined identifier %s\n", t.line, t.text);
			return;
		}
		else
		{
			/*must be symbol type =  PROC, PROC_LBL */

			U8 val;
			if ((*hptr).type == PROC)
			{
				/*resolve offset/address */
				val = (proc[(*hptr).index]).address; 
				qwordToBytecode(val, &encoded[2]); 
			}
			else if ((*hptr).type == PROC_LBL)
			{
				/*resolve offset/address */
				val = (proc[(*hptr).index]).label[(*hptr).subIndex].address;
				qwordToBytecode(val, &encoded[2]); 
			}
			else
			{
				ERROR2("IRA(): line %lu, invalid operand for LAD %s\n", t.line, t.text);
				return;
			}
		}
	}
	else
	{ 
		ERROR2("IRA(): line %lu, invalid constant %s\n", t.line, t.text);
		return; 
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("IRA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}/*end IRA*/

/*------------------------------------------------------------------*/

/* Instruction 2IntegerRegisters identifier */

void I2RA(struct Token * tptr) 
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;
	struct HashTbl *hptr;

	nBYTES = 3 + 8; /*address = 8 bytes*/
	sprintf(lineNumber, "%lu", (*tptr).line);
	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = LAI;

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("I2RA(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}

	bRet = match(&t, TOK_COMMA);
	if (bRet == TRUE)
	{ 
		strcat(listingfile_line, t.text); 
	}
	else
	{ 
        ERROR2("I2RA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[2] = (U1)t.val;
	}
	else
	{ 
        ERROR2("I2RA(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}

	bRet = match(&t, TOK_COMMA);
	if (bRet == TRUE)
	{ 
		strcat(listingfile_line, t.text); 
	}
	else
	{ 
        ERROR2("I2RA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}

	t = getNextLineToken();
	if (t.type == TOK_IDENTIFIER)
	{
		strcat(listingfile_line, t.text);

		/*symbol must exist*/

		hptr = queryHashTbl(t.text);
		if (hptr == NULL)
		{
			ERROR2("I2RA(): line %lu, undefined identifier %s\n", t.line, t.text);
			return;
		}
		else
		{
			/*must be symbol type = GLOBAL_VAR, PROC_RET, PROC_ARG, PROC_LOC */

			S8 val;
			if ((*hptr).type == GLOBAL_VAR)
			{
				/*resolve offset/address */
				val = -((S8)globVar[(*hptr).index].offset);
				qwordToBytecode(val, &encoded[3]); 
			}
			else if ((*hptr).type == PROC_RET)
			{
				/*resolve offset/address */
				val = (proc[(*hptr).index].ret).fpOffset;
				qwordToBytecode(val, &encoded[3]); 
			}
			else if ((*hptr).type == PROC_ARG)
			{
				/*resolve offset/address */
				val = (proc[(*hptr).index]).arg[(*hptr).subIndex].fpOffset;
				qwordToBytecode(val, &encoded[3]); 
			}
			else if ((*hptr).type == PROC_LOC)
			{
				/*resolve offset/address */
				val = (proc[(*hptr).index]).local[(*hptr).subIndex].fpOffset;
				qwordToBytecode(val, &encoded[3]); 
			}
			else
			{
				ERROR2("I2RA(): line %lu, invalid operand for LAI %s\n", t.line, t.text);
				return;
			}
		}
	}
	else
	{ 
		ERROR2("I2RA(): line %lu, invalid constant %s\n", t.line, t.text);
		return; 
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("I2RA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}/*end I2RA*/

/*------------------------------------------------------------------*/

void I2R(U1 opcode, struct Token * tptr) /* Instruction 2IntegerRegisters */
{
	struct Token t;
	U1 bRet;
	U1 nBYTES;

	nBYTES = 3;
	sprintf(lineNumber, "%lu", (*tptr).line);
	strcpy(listingfile_line, (*tptr).text);
	strcat(listingfile_line, " ");
	encoded[0] = opcode;

	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[1] = (U1)t.val;
	}
	else
	{ 
        ERROR2("I2R(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}
					
	bRet = match(&t,TOK_COMMA);
	if (bRet == TRUE)
	{ 
		strcat(listingfile_line, t.text); 
	}
	else
	{ 
        ERROR2("I2R(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}
					
	bRet = match(&t, TOK_INT_REG);
	if (bRet == TRUE)
	{
		strcat(listingfile_line, t.text);
		encoded[2] = (U1)t.val;
	}
	else
	{ 
        ERROR2("I2R(): line %d, invalid operand (%s)\n", (*tptr).line, (*tptr).text);
        return;
	}

	bRet = match(&t, TOK_NO_MORE);
	if (bRet != TRUE)
	{ 
        ERROR2("I2RA(): line %d, invalid opcode (%s)\n", (*tptr).line, (*tptr).text);
        return; 
	}
	commitToFiles(nBYTES);
	bytePosPass2 = bytePosPass2 + nBYTES;
	return;

}/*end I2R*/

⌨️ 快捷键说明

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