Skip to content
Snippets Groups Projects
iop.cpp 28.1 KiB
Newer Older
Geo Ster's avatar
Geo Ster committed
    {
        uint16_t rt = instr.i_type.rt;
        uint16_t rs = instr.i_type.rs;
        int16_t imm = (int16_t)instr.i_type.immediate;

        set_reg(rt, gpr[rs] + imm);

        log("ADDIU: GPR[{:d}] = GPR[{:d}] ({:#x}) + {:#x}\n", rt, rs, gpr[rs], imm);
    }

    void IOProcessor::op_sll()
    {
        uint16_t rt = instr.r_type.rt;
        uint16_t rd = instr.r_type.rd;
        uint16_t sa = instr.r_type.sa;

        set_reg(rd, gpr[rt] << sa);

        if (instr.value == 0) log("NOP\n");
        else log("SLL: GPR[{:d}] = GPR[{:d}] ({:#x}) << {:d}\n", rd, rt, gpr[rt], sa);
    }

    void IOProcessor::op_sw()
    {
        uint16_t rt = instr.i_type.rt;
        uint16_t base = instr.i_type.rs;
        int16_t offset = (int16_t)instr.i_type.immediate;

        uint32_t vaddr = gpr[base] + offset;
        if (!cop0.sr.IsC) 
        {
            if (vaddr & 0x3) 
            {
                cop0.BadA = vaddr;
                exception(Exception::WriteError, 0);
            }
            else 
            {
                write<uint32_t>(vaddr, gpr[rt]);
            }
        }

        log("SW: Writing GPR[{:d}] ({:#x}) to address {:#x} = GPR[{:d}] ({:#x}) + {:d}\n", rt, gpr[rt], vaddr, base, gpr[base], offset);
    }

    void IOProcessor::op_lui()
    {
        uint16_t rt = instr.i_type.rt;
        uint32_t imm = instr.i_type.immediate;

        set_reg(rt, imm << 16);

        log("LUI: GPR[{:d}] = {:#x}\n", rt, imm << 16);
    }

    void IOProcessor::op_ori()
    {
        uint16_t rt = instr.i_type.rt;
        uint16_t rs = instr.i_type.rs;
        uint32_t imm = instr.i_type.immediate;

        set_reg(rt, gpr[rs] | imm);

        log("ORI: GPR[{:d}] = GPR[{:d}] ({:#x}) | {:#x}\n", rt, rs, gpr[rs], imm);
    }

    void IOProcessor::set_reg(uint32_t regN, uint32_t value)
    {
        write_back.reg = regN;
        write_back.value = value;
    }

    void IOProcessor::load(uint32_t regN, uint32_t value)
    {
        delayed_memory_load.reg = regN;
        delayed_memory_load.value = value;
    }
};