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; } } }
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; } } }
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; } } }
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; } } }