InstEmitFlow32.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using ARMeilleure.Decoders;
  2. using ARMeilleure.IntermediateRepresentation;
  3. using ARMeilleure.State;
  4. using ARMeilleure.Translation;
  5. using static ARMeilleure.Instructions.InstEmitFlowHelper;
  6. using static ARMeilleure.Instructions.InstEmitHelper;
  7. using static ARMeilleure.IntermediateRepresentation.OperandHelper;
  8. namespace ARMeilleure.Instructions
  9. {
  10. static partial class InstEmit32
  11. {
  12. public static void B(ArmEmitterContext context)
  13. {
  14. IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;
  15. if (context.CurrBlock.Branch != null)
  16. {
  17. context.Branch(context.GetLabel((ulong)op.Immediate));
  18. }
  19. else
  20. {
  21. EmitTailContinue(context, Const(op.Immediate));
  22. }
  23. }
  24. public static void Bl(ArmEmitterContext context)
  25. {
  26. Blx(context, x: false);
  27. }
  28. public static void Blx(ArmEmitterContext context)
  29. {
  30. Blx(context, x: true);
  31. }
  32. private static void Blx(ArmEmitterContext context, bool x)
  33. {
  34. IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;
  35. uint pc = op.GetPc();
  36. bool isThumb = IsThumb(context.CurrOp);
  37. uint currentPc = isThumb
  38. ? pc | 1
  39. : pc - 4;
  40. SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc));
  41. // If x is true, then this is a branch with link and exchange.
  42. // In this case we need to swap the mode between Arm <-> Thumb.
  43. if (x)
  44. {
  45. SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1));
  46. }
  47. EmitCall(context, (ulong)op.Immediate);
  48. }
  49. public static void Blxr(ArmEmitterContext context)
  50. {
  51. IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
  52. uint pc = op.GetPc();
  53. Operand addr = context.Copy(GetIntA32(context, op.Rm));
  54. Operand bitOne = context.BitwiseAnd(addr, Const(1));
  55. bool isThumb = IsThumb(context.CurrOp);
  56. uint currentPc = isThumb
  57. ? pc | 1
  58. : pc - 4;
  59. SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc));
  60. SetFlag(context, PState.TFlag, bitOne);
  61. EmitVirtualCall(context, addr);
  62. }
  63. public static void Bx(ArmEmitterContext context)
  64. {
  65. IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
  66. EmitBxWritePc(context, GetIntA32(context, op.Rm), op.Rm);
  67. }
  68. }
  69. }