fp.isa (7435:62bdb68bb314) fp.isa (7591:aabe621e58df)
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48let {{
49 header_output = '''
50 StaticInstPtr
51 decodeNeonMem(ExtMachInst machInst);
52
53 StaticInstPtr
54 decodeNeonData(ExtMachInst machInst);
55 '''
56
57 decoder_output = '''
58 StaticInstPtr
59 decodeNeonMem(ExtMachInst machInst)
60 {
61 const uint32_t b = bits(machInst, 11, 8);
62 const bool a = bits(machInst, 23);
63 const bool l = bits(machInst, 21);
64
65 if (l) {
66 // Load instructions.
67 if (a) {
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder. You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Copyright (c) 2007-2008 The Florida State University
16// All rights reserved.
17//
18// Redistribution and use in source and binary forms, with or without
19// modification, are permitted provided that the following conditions are
20// met: redistributions of source code must retain the above copyright
21// notice, this list of conditions and the following disclaimer;
22// redistributions in binary form must reproduce the above copyright
23// notice, this list of conditions and the following disclaimer in the
24// documentation and/or other materials provided with the distribution;
25// neither the name of the copyright holders nor the names of its
26// contributors may be used to endorse or promote products derived from
27// this software without specific prior written permission.
28//
29// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48let {{
49 header_output = '''
50 StaticInstPtr
51 decodeNeonMem(ExtMachInst machInst);
52
53 StaticInstPtr
54 decodeNeonData(ExtMachInst machInst);
55 '''
56
57 decoder_output = '''
58 StaticInstPtr
59 decodeNeonMem(ExtMachInst machInst)
60 {
61 const uint32_t b = bits(machInst, 11, 8);
62 const bool a = bits(machInst, 23);
63 const bool l = bits(machInst, 21);
64
65 if (l) {
66 // Load instructions.
67 if (a) {
68 switch (b) {
68 if (bits(b, 3, 2) != 3) {
69 switch (bits(b, 1, 0)) {
70 case 0x0:
71 return new WarnUnimplemented("vld1 single", machInst);
72 case 0x1:
73 return new WarnUnimplemented("vld2 single", machInst);
74 case 0x2:
75 return new WarnUnimplemented("vld3 single", machInst);
76 case 0x3:
77 return new WarnUnimplemented("vld4 single", machInst);
78 }
79 } else {
80 switch (bits(b, 1, 0)) {
81 case 0x0:
82 return new WarnUnimplemented("vld1 single all",
83 machInst);
84 case 0x1:
85 return new WarnUnimplemented("vld2 single all",
86 machInst);
87 case 0x2:
88 return new WarnUnimplemented("vld3 single all",
89 machInst);
90 case 0x3:
91 return new WarnUnimplemented("vld4 single all",
92 machInst);
93 }
69 }
94 }
70 // Single.
71 } else {
95 } else {
72 switch (b) {
96 switch (bits(b, 3, 1)) {
97 case 0x0:
98 return new WarnUnimplemented("vld4 multiple", machInst);
99 case 0x2:
100 return new WarnUnimplemented("vld3 multiple", machInst);
101 case 0x3:
102 return new WarnUnimplemented("vld1 multiple", machInst);
103 case 0x4:
104 return new WarnUnimplemented("vld2 multiple", machInst);
105 case 0x1:
106 if (b & 0x1) {
107 return new WarnUnimplemented("vld2 multiple", machInst);
108 } else {
109 return new WarnUnimplemented("vld1 multiple", machInst);
110 }
111 case 0x5:
112 if ((b & 0x1) == 0) {
113 return new WarnUnimplemented("vld1 multiple", machInst);
114 } else {
115 break;
116 }
73 }
117 }
74 // Multiple.
75 }
76 } else {
77 // Store instructions.
78 if (a) {
118 }
119 } else {
120 // Store instructions.
121 if (a) {
79 switch (b) {
122 if (bits(b, 3, 2) != 3) {
123 switch (bits(b, 1, 0)) {
124 case 0x0:
125 return new WarnUnimplemented("vst1 single", machInst);
126 case 0x1:
127 return new WarnUnimplemented("vst2 single", machInst);
128 case 0x2:
129 return new WarnUnimplemented("vst3 single", machInst);
130 case 0x3:
131 return new WarnUnimplemented("vst4 single", machInst);
132 }
133 } else {
134 switch (bits(b, 1, 0)) {
135 case 0x0:
136 return new WarnUnimplemented("vst1 single all",
137 machInst);
138 case 0x1:
139 return new WarnUnimplemented("vst2 single all",
140 machInst);
141 case 0x2:
142 return new WarnUnimplemented("vst3 single all",
143 machInst);
144 case 0x3:
145 return new WarnUnimplemented("vst4 single all",
146 machInst);
147 }
80 }
148 }
81 // Single.
82 } else {
149 } else {
83 switch (b) {
150 switch (bits(b, 3, 1)) {
151 case 0x0:
152 return new WarnUnimplemented("vst4 multiple", machInst);
153 case 0x2:
154 return new WarnUnimplemented("vst3 multiple", machInst);
155 case 0x3:
156 return new WarnUnimplemented("vst1 multiple", machInst);
157 case 0x4:
158 return new WarnUnimplemented("vst2 multiple", machInst);
159 case 0x1:
160 if (b & 0x1) {
161 return new WarnUnimplemented("vst2 multiple", machInst);
162 } else {
163 return new WarnUnimplemented("vst1 multiple", machInst);
164 }
165 case 0x5:
166 if ((b & 0x1) == 0) {
167 return new WarnUnimplemented("vst1 multiple", machInst);
168 } else {
169 break;
170 }
84 }
171 }
85 // Multiple.
86 }
87 }
172 }
173 }
88 return new WarnUnimplemented("neon memory", machInst);
174 return new Unknown(machInst);
89 }
90 '''
91
92 decoder_output += '''
93 static StaticInstPtr
94 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
95 {
96 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
97 const uint32_t a = bits(machInst, 11, 8);
98 const bool b = bits(machInst, 4);
99 const uint32_t c = bits(machInst, 21, 20);
100 switch (a) {
101 case 0x0:
102 if (b) {
103 if (bits(machInst, 9) == 0) {
104 return new WarnUnimplemented("vhadd", machInst);
105 } else {
106 return new WarnUnimplemented("vhsub", machInst);
107 }
108 } else {
109 return new WarnUnimplemented("vqadd", machInst);
110 }
111 case 0x1:
112 if (!b) {
113 return new WarnUnimplemented("vrhadd", machInst);
114 } else {
115 if (u) {
116 switch (c) {
117 case 0:
118 return new WarnUnimplemented("veor", machInst);
119 case 1:
120 return new WarnUnimplemented("vbsl", machInst);
121 case 2:
122 return new WarnUnimplemented("vbit", machInst);
123 case 3:
124 return new WarnUnimplemented("vbif", machInst);
125 }
126 } else {
127 switch (c) {
128 case 0:
129 return new WarnUnimplemented("vand (reg)", machInst);
130 case 1:
131 return new WarnUnimplemented("vbic (reg)", machInst);
132 case 2:
133 {
134 const IntRegIndex n = (IntRegIndex)(
135 (uint32_t)bits(machInst, 19, 16) |
136 (uint32_t)(bits(machInst, 7) << 4));
137 const IntRegIndex m = (IntRegIndex)(
138 (uint32_t)bits(machInst, 3, 0) |
139 (uint32_t)(bits(machInst, 5) << 4));
140 if (n == m) {
141 return new WarnUnimplemented("vmov (reg)",
142 machInst);
143 } else {
144 return new WarnUnimplemented("vorr (reg)",
145 machInst);
146 }
147 }
148 case 3:
149 return new WarnUnimplemented("vorn (reg)", machInst);
150 }
151 }
152 }
153 case 0x2:
154 if (b) {
155 return new WarnUnimplemented("vqsub", machInst);
156 } else {
157 if (bits(machInst, 9) == 0) {
158 return new WarnUnimplemented("vhadd", machInst);
159 } else {
160 return new WarnUnimplemented("vhsub", machInst);
161 }
162 }
163 case 0x3:
164 if (b) {
165 return new WarnUnimplemented("vcge (reg)", machInst);
166 } else {
167 return new WarnUnimplemented("vcgt (reg)", machInst);
168 }
169 case 0x4:
170 if (b) {
171 return new WarnUnimplemented("vqshl (reg)", machInst);
172 } else {
173 return new WarnUnimplemented("vshl (reg)", machInst);
174 }
175 case 0x5:
176 if (b) {
177 return new WarnUnimplemented("vqrshl", machInst);
178 } else {
179 return new WarnUnimplemented("vrshl", machInst);
180 }
181 case 0x6:
182 if (b) {
183 return new WarnUnimplemented("vmin (int)", machInst);
184 } else {
185 return new WarnUnimplemented("vmax (int)", machInst);
186 }
187 case 0x7:
188 if (b) {
189 return new WarnUnimplemented("vaba", machInst);
190 } else {
191 if (bits(machInst, 23) == 1) {
192 if (bits(machInst, 6) == 1) {
193 return new Unknown(machInst);
194 } else {
195 return new WarnUnimplemented("vabdl (int)", machInst);
196 }
197 } else {
198 return new WarnUnimplemented("vabd (int)", machInst);
199 }
200 }
201 case 0x8:
202 if (b) {
203 if (u) {
204 return new WarnUnimplemented("vceq (reg)", machInst);
205 } else {
206 return new WarnUnimplemented("vtst", machInst);
207 }
208 } else {
209 if (u) {
210 return new WarnUnimplemented("vsub (int)", machInst);
211 } else {
212 return new WarnUnimplemented("vadd (int)", machInst);
213 }
214 }
215 case 0x9:
216 if (b) {
217 if (u) {
218 return new WarnUnimplemented("vmul (poly)", machInst);
219 } else {
220 return new WarnUnimplemented("vmul (int)", machInst);
221 }
222 } else {
223 if (u) {
224 return new WarnUnimplemented("vmls (int)", machInst);
225 } else {
226 return new WarnUnimplemented("vmla (int)", machInst);
227 }
228 }
229 case 0xa:
230 if (b) {
231 return new WarnUnimplemented("vpmin (int)", machInst);
232 } else {
233 return new WarnUnimplemented("vpmax (int)", machInst);
234 }
235 case 0xb:
236 if (b) {
237 if (u) {
238 return new Unknown(machInst);
239 } else {
240 return new WarnUnimplemented("vpadd (int)", machInst);
241 }
242 } else {
243 if (u) {
244 return new WarnUnimplemented("vqrdmulh", machInst);
245 } else {
246 return new WarnUnimplemented("vqdmulh", machInst);
247 }
248 }
249 case 0xc:
250 return new Unknown(machInst);
251 case 0xd:
252 if (b) {
253 if (u) {
254 if (bits(c, 1) == 0) {
255 return new WarnUnimplemented("vmul (fp)", machInst);
256 } else {
257 return new Unknown(machInst);
258 }
259 } else {
260 if (bits(c, 1) == 0) {
261 return new WarnUnimplemented("vmla (fp)", machInst);
262 } else {
263 return new WarnUnimplemented("vmls (fp)", machInst);
264 }
265 }
266 } else {
267 if (u) {
268 if (bits(c, 1) == 0) {
269 return new WarnUnimplemented("vpadd (fp)", machInst);
270 } else {
271 return new WarnUnimplemented("vabd (fp)", machInst);
272 }
273 } else {
274 if (bits(c, 1) == 0) {
275 return new WarnUnimplemented("vadd (fp)", machInst);
276 } else {
277 return new WarnUnimplemented("vsub (fp)", machInst);
278 }
279 }
280 }
281 case 0xe:
282 if (b) {
283 if (u) {
284 if (bits(c, 1) == 0) {
285 return new WarnUnimplemented("vacge", machInst);
286 } else {
287 return new WarnUnimplemented("vacgt", machInst);
288 }
289 } else {
290 return new Unknown(machInst);
291 }
292 } else {
293 if (u) {
294 if (bits(c, 1) == 0) {
295 return new WarnUnimplemented("vcge (reg)", machInst);
296 } else {
297 return new WarnUnimplemented("vcgt (reg)", machInst);
298 }
299 } else {
300 if (bits(c, 1) == 0) {
301 return new WarnUnimplemented("vceq (reg)", machInst);
302 } else {
303 return new Unknown(machInst);
304 }
305 }
306 }
307 case 0xf:
308 if (b) {
309 if (u) {
310 return new Unknown(machInst);
311 } else {
312 if (bits(c, 1) == 0) {
313 return new WarnUnimplemented("vrecps", machInst);
314 } else {
315 return new WarnUnimplemented("vrsqrts", machInst);
316 }
317 }
318 } else {
319 if (u) {
320 if (bits(c, 1) == 0) {
321 return new WarnUnimplemented("vpmax (fp)", machInst);
322 } else {
323 return new WarnUnimplemented("vpmin (fp)", machInst);
324 }
325 } else {
326 if (bits(c, 1) == 0) {
327 return new WarnUnimplemented("vmax (fp)", machInst);
328 } else {
329 return new WarnUnimplemented("vmin (fp)", machInst);
330 }
331 }
332 }
333 }
334 return new Unknown(machInst);
335 }
336
337 static StaticInstPtr
338 decodeNeonOneRegModImm(ExtMachInst machInst)
339 {
340 const bool op = bits(machInst, 5);
341 const uint32_t cmode = bits(machInst, 11, 8);
342 if (op) {
343 if (bits(cmode, 3) == 0) {
344 if (bits(cmode, 0) == 0) {
345 return new WarnUnimplemented("vmov (imm)", machInst);
346 } else {
347 return new WarnUnimplemented("vorr (imm)", machInst);
348 }
349 } else {
350 if (bits(cmode, 2) == 1) {
351 return new WarnUnimplemented("vmov (imm)", machInst);
352 } else {
353 if (bits(cmode, 0) == 0) {
354 return new WarnUnimplemented("vmov (imm)", machInst);
355 } else {
356 return new WarnUnimplemented("vorr (imm)", machInst);
357 }
358 }
359 }
360 } else {
361 if (bits(cmode, 3) == 0) {
362 if (bits(cmode, 0) == 0) {
363 return new WarnUnimplemented("vmvn (imm)", machInst);
364 } else {
365 return new WarnUnimplemented("vbic (imm)", machInst);
366 }
367 } else {
368 if (bits(cmode, 2) == 1) {
369 switch (bits(cmode, 1, 0)) {
370 case 0:
371 case 1:
372 return new WarnUnimplemented("vmvn (imm)", machInst);
373 case 2:
374 return new WarnUnimplemented("vmov (imm)", machInst);
375 case 3:
376 return new Unknown(machInst);
377 }
378 return new WarnUnimplemented("vmov (imm)", machInst);
379 } else {
380 if (bits(cmode, 0) == 0) {
381 return new WarnUnimplemented("vmvn (imm)", machInst);
382 } else {
383 return new WarnUnimplemented("vbic (imm)", machInst);
384 }
385 }
386 }
387 }
388 return new Unknown(machInst);
389 }
390
391 static StaticInstPtr
392 decodeNeonTwoRegAndShift(ExtMachInst machInst)
393 {
394 const uint32_t a = bits(machInst, 11, 8);
395 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
396 const bool b = bits(machInst, 6);
397 const bool l = bits(machInst, 7);
398
399 switch (a) {
400 case 0x0:
401 return new WarnUnimplemented("vshr", machInst);
402 case 0x1:
403 return new WarnUnimplemented("vsra", machInst);
404 case 0x2:
405 return new WarnUnimplemented("vrshr", machInst);
406 case 0x3:
407 return new WarnUnimplemented("vrsra", machInst);
408 case 0x4:
409 if (u) {
410 return new WarnUnimplemented("vsri", machInst);
411 } else {
412 return new Unknown(machInst);
413 }
414 case 0x5:
415 if (u) {
416 return new WarnUnimplemented("vsli", machInst);
417 } else {
418 return new WarnUnimplemented("vshl (imm)", machInst);
419 }
420 case 0x6:
421 case 0x7:
422 return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
423 case 0x8:
424 if (l) {
425 return new Unknown(machInst);
426 } else if (u) {
427 if (b) {
428 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
429 } else {
430 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
431 }
432 } else {
433 if (b) {
434 return new WarnUnimplemented("vrshrn", machInst);
435 } else {
436 return new WarnUnimplemented("vshrn", machInst);
437 }
438 }
439 case 0x9:
440 if (l) {
441 return new Unknown(machInst);
442 } else if (b) {
443 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
444 } else {
445 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
446 }
447 case 0xa:
448 if (l || b) {
449 return new Unknown(machInst);
450 } else {
451 // If the shift amount is zero, it's vmovl.
452 return new WarnUnimplemented("vshll, vmovl", machInst);
453 }
454 case 0xe:
455 case 0xf:
456 if (l) {
457 return new Unknown(machInst);
458 } else if (a == 0xe) {
459 return new WarnUnimplemented("vcvt (fixed to fp)", machInst);
460 } else if (a == 0xf) {
461 return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
462 }
463 }
464 return new Unknown(machInst);
465 }
466
467 static StaticInstPtr
468 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
469 {
470 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
471 const uint32_t a = bits(machInst, 11, 8);
472
473 switch (a) {
474 case 0x0:
475 return new WarnUnimplemented("vaddl", machInst);
476 case 0x1:
477 return new WarnUnimplemented("vaddw", machInst);
478 case 0x2:
479 return new WarnUnimplemented("vsubl", machInst);
480 case 0x3:
481 return new WarnUnimplemented("vsubw", machInst);
482 case 0x4:
483 if (u) {
484 return new WarnUnimplemented("vraddhn", machInst);
485 } else {
486 return new WarnUnimplemented("vaddhn", machInst);
487 }
488 case 0x5:
489 return new WarnUnimplemented("vabal", machInst);
490 case 0x6:
491 if (u) {
492 return new WarnUnimplemented("vrsubhn", machInst);
493 } else {
494 return new WarnUnimplemented("vsubhn", machInst);
495 }
496 case 0x7:
497 if (bits(machInst, 23)) {
498 return new WarnUnimplemented("vabdl (int)", machInst);
499 } else {
500 return new WarnUnimplemented("vabd (int)", machInst);
501 }
502 case 0x8:
503 return new WarnUnimplemented("vmlal (int)", machInst);
504 case 0xa:
505 return new WarnUnimplemented("vmlsl (int)", machInst);
506 case 0x9:
507 if (bits(machInst, 23) == 0) {
508 if (bits(machInst, 4) == 0) {
509 if (u) {
510 return new WarnUnimplemented("vmls (int)", machInst);
511 } else {
512 return new WarnUnimplemented("vmla (int)", machInst);
513 }
514 } else {
515 if (u) {
516 return new WarnUnimplemented("vmul (poly)", machInst);
517 } else {
518 return new WarnUnimplemented("vmul (int)", machInst);
519 }
520 }
521 } else {
522 return new WarnUnimplemented("vqdmlal", machInst);
523 }
524 case 0xb:
525 if (!u) {
526 return new Unknown(machInst);
527 } else {
528 return new WarnUnimplemented("vqdmlsl", machInst);
529 }
530 case 0xc:
531 return new WarnUnimplemented("vmull (int)", machInst);
532 case 0xd:
533 if (!u) {
534 return new Unknown(machInst);
535 } else {
536 return new WarnUnimplemented("vqdmull", machInst);
537 }
538 case 0xe:
539 return new WarnUnimplemented("vmull (poly)", machInst);
540 }
541 return new Unknown(machInst);
542 }
543
544 static StaticInstPtr
545 decodeNeonTwoRegScalar(ExtMachInst machInst)
546 {
547 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
548 const uint32_t a = bits(machInst, 11, 8);
549
550 switch (a) {
551 case 0x0:
552 return new WarnUnimplemented("vmla (int scalar)", machInst);
553 case 0x1:
554 return new WarnUnimplemented("vmla (fp scalar)", machInst);
555 case 0x4:
556 return new WarnUnimplemented("vmls (int scalar)", machInst);
557 case 0x5:
558 return new WarnUnimplemented("vmls (fp scalar)", machInst);
559 case 0x2:
560 return new WarnUnimplemented("vmlal (scalar)", machInst);
561 case 0x6:
562 return new WarnUnimplemented("vmlsl (scalar)", machInst);
563 case 0x3:
564 if (u) {
565 return new Unknown(machInst);
566 } else {
567 return new WarnUnimplemented("vqdmlal", machInst);
568 }
569 case 0x7:
570 if (u) {
571 return new Unknown(machInst);
572 } else {
573 return new WarnUnimplemented("vqdmlsl", machInst);
574 }
575 case 0x8:
576 return new WarnUnimplemented("vmul (int scalar)", machInst);
577 case 0x9:
578 return new WarnUnimplemented("vmul (fp scalar)", machInst);
579 case 0xa:
580 return new WarnUnimplemented("vmull (scalar)", machInst);
581 case 0xb:
582 if (u) {
583 return new Unknown(machInst);
584 } else {
585 return new WarnUnimplemented("vqdmull", machInst);
586 }
587 case 0xc:
588 return new WarnUnimplemented("vqdmulh", machInst);
589 case 0xd:
590 return new WarnUnimplemented("vqrdmulh", machInst);
591 }
592 return new Unknown(machInst);
593 }
594
595 static StaticInstPtr
596 decodeNeonTwoRegMisc(ExtMachInst machInst)
597 {
598 const uint32_t a = bits(machInst, 17, 16);
599 const uint32_t b = bits(machInst, 10, 6);
600 switch (a) {
601 case 0x0:
602 switch (bits(b, 4, 1)) {
603 case 0x0:
604 return new WarnUnimplemented("vrev64", machInst);
605 case 0x1:
606 return new WarnUnimplemented("vrev32", machInst);
607 case 0x2:
608 return new WarnUnimplemented("vrev16", machInst);
609 case 0x4:
610 case 0x5:
611 return new WarnUnimplemented("vpaddl", machInst);
612 case 0x8:
613 return new WarnUnimplemented("vcls", machInst);
614 case 0x9:
615 return new WarnUnimplemented("vclz", machInst);
616 case 0xa:
617 return new WarnUnimplemented("vcnt", machInst);
618 case 0xb:
619 return new WarnUnimplemented("vmvn (reg)", machInst);
620 case 0xc:
621 case 0xd:
622 return new WarnUnimplemented("vpadal", machInst);
623 case 0xe:
624 return new WarnUnimplemented("vqabs", machInst);
625 case 0xf:
626 return new WarnUnimplemented("vqneg", machInst);
627 default:
628 return new Unknown(machInst);
629 }
630 case 0x1:
631 switch (bits(b, 3, 1)) {
632 case 0x0:
633 return new WarnUnimplemented("vcgt (imm #0)", machInst);
634 case 0x1:
635 return new WarnUnimplemented("vcge (imm #0)", machInst);
636 case 0x2:
637 return new WarnUnimplemented("vceq (imm #0)", machInst);
638 case 0x3:
639 return new WarnUnimplemented("vcle (imm #0)", machInst);
640 case 0x4:
641 return new WarnUnimplemented("vclt (imm #0)", machInst);
642 case 0x6:
643 return new WarnUnimplemented("vabs (imm #0)", machInst);
644 case 0x7:
645 return new WarnUnimplemented("vneg (imm #0)", machInst);
646 }
647 case 0x2:
648 switch (bits(b, 4, 1)) {
649 case 0x0:
650 return new WarnUnimplemented("vswp", machInst);
651 case 0x1:
652 return new WarnUnimplemented("vtrn", machInst);
653 case 0x2:
654 return new WarnUnimplemented("vuzp", machInst);
655 case 0x3:
656 return new WarnUnimplemented("vzip", machInst);
657 case 0x4:
658 if (b == 0x8) {
659 return new WarnUnimplemented("vmovn", machInst);
660 } else {
661 return new WarnUnimplemented("vqmovun", machInst);
662 }
663 case 0x5:
664 return new WarnUnimplemented("vqmovn", machInst);
665 case 0x6:
666 if (b == 0xc) {
667 return new WarnUnimplemented("vshll", machInst);
668 } else {
669 return new Unknown(machInst);
670 }
671 case 0xc:
672 case 0xe:
673 if (b == 0x18) {
674 return new WarnUnimplemented("vcvt (single to half)",
675 machInst);
676 } else if (b == 0x1c) {
677 return new WarnUnimplemented("vcvt (half to single)",
678 machInst);
679 } else {
680 return new Unknown(machInst);
681 }
682 default:
683 return new Unknown(machInst);
684 }
685 case 0x3:
686 if (bits(b, 4, 3) == 0x3) {
687 return new WarnUnimplemented("vcvt (fp and int)", machInst);
688 } else if ((b & 0x1a) == 0x10) {
689 return new WarnUnimplemented("vrecpe", machInst);
690 } else if ((b & 0x1a) == 0x12) {
691 return new WarnUnimplemented("vrsqrte", machInst);
692 } else {
693 return new Unknown(machInst);
694 }
695 }
696 return new Unknown(machInst);
697 }
698
699 StaticInstPtr
700 decodeNeonData(ExtMachInst machInst)
701 {
702 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
703 const uint32_t a = bits(machInst, 23, 19);
704 const uint32_t b = bits(machInst, 11, 8);
705 const uint32_t c = bits(machInst, 7, 4);
706 if (bits(a, 4) == 0) {
707 return decodeNeonThreeRegistersSameLength(machInst);
708 } else if ((c & 0x9) == 1) {
709 if ((a & 0x7) == 0) {
710 return decodeNeonOneRegModImm(machInst);
711 } else {
712 return decodeNeonTwoRegAndShift(machInst);
713 }
714 } else if ((c & 0x9) == 9) {
715 return decodeNeonTwoRegAndShift(machInst);
716 } else if ((c & 0x5) == 0) {
717 if (bits(a, 3, 2) != 0x3) {
718 return decodeNeonThreeRegDiffLengths(machInst);
719 }
720 } else if ((c & 0x5) == 4) {
721 if (bits(a, 3, 2) != 0x3) {
722 return decodeNeonTwoRegScalar(machInst);
723 }
724 } else if ((a & 0x16) == 0x16) {
725 if (!u) {
726 if (bits(c, 0) == 0) {
727 return new WarnUnimplemented("vext", machInst);
728 }
729 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
730 return decodeNeonTwoRegMisc(machInst);
731 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
732 if (bits(machInst, 6) == 0) {
733 return new WarnUnimplemented("vtbl", machInst);
734 } else {
735 return new WarnUnimplemented("vtbx", machInst);
736 }
737 } else if (b == 0xc && (c & 0x9) == 0) {
738 return new WarnUnimplemented("vdup (scalar)", machInst);
739 }
740 }
741 return new Unknown(machInst);
742 }
743 '''
744}};
745
746def format ThumbNeonMem() {{
747 decode_block = '''
748 return decodeNeonMem(machInst);
749 '''
750}};
751
752def format ThumbNeonData() {{
753 decode_block = '''
754 return decodeNeonMem(machInst);
755 '''
756}};
757
758let {{
759 header_output = '''
760 StaticInstPtr
761 decodeExtensionRegLoadStore(ExtMachInst machInst);
762 '''
763 decoder_output = '''
764 StaticInstPtr
765 decodeExtensionRegLoadStore(ExtMachInst machInst)
766 {
767 const uint32_t opcode = bits(machInst, 24, 20);
768 const uint32_t offset = bits(machInst, 7, 0);
769 const bool single = (bits(machInst, 8) == 0);
770 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
771 RegIndex vd;
772 if (single) {
773 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
774 bits(machInst, 22));
775 } else {
776 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
777 (bits(machInst, 22) << 5));
778 }
779 switch (bits(opcode, 4, 3)) {
780 case 0x0:
781 if (bits(opcode, 4, 1) == 0x2 &&
782 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
783 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
784 if ((bits(machInst, 7, 4) & 0xd) != 1) {
785 break;
786 }
787 const IntRegIndex rt =
788 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
789 const IntRegIndex rt2 =
790 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
791 const bool op = bits(machInst, 20);
792 uint32_t vm;
793 if (single) {
794 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
795 } else {
796 vm = (bits(machInst, 3, 0) << 1) |
797 (bits(machInst, 5) << 5);
798 }
799 if (op) {
800 return new Vmov2Core2Reg(machInst, rt, rt2,
801 (IntRegIndex)vm);
802 } else {
803 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
804 rt, rt2);
805 }
806 }
807 break;
808 case 0x1:
809 {
810 if (offset == 0 || vd + offset > NumFloatArchRegs) {
811 break;
812 }
813 switch (bits(opcode, 1, 0)) {
814 case 0x0:
815 return new VLdmStm(machInst, rn, vd, single,
816 true, false, false, offset);
817 case 0x1:
818 return new VLdmStm(machInst, rn, vd, single,
819 true, false, true, offset);
820 case 0x2:
821 return new VLdmStm(machInst, rn, vd, single,
822 true, true, false, offset);
823 case 0x3:
824 // If rn == sp, then this is called vpop.
825 return new VLdmStm(machInst, rn, vd, single,
826 true, true, true, offset);
827 }
828 }
829 case 0x2:
830 if (bits(opcode, 1, 0) == 0x2) {
831 // If rn == sp, then this is called vpush.
832 return new VLdmStm(machInst, rn, vd, single,
833 false, true, false, offset);
834 } else if (bits(opcode, 1, 0) == 0x3) {
835 return new VLdmStm(machInst, rn, vd, single,
836 false, true, true, offset);
837 }
838 // Fall through on purpose
839 case 0x3:
840 const bool up = (bits(machInst, 23) == 1);
841 const uint32_t imm = bits(machInst, 7, 0) << 2;
842 RegIndex vd;
843 if (single) {
844 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
845 (bits(machInst, 22)));
846 } else {
847 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
848 (bits(machInst, 22) << 5));
849 }
850 if (bits(opcode, 1, 0) == 0x0) {
851 if (single) {
852 if (up) {
853 return new %(vstr_us)s(machInst, vd, rn, up, imm);
854 } else {
855 return new %(vstr_s)s(machInst, vd, rn, up, imm);
856 }
857 } else {
858 if (up) {
859 return new %(vstr_ud)s(machInst, vd, vd + 1,
860 rn, up, imm);
861 } else {
862 return new %(vstr_d)s(machInst, vd, vd + 1,
863 rn, up, imm);
864 }
865 }
866 } else if (bits(opcode, 1, 0) == 0x1) {
867 if (single) {
868 if (up) {
869 return new %(vldr_us)s(machInst, vd, rn, up, imm);
870 } else {
871 return new %(vldr_s)s(machInst, vd, rn, up, imm);
872 }
873 } else {
874 if (up) {
875 return new %(vldr_ud)s(machInst, vd, vd + 1,
876 rn, up, imm);
877 } else {
878 return new %(vldr_d)s(machInst, vd, vd + 1,
879 rn, up, imm);
880 }
881 }
882 }
883 }
884 return new Unknown(machInst);
885 }
886 ''' % {
887 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
888 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
889 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
890 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
891 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
892 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
893 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
894 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
895 }
896}};
897
898def format ExtensionRegLoadStore() {{
899 decode_block = '''
900 return decodeExtensionRegLoadStore(machInst);
901 '''
902}};
903
904let {{
905 header_output = '''
906 StaticInstPtr
907 decodeShortFpTransfer(ExtMachInst machInst);
908 '''
909 decoder_output = '''
910 StaticInstPtr
911 decodeShortFpTransfer(ExtMachInst machInst)
912 {
913 const uint32_t l = bits(machInst, 20);
914 const uint32_t c = bits(machInst, 8);
915 const uint32_t a = bits(machInst, 23, 21);
916 const uint32_t b = bits(machInst, 6, 5);
917 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
918 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
919 return new Unknown(machInst);
920 }
921 if (l == 0 && c == 0) {
922 if (a == 0) {
923 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
924 bits(machInst, 7);
925 const IntRegIndex rt =
926 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
927 if (bits(machInst, 20) == 1) {
928 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
929 } else {
930 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
931 }
932 } else if (a == 0x7) {
933 const IntRegIndex rt =
934 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
935 uint32_t specReg = bits(machInst, 19, 16);
936 switch (specReg) {
937 case 0:
938 specReg = MISCREG_FPSID;
939 break;
940 case 1:
941 specReg = MISCREG_FPSCR;
942 break;
943 case 6:
944 specReg = MISCREG_MVFR1;
945 break;
946 case 7:
947 specReg = MISCREG_MVFR0;
948 break;
949 case 8:
950 specReg = MISCREG_FPEXC;
951 break;
952 default:
953 return new Unknown(machInst);
954 }
955 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
956 }
957 } else if (l == 0 && c == 1) {
958 if (bits(a, 2) == 0) {
959 uint32_t vd = (bits(machInst, 7) << 5) |
960 (bits(machInst, 19, 16) << 1);
961 uint32_t index, size;
962 const IntRegIndex rt =
963 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
964 if (bits(machInst, 22) == 1) {
965 size = 8;
966 index = (bits(machInst, 21) << 2) |
967 bits(machInst, 6, 5);
968 } else if (bits(machInst, 5) == 1) {
969 size = 16;
970 index = (bits(machInst, 21) << 1) |
971 bits(machInst, 6);
972 } else if (bits(machInst, 6) == 0) {
973 size = 32;
974 index = bits(machInst, 21);
975 } else {
976 return new Unknown(machInst);
977 }
978 if (index >= (32 / size)) {
979 index -= (32 / size);
980 vd++;
981 }
982 switch (size) {
983 case 8:
984 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
985 rt, index);
986 case 16:
987 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
988 rt, index);
989 case 32:
990 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
991 }
992 } else if (bits(b, 1) == 0) {
993 // A8-594
994 return new WarnUnimplemented("vdup", machInst);
995 }
996 } else if (l == 1 && c == 0) {
997 if (a == 0) {
998 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
999 bits(machInst, 7);
1000 const IntRegIndex rt =
1001 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1002 if (bits(machInst, 20) == 1) {
1003 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1004 } else {
1005 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1006 }
1007 } else if (a == 7) {
1008 const IntRegIndex rt =
1009 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1010 uint32_t specReg = bits(machInst, 19, 16);
1011 switch (specReg) {
1012 case 0:
1013 specReg = MISCREG_FPSID;
1014 break;
1015 case 1:
1016 specReg = MISCREG_FPSCR;
1017 break;
1018 case 6:
1019 specReg = MISCREG_MVFR1;
1020 break;
1021 case 7:
1022 specReg = MISCREG_MVFR0;
1023 break;
1024 case 8:
1025 specReg = MISCREG_FPEXC;
1026 break;
1027 default:
1028 return new Unknown(machInst);
1029 }
1030 if (rt == 0xf) {
1031 CPSR cpsrMask = 0;
1032 cpsrMask.n = 1;
1033 cpsrMask.z = 1;
1034 cpsrMask.c = 1;
1035 cpsrMask.v = 1;
1036 return new VmrsApsr(machInst, INTREG_CONDCODES,
1037 (IntRegIndex)specReg, (uint32_t)cpsrMask);
1038 } else {
1039 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
1040 }
1041 }
1042 } else {
1043 uint32_t vd = (bits(machInst, 7) << 5) |
1044 (bits(machInst, 19, 16) << 1);
1045 uint32_t index, size;
1046 const IntRegIndex rt =
1047 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1048 const bool u = (bits(machInst, 23) == 1);
1049 if (bits(machInst, 22) == 1) {
1050 size = 8;
1051 index = (bits(machInst, 21) << 2) |
1052 bits(machInst, 6, 5);
1053 } else if (bits(machInst, 5) == 1) {
1054 size = 16;
1055 index = (bits(machInst, 21) << 1) |
1056 bits(machInst, 6);
1057 } else if (bits(machInst, 6) == 0 && !u) {
1058 size = 32;
1059 index = bits(machInst, 21);
1060 } else {
1061 return new Unknown(machInst);
1062 }
1063 if (index >= (32 / size)) {
1064 index -= (32 / size);
1065 vd++;
1066 }
1067 switch (size) {
1068 case 8:
1069 if (u) {
1070 return new VmovRegCoreUB(machInst, rt,
1071 (IntRegIndex)vd, index);
1072 } else {
1073 return new VmovRegCoreSB(machInst, rt,
1074 (IntRegIndex)vd, index);
1075 }
1076 case 16:
1077 if (u) {
1078 return new VmovRegCoreUH(machInst, rt,
1079 (IntRegIndex)vd, index);
1080 } else {
1081 return new VmovRegCoreSH(machInst, rt,
1082 (IntRegIndex)vd, index);
1083 }
1084 case 32:
1085 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
1086 }
1087 }
1088 return new Unknown(machInst);
1089 }
1090 '''
1091}};
1092
1093def format ShortFpTransfer() {{
1094 decode_block = '''
1095 return decodeShortFpTransfer(machInst);
1096 '''
1097}};
1098
1099let {{
1100 header_output = '''
1101 StaticInstPtr
1102 decodeVfpData(ExtMachInst machInst);
1103 '''
1104 decoder_output = '''
1105 StaticInstPtr
1106 decodeVfpData(ExtMachInst machInst)
1107 {
1108 const uint32_t opc1 = bits(machInst, 23, 20);
1109 const uint32_t opc2 = bits(machInst, 19, 16);
1110 const uint32_t opc3 = bits(machInst, 7, 6);
1111 //const uint32_t opc4 = bits(machInst, 3, 0);
1112 const bool single = (bits(machInst, 8) == 0);
1113 // Used to select between vcmp and vcmpe.
1114 const bool e = (bits(machInst, 7) == 1);
1115 IntRegIndex vd;
1116 IntRegIndex vm;
1117 IntRegIndex vn;
1118 if (single) {
1119 vd = (IntRegIndex)(bits(machInst, 22) |
1120 (bits(machInst, 15, 12) << 1));
1121 vm = (IntRegIndex)(bits(machInst, 5) |
1122 (bits(machInst, 3, 0) << 1));
1123 vn = (IntRegIndex)(bits(machInst, 7) |
1124 (bits(machInst, 19, 16) << 1));
1125 } else {
1126 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
1127 (bits(machInst, 15, 12) << 1));
1128 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
1129 (bits(machInst, 3, 0) << 1));
1130 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
1131 (bits(machInst, 19, 16) << 1));
1132 }
1133 switch (opc1 & 0xb /* 1011 */) {
1134 case 0x0:
1135 if (bits(machInst, 6) == 0) {
1136 if (single) {
1137 return decodeVfpRegRegRegOp<VmlaS>(
1138 machInst, vd, vn, vm, false);
1139 } else {
1140 return decodeVfpRegRegRegOp<VmlaD>(
1141 machInst, vd, vn, vm, true);
1142 }
1143 } else {
1144 if (single) {
1145 return decodeVfpRegRegRegOp<VmlsS>(
1146 machInst, vd, vn, vm, false);
1147 } else {
1148 return decodeVfpRegRegRegOp<VmlsD>(
1149 machInst, vd, vn, vm, true);
1150 }
1151 }
1152 case 0x1:
1153 if (bits(machInst, 6) == 1) {
1154 if (single) {
1155 return decodeVfpRegRegRegOp<VnmlaS>(
1156 machInst, vd, vn, vm, false);
1157 } else {
1158 return decodeVfpRegRegRegOp<VnmlaD>(
1159 machInst, vd, vn, vm, true);
1160 }
1161 } else {
1162 if (single) {
1163 return decodeVfpRegRegRegOp<VnmlsS>(
1164 machInst, vd, vn, vm, false);
1165 } else {
1166 return decodeVfpRegRegRegOp<VnmlsD>(
1167 machInst, vd, vn, vm, true);
1168 }
1169 }
1170 case 0x2:
1171 if ((opc3 & 0x1) == 0) {
1172 if (single) {
1173 return decodeVfpRegRegRegOp<VmulS>(
1174 machInst, vd, vn, vm, false);
1175 } else {
1176 return decodeVfpRegRegRegOp<VmulD>(
1177 machInst, vd, vn, vm, true);
1178 }
1179 } else {
1180 if (single) {
1181 return decodeVfpRegRegRegOp<VnmulS>(
1182 machInst, vd, vn, vm, false);
1183 } else {
1184 return decodeVfpRegRegRegOp<VnmulD>(
1185 machInst, vd, vn, vm, true);
1186 }
1187 }
1188 case 0x3:
1189 if ((opc3 & 0x1) == 0) {
1190 if (single) {
1191 return decodeVfpRegRegRegOp<VaddS>(
1192 machInst, vd, vn, vm, false);
1193 } else {
1194 return decodeVfpRegRegRegOp<VaddD>(
1195 machInst, vd, vn, vm, true);
1196 }
1197 } else {
1198 if (single) {
1199 return decodeVfpRegRegRegOp<VsubS>(
1200 machInst, vd, vn, vm, false);
1201 } else {
1202 return decodeVfpRegRegRegOp<VsubD>(
1203 machInst, vd, vn, vm, true);
1204 }
1205 }
1206 case 0x8:
1207 if ((opc3 & 0x1) == 0) {
1208 if (single) {
1209 return decodeVfpRegRegRegOp<VdivS>(
1210 machInst, vd, vn, vm, false);
1211 } else {
1212 return decodeVfpRegRegRegOp<VdivD>(
1213 machInst, vd, vn, vm, true);
1214 }
1215 }
1216 break;
1217 case 0xb:
1218 if ((opc3 & 0x1) == 0) {
1219 const uint32_t baseImm =
1220 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
1221 if (single) {
1222 uint32_t imm = vfp_modified_imm(baseImm, false);
1223 return decodeVfpRegImmOp<VmovImmS>(
1224 machInst, vd, imm, false);
1225 } else {
1226 uint64_t imm = vfp_modified_imm(baseImm, true);
1227 return decodeVfpRegImmOp<VmovImmD>(
1228 machInst, vd, imm, true);
1229 }
1230 }
1231 switch (opc2) {
1232 case 0x0:
1233 if (opc3 == 1) {
1234 if (single) {
1235 return decodeVfpRegRegOp<VmovRegS>(
1236 machInst, vd, vm, false);
1237 } else {
1238 return decodeVfpRegRegOp<VmovRegD>(
1239 machInst, vd, vm, true);
1240 }
1241 } else {
1242 if (single) {
1243 return decodeVfpRegRegOp<VabsS>(
1244 machInst, vd, vm, false);
1245 } else {
1246 return decodeVfpRegRegOp<VabsD>(
1247 machInst, vd, vm, true);
1248 }
1249 }
1250 case 0x1:
1251 if (opc3 == 1) {
1252 if (single) {
1253 return decodeVfpRegRegOp<VnegS>(
1254 machInst, vd, vm, false);
1255 } else {
1256 return decodeVfpRegRegOp<VnegD>(
1257 machInst, vd, vm, true);
1258 }
1259 } else {
1260 if (single) {
1261 return decodeVfpRegRegOp<VsqrtS>(
1262 machInst, vd, vm, false);
1263 } else {
1264 return decodeVfpRegRegOp<VsqrtD>(
1265 machInst, vd, vm, true);
1266 }
1267 }
1268 case 0x2:
1269 case 0x3:
1270 {
1271 const bool toHalf = bits(machInst, 16);
1272 const bool top = bits(machInst, 7);
1273 if (top) {
1274 if (toHalf) {
1275 return new VcvtFpSFpHT(machInst, vd, vm);
1276 } else {
1277 return new VcvtFpHTFpS(machInst, vd, vm);
1278 }
1279 } else {
1280 if (toHalf) {
1281 return new VcvtFpSFpHB(machInst, vd, vm);
1282 } else {
1283 return new VcvtFpHBFpS(machInst, vd, vm);
1284 }
1285 }
1286 }
1287 case 0x4:
1288 if (single) {
1289 if (e) {
1290 return new VcmpeS(machInst, vd, vm);
1291 } else {
1292 return new VcmpS(machInst, vd, vm);
1293 }
1294 } else {
1295 if (e) {
1296 return new VcmpeD(machInst, vd, vm);
1297 } else {
1298 return new VcmpD(machInst, vd, vm);
1299 }
1300 }
1301 case 0x5:
1302 if (single) {
1303 if (e) {
1304 return new VcmpeZeroS(machInst, vd, 0);
1305 } else {
1306 return new VcmpZeroS(machInst, vd, 0);
1307 }
1308 } else {
1309 if (e) {
1310 return new VcmpeZeroD(machInst, vd, 0);
1311 } else {
1312 return new VcmpZeroD(machInst, vd, 0);
1313 }
1314 }
1315 case 0x7:
1316 if (opc3 == 0x3) {
1317 if (single) {
1318 vm = (IntRegIndex)(bits(machInst, 5) |
1319 (bits(machInst, 3, 0) << 1));
1320 return new VcvtFpSFpD(machInst, vd, vm);
1321 } else {
1322 vd = (IntRegIndex)(bits(machInst, 22) |
1323 (bits(machInst, 15, 12) << 1));
1324 return new VcvtFpDFpS(machInst, vd, vm);
1325 }
1326 }
1327 break;
1328 case 0x8:
1329 if (bits(machInst, 7) == 0) {
1330 if (single) {
1331 return new VcvtUIntFpS(machInst, vd, vm);
1332 } else {
1333 vm = (IntRegIndex)(bits(machInst, 5) |
1334 (bits(machInst, 3, 0) << 1));
1335 return new VcvtUIntFpD(machInst, vd, vm);
1336 }
1337 } else {
1338 if (single) {
1339 return new VcvtSIntFpS(machInst, vd, vm);
1340 } else {
1341 vm = (IntRegIndex)(bits(machInst, 5) |
1342 (bits(machInst, 3, 0) << 1));
1343 return new VcvtSIntFpD(machInst, vd, vm);
1344 }
1345 }
1346 case 0xa:
1347 {
1348 const bool half = (bits(machInst, 7) == 0);
1349 const uint32_t imm = bits(machInst, 5) |
1350 (bits(machInst, 3, 0) << 1);
1351 const uint32_t size =
1352 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1353 if (single) {
1354 if (half) {
1355 return new VcvtSHFixedFpS(machInst, vd, vd, size);
1356 } else {
1357 return new VcvtSFixedFpS(machInst, vd, vd, size);
1358 }
1359 } else {
1360 if (half) {
1361 return new VcvtSHFixedFpD(machInst, vd, vd, size);
1362 } else {
1363 return new VcvtSFixedFpD(machInst, vd, vd, size);
1364 }
1365 }
1366 }
1367 case 0xb:
1368 {
1369 const bool half = (bits(machInst, 7) == 0);
1370 const uint32_t imm = bits(machInst, 5) |
1371 (bits(machInst, 3, 0) << 1);
1372 const uint32_t size =
1373 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1374 if (single) {
1375 if (half) {
1376 return new VcvtUHFixedFpS(machInst, vd, vd, size);
1377 } else {
1378 return new VcvtUFixedFpS(machInst, vd, vd, size);
1379 }
1380 } else {
1381 if (half) {
1382 return new VcvtUHFixedFpD(machInst, vd, vd, size);
1383 } else {
1384 return new VcvtUFixedFpD(machInst, vd, vd, size);
1385 }
1386 }
1387 }
1388 case 0xc:
1389 if (bits(machInst, 7) == 0) {
1390 if (single) {
1391 return new VcvtFpUIntSR(machInst, vd, vm);
1392 } else {
1393 vd = (IntRegIndex)(bits(machInst, 22) |
1394 (bits(machInst, 15, 12) << 1));
1395 return new VcvtFpUIntDR(machInst, vd, vm);
1396 }
1397 } else {
1398 if (single) {
1399 return new VcvtFpUIntS(machInst, vd, vm);
1400 } else {
1401 vd = (IntRegIndex)(bits(machInst, 22) |
1402 (bits(machInst, 15, 12) << 1));
1403 return new VcvtFpUIntD(machInst, vd, vm);
1404 }
1405 }
1406 case 0xd:
1407 if (bits(machInst, 7) == 0) {
1408 if (single) {
1409 return new VcvtFpSIntSR(machInst, vd, vm);
1410 } else {
1411 vd = (IntRegIndex)(bits(machInst, 22) |
1412 (bits(machInst, 15, 12) << 1));
1413 return new VcvtFpSIntDR(machInst, vd, vm);
1414 }
1415 } else {
1416 if (single) {
1417 return new VcvtFpSIntS(machInst, vd, vm);
1418 } else {
1419 vd = (IntRegIndex)(bits(machInst, 22) |
1420 (bits(machInst, 15, 12) << 1));
1421 return new VcvtFpSIntD(machInst, vd, vm);
1422 }
1423 }
1424 case 0xe:
1425 {
1426 const bool half = (bits(machInst, 7) == 0);
1427 const uint32_t imm = bits(machInst, 5) |
1428 (bits(machInst, 3, 0) << 1);
1429 const uint32_t size =
1430 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1431 if (single) {
1432 if (half) {
1433 return new VcvtFpSHFixedS(machInst, vd, vd, size);
1434 } else {
1435 return new VcvtFpSFixedS(machInst, vd, vd, size);
1436 }
1437 } else {
1438 if (half) {
1439 return new VcvtFpSHFixedD(machInst, vd, vd, size);
1440 } else {
1441 return new VcvtFpSFixedD(machInst, vd, vd, size);
1442 }
1443 }
1444 }
1445 case 0xf:
1446 {
1447 const bool half = (bits(machInst, 7) == 0);
1448 const uint32_t imm = bits(machInst, 5) |
1449 (bits(machInst, 3, 0) << 1);
1450 const uint32_t size =
1451 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1452 if (single) {
1453 if (half) {
1454 return new VcvtFpUHFixedS(machInst, vd, vd, size);
1455 } else {
1456 return new VcvtFpUFixedS(machInst, vd, vd, size);
1457 }
1458 } else {
1459 if (half) {
1460 return new VcvtFpUHFixedD(machInst, vd, vd, size);
1461 } else {
1462 return new VcvtFpUFixedD(machInst, vd, vd, size);
1463 }
1464 }
1465 }
1466 }
1467 break;
1468 }
1469 return new Unknown(machInst);
1470 }
1471 '''
1472}};
1473
1474def format VfpData() {{
1475 decode_block = '''
1476 return decodeVfpData(machInst);
1477 '''
1478}};
175 }
176 '''
177
178 decoder_output += '''
179 static StaticInstPtr
180 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
181 {
182 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
183 const uint32_t a = bits(machInst, 11, 8);
184 const bool b = bits(machInst, 4);
185 const uint32_t c = bits(machInst, 21, 20);
186 switch (a) {
187 case 0x0:
188 if (b) {
189 if (bits(machInst, 9) == 0) {
190 return new WarnUnimplemented("vhadd", machInst);
191 } else {
192 return new WarnUnimplemented("vhsub", machInst);
193 }
194 } else {
195 return new WarnUnimplemented("vqadd", machInst);
196 }
197 case 0x1:
198 if (!b) {
199 return new WarnUnimplemented("vrhadd", machInst);
200 } else {
201 if (u) {
202 switch (c) {
203 case 0:
204 return new WarnUnimplemented("veor", machInst);
205 case 1:
206 return new WarnUnimplemented("vbsl", machInst);
207 case 2:
208 return new WarnUnimplemented("vbit", machInst);
209 case 3:
210 return new WarnUnimplemented("vbif", machInst);
211 }
212 } else {
213 switch (c) {
214 case 0:
215 return new WarnUnimplemented("vand (reg)", machInst);
216 case 1:
217 return new WarnUnimplemented("vbic (reg)", machInst);
218 case 2:
219 {
220 const IntRegIndex n = (IntRegIndex)(
221 (uint32_t)bits(machInst, 19, 16) |
222 (uint32_t)(bits(machInst, 7) << 4));
223 const IntRegIndex m = (IntRegIndex)(
224 (uint32_t)bits(machInst, 3, 0) |
225 (uint32_t)(bits(machInst, 5) << 4));
226 if (n == m) {
227 return new WarnUnimplemented("vmov (reg)",
228 machInst);
229 } else {
230 return new WarnUnimplemented("vorr (reg)",
231 machInst);
232 }
233 }
234 case 3:
235 return new WarnUnimplemented("vorn (reg)", machInst);
236 }
237 }
238 }
239 case 0x2:
240 if (b) {
241 return new WarnUnimplemented("vqsub", machInst);
242 } else {
243 if (bits(machInst, 9) == 0) {
244 return new WarnUnimplemented("vhadd", machInst);
245 } else {
246 return new WarnUnimplemented("vhsub", machInst);
247 }
248 }
249 case 0x3:
250 if (b) {
251 return new WarnUnimplemented("vcge (reg)", machInst);
252 } else {
253 return new WarnUnimplemented("vcgt (reg)", machInst);
254 }
255 case 0x4:
256 if (b) {
257 return new WarnUnimplemented("vqshl (reg)", machInst);
258 } else {
259 return new WarnUnimplemented("vshl (reg)", machInst);
260 }
261 case 0x5:
262 if (b) {
263 return new WarnUnimplemented("vqrshl", machInst);
264 } else {
265 return new WarnUnimplemented("vrshl", machInst);
266 }
267 case 0x6:
268 if (b) {
269 return new WarnUnimplemented("vmin (int)", machInst);
270 } else {
271 return new WarnUnimplemented("vmax (int)", machInst);
272 }
273 case 0x7:
274 if (b) {
275 return new WarnUnimplemented("vaba", machInst);
276 } else {
277 if (bits(machInst, 23) == 1) {
278 if (bits(machInst, 6) == 1) {
279 return new Unknown(machInst);
280 } else {
281 return new WarnUnimplemented("vabdl (int)", machInst);
282 }
283 } else {
284 return new WarnUnimplemented("vabd (int)", machInst);
285 }
286 }
287 case 0x8:
288 if (b) {
289 if (u) {
290 return new WarnUnimplemented("vceq (reg)", machInst);
291 } else {
292 return new WarnUnimplemented("vtst", machInst);
293 }
294 } else {
295 if (u) {
296 return new WarnUnimplemented("vsub (int)", machInst);
297 } else {
298 return new WarnUnimplemented("vadd (int)", machInst);
299 }
300 }
301 case 0x9:
302 if (b) {
303 if (u) {
304 return new WarnUnimplemented("vmul (poly)", machInst);
305 } else {
306 return new WarnUnimplemented("vmul (int)", machInst);
307 }
308 } else {
309 if (u) {
310 return new WarnUnimplemented("vmls (int)", machInst);
311 } else {
312 return new WarnUnimplemented("vmla (int)", machInst);
313 }
314 }
315 case 0xa:
316 if (b) {
317 return new WarnUnimplemented("vpmin (int)", machInst);
318 } else {
319 return new WarnUnimplemented("vpmax (int)", machInst);
320 }
321 case 0xb:
322 if (b) {
323 if (u) {
324 return new Unknown(machInst);
325 } else {
326 return new WarnUnimplemented("vpadd (int)", machInst);
327 }
328 } else {
329 if (u) {
330 return new WarnUnimplemented("vqrdmulh", machInst);
331 } else {
332 return new WarnUnimplemented("vqdmulh", machInst);
333 }
334 }
335 case 0xc:
336 return new Unknown(machInst);
337 case 0xd:
338 if (b) {
339 if (u) {
340 if (bits(c, 1) == 0) {
341 return new WarnUnimplemented("vmul (fp)", machInst);
342 } else {
343 return new Unknown(machInst);
344 }
345 } else {
346 if (bits(c, 1) == 0) {
347 return new WarnUnimplemented("vmla (fp)", machInst);
348 } else {
349 return new WarnUnimplemented("vmls (fp)", machInst);
350 }
351 }
352 } else {
353 if (u) {
354 if (bits(c, 1) == 0) {
355 return new WarnUnimplemented("vpadd (fp)", machInst);
356 } else {
357 return new WarnUnimplemented("vabd (fp)", machInst);
358 }
359 } else {
360 if (bits(c, 1) == 0) {
361 return new WarnUnimplemented("vadd (fp)", machInst);
362 } else {
363 return new WarnUnimplemented("vsub (fp)", machInst);
364 }
365 }
366 }
367 case 0xe:
368 if (b) {
369 if (u) {
370 if (bits(c, 1) == 0) {
371 return new WarnUnimplemented("vacge", machInst);
372 } else {
373 return new WarnUnimplemented("vacgt", machInst);
374 }
375 } else {
376 return new Unknown(machInst);
377 }
378 } else {
379 if (u) {
380 if (bits(c, 1) == 0) {
381 return new WarnUnimplemented("vcge (reg)", machInst);
382 } else {
383 return new WarnUnimplemented("vcgt (reg)", machInst);
384 }
385 } else {
386 if (bits(c, 1) == 0) {
387 return new WarnUnimplemented("vceq (reg)", machInst);
388 } else {
389 return new Unknown(machInst);
390 }
391 }
392 }
393 case 0xf:
394 if (b) {
395 if (u) {
396 return new Unknown(machInst);
397 } else {
398 if (bits(c, 1) == 0) {
399 return new WarnUnimplemented("vrecps", machInst);
400 } else {
401 return new WarnUnimplemented("vrsqrts", machInst);
402 }
403 }
404 } else {
405 if (u) {
406 if (bits(c, 1) == 0) {
407 return new WarnUnimplemented("vpmax (fp)", machInst);
408 } else {
409 return new WarnUnimplemented("vpmin (fp)", machInst);
410 }
411 } else {
412 if (bits(c, 1) == 0) {
413 return new WarnUnimplemented("vmax (fp)", machInst);
414 } else {
415 return new WarnUnimplemented("vmin (fp)", machInst);
416 }
417 }
418 }
419 }
420 return new Unknown(machInst);
421 }
422
423 static StaticInstPtr
424 decodeNeonOneRegModImm(ExtMachInst machInst)
425 {
426 const bool op = bits(machInst, 5);
427 const uint32_t cmode = bits(machInst, 11, 8);
428 if (op) {
429 if (bits(cmode, 3) == 0) {
430 if (bits(cmode, 0) == 0) {
431 return new WarnUnimplemented("vmov (imm)", machInst);
432 } else {
433 return new WarnUnimplemented("vorr (imm)", machInst);
434 }
435 } else {
436 if (bits(cmode, 2) == 1) {
437 return new WarnUnimplemented("vmov (imm)", machInst);
438 } else {
439 if (bits(cmode, 0) == 0) {
440 return new WarnUnimplemented("vmov (imm)", machInst);
441 } else {
442 return new WarnUnimplemented("vorr (imm)", machInst);
443 }
444 }
445 }
446 } else {
447 if (bits(cmode, 3) == 0) {
448 if (bits(cmode, 0) == 0) {
449 return new WarnUnimplemented("vmvn (imm)", machInst);
450 } else {
451 return new WarnUnimplemented("vbic (imm)", machInst);
452 }
453 } else {
454 if (bits(cmode, 2) == 1) {
455 switch (bits(cmode, 1, 0)) {
456 case 0:
457 case 1:
458 return new WarnUnimplemented("vmvn (imm)", machInst);
459 case 2:
460 return new WarnUnimplemented("vmov (imm)", machInst);
461 case 3:
462 return new Unknown(machInst);
463 }
464 return new WarnUnimplemented("vmov (imm)", machInst);
465 } else {
466 if (bits(cmode, 0) == 0) {
467 return new WarnUnimplemented("vmvn (imm)", machInst);
468 } else {
469 return new WarnUnimplemented("vbic (imm)", machInst);
470 }
471 }
472 }
473 }
474 return new Unknown(machInst);
475 }
476
477 static StaticInstPtr
478 decodeNeonTwoRegAndShift(ExtMachInst machInst)
479 {
480 const uint32_t a = bits(machInst, 11, 8);
481 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
482 const bool b = bits(machInst, 6);
483 const bool l = bits(machInst, 7);
484
485 switch (a) {
486 case 0x0:
487 return new WarnUnimplemented("vshr", machInst);
488 case 0x1:
489 return new WarnUnimplemented("vsra", machInst);
490 case 0x2:
491 return new WarnUnimplemented("vrshr", machInst);
492 case 0x3:
493 return new WarnUnimplemented("vrsra", machInst);
494 case 0x4:
495 if (u) {
496 return new WarnUnimplemented("vsri", machInst);
497 } else {
498 return new Unknown(machInst);
499 }
500 case 0x5:
501 if (u) {
502 return new WarnUnimplemented("vsli", machInst);
503 } else {
504 return new WarnUnimplemented("vshl (imm)", machInst);
505 }
506 case 0x6:
507 case 0x7:
508 return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
509 case 0x8:
510 if (l) {
511 return new Unknown(machInst);
512 } else if (u) {
513 if (b) {
514 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
515 } else {
516 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
517 }
518 } else {
519 if (b) {
520 return new WarnUnimplemented("vrshrn", machInst);
521 } else {
522 return new WarnUnimplemented("vshrn", machInst);
523 }
524 }
525 case 0x9:
526 if (l) {
527 return new Unknown(machInst);
528 } else if (b) {
529 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
530 } else {
531 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
532 }
533 case 0xa:
534 if (l || b) {
535 return new Unknown(machInst);
536 } else {
537 // If the shift amount is zero, it's vmovl.
538 return new WarnUnimplemented("vshll, vmovl", machInst);
539 }
540 case 0xe:
541 case 0xf:
542 if (l) {
543 return new Unknown(machInst);
544 } else if (a == 0xe) {
545 return new WarnUnimplemented("vcvt (fixed to fp)", machInst);
546 } else if (a == 0xf) {
547 return new WarnUnimplemented("vcvt (fp to fixed)", machInst);
548 }
549 }
550 return new Unknown(machInst);
551 }
552
553 static StaticInstPtr
554 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
555 {
556 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
557 const uint32_t a = bits(machInst, 11, 8);
558
559 switch (a) {
560 case 0x0:
561 return new WarnUnimplemented("vaddl", machInst);
562 case 0x1:
563 return new WarnUnimplemented("vaddw", machInst);
564 case 0x2:
565 return new WarnUnimplemented("vsubl", machInst);
566 case 0x3:
567 return new WarnUnimplemented("vsubw", machInst);
568 case 0x4:
569 if (u) {
570 return new WarnUnimplemented("vraddhn", machInst);
571 } else {
572 return new WarnUnimplemented("vaddhn", machInst);
573 }
574 case 0x5:
575 return new WarnUnimplemented("vabal", machInst);
576 case 0x6:
577 if (u) {
578 return new WarnUnimplemented("vrsubhn", machInst);
579 } else {
580 return new WarnUnimplemented("vsubhn", machInst);
581 }
582 case 0x7:
583 if (bits(machInst, 23)) {
584 return new WarnUnimplemented("vabdl (int)", machInst);
585 } else {
586 return new WarnUnimplemented("vabd (int)", machInst);
587 }
588 case 0x8:
589 return new WarnUnimplemented("vmlal (int)", machInst);
590 case 0xa:
591 return new WarnUnimplemented("vmlsl (int)", machInst);
592 case 0x9:
593 if (bits(machInst, 23) == 0) {
594 if (bits(machInst, 4) == 0) {
595 if (u) {
596 return new WarnUnimplemented("vmls (int)", machInst);
597 } else {
598 return new WarnUnimplemented("vmla (int)", machInst);
599 }
600 } else {
601 if (u) {
602 return new WarnUnimplemented("vmul (poly)", machInst);
603 } else {
604 return new WarnUnimplemented("vmul (int)", machInst);
605 }
606 }
607 } else {
608 return new WarnUnimplemented("vqdmlal", machInst);
609 }
610 case 0xb:
611 if (!u) {
612 return new Unknown(machInst);
613 } else {
614 return new WarnUnimplemented("vqdmlsl", machInst);
615 }
616 case 0xc:
617 return new WarnUnimplemented("vmull (int)", machInst);
618 case 0xd:
619 if (!u) {
620 return new Unknown(machInst);
621 } else {
622 return new WarnUnimplemented("vqdmull", machInst);
623 }
624 case 0xe:
625 return new WarnUnimplemented("vmull (poly)", machInst);
626 }
627 return new Unknown(machInst);
628 }
629
630 static StaticInstPtr
631 decodeNeonTwoRegScalar(ExtMachInst machInst)
632 {
633 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
634 const uint32_t a = bits(machInst, 11, 8);
635
636 switch (a) {
637 case 0x0:
638 return new WarnUnimplemented("vmla (int scalar)", machInst);
639 case 0x1:
640 return new WarnUnimplemented("vmla (fp scalar)", machInst);
641 case 0x4:
642 return new WarnUnimplemented("vmls (int scalar)", machInst);
643 case 0x5:
644 return new WarnUnimplemented("vmls (fp scalar)", machInst);
645 case 0x2:
646 return new WarnUnimplemented("vmlal (scalar)", machInst);
647 case 0x6:
648 return new WarnUnimplemented("vmlsl (scalar)", machInst);
649 case 0x3:
650 if (u) {
651 return new Unknown(machInst);
652 } else {
653 return new WarnUnimplemented("vqdmlal", machInst);
654 }
655 case 0x7:
656 if (u) {
657 return new Unknown(machInst);
658 } else {
659 return new WarnUnimplemented("vqdmlsl", machInst);
660 }
661 case 0x8:
662 return new WarnUnimplemented("vmul (int scalar)", machInst);
663 case 0x9:
664 return new WarnUnimplemented("vmul (fp scalar)", machInst);
665 case 0xa:
666 return new WarnUnimplemented("vmull (scalar)", machInst);
667 case 0xb:
668 if (u) {
669 return new Unknown(machInst);
670 } else {
671 return new WarnUnimplemented("vqdmull", machInst);
672 }
673 case 0xc:
674 return new WarnUnimplemented("vqdmulh", machInst);
675 case 0xd:
676 return new WarnUnimplemented("vqrdmulh", machInst);
677 }
678 return new Unknown(machInst);
679 }
680
681 static StaticInstPtr
682 decodeNeonTwoRegMisc(ExtMachInst machInst)
683 {
684 const uint32_t a = bits(machInst, 17, 16);
685 const uint32_t b = bits(machInst, 10, 6);
686 switch (a) {
687 case 0x0:
688 switch (bits(b, 4, 1)) {
689 case 0x0:
690 return new WarnUnimplemented("vrev64", machInst);
691 case 0x1:
692 return new WarnUnimplemented("vrev32", machInst);
693 case 0x2:
694 return new WarnUnimplemented("vrev16", machInst);
695 case 0x4:
696 case 0x5:
697 return new WarnUnimplemented("vpaddl", machInst);
698 case 0x8:
699 return new WarnUnimplemented("vcls", machInst);
700 case 0x9:
701 return new WarnUnimplemented("vclz", machInst);
702 case 0xa:
703 return new WarnUnimplemented("vcnt", machInst);
704 case 0xb:
705 return new WarnUnimplemented("vmvn (reg)", machInst);
706 case 0xc:
707 case 0xd:
708 return new WarnUnimplemented("vpadal", machInst);
709 case 0xe:
710 return new WarnUnimplemented("vqabs", machInst);
711 case 0xf:
712 return new WarnUnimplemented("vqneg", machInst);
713 default:
714 return new Unknown(machInst);
715 }
716 case 0x1:
717 switch (bits(b, 3, 1)) {
718 case 0x0:
719 return new WarnUnimplemented("vcgt (imm #0)", machInst);
720 case 0x1:
721 return new WarnUnimplemented("vcge (imm #0)", machInst);
722 case 0x2:
723 return new WarnUnimplemented("vceq (imm #0)", machInst);
724 case 0x3:
725 return new WarnUnimplemented("vcle (imm #0)", machInst);
726 case 0x4:
727 return new WarnUnimplemented("vclt (imm #0)", machInst);
728 case 0x6:
729 return new WarnUnimplemented("vabs (imm #0)", machInst);
730 case 0x7:
731 return new WarnUnimplemented("vneg (imm #0)", machInst);
732 }
733 case 0x2:
734 switch (bits(b, 4, 1)) {
735 case 0x0:
736 return new WarnUnimplemented("vswp", machInst);
737 case 0x1:
738 return new WarnUnimplemented("vtrn", machInst);
739 case 0x2:
740 return new WarnUnimplemented("vuzp", machInst);
741 case 0x3:
742 return new WarnUnimplemented("vzip", machInst);
743 case 0x4:
744 if (b == 0x8) {
745 return new WarnUnimplemented("vmovn", machInst);
746 } else {
747 return new WarnUnimplemented("vqmovun", machInst);
748 }
749 case 0x5:
750 return new WarnUnimplemented("vqmovn", machInst);
751 case 0x6:
752 if (b == 0xc) {
753 return new WarnUnimplemented("vshll", machInst);
754 } else {
755 return new Unknown(machInst);
756 }
757 case 0xc:
758 case 0xe:
759 if (b == 0x18) {
760 return new WarnUnimplemented("vcvt (single to half)",
761 machInst);
762 } else if (b == 0x1c) {
763 return new WarnUnimplemented("vcvt (half to single)",
764 machInst);
765 } else {
766 return new Unknown(machInst);
767 }
768 default:
769 return new Unknown(machInst);
770 }
771 case 0x3:
772 if (bits(b, 4, 3) == 0x3) {
773 return new WarnUnimplemented("vcvt (fp and int)", machInst);
774 } else if ((b & 0x1a) == 0x10) {
775 return new WarnUnimplemented("vrecpe", machInst);
776 } else if ((b & 0x1a) == 0x12) {
777 return new WarnUnimplemented("vrsqrte", machInst);
778 } else {
779 return new Unknown(machInst);
780 }
781 }
782 return new Unknown(machInst);
783 }
784
785 StaticInstPtr
786 decodeNeonData(ExtMachInst machInst)
787 {
788 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
789 const uint32_t a = bits(machInst, 23, 19);
790 const uint32_t b = bits(machInst, 11, 8);
791 const uint32_t c = bits(machInst, 7, 4);
792 if (bits(a, 4) == 0) {
793 return decodeNeonThreeRegistersSameLength(machInst);
794 } else if ((c & 0x9) == 1) {
795 if ((a & 0x7) == 0) {
796 return decodeNeonOneRegModImm(machInst);
797 } else {
798 return decodeNeonTwoRegAndShift(machInst);
799 }
800 } else if ((c & 0x9) == 9) {
801 return decodeNeonTwoRegAndShift(machInst);
802 } else if ((c & 0x5) == 0) {
803 if (bits(a, 3, 2) != 0x3) {
804 return decodeNeonThreeRegDiffLengths(machInst);
805 }
806 } else if ((c & 0x5) == 4) {
807 if (bits(a, 3, 2) != 0x3) {
808 return decodeNeonTwoRegScalar(machInst);
809 }
810 } else if ((a & 0x16) == 0x16) {
811 if (!u) {
812 if (bits(c, 0) == 0) {
813 return new WarnUnimplemented("vext", machInst);
814 }
815 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
816 return decodeNeonTwoRegMisc(machInst);
817 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
818 if (bits(machInst, 6) == 0) {
819 return new WarnUnimplemented("vtbl", machInst);
820 } else {
821 return new WarnUnimplemented("vtbx", machInst);
822 }
823 } else if (b == 0xc && (c & 0x9) == 0) {
824 return new WarnUnimplemented("vdup (scalar)", machInst);
825 }
826 }
827 return new Unknown(machInst);
828 }
829 '''
830}};
831
832def format ThumbNeonMem() {{
833 decode_block = '''
834 return decodeNeonMem(machInst);
835 '''
836}};
837
838def format ThumbNeonData() {{
839 decode_block = '''
840 return decodeNeonMem(machInst);
841 '''
842}};
843
844let {{
845 header_output = '''
846 StaticInstPtr
847 decodeExtensionRegLoadStore(ExtMachInst machInst);
848 '''
849 decoder_output = '''
850 StaticInstPtr
851 decodeExtensionRegLoadStore(ExtMachInst machInst)
852 {
853 const uint32_t opcode = bits(machInst, 24, 20);
854 const uint32_t offset = bits(machInst, 7, 0);
855 const bool single = (bits(machInst, 8) == 0);
856 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
857 RegIndex vd;
858 if (single) {
859 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
860 bits(machInst, 22));
861 } else {
862 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
863 (bits(machInst, 22) << 5));
864 }
865 switch (bits(opcode, 4, 3)) {
866 case 0x0:
867 if (bits(opcode, 4, 1) == 0x2 &&
868 !(machInst.thumb == 1 && bits(machInst, 28) == 1) &&
869 !(machInst.thumb == 0 && machInst.condCode == 0xf)) {
870 if ((bits(machInst, 7, 4) & 0xd) != 1) {
871 break;
872 }
873 const IntRegIndex rt =
874 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
875 const IntRegIndex rt2 =
876 (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
877 const bool op = bits(machInst, 20);
878 uint32_t vm;
879 if (single) {
880 vm = (bits(machInst, 3, 0) << 1) | bits(machInst, 5);
881 } else {
882 vm = (bits(machInst, 3, 0) << 1) |
883 (bits(machInst, 5) << 5);
884 }
885 if (op) {
886 return new Vmov2Core2Reg(machInst, rt, rt2,
887 (IntRegIndex)vm);
888 } else {
889 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
890 rt, rt2);
891 }
892 }
893 break;
894 case 0x1:
895 {
896 if (offset == 0 || vd + offset > NumFloatArchRegs) {
897 break;
898 }
899 switch (bits(opcode, 1, 0)) {
900 case 0x0:
901 return new VLdmStm(machInst, rn, vd, single,
902 true, false, false, offset);
903 case 0x1:
904 return new VLdmStm(machInst, rn, vd, single,
905 true, false, true, offset);
906 case 0x2:
907 return new VLdmStm(machInst, rn, vd, single,
908 true, true, false, offset);
909 case 0x3:
910 // If rn == sp, then this is called vpop.
911 return new VLdmStm(machInst, rn, vd, single,
912 true, true, true, offset);
913 }
914 }
915 case 0x2:
916 if (bits(opcode, 1, 0) == 0x2) {
917 // If rn == sp, then this is called vpush.
918 return new VLdmStm(machInst, rn, vd, single,
919 false, true, false, offset);
920 } else if (bits(opcode, 1, 0) == 0x3) {
921 return new VLdmStm(machInst, rn, vd, single,
922 false, true, true, offset);
923 }
924 // Fall through on purpose
925 case 0x3:
926 const bool up = (bits(machInst, 23) == 1);
927 const uint32_t imm = bits(machInst, 7, 0) << 2;
928 RegIndex vd;
929 if (single) {
930 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
931 (bits(machInst, 22)));
932 } else {
933 vd = (RegIndex)(uint32_t)((bits(machInst, 15, 12) << 1) |
934 (bits(machInst, 22) << 5));
935 }
936 if (bits(opcode, 1, 0) == 0x0) {
937 if (single) {
938 if (up) {
939 return new %(vstr_us)s(machInst, vd, rn, up, imm);
940 } else {
941 return new %(vstr_s)s(machInst, vd, rn, up, imm);
942 }
943 } else {
944 if (up) {
945 return new %(vstr_ud)s(machInst, vd, vd + 1,
946 rn, up, imm);
947 } else {
948 return new %(vstr_d)s(machInst, vd, vd + 1,
949 rn, up, imm);
950 }
951 }
952 } else if (bits(opcode, 1, 0) == 0x1) {
953 if (single) {
954 if (up) {
955 return new %(vldr_us)s(machInst, vd, rn, up, imm);
956 } else {
957 return new %(vldr_s)s(machInst, vd, rn, up, imm);
958 }
959 } else {
960 if (up) {
961 return new %(vldr_ud)s(machInst, vd, vd + 1,
962 rn, up, imm);
963 } else {
964 return new %(vldr_d)s(machInst, vd, vd + 1,
965 rn, up, imm);
966 }
967 }
968 }
969 }
970 return new Unknown(machInst);
971 }
972 ''' % {
973 "vldr_us" : "VLDR_" + loadImmClassName(False, True, False),
974 "vldr_s" : "VLDR_" + loadImmClassName(False, False, False),
975 "vldr_ud" : "VLDR_" + loadDoubleImmClassName(False, True, False),
976 "vldr_d" : "VLDR_" + loadDoubleImmClassName(False, False, False),
977 "vstr_us" : "VSTR_" + storeImmClassName(False, True, False),
978 "vstr_s" : "VSTR_" + storeImmClassName(False, False, False),
979 "vstr_ud" : "VSTR_" + storeDoubleImmClassName(False, True, False),
980 "vstr_d" : "VSTR_" + storeDoubleImmClassName(False, False, False)
981 }
982}};
983
984def format ExtensionRegLoadStore() {{
985 decode_block = '''
986 return decodeExtensionRegLoadStore(machInst);
987 '''
988}};
989
990let {{
991 header_output = '''
992 StaticInstPtr
993 decodeShortFpTransfer(ExtMachInst machInst);
994 '''
995 decoder_output = '''
996 StaticInstPtr
997 decodeShortFpTransfer(ExtMachInst machInst)
998 {
999 const uint32_t l = bits(machInst, 20);
1000 const uint32_t c = bits(machInst, 8);
1001 const uint32_t a = bits(machInst, 23, 21);
1002 const uint32_t b = bits(machInst, 6, 5);
1003 if ((machInst.thumb == 1 && bits(machInst, 28) == 1) ||
1004 (machInst.thumb == 0 && machInst.condCode == 0xf)) {
1005 return new Unknown(machInst);
1006 }
1007 if (l == 0 && c == 0) {
1008 if (a == 0) {
1009 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1010 bits(machInst, 7);
1011 const IntRegIndex rt =
1012 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1013 if (bits(machInst, 20) == 1) {
1014 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1015 } else {
1016 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1017 }
1018 } else if (a == 0x7) {
1019 const IntRegIndex rt =
1020 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1021 uint32_t specReg = bits(machInst, 19, 16);
1022 switch (specReg) {
1023 case 0:
1024 specReg = MISCREG_FPSID;
1025 break;
1026 case 1:
1027 specReg = MISCREG_FPSCR;
1028 break;
1029 case 6:
1030 specReg = MISCREG_MVFR1;
1031 break;
1032 case 7:
1033 specReg = MISCREG_MVFR0;
1034 break;
1035 case 8:
1036 specReg = MISCREG_FPEXC;
1037 break;
1038 default:
1039 return new Unknown(machInst);
1040 }
1041 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1042 }
1043 } else if (l == 0 && c == 1) {
1044 if (bits(a, 2) == 0) {
1045 uint32_t vd = (bits(machInst, 7) << 5) |
1046 (bits(machInst, 19, 16) << 1);
1047 uint32_t index, size;
1048 const IntRegIndex rt =
1049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1050 if (bits(machInst, 22) == 1) {
1051 size = 8;
1052 index = (bits(machInst, 21) << 2) |
1053 bits(machInst, 6, 5);
1054 } else if (bits(machInst, 5) == 1) {
1055 size = 16;
1056 index = (bits(machInst, 21) << 1) |
1057 bits(machInst, 6);
1058 } else if (bits(machInst, 6) == 0) {
1059 size = 32;
1060 index = bits(machInst, 21);
1061 } else {
1062 return new Unknown(machInst);
1063 }
1064 if (index >= (32 / size)) {
1065 index -= (32 / size);
1066 vd++;
1067 }
1068 switch (size) {
1069 case 8:
1070 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1071 rt, index);
1072 case 16:
1073 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1074 rt, index);
1075 case 32:
1076 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
1077 }
1078 } else if (bits(b, 1) == 0) {
1079 // A8-594
1080 return new WarnUnimplemented("vdup", machInst);
1081 }
1082 } else if (l == 1 && c == 0) {
1083 if (a == 0) {
1084 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
1085 bits(machInst, 7);
1086 const IntRegIndex rt =
1087 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1088 if (bits(machInst, 20) == 1) {
1089 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vn);
1090 } else {
1091 return new VmovCoreRegW(machInst, (IntRegIndex)vn, rt);
1092 }
1093 } else if (a == 7) {
1094 const IntRegIndex rt =
1095 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1096 uint32_t specReg = bits(machInst, 19, 16);
1097 switch (specReg) {
1098 case 0:
1099 specReg = MISCREG_FPSID;
1100 break;
1101 case 1:
1102 specReg = MISCREG_FPSCR;
1103 break;
1104 case 6:
1105 specReg = MISCREG_MVFR1;
1106 break;
1107 case 7:
1108 specReg = MISCREG_MVFR0;
1109 break;
1110 case 8:
1111 specReg = MISCREG_FPEXC;
1112 break;
1113 default:
1114 return new Unknown(machInst);
1115 }
1116 if (rt == 0xf) {
1117 CPSR cpsrMask = 0;
1118 cpsrMask.n = 1;
1119 cpsrMask.z = 1;
1120 cpsrMask.c = 1;
1121 cpsrMask.v = 1;
1122 return new VmrsApsr(machInst, INTREG_CONDCODES,
1123 (IntRegIndex)specReg, (uint32_t)cpsrMask);
1124 } else {
1125 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
1126 }
1127 }
1128 } else {
1129 uint32_t vd = (bits(machInst, 7) << 5) |
1130 (bits(machInst, 19, 16) << 1);
1131 uint32_t index, size;
1132 const IntRegIndex rt =
1133 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1134 const bool u = (bits(machInst, 23) == 1);
1135 if (bits(machInst, 22) == 1) {
1136 size = 8;
1137 index = (bits(machInst, 21) << 2) |
1138 bits(machInst, 6, 5);
1139 } else if (bits(machInst, 5) == 1) {
1140 size = 16;
1141 index = (bits(machInst, 21) << 1) |
1142 bits(machInst, 6);
1143 } else if (bits(machInst, 6) == 0 && !u) {
1144 size = 32;
1145 index = bits(machInst, 21);
1146 } else {
1147 return new Unknown(machInst);
1148 }
1149 if (index >= (32 / size)) {
1150 index -= (32 / size);
1151 vd++;
1152 }
1153 switch (size) {
1154 case 8:
1155 if (u) {
1156 return new VmovRegCoreUB(machInst, rt,
1157 (IntRegIndex)vd, index);
1158 } else {
1159 return new VmovRegCoreSB(machInst, rt,
1160 (IntRegIndex)vd, index);
1161 }
1162 case 16:
1163 if (u) {
1164 return new VmovRegCoreUH(machInst, rt,
1165 (IntRegIndex)vd, index);
1166 } else {
1167 return new VmovRegCoreSH(machInst, rt,
1168 (IntRegIndex)vd, index);
1169 }
1170 case 32:
1171 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
1172 }
1173 }
1174 return new Unknown(machInst);
1175 }
1176 '''
1177}};
1178
1179def format ShortFpTransfer() {{
1180 decode_block = '''
1181 return decodeShortFpTransfer(machInst);
1182 '''
1183}};
1184
1185let {{
1186 header_output = '''
1187 StaticInstPtr
1188 decodeVfpData(ExtMachInst machInst);
1189 '''
1190 decoder_output = '''
1191 StaticInstPtr
1192 decodeVfpData(ExtMachInst machInst)
1193 {
1194 const uint32_t opc1 = bits(machInst, 23, 20);
1195 const uint32_t opc2 = bits(machInst, 19, 16);
1196 const uint32_t opc3 = bits(machInst, 7, 6);
1197 //const uint32_t opc4 = bits(machInst, 3, 0);
1198 const bool single = (bits(machInst, 8) == 0);
1199 // Used to select between vcmp and vcmpe.
1200 const bool e = (bits(machInst, 7) == 1);
1201 IntRegIndex vd;
1202 IntRegIndex vm;
1203 IntRegIndex vn;
1204 if (single) {
1205 vd = (IntRegIndex)(bits(machInst, 22) |
1206 (bits(machInst, 15, 12) << 1));
1207 vm = (IntRegIndex)(bits(machInst, 5) |
1208 (bits(machInst, 3, 0) << 1));
1209 vn = (IntRegIndex)(bits(machInst, 7) |
1210 (bits(machInst, 19, 16) << 1));
1211 } else {
1212 vd = (IntRegIndex)((bits(machInst, 22) << 5) |
1213 (bits(machInst, 15, 12) << 1));
1214 vm = (IntRegIndex)((bits(machInst, 5) << 5) |
1215 (bits(machInst, 3, 0) << 1));
1216 vn = (IntRegIndex)((bits(machInst, 7) << 5) |
1217 (bits(machInst, 19, 16) << 1));
1218 }
1219 switch (opc1 & 0xb /* 1011 */) {
1220 case 0x0:
1221 if (bits(machInst, 6) == 0) {
1222 if (single) {
1223 return decodeVfpRegRegRegOp<VmlaS>(
1224 machInst, vd, vn, vm, false);
1225 } else {
1226 return decodeVfpRegRegRegOp<VmlaD>(
1227 machInst, vd, vn, vm, true);
1228 }
1229 } else {
1230 if (single) {
1231 return decodeVfpRegRegRegOp<VmlsS>(
1232 machInst, vd, vn, vm, false);
1233 } else {
1234 return decodeVfpRegRegRegOp<VmlsD>(
1235 machInst, vd, vn, vm, true);
1236 }
1237 }
1238 case 0x1:
1239 if (bits(machInst, 6) == 1) {
1240 if (single) {
1241 return decodeVfpRegRegRegOp<VnmlaS>(
1242 machInst, vd, vn, vm, false);
1243 } else {
1244 return decodeVfpRegRegRegOp<VnmlaD>(
1245 machInst, vd, vn, vm, true);
1246 }
1247 } else {
1248 if (single) {
1249 return decodeVfpRegRegRegOp<VnmlsS>(
1250 machInst, vd, vn, vm, false);
1251 } else {
1252 return decodeVfpRegRegRegOp<VnmlsD>(
1253 machInst, vd, vn, vm, true);
1254 }
1255 }
1256 case 0x2:
1257 if ((opc3 & 0x1) == 0) {
1258 if (single) {
1259 return decodeVfpRegRegRegOp<VmulS>(
1260 machInst, vd, vn, vm, false);
1261 } else {
1262 return decodeVfpRegRegRegOp<VmulD>(
1263 machInst, vd, vn, vm, true);
1264 }
1265 } else {
1266 if (single) {
1267 return decodeVfpRegRegRegOp<VnmulS>(
1268 machInst, vd, vn, vm, false);
1269 } else {
1270 return decodeVfpRegRegRegOp<VnmulD>(
1271 machInst, vd, vn, vm, true);
1272 }
1273 }
1274 case 0x3:
1275 if ((opc3 & 0x1) == 0) {
1276 if (single) {
1277 return decodeVfpRegRegRegOp<VaddS>(
1278 machInst, vd, vn, vm, false);
1279 } else {
1280 return decodeVfpRegRegRegOp<VaddD>(
1281 machInst, vd, vn, vm, true);
1282 }
1283 } else {
1284 if (single) {
1285 return decodeVfpRegRegRegOp<VsubS>(
1286 machInst, vd, vn, vm, false);
1287 } else {
1288 return decodeVfpRegRegRegOp<VsubD>(
1289 machInst, vd, vn, vm, true);
1290 }
1291 }
1292 case 0x8:
1293 if ((opc3 & 0x1) == 0) {
1294 if (single) {
1295 return decodeVfpRegRegRegOp<VdivS>(
1296 machInst, vd, vn, vm, false);
1297 } else {
1298 return decodeVfpRegRegRegOp<VdivD>(
1299 machInst, vd, vn, vm, true);
1300 }
1301 }
1302 break;
1303 case 0xb:
1304 if ((opc3 & 0x1) == 0) {
1305 const uint32_t baseImm =
1306 bits(machInst, 3, 0) | (bits(machInst, 19, 16) << 4);
1307 if (single) {
1308 uint32_t imm = vfp_modified_imm(baseImm, false);
1309 return decodeVfpRegImmOp<VmovImmS>(
1310 machInst, vd, imm, false);
1311 } else {
1312 uint64_t imm = vfp_modified_imm(baseImm, true);
1313 return decodeVfpRegImmOp<VmovImmD>(
1314 machInst, vd, imm, true);
1315 }
1316 }
1317 switch (opc2) {
1318 case 0x0:
1319 if (opc3 == 1) {
1320 if (single) {
1321 return decodeVfpRegRegOp<VmovRegS>(
1322 machInst, vd, vm, false);
1323 } else {
1324 return decodeVfpRegRegOp<VmovRegD>(
1325 machInst, vd, vm, true);
1326 }
1327 } else {
1328 if (single) {
1329 return decodeVfpRegRegOp<VabsS>(
1330 machInst, vd, vm, false);
1331 } else {
1332 return decodeVfpRegRegOp<VabsD>(
1333 machInst, vd, vm, true);
1334 }
1335 }
1336 case 0x1:
1337 if (opc3 == 1) {
1338 if (single) {
1339 return decodeVfpRegRegOp<VnegS>(
1340 machInst, vd, vm, false);
1341 } else {
1342 return decodeVfpRegRegOp<VnegD>(
1343 machInst, vd, vm, true);
1344 }
1345 } else {
1346 if (single) {
1347 return decodeVfpRegRegOp<VsqrtS>(
1348 machInst, vd, vm, false);
1349 } else {
1350 return decodeVfpRegRegOp<VsqrtD>(
1351 machInst, vd, vm, true);
1352 }
1353 }
1354 case 0x2:
1355 case 0x3:
1356 {
1357 const bool toHalf = bits(machInst, 16);
1358 const bool top = bits(machInst, 7);
1359 if (top) {
1360 if (toHalf) {
1361 return new VcvtFpSFpHT(machInst, vd, vm);
1362 } else {
1363 return new VcvtFpHTFpS(machInst, vd, vm);
1364 }
1365 } else {
1366 if (toHalf) {
1367 return new VcvtFpSFpHB(machInst, vd, vm);
1368 } else {
1369 return new VcvtFpHBFpS(machInst, vd, vm);
1370 }
1371 }
1372 }
1373 case 0x4:
1374 if (single) {
1375 if (e) {
1376 return new VcmpeS(machInst, vd, vm);
1377 } else {
1378 return new VcmpS(machInst, vd, vm);
1379 }
1380 } else {
1381 if (e) {
1382 return new VcmpeD(machInst, vd, vm);
1383 } else {
1384 return new VcmpD(machInst, vd, vm);
1385 }
1386 }
1387 case 0x5:
1388 if (single) {
1389 if (e) {
1390 return new VcmpeZeroS(machInst, vd, 0);
1391 } else {
1392 return new VcmpZeroS(machInst, vd, 0);
1393 }
1394 } else {
1395 if (e) {
1396 return new VcmpeZeroD(machInst, vd, 0);
1397 } else {
1398 return new VcmpZeroD(machInst, vd, 0);
1399 }
1400 }
1401 case 0x7:
1402 if (opc3 == 0x3) {
1403 if (single) {
1404 vm = (IntRegIndex)(bits(machInst, 5) |
1405 (bits(machInst, 3, 0) << 1));
1406 return new VcvtFpSFpD(machInst, vd, vm);
1407 } else {
1408 vd = (IntRegIndex)(bits(machInst, 22) |
1409 (bits(machInst, 15, 12) << 1));
1410 return new VcvtFpDFpS(machInst, vd, vm);
1411 }
1412 }
1413 break;
1414 case 0x8:
1415 if (bits(machInst, 7) == 0) {
1416 if (single) {
1417 return new VcvtUIntFpS(machInst, vd, vm);
1418 } else {
1419 vm = (IntRegIndex)(bits(machInst, 5) |
1420 (bits(machInst, 3, 0) << 1));
1421 return new VcvtUIntFpD(machInst, vd, vm);
1422 }
1423 } else {
1424 if (single) {
1425 return new VcvtSIntFpS(machInst, vd, vm);
1426 } else {
1427 vm = (IntRegIndex)(bits(machInst, 5) |
1428 (bits(machInst, 3, 0) << 1));
1429 return new VcvtSIntFpD(machInst, vd, vm);
1430 }
1431 }
1432 case 0xa:
1433 {
1434 const bool half = (bits(machInst, 7) == 0);
1435 const uint32_t imm = bits(machInst, 5) |
1436 (bits(machInst, 3, 0) << 1);
1437 const uint32_t size =
1438 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1439 if (single) {
1440 if (half) {
1441 return new VcvtSHFixedFpS(machInst, vd, vd, size);
1442 } else {
1443 return new VcvtSFixedFpS(machInst, vd, vd, size);
1444 }
1445 } else {
1446 if (half) {
1447 return new VcvtSHFixedFpD(machInst, vd, vd, size);
1448 } else {
1449 return new VcvtSFixedFpD(machInst, vd, vd, size);
1450 }
1451 }
1452 }
1453 case 0xb:
1454 {
1455 const bool half = (bits(machInst, 7) == 0);
1456 const uint32_t imm = bits(machInst, 5) |
1457 (bits(machInst, 3, 0) << 1);
1458 const uint32_t size =
1459 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1460 if (single) {
1461 if (half) {
1462 return new VcvtUHFixedFpS(machInst, vd, vd, size);
1463 } else {
1464 return new VcvtUFixedFpS(machInst, vd, vd, size);
1465 }
1466 } else {
1467 if (half) {
1468 return new VcvtUHFixedFpD(machInst, vd, vd, size);
1469 } else {
1470 return new VcvtUFixedFpD(machInst, vd, vd, size);
1471 }
1472 }
1473 }
1474 case 0xc:
1475 if (bits(machInst, 7) == 0) {
1476 if (single) {
1477 return new VcvtFpUIntSR(machInst, vd, vm);
1478 } else {
1479 vd = (IntRegIndex)(bits(machInst, 22) |
1480 (bits(machInst, 15, 12) << 1));
1481 return new VcvtFpUIntDR(machInst, vd, vm);
1482 }
1483 } else {
1484 if (single) {
1485 return new VcvtFpUIntS(machInst, vd, vm);
1486 } else {
1487 vd = (IntRegIndex)(bits(machInst, 22) |
1488 (bits(machInst, 15, 12) << 1));
1489 return new VcvtFpUIntD(machInst, vd, vm);
1490 }
1491 }
1492 case 0xd:
1493 if (bits(machInst, 7) == 0) {
1494 if (single) {
1495 return new VcvtFpSIntSR(machInst, vd, vm);
1496 } else {
1497 vd = (IntRegIndex)(bits(machInst, 22) |
1498 (bits(machInst, 15, 12) << 1));
1499 return new VcvtFpSIntDR(machInst, vd, vm);
1500 }
1501 } else {
1502 if (single) {
1503 return new VcvtFpSIntS(machInst, vd, vm);
1504 } else {
1505 vd = (IntRegIndex)(bits(machInst, 22) |
1506 (bits(machInst, 15, 12) << 1));
1507 return new VcvtFpSIntD(machInst, vd, vm);
1508 }
1509 }
1510 case 0xe:
1511 {
1512 const bool half = (bits(machInst, 7) == 0);
1513 const uint32_t imm = bits(machInst, 5) |
1514 (bits(machInst, 3, 0) << 1);
1515 const uint32_t size =
1516 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1517 if (single) {
1518 if (half) {
1519 return new VcvtFpSHFixedS(machInst, vd, vd, size);
1520 } else {
1521 return new VcvtFpSFixedS(machInst, vd, vd, size);
1522 }
1523 } else {
1524 if (half) {
1525 return new VcvtFpSHFixedD(machInst, vd, vd, size);
1526 } else {
1527 return new VcvtFpSFixedD(machInst, vd, vd, size);
1528 }
1529 }
1530 }
1531 case 0xf:
1532 {
1533 const bool half = (bits(machInst, 7) == 0);
1534 const uint32_t imm = bits(machInst, 5) |
1535 (bits(machInst, 3, 0) << 1);
1536 const uint32_t size =
1537 (bits(machInst, 7) == 0 ? 16 : 32) - imm;
1538 if (single) {
1539 if (half) {
1540 return new VcvtFpUHFixedS(machInst, vd, vd, size);
1541 } else {
1542 return new VcvtFpUFixedS(machInst, vd, vd, size);
1543 }
1544 } else {
1545 if (half) {
1546 return new VcvtFpUHFixedD(machInst, vd, vd, size);
1547 } else {
1548 return new VcvtFpUFixedD(machInst, vd, vd, size);
1549 }
1550 }
1551 }
1552 }
1553 break;
1554 }
1555 return new Unknown(machInst);
1556 }
1557 '''
1558}};
1559
1560def format VfpData() {{
1561 decode_block = '''
1562 return decodeVfpData(machInst);
1563 '''
1564}};