IRBuilderAsmJs.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. namespace AsmJsRegSlots
  7. {
  8. enum ConstSlots
  9. {
  10. ReturnReg = 0,
  11. ModuleMemReg,
  12. ArrayReg,
  13. BufferReg,
  14. LengthReg,
  15. RegCount
  16. };
  17. };
  18. class IRBuilderAsmJs
  19. {
  20. friend struct IRBuilderAsmJsSwitchAdapter;
  21. public:
  22. IRBuilderAsmJs(Func * func)
  23. : m_func(func)
  24. , m_IsTJLoopBody(false)
  25. , m_switchAdapter(this)
  26. , m_switchBuilder(&m_switchAdapter)
  27. {
  28. func->m_workItem->InitializeReader(m_jnReader, m_statementReader);
  29. m_asmFuncInfo = m_func->GetJnFunction()->GetAsmJsFunctionInfo();
  30. if (func->IsLoopBody())
  31. {
  32. Js::LoopEntryPointInfo* loopEntryPointInfo = (Js::LoopEntryPointInfo*)(func->m_workItem->GetEntryPoint());
  33. if (loopEntryPointInfo->GetIsTJMode())
  34. {
  35. m_IsTJLoopBody = true;
  36. func->isTJLoopBody = true;
  37. }
  38. }
  39. }
  40. void Build();
  41. private:
  42. void AddInstr(IR::Instr * instr, uint32 offset);
  43. bool IsLoopBody()const;
  44. uint GetLoopBodyExitInstrOffset() const;
  45. IR::SymOpnd * BuildLoopBodySlotOpnd(SymID symId);
  46. IR::SymOpnd * BuildAsmJsLoopBodySlotOpnd(SymID symId, IRType opndType);
  47. void EnsureLoopBodyLoadSlot(SymID symId);
  48. void EnsureLoopBodyAsmJsLoadSlot(SymID symId, IRType type);
  49. bool IsLoopBodyOuterOffset(uint offset) const;
  50. bool IsLoopBodyReturnIPInstr(IR::Instr * instr) const;
  51. IR::Opnd * InsertLoopBodyReturnIPInstr(uint targetOffset, uint offset);
  52. IR::Instr * CreateLoopBodyReturnIPInstr(uint targetOffset, uint offset);
  53. IR::RegOpnd * BuildDstOpnd(Js::RegSlot dstRegSlot, IRType type);
  54. IR::RegOpnd * BuildSrcOpnd(Js::RegSlot srcRegSlot, IRType type);
  55. IR::RegOpnd * BuildIntConstOpnd(Js::RegSlot regSlot);
  56. SymID BuildSrcStackSymID(Js::RegSlot regSlot, IRType type = IRType::TyVar);
  57. IR::SymOpnd * BuildFieldOpnd(Js::RegSlot reg, Js::PropertyId propertyId, PropertyKind propertyKind, IRType type, bool scale = true);
  58. PropertySym * BuildFieldSym(Js::RegSlot reg, Js::PropertyId propertyId, PropertyKind propertyKind);
  59. uint AddStatementBoundary(uint statementIndex, uint offset);
  60. BranchReloc * AddBranchInstr(IR::BranchInstr *instr, uint32 offset, uint32 targetOffset);
  61. BranchReloc * CreateRelocRecord(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset);
  62. void BuildHeapBufferReload(uint32 offset);
  63. void BuildConstantLoads();
  64. void BuildImplicitArgIns();
  65. void InsertLabels();
  66. IR::LabelInstr * CreateLabel(IR::BranchInstr * branchInstr, uint& offset);
  67. #if DBG
  68. BVFixed * m_usedAsTemp;
  69. #endif
  70. Js::RegSlot GetRegSlotFromIntReg(Js::RegSlot srcIntReg);
  71. Js::RegSlot GetRegSlotFromFloatReg(Js::RegSlot srcFloatReg);
  72. Js::RegSlot GetRegSlotFromDoubleReg(Js::RegSlot srcDoubleReg);
  73. Js::RegSlot GetRegSlotFromVarReg(Js::RegSlot srcVarReg);
  74. Js::OpCode GetSimdOpcode(Js::OpCodeAsmJs asmjsOpcode);
  75. Js::RegSlot GetRegSlotFromSimd128Reg(Js::RegSlot srcSimd128Reg);
  76. IR::Instr * AddExtendedArg(IR::RegOpnd *src1, IR::RegOpnd *src2, uint32 offset);
  77. BOOL RegIsSimd128Var(Js::RegSlot reg);
  78. SymID GetMappedTemp(Js::RegSlot reg);
  79. void SetMappedTemp(Js::RegSlot reg, SymID tempId);
  80. BOOL GetTempUsed(Js::RegSlot reg);
  81. void SetTempUsed(Js::RegSlot reg, BOOL used);
  82. BOOL RegIsTemp(Js::RegSlot reg);
  83. BOOL RegIsConstant(Js::RegSlot reg);
  84. BOOL RegIsVar(Js::RegSlot reg);
  85. BOOL RegIsIntVar(Js::RegSlot reg);
  86. BOOL RegIsFloatVar(Js::RegSlot reg);
  87. BOOL RegIsDoubleVar(Js::RegSlot reg);
  88. #define LAYOUT_TYPE(layout) \
  89. void Build##layout(Js::OpCodeAsmJs newOpcode, uint32 offset);
  90. #define LAYOUT_TYPE_WMS(layout) \
  91. template <typename SizePolicy> void Build##layout(Js::OpCodeAsmJs newOpcode, uint32 offset);
  92. #define EXCLUDE_FRONTEND_LAYOUT
  93. #include "ByteCode\LayoutTypesAsmJs.h"
  94. void BuildElementSlot(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 slotIndex, Js::RegSlot value, Js::RegSlot instance);
  95. void BuildAsmUnsigned1(Js::OpCodeAsmJs newOpcode, uint value);
  96. void BuildAsmTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, int8 viewType);
  97. void BuildAsmSimdTypedArr(Js::OpCodeAsmJs newOpcode, uint32 offset, uint32 slotIndex, Js::RegSlot value, int8 viewType, uint8 DataWidth);
  98. void BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSlot argCount, Js::RegSlot ret, Js::RegSlot function, int8 returnType);
  99. void BuildAsmReg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg);
  100. void BuildInt1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstIntReg, Js::RegSlot srcDoubleReg);
  101. void BuildInt1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstIntReg, Js::RegSlot srcFloatReg);
  102. void BuildDouble1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstDoubleReg, Js::RegSlot srcIntReg);
  103. void BuildDouble1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstDoubleReg, Js::RegSlot srcFloatReg);
  104. void BuildFloat1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstFloatReg, Js::RegSlot srcVarReg);
  105. void BuildDouble1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstDoubleReg, Js::RegSlot srcVarReg);
  106. void BuildInt1Reg1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstIntReg, Js::RegSlot srcVarReg);
  107. void BuildReg1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcDoubleReg);
  108. void BuildReg1Float1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcFloatReg);
  109. void BuildReg1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstReg, Js::RegSlot srcIntReg);
  110. void BuildInt1Const1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dstInt, int constInt);
  111. void BuildInt1Double2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src1, Js::RegSlot src2);
  112. void BuildInt1Float2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src1, Js::RegSlot src2);
  113. void BuildInt2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src);
  114. void BuildInt3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src1, Js::RegSlot src2);
  115. void BuildDouble2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src);
  116. void BuildFloat2(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src);
  117. void BuildFloat3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src1, Js::RegSlot src2);
  118. void BuildFloat1Double1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src);
  119. void BuildFloat1Int1(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src);
  120. void BuildDouble3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot dst, Js::RegSlot src1, Js::RegSlot src2);
  121. void BuildBrInt1(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, Js::RegSlot src);
  122. void BuildBrInt2(Js::OpCodeAsmJs newOpcode, uint32 offset, int32 relativeOffset, Js::RegSlot src1, Js::RegSlot src2);
  123. void GenerateLoopBodySlotAccesses(uint offset);
  124. void GenerateLoopBodyStSlots(SymID loopParamSymId, uint offset);
  125. IR::Instr* GenerateStSlotForReturn(IR::RegOpnd* srcOpnd, IRType type);
  126. JitArenaAllocator * m_tempAlloc;
  127. JitArenaAllocator * m_funcAlloc;
  128. Func * m_func;
  129. IR::Instr * m_lastInstr;
  130. IR::Instr ** m_offsetToInstruction;
  131. Js::ByteCodeReader m_jnReader;
  132. Js::StatementReader m_statementReader;
  133. SList<IR::Instr *> * m_argStack;
  134. SList<IR::Instr *> * m_tempList;
  135. SList<int32> * m_argOffsetStack;
  136. SList<BranchReloc *> * m_branchRelocList;
  137. Js::RegSlot m_firstIntConst;
  138. Js::RegSlot m_firstFloatConst;
  139. Js::RegSlot m_firstDoubleConst;
  140. Js::RegSlot m_firstVarConst;
  141. Js::RegSlot m_firstIntVar;
  142. Js::RegSlot m_firstFloatVar;
  143. Js::RegSlot m_firstDoubleVar;
  144. Js::RegSlot m_firstIntTemp;
  145. Js::RegSlot m_firstFloatTemp;
  146. Js::RegSlot m_firstDoubleTemp;
  147. Js::RegSlot m_firstIRTemp;
  148. Js::RegSlot m_firstSimdConst;
  149. Js::RegSlot m_firstSimdVar;
  150. Js::RegSlot m_firstSimdTemp;
  151. Js::OpCode * m_simdOpcodesMap;
  152. SymID * m_tempMap;
  153. BVFixed * m_fbvTempUsed;
  154. uint32 m_functionStartOffset;
  155. Js::AsmJsFunctionInfo * m_asmFuncInfo;
  156. StackSym * m_loopBodyRetIPSym;
  157. BVFixed * m_ldSlots;
  158. BVFixed * m_stSlots;
  159. BOOL m_IsTJLoopBody;
  160. IRBuilderAsmJsSwitchAdapter m_switchAdapter;
  161. SwitchIRBuilder m_switchBuilder;
  162. IR::RegOpnd * m_funcOpnd;
  163. #if DBG
  164. uint32 m_offsetToInstructionCount;
  165. #endif
  166. };