public override object VisitB_xor([NotNull] KCCParser.B_xorContext context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } _controller.AddInstruction(InstOp.BXor, lval, rval, null, mod); return(null); }
public InstEntry(InstOp op, string arg0, string arg1, OpModifier opModifier = OpModifier.None) { Op = op; Arg0 = arg0; Arg1 = arg1; OpModifier = opModifier; }
public Instruction(OpCode opCode = OpCode.NOOPERATION, OpModifier modifier1 = OpModifier.Empty, OpModifier modifier2 = OpModifier.Empty, Int32 parameter1 = 0, Int32 parameter2 = 0) { Operation = opCode; Modifier1 = (UInt16)modifier1; Modifier2 = (UInt16)modifier2; Parameter1 = parameter1; Parameter2 = parameter2; }
public Instruction(InstOp op, int arg0, int arg1, int spcl0, int spcl1, OpModifier modifier) { Op = op; Arg0 = arg0; Arg1 = arg1; Spcl0 = spcl0; Spcl1 = spcl1; Modifier = modifier; }
//Expressions*********************************** public override object VisitSet_alt([NotNull] KCCParser.Set_altContext context) { string declType; string symbolId; string op = context.op_sum.Text; string index = context.index_anyvalue()?.GetText(); InstOp instOp = InstOp.NoOp; var dCtx = context.expression(); symbolId = context.accessor().GetText(); if (context.symbol_id() != null)//Contains a type, so is definition { declType = context.symbol_id().GetText(); _controller.DeclareVariable(symbolId, declType); } if (op != null) { switch (context.op_sum.Text) { case "=": instOp = InstOp.Set; break; case "+=": instOp = InstOp.SetAdd; break; case "-=": instOp = InstOp.SetSub; break; case "*=": instOp = InstOp.SetMult; break; case "/=": instOp = InstOp.SetDiv; break; case "%=": instOp = InstOp.SetModulo; break; case "&=": instOp = InstOp.SetAnd; break; case "^=": instOp = InstOp.SetOr; break; case "|=": instOp = InstOp.SetXor; break; } var value = (string)Visit(dCtx); OpModifier valueType = value == null ? OpModifier.FromLastTemp : OpModifier.None; _controller.AddInstruction(instOp, symbolId, value, index, valueType); } else { _controller.AddInstruction(InstOp.Set, symbolId, null, index, OpModifier.NullOrDefault); } return(null); }
void FillInstructionTable() { const UInt32 instructionCount = 22; const UInt32 instructionsTotalSize = Instruction.InstructionSize * instructionCount; mCurrentCell = null; this.dataGridView1.Rows.Clear(); if (mDebugger.Machine.MachineState.mExecutionPointer < mTableStartAddress + Instruction.InstructionSize || mDebugger.Machine.MachineState.mExecutionPointer > mTableStartAddress + instructionsTotalSize - 2 * Instruction.InstructionSize) { mTableStartAddress = mDebugger.Machine.MachineState.mExecutionPointer - Instruction.InstructionSize * 4;//lets start filling from 4 instructions earlier } for (UInt32 address = mTableStartAddress; address < mTableStartAddress + instructionsTotalSize; address += Instruction.InstructionSize) { Int32 op = BitConverter.ToInt32(mDebugger.Machine.MachineMemory, (int)address); Int16 mod1 = BitConverter.ToInt16(mDebugger.Machine.MachineMemory, (int)address + 4); Int16 mod2 = BitConverter.ToInt16(mDebugger.Machine.MachineMemory, (int)address + 6); Int32 param1 = BitConverter.ToInt32(mDebugger.Machine.MachineMemory, (int)address + 8); Int32 param2 = BitConverter.ToInt32(mDebugger.Machine.MachineMemory, (int)address + 12); OpModifier m1 = (OpModifier)mod1; OpModifier m2 = (OpModifier)mod2; Instruction instruction = new Instruction((OpCode)op, m1, m2, param1, param2); string param1Str = param1.ToString(); string param2Str = param2.ToString(); if ((m1 & (OpModifier.Register | OpModifier.MemoryAtRegister)) > 0) { param1Str = ((Register)param1).ToString(); } if ((m2 & (OpModifier.Register | OpModifier.MemoryAtRegister)) > 0) { param2Str = ((Register)param2).ToString(); } this.dataGridView1.Rows.Add( address, instruction.Operation.ToString(), m1.ToString(), m2.ToString(), param1Str, param2Str); } SetCurrentInstructionIndicator(); }
//Math************************* public override object VisitMath1([NotNull] KCCParser.Math1Context context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.prod_op.Text) { case "*": op = InstOp.Mult; break; case "/": op = InstOp.Div; break; case "%": op = InstOp.Modulo; break; case "**": op = InstOp.Power; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
public override object VisitCompare1([NotNull] KCCParser.Compare1Context context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.gl_compare.Text) { case "<": op = InstOp.Lss; break; case "<=": op = InstOp.LssEqu; break; case ">": op = InstOp.Gtr; break; case ">=": op = InstOp.GtrEqu; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
public override object VisitL_or([NotNull] KCCParser.L_orContext context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.lg_or.Text) { case "||": op = InstOp.Or; break; case "!|": op = InstOp.Nor; break; case "|||": op = InstOp.Xor; break; case "!||": op = InstOp.XNor; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
void EmitConditionalJump(OpCode op, string label, OpModifier dataType) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.COMPARE, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mSymbolUseList.Add(new SymbolUsage(label, EnSection.Code, mInstructions.Count)); /* * if (mSymbolsForCode.ContainsKey(label)) * { * int address = mSymbolsForCode[label]; * mInstructions.Add(new Instruction(op, OpModifier.Immediate | OpModifier.Far, OpModifier.Empty, address * Instruction.InstructionSize)); * } * else*/ { Instruction ins = new Instruction(op, OpModifier.Immediate | OpModifier.Absolute, OpModifier.Empty, 0); mInstructions.Add(ins); //AddUnresolvedLabel(label, ins); } }
//Comparators********************** public override object VisitShift([NotNull] KCCParser.ShiftContext context) { var lval = (string)Visit(context.expression()[0]); var rval = (string)Visit(context.expression()[1]); OpModifier mod = OpModifier.None; InstOp op = InstOp.NoOp; if (lval == null && rval == null) { mod = OpModifier.LTempRTemp; } else if (lval != null && rval == null) { mod = OpModifier.LRawRTemp; } else if (lval == null && rval != null) { mod = OpModifier.LTempRRaw; } else { mod = OpModifier.LRawRRaw; } switch (context.shift_op.Text) { case "<<": op = InstOp.ShL; break; case ">>": op = InstOp.ShR; break; } _controller.AddInstruction(op, lval, rval, null, mod); return(null); }
OpModifier ConvertStringToOpModifierDataType(string str) { OpModifier result = OpModifier.Empty; if (str == "U4") { result = OpModifier.DataTypeU4; } else if (str == "P4") { result = OpModifier.DataTypeU4; } else if (str == "I4") { result = OpModifier.DataTypeI4; } else if (str == "I2") { result = OpModifier.DataTypeI2; } else if (str == "U2") { result = OpModifier.DataTypeU2; } else if (str == "I1") { result = OpModifier.DataTypeI1; } else if (str == "U1") { result = OpModifier.DataTypeU1; } else if (str == "F4") { result = OpModifier.DataTypeF4; } return(result); }
void AssembleLine(string line) { string[] tokens = line.Split(Seperator, StringSplitOptions.RemoveEmptyEntries); if (tokens.Length == 0) { return; } string op = tokens[0]; string p1Str = ""; Int32 p1 = 0; bool isP1Int = false; bool isP1Exists = (tokens.Length > 1); if (isP1Exists) { p1Str = tokens[1]; isP1Int = Int32.TryParse(p1Str, out p1); } if (op.StartsWith("CNST")) { if (isP1Int) { mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Immediate, OpModifier.Empty, p1)); } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "ADDRLP4") { if (isP1Exists) { int val = 0; if (isP1Int) { val = p1; } else { if (p1Str.Contains("+")) { string[] values = p1Str.Split(new string[] { "+" }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 2) { int v1 = 0; int v2 = 0; bool success = Int32.TryParse(values[0], out v1); if (!success) { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } success = Int32.TryParse(values[1], out v2); if (!success) { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } val = v1 + v2; } else { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } } else if (p1Str.Contains("-")) { string[] values = p1Str.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 2) { int v1 = 0; int v2 = 0; bool success = Int32.TryParse(values[0], out v1); if (!success) { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } success = Int32.TryParse(values[1], out v2); if (!success) { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } val = v1 - v2; } else { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } } } mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.Register, (int)Register.Alp1, (int)Register.BasePointer)); mInstructions.Add(new Instruction(OpCode.ADD, OpModifier.Register, OpModifier.Immediate, (int)Register.Alp1, val + 4 + mCurrentFunction.ArgumentsCallDataSize)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "ADDRFP4") { if (isP1Int) { mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.MemoryAtRegister, (int)Register.Alp1, (int)Register.BasePointer)); //Going to previous stack frame, because LCC bytecode assumes args are there mInstructions.Add(new Instruction(OpCode.ADD, OpModifier.Register, OpModifier.Immediate, (int)Register.Alp1, p1 + 4)); //0 is previous of previous function's ebp value, so args start from +4 mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "ADDRGP4") { if (isP1Exists) { if (p1Str.Contains("+")) { string[] values = p1Str.Split(new string[] { "+" }, StringSplitOptions.RemoveEmptyEntries); if (values.Length == 2) { string symbol = values[0]; int v2 = 0; bool success = Int32.TryParse(values[1], out v2); if (!success) { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } mSymbolUseList.Add(new SymbolUsage(symbol, EnSection.Code, mInstructions.Count)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Immediate, OpModifier.Empty, 0)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp5)); mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.Immediate, (int)Register.Alp6, v2)); mInstructions.Add(new Instruction(OpCode.ADD, OpModifier.Register, OpModifier.Register, (int)Register.Alp5, (int)Register.Alp6)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp5)); } else { throw new Exception(string.Format("{0} not understood: {1}", op, p1Str)); } } else { string label = p1Str; mSymbolUseList.Add(new SymbolUsage(label, EnSection.Code, mInstructions.Count)); Instruction ins = new Instruction(OpCode.PUSH, OpModifier.Immediate, OpModifier.Empty, 0); mInstructions.Add(ins); } } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("ARG")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); //mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Memory | OpModifier.BpOffset, OpModifier.Register, mCurrentArgSize + 4, (int)Register.Alp1)); mCurrentArgSize += 4; } else if (op == "ASGNB") { if (isP1Int) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.SET_COUNTER, OpModifier.Immediate, OpModifier.Empty, p1)); mInstructions.Add(new Instruction(OpCode.COPY_MEMORY_ARRAY, OpModifier.Register, OpModifier.Register, (int)Register.Alp2, (int)Register.Alp1)); } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op.StartsWith("ASGN")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(4)); mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.MemoryAtRegister | dataType, OpModifier.Register, (int)Register.Alp2, (int)Register.Alp1)); } else if (op == "INDIRB") { //Do nothing. We have address already on top of stack. } else if (op.StartsWith("INDIR")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.MemoryAtRegister, (int)Register.Alp2, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); } else if (op.StartsWith("LABEL")) { if (isP1Exists) { if (mSymbols.ContainsKey(p1Str)) { throw new Exception(string.Format("LABEL {0} already defined", p1Str)); } if (mCurrentSection == EnSection.Code) { //mSymbolsForCode.Add(p1Str, mInstructions.Count); mSymbols.Add(p1Str, new Symbol(p1Str, EnSection.Code, mInstructions.Count)); } else if (mCurrentSection == EnSection.Data) { int dataIndex = mData.Count; if (mCurrentAlign > 1) { int mod = dataIndex % (int)mCurrentAlign; if (mod != 0) { //Align to mCurrentAlign byte boundry int bytesNeeded = (int)mCurrentAlign - mod; for (int i = 0; i < bytesNeeded; ++i) { mData.Add(0);//Fill bytesNeeded bytes } dataIndex = mData.Count; } } //mSymbolsForData.Add(p1Str, dataIndex); mSymbols.Add(p1Str, new Symbol(p1Str, EnSection.Data, dataIndex)); } else if (mCurrentSection == EnSection.Lit) { int dataIndex = mLit.Count; if (mCurrentAlign > 1) { int mod = dataIndex % (int)mCurrentAlign; if (mod != 0) { //Align to mCurrentAlign byte boundry int bytesNeeded = (int)mCurrentAlign - mod; for (int i = 0; i < bytesNeeded; ++i) { mLit.Add(0);//Fill bytesNeeded bytes } dataIndex = mLit.Count; } } //mSymbolsForLit.Add(p1Str, dataIndex); mSymbols.Add(p1Str, new Symbol(p1Str, EnSection.Lit, dataIndex)); } else if (mCurrentSection == EnSection.Bss) { int dataIndex = mBss; if (mCurrentAlign > 1) { int mod = dataIndex % (int)mCurrentAlign; if (mod != 0) { //Align to mCurrentAlign byte boundry int bytesNeeded = (int)mCurrentAlign - mod; mBss += bytesNeeded; dataIndex = mBss; } } //mSymbolsForBss.Add(p1Str, dataIndex); mSymbols.Add(p1Str, new Symbol(p1Str, EnSection.Bss, dataIndex)); } } else { throw new Exception(string.Format("LABEL needs a parameter")); } } else if (op.StartsWith("ADD")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.ADD, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("SUB")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.SUB, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("MUL")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.MUL, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("DIV")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.DIV, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("MOD")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.MOD, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("LSH")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.SHIFTLEFT, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("RSH")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.SHIFTRIGHT, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("BAND")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.BITWISE_AND, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("BCOM")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.BITWISE_COMPLEMENT, OpModifier.Register | dataType, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("BOR")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.BITWISE_OR, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("BXOR")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.BITWISE_XOR, OpModifier.Register | dataType, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("CVF")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.CONVERT, OpModifier.Register | OpModifier.DataTypeF4, OpModifier.Register | dataType, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("CVI")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.CONVERT, OpModifier.Register | OpModifier.DataTypeI4, OpModifier.Register | dataType, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("CVU")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.CONVERT, OpModifier.Register | OpModifier.DataTypeU4, OpModifier.Register | dataType, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("CVP")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); mInstructions.Add(new Instruction(OpCode.CONVERT, OpModifier.Register | OpModifier.DataTypeU4, OpModifier.Register | dataType, (int)Register.Alp1, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("JUMP")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1));//Address for JUMP is in Alp1 mInstructions.Add(new Instruction(OpCode.JUMP, OpModifier.Register | OpModifier.Absolute, OpModifier.Empty, (int)Register.Alp1)); } else if (op.StartsWith("EQ")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_EQ, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("NE")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_NEQ, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("LE")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_LTE, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("LT")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_LT, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("GE")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_GTE, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("GT")) { if (isP1Exists) { string label = p1Str; OpModifier dataType = ConvertStringToOpModifierDataType(op.Substring(op.Length - 2)); EmitConditionalJump(OpCode.JUMPIF_GT, label, dataType); } else { throw new Exception(string.Format("{0} needs label parameter", op)); } } else if (op.StartsWith("CALL")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1));//Address for CALL is in Alp1 /* * if (mCurrentArgSize > 0) * { * mInstructions.Add(new Instruction(OpCode.REVERSE_STACK, OpModifier.Immediate, OpModifier.Immediate, 0, mCurrentArgSize / 4)); * }*/ mInstructions.Add(new Instruction(OpCode.CALL, OpModifier.Register | OpModifier.Absolute, OpModifier.Empty, (int)Register.Alp1)); //mInstructions.Add(new Instruction(OpCode.DEC_SP, OpModifier.Immediate, OpModifier.Empty, mCurrentArgSize));//Cleanup mCurrentArgSize = 0; //We assume, we have put return value to Return register. So we should push it here. mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (Int32)Register.Return)); } else if (op.StartsWith("RET")) { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Return)); } else if (op.StartsWith("proc")) { if (tokens.Length > 3) { string functionName = p1Str; Int32 localSize = Int32.Parse(tokens[2]); Int32 argSize = Int32.Parse(tokens[3]); if (mFunctions.ContainsKey(functionName)) { throw new Exception(string.Format("Function {0} already exists", functionName)); } else { if (null != mCurrentFunction) { throw new Exception(string.Format("Already inside a function, found a new function: {0}", functionName)); } mCurrentFunction = new Function(functionName, mInstructions.Count, localSize, argSize); mFunctions.Add(functionName, mCurrentFunction); if (mSymbols.ContainsKey(functionName)) { throw new Exception(string.Format("Symbol already defined: {0}", functionName)); } else { mSymbols.Add(functionName, new Symbol(functionName, EnSection.Code, mInstructions.Count)); } } //Prolog mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (Int32)Register.BasePointer)); mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.Register, (Int32)Register.BasePointer, (Int32)Register.StackPointer)); mInstructions.Add(new Instruction(OpCode.INC_SP, OpModifier.Immediate, OpModifier.Empty, localSize + argSize)); //TODO:Save registers here (excluding BS, SP) } else { throw new Exception(string.Format("{0} needs two parameters", op)); } } else if (op.StartsWith("endproc")) { if (tokens.Length > 3) { string functionName = p1Str; Int32 localSize = Int32.Parse(tokens[2]); Int32 argSize = Int32.Parse(tokens[3]); if (null == mCurrentFunction) { throw new Exception(string.Format("Not in a function, found end of function", functionName)); } mCurrentFunction = null; //TODO:Restore registers here (excluding BS, SP) //Epilog mInstructions.Add(new Instruction(OpCode.ASSIGN, OpModifier.Register, OpModifier.Register, (Int32)Register.StackPointer, (Int32)Register.BasePointer)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (Int32)Register.BasePointer)); /* * if (IsInterruptHandler) * { * AddInstruction(EnOpCode.OC_IRET); * } * else * { * AddInstruction(EnOpCode.OC_RET); * }*/ mInstructions.Add(new Instruction(OpCode.RET)); } else { throw new Exception(string.Format("{0} needs two parameters", op)); } } else if (op == "export") { if (!mExports.Contains(p1Str)) { mExports.Add(p1Str); } } else if (op == "code") { mCurrentSection = EnSection.Code; } else if (op == "data") { mCurrentSection = EnSection.Data; } else if (op == "bss") { mCurrentSection = EnSection.Bss; } else if (op == "lit") { mCurrentSection = EnSection.Lit; } else if (op == "align") { if (isP1Int) { mCurrentAlign = (UInt32)p1; } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "skip") { if (isP1Int) { if (mCurrentSection != EnSection.Bss) { throw new Exception("Encountered a skip in non-bss section"); } else { mBss += p1; } } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "byte") { if (isP1Int) { Int32 p2 = 0; bool isP2Int = false; bool isP2Exists = (tokens.Length > 2); if (isP2Exists) { string p2Str = tokens[2]; isP2Int = Int32.TryParse(p2Str, out p2); } if (isP2Int) { List <byte> target = null; if (mCurrentSection == EnSection.Data) { target = mData; } else if (mCurrentSection == EnSection.Lit) { target = mLit; } else { throw new Exception("Unknown section while parsing byte"); } if (null != target) { switch (p1) { case 1: target.Add((byte)(p2 & 0x000000FF)); break; case 2: { target.Add((byte)(p2 & 0x000000FF)); target.Add((byte)((p2 & 0x0000FF00) >> 8)); } break; case 4: { target.Add((byte)(p2 & 0x000000FF)); target.Add((byte)((p2 & 0x0000FF00) >> 8)); target.Add((byte)((p2 & 0x00FF0000) >> 16)); target.Add((byte)((p2 & 0xFF000000) >> 24)); } break; } } } else { throw new Exception(string.Format("{0} needs two integer parameters", op)); } } else { throw new Exception(string.Format("{0} needs two integer parameters", op)); } } else if (op == "address") { if (isP1Exists) { string label = p1Str; if (mCurrentSection != EnSection.Data) { throw new Exception("Encountered 'address' in non-data section"); } else { mSymbolUseList.Add(new SymbolUsage(label, EnSection.Data, mData.Count)); //These 4 bytes will be filled with address of the label when linking mData.Add(0); mData.Add(0); mData.Add(0); mData.Add(0); } } else { throw new Exception(string.Format("{0} needs parameter", op)); } } else if (op == "import") { if (!mImports.Contains(p1Str)) { mImports.Add(p1Str); } } else if (op == "_SETCOUNTER") { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.SET_COUNTER, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op == "_READCOUNTER") { mInstructions.Add(new Instruction(OpCode.READ_COUNTER, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.PUSH, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); } else if (op == "_MEMSET") { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp2)); mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Register, OpModifier.Empty, (int)Register.Alp1)); mInstructions.Add(new Instruction(OpCode.SET_MEMORY_ARRAY, OpModifier.Register, OpModifier.Register, (int)Register.Alp1, (int)Register.Alp2)); } else if (op == "_POP") { mInstructions.Add(new Instruction(OpCode.POP, OpModifier.Empty, OpModifier.Empty)); } else { throw new Exception(string.Format("{0} not implemented", op)); } }
internal bool AddInstruction(InstOp op, int arg0, int arg1, int spcl0, int spcl1, OpModifier modifier) { if (_trackedRecord == null) { return(false); } _trackedRecord.AddInstruction(new Instruction( op, arg0, arg1, spcl0, spcl1, modifier)); return(true); }
public bool AddInstruction(InstOp op, string arg0, string arg1, string special = null, OpModifier opModifier = OpModifier.None) { _currentScope.Instructions.AddRecord(new InstEntry(op, arg0, arg1, opModifier)); Debug.PrintDbg($"{op} {arg0} {arg1} {opModifier}"); return(true); }
public string FormatInstruction(InstOp opcode, string arg0, string arg1, string spcl1, string spcl2, OpModifier mode) { var ret = ""; switch (opcode) { case InstOp.Print: ret = $" leaq .LC{arg0}(%{AsmRef.GetInstructionPointer(BitCntr.B64)}), %{AsmRef.GetCounter(BitCntr.B64)}" + _nl + $" call printf"; break; case InstOp.Exit: ret = $" movl %{arg0}, %{AsmRef.GetDestination(BitCntr.B32)}" + _nl + " call exit"; break; } return(ret); }
public bool Open(string file) { mSymbols.Clear(); mSymbolUseList.Clear(); mInstructions.Clear(); mData.Clear(); mLit.Clear(); UnresolvedSymbols.Clear(); File = file; FileStream stream = new FileStream(file, FileMode.Open); BinaryReader reader = new BinaryReader(stream); mHeader.Deserialize(reader); if (mHeader.CodeSize > 0) { int counter = (int)mHeader.CodeSize; while (counter > 0) { Int32 op = reader.ReadInt32(); Int16 mod1 = reader.ReadInt16(); Int16 mod2 = reader.ReadInt16(); Int32 param1 = reader.ReadInt32(); Int32 param2 = reader.ReadInt32(); OpModifier m1 = (OpModifier)mod1; OpModifier m2 = (OpModifier)mod2; Instruction instruction = new Instruction((OpCode)op, m1, m2, param1, param2); mInstructions.Add(instruction); counter -= Instruction.InstructionSize; } } mData = reader.ReadBytes((int)mHeader.DataSize).ToList(); mLit = reader.ReadBytes((int)mHeader.LitSize).ToList(); if (mHeader.SymbolDefinitionTableSize > 0) { int counter = (int)mHeader.SymbolDefinitionTableSize; while (counter > 0) { Symbol symbol = Symbol.Deserialize(reader); counter -= symbol.CalculateSize(); mSymbols.Add(symbol.Name, symbol); } } if (mHeader.SymbolUsageTableSize > 0) { int counter = (int)mHeader.SymbolUsageTableSize; while (counter > 0) { SymbolUsage symbolUsage = SymbolUsage.Deserialize(reader); counter -= symbolUsage.CalculateSize(); mSymbolUseList.Add(symbolUsage); } } return(true); }