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); } } }