//See general definition in parent(Instruction) public override void DecodeInst() { cond = Memory.ExtractBits(Inst, 0, 3); typ = Memory.ExtractBits(Inst, 4, 6); bit7 = Memory.ExtractBits(Inst, 24, 24); bit4 = Memory.ExtractBits(Inst, 27, 27); if (typ == 0 && bit7 == 1 && bit4 == 1) { opcode = 0x10; //for convenience, I suppose. Rd = Memory.ExtractBits(Inst, 12, 15); Rs = Memory.ExtractBits(Inst, 20, 23); Rm = Memory.ExtractBits(Inst, 28, 31); } else { regimm = Convert.ToBoolean(Memory.ExtractBits(typ, 31, 31)); //true == 1; false = 0; opcode = Memory.ExtractBits(Inst, 7, 10); sbit = Convert.ToBoolean(Memory.ExtractBits(Inst, 11, 11)); //same as regimm; Rn = Memory.ExtractBits(Inst, 12, 15); Rd = Memory.ExtractBits(Inst, 16, 19); Oper2 = Operand2.GetOper2(regimm, Memory.ExtractBits(Inst, 20, 31)); Oper2.Oper2Regs = I_Reg; } }
//Update flags after Rn - shifter_operand public override void Execute(uint Rn, uint Rd, Operand2 oper2) { uint rnval = (uint)CPU.GetRegr(I_Reg, (int)Rn), op2val = (uint)oper2.GetValue(); int val = (int)(rnval - op2val); uint N = Memory.ExtractBits((uint)val, 0, 0); int Z = val == 0 ? 1 : 0; int C = op2val <= rnval ? 1 : 0; //May not be correctly handling C flag will need to modify int rnv = (int)rnval, op2v = (int)op2val; val = rnv - op2v; int V = (rnv > 0 && op2v < 0 && val < 0) || (rnv < 0 && op2v > 0 && val > 0) ? 1 : 0; bool[] flags = { Convert.ToBoolean(N), Convert.ToBoolean(Z), Convert.ToBoolean(C), Convert.ToBoolean(V) }; for (int i = 0; i < 4; ++i) { I_Reg.SetFlag(4 * 16, i, flags[i]); } }
//Rd := shifter_operand (no Rn) public override void Execute(uint Rn, uint Rd, Operand2 oper2) { CPU.SetReg(I_Reg, (int)Rd, oper2.GetValue()); int mode = (int)Memory.ExtractBits((uint)CPU.GetRegr(I_Reg, 16), 27, 31); if (sbit && Rd == 15) { int spsr = CPU.GetRegr(I_Reg, 16); if (mode == 0b10010) { spsr = CPU.GetRegr(I_Reg, 19); //because I had to place them weirdly. //CPU.SetReg(I_Reg, (int)Rd, oper2.GetValue() - 4); //adjust the LR for the PC when IRQ } else if (mode == 0b10011) { spsr = CPU.GetRegr(I_Reg, 22); } CPU.SetReg(I_Reg, 16, spsr); } }
//override for execute which all subclasses, except for MUL, use. public virtual void Execute(uint Rn, uint Rd, Operand2 oper2) { ; }
//Rd := Rn AND NOT(shifter_operand) public override void Execute(uint Rn, uint Rd, Operand2 oper2) { int val = CPU.GetRegr(I_Reg, (int)Rn) & (~oper2.GetValue()); CPU.SetReg(I_Reg, (int)Rd, val); }
//Rd := NOT shifter_operand (no Rn) public override void Execute(uint Rn, uint Rd, Operand2 oper2) { CPU.SetReg(I_Reg, (int)Rd, ~oper2.GetValue()); }