Example #1
0
        public static Register MakeRegisterWithCorrectSize(this Type type, Register64 intRegister, XmmRegister floatRegister)
        {
            if (!type.IsIntegerRegisterType())
            {
                return(floatRegister);
            }

            switch (type.SizeOf())
            {
            case 8:
                return(intRegister);

            case 4:
                return((Register32)intRegister);

            case 2:
                return((Register16)intRegister);

            case 1:
                return((Register8)intRegister);

            default:
                throw new NotImplementedException($"Proper register for type {type} (size {type.SizeOf()}) has not been implemented yet");
            }
        }
Example #2
0
 public ExpressionResult(Type valueType, Register64 ptr, int offset, Segment segment = Segment.DS)
 {
     ValueType = valueType ?? throw new ArgumentNullException(nameof(valueType));
     Ptr       = ptr;
     Offset    = offset;
     Segment   = segment;
     Kind      = ResultKind.Pointer;
 }
Example #3
0
        private static byte GetPrefix(ref Register64 r)
        {
            if (r.Value < 8)
            {
                return(r.Value);
            }

            r = new Register64((byte)(r.Value - 8));
            return(1);
        }
Example #4
0
        public BootstrapCore64(Architecture architecture)
        {
            Memory       = Factory.CreateDynamicMemory(architecture);
            Register     = new Register64();
            CsrRegister  = Factory.CreateCsrRegister();
            RasStack     = new Stack <ulong>();
            Environment  = HartEnvironmentFactory.Build(architecture, Register, Memory, CsrRegister);
            BaseAddres   = 0x100;
            EndianCoding = EndianType.Little;

            InstructionsProcessed = new List <Instruction>();
            InstructionPayloads   = new List <InstructionPayload>();
        }
Example #5
0
        public ExpressionResult(Type valueType, Register64 ptr, byte ptrMul, int offsetFlat = 0, Segment segment = Segment.DS)
        {
            if (ptrMul != 1 && ptrMul != 2 && ptrMul != 4 && ptrMul != 8)
            {
                throw new ArgumentOutOfRangeException("The multiplicative offset may only be 1, 2, 4 or 8");
            }

            ValueType = valueType ?? throw new ArgumentNullException(nameof(valueType));
            Ptr       = ptr;
            OffsetMul = ptrMul;
            Offset    = offsetFlat;
            Segment   = segment;
            Kind      = ResultKind.Pointer3;
        }
Example #6
0
        public ExpressionResult Compile(
            ArrayAccessExpression expression,
            PreferredRegister target,
            ICompilationContext context
            )
        {
            var arrayTemp = context.Storage.Allocate(true);
            var array     = context.CompileExpression(expression.Array, arrayTemp.IsRegister ? arrayTemp.Register : Register64.RAX);
            var arrayType = array.ValueType;

            arrayTemp.Store(array, context.Generator, context.Linking);

            const Register64 structOffsetRegister = Register64.RCX;
            const Register64 arrayRegister        = Register64.RAX;
            var arrayIndex = context.CompileExpression(expression.Index, new PreferredRegister(structOffsetRegister));

            Constants.LongType.AssertCanAssignImplicitly(arrayIndex.ValueType);

            arrayIndex.GenerateMoveTo(structOffsetRegister, Constants.LongType, context.Generator, context.Linking);
            arrayTemp.AsExpressionResult(arrayType).GenerateMoveTo(arrayRegister, context.Generator, context.Linking);
            context.Storage.Release(arrayTemp);

            if (arrayType == Constants.CstrType)
            {
                return(new ExpressionResult(Constants.SbyteType, arrayRegister, structOffsetRegister, 1));
            }

            var itemType = arrayType.Child;

            if (arrayType.ChildRelation == Type.WrappingType.PointerOf)
            {
                return(new ExpressionResult(itemType, arrayRegister, structOffsetRegister, (byte)itemType.SizeOf()));
            }
            if (arrayType.ChildRelation == Type.WrappingType.ArrayOf)
            {
                return(new ExpressionResult(itemType, arrayRegister, structOffsetRegister, (byte)itemType.SizeOf(), 8));
            }

            throw new TypeMismatchException("Array or pointer", arrayType.ToString());
        }
Example #7
0
 public PreferredRegister(Register64 intRegister) => IntRegister = intRegister;
Example #8
0
 public PreferredRegister(Register64 intRegister, XmmRegister floatRegister)
 {
     IntRegister   = intRegister;
     FloatRegister = floatRegister;
 }
Example #9
0
        public void PopTest()
        {
            var stack = new FpuStack();

            stack.Push(Register64.FromDouble(1));
            Assert.Equal(Register64.FromDouble(1), stack[0]);

            stack.Push(Register64.FromDouble(2));
            Assert.Equal(Register64.FromDouble(2), stack[0]);
            Assert.Equal(Register64.FromDouble(1), stack[1]);

            stack.Push(Register64.FromDouble(3));
            Assert.Equal(Register64.FromDouble(3), stack[0]);
            Assert.Equal(Register64.FromDouble(2), stack[1]);
            Assert.Equal(Register64.FromDouble(1), stack[2]);

            stack.Push(Register64.FromDouble(4));
            Assert.Equal(Register64.FromDouble(4), stack[0]);
            Assert.Equal(Register64.FromDouble(3), stack[1]);
            Assert.Equal(Register64.FromDouble(2), stack[2]);
            Assert.Equal(Register64.FromDouble(1), stack[3]);

            stack.Push(Register64.FromDouble(5));
            Assert.Equal(Register64.FromDouble(5), stack[0]);
            Assert.Equal(Register64.FromDouble(4), stack[1]);
            Assert.Equal(Register64.FromDouble(3), stack[2]);
            Assert.Equal(Register64.FromDouble(2), stack[3]);
            Assert.Equal(Register64.FromDouble(1), stack[4]);

            stack.Push(Register64.FromDouble(6));
            Assert.Equal(Register64.FromDouble(6), stack[0]);
            Assert.Equal(Register64.FromDouble(5), stack[1]);
            Assert.Equal(Register64.FromDouble(4), stack[2]);
            Assert.Equal(Register64.FromDouble(3), stack[3]);
            Assert.Equal(Register64.FromDouble(2), stack[4]);
            Assert.Equal(Register64.FromDouble(1), stack[5]);

            stack.Push(Register64.FromDouble(7));
            Assert.Equal(Register64.FromDouble(7), stack[0]);
            Assert.Equal(Register64.FromDouble(6), stack[1]);
            Assert.Equal(Register64.FromDouble(5), stack[2]);
            Assert.Equal(Register64.FromDouble(4), stack[3]);
            Assert.Equal(Register64.FromDouble(3), stack[4]);
            Assert.Equal(Register64.FromDouble(2), stack[5]);
            Assert.Equal(Register64.FromDouble(1), stack[6]);

            stack.Push(Register64.FromDouble(8));
            Assert.Equal(Register64.FromDouble(8), stack[0]);
            Assert.Equal(Register64.FromDouble(7), stack[1]);
            Assert.Equal(Register64.FromDouble(6), stack[2]);
            Assert.Equal(Register64.FromDouble(5), stack[3]);
            Assert.Equal(Register64.FromDouble(4), stack[4]);
            Assert.Equal(Register64.FromDouble(3), stack[5]);
            Assert.Equal(Register64.FromDouble(2), stack[6]);
            Assert.Equal(Register64.FromDouble(1), stack[7]);

            Assert.Equal(Register64.FromDouble(8), stack.Pop());
            Assert.Equal(Register64.FromDouble(7), stack.Pop());
            Assert.Equal(Register64.FromDouble(6), stack.Pop());
            Assert.Equal(Register64.FromDouble(5), stack.Pop());
            Assert.Equal(Register64.FromDouble(4), stack.Pop());
            Assert.Equal(Register64.FromDouble(3), stack.Pop());
            Assert.Equal(Register64.FromDouble(2), stack.Pop());
            Assert.Equal(Register64.FromDouble(1), stack.Pop());
        }
Example #10
0
 public PreferredRegister MakePreferredRegister(Register64 fallbackInt = Register64.RAX, XmmRegister fallbackFloat = XmmRegister.XMM0) =>
 new PreferredRegister(
     _registerStorageInt.Count > 0 ? _registerStorageInt.Peek().Register.AsR64() : fallbackInt,
     _registerStorageFloat.Count > 0 ? _registerStorageFloat.Peek().Register.AsFloat() : fallbackFloat
     );
Example #11
0
 static ExpressionResult MakeRegister(Type type, Register64 registerInt, XmmRegister registerFloat) =>
 new ExpressionResult(
     type,
     type.MakeRegisterWithCorrectSize(registerInt, registerFloat)
     );