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

📄 instrumenttype.cpp

📁 mini mips 小型mips软件
💻 CPP
字号:
#include "StdAfx.h"
#include "InstrumentType.h"
#include "CompilingErrorException.h"
#include <fstream>
#include <sstream>
#include <iostream>

map<string, InstrumentInformation>& InstrumentType::infoTable = InitInfoTable();

#ifndef AddOperation
#define AddOperation(name) if (infoTable.find(#name) != infoTable.end()) infoTable[#name].operation=&ALUOp::name
#endif

#ifndef AddOperation2
#define AddOperation2(name) if (infoTable.find(LToD(#name)) != infoTable.end()) infoTable[LToD(#name)].operation=&ALUOp::name
#endif

string LToD(const char* s){
	string ret;
	for (unsigned i = 0; s[i] != '\0'; ++i) ret += (s[i] == '_') ?  '.' : s[i];
	return ret;
}

InstrumentType::InstrumentType(void){
	ifstream fin("Lable.ini");
	string word;
	while (fin >> word){
		lableInstrument.insert(word);
	}
	zeroExtendInstrument.insert("andi");
	zeroExtendInstrument.insert("ori");
}

map<string, InstrumentInformation>& InstrumentType::InitInfoTable(string ininame){
	    map<string, InstrumentInformation>& infoTable = *(new map<string, InstrumentInformation>);
		ifstream fin(ininame.c_str());
		InstrumentInformation item;
		while(fin >> item.name){
			string s;
			item.encoding = "";
			for (int i = 0; i < 8; ++i){
				fin >> s;
				item.encoding += s;
			}
			fin >> item.syntax;
			fin >> item.com;
			infoTable[item.name] = item;
		}
		AddOperation(add);
		AddOperation(addi);
		AddOperation(addiu);
		AddOperation(addu);
		AddOperation(and);
		AddOperation(andi);
		AddOperation(beq);
		AddOperation(bgez);
		AddOperation(bgezal);
		AddOperation(bgtz);
		AddOperation(blez);
		AddOperation(bltz);
		AddOperation(bltzal);
		AddOperation(bne);
		AddOperation(div);
		AddOperation(divu);
		AddOperation(j);
		AddOperation(jal);
		AddOperation(jr);
		AddOperation(lb);
		AddOperation(lui);
		AddOperation(lw);
		AddOperation(mfhi);
		AddOperation(mflo);
		AddOperation(mult);
		AddOperation(multu);
		AddOperation(noop);
		AddOperation(or);
		AddOperation(ori);
		AddOperation(sb);
		AddOperation(sll);
		AddOperation(sllv);
		AddOperation(slt);
		AddOperation(slti);
		AddOperation(sltiu);
		AddOperation(sltu);
		AddOperation(sra);
		AddOperation(srl);
		AddOperation(srlv);
		AddOperation(sub);
		AddOperation(subu);
		AddOperation(sw);
		AddOperation(syscall);
		AddOperation(xor);
		AddOperation(xori);
		AddOperation2(swcl);
		AddOperation2(sdcl);
		AddOperation2(add_s);
		AddOperation2(add_d);
		AddOperation2(div_s);
		AddOperation2(div_d);
		AddOperation2(mul_s);
		AddOperation2(mul_d);
		AddOperation2(sub_s);
		AddOperation2(sub_d);
		AddOperation2(bclt);
		AddOperation2(bclf);
		AddOperation2(c_eq_s);
		AddOperation2(c_eq_d);
		AddOperation2(c_lt_s);
		AddOperation2(c_lt_d);
		AddOperation2(c_le_s);
		AddOperation2(c_le_d);
		AddOperation(mfc0);
		AddOperation(mfc1);
		AddOperation(mtc0);
		AddOperation(mtc1);
		return infoTable;
}

// return the num of arguments of given instrument.
int InstrumentType::ArgumentNumOfInstrument(string name){
	if (name == "syscall" || name == "noop" || name == "nop") return 0;
	return infoTable[name].syntax.length();
}

void InstrumentType::SetAsmCode(vector<string>& asmCode){
	AsmCode = asmCode;
	InstrumentInformation &info = infoCurrentSentence;
	info = infoTable[asmCode[0]];
	for (int j = 0; j < ArgumentNumOfInstrument(info.name); ++j){
		switch (info.syntax[j]){
			case 'd': d = RegisterToInt(asmCode[j + 1], info.com[0]); break;
			case 's': s = RegisterToInt(asmCode[j + 1], info.com[1]); break;
			case 't': t = RegisterToInt(asmCode[j + 1], info.com[2]); break;
			case 'i': i = StringToInt(asmCode[j + 1]); break;
			case 'h': h = StringToInt(asmCode[j + 1]); break;
		}
	}
	int si = 0;
	for (int j = 0; j < 32; ++j) if (info.encoding[j] == 'i') ++si;
	i = extend(i, si, info.name);
	TranslateAsmToBinary();
}

bool InstrumentType::equal(string a, string b){
	if (a.length() != b.length()) return false;
	for (unsigned i = 0; i < a.length(); ++i)
		if (a[i] != b[i] && (a[i] == '0' || a[i] == '1' )) return false;
	return true;
}

void InstrumentType::SetBinaryCode(string& binaryCode){
	// TODO parser d, s, t, i, h
	map<string, InstrumentInformation>::iterator item;
	BinaryCode = binaryCode;
	d = s = t = i = h = 0;
	int si = 0;
	for(item = infoTable.begin(); item != infoTable.end(); ++item)
		if (equal(item->second.encoding, binaryCode)) break;
	if (item == infoTable.end()) throw CompilingErrorException("Unknow binary instrument.");
	infoCurrentSentence = item->second;
	for (int j = 0; j < 32; ++j){
		switch(infoCurrentSentence.encoding[j]){
			case 'd': d = d * 2 + binaryCode[j] - '0'; break;
			case 's': s = s * 2 + binaryCode[j] - '0'; break;
			case 't': t = t * 2 + binaryCode[j] - '0'; break;
			case 'h': h = h * 2 + binaryCode[j] - '0'; break;
			case 'i': i = i * 2 + binaryCode[j] - '0'; ++si; break;
		}
	}
	i = extend(i, si, infoCurrentSentence.name);
	TranslateBinaryToCode();
	TranslateBinaryToAsm();
}

int InstrumentType::extend(int immValue, int length, string& name){
	if (length && name != "j" && name != "jal"	&& name != "andi" && name != "ori" && name != "xori"){
		if (immValue & (1 << (length - 1))){
			for (int i = length; i < 32; ++i) immValue &= 1 << i;
		}
	}
	return immValue;
}

string InstrumentType::TranslateAsmToBinary(){
	//  TODO
	int d = this->d;
	int s = this->s;
	int t = this->t;
	int i = this->i;
	int h = this->h;
	InstrumentInformation &info = infoCurrentSentence;
	BinaryCode = info.encoding;
	for (int j = 31; j >= 0; --j){
		switch(info.encoding[j]){
			case '-': BinaryCode[j] = '0'; break;
			case 'd': BinaryCode[j] = (d & 1) ? '1' : '0'; d >>= 1; break;
			case 's': BinaryCode[j] = (s & 1) ? '1' : '0'; s >>= 1; break;
			case 't': BinaryCode[j] = (t & 1) ? '1' : '0'; t >>= 1; break;
			case 'h': BinaryCode[j] = (h & 1) ? '1' : '0'; h >>= 1; break;
			case 'i': BinaryCode[j] = (i & 1) ? '1' : '0'; i >>= 1; break;
		}
	}
	TranslateBinaryToCode();
	return  BinaryCode;
}

int InstrumentType::StringToInt(string& str){
	istringstream is(str);
	if (str[0] == '$') is.get();
	int value;
	is >> value;
	return value;
}

int InstrumentType::RegisterToInt(string name, char com){
	static GeneralRegister gr;
	if (com == 'g'){
		try{
			return gr.GetID(name);
		}
		catch(RegistersErrorException e){
			throw CompilingErrorException(e.msg);
		}
	}
	return StringToInt(name);
}

string InstrumentType::IntToString(int num){
	ostringstream os;
	os << num;
	return os.str();
}

string InstrumentType::IntToName(int id, char com){
	static GeneralRegister gr;
	if (com == 'g'){
		return gr.GetName(id);
	}
	return "$" + IntToString(id);
}


string InstrumentType::TranslateBinaryToAsm(){
	InstrumentInformation &info = infoCurrentSentence;
	AsmCode.clear();
	AsmCode.push_back(info.name);
	for (int j = 0; j < ArgumentNumOfInstrument(info.name); ++j){
		switch(info.syntax[j]){
			case 'd': AsmCode.push_back(IntToName(d, info.com[0]));break;
			case 's': AsmCode.push_back(IntToName(s, info.com[1]));break;
			case 't': AsmCode.push_back(IntToName(t, info.com[2]));break;
			case 'h': AsmCode.push_back(IntToString(h));break;
			case 'i': AsmCode.push_back(IntToString(i));break;
		}
	}
	return GetAsmCode();
}

void InstrumentType::Run(CPUData& Data){
	SetCodeRegister(Data.Mem.Load(Data.PC.GetPC()));
	infoCurrentSentence.operation(d, s, t, i, h, Data);
}

string InstrumentType::GetAsmCode(){
	string ret = AsmCode[0];
	InstrumentInformation &info = infoCurrentSentence;
	if (info.name == "sw" || info.name == "lw" || info.name == "sb" || info.name == "lb"){
		ret += " " + AsmCode[1] + ", " + AsmCode[2] + "(" + AsmCode[3] + ")";
		return ret;
	}
	for (unsigned i = 1; i < AsmCode.size(); ++i){
		ret += " " + AsmCode[i];
		if (i != AsmCode.size() - 1) ret += ",";
	}
	return ret;
}

string InstrumentType::GetBinaryCode(){
	return BinaryCode;
}

void InstrumentType::SetCodeRegister(RegisterType &Code){
	CodeRegister = Code;
	TranslateCodeToBinary();
	SetBinaryCode(BinaryCode);
}

RegisterType InstrumentType::GetCodeRegister(){
	return CodeRegister;
}

void InstrumentType::TranslateCodeToBinary(){
	unsigned code = CodeRegister.UIntV;
	BinaryCode = "";
	for (int i = 31; i >= 0; --i) BinaryCode += (code & (1 << i)) ? '1' : '0';
}

void InstrumentType::TranslateBinaryToCode(){
	unsigned code = 0;
	for (int i = 0; i < 32; ++i) code = code * 2 + BinaryCode[i] - '0';
	CodeRegister.UIntV = code;
}

⌨️ 快捷键说明

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