2
0

LowererMDArch.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. #pragma once
  6. class LowererMD;
  7. ///---------------------------------------------------------------------------
  8. ///
  9. /// class LowererMD
  10. ///
  11. ///---------------------------------------------------------------------------
  12. class LowererMDArch
  13. {
  14. friend LowererMD;
  15. public:
  16. static const int MaxArgumentsToHelper = 16;
  17. private:
  18. Func * m_func;
  19. LowererMD * lowererMD;
  20. //
  21. // Support to load helper arguments.
  22. //
  23. int helperCallArgsCount;
  24. IR::Opnd * helperCallArgs[MaxArgumentsToHelper];
  25. public:
  26. LowererMDArch(Func* function):
  27. m_func(function)
  28. { }
  29. void Init(LowererMD * lowererMD);
  30. void FinalLower();
  31. void FlipHelperCallArgsOrder()
  32. {
  33. int left = 0;
  34. int right = helperCallArgsCount - 1;
  35. while (left < right)
  36. {
  37. IR::Opnd *tempOpnd = helperCallArgs[left];
  38. helperCallArgs[left] = helperCallArgs[right];
  39. helperCallArgs[right] = tempOpnd;
  40. left++;
  41. right--;
  42. }
  43. }
  44. static bool IsLegalMemLoc(IR::MemRefOpnd *opnd)
  45. {
  46. return Math::FitsInDWord((size_t)opnd->GetMemLoc());
  47. }
  48. IR::Opnd * GetArgSlotOpnd(Js::ArgSlot slotIndex, StackSym * argSym = nullptr);
  49. IR::Instr * LoadNewScObjFirstArg(IR::Instr * instr, IR::Opnd * dst, ushort extraArgs = 0);
  50. IR::Instr * LoadInputParamPtr(IR::Instr *instrInsert, IR::RegOpnd *optionalDstOpnd = nullptr);
  51. int32 LowerCallArgs(IR::Instr *callInstr, ushort callFlags, Js::ArgSlot extraParams = 1 /* for function object */, IR::IntConstOpnd **callInfoOpndRef = nullptr);
  52. IR::Instr * LowerCall(IR::Instr * callInstr, uint32 argCount);
  53. IR::Instr * LowerCallI(IR::Instr * callInstr, ushort callFlags, bool isHelper = false, IR::Instr * insertBeforeInstrForCFG = nullptr);
  54. IR::Instr * LowerCallIDynamic(IR::Instr * callInstr, IR::Instr* saveThis, IR::Opnd* argsLengthOpnd, ushort callFlags, IR::Instr * insertBeforeInstrForCFG = nullptr);
  55. IR::Instr * LowerCallPut(IR::Instr * callInstr);
  56. IR::Instr * LowerStartCall(IR::Instr * instr);
  57. IR::Instr * LowerAsmJsCallI(IR::Instr * callInstr);
  58. IR::Instr * LowerAsmJsCallE(IR::Instr * callInstr);
  59. IR::Instr * LowerAsmJsLdElemHelper(IR::Instr * instr, bool isSimdLoad = false, bool checkEndOffset = false);
  60. IR::Instr * LowerAsmJsStElemHelper(IR::Instr * instr, bool isSimdStore = false, bool checkEndOffset = false);
  61. IR::Instr * LoadHelperArgument(IR::Instr * instr, IR::Opnd * opndArg);
  62. IR::Instr * LoadDynamicArgument(IR::Instr * instr, uint argNumber);
  63. IR::Instr * LoadDynamicArgumentUsingLength(IR::Instr *instr);
  64. IR::Instr * LoadDoubleHelperArgument(IR::Instr * instr, IR::Opnd * opndArg);
  65. IR::Instr * LoadFloatHelperArgument(IR::Instr * instr, IR::Opnd * opndArg);
  66. IR::Instr * LoadStackArgPtr(IR::Instr * instr);
  67. IR::Instr * LoadHeapArguments(IR::Instr * instr, bool force = false, IR::Opnd* opndInputParamCount = nullptr);
  68. IR::Instr * LoadHeapArgsCached(IR::Instr * instr);
  69. IR::Instr * LoadFuncExpression(IR::Instr * instr);
  70. IR::Instr * LowerEntryInstr(IR::EntryInstr * entryInstr);
  71. void GeneratePrologueStackProbe(IR::Instr *entryInstr, IntConstType frameSize);
  72. IR::Instr * LowerExitInstr(IR::ExitInstr * exitInstr);
  73. IR::Instr * LowerEntryInstrAsmJs(IR::EntryInstr * entryInstr);
  74. IR::Instr * LowerExitInstrAsmJs(IR::ExitInstr * exitInstr);
  75. static void EmitInt4Instr(IR::Instr *instr, bool signExtend = false);
  76. static void EmitPtrInstr(IR::Instr *instr);
  77. void EmitLoadVar(IR::Instr *instrLoad, bool isFromUint32 = false, bool isHelper = false);
  78. void EmitIntToFloat(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
  79. void EmitUIntToFloat(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsert);
  80. bool EmitLoadInt32(IR::Instr *instrLoad, bool conversionFromObjectAllowed);
  81. IR::Instr * LoadCheckedFloat(IR::RegOpnd *opndOrig, IR::RegOpnd *opndFloat, IR::LabelInstr *labelInline, IR::LabelInstr *labelHelper, IR::Instr *instrInsert, const bool checkForNullInLoopBody = false);
  82. static BYTE GetDefaultIndirScale();
  83. static RegNum GetRegShiftCount();
  84. static RegNum GetRegReturn(IRType type);
  85. static RegNum GetRegReturnAsmJs(IRType type);
  86. static RegNum GetRegStackPointer();
  87. static RegNum GetRegBlockPointer();
  88. static RegNum GetRegFramePointer();
  89. static RegNum GetRegChkStkParam();
  90. static RegNum GetRegIMulDestLower();
  91. static RegNum GetRegIMulHighDestLower();
  92. static RegNum GetRegArgI4(int32 argNum);
  93. static RegNum GetRegArgR8(int32 argNum);
  94. static Js::OpCode GetAssignOp(IRType type);
  95. bool GenerateFastAnd(IR::Instr * instrAnd);
  96. bool GenerateFastXor(IR::Instr * instrXor);
  97. bool GenerateFastOr(IR::Instr * instrOr);
  98. bool GenerateFastNot(IR::Instr * instrNot);
  99. bool GenerateFastShiftLeft(IR::Instr * instrShift);
  100. bool GenerateFastShiftRight(IR::Instr * instrShift);
  101. IR::Opnd* GenerateArgOutForStackArgs(IR::Instr* callInstr, IR::Instr* stackArgsInstr);
  102. void GenerateFunctionObjectTest(IR::Instr * callInstr, IR::RegOpnd *functionObjOpnd, bool isHelper, IR::LabelInstr* afterCallLabel = nullptr);
  103. int GetHelperArgsCount() { return this->helperCallArgsCount; }
  104. void ResetHelperArgsCount() { this->helperCallArgsCount = 0; }
  105. void LowerInlineSpreadArgOutLoop(IR::Instr *callInstr, IR::RegOpnd *indexOpnd, IR::RegOpnd *arrayElementsStartOpnd);
  106. IR::Instr * LowerEHRegionReturn(IR::Instr * insertBeforeInstr, IR::Opnd * targetOpnd);
  107. private:
  108. void MovArgFromReg2Stack(IR::Instr * instr, RegNum reg, Js::ArgSlot slotNumber, IRType type = TyMachReg);
  109. void GenerateStackAllocation(IR::Instr *instr, uint32 size);
  110. IR::LabelInstr * GetBailOutStackRestoreLabel(BailOutInfo * bailOutInfo, IR::LabelInstr * exitTargetInstr);
  111. void GeneratePreCall(IR::Instr * callInstr, IR::Opnd *functionObjOpnd, IR::Instr* insertBeforeInstrForCFGCheck = nullptr);
  112. void SetMaxArgSlots(Js::ArgSlot actualCount /*including this*/);
  113. };