OpLayouts.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Copyright (c) 2021 ChakraCore Project Contributors. All rights reserved.
  4. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  5. //-------------------------------------------------------------------------------------------------------
  6. #pragma once
  7. namespace Js {
  8. ///----------------------------------------------------------------------------
  9. ///
  10. /// enum OpCode
  11. ///
  12. /// OpCode defines the set of p-code instructions available for byte-code.
  13. ///
  14. ///----------------------------------------------------------------------------
  15. enum class OpCode : ushort
  16. {
  17. #define DEF_OP(x, y, ...) x,
  18. #include "OpCodeList.h"
  19. MaxByteSizedOpcodes = 255,
  20. #include "ExtendedOpCodeList.h"
  21. ByteCodeLast,
  22. #if ENABLE_NATIVE_CODEGEN
  23. #include "BackendOpCodeList.h"
  24. #endif
  25. #undef DEF_OP
  26. Count // Number of operations
  27. };
  28. inline OpCode operator+(OpCode o1, OpCode o2) { return (OpCode)((uint)o1 + (uint)o2); }
  29. inline uint operator+(OpCode o1, uint i) { return ((uint)o1 + i); }
  30. inline uint operator+(uint i, OpCode &o2) { return (i + (uint)o2); }
  31. inline OpCode operator++(OpCode &o) { return o = (OpCode)(o + 1U); }
  32. inline OpCode operator++(OpCode &o, int) { OpCode prev_o = o; o = (OpCode)(o + 1U); return prev_o; }
  33. inline OpCode operator-(OpCode o1, OpCode o2) { return (OpCode)((uint)o1 - (uint)o2); }
  34. inline uint operator-(OpCode o1, uint i) { return ((uint)o1 - i); }
  35. inline uint operator-(uint i, OpCode &o2) { return (i - (uint)o2); }
  36. inline OpCode operator--(OpCode &o) { return o = (OpCode)(o - 1U); }
  37. inline OpCode operator--(OpCode &o, int) { return o = (OpCode)(o - 1U); }
  38. inline uint operator<<(OpCode o1, uint i) { return ((uint)o1 << i); }
  39. inline OpCode& operator+=(OpCode &o, uint i) { return (o = (OpCode)(o + i)); }
  40. inline OpCode& operator-=(OpCode &o, uint i) { return (o = (OpCode)(o - i)); }
  41. inline bool operator==(OpCode &o, uint i) { return ((uint)(o) == i); }
  42. inline bool operator==(uint i, OpCode &o) { return (i == (uint)(o)); }
  43. inline bool operator!=(OpCode &o, uint i) { return ((uint)(o) != i); }
  44. inline bool operator!=(uint i, OpCode &o) { return (i != (uint)(o)); }
  45. inline bool operator<(OpCode &o, uint i) { return ((uint)(o) < i); }
  46. inline bool operator<(uint i, OpCode &o) { return (i < (uint)(o)); }
  47. inline bool operator>(OpCode &o, uint i) { return ((uint)(o) > i); }
  48. inline bool operator>(uint i, OpCode &o) { return (i > (uint)(o)); }
  49. #if ENABLE_NATIVE_CODEGEN
  50. inline bool IsSimd128Opcode(OpCode o) { return (o > Js::OpCode::Simd128_Start && o < Js::OpCode::Simd128_End) || (o > Js::OpCode::Simd128_Start_Extend && o < Js::OpCode::Simd128_End_Extend); }
  51. inline uint Simd128OpcodeCount() { return (uint)(Js::OpCode::Simd128_End - Js::OpCode::Simd128_Start) + 1 + (uint)(Js::OpCode::Simd128_End_Extend - Js::OpCode::Simd128_Start_Extend) + 1; }
  52. inline bool IsSimd128Load(OpCode o){ return o == Js::OpCode::Simd128_LdArr_I4 || o == Js::OpCode::Simd128_LdArr_F4; }
  53. inline bool IsSimd128Store(OpCode o){ return o == Js::OpCode::Simd128_StArr_I4 || o == Js::OpCode::Simd128_StArr_F4; }
  54. inline bool IsSimd128LoadStore(OpCode o) { return IsSimd128Load(o) || IsSimd128Store(o); }
  55. #endif
  56. ///----------------------------------------------------------------------------
  57. ///
  58. /// enum OpLayoutType
  59. ///
  60. /// OpLayoutType defines a set of layouts available for OpCodes. These layouts
  61. /// correspond to "OpLayout" structs defined below, such as "OpLayoutReg1".
  62. ///
  63. ///----------------------------------------------------------------------------
  64. BEGIN_ENUM_UINT(OpLayoutType)
  65. // This define only one enum for each layout type, but not for each layout variant
  66. #define LAYOUT_TYPE(x) x,
  67. #define LAYOUT_TYPE_WMS LAYOUT_TYPE
  68. #include "LayoutTypes.h"
  69. Count,
  70. END_ENUM_UINT()
  71. ///----------------------------------------------------------------------------
  72. ///
  73. /// struct OpLayoutXYZ
  74. ///
  75. /// OpLayoutXYZ structs define the standard patterns used to layout each
  76. /// OpCode's arguments.
  77. ///
  78. /// Set up packing:
  79. /// - Since we are reading / writing from a byte-stream, and we want everything
  80. /// to be tightly aligned with no unintended spaces, change to 'byte'
  81. /// packing.
  82. /// - On processors with alignment requirements, this will automatically
  83. /// generate read / write code to handle 'unaligned' access.
  84. ///
  85. /// - 3/9/10: Changing the layouts to make all fields well-aligned. This involves
  86. /// reducing the RegSlot from 4 bytes to 2, increasing the OpCode from 1 byte to 2,
  87. /// reordering fields, and adding pads where appropriate. Note that we assume all
  88. /// layouts are preceded by a 2-byte op. The orderings and padding will need to
  89. /// be revisited for Win64.
  90. ///
  91. /// - 5/2: X86-64 alignment: Changing code to expect all opcode layout structs
  92. /// to be aligned on 4 byte boundaries (on I386 and x86-64). This aligns all
  93. /// members on their natural boundaries except for Call and Regex which require
  94. /// padding before the pointers on x86-64.
  95. ///
  96. /// - 09/12: Adding one-byte RegSlot based OpLayout. These remove all the paddings to be
  97. /// able to compress the size. Also remove paddings for non ARM build
  98. ///
  99. /// - 08/22/2011: Removed paddings for ARM & x64 as well as both support unaligned access
  100. /// There is still paddings to make sure every opcode starts at 2 byte boundary to avoid
  101. /// pathological cases.
  102. /// Note: RegSlot is changed to 4 byte instead of 1 byte in this change.
  103. ///
  104. ///----------------------------------------------------------------------------
  105. #pragma pack(push, 1)
  106. template <typename SizePolicy>
  107. struct OpLayoutT_Reg1 // R0 <- op
  108. {
  109. typename SizePolicy::RegSlotType R0;
  110. };
  111. template <typename SizePolicy>
  112. struct OpLayoutT_Reg1Unsigned1 // R0 <- op
  113. {
  114. typename SizePolicy::RegSlotType R0;
  115. typename SizePolicy::UnsignedType C1;
  116. };
  117. template <typename SizePolicy>
  118. struct OpLayoutT_Reg2 // R0 <- op R1
  119. {
  120. typename SizePolicy::RegSlotType R0;
  121. typename SizePolicy::RegSlotType R1;
  122. };
  123. template <typename SizePolicy>
  124. struct OpLayoutT_Reg3 // R0 <- R1 op R2 -- or -- R0 op R1 <- R2
  125. {
  126. typename SizePolicy::RegSlotType R0;
  127. typename SizePolicy::RegSlotType R1;
  128. typename SizePolicy::RegSlotType R2;
  129. };
  130. template <typename SizePolicy>
  131. struct OpLayoutT_Reg3C // R0 <- R1 op R2 with space for FastPath
  132. {
  133. typename SizePolicy::RegSlotType R0;
  134. typename SizePolicy::RegSlotType R1;
  135. typename SizePolicy::RegSlotType R2;
  136. typename SizePolicy::CacheIdType inlineCacheIndex;
  137. };
  138. template <typename SizePolicy>
  139. struct OpLayoutT_Reg2U
  140. {
  141. typename SizePolicy::RegSlotType R0;
  142. typename SizePolicy::RegSlotType R1;
  143. typename SizePolicy::UnsignedType SlotIndex;
  144. };
  145. template <typename SizePolicy>
  146. struct OpLayoutT_Reg2B1
  147. {
  148. typename SizePolicy::RegSlotType R0;
  149. typename SizePolicy::RegSlotType R1;
  150. byte B2;
  151. };
  152. template <typename SizePolicy>
  153. struct OpLayoutT_Reg3B1
  154. {
  155. typename SizePolicy::RegSlotType R0;
  156. typename SizePolicy::RegSlotType R1;
  157. typename SizePolicy::RegSlotType R2;
  158. byte B3;
  159. };
  160. template <typename SizePolicy>
  161. struct OpLayoutT_Reg3U
  162. {
  163. typename SizePolicy::RegSlotType R0;
  164. typename SizePolicy::RegSlotType R1;
  165. typename SizePolicy::RegSlotType R2;
  166. typename SizePolicy::UnsignedType SlotIndex;
  167. };
  168. template <typename SizePolicy>
  169. struct OpLayoutT_Reg4 // R0 <- R1 op R2 op R3
  170. {
  171. typename SizePolicy::RegSlotType R0;
  172. typename SizePolicy::RegSlotType R1;
  173. typename SizePolicy::RegSlotType R2;
  174. typename SizePolicy::RegSlotType R3;
  175. };
  176. template <typename SizePolicy>
  177. struct OpLayoutT_Reg4U
  178. {
  179. typename SizePolicy::RegSlotType R0;
  180. typename SizePolicy::RegSlotType R1;
  181. typename SizePolicy::RegSlotType R2;
  182. typename SizePolicy::RegSlotType R3;
  183. typename SizePolicy::UnsignedType SlotIndex;
  184. };
  185. template <typename SizePolicy>
  186. struct OpLayoutT_Reg5 // R0 <- R1 op R2 op R3 op R4
  187. {
  188. typename SizePolicy::RegSlotType R0;
  189. typename SizePolicy::RegSlotType R1;
  190. typename SizePolicy::RegSlotType R2;
  191. typename SizePolicy::RegSlotType R3;
  192. typename SizePolicy::RegSlotType R4;
  193. };
  194. template <typename SizePolicy>
  195. struct OpLayoutT_Reg5U
  196. {
  197. typename SizePolicy::RegSlotType R0;
  198. typename SizePolicy::RegSlotType R1;
  199. typename SizePolicy::RegSlotType R2;
  200. typename SizePolicy::RegSlotType R3;
  201. typename SizePolicy::RegSlotType R4;
  202. typename SizePolicy::UnsignedType SlotIndex;
  203. };
  204. template <typename SizePolicy>
  205. struct OpLayoutT_ArgNoSrc // OutArg
  206. {
  207. typename SizePolicy::ArgSlotType Arg;
  208. };
  209. template <typename SizePolicy>
  210. struct OpLayoutT_Arg // OutArg <- Reg -- or -- Reg <- InArg
  211. {
  212. typename SizePolicy::ArgSlotType Arg;
  213. typename SizePolicy::RegSlotType Reg;
  214. };
  215. struct OpLayoutBr // goto Offset
  216. {
  217. JumpOffset RelativeJumpOffset;
  218. };
  219. struct OpLayoutBrS // if (op val) goto Offset
  220. {
  221. JumpOffset RelativeJumpOffset;
  222. byte val;
  223. };
  224. template <typename SizePolicy>
  225. struct OpLayoutT_BrReg1 // if (op R1) goto Offset
  226. {
  227. JumpOffset RelativeJumpOffset;
  228. typename SizePolicy::RegSlotType R1;
  229. };
  230. template <typename SizePolicy>
  231. struct OpLayoutT_BrReg1Unsigned1
  232. {
  233. JumpOffset RelativeJumpOffset;
  234. typename SizePolicy::RegSlotType R1;
  235. typename SizePolicy::RegSlotType C2;
  236. };
  237. template <typename SizePolicy>
  238. struct OpLayoutT_BrReg2 // if (R1 op R2) goto Offset
  239. {
  240. JumpOffset RelativeJumpOffset;
  241. typename SizePolicy::RegSlotType R1;
  242. typename SizePolicy::RegSlotType R2;
  243. };
  244. struct OpLayoutBrProperty // if (R1.id) goto Offset
  245. {
  246. JumpOffset RelativeJumpOffset;
  247. RegSlot Instance;
  248. PropertyIdIndexType PropertyIdIndex;
  249. };
  250. struct OpLayoutBrLocalProperty // if (id) goto Offset
  251. {
  252. JumpOffset RelativeJumpOffset;
  253. PropertyIdIndexType PropertyIdIndex;
  254. };
  255. struct OpLayoutBrEnvProperty // if ([1].id) goto Offset
  256. {
  257. JumpOffset RelativeJumpOffset;
  258. PropertyIdIndexType PropertyIdIndex;
  259. int32 SlotIndex;
  260. };
  261. #ifdef BYTECODE_BRANCH_ISLAND
  262. struct OpLayoutBrLong
  263. {
  264. LongJumpOffset RelativeJumpOffset;
  265. };
  266. #endif
  267. struct OpLayoutStartCall
  268. {
  269. ArgSlot ArgCount;
  270. };
  271. enum CallIExtendedOptions : byte
  272. {
  273. CallIExtended_None = 0,
  274. CallIExtended_SpreadArgs = 1 << 0 // This call has arguments that need to be spread
  275. };
  276. template <typename SizePolicy>
  277. struct OpLayoutT_CallI // Return = Function(ArgCount)
  278. {
  279. typename SizePolicy::ArgSlotType ArgCount;
  280. typename SizePolicy::RegSlotSType Return;
  281. typename SizePolicy::RegSlotType Function;
  282. };
  283. template <typename SizePolicy>
  284. struct OpLayoutT_CallIExtended : public OpLayoutT_CallI<SizePolicy>
  285. {
  286. CallIExtendedOptions Options;
  287. uint32 SpreadAuxOffset; // Valid with Options & CallIExtended_SpreadArgs
  288. };
  289. template <typename SizePolicy>
  290. struct OpLayoutT_CallIFlags : public OpLayoutT_CallI<SizePolicy>
  291. {
  292. CallFlags callFlags;
  293. };
  294. template <typename SizePolicy>
  295. struct OpLayoutT_CallIWithICIndex : public OpLayoutT_CallI<SizePolicy>
  296. {
  297. InlineCacheIndex inlineCacheIndex;
  298. };
  299. template <typename SizePolicy>
  300. struct OpLayoutT_CallIFlagsWithICIndex : public OpLayoutT_CallIWithICIndex<SizePolicy>
  301. {
  302. CallFlags callFlags;
  303. };
  304. template <typename SizePolicy>
  305. struct OpLayoutT_CallIExtendedFlags : public OpLayoutT_CallIExtended<SizePolicy>
  306. {
  307. CallFlags callFlags;
  308. };
  309. template <typename SizePolicy>
  310. struct OpLayoutT_CallIExtendedWithICIndex : public OpLayoutT_CallIExtended<SizePolicy>
  311. {
  312. InlineCacheIndex inlineCacheIndex;
  313. };
  314. template <typename SizePolicy>
  315. struct OpLayoutT_CallIExtendedFlagsWithICIndex : public OpLayoutT_CallIExtendedWithICIndex<SizePolicy>
  316. {
  317. CallFlags callFlags;
  318. };
  319. template <typename SizePolicy>
  320. struct OpLayoutT_ElementU // Instance.PropertyIndex = <some constant value>. e.g. undefined
  321. {
  322. typename SizePolicy::RegSlotType Instance;
  323. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  324. };
  325. template <typename SizePolicy>
  326. struct OpLayoutT_ElementScopedU // [env].PropertyIndex = <some constant value>. e.g. undefined
  327. {
  328. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  329. };
  330. template <typename SizePolicy>
  331. struct OpLayoutT_ElementRootU // Root.PropertyIndex = <some constant value>. e.g. undefined
  332. {
  333. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  334. };
  335. template <typename SizePolicy>
  336. struct OpLayoutT_ElementC // Value = Instance.PropertyIndex or Instance.PropertyIndex = Value
  337. {
  338. typename SizePolicy::RegSlotType Value;
  339. typename SizePolicy::RegSlotType Instance;
  340. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  341. };
  342. template <typename SizePolicy>
  343. struct OpLayoutT_ElementScopedC // Value = [env].PropertyIndex or [env].PropertyIndex = Value
  344. {
  345. typename SizePolicy::RegSlotType Value;
  346. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  347. };
  348. template <typename SizePolicy>
  349. struct OpLayoutT_ElementSlot // Value = Instance[SlotIndex] or Instance[SlotIndex] = Value
  350. {
  351. typename SizePolicy::UnsignedType SlotIndex;
  352. typename SizePolicy::RegSlotType Value;
  353. typename SizePolicy::RegSlotType Instance;
  354. };
  355. template <typename SizePolicy>
  356. struct OpLayoutT_ElementSlotI1
  357. {
  358. typename SizePolicy::UnsignedType SlotIndex;
  359. typename SizePolicy::RegSlotType Value;
  360. };
  361. template <typename SizePolicy>
  362. struct OpLayoutT_ElementSlotI2
  363. {
  364. typename SizePolicy::UnsignedType SlotIndex1;
  365. typename SizePolicy::UnsignedType SlotIndex2;
  366. typename SizePolicy::RegSlotType Value;
  367. };
  368. template <typename SizePolicy>
  369. struct OpLayoutT_ElementSlotI3
  370. {
  371. typename SizePolicy::UnsignedType SlotIndex;
  372. typename SizePolicy::RegSlotType Value;
  373. typename SizePolicy::RegSlotType Instance;
  374. typename SizePolicy::RegSlotType HomeObj;
  375. };
  376. template <typename SizePolicy>
  377. struct OpLayoutT_ElementCP // As OpLayoutElementC, with space for a FastPath LoadPatch
  378. {
  379. typename SizePolicy::RegSlotType Value;
  380. typename SizePolicy::RegSlotType Instance;
  381. typename SizePolicy::CacheIdType inlineCacheIndex;
  382. };
  383. template <typename SizePolicy>
  384. struct OpLayoutT_ElementP // As OpLayoutElementCP, but with no base pointer
  385. {
  386. typename SizePolicy::RegSlotType Value;
  387. typename SizePolicy::CacheIdType inlineCacheIndex;
  388. };
  389. template <typename SizePolicy>
  390. struct OpLayoutT_ElementPIndexed // As OpLayoutElementCP, but with scope index instead of base pointer
  391. {
  392. typename SizePolicy::RegSlotType Value;
  393. typename SizePolicy::CacheIdType inlineCacheIndex;
  394. typename SizePolicy::UnsignedType scopeIndex;
  395. };
  396. template <typename SizePolicy>
  397. struct OpLayoutT_ElementRootCP // Same as ElementCP, but for root object
  398. {
  399. RootCacheId inlineCacheIndex;
  400. typename SizePolicy::RegSlotType Value;
  401. };
  402. template <typename SizePolicy>
  403. struct OpLayoutT_ElementScopedC2 // [implied base].PropertyIndex = Value, Instance2
  404. {
  405. typename SizePolicy::RegSlotType Value;
  406. typename SizePolicy::RegSlotType Value2;
  407. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  408. };
  409. template <typename SizePolicy>
  410. struct OpLayoutT_ElementC2 // Instance.PropertyIndex = Value, Instance2
  411. {
  412. typename SizePolicy::RegSlotType Value;
  413. typename SizePolicy::RegSlotType Instance;
  414. typename SizePolicy::RegSlotType Value2;
  415. typename SizePolicy::PropertyIdIndexType PropertyIdIndex;
  416. };
  417. template <typename SizePolicy>
  418. struct OpLayoutT_ElementI // Value = Instance[Element] or Instance[Element] = Value
  419. {
  420. typename SizePolicy::RegSlotType Value;
  421. typename SizePolicy::RegSlotType Instance;
  422. typename SizePolicy::RegSlotType Element;
  423. };
  424. template <typename SizePolicy>
  425. struct OpLayoutT_ElementUnsigned1 // Value = Instance[Element] or Instance[Element] = Value
  426. {
  427. typename SizePolicy::UnsignedType Element;
  428. typename SizePolicy::RegSlotType Value;
  429. typename SizePolicy::RegSlotType Instance;
  430. };
  431. struct OpLayoutW1
  432. {
  433. unsigned short C1;
  434. };
  435. template <typename SizePolicy>
  436. struct OpLayoutT_Reg2Int1 // R0 <- func(R1, C1)
  437. {
  438. int32 C1;
  439. typename SizePolicy::RegSlotType R0;
  440. typename SizePolicy::RegSlotType R1;
  441. };
  442. struct OpLayoutAuxNoReg
  443. {
  444. uint32 Offset;
  445. int32 C1;
  446. };
  447. struct OpLayoutAuxiliary : public OpLayoutAuxNoReg // R0 <- Load(Offset, C1)
  448. {
  449. RegSlot R0;
  450. };
  451. struct OpLayoutReg2Aux : public OpLayoutAuxiliary // R0 <- Load(Offset, R1, C1)
  452. {
  453. RegSlot R1;
  454. };
  455. template <typename SizePolicy>
  456. struct OpLayoutT_Unsigned1
  457. {
  458. typename SizePolicy::UnsignedType C1;
  459. };
  460. // Dynamic profile layout wrapper
  461. template <typename LayoutType>
  462. struct OpLayoutDynamicProfile : public LayoutType
  463. {
  464. ProfileId profileId;
  465. };
  466. template <typename LayoutType>
  467. struct OpLayoutDynamicProfile2 : public LayoutType
  468. {
  469. ProfileId profileId;
  470. ProfileId profileId2;
  471. };
  472. // Generate the multi size layout type defs
  473. #define LAYOUT_TYPE_WMS(layout) \
  474. typedef OpLayoutT_##layout<LargeLayoutSizePolicy> OpLayout##layout##_Large; \
  475. typedef OpLayoutT_##layout<MediumLayoutSizePolicy> OpLayout##layout##_Medium; \
  476. typedef OpLayoutT_##layout<SmallLayoutSizePolicy> OpLayout##layout##_Small;
  477. // Generate the profiled type defs
  478. #define LAYOUT_TYPE_PROFILED(layout) \
  479. typedef OpLayoutDynamicProfile<OpLayout##layout> OpLayoutProfiled##layout;
  480. #define LAYOUT_TYPE_PROFILED2(layout) \
  481. typedef OpLayoutDynamicProfile2<OpLayout##layout> OpLayoutProfiled2##layout;
  482. #define LAYOUT_TYPE_PROFILED_WMS(layout) \
  483. LAYOUT_TYPE_WMS(layout) \
  484. LAYOUT_TYPE_PROFILED(layout##_Large) \
  485. LAYOUT_TYPE_PROFILED(layout##_Medium) \
  486. LAYOUT_TYPE_PROFILED(layout##_Small)
  487. #define LAYOUT_TYPE_PROFILED2_WMS(layout) \
  488. LAYOUT_TYPE_PROFILED_WMS(layout) \
  489. LAYOUT_TYPE_PROFILED2(layout##_Large) \
  490. LAYOUT_TYPE_PROFILED2(layout##_Medium) \
  491. LAYOUT_TYPE_PROFILED2(layout##_Small)
  492. #include "LayoutTypes.h"
  493. #pragma pack(pop)
  494. // Generate structure to automatically map layout to its info
  495. template <OpLayoutType::_E layout> struct OpLayoutInfo;
  496. #define LAYOUT_TYPE(layout) \
  497. CompileAssert(sizeof(OpLayout##layout) <= MaxLayoutSize); \
  498. template <> struct OpLayoutInfo<OpLayoutType::layout> \
  499. { \
  500. static const bool HasMultiSizeLayout = false; \
  501. };
  502. #define LAYOUT_TYPE_WMS(layout) \
  503. CompileAssert(sizeof(OpLayout##layout##_Large) <= MaxLayoutSize); \
  504. template <> struct OpLayoutInfo<OpLayoutType::layout> \
  505. { \
  506. static const bool HasMultiSizeLayout = true; \
  507. };
  508. #include "LayoutTypes.h"
  509. // Generate structure to automatically map opcode to its info
  510. // Also generate assert to make sure the layout and opcode use the same macro with and without multiple size layout
  511. template <OpCode opcode> struct OpCodeInfo;
  512. #define DEFINE_OPCODEINFO(op, layout, extended) \
  513. CompileAssert(!OpLayoutInfo<OpLayoutType::layout>::HasMultiSizeLayout); \
  514. template <> struct OpCodeInfo<OpCode::op> \
  515. { \
  516. static const OpLayoutType::_E Layout = OpLayoutType::layout; \
  517. static const bool HasMultiSizeLayout = false; \
  518. static const bool IsExtendedOpcode = extended; \
  519. typedef OpLayout##layout LayoutType; \
  520. };
  521. #define DEFINE_OPCODEINFO_WMS(op, layout, extended) \
  522. CompileAssert(OpLayoutInfo<OpLayoutType::layout>::HasMultiSizeLayout); \
  523. template <> struct OpCodeInfo<OpCode::op> \
  524. { \
  525. static const OpLayoutType::_E Layout = OpLayoutType::layout; \
  526. static const bool HasMultiSizeLayout = true; \
  527. static const bool IsExtendedOpcode = extended; \
  528. typedef OpLayout##layout##_Large LayoutType_Large; \
  529. typedef OpLayout##layout##_Medium LayoutType_Medium; \
  530. typedef OpLayout##layout##_Small LayoutType_Small; \
  531. };
  532. #define MACRO(op, layout, ...) DEFINE_OPCODEINFO(op, layout, false)
  533. #define MACRO_WMS(op, layout, ...) DEFINE_OPCODEINFO_WMS(op, layout, false)
  534. #define MACRO_EXTEND(op, layout, ...) DEFINE_OPCODEINFO(op, layout, true)
  535. #define MACRO_EXTEND_WMS(op, layout, ...) DEFINE_OPCODEINFO_WMS(op, layout, true)
  536. #include "OpCodes.h"
  537. #undef DEFINE_OPCODEINFO
  538. #undef DEFINE_OPCODEINFO_WMS
  539. } // namespace Js