/**
* ****************************************************************************
* Copyright (c) 2010-2016 by Min Cai (min.cai.china@gmail.com).
* <p>
* This file is part of the Archimulator multicore architectural simulator.
* <p>
* Archimulator 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
* (at your option) any later version.
* <p>
* Archimulator 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.
* <p>
* You should have received a copy of the GNU General Public License
* along with Archimulator. If not, see <http://www.gnu.org/licenses/>.
* ****************************************************************************
*/
package archimulator.isa;
import archimulator.common.Logger;
import archimulator.core.functionalUnit.FunctionalUnitOperationType;
import archimulator.isa.event.FunctionCallEvent;
import archimulator.isa.event.FunctionReturnEvent;
import archimulator.isa.event.InstructionFunctionallyExecutedEvent;
import archimulator.isa.event.PseudoCallEncounteredEvent;
import archimulator.os.Context;
import archimulator.os.FunctionCallContext;
import archimulator.util.Reference;
import archimulator.util.math.MathHelper;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
/**
* Static instruction.
*
* @author Min Cai
*/
public class StaticInstruction {
private Mnemonic mnemonic;
private int machineInstruction;
private List<Integer> inputDependencies;
private List<Integer> outputDependencies;
private int nonEffectiveAddressBaseDependency;
private Map<RegisterDependencyType, Integer> numFreePhysicalRegistersToAllocate = new EnumMap<>(RegisterDependencyType.class);
/**
* Create a static instruction.
*
* @param mnemonic the mnemonic
* @param machineInstruction the machine instruction
*/
public StaticInstruction(Mnemonic mnemonic, int machineInstruction) {
this.mnemonic = mnemonic;
this.machineInstruction = machineInstruction;
this.inputDependencies = mnemonic.getInputDependencies(machineInstruction);
this.outputDependencies = mnemonic.getOutputDependencies(machineInstruction);
if (this.mnemonic.getType() == StaticInstructionType.LOAD || this.mnemonic.getType() == StaticInstructionType.STORE) {
this.nonEffectiveAddressBaseDependency = mnemonic.getNonEffectiveAddressBaseDep(machineInstruction);
}
this.outputDependencies.stream().filter(outputDependency -> outputDependency != 0).forEach(outputDependency -> {
RegisterDependencyType outputDependencyType = RegisterDependencyType.getType(outputDependency);
if (!this.numFreePhysicalRegistersToAllocate.containsKey(outputDependencyType)) {
this.numFreePhysicalRegistersToAllocate.put(outputDependencyType, 0);
}
this.numFreePhysicalRegistersToAllocate.put(outputDependencyType, this.numFreePhysicalRegistersToAllocate.get(outputDependencyType) + 1);
});
}
/**
* Get the mnemonic.
*
* @return the mnemonic
*/
public Mnemonic getMnemonic() {
return mnemonic;
}
/**
* Get the machine instruction.
*
* @return the machine instruction
*/
public int getMachineInstruction() {
return machineInstruction;
}
/**
* Get the list of input dependencies.
*
* @return the list of input dependencies
*/
public List<Integer> getInputDependencies() {
return inputDependencies;
}
/**
* Get the list of output dependencies.
*
* @return the list of output dependencies
*/
public List<Integer> getOutputDependencies() {
return outputDependencies;
}
/**
* Get the non effective address base dependency.
*
* @return the non effective address base dependency
*/
public int getNonEffectiveAddressBaseDependency() {
return nonEffectiveAddressBaseDependency;
}
/**
* Get the number of free physical registers to be allocated.
*
* @return the number of free physical registers to be allocated
*/
public Map<RegisterDependencyType, Integer> getNumFreePhysicalRegistersToAllocate() {
return numFreePhysicalRegistersToAllocate;
}
private static final int FMT_SINGLE = 16;
private static final int FMT_DOUBLE = 17;
private static final int FMT_WORD = 20;
private static final int FMT_LONG = 21;
private static final int FMT_PS = 22;
private static final int FMT3_SINGLE = 0;
private static final int FMT3_DOUBLE = 1;
private static final int FMT3_WORD = 4;
private static final int FMT3_LONG = 5;
private static final int FMT3_PS = 6;
/**
* Dependency.
*/
public enum Dependency {
/**
* RS.
*/
RS,
/**
* RT.
*/
RT,
/**
* RD.
*/
RD,
/**
* FS.
*/
FS,
/**
* FT.
*/
FT,
/**
* FD.
*/
FD,
/**
* Register RA.
*/
REGISTER_RA,
/**
* Register V0.
*/
REGISTER_V0,
/**
* Register HI.
*/
REGISTER_HI,
/**
* Register LO.
*/
REGISTER_LO,
/**
* Register FCSR.
*/
REGISTER_FCSR
}
/**
* The list of mnemonics.
*/
public static final List<Mnemonic> MNEMONICS;
/**
* Static constructor.
*/
static {
Method[] declaredMethods = StaticInstruction.class.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
StaticInstructionIntrinsic staticInstIntrinsic = declaredMethod.getAnnotation(StaticInstructionIntrinsic.class);
if (staticInstIntrinsic != null) {
staticInstIntrinsic.mnemonic().setMethod(declaredMethod);
}
}
MNEMONICS = new ArrayList<Mnemonic>() {{
add(Mnemonic.NOP);
add(Mnemonic.BC1F);
add(Mnemonic.BC1T);
add(Mnemonic.MFC1);
add(Mnemonic.MTC1);
add(Mnemonic.CFC1);
add(Mnemonic.CTC1);
add(Mnemonic.ABS_S);
add(Mnemonic.ABS_D);
add(Mnemonic.ADD);
add(Mnemonic.ADD_S);
add(Mnemonic.ADD_D);
add(Mnemonic.ADDI);
add(Mnemonic.ADDIU);
add(Mnemonic.ADDU);
add(Mnemonic.AND);
add(Mnemonic.ANDI);
add(Mnemonic.B);
add(Mnemonic.BAL);
add(Mnemonic.BEQ);
add(Mnemonic.BGEZ);
add(Mnemonic.BGEZAL);
add(Mnemonic.BGTZ);
add(Mnemonic.BLEZ);
add(Mnemonic.BLTZ);
add(Mnemonic.BNE);
add(Mnemonic.BREAK);
add(Mnemonic.C_COND_S);
add(Mnemonic.C_COND_D);
add(Mnemonic.CVT_D_S);
add(Mnemonic.CVT_D_W);
add(Mnemonic.CVT_D_L);
add(Mnemonic.CVT_S_D);
add(Mnemonic.CVT_S_W);
add(Mnemonic.CVT_S_L);
add(Mnemonic.CVT_W_S);
add(Mnemonic.CVT_W_D);
add(Mnemonic.DIV);
add(Mnemonic.DIV_S);
add(Mnemonic.DIV_D);
add(Mnemonic.DIVU);
add(Mnemonic.J);
add(Mnemonic.JAL);
add(Mnemonic.JALR);
add(Mnemonic.JR);
add(Mnemonic.LB);
add(Mnemonic.LBU);
add(Mnemonic.LDC1);
add(Mnemonic.LH);
add(Mnemonic.LHU);
add(Mnemonic.LL);
add(Mnemonic.LUI);
add(Mnemonic.LW);
add(Mnemonic.LWC1);
add(Mnemonic.LWL);
add(Mnemonic.LWR);
add(Mnemonic.MADD);
add(Mnemonic.MFHI);
add(Mnemonic.MFLO);
add(Mnemonic.MOV_S);
add(Mnemonic.MOV_D);
add(Mnemonic.MOVF);
add(Mnemonic._MOVF);
add(Mnemonic.MOVN);
add(Mnemonic._MOVN);
add(Mnemonic._MOVT);
add(Mnemonic.MOVZ);
add(Mnemonic._MOVZ);
add(Mnemonic.MSUB);
add(Mnemonic.MTLO);
add(Mnemonic.MUL);
add(Mnemonic.MUL_S);
add(Mnemonic.MUL_D);
add(Mnemonic.MULT);
add(Mnemonic.MULTU);
add(Mnemonic.NEG_S);
add(Mnemonic.NEG_D);
add(Mnemonic.NOR);
add(Mnemonic.OR);
add(Mnemonic.ORI);
add(Mnemonic.SB);
add(Mnemonic.SC);
add(Mnemonic.SDC1);
add(Mnemonic.SH);
add(Mnemonic.SLL);
add(Mnemonic.SLLV);
add(Mnemonic.SLT);
add(Mnemonic.SLTI);
add(Mnemonic.SLTIU);
add(Mnemonic.SLTU);
add(Mnemonic.SQRT_S);
add(Mnemonic.SQRT_D);
add(Mnemonic.SRA);
add(Mnemonic.SRAV);
add(Mnemonic.SRL);
add(Mnemonic.SRLV);
add(Mnemonic.SUB_S);
add(Mnemonic.SUB_D);
add(Mnemonic.SUBU);
add(Mnemonic.SW);
add(Mnemonic.SWC1);
add(Mnemonic.SWL);
add(Mnemonic.SWR);
add(Mnemonic.SYSTEM_CALL);
add(Mnemonic.TRUNC_W);
add(Mnemonic.XOR);
add(Mnemonic.XORI);
}};
}
/**
* "Add" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADD, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000020, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void add(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) + context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Addi" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADDI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x20000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void addi(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) + MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction))
);
}
/**
* "Addiu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADDIU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x24000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void addiu(Context context, int machineInstruction) {
if (!context.isSpeculative()) {
PseudoCall pseudoCall = getPseudoCall(machineInstruction);
if (pseudoCall != null) {
context.setPseudoCallEncounteredInLastInstructionExecution(true);
context.getBlockingEventDispatcher().dispatch(new PseudoCallEncounteredEvent(context, pseudoCall));
return;
}
}
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) + MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction))
);
}
/**
* "Addu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADDU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000021, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void addu(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) + context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "And" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.AND, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000024, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void and(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) & context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Andi" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ANDI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x30000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void andi(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) & MathHelper.zeroExtend(BitField.INTIMM.valueOf(machineInstruction))
);
}
/**
* "Div" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.DIV, functionalUnitOperationType = FunctionalUnitOperationType.INT_DIVIDE)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x0000001a, mask = 0xfc00ffff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({Dependency.REGISTER_HI, Dependency.REGISTER_LO})
private static void div(Context context, int machineInstruction) {
int rs = context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
int rt = context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction));
context.getRegisterFile().setHi(rt != 0 ? rs % rt : 0);
context.getRegisterFile().setLo(rt != 0 ? rs / rt : 0);
}
/**
* "Divu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.DIVU, functionalUnitOperationType = FunctionalUnitOperationType.INT_DIVIDE)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x0000001b, mask = 0xfc00003f)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({Dependency.REGISTER_HI, Dependency.REGISTER_LO})
private static void divu(Context context, int machineInstruction) {
long rs = ((long) context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction))) << 32 >>> 32;
long rt = ((long) context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) << 32 >>> 32;
context.getRegisterFile().setHi(rt != 0 ? (int) (((rs % rt) << 32) >> 32) : 0);
context.getRegisterFile().setLo(rt != 0 ? (int) (((rs / rt) << 32) >> 32) : 0);
}
/**
* "Lui" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LUI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x3c000000, mask = 0xffe00000)
@InputDependencies({})
@OutputDependencies(Dependency.RT)
private static void lui(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), BitField.INTIMM.valueOf(machineInstruction) << 16);
}
/**
* "Madd" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MADD, functionalUnitOperationType = FunctionalUnitOperationType.INT_MULTIPLY)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x70000000, mask = 0xfc00ffff)
@InputDependencies({Dependency.RS, Dependency.RT, Dependency.REGISTER_HI, Dependency.REGISTER_LO})
@OutputDependencies({Dependency.REGISTER_HI, Dependency.REGISTER_LO})
private static void madd(Context context, int machineInstruction) {
long temp = (long) context.getRegisterFile().getHi() << 32 | (long) context.getRegisterFile().getLo() + context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) * context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction));
context.getRegisterFile().setHi((int) (temp >> 32));
context.getRegisterFile().setLo((int) ((temp << 32) >> 32));
}
/**
* "Mfhi" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MFHI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000010, mask = 0xffff07ff)
@InputDependencies(Dependency.REGISTER_HI)
@OutputDependencies(Dependency.RD)
private static void mfhi(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(BitField.RD.valueOf(machineInstruction), context.getRegisterFile().getHi());
}
/**
* "Mflo" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MFLO, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000012, mask = 0xffff07ff)
@InputDependencies(Dependency.REGISTER_LO)
@OutputDependencies(Dependency.RD)
private static void mflo(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(BitField.RD.valueOf(machineInstruction), context.getRegisterFile().getLo());
}
/**
* "Msub" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MSUB, functionalUnitOperationType = FunctionalUnitOperationType.INT_MULTIPLY)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x70000004, mask = 0xfc00ffff)
@InputDependencies({Dependency.RS, Dependency.RT, Dependency.REGISTER_HI, Dependency.REGISTER_LO})
@OutputDependencies({Dependency.REGISTER_HI, Dependency.REGISTER_LO})
private static void msub(Context context, int machineInstruction) {
long temp = (long) context.getRegisterFile().getHi() << 32 | (long) context.getRegisterFile().getLo() - context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) * context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction));
context.getRegisterFile().setHi((int) (temp >> 32));
context.getRegisterFile().setLo((int) ((temp << 32) >> 32));
}
/**
* "Mthi" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MTHI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RD)
@OutputDependencies(Dependency.REGISTER_HI)
private static void mthi(Context context, int machineInstruction) {
context.getRegisterFile().setHi(context.getRegisterFile().getGpr(BitField.RD.valueOf(machineInstruction)));
}
/**
* "Mtlo" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MTLO, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000013, mask = 0xfc1fffff)
@InputDependencies(Dependency.RD)
@OutputDependencies(Dependency.REGISTER_LO)
private static void mtlo(Context context, int machineInstruction) {
context.getRegisterFile().setLo(context.getRegisterFile().getGpr(BitField.RD.valueOf(machineInstruction)));
}
/**
* "Mult" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MULT, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000018, mask = 0xfc00003f)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({Dependency.REGISTER_LO, Dependency.REGISTER_HI})
private static void mult(Context context, int machineInstruction) {
long product = (long) (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction))) * (long) (context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
context.getRegisterFile().setHi((int) (product >> 32));
context.getRegisterFile().setLo((int) ((product << 32) >> 32));
}
/**
* "Multu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MULTU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000019, mask = 0xfc00003f)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({Dependency.REGISTER_LO, Dependency.REGISTER_HI})
private static void multu(Context context, int machineInstruction) {
long product = (((long) context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction))) << 32 >>> 32) * (((long) context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) << 32 >>> 32);
context.getRegisterFile().setHi((int) (product >> 32));
context.getRegisterFile().setLo((int) ((product << 32) >> 32));
}
/**
* "Nor" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.NOR, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000027, mask = 0xfc00003f)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void nor(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
~(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) | context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)))
);
}
/**
* "Or" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.OR, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000025, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void or(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) | context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Ori" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ORI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x34000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void ori(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) | MathHelper.zeroExtend(BitField.INTIMM.valueOf(machineInstruction))
);
}
/**
* "Sll" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000000, mask = 0xffe0003f)
@InputDependencies(Dependency.RT)
@OutputDependencies(Dependency.RD)
private static void sll(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) << BitField.SHIFT.valueOf(machineInstruction)
);
}
/**
* "Sllv" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLLV, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000004, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void sllv(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) << MathHelper.bits(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)), 4, 0)
);
}
/**
* "Slt" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLT, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x0000002a, mask = 0xfc00003f)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void slt(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) ? 1 : 0
);
}
/**
* "Slti" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLTI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x28000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void slti(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction))) ? 1 : 0
);
}
/**
* "Sltiu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLTIU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x2c000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void sltiu(Context context, int machineInstruction) {
int rs = context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
int imm = MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction));
if (rs >= 0 && imm >= 0 || rs < 0 && imm < 0) {
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), (rs < imm) ? 1 : 0);
} else {
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), (rs >= 0) ? 1 : 0);
}
}
/**
* "Sltu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SLTU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION})
@DecodeMethod(bits = 0x0000002b, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void sltu(Context context, int machineInstruction) {
int rs = context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
int rt = context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction));
if (rs >= 0 && rt >= 0 || rs < 0 && rt < 0) {
context.getRegisterFile().setGpr(BitField.RD.valueOf(machineInstruction), (rs < rt) ? 1 : 0);
} else {
context.getRegisterFile().setGpr(BitField.RD.valueOf(machineInstruction), (rs >= 0) ? 1 : 0);
}
}
/**
* "Sra" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SRA, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000003, mask = 0xffe0003f)
@InputDependencies(Dependency.RT)
@OutputDependencies(Dependency.RD)
private static void sra(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) >> BitField.SHIFT.valueOf(machineInstruction)
);
}
/**
* "Srav" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SRAV, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000007, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void srav(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) >> MathHelper.bits(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)), 4, 0)
);
}
/**
* "Srl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SRL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000002, mask = 0xffe0003f)
@InputDependencies(Dependency.RT)
@OutputDependencies(Dependency.RD)
private static void srl(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) >>> BitField.SHIFT.valueOf(machineInstruction)
);
}
/**
* "Srlv" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SRLV, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000006, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void srlv(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)) >>> MathHelper.bits(context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)), 4, 0)
);
}
/**
* "Sub" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SUB, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x0, mask = 0x0) // TODO: missing decoding information
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void sub(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) - context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Subu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SUBU, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000023, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void subu(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) - context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Xor" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.XOR, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags(StaticInstructionFlag.INTEGER_COMPUTATION)
@DecodeMethod(bits = 0x00000026, mask = 0xfc0007ff)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RD)
private static void xor(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RD.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) ^ context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Xori" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.XORI, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION, StaticInstructionFlag.IMMEDIATE})
@DecodeMethod(bits = 0x38000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
private static void xori(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) ^ MathHelper.zeroExtend(BitField.INTIMM.valueOf(machineInstruction))
);
}
/**
* "Abs_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ABS_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000005, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void abs_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
Math.abs(context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)))
);
}
/**
* "Abs_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ABS_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000005, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void abs_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
Math.abs(context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)))
);
}
/**
* "Add_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADD_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_ADD)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000000, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void add_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)) + context.getRegisterFile().getFprs().getDouble(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Add_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.ADD_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_ADD)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000000, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void add_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)) + context.getRegisterFile().getFprs().getFloat(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "C_cond_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.C_COND_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000030, mask = 0xfc0000f0)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies({Dependency.FS, Dependency.FT, Dependency.REGISTER_FCSR})
@OutputDependencies(Dependency.REGISTER_FCSR)
private static void c_cond_d(Context context, int machineInstruction) {
double fs = context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction));
double ft = context.getRegisterFile().getFprs().getDouble(BitField.FT.valueOf(machineInstruction));
boolean unordered = Double.isNaN(fs) || Double.isNaN(ft);
c_cond(context, machineInstruction, unordered, !unordered && fs < ft, !unordered && fs == ft);
}
/**
* "C_cond_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.C_COND_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000030, mask = 0xfc0000f0)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies({Dependency.FS, Dependency.FT, Dependency.REGISTER_FCSR})
@OutputDependencies(Dependency.REGISTER_FCSR)
private static void c_cond_s(Context context, int machineInstruction) {
float fs = context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction));
float ft = context.getRegisterFile().getFprs().getFloat(BitField.FT.valueOf(machineInstruction));
boolean unordered = Float.isNaN(fs) || Float.isNaN(ft);
c_cond(context, machineInstruction, unordered, !unordered && fs < ft, !unordered && fs == ft);
}
/**
* "C_cond" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
* @param unordered a value indicating whether the instruction is unordered or not
* @param less a value indicating whether the condition is less or not.
* @param equal a value indicating whether the condition is equal or not.
*/
private static void c_cond(Context context, int machineInstruction, boolean unordered, boolean less, boolean equal) {
int cond = BitField.COND.valueOf(machineInstruction);
Reference<Integer> fcsrRef = new Reference<>(context.getRegisterFile().getFcsr());
if ((((cond & 0x4) != 0) && less) || (((cond & 0x2) != 0) && equal) || (((cond & 0x1) != 0) && unordered)) {
setFCC(fcsrRef, BitField.CC.valueOf(machineInstruction));
} else {
clearFCC(fcsrRef, BitField.CC.valueOf(machineInstruction));
}
context.getRegisterFile().setFcsr(fcsrRef.get());
}
/**
* "Cvt_d_l" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_D_L, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000021, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_LONG)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_d_l(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getLong(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_d_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_D_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000021, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_d_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_d_w" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_D_W, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000021, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_WORD)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_d_w(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getInt(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_l_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_L_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_l_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setLong(
BitField.FD.valueOf(machineInstruction),
(long) context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_l_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_L_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_l_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setLong(
BitField.FD.valueOf(machineInstruction),
(long) context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_s_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_S_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000020, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_s_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
(float) context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_s_l" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_S_L, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000020, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_LONG)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_s_l(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getLong(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_s_w" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_S_W, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000020, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_WORD)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_s_w(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getInt(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_w_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_W_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000024, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_w_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setInt(
BitField.FD.valueOf(machineInstruction),
(int) context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Cvt_w_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CVT_W_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_CONVERT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000024, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void cvt_w_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setInt(
BitField.FD.valueOf(machineInstruction),
(int) context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Div_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.DIV_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_DIVIDE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000003, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void div_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)) / context.getRegisterFile().getFprs().getDouble(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Div_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.DIV_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_DIVIDE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000003, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void div_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)) / context.getRegisterFile().getFprs().getFloat(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Mov_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MOV_D, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.FLOAT_COMPUTATION})
@DecodeMethod(bits = 0x44000006, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void mov_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Mov_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MOV_S, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.FLOAT_COMPUTATION})
@DecodeMethod(bits = 0x44000006, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void mov_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Movf" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MOVF, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x00000001, mask = 0xfc0307ff)
private static void movf(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: movf
}
/**
* "_movf" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic._MOVF, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x44000011, mask = 0xfc03003f)
private static void _movf(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: _movf
}
/**
* "Movn" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MOVN, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x0000000b, mask = 0xfc0007ff)
private static void movn(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: movn
}
/**
* "_movn" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic._MOVN, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x44000013, mask = 0xfc00003f)
private static void _movn(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: _movn
}
/**
* "_movt" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic._MOVT, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x44010011, mask = 0xfc03003f)
private static void _movt(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: _movt
}
/**
* "Movz" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MOVZ, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x0000000a, mask = 0xfc0007ff)
private static void movz(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: movz
}
/**
* "_movz" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic._MOVZ, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x44000012, mask = 0xfc00003f)
private static void _movz(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: _movz
}
/**
* "Mul" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MUL, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x70000002, mask = 0xfc0007ff)
private static void mul(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: mul
}
/**
* "Trunc_w" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.TRUNC_W, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNIMPLEMENTED})
@DecodeMethod(bits = 0x4400000d, mask = 0xfc1f003f)
private static void trunc_w(Context context, int machineInstruction) {
throw new UnsupportedOperationException(); //TODO: trunc_w
}
/**
* "Mul_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MUL_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_MULTIPLY)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000002, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void mul_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)) * context.getRegisterFile().getFprs().getDouble(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Mul_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MUL_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_MULTIPLY)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000002, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void mul_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)) * context.getRegisterFile().getFprs().getFloat(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Neg_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.NEG_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000007, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void neg_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
-context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Neg_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.NEG_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_COMPARE)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000007, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void neg_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
-context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction))
);
}
/**
* "Sqrt_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SQRT_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_SQRT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000004, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void sqrt_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
Math.sqrt(context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)))
);
}
/**
* "Sqrt_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SQRT_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_SQRT)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000004, mask = 0xfc1f003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.FD)
private static void sqrt_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
(float) Math.sqrt(context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)))
);
}
/**
* "Sub_d" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SUB_D, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_ADD)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000001, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_DOUBLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void sub_d(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setDouble(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getDouble(BitField.FS.valueOf(machineInstruction)) - context.getRegisterFile().getFprs().getDouble(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Sub_s" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SUB_S, functionalUnitOperationType = FunctionalUnitOperationType.FLOAT_ADD)
@StaticInstructionFlags(StaticInstructionFlag.FLOAT_COMPUTATION)
@DecodeMethod(bits = 0x44000001, mask = 0xfc00003f)
@DecodeCondition(bitField = "fmt", value = FMT_SINGLE)
@InputDependencies({Dependency.FS, Dependency.FT})
@OutputDependencies(Dependency.FD)
private static void sub_s(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setFloat(
BitField.FD.valueOf(machineInstruction),
context.getRegisterFile().getFprs().getFloat(BitField.FS.valueOf(machineInstruction)) - context.getRegisterFile().getFprs().getFloat(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "J" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.J, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x08000000, mask = 0xfc000000)
@InputDependencies({})
@OutputDependencies({})
private static void j(Context context, int machineInstruction) {
doJump(context, getTargetPcForJ(context.getRegisterFile().getNpc(), machineInstruction));
}
/**
* "Jal" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.JAL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0c000000, mask = 0xfc000000)
@InputDependencies({})
@OutputDependencies(Dependency.REGISTER_RA)
private static void jal(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
doJump(context, getTargetPcForJal(context.getRegisterFile().getNpc(), machineInstruction));
if (!context.isSpeculative()) {
onFunctionCall(context, false);
}
}
/**
* "Jalr" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.JALR, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.INDIRECT_JUMP})
@DecodeMethod(bits = 0x00000009, mask = 0xfc00003f)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RD)
private static void jalr(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(BitField.RD.valueOf(machineInstruction), context.getRegisterFile().getNnpc());
doJump(context, getTargetPcForJalr(context, machineInstruction));
if (!context.isSpeculative()) {
onFunctionCall(context, true);
}
}
/**
* "Jr" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.JR, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.FUNCTION_RETURN, StaticInstructionFlag.INDIRECT_JUMP})
@DecodeMethod(bits = 0x00000008, mask = 0xfc00003f)
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void jr(Context context, int machineInstruction) {
doJump(context, getTargetPcForJr(context, machineInstruction));
if (!context.isSpeculative() && BitField.RS.valueOf(machineInstruction) == ArchitecturalRegisterFile.REGISTER_RA) {
onFunctionReturn(context);
}
}
/**
* "B" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.B, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x10000000, mask = 0xffff0000)
@InputDependencies({})
@OutputDependencies({})
private static void b(Context context, int machineInstruction) {
doBranch(context, machineInstruction);
}
/**
* "Bal" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BAL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.UNCONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x04110000, mask = 0xffff0000)
@InputDependencies({})
@OutputDependencies(Dependency.REGISTER_RA)
private static void bal(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
doBranch(context, machineInstruction);
}
/**
* "Bc1f" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BC1F, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL})
@DecodeMethod(bits = 0x45000000, mask = 0xffe30000)
@InputDependencies(Dependency.REGISTER_FCSR)
@OutputDependencies({})
private static void bc1f(Context context, int machineInstruction) {
if (!getFCC(context.getRegisterFile().getFcsr(), BitField.BRANCH_CC.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
}
}
/**
* "Bc1fl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BC1FL, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.REGISTER_FCSR)
@OutputDependencies({})
private static void bc1fl(Context context, int machineInstruction) {
if (!getFCC(context.getRegisterFile().getFcsr(), BitField.BRANCH_CC.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bc1t" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BC1T, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL})
@DecodeMethod(bits = 0x45010000, mask = 0xffe30000)
@InputDependencies(Dependency.REGISTER_FCSR)
@OutputDependencies({})
private static void bc1t(Context context, int machineInstruction) {
if (getFCC(context.getRegisterFile().getFcsr(), BitField.BRANCH_CC.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
}
}
/**
* "Bc1tl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BC1TL, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.REGISTER_FCSR)
@OutputDependencies({})
private static void bc1tl(Context context, int machineInstruction) {
if (getFCC(context.getRegisterFile().getFcsr(), BitField.BRANCH_CC.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Beq" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BEQ, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x10000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
private static void beq(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) == context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
}
}
/**
* "Beql" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BEQL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
private static void beql(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) == context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bgez" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGEZ, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x04010000, mask = 0xfc1f0000)
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bgez(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) >= 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bgezal" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGEZAL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x04110000, mask = 0xfc1f0000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.REGISTER_RA)
private static void bgezal(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) >= 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bgezall" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGEZALL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.REGISTER_RA)
private static void bgezall(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) >= 0) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bgezl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGEZL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bgezl(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) >= 0) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bgtz" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGTZ, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x1c000000, mask = 0xfc1f0000)
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bgtz(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) > 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bgtzl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BGTZL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bgtzl(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) > 0) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Blez" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLEZ, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x18000000, mask = 0xfc1f0000)
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void blez(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) <= 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Blezl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLEZL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void blezl(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) <= 0) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bltz" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLTZ, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x04000000, mask = 0xfc1f0000)
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bltz(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bltzal" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLTZAL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.REGISTER_RA)
private static void bltzal(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bltzall" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLTZALL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.FUNCTION_CALL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.REGISTER_RA)
private static void bltzall(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(ArchitecturalRegisterFile.REGISTER_RA, context.getRegisterFile().getNnpc());
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < 0) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Bltzl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BLTZL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies(Dependency.RS)
@OutputDependencies({})
private static void bltzl(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) < 0) {
doBranch(context, machineInstruction);
}
}
/**
* "Bne" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BNE, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x14000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
private static void bne(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) != context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
}
}
/**
* "Bnel" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BNEL, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.CONDITIONAL, StaticInstructionFlag.DIRECT_JUMP})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: missing decoding information
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
private static void bnel(Context context, int machineInstruction) {
if (context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction)) != context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))) {
doBranch(context, machineInstruction);
} else {
skipDelaySlot(context);
}
}
/**
* "Lb" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LB, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x80000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lb(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readByte(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lbu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LBU, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x90000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lbu(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readByte(getEffectiveAddress(context, machineInstruction)) & 0xff
);
}
/**
* "Ldc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LDC1, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xd4000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.FT)
@NonEffectiveAddressBaseDependency(Dependency.FT)
private static void ldc1(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setLong(
BitField.FT.valueOf(machineInstruction),
context.getProcess().getMemory().readDoubleWord(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lh" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LH, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x84000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lh(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readHalfWord(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lhu" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LHU, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x94000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lhu(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readHalfWord(getEffectiveAddress(context, machineInstruction)) & 0xffff
);
}
/**
* "Ll" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LL, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xc0000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void ll(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readWord(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lw" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LW, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x8c000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lw(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(
BitField.RT.valueOf(machineInstruction),
context.getProcess().getMemory().readWord(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lwc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LWC1, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xc4000000, mask = 0xfc000000)
@InputDependencies(Dependency.RS)
@OutputDependencies(Dependency.FT)
@NonEffectiveAddressBaseDependency(Dependency.FT)
private static void lwc1(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setInt(
BitField.FT.valueOf(machineInstruction),
context.getProcess().getMemory().readWord(getEffectiveAddress(context, machineInstruction))
);
}
/**
* "Lwl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LWL, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x88000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lwl(Context context, int machineInstruction) {
int addr = getEffectiveAddress(context, machineInstruction);
int size = 4 - (addr & 3);
byte[] src = new byte[4];
ByteBuffer.wrap(src).order(context.getProcess().isLittleEndian() ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN).put(context.getProcess().getMemory().readBlock(addr, size));
byte[] dst = new byte[4];
ByteBuffer.wrap(dst).order(ByteOrder.LITTLE_ENDIAN).putInt(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
for (int i = 0; i < size; i++) {
dst[3 - i] = src[i];
}
int rt = ByteBuffer.wrap(dst).order(ByteOrder.LITTLE_ENDIAN).getInt();
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), rt);
}
/**
* "Lwr" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.LWR, functionalUnitOperationType = FunctionalUnitOperationType.READ_PORT)
@StaticInstructionFlags({StaticInstructionFlag.LOAD, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0x98000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void lwr(Context context, int machineInstruction) {
int addr = getEffectiveAddress(context, machineInstruction);
int size = 1 + (addr & 3);
byte[] src = new byte[4];
ByteBuffer.wrap(src).order(context.getProcess().isLittleEndian() ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN).put(context.getProcess().getMemory().readBlock(addr - size + 1, size));
byte[] dst = new byte[4];
ByteBuffer.wrap(dst).order(ByteOrder.LITTLE_ENDIAN).putInt(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
for (int i = 0; i < size; i++) {
dst[size - i - 1] = src[i];
}
int rt = ByteBuffer.wrap(dst).order(ByteOrder.LITTLE_ENDIAN).getInt();
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), rt);
}
/**
* "Sb" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SB, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xa0000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void sb(Context context, int machineInstruction) {
context.getProcess().getMemory().writeByte(
getEffectiveAddress(context, machineInstruction),
(byte) MathHelper.bits(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)), 7, 0)
);
}
/**
* "Sc" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SC, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xe0000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies(Dependency.RT)
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void sc(Context context, int machineInstruction) {
context.getProcess().getMemory().writeWord(
getEffectiveAddress(context, machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), 1);
}
/**
* "Sdc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SDC1, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xf4000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.FT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.FT)
private static void sdc1(Context context, int machineInstruction) {
context.getProcess().getMemory().writeDoubleWord(
getEffectiveAddress(context, machineInstruction),
context.getRegisterFile().getFprs().getLong(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Sh" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SH, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xa4000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void sh(Context context, int machineInstruction) {
context.getProcess().getMemory().writeHalfWord(
getEffectiveAddress(context, machineInstruction),
(short) MathHelper.bits(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)), 15, 0)
);
}
/**
* "Sw" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SW, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xac000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void sw(Context context, int machineInstruction) {
context.getProcess().getMemory().writeWord(
getEffectiveAddress(context, machineInstruction),
context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction))
);
}
/**
* "Swc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SWC1, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xe4000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.FT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.FT)
private static void swc1(Context context, int machineInstruction) {
context.getProcess().getMemory().writeWord(
getEffectiveAddress(context, machineInstruction),
context.getRegisterFile().getFprs().getInt(BitField.FT.valueOf(machineInstruction))
);
}
/**
* "Swl" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SWL, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xa8000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void swl(Context context, int machineInstruction) {
int addr = getEffectiveAddress(context, machineInstruction);
int size = 4 - (addr & 3);
byte[] src = new byte[4];
ByteBuffer.wrap(src).order(ByteOrder.LITTLE_ENDIAN).putInt(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
byte[] dst = new byte[4];
for (int i = 0; i < size; i++) {
dst[i] = src[3 - i];
}
context.getProcess().getMemory().writeBlock(addr, size, dst);
}
/**
* "Swr" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SWR, functionalUnitOperationType = FunctionalUnitOperationType.WRITE_PORT)
@StaticInstructionFlags({StaticInstructionFlag.STORE, StaticInstructionFlag.DISPLACED_ADDRESSING})
@DecodeMethod(bits = 0xb8000000, mask = 0xfc000000)
@InputDependencies({Dependency.RS, Dependency.RT})
@OutputDependencies({})
@NonEffectiveAddressBaseDependency(Dependency.RT)
private static void swr(Context context, int machineInstruction) {
int addr = getEffectiveAddress(context, machineInstruction);
int size = 1 + (addr & 3);
byte[] src = new byte[4];
ByteBuffer.wrap(src).order(ByteOrder.LITTLE_ENDIAN).putInt(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
byte[] dst = new byte[4];
for (int i = 0; i < size; i++) {
dst[i] = src[size - i - 1];
}
context.getProcess().getMemory().writeBlock(addr - size + 1, size, dst);
}
/**
* "Cfc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CFC1, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION})
@DecodeMethod(bits = 0x44400000, mask = 0xffe007ff)
@InputDependencies(Dependency.REGISTER_FCSR)
@OutputDependencies(Dependency.RT)
private static void cfc1(Context context, int machineInstruction) {
if (BitField.FS.valueOf(machineInstruction) == 31) {
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), context.getRegisterFile().getFcsr());
}
}
/**
* "Ctc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.CTC1, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION})
@DecodeMethod(bits = 0x44c00000, mask = 0xffe007ff)
@InputDependencies(Dependency.RT)
@OutputDependencies(Dependency.REGISTER_FCSR)
private static void ctc1(Context context, int machineInstruction) {
if (BitField.FS.valueOf(machineInstruction) != 0) {
context.getRegisterFile().setFcsr(context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
}
}
/**
* "Mfc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MFC1, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION})
@DecodeMethod(bits = 0x44000000, mask = 0xffe007ff)
@InputDependencies(Dependency.FS)
@OutputDependencies(Dependency.RT)
private static void mfc1(Context context, int machineInstruction) {
context.getRegisterFile().setGpr(BitField.RT.valueOf(machineInstruction), context.getRegisterFile().getFprs().getInt(BitField.FS.valueOf(machineInstruction)));
}
/**
* "Mtc1" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.MTC1, functionalUnitOperationType = FunctionalUnitOperationType.INT_ALU)
@StaticInstructionFlags({StaticInstructionFlag.INTEGER_COMPUTATION})
@DecodeMethod(bits = 0x44800000, mask = 0xffe007ff)
@InputDependencies(Dependency.RT)
@OutputDependencies(Dependency.FS)
private static void mtc1(Context context, int machineInstruction) {
context.getRegisterFile().getFprs().setInt(BitField.FS.valueOf(machineInstruction), context.getRegisterFile().getGpr(BitField.RT.valueOf(machineInstruction)));
}
/**
* "_break" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.BREAK, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.TRAP})
@DecodeMethod(bits = 0x0000000d, mask = 0xfc00003f)
@InputDependencies({})
@OutputDependencies({})
private static void _break(Context context, int machineInstruction) {
if (!context.isSpeculative()) {
context.finish();
}
}
/**
* "System call" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.SYSTEM_CALL, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.TRAP})
@DecodeMethod(bits = 0x0000000c, mask = 0xfc00003f)
@InputDependencies(Dependency.REGISTER_V0)
@OutputDependencies({})
private static void system_call(Context context, int machineInstruction) {
if (!context.isSpeculative()) {
context.getKernel().getSystemCallEmulation().doSystemCall(context.getRegisterFile().getGpr(ArchitecturalRegisterFile.REGISTER_V0), context);
}
}
/**
* "No operation (NOP)" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.NOP, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.NOP})
@DecodeMethod(bits = 0x00000000, mask = 0xffffffff)
@InputDependencies({})
@OutputDependencies({})
private static void nop(Context context, int machineInstruction) {
}
/**
* "Unknown" instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
@StaticInstructionIntrinsic(mnemonic = Mnemonic.UNKNOWN, functionalUnitOperationType = FunctionalUnitOperationType.NONE)
@StaticInstructionFlags({StaticInstructionFlag.UNKNOWN})
@DecodeMethod(bits = 0x0, mask = 0x0) //TODO: special support for unknown instruction
@InputDependencies({})
@OutputDependencies({})
private static void unknown(Context context, int machineInstruction) {
if (!context.isSpeculative()) {
Logger.panicf(Logger.INSTRUCTION, "{ctx-%d} 0x%08x: Unknown instruction 0x%08x", context.getCycleAccurateEventQueue().getCurrentCycle(), context.getId(), context.getRegisterFile().getPc(), machineInstruction);
}
}
/**
* Act on a function call.
*
* @param context the context
* @param jalr a value indicating whether the instruction is jalr or not.
*/
private static void onFunctionCall(Context context, boolean jalr) {
StaticInstruction staticInst = context.getProcess().getStaticInstruction(context.getRegisterFile().getPc());
int targetPc = jalr ? getTargetPcForJalr(context, staticInst.getMachineInstruction()) : getTargetPcForJr(context, staticInst.getMachineInstruction());
FunctionCallContext functionCallContext = new FunctionCallContext(context, context.getRegisterFile().getPc(), targetPc);
context.getFunctionCallContextStack().push(functionCallContext);
context.getBlockingEventDispatcher().dispatch(new FunctionCallEvent(functionCallContext));
}
/**
* Act on a function return.
*
* @param context the context
*/
private static void onFunctionReturn(Context context) {
FunctionCallContext functionCallContext = context.getFunctionCallContextStack().pop();
context.getBlockingEventDispatcher().dispatch(new FunctionReturnEvent(functionCallContext));
}
/**
* Get a value indicating whether using the stack pointer as the effective address base.
*
* @return a value indicating whether using the stack pointer as the effective address base
*/
public boolean useStackPointerAsEffectiveAddressBase() {
return useStackPointerAsEffectiveAddressBase(this.machineInstruction);
}
/**
* Get the effective address base for the instruction in the specified context.
*
* @param context the context
* @return the effective address base for the instruction in the specified context
*/
public int getEffectiveAddressBase(Context context) {
return getEffectiveAddress(context, this.machineInstruction);
}
/**
* Get the effective address displacement.
*
* @return the effective address displacement
*/
public int getEffectiveAddressDisplacement() {
return getEffectiveAddressDisplacement(this.machineInstruction);
}
/**
* Get the effective address for the instruction in the specified context.
*
* @param context the context the context
* @return the effective address for the instruction in the specified context
*/
public int getEffectiveAddress(Context context) {
return getEffectiveAddress(context, this.machineInstruction);
}
/**
* Get a value indicating whether using the stack pointer as the effective address base for the specified machine instruction.
*
* @param machineInstruction the machine instruction
* @return a value indicating whether using the stack pointer as the effective address base for the specified machine instruction
*/
public static boolean useStackPointerAsEffectiveAddressBase(int machineInstruction) {
return BitField.RS.valueOf(machineInstruction) == ArchitecturalRegisterFile.REGISTER_SP;
}
/**
* Get the effective address base for the specified machine instruction in the specified context.
*
* @param context the context
* @param machineInstruction the machine instruction
* @return the effective address base for the specified machine instruction in the specifid context
*/
public static int getEffectiveAddressBase(Context context, int machineInstruction) {
return context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
}
/**
* Get the effective address displacement for the specified machine instruction.
*
* @param machineInstruction the machine instruction
* @return the effective address displacement for the specified machine instruction
*/
public static int getEffectiveAddressDisplacement(int machineInstruction) {
return MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction));
}
/**
* Get the effective address for the specified machine instruction in the specified context.
*
* @param context the context
* @param machineInstruction the machine instruction
* @return the effective address for the specified machine instruction in the specified context
*/
public static int getEffectiveAddress(Context context, int machineInstruction) {
return getEffectiveAddressBase(context, machineInstruction) + getEffectiveAddressDisplacement(machineInstruction);
}
/**
* Get the FCC value in the FCSR register.
*
* @param fcsr the FCSR register
* @param ccIdx the CC index
* @return the computed FCC value
*/
private static boolean getFCC(int fcsr, int ccIdx) {
return ((fcsr >> ((ccIdx == 0) ? 23 : ccIdx + 24)) & 0x00000001) != 0;
}
/**
* Set the FCC value in the FCSR register.
*
* @param fcsr the FCSR register
* @param cc the CC value
*/
private static void setFCC(Reference<Integer> fcsr, int cc) {
fcsr.set(fcsr.get() | (cc == 0 ? 0x800000 : 0x1000000 << cc));
}
/**
* Clear the FCC value in the FCSR register.
*
* @param fcsr the FCSR register
* @param cc the CC value
*/
private static void clearFCC(Reference<Integer> fcsr, int cc) {
fcsr.set(fcsr.get() & (cc == 0 ? 0xFF7FFFFF : 0xFEFFFFFF << cc));
}
/**
* Act on a jump.
*
* @param context the context
* @param targetPc the target program counter (PC)
*/
private static void doJump(Context context, int targetPc) {
context.getRegisterFile().setNnpc(targetPc);
}
/**
* Act on a branch.
*
* @param context the context
* @param machineInstruction the machine instruction
*/
private static void doBranch(Context context, int machineInstruction) {
context.getRegisterFile().setNnpc(getTargetPcForBranch(context.getRegisterFile().getNpc(), machineInstruction));
}
/**
* Skip delay slot.
*
* @param context the context
*/
private static void skipDelaySlot(Context context) {
context.getRegisterFile().setNpc(context.getRegisterFile().getNnpc());
context.getRegisterFile().setNnpc(context.getRegisterFile().getNnpc() + 4);
}
/**
* Get the target PC for the specified control instruction.
*
* @param pc the current program counter (PC) value
* @param machineInstruction the machine instruction
* @param mnemonic the mnemonic
* @return the target PC for the specified control instruction
*/
public static int getTargetPcForControl(int pc, int machineInstruction, Mnemonic mnemonic) {
switch (mnemonic) {
case J:
return getTargetPcForJ(pc, machineInstruction);
case JAL:
return getTargetPcForJal(pc, machineInstruction);
case JALR:
throw new IllegalArgumentException();
case JR:
throw new IllegalArgumentException();
default:
return getTargetPcForBranch(pc, machineInstruction);
}
}
/**
* Get the target PC for the specified branch instruction.
*
* @param pc the current program counter (PC) value
* @param machineInstruction the machine instruction
* @return the target PC for the specified branch instruction
*/
private static int getTargetPcForBranch(int pc, int machineInstruction) {
return pc + MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction) << 2);
}
/**
* Get the target PC for the specified J instruction.
*
* @param pc the current program counter (PC) value
* @param machineInstruction the machine instruction
* @return the target PC for the specified J instruction
*/
private static int getTargetPcForJ(int pc, int machineInstruction) {
return MathHelper.mbits(pc, 32, 28) | (BitField.TARGET.valueOf(machineInstruction) << 2);
}
private static int getTargetPcForJal(int pc, int machineInstruction) {
return MathHelper.mbits(pc, 32, 28) | (BitField.TARGET.valueOf(machineInstruction) << 2);
}
/**
* Get the target PC for the specified jalr instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
* @return the target PC for the specified jalr instruction
*/
public static int getTargetPcForJalr(Context context, int machineInstruction) {
return context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
}
/**
* Get the target PC for the specified jr instruction.
*
* @param context the context
* @param machineInstruction the machine instruction
* @return the target PC for the specified jr instruction
*/
public static int getTargetPcForJr(Context context, int machineInstruction) {
return context.getRegisterFile().getGpr(BitField.RS.valueOf(machineInstruction));
}
/**
* Execute the specified static instruction under the specified context.
*
* @param staticInstruction the static instruction
* @param context the context
*/
public static void execute(StaticInstruction staticInstruction, Context context) {
int oldPc = context.getRegisterFile().getPc();
try {
staticInstruction.mnemonic.getMethod().invoke(null, context, staticInstruction.machineInstruction);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
context.getBlockingEventDispatcher().dispatch(new InstructionFunctionallyExecutedEvent(context, oldPc, staticInstruction));
}
/**
* Get the pseudocall object if the specified machine instruction is a pseudocall.
*
* @param machineInstruction the machine instruction
* @return the pseudocall object if the machine instruction is a pseudocall; otherwise null.
*/
public static PseudoCall getPseudoCall(int machineInstruction) {
if (BitField.RT.valueOf(machineInstruction) == 0 && MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction)) != 0) {
return new PseudoCall(BitField.RS.valueOf(machineInstruction), MathHelper.signExtend(BitField.INTIMM.valueOf(machineInstruction)));
}
return null;
}
/**
* The constant "no operation" (NOP) instruction.
*/
public static final StaticInstruction NOP = new StaticInstruction(Mnemonic.NOP, 0x0);
}