private void XorInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.None: { if ((tkn.ParameterRegisters[0] & AssemRegisters.Const) != 0) { Emitter.XorConst(tkn.Parameters[0].Value, tkn.ParameterRegisters[1], tkn.ResultRegisters[0]); } else { if (tkn.Parameters[0].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegister(tkn.Parameters[0].Value, tkn.ParameterRegisters[0]); } Emitter.Xor(tkn.ParameterRegisters[0], tkn.ParameterRegisters[1], tkn.ResultRegisters[0]); } } break; default: throw new NotImplementedException(); } }
private void NewInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.Array: { } break; } }
private void StInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.Local: if ((tkn.Parameters[0].ParameterLocation & OptimizationParameterLocation.Const) != 0) { Emitter.MovConstantToRegisterSize(tkn.Parameters[0].Value, tkn.ParameterRegisters[0], tkn.Parameters[0].Size); } Emitter.MovRegisterToRegisterRelativeAddressMultSize(tkn.ParameterRegisters[0], tkn.Parameters[0].Size, AssemRegisters.Rsp, AssemRegisters.Rsp, 0, LocalTopOffset + (int)tkn.Constants[0] * MachineSpec.PointerSize); break; case OptimizationInstructionSubType.Arg: if ((tkn.Parameters[0].ParameterLocation & OptimizationParameterLocation.Const) != 0) { Emitter.MovConstantToRegisterSize(tkn.Parameters[0].Value, tkn.ParameterRegisters[0], tkn.Parameters[0].Size); } Emitter.MovRegisterToRegisterRelativeAddressMultSize(tkn.ParameterRegisters[0], tkn.Parameters[0].Size, AssemRegisters.Rsp, AssemRegisters.Rsp, 0, ArgumentTopOffset + (int)tkn.Constants[0] * MachineSpec.PointerSize); break; case OptimizationInstructionSubType.StaticField: if ((tkn.Parameters[0].ParameterLocation & OptimizationParameterLocation.Const) != 0) { Emitter.MovConstantToRegisterSize(tkn.Parameters[0].Value, tkn.ParameterRegisters[0], tkn.Parameters[0].Size); } Emitter.MovRegisterToLabelRelativeAddressSize(tkn.ParameterRegisters[0], tkn.Parameters[0].Size, tkn.Strings[0] + "_static", (int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Indirect: if (tkn.Parameters[0].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegisterSize(tkn.Parameters[0].Value, tkn.ParameterRegisters[0], tkn.Parameters[0].Size); } if (tkn.Parameters[1].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovRegisterToAddressSize(tkn.ParameterRegisters[0], tkn.Parameters[1].Value, tkn.Parameters[0].Size); } else { Emitter.MovRegisterToRegisterAddressSize(tkn.ParameterRegisters[0], tkn.ParameterRegisters[1], tkn.Parameters[0].Size); } break; default: throw new NotImplementedException(); } }
private void RetInstr(OptimizationToken tkn) { Emitter.AddRegConst(AssemRegisters.Rsp, LocalTopSize); if (tkn.Parameters.Length == 1) { Emitter.MovRegisterToRegisterRelativeAddress(tkn.ParameterRegisters[0], AssemRegisters.Rsp, MachineSpec.PointerSize); } else if (tkn.Parameters.Length != 0) { throw new Exception("Unexpected parameter count."); } Emitter.Ret(); }
private void NotInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.None: { Emitter.Not(tkn.ParameterRegisters[0], tkn.ResultRegisters[0]); } break; default: throw new NotImplementedException(); } }
private void ConvertInstr(OptimizationToken tkn) { bool usigned = false; bool check_ovf = false; switch (tkn.SubType) { case OptimizationInstructionSubType.None: check_ovf = false; usigned = false; break; case OptimizationInstructionSubType.Unsigned: check_ovf = false; usigned = true; break; case OptimizationInstructionSubType.CheckOverflow: check_ovf = true; usigned = false; break; case OptimizationInstructionSubType.CheckOverflow | OptimizationInstructionSubType.Unsigned: check_ovf = true; usigned = true; break; default: throw new NotImplementedException(); } if (check_ovf) { throw new NotImplementedException(); } if (tkn.Parameters[0].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegisterSize(tkn.Parameters[0].Value, tkn.ParameterRegisters[0], tkn.Parameters[0].Size); } if (tkn.Parameters[0].Size == 0) { Console.WriteLine("Warning: Unable to determine operand size, defaulting to MachineSpec.PointerSize."); tkn.Parameters[0].Size = MachineSpec.PointerSize; } Emitter.MovRegisterToRegisterSignSize(tkn.ParameterRegisters[0], tkn.Parameters[0].Size, tkn.ResultRegisters[0], tkn.Results[0].Size, !usigned); }
private void LdInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.String: AddString(tkn.Strings[0], stringIdx); Emitter.MovLabelAddressToRegister(tkn.ResultRegisters[0], GetStringLabel(stringIdx++)); break; case OptimizationInstructionSubType.Local: Emitter.MovRelativeAddressMultToRegisterSize(AssemRegisters.Rsp, AssemRegisters.Rsp, 0, LocalTopOffset + (int)tkn.Constants[0] * MachineSpec.PointerSize, tkn.ResultRegisters[0], tkn.Results[0].Size); break; case OptimizationInstructionSubType.Arg: Emitter.MovRelativeAddressMultToRegisterSize(AssemRegisters.Rsp, AssemRegisters.Rsp, 0, ArgumentTopOffset + (int)tkn.Constants[0] * MachineSpec.PointerSize, tkn.ResultRegisters[0], tkn.Results[0].Size); break; case OptimizationInstructionSubType.StaticField: Emitter.MovLabelRelativeAddressToRegisterSize(tkn.Strings[0] + "_static", (int)tkn.Constants[0], tkn.ResultRegisters[0], tkn.Results[0].Size); break; case OptimizationInstructionSubType.FieldAddress: Emitter.LoadEffectiveAddress(tkn.ParameterRegisters[0], (int)tkn.Constants[0], tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Indirect: Emitter.MovRelativeAddressToRegisterSize(tkn.ParameterRegisters[0], 0, tkn.ResultRegisters[0], tkn.Results[0].Size); break; case OptimizationInstructionSubType.Null: Emitter.MovConstantToRegister(0, tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Function: { if (!externals.Contains(tkn.Strings[0])) { externals.Add(tkn.Strings[0]); } Emitter.MovLabelAddressToRegister(tkn.ResultRegisters[0], tkn.Strings[0]); } break; default: throw new NotImplementedException(); } }
private void OutOp(OptimizationToken tkn, int sz) { if (tkn.ParameterRegisters[0] == AssemRegisters.Const8) { Emitter.OutConst((byte)tkn.Parameters[0].Value, tkn.ParameterRegisters[1], sz); } else { if (tkn.Parameters[0].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegister(tkn.Parameters[0].Value, tkn.ParameterRegisters[0]); } Emitter.Out(tkn.ParameterRegisters[0], tkn.ParameterRegisters[1], sz); } }
private void SwitchInstr(OptimizationToken tkn) { }
private void PopInstr(OptimizationToken tkn) { Emitter.Pop(tkn.ParameterRegisters[0]); }
private void DupInstr(OptimizationToken tkn) { Emitter.MovRegisterToRegister(tkn.ParameterRegisters[0], tkn.ResultRegisters[0]); Emitter.MovRegisterToRegister(tkn.ParameterRegisters[0], tkn.ResultRegisters[1]); }
private void CompareInstr(OptimizationToken tkn) { if (tkn.Parameters[0].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegister(tkn.Parameters[0].Value, tkn.ParameterRegisters[0]); } if (tkn.Parameters[1].ParameterLocation == OptimizationParameterLocation.Const) { Emitter.MovConstantToRegister(tkn.Parameters[1].Value, tkn.ParameterRegisters[1]); } switch (tkn.SubType) { case OptimizationInstructionSubType.Greater: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpGtRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Less: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpLtRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Equal: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpGeRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Equal: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpLeRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpGtUnRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpLtUnRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Equal | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpGeUnRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Equal | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpLeUnRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.Equal: Emitter.Test(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpEqRelativeLabel(tkn.ResultRegisters[0]); break; case OptimizationInstructionSubType.NotEqual | OptimizationInstructionSubType.Unsigned: Emitter.Test(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.CmpNeRelativeLabel(tkn.ResultRegisters[0]); break; default: throw new NotImplementedException(); } }
private void InOp(OptimizationToken tkn) { //TODO: In operation needs to write to the argument address throw new NotImplementedException(); }
private void BranchInstr(OptimizationToken tkn) { switch (tkn.SubType) { case OptimizationInstructionSubType.None: Emitter.JmpRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Greater: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpGtRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Less: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpLtRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Equal: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpGeRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Equal: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpLeRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpGtUnRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpLtUnRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Greater | OptimizationInstructionSubType.Equal | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpGeUnRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Less | OptimizationInstructionSubType.Equal | OptimizationInstructionSubType.Unsigned: Emitter.Compare(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpLeUnRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.Equal: Emitter.Test(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpEqRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.NotEqual | OptimizationInstructionSubType.Unsigned: Emitter.Test(tkn.ParameterRegisters[1], tkn.ParameterRegisters[0]); Emitter.JmpNeRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.True: Emitter.TestBool(tkn.ParameterRegisters[0]); Emitter.JmpNZeroRelativeLabel((int)tkn.Constants[0]); break; case OptimizationInstructionSubType.False: Emitter.TestBool(tkn.ParameterRegisters[0]); Emitter.JmpZeroRelativeLabel((int)tkn.Constants[0]); break; default: throw new NotImplementedException(); } }
public void PropogateRegisters(int root, Graph <GraphNode <OptimizationToken> > graph) { var node = graph.Nodes[root]; var tkn = node.Node.Token; //If the ParameterRegisters is given, is not an active thunk register and the associated incoming connection is Any, update ResultRegisters //If the ParameterRegisters is given and is an active thunk register, mark the register as needing to be saved for (int j = 0; j < tkn.ParameterRegisters.Length; j++) { OptimizationToken res = null; int resultIdx = -1; if (tkn.Parameters[j].ParameterLocation == OptimizationParameterLocation.Index) { res = graph.Nodes[(int)tkn.Parameters[j].Value].Node.Token; resultIdx = res.GetResultIdx(); } bool isRegBased = true; if (tkn.Parameters[j].ParameterLocation == OptimizationParameterLocation.Const && (tkn.ParameterRegisters[j] & AssemRegisters.Const) != 0) { isRegBased = false; //Update the entry to be using the constant form if (tkn.Parameters[j].Value <= byte.MaxValue && tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Const8)) { tkn.ParameterRegisters[j] = AssemRegisters.Const8; tkn.Parameters[j].Size = 1; } else if (tkn.Parameters[j].Value <= ushort.MaxValue && tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Const16)) { tkn.ParameterRegisters[j] = AssemRegisters.Const16; tkn.Parameters[j].Size = 2; } else if (tkn.Parameters[j].Value <= uint.MaxValue && tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Const32)) { tkn.ParameterRegisters[j] = AssemRegisters.Const32; tkn.Parameters[j].Size = 4; } else if (tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Const64)) { tkn.ParameterRegisters[j] = AssemRegisters.Const64; tkn.Parameters[j].Size = 8; } else { tkn.ParameterRegisters[j] &= ~AssemRegisters.Const; isRegBased = true; } } if (isRegBased && !tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Any)) { var reg = tkn.ParameterRegisters[j] & ~AssemRegisters.Const; //Propogate the result register if (res != null && res.ResultRegisters.Length != 0) { if (res.ResultRegisters[resultIdx].HasFlag(AssemRegisters.Any)) { res.ResultRegisters[resultIdx] = reg; tkn.ParameterRegisters[j] = reg; } else if (res.ResultRegisters[resultIdx] != reg) { //We have a conflict of assignments, will need to insert a move during code generation } } else { tkn.ParameterRegisters[j] = reg; } } else if (isRegBased && tkn.ParameterRegisters[j].HasFlag(AssemRegisters.Any)) { if (res != null && tkn.Parameters[j].ParameterLocation != OptimizationParameterLocation.Const) { //Propogate the register from Result into the Parameter if (res.ResultRegisters.Length == 0) { throw new Exception("Expected more than 0 results from previous token."); } tkn.ParameterRegisters[j] = res.ResultRegisters[resultIdx]; if (tkn.Parameters[j].Size != 0) { res.Results[resultIdx].Size = tkn.Parameters[j].Size; } else { throw new Exception(); } } } if (tkn.Parameters[j].ParameterLocation == OptimizationParameterLocation.Index) { PropogateRegisters((int)tkn.Parameters[j].Value, graph); } } }