75 lines
		
	
	
		
			No EOL
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			No EOL
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using ChocolArm64.State;
 | |
| using System.Reflection.Emit;
 | |
| 
 | |
| namespace ChocolArm64.Translation
 | |
| {
 | |
|     struct AILOpCodeStore : IAILEmit
 | |
|     {
 | |
|         public int Index { get; private set; }
 | |
| 
 | |
|         public AIoType IoType { get; private set; }
 | |
| 
 | |
|         public ARegisterSize RegisterSize { get; private set; }
 | |
| 
 | |
|         public AILOpCodeStore(int Index, AIoType IoType, ARegisterSize RegisterSize = 0)
 | |
|         {
 | |
|             this.Index        = Index;
 | |
|             this.IoType       = IoType;
 | |
|             this.RegisterSize = RegisterSize;
 | |
|         }
 | |
| 
 | |
|         public void Emit(AILEmitter Context)
 | |
|         {
 | |
|             switch (IoType)
 | |
|             {
 | |
|                 case AIoType.Arg: Context.Generator.EmitStarg(Index); break;
 | |
| 
 | |
|                 case AIoType.Fields:
 | |
|                 {
 | |
|                     long IntOutputs = Context.LocalAlloc.GetIntOutputs(Context.GetILBlock(Index));
 | |
|                     long VecOutputs = Context.LocalAlloc.GetVecOutputs(Context.GetILBlock(Index));
 | |
| 
 | |
|                     StoreLocals(Context, IntOutputs, ARegisterType.Int);
 | |
|                     StoreLocals(Context, VecOutputs, ARegisterType.Vector);
 | |
|                     
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 case AIoType.Flag:   EmitStloc(Context, Index, ARegisterType.Flag);   break;
 | |
|                 case AIoType.Int:    EmitStloc(Context, Index, ARegisterType.Int);    break;
 | |
|                 case AIoType.Vector: EmitStloc(Context, Index, ARegisterType.Vector); break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void StoreLocals(AILEmitter Context, long Outputs, ARegisterType BaseType)
 | |
|         {
 | |
|             for (int Bit = 0; Bit < 64; Bit++)
 | |
|             {
 | |
|                 long Mask = 1L << Bit;
 | |
| 
 | |
|                 if ((Outputs & Mask) != 0)
 | |
|                 {
 | |
|                     ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
 | |
| 
 | |
|                     Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx);
 | |
|                     Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));
 | |
| 
 | |
|                     Context.Generator.Emit(OpCodes.Stfld, Reg.GetField());
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void EmitStloc(AILEmitter Context, int Index, ARegisterType RegisterType)
 | |
|         {
 | |
|             ARegister Reg = new ARegister(Index, RegisterType);
 | |
| 
 | |
|             if (RegisterType == ARegisterType.Int &&
 | |
|                 RegisterSize == ARegisterSize.Int32)
 | |
|             {
 | |
|                 Context.Generator.Emit(OpCodes.Conv_U8);
 | |
|             }
 | |
| 
 | |
|             Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));
 | |
|         }
 | |
|     }
 | |
| } | 
