1 // Copyright 2015, ARM Limited
2 // 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 are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifdef JS_SIMULATOR_ARM64
28 
29 #include <cmath>
30 
31 #include "jit/arm64/vixl/Simulator-vixl.h"
32 
33 namespace vixl {
34 
FPDefaultNaN()35 template<> double Simulator::FPDefaultNaN<double>() {
36   return kFP64DefaultNaN;
37 }
38 
39 
FPDefaultNaN()40 template<> float Simulator::FPDefaultNaN<float>() {
41   return kFP32DefaultNaN;
42 }
43 
44 
FixedToDouble(int64_t src,int fbits,FPRounding round)45 double Simulator::FixedToDouble(int64_t src, int fbits, FPRounding round) {
46   if (src >= 0) {
47     return UFixedToDouble(src, fbits, round);
48   } else {
49     // This works for all negative values, including INT64_MIN.
50     return -UFixedToDouble(-src, fbits, round);
51   }
52 }
53 
54 
UFixedToDouble(uint64_t src,int fbits,FPRounding round)55 double Simulator::UFixedToDouble(uint64_t src, int fbits, FPRounding round) {
56   // An input of 0 is a special case because the result is effectively
57   // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
58   if (src == 0) {
59     return 0.0;
60   }
61 
62   // Calculate the exponent. The highest significant bit will have the value
63   // 2^exponent.
64   const int highest_significant_bit = 63 - CountLeadingZeros(src);
65   const int64_t exponent = highest_significant_bit - fbits;
66 
67   return FPRoundToDouble(0, exponent, src, round);
68 }
69 
70 
FixedToFloat(int64_t src,int fbits,FPRounding round)71 float Simulator::FixedToFloat(int64_t src, int fbits, FPRounding round) {
72   if (src >= 0) {
73     return UFixedToFloat(src, fbits, round);
74   } else {
75     // This works for all negative values, including INT64_MIN.
76     return -UFixedToFloat(-src, fbits, round);
77   }
78 }
79 
80 
UFixedToFloat(uint64_t src,int fbits,FPRounding round)81 float Simulator::UFixedToFloat(uint64_t src, int fbits, FPRounding round) {
82   // An input of 0 is a special case because the result is effectively
83   // subnormal: The exponent is encoded as 0 and there is no implicit 1 bit.
84   if (src == 0) {
85     return 0.0f;
86   }
87 
88   // Calculate the exponent. The highest significant bit will have the value
89   // 2^exponent.
90   const int highest_significant_bit = 63 - CountLeadingZeros(src);
91   const int32_t exponent = highest_significant_bit - fbits;
92 
93   return FPRoundToFloat(0, exponent, src, round);
94 }
95 
96 
ld1(VectorFormat vform,LogicVRegister dst,uint64_t addr)97 void Simulator::ld1(VectorFormat vform,
98                     LogicVRegister dst,
99                     uint64_t addr) {
100   if (handle_wasm_seg_fault(addr, 16))
101     return;
102   dst.ClearForWrite(vform);
103   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
104     dst.ReadUintFromMem(vform, i, addr);
105     addr += LaneSizeInBytesFromFormat(vform);
106   }
107 }
108 
109 
ld1(VectorFormat vform,LogicVRegister dst,int index,uint64_t addr)110 void Simulator::ld1(VectorFormat vform,
111                     LogicVRegister dst,
112                     int index,
113                     uint64_t addr) {
114   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)))
115     return;
116   dst.ReadUintFromMem(vform, index, addr);
117 }
118 
119 
ld1r(VectorFormat vform,LogicVRegister dst,uint64_t addr)120 void Simulator::ld1r(VectorFormat vform,
121                      LogicVRegister dst,
122                      uint64_t addr) {
123   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)))
124     return;
125   dst.ClearForWrite(vform);
126   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
127     dst.ReadUintFromMem(vform, i, addr);
128   }
129 }
130 
131 
ld2(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,uint64_t addr1)132 void Simulator::ld2(VectorFormat vform,
133                     LogicVRegister dst1,
134                     LogicVRegister dst2,
135                     uint64_t addr1) {
136   if (handle_wasm_seg_fault(addr1, 16*2))
137     return;
138   dst1.ClearForWrite(vform);
139   dst2.ClearForWrite(vform);
140   int esize = LaneSizeInBytesFromFormat(vform);
141   uint64_t addr2 = addr1 + esize;
142   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
143     dst1.ReadUintFromMem(vform, i, addr1);
144     dst2.ReadUintFromMem(vform, i, addr2);
145     addr1 += 2 * esize;
146     addr2 += 2 * esize;
147   }
148 }
149 
150 
ld2(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,int index,uint64_t addr1)151 void Simulator::ld2(VectorFormat vform,
152                     LogicVRegister dst1,
153                     LogicVRegister dst2,
154                     int index,
155                     uint64_t addr1) {
156   if (handle_wasm_seg_fault(addr1, LaneSizeInBytesFromFormat(vform)*2))
157     return;
158   dst1.ClearForWrite(vform);
159   dst2.ClearForWrite(vform);
160   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
161   dst1.ReadUintFromMem(vform, index, addr1);
162   dst2.ReadUintFromMem(vform, index, addr2);
163 }
164 
165 
ld2r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,uint64_t addr)166 void Simulator::ld2r(VectorFormat vform,
167                      LogicVRegister dst1,
168                      LogicVRegister dst2,
169                      uint64_t addr) {
170   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*2))
171     return;
172   dst1.ClearForWrite(vform);
173   dst2.ClearForWrite(vform);
174   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
175   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
176     dst1.ReadUintFromMem(vform, i, addr);
177     dst2.ReadUintFromMem(vform, i, addr2);
178   }
179 }
180 
181 
ld3(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr1)182 void Simulator::ld3(VectorFormat vform,
183                     LogicVRegister dst1,
184                     LogicVRegister dst2,
185                     LogicVRegister dst3,
186                     uint64_t addr1) {
187   if (handle_wasm_seg_fault(addr1, 16*3))
188     return;
189   dst1.ClearForWrite(vform);
190   dst2.ClearForWrite(vform);
191   dst3.ClearForWrite(vform);
192   int esize = LaneSizeInBytesFromFormat(vform);
193   uint64_t addr2 = addr1 + esize;
194   uint64_t addr3 = addr2 + esize;
195   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
196     dst1.ReadUintFromMem(vform, i, addr1);
197     dst2.ReadUintFromMem(vform, i, addr2);
198     dst3.ReadUintFromMem(vform, i, addr3);
199     addr1 += 3 * esize;
200     addr2 += 3 * esize;
201     addr3 += 3 * esize;
202   }
203 }
204 
205 
ld3(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,int index,uint64_t addr1)206 void Simulator::ld3(VectorFormat vform,
207                     LogicVRegister dst1,
208                     LogicVRegister dst2,
209                     LogicVRegister dst3,
210                     int index,
211                     uint64_t addr1) {
212   if (handle_wasm_seg_fault(addr1, LaneSizeInBytesFromFormat(vform)*3))
213     return;
214   dst1.ClearForWrite(vform);
215   dst2.ClearForWrite(vform);
216   dst3.ClearForWrite(vform);
217   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
218   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
219   dst1.ReadUintFromMem(vform, index, addr1);
220   dst2.ReadUintFromMem(vform, index, addr2);
221   dst3.ReadUintFromMem(vform, index, addr3);
222 }
223 
224 
ld3r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr)225 void Simulator::ld3r(VectorFormat vform,
226                      LogicVRegister dst1,
227                      LogicVRegister dst2,
228                      LogicVRegister dst3,
229                      uint64_t addr) {
230   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*3))
231     return;
232   dst1.ClearForWrite(vform);
233   dst2.ClearForWrite(vform);
234   dst3.ClearForWrite(vform);
235   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
236   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
237   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
238     dst1.ReadUintFromMem(vform, i, addr);
239     dst2.ReadUintFromMem(vform, i, addr2);
240     dst3.ReadUintFromMem(vform, i, addr3);
241   }
242 }
243 
244 
ld4(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr1)245 void Simulator::ld4(VectorFormat vform,
246                     LogicVRegister dst1,
247                     LogicVRegister dst2,
248                     LogicVRegister dst3,
249                     LogicVRegister dst4,
250                     uint64_t addr1) {
251   if (handle_wasm_seg_fault(addr1, 16*4))
252     return;
253   dst1.ClearForWrite(vform);
254   dst2.ClearForWrite(vform);
255   dst3.ClearForWrite(vform);
256   dst4.ClearForWrite(vform);
257   int esize = LaneSizeInBytesFromFormat(vform);
258   uint64_t addr2 = addr1 + esize;
259   uint64_t addr3 = addr2 + esize;
260   uint64_t addr4 = addr3 + esize;
261   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
262     dst1.ReadUintFromMem(vform, i, addr1);
263     dst2.ReadUintFromMem(vform, i, addr2);
264     dst3.ReadUintFromMem(vform, i, addr3);
265     dst4.ReadUintFromMem(vform, i, addr4);
266     addr1 += 4 * esize;
267     addr2 += 4 * esize;
268     addr3 += 4 * esize;
269     addr4 += 4 * esize;
270   }
271 }
272 
273 
ld4(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,int index,uint64_t addr1)274 void Simulator::ld4(VectorFormat vform,
275                     LogicVRegister dst1,
276                     LogicVRegister dst2,
277                     LogicVRegister dst3,
278                     LogicVRegister dst4,
279                     int index,
280                     uint64_t addr1) {
281   if (handle_wasm_seg_fault(addr1, LaneSizeInBytesFromFormat(vform)*4))
282     return;
283   dst1.ClearForWrite(vform);
284   dst2.ClearForWrite(vform);
285   dst3.ClearForWrite(vform);
286   dst4.ClearForWrite(vform);
287   uint64_t addr2 = addr1 + LaneSizeInBytesFromFormat(vform);
288   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
289   uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
290   dst1.ReadUintFromMem(vform, index, addr1);
291   dst2.ReadUintFromMem(vform, index, addr2);
292   dst3.ReadUintFromMem(vform, index, addr3);
293   dst4.ReadUintFromMem(vform, index, addr4);
294 }
295 
296 
ld4r(VectorFormat vform,LogicVRegister dst1,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr)297 void Simulator::ld4r(VectorFormat vform,
298                      LogicVRegister dst1,
299                      LogicVRegister dst2,
300                      LogicVRegister dst3,
301                      LogicVRegister dst4,
302                      uint64_t addr) {
303   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*4))
304     return;
305   dst1.ClearForWrite(vform);
306   dst2.ClearForWrite(vform);
307   dst3.ClearForWrite(vform);
308   dst4.ClearForWrite(vform);
309   uint64_t addr2 = addr + LaneSizeInBytesFromFormat(vform);
310   uint64_t addr3 = addr2 + LaneSizeInBytesFromFormat(vform);
311   uint64_t addr4 = addr3 + LaneSizeInBytesFromFormat(vform);
312   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
313     dst1.ReadUintFromMem(vform, i, addr);
314     dst2.ReadUintFromMem(vform, i, addr2);
315     dst3.ReadUintFromMem(vform, i, addr3);
316     dst4.ReadUintFromMem(vform, i, addr4);
317   }
318 }
319 
320 
st1(VectorFormat vform,LogicVRegister src,uint64_t addr)321 void Simulator::st1(VectorFormat vform,
322                     LogicVRegister src,
323                     uint64_t addr) {
324   if (handle_wasm_seg_fault(addr, 16))
325     return;
326   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
327     src.WriteUintToMem(vform, i, addr);
328     addr += LaneSizeInBytesFromFormat(vform);
329   }
330 }
331 
332 
st1(VectorFormat vform,LogicVRegister src,int index,uint64_t addr)333 void Simulator::st1(VectorFormat vform,
334                     LogicVRegister src,
335                     int index,
336                     uint64_t addr) {
337   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)))
338     return;
339   src.WriteUintToMem(vform, index, addr);
340 }
341 
342 
st2(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,uint64_t addr)343 void Simulator::st2(VectorFormat vform,
344                     LogicVRegister dst,
345                     LogicVRegister dst2,
346                     uint64_t addr) {
347   if (handle_wasm_seg_fault(addr, 16*2))
348     return;
349   int esize = LaneSizeInBytesFromFormat(vform);
350   uint64_t addr2 = addr + esize;
351   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
352     dst.WriteUintToMem(vform, i, addr);
353     dst2.WriteUintToMem(vform, i, addr2);
354     addr += 2 * esize;
355     addr2 += 2 * esize;
356   }
357 }
358 
359 
st2(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,int index,uint64_t addr)360 void Simulator::st2(VectorFormat vform,
361                     LogicVRegister dst,
362                     LogicVRegister dst2,
363                     int index,
364                     uint64_t addr) {
365   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*2))
366     return;
367   int esize = LaneSizeInBytesFromFormat(vform);
368   dst.WriteUintToMem(vform, index, addr);
369   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
370 }
371 
372 
st3(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,uint64_t addr)373 void Simulator::st3(VectorFormat vform,
374                     LogicVRegister dst,
375                     LogicVRegister dst2,
376                     LogicVRegister dst3,
377                     uint64_t addr) {
378   if (handle_wasm_seg_fault(addr, 16*3))
379     return;
380   int esize = LaneSizeInBytesFromFormat(vform);
381   uint64_t addr2 = addr + esize;
382   uint64_t addr3 = addr2 + esize;
383   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
384     dst.WriteUintToMem(vform, i, addr);
385     dst2.WriteUintToMem(vform, i, addr2);
386     dst3.WriteUintToMem(vform, i, addr3);
387     addr += 3 * esize;
388     addr2 += 3 * esize;
389     addr3 += 3 * esize;
390   }
391 }
392 
393 
st3(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,int index,uint64_t addr)394 void Simulator::st3(VectorFormat vform,
395                     LogicVRegister dst,
396                     LogicVRegister dst2,
397                     LogicVRegister dst3,
398                     int index,
399                     uint64_t addr) {
400   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*3))
401     return;
402   int esize = LaneSizeInBytesFromFormat(vform);
403   dst.WriteUintToMem(vform, index, addr);
404   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
405   dst3.WriteUintToMem(vform, index, addr + 2 * esize);
406 }
407 
408 
st4(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,uint64_t addr)409 void Simulator::st4(VectorFormat vform,
410                     LogicVRegister dst,
411                     LogicVRegister dst2,
412                     LogicVRegister dst3,
413                     LogicVRegister dst4,
414                     uint64_t addr) {
415   if (handle_wasm_seg_fault(addr, 16*4))
416     return;
417   int esize = LaneSizeInBytesFromFormat(vform);
418   uint64_t addr2 = addr + esize;
419   uint64_t addr3 = addr2 + esize;
420   uint64_t addr4 = addr3 + esize;
421   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
422     dst.WriteUintToMem(vform, i, addr);
423     dst2.WriteUintToMem(vform, i, addr2);
424     dst3.WriteUintToMem(vform, i, addr3);
425     dst4.WriteUintToMem(vform, i, addr4);
426     addr += 4 * esize;
427     addr2 += 4 * esize;
428     addr3 += 4 * esize;
429     addr4 += 4 * esize;
430   }
431 }
432 
433 
st4(VectorFormat vform,LogicVRegister dst,LogicVRegister dst2,LogicVRegister dst3,LogicVRegister dst4,int index,uint64_t addr)434 void Simulator::st4(VectorFormat vform,
435                     LogicVRegister dst,
436                     LogicVRegister dst2,
437                     LogicVRegister dst3,
438                     LogicVRegister dst4,
439                     int index,
440                     uint64_t addr) {
441   if (handle_wasm_seg_fault(addr, LaneSizeInBytesFromFormat(vform)*4))
442     return;
443   int esize = LaneSizeInBytesFromFormat(vform);
444   dst.WriteUintToMem(vform, index, addr);
445   dst2.WriteUintToMem(vform, index, addr + 1 * esize);
446   dst3.WriteUintToMem(vform, index, addr + 2 * esize);
447   dst4.WriteUintToMem(vform, index, addr + 3 * esize);
448 }
449 
450 
cmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)451 LogicVRegister Simulator::cmp(VectorFormat vform,
452                               LogicVRegister dst,
453                               const LogicVRegister& src1,
454                               const LogicVRegister& src2,
455                               Condition cond) {
456   dst.ClearForWrite(vform);
457   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
458     int64_t  sa = src1.Int(vform, i);
459     int64_t  sb = src2.Int(vform, i);
460     uint64_t ua = src1.Uint(vform, i);
461     uint64_t ub = src2.Uint(vform, i);
462     bool result = false;
463     switch (cond) {
464       case eq: result = (ua == ub); break;
465       case ge: result = (sa >= sb); break;
466       case gt: result = (sa > sb) ; break;
467       case hi: result = (ua > ub) ; break;
468       case hs: result = (ua >= ub); break;
469       case lt: result = (sa < sb) ; break;
470       case le: result = (sa <= sb); break;
471       default: VIXL_UNREACHABLE(); break;
472     }
473     dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
474   }
475   return dst;
476 }
477 
478 
cmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,int imm,Condition cond)479 LogicVRegister Simulator::cmp(VectorFormat vform,
480                               LogicVRegister dst,
481                               const LogicVRegister& src1,
482                               int imm,
483                               Condition cond) {
484   SimVRegister temp;
485   LogicVRegister imm_reg = dup_immediate(vform, temp, imm);
486   return cmp(vform, dst, src1, imm_reg, cond);
487 }
488 
489 
cmptst(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)490 LogicVRegister Simulator::cmptst(VectorFormat vform,
491                                  LogicVRegister dst,
492                                  const LogicVRegister& src1,
493                                  const LogicVRegister& src2) {
494   dst.ClearForWrite(vform);
495   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
496     uint64_t ua = src1.Uint(vform, i);
497     uint64_t ub = src2.Uint(vform, i);
498     dst.SetUint(vform, i, ((ua & ub) != 0) ? MaxUintFromFormat(vform) : 0);
499   }
500   return dst;
501 }
502 
503 
add(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)504 LogicVRegister Simulator::add(VectorFormat vform,
505                               LogicVRegister dst,
506                               const LogicVRegister& src1,
507                               const LogicVRegister& src2) {
508   dst.ClearForWrite(vform);
509   // TODO(all): consider assigning the result of LaneCountFromFormat to a local.
510   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
511     // Test for unsigned saturation.
512     uint64_t ua = src1.UintLeftJustified(vform, i);
513     uint64_t ub = src2.UintLeftJustified(vform, i);
514     uint64_t ur = ua + ub;
515     if (ur < ua) {
516       dst.SetUnsignedSat(i, true);
517     }
518 
519     // Test for signed saturation.
520     int64_t sa = src1.IntLeftJustified(vform, i);
521     int64_t sb = src2.IntLeftJustified(vform, i);
522     int64_t sr = sa + sb;
523     // If the signs of the operands are the same, but different from the result,
524     // there was an overflow.
525     if (((sa >= 0) == (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
526       dst.SetSignedSat(i, sa >= 0);
527     }
528 
529     dst.SetInt(vform, i, src1.Int(vform, i) + src2.Int(vform, i));
530   }
531   return dst;
532 }
533 
534 
addp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)535 LogicVRegister Simulator::addp(VectorFormat vform,
536                                LogicVRegister dst,
537                                const LogicVRegister& src1,
538                                const LogicVRegister& src2) {
539   SimVRegister temp1, temp2;
540   uzp1(vform, temp1, src1, src2);
541   uzp2(vform, temp2, src1, src2);
542   add(vform, dst, temp1, temp2);
543   return dst;
544 }
545 
546 
mla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)547 LogicVRegister Simulator::mla(VectorFormat vform,
548                               LogicVRegister dst,
549                               const LogicVRegister& src1,
550                               const LogicVRegister& src2) {
551   SimVRegister temp;
552   mul(vform, temp, src1, src2);
553   add(vform, dst, dst, temp);
554   return dst;
555 }
556 
557 
mls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)558 LogicVRegister Simulator::mls(VectorFormat vform,
559                               LogicVRegister dst,
560                               const LogicVRegister& src1,
561                               const LogicVRegister& src2) {
562   SimVRegister temp;
563   mul(vform, temp, src1, src2);
564   sub(vform, dst, dst, temp);
565   return dst;
566 }
567 
568 
mul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)569 LogicVRegister Simulator::mul(VectorFormat vform,
570                               LogicVRegister dst,
571                               const LogicVRegister& src1,
572                               const LogicVRegister& src2) {
573   dst.ClearForWrite(vform);
574   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
575     dst.SetUint(vform, i, src1.Uint(vform, i) * src2.Uint(vform, i));
576   }
577   return dst;
578 }
579 
580 
mul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)581 LogicVRegister Simulator::mul(VectorFormat vform,
582                               LogicVRegister dst,
583                               const LogicVRegister& src1,
584                               const LogicVRegister& src2,
585                               int index) {
586   SimVRegister temp;
587   VectorFormat indexform = VectorFormatFillQ(vform);
588   return mul(vform, dst, src1, dup_element(indexform, temp, src2, index));
589 }
590 
591 
mla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)592 LogicVRegister Simulator::mla(VectorFormat vform,
593                               LogicVRegister dst,
594                               const LogicVRegister& src1,
595                               const LogicVRegister& src2,
596                               int index) {
597   SimVRegister temp;
598   VectorFormat indexform = VectorFormatFillQ(vform);
599   return mla(vform, dst, src1, dup_element(indexform, temp, src2, index));
600 }
601 
602 
mls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)603 LogicVRegister Simulator::mls(VectorFormat vform,
604                               LogicVRegister dst,
605                               const LogicVRegister& src1,
606                               const LogicVRegister& src2,
607                               int index) {
608   SimVRegister temp;
609   VectorFormat indexform = VectorFormatFillQ(vform);
610   return mls(vform, dst, src1, dup_element(indexform, temp, src2, index));
611 }
612 
613 
smull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)614 LogicVRegister Simulator::smull(VectorFormat vform,
615                                 LogicVRegister dst,
616                                 const LogicVRegister& src1,
617                                 const LogicVRegister& src2,
618                                 int index) {
619   SimVRegister temp;
620   VectorFormat indexform =
621                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
622   return smull(vform, dst, src1, dup_element(indexform, temp, src2, index));
623 }
624 
625 
smull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)626 LogicVRegister Simulator::smull2(VectorFormat vform,
627                                 LogicVRegister dst,
628                                 const LogicVRegister& src1,
629                                 const LogicVRegister& src2,
630                                 int index) {
631   SimVRegister temp;
632   VectorFormat indexform =
633                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
634   return smull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
635 }
636 
637 
umull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)638 LogicVRegister Simulator::umull(VectorFormat vform,
639                                 LogicVRegister dst,
640                                 const LogicVRegister& src1,
641                                 const LogicVRegister& src2,
642                                 int index) {
643   SimVRegister temp;
644   VectorFormat indexform =
645                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
646   return umull(vform, dst, src1, dup_element(indexform, temp, src2, index));
647 }
648 
649 
umull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)650 LogicVRegister Simulator::umull2(VectorFormat vform,
651                                 LogicVRegister dst,
652                                 const LogicVRegister& src1,
653                                 const LogicVRegister& src2,
654                                 int index) {
655   SimVRegister temp;
656   VectorFormat indexform =
657                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
658   return umull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
659 }
660 
661 
smlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)662 LogicVRegister Simulator::smlal(VectorFormat vform,
663                                 LogicVRegister dst,
664                                 const LogicVRegister& src1,
665                                 const LogicVRegister& src2,
666                                 int index) {
667   SimVRegister temp;
668   VectorFormat indexform =
669                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
670   return smlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
671 }
672 
673 
smlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)674 LogicVRegister Simulator::smlal2(VectorFormat vform,
675                                 LogicVRegister dst,
676                                 const LogicVRegister& src1,
677                                 const LogicVRegister& src2,
678                                 int index) {
679   SimVRegister temp;
680   VectorFormat indexform =
681                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
682   return smlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
683 }
684 
685 
umlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)686 LogicVRegister Simulator::umlal(VectorFormat vform,
687                                 LogicVRegister dst,
688                                 const LogicVRegister& src1,
689                                 const LogicVRegister& src2,
690                                 int index) {
691   SimVRegister temp;
692   VectorFormat indexform =
693                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
694   return umlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
695 }
696 
697 
umlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)698 LogicVRegister Simulator::umlal2(VectorFormat vform,
699                                 LogicVRegister dst,
700                                 const LogicVRegister& src1,
701                                 const LogicVRegister& src2,
702                                 int index) {
703   SimVRegister temp;
704   VectorFormat indexform =
705                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
706   return umlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
707 }
708 
709 
smlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)710 LogicVRegister Simulator::smlsl(VectorFormat vform,
711                                 LogicVRegister dst,
712                                 const LogicVRegister& src1,
713                                 const LogicVRegister& src2,
714                                 int index) {
715   SimVRegister temp;
716   VectorFormat indexform =
717                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
718   return smlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
719 }
720 
721 
smlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)722 LogicVRegister Simulator::smlsl2(VectorFormat vform,
723                                 LogicVRegister dst,
724                                 const LogicVRegister& src1,
725                                 const LogicVRegister& src2,
726                                 int index) {
727   SimVRegister temp;
728   VectorFormat indexform =
729                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
730   return smlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
731 }
732 
733 
umlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)734 LogicVRegister Simulator::umlsl(VectorFormat vform,
735                                 LogicVRegister dst,
736                                 const LogicVRegister& src1,
737                                 const LogicVRegister& src2,
738                                 int index) {
739   SimVRegister temp;
740   VectorFormat indexform =
741                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
742   return umlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
743 }
744 
745 
umlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)746 LogicVRegister Simulator::umlsl2(VectorFormat vform,
747                                 LogicVRegister dst,
748                                 const LogicVRegister& src1,
749                                 const LogicVRegister& src2,
750                                 int index) {
751   SimVRegister temp;
752   VectorFormat indexform =
753                VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
754   return umlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
755 }
756 
757 
sqdmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)758 LogicVRegister Simulator::sqdmull(VectorFormat vform,
759                                   LogicVRegister dst,
760                                   const LogicVRegister& src1,
761                                   const LogicVRegister& src2,
762                                   int index) {
763   SimVRegister temp;
764   VectorFormat indexform =
765       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
766   return sqdmull(vform, dst, src1, dup_element(indexform, temp, src2, index));
767 }
768 
769 
sqdmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)770 LogicVRegister Simulator::sqdmull2(VectorFormat vform,
771                                   LogicVRegister dst,
772                                   const LogicVRegister& src1,
773                                   const LogicVRegister& src2,
774                                   int index) {
775   SimVRegister temp;
776   VectorFormat indexform =
777       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
778   return sqdmull2(vform, dst, src1, dup_element(indexform, temp, src2, index));
779 }
780 
781 
sqdmlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)782 LogicVRegister Simulator::sqdmlal(VectorFormat vform,
783                                   LogicVRegister dst,
784                                   const LogicVRegister& src1,
785                                   const LogicVRegister& src2,
786                                   int index) {
787   SimVRegister temp;
788   VectorFormat indexform =
789       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
790   return sqdmlal(vform, dst, src1, dup_element(indexform, temp, src2, index));
791 }
792 
793 
sqdmlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)794 LogicVRegister Simulator::sqdmlal2(VectorFormat vform,
795                                   LogicVRegister dst,
796                                   const LogicVRegister& src1,
797                                   const LogicVRegister& src2,
798                                   int index) {
799   SimVRegister temp;
800   VectorFormat indexform =
801       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
802   return sqdmlal2(vform, dst, src1, dup_element(indexform, temp, src2, index));
803 }
804 
805 
sqdmlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)806 LogicVRegister Simulator::sqdmlsl(VectorFormat vform,
807                                   LogicVRegister dst,
808                                   const LogicVRegister& src1,
809                                   const LogicVRegister& src2,
810                                   int index) {
811   SimVRegister temp;
812   VectorFormat indexform =
813       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
814   return sqdmlsl(vform, dst, src1, dup_element(indexform, temp, src2, index));
815 }
816 
817 
sqdmlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)818 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
819                                   LogicVRegister dst,
820                                   const LogicVRegister& src1,
821                                   const LogicVRegister& src2,
822                                   int index) {
823   SimVRegister temp;
824   VectorFormat indexform =
825       VectorFormatHalfWidthDoubleLanes(VectorFormatFillQ(vform));
826   return sqdmlsl2(vform, dst, src1, dup_element(indexform, temp, src2, index));
827 }
828 
829 
sqdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)830 LogicVRegister Simulator::sqdmulh(VectorFormat vform,
831                                   LogicVRegister dst,
832                                   const LogicVRegister& src1,
833                                   const LogicVRegister& src2,
834                                   int index) {
835   SimVRegister temp;
836   VectorFormat indexform = VectorFormatFillQ(vform);
837   return sqdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
838 }
839 
840 
sqrdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)841 LogicVRegister Simulator::sqrdmulh(VectorFormat vform,
842                                   LogicVRegister dst,
843                                   const LogicVRegister& src1,
844                                   const LogicVRegister& src2,
845                                   int index) {
846   SimVRegister temp;
847   VectorFormat indexform = VectorFormatFillQ(vform);
848   return sqrdmulh(vform, dst, src1, dup_element(indexform, temp, src2, index));
849 }
850 
851 
PolynomialMult(uint8_t op1,uint8_t op2)852 uint16_t Simulator::PolynomialMult(uint8_t op1, uint8_t op2) {
853   uint16_t result = 0;
854   uint16_t extended_op2 = op2;
855   for (int i = 0; i < 8; ++i) {
856     if ((op1 >> i) & 1) {
857       result = result ^ (extended_op2 << i);
858     }
859   }
860   return result;
861 }
862 
863 
pmul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)864 LogicVRegister Simulator::pmul(VectorFormat vform,
865                                LogicVRegister dst,
866                                const LogicVRegister& src1,
867                                const LogicVRegister& src2) {
868   dst.ClearForWrite(vform);
869   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
870     dst.SetUint(vform, i,
871                 PolynomialMult(src1.Uint(vform, i), src2.Uint(vform, i)));
872   }
873   return dst;
874 }
875 
876 
pmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)877 LogicVRegister Simulator::pmull(VectorFormat vform,
878                                LogicVRegister dst,
879                                const LogicVRegister& src1,
880                                const LogicVRegister& src2) {
881   VectorFormat vform_src = VectorFormatHalfWidth(vform);
882   dst.ClearForWrite(vform);
883   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
884     dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, i),
885                                          src2.Uint(vform_src, i)));
886   }
887   return dst;
888 }
889 
890 
pmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)891 LogicVRegister Simulator::pmull2(VectorFormat vform,
892                                 LogicVRegister dst,
893                                 const LogicVRegister& src1,
894                                 const LogicVRegister& src2) {
895   VectorFormat vform_src = VectorFormatHalfWidthDoubleLanes(vform);
896   dst.ClearForWrite(vform);
897   int lane_count = LaneCountFromFormat(vform);
898   for (int i = 0; i < lane_count; i++) {
899     dst.SetUint(vform, i, PolynomialMult(src1.Uint(vform_src, lane_count + i),
900                                          src2.Uint(vform_src, lane_count + i)));
901   }
902   return dst;
903 }
904 
905 
sub(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)906 LogicVRegister Simulator::sub(VectorFormat vform,
907                               LogicVRegister dst,
908                               const LogicVRegister& src1,
909                               const LogicVRegister& src2) {
910   dst.ClearForWrite(vform);
911   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
912     // Test for unsigned saturation.
913     if (src2.Uint(vform, i) > src1.Uint(vform, i)) {
914       dst.SetUnsignedSat(i, false);
915     }
916 
917     // Test for signed saturation.
918     int64_t sa = src1.IntLeftJustified(vform, i);
919     int64_t sb = src2.IntLeftJustified(vform, i);
920     int64_t sr = sa - sb;
921     // If the signs of the operands are different, and the sign of the first
922     // operand doesn't match the result, there was an overflow.
923     if (((sa >= 0) != (sb >= 0)) && ((sa >= 0) != (sr >= 0))) {
924       dst.SetSignedSat(i, sr < 0);
925     }
926 
927     dst.SetInt(vform, i, src1.Int(vform, i) - src2.Int(vform, i));
928   }
929   return dst;
930 }
931 
932 
and_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)933 LogicVRegister Simulator::and_(VectorFormat vform,
934                                LogicVRegister dst,
935                                const LogicVRegister& src1,
936                                const LogicVRegister& src2) {
937   dst.ClearForWrite(vform);
938   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
939     dst.SetUint(vform, i, src1.Uint(vform, i) & src2.Uint(vform, i));
940   }
941   return dst;
942 }
943 
944 
orr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)945 LogicVRegister Simulator::orr(VectorFormat vform,
946                               LogicVRegister dst,
947                               const LogicVRegister& src1,
948                               const LogicVRegister& src2) {
949   dst.ClearForWrite(vform);
950   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
951     dst.SetUint(vform, i, src1.Uint(vform, i) | src2.Uint(vform, i));
952   }
953   return dst;
954 }
955 
956 
orn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)957 LogicVRegister Simulator::orn(VectorFormat vform,
958                               LogicVRegister dst,
959                               const LogicVRegister& src1,
960                               const LogicVRegister& src2) {
961   dst.ClearForWrite(vform);
962   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
963     dst.SetUint(vform, i, src1.Uint(vform, i) | ~src2.Uint(vform, i));
964   }
965   return dst;
966 }
967 
968 
eor(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)969 LogicVRegister Simulator::eor(VectorFormat vform,
970                               LogicVRegister dst,
971                               const LogicVRegister& src1,
972                               const LogicVRegister& src2) {
973   dst.ClearForWrite(vform);
974   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
975     dst.SetUint(vform, i, src1.Uint(vform, i) ^ src2.Uint(vform, i));
976   }
977   return dst;
978 }
979 
980 
bic(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)981 LogicVRegister Simulator::bic(VectorFormat vform,
982                               LogicVRegister dst,
983                               const LogicVRegister& src1,
984                               const LogicVRegister& src2) {
985   dst.ClearForWrite(vform);
986   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
987     dst.SetUint(vform, i, src1.Uint(vform, i) & ~src2.Uint(vform, i));
988   }
989   return dst;
990 }
991 
992 
bic(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,uint64_t imm)993 LogicVRegister Simulator::bic(VectorFormat vform,
994                               LogicVRegister dst,
995                               const LogicVRegister& src,
996                               uint64_t imm) {
997   uint64_t result[16];
998   int laneCount = LaneCountFromFormat(vform);
999   for (int i = 0; i < laneCount; ++i) {
1000     result[i] = src.Uint(vform, i) & ~imm;
1001   }
1002   dst.ClearForWrite(vform);
1003   for (int i = 0; i < laneCount; ++i) {
1004     dst.SetUint(vform, i, result[i]);
1005   }
1006   return dst;
1007 }
1008 
1009 
bif(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1010 LogicVRegister Simulator::bif(VectorFormat vform,
1011                               LogicVRegister dst,
1012                               const LogicVRegister& src1,
1013                               const LogicVRegister& src2) {
1014   dst.ClearForWrite(vform);
1015   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1016     uint64_t operand1 = dst.Uint(vform, i);
1017     uint64_t operand2 = ~src2.Uint(vform, i);
1018     uint64_t operand3 = src1.Uint(vform, i);
1019     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1020     dst.SetUint(vform, i, result);
1021   }
1022   return dst;
1023 }
1024 
1025 
bit(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1026 LogicVRegister Simulator::bit(VectorFormat vform,
1027                               LogicVRegister dst,
1028                               const LogicVRegister& src1,
1029                               const LogicVRegister& src2) {
1030   dst.ClearForWrite(vform);
1031   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1032     uint64_t operand1 = dst.Uint(vform, i);
1033     uint64_t operand2 = src2.Uint(vform, i);
1034     uint64_t operand3 = src1.Uint(vform, i);
1035     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1036     dst.SetUint(vform, i, result);
1037   }
1038   return dst;
1039 }
1040 
1041 
bsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1042 LogicVRegister Simulator::bsl(VectorFormat vform,
1043                               LogicVRegister dst,
1044                               const LogicVRegister& src1,
1045                               const LogicVRegister& src2) {
1046   dst.ClearForWrite(vform);
1047   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1048     uint64_t operand1 = src2.Uint(vform, i);
1049     uint64_t operand2 = dst.Uint(vform, i);
1050     uint64_t operand3 = src1.Uint(vform, i);
1051     uint64_t result = operand1 ^ ((operand1 ^ operand3) & operand2);
1052     dst.SetUint(vform, i, result);
1053   }
1054   return dst;
1055 }
1056 
1057 
sminmax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool max)1058 LogicVRegister Simulator::sminmax(VectorFormat vform,
1059                                   LogicVRegister dst,
1060                                   const LogicVRegister& src1,
1061                                   const LogicVRegister& src2,
1062                                   bool max) {
1063   dst.ClearForWrite(vform);
1064   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1065     int64_t src1_val = src1.Int(vform, i);
1066     int64_t src2_val = src2.Int(vform, i);
1067     int64_t dst_val;
1068     if (max == true) {
1069       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1070     } else {
1071       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1072     }
1073     dst.SetInt(vform, i, dst_val);
1074   }
1075   return dst;
1076 }
1077 
1078 
smax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1079 LogicVRegister Simulator::smax(VectorFormat vform,
1080                                LogicVRegister dst,
1081                                const LogicVRegister& src1,
1082                                const LogicVRegister& src2) {
1083   return sminmax(vform, dst, src1, src2, true);
1084 }
1085 
1086 
smin(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1087 LogicVRegister Simulator::smin(VectorFormat vform,
1088                                LogicVRegister dst,
1089                                const LogicVRegister& src1,
1090                                const LogicVRegister& src2) {
1091   return sminmax(vform, dst, src1, src2, false);
1092 }
1093 
1094 
sminmaxp(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,bool max)1095 LogicVRegister Simulator::sminmaxp(VectorFormat vform,
1096                                    LogicVRegister dst,
1097                                    int dst_index,
1098                                    const LogicVRegister& src,
1099                                    bool max) {
1100   for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
1101     int64_t src1_val = src.Int(vform, i);
1102     int64_t src2_val = src.Int(vform, i + 1);
1103     int64_t dst_val;
1104     if (max == true) {
1105       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1106     } else {
1107       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1108     }
1109     dst.SetInt(vform, dst_index + (i >> 1), dst_val);
1110   }
1111   return dst;
1112 }
1113 
1114 
smaxp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1115 LogicVRegister Simulator::smaxp(VectorFormat vform,
1116                                 LogicVRegister dst,
1117                                 const LogicVRegister& src1,
1118                                 const LogicVRegister& src2) {
1119   dst.ClearForWrite(vform);
1120   sminmaxp(vform, dst, 0, src1, true);
1121   sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
1122   return dst;
1123 }
1124 
1125 
sminp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1126 LogicVRegister Simulator::sminp(VectorFormat vform,
1127                                 LogicVRegister dst,
1128                                 const LogicVRegister& src1,
1129                                 const LogicVRegister& src2) {
1130   dst.ClearForWrite(vform);
1131   sminmaxp(vform, dst, 0, src1, false);
1132   sminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
1133   return dst;
1134 }
1135 
1136 
addp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1137 LogicVRegister Simulator::addp(VectorFormat vform,
1138                                LogicVRegister dst,
1139                                const LogicVRegister& src) {
1140   VIXL_ASSERT(vform == kFormatD);
1141 
1142   int64_t dst_val = src.Int(kFormat2D, 0) + src.Int(kFormat2D, 1);
1143   dst.ClearForWrite(vform);
1144   dst.SetInt(vform, 0, dst_val);
1145   return dst;
1146 }
1147 
1148 
addv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1149 LogicVRegister Simulator::addv(VectorFormat vform,
1150                                LogicVRegister dst,
1151                                const LogicVRegister& src) {
1152   VectorFormat vform_dst
1153     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform));
1154 
1155 
1156   int64_t dst_val = 0;
1157   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1158     dst_val += src.Int(vform, i);
1159   }
1160 
1161   dst.ClearForWrite(vform_dst);
1162   dst.SetInt(vform_dst, 0, dst_val);
1163   return dst;
1164 }
1165 
1166 
saddlv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1167 LogicVRegister Simulator::saddlv(VectorFormat vform,
1168                                  LogicVRegister dst,
1169                                  const LogicVRegister& src) {
1170   VectorFormat vform_dst
1171     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1172 
1173   int64_t dst_val = 0;
1174   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1175     dst_val += src.Int(vform, i);
1176   }
1177 
1178   dst.ClearForWrite(vform_dst);
1179   dst.SetInt(vform_dst, 0, dst_val);
1180   return dst;
1181 }
1182 
1183 
uaddlv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1184 LogicVRegister Simulator::uaddlv(VectorFormat vform,
1185                                  LogicVRegister dst,
1186                                  const LogicVRegister& src) {
1187   VectorFormat vform_dst
1188     = ScalarFormatFromLaneSize(LaneSizeInBitsFromFormat(vform) * 2);
1189 
1190   uint64_t dst_val = 0;
1191   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1192     dst_val += src.Uint(vform, i);
1193   }
1194 
1195   dst.ClearForWrite(vform_dst);
1196   dst.SetUint(vform_dst, 0, dst_val);
1197   return dst;
1198 }
1199 
1200 
sminmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool max)1201 LogicVRegister Simulator::sminmaxv(VectorFormat vform,
1202                                    LogicVRegister dst,
1203                                    const LogicVRegister& src,
1204                                    bool max) {
1205   dst.ClearForWrite(vform);
1206   int64_t dst_val = max ? INT64_MIN : INT64_MAX;
1207   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1208     int64_t src_val = src.Int(vform, i);
1209     if (max == true) {
1210       dst_val = (src_val > dst_val) ? src_val : dst_val;
1211     } else {
1212       dst_val = (src_val < dst_val) ? src_val : dst_val;
1213     }
1214   }
1215   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1216     dst.SetInt(vform, i, 0);
1217   }
1218   dst.SetInt(vform, 0, dst_val);
1219   return dst;
1220 }
1221 
1222 
smaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1223 LogicVRegister Simulator::smaxv(VectorFormat vform,
1224                                 LogicVRegister dst,
1225                                 const LogicVRegister& src) {
1226   sminmaxv(vform, dst, src, true);
1227   return dst;
1228 }
1229 
1230 
sminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1231 LogicVRegister Simulator::sminv(VectorFormat vform,
1232                                 LogicVRegister dst,
1233                                 const LogicVRegister& src) {
1234   sminmaxv(vform, dst, src, false);
1235   return dst;
1236 }
1237 
1238 
uminmax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool max)1239 LogicVRegister Simulator::uminmax(VectorFormat vform,
1240                                   LogicVRegister dst,
1241                                   const LogicVRegister& src1,
1242                                   const LogicVRegister& src2,
1243                                   bool max) {
1244   dst.ClearForWrite(vform);
1245   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1246     uint64_t src1_val = src1.Uint(vform, i);
1247     uint64_t src2_val = src2.Uint(vform, i);
1248     uint64_t dst_val;
1249     if (max == true) {
1250       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1251     } else {
1252       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1253     }
1254     dst.SetUint(vform, i, dst_val);
1255   }
1256   return dst;
1257 }
1258 
1259 
umax(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1260 LogicVRegister Simulator::umax(VectorFormat vform,
1261                                LogicVRegister dst,
1262                                const LogicVRegister& src1,
1263                                const LogicVRegister& src2) {
1264   return uminmax(vform, dst, src1, src2, true);
1265 }
1266 
1267 
umin(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1268 LogicVRegister Simulator::umin(VectorFormat vform,
1269                                LogicVRegister dst,
1270                                const LogicVRegister& src1,
1271                                const LogicVRegister& src2) {
1272   return uminmax(vform, dst, src1, src2, false);
1273 }
1274 
1275 
uminmaxp(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,bool max)1276 LogicVRegister Simulator::uminmaxp(VectorFormat vform,
1277                                    LogicVRegister dst,
1278                                    int dst_index,
1279                                    const LogicVRegister& src,
1280                                    bool max) {
1281   for (int i = 0; i < LaneCountFromFormat(vform); i += 2) {
1282     uint64_t src1_val = src.Uint(vform, i);
1283     uint64_t src2_val = src.Uint(vform, i + 1);
1284     uint64_t dst_val;
1285     if (max == true) {
1286       dst_val = (src1_val > src2_val) ? src1_val : src2_val;
1287     } else {
1288       dst_val = (src1_val < src2_val) ? src1_val : src2_val;
1289     }
1290     dst.SetUint(vform, dst_index + (i >> 1), dst_val);
1291   }
1292   return dst;
1293 }
1294 
1295 
umaxp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1296 LogicVRegister Simulator::umaxp(VectorFormat vform,
1297                                 LogicVRegister dst,
1298                                 const LogicVRegister& src1,
1299                                 const LogicVRegister& src2) {
1300   dst.ClearForWrite(vform);
1301   uminmaxp(vform, dst, 0, src1, true);
1302   uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, true);
1303   return dst;
1304 }
1305 
1306 
uminp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1307 LogicVRegister Simulator::uminp(VectorFormat vform,
1308                                 LogicVRegister dst,
1309                                 const LogicVRegister& src1,
1310                                 const LogicVRegister& src2) {
1311   dst.ClearForWrite(vform);
1312   uminmaxp(vform, dst, 0, src1, false);
1313   uminmaxp(vform, dst, LaneCountFromFormat(vform) >> 1, src2, false);
1314   return dst;
1315 }
1316 
1317 
uminmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool max)1318 LogicVRegister Simulator::uminmaxv(VectorFormat vform,
1319                                    LogicVRegister dst,
1320                                    const LogicVRegister& src,
1321                                    bool max) {
1322   dst.ClearForWrite(vform);
1323   uint64_t dst_val = max ? 0 : UINT64_MAX;
1324   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1325     uint64_t src_val = src.Uint(vform, i);
1326     if (max == true) {
1327       dst_val = (src_val > dst_val) ? src_val : dst_val;
1328     } else {
1329       dst_val = (src_val < dst_val) ? src_val : dst_val;
1330     }
1331   }
1332   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1333     dst.SetUint(vform, i, 0);
1334   }
1335   dst.SetUint(vform, 0, dst_val);
1336   return dst;
1337 }
1338 
1339 
umaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1340 LogicVRegister Simulator::umaxv(VectorFormat vform,
1341                                 LogicVRegister dst,
1342                                 const LogicVRegister& src) {
1343   uminmaxv(vform, dst, src, true);
1344   return dst;
1345 }
1346 
1347 
uminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1348 LogicVRegister Simulator::uminv(VectorFormat vform,
1349                                 LogicVRegister dst,
1350                                 const LogicVRegister& src) {
1351   uminmaxv(vform, dst, src, false);
1352   return dst;
1353 }
1354 
1355 
shl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1356 LogicVRegister Simulator::shl(VectorFormat vform,
1357                               LogicVRegister dst,
1358                               const LogicVRegister& src,
1359                               int shift) {
1360   VIXL_ASSERT(shift >= 0);
1361   SimVRegister temp;
1362   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1363   return ushl(vform, dst, src, shiftreg);
1364 }
1365 
1366 
sshll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1367 LogicVRegister Simulator::sshll(VectorFormat vform,
1368                                 LogicVRegister dst,
1369                                 const LogicVRegister& src,
1370                                 int shift) {
1371   VIXL_ASSERT(shift >= 0);
1372   SimVRegister temp1, temp2;
1373   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1374   LogicVRegister extendedreg = sxtl(vform, temp2, src);
1375   return sshl(vform, dst, extendedreg, shiftreg);
1376 }
1377 
1378 
sshll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1379 LogicVRegister Simulator::sshll2(VectorFormat vform,
1380                                  LogicVRegister dst,
1381                                  const LogicVRegister& src,
1382                                  int shift) {
1383   VIXL_ASSERT(shift >= 0);
1384   SimVRegister temp1, temp2;
1385   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1386   LogicVRegister extendedreg = sxtl2(vform, temp2, src);
1387   return sshl(vform, dst, extendedreg, shiftreg);
1388 }
1389 
1390 
shll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1391 LogicVRegister Simulator::shll(VectorFormat vform,
1392                                LogicVRegister dst,
1393                                const LogicVRegister& src) {
1394   int shift = LaneSizeInBitsFromFormat(vform) / 2;
1395   return sshll(vform, dst, src, shift);
1396 }
1397 
1398 
shll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1399 LogicVRegister Simulator::shll2(VectorFormat vform,
1400                                 LogicVRegister dst,
1401                                 const LogicVRegister& src) {
1402   int shift = LaneSizeInBitsFromFormat(vform) / 2;
1403   return sshll2(vform, dst, src, shift);
1404 }
1405 
1406 
ushll(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1407 LogicVRegister Simulator::ushll(VectorFormat vform,
1408                                 LogicVRegister dst,
1409                                 const LogicVRegister& src,
1410                                 int shift) {
1411   VIXL_ASSERT(shift >= 0);
1412   SimVRegister temp1, temp2;
1413   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1414   LogicVRegister extendedreg = uxtl(vform, temp2, src);
1415   return ushl(vform, dst, extendedreg, shiftreg);
1416 }
1417 
1418 
ushll2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1419 LogicVRegister Simulator::ushll2(VectorFormat vform,
1420                                  LogicVRegister dst,
1421                                  const LogicVRegister& src,
1422                                  int shift) {
1423   VIXL_ASSERT(shift >= 0);
1424   SimVRegister temp1, temp2;
1425   LogicVRegister shiftreg = dup_immediate(vform, temp1, shift);
1426   LogicVRegister extendedreg = uxtl2(vform, temp2, src);
1427   return ushl(vform, dst, extendedreg, shiftreg);
1428 }
1429 
1430 
sli(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1431 LogicVRegister Simulator::sli(VectorFormat vform,
1432                               LogicVRegister dst,
1433                               const LogicVRegister& src,
1434                               int shift) {
1435   dst.ClearForWrite(vform);
1436   int laneCount = LaneCountFromFormat(vform);
1437   for (int i = 0; i < laneCount; i++) {
1438     uint64_t src_lane = src.Uint(vform, i);
1439     uint64_t dst_lane = dst.Uint(vform, i);
1440     uint64_t shifted = src_lane << shift;
1441     uint64_t mask = MaxUintFromFormat(vform) << shift;
1442     dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
1443   }
1444   return dst;
1445 }
1446 
1447 
sqshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1448 LogicVRegister Simulator::sqshl(VectorFormat vform,
1449                                 LogicVRegister dst,
1450                                 const LogicVRegister& src,
1451                                 int shift) {
1452   VIXL_ASSERT(shift >= 0);
1453   SimVRegister temp;
1454   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1455   return sshl(vform, dst, src, shiftreg).SignedSaturate(vform);
1456 }
1457 
1458 
uqshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1459 LogicVRegister Simulator::uqshl(VectorFormat vform,
1460                                 LogicVRegister dst,
1461                                 const LogicVRegister& src,
1462                                 int shift) {
1463   VIXL_ASSERT(shift >= 0);
1464   SimVRegister temp;
1465   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1466   return ushl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1467 }
1468 
1469 
sqshlu(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1470 LogicVRegister Simulator::sqshlu(VectorFormat vform,
1471                                  LogicVRegister dst,
1472                                  const LogicVRegister& src,
1473                                  int shift) {
1474   VIXL_ASSERT(shift >= 0);
1475   SimVRegister temp;
1476   LogicVRegister shiftreg = dup_immediate(vform, temp, shift);
1477   return sshl(vform, dst, src, shiftreg).UnsignedSaturate(vform);
1478 }
1479 
1480 
sri(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1481 LogicVRegister Simulator::sri(VectorFormat vform,
1482                               LogicVRegister dst,
1483                               const LogicVRegister& src,
1484                               int shift) {
1485   dst.ClearForWrite(vform);
1486   int laneCount = LaneCountFromFormat(vform);
1487   VIXL_ASSERT((shift > 0) &&
1488               (shift <= static_cast<int>(LaneSizeInBitsFromFormat(vform))));
1489   for (int i = 0; i < laneCount; i++) {
1490     uint64_t src_lane = src.Uint(vform, i);
1491     uint64_t dst_lane = dst.Uint(vform, i);
1492     uint64_t shifted;
1493     uint64_t mask;
1494     if (shift == 64) {
1495       shifted = 0;
1496       mask = 0;
1497     } else {
1498       shifted = src_lane >> shift;
1499       mask = MaxUintFromFormat(vform) >> shift;
1500     }
1501     dst.SetUint(vform, i, (dst_lane & ~mask) | shifted);
1502   }
1503   return dst;
1504 }
1505 
1506 
ushr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1507 LogicVRegister Simulator::ushr(VectorFormat vform,
1508                                LogicVRegister dst,
1509                                const LogicVRegister& src,
1510                                int shift) {
1511   VIXL_ASSERT(shift >= 0);
1512   SimVRegister temp;
1513   LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1514   return ushl(vform, dst, src, shiftreg);
1515 }
1516 
1517 
sshr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1518 LogicVRegister Simulator::sshr(VectorFormat vform,
1519                                LogicVRegister dst,
1520                                const LogicVRegister& src,
1521                                int shift) {
1522   VIXL_ASSERT(shift >= 0);
1523   SimVRegister temp;
1524   LogicVRegister shiftreg = dup_immediate(vform, temp, -shift);
1525   return sshl(vform, dst, src, shiftreg);
1526 }
1527 
1528 
ssra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1529 LogicVRegister Simulator::ssra(VectorFormat vform,
1530                                LogicVRegister dst,
1531                                const LogicVRegister& src,
1532                                int shift) {
1533   SimVRegister temp;
1534   LogicVRegister shifted_reg = sshr(vform, temp, src, shift);
1535   return add(vform, dst, dst, shifted_reg);
1536 }
1537 
1538 
usra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1539 LogicVRegister Simulator::usra(VectorFormat vform,
1540                                LogicVRegister dst,
1541                                const LogicVRegister& src,
1542                                int shift) {
1543   SimVRegister temp;
1544   LogicVRegister shifted_reg = ushr(vform, temp, src, shift);
1545   return add(vform, dst, dst, shifted_reg);
1546 }
1547 
1548 
srsra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1549 LogicVRegister Simulator::srsra(VectorFormat vform,
1550                                 LogicVRegister dst,
1551                                 const LogicVRegister& src,
1552                                 int shift) {
1553   SimVRegister temp;
1554   LogicVRegister shifted_reg = sshr(vform, temp, src, shift).Round(vform);
1555   return add(vform, dst, dst, shifted_reg);
1556 }
1557 
1558 
ursra(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)1559 LogicVRegister Simulator::ursra(VectorFormat vform,
1560                                 LogicVRegister dst,
1561                                 const LogicVRegister& src,
1562                                 int shift) {
1563   SimVRegister temp;
1564   LogicVRegister shifted_reg = ushr(vform, temp, src, shift).Round(vform);
1565   return add(vform, dst, dst, shifted_reg);
1566 }
1567 
1568 
cls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1569 LogicVRegister Simulator::cls(VectorFormat vform,
1570                               LogicVRegister dst,
1571                               const LogicVRegister& src) {
1572   uint64_t result[16];
1573   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1574   int laneCount = LaneCountFromFormat(vform);
1575   for (int i = 0; i < laneCount; i++) {
1576     result[i] = CountLeadingSignBits(src.Int(vform, i), laneSizeInBits);
1577   }
1578 
1579   dst.ClearForWrite(vform);
1580   for (int i = 0; i < laneCount; ++i) {
1581     dst.SetUint(vform, i, result[i]);
1582   }
1583   return dst;
1584 }
1585 
1586 
clz(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1587 LogicVRegister Simulator::clz(VectorFormat vform,
1588                               LogicVRegister dst,
1589                               const LogicVRegister& src) {
1590   uint64_t result[16];
1591   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1592   int laneCount = LaneCountFromFormat(vform);
1593   for (int i = 0; i < laneCount; i++) {
1594     result[i] = CountLeadingZeros(src.Uint(vform, i), laneSizeInBits);
1595   }
1596 
1597   dst.ClearForWrite(vform);
1598   for (int i = 0; i < laneCount; ++i) {
1599     dst.SetUint(vform, i, result[i]);
1600   }
1601   return dst;
1602 }
1603 
1604 
cnt(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1605 LogicVRegister Simulator::cnt(VectorFormat vform,
1606                               LogicVRegister dst,
1607                               const LogicVRegister& src) {
1608   uint64_t result[16];
1609   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1610   int laneCount = LaneCountFromFormat(vform);
1611   for (int i = 0; i < laneCount; i++) {
1612     uint64_t value = src.Uint(vform, i);
1613     result[i] = 0;
1614     for (int j = 0; j < laneSizeInBits; j++) {
1615       result[i] += (value & 1);
1616       value >>= 1;
1617     }
1618   }
1619 
1620   dst.ClearForWrite(vform);
1621   for (int i = 0; i < laneCount; ++i) {
1622     dst.SetUint(vform, i, result[i]);
1623   }
1624   return dst;
1625 }
1626 
1627 
sshl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1628 LogicVRegister Simulator::sshl(VectorFormat vform,
1629                                LogicVRegister dst,
1630                                const LogicVRegister& src1,
1631                                const LogicVRegister& src2) {
1632   dst.ClearForWrite(vform);
1633   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1634     int8_t shift_val = src2.Int(vform, i);
1635     int64_t lj_src_val = src1.IntLeftJustified(vform, i);
1636 
1637     // Set signed saturation state.
1638     if ((shift_val > CountLeadingSignBits(lj_src_val)) &&
1639         (lj_src_val != 0)) {
1640       dst.SetSignedSat(i, lj_src_val >= 0);
1641     }
1642 
1643     // Set unsigned saturation state.
1644     if (lj_src_val < 0) {
1645       dst.SetUnsignedSat(i, false);
1646     } else if ((shift_val > CountLeadingZeros(lj_src_val)) &&
1647                (lj_src_val != 0)) {
1648       dst.SetUnsignedSat(i, true);
1649     }
1650 
1651     int64_t src_val = src1.Int(vform, i);
1652     if (shift_val > 63) {
1653       dst.SetInt(vform, i, 0);
1654     } else if (shift_val < -63) {
1655       dst.SetRounding(i, src_val < 0);
1656       dst.SetInt(vform, i, (src_val < 0) ? -1 : 0);
1657     } else {
1658       if (shift_val < 0) {
1659         // Set rounding state. Rounding only needed on right shifts.
1660         if (((src_val >> (-shift_val - 1)) & 1) == 1) {
1661           dst.SetRounding(i, true);
1662         }
1663         src_val >>= -shift_val;
1664       } else {
1665         src_val <<= shift_val;
1666       }
1667       dst.SetInt(vform, i, src_val);
1668     }
1669   }
1670   return dst;
1671 }
1672 
1673 
ushl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1674 LogicVRegister Simulator::ushl(VectorFormat vform,
1675                                LogicVRegister dst,
1676                                const LogicVRegister& src1,
1677                                const LogicVRegister& src2) {
1678   dst.ClearForWrite(vform);
1679   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1680     int8_t shift_val = src2.Int(vform, i);
1681     uint64_t lj_src_val = src1.UintLeftJustified(vform, i);
1682 
1683     // Set saturation state.
1684     if ((shift_val > CountLeadingZeros(lj_src_val)) && (lj_src_val != 0)) {
1685       dst.SetUnsignedSat(i, true);
1686     }
1687 
1688     uint64_t src_val = src1.Uint(vform, i);
1689     if ((shift_val > 63) || (shift_val < -64)) {
1690       dst.SetUint(vform, i, 0);
1691     } else {
1692       if (shift_val < 0) {
1693         // Set rounding state. Rounding only needed on right shifts.
1694         if (((src_val >> (-shift_val - 1)) & 1) == 1) {
1695           dst.SetRounding(i, true);
1696         }
1697 
1698         if (shift_val == -64) {
1699           src_val = 0;
1700         } else {
1701           src_val >>= -shift_val;
1702         }
1703       } else {
1704         src_val <<= shift_val;
1705       }
1706       dst.SetUint(vform, i, src_val);
1707     }
1708   }
1709   return dst;
1710 }
1711 
1712 
neg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1713 LogicVRegister Simulator::neg(VectorFormat vform,
1714                               LogicVRegister dst,
1715                               const LogicVRegister& src) {
1716   dst.ClearForWrite(vform);
1717   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1718     // Test for signed saturation.
1719     int64_t sa = src.Int(vform, i);
1720     if (sa == MinIntFromFormat(vform)) {
1721       dst.SetSignedSat(i, true);
1722     }
1723     dst.SetInt(vform, i, -sa);
1724   }
1725   return dst;
1726 }
1727 
1728 
suqadd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1729 LogicVRegister Simulator::suqadd(VectorFormat vform,
1730                                  LogicVRegister dst,
1731                                  const LogicVRegister& src) {
1732   dst.ClearForWrite(vform);
1733   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1734     int64_t  sa = dst.IntLeftJustified(vform, i);
1735     uint64_t ub = src.UintLeftJustified(vform, i);
1736     int64_t  sr = sa + ub;
1737 
1738     if (sr < sa) {  // Test for signed positive saturation.
1739       dst.SetInt(vform, i, MaxIntFromFormat(vform));
1740     } else {
1741       dst.SetInt(vform, i, dst.Int(vform, i) + src.Int(vform, i));
1742     }
1743   }
1744   return dst;
1745 }
1746 
1747 
usqadd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1748 LogicVRegister Simulator::usqadd(VectorFormat vform,
1749                                  LogicVRegister dst,
1750                                  const LogicVRegister& src) {
1751   dst.ClearForWrite(vform);
1752   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1753     uint64_t  ua = dst.UintLeftJustified(vform, i);
1754     int64_t   sb = src.IntLeftJustified(vform, i);
1755     uint64_t  ur = ua + sb;
1756 
1757     if ((sb > 0) && (ur <= ua)) {
1758       dst.SetUint(vform, i, MaxUintFromFormat(vform));  // Positive saturation.
1759     } else if ((sb < 0) && (ur >= ua)) {
1760       dst.SetUint(vform, i, 0);                         // Negative saturation.
1761     } else {
1762       dst.SetUint(vform, i, dst.Uint(vform, i) + src.Int(vform, i));
1763     }
1764   }
1765   return dst;
1766 }
1767 
1768 
abs(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1769 LogicVRegister Simulator::abs(VectorFormat vform,
1770                               LogicVRegister dst,
1771                               const LogicVRegister& src) {
1772   dst.ClearForWrite(vform);
1773   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1774     // Test for signed saturation.
1775     int64_t sa = src.Int(vform, i);
1776     if (sa == MinIntFromFormat(vform)) {
1777       dst.SetSignedSat(i, true);
1778     }
1779     if (sa < 0) {
1780       dst.SetInt(vform, i, -sa);
1781     } else {
1782       dst.SetInt(vform, i, sa);
1783     }
1784   }
1785   return dst;
1786 }
1787 
1788 
extractnarrow(VectorFormat dstform,LogicVRegister dst,bool dstIsSigned,const LogicVRegister & src,bool srcIsSigned)1789 LogicVRegister Simulator::extractnarrow(VectorFormat dstform,
1790                                         LogicVRegister dst,
1791                                         bool dstIsSigned,
1792                                         const LogicVRegister& src,
1793                                         bool srcIsSigned) {
1794   bool upperhalf = false;
1795   VectorFormat srcform = kFormatUndefined;
1796   int64_t  ssrc[8];
1797   uint64_t usrc[8];
1798 
1799   switch (dstform) {
1800     case kFormat8B : upperhalf = false; srcform = kFormat8H; break;
1801     case kFormat16B: upperhalf = true;  srcform = kFormat8H; break;
1802     case kFormat4H : upperhalf = false; srcform = kFormat4S; break;
1803     case kFormat8H : upperhalf = true;  srcform = kFormat4S; break;
1804     case kFormat2S : upperhalf = false; srcform = kFormat2D; break;
1805     case kFormat4S : upperhalf = true;  srcform = kFormat2D; break;
1806     case kFormatB  : upperhalf = false; srcform = kFormatH;  break;
1807     case kFormatH  : upperhalf = false; srcform = kFormatS;  break;
1808     case kFormatS  : upperhalf = false; srcform = kFormatD;  break;
1809     default:VIXL_UNIMPLEMENTED();
1810   }
1811 
1812   for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
1813     ssrc[i] = src.Int(srcform, i);
1814     usrc[i] = src.Uint(srcform, i);
1815   }
1816 
1817   int offset;
1818   if (upperhalf) {
1819     offset = LaneCountFromFormat(dstform) / 2;
1820   } else {
1821     offset = 0;
1822     dst.ClearForWrite(dstform);
1823   }
1824 
1825   for (int i = 0; i < LaneCountFromFormat(srcform); i++) {
1826     // Test for signed saturation
1827     if (ssrc[i] > MaxIntFromFormat(dstform)) {
1828       dst.SetSignedSat(offset + i, true);
1829     } else if (ssrc[i] < MinIntFromFormat(dstform)) {
1830       dst.SetSignedSat(offset + i, false);
1831     }
1832 
1833     // Test for unsigned saturation
1834     if (srcIsSigned) {
1835       if (ssrc[i] > static_cast<int64_t>(MaxUintFromFormat(dstform))) {
1836         dst.SetUnsignedSat(offset + i, true);
1837       } else if (ssrc[i] < 0) {
1838         dst.SetUnsignedSat(offset + i, false);
1839       }
1840     } else {
1841       if (usrc[i] > MaxUintFromFormat(dstform)) {
1842         dst.SetUnsignedSat(offset + i, true);
1843       }
1844     }
1845 
1846     int64_t result;
1847     if (srcIsSigned) {
1848       result = ssrc[i] & MaxUintFromFormat(dstform);
1849     } else {
1850       result = usrc[i] & MaxUintFromFormat(dstform);
1851     }
1852 
1853     if (dstIsSigned) {
1854       dst.SetInt(dstform, offset + i, result);
1855     } else {
1856       dst.SetUint(dstform, offset + i, result);
1857     }
1858   }
1859   return dst;
1860 }
1861 
1862 
xtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1863 LogicVRegister Simulator::xtn(VectorFormat vform,
1864                               LogicVRegister dst,
1865                               const LogicVRegister& src) {
1866   return extractnarrow(vform, dst, true, src, true);
1867 }
1868 
1869 
sqxtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1870 LogicVRegister Simulator::sqxtn(VectorFormat vform,
1871                                 LogicVRegister dst,
1872                                 const LogicVRegister& src) {
1873   return extractnarrow(vform, dst, true, src, true).SignedSaturate(vform);
1874 }
1875 
1876 
sqxtun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1877 LogicVRegister Simulator::sqxtun(VectorFormat vform,
1878                                  LogicVRegister dst,
1879                                  const LogicVRegister& src) {
1880   return extractnarrow(vform, dst, false, src, true).UnsignedSaturate(vform);
1881 }
1882 
1883 
uqxtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1884 LogicVRegister Simulator::uqxtn(VectorFormat vform,
1885                                 LogicVRegister dst,
1886                                 const LogicVRegister& src) {
1887   return extractnarrow(vform, dst, false, src, false).UnsignedSaturate(vform);
1888 }
1889 
1890 
absdiff(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool issigned)1891 LogicVRegister Simulator::absdiff(VectorFormat vform,
1892                                   LogicVRegister dst,
1893                                   const LogicVRegister& src1,
1894                                   const LogicVRegister& src2,
1895                                   bool issigned) {
1896   dst.ClearForWrite(vform);
1897   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1898     if (issigned) {
1899       int64_t sr = src1.Int(vform, i) - src2.Int(vform, i);
1900       sr = sr > 0 ? sr : -sr;
1901       dst.SetInt(vform, i, sr);
1902     } else {
1903       int64_t sr = src1.Uint(vform, i) - src2.Uint(vform, i);
1904       sr = sr > 0 ? sr : -sr;
1905       dst.SetUint(vform, i, sr);
1906     }
1907   }
1908   return dst;
1909 }
1910 
1911 
saba(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1912 LogicVRegister Simulator::saba(VectorFormat vform,
1913                                LogicVRegister dst,
1914                                const LogicVRegister& src1,
1915                                const LogicVRegister& src2) {
1916   SimVRegister temp;
1917   dst.ClearForWrite(vform);
1918   absdiff(vform, temp, src1, src2, true);
1919   add(vform, dst, dst, temp);
1920   return dst;
1921 }
1922 
1923 
uaba(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)1924 LogicVRegister Simulator::uaba(VectorFormat vform,
1925                                LogicVRegister dst,
1926                                const LogicVRegister& src1,
1927                                const LogicVRegister& src2) {
1928   SimVRegister temp;
1929   dst.ClearForWrite(vform);
1930   absdiff(vform, temp, src1, src2, false);
1931   add(vform, dst, dst, temp);
1932   return dst;
1933 }
1934 
1935 
not_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1936 LogicVRegister Simulator::not_(VectorFormat vform,
1937                                LogicVRegister dst,
1938                                const LogicVRegister& src) {
1939   dst.ClearForWrite(vform);
1940   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
1941     dst.SetUint(vform, i, ~src.Uint(vform, i));
1942   }
1943   return dst;
1944 }
1945 
1946 
rbit(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1947 LogicVRegister Simulator::rbit(VectorFormat vform,
1948                                LogicVRegister dst,
1949                                const LogicVRegister& src) {
1950   uint64_t result[16];
1951   int laneCount = LaneCountFromFormat(vform);
1952   int laneSizeInBits  = LaneSizeInBitsFromFormat(vform);
1953   uint64_t reversed_value;
1954   uint64_t value;
1955   for (int i = 0; i < laneCount; i++) {
1956     value = src.Uint(vform, i);
1957     reversed_value = 0;
1958     for (int j = 0; j < laneSizeInBits; j++) {
1959       reversed_value = (reversed_value << 1) | (value & 1);
1960       value >>= 1;
1961     }
1962     result[i] = reversed_value;
1963   }
1964 
1965   dst.ClearForWrite(vform);
1966   for (int i = 0; i < laneCount; ++i) {
1967     dst.SetUint(vform, i, result[i]);
1968   }
1969   return dst;
1970 }
1971 
1972 
rev(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int revSize)1973 LogicVRegister Simulator::rev(VectorFormat vform,
1974                               LogicVRegister dst,
1975                               const LogicVRegister& src,
1976                               int revSize) {
1977   uint64_t result[16];
1978   int laneCount = LaneCountFromFormat(vform);
1979   int laneSize = LaneSizeInBytesFromFormat(vform);
1980   int lanesPerLoop =  revSize / laneSize;
1981   for (int i = 0; i < laneCount; i += lanesPerLoop) {
1982     for (int j = 0; j < lanesPerLoop; j++) {
1983       result[i + lanesPerLoop - 1 - j] = src.Uint(vform, i + j);
1984     }
1985   }
1986   dst.ClearForWrite(vform);
1987   for (int i = 0; i < laneCount; ++i) {
1988     dst.SetUint(vform, i, result[i]);
1989   }
1990   return dst;
1991 }
1992 
1993 
rev16(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)1994 LogicVRegister Simulator::rev16(VectorFormat vform,
1995                                 LogicVRegister dst,
1996                                 const LogicVRegister& src) {
1997   return rev(vform, dst, src, 2);
1998 }
1999 
2000 
rev32(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2001 LogicVRegister Simulator::rev32(VectorFormat vform,
2002                                 LogicVRegister dst,
2003                                 const LogicVRegister& src) {
2004   return rev(vform, dst, src, 4);
2005 }
2006 
2007 
rev64(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2008 LogicVRegister Simulator::rev64(VectorFormat vform,
2009                                 LogicVRegister dst,
2010                                 const LogicVRegister& src) {
2011   return rev(vform, dst, src, 8);
2012 }
2013 
2014 
addlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,bool is_signed,bool do_accumulate)2015 LogicVRegister Simulator::addlp(VectorFormat vform,
2016                                  LogicVRegister dst,
2017                                  const LogicVRegister& src,
2018                                  bool is_signed,
2019                                  bool do_accumulate) {
2020   VectorFormat vformsrc = VectorFormatHalfWidthDoubleLanes(vform);
2021 
2022   int64_t  sr[16];
2023   uint64_t ur[16];
2024 
2025   int laneCount = LaneCountFromFormat(vform);
2026   for (int i = 0; i < laneCount; ++i) {
2027     if (is_signed) {
2028       sr[i] = src.Int(vformsrc, 2 * i) + src.Int(vformsrc, 2 * i + 1);
2029     } else {
2030       ur[i] = src.Uint(vformsrc, 2 * i) + src.Uint(vformsrc, 2 * i + 1);
2031     }
2032   }
2033 
2034   dst.ClearForWrite(vform);
2035   for (int i = 0; i < laneCount; ++i) {
2036     if (do_accumulate) {
2037       if (is_signed) {
2038         dst.SetInt(vform, i, dst.Int(vform, i) + sr[i]);
2039       } else {
2040         dst.SetUint(vform, i, dst.Uint(vform, i) + ur[i]);
2041       }
2042     } else {
2043       if (is_signed) {
2044         dst.SetInt(vform, i, sr[i]);
2045       } else {
2046         dst.SetUint(vform, i, ur[i]);
2047       }
2048     }
2049   }
2050 
2051   return dst;
2052 }
2053 
2054 
saddlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2055 LogicVRegister Simulator::saddlp(VectorFormat vform,
2056                                  LogicVRegister dst,
2057                                  const LogicVRegister& src) {
2058   return addlp(vform, dst, src, true, false);
2059 }
2060 
2061 
uaddlp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2062 LogicVRegister Simulator::uaddlp(VectorFormat vform,
2063                                  LogicVRegister dst,
2064                                  const LogicVRegister& src) {
2065   return addlp(vform, dst, src, false, false);
2066 }
2067 
2068 
sadalp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2069 LogicVRegister Simulator::sadalp(VectorFormat vform,
2070                                  LogicVRegister dst,
2071                                  const LogicVRegister& src) {
2072   return addlp(vform, dst, src, true, true);
2073 }
2074 
2075 
uadalp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2076 LogicVRegister Simulator::uadalp(VectorFormat vform,
2077                                  LogicVRegister dst,
2078                                  const LogicVRegister& src) {
2079   return addlp(vform, dst, src, false, true);
2080 }
2081 
2082 
ext(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)2083 LogicVRegister Simulator::ext(VectorFormat vform,
2084                               LogicVRegister dst,
2085                               const LogicVRegister& src1,
2086                               const LogicVRegister& src2,
2087                               int index) {
2088   uint8_t result[16];
2089   int laneCount = LaneCountFromFormat(vform);
2090   for (int i = 0; i < laneCount - index; ++i) {
2091     result[i] = src1.Uint(vform, i + index);
2092   }
2093   for (int i = 0; i < index; ++i) {
2094     result[laneCount - index + i] = src2.Uint(vform, i);
2095   }
2096   dst.ClearForWrite(vform);
2097   for (int i = 0; i < laneCount; ++i) {
2098     dst.SetUint(vform, i, result[i]);
2099   }
2100   return dst;
2101 }
2102 
2103 
dup_element(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int src_index)2104 LogicVRegister Simulator::dup_element(VectorFormat vform,
2105                                       LogicVRegister dst,
2106                                       const LogicVRegister& src,
2107                                       int src_index) {
2108   int laneCount = LaneCountFromFormat(vform);
2109   uint64_t value = src.Uint(vform, src_index);
2110   dst.ClearForWrite(vform);
2111   for (int i = 0; i < laneCount; ++i) {
2112     dst.SetUint(vform, i, value);
2113   }
2114   return dst;
2115 }
2116 
2117 
dup_immediate(VectorFormat vform,LogicVRegister dst,uint64_t imm)2118 LogicVRegister Simulator::dup_immediate(VectorFormat vform,
2119                                         LogicVRegister dst,
2120                                         uint64_t imm) {
2121   int laneCount = LaneCountFromFormat(vform);
2122   uint64_t value = imm & MaxUintFromFormat(vform);
2123   dst.ClearForWrite(vform);
2124   for (int i = 0; i < laneCount; ++i) {
2125     dst.SetUint(vform, i, value);
2126   }
2127   return dst;
2128 }
2129 
2130 
ins_element(VectorFormat vform,LogicVRegister dst,int dst_index,const LogicVRegister & src,int src_index)2131 LogicVRegister Simulator::ins_element(VectorFormat vform,
2132                                       LogicVRegister dst,
2133                                       int dst_index,
2134                                       const LogicVRegister& src,
2135                                       int src_index) {
2136   dst.SetUint(vform, dst_index, src.Uint(vform, src_index));
2137   return dst;
2138 }
2139 
2140 
ins_immediate(VectorFormat vform,LogicVRegister dst,int dst_index,uint64_t imm)2141 LogicVRegister Simulator::ins_immediate(VectorFormat vform,
2142                                         LogicVRegister dst,
2143                                         int dst_index,
2144                                         uint64_t imm) {
2145   uint64_t value = imm & MaxUintFromFormat(vform);
2146   dst.SetUint(vform, dst_index, value);
2147   return dst;
2148 }
2149 
2150 
mov(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2151 LogicVRegister Simulator::mov(VectorFormat vform,
2152                               LogicVRegister dst,
2153                               const LogicVRegister& src) {
2154   dst.ClearForWrite(vform);
2155   for (int lane = 0; lane < LaneCountFromFormat(vform); lane++) {
2156     dst.SetUint(vform, lane, src.Uint(vform, lane));
2157   }
2158   return dst;
2159 }
2160 
2161 
movi(VectorFormat vform,LogicVRegister dst,uint64_t imm)2162 LogicVRegister Simulator::movi(VectorFormat vform,
2163                                LogicVRegister dst,
2164                                uint64_t imm) {
2165   int laneCount = LaneCountFromFormat(vform);
2166   dst.ClearForWrite(vform);
2167   for (int i = 0; i < laneCount; ++i) {
2168     dst.SetUint(vform, i, imm);
2169   }
2170   return dst;
2171 }
2172 
2173 
mvni(VectorFormat vform,LogicVRegister dst,uint64_t imm)2174 LogicVRegister Simulator::mvni(VectorFormat vform,
2175                                LogicVRegister dst,
2176                                uint64_t imm) {
2177   int laneCount = LaneCountFromFormat(vform);
2178   dst.ClearForWrite(vform);
2179   for (int i = 0; i < laneCount; ++i) {
2180     dst.SetUint(vform, i, ~imm);
2181   }
2182   return dst;
2183 }
2184 
2185 
orr(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,uint64_t imm)2186 LogicVRegister Simulator::orr(VectorFormat vform,
2187                               LogicVRegister dst,
2188                               const LogicVRegister& src,
2189                               uint64_t imm) {
2190   uint64_t result[16];
2191   int laneCount = LaneCountFromFormat(vform);
2192   for (int i = 0; i < laneCount; ++i) {
2193     result[i] = src.Uint(vform, i) | imm;
2194   }
2195   dst.ClearForWrite(vform);
2196   for (int i = 0; i < laneCount; ++i) {
2197     dst.SetUint(vform, i, result[i]);
2198   }
2199   return dst;
2200 }
2201 
2202 
uxtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2203 LogicVRegister Simulator::uxtl(VectorFormat vform,
2204                                LogicVRegister dst,
2205                                const LogicVRegister& src) {
2206   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2207 
2208   dst.ClearForWrite(vform);
2209   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2210     dst.SetUint(vform, i, src.Uint(vform_half, i));
2211   }
2212   return dst;
2213 }
2214 
2215 
sxtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2216 LogicVRegister Simulator::sxtl(VectorFormat vform,
2217                                LogicVRegister dst,
2218                                const LogicVRegister& src) {
2219   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2220 
2221   dst.ClearForWrite(vform);
2222   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2223     dst.SetInt(vform, i, src.Int(vform_half, i));
2224   }
2225   return dst;
2226 }
2227 
2228 
uxtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2229 LogicVRegister Simulator::uxtl2(VectorFormat vform,
2230                                 LogicVRegister dst,
2231                                 const LogicVRegister& src) {
2232   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2233   int lane_count = LaneCountFromFormat(vform);
2234 
2235   dst.ClearForWrite(vform);
2236   for (int i = 0; i < lane_count; i++) {
2237     dst.SetUint(vform, i, src.Uint(vform_half, lane_count + i));
2238   }
2239   return dst;
2240 }
2241 
2242 
sxtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)2243 LogicVRegister Simulator::sxtl2(VectorFormat vform,
2244                                 LogicVRegister dst,
2245                                 const LogicVRegister& src) {
2246   VectorFormat vform_half = VectorFormatHalfWidth(vform);
2247   int lane_count = LaneCountFromFormat(vform);
2248 
2249   dst.ClearForWrite(vform);
2250   for (int i = 0; i < lane_count; i++) {
2251     dst.SetInt(vform, i, src.Int(vform_half, lane_count + i));
2252   }
2253   return dst;
2254 }
2255 
2256 
shrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2257 LogicVRegister Simulator::shrn(VectorFormat vform,
2258                                LogicVRegister dst,
2259                                const LogicVRegister& src,
2260                                int shift) {
2261   SimVRegister temp;
2262   VectorFormat vform_src = VectorFormatDoubleWidth(vform);
2263   VectorFormat vform_dst = vform;
2264   LogicVRegister shifted_src = ushr(vform_src, temp, src, shift);
2265   return extractnarrow(vform_dst, dst, false, shifted_src, false);
2266 }
2267 
2268 
shrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2269 LogicVRegister Simulator::shrn2(VectorFormat vform,
2270                                 LogicVRegister dst,
2271                                 const LogicVRegister& src,
2272                                 int shift) {
2273   SimVRegister temp;
2274   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2275   VectorFormat vformdst = vform;
2276   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift);
2277   return extractnarrow(vformdst, dst, false, shifted_src, false);
2278 }
2279 
2280 
rshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2281 LogicVRegister Simulator::rshrn(VectorFormat vform,
2282                                 LogicVRegister dst,
2283                                 const LogicVRegister& src,
2284                                 int shift) {
2285   SimVRegister temp;
2286   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2287   VectorFormat vformdst = vform;
2288   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2289   return extractnarrow(vformdst, dst, false, shifted_src, false);
2290 }
2291 
2292 
rshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2293 LogicVRegister Simulator::rshrn2(VectorFormat vform,
2294                                  LogicVRegister dst,
2295                                  const LogicVRegister& src,
2296                                  int shift) {
2297   SimVRegister temp;
2298   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2299   VectorFormat vformdst = vform;
2300   LogicVRegister shifted_src = ushr(vformsrc, temp, src, shift).Round(vformsrc);
2301   return extractnarrow(vformdst, dst, false, shifted_src, false);
2302 }
2303 
2304 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & ind)2305 LogicVRegister Simulator::tbl(VectorFormat vform,
2306                               LogicVRegister dst,
2307                               const LogicVRegister& tab,
2308                               const LogicVRegister& ind) {
2309   SimVRegister result;
2310   movi(vform, result, 0);
2311   tbx(vform, result, tab, ind);
2312   return orr(vform, dst, result, result);
2313 }
2314 
2315 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & ind)2316 LogicVRegister Simulator::tbl(VectorFormat vform,
2317                               LogicVRegister dst,
2318                               const LogicVRegister& tab,
2319                               const LogicVRegister& tab2,
2320                               const LogicVRegister& ind) {
2321   SimVRegister result;
2322   movi(vform, result, 0);
2323   tbx(vform, result, tab, tab2, ind);
2324   return orr(vform, dst, result, result);
2325 }
2326 
2327 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & ind)2328 LogicVRegister Simulator::tbl(VectorFormat vform,
2329                               LogicVRegister dst,
2330                               const LogicVRegister& tab,
2331                               const LogicVRegister& tab2,
2332                               const LogicVRegister& tab3,
2333                               const LogicVRegister& ind) {
2334   SimVRegister result;
2335   movi(vform, result, 0);
2336   tbx(vform, result, tab, tab2, tab3, ind);
2337   return orr(vform, dst, result, result);
2338 }
2339 
2340 
tbl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & tab4,const LogicVRegister & ind)2341 LogicVRegister Simulator::tbl(VectorFormat vform,
2342                               LogicVRegister dst,
2343                               const LogicVRegister& tab,
2344                               const LogicVRegister& tab2,
2345                               const LogicVRegister& tab3,
2346                               const LogicVRegister& tab4,
2347                               const LogicVRegister& ind) {
2348   SimVRegister result;
2349   movi(vform, result, 0);
2350   tbx(vform, result, tab, tab2, tab3, tab4, ind);
2351   return orr(vform, dst, result, result);
2352 }
2353 
2354 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & ind)2355 LogicVRegister Simulator::tbx(VectorFormat vform,
2356                               LogicVRegister dst,
2357                               const LogicVRegister& tab,
2358                               const LogicVRegister& ind) {
2359   dst.ClearForWrite(vform);
2360   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2361     uint64_t j = ind.Uint(vform, i);
2362     switch (j >> 4) {
2363       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2364     }
2365   }
2366   return dst;
2367 }
2368 
2369 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & ind)2370 LogicVRegister Simulator::tbx(VectorFormat vform,
2371                               LogicVRegister dst,
2372                               const LogicVRegister& tab,
2373                               const LogicVRegister& tab2,
2374                               const LogicVRegister& ind) {
2375   dst.ClearForWrite(vform);
2376   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2377     uint64_t j = ind.Uint(vform, i);
2378     switch (j >> 4) {
2379       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2380       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2381     }
2382   }
2383   return dst;
2384 }
2385 
2386 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & ind)2387 LogicVRegister Simulator::tbx(VectorFormat vform,
2388                               LogicVRegister dst,
2389                               const LogicVRegister& tab,
2390                               const LogicVRegister& tab2,
2391                               const LogicVRegister& tab3,
2392                               const LogicVRegister& ind) {
2393   dst.ClearForWrite(vform);
2394   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2395     uint64_t j = ind.Uint(vform, i);
2396     switch (j >> 4) {
2397       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2398       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2399       case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
2400     }
2401   }
2402   return dst;
2403 }
2404 
2405 
tbx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & tab,const LogicVRegister & tab2,const LogicVRegister & tab3,const LogicVRegister & tab4,const LogicVRegister & ind)2406 LogicVRegister Simulator::tbx(VectorFormat vform,
2407                               LogicVRegister dst,
2408                               const LogicVRegister& tab,
2409                               const LogicVRegister& tab2,
2410                               const LogicVRegister& tab3,
2411                               const LogicVRegister& tab4,
2412                               const LogicVRegister& ind) {
2413   dst.ClearForWrite(vform);
2414   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
2415     uint64_t j = ind.Uint(vform, i);
2416     switch (j >> 4) {
2417       case 0: dst.SetUint(vform, i, tab.Uint(kFormat16B, j & 15)); break;
2418       case 1: dst.SetUint(vform, i, tab2.Uint(kFormat16B, j & 15)); break;
2419       case 2: dst.SetUint(vform, i, tab3.Uint(kFormat16B, j & 15)); break;
2420       case 3: dst.SetUint(vform, i, tab4.Uint(kFormat16B, j & 15)); break;
2421     }
2422   }
2423   return dst;
2424 }
2425 
2426 
uqshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2427 LogicVRegister Simulator::uqshrn(VectorFormat vform,
2428                                  LogicVRegister dst,
2429                                  const LogicVRegister& src,
2430                                  int shift) {
2431   return shrn(vform, dst, src, shift).UnsignedSaturate(vform);
2432 }
2433 
2434 
uqshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2435 LogicVRegister Simulator::uqshrn2(VectorFormat vform,
2436                                   LogicVRegister dst,
2437                                   const LogicVRegister& src,
2438                                   int shift) {
2439   return shrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2440 }
2441 
2442 
uqrshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2443 LogicVRegister Simulator::uqrshrn(VectorFormat vform,
2444                                   LogicVRegister dst,
2445                                   const LogicVRegister& src,
2446                                   int shift) {
2447   return rshrn(vform, dst, src, shift).UnsignedSaturate(vform);
2448 }
2449 
2450 
uqrshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2451 LogicVRegister Simulator::uqrshrn2(VectorFormat vform,
2452                                    LogicVRegister dst,
2453                                    const LogicVRegister& src,
2454                                    int shift) {
2455   return rshrn2(vform, dst, src, shift).UnsignedSaturate(vform);
2456 }
2457 
2458 
sqshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2459 LogicVRegister Simulator::sqshrn(VectorFormat vform,
2460                                  LogicVRegister dst,
2461                                  const LogicVRegister& src,
2462                                  int shift) {
2463   SimVRegister temp;
2464   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2465   VectorFormat vformdst = vform;
2466   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2467   return sqxtn(vformdst, dst, shifted_src);
2468 }
2469 
2470 
sqshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2471 LogicVRegister Simulator::sqshrn2(VectorFormat vform,
2472                                   LogicVRegister dst,
2473                                   const LogicVRegister& src,
2474                                   int shift) {
2475   SimVRegister temp;
2476   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2477   VectorFormat vformdst = vform;
2478   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2479   return sqxtn(vformdst, dst, shifted_src);
2480 }
2481 
2482 
sqrshrn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2483 LogicVRegister Simulator::sqrshrn(VectorFormat vform,
2484                                   LogicVRegister dst,
2485                                   const LogicVRegister& src,
2486                                   int shift) {
2487   SimVRegister temp;
2488   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2489   VectorFormat vformdst = vform;
2490   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2491   return sqxtn(vformdst, dst, shifted_src);
2492 }
2493 
2494 
sqrshrn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2495 LogicVRegister Simulator::sqrshrn2(VectorFormat vform,
2496                                    LogicVRegister dst,
2497                                    const LogicVRegister& src,
2498                                    int shift) {
2499   SimVRegister temp;
2500   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2501   VectorFormat vformdst = vform;
2502   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2503   return sqxtn(vformdst, dst, shifted_src);
2504 }
2505 
2506 
sqshrun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2507 LogicVRegister Simulator::sqshrun(VectorFormat vform,
2508                                   LogicVRegister dst,
2509                                   const LogicVRegister& src,
2510                                   int shift) {
2511   SimVRegister temp;
2512   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2513   VectorFormat vformdst = vform;
2514   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2515   return sqxtun(vformdst, dst, shifted_src);
2516 }
2517 
2518 
sqshrun2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2519 LogicVRegister Simulator::sqshrun2(VectorFormat vform,
2520                                    LogicVRegister dst,
2521                                    const LogicVRegister& src,
2522                                    int shift) {
2523   SimVRegister temp;
2524   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2525   VectorFormat vformdst = vform;
2526   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift);
2527   return sqxtun(vformdst, dst, shifted_src);
2528 }
2529 
2530 
sqrshrun(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2531 LogicVRegister Simulator::sqrshrun(VectorFormat vform,
2532                                    LogicVRegister dst,
2533                                    const LogicVRegister& src,
2534                                    int shift) {
2535   SimVRegister temp;
2536   VectorFormat vformsrc = VectorFormatDoubleWidth(vform);
2537   VectorFormat vformdst = vform;
2538   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2539   return sqxtun(vformdst, dst, shifted_src);
2540 }
2541 
2542 
sqrshrun2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int shift)2543 LogicVRegister Simulator::sqrshrun2(VectorFormat vform,
2544                                     LogicVRegister dst,
2545                                     const LogicVRegister& src,
2546                                     int shift) {
2547   SimVRegister temp;
2548   VectorFormat vformsrc = VectorFormatDoubleWidth(VectorFormatHalfLanes(vform));
2549   VectorFormat vformdst = vform;
2550   LogicVRegister shifted_src = sshr(vformsrc, temp, src, shift).Round(vformsrc);
2551   return sqxtun(vformdst, dst, shifted_src);
2552 }
2553 
2554 
uaddl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2555 LogicVRegister Simulator::uaddl(VectorFormat vform,
2556                                 LogicVRegister dst,
2557                                 const LogicVRegister& src1,
2558                                 const LogicVRegister& src2) {
2559   SimVRegister temp1, temp2;
2560   uxtl(vform, temp1, src1);
2561   uxtl(vform, temp2, src2);
2562   add(vform, dst, temp1, temp2);
2563   return dst;
2564 }
2565 
2566 
uaddl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2567 LogicVRegister Simulator::uaddl2(VectorFormat vform,
2568                                  LogicVRegister dst,
2569                                  const LogicVRegister& src1,
2570                                  const LogicVRegister& src2) {
2571   SimVRegister temp1, temp2;
2572   uxtl2(vform, temp1, src1);
2573   uxtl2(vform, temp2, src2);
2574   add(vform, dst, temp1, temp2);
2575   return dst;
2576 }
2577 
2578 
uaddw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2579 LogicVRegister Simulator::uaddw(VectorFormat vform,
2580                                 LogicVRegister dst,
2581                                 const LogicVRegister& src1,
2582                                 const LogicVRegister& src2) {
2583   SimVRegister temp;
2584   uxtl(vform, temp, src2);
2585   add(vform, dst, src1, temp);
2586   return dst;
2587 }
2588 
2589 
uaddw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2590 LogicVRegister Simulator::uaddw2(VectorFormat vform,
2591                                  LogicVRegister dst,
2592                                  const LogicVRegister& src1,
2593                                  const LogicVRegister& src2) {
2594   SimVRegister temp;
2595   uxtl2(vform, temp, src2);
2596   add(vform, dst, src1, temp);
2597   return dst;
2598 }
2599 
2600 
saddl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2601 LogicVRegister Simulator::saddl(VectorFormat vform,
2602                                 LogicVRegister dst,
2603                                 const LogicVRegister& src1,
2604                                 const LogicVRegister& src2) {
2605   SimVRegister temp1, temp2;
2606   sxtl(vform, temp1, src1);
2607   sxtl(vform, temp2, src2);
2608   add(vform, dst, temp1, temp2);
2609   return dst;
2610 }
2611 
2612 
saddl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2613 LogicVRegister Simulator::saddl2(VectorFormat vform,
2614                                  LogicVRegister dst,
2615                                  const LogicVRegister& src1,
2616                                  const LogicVRegister& src2) {
2617   SimVRegister temp1, temp2;
2618   sxtl2(vform, temp1, src1);
2619   sxtl2(vform, temp2, src2);
2620   add(vform, dst, temp1, temp2);
2621   return dst;
2622 }
2623 
2624 
saddw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2625 LogicVRegister Simulator::saddw(VectorFormat vform,
2626                                 LogicVRegister dst,
2627                                 const LogicVRegister& src1,
2628                                 const LogicVRegister& src2) {
2629   SimVRegister temp;
2630   sxtl(vform, temp, src2);
2631   add(vform, dst, src1, temp);
2632   return dst;
2633 }
2634 
2635 
saddw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2636 LogicVRegister Simulator::saddw2(VectorFormat vform,
2637                                  LogicVRegister dst,
2638                                  const LogicVRegister& src1,
2639                                  const LogicVRegister& src2) {
2640   SimVRegister temp;
2641   sxtl2(vform, temp, src2);
2642   add(vform, dst, src1, temp);
2643   return dst;
2644 }
2645 
2646 
usubl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2647 LogicVRegister Simulator::usubl(VectorFormat vform,
2648                                 LogicVRegister dst,
2649                                 const LogicVRegister& src1,
2650                                 const LogicVRegister& src2) {
2651   SimVRegister temp1, temp2;
2652   uxtl(vform, temp1, src1);
2653   uxtl(vform, temp2, src2);
2654   sub(vform, dst, temp1, temp2);
2655   return dst;
2656 }
2657 
2658 
usubl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2659 LogicVRegister Simulator::usubl2(VectorFormat vform,
2660                                  LogicVRegister dst,
2661                                  const LogicVRegister& src1,
2662                                  const LogicVRegister& src2) {
2663   SimVRegister temp1, temp2;
2664   uxtl2(vform, temp1, src1);
2665   uxtl2(vform, temp2, src2);
2666   sub(vform, dst, temp1, temp2);
2667   return dst;
2668 }
2669 
2670 
usubw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2671 LogicVRegister Simulator::usubw(VectorFormat vform,
2672                                 LogicVRegister dst,
2673                                 const LogicVRegister& src1,
2674                                 const LogicVRegister& src2) {
2675   SimVRegister temp;
2676   uxtl(vform, temp, src2);
2677   sub(vform, dst, src1, temp);
2678   return dst;
2679 }
2680 
2681 
usubw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2682 LogicVRegister Simulator::usubw2(VectorFormat vform,
2683                                  LogicVRegister dst,
2684                                  const LogicVRegister& src1,
2685                                  const LogicVRegister& src2) {
2686   SimVRegister temp;
2687   uxtl2(vform, temp, src2);
2688   sub(vform, dst, src1, temp);
2689   return dst;
2690 }
2691 
2692 
ssubl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2693 LogicVRegister Simulator::ssubl(VectorFormat vform,
2694                                 LogicVRegister dst,
2695                                 const LogicVRegister& src1,
2696                                 const LogicVRegister& src2) {
2697   SimVRegister temp1, temp2;
2698   sxtl(vform, temp1, src1);
2699   sxtl(vform, temp2, src2);
2700   sub(vform, dst, temp1, temp2);
2701   return dst;
2702 }
2703 
2704 
ssubl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2705 LogicVRegister Simulator::ssubl2(VectorFormat vform,
2706                                  LogicVRegister dst,
2707                                  const LogicVRegister& src1,
2708                                  const LogicVRegister& src2) {
2709   SimVRegister temp1, temp2;
2710   sxtl2(vform, temp1, src1);
2711   sxtl2(vform, temp2, src2);
2712   sub(vform, dst, temp1, temp2);
2713   return dst;
2714 }
2715 
2716 
ssubw(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2717 LogicVRegister Simulator::ssubw(VectorFormat vform,
2718                                 LogicVRegister dst,
2719                                 const LogicVRegister& src1,
2720                                 const LogicVRegister& src2) {
2721   SimVRegister temp;
2722   sxtl(vform, temp, src2);
2723   sub(vform, dst, src1, temp);
2724   return dst;
2725 }
2726 
2727 
ssubw2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2728 LogicVRegister Simulator::ssubw2(VectorFormat vform,
2729                                  LogicVRegister dst,
2730                                  const LogicVRegister& src1,
2731                                  const LogicVRegister& src2) {
2732   SimVRegister temp;
2733   sxtl2(vform, temp, src2);
2734   sub(vform, dst, src1, temp);
2735   return dst;
2736 }
2737 
2738 
uabal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2739 LogicVRegister Simulator::uabal(VectorFormat vform,
2740                                 LogicVRegister dst,
2741                                 const LogicVRegister& src1,
2742                                 const LogicVRegister& src2) {
2743   SimVRegister temp1, temp2;
2744   uxtl(vform, temp1, src1);
2745   uxtl(vform, temp2, src2);
2746   uaba(vform, dst, temp1, temp2);
2747   return dst;
2748 }
2749 
2750 
uabal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2751 LogicVRegister Simulator::uabal2(VectorFormat vform,
2752                                  LogicVRegister dst,
2753                                  const LogicVRegister& src1,
2754                                  const LogicVRegister& src2) {
2755   SimVRegister temp1, temp2;
2756   uxtl2(vform, temp1, src1);
2757   uxtl2(vform, temp2, src2);
2758   uaba(vform, dst, temp1, temp2);
2759   return dst;
2760 }
2761 
2762 
sabal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2763 LogicVRegister Simulator::sabal(VectorFormat vform,
2764                                 LogicVRegister dst,
2765                                 const LogicVRegister& src1,
2766                                 const LogicVRegister& src2) {
2767   SimVRegister temp1, temp2;
2768   sxtl(vform, temp1, src1);
2769   sxtl(vform, temp2, src2);
2770   saba(vform, dst, temp1, temp2);
2771   return dst;
2772 }
2773 
2774 
sabal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2775 LogicVRegister Simulator::sabal2(VectorFormat vform,
2776                                  LogicVRegister dst,
2777                                  const LogicVRegister& src1,
2778                                  const LogicVRegister& src2) {
2779   SimVRegister temp1, temp2;
2780   sxtl2(vform, temp1, src1);
2781   sxtl2(vform, temp2, src2);
2782   saba(vform, dst, temp1, temp2);
2783   return dst;
2784 }
2785 
2786 
uabdl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2787 LogicVRegister Simulator::uabdl(VectorFormat vform,
2788                                 LogicVRegister dst,
2789                                 const LogicVRegister& src1,
2790                                 const LogicVRegister& src2) {
2791   SimVRegister temp1, temp2;
2792   uxtl(vform, temp1, src1);
2793   uxtl(vform, temp2, src2);
2794   absdiff(vform, dst, temp1, temp2, false);
2795   return dst;
2796 }
2797 
2798 
uabdl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2799 LogicVRegister Simulator::uabdl2(VectorFormat vform,
2800                                  LogicVRegister dst,
2801                                  const LogicVRegister& src1,
2802                                  const LogicVRegister& src2) {
2803   SimVRegister temp1, temp2;
2804   uxtl2(vform, temp1, src1);
2805   uxtl2(vform, temp2, src2);
2806   absdiff(vform, dst, temp1, temp2, false);
2807   return dst;
2808 }
2809 
2810 
sabdl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2811 LogicVRegister Simulator::sabdl(VectorFormat vform,
2812                                 LogicVRegister dst,
2813                                 const LogicVRegister& src1,
2814                                 const LogicVRegister& src2) {
2815   SimVRegister temp1, temp2;
2816   sxtl(vform, temp1, src1);
2817   sxtl(vform, temp2, src2);
2818   absdiff(vform, dst, temp1, temp2, true);
2819   return dst;
2820 }
2821 
2822 
sabdl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2823 LogicVRegister Simulator::sabdl2(VectorFormat vform,
2824                                  LogicVRegister dst,
2825                                  const LogicVRegister& src1,
2826                                  const LogicVRegister& src2) {
2827   SimVRegister temp1, temp2;
2828   sxtl2(vform, temp1, src1);
2829   sxtl2(vform, temp2, src2);
2830   absdiff(vform, dst, temp1, temp2, true);
2831   return dst;
2832 }
2833 
2834 
umull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2835 LogicVRegister Simulator::umull(VectorFormat vform,
2836                                 LogicVRegister dst,
2837                                 const LogicVRegister& src1,
2838                                 const LogicVRegister& src2) {
2839   SimVRegister temp1, temp2;
2840   uxtl(vform, temp1, src1);
2841   uxtl(vform, temp2, src2);
2842   mul(vform, dst, temp1, temp2);
2843   return dst;
2844 }
2845 
2846 
umull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2847 LogicVRegister Simulator::umull2(VectorFormat vform,
2848                                  LogicVRegister dst,
2849                                  const LogicVRegister& src1,
2850                                  const LogicVRegister& src2) {
2851   SimVRegister temp1, temp2;
2852   uxtl2(vform, temp1, src1);
2853   uxtl2(vform, temp2, src2);
2854   mul(vform, dst, temp1, temp2);
2855   return dst;
2856 }
2857 
2858 
smull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2859 LogicVRegister Simulator::smull(VectorFormat vform,
2860                                 LogicVRegister dst,
2861                                 const LogicVRegister& src1,
2862                                 const LogicVRegister& src2) {
2863   SimVRegister temp1, temp2;
2864   sxtl(vform, temp1, src1);
2865   sxtl(vform, temp2, src2);
2866   mul(vform, dst, temp1, temp2);
2867   return dst;
2868 }
2869 
2870 
smull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2871 LogicVRegister Simulator::smull2(VectorFormat vform,
2872                                  LogicVRegister dst,
2873                                  const LogicVRegister& src1,
2874                                  const LogicVRegister& src2) {
2875   SimVRegister temp1, temp2;
2876   sxtl2(vform, temp1, src1);
2877   sxtl2(vform, temp2, src2);
2878   mul(vform, dst, temp1, temp2);
2879   return dst;
2880 }
2881 
2882 
umlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2883 LogicVRegister Simulator::umlsl(VectorFormat vform,
2884                                 LogicVRegister dst,
2885                                 const LogicVRegister& src1,
2886                                 const LogicVRegister& src2) {
2887   SimVRegister temp1, temp2;
2888   uxtl(vform, temp1, src1);
2889   uxtl(vform, temp2, src2);
2890   mls(vform, dst, temp1, temp2);
2891   return dst;
2892 }
2893 
2894 
umlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2895 LogicVRegister Simulator::umlsl2(VectorFormat vform,
2896                                  LogicVRegister dst,
2897                                  const LogicVRegister& src1,
2898                                  const LogicVRegister& src2) {
2899   SimVRegister temp1, temp2;
2900   uxtl2(vform, temp1, src1);
2901   uxtl2(vform, temp2, src2);
2902   mls(vform, dst, temp1, temp2);
2903   return dst;
2904 }
2905 
2906 
smlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2907 LogicVRegister Simulator::smlsl(VectorFormat vform,
2908                                 LogicVRegister dst,
2909                                 const LogicVRegister& src1,
2910                                 const LogicVRegister& src2) {
2911   SimVRegister temp1, temp2;
2912   sxtl(vform, temp1, src1);
2913   sxtl(vform, temp2, src2);
2914   mls(vform, dst, temp1, temp2);
2915   return dst;
2916 }
2917 
2918 
smlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2919 LogicVRegister Simulator::smlsl2(VectorFormat vform,
2920                                  LogicVRegister dst,
2921                                  const LogicVRegister& src1,
2922                                  const LogicVRegister& src2) {
2923   SimVRegister temp1, temp2;
2924   sxtl2(vform, temp1, src1);
2925   sxtl2(vform, temp2, src2);
2926   mls(vform, dst, temp1, temp2);
2927   return dst;
2928 }
2929 
2930 
umlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2931 LogicVRegister Simulator::umlal(VectorFormat vform,
2932                                 LogicVRegister dst,
2933                                 const LogicVRegister& src1,
2934                                 const LogicVRegister& src2) {
2935   SimVRegister temp1, temp2;
2936   uxtl(vform, temp1, src1);
2937   uxtl(vform, temp2, src2);
2938   mla(vform, dst, temp1, temp2);
2939   return dst;
2940 }
2941 
2942 
umlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2943 LogicVRegister Simulator::umlal2(VectorFormat vform,
2944                                  LogicVRegister dst,
2945                                  const LogicVRegister& src1,
2946                                  const LogicVRegister& src2) {
2947   SimVRegister temp1, temp2;
2948   uxtl2(vform, temp1, src1);
2949   uxtl2(vform, temp2, src2);
2950   mla(vform, dst, temp1, temp2);
2951   return dst;
2952 }
2953 
2954 
smlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2955 LogicVRegister Simulator::smlal(VectorFormat vform,
2956                                 LogicVRegister dst,
2957                                 const LogicVRegister& src1,
2958                                 const LogicVRegister& src2) {
2959   SimVRegister temp1, temp2;
2960   sxtl(vform, temp1, src1);
2961   sxtl(vform, temp2, src2);
2962   mla(vform, dst, temp1, temp2);
2963   return dst;
2964 }
2965 
2966 
smlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2967 LogicVRegister Simulator::smlal2(VectorFormat vform,
2968                                  LogicVRegister dst,
2969                                  const LogicVRegister& src1,
2970                                  const LogicVRegister& src2) {
2971   SimVRegister temp1, temp2;
2972   sxtl2(vform, temp1, src1);
2973   sxtl2(vform, temp2, src2);
2974   mla(vform, dst, temp1, temp2);
2975   return dst;
2976 }
2977 
2978 
sqdmlal(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2979 LogicVRegister Simulator::sqdmlal(VectorFormat vform,
2980                                   LogicVRegister dst,
2981                                   const LogicVRegister& src1,
2982                                   const LogicVRegister& src2) {
2983   SimVRegister temp;
2984   LogicVRegister product = sqdmull(vform, temp, src1, src2);
2985   return add(vform, dst, dst, product).SignedSaturate(vform);
2986 }
2987 
2988 
sqdmlal2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2989 LogicVRegister Simulator::sqdmlal2(VectorFormat vform,
2990                                   LogicVRegister dst,
2991                                   const LogicVRegister& src1,
2992                                   const LogicVRegister& src2) {
2993   SimVRegister temp;
2994   LogicVRegister product = sqdmull2(vform, temp, src1, src2);
2995   return add(vform, dst, dst, product).SignedSaturate(vform);
2996 }
2997 
2998 
sqdmlsl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)2999 LogicVRegister Simulator::sqdmlsl(VectorFormat vform,
3000                                   LogicVRegister dst,
3001                                   const LogicVRegister& src1,
3002                                   const LogicVRegister& src2) {
3003   SimVRegister temp;
3004   LogicVRegister product = sqdmull(vform, temp, src1, src2);
3005   return sub(vform, dst, dst, product).SignedSaturate(vform);
3006 }
3007 
3008 
sqdmlsl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3009 LogicVRegister Simulator::sqdmlsl2(VectorFormat vform,
3010                                   LogicVRegister dst,
3011                                   const LogicVRegister& src1,
3012                                   const LogicVRegister& src2) {
3013   SimVRegister temp;
3014   LogicVRegister product = sqdmull2(vform, temp, src1, src2);
3015   return sub(vform, dst, dst, product).SignedSaturate(vform);
3016 }
3017 
3018 
sqdmull(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3019 LogicVRegister Simulator::sqdmull(VectorFormat vform,
3020                                   LogicVRegister dst,
3021                                   const LogicVRegister& src1,
3022                                   const LogicVRegister& src2) {
3023   SimVRegister temp;
3024   LogicVRegister product = smull(vform, temp, src1, src2);
3025   return add(vform, dst, product, product).SignedSaturate(vform);
3026 }
3027 
3028 
sqdmull2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3029 LogicVRegister Simulator::sqdmull2(VectorFormat vform,
3030                                   LogicVRegister dst,
3031                                   const LogicVRegister& src1,
3032                                   const LogicVRegister& src2) {
3033   SimVRegister temp;
3034   LogicVRegister product = smull2(vform, temp, src1, src2);
3035   return add(vform, dst, product, product).SignedSaturate(vform);
3036 }
3037 
3038 
sqrdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,bool round)3039 LogicVRegister Simulator::sqrdmulh(VectorFormat vform,
3040                                    LogicVRegister dst,
3041                                    const LogicVRegister& src1,
3042                                    const LogicVRegister& src2,
3043                                    bool round) {
3044   // 2 * INT_32_MIN * INT_32_MIN causes int64_t to overflow.
3045   // To avoid this, we use (src1 * src2 + 1 << (esize - 2)) >> (esize - 1)
3046   // which is same as (2 * src1 * src2 + 1 << (esize - 1)) >> esize.
3047 
3048   int esize = LaneSizeInBitsFromFormat(vform);
3049   int round_const = round ? (1 << (esize - 2)) : 0;
3050   int64_t product;
3051 
3052   dst.ClearForWrite(vform);
3053   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3054     product = src1.Int(vform, i) * src2.Int(vform, i);
3055     product += round_const;
3056     product = product >> (esize - 1);
3057 
3058     if (product > MaxIntFromFormat(vform)) {
3059       product = MaxIntFromFormat(vform);
3060     } else if (product < MinIntFromFormat(vform)) {
3061       product = MinIntFromFormat(vform);
3062     }
3063     dst.SetInt(vform, i, product);
3064   }
3065   return dst;
3066 }
3067 
3068 
sqdmulh(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3069 LogicVRegister Simulator::sqdmulh(VectorFormat vform,
3070                                   LogicVRegister dst,
3071                                   const LogicVRegister& src1,
3072                                   const LogicVRegister& src2) {
3073   return sqrdmulh(vform, dst, src1, src2, false);
3074 }
3075 
3076 
addhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3077 LogicVRegister Simulator::addhn(VectorFormat vform,
3078                                 LogicVRegister dst,
3079                                 const LogicVRegister& src1,
3080                                 const LogicVRegister& src2) {
3081   SimVRegister temp;
3082   add(VectorFormatDoubleWidth(vform), temp, src1, src2);
3083   shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3084   return dst;
3085 }
3086 
3087 
addhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3088 LogicVRegister Simulator::addhn2(VectorFormat vform,
3089                                  LogicVRegister dst,
3090                                  const LogicVRegister& src1,
3091                                  const LogicVRegister& src2) {
3092   SimVRegister temp;
3093   add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3094   shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3095   return dst;
3096 }
3097 
3098 
raddhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3099 LogicVRegister Simulator::raddhn(VectorFormat vform,
3100                                  LogicVRegister dst,
3101                                  const LogicVRegister& src1,
3102                                  const LogicVRegister& src2) {
3103   SimVRegister temp;
3104   add(VectorFormatDoubleWidth(vform), temp, src1, src2);
3105   rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3106   return dst;
3107 }
3108 
3109 
raddhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3110 LogicVRegister Simulator::raddhn2(VectorFormat vform,
3111                                   LogicVRegister dst,
3112                                   const LogicVRegister& src1,
3113                                   const LogicVRegister& src2) {
3114   SimVRegister temp;
3115   add(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3116   rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3117   return dst;
3118 }
3119 
3120 
subhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3121 LogicVRegister Simulator::subhn(VectorFormat vform,
3122                                 LogicVRegister dst,
3123                                 const LogicVRegister& src1,
3124                                 const LogicVRegister& src2) {
3125   SimVRegister temp;
3126   sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
3127   shrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3128   return dst;
3129 }
3130 
3131 
subhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3132 LogicVRegister Simulator::subhn2(VectorFormat vform,
3133                                  LogicVRegister dst,
3134                                  const LogicVRegister& src1,
3135                                  const LogicVRegister& src2) {
3136   SimVRegister temp;
3137   sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3138   shrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3139   return dst;
3140 }
3141 
3142 
rsubhn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3143 LogicVRegister Simulator::rsubhn(VectorFormat vform,
3144                                  LogicVRegister dst,
3145                                  const LogicVRegister& src1,
3146                                  const LogicVRegister& src2) {
3147   SimVRegister temp;
3148   sub(VectorFormatDoubleWidth(vform), temp, src1, src2);
3149   rshrn(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3150   return dst;
3151 }
3152 
3153 
rsubhn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3154 LogicVRegister Simulator::rsubhn2(VectorFormat vform,
3155                                   LogicVRegister dst,
3156                                   const LogicVRegister& src1,
3157                                   const LogicVRegister& src2) {
3158   SimVRegister temp;
3159   sub(VectorFormatDoubleWidth(VectorFormatHalfLanes(vform)), temp, src1, src2);
3160   rshrn2(vform, dst, temp, LaneSizeInBitsFromFormat(vform));
3161   return dst;
3162 }
3163 
3164 
trn1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3165 LogicVRegister Simulator::trn1(VectorFormat vform,
3166                                LogicVRegister dst,
3167                                const LogicVRegister& src1,
3168                                const LogicVRegister& src2) {
3169   uint64_t result[16];
3170   int laneCount = LaneCountFromFormat(vform);
3171   int pairs = laneCount / 2;
3172   for (int i = 0; i < pairs; ++i) {
3173     result[2 * i]       = src1.Uint(vform, 2 * i);
3174     result[(2 * i) + 1] = src2.Uint(vform, 2 * i);
3175   }
3176 
3177   dst.ClearForWrite(vform);
3178   for (int i = 0; i < laneCount; ++i) {
3179     dst.SetUint(vform, i, result[i]);
3180   }
3181   return dst;
3182 }
3183 
3184 
trn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3185 LogicVRegister Simulator::trn2(VectorFormat vform,
3186                                LogicVRegister dst,
3187                                const LogicVRegister& src1,
3188                                const LogicVRegister& src2) {
3189   uint64_t result[16];
3190   int laneCount = LaneCountFromFormat(vform);
3191   int pairs = laneCount / 2;
3192   for (int i = 0; i < pairs; ++i) {
3193     result[2 * i]       = src1.Uint(vform, (2 * i) + 1);
3194     result[(2 * i) + 1] = src2.Uint(vform, (2 * i) + 1);
3195   }
3196 
3197   dst.ClearForWrite(vform);
3198   for (int i = 0; i < laneCount; ++i) {
3199     dst.SetUint(vform, i, result[i]);
3200   }
3201   return dst;
3202 }
3203 
3204 
zip1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3205 LogicVRegister Simulator::zip1(VectorFormat vform,
3206                                LogicVRegister dst,
3207                                const LogicVRegister& src1,
3208                                const LogicVRegister& src2) {
3209   uint64_t result[16];
3210   int laneCount = LaneCountFromFormat(vform);
3211   int pairs = laneCount / 2;
3212   for (int i = 0; i < pairs; ++i) {
3213     result[2 * i]       = src1.Uint(vform, i);
3214     result[(2 * i) + 1] = src2.Uint(vform, i);
3215   }
3216 
3217   dst.ClearForWrite(vform);
3218   for (int i = 0; i < laneCount; ++i) {
3219     dst.SetUint(vform, i, result[i]);
3220   }
3221   return dst;
3222 }
3223 
3224 
zip2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3225 LogicVRegister Simulator::zip2(VectorFormat vform,
3226                                LogicVRegister dst,
3227                                const LogicVRegister& src1,
3228                                const LogicVRegister& src2) {
3229   uint64_t result[16];
3230   int laneCount = LaneCountFromFormat(vform);
3231   int pairs = laneCount / 2;
3232   for (int i = 0; i < pairs; ++i) {
3233     result[2 * i]       = src1.Uint(vform, pairs + i);
3234     result[(2 * i) + 1] = src2.Uint(vform, pairs + i);
3235   }
3236 
3237   dst.ClearForWrite(vform);
3238   for (int i = 0; i < laneCount; ++i) {
3239     dst.SetUint(vform, i, result[i]);
3240   }
3241   return dst;
3242 }
3243 
3244 
uzp1(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3245 LogicVRegister Simulator::uzp1(VectorFormat vform,
3246                                LogicVRegister dst,
3247                                const LogicVRegister& src1,
3248                                const LogicVRegister& src2) {
3249   uint64_t result[32];
3250   int laneCount = LaneCountFromFormat(vform);
3251   for (int i = 0; i < laneCount; ++i) {
3252     result[i]             = src1.Uint(vform, i);
3253     result[laneCount + i] = src2.Uint(vform, i);
3254   }
3255 
3256   dst.ClearForWrite(vform);
3257   for (int i = 0; i < laneCount; ++i) {
3258     dst.SetUint(vform, i, result[2 * i]);
3259   }
3260   return dst;
3261 }
3262 
3263 
uzp2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3264 LogicVRegister Simulator::uzp2(VectorFormat vform,
3265                                LogicVRegister dst,
3266                                const LogicVRegister& src1,
3267                                const LogicVRegister& src2) {
3268   uint64_t result[32];
3269   int laneCount = LaneCountFromFormat(vform);
3270   for (int i = 0; i < laneCount; ++i) {
3271     result[i]             = src1.Uint(vform, i);
3272     result[laneCount + i] = src2.Uint(vform, i);
3273   }
3274 
3275   dst.ClearForWrite(vform);
3276   for (int i = 0; i < laneCount; ++i) {
3277     dst.SetUint(vform, i, result[ (2 * i) + 1]);
3278   }
3279   return dst;
3280 }
3281 
3282 
3283 template <typename T>
FPAdd(T op1,T op2)3284 T Simulator::FPAdd(T op1, T op2) {
3285   T result = FPProcessNaNs(op1, op2);
3286   if (std::isnan(result)) return result;
3287 
3288   if (std::isinf(op1) && std::isinf(op2) && (op1 != op2)) {
3289     // inf + -inf returns the default NaN.
3290     FPProcessException();
3291     return FPDefaultNaN<T>();
3292   } else {
3293     // Other cases should be handled by standard arithmetic.
3294     return op1 + op2;
3295   }
3296 }
3297 
3298 
3299 template <typename T>
FPSub(T op1,T op2)3300 T Simulator::FPSub(T op1, T op2) {
3301   // NaNs should be handled elsewhere.
3302   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3303 
3304   if (std::isinf(op1) && std::isinf(op2) && (op1 == op2)) {
3305     // inf - inf returns the default NaN.
3306     FPProcessException();
3307     return FPDefaultNaN<T>();
3308   } else {
3309     // Other cases should be handled by standard arithmetic.
3310     return op1 - op2;
3311   }
3312 }
3313 
3314 
3315 template <typename T>
FPMul(T op1,T op2)3316 T Simulator::FPMul(T op1, T op2) {
3317   // NaNs should be handled elsewhere.
3318   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3319 
3320   if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
3321     // inf * 0.0 returns the default NaN.
3322     FPProcessException();
3323     return FPDefaultNaN<T>();
3324   } else {
3325     // Other cases should be handled by standard arithmetic.
3326     return op1 * op2;
3327   }
3328 }
3329 
3330 
3331 template<typename T>
FPMulx(T op1,T op2)3332 T Simulator::FPMulx(T op1, T op2) {
3333   if ((std::isinf(op1) && (op2 == 0.0)) || (std::isinf(op2) && (op1 == 0.0))) {
3334     // inf * 0.0 returns +/-2.0.
3335     T two = 2.0;
3336     return copysign(1.0, op1) * copysign(1.0, op2) * two;
3337   }
3338   return FPMul(op1, op2);
3339 }
3340 
3341 
3342 template<typename T>
FPMulAdd(T a,T op1,T op2)3343 T Simulator::FPMulAdd(T a, T op1, T op2) {
3344   T result = FPProcessNaNs3(a, op1, op2);
3345 
3346   T sign_a = copysign(1.0, a);
3347   T sign_prod = copysign(1.0, op1) * copysign(1.0, op2);
3348   bool isinf_prod = std::isinf(op1) || std::isinf(op2);
3349   bool operation_generates_nan =
3350       (std::isinf(op1) && (op2 == 0.0)) ||                     // inf * 0.0
3351       (std::isinf(op2) && (op1 == 0.0)) ||                     // 0.0 * inf
3352       (std::isinf(a) && isinf_prod && (sign_a != sign_prod));  // inf - inf
3353 
3354   if (std::isnan(result)) {
3355     // Generated NaNs override quiet NaNs propagated from a.
3356     if (operation_generates_nan && IsQuietNaN(a)) {
3357       FPProcessException();
3358       return FPDefaultNaN<T>();
3359     } else {
3360       return result;
3361     }
3362   }
3363 
3364   // If the operation would produce a NaN, return the default NaN.
3365   if (operation_generates_nan) {
3366     FPProcessException();
3367     return FPDefaultNaN<T>();
3368   }
3369 
3370   // Work around broken fma implementations for exact zero results: The sign of
3371   // exact 0.0 results is positive unless both a and op1 * op2 are negative.
3372   if (((op1 == 0.0) || (op2 == 0.0)) && (a == 0.0)) {
3373     return ((sign_a < 0) && (sign_prod < 0)) ? -0.0 : 0.0;
3374   }
3375 
3376   result = FusedMultiplyAdd(op1, op2, a);
3377   VIXL_ASSERT(!std::isnan(result));
3378 
3379   // Work around broken fma implementations for rounded zero results: If a is
3380   // 0.0, the sign of the result is the sign of op1 * op2 before rounding.
3381   if ((a == 0.0) && (result == 0.0)) {
3382     return copysign(0.0, sign_prod);
3383   }
3384 
3385   return result;
3386 }
3387 
3388 
3389 template <typename T>
FPDiv(T op1,T op2)3390 T Simulator::FPDiv(T op1, T op2) {
3391   // NaNs should be handled elsewhere.
3392   VIXL_ASSERT(!std::isnan(op1) && !std::isnan(op2));
3393 
3394   if ((std::isinf(op1) && std::isinf(op2)) || ((op1 == 0.0) && (op2 == 0.0))) {
3395     // inf / inf and 0.0 / 0.0 return the default NaN.
3396     FPProcessException();
3397     return FPDefaultNaN<T>();
3398   } else {
3399     if (op2 == 0.0) FPProcessException();
3400 
3401     // Other cases should be handled by standard arithmetic.
3402     return op1 / op2;
3403   }
3404 }
3405 
3406 
3407 template <typename T>
FPSqrt(T op)3408 T Simulator::FPSqrt(T op) {
3409   if (std::isnan(op)) {
3410     return FPProcessNaN(op);
3411   } else if (op < 0.0) {
3412     FPProcessException();
3413     return FPDefaultNaN<T>();
3414   } else {
3415     return sqrt(op);
3416   }
3417 }
3418 
3419 
3420 template <typename T>
FPMax(T a,T b)3421 T Simulator::FPMax(T a, T b) {
3422   T result = FPProcessNaNs(a, b);
3423   if (std::isnan(result)) return result;
3424 
3425   if ((a == 0.0) && (b == 0.0) &&
3426       (copysign(1.0, a) != copysign(1.0, b))) {
3427     // a and b are zero, and the sign differs: return +0.0.
3428     return 0.0;
3429   } else {
3430     return (a > b) ? a : b;
3431   }
3432 }
3433 
3434 
3435 template <typename T>
FPMaxNM(T a,T b)3436 T Simulator::FPMaxNM(T a, T b) {
3437   if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3438     a = kFP64NegativeInfinity;
3439   } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3440     b = kFP64NegativeInfinity;
3441   }
3442 
3443   T result = FPProcessNaNs(a, b);
3444   return std::isnan(result) ? result : FPMax(a, b);
3445 }
3446 
3447 
3448 template <typename T>
FPMin(T a,T b)3449 T Simulator::FPMin(T a, T b) {
3450   T result = FPProcessNaNs(a, b);
3451   if (std::isnan(result)) return result;
3452 
3453   if ((a == 0.0) && (b == 0.0) &&
3454       (copysign(1.0, a) != copysign(1.0, b))) {
3455     // a and b are zero, and the sign differs: return -0.0.
3456     return -0.0;
3457   } else {
3458     return (a < b) ? a : b;
3459   }
3460 }
3461 
3462 
3463 template <typename T>
FPMinNM(T a,T b)3464 T Simulator::FPMinNM(T a, T b) {
3465   if (IsQuietNaN(a) && !IsQuietNaN(b)) {
3466     a = kFP64PositiveInfinity;
3467   } else if (!IsQuietNaN(a) && IsQuietNaN(b)) {
3468     b = kFP64PositiveInfinity;
3469   }
3470 
3471   T result = FPProcessNaNs(a, b);
3472   return std::isnan(result) ? result : FPMin(a, b);
3473 }
3474 
3475 
3476 template <typename T>
FPRecipStepFused(T op1,T op2)3477 T Simulator::FPRecipStepFused(T op1, T op2) {
3478   const T two = 2.0;
3479   if ((std::isinf(op1) && (op2 == 0.0))
3480       || ((op1 == 0.0) && (std::isinf(op2)))) {
3481     return two;
3482   } else if (std::isinf(op1) || std::isinf(op2)) {
3483     // Return +inf if signs match, otherwise -inf.
3484     return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3485                                           : kFP64NegativeInfinity;
3486   } else {
3487     return FusedMultiplyAdd(op1, op2, two);
3488   }
3489 }
3490 
3491 
3492 template <typename T>
FPRSqrtStepFused(T op1,T op2)3493 T Simulator::FPRSqrtStepFused(T op1, T op2) {
3494   const T one_point_five = 1.5;
3495   const T two = 2.0;
3496 
3497   if ((std::isinf(op1) && (op2 == 0.0))
3498       || ((op1 == 0.0) && (std::isinf(op2)))) {
3499     return one_point_five;
3500   } else if (std::isinf(op1) || std::isinf(op2)) {
3501     // Return +inf if signs match, otherwise -inf.
3502     return ((op1 >= 0.0) == (op2 >= 0.0)) ? kFP64PositiveInfinity
3503                                           : kFP64NegativeInfinity;
3504   } else {
3505     // The multiply-add-halve operation must be fully fused, so avoid interim
3506     // rounding by checking which operand can be losslessly divided by two
3507     // before doing the multiply-add.
3508     if (std::isnormal(op1 / two)) {
3509       return FusedMultiplyAdd(op1 / two, op2, one_point_five);
3510     } else if (std::isnormal(op2 / two)) {
3511       return FusedMultiplyAdd(op1, op2 / two, one_point_five);
3512     } else {
3513       // Neither operand is normal after halving: the result is dominated by
3514       // the addition term, so just return that.
3515       return one_point_five;
3516     }
3517   }
3518 }
3519 
FPToFixedJS(double value)3520 int32_t Simulator::FPToFixedJS(double value) {
3521   // The Z-flag is set when the conversion from double precision floating-point
3522   // to 32-bit integer is exact. If the source value is +/-Infinity, -0.0, NaN,
3523   // outside the bounds of a 32-bit integer, or isn't an exact integer then the
3524   // Z-flag is unset.
3525   int Z = 1;
3526   int32_t result;
3527 
3528   if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
3529       (value == kFP64NegativeInfinity)) {
3530     // +/- zero and infinity all return zero, however -0 and +/- Infinity also
3531     // unset the Z-flag.
3532     result = 0.0;
3533     if ((value != 0.0) || std::signbit(value)) {
3534       Z = 0;
3535     }
3536   } else if (std::isnan(value)) {
3537     // NaN values unset the Z-flag and set the result to 0.
3538     FPProcessNaN(value);
3539     result = 0;
3540     Z = 0;
3541   } else {
3542     // All other values are converted to an integer representation, rounded
3543     // toward zero.
3544     double int_result = std::floor(value);
3545     double error = value - int_result;
3546 
3547     if ((error != 0.0) && (int_result < 0.0)) {
3548       int_result++;
3549     }
3550 
3551     // Constrain the value into the range [INT32_MIN, INT32_MAX]. We can almost
3552     // write a one-liner with std::round, but the behaviour on ties is incorrect
3553     // for our purposes.
3554     double mod_const = static_cast<double>(UINT64_C(1) << 32);
3555     double mod_error =
3556         (int_result / mod_const) - std::floor(int_result / mod_const);
3557     double constrained;
3558     if (mod_error == 0.5) {
3559       constrained = INT32_MIN;
3560     } else {
3561       constrained = int_result - mod_const * round(int_result / mod_const);
3562     }
3563 
3564     VIXL_ASSERT(std::floor(constrained) == constrained);
3565     VIXL_ASSERT(constrained >= INT32_MIN);
3566     VIXL_ASSERT(constrained <= INT32_MAX);
3567 
3568     // Take the bottom 32 bits of the result as a 32-bit integer.
3569     result = static_cast<int32_t>(constrained);
3570 
3571     if ((int_result < INT32_MIN) || (int_result > INT32_MAX) ||
3572         (error != 0.0)) {
3573       // If the integer result is out of range or the conversion isn't exact,
3574       // take exception and unset the Z-flag.
3575       FPProcessException();
3576       Z = 0;
3577     }
3578   }
3579 
3580   ReadNzcv().SetN(0);
3581   ReadNzcv().SetZ(Z);
3582   ReadNzcv().SetC(0);
3583   ReadNzcv().SetV(0);
3584 
3585   return result;
3586 }
3587 
3588 
FPRoundInt(double value,FPRounding round_mode)3589 double Simulator::FPRoundInt(double value, FPRounding round_mode) {
3590   if ((value == 0.0) || (value == kFP64PositiveInfinity) ||
3591       (value == kFP64NegativeInfinity)) {
3592     return value;
3593   } else if (std::isnan(value)) {
3594     return FPProcessNaN(value);
3595   }
3596 
3597   double int_result = std::floor(value);
3598   double error = value - int_result;
3599   switch (round_mode) {
3600     case FPTieAway: {
3601       // Take care of correctly handling the range ]-0.5, -0.0], which must
3602       // yield -0.0.
3603       if ((-0.5 < value) && (value < 0.0)) {
3604         int_result = -0.0;
3605 
3606       } else if ((error > 0.5) || ((error == 0.5) && (int_result >= 0.0))) {
3607         // If the error is greater than 0.5, or is equal to 0.5 and the integer
3608         // result is positive, round up.
3609         int_result++;
3610       }
3611       break;
3612     }
3613     case FPTieEven: {
3614       // Take care of correctly handling the range [-0.5, -0.0], which must
3615       // yield -0.0.
3616       if ((-0.5 <= value) && (value < 0.0)) {
3617         int_result = -0.0;
3618 
3619       // If the error is greater than 0.5, or is equal to 0.5 and the integer
3620       // result is odd, round up.
3621       } else if ((error > 0.5) ||
3622           ((error == 0.5) && (std::fmod(int_result, 2) != 0))) {
3623         int_result++;
3624       }
3625       break;
3626     }
3627     case FPZero: {
3628       // If value>0 then we take floor(value)
3629       // otherwise, ceil(value).
3630       if (value < 0) {
3631          int_result = ceil(value);
3632       }
3633       break;
3634     }
3635     case FPNegativeInfinity: {
3636       // We always use floor(value).
3637       break;
3638     }
3639     case FPPositiveInfinity: {
3640       // Take care of correctly handling the range ]-1.0, -0.0], which must
3641       // yield -0.0.
3642       if ((-1.0 < value) && (value < 0.0)) {
3643         int_result = -0.0;
3644 
3645       // If the error is non-zero, round up.
3646       } else if (error > 0.0) {
3647         int_result++;
3648       }
3649       break;
3650     }
3651     default: VIXL_UNIMPLEMENTED();
3652   }
3653   return int_result;
3654 }
3655 
3656 
FPToInt32(double value,FPRounding rmode)3657 int32_t Simulator::FPToInt32(double value, FPRounding rmode) {
3658   value = FPRoundInt(value, rmode);
3659   if (value >= kWMaxInt) {
3660     return kWMaxInt;
3661   } else if (value < kWMinInt) {
3662     return kWMinInt;
3663   }
3664   return std::isnan(value) ? 0 : static_cast<int32_t>(value);
3665 }
3666 
3667 
FPToInt64(double value,FPRounding rmode)3668 int64_t Simulator::FPToInt64(double value, FPRounding rmode) {
3669   value = FPRoundInt(value, rmode);
3670   // The compiler would have to round kXMaxInt, triggering a warning. Compare
3671   // against the largest int64_t that is exactly representable as a double.
3672   if (value > kXMaxExactInt) {
3673     return kXMaxInt;
3674   } else if (value < kXMinInt) {
3675     return kXMinInt;
3676   }
3677   return std::isnan(value) ? 0 : static_cast<int64_t>(value);
3678 }
3679 
3680 
FPToUInt32(double value,FPRounding rmode)3681 uint32_t Simulator::FPToUInt32(double value, FPRounding rmode) {
3682   value = FPRoundInt(value, rmode);
3683   if (value >= kWMaxUInt) {
3684     return kWMaxUInt;
3685   } else if (value < 0.0) {
3686     return 0;
3687   }
3688   return std::isnan(value) ? 0 : static_cast<uint32_t>(value);
3689 }
3690 
3691 
FPToUInt64(double value,FPRounding rmode)3692 uint64_t Simulator::FPToUInt64(double value, FPRounding rmode) {
3693   value = FPRoundInt(value, rmode);
3694   // The compiler would have to round kXMaxUInt, triggering a warning. Compare
3695   // against the largest uint64_t that is exactly representable as a double.
3696   if (value > kXMaxExactUInt) {
3697     return kXMaxUInt;
3698   } else if (value < 0.0) {
3699     return 0;
3700   }
3701   return std::isnan(value) ? 0 : static_cast<uint64_t>(value);
3702 }
3703 
3704 
3705 #define DEFINE_NEON_FP_VECTOR_OP(FN, OP, PROCNAN)                \
3706 template <typename T>                                            \
3707 LogicVRegister Simulator::FN(VectorFormat vform,                 \
3708                              LogicVRegister dst,                 \
3709                              const LogicVRegister& src1,         \
3710                              const LogicVRegister& src2) {       \
3711   dst.ClearForWrite(vform);                                      \
3712   for (int i = 0; i < LaneCountFromFormat(vform); i++) {         \
3713     T op1 = src1.Float<T>(i);                                    \
3714     T op2 = src2.Float<T>(i);                                    \
3715     T result;                                                    \
3716     if (PROCNAN) {                                               \
3717       result = FPProcessNaNs(op1, op2);                          \
3718       if (!std::isnan(result)) {                                      \
3719         result = OP(op1, op2);                                   \
3720       }                                                          \
3721     } else {                                                     \
3722       result = OP(op1, op2);                                     \
3723     }                                                            \
3724     dst.SetFloat(i, result);                                     \
3725   }                                                              \
3726   return dst;                                                    \
3727 }                                                                \
3728                                                                  \
3729 LogicVRegister Simulator::FN(VectorFormat vform,                 \
3730                              LogicVRegister dst,                 \
3731                              const LogicVRegister& src1,         \
3732                              const LogicVRegister& src2) {       \
3733   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {            \
3734     FN<float>(vform, dst, src1, src2);                           \
3735   } else {                                                       \
3736     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);   \
3737     FN<double>(vform, dst, src1, src2);                          \
3738   }                                                              \
3739   return dst;                                                    \
3740 }
NEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)3741 NEON_FP3SAME_LIST(DEFINE_NEON_FP_VECTOR_OP)
3742 #undef DEFINE_NEON_FP_VECTOR_OP
3743 
3744 
3745 LogicVRegister Simulator::fnmul(VectorFormat vform,
3746                                 LogicVRegister dst,
3747                                 const LogicVRegister& src1,
3748                                 const LogicVRegister& src2) {
3749   SimVRegister temp;
3750   LogicVRegister product = fmul(vform, temp, src1, src2);
3751   return fneg(vform, dst, product);
3752 }
3753 
3754 
3755 template <typename T>
frecps(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3756 LogicVRegister Simulator::frecps(VectorFormat vform,
3757                                  LogicVRegister dst,
3758                                  const LogicVRegister& src1,
3759                                  const LogicVRegister& src2) {
3760   dst.ClearForWrite(vform);
3761   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3762     T op1 = -src1.Float<T>(i);
3763     T op2 = src2.Float<T>(i);
3764     T result = FPProcessNaNs(op1, op2);
3765     dst.SetFloat(i, std::isnan(result) ? result : FPRecipStepFused(op1, op2));
3766   }
3767   return dst;
3768 }
3769 
3770 
frecps(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3771 LogicVRegister Simulator::frecps(VectorFormat vform,
3772                                  LogicVRegister dst,
3773                                  const LogicVRegister& src1,
3774                                  const LogicVRegister& src2) {
3775   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3776     frecps<float>(vform, dst, src1, src2);
3777   } else {
3778     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3779     frecps<double>(vform, dst, src1, src2);
3780   }
3781   return dst;
3782 }
3783 
3784 
3785 template <typename T>
frsqrts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3786 LogicVRegister Simulator::frsqrts(VectorFormat vform,
3787                                   LogicVRegister dst,
3788                                   const LogicVRegister& src1,
3789                                   const LogicVRegister& src2) {
3790   dst.ClearForWrite(vform);
3791   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3792     T op1 = -src1.Float<T>(i);
3793     T op2 = src2.Float<T>(i);
3794     T result = FPProcessNaNs(op1, op2);
3795     dst.SetFloat(i, std::isnan(result) ? result : FPRSqrtStepFused(op1, op2));
3796   }
3797   return dst;
3798 }
3799 
3800 
frsqrts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3801 LogicVRegister Simulator::frsqrts(VectorFormat vform,
3802                                   LogicVRegister dst,
3803                                   const LogicVRegister& src1,
3804                                   const LogicVRegister& src2) {
3805   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3806     frsqrts<float>(vform, dst, src1, src2);
3807   } else {
3808     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3809     frsqrts<double>(vform, dst, src1, src2);
3810   }
3811   return dst;
3812 }
3813 
3814 
3815 template <typename T>
fcmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)3816 LogicVRegister Simulator::fcmp(VectorFormat vform,
3817                                LogicVRegister dst,
3818                                const LogicVRegister& src1,
3819                                const LogicVRegister& src2,
3820                                Condition cond) {
3821   dst.ClearForWrite(vform);
3822   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3823     bool result = false;
3824     T op1 = src1.Float<T>(i);
3825     T op2 = src2.Float<T>(i);
3826     T nan_result = FPProcessNaNs(op1, op2);
3827     if (!std::isnan(nan_result)) {
3828       switch (cond) {
3829         case eq: result = (op1 == op2); break;
3830         case ge: result = (op1 >= op2); break;
3831         case gt: result = (op1 > op2) ; break;
3832         case le: result = (op1 <= op2); break;
3833         case lt: result = (op1 < op2) ; break;
3834         default: VIXL_UNREACHABLE(); break;
3835       }
3836     }
3837     dst.SetUint(vform, i, result ? MaxUintFromFormat(vform) : 0);
3838   }
3839   return dst;
3840 }
3841 
3842 
fcmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)3843 LogicVRegister Simulator::fcmp(VectorFormat vform,
3844                                LogicVRegister dst,
3845                                const LogicVRegister& src1,
3846                                const LogicVRegister& src2,
3847                                Condition cond) {
3848   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3849     fcmp<float>(vform, dst, src1, src2, cond);
3850   } else {
3851     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3852     fcmp<double>(vform, dst, src1, src2, cond);
3853   }
3854   return dst;
3855 }
3856 
3857 
fcmp_zero(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,Condition cond)3858 LogicVRegister Simulator::fcmp_zero(VectorFormat vform,
3859                                     LogicVRegister dst,
3860                                     const LogicVRegister& src,
3861                                     Condition cond) {
3862   SimVRegister temp;
3863   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3864     LogicVRegister zero_reg = dup_immediate(vform, temp, FloatToRawbits(0.0));
3865     fcmp<float>(vform, dst, src, zero_reg, cond);
3866   } else {
3867     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3868     LogicVRegister zero_reg = dup_immediate(vform, temp,
3869                                             DoubleToRawbits(0.0));
3870     fcmp<double>(vform, dst, src, zero_reg, cond);
3871   }
3872   return dst;
3873 }
3874 
3875 
fabscmp(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,Condition cond)3876 LogicVRegister Simulator::fabscmp(VectorFormat vform,
3877                                   LogicVRegister dst,
3878                                   const LogicVRegister& src1,
3879                                   const LogicVRegister& src2,
3880                                   Condition cond) {
3881   SimVRegister temp1, temp2;
3882   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3883     LogicVRegister abs_src1 = fabs_<float>(vform, temp1, src1);
3884     LogicVRegister abs_src2 = fabs_<float>(vform, temp2, src2);
3885     fcmp<float>(vform, dst, abs_src1, abs_src2, cond);
3886   } else {
3887     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3888     LogicVRegister abs_src1 = fabs_<double>(vform, temp1, src1);
3889     LogicVRegister abs_src2 = fabs_<double>(vform, temp2, src2);
3890     fcmp<double>(vform, dst, abs_src1, abs_src2, cond);
3891   }
3892   return dst;
3893 }
3894 
3895 
3896 template <typename T>
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3897 LogicVRegister Simulator::fmla(VectorFormat vform,
3898                                LogicVRegister dst,
3899                                const LogicVRegister& src1,
3900                                const LogicVRegister& src2) {
3901   dst.ClearForWrite(vform);
3902   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3903     T op1 = src1.Float<T>(i);
3904     T op2 = src2.Float<T>(i);
3905     T acc = dst.Float<T>(i);
3906     T result = FPMulAdd(acc, op1, op2);
3907     dst.SetFloat(i, result);
3908   }
3909   return dst;
3910 }
3911 
3912 
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3913 LogicVRegister Simulator::fmla(VectorFormat vform,
3914                                LogicVRegister dst,
3915                                const LogicVRegister& src1,
3916                                const LogicVRegister& src2) {
3917   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3918     fmla<float>(vform, dst, src1, src2);
3919   } else {
3920     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3921     fmla<double>(vform, dst, src1, src2);
3922   }
3923   return dst;
3924 }
3925 
3926 
3927 template <typename T>
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3928 LogicVRegister Simulator::fmls(VectorFormat vform,
3929                                LogicVRegister dst,
3930                                const LogicVRegister& src1,
3931                                const LogicVRegister& src2) {
3932   dst.ClearForWrite(vform);
3933   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3934     T op1 = -src1.Float<T>(i);
3935     T op2 = src2.Float<T>(i);
3936     T acc = dst.Float<T>(i);
3937     T result = FPMulAdd(acc, op1, op2);
3938     dst.SetFloat(i, result);
3939   }
3940   return dst;
3941 }
3942 
3943 
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)3944 LogicVRegister Simulator::fmls(VectorFormat vform,
3945                                LogicVRegister dst,
3946                                const LogicVRegister& src1,
3947                                const LogicVRegister& src2) {
3948   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3949     fmls<float>(vform, dst, src1, src2);
3950   } else {
3951     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3952     fmls<double>(vform, dst, src1, src2);
3953   }
3954   return dst;
3955 }
3956 
3957 
3958 template <typename T>
fneg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)3959 LogicVRegister Simulator::fneg(VectorFormat vform,
3960                                LogicVRegister dst,
3961                                const LogicVRegister& src) {
3962   dst.ClearForWrite(vform);
3963   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3964     T op = src.Float<T>(i);
3965     op = -op;
3966     dst.SetFloat(i, op);
3967   }
3968   return dst;
3969 }
3970 
3971 
fneg(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)3972 LogicVRegister Simulator::fneg(VectorFormat vform,
3973                                LogicVRegister dst,
3974                                const LogicVRegister& src) {
3975   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
3976     fneg<float>(vform, dst, src);
3977   } else {
3978     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
3979     fneg<double>(vform, dst, src);
3980   }
3981   return dst;
3982 }
3983 
3984 
3985 template <typename T>
fabs_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)3986 LogicVRegister Simulator::fabs_(VectorFormat vform,
3987                                 LogicVRegister dst,
3988                                 const LogicVRegister& src) {
3989   dst.ClearForWrite(vform);
3990   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
3991     T op = src.Float<T>(i);
3992     if (copysign(1.0, op) < 0.0) {
3993       op = -op;
3994     }
3995     dst.SetFloat(i, op);
3996   }
3997   return dst;
3998 }
3999 
4000 
fabs_(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4001 LogicVRegister Simulator::fabs_(VectorFormat vform,
4002                                 LogicVRegister dst,
4003                                 const LogicVRegister& src) {
4004   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4005     fabs_<float>(vform, dst, src);
4006   } else {
4007     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4008     fabs_<double>(vform, dst, src);
4009   }
4010   return dst;
4011 }
4012 
4013 
fabd(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2)4014 LogicVRegister Simulator::fabd(VectorFormat vform,
4015                                LogicVRegister dst,
4016                                const LogicVRegister& src1,
4017                                const LogicVRegister& src2) {
4018   SimVRegister temp;
4019   fsub(vform, temp, src1, src2);
4020   fabs_(vform, dst, temp);
4021   return dst;
4022 }
4023 
4024 
fsqrt(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4025 LogicVRegister Simulator::fsqrt(VectorFormat vform,
4026                                 LogicVRegister dst,
4027                                 const LogicVRegister& src) {
4028   dst.ClearForWrite(vform);
4029   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4030     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4031       float result = FPSqrt(src.Float<float>(i));
4032       dst.SetFloat(i, result);
4033     }
4034   } else {
4035     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4036     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4037       double result = FPSqrt(src.Float<double>(i));
4038       dst.SetFloat(i, result);
4039     }
4040   }
4041   return dst;
4042 }
4043 
4044 
4045 #define DEFINE_NEON_FP_PAIR_OP(FNP, FN, OP)                          \
4046 LogicVRegister Simulator::FNP(VectorFormat vform,                    \
4047                               LogicVRegister dst,                    \
4048                               const LogicVRegister& src1,            \
4049                               const LogicVRegister& src2) {          \
4050   SimVRegister temp1, temp2;                                         \
4051   uzp1(vform, temp1, src1, src2);                                    \
4052   uzp2(vform, temp2, src1, src2);                                    \
4053   FN(vform, dst, temp1, temp2);                                      \
4054   return dst;                                                        \
4055 }                                                                    \
4056                                                                      \
4057 LogicVRegister Simulator::FNP(VectorFormat vform,                    \
4058                               LogicVRegister dst,                    \
4059                               const LogicVRegister& src) {           \
4060   if (vform == kFormatS) {                                           \
4061     float result = OP(src.Float<float>(0), src.Float<float>(1));     \
4062     dst.SetFloat(0, result);                                         \
4063   } else {                                                           \
4064     VIXL_ASSERT(vform == kFormatD);                                  \
4065     double result = OP(src.Float<double>(0), src.Float<double>(1));  \
4066     dst.SetFloat(0, result);                                         \
4067   }                                                                  \
4068   dst.ClearForWrite(vform);                                          \
4069   return dst;                                                        \
4070 }
NEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)4071 NEON_FPPAIRWISE_LIST(DEFINE_NEON_FP_PAIR_OP)
4072 #undef DEFINE_NEON_FP_PAIR_OP
4073 
4074 
4075 LogicVRegister Simulator::fminmaxv(VectorFormat vform,
4076                                    LogicVRegister dst,
4077                                    const LogicVRegister& src,
4078                                    FPMinMaxOp Op) {
4079   VIXL_ASSERT(vform == kFormat4S);
4080   USE(vform);
4081   float result1 = (this->*Op)(src.Float<float>(0), src.Float<float>(1));
4082   float result2 = (this->*Op)(src.Float<float>(2), src.Float<float>(3));
4083   float result = (this->*Op)(result1, result2);
4084   dst.ClearForWrite(kFormatS);
4085   dst.SetFloat<float>(0, result);
4086   return dst;
4087 }
4088 
4089 
fmaxv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4090 LogicVRegister Simulator::fmaxv(VectorFormat vform,
4091                                 LogicVRegister dst,
4092                                 const LogicVRegister& src) {
4093   return fminmaxv(vform, dst, src, &Simulator::FPMax);
4094 }
4095 
4096 
fminv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4097 LogicVRegister Simulator::fminv(VectorFormat vform,
4098                                 LogicVRegister dst,
4099                                 const LogicVRegister& src) {
4100   return fminmaxv(vform, dst, src, &Simulator::FPMin);
4101 }
4102 
4103 
fmaxnmv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4104 LogicVRegister Simulator::fmaxnmv(VectorFormat vform,
4105                                  LogicVRegister dst,
4106                                  const LogicVRegister& src) {
4107   return fminmaxv(vform, dst, src, &Simulator::FPMaxNM);
4108 }
4109 
4110 
fminnmv(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4111 LogicVRegister Simulator::fminnmv(VectorFormat vform,
4112                                   LogicVRegister dst,
4113                                   const LogicVRegister& src) {
4114   return fminmaxv(vform, dst, src, &Simulator::FPMinNM);
4115 }
4116 
4117 
fmul(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4118 LogicVRegister Simulator::fmul(VectorFormat vform,
4119                                LogicVRegister dst,
4120                                const LogicVRegister& src1,
4121                                const LogicVRegister& src2,
4122                                int index) {
4123   dst.ClearForWrite(vform);
4124   SimVRegister temp;
4125   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4126     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4127     fmul<float>(vform, dst, src1, index_reg);
4128 
4129   } else {
4130     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4131     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4132     fmul<double>(vform, dst, src1, index_reg);
4133   }
4134   return dst;
4135 }
4136 
4137 
fmla(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4138 LogicVRegister Simulator::fmla(VectorFormat vform,
4139                                LogicVRegister dst,
4140                                const LogicVRegister& src1,
4141                                const LogicVRegister& src2,
4142                                int index) {
4143   dst.ClearForWrite(vform);
4144   SimVRegister temp;
4145   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4146     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4147     fmla<float>(vform, dst, src1, index_reg);
4148 
4149   } else {
4150     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4151     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4152     fmla<double>(vform, dst, src1, index_reg);
4153   }
4154   return dst;
4155 }
4156 
4157 
fmls(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4158 LogicVRegister Simulator::fmls(VectorFormat vform,
4159                                LogicVRegister dst,
4160                                const LogicVRegister& src1,
4161                                const LogicVRegister& src2,
4162                                int index) {
4163   dst.ClearForWrite(vform);
4164   SimVRegister temp;
4165   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4166     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4167     fmls<float>(vform, dst, src1, index_reg);
4168 
4169   } else {
4170     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4171     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4172     fmls<double>(vform, dst, src1, index_reg);
4173   }
4174   return dst;
4175 }
4176 
4177 
fmulx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src1,const LogicVRegister & src2,int index)4178 LogicVRegister Simulator::fmulx(VectorFormat vform,
4179                                 LogicVRegister dst,
4180                                 const LogicVRegister& src1,
4181                                 const LogicVRegister& src2,
4182                                 int index) {
4183   dst.ClearForWrite(vform);
4184   SimVRegister temp;
4185   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4186     LogicVRegister index_reg = dup_element(kFormat4S, temp, src2, index);
4187     fmulx<float>(vform, dst, src1, index_reg);
4188 
4189   } else {
4190     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4191     LogicVRegister index_reg = dup_element(kFormat2D, temp, src2, index);
4192     fmulx<double>(vform, dst, src1, index_reg);
4193   }
4194   return dst;
4195 }
4196 
4197 
frint(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,bool inexact_exception)4198 LogicVRegister Simulator::frint(VectorFormat vform,
4199                                 LogicVRegister dst,
4200                                 const LogicVRegister& src,
4201                                 FPRounding rounding_mode,
4202                                 bool inexact_exception) {
4203   dst.ClearForWrite(vform);
4204   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4205     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4206       float input = src.Float<float>(i);
4207       float rounded = FPRoundInt(input, rounding_mode);
4208       if (inexact_exception && !std::isnan(input) && (input != rounded)) {
4209         FPProcessException();
4210       }
4211       dst.SetFloat<float>(i, rounded);
4212     }
4213   } else {
4214     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4215     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4216       double input = src.Float<double>(i);
4217       double rounded = FPRoundInt(input, rounding_mode);
4218       if (inexact_exception && !std::isnan(input) && (input != rounded)) {
4219         FPProcessException();
4220       }
4221       dst.SetFloat<double>(i, rounded);
4222     }
4223   }
4224   return dst;
4225 }
4226 
4227 
fcvts(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,int fbits)4228 LogicVRegister Simulator::fcvts(VectorFormat vform,
4229                                 LogicVRegister dst,
4230                                 const LogicVRegister& src,
4231                                 FPRounding rounding_mode,
4232                                 int fbits) {
4233   dst.ClearForWrite(vform);
4234   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4235     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4236       float op = src.Float<float>(i) * std::pow(2.0f, fbits);
4237       dst.SetInt(vform, i, FPToInt32(op, rounding_mode));
4238     }
4239   } else {
4240     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4241     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4242       double op = src.Float<double>(i) * std::pow(2.0, fbits);
4243       dst.SetInt(vform, i, FPToInt64(op, rounding_mode));
4244     }
4245   }
4246   return dst;
4247 }
4248 
4249 
fcvtu(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding rounding_mode,int fbits)4250 LogicVRegister Simulator::fcvtu(VectorFormat vform,
4251                                 LogicVRegister dst,
4252                                 const LogicVRegister& src,
4253                                 FPRounding rounding_mode,
4254                                 int fbits) {
4255   dst.ClearForWrite(vform);
4256   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4257     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4258       float op = src.Float<float>(i) * std::pow(2.0f, fbits);
4259       dst.SetUint(vform, i, FPToUInt32(op, rounding_mode));
4260     }
4261   } else {
4262     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4263     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4264       double op = src.Float<double>(i) * std::pow(2.0, fbits);
4265       dst.SetUint(vform, i, FPToUInt64(op, rounding_mode));
4266     }
4267   }
4268   return dst;
4269 }
4270 
4271 
fcvtl(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4272 LogicVRegister Simulator::fcvtl(VectorFormat vform,
4273                                 LogicVRegister dst,
4274                                 const LogicVRegister& src) {
4275   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4276     for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
4277       // TODO: Full support for SimFloat16 in SimRegister(s).
4278       dst.SetFloat(i,
4279                    FPToFloat(RawbitsToFloat16(src.Float<uint16_t>(i)),
4280                              ReadDN()));
4281     }
4282   } else {
4283     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4284     for (int i = LaneCountFromFormat(vform) - 1; i >= 0; i--) {
4285       dst.SetFloat(i, FPToDouble(src.Float<float>(i), ReadDN()));
4286     }
4287   }
4288   return dst;
4289 }
4290 
4291 
fcvtl2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4292 LogicVRegister Simulator::fcvtl2(VectorFormat vform,
4293                                  LogicVRegister dst,
4294                                  const LogicVRegister& src) {
4295   int lane_count = LaneCountFromFormat(vform);
4296   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4297     for (int i = 0; i < lane_count; i++) {
4298       // TODO: Full support for SimFloat16 in SimRegister(s).
4299       dst.SetFloat(i,
4300                    FPToFloat(RawbitsToFloat16(
4301                                  src.Float<uint16_t>(i + lane_count)),
4302                              ReadDN()));
4303     }
4304   } else {
4305     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4306     for (int i = 0; i < lane_count; i++) {
4307       dst.SetFloat(i, FPToDouble(src.Float<float>(i + lane_count), ReadDN()));
4308     }
4309   }
4310   return dst;
4311 }
4312 
4313 
fcvtn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4314 LogicVRegister Simulator::fcvtn(VectorFormat vform,
4315                                 LogicVRegister dst,
4316                                 const LogicVRegister& src) {
4317   SimVRegister tmp;
4318   LogicVRegister srctmp = mov(kFormat2D, tmp, src);
4319   dst.ClearForWrite(vform);
4320   if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
4321     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4322       dst.SetFloat(i,
4323                    Float16ToRawbits(FPToFloat16(srctmp.Float<float>(i),
4324                                                 FPTieEven,
4325                                                 ReadDN())));
4326     }
4327   } else {
4328     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4329     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4330       dst.SetFloat(i, FPToFloat(srctmp.Float<double>(i), FPTieEven, ReadDN()));
4331     }
4332   }
4333   return dst;
4334 }
4335 
4336 
fcvtn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4337 LogicVRegister Simulator::fcvtn2(VectorFormat vform,
4338                                  LogicVRegister dst,
4339                                  const LogicVRegister& src) {
4340   int lane_count = LaneCountFromFormat(vform) / 2;
4341   if (LaneSizeInBitsFromFormat(vform) == kHRegSize) {
4342     for (int i = lane_count - 1; i >= 0; i--) {
4343       dst.SetFloat(i + lane_count,
4344                    Float16ToRawbits(
4345                        FPToFloat16(src.Float<float>(i), FPTieEven, ReadDN())));
4346     }
4347   } else {
4348     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4349     for (int i = lane_count - 1; i >= 0; i--) {
4350       dst.SetFloat(i + lane_count,
4351                    FPToFloat(src.Float<double>(i), FPTieEven, ReadDN()));
4352     }
4353   }
4354   return dst;
4355 }
4356 
4357 
fcvtxn(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4358 LogicVRegister Simulator::fcvtxn(VectorFormat vform,
4359                                  LogicVRegister dst,
4360                                  const LogicVRegister& src) {
4361   SimVRegister tmp;
4362   LogicVRegister srctmp = mov(kFormat2D, tmp, src);
4363   dst.ClearForWrite(vform);
4364   VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4365   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4366     dst.SetFloat(i, FPToFloat(srctmp.Float<double>(i), FPRoundOdd, ReadDN()));
4367   }
4368   return dst;
4369 }
4370 
4371 
fcvtxn2(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4372 LogicVRegister Simulator::fcvtxn2(VectorFormat vform,
4373                                   LogicVRegister dst,
4374                                   const LogicVRegister& src) {
4375   VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kSRegSize);
4376   int lane_count = LaneCountFromFormat(vform) / 2;
4377   for (int i = lane_count - 1; i >= 0; i--) {
4378     dst.SetFloat(i + lane_count,
4379                  FPToFloat(src.Float<double>(i), FPRoundOdd, ReadDN()));
4380   }
4381   return dst;
4382 }
4383 
4384 
4385 // Based on reference C function recip_sqrt_estimate from ARM ARM.
recip_sqrt_estimate(double a)4386 double Simulator::recip_sqrt_estimate(double a) {
4387   int q0, q1, s;
4388   double r;
4389   if (a < 0.5) {
4390     q0 = static_cast<int>(a * 512.0);
4391     r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
4392   } else  {
4393     q1 = static_cast<int>(a * 256.0);
4394     r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
4395   }
4396   s = static_cast<int>(256.0 * r + 0.5);
4397   return static_cast<double>(s) / 256.0;
4398 }
4399 
4400 
Bits(uint64_t val,int start_bit,int end_bit)4401 static inline uint64_t Bits(uint64_t val, int start_bit, int end_bit) {
4402   return ExtractUnsignedBitfield64(start_bit, end_bit, val);
4403 }
4404 
4405 
4406 template <typename T>
FPRecipSqrtEstimate(T op)4407 T Simulator::FPRecipSqrtEstimate(T op) {
4408   if (std::isnan(op)) {
4409     return FPProcessNaN(op);
4410   } else if (op == 0.0) {
4411     if (copysign(1.0, op) < 0.0) {
4412       return kFP64NegativeInfinity;
4413     } else {
4414       return kFP64PositiveInfinity;
4415     }
4416   } else if (copysign(1.0, op) < 0.0) {
4417     FPProcessException();
4418     return FPDefaultNaN<T>();
4419   } else if (std::isinf(op)) {
4420     return 0.0;
4421   } else {
4422     uint64_t fraction;
4423     int exp, result_exp;
4424 
4425     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4426       exp = FloatExp(op);
4427       fraction = FloatMantissa(op);
4428       fraction <<= 29;
4429     } else {
4430       exp = DoubleExp(op);
4431       fraction = DoubleMantissa(op);
4432     }
4433 
4434     if (exp == 0) {
4435       while (Bits(fraction, 51, 51) == 0) {
4436         fraction = Bits(fraction, 50, 0) << 1;
4437         exp -= 1;
4438       }
4439       fraction = Bits(fraction, 50, 0) << 1;
4440     }
4441 
4442     double scaled;
4443     if (Bits(exp, 0, 0) == 0) {
4444       scaled = DoublePack(0, 1022, Bits(fraction, 51, 44) << 44);
4445     } else {
4446       scaled = DoublePack(0, 1021, Bits(fraction, 51, 44) << 44);
4447     }
4448 
4449     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4450       result_exp = (380 - exp) / 2;
4451     } else {
4452       result_exp = (3068 - exp) / 2;
4453     }
4454 
4455     uint64_t estimate = DoubleToRawbits(recip_sqrt_estimate(scaled));
4456 
4457     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4458       uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4459       uint32_t est_bits = static_cast<uint32_t>(Bits(estimate, 51, 29));
4460       return FloatPack(0, exp_bits, est_bits);
4461     } else {
4462       return DoublePack(0, Bits(result_exp, 10, 0), Bits(estimate, 51, 0));
4463     }
4464   }
4465 }
4466 
4467 
frsqrte(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4468 LogicVRegister Simulator::frsqrte(VectorFormat vform,
4469                                   LogicVRegister dst,
4470                                   const LogicVRegister& src) {
4471   dst.ClearForWrite(vform);
4472   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4473     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4474       float input = src.Float<float>(i);
4475       dst.SetFloat(i, FPRecipSqrtEstimate<float>(input));
4476     }
4477   } else {
4478     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4479     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4480       double input = src.Float<double>(i);
4481       dst.SetFloat(i, FPRecipSqrtEstimate<double>(input));
4482     }
4483   }
4484   return dst;
4485 }
4486 
4487 template <typename T>
FPRecipEstimate(T op,FPRounding rounding)4488 T Simulator::FPRecipEstimate(T op, FPRounding rounding) {
4489   uint32_t sign;
4490 
4491   if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4492     sign = FloatSign(op);
4493   } else {
4494     sign = DoubleSign(op);
4495   }
4496 
4497   if (std::isnan(op)) {
4498     return FPProcessNaN(op);
4499   } else if (std::isinf(op)) {
4500     return (sign == 1) ? -0.0 : 0.0;
4501   } else if (op == 0.0) {
4502     FPProcessException();  // FPExc_DivideByZero exception.
4503     return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
4504   } else if (((sizeof(T) == sizeof(float)) &&  // NOLINT(runtime/sizeof)
4505               (std::fabs(op) < std::pow(2.0, -128.0))) ||
4506              ((sizeof(T) == sizeof(double)) &&  // NOLINT(runtime/sizeof)
4507               (std::fabs(op) < std::pow(2.0, -1024.0)))) {
4508     bool overflow_to_inf = false;
4509     switch (rounding) {
4510       case FPTieEven: overflow_to_inf = true; break;
4511       case FPPositiveInfinity: overflow_to_inf = (sign == 0); break;
4512       case FPNegativeInfinity: overflow_to_inf = (sign == 1); break;
4513       case FPZero: overflow_to_inf = false; break;
4514       default: break;
4515     }
4516     FPProcessException();  // FPExc_Overflow and FPExc_Inexact.
4517     if (overflow_to_inf) {
4518       return (sign == 1) ? kFP64NegativeInfinity : kFP64PositiveInfinity;
4519     } else {
4520       // Return FPMaxNormal(sign).
4521       if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4522         return FloatPack(sign, 0xfe, 0x07fffff);
4523       } else {
4524         return DoublePack(sign, 0x7fe, 0x0fffffffffffffl);
4525       }
4526     }
4527   } else {
4528     uint64_t fraction;
4529     int exp, result_exp;
4530     uint32_t sign;
4531 
4532     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4533       sign = FloatSign(op);
4534       exp = FloatExp(op);
4535       fraction = FloatMantissa(op);
4536       fraction <<= 29;
4537     } else {
4538       sign = DoubleSign(op);
4539       exp = DoubleExp(op);
4540       fraction = DoubleMantissa(op);
4541     }
4542 
4543     if (exp == 0) {
4544       if (Bits(fraction, 51, 51) == 0) {
4545         exp -= 1;
4546         fraction = Bits(fraction, 49, 0) << 2;
4547       } else {
4548         fraction = Bits(fraction, 50, 0) << 1;
4549       }
4550     }
4551 
4552     double scaled = DoublePack(0, 1022, Bits(fraction, 51, 44) << 44);
4553 
4554     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4555       result_exp = (253 - exp);  // In range 253-254 = -1 to 253+1 = 254.
4556     } else {
4557       result_exp = (2045 - exp);  // In range 2045-2046 = -1 to 2045+1 = 2046.
4558     }
4559 
4560     double estimate = recip_estimate(scaled);
4561 
4562     fraction = DoubleMantissa(estimate);
4563     if (result_exp == 0) {
4564       fraction = (UINT64_C(1) << 51) | Bits(fraction, 51, 1);
4565     } else if (result_exp == -1) {
4566       fraction = (UINT64_C(1) << 50) | Bits(fraction, 51, 2);
4567       result_exp = 0;
4568     }
4569     if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4570       uint32_t exp_bits = static_cast<uint32_t>(Bits(result_exp, 7, 0));
4571       uint32_t frac_bits = static_cast<uint32_t>(Bits(fraction, 51, 29));
4572       return FloatPack(sign, exp_bits, frac_bits);
4573     } else {
4574       return DoublePack(sign, Bits(result_exp, 10, 0), Bits(fraction, 51, 0));
4575     }
4576   }
4577 }
4578 
4579 
frecpe(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,FPRounding round)4580 LogicVRegister Simulator::frecpe(VectorFormat vform,
4581                                  LogicVRegister dst,
4582                                  const LogicVRegister& src,
4583                                  FPRounding round) {
4584   dst.ClearForWrite(vform);
4585   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4586     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4587       float input = src.Float<float>(i);
4588       dst.SetFloat(i, FPRecipEstimate<float>(input, round));
4589     }
4590   } else {
4591     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4592     for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4593       double input = src.Float<double>(i);
4594       dst.SetFloat(i, FPRecipEstimate<double>(input, round));
4595     }
4596   }
4597   return dst;
4598 }
4599 
4600 
ursqrte(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4601 LogicVRegister Simulator::ursqrte(VectorFormat vform,
4602                                   LogicVRegister dst,
4603                                   const LogicVRegister& src) {
4604   dst.ClearForWrite(vform);
4605   uint64_t operand;
4606   uint32_t result;
4607   double dp_operand, dp_result;
4608   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4609     operand = src.Uint(vform, i);
4610     if (operand <= 0x3FFFFFFF) {
4611       result = 0xFFFFFFFF;
4612     } else {
4613       dp_operand = operand * std::pow(2.0, -32);
4614       dp_result = recip_sqrt_estimate(dp_operand) * std::pow(2.0, 31);
4615       result = static_cast<uint32_t>(dp_result);
4616     }
4617     dst.SetUint(vform, i, result);
4618   }
4619   return dst;
4620 }
4621 
4622 
4623 // Based on reference C function recip_estimate from ARM ARM.
recip_estimate(double a)4624 double Simulator::recip_estimate(double a) {
4625   int q, s;
4626   double r;
4627   q = static_cast<int>(a * 512.0);
4628   r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
4629   s = static_cast<int>(256.0 * r + 0.5);
4630   return static_cast<double>(s) / 256.0;
4631 }
4632 
4633 
urecpe(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4634 LogicVRegister Simulator::urecpe(VectorFormat vform,
4635                                  LogicVRegister dst,
4636                                  const LogicVRegister& src) {
4637   dst.ClearForWrite(vform);
4638   uint64_t operand;
4639   uint32_t result;
4640   double dp_operand, dp_result;
4641   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4642     operand = src.Uint(vform, i);
4643     if (operand <= 0x7FFFFFFF) {
4644       result = 0xFFFFFFFF;
4645     } else {
4646       dp_operand = operand * std::pow(2.0, -32);
4647       dp_result = recip_estimate(dp_operand) * std::pow(2.0, 31);
4648       result = static_cast<uint32_t>(dp_result);
4649     }
4650     dst.SetUint(vform, i, result);
4651   }
4652   return dst;
4653 }
4654 
4655 template <typename T>
frecpx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4656 LogicVRegister Simulator::frecpx(VectorFormat vform,
4657                                  LogicVRegister dst,
4658                                  const LogicVRegister& src) {
4659   dst.ClearForWrite(vform);
4660   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4661     T op = src.Float<T>(i);
4662     T result;
4663     if (std::isnan(op)) {
4664        result = FPProcessNaN(op);
4665     } else {
4666       int exp;
4667       uint32_t sign;
4668       if (sizeof(T) == sizeof(float)) {  // NOLINT(runtime/sizeof)
4669         sign = FloatSign(op);
4670         exp = FloatExp(op);
4671         exp = (exp == 0) ? (0xFF - 1) : static_cast<int>(Bits(~exp, 7, 0));
4672         result = FloatPack(sign, exp, 0);
4673       } else {
4674         sign = DoubleSign(op);
4675         exp = DoubleExp(op);
4676         exp = (exp == 0) ? (0x7FF - 1) : static_cast<int>(Bits(~exp, 10, 0));
4677         result = DoublePack(sign, exp, 0);
4678       }
4679     }
4680     dst.SetFloat(i, result);
4681   }
4682   return dst;
4683 }
4684 
4685 
frecpx(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src)4686 LogicVRegister Simulator::frecpx(VectorFormat vform,
4687                                  LogicVRegister dst,
4688                                  const LogicVRegister& src) {
4689   if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4690     frecpx<float>(vform, dst, src);
4691   } else {
4692     VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4693     frecpx<double>(vform, dst, src);
4694   }
4695   return dst;
4696 }
4697 
scvtf(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int fbits,FPRounding round)4698 LogicVRegister Simulator::scvtf(VectorFormat vform,
4699                                 LogicVRegister dst,
4700                                 const LogicVRegister& src,
4701                                 int fbits,
4702                                 FPRounding round) {
4703   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4704     if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4705       float result = FixedToFloat(src.Int(kFormatS, i), fbits, round);
4706       dst.SetFloat<float>(i, result);
4707     } else {
4708       VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4709       double result = FixedToDouble(src.Int(kFormatD, i), fbits, round);
4710       dst.SetFloat<double>(i, result);
4711     }
4712   }
4713   return dst;
4714 }
4715 
4716 
ucvtf(VectorFormat vform,LogicVRegister dst,const LogicVRegister & src,int fbits,FPRounding round)4717 LogicVRegister Simulator::ucvtf(VectorFormat vform,
4718                                 LogicVRegister dst,
4719                                 const LogicVRegister& src,
4720                                 int fbits,
4721                                 FPRounding round) {
4722   for (int i = 0; i < LaneCountFromFormat(vform); i++) {
4723     if (LaneSizeInBitsFromFormat(vform) == kSRegSize) {
4724       float result = UFixedToFloat(src.Uint(kFormatS, i), fbits, round);
4725       dst.SetFloat<float>(i, result);
4726     } else {
4727       VIXL_ASSERT(LaneSizeInBitsFromFormat(vform) == kDRegSize);
4728       double result = UFixedToDouble(src.Uint(kFormatD, i), fbits, round);
4729       dst.SetFloat<double>(i, result);
4730     }
4731   }
4732   return dst;
4733 }
4734 
4735 
4736 }  // namespace vixl
4737 
4738 #endif  // JS_SIMULATOR_ARM64
4739