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

📄 wasm.cpp

📁 两条5级的并行流水线
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "WASM.h"
#include <iostream>
#include <fstream>
#include <list>
#include <string.h>

using namespace std;

/*
struct Symbol,一个标号
*/
struct Symbol
{
	char *name;
	unsigned long value;
};

/*
struct Instruction,一条指令
若type=LABEL,op1为标号字符串地址
*/
struct Instruction
{
	int type;
	unsigned long code;
	unsigned long op1, op2, op3;
};

/*
struct Param,字符串形式的指令各参数
*/
struct Param
{
	int type;							//0-空,1-普通,2-标号
	int ops;							//操作数数目
	char code[256];						//op
	char op1[256], op2[256], op3[256];
};

/*
显示软件版本等信息
*/
void showInfo(void);

/*
根据错误码显示错误原因
*/
void showError(int err);

/*
完成汇编
*/
int assemble(char *src, char *dst);

/*
firstLoop,记录标号
*/
int firstLoop(ifstream *pIn, list<Symbol> &symbols);

/*
secondLoop,完成输出
*/
int secondLoop(ifstream *pIn, ofstream *pOut, list<Symbol> &symbols);

/*
分离出指令各参数(字符串形式)
*/
int getParam(char *str, Param *param);
/*
将指令op字符串转换为代码
*/
int insEncode(char *str, unsigned long *pCode, int *type);
/*
将寄存器字符串转换为代码
*/
int regEncode(char *str, unsigned long *pCode);
/*
将立即数和标号字符串转换为代码
*/
int numEncode(char *str, unsigned long *value, list<Symbol> &symbols);
/*
是否为伪指令,返回指令总长度
*/
int isMacro(char *str);

int errLine;		//出错行号

void main(int argc, char**argv)
{
	errLine = 0;

	char srcFilename[1024],dstFilename[1024];

	if(argc<=1)
	{
		showInfo();
		return;
	}

	strcpy(srcFilename,argv[1]);

	if(argc>=3)
	{
		strcpy(dstFilename,argv[2]);
	}
	else
	{
		strcpy(dstFilename,srcFilename);

		char *ext;
		ext = strrchr(dstFilename,'.');				//加扩展名
		if(!ext || stricmp(ext, ".asm")&&stricmp(ext, ".txt") )
		{
			int len = strlen(dstFilename);
			ext = dstFilename+len;
		}
		ext[0] = '.';
		ext[1] = 'w';
		ext[2] = 0;
	}

	int err;
	err = assemble(srcFilename, dstFilename);
	if(!err)
	{
		cout << "Assembling succeeded." << endl;
		showInfo();
	}
	else
	{
		cout << "Assembling failed." << endl;
		cout << endl;
		if(errLine!=0)
			cout << "line(" << errLine <<")" << endl;		//出错行号
		showError(err);										//出错原因
		cout << endl;
		showInfo();
	}
}

void showInfo(void)
{
	cout << endl;
	cout << "Wisp CPU Assembler 1.0 - by Quifi - Dec.2005" << endl;
}

void showError(int err)
{
	switch(err)
	{
	case SOURCE_FILE_CANNOT_BE_OPENED:
		cout << "Source file cannot be opened";
		break;
	case DESTINED_FILE_CANNOT_BE_WRITEN:
		cout << "Destined file cannot be written";
		break;
	case UNDEFINED_INSTRUCTION:
		cout << "Undefined instruction";
		break;
	case UNDEFINED_REGISTER:
		cout << "Undefined register";
		break;
	case UNDEFINED_SYMBOL:
		cout << "Undefined symbol";
		break;
	case SYMBOL_REDEFINED:
		cout << "Symbol redefined";
		break;
	case BAD_FORMAT:
		cout << "Bad format";
		break;
	case IMM_OUT_OF_RANGE:
		cout << "Immediate is out of range";
		break;
	case ADDRESS_NOT_ALIGN:
		cout << "Address is not align to 4 bytes";
		break;
	default:
		cout << "Error";
	}
}


int assemble(char *src, char *dst)
{
	int err;
	ifstream in1, in2;
	ofstream out;

	in1.open(src);
	if(!in1.is_open())
	{
		return SOURCE_FILE_CANNOT_BE_OPENED;
	}

	list<Symbol> symbols;

	err = firstLoop(&in1,symbols);
	in1.close();

	if(err)
	{
		return err;
	}

	in2.open(src);
	if(!in2.is_open())
	{
		return SOURCE_FILE_CANNOT_BE_OPENED;
	}
	out.open(dst, ios::binary);
	if(!out.is_open())
	{
		return DESTINED_FILE_CANNOT_BE_WRITEN;
	}

	err = secondLoop(&in2, &out, symbols);

	list<Symbol>::iterator it;
	for(it=symbols.begin(); it!=symbols.end(); ++it)
	{
		delete[] (*it).name;
	}

	in2.close();
	out.close();
	return err;
}


int firstLoop(ifstream *pIn, list<Symbol> &symbols)
{
	errLine=0;								//出错行号归零

	unsigned long ip;
	int err;
	Param param;

	char line[1024];
	Symbol sym;

	ip = 0;

	while(pIn->getline(line, 1024))
	{
		++errLine;
		
		err = getParam(line,&param);
		if(err) return err;					//错误

		if(param.type == EMPTY)				//空行
		{
			continue;
		}

		if(param.type == LABEL)				//标号
		{
			list<Symbol>::iterator it;
			for(it=symbols.begin(); it!=symbols.end(); ++it)
			{
				if(!stricmp((char *)param.code, it->name))
					return SYMBOL_REDEFINED;
			}
			sym.name = new char[strlen((char *)param.code)+1];
			strcpy(sym.name, (char *)param.code);
			sym.value = ip;
			symbols.push_back(sym);
			continue;
		}

		if(param.type == MACRO)				//伪指令
		{
			ip += param.ops;				//param.ops为指令总长
			continue;
		}

		ip += 4;							//普通指令或数据
	}
	return 0;								//成功
}


int secondLoop(ifstream *pIn, ofstream *pOut, list<Symbol> &symbols)
{
	errLine = 0;

	unsigned long ipn;
	int err;
	bool imm;										//是否立即数
	Instruction ins;
	Param param;
	unsigned long dwIns;
	char line[1024];

	ipn = 0;

	while(pIn->getline(line, 1024))
	{
		++errLine;

		err = getParam(line, &param);
		if(err) return err;							//错误

		if(param.type==LABEL || param.type==EMPTY)
		{
			continue;
		}

		if(param.type==DATA)
		{
			numEncode(param.op1, &ins.op1, symbols);
			dwIns =  ins.op1;
			pOut->write((char*)&dwIns, 4);

			ipn += 4;
			continue;
		}

		if(param.type == MACRO)							//伪指令
		{
			if(!stricmp(param.code,"INIT"))				//载入32位立即数(不使用其他寄存器)
			{
				err = regEncode(param.op1, &ins.op1);
				if(err) return err;

				err = numEncode(param.op2, &ins.op2, symbols);
				if(err) return err;

				unsigned long imm16;

				//31:16
				imm16 = (ins.op2 & 0xffff0000)>>16;

				ins.code = 0x1c;
				dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op1<<(32-6-5-5))
					+ ( imm16 );						//LDA rx, imm[31:16]
				pOut->write((char*)&dwIns, 4);

				//15:0
				imm16 = ins.op2 & 0xffff;

				ins.code = 0x1d;
				dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op1<<(32-6-5-5))
					+ ( imm16 );						//LDA32 rx, imm[15:0]
				pOut->write((char*)&dwIns, 4);

				ipn += 8;
				continue;
			}

		}

		err = insEncode(param.code, &ins.code, &ins.type); 
		if(err) return err;							//错误

		if(ins.type == NOP)							//空操作
		{
			dwIns = 0;
		}

		else if(ins.type == MUL)							//乘法
		{
			err = regEncode(param.op1, &ins.op1);
			if(err) return err;
			err = regEncode(param.op2, &ins.op2);
			if(err) return err;
			err = regEncode(param.op3, &ins.op3);
			if(err) return err;
			
			dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5)) 
				+ (ins.op3<<(32-6-5-5-5));
		}
		else if(ins.type == ADD)							//三操作数ALU运算
		{
			err = regEncode(param.op1, &ins.op1);
			if(err) return err;
			err = regEncode(param.op2, &ins.op2);
			if(err) return err;
			if( regEncode(param.op3, &ins.op3) )	//若第三个操作数不是寄存器
			{
				err = numEncode(param.op3, &ins.op3, symbols);
				if(err) return err;
				imm = true;
			}
			else imm = false;
			
			if(imm)				//立即数
			{
				if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
					return IMM_OUT_OF_RANGE;

				dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5)) 
					+ (ins.op3 & 0xffff);
			}
			else				//寄存器
			{
				dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5)) 
					+ (ins.op3<<(32-6-5-5-5));
			}
		}

		else if(ins.type == NOT)							//NOT
		{
			err = regEncode(param.op1, &ins.op1);
			if(err) return err;
			if( regEncode(param.op2, &ins.op2) )	//若第二个操作数不是寄存器
			{
				err = numEncode(param.op2, &ins.op2, symbols);
				if(err) return err;
				imm = true;
			}
			else imm = false;
			
			if(imm)				//立即数
			{
				if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
					return IMM_OUT_OF_RANGE;

				dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2 & 0xffff);
			}
			else				//寄存器
			{
				dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5-5));
			}
		}

		else if(ins.type == CMP)					//CMP&TST
		{
			err = regEncode(param.op1, &ins.op1);
			if(err) return err;
			if( regEncode(param.op2, &ins.op2) )	//若第二个操作数不是寄存器
			{
				err = numEncode(param.op2, &ins.op2, symbols);
				if(err) return err;
				imm = true;
			}
			else imm = false;
			
			if(imm)				//立即数
			{
				if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
					return IMM_OUT_OF_RANGE;

				dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5-5)) + (ins.op2 & 0xffff);
			}
			else				//寄存器
			{
				dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5-5)) + (ins.op2<<(32-6-5-5-5));
			}
		}

		else if(ins.type == MOV)					//MOV
		{
			err = regEncode(param.op1, &ins.op1);
			if(err) return err;
			err = regEncode(param.op2, &ins.op2);
			if(err) return err;

			dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5-5));
		}

		else if(ins.type == JMP)					//JMP imm26/REG
		{
			if( regEncode(param.op1, &ins.op1) )	//若操作数不是寄存器

⌨️ 快捷键说明

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