PrologEncoderMD.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "Backend.h"
  6. #include "PrologEncoderMD.h"
  7. unsigned __int8 PrologEncoderMD::GetRequiredNodeCountForAlloca(size_t size)
  8. {
  9. Assert(size);
  10. Assert(size % 8 == 0);
  11. if (size <= 0x80)
  12. return 1;
  13. else if (size <= 0x7FF8)
  14. return 2;
  15. else
  16. return 3;
  17. }
  18. unsigned __int8 PrologEncoderMD::GetOp(IR::Instr *instr)
  19. {
  20. switch (instr->m_opcode)
  21. {
  22. case Js::OpCode::PUSH:
  23. Assert(instr->GetSrc1()->IsRegOpnd());
  24. return UWOP_PUSH_NONVOL;
  25. case Js::OpCode::MOVAPD:
  26. case Js::OpCode::MOVAPS:
  27. Assert(instr->GetSrc1()->IsRegOpnd() && REGNUM_ISXMMXREG(instr->GetSrc1()->AsRegOpnd()->GetReg()));
  28. return UWOP_SAVE_XMM128;
  29. case Js::OpCode::MOV:
  30. // MOV rbp, rsp (or)
  31. // MOV rax, imm
  32. Assert(instr->GetDst() && instr->GetSrc1());
  33. return UWOP_IGNORE;
  34. case Js::OpCode::SUB:
  35. Assert(instr->GetSrc1() && instr->GetSrc2());
  36. Assert(instr->GetSrc1()->AsRegOpnd()->GetReg() == RegRSP &&
  37. instr->GetSrc2()->IsIntConstOpnd());
  38. if (instr->GetSrc2()->AsIntConstOpnd()->GetValue() <= 128)
  39. return UWOP_ALLOC_SMALL;
  40. else
  41. return UWOP_ALLOC_LARGE;
  42. case Js::OpCode::CALL:
  43. // TODO: call target could also be a stack overflow check.
  44. // Assert(instr->GetSrc1()->AsHelperCallOpnd()->m_fnHelper == IR::HelperCRT_chkstk);
  45. Assert(instr->GetSrc1()->IsRegOpnd());
  46. return UWOP_IGNORE;
  47. default:
  48. AssertMsg(false, "Unsupported opcode in prolog.");
  49. }
  50. return UWOP_IGNORE;
  51. }
  52. unsigned __int8 PrologEncoderMD::GetNonVolRegToSave(IR::Instr *instr)
  53. {
  54. Assert(instr->m_opcode == Js::OpCode::PUSH);
  55. return (instr->GetSrc1()->AsRegOpnd()->GetReg() - 1) & 0xFF;
  56. }
  57. unsigned __int8 PrologEncoderMD::GetXmmRegToSave(IR::Instr *instr, unsigned __int16 *scaledOffset)
  58. {
  59. Assert(scaledOffset);
  60. Assert(instr->m_opcode == Js::OpCode::MOVAPD || instr->m_opcode == Js::OpCode::MOVAPS);
  61. Assert(instr->GetDst() && instr->GetDst()->IsIndirOpnd());
  62. unsigned __int8 reg = ((instr->GetSrc1()->AsRegOpnd()->GetReg() - FIRST_XMM_REG) & 0xFF);
  63. unsigned __int32 offsetFromInstr = instr->GetDst()->AsIndirOpnd()->GetOffset();
  64. // The offset in the instruction is relative to the stack pointer before the saved reg size and stack args size were
  65. // subtracted, but the offset in the unwind info needs to be relative to the final stack pointer value
  66. // (see LowererMDArch::LowerEntryInstr), so adjust for that
  67. Assert(instr->GetDst()->AsIndirOpnd()->GetBaseOpnd()->GetReg() == LowererMDArch::GetRegStackPointer());
  68. Func *const topFunc = instr->m_func->GetTopFunc();
  69. offsetFromInstr += topFunc->GetArgsSize() + topFunc->GetSavedRegSize();
  70. // Can only encode nonnegative 16-byte-aligned offsets in the unwind info
  71. Assert(static_cast<int32>(offsetFromInstr) >= 0);
  72. Assert(::Math::Align(offsetFromInstr, static_cast<unsigned __int32>(MachDouble * 2)) == offsetFromInstr);
  73. // Stored offset is scaled by 16
  74. offsetFromInstr /= MachDouble * 2;
  75. // We currently don't allow a total stack size greater than 1 MB. If we start allowing that, we will need to handle offsets
  76. // greater than (1 MB - 16) in the unwind info as well, for which a FAR version of the op-code is necessary.
  77. Assert(IS_UINT16(offsetFromInstr));
  78. *scaledOffset = TO_UINT16(offsetFromInstr);
  79. return reg;
  80. }
  81. size_t PrologEncoderMD::GetAllocaSize(IR::Instr *instr)
  82. {
  83. Assert(instr->m_opcode == Js::OpCode::SUB);
  84. Assert(instr->GetSrc1() && instr->GetSrc2());
  85. Assert(instr->GetSrc1()->AsRegOpnd()->GetReg() == RegRSP &&
  86. instr->GetSrc2()->IsIntConstOpnd());
  87. Assert(instr->GetSrc2()->AsIntConstOpnd()->GetValue() % 8 == 0);
  88. return instr->GetSrc2()->AsIntConstOpnd()->GetValue();
  89. }
  90. unsigned __int8 PrologEncoderMD::GetFPReg()
  91. {
  92. return RegRBP - 1;
  93. }