DFGCCallHelpers.h 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998
  1. /*
  2. * Copyright (C) 2011 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef DFGCCallHelpers_h
  26. #define DFGCCallHelpers_h
  27. #include <wtf/Platform.h>
  28. #if ENABLE(DFG_JIT)
  29. #include "DFGAssemblyHelpers.h"
  30. #include "DFGGPRInfo.h"
  31. namespace JSC { namespace DFG {
  32. class CCallHelpers : public AssemblyHelpers {
  33. public:
  34. CCallHelpers(VM* vm, CodeBlock* codeBlock = 0)
  35. : AssemblyHelpers(vm, codeBlock)
  36. {
  37. }
  38. // These methods used to sort arguments into the correct registers.
  39. // On X86 we use cdecl calling conventions, which pass all arguments on the
  40. // stack. On other architectures we may need to sort values into the
  41. // correct registers.
  42. #if !NUMBER_OF_ARGUMENT_REGISTERS
  43. unsigned m_callArgumentOffset;
  44. void resetCallArguments() { m_callArgumentOffset = 0; }
  45. // These methods are using internally to implement the callOperation methods.
  46. void addCallArgument(GPRReg value)
  47. {
  48. poke(value, m_callArgumentOffset++);
  49. }
  50. void addCallArgument(TrustedImm32 imm)
  51. {
  52. poke(imm, m_callArgumentOffset++);
  53. }
  54. void addCallArgument(TrustedImmPtr pointer)
  55. {
  56. poke(pointer, m_callArgumentOffset++);
  57. }
  58. void addCallArgument(FPRReg value)
  59. {
  60. storeDouble(value, Address(stackPointerRegister, m_callArgumentOffset * sizeof(void*)));
  61. m_callArgumentOffset += sizeof(double) / sizeof(void*);
  62. }
  63. ALWAYS_INLINE void setupArguments(FPRReg arg1)
  64. {
  65. resetCallArguments();
  66. addCallArgument(arg1);
  67. }
  68. ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
  69. {
  70. resetCallArguments();
  71. addCallArgument(arg1);
  72. addCallArgument(arg2);
  73. }
  74. ALWAYS_INLINE void setupArguments(GPRReg arg1)
  75. {
  76. resetCallArguments();
  77. addCallArgument(arg1);
  78. }
  79. ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
  80. {
  81. resetCallArguments();
  82. addCallArgument(arg1);
  83. addCallArgument(arg2);
  84. }
  85. ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
  86. {
  87. resetCallArguments();
  88. addCallArgument(arg1);
  89. }
  90. ALWAYS_INLINE void setupArgumentsExecState()
  91. {
  92. resetCallArguments();
  93. addCallArgument(GPRInfo::callFrameRegister);
  94. }
  95. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
  96. {
  97. resetCallArguments();
  98. addCallArgument(GPRInfo::callFrameRegister);
  99. addCallArgument(arg1);
  100. }
  101. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
  102. {
  103. resetCallArguments();
  104. addCallArgument(GPRInfo::callFrameRegister);
  105. addCallArgument(arg1);
  106. }
  107. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
  108. {
  109. resetCallArguments();
  110. addCallArgument(GPRInfo::callFrameRegister);
  111. addCallArgument(arg1);
  112. }
  113. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
  114. {
  115. resetCallArguments();
  116. addCallArgument(GPRInfo::callFrameRegister);
  117. addCallArgument(arg1);
  118. addCallArgument(arg2);
  119. }
  120. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
  121. {
  122. resetCallArguments();
  123. addCallArgument(GPRInfo::callFrameRegister);
  124. addCallArgument(arg1);
  125. addCallArgument(arg2);
  126. }
  127. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
  128. {
  129. resetCallArguments();
  130. addCallArgument(GPRInfo::callFrameRegister);
  131. addCallArgument(arg1);
  132. addCallArgument(arg2);
  133. }
  134. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
  135. {
  136. resetCallArguments();
  137. addCallArgument(GPRInfo::callFrameRegister);
  138. addCallArgument(arg1);
  139. addCallArgument(arg2);
  140. }
  141. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
  142. {
  143. resetCallArguments();
  144. addCallArgument(GPRInfo::callFrameRegister);
  145. addCallArgument(arg1);
  146. addCallArgument(arg2);
  147. }
  148. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
  149. {
  150. resetCallArguments();
  151. addCallArgument(GPRInfo::callFrameRegister);
  152. addCallArgument(arg1);
  153. addCallArgument(arg2);
  154. }
  155. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
  156. {
  157. resetCallArguments();
  158. addCallArgument(GPRInfo::callFrameRegister);
  159. addCallArgument(arg1);
  160. addCallArgument(arg2);
  161. }
  162. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
  163. {
  164. resetCallArguments();
  165. addCallArgument(GPRInfo::callFrameRegister);
  166. addCallArgument(arg1);
  167. addCallArgument(arg2);
  168. }
  169. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
  170. {
  171. resetCallArguments();
  172. addCallArgument(GPRInfo::callFrameRegister);
  173. addCallArgument(arg1);
  174. addCallArgument(arg2);
  175. addCallArgument(arg3);
  176. }
  177. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
  178. {
  179. resetCallArguments();
  180. addCallArgument(GPRInfo::callFrameRegister);
  181. addCallArgument(arg1);
  182. addCallArgument(arg2);
  183. addCallArgument(arg3);
  184. }
  185. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
  186. {
  187. resetCallArguments();
  188. addCallArgument(GPRInfo::callFrameRegister);
  189. addCallArgument(arg1);
  190. addCallArgument(arg2);
  191. addCallArgument(arg3);
  192. }
  193. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
  194. {
  195. resetCallArguments();
  196. addCallArgument(GPRInfo::callFrameRegister);
  197. addCallArgument(arg1);
  198. addCallArgument(arg2);
  199. addCallArgument(arg3);
  200. }
  201. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
  202. {
  203. resetCallArguments();
  204. addCallArgument(GPRInfo::callFrameRegister);
  205. addCallArgument(arg1);
  206. addCallArgument(arg2);
  207. addCallArgument(arg3);
  208. }
  209. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
  210. {
  211. resetCallArguments();
  212. addCallArgument(GPRInfo::callFrameRegister);
  213. addCallArgument(arg1);
  214. addCallArgument(arg2);
  215. addCallArgument(arg3);
  216. }
  217. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
  218. {
  219. resetCallArguments();
  220. addCallArgument(GPRInfo::callFrameRegister);
  221. addCallArgument(arg1);
  222. addCallArgument(arg2);
  223. addCallArgument(arg3);
  224. addCallArgument(arg4);
  225. }
  226. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
  227. {
  228. resetCallArguments();
  229. addCallArgument(GPRInfo::callFrameRegister);
  230. addCallArgument(arg1);
  231. addCallArgument(arg2);
  232. addCallArgument(arg3);
  233. addCallArgument(arg4);
  234. addCallArgument(arg5);
  235. }
  236. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
  237. {
  238. resetCallArguments();
  239. addCallArgument(GPRInfo::callFrameRegister);
  240. addCallArgument(arg1);
  241. addCallArgument(arg2);
  242. addCallArgument(arg3);
  243. addCallArgument(arg4);
  244. }
  245. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
  246. {
  247. resetCallArguments();
  248. addCallArgument(GPRInfo::callFrameRegister);
  249. addCallArgument(arg1);
  250. addCallArgument(arg2);
  251. addCallArgument(arg3);
  252. addCallArgument(arg4);
  253. }
  254. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
  255. {
  256. resetCallArguments();
  257. addCallArgument(GPRInfo::callFrameRegister);
  258. addCallArgument(arg1);
  259. addCallArgument(arg2);
  260. addCallArgument(arg3);
  261. }
  262. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
  263. {
  264. resetCallArguments();
  265. addCallArgument(GPRInfo::callFrameRegister);
  266. addCallArgument(arg1);
  267. addCallArgument(arg2);
  268. addCallArgument(arg3);
  269. addCallArgument(arg4);
  270. }
  271. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
  272. {
  273. resetCallArguments();
  274. addCallArgument(GPRInfo::callFrameRegister);
  275. addCallArgument(arg1);
  276. addCallArgument(arg2);
  277. addCallArgument(arg3);
  278. addCallArgument(arg4);
  279. }
  280. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
  281. {
  282. resetCallArguments();
  283. addCallArgument(GPRInfo::callFrameRegister);
  284. addCallArgument(arg1);
  285. addCallArgument(arg2);
  286. addCallArgument(arg3);
  287. addCallArgument(arg4);
  288. }
  289. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
  290. {
  291. resetCallArguments();
  292. addCallArgument(GPRInfo::callFrameRegister);
  293. addCallArgument(arg1);
  294. addCallArgument(arg2);
  295. addCallArgument(arg3);
  296. addCallArgument(arg4);
  297. addCallArgument(arg5);
  298. }
  299. ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
  300. {
  301. resetCallArguments();
  302. addCallArgument(GPRInfo::callFrameRegister);
  303. addCallArgument(arg1);
  304. addCallArgument(arg2);
  305. }
  306. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
  307. {
  308. resetCallArguments();
  309. addCallArgument(GPRInfo::callFrameRegister);
  310. addCallArgument(arg1);
  311. addCallArgument(arg2);
  312. addCallArgument(arg3);
  313. }
  314. #endif // !NUMBER_OF_ARGUMENT_REGISTERS
  315. // These methods are suitable for any calling convention that provides for
  316. // at least 4 argument registers, e.g. X86_64, ARMv7.
  317. #if NUMBER_OF_ARGUMENT_REGISTERS >= 4
  318. template<GPRReg destA, GPRReg destB>
  319. void setupTwoStubArgs(GPRReg srcA, GPRReg srcB)
  320. {
  321. // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
  322. // (1) both are already in arg regs, the right way around.
  323. // (2) both are already in arg regs, the wrong way around.
  324. // (3) neither are currently in arg registers.
  325. // (4) srcA in in its correct reg.
  326. // (5) srcA in in the incorrect reg.
  327. // (6) srcB in in its correct reg.
  328. // (7) srcB in in the incorrect reg.
  329. //
  330. // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
  331. // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
  332. // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
  333. // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
  334. if (srcB != destA) {
  335. // Handle the easy cases - two simple moves.
  336. move(srcA, destA);
  337. move(srcB, destB);
  338. } else if (srcA != destB) {
  339. // Handle the non-swap case - just put srcB in place first.
  340. move(srcB, destB);
  341. move(srcA, destA);
  342. } else
  343. swap(destA, destB);
  344. }
  345. #if CPU(X86_64)
  346. template<FPRReg destA, FPRReg destB>
  347. void setupTwoStubArgs(FPRReg srcA, FPRReg srcB)
  348. {
  349. // Assuming that srcA != srcB, there are 7 interesting states the registers may be in:
  350. // (1) both are already in arg regs, the right way around.
  351. // (2) both are already in arg regs, the wrong way around.
  352. // (3) neither are currently in arg registers.
  353. // (4) srcA in in its correct reg.
  354. // (5) srcA in in the incorrect reg.
  355. // (6) srcB in in its correct reg.
  356. // (7) srcB in in the incorrect reg.
  357. //
  358. // The trivial approach is to simply emit two moves, to put srcA in place then srcB in
  359. // place (the MacroAssembler will omit redundant moves). This apporach will be safe in
  360. // cases 1, 3, 4, 5, 6, and in cases where srcA==srcB. The two problem cases are 2
  361. // (requires a swap) and 7 (must move srcB first, to avoid trampling.)
  362. if (srcB != destA) {
  363. // Handle the easy cases - two simple moves.
  364. moveDouble(srcA, destA);
  365. moveDouble(srcB, destB);
  366. return;
  367. }
  368. if (srcA != destB) {
  369. // Handle the non-swap case - just put srcB in place first.
  370. moveDouble(srcB, destB);
  371. moveDouble(srcA, destA);
  372. return;
  373. }
  374. ASSERT(srcB == destA && srcA == destB);
  375. // Need to swap; pick a temporary register.
  376. FPRReg temp;
  377. if (destA != FPRInfo::argumentFPR3 && destA != FPRInfo::argumentFPR3)
  378. temp = FPRInfo::argumentFPR3;
  379. else if (destA != FPRInfo::argumentFPR2 && destA != FPRInfo::argumentFPR2)
  380. temp = FPRInfo::argumentFPR2;
  381. else {
  382. ASSERT(destA != FPRInfo::argumentFPR1 && destA != FPRInfo::argumentFPR1);
  383. temp = FPRInfo::argumentFPR1;
  384. }
  385. moveDouble(destA, temp);
  386. moveDouble(destB, destA);
  387. moveDouble(temp, destB);
  388. }
  389. #endif
  390. void setupStubArguments(GPRReg arg1, GPRReg arg2)
  391. {
  392. setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
  393. }
  394. void setupStubArguments(GPRReg arg1, GPRReg arg2, GPRReg arg3)
  395. {
  396. // If neither of arg2/arg3 are in our way, then we can move arg1 into place.
  397. // Then we can use setupTwoStubArgs to fix arg2/arg3.
  398. if (arg2 != GPRInfo::argumentGPR1 && arg3 != GPRInfo::argumentGPR1) {
  399. move(arg1, GPRInfo::argumentGPR1);
  400. setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
  401. return;
  402. }
  403. // If neither of arg1/arg3 are in our way, then we can move arg2 into place.
  404. // Then we can use setupTwoStubArgs to fix arg1/arg3.
  405. if (arg1 != GPRInfo::argumentGPR2 && arg3 != GPRInfo::argumentGPR2) {
  406. move(arg2, GPRInfo::argumentGPR2);
  407. setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
  408. return;
  409. }
  410. // If neither of arg1/arg2 are in our way, then we can move arg3 into place.
  411. // Then we can use setupTwoStubArgs to fix arg1/arg2.
  412. if (arg1 != GPRInfo::argumentGPR3 && arg2 != GPRInfo::argumentGPR3) {
  413. move(arg3, GPRInfo::argumentGPR3);
  414. setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(arg1, arg2);
  415. return;
  416. }
  417. // If we get here, we haven't been able to move any of arg1/arg2/arg3.
  418. // Since all three are blocked, then all three must already be in the argument register.
  419. // But are they in the right ones?
  420. // First, ensure arg1 is in place.
  421. if (arg1 != GPRInfo::argumentGPR1) {
  422. swap(arg1, GPRInfo::argumentGPR1);
  423. // If arg1 wasn't in argumentGPR1, one of arg2/arg3 must be.
  424. ASSERT(arg2 == GPRInfo::argumentGPR1 || arg3 == GPRInfo::argumentGPR1);
  425. // If arg2 was in argumentGPR1 it no longer is (due to the swap).
  426. // Otherwise arg3 must have been. Mark him as moved.
  427. if (arg2 == GPRInfo::argumentGPR1)
  428. arg2 = arg1;
  429. else
  430. arg3 = arg1;
  431. }
  432. // Either arg2 & arg3 need swapping, or we're all done.
  433. ASSERT((arg2 == GPRInfo::argumentGPR2 || arg3 == GPRInfo::argumentGPR3)
  434. || (arg2 == GPRInfo::argumentGPR3 || arg3 == GPRInfo::argumentGPR2));
  435. if (arg2 != GPRInfo::argumentGPR2)
  436. swap(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3);
  437. }
  438. #if CPU(X86_64)
  439. ALWAYS_INLINE void setupArguments(FPRReg arg1)
  440. {
  441. moveDouble(arg1, FPRInfo::argumentFPR0);
  442. }
  443. ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
  444. {
  445. setupTwoStubArgs<FPRInfo::argumentFPR0, FPRInfo::argumentFPR1>(arg1, arg2);
  446. }
  447. ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
  448. {
  449. moveDouble(arg1, FPRInfo::argumentFPR0);
  450. move(arg2, GPRInfo::argumentGPR1);
  451. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  452. }
  453. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
  454. {
  455. moveDouble(arg3, FPRInfo::argumentFPR0);
  456. setupStubArguments(arg1, arg2);
  457. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  458. }
  459. #elif CPU(ARM)
  460. #if CPU(ARM_HARDFP)
  461. ALWAYS_INLINE void setupArguments(FPRReg arg1)
  462. {
  463. moveDouble(arg1, FPRInfo::argumentFPR0);
  464. }
  465. ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
  466. {
  467. if (arg2 != FPRInfo::argumentFPR0) {
  468. moveDouble(arg1, FPRInfo::argumentFPR0);
  469. moveDouble(arg2, FPRInfo::argumentFPR1);
  470. } else if (arg1 != FPRInfo::argumentFPR1) {
  471. moveDouble(arg2, FPRInfo::argumentFPR1);
  472. moveDouble(arg1, FPRInfo::argumentFPR0);
  473. } else {
  474. // Swap arg1, arg2.
  475. moveDouble(FPRInfo::argumentFPR0, ARMRegisters::d2);
  476. moveDouble(FPRInfo::argumentFPR1, FPRInfo::argumentFPR0);
  477. moveDouble(ARMRegisters::d2, FPRInfo::argumentFPR1);
  478. }
  479. }
  480. ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
  481. {
  482. moveDouble(arg1, FPRInfo::argumentFPR0);
  483. move(arg2, GPRInfo::argumentGPR1);
  484. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  485. }
  486. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
  487. {
  488. moveDouble(arg3, FPRInfo::argumentFPR0);
  489. setupStubArguments(arg1, arg2);
  490. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  491. }
  492. #else
  493. ALWAYS_INLINE void setupArguments(FPRReg arg1)
  494. {
  495. assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
  496. }
  497. ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
  498. {
  499. assembler().vmov(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1, arg1);
  500. assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg2);
  501. }
  502. ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
  503. {
  504. move(arg2, GPRInfo::argumentGPR3);
  505. assembler().vmov(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, arg1);
  506. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  507. }
  508. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
  509. {
  510. setupStubArguments(arg1, arg2);
  511. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  512. assembler().vmov(GPRInfo::argumentGPR3, GPRInfo::nonArgGPR0, arg3);
  513. poke(GPRInfo::nonArgGPR0);
  514. }
  515. #endif // CPU(ARM_HARDFP)
  516. #elif CPU(MIPS)
  517. ALWAYS_INLINE void setupArguments(FPRReg arg1)
  518. {
  519. moveDouble(arg1, FPRInfo::argumentFPR0);
  520. }
  521. ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
  522. {
  523. if (arg2 != FPRInfo::argumentFPR0) {
  524. moveDouble(arg1, FPRInfo::argumentFPR0);
  525. moveDouble(arg2, FPRInfo::argumentFPR1);
  526. } else if (arg1 != FPRInfo::argumentFPR1) {
  527. moveDouble(arg2, FPRInfo::argumentFPR1);
  528. moveDouble(arg1, FPRInfo::argumentFPR0);
  529. } else {
  530. // Swap arg1, arg2.
  531. swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
  532. }
  533. }
  534. ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
  535. {
  536. assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
  537. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  538. poke(arg2, 4);
  539. }
  540. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
  541. {
  542. setupStubArguments(arg1, arg2);
  543. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  544. poke(arg3, 4);
  545. }
  546. #else
  547. #error "DFG JIT not supported on this platform."
  548. #endif
  549. ALWAYS_INLINE void setupArguments(GPRReg arg1)
  550. {
  551. move(arg1, GPRInfo::argumentGPR0);
  552. }
  553. ALWAYS_INLINE void setupArguments(GPRReg arg1, GPRReg arg2)
  554. {
  555. setupTwoStubArgs<GPRInfo::argumentGPR0, GPRInfo::argumentGPR1>(arg1, arg2);
  556. }
  557. ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1)
  558. {
  559. move(arg1, GPRInfo::argumentGPR0);
  560. }
  561. ALWAYS_INLINE void setupArgumentsExecState()
  562. {
  563. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  564. }
  565. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1)
  566. {
  567. move(arg1, GPRInfo::argumentGPR1);
  568. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  569. }
  570. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1)
  571. {
  572. move(arg1, GPRInfo::argumentGPR1);
  573. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  574. }
  575. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1)
  576. {
  577. move(arg1, GPRInfo::argumentGPR1);
  578. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  579. }
  580. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2)
  581. {
  582. setupStubArguments(arg1, arg2);
  583. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  584. }
  585. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2)
  586. {
  587. move(arg1, GPRInfo::argumentGPR1);
  588. move(arg2, GPRInfo::argumentGPR2);
  589. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  590. }
  591. #if CPU(X86_64)
  592. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm64 arg2)
  593. {
  594. move(arg1, GPRInfo::argumentGPR1);
  595. move(arg2, GPRInfo::argumentGPR2);
  596. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  597. }
  598. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm64 arg1, GPRReg arg2)
  599. {
  600. move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
  601. move(arg1, GPRInfo::argumentGPR1);
  602. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  603. }
  604. #endif
  605. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2)
  606. {
  607. move(arg1, GPRInfo::argumentGPR1);
  608. move(arg2, GPRInfo::argumentGPR2);
  609. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  610. }
  611. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, ImmPtr arg2)
  612. {
  613. move(arg1, GPRInfo::argumentGPR1);
  614. move(arg2, GPRInfo::argumentGPR2);
  615. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  616. }
  617. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, GPRReg arg2)
  618. {
  619. move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
  620. move(arg1, GPRInfo::argumentGPR1);
  621. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  622. }
  623. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2)
  624. {
  625. move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
  626. move(arg1, GPRInfo::argumentGPR1);
  627. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  628. }
  629. ALWAYS_INLINE void setupArgumentsWithExecState(ImmPtr arg1, GPRReg arg2)
  630. {
  631. move(arg2, GPRInfo::argumentGPR2); // Move this first, so setting arg1 does not trample!
  632. move(arg1, GPRInfo::argumentGPR1);
  633. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  634. }
  635. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2)
  636. {
  637. move(arg1, GPRInfo::argumentGPR1);
  638. move(arg2, GPRInfo::argumentGPR2);
  639. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  640. }
  641. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2)
  642. {
  643. move(arg1, GPRInfo::argumentGPR1);
  644. move(arg2, GPRInfo::argumentGPR2);
  645. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  646. }
  647. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2)
  648. {
  649. move(arg1, GPRInfo::argumentGPR1);
  650. move(arg2, GPRInfo::argumentGPR2);
  651. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  652. }
  653. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3)
  654. {
  655. setupStubArguments(arg1, arg2, arg3);
  656. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  657. }
  658. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3)
  659. {
  660. setupStubArguments(arg1, arg2);
  661. move(arg3, GPRInfo::argumentGPR3);
  662. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  663. }
  664. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, GPRReg arg3)
  665. {
  666. setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR3>(arg1, arg3);
  667. move(arg2, GPRInfo::argumentGPR2);
  668. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  669. }
  670. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImm32 arg2, TrustedImmPtr arg3)
  671. {
  672. move(arg1, GPRInfo::argumentGPR1);
  673. move(arg2, GPRInfo::argumentGPR2);
  674. move(arg3, GPRInfo::argumentGPR3);
  675. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  676. }
  677. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3)
  678. {
  679. move(arg1, GPRInfo::argumentGPR1);
  680. move(arg2, GPRInfo::argumentGPR2);
  681. move(arg3, GPRInfo::argumentGPR3);
  682. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  683. }
  684. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
  685. {
  686. move(arg1, GPRInfo::argumentGPR1);
  687. move(arg2, GPRInfo::argumentGPR2);
  688. move(arg3, GPRInfo::argumentGPR3);
  689. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  690. }
  691. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImmPtr arg3)
  692. {
  693. setupStubArguments(arg1, arg2);
  694. move(arg3, GPRInfo::argumentGPR3);
  695. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  696. }
  697. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3)
  698. {
  699. move(arg3, GPRInfo::argumentGPR3);
  700. move(arg1, GPRInfo::argumentGPR1);
  701. move(arg2, GPRInfo::argumentGPR2);
  702. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  703. }
  704. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3)
  705. {
  706. move(arg3, GPRInfo::argumentGPR3);
  707. move(arg1, GPRInfo::argumentGPR1);
  708. move(arg2, GPRInfo::argumentGPR2);
  709. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  710. }
  711. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3)
  712. {
  713. move(arg2, GPRInfo::argumentGPR2);
  714. move(arg1, GPRInfo::argumentGPR1);
  715. move(arg3, GPRInfo::argumentGPR3);
  716. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  717. }
  718. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3)
  719. {
  720. setupTwoStubArgs<GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg2, arg3);
  721. move(arg1, GPRInfo::argumentGPR1);
  722. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  723. }
  724. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImmPtr arg2, TrustedImmPtr arg3)
  725. {
  726. move(arg1, GPRInfo::argumentGPR1);
  727. move(arg2, GPRInfo::argumentGPR2);
  728. move(arg3, GPRInfo::argumentGPR3);
  729. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  730. }
  731. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3)
  732. {
  733. move(arg1, GPRInfo::argumentGPR1);
  734. move(arg2, GPRInfo::argumentGPR2);
  735. move(arg3, GPRInfo::argumentGPR3);
  736. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  737. }
  738. #endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
  739. // These methods are suitable for any calling convention that provides for
  740. // exactly 4 argument registers, e.g. ARMv7.
  741. #if NUMBER_OF_ARGUMENT_REGISTERS == 4
  742. #if CPU(MIPS)
  743. #define POKE_ARGUMENT_OFFSET 4
  744. #else
  745. #define POKE_ARGUMENT_OFFSET 0
  746. #endif
  747. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
  748. {
  749. poke(arg4, POKE_ARGUMENT_OFFSET);
  750. setupArgumentsWithExecState(arg1, arg2, arg3);
  751. }
  752. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
  753. {
  754. poke(arg4, POKE_ARGUMENT_OFFSET);
  755. setupArgumentsWithExecState(arg1, arg2, arg3);
  756. }
  757. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
  758. {
  759. poke(arg4, POKE_ARGUMENT_OFFSET);
  760. setupArgumentsWithExecState(arg1, arg2, arg3);
  761. }
  762. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
  763. {
  764. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  765. poke(arg4, POKE_ARGUMENT_OFFSET);
  766. setupArgumentsWithExecState(arg1, arg2, arg3);
  767. }
  768. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
  769. {
  770. poke(arg4, POKE_ARGUMENT_OFFSET);
  771. setupArgumentsWithExecState(arg1, arg2, arg3);
  772. }
  773. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
  774. {
  775. poke(arg4, POKE_ARGUMENT_OFFSET);
  776. setupArgumentsWithExecState(arg1, arg2, arg3);
  777. }
  778. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
  779. {
  780. poke(arg4, POKE_ARGUMENT_OFFSET);
  781. setupArgumentsWithExecState(arg1, arg2, arg3);
  782. }
  783. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
  784. {
  785. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  786. poke(arg4, POKE_ARGUMENT_OFFSET);
  787. setupArgumentsWithExecState(arg1, arg2, arg3);
  788. }
  789. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
  790. {
  791. poke(arg4, POKE_ARGUMENT_OFFSET);
  792. setupArgumentsWithExecState(arg1, arg2, arg3);
  793. }
  794. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
  795. {
  796. poke(arg4, POKE_ARGUMENT_OFFSET);
  797. setupArgumentsWithExecState(arg1, arg2, arg3);
  798. }
  799. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
  800. {
  801. poke(arg4, POKE_ARGUMENT_OFFSET);
  802. setupArgumentsWithExecState(arg1, arg2, arg3);
  803. }
  804. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
  805. {
  806. poke(arg4, POKE_ARGUMENT_OFFSET);
  807. setupArgumentsWithExecState(arg1, arg2, arg3);
  808. }
  809. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
  810. {
  811. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  812. poke(arg4, POKE_ARGUMENT_OFFSET);
  813. setupArgumentsWithExecState(arg1, arg2, arg3);
  814. }
  815. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
  816. {
  817. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  818. poke(arg4, POKE_ARGUMENT_OFFSET);
  819. setupArgumentsWithExecState(arg1, arg2, arg3);
  820. }
  821. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
  822. {
  823. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  824. poke(arg4, POKE_ARGUMENT_OFFSET);
  825. setupArgumentsWithExecState(arg1, arg2, arg3);
  826. }
  827. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
  828. {
  829. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  830. poke(arg4, POKE_ARGUMENT_OFFSET);
  831. setupArgumentsWithExecState(arg1, arg2, arg3);
  832. }
  833. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
  834. {
  835. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  836. poke(arg4, POKE_ARGUMENT_OFFSET);
  837. setupArgumentsWithExecState(arg1, arg2, arg3);
  838. }
  839. ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
  840. {
  841. poke(arg5, POKE_ARGUMENT_OFFSET + 1);
  842. poke(arg4, POKE_ARGUMENT_OFFSET);
  843. setupArgumentsWithExecState(arg1, arg2, arg3);
  844. }
  845. #endif // NUMBER_OF_ARGUMENT_REGISTERS == 4
  846. #if NUMBER_OF_ARGUMENT_REGISTERS >= 5
  847. ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
  848. {
  849. setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR4>(arg1, arg4);
  850. move(arg2, GPRInfo::argumentGPR2);
  851. move(arg3, GPRInfo::argumentGPR3);
  852. move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
  853. }
  854. #endif
  855. void setupResults(GPRReg destA, GPRReg destB)
  856. {
  857. GPRReg srcA = GPRInfo::returnValueGPR;
  858. GPRReg srcB = GPRInfo::returnValueGPR2;
  859. if (srcB != destA) {
  860. // Handle the easy cases - two simple moves.
  861. move(srcA, destA);
  862. move(srcB, destB);
  863. } else if (srcA != destB) {
  864. // Handle the non-swap case - just put srcB in place first.
  865. move(srcB, destB);
  866. move(srcA, destA);
  867. } else
  868. swap(destA, destB);
  869. }
  870. };
  871. } } // namespace JSC::DFG
  872. #endif // ENABLE(DFG_JIT)
  873. #endif // DFGCCallHelpers_h