InstEmitFlow32.cs 1.9 KB

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