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

📄 aluop.cpp

📁 mini mips 小型mips软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"
#include "ALUOp.h"
#include "RunningErrorException.h"
#include <stdio.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>

void (*ALUOp::SystemCallOperation[18])(CPUData& Data)={NULL, print_int, print_float, print_double, print_string,
read_int, read_float, read_double, read_string, sbrk, exit, print_char, read_char, open, read, write, close, exit2};

void ALUOp::add(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[s].IntV + Data.generalRegister[t].IntV;
	Data.PC.advance_pc();
}

void ALUOp::addi(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].IntV + i;
	Data.PC.advance_pc();
}

void ALUOp::addiu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].UIntV = Data.generalRegister[s].UIntV + i; 
	Data.PC.advance_pc();
}

void ALUOp::addu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[s].UIntV + Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::and(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[s].UIntV & Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::andi(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].IntV & i;
	Data.PC.advance_pc();
}

void ALUOp::beq(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV == Data.generalRegister[t].IntV) Data.PC.advance_pc(i << 2);
	                                                             else Data.PC.advance_pc();
}

void ALUOp::bgez(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV >= 0) Data.PC.advance_pc(i << 2); else Data.PC.advance_pc();
}

void ALUOp::bgezal(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV >= 0){
		Data.generalRegister[31].UIntV = Data.PC.GetPC() + 8;
		Data.PC.advance_pc(i << 2);
	}
	else{
		Data.PC.advance_pc();
	}
}

void ALUOp::bgtz(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV > 0) Data.PC.advance_pc(i << 2); else Data.PC.advance_pc();
}

void ALUOp::blez(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV <= 0) Data.PC.advance_pc(i << 2); else Data.PC.advance_pc();
}

void ALUOp::bltz(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV < 0) Data.PC.advance_pc(i << 2); else Data.PC.advance_pc();
}

void ALUOp::bltzal(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV < 0){
		Data.generalRegister[31].UIntV = Data.PC.GetPC() + 8;
		Data.PC.advance_pc(i << 2);
	}
	else{
		Data.PC.advance_pc();
	}
}

void ALUOp::bne(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister[s].IntV != Data.generalRegister[t].IntV) Data.PC.advance_pc(i << 2);
	                                                             else Data.PC.advance_pc();
}

void ALUOp::div(int d, int s, int t, int i, int h, CPUData& Data){
	Data.LO.IntV = Data.generalRegister[s].IntV / Data.generalRegister[t].IntV;
	Data.HI.IntV = Data.generalRegister[s].IntV % Data.generalRegister[t].IntV;
	Data.PC.advance_pc();
}

void ALUOp::divu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.LO.UIntV = Data.generalRegister[s].UIntV / Data.generalRegister[t].UIntV;
	Data.HI.UIntV = Data.generalRegister[s].UIntV % Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::j(int d, int s, int t, int i, int h, CPUData& Data){
	Data.PC.Jump(i);
}

void ALUOp::jal(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[31].UIntV = Data.PC.GetPC() + 8;
	Data.PC.Jump(i);
}

void ALUOp::jr(int d, int s, int t, int i, int h, CPUData& Data){
	Data.PC.Jump(Data.generalRegister[s]);
}

void ALUOp::lb(int d, int s, int t, int i, int h, CPUData& Data){
	unsigned address = Data.generalRegister[s].UIntV + i;
	RegisterType value = Data.Mem.Load(address & 0xfffffffc);
	Data.generalRegister[t].UIntV = value.CV[address & 3];
	Data.PC.advance_pc();
}

void ALUOp::lui(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].UIntV = i << 16;
	Data.PC.advance_pc();
}

void ALUOp::lw(int d, int s, int t, int i, int h, CPUData& Data){
	unsigned address = Data.generalRegister[s].UIntV + i;
	if (address & 3){
		RegisterType value;
		int offset = address & 3, i;
		value = Data.Mem.Load(address & 0xfffffffc);
		for (i = 0; i + offset < 4; ++i) Data.generalRegister[t].CV[i] = value.CV[i + offset];
		value = Data.Mem.Load((address & 0xfffffffc) + 1);
		for (i = 0; i < offset; ++i) Data.generalRegister[t].CV[i + 4 - offset] = value.CV[i];
	}
	else{
		Data.generalRegister[t] = Data.Mem.Load(address);
	}
	Data.PC.advance_pc();
}

void ALUOp::mfhi(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d] = Data.HI;
	Data.PC.advance_pc();
}

void ALUOp::mflo(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d] = Data.LO;
	Data.PC.advance_pc();
}

void ALUOp::mult(int d, int s, int t, int i, int h, CPUData& Data){
	Data.LO.IntV = Data.generalRegister[s].IntV * Data.generalRegister[t].IntV;
	Data.PC.advance_pc();
}

void ALUOp::multu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.LO.UIntV = Data.generalRegister[s].UIntV * Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::noop(int d, int s, int t, int i, int h, CPUData& Data){
	Data.PC.advance_pc();
}

void ALUOp::or(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[s].UIntV | Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::ori(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].IntV | i;
	Data.PC.advance_pc();
}

void ALUOp::sb(int d, int s, int t, int i, int h, CPUData& Data){
	unsigned address = Data.generalRegister[s].UIntV + i;
	RegisterType value = Data.Mem.Load(address & 0xfffffffc);
	value.CV[address & 3] = Data.generalRegister[t].CV[0];
	Data.Mem.Save(address & 0xfffffffc, value);
	Data.PC.advance_pc();
}

void ALUOp::sll(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[t].IntV << h;
	Data.PC.advance_pc();
}

void ALUOp::sllv(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[t].IntV << Data.generalRegister[s].IntV;
	Data.PC.advance_pc();
}

void ALUOp::slt(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[s].IntV < Data.generalRegister[t].IntV ? 1 : 0;
	Data.PC.advance_pc();
}

void ALUOp::slti(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].IntV < i ? 1 : 0;
	Data.PC.advance_pc();
}

void ALUOp::sltiu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].UIntV < (unsigned)i ? 1 : 0;
	Data.PC.advance_pc();
}

void ALUOp::sltu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[s].UIntV < Data.generalRegister[t].UIntV ? 1 : 0;
	Data.PC.advance_pc();
}

void ALUOp::sra(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[t].IntV >> h;
	Data.PC.advance_pc();
}

void ALUOp::srl(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[t].UIntV >> h;
	Data.PC.advance_pc();
}

void ALUOp::srlv(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[t].UIntV >> Data.generalRegister[s].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::sub(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].IntV = Data.generalRegister[s].IntV - Data.generalRegister[t].IntV;
	Data.PC.advance_pc();
}

void ALUOp::subu(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[s].UIntV - Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::sw(int d, int s, int t, int i, int h, CPUData& Data){
	unsigned address = Data.generalRegister[s].UIntV + i;
	if (address & 3){
		RegisterType value;
		int offset = address & 3, i;
		value = Data.Mem.Load(address & 0xfffffffc);
		for (i = 0; i + offset < 4; ++i) value.CV[i + offset] = Data.generalRegister[t].CV[i];
		Data.Mem.Save(address & 0xfffffffc, value);
		value = Data.Mem.Load((address & 0xfffffffc) + 1);
		for (i = 0; i < offset; ++i) value.CV[i] = Data.generalRegister[t].CV[i + 4 - offset];
		Data.Mem.Save((address & 0xfffffffc) + 1, value);
	}
	else{
		Data.Mem.Save(address, Data.generalRegister[t]);
	}
	Data.PC.advance_pc();
}

void ALUOp::syscall(int d, int s, int t, int i, int h, CPUData& Data){
	if (Data.generalRegister["$v0"].IntV > 17 || Data.generalRegister["$v0"].IntV < 0){
		throw RunningErrorException("Wrong syscall!");
	}
	SystemCallOperation[Data.generalRegister["$v0"].IntV](Data);
	Data.PC.advance_pc();
}

void ALUOp::xor(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[d].UIntV = Data.generalRegister[s].UIntV ^ Data.generalRegister[t].UIntV;
	Data.PC.advance_pc();
}

void ALUOp::xori(int d, int s, int t, int i, int h, CPUData& Data){
	Data.generalRegister[t].IntV = Data.generalRegister[s].IntV ^ i;
	Data.PC.advance_pc();
}

void ALUOp::print_int(CPUData& Data){
	//printf_s("%d", Data.generalRegister["$a0"].IntV);
	cout << Data.generalRegister["$a0"].IntV;
}

void ALUOp::print_float(CPUData& Data){
	//printf_s("%f", Data.floatingRegister.GetValueF(12));
	cout << Data.floatingRegister.GetValueF(12);
}

void ALUOp::print_double(CPUData& Data){
	//printf_s("%lf", Data.floatingRegister.GetValueD(12));
	cout << Data.floatingRegister.GetValueD(12);
}

void ALUOp::print_string(CPUData& Data){
	unsigned address = Data.generalRegister["$a0"].UIntV;
	RegisterType value = Data.Mem.Load(address & 0xfffffffc);
	char ch = value.CV[address & 3];
	while(ch != '\0'){
		//putchar(ch);
		cout.put(ch);
		++address;
		value = Data.Mem.Load(address & 0xfffffffc);
	    ch = value.CV[address & 3];
	}
}

void ALUOp::read_int(CPUData& Data){
	//scanf_s("%d", &Data.generalRegister["$v0"].IntV);
	cin >> Data.generalRegister["$v0"].IntV;
}

void ALUOp::read_float(CPUData& Data){
	float temp;
	//scanf_s("%f%n", &temp);
	cin >> temp;
	Data.floatingRegister.SetValueF(0, temp);
}

void ALUOp::read_double(CPUData& Data){

⌨️ 快捷键说明

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