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 AILOpCodeLoad : IAILEmit
 | |
|     {
 | |
|         public int Index { get; private set; }
 | |
| 
 | |
|         public AIoType IoType { get; private set; }
 | |
| 
 | |
|         public ARegisterSize RegisterSize { get; private set; }
 | |
| 
 | |
|         public AILOpCodeLoad(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.EmitLdarg(Index); break;
 | |
| 
 | |
|                 case AIoType.Fields:
 | |
|                 {
 | |
|                     long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index));
 | |
|                     long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index));
 | |
| 
 | |
|                     LoadLocals(Context, IntInputs, ARegisterType.Int);
 | |
|                     LoadLocals(Context, VecInputs, ARegisterType.Vector);
 | |
| 
 | |
|                     break;
 | |
|                 }
 | |
| 
 | |
|                 case AIoType.Flag:   EmitLdloc(Context, Index, ARegisterType.Flag);   break;
 | |
|                 case AIoType.Int:    EmitLdloc(Context, Index, ARegisterType.Int);    break;
 | |
|                 case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void LoadLocals(AILEmitter Context, long Inputs, ARegisterType BaseType)
 | |
|         {
 | |
|             for (int Bit = 0; Bit < 64; Bit++)
 | |
|             {
 | |
|                 long Mask = 1L << Bit;
 | |
| 
 | |
|                 if ((Inputs & Mask) != 0)
 | |
|                 {
 | |
|                     ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
 | |
| 
 | |
|                     Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx);
 | |
|                     Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField());
 | |
| 
 | |
|                     Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void EmitLdloc(AILEmitter Context, int Index, ARegisterType RegisterType)
 | |
|         {
 | |
|             ARegister Reg = new ARegister(Index, RegisterType);
 | |
| 
 | |
|             Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));
 | |
| 
 | |
|             if (RegisterType == ARegisterType.Int &&
 | |
|                 RegisterSize == ARegisterSize.Int32)
 | |
|             {
 | |
|                 Context.Generator.Emit(OpCodes.Conv_U4);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| } | 
