예제 #1
0
        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();
            }
        }
예제 #2
0
 private void NewInstr(OptimizationToken tkn)
 {
     switch (tkn.SubType)
     {
     case OptimizationInstructionSubType.Array:
     {
     }
     break;
     }
 }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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();
        }
예제 #5
0
        private void NotInstr(OptimizationToken tkn)
        {
            switch (tkn.SubType)
            {
            case OptimizationInstructionSubType.None:
            {
                Emitter.Not(tkn.ParameterRegisters[0], tkn.ResultRegisters[0]);
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
 private void SwitchInstr(OptimizationToken tkn)
 {
 }
예제 #10
0
 private void PopInstr(OptimizationToken tkn)
 {
     Emitter.Pop(tkn.ParameterRegisters[0]);
 }
예제 #11
0
 private void DupInstr(OptimizationToken tkn)
 {
     Emitter.MovRegisterToRegister(tkn.ParameterRegisters[0], tkn.ResultRegisters[0]);
     Emitter.MovRegisterToRegister(tkn.ParameterRegisters[0], tkn.ResultRegisters[1]);
 }
예제 #12
0
        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();
            }
        }
예제 #13
0
 private void InOp(OptimizationToken tkn)
 {
     //TODO: In operation needs to write to the argument address
     throw new NotImplementedException();
 }
예제 #14
0
        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();
            }
        }
예제 #15
0
        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);
                }
            }
        }