SimdFloat32x4Lib.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeLibraryPch.h"
  6. namespace Js
  7. {
  8. Var SIMDFloat32x4Lib::EntryFloat32x4(RecyclableObject* function, CallInfo callInfo, ...)
  9. {
  10. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  11. ARGUMENTS(args, callInfo);
  12. ScriptContext* scriptContext = function->GetScriptContext();
  13. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  14. Assert(!(callInfo.Flags & CallFlags_New));
  15. Var undefinedVar = scriptContext->GetLibrary()->GetUndefined();
  16. // Convert all args to float32
  17. float fSIMDX = JavascriptConversion::ToFloat(args.Info.Count >= 2 ? args[1] : undefinedVar, scriptContext);
  18. float fSIMDY = JavascriptConversion::ToFloat(args.Info.Count >= 3 ? args[2] : undefinedVar, scriptContext);
  19. float fSIMDZ = JavascriptConversion::ToFloat(args.Info.Count >= 4 ? args[3] : undefinedVar, scriptContext);
  20. float fSIMDW = JavascriptConversion::ToFloat(args.Info.Count >= 5 ? args[4] : undefinedVar, scriptContext);
  21. SIMDValue lanes = SIMDFloat32x4Operation::OpFloat32x4(fSIMDX, fSIMDY, fSIMDZ, fSIMDW);
  22. return JavascriptSIMDFloat32x4::New(&lanes, scriptContext);
  23. }
  24. Var SIMDFloat32x4Lib::EntryCheck(RecyclableObject* function, CallInfo callInfo, ...)
  25. {
  26. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  27. ARGUMENTS(args, callInfo);
  28. ScriptContext* scriptContext = function->GetScriptContext();
  29. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  30. Assert(!(callInfo.Flags & CallFlags_New));
  31. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  32. {
  33. return args[1];
  34. }
  35. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("float32x4"));
  36. }
  37. Var SIMDFloat32x4Lib::EntrySplat(RecyclableObject* function, CallInfo callInfo, ...)
  38. {
  39. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  40. ARGUMENTS(args, callInfo);
  41. ScriptContext* scriptContext = function->GetScriptContext();
  42. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  43. Assert(!(callInfo.Flags & CallFlags_New));
  44. Var undefinedVar = scriptContext->GetLibrary()->GetUndefined();
  45. float value = JavascriptConversion::ToFloat(args.Info.Count >= 2 ? args[1] : undefinedVar, scriptContext);
  46. SIMDValue lanes = SIMDFloat32x4Operation::OpSplat(value);
  47. return JavascriptSIMDFloat32x4::New(&lanes, scriptContext);
  48. }
  49. Var SIMDFloat32x4Lib::EntryFromFloat64x2(RecyclableObject* function, CallInfo callInfo, ...)
  50. {
  51. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  52. ARGUMENTS(args, callInfo);
  53. ScriptContext* scriptContext = function->GetScriptContext();
  54. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  55. Assert(!(callInfo.Flags & CallFlags_New));
  56. if (args.Info.Count >= 2 && JavascriptSIMDFloat64x2::Is(args[1]))
  57. {
  58. JavascriptSIMDFloat64x2 *instance = JavascriptSIMDFloat64x2::FromVar(args[1]);
  59. SIMDValue result = SIMDFloat32x4Operation::OpFromFloat64x2(instance->GetValue());
  60. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  61. }
  62. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromFloat64x2"));
  63. }
  64. Var SIMDFloat32x4Lib::EntryFromFloat64x2Bits(RecyclableObject* function, CallInfo callInfo, ...)
  65. {
  66. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  67. ARGUMENTS(args, callInfo);
  68. ScriptContext* scriptContext = function->GetScriptContext();
  69. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  70. Assert(!(callInfo.Flags & CallFlags_New));
  71. if (args.Info.Count >= 2 && JavascriptSIMDFloat64x2::Is(args[1]))
  72. {
  73. JavascriptSIMDFloat64x2 *instance = JavascriptSIMDFloat64x2::FromVar(args[1]);
  74. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDFloat64x2, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  75. }
  76. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromFloat64x2Bits"));
  77. }
  78. Var SIMDFloat32x4Lib::EntryFromInt32x4(RecyclableObject* function, CallInfo callInfo, ...)
  79. {
  80. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  81. ARGUMENTS(args, callInfo);
  82. ScriptContext* scriptContext = function->GetScriptContext();
  83. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  84. Assert(!(callInfo.Flags & CallFlags_New));
  85. if (args.Info.Count >= 2 && JavascriptSIMDInt32x4::Is(args[1]))
  86. {
  87. JavascriptSIMDInt32x4 *instance = JavascriptSIMDInt32x4::FromVar(args[1]);
  88. SIMDValue result = SIMDFloat32x4Operation::OpFromInt32x4(instance->GetValue());
  89. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  90. }
  91. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromInt32x4"));
  92. }
  93. Var SIMDFloat32x4Lib::EntryFromUint32x4(RecyclableObject* function, CallInfo callInfo, ...)
  94. {
  95. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  96. ARGUMENTS(args, callInfo);
  97. ScriptContext* scriptContext = function->GetScriptContext();
  98. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  99. Assert(!(callInfo.Flags & CallFlags_New));
  100. if (args.Info.Count >= 2 && JavascriptSIMDUint32x4::Is(args[1]))
  101. {
  102. JavascriptSIMDUint32x4 *instance = JavascriptSIMDUint32x4::FromVar(args[1]);
  103. SIMDValue result = SIMDFloat32x4Operation::OpFromUint32x4(instance->GetValue());
  104. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  105. }
  106. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromUint32x4"));
  107. }
  108. Var SIMDFloat32x4Lib::EntryFromInt32x4Bits(RecyclableObject* function, CallInfo callInfo, ...)
  109. {
  110. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  111. ARGUMENTS(args, callInfo);
  112. ScriptContext* scriptContext = function->GetScriptContext();
  113. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  114. Assert(!(callInfo.Flags & CallFlags_New));
  115. if (args.Info.Count >= 2 && JavascriptSIMDInt32x4::Is(args[1]))
  116. {
  117. JavascriptSIMDInt32x4 *instance = JavascriptSIMDInt32x4::FromVar(args[1]);
  118. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDInt32x4, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  119. }
  120. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromInt32x4Bits"));
  121. }
  122. Var SIMDFloat32x4Lib::EntryFromInt16x8Bits(RecyclableObject* function, CallInfo callInfo, ...)
  123. {
  124. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  125. ARGUMENTS(args, callInfo);
  126. ScriptContext* scriptContext = function->GetScriptContext();
  127. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  128. Assert(!(callInfo.Flags & CallFlags_New));
  129. if (args.Info.Count >= 2 && JavascriptSIMDInt16x8::Is(args[1]))
  130. {
  131. JavascriptSIMDInt16x8 *instance = JavascriptSIMDInt16x8::FromVar(args[1]);
  132. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDInt16x8, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  133. }
  134. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromInt16x8Bits"));
  135. }
  136. Var SIMDFloat32x4Lib::EntryFromInt8x16Bits(RecyclableObject* function, CallInfo callInfo, ...)
  137. {
  138. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  139. ARGUMENTS(args, callInfo);
  140. ScriptContext* scriptContext = function->GetScriptContext();
  141. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  142. Assert(!(callInfo.Flags & CallFlags_New));
  143. if (args.Info.Count >= 2 && JavascriptSIMDInt8x16::Is(args[1]))
  144. {
  145. JavascriptSIMDInt8x16 *instance = JavascriptSIMDInt8x16::FromVar(args[1]);
  146. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDInt8x16, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  147. }
  148. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromInt8x16Bits"));
  149. }
  150. Var SIMDFloat32x4Lib::EntryFromUint32x4Bits(RecyclableObject* function, CallInfo callInfo, ...)
  151. {
  152. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  153. ARGUMENTS(args, callInfo);
  154. ScriptContext* scriptContext = function->GetScriptContext();
  155. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  156. Assert(!(callInfo.Flags & CallFlags_New));
  157. if (args.Info.Count >= 2 && JavascriptSIMDUint32x4::Is(args[1]))
  158. {
  159. JavascriptSIMDUint32x4 *instance = JavascriptSIMDUint32x4::FromVar(args[1]);
  160. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDUint32x4, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  161. }
  162. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromUint32x4Bits"));
  163. }
  164. Var SIMDFloat32x4Lib::EntryFromUint16x8Bits(RecyclableObject* function, CallInfo callInfo, ...)
  165. {
  166. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  167. ARGUMENTS(args, callInfo);
  168. ScriptContext* scriptContext = function->GetScriptContext();
  169. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  170. Assert(!(callInfo.Flags & CallFlags_New));
  171. if (args.Info.Count >= 2 && JavascriptSIMDUint16x8::Is(args[1]))
  172. {
  173. JavascriptSIMDUint16x8 *instance = JavascriptSIMDUint16x8::FromVar(args[1]);
  174. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDUint16x8, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  175. }
  176. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromUint16x8Bits"));
  177. }
  178. Var SIMDFloat32x4Lib::EntryFromUint8x16Bits(RecyclableObject* function, CallInfo callInfo, ...)
  179. {
  180. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  181. ARGUMENTS(args, callInfo);
  182. ScriptContext* scriptContext = function->GetScriptContext();
  183. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  184. Assert(!(callInfo.Flags & CallFlags_New));
  185. if (args.Info.Count >= 2 && JavascriptSIMDUint8x16::Is(args[1]))
  186. {
  187. JavascriptSIMDUint8x16 *instance = JavascriptSIMDUint8x16::FromVar(args[1]);
  188. return SIMDUtils::SIMDConvertTypeFromBits<JavascriptSIMDUint8x16, JavascriptSIMDFloat32x4>(*instance, *scriptContext);
  189. }
  190. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("fromUint8x16Bits"));
  191. }
  192. //Lane Access
  193. Var SIMDFloat32x4Lib::EntryExtractLane(RecyclableObject* function, CallInfo callInfo, ...)
  194. {
  195. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  196. ARGUMENTS(args, callInfo);
  197. ScriptContext* scriptContext = function->GetScriptContext();
  198. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  199. Assert(!(callInfo.Flags & CallFlags_New));
  200. // first arg has to be of type float32x4, so cannot be missing.
  201. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]))
  202. {
  203. // if value arg is missing, then it is undefined.
  204. Var laneVar = args.Info.Count >= 3 ? args[2] : scriptContext->GetLibrary()->GetUndefined();
  205. float result = SIMDUtils::SIMD128ExtractLane<JavascriptSIMDFloat32x4, 4, float>(args[1], laneVar, scriptContext);
  206. return JavascriptNumber::ToVarWithCheck(result, scriptContext);
  207. }
  208. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("ExtractLane"));
  209. }
  210. Var SIMDFloat32x4Lib::EntryReplaceLane(RecyclableObject* function, CallInfo callInfo, ...)
  211. {
  212. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  213. ARGUMENTS(args, callInfo);
  214. ScriptContext* scriptContext = function->GetScriptContext();
  215. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  216. Assert(!(callInfo.Flags & CallFlags_New));
  217. // first arg has to be of type float32x4, so cannot be missing.
  218. if (args.Info.Count >= 4 && JavascriptSIMDFloat32x4::Is(args[1]))
  219. {
  220. // if value arg is missing, then it is undefined.
  221. Var laneVar = args.Info.Count >= 4 ? args[2] : scriptContext->GetLibrary()->GetUndefined();
  222. Var argVal = args.Info.Count >= 4 ? args[3] : scriptContext->GetLibrary()->GetUndefined();
  223. float value = JavascriptConversion::ToFloat(argVal, scriptContext);
  224. SIMDValue result = SIMDUtils::SIMD128ReplaceLane<JavascriptSIMDFloat32x4, 4, float>(args[1], laneVar, value, scriptContext);
  225. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  226. }
  227. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("ReplaceLane"));
  228. }
  229. // UnaryOps
  230. Var SIMDFloat32x4Lib::EntryAbs(RecyclableObject* function, CallInfo callInfo, ...)
  231. {
  232. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  233. ARGUMENTS(args, callInfo);
  234. ScriptContext* scriptContext = function->GetScriptContext();
  235. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  236. Assert(!(callInfo.Flags & CallFlags_New));
  237. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  238. {
  239. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  240. SIMDValue result = SIMDFloat32x4Operation::OpAbs(a->GetValue());
  241. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  242. }
  243. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("abs"));
  244. }
  245. Var SIMDFloat32x4Lib::EntryNeg(RecyclableObject* function, CallInfo callInfo, ...)
  246. {
  247. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  248. ARGUMENTS(args, callInfo);
  249. ScriptContext* scriptContext = function->GetScriptContext();
  250. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  251. Assert(!(callInfo.Flags & CallFlags_New));
  252. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  253. {
  254. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  255. SIMDValue result = SIMDFloat32x4Operation::OpNeg(a->GetValue());
  256. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  257. }
  258. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("neg"));
  259. }
  260. Var SIMDFloat32x4Lib::EntryNot(RecyclableObject* function, CallInfo callInfo, ...)
  261. {
  262. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  263. ARGUMENTS(args, callInfo);
  264. ScriptContext* scriptContext = function->GetScriptContext();
  265. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  266. Assert(!(callInfo.Flags & CallFlags_New));
  267. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  268. {
  269. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  270. SIMDValue result = SIMDFloat32x4Operation::OpNot(a->GetValue());
  271. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  272. }
  273. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("not"));
  274. }
  275. Var SIMDFloat32x4Lib::EntryReciprocal(RecyclableObject* function, CallInfo callInfo, ...)
  276. {
  277. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  278. ARGUMENTS(args, callInfo);
  279. ScriptContext* scriptContext = function->GetScriptContext();
  280. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  281. Assert(!(callInfo.Flags & CallFlags_New));
  282. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  283. {
  284. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  285. SIMDValue result = SIMDFloat32x4Operation::OpReciprocal(a->GetValue());
  286. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  287. }
  288. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("reciprocalApproximation"));
  289. }
  290. Var SIMDFloat32x4Lib::EntryReciprocalSqrt(RecyclableObject* function, CallInfo callInfo, ...)
  291. {
  292. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  293. ARGUMENTS(args, callInfo);
  294. ScriptContext* scriptContext = function->GetScriptContext();
  295. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  296. Assert(!(callInfo.Flags & CallFlags_New));
  297. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  298. {
  299. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  300. SIMDValue result = SIMDFloat32x4Operation::OpReciprocalSqrt(a->GetValue());
  301. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  302. }
  303. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("reciprocalSqrtApproximation"));
  304. }
  305. Var SIMDFloat32x4Lib::EntrySqrt(RecyclableObject* function, CallInfo callInfo, ...)
  306. {
  307. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  308. ARGUMENTS(args, callInfo);
  309. ScriptContext* scriptContext = function->GetScriptContext();
  310. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  311. Assert(!(callInfo.Flags & CallFlags_New));
  312. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  313. {
  314. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  315. SIMDValue result = SIMDFloat32x4Operation::OpSqrt(a->GetValue());
  316. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  317. }
  318. else
  319. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("sqrt"));
  320. }
  321. Var SIMDFloat32x4Lib::EntryAdd(RecyclableObject* function, CallInfo callInfo, ...)
  322. {
  323. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  324. ARGUMENTS(args, callInfo);
  325. ScriptContext* scriptContext = function->GetScriptContext();
  326. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  327. Assert(!(callInfo.Flags & CallFlags_New));
  328. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  329. // strict type on both operands
  330. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  331. {
  332. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  333. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  334. SIMDValue result, aValue, bValue;
  335. aValue = a->GetValue();
  336. bValue = b->GetValue();
  337. result = SIMDFloat32x4Operation::OpAdd(aValue, bValue);
  338. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  339. }
  340. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("add"));
  341. }
  342. Var SIMDFloat32x4Lib::EntrySub(RecyclableObject* function, CallInfo callInfo, ...)
  343. {
  344. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  345. ARGUMENTS(args, callInfo);
  346. ScriptContext* scriptContext = function->GetScriptContext();
  347. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  348. Assert(!(callInfo.Flags & CallFlags_New));
  349. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  350. // strict type on both operands
  351. if (args.Info.Count >= 3)
  352. {
  353. // strict type on both operands
  354. if (JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  355. {
  356. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  357. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  358. SIMDValue result, aValue, bValue;
  359. aValue = a->GetValue();
  360. bValue = b->GetValue();
  361. result = SIMDFloat32x4Operation::OpSub(aValue, bValue);
  362. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  363. }
  364. }
  365. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("sub"));
  366. }
  367. Var SIMDFloat32x4Lib::EntryMul(RecyclableObject* function, CallInfo callInfo, ...)
  368. {
  369. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  370. ARGUMENTS(args, callInfo);
  371. ScriptContext* scriptContext = function->GetScriptContext();
  372. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  373. Assert(!(callInfo.Flags & CallFlags_New));
  374. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  375. // strict type on both operands
  376. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  377. {
  378. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  379. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  380. SIMDValue result, aValue, bValue;
  381. aValue = a->GetValue();
  382. bValue = b->GetValue();
  383. result = SIMDFloat32x4Operation::OpMul(aValue, bValue);
  384. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  385. }
  386. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("mul"));
  387. }
  388. Var SIMDFloat32x4Lib::EntryDiv(RecyclableObject* function, CallInfo callInfo, ...)
  389. {
  390. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  391. ARGUMENTS(args, callInfo);
  392. ScriptContext* scriptContext = function->GetScriptContext();
  393. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  394. Assert(!(callInfo.Flags & CallFlags_New));
  395. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  396. // strict type on both operands
  397. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  398. {
  399. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  400. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  401. SIMDValue result, aValue, bValue;
  402. aValue = a->GetValue();
  403. bValue = b->GetValue();
  404. result = SIMDFloat32x4Operation::OpDiv(aValue, bValue);
  405. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  406. }
  407. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("div"));
  408. }
  409. Var SIMDFloat32x4Lib::EntryAnd(RecyclableObject* function, CallInfo callInfo, ...)
  410. {
  411. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  412. ARGUMENTS(args, callInfo);
  413. ScriptContext* scriptContext = function->GetScriptContext();
  414. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  415. Assert(!(callInfo.Flags & CallFlags_New));
  416. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  417. // strict type on both operands
  418. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  419. {
  420. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  421. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  422. SIMDValue result, aValue, bValue;
  423. aValue = a->GetValue();
  424. bValue = b->GetValue();
  425. result = SIMDFloat32x4Operation::OpAnd(aValue, bValue);
  426. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  427. }
  428. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("and"));
  429. }
  430. Var SIMDFloat32x4Lib::EntryOr(RecyclableObject* function, CallInfo callInfo, ...)
  431. {
  432. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  433. ARGUMENTS(args, callInfo);
  434. ScriptContext* scriptContext = function->GetScriptContext();
  435. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  436. Assert(!(callInfo.Flags & CallFlags_New));
  437. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  438. // strict type on both operands
  439. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  440. {
  441. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  442. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  443. SIMDValue result, aValue, bValue;
  444. aValue = a->GetValue();
  445. bValue = b->GetValue();
  446. result = SIMDFloat32x4Operation::OpOr(aValue, bValue);
  447. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  448. }
  449. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("or"));
  450. }
  451. Var SIMDFloat32x4Lib::EntryXor(RecyclableObject* function, CallInfo callInfo, ...)
  452. {
  453. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  454. ARGUMENTS(args, callInfo);
  455. ScriptContext* scriptContext = function->GetScriptContext();
  456. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  457. Assert(!(callInfo.Flags & CallFlags_New));
  458. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  459. // strict type on both operands
  460. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  461. {
  462. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  463. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  464. SIMDValue result, aValue, bValue;
  465. aValue = a->GetValue();
  466. bValue = b->GetValue();
  467. result = SIMDFloat32x4Operation::OpXor(aValue, bValue);
  468. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  469. }
  470. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("xor"));
  471. }
  472. Var SIMDFloat32x4Lib::EntryMin(RecyclableObject* function, CallInfo callInfo, ...)
  473. {
  474. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  475. ARGUMENTS(args, callInfo);
  476. ScriptContext* scriptContext = function->GetScriptContext();
  477. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  478. Assert(!(callInfo.Flags & CallFlags_New));
  479. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  480. // strict type on both operands
  481. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  482. {
  483. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  484. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  485. SIMDValue result, aValue, bValue;
  486. aValue = a->GetValue();
  487. bValue = b->GetValue();
  488. result = SIMDFloat32x4Operation::OpMin(aValue, bValue);
  489. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  490. }
  491. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("min"));
  492. }
  493. Var SIMDFloat32x4Lib::EntryMax(RecyclableObject* function, CallInfo callInfo, ...)
  494. {
  495. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  496. ARGUMENTS(args, callInfo);
  497. ScriptContext* scriptContext = function->GetScriptContext();
  498. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  499. Assert(!(callInfo.Flags & CallFlags_New));
  500. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  501. // strict type on both operands
  502. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  503. {
  504. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  505. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  506. SIMDValue result, aValue, bValue;
  507. aValue = a->GetValue();
  508. bValue = b->GetValue();
  509. result = SIMDFloat32x4Operation::OpMax(aValue, bValue);
  510. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  511. }
  512. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("maxNum"));
  513. }
  514. Var SIMDFloat32x4Lib::EntryMinNum(RecyclableObject* function, CallInfo callInfo, ...)
  515. {
  516. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  517. ARGUMENTS(args, callInfo);
  518. ScriptContext* scriptContext = function->GetScriptContext();
  519. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  520. Assert(!(callInfo.Flags & CallFlags_New));
  521. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  522. // strict type on both operands
  523. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  524. {
  525. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  526. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  527. SIMDValue result, aValue, bValue;
  528. aValue = a->GetValue();
  529. bValue = b->GetValue();
  530. result = SIMDFloat32x4Operation::OpMinNum(aValue, bValue);
  531. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  532. }
  533. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("minNum"));
  534. }
  535. Var SIMDFloat32x4Lib::EntryMaxNum(RecyclableObject* function, CallInfo callInfo, ...)
  536. {
  537. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  538. ARGUMENTS(args, callInfo);
  539. ScriptContext* scriptContext = function->GetScriptContext();
  540. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  541. Assert(!(callInfo.Flags & CallFlags_New));
  542. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  543. // strict type on both operands
  544. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  545. {
  546. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  547. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  548. SIMDValue result, aValue, bValue;
  549. aValue = a->GetValue();
  550. bValue = b->GetValue();
  551. result = SIMDFloat32x4Operation::OpMaxNum(aValue, bValue);
  552. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  553. }
  554. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("max"));
  555. }
  556. Var SIMDFloat32x4Lib::EntryScale(RecyclableObject* function, CallInfo callInfo, ...)
  557. {
  558. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  559. ARGUMENTS(args, callInfo);
  560. ScriptContext* scriptContext = function->GetScriptContext();
  561. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  562. Assert(!(callInfo.Flags & CallFlags_New));
  563. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  564. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]))
  565. {
  566. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  567. SIMDValue result, aValue;
  568. aValue = a->GetValue();
  569. float scaleValue = JavascriptConversion::ToFloat(args[2], scriptContext);
  570. result = SIMDFloat32x4Operation::OpScale(aValue, scaleValue);
  571. return JavascriptSIMDFloat32x4::New(&result, scriptContext);
  572. }
  573. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("scale"));
  574. }
  575. Var SIMDFloat32x4Lib::EntryLessThan(RecyclableObject* function, CallInfo callInfo, ...)
  576. {
  577. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  578. ARGUMENTS(args, callInfo);
  579. ScriptContext* scriptContext = function->GetScriptContext();
  580. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  581. Assert(!(callInfo.Flags & CallFlags_New));
  582. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  583. // strict type on both operands
  584. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  585. {
  586. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  587. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  588. SIMDValue result, aValue, bValue;
  589. aValue = a->GetValue();
  590. bValue = b->GetValue();
  591. result = SIMDFloat32x4Operation::OpLessThan(aValue, bValue);
  592. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  593. }
  594. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("lessThan"));
  595. }
  596. Var SIMDFloat32x4Lib::EntryLessThanOrEqual(RecyclableObject* function, CallInfo callInfo, ...)
  597. {
  598. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  599. ARGUMENTS(args, callInfo);
  600. ScriptContext* scriptContext = function->GetScriptContext();
  601. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  602. Assert(!(callInfo.Flags & CallFlags_New));
  603. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  604. // strict type on both operands
  605. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  606. {
  607. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  608. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  609. SIMDValue result, aValue, bValue;
  610. aValue = a->GetValue();
  611. bValue = b->GetValue();
  612. result = SIMDFloat32x4Operation::OpLessThanOrEqual(aValue, bValue);
  613. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  614. }
  615. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("lessThanOrEqual"));
  616. }
  617. Var SIMDFloat32x4Lib::EntryEqual(RecyclableObject* function, CallInfo callInfo, ...)
  618. {
  619. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  620. ARGUMENTS(args, callInfo);
  621. ScriptContext* scriptContext = function->GetScriptContext();
  622. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  623. Assert(!(callInfo.Flags & CallFlags_New));
  624. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  625. // strict type on both operands
  626. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  627. {
  628. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  629. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  630. SIMDValue result, aValue, bValue;
  631. aValue = a->GetValue();
  632. bValue = b->GetValue();
  633. result = SIMDFloat32x4Operation::OpEqual(aValue, bValue);
  634. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  635. }
  636. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("equal"));
  637. }
  638. Var SIMDFloat32x4Lib::EntryNotEqual(RecyclableObject* function, CallInfo callInfo, ...)
  639. {
  640. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  641. ARGUMENTS(args, callInfo);
  642. ScriptContext* scriptContext = function->GetScriptContext();
  643. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  644. Assert(!(callInfo.Flags & CallFlags_New));
  645. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  646. // strict type on both operands
  647. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  648. {
  649. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  650. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  651. SIMDValue result, aValue, bValue;
  652. aValue = a->GetValue();
  653. bValue = b->GetValue();
  654. result = SIMDFloat32x4Operation::OpNotEqual(aValue, bValue);
  655. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  656. }
  657. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("NotEqual"));
  658. }
  659. Var SIMDFloat32x4Lib::EntryGreaterThan(RecyclableObject* function, CallInfo callInfo, ...)
  660. {
  661. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  662. ARGUMENTS(args, callInfo);
  663. ScriptContext* scriptContext = function->GetScriptContext();
  664. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  665. Assert(!(callInfo.Flags & CallFlags_New));
  666. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  667. // strict type on both operands
  668. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  669. {
  670. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  671. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  672. SIMDValue result, aValue, bValue;
  673. aValue = a->GetValue();
  674. bValue = b->GetValue();
  675. result = SIMDFloat32x4Operation::OpGreaterThan(aValue, bValue);
  676. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  677. }
  678. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("greaterThan"));
  679. }
  680. Var SIMDFloat32x4Lib::EntryGreaterThanOrEqual(RecyclableObject* function, CallInfo callInfo, ...)
  681. {
  682. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  683. ARGUMENTS(args, callInfo);
  684. ScriptContext* scriptContext = function->GetScriptContext();
  685. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  686. Assert(!(callInfo.Flags & CallFlags_New));
  687. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  688. // strict type on both operands
  689. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  690. {
  691. JavascriptSIMDFloat32x4 *a = JavascriptSIMDFloat32x4::FromVar(args[1]);
  692. JavascriptSIMDFloat32x4 *b = JavascriptSIMDFloat32x4::FromVar(args[2]);
  693. SIMDValue result, aValue, bValue;
  694. aValue = a->GetValue();
  695. bValue = b->GetValue();
  696. result = SIMDFloat32x4Operation::OpGreaterThanOrEqual(aValue, bValue);
  697. return JavascriptSIMDBool32x4::New(&result, scriptContext);
  698. }
  699. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("greaterThanOrEqual"));
  700. }
  701. Var SIMDFloat32x4Lib::EntrySwizzle(RecyclableObject* function, CallInfo callInfo, ...)
  702. {
  703. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  704. ARGUMENTS(args, callInfo);
  705. ScriptContext* scriptContext = function->GetScriptContext();
  706. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  707. Assert(!(callInfo.Flags & CallFlags_New));
  708. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  709. if (args.Info.Count >= 2 && JavascriptSIMDFloat32x4::Is(args[1]))
  710. {
  711. // type check on lane indices
  712. if (args.Info.Count < 6)
  713. {
  714. // missing lane args
  715. JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedNumber, _u("Lane index"));
  716. }
  717. Var lane0 = args[2];
  718. Var lane1 = args[3];
  719. Var lane2 = args[4];
  720. Var lane3 = args[5];
  721. return SIMDUtils::SIMD128SlowShuffle<JavascriptSIMDFloat32x4>(args[1], args[1], lane0, lane1, lane2, lane3, 4, scriptContext);
  722. }
  723. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("swizzle"));
  724. }
  725. Var SIMDFloat32x4Lib::EntryShuffle(RecyclableObject* function, CallInfo callInfo, ...)
  726. {
  727. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  728. ARGUMENTS(args, callInfo);
  729. ScriptContext* scriptContext = function->GetScriptContext();
  730. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  731. Assert(!(callInfo.Flags & CallFlags_New));
  732. // If any of the args are missing, then it is Undefined type which causes TypeError exception.
  733. // strict type on both operands
  734. if (args.Info.Count >= 3 && JavascriptSIMDFloat32x4::Is(args[1]) && JavascriptSIMDFloat32x4::Is(args[2]))
  735. {
  736. // type check on lane indices
  737. if (args.Info.Count < 7)
  738. {
  739. // missing lane args
  740. JavascriptError::ThrowTypeError(scriptContext, JSERR_NeedNumber, _u("Lane index"));
  741. }
  742. Var lane0 = args[3];
  743. Var lane1 = args[4];
  744. Var lane2 = args[5];
  745. Var lane3 = args[6];
  746. return SIMDUtils::SIMD128SlowShuffle<JavascriptSIMDFloat32x4>(args[1], args[2], lane0, lane1, lane2, lane3, 8, scriptContext);
  747. }
  748. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("shuffle"));
  749. }
  750. Var SIMDFloat32x4Lib::EntryClamp(RecyclableObject* function, CallInfo callInfo, ...)
  751. {
  752. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  753. ARGUMENTS(args, callInfo);
  754. ScriptContext* scriptContext = function->GetScriptContext();
  755. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  756. Assert(!(callInfo.Flags & CallFlags_New));
  757. // we expect at least 3 explicit args with Float32x4 type
  758. if (args.Info.Count >= 4 &&
  759. JavascriptSIMDFloat32x4::Is(args[1]) &&
  760. JavascriptSIMDFloat32x4::Is(args[2]) &&
  761. JavascriptSIMDFloat32x4::Is(args[3]))
  762. {
  763. JavascriptSIMDFloat32x4 *t = JavascriptSIMDFloat32x4::FromVar(args[1]);
  764. JavascriptSIMDFloat32x4 *lower = JavascriptSIMDFloat32x4::FromVar(args[2]);
  765. JavascriptSIMDFloat32x4 *upper = JavascriptSIMDFloat32x4::FromVar(args[3]);
  766. Assert(t && lower && upper);
  767. SIMDValue tValue, lowerValue, upperValue, resultValue;
  768. tValue = t->GetValue();
  769. lowerValue = lower->GetValue();
  770. upperValue = upper->GetValue();
  771. resultValue = SIMDFloat32x4Operation::OpClamp(tValue, lowerValue, upperValue);
  772. return JavascriptSIMDFloat32x4::New(&resultValue, scriptContext);
  773. }
  774. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("clamp"));
  775. }
  776. Var SIMDFloat32x4Lib::EntrySelect(RecyclableObject* function, CallInfo callInfo, ...)
  777. {
  778. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  779. ARGUMENTS(args, callInfo);
  780. ScriptContext* scriptContext = function->GetScriptContext();
  781. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  782. Assert(!(callInfo.Flags & CallFlags_New));
  783. // we expect at least 3 explicit args (Int32x4, Float32x4, Float32x4)
  784. if (args.Info.Count >= 4 &&
  785. JavascriptSIMDBool32x4::Is(args[1]) &&
  786. JavascriptSIMDFloat32x4::Is(args[2]) &&
  787. JavascriptSIMDFloat32x4::Is(args[3]))
  788. {
  789. JavascriptSIMDBool32x4 *fmask = JavascriptSIMDBool32x4::FromVar(args[1]);
  790. Assert(fmask);
  791. JavascriptSIMDFloat32x4 *tvalue = JavascriptSIMDFloat32x4::FromVar(args[2]);
  792. JavascriptSIMDFloat32x4 *fvalue = JavascriptSIMDFloat32x4::FromVar(args[3]);
  793. Assert(fmask && tvalue && fvalue);
  794. SIMDValue maskValue, trueValue, falseValue, resultValue;
  795. maskValue = fmask->GetValue();
  796. trueValue = tvalue->GetValue();
  797. falseValue = fvalue->GetValue();
  798. resultValue = SIMDFloat32x4Operation::OpSelect(maskValue, trueValue, falseValue);
  799. return JavascriptSIMDFloat32x4::New(&resultValue, scriptContext);
  800. }
  801. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdFloat32x4TypeMismatch, _u("select"));
  802. }
  803. Var SIMDFloat32x4Lib::EntryLoad(RecyclableObject* function, CallInfo callInfo, ...)
  804. {
  805. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  806. ARGUMENTS(args, callInfo);
  807. ScriptContext* scriptContext = function->GetScriptContext();
  808. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  809. Assert(!(callInfo.Flags & CallFlags_New));
  810. return SIMDUtils::SIMD128TypedArrayLoad<JavascriptSIMDFloat32x4>(args[1], args[2], 4 * FLOAT32_SIZE, scriptContext);
  811. }
  812. Var SIMDFloat32x4Lib::EntryLoad1(RecyclableObject* function, CallInfo callInfo, ...)
  813. {
  814. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  815. ARGUMENTS(args, callInfo);
  816. ScriptContext* scriptContext = function->GetScriptContext();
  817. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  818. Assert(!(callInfo.Flags & CallFlags_New));
  819. return SIMDUtils::SIMD128TypedArrayLoad<JavascriptSIMDFloat32x4>(args[1], args[2], 1 * FLOAT32_SIZE, scriptContext);
  820. }
  821. Var SIMDFloat32x4Lib::EntryLoad2(RecyclableObject* function, CallInfo callInfo, ...)
  822. {
  823. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  824. ARGUMENTS(args, callInfo);
  825. ScriptContext* scriptContext = function->GetScriptContext();
  826. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  827. Assert(!(callInfo.Flags & CallFlags_New));
  828. return SIMDUtils::SIMD128TypedArrayLoad<JavascriptSIMDFloat32x4>(args[1], args[2], 2 * FLOAT32_SIZE, scriptContext);
  829. }
  830. Var SIMDFloat32x4Lib::EntryLoad3(RecyclableObject* function, CallInfo callInfo, ...)
  831. {
  832. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  833. ARGUMENTS(args, callInfo);
  834. ScriptContext* scriptContext = function->GetScriptContext();
  835. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  836. Assert(!(callInfo.Flags & CallFlags_New));
  837. return SIMDUtils::SIMD128TypedArrayLoad<JavascriptSIMDFloat32x4>(args[1], args[2], 3 * FLOAT32_SIZE, scriptContext);
  838. }
  839. Var SIMDFloat32x4Lib::EntryStore(RecyclableObject* function, CallInfo callInfo, ...)
  840. {
  841. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  842. ARGUMENTS(args, callInfo);
  843. ScriptContext* scriptContext = function->GetScriptContext();
  844. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  845. Assert(!(callInfo.Flags & CallFlags_New));
  846. if (args.Info.Count >= 4 && JavascriptSIMDFloat32x4::Is(args[3]))
  847. {
  848. SIMDUtils::SIMD128TypedArrayStore<JavascriptSIMDFloat32x4>(args[1], args[2], args[3], 4 * FLOAT32_SIZE, scriptContext);
  849. return JavascriptSIMDFloat32x4::FromVar(args[3]);
  850. }
  851. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdInvalidArgType, _u("SIMD.Float32x4.store"));
  852. }
  853. Var SIMDFloat32x4Lib::EntryStore1(RecyclableObject* function, CallInfo callInfo, ...)
  854. {
  855. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  856. ARGUMENTS(args, callInfo);
  857. ScriptContext* scriptContext = function->GetScriptContext();
  858. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  859. Assert(!(callInfo.Flags & CallFlags_New));
  860. if (args.Info.Count >= 4 && JavascriptSIMDFloat32x4::Is(args[3]))
  861. {
  862. SIMDUtils::SIMD128TypedArrayStore<JavascriptSIMDFloat32x4>(args[1], args[2], args[3], 1 * FLOAT32_SIZE, scriptContext);
  863. return JavascriptSIMDFloat32x4::FromVar(args[3]);
  864. }
  865. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdInvalidArgType, _u("SIMD.Float32x4.store"));
  866. }
  867. Var SIMDFloat32x4Lib::EntryStore2(RecyclableObject* function, CallInfo callInfo, ...)
  868. {
  869. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  870. ARGUMENTS(args, callInfo);
  871. ScriptContext* scriptContext = function->GetScriptContext();
  872. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  873. Assert(!(callInfo.Flags & CallFlags_New));
  874. if (args.Info.Count >= 4 && JavascriptSIMDFloat32x4::Is(args[3]))
  875. {
  876. SIMDUtils::SIMD128TypedArrayStore<JavascriptSIMDFloat32x4>(args[1], args[2], args[3], 2 * FLOAT32_SIZE, scriptContext);
  877. return JavascriptSIMDFloat32x4::FromVar(args[3]);
  878. }
  879. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdInvalidArgType, _u("SIMD.Float32x4.store"));
  880. }
  881. Var SIMDFloat32x4Lib::EntryStore3(RecyclableObject* function, CallInfo callInfo, ...)
  882. {
  883. PROBE_STACK(function->GetScriptContext(), Js::Constants::MinStackDefault);
  884. ARGUMENTS(args, callInfo);
  885. ScriptContext* scriptContext = function->GetScriptContext();
  886. AssertMsg(args.Info.Count > 0, "Should always have implicit 'this'");
  887. Assert(!(callInfo.Flags & CallFlags_New));
  888. if (args.Info.Count >= 4 && JavascriptSIMDFloat32x4::Is(args[3]))
  889. {
  890. SIMDUtils::SIMD128TypedArrayStore<JavascriptSIMDFloat32x4>(args[1], args[2], args[3], 3 * FLOAT32_SIZE, scriptContext);
  891. return JavascriptSIMDFloat32x4::FromVar(args[3]);
  892. }
  893. JavascriptError::ThrowTypeError(scriptContext, JSERR_SimdInvalidArgType, _u("SIMD.Float32x4.store"));
  894. }
  895. }