InstEmitFlow32.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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.Operand.Factory;
  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. context.Branch(context.GetLabel((ulong)op.Immediate));
  16. }
  17. public static void Bl(ArmEmitterContext context)
  18. {
  19. Blx(context, x: false);
  20. }
  21. public static void Blx(ArmEmitterContext context)
  22. {
  23. Blx(context, x: true);
  24. }
  25. private static void Blx(ArmEmitterContext context, bool x)
  26. {
  27. IOpCode32BImm op = (IOpCode32BImm)context.CurrOp;
  28. uint pc = op.GetPc();
  29. bool isThumb = IsThumb(context.CurrOp);
  30. uint currentPc = isThumb
  31. ? pc | 1
  32. : pc - 4;
  33. SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc));
  34. // If x is true, then this is a branch with link and exchange.
  35. // In this case we need to swap the mode between Arm <-> Thumb.
  36. if (x)
  37. {
  38. SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1));
  39. }
  40. EmitCall(context, (ulong)op.Immediate);
  41. }
  42. public static void Blxr(ArmEmitterContext context)
  43. {
  44. IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
  45. uint pc = op.GetPc();
  46. Operand addr = context.Copy(GetIntA32(context, op.Rm));
  47. Operand bitOne = context.BitwiseAnd(addr, Const(1));
  48. bool isThumb = IsThumb(context.CurrOp);
  49. uint currentPc = isThumb
  50. ? pc | 1
  51. : pc - 4;
  52. SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc));
  53. SetFlag(context, PState.TFlag, bitOne);
  54. EmitVirtualCall(context, addr);
  55. }
  56. public static void Bx(ArmEmitterContext context)
  57. {
  58. IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
  59. EmitBxWritePc(context, GetIntA32(context, op.Rm), op.Rm);
  60. }
  61. }
  62. }