2
0

Opnd.inl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  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 IR {
  7. ///----------------------------------------------------------------------------
  8. ///
  9. /// Opnd::Use
  10. ///
  11. /// If this operand is not inUse, use it. Otherwise, make a copy.
  12. ///
  13. ///----------------------------------------------------------------------------
  14. inline Opnd *
  15. Opnd::Use(Func *func)
  16. {
  17. AssertMsg(!isDeleted, "Using deleted operand");
  18. if (!m_inUse)
  19. {
  20. m_inUse = true;
  21. return this;
  22. }
  23. Opnd * newOpnd = this->Copy(func);
  24. newOpnd->m_inUse = true;
  25. return newOpnd;
  26. }
  27. ///----------------------------------------------------------------------------
  28. ///
  29. /// Opnd::UnUse
  30. ///
  31. ///----------------------------------------------------------------------------
  32. inline void
  33. Opnd::UnUse()
  34. {
  35. AssertMsg(m_inUse, "Expected inUse to be set...");
  36. m_inUse = false;
  37. }
  38. ///----------------------------------------------------------------------------
  39. ///
  40. /// Opnd::IsSymOpnd
  41. ///
  42. ///----------------------------------------------------------------------------
  43. inline bool
  44. Opnd::IsSymOpnd() const
  45. {
  46. return GetKind() == OpndKindSym;
  47. }
  48. ///----------------------------------------------------------------------------
  49. ///
  50. /// Opnd::AsSymOpnd
  51. ///
  52. /// Use this opnd as a SymOpnd.
  53. ///
  54. ///----------------------------------------------------------------------------
  55. inline SymOpnd *
  56. Opnd::AsSymOpnd()
  57. {
  58. AssertMsg(this->IsSymOpnd(), "Bad call to AsSymOpnd()");
  59. return reinterpret_cast<SymOpnd *>(this);
  60. }
  61. inline const SymOpnd *
  62. Opnd::AsSymOpnd() const
  63. {
  64. AssertMsg(this->IsSymOpnd(), "Bad call to AsSymOpnd() const");
  65. return reinterpret_cast<const SymOpnd*>(this);
  66. }
  67. inline PropertySymOpnd *
  68. Opnd::AsPropertySymOpnd()
  69. {
  70. AssertMsg(this->IsSymOpnd() && this->AsSymOpnd()->IsPropertySymOpnd(), "Bad call to AsPropertySymOpnd()");
  71. return reinterpret_cast<PropertySymOpnd *>(this);
  72. }
  73. inline const PropertySymOpnd *
  74. Opnd::AsPropertySymOpnd() const
  75. {
  76. AssertMsg(this->IsSymOpnd() && this->AsSymOpnd()->IsPropertySymOpnd(), "Bad call to AsPropertySymOpnd() const");
  77. return reinterpret_cast<const PropertySymOpnd *>(this);
  78. }
  79. ///----------------------------------------------------------------------------
  80. ///
  81. /// Opnd::IsRegOpnd
  82. ///
  83. ///----------------------------------------------------------------------------
  84. inline bool
  85. Opnd::IsRegOpnd() const
  86. {
  87. return GetKind() == OpndKindReg;
  88. }
  89. ///----------------------------------------------------------------------------
  90. ///
  91. /// Opnd::AsRegOpnd
  92. ///
  93. /// Use this opnd as a RegOpnd.
  94. ///
  95. ///----------------------------------------------------------------------------
  96. inline RegOpnd *
  97. Opnd::AsRegOpnd()
  98. {
  99. AssertMsg(this->IsRegOpnd(), "Bad call to AsRegOpnd()");
  100. return reinterpret_cast<RegOpnd *>(this);
  101. }
  102. inline const RegOpnd *
  103. Opnd::AsRegOpnd() const
  104. {
  105. AssertMsg(this->IsRegOpnd(), "Bad call to AsRegOpnd() const");
  106. return reinterpret_cast<const RegOpnd *>(this);
  107. }
  108. ///----------------------------------------------------------------------------
  109. ///
  110. /// Opnd::IsRegBVOpnd
  111. ///
  112. ///----------------------------------------------------------------------------
  113. inline bool
  114. Opnd::IsRegBVOpnd() const
  115. {
  116. return GetKind() == OpndKindRegBV;
  117. }
  118. ///----------------------------------------------------------------------------
  119. ///
  120. /// Opnd::AsRegBVOpnd
  121. ///
  122. /// Use this opnd as a RegBVOpnd.
  123. ///
  124. ///----------------------------------------------------------------------------
  125. inline RegBVOpnd *
  126. Opnd::AsRegBVOpnd()
  127. {
  128. AssertMsg(this->IsRegBVOpnd(), "Bad call to AsRegBVOpnd()");
  129. return reinterpret_cast<RegBVOpnd *>(this);
  130. }
  131. inline const RegBVOpnd *
  132. Opnd::AsRegBVOpnd() const
  133. {
  134. AssertMsg(this->IsRegBVOpnd(), "Bad call to AsRegBVOpnd() const");
  135. return reinterpret_cast<const RegBVOpnd *>(this);
  136. }
  137. ///----------------------------------------------------------------------------
  138. ///
  139. /// Opnd::IsIntConstOpnd
  140. ///
  141. ///----------------------------------------------------------------------------
  142. inline bool
  143. Opnd::IsIntConstOpnd() const
  144. {
  145. return GetKind() == OpndKindIntConst;
  146. }
  147. ///----------------------------------------------------------------------------
  148. ///
  149. /// Opnd::AsIntConstOpnd
  150. ///
  151. /// Use this opnd as an IntConstOpnd.
  152. ///
  153. ///----------------------------------------------------------------------------
  154. inline IntConstOpnd *
  155. Opnd::AsIntConstOpnd()
  156. {
  157. AssertMsg(this->IsIntConstOpnd(), "Bad call to AsIntConstOpnd()");
  158. return reinterpret_cast<IntConstOpnd *>(this);
  159. }
  160. inline const IntConstOpnd *
  161. Opnd::AsIntConstOpnd() const
  162. {
  163. AssertMsg(this->IsIntConstOpnd(), "Bad call to AsIntConstOpnd() const");
  164. return reinterpret_cast<const IntConstOpnd *>(this);
  165. }
  166. ///----------------------------------------------------------------------------
  167. ///
  168. /// Opnd::IsInt64ConstOpnd
  169. ///
  170. ///----------------------------------------------------------------------------
  171. inline bool
  172. Opnd::IsInt64ConstOpnd() const
  173. {
  174. return GetKind() == OpndKindInt64Const;
  175. }
  176. ///----------------------------------------------------------------------------
  177. ///
  178. /// Opnd::AsInt64ConstOpnd
  179. ///
  180. /// Use this opnd as an Int64ConstOpnd.
  181. ///
  182. ///----------------------------------------------------------------------------
  183. inline Int64ConstOpnd *
  184. Opnd::AsInt64ConstOpnd()
  185. {
  186. AssertMsg(this->IsInt64ConstOpnd(), "Bad call to AsInt64ConstOpnd()");
  187. return reinterpret_cast<Int64ConstOpnd *>(this);
  188. }
  189. inline const Int64ConstOpnd *
  190. Opnd::AsInt64ConstOpnd() const
  191. {
  192. AssertMsg(this->IsInt64ConstOpnd(), "Bad call to AsInt64ConstOpnd() const");
  193. return reinterpret_cast<const Int64ConstOpnd *>(this);
  194. }
  195. ///----------------------------------------------------------------------------
  196. ///
  197. /// Opnd::IsFloatConstOpnd
  198. ///
  199. ///----------------------------------------------------------------------------
  200. inline bool
  201. Opnd::IsFloatConstOpnd() const
  202. {
  203. return GetKind() == OpndKindFloatConst;
  204. }
  205. ///----------------------------------------------------------------------------
  206. ///
  207. /// Opnd::AsFloatConstOpnd
  208. ///
  209. /// Use this opnd as a FloatConstOpnd.
  210. ///
  211. ///----------------------------------------------------------------------------
  212. inline FloatConstOpnd *
  213. Opnd::AsFloatConstOpnd()
  214. {
  215. AssertMsg(this->IsFloatConstOpnd(), "Bad call to AsFloatConstOpnd()");
  216. return reinterpret_cast<FloatConstOpnd *>(this);
  217. }
  218. inline const FloatConstOpnd *
  219. Opnd::AsFloatConstOpnd() const
  220. {
  221. AssertMsg(this->IsFloatConstOpnd(), "Bad call to AsFloatConstOpnd() const");
  222. return reinterpret_cast<const FloatConstOpnd *>(this);
  223. }
  224. ///----------------------------------------------------------------------------
  225. ///
  226. /// Opnd::IsFloat32ConstOpnd
  227. ///
  228. ///----------------------------------------------------------------------------
  229. inline bool
  230. Opnd::IsFloat32ConstOpnd() const
  231. {
  232. return GetKind() == OpndKindFloat32Const;
  233. }
  234. ///----------------------------------------------------------------------------
  235. ///
  236. /// Opnd::AsFloat32ConstOpnd
  237. ///
  238. /// Use this opnd as a FloatConstOpnd.
  239. ///
  240. ///----------------------------------------------------------------------------
  241. inline Float32ConstOpnd *
  242. Opnd::AsFloat32ConstOpnd()
  243. {
  244. AssertMsg(this->IsFloat32ConstOpnd(), "Bad call to AsFloat32ConstOpnd()");
  245. return reinterpret_cast<Float32ConstOpnd *>(this);
  246. }
  247. ///----------------------------------------------------------------------------
  248. ///
  249. /// Opnd::IsSimd128ConstOpnd
  250. ///
  251. ///----------------------------------------------------------------------------
  252. inline bool
  253. Opnd::IsSimd128ConstOpnd() const
  254. {
  255. return GetKind() == OpndKindSimd128Const;
  256. }
  257. ///----------------------------------------------------------------------------
  258. ///
  259. /// Opnd::AsSimd128ConstOpnd
  260. ///
  261. /// Use this opnd as a Simd128ConstOpnd.
  262. ///
  263. ///----------------------------------------------------------------------------
  264. inline Simd128ConstOpnd *
  265. Opnd::AsSimd128ConstOpnd()
  266. {
  267. AssertMsg(this->IsSimd128ConstOpnd(), "Bad call to AsSimd128ConstOpnd()");
  268. return reinterpret_cast<Simd128ConstOpnd *>(this);
  269. }
  270. inline const Simd128ConstOpnd *
  271. Opnd::AsSimd128ConstOpnd() const
  272. {
  273. AssertMsg(this->IsSimd128ConstOpnd(), "Bad call to AsSimd128ConstOpnd() const");
  274. return reinterpret_cast<const Simd128ConstOpnd *>(this);
  275. }
  276. ///----------------------------------------------------------------------------
  277. ///
  278. /// Opnd::IsHelperCallOpnd
  279. ///
  280. ///----------------------------------------------------------------------------
  281. inline bool
  282. Opnd::IsHelperCallOpnd() const
  283. {
  284. return GetKind() == OpndKindHelperCall;
  285. }
  286. ///----------------------------------------------------------------------------
  287. ///
  288. /// Opnd::AsHelperCallOpnd
  289. ///
  290. /// Use this opnd as a HelperCallOpnd.
  291. ///
  292. ///----------------------------------------------------------------------------
  293. inline HelperCallOpnd *
  294. Opnd::AsHelperCallOpnd()
  295. {
  296. AssertMsg(this->IsHelperCallOpnd(), "Bad call to AsHelperCallOpnd()");
  297. return reinterpret_cast<HelperCallOpnd *>(this);
  298. }
  299. inline const HelperCallOpnd *
  300. Opnd::AsHelperCallOpnd() const
  301. {
  302. AssertMsg(this->IsHelperCallOpnd(), "Bad call to AsHelperCallOpnd() const");
  303. return reinterpret_cast<const HelperCallOpnd *>(this);
  304. }
  305. ///----------------------------------------------------------------------------
  306. ///
  307. /// Opnd::IsAddrOpnd
  308. ///
  309. ///----------------------------------------------------------------------------
  310. inline bool
  311. Opnd::IsAddrOpnd() const
  312. {
  313. return GetKind() == OpndKindAddr;
  314. }
  315. ///----------------------------------------------------------------------------
  316. ///
  317. /// Opnd::AsAddrOpnd
  318. ///
  319. /// Use this opnd as an AddrOpnd.
  320. ///
  321. ///----------------------------------------------------------------------------
  322. inline AddrOpnd *
  323. Opnd::AsAddrOpnd()
  324. {
  325. AssertMsg(this->IsAddrOpnd(), "Bad call to AsAddrOpnd()");
  326. return reinterpret_cast<AddrOpnd *>(this);
  327. }
  328. inline const AddrOpnd *
  329. Opnd::AsAddrOpnd() const
  330. {
  331. AssertMsg(this->IsAddrOpnd(), "Bad call to AsAddrOpnd() const");
  332. return reinterpret_cast<const AddrOpnd *>(this);
  333. }
  334. inline bool
  335. Opnd::IsListOpnd() const
  336. {
  337. return GetKind() == OpndKindList;
  338. }
  339. inline ListOpnd *
  340. Opnd::AsListOpnd()
  341. {
  342. AssertMsg(this->IsListOpnd(), "Bad call to AsListOpnd()");
  343. return static_cast<ListOpnd *>(this);
  344. }
  345. inline const ListOpnd *
  346. Opnd::AsListOpnd() const
  347. {
  348. AssertMsg(this->IsListOpnd(), "Bad call to AsListOpnd() const");
  349. return static_cast<const ListOpnd *>(this);
  350. }
  351. ///----------------------------------------------------------------------------
  352. ///
  353. /// Opnd::IsIndirOpnd
  354. ///
  355. ///----------------------------------------------------------------------------
  356. inline bool
  357. Opnd::IsIndirOpnd() const
  358. {
  359. return GetKind() == OpndKindIndir;
  360. }
  361. ///----------------------------------------------------------------------------
  362. ///
  363. /// Opnd::AsIndirOpnd
  364. ///
  365. /// Use this opnd as an IndirOpnd.
  366. ///
  367. ///----------------------------------------------------------------------------
  368. inline IndirOpnd *
  369. Opnd::AsIndirOpnd()
  370. {
  371. AssertMsg(this->IsIndirOpnd(), "Bad call to AsIndirOpnd()");
  372. return reinterpret_cast<IndirOpnd *>(this);
  373. }
  374. inline const IndirOpnd *
  375. Opnd::AsIndirOpnd() const
  376. {
  377. AssertMsg(this->IsIndirOpnd(), "Bad call to AsIndirOpnd() const");
  378. return reinterpret_cast<const IndirOpnd *>(this);
  379. }
  380. ///----------------------------------------------------------------------------
  381. ///
  382. /// Opnd::IsMemRefOpnd
  383. ///
  384. ///----------------------------------------------------------------------------
  385. inline bool
  386. Opnd::IsMemRefOpnd() const
  387. {
  388. return GetKind() == OpndKindMemRef;
  389. }
  390. ///----------------------------------------------------------------------------
  391. ///
  392. /// Opnd::AsMemRefOpnd
  393. ///
  394. /// Use this opnd as a MemRefOpnd.
  395. ///
  396. ///----------------------------------------------------------------------------
  397. inline MemRefOpnd *
  398. Opnd::AsMemRefOpnd()
  399. {
  400. AssertMsg(this->IsMemRefOpnd(), "Bad call to AsMemRefOpnd()");
  401. return reinterpret_cast<MemRefOpnd *>(this);
  402. }
  403. inline const MemRefOpnd *
  404. Opnd::AsMemRefOpnd() const
  405. {
  406. AssertMsg(this->IsMemRefOpnd(), "Bad call to AsMemRefOpnd() const");
  407. return reinterpret_cast<const MemRefOpnd *>(this);
  408. }
  409. ///----------------------------------------------------------------------------
  410. ///
  411. /// Opnd::IsLabelOpnd
  412. ///
  413. ///----------------------------------------------------------------------------
  414. inline bool
  415. Opnd::IsLabelOpnd() const
  416. {
  417. return GetKind() == OpndKindLabel;
  418. }
  419. ///----------------------------------------------------------------------------
  420. ///
  421. /// Opnd::AsLabelOpnd
  422. ///
  423. /// Use this opnd as a LabelOpnd.
  424. ///
  425. ///----------------------------------------------------------------------------
  426. inline LabelOpnd *
  427. Opnd::AsLabelOpnd()
  428. {
  429. AssertMsg(this->IsLabelOpnd(), "Bad call to AsLabelOpnd()");
  430. return reinterpret_cast<LabelOpnd *>(this);
  431. }
  432. inline const LabelOpnd *
  433. Opnd::AsLabelOpnd() const
  434. {
  435. AssertMsg(this->IsLabelOpnd(), "Bad call to AsLabelOpnd() const");
  436. return reinterpret_cast<const LabelOpnd *>(this);
  437. }
  438. ///----------------------------------------------------------------------------
  439. ///
  440. /// Opnd::IsImmediateOpnd
  441. ///
  442. ///----------------------------------------------------------------------------
  443. inline bool
  444. Opnd::IsImmediateOpnd() const
  445. {
  446. return this->IsIntConstOpnd() || this->IsInt64ConstOpnd() || this->IsAddrOpnd() || this->IsHelperCallOpnd();
  447. }
  448. inline bool Opnd::IsMemoryOpnd() const
  449. {
  450. switch(GetKind())
  451. {
  452. case OpndKindSym:
  453. case OpndKindIndir:
  454. case OpndKindMemRef:
  455. return true;
  456. }
  457. return false;
  458. }
  459. ///----------------------------------------------------------------------------
  460. ///
  461. /// Opnd::IsConstOpnd
  462. ///
  463. ///----------------------------------------------------------------------------
  464. inline bool
  465. Opnd::IsConstOpnd() const
  466. {
  467. bool result = this->IsImmediateOpnd() || this->IsFloatConstOpnd();
  468. result = result || this->IsSimd128ConstOpnd();
  469. return result;
  470. }
  471. ///----------------------------------------------------------------------------
  472. ///
  473. /// RegOpnd::AsArrayRegOpnd
  474. ///
  475. ///----------------------------------------------------------------------------
  476. inline ArrayRegOpnd *RegOpnd::AsArrayRegOpnd()
  477. {
  478. Assert(IsArrayRegOpnd());
  479. return static_cast<ArrayRegOpnd *>(this);
  480. }
  481. ///----------------------------------------------------------------------------
  482. ///
  483. /// RegOpnd::GetReg
  484. ///
  485. ///----------------------------------------------------------------------------
  486. inline RegNum
  487. RegOpnd::GetReg() const
  488. {
  489. return m_reg;
  490. }
  491. ///----------------------------------------------------------------------------
  492. ///
  493. /// RegOpnd::SetReg
  494. ///
  495. ///----------------------------------------------------------------------------
  496. inline void
  497. RegOpnd::SetReg(RegNum reg)
  498. {
  499. m_reg = reg;
  500. }
  501. ///----------------------------------------------------------------------------
  502. ///
  503. /// IndirOpnd::GetBaseOpnd
  504. ///
  505. ///----------------------------------------------------------------------------
  506. inline RegOpnd *
  507. IndirOpnd::GetBaseOpnd()
  508. {
  509. return this->m_baseOpnd;
  510. }
  511. inline RegOpnd const *
  512. IndirOpnd::GetBaseOpnd() const
  513. {
  514. return this->m_baseOpnd;
  515. }
  516. ///----------------------------------------------------------------------------
  517. ///
  518. /// IndirOpnd::GetIndexOpnd
  519. ///
  520. ///----------------------------------------------------------------------------
  521. inline RegOpnd *
  522. IndirOpnd::GetIndexOpnd()
  523. {
  524. return m_indexOpnd;
  525. }
  526. inline RegOpnd const *
  527. IndirOpnd::GetIndexOpnd() const
  528. {
  529. return m_indexOpnd;
  530. }
  531. ///----------------------------------------------------------------------------
  532. ///
  533. /// IndirOpnd::GetOffset
  534. ///
  535. ///----------------------------------------------------------------------------
  536. inline int32
  537. IndirOpnd::GetOffset() const
  538. {
  539. return m_offset;
  540. }
  541. ///----------------------------------------------------------------------------
  542. ///
  543. /// IndirOpnd::SetOffset
  544. ///
  545. ///----------------------------------------------------------------------------
  546. inline void
  547. IndirOpnd::SetOffset(int32 offset, bool dontEncode /* = false */)
  548. {
  549. m_offset = offset;
  550. m_dontEncode = dontEncode;
  551. }
  552. ///----------------------------------------------------------------------------
  553. ///
  554. /// IndirOpnd::GetScale
  555. ///
  556. ///----------------------------------------------------------------------------
  557. inline byte
  558. IndirOpnd::GetScale() const
  559. {
  560. return m_scale;
  561. }
  562. ///----------------------------------------------------------------------------
  563. ///
  564. /// IndirOpnd::SetScale
  565. ///
  566. ///----------------------------------------------------------------------------
  567. inline void
  568. IndirOpnd::SetScale(byte scale)
  569. {
  570. m_scale = scale;
  571. }
  572. ///----------------------------------------------------------------------------
  573. ///
  574. /// MemRefOpnd::GetMemLoc
  575. ///
  576. ///----------------------------------------------------------------------------
  577. inline intptr_t
  578. MemRefOpnd::GetMemLoc() const
  579. {
  580. return m_memLoc;
  581. }
  582. ///----------------------------------------------------------------------------
  583. ///
  584. /// MemRefOpnd::SetMemLoc
  585. ///
  586. ///----------------------------------------------------------------------------
  587. inline void
  588. MemRefOpnd::SetMemLoc(intptr_t pMemLoc)
  589. {
  590. m_memLoc = pMemLoc;
  591. }
  592. inline LabelInstr *
  593. LabelOpnd::GetLabel() const
  594. {
  595. return m_label;
  596. }
  597. inline void
  598. LabelOpnd::SetLabel(LabelInstr * labelInstr)
  599. {
  600. m_label = labelInstr;
  601. }
  602. inline BVUnit
  603. RegBVOpnd::GetValue() const
  604. {
  605. return m_value;
  606. }
  607. } // namespace IR