OpLayouts.h 21 KB

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