📄 aluop.cpp
字号:
#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 + -