fp.isa (7591:aabe621e58df) fp.isa (7639:8c09b7ff5b57)
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

--- 31 unchanged lines hidden (view full) ---

40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
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

--- 31 unchanged lines hidden (view full) ---

40//
41// Authors: Stephen Hines
42
43////////////////////////////////////////////////////////////////////
44//
45// Floating Point operate instructions
46//
47
48output header {{
49
50 template<template <typename T> class Base>
51 StaticInstPtr
52 newNeonMemInst(const unsigned size,
53 const ExtMachInst &machInst,
54 const RegIndex dest, const RegIndex ra,
55 const uint32_t imm, const unsigned extraMemFlags)
56 {
57 switch (size) {
58 case 0:
59 return new Base<uint8_t>(machInst, dest, ra, imm, extraMemFlags);
60 case 1:
61 return new Base<uint16_t>(machInst, dest, ra, imm, extraMemFlags);
62 case 2:
63 return new Base<uint32_t>(machInst, dest, ra, imm, extraMemFlags);
64 case 3:
65 return new Base<uint64_t>(machInst, dest, ra, imm, extraMemFlags);
66 default:
67 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
68 }
69 }
70
71 template<template <typename T> class Base>
72 StaticInstPtr
73 newNeonMixInst(const unsigned size,
74 const ExtMachInst &machInst,
75 const RegIndex dest, const RegIndex op1,
76 const uint32_t step)
77 {
78 switch (size) {
79 case 0:
80 return new Base<uint8_t>(machInst, dest, op1, step);
81 case 1:
82 return new Base<uint16_t>(machInst, dest, op1, step);
83 case 2:
84 return new Base<uint32_t>(machInst, dest, op1, step);
85 case 3:
86 return new Base<uint64_t>(machInst, dest, op1, step);
87 default:
88 panic("Unrecognized width %d for Neon mem inst.\n", (1 << size));
89 }
90 }
91
92}};
93
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);
94let {{
95 header_output = '''
96 StaticInstPtr
97 decodeNeonMem(ExtMachInst machInst);
98
99 StaticInstPtr
100 decodeNeonData(ExtMachInst machInst);
101 '''
102
103 decoder_output = '''
104 StaticInstPtr
105 decodeNeonMem(ExtMachInst machInst)
106 {
107 const uint32_t b = bits(machInst, 11, 8);
62 const bool a = bits(machInst, 23);
63 const bool l = bits(machInst, 21);
108 const bool single = bits(machInst, 23);
109 const bool singleAll = single && (bits(b, 3, 2) == 3);
110 const bool load = bits(machInst, 21);
64
111
65 if (l) {
66 // Load instructions.
67 if (a) {
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 }
112 unsigned width = 0;
113
114 if (single) {
115 width = bits(b, 1, 0) + 1;
116 } else {
117 switch (bits(b, 3, 1)) {
118 case 0x0: width = 4;
119 break;
120 case 0x1: width = (b & 0x1) ? 2 : 1;
121 break;
122 case 0x2: width = 3;
123 break;
124 case 0x3: width = 1;
125 break;
126 case 0x4: width = 2;
127 break;
128 case 0x5:
129 if ((b & 0x1) == 0) {
130 width = 1;
131 break;
132 }
133 // Fall through on purpose.
134 default:
135 return new Unknown(machInst);
136 }
137 }
138 assert(width > 0 && width <= 4);
139
140 const RegIndex rm = (RegIndex)(uint32_t)bits(machInst, 3, 0);
141 const RegIndex rn = (RegIndex)(uint32_t)bits(machInst, 19, 16);
142 const RegIndex vd = (RegIndex)(uint32_t)(bits(machInst, 15, 12) |
143 bits(machInst, 22) << 4);
144 const uint32_t type = bits(machInst, 11, 8);
145 uint32_t size = 0;
146 uint32_t align = 0;
147 unsigned inc = 1;
148 unsigned regs = 1;
149 unsigned lane = 0;
150 if (single) {
151 if (singleAll) {
152 size = bits(machInst, 7, 6);
153 bool t = bits(machInst, 5);
154 unsigned eBytes = (1 << size);
155 align = (eBytes - 1) | TLB::AllowUnaligned;
156 if (width == 1) {
157 regs = t ? 2 : 1;
158 inc = 1;
79 } else {
159 } 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);
160 regs = width;
161 inc = t ? 2 : 1;
162 }
163 switch (width) {
164 case 1:
165 case 2:
166 if (bits(machInst, 4))
167 align = width * eBytes - 1;
168 break;
169 case 3:
170 break;
171 case 4:
172 if (size == 3) {
173 if (bits(machInst, 4) == 0)
174 return new Unknown(machInst);
175 size = 2;
176 align = 0xf;
177 } else if (size == 2) {
178 if (bits(machInst, 4))
179 align = 7;
180 } else {
181 if (bits(machInst, 4))
182 align = 4 * eBytes - 1;
93 }
183 }
184 break;
94 }
95 } else {
185 }
186 } else {
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);
187 size = bits(machInst, 11, 10);
188 unsigned eBytes = (1 << size);
189 align = (eBytes - 1) | TLB::AllowUnaligned;
190 regs = width;
191 unsigned indexAlign = bits(machInst, 7, 4);
192 // If width is 1, inc is always 1. That's overridden later.
193 switch (size) {
194 case 0:
195 inc = 1;
196 lane = bits(indexAlign, 3, 1);
197 break;
198 case 1:
199 inc = bits(indexAlign, 1) ? 2 : 1;
200 lane = bits(indexAlign, 3, 2);
201 break;
202 case 2:
203 inc = bits(indexAlign, 2) ? 2 : 1;
204 lane = bits(indexAlign, 3);
205 break;
206 }
207 // Override inc for width of 1.
208 if (width == 1) {
209 inc = 1;
210 }
211 switch (width) {
212 case 1:
213 switch (size) {
214 case 0:
215 break;
216 case 1:
217 if (bits(indexAlign, 0))
218 align = 1;
219 break;
220 case 2:
221 if (bits(indexAlign, 1, 0))
222 align = 3;
223 break;
110 }
224 }
111 case 0x5:
112 if ((b & 0x1) == 0) {
113 return new WarnUnimplemented("vld1 multiple", machInst);
114 } else {
225 break;
226 case 2:
227 if (bits(indexAlign, 0))
228 align = (2 * eBytes) - 1;
229 break;
230 case 3:
231 break;
232 case 4:
233 switch (size) {
234 case 0:
235 case 1:
236 if (bits(indexAlign, 0))
237 align = (4 * eBytes) - 1;
115 break;
238 break;
239 case 2:
240 if (bits(indexAlign, 0))
241 align = (4 << bits(indexAlign, 1, 0)) - 1;
242 break;
116 }
243 }
244 break;
117 }
118 }
245 }
246 }
247 if (size == 0x3) {
248 return new Unknown(machInst);
249 }
119 } else {
250 } else {
251 size = bits(machInst, 7, 6);
252 align = bits(machInst, 5, 4);
253 if (align == 0) {
254 // @align wasn't specified, so alignment can be turned off.
255 align = ((1 << size) - 1) | TLB::AllowUnaligned;
256 } else {
257 align = ((4 << align) - 1);
258 }
259 switch (width) {
260 case 1:
261 switch (type) {
262 case 0x7: regs = 1;
263 break;
264 case 0xa: regs = 2;
265 break;
266 case 0x6: regs = 3;
267 break;
268 case 0x2: regs = 4;
269 break;
270 default:
271 return new Unknown(machInst);
272 }
273 break;
274 case 2:
275 // Regs doesn't behave exactly as it does in the manual
276 // because they loop over regs registers twice and we break
277 // it down in the macroop.
278 switch (type) {
279 case 0x8: regs = 2; inc = 1;
280 break;
281 case 0x9: regs = 2; inc = 2;
282 break;
283 case 0x3: regs = 4; inc = 2;
284 break;
285 default:
286 return new Unknown(machInst);
287 }
288 break;
289 case 3:
290 regs = 3;
291 switch (type) {
292 case 0x4: inc = 1;
293 break;
294 case 0x5: inc = 2;;
295 break;
296 default:
297 return new Unknown(machInst);
298 }
299 break;
300 case 4:
301 regs = 4;
302 switch (type) {
303 case 0: inc = 1;
304 break;
305 case 1: inc = 2;
306 break;
307 default:
308 return new Unknown(machInst);
309 }
310 break;
311 }
312 }
313
314 if (load) {
315 // Load instructions.
316 if (single) {
317 return new VldSingle(machInst, singleAll, width, rn, vd,
318 regs, inc, size, align, rm, lane);
319 } else {
320 return new VldMult(machInst, width, rn, vd,
321 regs, inc, size, align, rm);
322 }
323 } else {
120 // Store instructions.
324 // Store instructions.
121 if (a) {
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 }
325 if (single) {
326 if (singleAll) {
327 return new Unknown(machInst);
133 } else {
328 } 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 }
329 return new VstSingle(machInst, false, width, rn, vd,
330 regs, inc, size, align, rm, lane);
148 }
149 } else {
331 }
332 } else {
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 }
171 }
333 return new VstMult(machInst, width, rn, vd,
334 regs, inc, size, align, rm);
172 }
173 }
174 return new Unknown(machInst);
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);
335 }
336 }
337 return new Unknown(machInst);
338 }
339 '''
340
341 decoder_output += '''
342 static StaticInstPtr
343 decodeNeonThreeRegistersSameLength(ExtMachInst machInst)
344 {
345 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
346 const uint32_t a = bits(machInst, 11, 8);
347 const bool b = bits(machInst, 4);
348 const uint32_t c = bits(machInst, 21, 20);
349 const IntRegIndex vd =
350 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
351 (bits(machInst, 22) << 4)));
352 const IntRegIndex vn =
353 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
354 (bits(machInst, 7) << 4)));
355 const IntRegIndex vm =
356 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
357 (bits(machInst, 5) << 4)));
358 const unsigned size = bits(machInst, 21, 20);
359 const bool q = bits(machInst, 6);
360 if (q && ((vd & 0x1) || (vn & 0x1) || (vm & 0x1)))
361 return new Unknown(machInst);
186 switch (a) {
187 case 0x0:
188 if (b) {
362 switch (a) {
363 case 0x0:
364 if (b) {
189 if (bits(machInst, 9) == 0) {
190 return new WarnUnimplemented("vhadd", machInst);
365 if (u) {
366 return decodeNeonUThreeReg<VqaddUD, VqaddUQ>(
367 q, size, machInst, vd, vn, vm);
191 } else {
368 } else {
192 return new WarnUnimplemented("vhsub", machInst);
369 return decodeNeonSThreeReg<VqaddSD, VqaddSQ>(
370 q, size, machInst, vd, vn, vm);
193 }
194 } else {
371 }
372 } else {
195 return new WarnUnimplemented("vqadd", machInst);
373 if (size == 3)
374 return new Unknown(machInst);
375 return decodeNeonUSThreeReg<VhaddD, VhaddQ>(
376 q, u, size, machInst, vd, vn, vm);
196 }
197 case 0x1:
198 if (!b) {
377 }
378 case 0x1:
379 if (!b) {
199 return new WarnUnimplemented("vrhadd", machInst);
380 return decodeNeonUSThreeReg<VrhaddD, VrhaddQ>(
381 q, u, size, machInst, vd, vn, vm);
200 } else {
201 if (u) {
202 switch (c) {
203 case 0:
382 } else {
383 if (u) {
384 switch (c) {
385 case 0:
204 return new WarnUnimplemented("veor", machInst);
386 if (q) {
387 return new VeorQ<uint64_t>(machInst, vd, vn, vm);
388 } else {
389 return new VeorD<uint64_t>(machInst, vd, vn, vm);
390 }
205 case 1:
391 case 1:
206 return new WarnUnimplemented("vbsl", machInst);
392 if (q) {
393 return new VbslQ<uint64_t>(machInst, vd, vn, vm);
394 } else {
395 return new VbslD<uint64_t>(machInst, vd, vn, vm);
396 }
207 case 2:
397 case 2:
208 return new WarnUnimplemented("vbit", machInst);
398 if (q) {
399 return new VbitQ<uint64_t>(machInst, vd, vn, vm);
400 } else {
401 return new VbitD<uint64_t>(machInst, vd, vn, vm);
402 }
209 case 3:
403 case 3:
210 return new WarnUnimplemented("vbif", machInst);
404 if (q) {
405 return new VbifQ<uint64_t>(machInst, vd, vn, vm);
406 } else {
407 return new VbifD<uint64_t>(machInst, vd, vn, vm);
408 }
211 }
212 } else {
213 switch (c) {
214 case 0:
409 }
410 } else {
411 switch (c) {
412 case 0:
215 return new WarnUnimplemented("vand (reg)", machInst);
413 if (q) {
414 return new VandQ<uint64_t>(machInst, vd, vn, vm);
415 } else {
416 return new VandD<uint64_t>(machInst, vd, vn, vm);
417 }
216 case 1:
418 case 1:
217 return new WarnUnimplemented("vbic (reg)", machInst);
419 if (q) {
420 return new VbicQ<uint64_t>(machInst, vd, vn, vm);
421 } else {
422 return new VbicD<uint64_t>(machInst, vd, vn, vm);
423 }
218 case 2:
424 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);
425 if (vn == vm) {
426 if (q) {
427 return new VmovQ<uint64_t>(
428 machInst, vd, vn, vm);
229 } else {
429 } else {
230 return new WarnUnimplemented("vorr (reg)",
231 machInst);
430 return new VmovD<uint64_t>(
431 machInst, vd, vn, vm);
232 }
432 }
433 } else {
434 if (q) {
435 return new VorrQ<uint64_t>(
436 machInst, vd, vn, vm);
437 } else {
438 return new VorrD<uint64_t>(
439 machInst, vd, vn, vm);
440 }
233 }
234 case 3:
441 }
442 case 3:
235 return new WarnUnimplemented("vorn (reg)", machInst);
443 if (q) {
444 return new VornQ<uint64_t>(
445 machInst, vd, vn, vm);
446 } else {
447 return new VornD<uint64_t>(
448 machInst, vd, vn, vm);
449 }
236 }
237 }
238 }
239 case 0x2:
240 if (b) {
450 }
451 }
452 }
453 case 0x2:
454 if (b) {
241 return new WarnUnimplemented("vqsub", machInst);
242 } else {
243 if (bits(machInst, 9) == 0) {
244 return new WarnUnimplemented("vhadd", machInst);
455 if (u) {
456 return decodeNeonUThreeReg<VqsubUD, VqsubUQ>(
457 q, size, machInst, vd, vn, vm);
245 } else {
458 } else {
246 return new WarnUnimplemented("vhsub", machInst);
459 return decodeNeonSThreeReg<VqsubSD, VqsubSQ>(
460 q, size, machInst, vd, vn, vm);
247 }
461 }
462 } else {
463 if (size == 3)
464 return new Unknown(machInst);
465 return decodeNeonUSThreeReg<VhsubD, VhsubQ>(
466 q, u, size, machInst, vd, vn, vm);
248 }
249 case 0x3:
250 if (b) {
467 }
468 case 0x3:
469 if (b) {
251 return new WarnUnimplemented("vcge (reg)", machInst);
470 return decodeNeonUSThreeReg<VcgeD, VcgeQ>(
471 q, u, size, machInst, vd, vn, vm);
252 } else {
472 } else {
253 return new WarnUnimplemented("vcgt (reg)", machInst);
473 return decodeNeonUSThreeReg<VcgtD, VcgtQ>(
474 q, u, size, machInst, vd, vn, vm);
254 }
255 case 0x4:
256 if (b) {
475 }
476 case 0x4:
477 if (b) {
257 return new WarnUnimplemented("vqshl (reg)", machInst);
478 if (u) {
479 return decodeNeonUThreeReg<VqshlUD, VqshlUQ>(
480 q, size, machInst, vd, vm, vn);
481 } else {
482 return decodeNeonSThreeReg<VqshlSD, VqshlSQ>(
483 q, size, machInst, vd, vm, vn);
484 }
258 } else {
485 } else {
259 return new WarnUnimplemented("vshl (reg)", machInst);
486 return decodeNeonUSThreeReg<VshlD, VshlQ>(
487 q, u, size, machInst, vd, vm, vn);
260 }
261 case 0x5:
262 if (b) {
488 }
489 case 0x5:
490 if (b) {
263 return new WarnUnimplemented("vqrshl", machInst);
491 if (u) {
492 return decodeNeonUThreeReg<VqrshlUD, VqrshlUQ>(
493 q, size, machInst, vd, vm, vn);
494 } else {
495 return decodeNeonSThreeReg<VqrshlSD, VqrshlSQ>(
496 q, size, machInst, vd, vm, vn);
497 }
264 } else {
498 } else {
265 return new WarnUnimplemented("vrshl", machInst);
499 return decodeNeonUSThreeReg<VrshlD, VrshlQ>(
500 q, u, size, machInst, vd, vm, vn);
266 }
267 case 0x6:
268 if (b) {
501 }
502 case 0x6:
503 if (b) {
269 return new WarnUnimplemented("vmin (int)", machInst);
504 return decodeNeonUSThreeReg<VminD, VminQ>(
505 q, u, size, machInst, vd, vn, vm);
270 } else {
506 } else {
271 return new WarnUnimplemented("vmax (int)", machInst);
507 return decodeNeonUSThreeReg<VmaxD, VmaxQ>(
508 q, u, size, machInst, vd, vn, vm);
272 }
273 case 0x7:
274 if (b) {
509 }
510 case 0x7:
511 if (b) {
275 return new WarnUnimplemented("vaba", machInst);
512 return decodeNeonUSThreeReg<VabaD, VabaQ>(
513 q, u, size, machInst, vd, vn, vm);
276 } else {
277 if (bits(machInst, 23) == 1) {
514 } else {
515 if (bits(machInst, 23) == 1) {
278 if (bits(machInst, 6) == 1) {
516 if (q) {
279 return new Unknown(machInst);
280 } else {
517 return new Unknown(machInst);
518 } else {
281 return new WarnUnimplemented("vabdl (int)", machInst);
519 return decodeNeonUSThreeUSReg<Vabdl>(
520 u, size, machInst, vd, vn, vm);
282 }
283 } else {
521 }
522 } else {
284 return new WarnUnimplemented("vabd (int)", machInst);
523 return decodeNeonUSThreeReg<VabdD, VabdQ>(
524 q, u, size, machInst, vd, vn, vm);
285 }
286 }
287 case 0x8:
288 if (b) {
289 if (u) {
525 }
526 }
527 case 0x8:
528 if (b) {
529 if (u) {
290 return new WarnUnimplemented("vceq (reg)", machInst);
530 return decodeNeonUThreeReg<VceqD, VceqQ>(
531 q, size, machInst, vd, vn, vm);
291 } else {
532 } else {
292 return new WarnUnimplemented("vtst", machInst);
533 return decodeNeonUThreeReg<VtstD, VtstQ>(
534 q, size, machInst, vd, vn, vm);
293 }
294 } else {
295 if (u) {
535 }
536 } else {
537 if (u) {
296 return new WarnUnimplemented("vsub (int)", machInst);
538 return decodeNeonUThreeReg<NVsubD, NVsubQ>(
539 q, size, machInst, vd, vn, vm);
297 } else {
540 } else {
298 return new WarnUnimplemented("vadd (int)", machInst);
541 return decodeNeonUThreeReg<NVaddD, NVaddQ>(
542 q, size, machInst, vd, vn, vm);
299 }
300 }
301 case 0x9:
302 if (b) {
303 if (u) {
543 }
544 }
545 case 0x9:
546 if (b) {
547 if (u) {
304 return new WarnUnimplemented("vmul (poly)", machInst);
548 return decodeNeonUThreeReg<NVmulpD, NVmulpQ>(
549 q, size, machInst, vd, vn, vm);
305 } else {
550 } else {
306 return new WarnUnimplemented("vmul (int)", machInst);
551 return decodeNeonSThreeReg<NVmulD, NVmulQ>(
552 q, size, machInst, vd, vn, vm);
307 }
308 } else {
309 if (u) {
553 }
554 } else {
555 if (u) {
310 return new WarnUnimplemented("vmls (int)", machInst);
556 return decodeNeonUSThreeReg<NVmlsD, NVmlsQ>(
557 q, u, size, machInst, vd, vn, vm);
311 } else {
558 } else {
312 return new WarnUnimplemented("vmla (int)", machInst);
559 return decodeNeonUSThreeReg<NVmlaD, NVmlaQ>(
560 q, u, size, machInst, vd, vn, vm);
313 }
314 }
315 case 0xa:
316 if (b) {
561 }
562 }
563 case 0xa:
564 if (b) {
317 return new WarnUnimplemented("vpmin (int)", machInst);
565 return decodeNeonUSThreeReg<VpminD, VpminQ>(
566 q, u, size, machInst, vd, vn, vm);
318 } else {
567 } else {
319 return new WarnUnimplemented("vpmax (int)", machInst);
568 return decodeNeonUSThreeReg<VpmaxD, VpmaxQ>(
569 q, u, size, machInst, vd, vn, vm);
320 }
321 case 0xb:
322 if (b) {
323 if (u) {
324 return new Unknown(machInst);
325 } else {
570 }
571 case 0xb:
572 if (b) {
573 if (u) {
574 return new Unknown(machInst);
575 } else {
326 return new WarnUnimplemented("vpadd (int)", machInst);
576 return decodeNeonUThreeReg<NVpaddD, NVpaddQ>(
577 q, size, machInst, vd, vn, vm);
327 }
328 } else {
329 if (u) {
578 }
579 } else {
580 if (u) {
330 return new WarnUnimplemented("vqrdmulh", machInst);
581 return decodeNeonSThreeSReg<VqrdmulhD, VqrdmulhQ>(
582 q, size, machInst, vd, vn, vm);
331 } else {
583 } else {
332 return new WarnUnimplemented("vqdmulh", machInst);
584 return decodeNeonSThreeSReg<VqdmulhD, VqdmulhQ>(
585 q, size, machInst, vd, vn, vm);
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) {
586 }
587 }
588 case 0xc:
589 return new Unknown(machInst);
590 case 0xd:
591 if (b) {
592 if (u) {
593 if (bits(c, 1) == 0) {
341 return new WarnUnimplemented("vmul (fp)", machInst);
594 if (q) {
595 return new NVmulQFp<float>(machInst, vd, vn, vm);
596 } else {
597 return new NVmulDFp<float>(machInst, vd, vn, vm);
598 }
342 } else {
343 return new Unknown(machInst);
344 }
345 } else {
346 if (bits(c, 1) == 0) {
599 } else {
600 return new Unknown(machInst);
601 }
602 } else {
603 if (bits(c, 1) == 0) {
347 return new WarnUnimplemented("vmla (fp)", machInst);
604 if (q) {
605 return new NVmlaQFp<float>(machInst, vd, vn, vm);
606 } else {
607 return new NVmlaDFp<float>(machInst, vd, vn, vm);
608 }
348 } else {
609 } else {
349 return new WarnUnimplemented("vmls (fp)", machInst);
610 if (q) {
611 return new NVmlsQFp<float>(machInst, vd, vn, vm);
612 } else {
613 return new NVmlsDFp<float>(machInst, vd, vn, vm);
614 }
350 }
351 }
352 } else {
353 if (u) {
354 if (bits(c, 1) == 0) {
615 }
616 }
617 } else {
618 if (u) {
619 if (bits(c, 1) == 0) {
355 return new WarnUnimplemented("vpadd (fp)", machInst);
620 if (q) {
621 return new VpaddQFp<float>(machInst, vd, vn, vm);
622 } else {
623 return new VpaddDFp<float>(machInst, vd, vn, vm);
624 }
356 } else {
625 } else {
357 return new WarnUnimplemented("vabd (fp)", machInst);
626 if (q) {
627 return new VabdQFp<float>(machInst, vd, vn, vm);
628 } else {
629 return new VabdDFp<float>(machInst, vd, vn, vm);
630 }
358 }
359 } else {
360 if (bits(c, 1) == 0) {
631 }
632 } else {
633 if (bits(c, 1) == 0) {
361 return new WarnUnimplemented("vadd (fp)", machInst);
634 if (q) {
635 return new VaddQFp<float>(machInst, vd, vn, vm);
636 } else {
637 return new VaddDFp<float>(machInst, vd, vn, vm);
638 }
362 } else {
639 } else {
363 return new WarnUnimplemented("vsub (fp)", machInst);
640 if (q) {
641 return new VsubQFp<float>(machInst, vd, vn, vm);
642 } else {
643 return new VsubDFp<float>(machInst, vd, vn, vm);
644 }
364 }
365 }
366 }
367 case 0xe:
368 if (b) {
369 if (u) {
370 if (bits(c, 1) == 0) {
645 }
646 }
647 }
648 case 0xe:
649 if (b) {
650 if (u) {
651 if (bits(c, 1) == 0) {
371 return new WarnUnimplemented("vacge", machInst);
652 if (q) {
653 return new VacgeQFp<float>(machInst, vd, vn, vm);
654 } else {
655 return new VacgeDFp<float>(machInst, vd, vn, vm);
656 }
372 } else {
657 } else {
373 return new WarnUnimplemented("vacgt", machInst);
658 if (q) {
659 return new VacgtQFp<float>(machInst, vd, vn, vm);
660 } else {
661 return new VacgtDFp<float>(machInst, vd, vn, vm);
662 }
374 }
375 } else {
376 return new Unknown(machInst);
377 }
378 } else {
379 if (u) {
380 if (bits(c, 1) == 0) {
663 }
664 } else {
665 return new Unknown(machInst);
666 }
667 } else {
668 if (u) {
669 if (bits(c, 1) == 0) {
381 return new WarnUnimplemented("vcge (reg)", machInst);
670 if (q) {
671 return new VcgeQFp<float>(machInst, vd, vn, vm);
672 } else {
673 return new VcgeDFp<float>(machInst, vd, vn, vm);
674 }
382 } else {
675 } else {
383 return new WarnUnimplemented("vcgt (reg)", machInst);
676 if (q) {
677 return new VcgtQFp<float>(machInst, vd, vn, vm);
678 } else {
679 return new VcgtDFp<float>(machInst, vd, vn, vm);
680 }
384 }
385 } else {
386 if (bits(c, 1) == 0) {
681 }
682 } else {
683 if (bits(c, 1) == 0) {
387 return new WarnUnimplemented("vceq (reg)", machInst);
684 if (q) {
685 return new VceqQFp<float>(machInst, vd, vn, vm);
686 } else {
687 return new VceqDFp<float>(machInst, vd, vn, vm);
688 }
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) {
689 } else {
690 return new Unknown(machInst);
691 }
692 }
693 }
694 case 0xf:
695 if (b) {
696 if (u) {
697 return new Unknown(machInst);
698 } else {
699 if (bits(c, 1) == 0) {
399 return new WarnUnimplemented("vrecps", machInst);
700 if (q) {
701 return new VrecpsQFp<float>(machInst, vd, vn, vm);
702 } else {
703 return new VrecpsDFp<float>(machInst, vd, vn, vm);
704 }
400 } else {
705 } else {
401 return new WarnUnimplemented("vrsqrts", machInst);
706 if (q) {
707 return new VrsqrtsQFp<float>(machInst, vd, vn, vm);
708 } else {
709 return new VrsqrtsDFp<float>(machInst, vd, vn, vm);
710 }
402 }
403 }
404 } else {
405 if (u) {
406 if (bits(c, 1) == 0) {
711 }
712 }
713 } else {
714 if (u) {
715 if (bits(c, 1) == 0) {
407 return new WarnUnimplemented("vpmax (fp)", machInst);
716 if (q) {
717 return new VpmaxQFp<float>(machInst, vd, vn, vm);
718 } else {
719 return new VpmaxDFp<float>(machInst, vd, vn, vm);
720 }
408 } else {
721 } else {
409 return new WarnUnimplemented("vpmin (fp)", machInst);
722 if (q) {
723 return new VpminQFp<float>(machInst, vd, vn, vm);
724 } else {
725 return new VpminDFp<float>(machInst, vd, vn, vm);
726 }
410 }
411 } else {
412 if (bits(c, 1) == 0) {
727 }
728 } else {
729 if (bits(c, 1) == 0) {
413 return new WarnUnimplemented("vmax (fp)", machInst);
730 if (q) {
731 return new VmaxQFp<float>(machInst, vd, vn, vm);
732 } else {
733 return new VmaxDFp<float>(machInst, vd, vn, vm);
734 }
414 } else {
735 } else {
415 return new WarnUnimplemented("vmin (fp)", machInst);
736 if (q) {
737 return new VminQFp<float>(machInst, vd, vn, vm);
738 } else {
739 return new VminDFp<float>(machInst, vd, vn, vm);
740 }
416 }
417 }
418 }
419 }
420 return new Unknown(machInst);
421 }
422
423 static StaticInstPtr
424 decodeNeonOneRegModImm(ExtMachInst machInst)
425 {
741 }
742 }
743 }
744 }
745 return new Unknown(machInst);
746 }
747
748 static StaticInstPtr
749 decodeNeonOneRegModImm(ExtMachInst machInst)
750 {
751 const IntRegIndex vd =
752 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
753 (bits(machInst, 22) << 4)));
754 const bool q = bits(machInst, 6);
426 const bool op = bits(machInst, 5);
755 const bool op = bits(machInst, 5);
427 const uint32_t cmode = bits(machInst, 11, 8);
756 const uint8_t cmode = bits(machInst, 11, 8);
757 const uint8_t imm = ((THUMB ? bits(machInst, 28) :
758 bits(machInst, 24)) << 7) |
759 (bits(machInst, 18, 16) << 4) |
760 (bits(machInst, 3, 0) << 0);
761 const uint64_t bigImm = simd_modified_imm(op, cmode, imm);
428 if (op) {
429 if (bits(cmode, 3) == 0) {
430 if (bits(cmode, 0) == 0) {
762 if (op) {
763 if (bits(cmode, 3) == 0) {
764 if (bits(cmode, 0) == 0) {
431 return new WarnUnimplemented("vmov (imm)", machInst);
765 if (q)
766 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
767 else
768 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
432 } else {
769 } else {
433 return new WarnUnimplemented("vorr (imm)", machInst);
770 if (q)
771 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
772 else
773 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
434 }
435 } else {
436 if (bits(cmode, 2) == 1) {
774 }
775 } else {
776 if (bits(cmode, 2) == 1) {
437 return new WarnUnimplemented("vmov (imm)", machInst);
777 switch (bits(cmode, 1, 0)) {
778 case 0:
779 case 1:
780 if (q)
781 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
782 else
783 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
784 case 2:
785 if (q)
786 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
787 else
788 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
789 case 3:
790 if (q)
791 return new Unknown(machInst);
792 else
793 return new Unknown(machInst);
794 }
438 } else {
439 if (bits(cmode, 0) == 0) {
795 } else {
796 if (bits(cmode, 0) == 0) {
440 return new WarnUnimplemented("vmov (imm)", machInst);
797 if (q)
798 return new NVmvniQ<uint64_t>(machInst, vd, bigImm);
799 else
800 return new NVmvniD<uint64_t>(machInst, vd, bigImm);
441 } else {
801 } else {
442 return new WarnUnimplemented("vorr (imm)", machInst);
802 if (q)
803 return new NVbiciQ<uint64_t>(machInst, vd, bigImm);
804 else
805 return new NVbiciD<uint64_t>(machInst, vd, bigImm);
443 }
444 }
445 }
446 } else {
447 if (bits(cmode, 3) == 0) {
448 if (bits(cmode, 0) == 0) {
806 }
807 }
808 }
809 } else {
810 if (bits(cmode, 3) == 0) {
811 if (bits(cmode, 0) == 0) {
449 return new WarnUnimplemented("vmvn (imm)", machInst);
812 if (q)
813 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
814 else
815 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
450 } else {
816 } else {
451 return new WarnUnimplemented("vbic (imm)", machInst);
817 if (q)
818 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
819 else
820 return new NVorriD<uint64_t>(machInst, vd, bigImm);
452 }
453 } else {
454 if (bits(cmode, 2) == 1) {
821 }
822 } else {
823 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);
824 if (q)
825 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
826 else
827 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
465 } else {
466 if (bits(cmode, 0) == 0) {
828 } else {
829 if (bits(cmode, 0) == 0) {
467 return new WarnUnimplemented("vmvn (imm)", machInst);
830 if (q)
831 return new NVmoviQ<uint64_t>(machInst, vd, bigImm);
832 else
833 return new NVmoviD<uint64_t>(machInst, vd, bigImm);
468 } else {
834 } else {
469 return new WarnUnimplemented("vbic (imm)", machInst);
835 if (q)
836 return new NVorriQ<uint64_t>(machInst, vd, bigImm);
837 else
838 return new NVorriD<uint64_t>(machInst, vd, bigImm);
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);
839 }
840 }
841 }
842 }
843 return new Unknown(machInst);
844 }
845
846 static StaticInstPtr
847 decodeNeonTwoRegAndShift(ExtMachInst machInst)
848 {
849 const uint32_t a = bits(machInst, 11, 8);
850 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
851 const bool b = bits(machInst, 6);
852 const bool l = bits(machInst, 7);
853 const IntRegIndex vd =
854 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
855 (bits(machInst, 22) << 4)));
856 const IntRegIndex vm =
857 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
858 (bits(machInst, 5) << 4)));
859 unsigned imm6 = bits(machInst, 21, 16);
860 unsigned imm = ((l ? 1 : 0) << 6) | imm6;
861 unsigned size = 3;
862 unsigned lShiftAmt = 0;
863 unsigned bitSel;
864 for (bitSel = 1 << 6; true; bitSel >>= 1) {
865 if (bitSel & imm)
866 break;
867 else if (!size)
868 return new Unknown(machInst);
869 size--;
870 }
871 lShiftAmt = imm6 & ~bitSel;
872 unsigned rShiftAmt = 0;
873 if (a != 0xe && a != 0xf) {
874 if (size > 2)
875 rShiftAmt = 64 - imm6;
876 else
877 rShiftAmt = 2 * (8 << size) - imm6;
878 }
484
485 switch (a) {
486 case 0x0:
879
880 switch (a) {
881 case 0x0:
487 return new WarnUnimplemented("vshr", machInst);
882 return decodeNeonUSTwoShiftReg<NVshrD, NVshrQ>(
883 b, u, size, machInst, vd, vm, rShiftAmt);
488 case 0x1:
884 case 0x1:
489 return new WarnUnimplemented("vsra", machInst);
885 return decodeNeonUSTwoShiftReg<NVsraD, NVsraQ>(
886 b, u, size, machInst, vd, vm, rShiftAmt);
490 case 0x2:
887 case 0x2:
491 return new WarnUnimplemented("vrshr", machInst);
888 return decodeNeonUSTwoShiftReg<NVrshrD, NVrshrQ>(
889 b, u, size, machInst, vd, vm, rShiftAmt);
492 case 0x3:
890 case 0x3:
493 return new WarnUnimplemented("vrsra", machInst);
891 return decodeNeonUSTwoShiftReg<NVrsraD, NVrsraQ>(
892 b, u, size, machInst, vd, vm, rShiftAmt);
494 case 0x4:
495 if (u) {
893 case 0x4:
894 if (u) {
496 return new WarnUnimplemented("vsri", machInst);
895 return decodeNeonUTwoShiftReg<NVsriD, NVsriQ>(
896 b, size, machInst, vd, vm, rShiftAmt);
497 } else {
498 return new Unknown(machInst);
499 }
500 case 0x5:
501 if (u) {
897 } else {
898 return new Unknown(machInst);
899 }
900 case 0x5:
901 if (u) {
502 return new WarnUnimplemented("vsli", machInst);
902 return decodeNeonUTwoShiftReg<NVsliD, NVsliQ>(
903 b, size, machInst, vd, vm, lShiftAmt);
503 } else {
904 } else {
504 return new WarnUnimplemented("vshl (imm)", machInst);
905 return decodeNeonUTwoShiftReg<NVshlD, NVshlQ>(
906 b, size, machInst, vd, vm, lShiftAmt);
505 }
506 case 0x6:
507 case 0x7:
907 }
908 case 0x6:
909 case 0x7:
508 return new WarnUnimplemented("vqshl, vqshlu (imm)", machInst);
910 if (u) {
911 if (a == 0x6) {
912 return decodeNeonSTwoShiftReg<NVqshlusD, NVqshlusQ>(
913 b, size, machInst, vd, vm, lShiftAmt);
914 } else {
915 return decodeNeonUTwoShiftReg<NVqshluD, NVqshluQ>(
916 b, size, machInst, vd, vm, lShiftAmt);
917 }
918 } else {
919 return decodeNeonSTwoShiftReg<NVqshlD, NVqshlQ>(
920 b, size, machInst, vd, vm, lShiftAmt);
921 }
509 case 0x8:
510 if (l) {
511 return new Unknown(machInst);
512 } else if (u) {
922 case 0x8:
923 if (l) {
924 return new Unknown(machInst);
925 } else if (u) {
513 if (b) {
514 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
515 } else {
516 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
517 }
926 return decodeNeonSTwoShiftSReg<NVqshruns, NVqrshruns>(
927 b, size, machInst, vd, vm, rShiftAmt);
518 } else {
928 } else {
519 if (b) {
520 return new WarnUnimplemented("vrshrn", machInst);
521 } else {
522 return new WarnUnimplemented("vshrn", machInst);
523 }
929 return decodeNeonUTwoShiftSReg<NVshrn, NVrshrn>(
930 b, size, machInst, vd, vm, rShiftAmt);
524 }
525 case 0x9:
526 if (l) {
527 return new Unknown(machInst);
931 }
932 case 0x9:
933 if (l) {
934 return new Unknown(machInst);
528 } else if (b) {
529 return new WarnUnimplemented("vqrshrn, vqrshrun", machInst);
935 } else if (u) {
936 return decodeNeonUTwoShiftSReg<NVqshrun, NVqrshrun>(
937 b, size, machInst, vd, vm, rShiftAmt);
530 } else {
938 } else {
531 return new WarnUnimplemented("vqshrn, vqshrun", machInst);
939 return decodeNeonSTwoShiftSReg<NVqshrn, NVqrshrn>(
940 b, size, machInst, vd, vm, rShiftAmt);
532 }
533 case 0xa:
534 if (l || b) {
535 return new Unknown(machInst);
536 } else {
941 }
942 case 0xa:
943 if (l || b) {
944 return new Unknown(machInst);
945 } else {
537 // If the shift amount is zero, it's vmovl.
538 return new WarnUnimplemented("vshll, vmovl", machInst);
946 return decodeNeonUSTwoShiftSReg<NVmovl, NVshll>(
947 lShiftAmt, u, size, machInst, vd, vm, lShiftAmt);
539 }
540 case 0xe:
948 }
949 case 0xe:
950 if (l) {
951 return new Unknown(machInst);
952 } else {
953 if (bits(imm6, 5) == 0)
954 return new Unknown(machInst);
955 if (u) {
956 if (b) {
957 return new NVcvtu2fpQ<float>(
958 machInst, vd, vm, 64 - imm6);
959 } else {
960 return new NVcvtu2fpD<float>(
961 machInst, vd, vm, 64 - imm6);
962 }
963 } else {
964 if (b) {
965 return new NVcvts2fpQ<float>(
966 machInst, vd, vm, 64 - imm6);
967 } else {
968 return new NVcvts2fpD<float>(
969 machInst, vd, vm, 64 - imm6);
970 }
971 }
972 }
541 case 0xf:
542 if (l) {
543 return new Unknown(machInst);
973 case 0xf:
974 if (l) {
975 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);
976 } else {
977 if (bits(imm6, 5) == 0)
978 return new Unknown(machInst);
979 if (u) {
980 if (b) {
981 return new NVcvt2ufxQ<float>(
982 machInst, vd, vm, 64 - imm6);
983 } else {
984 return new NVcvt2ufxD<float>(
985 machInst, vd, vm, 64 - imm6);
986 }
987 } else {
988 if (b) {
989 return new NVcvt2sfxQ<float>(
990 machInst, vd, vm, 64 - imm6);
991 } else {
992 return new NVcvt2sfxD<float>(
993 machInst, vd, vm, 64 - imm6);
994 }
995 }
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);
996 }
997 }
998 return new Unknown(machInst);
999 }
1000
1001 static StaticInstPtr
1002 decodeNeonThreeRegDiffLengths(ExtMachInst machInst)
1003 {
1004 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1005 const uint32_t a = bits(machInst, 11, 8);
558
1006 const IntRegIndex vd =
1007 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1008 (bits(machInst, 22) << 4)));
1009 const IntRegIndex vn =
1010 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1011 (bits(machInst, 7) << 4)));
1012 const IntRegIndex vm =
1013 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1014 (bits(machInst, 5) << 4)));
1015 const unsigned size = bits(machInst, 21, 20);
559 switch (a) {
560 case 0x0:
1016 switch (a) {
1017 case 0x0:
561 return new WarnUnimplemented("vaddl", machInst);
1018 return decodeNeonUSThreeUSReg<Vaddl>(
1019 u, size, machInst, vd, vn, vm);
562 case 0x1:
1020 case 0x1:
563 return new WarnUnimplemented("vaddw", machInst);
1021 return decodeNeonUSThreeUSReg<Vaddw>(
1022 u, size, machInst, vd, vn, vm);
564 case 0x2:
1023 case 0x2:
565 return new WarnUnimplemented("vsubl", machInst);
1024 return decodeNeonUSThreeUSReg<Vsubl>(
1025 u, size, machInst, vd, vn, vm);
566 case 0x3:
1026 case 0x3:
567 return new WarnUnimplemented("vsubw", machInst);
1027 return decodeNeonUSThreeUSReg<Vsubw>(
1028 u, size, machInst, vd, vn, vm);
568 case 0x4:
569 if (u) {
1029 case 0x4:
1030 if (u) {
570 return new WarnUnimplemented("vraddhn", machInst);
1031 return decodeNeonUThreeUSReg<Vraddhn>(
1032 size, machInst, vd, vn, vm);
571 } else {
1033 } else {
572 return new WarnUnimplemented("vaddhn", machInst);
1034 return decodeNeonUThreeUSReg<Vaddhn>(
1035 size, machInst, vd, vn, vm);
573 }
574 case 0x5:
1036 }
1037 case 0x5:
575 return new WarnUnimplemented("vabal", machInst);
1038 return decodeNeonUSThreeUSReg<Vabal>(
1039 u, size, machInst, vd, vn, vm);
576 case 0x6:
577 if (u) {
1040 case 0x6:
1041 if (u) {
578 return new WarnUnimplemented("vrsubhn", machInst);
1042 return decodeNeonUThreeUSReg<Vrsubhn>(
1043 size, machInst, vd, vn, vm);
579 } else {
1044 } else {
580 return new WarnUnimplemented("vsubhn", machInst);
1045 return decodeNeonUThreeUSReg<Vsubhn>(
1046 size, machInst, vd, vn, vm);
581 }
582 case 0x7:
583 if (bits(machInst, 23)) {
1047 }
1048 case 0x7:
1049 if (bits(machInst, 23)) {
584 return new WarnUnimplemented("vabdl (int)", machInst);
1050 return decodeNeonUSThreeUSReg<Vabdl>(
1051 u, size, machInst, vd, vn, vm);
585 } else {
1052 } else {
586 return new WarnUnimplemented("vabd (int)", machInst);
1053 return decodeNeonUSThreeReg<VabdD, VabdQ>(
1054 bits(machInst, 6), u, size, machInst, vd, vn, vm);
587 }
588 case 0x8:
1055 }
1056 case 0x8:
589 return new WarnUnimplemented("vmlal (int)", machInst);
1057 return decodeNeonUSThreeUSReg<Vmlal>(
1058 u, size, machInst, vd, vn, vm);
590 case 0xa:
1059 case 0xa:
591 return new WarnUnimplemented("vmlsl (int)", machInst);
1060 return decodeNeonUSThreeUSReg<Vmlsl>(
1061 u, size, machInst, vd, vn, vm);
592 case 0x9:
1062 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 }
1063 if (u) {
1064 return new Unknown(machInst);
607 } else {
1065 } else {
608 return new WarnUnimplemented("vqdmlal", machInst);
1066 return decodeNeonSThreeUSReg<Vqdmlal>(
1067 size, machInst, vd, vn, vm);
609 }
610 case 0xb:
1068 }
1069 case 0xb:
611 if (!u) {
1070 if (u) {
612 return new Unknown(machInst);
613 } else {
1071 return new Unknown(machInst);
1072 } else {
614 return new WarnUnimplemented("vqdmlsl", machInst);
1073 return decodeNeonSThreeUSReg<Vqdmlsl>(
1074 size, machInst, vd, vn, vm);
615 }
616 case 0xc:
1075 }
1076 case 0xc:
617 return new WarnUnimplemented("vmull (int)", machInst);
1077 return decodeNeonUSThreeUSReg<Vmull>(
1078 u, size, machInst, vd, vn, vm);
618 case 0xd:
1079 case 0xd:
619 if (!u) {
1080 if (u) {
620 return new Unknown(machInst);
621 } else {
1081 return new Unknown(machInst);
1082 } else {
622 return new WarnUnimplemented("vqdmull", machInst);
1083 return decodeNeonSThreeUSReg<Vqdmull>(
1084 size, machInst, vd, vn, vm);
623 }
624 case 0xe:
1085 }
1086 case 0xe:
625 return new WarnUnimplemented("vmull (poly)", machInst);
1087 return decodeNeonUThreeUSReg<Vmullp>(
1088 size, machInst, vd, vn, vm);
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);
1089 }
1090 return new Unknown(machInst);
1091 }
1092
1093 static StaticInstPtr
1094 decodeNeonTwoRegScalar(ExtMachInst machInst)
1095 {
1096 const bool u = THUMB ? bits(machInst, 28) : bits(machInst, 24);
1097 const uint32_t a = bits(machInst, 11, 8);
635
1098 const unsigned size = bits(machInst, 21, 20);
1099 const IntRegIndex vd =
1100 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1101 (bits(machInst, 22) << 4)));
1102 const IntRegIndex vn =
1103 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1104 (bits(machInst, 7) << 4)));
1105 const IntRegIndex vm = (size == 2) ?
1106 (IntRegIndex)(2 * bits(machInst, 3, 0)) :
1107 (IntRegIndex)(2 * bits(machInst, 2, 0));
1108 const unsigned index = (size == 2) ? (unsigned)bits(machInst, 5) :
1109 (bits(machInst, 3) | (bits(machInst, 5) << 1));
636 switch (a) {
637 case 0x0:
1110 switch (a) {
1111 case 0x0:
638 return new WarnUnimplemented("vmla (int scalar)", machInst);
1112 if (u) {
1113 switch (size) {
1114 case 1:
1115 return new VmlasQ<uint16_t>(machInst, vd, vn, vm, index);
1116 case 2:
1117 return new VmlasQ<uint32_t>(machInst, vd, vn, vm, index);
1118 default:
1119 return new Unknown(machInst);
1120 }
1121 } else {
1122 switch (size) {
1123 case 1:
1124 return new VmlasD<uint16_t>(machInst, vd, vn, vm, index);
1125 case 2:
1126 return new VmlasD<uint32_t>(machInst, vd, vn, vm, index);
1127 default:
1128 return new Unknown(machInst);
1129 }
1130 }
639 case 0x1:
1131 case 0x1:
640 return new WarnUnimplemented("vmla (fp scalar)", machInst);
1132 if (u)
1133 return new VmlasQFp<float>(machInst, vd, vn, vm, index);
1134 else
1135 return new VmlasDFp<float>(machInst, vd, vn, vm, index);
641 case 0x4:
1136 case 0x4:
642 return new WarnUnimplemented("vmls (int scalar)", machInst);
1137 if (u) {
1138 switch (size) {
1139 case 1:
1140 return new VmlssQ<uint16_t>(machInst, vd, vn, vm, index);
1141 case 2:
1142 return new VmlssQ<uint32_t>(machInst, vd, vn, vm, index);
1143 default:
1144 return new Unknown(machInst);
1145 }
1146 } else {
1147 switch (size) {
1148 case 1:
1149 return new VmlssD<uint16_t>(machInst, vd, vn, vm, index);
1150 case 2:
1151 return new VmlssD<uint32_t>(machInst, vd, vn, vm, index);
1152 default:
1153 return new Unknown(machInst);
1154 }
1155 }
643 case 0x5:
1156 case 0x5:
644 return new WarnUnimplemented("vmls (fp scalar)", machInst);
1157 if (u)
1158 return new VmlssQFp<float>(machInst, vd, vn, vm, index);
1159 else
1160 return new VmlssDFp<float>(machInst, vd, vn, vm, index);
645 case 0x2:
1161 case 0x2:
646 return new WarnUnimplemented("vmlal (scalar)", machInst);
1162 if (u) {
1163 switch (size) {
1164 case 1:
1165 return new Vmlals<uint16_t>(machInst, vd, vn, vm, index);
1166 case 2:
1167 return new Vmlals<uint32_t>(machInst, vd, vn, vm, index);
1168 default:
1169 return new Unknown(machInst);
1170 }
1171 } else {
1172 switch (size) {
1173 case 1:
1174 return new Vmlals<int16_t>(machInst, vd, vn, vm, index);
1175 case 2:
1176 return new Vmlals<int32_t>(machInst, vd, vn, vm, index);
1177 default:
1178 return new Unknown(machInst);
1179 }
1180 }
647 case 0x6:
1181 case 0x6:
648 return new WarnUnimplemented("vmlsl (scalar)", machInst);
1182 if (u) {
1183 switch (size) {
1184 case 1:
1185 return new Vmlsls<uint16_t>(machInst, vd, vn, vm, index);
1186 case 2:
1187 return new Vmlsls<uint32_t>(machInst, vd, vn, vm, index);
1188 default:
1189 return new Unknown(machInst);
1190 }
1191 } else {
1192 switch (size) {
1193 case 1:
1194 return new Vmlsls<int16_t>(machInst, vd, vn, vm, index);
1195 case 2:
1196 return new Vmlsls<int32_t>(machInst, vd, vn, vm, index);
1197 default:
1198 return new Unknown(machInst);
1199 }
1200 }
649 case 0x3:
650 if (u) {
651 return new Unknown(machInst);
652 } else {
1201 case 0x3:
1202 if (u) {
1203 return new Unknown(machInst);
1204 } else {
653 return new WarnUnimplemented("vqdmlal", machInst);
1205 switch (size) {
1206 case 1:
1207 return new Vqdmlals<int16_t>(machInst, vd, vn, vm, index);
1208 case 2:
1209 return new Vqdmlals<int32_t>(machInst, vd, vn, vm, index);
1210 default:
1211 return new Unknown(machInst);
1212 }
654 }
655 case 0x7:
656 if (u) {
657 return new Unknown(machInst);
658 } else {
1213 }
1214 case 0x7:
1215 if (u) {
1216 return new Unknown(machInst);
1217 } else {
659 return new WarnUnimplemented("vqdmlsl", machInst);
1218 switch (size) {
1219 case 1:
1220 return new Vqdmlsls<int16_t>(machInst, vd, vn, vm, index);
1221 case 2:
1222 return new Vqdmlsls<int32_t>(machInst, vd, vn, vm, index);
1223 default:
1224 return new Unknown(machInst);
1225 }
660 }
661 case 0x8:
1226 }
1227 case 0x8:
662 return new WarnUnimplemented("vmul (int scalar)", machInst);
1228 if (u) {
1229 switch (size) {
1230 case 1:
1231 return new VmulsQ<uint16_t>(machInst, vd, vn, vm, index);
1232 case 2:
1233 return new VmulsQ<uint32_t>(machInst, vd, vn, vm, index);
1234 default:
1235 return new Unknown(machInst);
1236 }
1237 } else {
1238 switch (size) {
1239 case 1:
1240 return new VmulsD<uint16_t>(machInst, vd, vn, vm, index);
1241 case 2:
1242 return new VmulsD<uint32_t>(machInst, vd, vn, vm, index);
1243 default:
1244 return new Unknown(machInst);
1245 }
1246 }
663 case 0x9:
1247 case 0x9:
664 return new WarnUnimplemented("vmul (fp scalar)", machInst);
1248 if (u)
1249 return new VmulsQFp<float>(machInst, vd, vn, vm, index);
1250 else
1251 return new VmulsDFp<float>(machInst, vd, vn, vm, index);
665 case 0xa:
1252 case 0xa:
666 return new WarnUnimplemented("vmull (scalar)", machInst);
1253 if (u) {
1254 switch (size) {
1255 case 1:
1256 return new Vmulls<uint16_t>(machInst, vd, vn, vm, index);
1257 case 2:
1258 return new Vmulls<uint32_t>(machInst, vd, vn, vm, index);
1259 default:
1260 return new Unknown(machInst);
1261 }
1262 } else {
1263 switch (size) {
1264 case 1:
1265 return new Vmulls<int16_t>(machInst, vd, vn, vm, index);
1266 case 2:
1267 return new Vmulls<int32_t>(machInst, vd, vn, vm, index);
1268 default:
1269 return new Unknown(machInst);
1270 }
1271 }
667 case 0xb:
668 if (u) {
669 return new Unknown(machInst);
670 } else {
1272 case 0xb:
1273 if (u) {
1274 return new Unknown(machInst);
1275 } else {
671 return new WarnUnimplemented("vqdmull", machInst);
1276 if (u) {
1277 switch (size) {
1278 case 1:
1279 return new Vqdmulls<uint16_t>(
1280 machInst, vd, vn, vm, index);
1281 case 2:
1282 return new Vqdmulls<uint32_t>(
1283 machInst, vd, vn, vm, index);
1284 default:
1285 return new Unknown(machInst);
1286 }
1287 } else {
1288 switch (size) {
1289 case 1:
1290 return new Vqdmulls<int16_t>(
1291 machInst, vd, vn, vm, index);
1292 case 2:
1293 return new Vqdmulls<int32_t>(
1294 machInst, vd, vn, vm, index);
1295 default:
1296 return new Unknown(machInst);
1297 }
1298 }
672 }
673 case 0xc:
1299 }
1300 case 0xc:
674 return new WarnUnimplemented("vqdmulh", machInst);
1301 if (u) {
1302 switch (size) {
1303 case 1:
1304 return new VqdmulhsQ<int16_t>(
1305 machInst, vd, vn, vm, index);
1306 case 2:
1307 return new VqdmulhsQ<int32_t>(
1308 machInst, vd, vn, vm, index);
1309 default:
1310 return new Unknown(machInst);
1311 }
1312 } else {
1313 switch (size) {
1314 case 1:
1315 return new VqdmulhsD<int16_t>(
1316 machInst, vd, vn, vm, index);
1317 case 2:
1318 return new VqdmulhsD<int32_t>(
1319 machInst, vd, vn, vm, index);
1320 default:
1321 return new Unknown(machInst);
1322 }
1323 }
675 case 0xd:
1324 case 0xd:
676 return new WarnUnimplemented("vqrdmulh", machInst);
1325 if (u) {
1326 switch (size) {
1327 case 1:
1328 return new VqrdmulhsQ<int16_t>(
1329 machInst, vd, vn, vm, index);
1330 case 2:
1331 return new VqrdmulhsQ<int32_t>(
1332 machInst, vd, vn, vm, index);
1333 default:
1334 return new Unknown(machInst);
1335 }
1336 } else {
1337 switch (size) {
1338 case 1:
1339 return new VqrdmulhsD<int16_t>(
1340 machInst, vd, vn, vm, index);
1341 case 2:
1342 return new VqrdmulhsD<int32_t>(
1343 machInst, vd, vn, vm, index);
1344 default:
1345 return new Unknown(machInst);
1346 }
1347 }
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);
1348 }
1349 return new Unknown(machInst);
1350 }
1351
1352 static StaticInstPtr
1353 decodeNeonTwoRegMisc(ExtMachInst machInst)
1354 {
1355 const uint32_t a = bits(machInst, 17, 16);
1356 const uint32_t b = bits(machInst, 10, 6);
1357 const bool q = bits(machInst, 6);
1358 const IntRegIndex vd =
1359 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1360 (bits(machInst, 22) << 4)));
1361 const IntRegIndex vm =
1362 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1363 (bits(machInst, 5) << 4)));
1364 const unsigned size = bits(machInst, 19, 18);
686 switch (a) {
687 case 0x0:
688 switch (bits(b, 4, 1)) {
689 case 0x0:
1365 switch (a) {
1366 case 0x0:
1367 switch (bits(b, 4, 1)) {
1368 case 0x0:
690 return new WarnUnimplemented("vrev64", machInst);
1369 switch (size) {
1370 case 0:
1371 if (q) {
1372 return new NVrev64Q<uint8_t>(machInst, vd, vm);
1373 } else {
1374 return new NVrev64D<uint8_t>(machInst, vd, vm);
1375 }
1376 case 1:
1377 if (q) {
1378 return new NVrev64Q<uint16_t>(machInst, vd, vm);
1379 } else {
1380 return new NVrev64D<uint16_t>(machInst, vd, vm);
1381 }
1382 case 2:
1383 if (q) {
1384 return new NVrev64Q<uint32_t>(machInst, vd, vm);
1385 } else {
1386 return new NVrev64D<uint32_t>(machInst, vd, vm);
1387 }
1388 default:
1389 return new Unknown(machInst);
1390 }
691 case 0x1:
1391 case 0x1:
692 return new WarnUnimplemented("vrev32", machInst);
1392 switch (size) {
1393 case 0:
1394 if (q) {
1395 return new NVrev32Q<uint8_t>(machInst, vd, vm);
1396 } else {
1397 return new NVrev32D<uint8_t>(machInst, vd, vm);
1398 }
1399 case 1:
1400 if (q) {
1401 return new NVrev32Q<uint16_t>(machInst, vd, vm);
1402 } else {
1403 return new NVrev32D<uint16_t>(machInst, vd, vm);
1404 }
1405 default:
1406 return new Unknown(machInst);
1407 }
693 case 0x2:
1408 case 0x2:
694 return new WarnUnimplemented("vrev16", machInst);
1409 if (size != 0) {
1410 return new Unknown(machInst);
1411 } else if (q) {
1412 return new NVrev16Q<uint8_t>(machInst, vd, vm);
1413 } else {
1414 return new NVrev16D<uint8_t>(machInst, vd, vm);
1415 }
695 case 0x4:
1416 case 0x4:
1417 return decodeNeonSTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1418 q, size, machInst, vd, vm);
696 case 0x5:
1419 case 0x5:
697 return new WarnUnimplemented("vpaddl", machInst);
1420 return decodeNeonUTwoMiscSReg<NVpaddlD, NVpaddlQ>(
1421 q, size, machInst, vd, vm);
698 case 0x8:
1422 case 0x8:
699 return new WarnUnimplemented("vcls", machInst);
1423 return decodeNeonSTwoMiscReg<NVclsD, NVclsQ>(
1424 q, size, machInst, vd, vm);
700 case 0x9:
1425 case 0x9:
701 return new WarnUnimplemented("vclz", machInst);
1426 return decodeNeonSTwoMiscReg<NVclzD, NVclzQ>(
1427 q, size, machInst, vd, vm);
702 case 0xa:
1428 case 0xa:
703 return new WarnUnimplemented("vcnt", machInst);
1429 return decodeNeonUTwoMiscReg<NVcntD, NVcntQ>(
1430 q, size, machInst, vd, vm);
704 case 0xb:
1431 case 0xb:
705 return new WarnUnimplemented("vmvn (reg)", machInst);
1432 if (q)
1433 return new NVmvnQ<uint64_t>(machInst, vd, vm);
1434 else
1435 return new NVmvnD<uint64_t>(machInst, vd, vm);
706 case 0xc:
1436 case 0xc:
1437 return decodeNeonSTwoMiscSReg<NVpadalD, NVpadalQ>(
1438 q, size, machInst, vd, vm);
707 case 0xd:
1439 case 0xd:
708 return new WarnUnimplemented("vpadal", machInst);
1440 return decodeNeonUTwoMiscSReg<NVpadalD, NVpadalQ>(
1441 q, size, machInst, vd, vm);
709 case 0xe:
1442 case 0xe:
710 return new WarnUnimplemented("vqabs", machInst);
1443 return decodeNeonSTwoMiscReg<NVqabsD, NVqabsQ>(
1444 q, size, machInst, vd, vm);
711 case 0xf:
1445 case 0xf:
712 return new WarnUnimplemented("vqneg", machInst);
1446 return decodeNeonSTwoMiscReg<NVqnegD, NVqnegQ>(
1447 q, size, machInst, vd, vm);
713 default:
714 return new Unknown(machInst);
715 }
716 case 0x1:
717 switch (bits(b, 3, 1)) {
718 case 0x0:
1448 default:
1449 return new Unknown(machInst);
1450 }
1451 case 0x1:
1452 switch (bits(b, 3, 1)) {
1453 case 0x0:
719 return new WarnUnimplemented("vcgt (imm #0)", machInst);
1454 if (bits(b, 4)) {
1455 if (q) {
1456 return new NVcgtQFp<float>(machInst, vd, vm);
1457 } else {
1458 return new NVcgtDFp<float>(machInst, vd, vm);
1459 }
1460 } else {
1461 return decodeNeonSTwoMiscReg<NVcgtD, NVcgtQ>(
1462 q, size, machInst, vd, vm);
1463 }
720 case 0x1:
1464 case 0x1:
721 return new WarnUnimplemented("vcge (imm #0)", machInst);
1465 if (bits(b, 4)) {
1466 if (q) {
1467 return new NVcgeQFp<float>(machInst, vd, vm);
1468 } else {
1469 return new NVcgeDFp<float>(machInst, vd, vm);
1470 }
1471 } else {
1472 return decodeNeonSTwoMiscReg<NVcgeD, NVcgeQ>(
1473 q, size, machInst, vd, vm);
1474 }
722 case 0x2:
1475 case 0x2:
723 return new WarnUnimplemented("vceq (imm #0)", machInst);
1476 if (bits(b, 4)) {
1477 if (q) {
1478 return new NVceqQFp<float>(machInst, vd, vm);
1479 } else {
1480 return new NVceqDFp<float>(machInst, vd, vm);
1481 }
1482 } else {
1483 return decodeNeonSTwoMiscReg<NVceqD, NVceqQ>(
1484 q, size, machInst, vd, vm);
1485 }
724 case 0x3:
1486 case 0x3:
725 return new WarnUnimplemented("vcle (imm #0)", machInst);
1487 if (bits(b, 4)) {
1488 if (q) {
1489 return new NVcleQFp<float>(machInst, vd, vm);
1490 } else {
1491 return new NVcleDFp<float>(machInst, vd, vm);
1492 }
1493 } else {
1494 return decodeNeonSTwoMiscReg<NVcleD, NVcleQ>(
1495 q, size, machInst, vd, vm);
1496 }
726 case 0x4:
1497 case 0x4:
727 return new WarnUnimplemented("vclt (imm #0)", machInst);
1498 if (bits(b, 4)) {
1499 if (q) {
1500 return new NVcltQFp<float>(machInst, vd, vm);
1501 } else {
1502 return new NVcltDFp<float>(machInst, vd, vm);
1503 }
1504 } else {
1505 return decodeNeonSTwoMiscReg<NVcltD, NVcltQ>(
1506 q, size, machInst, vd, vm);
1507 }
728 case 0x6:
1508 case 0x6:
729 return new WarnUnimplemented("vabs (imm #0)", machInst);
1509 if (bits(machInst, 10)) {
1510 if (q)
1511 return new NVabsQFp<float>(machInst, vd, vm);
1512 else
1513 return new NVabsDFp<float>(machInst, vd, vm);
1514 } else {
1515 return decodeNeonSTwoMiscReg<NVabsD, NVabsQ>(
1516 q, size, machInst, vd, vm);
1517 }
730 case 0x7:
1518 case 0x7:
731 return new WarnUnimplemented("vneg (imm #0)", machInst);
1519 if (bits(machInst, 10)) {
1520 if (q)
1521 return new NVnegQFp<float>(machInst, vd, vm);
1522 else
1523 return new NVnegDFp<float>(machInst, vd, vm);
1524 } else {
1525 return decodeNeonSTwoMiscReg<NVnegD, NVnegQ>(
1526 q, size, machInst, vd, vm);
1527 }
732 }
733 case 0x2:
734 switch (bits(b, 4, 1)) {
735 case 0x0:
1528 }
1529 case 0x2:
1530 switch (bits(b, 4, 1)) {
1531 case 0x0:
736 return new WarnUnimplemented("vswp", machInst);
1532 if (q)
1533 return new NVswpQ<uint64_t>(machInst, vd, vm);
1534 else
1535 return new NVswpD<uint64_t>(machInst, vd, vm);
737 case 0x1:
1536 case 0x1:
738 return new WarnUnimplemented("vtrn", machInst);
1537 return decodeNeonUTwoMiscReg<NVtrnD, NVtrnQ>(
1538 q, size, machInst, vd, vm);
739 case 0x2:
1539 case 0x2:
740 return new WarnUnimplemented("vuzp", machInst);
1540 return decodeNeonUTwoMiscReg<NVuzpD, NVuzpQ>(
1541 q, size, machInst, vd, vm);
741 case 0x3:
1542 case 0x3:
742 return new WarnUnimplemented("vzip", machInst);
1543 return decodeNeonUTwoMiscReg<NVzipD, NVzipQ>(
1544 q, size, machInst, vd, vm);
743 case 0x4:
744 if (b == 0x8) {
1545 case 0x4:
1546 if (b == 0x8) {
745 return new WarnUnimplemented("vmovn", machInst);
1547 return decodeNeonUTwoMiscUSReg<NVmovn>(
1548 size, machInst, vd, vm);
746 } else {
1549 } else {
747 return new WarnUnimplemented("vqmovun", machInst);
1550 return decodeNeonSTwoMiscUSReg<NVqmovuns>(
1551 size, machInst, vd, vm);
748 }
749 case 0x5:
1552 }
1553 case 0x5:
750 return new WarnUnimplemented("vqmovn", machInst);
1554 if (q) {
1555 return decodeNeonUTwoMiscUSReg<NVqmovun>(
1556 size, machInst, vd, vm);
1557 } else {
1558 return decodeNeonSTwoMiscUSReg<NVqmovn>(
1559 size, machInst, vd, vm);
1560 }
751 case 0x6:
752 if (b == 0xc) {
1561 case 0x6:
1562 if (b == 0xc) {
753 return new WarnUnimplemented("vshll", machInst);
1563 const IntRegIndex vd =
1564 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1565 (bits(machInst, 22) << 4)));
1566 const IntRegIndex vm =
1567 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1568 (bits(machInst, 5) << 4)));
1569 unsigned size = bits(machInst, 19, 18);
1570 return decodeNeonSTwoShiftUSReg<NVshll>(
1571 size, machInst, vd, vm, 8 << size);
754 } else {
755 return new Unknown(machInst);
756 }
757 case 0xc:
758 case 0xe:
759 if (b == 0x18) {
1572 } else {
1573 return new Unknown(machInst);
1574 }
1575 case 0xc:
1576 case 0xe:
1577 if (b == 0x18) {
760 return new WarnUnimplemented("vcvt (single to half)",
761 machInst);
1578 if (size != 1 || (vm % 2))
1579 return new Unknown(machInst);
1580 return new NVcvts2h<uint16_t>(machInst, vd, vm);
762 } else if (b == 0x1c) {
1581 } else if (b == 0x1c) {
763 return new WarnUnimplemented("vcvt (half to single)",
764 machInst);
1582 if (size != 1 || (vd % 2))
1583 return new Unknown(machInst);
1584 return new NVcvth2s<uint16_t>(machInst, vd, vm);
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) {
1585 } else {
1586 return new Unknown(machInst);
1587 }
1588 default:
1589 return new Unknown(machInst);
1590 }
1591 case 0x3:
1592 if (bits(b, 4, 3) == 0x3) {
773 return new WarnUnimplemented("vcvt (fp and int)", machInst);
1593 if ((q && (vd % 2 || vm % 2)) || size != 2) {
1594 return new Unknown(machInst);
1595 } else {
1596 if (bits(b, 2)) {
1597 if (bits(b, 1)) {
1598 if (q) {
1599 return new NVcvt2ufxQ<float>(
1600 machInst, vd, vm, 0);
1601 } else {
1602 return new NVcvt2ufxD<float>(
1603 machInst, vd, vm, 0);
1604 }
1605 } else {
1606 if (q) {
1607 return new NVcvt2sfxQ<float>(
1608 machInst, vd, vm, 0);
1609 } else {
1610 return new NVcvt2sfxD<float>(
1611 machInst, vd, vm, 0);
1612 }
1613 }
1614 } else {
1615 if (bits(b, 1)) {
1616 if (q) {
1617 return new NVcvtu2fpQ<float>(
1618 machInst, vd, vm, 0);
1619 } else {
1620 return new NVcvtu2fpD<float>(
1621 machInst, vd, vm, 0);
1622 }
1623 } else {
1624 if (q) {
1625 return new NVcvts2fpQ<float>(
1626 machInst, vd, vm, 0);
1627 } else {
1628 return new NVcvts2fpD<float>(
1629 machInst, vd, vm, 0);
1630 }
1631 }
1632 }
1633 }
774 } else if ((b & 0x1a) == 0x10) {
1634 } else if ((b & 0x1a) == 0x10) {
775 return new WarnUnimplemented("vrecpe", machInst);
1635 if (bits(b, 2)) {
1636 if (q) {
1637 return new NVrecpeQFp<float>(machInst, vd, vm);
1638 } else {
1639 return new NVrecpeDFp<float>(machInst, vd, vm);
1640 }
1641 } else {
1642 if (q) {
1643 return new NVrecpeQ<uint32_t>(machInst, vd, vm);
1644 } else {
1645 return new NVrecpeD<uint32_t>(machInst, vd, vm);
1646 }
1647 }
776 } else if ((b & 0x1a) == 0x12) {
1648 } else if ((b & 0x1a) == 0x12) {
777 return new WarnUnimplemented("vrsqrte", machInst);
1649 if (bits(b, 2)) {
1650 if (q) {
1651 return new NVrsqrteQFp<float>(machInst, vd, vm);
1652 } else {
1653 return new NVrsqrteDFp<float>(machInst, vd, vm);
1654 }
1655 } else {
1656 if (q) {
1657 return new NVrsqrteQ<uint32_t>(machInst, vd, vm);
1658 } else {
1659 return new NVrsqrteD<uint32_t>(machInst, vd, vm);
1660 }
1661 }
778 } else {
779 return new Unknown(machInst);
780 }
781 }
782 return new Unknown(machInst);
783 }
784
785 StaticInstPtr

--- 8 unchanged lines hidden (view full) ---

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);
1662 } else {
1663 return new Unknown(machInst);
1664 }
1665 }
1666 return new Unknown(machInst);
1667 }
1668
1669 StaticInstPtr

--- 8 unchanged lines hidden (view full) ---

1678 } else if ((c & 0x9) == 1) {
1679 if ((a & 0x7) == 0) {
1680 return decodeNeonOneRegModImm(machInst);
1681 } else {
1682 return decodeNeonTwoRegAndShift(machInst);
1683 }
1684 } else if ((c & 0x9) == 9) {
1685 return decodeNeonTwoRegAndShift(machInst);
802 } else if ((c & 0x5) == 0) {
803 if (bits(a, 3, 2) != 0x3) {
1686 } else if (bits(a, 2, 1) != 0x3) {
1687 if ((c & 0x5) == 0) {
804 return decodeNeonThreeRegDiffLengths(machInst);
1688 return decodeNeonThreeRegDiffLengths(machInst);
805 }
806 } else if ((c & 0x5) == 4) {
807 if (bits(a, 3, 2) != 0x3) {
1689 } else if ((c & 0x5) == 4) {
808 return decodeNeonTwoRegScalar(machInst);
809 }
810 } else if ((a & 0x16) == 0x16) {
1690 return decodeNeonTwoRegScalar(machInst);
1691 }
1692 } else if ((a & 0x16) == 0x16) {
1693 const IntRegIndex vd =
1694 (IntRegIndex)(2 * (bits(machInst, 15, 12) |
1695 (bits(machInst, 22) << 4)));
1696 const IntRegIndex vn =
1697 (IntRegIndex)(2 * (bits(machInst, 19, 16) |
1698 (bits(machInst, 7) << 4)));
1699 const IntRegIndex vm =
1700 (IntRegIndex)(2 * (bits(machInst, 3, 0) |
1701 (bits(machInst, 5) << 4)));
811 if (!u) {
812 if (bits(c, 0) == 0) {
1702 if (!u) {
1703 if (bits(c, 0) == 0) {
813 return new WarnUnimplemented("vext", machInst);
1704 unsigned imm4 = bits(machInst, 11, 8);
1705 bool q = bits(machInst, 6);
1706 if (imm4 >= 16 && !q)
1707 return new Unknown(machInst);
1708 if (q) {
1709 return new NVextQ<uint8_t>(machInst, vd, vn, vm, imm4);
1710 } else {
1711 return new NVextD<uint8_t>(machInst, vd, vn, vm, imm4);
1712 }
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) {
1713 }
1714 } else if (bits(b, 3) == 0 && bits(c, 0) == 0) {
1715 return decodeNeonTwoRegMisc(machInst);
1716 } else if (bits(b, 3, 2) == 0x2 && bits(c, 0) == 0) {
1717 unsigned length = bits(machInst, 9, 8) + 1;
1718 if ((uint32_t)vn / 2 + length > 32)
1719 return new Unknown(machInst);
818 if (bits(machInst, 6) == 0) {
1720 if (bits(machInst, 6) == 0) {
819 return new WarnUnimplemented("vtbl", machInst);
1721 switch (length) {
1722 case 1:
1723 return new NVtbl1(machInst, vd, vn, vm);
1724 case 2:
1725 return new NVtbl2(machInst, vd, vn, vm);
1726 case 3:
1727 return new NVtbl3(machInst, vd, vn, vm);
1728 case 4:
1729 return new NVtbl4(machInst, vd, vn, vm);
1730 }
820 } else {
1731 } else {
821 return new WarnUnimplemented("vtbx", machInst);
1732 switch (length) {
1733 case 1:
1734 return new NVtbx1(machInst, vd, vn, vm);
1735 case 2:
1736 return new NVtbx2(machInst, vd, vn, vm);
1737 case 3:
1738 return new NVtbx3(machInst, vd, vn, vm);
1739 case 4:
1740 return new NVtbx4(machInst, vd, vn, vm);
1741 }
822 }
823 } else if (b == 0xc && (c & 0x9) == 0) {
1742 }
1743 } else if (b == 0xc && (c & 0x9) == 0) {
824 return new WarnUnimplemented("vdup (scalar)", machInst);
1744 unsigned imm4 = bits(machInst, 19, 16);
1745 if (bits(imm4, 2, 0) == 0)
1746 return new Unknown(machInst);
1747 unsigned size = 0;
1748 while ((imm4 & 0x1) == 0) {
1749 size++;
1750 imm4 >>= 1;
1751 }
1752 unsigned index = imm4 >> 1;
1753 const bool q = bits(machInst, 6);
1754 return decodeNeonUTwoShiftSReg<NVdupD, NVdupQ>(
1755 q, size, machInst, vd, vm, index);
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 = '''
1756 }
1757 }
1758 return new Unknown(machInst);
1759 }
1760 '''
1761}};
1762
1763def format ThumbNeonMem() {{
1764 decode_block = '''
1765 return decodeNeonMem(machInst);
1766 '''
1767}};
1768
1769def format ThumbNeonData() {{
1770 decode_block = '''
840 return decodeNeonMem(machInst);
1771 return decodeNeonData(machInst);
841 '''
842}};
843
844let {{
845 header_output = '''
846 StaticInstPtr
847 decodeExtensionRegLoadStore(ExtMachInst machInst);
848 '''

--- 39 unchanged lines hidden (view full) ---

888 } else {
889 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
890 rt, rt2);
891 }
892 }
893 break;
894 case 0x1:
895 {
1772 '''
1773}};
1774
1775let {{
1776 header_output = '''
1777 StaticInstPtr
1778 decodeExtensionRegLoadStore(ExtMachInst machInst);
1779 '''

--- 39 unchanged lines hidden (view full) ---

1819 } else {
1820 return new Vmov2Reg2Core(machInst, (IntRegIndex)vm,
1821 rt, rt2);
1822 }
1823 }
1824 break;
1825 case 0x1:
1826 {
896 if (offset == 0 || vd + offset > NumFloatArchRegs) {
1827 if (offset == 0 || vd + offset/2 > 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,

--- 134 unchanged lines hidden (view full) ---

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);
1828 break;
1829 }
1830 switch (bits(opcode, 1, 0)) {
1831 case 0x0:
1832 return new VLdmStm(machInst, rn, vd, single,
1833 true, false, false, offset);
1834 case 0x1:
1835 return new VLdmStm(machInst, rn, vd, single,

--- 134 unchanged lines hidden (view full) ---

1970 return new Unknown(machInst);
1971 }
1972 return new Vmsr(machInst, (IntRegIndex)specReg, rt);
1973 }
1974 } else if (l == 0 && c == 1) {
1975 if (bits(a, 2) == 0) {
1976 uint32_t vd = (bits(machInst, 7) << 5) |
1977 (bits(machInst, 19, 16) << 1);
1047 uint32_t index, size;
1978 // Handle accessing each single precision half of the vector.
1979 vd += bits(machInst, 21);
1048 const IntRegIndex rt =
1049 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1050 if (bits(machInst, 22) == 1) {
1980 const IntRegIndex rt =
1981 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
1982 if (bits(machInst, 22) == 1) {
1051 size = 8;
1052 index = (bits(machInst, 21) << 2) |
1053 bits(machInst, 6, 5);
1983 return new VmovCoreRegB(machInst, (IntRegIndex)vd,
1984 rt, bits(machInst, 6, 5));
1054 } else if (bits(machInst, 5) == 1) {
1985 } else if (bits(machInst, 5) == 1) {
1055 size = 16;
1056 index = (bits(machInst, 21) << 1) |
1057 bits(machInst, 6);
1986 return new VmovCoreRegH(machInst, (IntRegIndex)vd,
1987 rt, bits(machInst, 6));
1058 } else if (bits(machInst, 6) == 0) {
1988 } else if (bits(machInst, 6) == 0) {
1059 size = 32;
1060 index = bits(machInst, 21);
1989 return new VmovCoreRegW(machInst, (IntRegIndex)vd, rt);
1061 } else {
1062 return new Unknown(machInst);
1063 }
1990 } else {
1991 return new Unknown(machInst);
1992 }
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) {
1993 } else if (bits(b, 1) == 0) {
1079 // A8-594
1080 return new WarnUnimplemented("vdup", machInst);
1994 bool q = bits(machInst, 21);
1995 unsigned be = (bits(machInst, 22) << 1) | (bits(machInst, 5));
1996 IntRegIndex vd = (IntRegIndex)(2 * (uint32_t)
1997 (bits(machInst, 19, 16) | (bits(machInst, 7) << 4)));
1998 IntRegIndex rt = (IntRegIndex)(uint32_t)
1999 bits(machInst, 15, 12);
2000 if (q) {
2001 switch (be) {
2002 case 0:
2003 return new NVdupQGpr<uint32_t>(machInst, vd, rt);
2004 case 1:
2005 return new NVdupQGpr<uint16_t>(machInst, vd, rt);
2006 case 2:
2007 return new NVdupQGpr<uint8_t>(machInst, vd, rt);
2008 case 3:
2009 return new Unknown(machInst);
2010 }
2011 } else {
2012 switch (be) {
2013 case 0:
2014 return new NVdupDGpr<uint32_t>(machInst, vd, rt);
2015 case 1:
2016 return new NVdupDGpr<uint16_t>(machInst, vd, rt);
2017 case 2:
2018 return new NVdupDGpr<uint8_t>(machInst, vd, rt);
2019 case 3:
2020 return new Unknown(machInst);
2021 }
2022 }
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) {

--- 34 unchanged lines hidden (view full) ---

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);
2023 }
2024 } else if (l == 1 && c == 0) {
2025 if (a == 0) {
2026 const uint32_t vn = (bits(machInst, 19, 16) << 1) |
2027 bits(machInst, 7);
2028 const IntRegIndex rt =
2029 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2030 if (bits(machInst, 20) == 1) {

--- 34 unchanged lines hidden (view full) ---

2065 (IntRegIndex)specReg, (uint32_t)cpsrMask);
2066 } else {
2067 return new Vmrs(machInst, rt, (IntRegIndex)specReg);
2068 }
2069 }
2070 } else {
2071 uint32_t vd = (bits(machInst, 7) << 5) |
2072 (bits(machInst, 19, 16) << 1);
1131 uint32_t index, size;
2073 // Handle indexing into each single precision half of the vector.
2074 vd += bits(machInst, 21);
2075 uint32_t index;
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) {
2076 const IntRegIndex rt =
2077 (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
2078 const bool u = (bits(machInst, 23) == 1);
2079 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:
2080 index = bits(machInst, 6, 5);
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 }
2081 if (u) {
2082 return new VmovRegCoreUB(machInst, rt,
2083 (IntRegIndex)vd, index);
2084 } else {
2085 return new VmovRegCoreSB(machInst, rt,
2086 (IntRegIndex)vd, index);
2087 }
1162 case 16:
2088 } else if (bits(machInst, 5) == 1) {
2089 index = bits(machInst, 6);
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 }
2090 if (u) {
2091 return new VmovRegCoreUH(machInst, rt,
2092 (IntRegIndex)vd, index);
2093 } else {
2094 return new VmovRegCoreSH(machInst, rt,
2095 (IntRegIndex)vd, index);
2096 }
1170 case 32:
2097 } else if (bits(machInst, 6) == 0 && !u) {
1171 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2098 return new VmovRegCoreW(machInst, rt, (IntRegIndex)vd);
2099 } else {
2100 return new Unknown(machInst);
1172 }
1173 }
1174 return new Unknown(machInst);
1175 }
1176 '''
1177}};
1178
1179def format ShortFpTransfer() {{

--- 385 unchanged lines hidden ---
2101 }
2102 }
2103 return new Unknown(machInst);
2104 }
2105 '''
2106}};
2107
2108def format ShortFpTransfer() {{

--- 385 unchanged lines hidden ---