PeepsMD.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. // PeepsMD::Init
  7. void
  8. PeepsMD::Init(Peeps *peeps)
  9. {
  10. this->peeps = peeps;
  11. }
  12. // PeepsMD::ProcessImplicitRegs
  13. // Note: only do calls for now
  14. void
  15. PeepsMD::ProcessImplicitRegs(IR::Instr *instr)
  16. {
  17. if (LowererMD::IsCall(instr))
  18. {
  19. #define REGDAT(Name, Listing, Encode, Type, BitVec) \
  20. if (!((BitVec) & (RA_CALLEESAVE | RA_DONTALLOCATE))) \
  21. { \
  22. this->peeps->ClearReg(Reg ## Name); \
  23. }
  24. #include "RegList.h"
  25. }
  26. else if (instr->m_opcode == Js::OpCode::IMUL)
  27. {
  28. this->peeps->ClearReg(RegRDX);
  29. }
  30. else if (instr->m_opcode == Js::OpCode::IDIV || instr->m_opcode == Js::OpCode::DIV)
  31. {
  32. if (instr->GetDst()->AsRegOpnd()->GetReg() == RegRDX)
  33. {
  34. this->peeps->ClearReg(RegRAX);
  35. }
  36. else
  37. {
  38. Assert(instr->GetDst()->AsRegOpnd()->GetReg() == RegRAX);
  39. this->peeps->ClearReg(RegRDX);
  40. }
  41. }
  42. else if (instr->m_opcode == Js::OpCode::XCHG)
  43. {
  44. // At time of writing, I believe that src1 is always identical to dst, but clear both for robustness.
  45. // Either of XCHG's operands (but not both) can be a memory address, so only clear registers.
  46. if (instr->GetSrc1()->IsRegOpnd())
  47. {
  48. this->peeps->ClearReg(instr->GetSrc1()->AsRegOpnd()->GetReg());
  49. }
  50. if (instr->GetSrc2()->IsRegOpnd())
  51. {
  52. this->peeps->ClearReg(instr->GetSrc2()->AsRegOpnd()->GetReg());
  53. }
  54. }
  55. }
  56. void
  57. PeepsMD::PeepAssign(IR::Instr *instr)
  58. {
  59. IR::Opnd* dst = instr->GetDst();
  60. IR::Opnd* src = instr->GetSrc1();
  61. if(dst->IsRegOpnd() && instr->m_opcode == Js::OpCode::MOV && !instr->isInlineeEntryInstr)
  62. {
  63. if (src->IsImmediateOpnd() && src->GetImmediateValue(instr->m_func) == 0)
  64. {
  65. Assert(instr->GetSrc2() == NULL);
  66. // 32-bit XOR has a smaller encoding
  67. if (TySize[dst->GetType()] == MachPtr)
  68. {
  69. dst->SetType(TyInt32);
  70. }
  71. instr->m_opcode = Js::OpCode::XOR;
  72. instr->ReplaceSrc1(dst);
  73. instr->SetSrc2(dst);
  74. }
  75. else
  76. {
  77. if(src->IsIntConstOpnd() && src->GetSize() <= TySize[TyUint32])
  78. {
  79. dst->SetType(TyUint32);
  80. src->SetType(TyUint32);
  81. }
  82. else if(src->IsAddrOpnd() && (((size_t)src->AsAddrOpnd()->m_address >> 32) == 0 ))
  83. {
  84. instr->ReplaceSrc1(IR::IntConstOpnd::New(::Math::PointerCastToIntegral<UIntConstType>(src->AsAddrOpnd()->m_address), TyUint32, instr->m_func));
  85. dst->SetType(TyUint32);
  86. }
  87. }
  88. }
  89. else if (((instr->m_opcode == Js::OpCode::MOVSD || instr->m_opcode == Js::OpCode::MOVSS)
  90. && src->IsRegOpnd()
  91. && dst->IsRegOpnd()
  92. && (TySize[src->GetType()] == TySize[dst->GetType()]))
  93. || ((instr->m_opcode == Js::OpCode::MOVUPS)
  94. && src->IsRegOpnd()
  95. && dst->IsRegOpnd())
  96. || (instr->m_opcode == Js::OpCode::MOVAPD))
  97. {
  98. // MOVAPS has 1 byte shorter encoding
  99. instr->m_opcode = Js::OpCode::MOVAPS;
  100. }
  101. else if (instr->m_opcode == Js::OpCode::MOVSD_ZERO)
  102. {
  103. instr->m_opcode = Js::OpCode::XORPS;
  104. instr->SetSrc1(dst);
  105. instr->SetSrc2(dst);
  106. }
  107. }