/*******************************************************************************
* openDLX - A DLX/MIPS processor simulator.
* Copyright (C) 2013 The openDLX project, University of Augsburg, Germany
* Project URL: <https://sourceforge.net/projects/opendlx>
* Development branch: <https://github.com/smetzlaff/openDLX>
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program, see <LICENSE>. If not, see
* <http://www.gnu.org/licenses/>.
******************************************************************************/
package openDLX;
import java.util.Queue;
import org.apache.log4j.Logger;
import openDLX.datatypes.*;
import openDLX.exception.CacheException;
import openDLX.exception.DecodeStageException;
import openDLX.exception.PipelineDataTypeException;
import openDLX.exception.UnknownInstructionException;
public class Decode
{
private static Logger logger = Logger.getLogger("DECODE");
private Instruction current_inst;
private RegisterSet reg_set;
private Queue<FetchDecodeData> fetch_decode_latch;
private final boolean throwExceptionForUntestedInstructions = true;
public Decode(RegisterSet reg_set)
{
this.reg_set = reg_set;
}
Instruction decodeInstr(uint32 instr) throws UnknownInstructionException, CacheException, PipelineDataTypeException
{
current_inst = new Instruction(instr);
if(instr.getValue() == 0)
{
// this is a nop
current_inst.setOpNormal(OpcodeNORMAL.NOP);
current_inst.setALUFunction(ALUFunction.NOP);
current_inst.setALUPortA(ALUPort.ZERO);
current_inst.setALUPortB(ALUPort.ZERO);
}
else
{
OpcodeNORMAL op_norm = determineOpcode();
if (op_norm == OpcodeNORMAL.SPECIAL)
{
determineFunction();
}
else if (op_norm == OpcodeNORMAL.REGIMM)
{
determineRegimm();
}
}
return current_inst;
}
private OpcodeNORMAL determineOpcode() throws UnknownInstructionException, CacheException, PipelineDataTypeException
{
OpcodeNORMAL op;
switch (current_inst.getOpcode().getValue() & 0x3F)
{
// bits 31..29 000
case 0x00:
op = (OpcodeNORMAL.SPECIAL);
break;
case 0x01:
op = (OpcodeNORMAL.REGIMM);
break;
case 0x02:
op = (OpcodeNORMAL.J);
current_inst.setType(InstructionType.JTYPE);
current_inst.setUseInstrIndex(true);
current_inst.setALUFunction(ALUFunction.BA);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IDX);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.UNCOND);
current_inst.setBranchPortA(BranchCtrlPort.ZERO);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x03:
op = (OpcodeNORMAL.JAL);
current_inst.setType(InstructionType.JTYPE);
current_inst.setUseInstrIndex(true);
current_inst.setWriteRA(true);
current_inst.setALUFunction(ALUFunction.BA);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IDX);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchCondition(BranchCondition.UNCOND);
current_inst.setBranchPortA(BranchCtrlPort.ZERO);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x04:
op = (OpcodeNORMAL.BEQ);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BEQ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.RT);
break;
case 0x05:
op = (OpcodeNORMAL.BNE);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BNE);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.RT);
break;
case 0x06:
op = (OpcodeNORMAL.BLEZ);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BLEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x07:
op = (OpcodeNORMAL.BGTZ);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BGTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 31..29 001
case 0x08:
op = (OpcodeNORMAL.ADDI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x09:
op = (OpcodeNORMAL.ADDIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.ADDU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0A:
op = (OpcodeNORMAL.SLTI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SLT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0B:
op = (OpcodeNORMAL.SLTIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SLTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0C:
op = (OpcodeNORMAL.ANDI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.ZERO);
current_inst.setALUFunction(ALUFunction.AND);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0D:
op = (OpcodeNORMAL.ORI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.ZERO);
current_inst.setALUFunction(ALUFunction.OR);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0E:
op = (OpcodeNORMAL.XORI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.ZERO);
current_inst.setALUFunction(ALUFunction.XOR);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x0F:
op = (OpcodeNORMAL.LUI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.LUI);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
// bits 31..29 010
case 0x10:
switch(ArchCfg.isa_type)
{
case DLX:
// use COP0 for implementation of SUBI (because is normal opcode like ADDI and is one row below ADDI)
op = (OpcodeNORMAL.SUBI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SUB);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.COP0);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x11:
switch(ArchCfg.isa_type)
{
case DLX:
// use COP1 for implementation of SUBIU (because is normal opcode like ADDIU and is one row below ADDIU)
op = (OpcodeNORMAL.SUBIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SUBU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.COP1);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x12:
switch(ArchCfg.isa_type)
{
case DLX:
// use COP2 for implementation of SGTI
op = (OpcodeNORMAL.SGTI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SGT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.COP2);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x13:
switch(ArchCfg.isa_type)
{
case DLX:
// use COP1X for implementation of SGTIU
op = (OpcodeNORMAL.SGTIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SGTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.COP1X);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x14:
op = (OpcodeNORMAL.BEQL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BEQ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.RT);
break;
case 0x15:
op = (OpcodeNORMAL.BNEL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BNE);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.RT);
break;
case 0x16:
op = (OpcodeNORMAL.BLEZL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BLEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x17:
op = (OpcodeNORMAL.BGTZL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BGTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
// bits 31..29 011
case 0x18:
op = (OpcodeNORMAL.DADDI);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x19:
op = (OpcodeNORMAL.DADDIU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1A:
op = (OpcodeNORMAL.LDL);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1B:
op = (OpcodeNORMAL.LDR);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1C:
case 0x1D:
case 0x1E:
case 0x1F:
op = (OpcodeNORMAL.UNKNOWN);
break;
// bits 31..29 100
case 0x20:
op = (OpcodeNORMAL.LB);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setLoad(true);
current_inst.setMemoryWidth(MemoryWidth.BYTE);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x21:
op = (OpcodeNORMAL.LH);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x22:
op = (OpcodeNORMAL.LWL);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x23:
op = (OpcodeNORMAL.LW);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setLoad(true);
current_inst.setMemoryWidth(MemoryWidth.WORD);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x24:
op = (OpcodeNORMAL.LBU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setLoad(true);
current_inst.setMemoryWidth(MemoryWidth.UBYTE);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x25:
op = (OpcodeNORMAL.LHU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x26:
op = (OpcodeNORMAL.LWR);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x27:
op = (OpcodeNORMAL.LWU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 31..29 101
case 0x28:
op = (OpcodeNORMAL.SB);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setStore(true);
current_inst.setMemoryWidth(MemoryWidth.BYTE);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x29:
op = (OpcodeNORMAL.SH);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2A:
op = (OpcodeNORMAL.SWL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setStore(true);
current_inst.setMemoryWidth(MemoryWidth.WORD_LEFT_PART);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2B:
op = (OpcodeNORMAL.SW);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setStore(true);
current_inst.setMemoryWidth(MemoryWidth.WORD);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x2C:
op = (OpcodeNORMAL.SDL);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2D:
op = (OpcodeNORMAL.SDR);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2E:
op = (OpcodeNORMAL.SWR);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setStore(true);
current_inst.setMemoryWidth(MemoryWidth.WORD_RIGHT_PART);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case 0x2F:
op = (OpcodeNORMAL.UNKNOWN);
break;
// bits 31..29 110
case 0x30:
op = (OpcodeNORMAL.LL);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x31:
switch(ArchCfg.isa_type)
{
case DLX:
// use LWC1 for implementation of SEQI
op = (OpcodeNORMAL.SEQI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SEQ);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.LWC1);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x32:
switch(ArchCfg.isa_type)
{
case DLX:
// use LWC2 for implementation of SNEI
op = (OpcodeNORMAL.SNEI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SNE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.LWC2);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x33:
op = (OpcodeNORMAL.PREF);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x34:
op = (OpcodeNORMAL.LLD);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x35:
switch(ArchCfg.isa_type)
{
case DLX:
// use LDC1 for implementation of SLEI
op = (OpcodeNORMAL.SLEI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SLE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.LDC1);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x36:
switch(ArchCfg.isa_type)
{
case DLX:
// use LDC2 for implementation of SGEI
op = (OpcodeNORMAL.SGEI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SGE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.LDC2);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x37:
op = (OpcodeNORMAL.LD);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 31..29 111
case 0x38:
op = (OpcodeNORMAL.SC);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x39:
switch(ArchCfg.isa_type)
{
case DLX:
// use SWC1 for implementation of SEQIU
op = (OpcodeNORMAL.SEQIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SEQU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.SWC1);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x3A:
switch(ArchCfg.isa_type)
{
case DLX:
// use SWC2 for implementation of SNEIU
op = (OpcodeNORMAL.SNEIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SNEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.SWC2);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x3B:
op = (OpcodeNORMAL.UNKNOWN);
break;
case 0x3C:
op = (OpcodeNORMAL.SCD);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x3D:
switch(ArchCfg.isa_type)
{
case DLX:
// use SDC1 for implementation of SLEIU
op = (OpcodeNORMAL.SLEIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SLEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.SDC1);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x3E:
switch(ArchCfg.isa_type)
{
case DLX:
// use SDC2 for implementation of SGEIU
op = (OpcodeNORMAL.SGEIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setWriteRt(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.SGEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
break;
case MIPS:
default:
op = (OpcodeNORMAL.SDC2);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case 0x3F:
switch(ArchCfg.isa_type)
{
case MIPS:
if(current_inst.getInstr() == PipelineConstants.PIPELINE_BUBBLE_INSTR)
{
op = (OpcodeNORMAL.NOP);
current_inst.setALUFunction(ALUFunction.NOP);
current_inst.setALUPortA(ALUPort.ZERO);
current_inst.setALUPortB(ALUPort.ZERO);
logger.info("Inserting is DLX pipeline bubble: " + current_inst.getInstr());
}
else
{
// TODO: what if and SD instruction with the bit mask of CONST.PIPELINE_BUBBLE_INSTR is issued??
op = (OpcodeNORMAL.SD);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
}
break;
case DLX:
if(current_inst.getInstr() != PipelineConstants.PIPELINE_BUBBLE_INSTR)
{
throw new UnknownInstructionException("Wrong DLX Bubble Instruction: " + current_inst.getInstr().getValueAsHexString());
}
op = (OpcodeNORMAL.NOP);
current_inst.setALUFunction(ALUFunction.NOP);
current_inst.setALUPortA(ALUPort.ZERO);
current_inst.setALUPortB(ALUPort.ZERO);
logger.info("Inserting is DLX pipeline bubble: " + current_inst.getInstr());
break;
default:
op = (OpcodeNORMAL.UNKNOWN);
}
break;
default:
op = (OpcodeNORMAL.UNKNOWN);
}
if(op == OpcodeNORMAL.UNKNOWN)
{
logger.error("Instruction " + op + " unknown. Type: NORMAL Opcode: " + current_inst.getOpcode().getValueAsHexString());
throw new UnknownInstructionException("Instruction " + op + " unknown. Type: NORMAL Opcode: " + current_inst.getOpcode().getValueAsHexString());
}
current_inst.setOpNormal(op);
return op;
}
private OpcodeSPECIAL determineFunction() throws UnknownInstructionException, PipelineDataTypeException
{
OpcodeSPECIAL op;
switch (current_inst.getFunction().getValue() & 0x3F)
{
// bits 5..3 000
case 0x00:
op = (OpcodeSPECIAL.SLL);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setUseShiftAmount(true);
current_inst.setALUFunction(ALUFunction.SLL);
current_inst.setALUPortA(ALUPort.RT);
current_inst.setALUPortB(ALUPort.SA);
break;
case 0x01:
op = (OpcodeSPECIAL.MOVCI);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x02:
op = (OpcodeSPECIAL.SRL);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setUseShiftAmount(true);
current_inst.setALUFunction(ALUFunction.SRL);
current_inst.setALUPortA(ALUPort.RT);
current_inst.setALUPortB(ALUPort.SA);
break;
case 0x03:
op = (OpcodeSPECIAL.SRA);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setUseShiftAmount(true);
current_inst.setALUFunction(ALUFunction.SRA);
current_inst.setALUPortA(ALUPort.RT);
current_inst.setALUPortB(ALUPort.SA);
break;
case 0x04:
op = (OpcodeSPECIAL.SLLV);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SLLV);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x05:
op = (OpcodeSPECIAL.UNKNOWN);
break;
case 0x06:
op = (OpcodeSPECIAL.SRLV);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SRLV);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x07:
op = (OpcodeSPECIAL.SRAV);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SRAV);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 5..3 001
case 0x08:
op = (OpcodeSPECIAL.JR);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setALUFunction(ALUFunction.ADDU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.ZERO);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.UNCOND);
current_inst.setBranchPortA(BranchCtrlPort.ZERO);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x09:
op = (OpcodeSPECIAL.JALR);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.ADDU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.ZERO);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchCondition(BranchCondition.UNCOND);
current_inst.setBranchPortA(BranchCtrlPort.ZERO);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x0A:
op = (OpcodeSPECIAL.MOVZ);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0B:
op = (OpcodeSPECIAL.MOVN);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0C:
switch(ArchCfg.isa_type)
{
case MIPS:
op = (OpcodeSPECIAL.SYSCALL);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadKernelRegisters(true);
current_inst.setALUFunction(ALUFunction.SYSCALL);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case DLX:
op = (OpcodeSPECIAL.TRAP);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadDLXTrapParameterRegister(true);
if(current_inst.getRs().getValue() == PipelineConstants.DLX_TRAP_READ)
{
// prepare to write the number of read bytes into register R1
current_inst.setWriteDLXTrapResultRegister(true);
}
current_inst.setALUFunction(ALUFunction.TRAP);
current_inst.setALUPortA(ALUPort.RT);
current_inst.setALUPortB(ALUPort.IMM);
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x0D:
op = (OpcodeSPECIAL.BREAK);
current_inst.setType(InstructionType.RTYPE);
break;
case 0x0E:
op = (OpcodeSPECIAL.UNKNOWN);
break;
case 0x0F:
op = (OpcodeSPECIAL.SYNC);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 5..3 010
case 0x10:
op = (OpcodeSPECIAL.MFHI);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadHI(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.HI);
current_inst.setALUPortB(ALUPort.ZERO); // or ALUPORT.RT
break;
case 0x11:
op = (OpcodeSPECIAL.MTHI);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setWriteHI(true);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.ZERO);
break;
case 0x12:
op = (OpcodeSPECIAL.MFLO);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadLO(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.LO);
current_inst.setALUPortB(ALUPort.ZERO); // or ALUPORT.RT
break;
case 0x13:
op = (OpcodeSPECIAL.MTLO);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setWriteLO(true);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.ZERO);
break;
case 0x14:
op = (OpcodeSPECIAL.DSLLV);
current_inst.setType(InstructionType.RTYPE);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x15:
op = (OpcodeSPECIAL.UNKNOWN);
break;
case 0x16:
op = (OpcodeSPECIAL.DSRLV);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x17:
op = (OpcodeSPECIAL.DSRAV);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 5..3 011
case 0x18:
switch(ArchCfg.isa_type)
{
case MIPS:
op = (OpcodeSPECIAL.MULT);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteHI(true);
current_inst.setWriteLO(true);
current_inst.setALUFunction(ALUFunction.MULT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case DLX:
op = (OpcodeSPECIAL.MULT);
// in DLX flavour the target register is determined by Rd
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.MULT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x19:
switch(ArchCfg.isa_type)
{
case MIPS:
op = (OpcodeSPECIAL.MULTU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteHI(true);
current_inst.setWriteLO(true);
current_inst.setALUFunction(ALUFunction.MULTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case DLX:
op = (OpcodeSPECIAL.MULTU);
// in DLX flavour the target register is determined by Rd
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.MULTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x1A:
switch(ArchCfg.isa_type)
{
case MIPS:
op = (OpcodeSPECIAL.DIV);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteHI(true);
current_inst.setWriteLO(true);
current_inst.setALUFunction(ALUFunction.DIV);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case DLX:
op = (OpcodeSPECIAL.DIV);
// in DLX flavour the target register is determined by Rd
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.DIV);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x1B:
switch(ArchCfg.isa_type)
{
case MIPS:
op = (OpcodeSPECIAL.DIVU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteHI(true);
current_inst.setWriteLO(true);
current_inst.setALUFunction(ALUFunction.DIVU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case DLX:
op = (OpcodeSPECIAL.DIVU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.DIVU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x1C:
op = (OpcodeSPECIAL.DMULT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1D:
op = (OpcodeSPECIAL.DMULTU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1E:
op = (OpcodeSPECIAL.DDIV);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x1F:
op = (OpcodeSPECIAL.DDIVU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 5..3 100
case 0x20:
op = (OpcodeSPECIAL.ADD);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.ADD);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x21:
op = (OpcodeSPECIAL.ADDU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.ADDU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x22:
op = (OpcodeSPECIAL.SUB);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SUB);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x23:
op = (OpcodeSPECIAL.SUBU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SUBU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x24:
op = (OpcodeSPECIAL.AND);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.AND);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x25:
op = (OpcodeSPECIAL.OR);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.OR);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x26:
op = (OpcodeSPECIAL.XOR);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.XOR);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x27:
op = (OpcodeSPECIAL.NOR);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.NOR);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
// bits 5..3 101
case 0x28:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SGT in DLX ISA
op = (OpcodeSPECIAL.SGT);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SGT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x29:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SGTU in DLX ISA
op = (OpcodeSPECIAL.SGTU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SGTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x2A:
op = (OpcodeSPECIAL.SLT);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SLT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x2B:
op = (OpcodeSPECIAL.SLTU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SLTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x2C:
op = (OpcodeSPECIAL.DADD);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2D:
op = (OpcodeSPECIAL.DADDU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2E:
op = (OpcodeSPECIAL.DSUB);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x2F:
op = (OpcodeSPECIAL.DSUBU);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
// bits 5..3 110
case 0x30:
op = (OpcodeSPECIAL.TGE);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TGE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x31:
op = (OpcodeSPECIAL.TGEU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TGEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x32:
op = (OpcodeSPECIAL.TLT);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TLT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x33:
op = (OpcodeSPECIAL.TLTU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TLTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x34:
op = (OpcodeSPECIAL.TEQ);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TEQ);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case 0x35:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SEQ in DLX ISA
op = (OpcodeSPECIAL.SEQ);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SEQ);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x36:
op = (OpcodeSPECIAL.TNE);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setALUFunction(ALUFunction.TNE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x37:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SNE in DLX ISA
op = (OpcodeSPECIAL.SNE);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SNE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
// bits 5..3 111
case 0x38:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SLE in DLX ISA
op = (OpcodeSPECIAL.SLE);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SLE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x39:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SGE in DLX ISA
op = (OpcodeSPECIAL.SGE);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SGE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x3A:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SEQU in DLX ISA
op = (OpcodeSPECIAL.SEQU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SEQU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x3B:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SNEU in DLX ISA
op = (OpcodeSPECIAL.SNEU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SNEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x3C:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SLEU in DLX ISA
op = (OpcodeSPECIAL.SLEU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SLEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x3D:
switch(ArchCfg.isa_type)
{
case DLX:
// using unused opcode of MIPS for SGEU in DLX ISA
op = (OpcodeSPECIAL.SGEU);
current_inst.setType(InstructionType.RTYPE);
current_inst.setReadRs(true);
current_inst.setReadRt(true);
current_inst.setWriteRd(true);
current_inst.setALUFunction(ALUFunction.SGEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.RT);
break;
case MIPS:
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
break;
case 0x3E:
op = (OpcodeSPECIAL.DSRL32);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x3F:
op = (OpcodeSPECIAL.DSRA32);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
default:
op = (OpcodeSPECIAL.UNKNOWN);
}
if(op == OpcodeSPECIAL.UNKNOWN)
{
logger.error("Instruction " + op + " unknown. Type: SPECIAL Opcode: " + current_inst.getOpcode().getValueAsHexString());
throw new UnknownInstructionException("Instruction " + op + " unknown. Type: SPECIAL Opcode: " + current_inst.getOpcode().getValueAsHexString());
}
current_inst.setOpSpecial(op);
return op;
}
private OpcodeREGIMM determineRegimm() throws UnknownInstructionException, PipelineDataTypeException
{
OpcodeREGIMM op;
switch (current_inst.getRegimm().getValue() & 0x1F)
{
// bits 20..19 00
case 0x00:
op = (OpcodeREGIMM.BLTZ);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BLTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x01:
op = (OpcodeREGIMM.BGEZ);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchCondition(BranchCondition.BGEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x02:
op = (OpcodeREGIMM.BLTZL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BLTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x03:
op = (OpcodeREGIMM.BGEZL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BGEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x04:
case 0x05:
case 0x06:
case 0x07:
op = (OpcodeREGIMM.UNKNOWN);
break;
// bits 20..19 01
case 0x08:
op = (OpcodeREGIMM.TGEI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TGE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x09:
op = (OpcodeREGIMM.TGEIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TGEU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0A:
op = (OpcodeREGIMM.TLTI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TLT);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0B:
op = (OpcodeREGIMM.TLTIU);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TLTU);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0C:
op = (OpcodeREGIMM.TEQI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TEQ);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0D:
op = (OpcodeREGIMM.UNKNOWN);
break;
case 0x0E:
op = (OpcodeREGIMM.TNEI);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setALUFunction(ALUFunction.TNE);
current_inst.setALUPortA(ALUPort.RS);
current_inst.setALUPortB(ALUPort.IMM);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x0F:
op = (OpcodeREGIMM.UNKNOWN);
break;
// bits 20..19 10
case 0x10:
op = (OpcodeREGIMM.BLTZAL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setWriteRA(true);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchCondition(BranchCondition.BLTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x11:
op = (OpcodeREGIMM.BGEZAL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setWriteRA(true);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchCondition(BranchCondition.BGEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
logger.error("Instruction " + op + " not yet supported.");
if(throwExceptionForUntestedInstructions)
{
throw new UnknownInstructionException("Instruction " + op + " not yet supported.");
}
break;
case 0x12:
op = (OpcodeREGIMM.BLTZALL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setWriteRA(true);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BLTZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x13:
op = (OpcodeREGIMM.BGEZALL);
current_inst.setType(InstructionType.ITYPE);
current_inst.setReadRs(true);
current_inst.setUseImmediate(true);
current_inst.setImmExtend(ImmExtend.SIGN);
current_inst.setWriteRA(true);
current_inst.setALUFunction(ALUFunction.BR);
current_inst.setALUPortA(ALUPort.PC);
current_inst.setALUPortB(ALUPort.IMM);
current_inst.setBranch(true);
current_inst.setBranchAndLink(true);
current_inst.setBranchLikely(true);
current_inst.setBranchCondition(BranchCondition.BGEZ);
current_inst.setBranchPortA(BranchCtrlPort.RS);
current_inst.setBranchPortB(BranchCtrlPort.ZERO);
break;
case 0x14:
case 0x15:
case 0x16:
case 0x17:
op = (OpcodeREGIMM.UNKNOWN);
break;
// bits 20..19 11
case 0x18:
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1E:
case 0x1F:
op = (OpcodeREGIMM.UNKNOWN);
break;
default:
op = (OpcodeREGIMM.UNKNOWN);
}
if(op == OpcodeREGIMM.UNKNOWN)
{
logger.error("Instruction " + op + " unknown. Type: REGIMM Opcode: " + current_inst.getOpcode().getValueAsHexString());
throw new UnknownInstructionException("Instruction " + op + " unknown. Type: REGIMM Opcode: " + current_inst.getOpcode().getValueAsHexString());
}
current_inst.setOpRegimm(op);
return op;
}
public void setInputLatch(Queue<FetchDecodeData> fetchDecodeLatch)
{
fetch_decode_latch = fetchDecodeLatch;
}
public DecodeOutputData doCycle() throws DecodeStageException, CacheException, PipelineDataTypeException
{
uint32 alu_in_a;
uint32 alu_in_b;
FetchDecodeData fdd = fetch_decode_latch.element();
uint32 decode_instr = fdd.getInstr();
uint32 pc = fdd.getPc();
Instruction inst = decodeInstr(decode_instr);
logger.debug("PC: " + pc.getValueAsHexString()
+ " instruction decoded as " + inst.getString());
// determination of input for ALU port A
switch (inst.getALUPortA())
{
case RS:
alu_in_a = reg_set.read(inst.getRs());
break;
case RT:
alu_in_a = reg_set.read(inst.getRt());
break;
case LO:
alu_in_a = reg_set.read_SP(SpecialRegisters.LO);
break;
case HI:
alu_in_a = reg_set.read_SP(SpecialRegisters.HI);
break;
case PC:
// increment the pc, because relative jumps assume the pc of the next instruction
alu_in_a = new uint32(pc.getValue()+4);
break;
case ZERO:
alu_in_a = new uint32(0);
break;
default:
alu_in_a = new uint32(0);
throw new DecodeStageException("Wrong ALU Port A");
}
// determination of input for ALU port B
switch (inst.getALUPortB())
{
case RT:
alu_in_b = reg_set.read(inst.getRt());
break;
case IDX:
alu_in_b = new uint32(inst.getInstrIndex().getValue());
break;
case IMM:
if(inst.getImmExtend()==ImmExtend.ZERO)
{
alu_in_b = new uint32((inst.getOffset().getValue())&0xFFFF);
}
else if(inst.getImmExtend()==ImmExtend.SIGN)
{
alu_in_b = new uint32((inst.getOffset().getValue()));
}
else if((ArchCfg.isa_type == ISAType.DLX) && (inst.getOpSpecial() == OpcodeSPECIAL.TRAP))
{
alu_in_b = new uint32(inst.getRs().getValue());
}
else
{
alu_in_b = new uint32(0);
throw new DecodeStageException("Wrong IMM at ALU Port B");
}
break;
case SA:
alu_in_b = new uint32(inst.getSa().getValue());
break;
case ZERO:
alu_in_b = new uint32(0);
break;
default:
alu_in_b = new uint32(0);
throw new DecodeStageException("Wrong ALU Port B");
}
uint32 branch_ctrl_in_a;
uint32 branch_ctrl_in_b;
// determination of input for BRANCH CONTROL port A
switch(inst.getBrachControlPortA())
{
case RS:
branch_ctrl_in_a = reg_set.read(inst.getRs());
break;
case ZERO:
branch_ctrl_in_a = new uint32(0);
break;
default:
branch_ctrl_in_a = new uint32(0);
throw new DecodeStageException("Wrong Branch Port A");
}
// determination of input for BRANCH CONTROL port B
switch(inst.getBrachControlPortB())
{
case RT:
branch_ctrl_in_b = reg_set.read(inst.getRt());
break;
case ZERO:
branch_ctrl_in_b = new uint32(0);
break;
default:
branch_ctrl_in_b = new uint32(0);
throw new DecodeStageException("Wrong Branch Port B");
}
// determination of the store value
uint32 store_value = new uint32(0);
if (inst.getStore())
{
store_value = reg_set.read(inst.getRt());
}
DecodeExecuteData ded = new DecodeExecuteData(inst, pc, alu_in_a, alu_in_b, branch_ctrl_in_a, branch_ctrl_in_b, store_value);
return new DecodeOutputData(ded);
}
}