示例#1
0
        public static void Stm(ArmEmitterContext context)
        {
            OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;

            Operand n = GetIntA32(context, op.Rn);

            Operand baseAddress = context.Add(n, Const(op.Offset));

            int mask   = op.RegisterMask;
            int offset = 0;

            for (int register = 0; mask != 0; mask >>= 1, register++)
            {
                if ((mask & 1) != 0)
                {
                    Operand address = context.Add(baseAddress, Const(offset));

                    EmitStore(context, address, register, WordSizeLog2);

                    // Note: If Rn is also specified on the register list,
                    // and Rn is the first register on this list, then the
                    // value that is written to memory is the unmodified value,
                    // before the write back. If it is on the list, but it's
                    // not the first one, then the value written to memory
                    // varies between CPUs.
                    if (offset == 0 && op.PostOffset != 0)
                    {
                        // Emit write back after the first write.
                        SetIntA32(context, op.Rn, context.Add(n, Const(op.PostOffset)));
                    }

                    offset += 4;
                }
            }
        }
示例#2
0
        public static void Ldm(ArmEmitterContext context)
        {
            OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;

            Operand n = GetIntA32(context, op.Rn);

            Operand baseAddress = context.Add(n, Const(op.Offset));

            bool writesToPc = (op.RegisterMask & (1 << RegisterAlias.Aarch32Pc)) != 0;

            bool writeBack = op.PostOffset != 0 && (op.Rn != RegisterAlias.Aarch32Pc || !writesToPc);

            if (writeBack)
            {
                SetIntA32(context, op.Rn, context.Add(n, Const(op.PostOffset)));
            }

            int mask   = op.RegisterMask;
            int offset = 0;

            for (int register = 0; mask != 0; mask >>= 1, register++)
            {
                if ((mask & 1) != 0)
                {
                    Operand address = context.Add(baseAddress, Const(offset));

                    EmitLoadZx(context, address, register, WordSizeLog2);

                    offset += 4;
                }
            }
        }
示例#3
0
        public static void Ldm(ILEmitterCtx context)
        {
            OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;

            EmitLoadFromRegister(context, op.Rn);

            bool writesToPc = (op.RegisterMask & (1 << RegisterAlias.Aarch32Pc)) != 0;

            bool writeBack = op.PostOffset != 0 && (op.Rn != RegisterAlias.Aarch32Pc || !writesToPc);

            if (writeBack)
            {
                context.Emit(OpCodes.Dup);
            }

            context.EmitLdc_I4(op.Offset);

            context.Emit(OpCodes.Add);

            context.EmitSttmp();

            if (writeBack)
            {
                context.EmitLdc_I4(op.PostOffset);

                context.Emit(OpCodes.Add);

                EmitStoreToRegister(context, op.Rn);
            }

            int mask   = op.RegisterMask;
            int offset = 0;

            for (int register = 0; mask != 0; mask >>= 1, register++)
            {
                if ((mask & 1) != 0)
                {
                    context.EmitLdarg(TranslatedSub.MemoryArgIdx);
                    context.EmitLdtmp();

                    context.EmitLdc_I4(offset);

                    context.Emit(OpCodes.Add);

                    EmitReadZxCall(context, WordSizeLog2);

                    EmitStoreToRegister(context, register);

                    offset += 4;
                }
            }
        }
示例#4
0
        public static void Stm(ILEmitterCtx context)
        {
            OpCode32MemMult op = (OpCode32MemMult)context.CurrOp;

            EmitLoadFromRegister(context, op.Rn);

            context.EmitLdc_I4(op.Offset);

            context.Emit(OpCodes.Add);

            context.EmitSttmp();

            int mask   = op.RegisterMask;
            int offset = 0;

            for (int register = 0; mask != 0; mask >>= 1, register++)
            {
                if ((mask & 1) != 0)
                {
                    context.EmitLdarg(TranslatedSub.MemoryArgIdx);
                    context.EmitLdtmp();

                    context.EmitLdc_I4(offset);

                    context.Emit(OpCodes.Add);

                    EmitLoadFromRegister(context, register);

                    EmitWriteCall(context, WordSizeLog2);

                    //Note: If Rn is also specified on the register list,
                    //and Rn is the first register on this list, then the
                    //value that is written to memory is the unmodified value,
                    //before the write back. If it is on the list, but it's
                    //not the first one, then the value written to memory
                    //varies between CPUs.
                    if (offset == 0 && op.PostOffset != 0)
                    {
                        //Emit write back after the first write.
                        EmitLoadFromRegister(context, op.Rn);

                        context.EmitLdc_I4(op.PostOffset);

                        context.Emit(OpCodes.Add);

                        EmitStoreToRegister(context, op.Rn);
                    }

                    offset += 4;
                }
            }
        }