OpLayouts.h 20 KB

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