ReadOrWriteStaticRegister.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. using Ryujinx.HLE.HOS.Tamper.Operations;
  2. namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters
  3. {
  4. /// <summary>
  5. /// Code type 0xC3 reads or writes a static register with a given register.
  6. /// NOTE: Registers are saved and restored to a different set of registers than the ones used
  7. /// for the other opcodes (Static Registers).
  8. /// </summary>
  9. class ReadOrWriteStaticRegister
  10. {
  11. private const int StaticRegisterIndex = 5;
  12. private const int RegisterIndex = 7;
  13. private const byte FirstWriteRegister = 0x80;
  14. private const int StaticRegisterSize = 2;
  15. public static void Emit(byte[] instruction, CompilationContext context)
  16. {
  17. // C3000XXx
  18. // XX: Static register index, 0x00 to 0x7F for reading or 0x80 to 0xFF for writing.
  19. // x: Register index.
  20. ulong staticRegisterIndex = InstructionHelper.GetImmediate(instruction, StaticRegisterIndex, StaticRegisterSize);
  21. Register register = context.GetRegister(instruction[RegisterIndex]);
  22. IOperand sourceRegister;
  23. IOperand destinationRegister;
  24. if (staticRegisterIndex < FirstWriteRegister)
  25. {
  26. // Read from static register.
  27. sourceRegister = context.GetStaticRegister((byte)staticRegisterIndex);
  28. destinationRegister = register;
  29. }
  30. else
  31. {
  32. // Write to static register.
  33. sourceRegister = register;
  34. destinationRegister = context.GetStaticRegister((byte)(staticRegisterIndex - FirstWriteRegister));
  35. }
  36. context.CurrentOperations.Add(new OpMov<ulong>(destinationRegister, sourceRegister));
  37. }
  38. }
  39. }