//determine if the instruction should execute based on condition flags (phase 4) //return a disassembled represntation of the instruction public override string ToAssembly() { string result = ""; if (type == 0) { result += "add" + GetOpcode(); } else if (type == 1) { result += "sub" + GetOpcode(); } else { result += "rsb" + GetOpcode(); } result += " r" + dest.RegNum; result += ", r" + source.RegNum; result += ", ";//immediate value if (operand2.immNum != uint.MaxValue) { if (operand2.rotateAmt > 0) { operand2.immNum = BarrelShifter.ROR(operand2.immNum, (int)operand2.rotateAmt * 2); } result += "#" + operand2.immNum; } else { result += "r" + operand2.RegNum; }//add shift operand if (operand2.shiftAmt > 0) { if (operand2.shiftNum == 0) { result += ", lsl"; } else if (operand2.shiftNum == 1) { result += ", lsr"; } else if (operand2.shiftNum == 2) { result += ", asr"; } else { result += ", ror"; } if (regshift > -1) { result += " r" + regshift; } else { result += " #" + operand2.shiftAmt; } } return(result); }
//return a disassembled representation of the instruction public override string ToAssembly() { string result = "mov" + GetOpcode() + " "; result += "r" + dest.RegNum; if (operand2.RegNum != uint.MaxValue) { result += ", r" + operand2.RegNum; if (operand2.shiftAmt > 0) { if (operand2.shiftNum == 0) { result += ", lsl"; } else if (operand2.shiftNum == 1) { result += ", lsr"; } else if (operand2.shiftNum == 2) { result += ", asr"; } else { result += ", ror"; } if (regshift > -1) { result += " r" + regshift; } else { result += " #" + operand2.shiftAmt; } } result = result.ToLower(); } else { if (operand2.rotateAmt > 0) { operand2.immNum = BarrelShifter.ROR(operand2.immNum, (int)operand2.rotateAmt * 2); } result += ", #" + operand2.immNum.ToString(); result = result.ToLower(); } return(result); }
//determine if the instruction should execute //change flags if needed //return a string representation of the instruction public override string ToAssembly() { string result = "bic" + GetOpcode(); result += " r" + dest.RegNum; result += ", r" + source.RegNum; result += ", "; if (operand2.immNum != uint.MaxValue) { if (operand2.rotateAmt > 0) { operand2.immNum = BarrelShifter.ROR(operand2.immNum, (int)operand2.rotateAmt); } result += "#" + operand2.immNum; } else { result += "r" + operand2.RegNum; } if (operand2.shiftAmt > 0) { if (operand2.shiftNum == 0) { result += ", lsl"; } else if (operand2.shiftNum == 1) { result += ", lsr"; } else { result += ", asr"; } if (regshift > -1) { result += " r" + regshift; } else { result += " #" + operand2.shiftAmt; } } return(result); }
//executes the instruction and swaps processsor modes if needed. public override void Execute() { if (dest != null) { if (!reg) { uint val = computer.getReg((int)dest.RegNum); if (Memory.ExtractBits(val, 0, 4) == 0b10010) { computer.Registers.swapStacks(2); } if (Memory.ExtractBits(val, 0, 4) == 0b10011) { computer.Registers.swapStacks(1); } if (Memory.ExtractBits(val, 0, 4) == 0b11111) { computer.Registers.swapStacks(0); } computer.Registers.cpsr = computer.getReg((int)dest.RegNum); } else { computer.Registers.writeSPSR(computer.getReg((int)dest.RegNum)); } } else { if (!reg) { uint val = BarrelShifter.ROR(source.immNum, (int)source.rotateAmt); computer.Registers.writeSPSR(val); } else { uint val = BarrelShifter.ROR(source.immNum, (int)source.rotateAmt); computer.Registers.writeSPSR(val); } } }
//execute a bit clear operation public override void Execute() { if (!ShouldExecute()) { return; } uint val1 = (computer.getReg((int)source.RegNum)); if (operand2.immNum != uint.MaxValue) { uint val2 = operand2.immNum; int rotate = (int)operand2.rotateAmt * 2; val2 = (val2 >> rotate) | (val2 << (32 - rotate)); uint result = (uint)(val1 & ~val2); uint d = (uint)(val1 & val2); computer.Registers.setRegister((int)dest.RegNum, result); } else { uint value = computer.getReg((int)operand2.RegNum); uint shifttype = operand2.shiftNum; uint shiftamt = operand2.shiftAmt; //shift amount according to type if (operand2.shiftNum == 0) { value = BarrelShifter.LogicLeftShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 1) { value = BarrelShifter.LogicalRightShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 2) { value = BarrelShifter.ArithRightShift(value, (int)(shiftamt)); } uint result = (uint)(val1 & ~value); computer.Registers.setRegister((int)dest.RegNum, result); return; } }
//moves the value from one op to another and stores it public override void Execute() { if (!ShouldExecute()) { return; } //execute a move for an immediate value if (value == 0xe1a00000) { return; } if (operand2.immNum != uint.MaxValue) { uint value = operand2.immNum; int rotate = (int)operand2.rotateAmt * 2; operand2.immNum = (uint)(value >> rotate) | (value << (32 - rotate)); if (mvn) { operand2.immNum = ~operand2.immNum; } computer.Registers.setRegister((int)dest.RegNum, operand2.immNum); if (sinstruct) { MovFlags(0, value); } return; } //execute a move for a register/shifted register else { uint value = computer.getReg((int)operand2.RegNum); uint shifttype = operand2.shiftNum; uint shiftamt = operand2.shiftAmt; //shift amount according to type if (operand2.shiftNum == 0) { value = BarrelShifter.LogicLeftShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 1) { value = BarrelShifter.LogicalRightShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 2) { value = BarrelShifter.ArithRightShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 3) { value = BarrelShifter.ROR(value, (int)shiftamt); } if (mvn) { value = ~value; } computer.Registers.setRegister((int)dest.RegNum, value); if (sinstruct) { MovFlags(0, value); } return; } throw new NotImplementedException(); }
//perform a comparison operation public override void Execute() { if (!ShouldExecute()) { return; } uint val1 = 0; if (type != 3) { val1 = computer.getReg((int)source.RegNum); } else { val1 = computer.getReg((int)dest.RegNum); } if (operand2.immNum != uint.MaxValue) { uint val2 = operand2.immNum; int rotate = (int)operand2.rotateAmt * 2; val2 = (uint)(val2 >> rotate) | (val2 << (32 - rotate)); //perform and cmp if (type == 0) { uint result = val1 & val2; computer.Registers.setRegister((int)dest.RegNum, result); //ChangeFlags(val1, val2, result); } //perform or cmp else if (type == 1) { uint result = val1 | val2; computer.Registers.setRegister((int)dest.RegNum, result); // ChangeFlags(val1, val2, result); } //perform eor cmp else if (type == 2) { uint result = val1 ^ val2; computer.Registers.setRegister((int)dest.RegNum, result); //ChangeFlags(val1, val2, result); } else { uint result = computer.getReg((int)dest.RegNum) - val2; ChangeFlags(val1, val2, result); } } else { uint value = computer.getReg((int)operand2.RegNum); uint shifttype = operand2.shiftNum; uint shiftamt = operand2.shiftAmt; //shift amount according to type if (operand2.shiftNum == 0) { value = BarrelShifter.LogicLeftShift(value, (int)(shiftamt)); } else if (operand2.shiftNum == 1) { value = BarrelShifter.LogicalRightShift(value, (int)(shiftamt)); } else if (operand2.shiftNum == 2) { value = BarrelShifter.ArithRightShift(value, (int)(shiftamt)); } else { value = BarrelShifter.ROR(value, (int)shiftamt); } //perform and cmp if (type == 0) { uint result = val1 & value; computer.Registers.setRegister((int)dest.RegNum, result); //ChangeFlags(val1, value, result); } //perform or cmp else if (type == 1) { uint result = val1 | value; computer.Registers.setRegister((int)dest.RegNum, result); //ChangeFlags(val1, value, result); } //perform eor cmp else if (type == 2) { uint result = val1 ^ value; computer.Registers.setRegister((int)dest.RegNum, result); //ChangeFlags(val1, value, result); } else { uint result = computer.getReg((int)dest.RegNum) - value; ChangeFlags(val1, value, result); } return; } }
//perform an addition/subtraction operation public override void Execute() { if (!ShouldExecute()) { return; } uint val1 = computer.getReg((int)source.RegNum); if (operand2.immNum != uint.MaxValue) { uint val2 = operand2.immNum; int rotate = (int)operand2.rotateAmt * 2; val2 = (uint)(val2 >> rotate) | (val2 << (32 - rotate)); //perform addition operation if (type == 0) { uint result = val2 + val1; computer.Registers.setRegister((int)dest.RegNum, result); } //perform subtraction operation else if (type == 1) { uint result = val1 - val2; computer.Registers.setRegister((int)dest.RegNum, result); } //rsb operation else { uint result = val2 - val1; computer.Registers.setRegister((int)dest.RegNum, result); } } else { uint value = computer.getReg((int)operand2.RegNum); uint shifttype = operand2.shiftNum; uint shiftamt = operand2.shiftAmt; //shift amount according to type if (operand2.shiftNum == 0) { value = BarrelShifter.LogicLeftShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 1) { value = BarrelShifter.LogicalRightShift(value, (int)(shiftamt)); } if (operand2.shiftNum == 2) { value = BarrelShifter.ArithRightShift(value, (int)(shiftamt)); } else if (operand2.shiftNum == 3) { value = BarrelShifter.ROR(value, (int)shiftamt); } //add with shifted register if (type == 0) { uint result = value + val1; computer.Registers.setRegister((int)dest.RegNum, result); } //subtract with shifted register else if (type == 1) { uint result = val1 - value; computer.Registers.setRegister((int)dest.RegNum, result); } //rsb with shifted register else { uint result = value - val1; computer.Registers.setRegister((int)dest.RegNum, result); } return; } }
//execute a load/store public override void Execute() { if (!ShouldExecute()) { return; } uint writeval; uint noffset = 0; if (operand2.immNum != uint.MaxValue) { uint memval; uint offset = computer.Registers.getRegister((int)source.RegNum); if (type) { if (updown) { noffset = offset + operand2.immNum; } else { noffset = offset - operand2.immNum; } if (noffset == 0x100001) { memval = computer.getChar(); } else { if (preindex == true) { if (!size) { memval = computer.RAM.ReadWord(noffset); } else { memval = computer.RAM.ReadByte(noffset); } } else { if (!size) { memval = computer.RAM.ReadWord(offset); } else { memval = computer.RAM.ReadByte(offset); } } } computer.Registers.setRegister((int)dest.RegNum, memval); } else { uint nuval = computer.Registers.getRegister((int)dest.RegNum); if (updown) { noffset = offset + operand2.immNum; } else { noffset = offset - operand2.immNum; } if (!size) { if (preindex == true) { computer.RAM.WriteWord(noffset, nuval); } else { computer.RAM.WriteWord(offset, nuval); } } else { if (noffset == 0x100000) { char c = (char)computer.getReg(0); computer.SendChar(c); } else { if (preindex == true) { computer.RAM.WriteByte(noffset, (byte)Memory.ExtractBits(nuval, 0, 7)); } else { computer.RAM.WriteByte(offset, (byte)Memory.ExtractBits(nuval, 0, 7)); } } } } writeval = noffset; } else { uint memval; uint offset1 = computer.Registers.getRegister((int)source.RegNum); uint off3 = offset1; uint offset2 = computer.Registers.getRegister((int)operand2.RegNum); if (operand2.shiftAmt > 0) { if (operand2.shiftNum == 0) { offset2 = BarrelShifter.LogicLeftShift(offset2, (int)operand2.shiftAmt); } else if (operand2.shiftNum == 1) { offset2 = BarrelShifter.LogicalRightShift(offset2, (int)operand2.shiftAmt); } else if (operand2.shiftNum == 2) { offset2 = BarrelShifter.ArithRightShift(offset2, (int)operand2.shiftAmt); } else { offset2 = BarrelShifter.ROR(offset2, (int)operand2.shiftAmt); } } if (updown) { offset1 = offset1 + offset2; } else { offset1 = offset1 - offset2; } if (type) { if (offset1 == 0x100001) { memval = computer.getChar(); } else { if (preindex == true) { if (!size) { memval = computer.RAM.ReadWord(offset1); } else { memval = computer.RAM.ReadByte(offset1); } } else { if (!size) { memval = computer.RAM.ReadWord(off3); } else { memval = computer.RAM.ReadByte(off3); } } } computer.Registers.setRegister((int)dest.RegNum, memval); } else { uint nuval = computer.Registers.getRegister((int)dest.RegNum); if (preindex == true) { if (!size) { computer.RAM.WriteWord(offset1, nuval); } else { computer.RAM.WriteByte(offset1, (byte)Memory.ExtractBits(nuval, 0, 7)); } } else { if (!size) { computer.RAM.WriteWord(off3, nuval); } else { computer.RAM.WriteByte(off3, (byte)Memory.ExtractBits(nuval, 0, 7)); } } } writeval = offset1; } if (writeBack || !preindex) { computer.Registers.setRegister((int)source.RegNum, writeval); } }