158 lines
5.1 KiB
Java
158 lines
5.1 KiB
Java
package processor.pipeline;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import generic.Instruction;
|
|
import processor.Processor;
|
|
import generic.Instruction.OperationType;
|
|
import generic.Operand.OperandType;
|
|
import generic.Operand;
|
|
|
|
public class OperandFetch {
|
|
Processor containingProcessor;
|
|
IF_OF_LatchType IF_OF_Latch;
|
|
OF_EX_LatchType OF_EX_Latch;
|
|
static OperationType[] opTypes = OperationType.values();
|
|
|
|
public OperandFetch(Processor containingProcessor, IF_OF_LatchType iF_OF_Latch, OF_EX_LatchType oF_EX_Latch)
|
|
{
|
|
this.containingProcessor = containingProcessor;
|
|
this.IF_OF_Latch = iF_OF_Latch;
|
|
this.OF_EX_Latch = oF_EX_Latch;
|
|
}
|
|
|
|
public static int twoscompliment(String s) {
|
|
char[] chars = s.toCharArray();
|
|
for (int i = 0; i < chars.length; i++) {
|
|
if (chars[i] == '0') {
|
|
chars[i] = '1';
|
|
} else {
|
|
chars[i] = '0';
|
|
}
|
|
}
|
|
String s1 = new String(chars);
|
|
int num = Integer.parseInt(s1, 2);
|
|
num = num + 1;
|
|
return num;
|
|
}
|
|
|
|
public void performOF()
|
|
{
|
|
if(IF_OF_Latch.isOF_enable())
|
|
{
|
|
int instruction = IF_OF_Latch.getInstruction();
|
|
Instruction instr = new Instruction();
|
|
String bin_instr = Integer.toBinaryString(instruction);
|
|
if (bin_instr.length() < 32) { // TODO: check if this is correct
|
|
int diff = 32 - bin_instr.length();
|
|
String zeros = "";
|
|
for (int i = 0; i < diff; i++) {
|
|
zeros += "0";
|
|
}
|
|
bin_instr = zeros + bin_instr;
|
|
}
|
|
instr.setProgramCounter(containingProcessor.getRegisterFile().getProgramCounter());
|
|
int opcode = Integer.parseInt(bin_instr.substring(0, 5), 2);
|
|
instr.setOperationType(opTypes[opcode]);
|
|
|
|
int R3_type_operators[] = {0,2,4,6,8,10,12,14,16,18,20};
|
|
int R2I_type_operators[] = {1,3,5,7,9,11,13,15,17,19,21,22,23,25,26,27,28};
|
|
int R1I_type_operators[] = {24,29};
|
|
|
|
// check if the instruction is of type R3
|
|
if (Arrays.stream(R3_type_operators).anyMatch(x -> x == opcode)) {
|
|
Operand rs1 = new Operand();
|
|
Operand rs2 = new Operand();
|
|
Operand rd = new Operand();
|
|
rs1.setOperandType(Operand.OperandType.Register);
|
|
rs2.setOperandType(Operand.OperandType.Register);
|
|
rd.setOperandType(Operand.OperandType.Register);
|
|
|
|
rs1.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2));
|
|
rs2.setValue(Integer.parseInt(bin_instr.substring(10, 15), 2));
|
|
rd.setValue(Integer.parseInt(bin_instr.substring(15, 20), 2));
|
|
|
|
int op1 = containingProcessor.getRegisterFile().getValue(rs1.getValue());
|
|
int op2 = containingProcessor.getRegisterFile().getValue(rs2.getValue());
|
|
|
|
OF_EX_Latch.setInstruction(instr);
|
|
OF_EX_Latch.setOp1(op1);
|
|
OF_EX_Latch.setOp2(op2);
|
|
instr.setDestinationOperand(rd);
|
|
instr.setSourceOperand1(rs1);
|
|
instr.setSourceOperand2(rs2);
|
|
}
|
|
else if (Arrays.stream(R2I_type_operators).anyMatch(x -> x == opcode)) {
|
|
Operand rs1 = new Operand();
|
|
Operand rd = new Operand();
|
|
rs1.setOperandType(Operand.OperandType.Register);
|
|
rd.setOperandType(Operand.OperandType.Register);
|
|
|
|
rs1.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2));
|
|
rd.setValue(Integer.parseInt(bin_instr.substring(10, 15), 2));
|
|
// check 15th bit to see if it is negative
|
|
int imm = Integer.parseInt(bin_instr.substring(15, 32), 2); // TODO: 2's complement
|
|
if (bin_instr.charAt(15)=='1'){
|
|
imm = -1*twoscompliment(bin_instr.substring(15, 32));
|
|
System.out.println(bin_instr);
|
|
}
|
|
int op1 = containingProcessor.getRegisterFile().getValue(rs1.getValue());
|
|
int op2 = containingProcessor.getRegisterFile().getValue(rd.getValue());
|
|
System.out.println("imm: " + imm);
|
|
|
|
OF_EX_Latch.setInstruction(instr);
|
|
OF_EX_Latch.setImm(imm);
|
|
OF_EX_Latch.setOp1(op1);
|
|
OF_EX_Latch.setOp2(op2);
|
|
|
|
System.out.println("op1: " + op1);
|
|
System.out.println("op2: " + rd);
|
|
instr.setDestinationOperand(rd);
|
|
instr.setSourceOperand1(rs1);
|
|
}
|
|
else if (Arrays.stream(R1I_type_operators).anyMatch(x -> x == opcode)) {
|
|
if(opcode != 24){
|
|
Operand rd = new Operand();
|
|
rd.setOperandType(Operand.OperandType.Register);
|
|
rd.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2));
|
|
|
|
instr.setDestinationOperand(rd);
|
|
|
|
int imm = Integer.parseInt(bin_instr.substring(10, 32), 2); // TODO: 2's complement
|
|
if (bin_instr.charAt(10)=='1'){
|
|
imm = -1*twoscompliment(bin_instr.substring(10, 32));
|
|
System.out.println(bin_instr);
|
|
}
|
|
System.out.println("imm: " + imm);
|
|
OF_EX_Latch.setInstruction(instr);
|
|
OF_EX_Latch.setImm(imm);
|
|
}
|
|
else{
|
|
Operand op = new Operand();
|
|
String imm = bin_instr.substring(10, 32);
|
|
int imm_val = Integer.parseInt(imm, 2);
|
|
if (imm.charAt(0) == '1'){
|
|
imm_val = -1*twoscompliment(imm);
|
|
}
|
|
if (imm_val != 0){
|
|
op.setOperandType(OperandType.Immediate);
|
|
op.setValue(imm_val);
|
|
instr.setSourceOperand1(op);
|
|
}
|
|
else{
|
|
op.setOperandType(OperandType.Register);
|
|
op.setValue(Integer.parseInt(bin_instr.substring(5, 10), 2));
|
|
instr.setSourceOperand1(op);
|
|
}
|
|
OF_EX_Latch.setInstruction(instr);
|
|
OF_EX_Latch.setImm(imm_val);
|
|
}
|
|
}
|
|
|
|
IF_OF_Latch.setOF_enable(false);
|
|
OF_EX_Latch.setEX_enable(true);
|
|
}
|
|
}
|
|
|
|
}
|