1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 
8 #if defined(JS_SIMULATOR_ARM)
9 
10 #  include "jit/arm/Assembler-arm.h"
11 #  include "jit/arm/MoveEmitter-arm.h"
12 #  include "jit/arm/Simulator-arm.h"
13 #  include "jit/Linker.h"
14 #  include "jit/MacroAssembler.h"
15 #  include "jit/MoveResolver.h"
16 
17 #  include "jsapi-tests/tests.h"
18 
19 #  include "vm/Runtime.h"
20 
21 static const int LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 4 * 1024;
22 
23 static constexpr js::jit::FloatRegister s0(0, js::jit::VFPRegister::Single);
24 static constexpr js::jit::FloatRegister s1(1, js::jit::VFPRegister::Single);
25 static constexpr js::jit::FloatRegister s2(2, js::jit::VFPRegister::Single);
26 static constexpr js::jit::FloatRegister s3(3, js::jit::VFPRegister::Single);
27 static constexpr js::jit::FloatRegister s4(4, js::jit::VFPRegister::Single);
28 static constexpr js::jit::FloatRegister s5(5, js::jit::VFPRegister::Single);
29 static constexpr js::jit::FloatRegister s6(6, js::jit::VFPRegister::Single);
30 static constexpr js::jit::FloatRegister s7(7, js::jit::VFPRegister::Single);
31 static constexpr js::jit::FloatRegister s8(8, js::jit::VFPRegister::Single);
32 static constexpr js::jit::FloatRegister s9(9, js::jit::VFPRegister::Single);
33 static constexpr js::jit::FloatRegister s10(10, js::jit::VFPRegister::Single);
34 static constexpr js::jit::FloatRegister s11(11, js::jit::VFPRegister::Single);
35 static constexpr js::jit::FloatRegister s12(12, js::jit::VFPRegister::Single);
36 static constexpr js::jit::FloatRegister s13(13, js::jit::VFPRegister::Single);
37 static constexpr js::jit::FloatRegister s14(14, js::jit::VFPRegister::Single);
38 static constexpr js::jit::FloatRegister s15(15, js::jit::VFPRegister::Single);
39 static constexpr js::jit::FloatRegister s16(16, js::jit::VFPRegister::Single);
40 static constexpr js::jit::FloatRegister s17(17, js::jit::VFPRegister::Single);
41 static constexpr js::jit::FloatRegister s18(18, js::jit::VFPRegister::Single);
42 static constexpr js::jit::FloatRegister s19(19, js::jit::VFPRegister::Single);
43 static constexpr js::jit::FloatRegister s20(20, js::jit::VFPRegister::Single);
44 static constexpr js::jit::FloatRegister s21(21, js::jit::VFPRegister::Single);
45 static constexpr js::jit::FloatRegister s22(22, js::jit::VFPRegister::Single);
46 static constexpr js::jit::FloatRegister s23(23, js::jit::VFPRegister::Single);
47 static constexpr js::jit::FloatRegister s24(24, js::jit::VFPRegister::Single);
48 static constexpr js::jit::FloatRegister s25(25, js::jit::VFPRegister::Single);
49 static constexpr js::jit::FloatRegister s26(26, js::jit::VFPRegister::Single);
50 static constexpr js::jit::FloatRegister s27(27, js::jit::VFPRegister::Single);
51 static constexpr js::jit::FloatRegister s28(28, js::jit::VFPRegister::Single);
52 static constexpr js::jit::FloatRegister s29(29, js::jit::VFPRegister::Single);
53 static constexpr js::jit::FloatRegister s30(30, js::jit::VFPRegister::Single);
54 static constexpr js::jit::FloatRegister s31(31, js::jit::VFPRegister::Single);
55 
linkAndAllocate(JSContext * cx,js::jit::MacroAssembler * masm)56 static js::jit::JitCode* linkAndAllocate(JSContext* cx,
57                                          js::jit::MacroAssembler* masm) {
58   using namespace js;
59   using namespace js::jit;
60   Linker l(*masm);
61   return l.newCode(cx, CodeKind::Ion);
62 }
63 
64 #  define TRY(x) \
65     if (!(x)) return false;
66 
BEGIN_TEST(testJitMoveEmitterCycles_simple)67 BEGIN_TEST(testJitMoveEmitterCycles_simple) {
68   using namespace js;
69   using namespace js::jit;
70   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
71   TempAllocator alloc(&lifo);
72   JitContext jc(cx, &alloc);
73   StackMacroAssembler masm;
74   MoveEmitter mover(masm);
75   MoveResolver mr;
76   mr.setAllocator(alloc);
77   Simulator* sim = Simulator::Current();
78   TRY(mr.addMove(MoveOperand(d0), MoveOperand(d2), MoveOp::DOUBLE));
79   sim->set_d_register_from_double(0, 2);
80   TRY(mr.addMove(MoveOperand(d3), MoveOperand(d1), MoveOp::DOUBLE));
81   sim->set_d_register_from_double(3, 1);
82   TRY(mr.addMove(MoveOperand(s4), MoveOperand(s0), MoveOp::FLOAT32));
83   sim->set_s_register_from_float(4, 0);
84   TRY(mr.addMove(MoveOperand(s5), MoveOperand(s6), MoveOp::FLOAT32));
85   sim->set_s_register_from_float(5, 6);
86   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s1), MoveOp::FLOAT32));
87   sim->set_s_register_from_float(2, 1);
88   TRY(mr.addMove(MoveOperand(s3), MoveOperand(s7), MoveOp::FLOAT32));
89   sim->set_s_register_from_float(3, 7);
90   // don't explode!
91   TRY(mr.resolve());
92   mover.emit(mr);
93   mover.finish();
94   masm.abiret();
95   JitCode* code = linkAndAllocate(cx, &masm);
96   sim->call(code->raw(), 1, 1);
97   float f;
98   double d;
99   sim->get_double_from_d_register(2, &d);
100   CHECK(d == 2);
101   sim->get_double_from_d_register(1, &d);
102   CHECK(int(d) == 1);
103   sim->get_float_from_s_register(0, &f);
104   CHECK(int(f) == 0);
105   sim->get_float_from_s_register(6, &f);
106   CHECK(int(f) == 6);
107   sim->get_float_from_s_register(1, &f);
108   CHECK(int(f) == 1);
109   sim->get_float_from_s_register(7, &f);
110   CHECK(int(f) == 7);
111   return true;
112 }
113 END_TEST(testJitMoveEmitterCycles_simple)
BEGIN_TEST(testJitMoveEmitterCycles_autogen)114 BEGIN_TEST(testJitMoveEmitterCycles_autogen) {
115   using namespace js;
116   using namespace js::jit;
117   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
118   TempAllocator alloc(&lifo);
119   JitContext jc(cx, &alloc);
120   StackMacroAssembler masm;
121   MoveEmitter mover(masm);
122   MoveResolver mr;
123   mr.setAllocator(alloc);
124   Simulator* sim = Simulator::Current();
125   TRY(mr.addMove(MoveOperand(d9), MoveOperand(d14), MoveOp::DOUBLE));
126   sim->set_d_register_from_double(9, 9);
127   TRY(mr.addMove(MoveOperand(s24), MoveOperand(s25), MoveOp::FLOAT32));
128   sim->set_s_register_from_float(24, 24);
129   TRY(mr.addMove(MoveOperand(d3), MoveOperand(d0), MoveOp::DOUBLE));
130   sim->set_d_register_from_double(3, 3);
131   TRY(mr.addMove(MoveOperand(s10), MoveOperand(s31), MoveOp::FLOAT32));
132   sim->set_s_register_from_float(10, 10);
133   TRY(mr.addMove(MoveOperand(d1), MoveOperand(d10), MoveOp::DOUBLE));
134   sim->set_d_register_from_double(1, 1);
135   TRY(mr.addMove(MoveOperand(s8), MoveOperand(s10), MoveOp::FLOAT32));
136   sim->set_s_register_from_float(8, 8);
137   TRY(mr.addMove(MoveOperand(d2), MoveOperand(d7), MoveOp::DOUBLE));
138   sim->set_d_register_from_double(2, 2);
139   TRY(mr.addMove(MoveOperand(s20), MoveOperand(s18), MoveOp::FLOAT32));
140   sim->set_s_register_from_float(20, 20);
141   TRY(mr.addMove(MoveOperand(s1), MoveOperand(s3), MoveOp::FLOAT32));
142   sim->set_s_register_from_float(1, 1);
143   TRY(mr.addMove(MoveOperand(s17), MoveOperand(s11), MoveOp::FLOAT32));
144   sim->set_s_register_from_float(17, 17);
145   TRY(mr.addMove(MoveOperand(s22), MoveOperand(s30), MoveOp::FLOAT32));
146   sim->set_s_register_from_float(22, 22);
147   TRY(mr.addMove(MoveOperand(s31), MoveOperand(s7), MoveOp::FLOAT32));
148   sim->set_s_register_from_float(31, 31);
149   TRY(mr.addMove(MoveOperand(d3), MoveOperand(d13), MoveOp::DOUBLE));
150   sim->set_d_register_from_double(3, 3);
151   TRY(mr.addMove(MoveOperand(d9), MoveOperand(d8), MoveOp::DOUBLE));
152   sim->set_d_register_from_double(9, 9);
153   TRY(mr.addMove(MoveOperand(s31), MoveOperand(s23), MoveOp::FLOAT32));
154   sim->set_s_register_from_float(31, 31);
155   TRY(mr.addMove(MoveOperand(s13), MoveOperand(s8), MoveOp::FLOAT32));
156   sim->set_s_register_from_float(13, 13);
157   TRY(mr.addMove(MoveOperand(s28), MoveOperand(s5), MoveOp::FLOAT32));
158   sim->set_s_register_from_float(28, 28);
159   TRY(mr.addMove(MoveOperand(s31), MoveOperand(s19), MoveOp::FLOAT32));
160   sim->set_s_register_from_float(31, 31);
161   TRY(mr.addMove(MoveOperand(s20), MoveOperand(s6), MoveOp::FLOAT32));
162   sim->set_s_register_from_float(20, 20);
163   TRY(mr.addMove(MoveOperand(s0), MoveOperand(s2), MoveOp::FLOAT32));
164   sim->set_s_register_from_float(0, 0);
165   TRY(mr.addMove(MoveOperand(d7), MoveOperand(d6), MoveOp::DOUBLE));
166   sim->set_d_register_from_double(7, 7);
167   TRY(mr.addMove(MoveOperand(s13), MoveOperand(s9), MoveOp::FLOAT32));
168   sim->set_s_register_from_float(13, 13);
169   TRY(mr.addMove(MoveOperand(s1), MoveOperand(s4), MoveOp::FLOAT32));
170   sim->set_s_register_from_float(1, 1);
171   TRY(mr.addMove(MoveOperand(s29), MoveOperand(s22), MoveOp::FLOAT32));
172   sim->set_s_register_from_float(29, 29);
173   TRY(mr.addMove(MoveOperand(s25), MoveOperand(s24), MoveOp::FLOAT32));
174   sim->set_s_register_from_float(25, 25);
175   // don't explode!
176   TRY(mr.resolve());
177   mover.emit(mr);
178   mover.finish();
179   masm.abiret();
180   JitCode* code = linkAndAllocate(cx, &masm);
181   sim->skipCalleeSavedRegsCheck = true;
182   sim->call(code->raw(), 1, 1);
183   double d;
184   float f;
185   sim->get_double_from_d_register(14, &d);
186   CHECK(int(d) == 9);
187   sim->get_float_from_s_register(25, &f);
188   CHECK(int(f) == 24);
189   sim->get_double_from_d_register(0, &d);
190   CHECK(int(d) == 3);
191   sim->get_float_from_s_register(31, &f);
192   CHECK(int(f) == 10);
193   sim->get_double_from_d_register(10, &d);
194   CHECK(int(d) == 1);
195   sim->get_float_from_s_register(10, &f);
196   CHECK(int(f) == 8);
197   sim->get_double_from_d_register(7, &d);
198   CHECK(int(d) == 2);
199   sim->get_float_from_s_register(18, &f);
200   CHECK(int(f) == 20);
201   sim->get_float_from_s_register(3, &f);
202   CHECK(int(f) == 1);
203   sim->get_float_from_s_register(11, &f);
204   CHECK(int(f) == 17);
205   sim->get_float_from_s_register(30, &f);
206   CHECK(int(f) == 22);
207   sim->get_float_from_s_register(7, &f);
208   CHECK(int(f) == 31);
209   sim->get_double_from_d_register(13, &d);
210   CHECK(int(d) == 3);
211   sim->get_double_from_d_register(8, &d);
212   CHECK(int(d) == 9);
213   sim->get_float_from_s_register(23, &f);
214   CHECK(int(f) == 31);
215   sim->get_float_from_s_register(8, &f);
216   CHECK(int(f) == 13);
217   sim->get_float_from_s_register(5, &f);
218   CHECK(int(f) == 28);
219   sim->get_float_from_s_register(19, &f);
220   CHECK(int(f) == 31);
221   sim->get_float_from_s_register(6, &f);
222   CHECK(int(f) == 20);
223   sim->get_float_from_s_register(2, &f);
224   CHECK(int(f) == 0);
225   sim->get_double_from_d_register(6, &d);
226   CHECK(int(d) == 7);
227   sim->get_float_from_s_register(9, &f);
228   CHECK(int(f) == 13);
229   sim->get_float_from_s_register(4, &f);
230   CHECK(int(f) == 1);
231   sim->get_float_from_s_register(22, &f);
232   CHECK(int(f) == 29);
233   sim->get_float_from_s_register(24, &f);
234   CHECK(int(f) == 25);
235   return true;
236 }
237 END_TEST(testJitMoveEmitterCycles_autogen)
238 
BEGIN_TEST(testJitMoveEmitterCycles_autogen2)239 BEGIN_TEST(testJitMoveEmitterCycles_autogen2) {
240   using namespace js;
241   using namespace js::jit;
242   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
243   TempAllocator alloc(&lifo);
244   JitContext jc(cx, &alloc);
245   StackMacroAssembler masm;
246   MoveEmitter mover(masm);
247   MoveResolver mr;
248   mr.setAllocator(alloc);
249   Simulator* sim = Simulator::Current();
250   TRY(mr.addMove(MoveOperand(d10), MoveOperand(d0), MoveOp::DOUBLE));
251   sim->set_d_register_from_double(10, 10);
252   TRY(mr.addMove(MoveOperand(s15), MoveOperand(s3), MoveOp::FLOAT32));
253   sim->set_s_register_from_float(15, 15);
254   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s28), MoveOp::FLOAT32));
255   sim->set_s_register_from_float(2, 2);
256   TRY(mr.addMove(MoveOperand(s30), MoveOperand(s25), MoveOp::FLOAT32));
257   sim->set_s_register_from_float(30, 30);
258   TRY(mr.addMove(MoveOperand(s16), MoveOperand(s2), MoveOp::FLOAT32));
259   sim->set_s_register_from_float(16, 16);
260   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s29), MoveOp::FLOAT32));
261   sim->set_s_register_from_float(2, 2);
262   TRY(mr.addMove(MoveOperand(s17), MoveOperand(s10), MoveOp::FLOAT32));
263   sim->set_s_register_from_float(17, 17);
264   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s19), MoveOp::FLOAT32));
265   sim->set_s_register_from_float(2, 2);
266   TRY(mr.addMove(MoveOperand(s9), MoveOperand(s26), MoveOp::FLOAT32));
267   sim->set_s_register_from_float(9, 9);
268   TRY(mr.addMove(MoveOperand(s1), MoveOperand(s23), MoveOp::FLOAT32));
269   sim->set_s_register_from_float(1, 1);
270   TRY(mr.addMove(MoveOperand(s8), MoveOperand(s6), MoveOp::FLOAT32));
271   sim->set_s_register_from_float(8, 8);
272   TRY(mr.addMove(MoveOperand(s24), MoveOperand(s16), MoveOp::FLOAT32));
273   sim->set_s_register_from_float(24, 24);
274   TRY(mr.addMove(MoveOperand(s19), MoveOperand(s4), MoveOp::FLOAT32));
275   sim->set_s_register_from_float(19, 19);
276   TRY(mr.addMove(MoveOperand(d5), MoveOperand(d6), MoveOp::DOUBLE));
277   sim->set_d_register_from_double(5, 5);
278   TRY(mr.addMove(MoveOperand(s18), MoveOperand(s15), MoveOp::FLOAT32));
279   sim->set_s_register_from_float(18, 18);
280   TRY(mr.addMove(MoveOperand(s23), MoveOperand(s30), MoveOp::FLOAT32));
281   sim->set_s_register_from_float(23, 23);
282   TRY(mr.addMove(MoveOperand(s27), MoveOperand(s17), MoveOp::FLOAT32));
283   sim->set_s_register_from_float(27, 27);
284   TRY(mr.addMove(MoveOperand(d3), MoveOperand(d4), MoveOp::DOUBLE));
285   sim->set_d_register_from_double(3, 3);
286   TRY(mr.addMove(MoveOperand(s14), MoveOperand(s27), MoveOp::FLOAT32));
287   sim->set_s_register_from_float(14, 14);
288   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s31), MoveOp::FLOAT32));
289   sim->set_s_register_from_float(2, 2);
290   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s24), MoveOp::FLOAT32));
291   sim->set_s_register_from_float(2, 2);
292   TRY(mr.addMove(MoveOperand(s31), MoveOperand(s11), MoveOp::FLOAT32));
293   sim->set_s_register_from_float(31, 31);
294   TRY(mr.addMove(MoveOperand(s0), MoveOperand(s18), MoveOp::FLOAT32));
295   sim->set_s_register_from_float(0, 0);
296   TRY(mr.addMove(MoveOperand(s24), MoveOperand(s7), MoveOp::FLOAT32));
297   sim->set_s_register_from_float(24, 24);
298   TRY(mr.addMove(MoveOperand(s0), MoveOperand(s21), MoveOp::FLOAT32));
299   sim->set_s_register_from_float(0, 0);
300   TRY(mr.addMove(MoveOperand(s27), MoveOperand(s20), MoveOp::FLOAT32));
301   sim->set_s_register_from_float(27, 27);
302   TRY(mr.addMove(MoveOperand(s14), MoveOperand(s5), MoveOp::FLOAT32));
303   sim->set_s_register_from_float(14, 14);
304   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s14), MoveOp::FLOAT32));
305   sim->set_s_register_from_float(2, 2);
306   TRY(mr.addMove(MoveOperand(s12), MoveOperand(s22), MoveOp::FLOAT32));
307   sim->set_s_register_from_float(12, 12);
308   // don't explode!
309   TRY(mr.resolve());
310   mover.emit(mr);
311   mover.finish();
312   masm.abiret();
313   JitCode* code = linkAndAllocate(cx, &masm);
314   sim->skipCalleeSavedRegsCheck = true;
315   sim->call(code->raw(), 1, 1);
316 
317   double d;
318   float f;
319   sim->get_double_from_d_register(0, &d);
320   CHECK(int(d) == 10);
321   sim->get_float_from_s_register(3, &f);
322   CHECK(int(f) == 15);
323   sim->get_float_from_s_register(28, &f);
324   CHECK(int(f) == 2);
325   sim->get_float_from_s_register(25, &f);
326   CHECK(int(f) == 30);
327   sim->get_float_from_s_register(2, &f);
328   CHECK(int(f) == 16);
329   sim->get_float_from_s_register(29, &f);
330   CHECK(int(f) == 2);
331   sim->get_float_from_s_register(10, &f);
332   CHECK(int(f) == 17);
333   sim->get_float_from_s_register(19, &f);
334   CHECK(int(f) == 2);
335   sim->get_float_from_s_register(26, &f);
336   CHECK(int(f) == 9);
337   sim->get_float_from_s_register(23, &f);
338   CHECK(int(f) == 1);
339   sim->get_float_from_s_register(6, &f);
340   CHECK(int(f) == 8);
341   sim->get_float_from_s_register(16, &f);
342   CHECK(int(f) == 24);
343   sim->get_float_from_s_register(4, &f);
344   CHECK(int(f) == 19);
345   sim->get_double_from_d_register(6, &d);
346   CHECK(int(d) == 5);
347   sim->get_float_from_s_register(15, &f);
348   CHECK(int(f) == 18);
349   sim->get_float_from_s_register(30, &f);
350   CHECK(int(f) == 23);
351   sim->get_float_from_s_register(17, &f);
352   CHECK(int(f) == 27);
353   sim->get_double_from_d_register(4, &d);
354   CHECK(int(d) == 3);
355   sim->get_float_from_s_register(27, &f);
356   CHECK(int(f) == 14);
357   sim->get_float_from_s_register(31, &f);
358   CHECK(int(f) == 2);
359   sim->get_float_from_s_register(24, &f);
360   CHECK(int(f) == 2);
361   sim->get_float_from_s_register(11, &f);
362   CHECK(int(f) == 31);
363   sim->get_float_from_s_register(18, &f);
364   CHECK(int(f) == 0);
365   sim->get_float_from_s_register(7, &f);
366   CHECK(int(f) == 24);
367   sim->get_float_from_s_register(21, &f);
368   CHECK(int(f) == 0);
369   sim->get_float_from_s_register(20, &f);
370   CHECK(int(f) == 27);
371   sim->get_float_from_s_register(5, &f);
372   CHECK(int(f) == 14);
373   sim->get_float_from_s_register(14, &f);
374   CHECK(int(f) == 2);
375   sim->get_float_from_s_register(22, &f);
376   CHECK(int(f) == 12);
377   return true;
378 }
379 END_TEST(testJitMoveEmitterCycles_autogen2)
380 
BEGIN_TEST(testJitMoveEmitterCycles_autogen3)381 BEGIN_TEST(testJitMoveEmitterCycles_autogen3) {
382   using namespace js;
383   using namespace js::jit;
384   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
385   TempAllocator alloc(&lifo);
386   JitContext jc(cx, &alloc);
387   StackMacroAssembler masm;
388   MoveEmitter mover(masm);
389   MoveResolver mr;
390   mr.setAllocator(alloc);
391   Simulator* sim = Simulator::Current();
392   TRY(mr.addMove(MoveOperand(s0), MoveOperand(s21), MoveOp::FLOAT32));
393   sim->set_s_register_from_float(0, 0);
394   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s26), MoveOp::FLOAT32));
395   sim->set_s_register_from_float(2, 2);
396   TRY(mr.addMove(MoveOperand(s19), MoveOperand(s20), MoveOp::FLOAT32));
397   sim->set_s_register_from_float(19, 19);
398   TRY(mr.addMove(MoveOperand(s4), MoveOperand(s24), MoveOp::FLOAT32));
399   sim->set_s_register_from_float(4, 4);
400   TRY(mr.addMove(MoveOperand(s22), MoveOperand(s9), MoveOp::FLOAT32));
401   sim->set_s_register_from_float(22, 22);
402   TRY(mr.addMove(MoveOperand(s5), MoveOperand(s28), MoveOp::FLOAT32));
403   sim->set_s_register_from_float(5, 5);
404   TRY(mr.addMove(MoveOperand(s15), MoveOperand(s7), MoveOp::FLOAT32));
405   sim->set_s_register_from_float(15, 15);
406   TRY(mr.addMove(MoveOperand(s26), MoveOperand(s14), MoveOp::FLOAT32));
407   sim->set_s_register_from_float(26, 26);
408   TRY(mr.addMove(MoveOperand(s13), MoveOperand(s30), MoveOp::FLOAT32));
409   sim->set_s_register_from_float(13, 13);
410   TRY(mr.addMove(MoveOperand(s26), MoveOperand(s22), MoveOp::FLOAT32));
411   sim->set_s_register_from_float(26, 26);
412   TRY(mr.addMove(MoveOperand(s21), MoveOperand(s6), MoveOp::FLOAT32));
413   sim->set_s_register_from_float(21, 21);
414   TRY(mr.addMove(MoveOperand(s23), MoveOperand(s31), MoveOp::FLOAT32));
415   sim->set_s_register_from_float(23, 23);
416   TRY(mr.addMove(MoveOperand(s7), MoveOperand(s12), MoveOp::FLOAT32));
417   sim->set_s_register_from_float(7, 7);
418   TRY(mr.addMove(MoveOperand(s14), MoveOperand(s10), MoveOp::FLOAT32));
419   sim->set_s_register_from_float(14, 14);
420   TRY(mr.addMove(MoveOperand(d12), MoveOperand(d8), MoveOp::DOUBLE));
421   sim->set_d_register_from_double(12, 12);
422   TRY(mr.addMove(MoveOperand(s5), MoveOperand(s1), MoveOp::FLOAT32));
423   sim->set_s_register_from_float(5, 5);
424   TRY(mr.addMove(MoveOperand(d12), MoveOperand(d2), MoveOp::DOUBLE));
425   sim->set_d_register_from_double(12, 12);
426   TRY(mr.addMove(MoveOperand(s3), MoveOperand(s8), MoveOp::FLOAT32));
427   sim->set_s_register_from_float(3, 3);
428   TRY(mr.addMove(MoveOperand(s14), MoveOperand(s0), MoveOp::FLOAT32));
429   sim->set_s_register_from_float(14, 14);
430   TRY(mr.addMove(MoveOperand(s28), MoveOperand(s29), MoveOp::FLOAT32));
431   sim->set_s_register_from_float(28, 28);
432   TRY(mr.addMove(MoveOperand(d12), MoveOperand(d9), MoveOp::DOUBLE));
433   sim->set_d_register_from_double(12, 12);
434   TRY(mr.addMove(MoveOperand(s29), MoveOperand(s2), MoveOp::FLOAT32));
435   sim->set_s_register_from_float(29, 29);
436   TRY(mr.addMove(MoveOperand(s22), MoveOperand(s27), MoveOp::FLOAT32));
437   sim->set_s_register_from_float(22, 22);
438   TRY(mr.addMove(MoveOperand(s19), MoveOperand(s3), MoveOp::FLOAT32));
439   sim->set_s_register_from_float(19, 19);
440   TRY(mr.addMove(MoveOperand(s21), MoveOperand(s11), MoveOp::FLOAT32));
441   sim->set_s_register_from_float(21, 21);
442   TRY(mr.addMove(MoveOperand(s22), MoveOperand(s13), MoveOp::FLOAT32));
443   sim->set_s_register_from_float(22, 22);
444   TRY(mr.addMove(MoveOperand(s29), MoveOperand(s25), MoveOp::FLOAT32));
445   sim->set_s_register_from_float(29, 29);
446   TRY(mr.addMove(MoveOperand(s29), MoveOperand(s15), MoveOp::FLOAT32));
447   sim->set_s_register_from_float(29, 29);
448   TRY(mr.addMove(MoveOperand(s16), MoveOperand(s23), MoveOp::FLOAT32));
449   sim->set_s_register_from_float(16, 16);
450   // don't explode!
451   TRY(mr.resolve());
452   mover.emit(mr);
453   mover.finish();
454   masm.abiret();
455   JitCode* code = linkAndAllocate(cx, &masm);
456   sim->skipCalleeSavedRegsCheck = true;
457   sim->call(code->raw(), 1, 1);
458 
459   float f;
460   double d;
461   sim->get_float_from_s_register(21, &f);
462   CHECK(int(f) == 0);
463   sim->get_float_from_s_register(26, &f);
464   CHECK(int(f) == 2);
465   sim->get_float_from_s_register(20, &f);
466   CHECK(int(f) == 19);
467   sim->get_float_from_s_register(24, &f);
468   CHECK(int(f) == 4);
469   sim->get_float_from_s_register(9, &f);
470   CHECK(int(f) == 22);
471   sim->get_float_from_s_register(28, &f);
472   CHECK(int(f) == 5);
473   sim->get_float_from_s_register(7, &f);
474   CHECK(int(f) == 15);
475   sim->get_float_from_s_register(14, &f);
476   CHECK(int(f) == 26);
477   sim->get_float_from_s_register(30, &f);
478   CHECK(int(f) == 13);
479   sim->get_float_from_s_register(22, &f);
480   CHECK(int(f) == 26);
481   sim->get_float_from_s_register(6, &f);
482   CHECK(int(f) == 21);
483   sim->get_float_from_s_register(31, &f);
484   CHECK(int(f) == 23);
485   sim->get_float_from_s_register(12, &f);
486   CHECK(int(f) == 7);
487   sim->get_float_from_s_register(10, &f);
488   CHECK(int(f) == 14);
489   sim->get_double_from_d_register(8, &d);
490   CHECK(int(d) == 12);
491   sim->get_float_from_s_register(1, &f);
492   CHECK(int(f) == 5);
493   sim->get_double_from_d_register(2, &d);
494   CHECK(int(d) == 12);
495   sim->get_float_from_s_register(8, &f);
496   CHECK(int(f) == 3);
497   sim->get_float_from_s_register(0, &f);
498   CHECK(int(f) == 14);
499   sim->get_float_from_s_register(29, &f);
500   CHECK(int(f) == 28);
501   sim->get_double_from_d_register(9, &d);
502   CHECK(int(d) == 12);
503   sim->get_float_from_s_register(2, &f);
504   CHECK(int(f) == 29);
505   sim->get_float_from_s_register(27, &f);
506   CHECK(int(f) == 22);
507   sim->get_float_from_s_register(3, &f);
508   CHECK(int(f) == 19);
509   sim->get_float_from_s_register(11, &f);
510   CHECK(int(f) == 21);
511   sim->get_float_from_s_register(13, &f);
512   CHECK(int(f) == 22);
513   sim->get_float_from_s_register(25, &f);
514   CHECK(int(f) == 29);
515   sim->get_float_from_s_register(15, &f);
516   CHECK(int(f) == 29);
517   sim->get_float_from_s_register(23, &f);
518   CHECK(int(f) == 16);
519   return true;
520 }
521 END_TEST(testJitMoveEmitterCycles_autogen3)
BEGIN_TEST(testJitMoveEmitterCycles_bug1299147_1)522 BEGIN_TEST(testJitMoveEmitterCycles_bug1299147_1) {
523   using namespace js;
524   using namespace js::jit;
525   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
526   TempAllocator alloc(&lifo);
527   JitContext jc(cx, &alloc);
528   StackMacroAssembler masm;
529   MoveEmitter mover(masm);
530   MoveResolver mr;
531   mr.setAllocator(alloc);
532   Simulator* sim = Simulator::Current();
533   // S2 -> S0
534   // S2 -> S6
535   // S3 -> S1
536   // S3 -> S7
537   // D0 -> D1
538   // D0 -> D2
539   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s0), MoveOp::FLOAT32));
540   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s6), MoveOp::FLOAT32));
541   sim->set_s_register_from_float(2, 2);
542   TRY(mr.addMove(MoveOperand(s3), MoveOperand(s1), MoveOp::FLOAT32));
543   TRY(mr.addMove(MoveOperand(s3), MoveOperand(s7), MoveOp::FLOAT32));
544   sim->set_s_register_from_float(3, 4);
545   TRY(mr.addMove(MoveOperand(d0), MoveOperand(d1), MoveOp::FLOAT32));
546   TRY(mr.addMove(MoveOperand(d0), MoveOperand(d2), MoveOp::FLOAT32));
547   sim->set_d_register_from_double(0, 1);
548   // don't explode!
549   TRY(mr.resolve());
550   mover.emit(mr);
551   mover.finish();
552   masm.abiret();
553   JitCode* code = linkAndAllocate(cx, &masm);
554   sim->call(code->raw(), 1, 1);
555   float f;
556   double d;
557   sim->get_double_from_d_register(1, &d);
558   CHECK(d == 1);
559   sim->get_double_from_d_register(2, &d);
560   CHECK(d == 1);
561   sim->get_float_from_s_register(0, &f);
562   CHECK(int(f) == 2);
563   sim->get_float_from_s_register(6, &f);
564   CHECK(int(f) == 2);
565   sim->get_float_from_s_register(1, &f);
566   CHECK(int(f) == 4);
567   sim->get_float_from_s_register(7, &f);
568   CHECK(int(f) == 4);
569   return true;
570 }
571 END_TEST(testJitMoveEmitterCycles_bug1299147_1)
BEGIN_TEST(testJitMoveEmitterCycles_bug1299147)572 BEGIN_TEST(testJitMoveEmitterCycles_bug1299147) {
573   using namespace js;
574   using namespace js::jit;
575   LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
576   TempAllocator alloc(&lifo);
577   JitContext jc(cx, &alloc);
578   StackMacroAssembler masm;
579   MoveEmitter mover(masm);
580   MoveResolver mr;
581   mr.setAllocator(alloc);
582   Simulator* sim = Simulator::Current();
583   // S2 -> S5
584   // S2 -> S6
585   // D0 -> D1
586   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s5), MoveOp::FLOAT32));
587   TRY(mr.addMove(MoveOperand(s2), MoveOperand(s6), MoveOp::FLOAT32));
588   sim->set_s_register_from_float(2, 2);
589   TRY(mr.addMove(MoveOperand(d0), MoveOperand(d1), MoveOp::FLOAT32));
590   sim->set_d_register_from_double(0, 1);
591   // don't explode!
592   TRY(mr.resolve());
593   mover.emit(mr);
594   mover.finish();
595   masm.abiret();
596   JitCode* code = linkAndAllocate(cx, &masm);
597   sim->call(code->raw(), 1, 1);
598   float f;
599   double d;
600   sim->get_double_from_d_register(1, &d);
601   CHECK(d == 1);
602   sim->get_float_from_s_register(5, &f);
603   CHECK(int(f) == 2);
604   sim->get_float_from_s_register(6, &f);
605   CHECK(int(f) == 2);
606   return true;
607 }
608 END_TEST(testJitMoveEmitterCycles_bug1299147)
609 
610 #endif  // JS_SIMULATOR_ARM
611