read_inst 讀指令
word memory::read_inst(int adr){
if((adr >= 0x10000000 && adr < 0x11000000) && adr % 4 == 0){
int index = (adr - 0x10000000) / 4;
return (*inst)[index];
}
std::cerr << "error: trying to read instruction from address: " << adr << '\n';
std::exit(-11);
}
先判斷是不是在合法的地址內,取偏移地址,得到指令
001111 00000 11101 0010001111111111
op 001111 lui
把0010001111111111存放到11101號寄存器
對象化
執行(lui 把16位寄存器存放到rt號寄存器高16位)
然後pc + 4(一條指令4B)
R型ADD(寄存器)
op | rs | rt | rd | sh | fun |
---|---|---|---|---|---|
000000 | 10000 | 00010 | 00010 | 00000 | 100001 |
void cpu::ADD(const instruction& inst){
s_word r1 = r[inst.src_s];
s_word r2 = r[inst.src_t];
s_word res = r1 + r2;
if((res < 0 && r1 >= 0 && r2 >= 0)||(res >= 0 && r1 < 0 && r2 < 0)){
std::cerr << "exception: arithmetic error" << std::endl;
std::exit(-10);
}
r[inst.destn] = res;
pc_increase(4);
}
void cpu::ADDU(const instruction& inst) {
word r1 = r[inst.src_s];
word r2 = r[inst.src_t];
word res = r1 + r2;
r[inst.destn] = res;
pc_increase(4);
}
結果
I型ADD(立即數)
void cpu::ADDI(const instruction& inst){
//TODO: check immiatde sing extension
s_word r1 = r[inst.src_s];
s_word imi = sign_extend_imi(inst);
s_word res = r1 + imi;
if( (res <= 0 && r1 > 0 && imi > 0) || (res >= 0 && r1 < 0 && imi < 0) ){
std::cerr << "exception: arithmetic error" << '\n';
std::exit(-10);
}
r[inst.src_t] = res;
pc_increase(4);
}
void cpu::ADDIU(const instruction& inst){
word r1 = r[inst.src_s];
word imi = sign_extend_imi(inst);
s_word res = r1 + imi;
r[inst.src_t] = res;
pc_increase(4);
}
word cpu::sign_extend_imi(const instruction& inst){
word imi = inst.i_imi;
return (imi >= 0x8000) ? (0xFFFF0000 | imi) : imi;
}