コード例 #1
0
        public List <IMOperation> Generate(IMOperand target, IMOperand operand)
        {
            if (operand.DataType.Kind == DataTypeKind.ARRAY || operand.DataType.Kind == DataTypeKind.STRING8)
            {
                //Array already is a pointer, so directly use it
                //Add 8 bytes to array pointer so it points to first value, not to the length
                var result = new List <IMOperation>(2)
                {
                    IMOperation.Mov(target, operand),
                    IMOperation.Add(target, target, IMOperand.Immediate(DataType.U64, 8L))
                };
                return(result);
            }

            return(IMOperation.Lea(target, operand).AsList);
        }
コード例 #2
0
ファイル: TypeCastOperator.cs プロジェクト: ericlass/erc
     public List <IMOperation> Generate(IMGeneratorEnv env, IMOperand target, IMOperand operand1, IMOperand operand2)
     {
         if (target.DataType.Kind == operand1.DataType.Kind)
         {
             return new List <IMOperation>()
                    {
                        IMOperation.Mov(target, operand1)
                    }
         }
         ;
         else
         {
             return new List <IMOperation>()
                    {
                        IMOperation.Cast(target, operand1)
                    }
         };
     }
 }
コード例 #3
0
        private List <IMOperation> GenerateStringConcat(IMGeneratorEnv env, IMOperand target, IMOperand operand1, IMOperand operand2)
        {
            var result = new List <IMOperation>(20);

            var op1LengthLocation = IMOperand.Reference(DataType.U64, operand1);
            var op2LengthLocation = IMOperand.Reference(DataType.U64, operand2);

            //Calculate new string length
            var lengthLocation = env.NewTempLocal(DataType.U64);

            result.Add(IMOperation.Mov(lengthLocation, op1LengthLocation));
            result.Add(IMOperation.Add(lengthLocation, lengthLocation, op2LengthLocation));

            //Calculate new string byte size
            var byteSizeLocation = env.NewTempLocal(DataType.U64);

            result.Add(IMOperation.Mov(byteSizeLocation, lengthLocation));
            result.Add(IMOperation.Add(lengthLocation, lengthLocation, IMOperand.Immediate(DataType.U64, 9L)));

            //Reserve new memory on stack, which is freed automatically
            result.Add(IMOperation.SAloc(target, byteSizeLocation));

            //Copy target address
            var targetAddressLocation = env.NewTempLocal(target.DataType);

            result.Add(IMOperation.Mov(targetAddressLocation, target));

            //Write new string length to target
            result.Add(IMOperation.Mov(IMOperand.Reference(DataType.U64, targetAddressLocation), lengthLocation));

            //Move pointer to first char
            result.Add(IMOperation.Add(targetAddressLocation, targetAddressLocation, IMOperand.Immediate(DataType.U64, 8L)));

            var targetRefLocation = IMOperand.Reference(DataType.CHAR8, targetAddressLocation);

            //Get address of first char of operand1
            var sourceAddressLocation = env.NewTempLocal(target.DataType);

            result.Add(IMOperation.Mov(sourceAddressLocation, operand1));
            result.Add(IMOperation.Add(sourceAddressLocation, sourceAddressLocation, IMOperand.Immediate(DataType.U64, 8L)));

            var sourceRefLocation = IMOperand.Reference(DataType.CHAR8, sourceAddressLocation);

            var startLabel = env.NewLabelName();
            var endLabel   = env.NewLabelName();

            //Start label
            result.Add(IMOperation.Labl(startLabel));

            //Check if more chars to copy (string ends with 0 char)
            result.Add(IMOperation.JmpE(sourceRefLocation, IMOperand.Immediate(DataType.CHAR8, "\0"), endLabel));

            //Copy char
            result.Add(IMOperation.Mov(targetRefLocation, sourceRefLocation));

            //Inc target and source pointers
            result.Add(IMOperation.Add(targetAddressLocation, targetAddressLocation, IMOperand.Immediate(DataType.U64, 1L)));
            result.Add(IMOperation.Add(sourceAddressLocation, sourceAddressLocation, IMOperand.Immediate(DataType.U64, 1L)));

            //Next iteration
            result.Add(IMOperation.Jmp(startLabel));
            result.Add(IMOperation.Labl(endLabel));

            //Get address of first char of operand2
            result.Add(IMOperation.Mov(sourceAddressLocation, operand2));
            result.Add(IMOperation.Add(sourceAddressLocation, sourceAddressLocation, IMOperand.Immediate(DataType.U64, 8L)));

            startLabel = env.NewLabelName();
            endLabel   = env.NewLabelName();

            //Start label
            result.Add(IMOperation.Labl(startLabel));

            //Check if more chars to copy (string ends with 0 char)
            result.Add(IMOperation.JmpE(sourceRefLocation, IMOperand.Immediate(DataType.CHAR8, "\0"), endLabel));

            //Copy char
            result.Add(IMOperation.Mov(targetRefLocation, sourceRefLocation));

            //Inc target and source pointers
            result.Add(IMOperation.Add(targetAddressLocation, targetAddressLocation, IMOperand.Immediate(DataType.U64, 1L)));
            result.Add(IMOperation.Add(sourceAddressLocation, sourceAddressLocation, IMOperand.Immediate(DataType.U64, 1L)));

            //Next iteration
            result.Add(IMOperation.Jmp(startLabel));
            result.Add(IMOperation.Labl(endLabel));

            //Terminating 0
            result.Add(IMOperation.Mov(targetRefLocation, IMOperand.Immediate(DataType.U8, (byte)0)));

            return(result);
        }
コード例 #4
0
        public List <IMOperation> Generate(IMOperand target, IMOperand operand)
        {
            var reference = IMOperand.Reference(operand.DataType.ElementType, operand);

            return(IMOperation.Mov(target, reference).AsList);
        }
コード例 #5
0
ファイル: LengthOperator.cs プロジェクト: ericlass/erc
 public List <IMOperation> Generate(IMOperand target, IMOperand operand)
 {
     return(IMOperation.Mov(target, IMOperand.Reference(DataType.U64, operand)).AsList);
 }